Hi, On Mon, 4 Nov 2013 16:40:38, Dodji Seketeli wrote: > +static ssize_t > +get_line (char **lineptr, size_t *n, FILE *fp) > +{ > + ssize_t cur_len = 0, len; > + char buf[16384]; > + > + if (lineptr == NULL || n == NULL) > + return -1; > + > + if (*lineptr == NULL || *n == 0) > + { > + *n = 120; > + *lineptr = XNEWVEC (char, *n); > + } > + > + len = fread (buf, 1, sizeof buf, fp); > + if (ferror (fp)) > + return -1; > + > + for (;;) > + { > + size_t needed; > + char *t = (char*) memchr (buf, '\n', len); > + if (t != NULL) len = (t - buf) + 1; > + if (__builtin_expect (len>= SSIZE_MAX - cur_len, 0)) > + return -1; > + needed = cur_len + len + 1; > + if (needed> *n) > + { > + char *new_lineptr; > + if (needed < 2 * *n) > + needed = 2 * *n; > + new_lineptr = XRESIZEVEC (char, *lineptr, needed); > + *lineptr = new_lineptr; > + *n = needed; > + } > + memcpy (*lineptr + cur_len, buf, len); > + cur_len += len; > + if (t != NULL) > + break; > + len = fread (buf, 1, sizeof buf, fp); > + if (ferror (fp)) > + return -1; > + if (len == 0) > + break; > + } > + (*lineptr)[cur_len] = '\0'; > + return cur_len; > +} > + > +/* Reads one line from FILE into a static buffer. LINE_LENGTH is set > + by this function to the length of the returned line. Note that the > + returned line can contain several zero bytes. */ > static const char * > -read_line (FILE *file) > +read_line (FILE *file, int *line_length) > { > static char *string; > - static size_t string_len; > + static size_t string_len, cur_len; > size_t pos = 0; > char *ptr; > > if (!string_len) > { > string_len = 200; > - string = XNEWVEC (char, string_len); > + string = XCNEWVEC (char, string_len); > } > + else > + memset (string, 0, string_len);
Is this memset still necessary? If the previous invocation of read_line already had read some characters of the following line, how is that information recovered? How is it detected if another file is to be read this time? > > - while ((ptr = fgets (string + pos, string_len - pos, file))) > + ptr = string; > + cur_len = string_len; > + while (size_t len = get_line (&ptr, &cur_len, file)) > { > - size_t len = strlen (string + pos); > - > - if (string[pos + len - 1] == '\n') > + if (ptr[len - 1] == '\n') > { > - string[pos + len - 1] = 0; > + ptr[len - 1] = 0; > + *line_length = len; > return string; > } > pos += len; > string = XRESIZEVEC (char, string, string_len * 2); > string_len *= 2; > - } > - > + ptr = string + pos; If "ptr" is passed to get_line it will try to reallocate it, which must fail, right? Maybe, this line of code is unreachable? Who is responsible for reallocating "string" get_line or read_line? > + cur_len = string_len - pos; > + } > + > + *line_length = pos ? string_len : 0; > return pos ? string : NULL; > } > > /* Return the physical source line that corresponds to xloc in a > buffer that is statically allocated. The newline is replaced by > - the null character. */ > + the null character. Note that the line can contain several null > + characters, so LINE_LEN contains the actual length of the line. */ > > const char * > -location_get_source_line (expanded_location xloc) > +location_get_source_line (expanded_location xloc, > + int& line_len) > { > const char *buffer; > int lines = 1; > @@ -132,7 +204,7 @@ location_get_source_line (expanded_location xloc) > if (!stream) > return NULL; > > - while ((buffer = read_line (stream)) && lines < xloc.line) > + while ((buffer = read_line (stream, &line_len)) && lines < xloc.line) > lines++; > > fclose (stream); Regards Bernd.