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 |
char ukcprog_fpgetline_sccsid[] = "$Id: fpgetline.c,v 1.7 1993/10/09 15:22:28 mtr Exp $ UKC"; |
11 |
|
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 |
} |