Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6536 | serge | 1 | /* Copyright 2002, Red Hat Inc. - all rights reserved */ |
2 | /* |
||
3 | FUNCTION |
||
4 | < |
||
5 | |||
6 | INDEX |
||
7 | getdelim |
||
8 | |||
9 | ANSI_SYNOPSIS |
||
10 | #include |
||
11 | int getdelim(char **<[bufptr]>, size_t *<[n]>, |
||
12 | int <[delim]>, FILE *<[fp]>); |
||
13 | |||
14 | TRAD_SYNOPSIS |
||
15 | #include |
||
16 | int getdelim(<[bufptr]>, <[n]>, <[delim]>, <[fp]>) |
||
17 | char **<[bufptr]>; |
||
18 | size_t *<[n]>; |
||
19 | int <[delim]>; |
||
20 | FILE *<[fp]>; |
||
21 | |||
22 | DESCRIPTION |
||
23 | < |
||
24 | delimiter <[delim]>. The line is read into a buffer pointed to |
||
25 | by <[bufptr]> and designated with size *<[n]>. If the buffer is |
||
26 | not large enough, it will be dynamically grown by < |
||
27 | As the buffer is grown, the pointer to the size <[n]> will be |
||
28 | updated. |
||
29 | |||
30 | RETURNS |
||
31 | < |
||
32 | otherwise, it returns the number of bytes successfully read. |
||
33 | At end of file, the result is nonzero. |
||
34 | |||
35 | PORTABILITY |
||
36 | < |
||
37 | |||
38 | No supporting OS subroutines are directly required. |
||
39 | */ |
||
40 | |||
41 | #include <_ansi.h> |
||
42 | #include |
||
43 | #include |
||
44 | #include |
||
45 | #include "local.h" |
||
46 | |||
47 | #define MIN_LINE_SIZE 4 |
||
48 | #define DEFAULT_LINE_SIZE 128 |
||
49 | |||
50 | ssize_t |
||
51 | _DEFUN(__getdelim, (bufptr, n, delim, fp), |
||
52 | char **bufptr _AND |
||
53 | size_t *n _AND |
||
54 | int delim _AND |
||
55 | FILE *fp) |
||
56 | { |
||
57 | char *buf; |
||
58 | char *ptr; |
||
59 | size_t newsize, numbytes; |
||
60 | int pos; |
||
61 | int ch; |
||
62 | int cont; |
||
63 | |||
64 | if (fp == NULL || bufptr == NULL || n == NULL) |
||
65 | { |
||
66 | errno = EINVAL; |
||
67 | return -1; |
||
68 | } |
||
69 | |||
70 | buf = *bufptr; |
||
71 | if (buf == NULL || *n < MIN_LINE_SIZE) |
||
72 | { |
||
73 | buf = (char *)realloc (*bufptr, DEFAULT_LINE_SIZE); |
||
74 | if (buf == NULL) |
||
75 | { |
||
76 | return -1; |
||
77 | } |
||
78 | *bufptr = buf; |
||
79 | *n = DEFAULT_LINE_SIZE; |
||
80 | } |
||
81 | |||
82 | CHECK_INIT (_REENT, fp); |
||
83 | |||
84 | _newlib_flockfile_start (fp); |
||
85 | |||
86 | numbytes = *n; |
||
87 | ptr = buf; |
||
88 | |||
89 | cont = 1; |
||
90 | |||
91 | while (cont) |
||
92 | { |
||
93 | /* fill buffer - leaving room for nul-terminator */ |
||
94 | while (--numbytes > 0) |
||
95 | { |
||
96 | if ((ch = getc_unlocked (fp)) == EOF) |
||
97 | { |
||
98 | cont = 0; |
||
99 | break; |
||
100 | } |
||
101 | else |
||
102 | { |
||
103 | *ptr++ = ch; |
||
104 | if (ch == delim) |
||
105 | { |
||
106 | cont = 0; |
||
107 | break; |
||
108 | } |
||
109 | } |
||
110 | } |
||
111 | |||
112 | if (cont) |
||
113 | { |
||
114 | /* Buffer is too small so reallocate a larger buffer. */ |
||
115 | pos = ptr - buf; |
||
116 | newsize = (*n << 1); |
||
117 | buf = realloc (buf, newsize); |
||
118 | if (buf == NULL) |
||
119 | { |
||
120 | cont = 0; |
||
121 | break; |
||
122 | } |
||
123 | |||
124 | /* After reallocating, continue in new buffer */ |
||
125 | *bufptr = buf; |
||
126 | *n = newsize; |
||
127 | ptr = buf + pos; |
||
128 | numbytes = newsize - pos; |
||
129 | } |
||
130 | } |
||
131 | |||
132 | _newlib_flockfile_end (fp); |
||
133 | |||
134 | /* if no input data, return failure */ |
||
135 | if (ptr == buf) |
||
136 | return -1; |
||
137 | |||
138 | /* otherwise, nul-terminate and return number of bytes read */ |
||
139 | *ptr = '\0'; |
||
140 | return (ssize_t)(ptr - buf); |
||
141 | }><>> |
||
142 |