views:

835

answers:

3

The experiment I am currently working uses a software base with a complicated source history and no well defined license. It would be a considerable amount of work to rationalize things and release under a fixed license.

It is also intended to run a a random unixish platform, and only some of the libc's we support have GNU getline, but right now the code expects it.

Does anyone know of a re-implementation of the GNU getline semantics that is available under a less restrictive license?

Edit:: I ask because google didn't help, and I'd like to avoid writing one if possible (it might be a fun exercise, but it can't be the best use of my time...)

To be more specific, the interface in question is:

size_t getline(char **_lineptr, size_t *_n, FILE *_stream);
+1  A: 

Take a look at Paul Hsieh's page on User Input. You can email the author if you want to know the exact terms.

dirkgently
If I must write something this will doubtless be a good scaffold. Thanks.
dmckee
Did you take a look at the example: 'size_t fgetstralloc (char ** p, FILE * fp)' on the page I linked to?
dirkgently
::sigh:: Of course not. I only looked at the page a couple of times. And I'm a trained observer, too.
dmckee
A: 

In case you are talking about readline, check out: editline

mitchnull
Nice, but I'm afraid I really mean getline.
dmckee
Eh, sorry, it's just that I usually found requests for readline replacement :)
mitchnull
It happens. The FGITW thing makes it happen a lot, but it does no harm...
dmckee
+1  A: 

I'm puzzled.

I looked at the link, read the description, and this is a fine utility.

But, are you saying you simply can't rewrite this function to spec? The spec seems quite clear,

Here:

/* This code is public domain -- Will Hartung 4/9/09 */
#include <stdio.h>
#include <stdlib.h>

size_t getline(char **lineptr, size_t *n, FILE *stream) {
    char *bufptr = NULL;
    char *p = bufptr;
    size_t size;
    int c;

    if (lineptr == NULL) {
     return -1;
    }
    if (stream == NULL) {
     return -1;
    }
    if (n == NULL) {
     return -1;
    }
    bufptr = *lineptr;
    size = *n;

    c = fgetc(stream);
    if (c == EOF) {
     return -1;
    }
    if (bufptr == NULL) {
     bufptr = malloc(128);
     if (bufptr == NULL) {
      return -1;
     }
     size = 128;
    }
    p = bufptr;
    while(c != EOF) {
     if ((p - bufptr) > (size - 1)) {
      size = size + 128;
      bufptr = realloc(bufptr, size);
      if (bufptr == NULL) {
       return -1;
      }
     }
     *p++ = c;
     if (c == '\n') {
      break;
     }
     c = fgetc(stream);
    }

    *p++ = '\0';
    *lineptr = bufptr;
    *n = size;

    return p - bufptr - 1;
}

int main(int argc, char** args) {
    char *buf = NULL; /*malloc(10);*/
    int bufSize = 0; /*10;*/

    printf("%d\n", bufSize);
    int charsRead =  getline(&buf, &bufSize, stdin);

    printf("'%s'", buf);
    printf("%d\n", bufSize);
    return 0;
}

15 minutes, and I haven't written C in 10 years. It minorly breaks the getline contract in that it only checks if the lineptr is NULL, rather than NULL and n == 0. You can fix that if you like. (The other case didn't make a whole lot of sense to me, I guess you could return -1 in that case.)

Replace the '\n' with a variable to implement "getdelim".

Do people still write code any more?

Will Hartung
I was saying that I'm lazy...
dmckee
This works fine for short strings but may fail after reallocation. bufptr may get a new address and p needs to be kept at the same relative offset. In my tests (with MinGW), realloc may return several times with the same pointer (if there happens to be enough memory at that spot) or may return a new address on the first reallocation. The new address can be near in memory or a ways away, and can also be before the first address as well as after. IE it can make p a random number. To fix, put "offset = p - bufptr;" under the while EOF line, and "p = bufptr + offset;" after the if NULL block.
Todd