1 |
tdb |
1.1 |
/* fpgetline.c - read an arbitrary length line from a stdio stream */ |
2 |
|
|
|
3 |
|
|
/* Copyright 1992 Mark Russell, University of Kent at Canterbury. |
4 |
|
|
* |
5 |
|
|
* You can do what you like with this source code as long as |
6 |
|
|
* you don't try to make money out of it and you include an |
7 |
|
|
* unaltered copy of this message (including the copyright). |
8 |
|
|
*/ |
9 |
|
|
|
10 |
tdb |
1.2 |
char ukcprog_fpgetline_sccsid[] = "$Id: fpgetline.c,v 1.1 2002/03/08 14:37:29 tdb Exp $ UKC"; |
11 |
tdb |
1.1 |
|
12 |
|
|
#ifndef __STDC__ |
13 |
|
|
#include <sys/types.h> /* for size_t */ |
14 |
|
|
#endif |
15 |
|
|
|
16 |
|
|
#include <stdio.h> |
17 |
|
|
#include <stdlib.h> |
18 |
|
|
|
19 |
|
|
#include "ukcprog.h" |
20 |
|
|
|
21 |
|
|
#define SMALLBUF_SIZE ((size_t)200) |
22 |
|
|
|
23 |
|
|
char * |
24 |
|
|
fpgetline(fp) |
25 |
|
|
FILE *fp; |
26 |
|
|
{ |
27 |
|
|
static char *buf; |
28 |
|
|
static size_t bufsize = 0; |
29 |
|
|
int ch, pos; |
30 |
|
|
|
31 |
|
|
if (bufsize == 0) { |
32 |
|
|
bufsize = 80; |
33 |
|
|
buf = e_malloc(bufsize + 1); |
34 |
|
|
} |
35 |
|
|
|
36 |
|
|
for (pos = 0; (ch = getc(fp)) != EOF && ch != '\n'; buf[pos++] = ch) { |
37 |
|
|
if (pos == bufsize) { |
38 |
|
|
bufsize *= 2; |
39 |
|
|
buf = e_realloc(buf, bufsize + 1); |
40 |
|
|
} |
41 |
|
|
} |
42 |
|
|
buf[pos] = '\0'; |
43 |
|
|
|
44 |
|
|
/* If we have a huge buffer from the last call and now have a |
45 |
|
|
* short line, try to dump the excess. |
46 |
|
|
*/ |
47 |
|
|
if (pos <= SMALLBUF_SIZE && bufsize > 5000) { |
48 |
|
|
char *smallbuf; |
49 |
|
|
|
50 |
|
|
if ((smallbuf = realloc(buf, SMALLBUF_SIZE + 1)) != NULL) { |
51 |
|
|
buf = smallbuf; |
52 |
|
|
bufsize = SMALLBUF_SIZE; |
53 |
|
|
} |
54 |
|
|
} |
55 |
|
|
|
56 |
|
|
return (pos == 0 && ch == EOF) ? NULL : buf; |
57 |
|
|
} |