]> pd.if.org Git - pdclib/blob - functions/stdio/fgets.c
Re-import from Subversion.
[pdclib] / functions / stdio / fgets.c
1 /* ----------------------------------------------------------------------------
2  * $Id$
3  * ----------------------------------------------------------------------------
4  * Public Domain C Library - http://pdclib.sourceforge.net
5  * This code is Public Domain. Use, modify, and redistribute at will.
6  * --------------------------------------------------------------------------*/
7
8 char * fgets( char * restrict s, int n, FILE * restrict stream ) { /* TODO */ };
9
10 /* PDPC code - unreviewed
11 /*
12
13 In fgets, we have the following possibilites...
14
15 1. we found a genuine '\n' that terminated the search.
16 2. we hit the '\n' at the endbuf.
17 3. we hit the '\n' sentinel.
18
19 */
20 #ifndef __MVS__
21 char *fgets(char *s, int n, FILE *stream)
22 {
23     char *p;
24     register char *t;
25     register char *u = s;
26     int c;
27     int processed;
28 #ifdef __OS2__
29     ULONG actualRead;
30     APIRET rc;
31 #endif
32 #ifdef __MSDOS__
33     size_t actualRead;
34     int errind;
35 #endif
36
37     if (stream->quickText)
38     {
39         p = stream->upto + n - 1;
40         t = stream->upto;
41         if (p < stream->endbuf)
42         {
43             c = *p;
44             *p = '\n';
45 #ifdef __OS2__
46             if (n < 8)
47             {
48 #endif
49                 while ((*u++ = *t++) != '\n') ; /* tight inner loop */
50 #ifdef __OS2__
51             }
52             else
53             {
54                 register unsigned int *i1;
55                 register unsigned int *i2;
56                 register unsigned int z;
57
58                 i1 = (unsigned int *)t;
59                 i2 = (unsigned int *)u;
60                 while (1)
61                 {
62                     z = *i1;
63                     if ((z & 0xffU) == '\n') break;
64                     z >>= 8;
65                     if ((z & 0xffU) == '\n') break;
66                     z >>= 8;
67                     if ((z & 0xffU) == '\n') break;
68                     z >>= 8;
69                     if ((z & 0xffU) == '\n') break;
70                     *i2++ = *i1++;
71                 }
72                 t = (char *)i1;
73                 u = (char *)i2;
74                 while ((*u++ = *t++) != '\n') ;
75             }
76 #endif
77             *p = (char)c;
78             if (t <= p)
79             {
80                 if (*(t - 2) == '\r') /* t is protected, u isn't */
81                 {
82                     *(u - 2) = '\n';
83                     *(u - 1) = '\0';
84                 }
85                 else
86                 {
87                     *u = '\0';
88                 }
89                 stream->upto = t;
90                 return (s);
91             }
92             else
93             {
94                 processed = (int)(t - stream->upto) - 1;
95                 stream->upto = t - 1;
96                 u--;
97             }
98         }
99         else
100         {
101             while ((*u++ = *t++) != '\n') ; /* tight inner loop */
102             if (t <= stream->endbuf)
103             {
104                 if (*(t - 2) == '\r') /* t is protected, u isn't */
105                 {
106                     *(u - 2) = '\n';
107                     *(u - 1) = '\0';
108                 }
109                 else
110                 {
111                     *u = '\0';
112                 }
113                 stream->upto = t;
114                 return (s);
115             }
116             else
117             {
118                 processed = (int)(t - stream->upto) - 1;
119                 stream->upto = t - 1;
120                 u--;
121             }
122         }
123     }
124     else
125     {
126         processed = 0;
127     }
128
129     if (n < 1)
130     {
131         return (NULL);
132     }
133     if (n < 2)
134     {
135         *u = '\0';
136         return (s);
137     }
138     if (stream->ungetCh != -1)
139     {
140         processed++;
141         *u++ = (char)stream->ungetCh;
142         stream->ungetCh = -1;
143     }
144     while (1)
145     {
146         t = stream->upto;
147         p = stream->upto + (n - processed) - 1;
148         if (p < stream->endbuf)
149         {
150             c = *p;
151             *p = '\n';
152         }
153         if (stream->noNl)
154         {
155             while (((*u++ = *t) != '\n') && (*t++ != '\r')) ;
156             if (*(u - 1) == '\n')
157             {
158                 t++;
159             }
160             else
161             {
162                 u--;
163                 while ((*u++ = *t++) != '\n') ;
164             }
165         }
166         else
167         {
168             while ((*u++ = *t++) != '\n') ; /* tight inner loop */
169         }
170         if (p < stream->endbuf)
171         {
172             *p = (char)c;
173         }
174         if (((t <= p) && (p < stream->endbuf))
175            || ((t <= stream->endbuf) && (p >= stream->endbuf)))
176         {
177             if (stream->textMode)
178             {
179                 if (stream->noNl)
180                 {
181                     if ((*(t - 1) == '\r') || (*(t - 1) == '\n'))
182                     {
183                         *(u - 1) = '\0';
184                     }
185                     else
186                     {
187                         *u = '\0';
188                     }
189                 }
190                 else if (*(t - 2) == '\r') /* t is protected, u isn't */
191                 {
192                     *(u - 2) = '\n';
193                     *(u - 1) = '\0';
194                 }
195                 else
196                 {
197                     *u = '\0';
198                 }
199             }
200             stream->upto = t;
201             if (stream->textMode)
202             {
203                 stream->quickText = 1;
204             }
205             return (s);
206         }
207         else if (((t > p) && (p < stream->endbuf))
208                  || ((t > stream->endbuf) && (p >= stream->endbuf)))
209         {
210             int leave = 1;
211
212             if (stream->textMode)
213             {
214                 if (t > stream->endbuf)
215                 {
216                     if ((t - stream->upto) > 1)
217                     {
218                         if (*(t - 2) == '\r') /* t is protected, u isn't */
219                         {
220                             processed -= 1; /* preparation for add */
221                         }
222                     }
223                     leave = 0;
224                 }
225                 else
226                 {
227                     if ((*(t - 2) == '\r') && (*(t - 1) == '\n'))
228                     {
229                         *(u - 2) = '\n';
230                         *(u - 1) = '\0';
231                     }
232                     else
233                     {
234                         t--;
235                         *(u - 1) = '\0';
236                     }
237                 }
238             }
239             else if (t > stream->endbuf)
240             {
241                 leave = 0;
242             }
243             else
244             {
245                 *u = '\0';
246             }
247             if (leave)
248             {
249                 stream->upto = t;
250                 if (stream->textMode)
251                 {
252                     stream->quickText = 1;
253                 }
254                 return (s);
255             }
256         }
257         processed += (int)(t - stream->upto) - 1;
258         u--;
259         stream->bufStartR += (stream->endbuf - stream->fbuf);
260 #ifdef __OS2__
261         rc = DosRead(stream->hfile, stream->fbuf, stream->szfbuf, &actualRead);
262         if (rc != 0)
263         {
264             actualRead = 0;
265             stream->errorInd = 1;
266             errno = rc;
267         }
268 #endif
269 #ifdef __MSDOS__
270         actualRead = __read(stream->hfile,
271                             stream->fbuf,
272                             stream->szfbuf,
273                             &errind);
274         if (errind)
275         {
276             errno = actualRead;
277             actualRead = 0;
278             stream->errorInd = 1;
279         }
280 #endif
281         stream->endbuf = stream->fbuf + actualRead;
282         *stream->endbuf = '\n';
283         if (actualRead == 0)
284         {
285             *u = '\0';
286             if ((u - s) <= 1)
287             {
288                 stream->eofInd = 1;
289                 return (NULL);
290             }
291             else
292             {
293                 return (s);
294             }
295         }
296         stream->upto = stream->fbuf;
297     }
298 }
299 #endif
300 */