-// ----------------------------------------------------------------------------
-// $Id$
-// ----------------------------------------------------------------------------
-// Public Domain C Library - http://pdclib.sourceforge.net
-// This code is Public Domain. Use, modify, and redistribute at will.
-// ----------------------------------------------------------------------------
+/* $Id$ */
-char * fgets( char * restrict s, int n, FILE * restrict stream ) { /* TODO */ };
-
-/* PDPC code - unreviewed
-/*
-
-In fgets, we have the following possibilites...
-
-1. we found a genuine '\n' that terminated the search.
-2. we hit the '\n' at the endbuf.
-3. we hit the '\n' sentinel.
+/* fgets( char *, int, FILE * )
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
*/
-#ifndef __MVS__
-char *fgets(char *s, int n, FILE *stream)
-{
- char *p;
- register char *t;
- register char *u = s;
- int c;
- int processed;
-#ifdef __OS2__
- ULONG actualRead;
- APIRET rc;
-#endif
-#ifdef __MSDOS__
- size_t actualRead;
- int errind;
-#endif
- if (stream->quickText)
- {
- p = stream->upto + n - 1;
- t = stream->upto;
- if (p < stream->endbuf)
- {
- c = *p;
- *p = '\n';
-#ifdef __OS2__
- if (n < 8)
- {
-#endif
- while ((*u++ = *t++) != '\n') ; /* tight inner loop */
-#ifdef __OS2__
- }
- else
- {
- register unsigned int *i1;
- register unsigned int *i2;
- register unsigned int z;
+#include <stdio.h>
- i1 = (unsigned int *)t;
- i2 = (unsigned int *)u;
- while (1)
- {
- z = *i1;
- if ((z & 0xffU) == '\n') break;
- z >>= 8;
- if ((z & 0xffU) == '\n') break;
- z >>= 8;
- if ((z & 0xffU) == '\n') break;
- z >>= 8;
- if ((z & 0xffU) == '\n') break;
- *i2++ = *i1++;
- }
- t = (char *)i1;
- u = (char *)i2;
- while ((*u++ = *t++) != '\n') ;
- }
-#endif
- *p = (char)c;
- if (t <= p)
- {
- if (*(t - 2) == '\r') /* t is protected, u isn't */
- {
- *(u - 2) = '\n';
- *(u - 1) = '\0';
- }
- else
- {
- *u = '\0';
- }
- stream->upto = t;
- return (s);
- }
- else
- {
- processed = (int)(t - stream->upto) - 1;
- stream->upto = t - 1;
- u--;
- }
- }
- else
- {
- while ((*u++ = *t++) != '\n') ; /* tight inner loop */
- if (t <= stream->endbuf)
- {
- if (*(t - 2) == '\r') /* t is protected, u isn't */
- {
- *(u - 2) = '\n';
- *(u - 1) = '\0';
- }
- else
- {
- *u = '\0';
- }
- stream->upto = t;
- return (s);
- }
- else
- {
- processed = (int)(t - stream->upto) - 1;
- stream->upto = t - 1;
- u--;
- }
- }
- }
- else
- {
- processed = 0;
- }
+#ifndef REGTEST
+#include <_PDCLIB_io.h>
- if (n < 1)
+char * _PDCLIB_fgets_unlocked( char * _PDCLIB_restrict s, int size, FILE * _PDCLIB_restrict stream )
+{
+ if ( size == 0 )
{
- return (NULL);
+ return NULL;
}
- if (n < 2)
+ if ( size == 1 )
{
- *u = '\0';
- return (s);
+ *s = '\0';
+ return s;
}
- if (stream->ungetCh != -1)
+ if ( _PDCLIB_prepread( stream ) == EOF )
{
- processed++;
- *u++ = (char)stream->ungetCh;
- stream->ungetCh = -1;
+ return NULL;
}
- while (1)
- {
- t = stream->upto;
- p = stream->upto + (n - processed) - 1;
- if (p < stream->endbuf)
- {
- c = *p;
- *p = '\n';
- }
- if (stream->noNl)
- {
- while (((*u++ = *t) != '\n') && (*t++ != '\r')) ;
- if (*(u - 1) == '\n')
- {
- t++;
- }
- else
- {
- u--;
- while ((*u++ = *t++) != '\n') ;
- }
- }
- else
- {
- while ((*u++ = *t++) != '\n') ; /* tight inner loop */
- }
- if (p < stream->endbuf)
- {
- *p = (char)c;
- }
- if (((t <= p) && (p < stream->endbuf))
- || ((t <= stream->endbuf) && (p >= stream->endbuf)))
- {
- if (stream->textMode)
- {
- if (stream->noNl)
- {
- if ((*(t - 1) == '\r') || (*(t - 1) == '\n'))
- {
- *(u - 1) = '\0';
- }
- else
- {
- *u = '\0';
- }
- }
- else if (*(t - 2) == '\r') /* t is protected, u isn't */
- {
- *(u - 2) = '\n';
- *(u - 1) = '\0';
- }
- else
- {
- *u = '\0';
- }
- }
- stream->upto = t;
- if (stream->textMode)
- {
- stream->quickText = 1;
- }
- return (s);
- }
- else if (((t > p) && (p < stream->endbuf))
- || ((t > stream->endbuf) && (p >= stream->endbuf)))
- {
- int leave = 1;
+ char * dest = s;
+
+ dest += _PDCLIB_getchars( dest, size - 1, '\n', stream );
+
+ *dest = '\0';
+ return ( dest == s ) ? NULL : s;
+}
+
+char * fgets( char * _PDCLIB_restrict s, int size,
+ FILE * _PDCLIB_restrict stream )
+{
+ _PDCLIB_flockfile( stream );
+ char* r = _PDCLIB_fgets_unlocked( s, size, stream );
+ _PDCLIB_funlockfile( stream );
+ return r;
+}
- if (stream->textMode)
- {
- if (t > stream->endbuf)
- {
- if ((t - stream->upto) > 1)
- {
- if (*(t - 2) == '\r') /* t is protected, u isn't */
- {
- processed -= 1; /* preparation for add */
- }
- }
- leave = 0;
- }
- else
- {
- if ((*(t - 2) == '\r') && (*(t - 1) == '\n'))
- {
- *(u - 2) = '\n';
- *(u - 1) = '\0';
- }
- else
- {
- t--;
- *(u - 1) = '\0';
- }
- }
- }
- else if (t > stream->endbuf)
- {
- leave = 0;
- }
- else
- {
- *u = '\0';
- }
- if (leave)
- {
- stream->upto = t;
- if (stream->textMode)
- {
- stream->quickText = 1;
- }
- return (s);
- }
- }
- processed += (int)(t - stream->upto) - 1;
- u--;
- stream->bufStartR += (stream->endbuf - stream->fbuf);
-#ifdef __OS2__
- rc = DosRead(stream->hfile, stream->fbuf, stream->szfbuf, &actualRead);
- if (rc != 0)
- {
- actualRead = 0;
- stream->errorInd = 1;
- errno = rc;
- }
-#endif
-#ifdef __MSDOS__
- actualRead = __read(stream->hfile,
- stream->fbuf,
- stream->szfbuf,
- &errind);
- if (errind)
- {
- errno = actualRead;
- actualRead = 0;
- stream->errorInd = 1;
- }
#endif
- stream->endbuf = stream->fbuf + actualRead;
- *stream->endbuf = '\n';
- if (actualRead == 0)
- {
- *u = '\0';
- if ((u - s) <= 1)
- {
- stream->eofInd = 1;
- return (NULL);
- }
- else
- {
- return (s);
- }
- }
- stream->upto = stream->fbuf;
- }
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+#include <string.h>
+
+int main( void )
+{
+ FILE * fh;
+ char buffer[10];
+ char const * fgets_test = "foo\nbar\0baz\nweenie";
+ TESTCASE( ( fh = fopen( testfile, "wb+" ) ) != NULL );
+ TESTCASE( fwrite( fgets_test, 1, 18, fh ) == 18 );
+ rewind( fh );
+ TESTCASE( fgets( buffer, 10, fh ) == buffer );
+ TESTCASE( strcmp( buffer, "foo\n" ) == 0 );
+ TESTCASE( fgets( buffer, 10, fh ) == buffer );
+ TESTCASE( memcmp( buffer, "bar\0baz\n", 8 ) == 0 );
+ TESTCASE( fgets( buffer, 10, fh ) == buffer );
+ TESTCASE( strcmp( buffer, "weenie" ) == 0 );
+ TESTCASE( feof( fh ) );
+ TESTCASE( fseek( fh, -1, SEEK_END ) == 0 );
+ TESTCASE( fgets( buffer, 1, fh ) == buffer );
+ TESTCASE( strcmp( buffer, "" ) == 0 );
+ TESTCASE( fgets( buffer, 0, fh ) == NULL );
+ TESTCASE( ! feof( fh ) );
+ TESTCASE( fgets( buffer, 1, fh ) == buffer );
+ TESTCASE( strcmp( buffer, "" ) == 0 );
+ TESTCASE( ! feof( fh ) );
+ TESTCASE( fgets( buffer, 2, fh ) == buffer );
+ TESTCASE( strcmp( buffer, "e" ) == 0 );
+ TESTCASE( fseek( fh, 0, SEEK_END ) == 0 );
+ TESTCASE( fgets( buffer, 2, fh ) == NULL );
+ TESTCASE( feof( fh ) );
+ TESTCASE( fclose( fh ) == 0 );
+ TESTCASE( remove( testfile ) == 0 );
+ return TEST_RESULTS;
}
+
#endif
-*/
+