From 0a5395faab237ba9008352b0f4bee9659bbd3d5f Mon Sep 17 00:00:00 2001 From: solar Date: Mon, 24 Nov 2003 18:57:15 +0000 Subject: [PATCH] Merged PDPCLIB and Therx code. --- functions/locale.c | 51 +++- functions/math/abs.c | 17 ++ functions/math/cbrt.c | 13 + functions/math/ceil.c | 20 ++ functions/math/copysign.c | 13 + functions/math/exp.c | 14 +- functions/math/fdim.c | 7 + functions/math/floor.c | 27 ++ functions/math/fma.c | 7 + functions/math/fmax.c | 7 + functions/math/fmin.c | 7 + functions/math/hypot.c | 7 + functions/math/mod.c | 13 + functions/math/nearbyint.c | 7 + functions/math/remainder.c | 7 + functions/math/rint.c | 7 + functions/math/round.c | 7 + functions/math/sqrt.c | 17 ++ functions/math/trunc.c | 7 + functions/signal.c | 58 ++++ functions/stdio/clearerr.c | 8 + functions/stdio/fclose.c | 35 +++ functions/stdio/feof.c | 6 + functions/stdio/ferror.c | 6 + functions/stdio/fflush.c | 47 ++++ functions/stdio/fgetc.c | 14 + functions/stdio/fgetpos.c | 7 + functions/stdio/fgets.c | 292 ++++++++++++++++++++ functions/stdio/fopen.c | 391 +++++++++++++++++++++++++++ functions/stdio/fprintf.c | 12 + functions/stdio/fputc.c | 50 ++++ functions/stdio/fputs.c | 13 + functions/stdio/fread.c | 349 ++++++++++++++++++++++++ functions/stdio/freopen.c | 7 + functions/stdio/fscanf.c | 77 ++++++ functions/stdio/fseek.c | 57 ++++ functions/stdio/fsetpos.c | 7 + functions/stdio/ftell.c | 6 + functions/stdio/fwrite.c | 474 ++++++++++++++++++++++++++++++++ functions/stdio/getc.c | 6 + functions/stdio/getchar.c | 6 + functions/stdio/gets.c | 13 + functions/stdio/perror.c | 18 ++ functions/stdio/printf.c | 12 + functions/stdio/putc.c | 6 + functions/stdio/putchar.c | 6 + functions/stdio/puts.c | 13 + functions/stdio/rewind.c | 7 + functions/stdio/scanf.c | 12 + functions/stdio/setbuf.c | 16 ++ functions/stdio/setvbuf.c | 59 ++++ functions/stdio/sprintf.c | 12 + functions/stdio/sscanf.c | 12 + functions/stdio/tmpfile.c | 6 + functions/stdio/tmpnam.c | 14 + functions/stdio/ungetc.c | 12 + functions/stdio/vfprintf.c | 401 +++++++++++++++++++++++++++ functions/stdio/vscanf.c | 1 + functions/stdio/vsprintf.c | 13 + functions/stdlib/abort.c | 7 + functions/stdlib/atexit.c | 16 ++ functions/stdlib/bsearch.c | 29 ++ functions/stdlib/calloc.c | 26 ++ functions/stdlib/mblen.c | 17 ++ functions/stdlib/mbstowcs.c | 11 + functions/stdlib/mbtowc.c | 21 ++ functions/stdlib/qsort.c | 150 +++++++++++ functions/stdlib/rand.c | 19 ++ functions/stdlib/realloc.c | 24 ++ functions/stdlib/strtox.c | 128 +++++++++ functions/stdlib/wcstombs.c | 11 + functions/stdlib/wctomb.c | 14 + functions/string/memchr.c | 16 ++ functions/string/memcmp.c | 18 ++ functions/string/memcpy.c | 66 +++++ functions/string/memmove.c | 30 +++ functions/string/memset.c | 23 ++ functions/string/strcat.c | 28 ++ functions/string/strchr.c | 11 + functions/string/strcmp.c | 30 +++ functions/string/strcoll.c | 6 + functions/string/strcpy.c | 20 ++ functions/string/strcspn.c | 20 ++ functions/string/strerror.c | 7 + functions/string/strlen.c | 21 ++ functions/string/strncat.c | 18 ++ functions/string/strncmp.c | 19 ++ functions/string/strncpy.c | 21 ++ functions/string/strpbrk.c | 20 ++ functions/string/strrchr.c | 14 + functions/string/strspn.c | 21 ++ functions/string/strstr.c | 22 ++ functions/string/strtok.c | 23 ++ functions/string/strxfrm.c | 14 + functions/time.c | 522 ++++++++++++++++++++++++++++++++++++ 95 files changed, 4277 insertions(+), 2 deletions(-) diff --git a/functions/locale.c b/functions/locale.c index 4dfe663..757bf8e 100644 --- a/functions/locale.c +++ b/functions/locale.c @@ -5,5 +5,54 @@ // This code is Public Domain. Use, modify, and redistribute at will. // ---------------------------------------------------------------------------- -struct lconv * localeconv( void ) { /* TODO */ }; +/* PDPC code - unreviewed +static struct lconv thislocale = { + ".", + "", + "", + "", + "", + "", + "", + "", + "", + "", + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX, + CHAR_MAX +}; +*/ + char * setlocale( int categories, const char * locale_name ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + (void)category; + if (locale == NULL) + { + return ("C"); + } + else if ((strcmp(locale, "C") == 0) + || (strcmp(locale, "") == 0)) + { + return ("C"); + } + else + { + return (NULL); + } +} +*/ + +struct lconv * localeconv( void ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (&thislocale); +} +*/ diff --git a/functions/math/abs.c b/functions/math/abs.c index 1cd660d..bba8e7e 100644 --- a/functions/math/abs.c +++ b/functions/math/abs.c @@ -21,6 +21,23 @@ long long abs( long long i ) { /* TODO */ }; // Standard C double fabs( double x ) { /* TODO */ }; + +/* Therx code +{ + return ( x < 0 ) ? -x : x; +} +*/ + +/* PDPC code - unreviewed +{ + if (x < 0.0) + { + x = -x; + } + return (x); +} +*/ + float fabsf( float x ) { /* TODO */ }; long double fabsl( long double x ) { /* TODO */ }; diff --git a/functions/math/cbrt.c b/functions/math/cbrt.c index cf6d16b..86ef690 100644 --- a/functions/math/cbrt.c +++ b/functions/math/cbrt.c @@ -15,5 +15,18 @@ long double cbrt( long double x ) { /* TODO */ }; // Standard C double cbrt( double x ) { /* TODO */ }; + +/* Therx code +{ + double i = x / 4; + // (15 DP) HOW GET MORE? + while ( ( fabs( i - ( x / i / i ) ) / i ) > 0.00000000000001 ) + { + i = ( i + ( x / i / i ) + i ) / 3; + } + return i; +} +*/ + float cbrtf( float x ) { /* TODO */ }; long double cbrtl( long double x ) { /* TODO */ }; diff --git a/functions/math/ceil.c b/functions/math/ceil.c index 11eb88f..d1ebdee 100644 --- a/functions/math/ceil.c +++ b/functions/math/ceil.c @@ -15,5 +15,25 @@ long double ceil( long double x ) { /* TODO */ }; // Standard C double ceil( double x ) { /* TODO */ }; + +/* Therx code +{ + return ( x < 0 ) ? (int) x : ( (int) x ) + 1; +} +*/ + +/* PDPC code - unreviewed +{ + int y; + + y = (int)x; + if ((double)y < x) + { + y++; + } + return ((double)y); +} +*/ + float ceilf( float x ) { /* TODO */ }; long double ceill( long double x ) { /* TODO */ }; diff --git a/functions/math/copysign.c b/functions/math/copysign.c index f22fcb7..7df32ce 100644 --- a/functions/math/copysign.c +++ b/functions/math/copysign.c @@ -15,5 +15,18 @@ long double copysign( long double x, long double y ) { /* TODO */ }; // Standard C double copysign( double x, double y ) { /* TODO */ }; + +/* Own code +{ + if ( y < 0 ) + { + return ( x < 0 ) ? x : -x; + } + else + { + return ( x < 0 ) ? -x : x; + } +} + float copysignf( float x, float y ) { /* TODO */ }; long double copysignl( long double x, long double y ) { /* TODO */ }; diff --git a/functions/math/exp.c b/functions/math/exp.c index 19d35a5..f0985cd 100644 --- a/functions/math/exp.c +++ b/functions/math/exp.c @@ -31,6 +31,18 @@ float expf( float x ) { /* TODO */ }; long double expl( long double x ) { /* TODO */ }; double exp2( double x ) { /* TODO */ }; + +/* Therx code +{ + double value = 1; + for( int i = 1; i <= x; i++ ) + { + value *= 2; + } + return value; +} +*/ + float exp2f( float x ) { /* TODO */ }; long double exp2l( long double x ) { /* TODO */ }; @@ -44,4 +56,4 @@ long double frexpl( long double x, int * exp ) { /* TODO */ }; double ldexp( double x, int exp ) { /* TODO */ }; float ldexpf( float x, int exp ) { /* TODO */ }; -long double ldexpl( long double x, int exp ) { /* TODO */ }; \ No newline at end of file +long double ldexpl( long double x, int exp ) { /* TODO */ }; diff --git a/functions/math/fdim.c b/functions/math/fdim.c index 9916763..9a00579 100644 --- a/functions/math/fdim.c +++ b/functions/math/fdim.c @@ -15,5 +15,12 @@ long double fdim( long double x, long double y ) { /* TODO */ }; // Standard C double fdim( double x, double y ) { /* TODO */ }; + +/* Therx code +{ + return ( ( x - y ) < 1 ) ? 0 : x - y; +} +*/ + float fdimf( float x, float y ) { /* TODO */ }; long double fdiml( long double x, long double y ) { /* TODO */ }; diff --git a/functions/math/floor.c b/functions/math/floor.c index 30cc463..a286149 100644 --- a/functions/math/floor.c +++ b/functions/math/floor.c @@ -15,5 +15,32 @@ long double floor( long double x ) { /* TODO */ }; // Standard C double floor( double x ) { /* TODO */ }; + +/* Therx code +{ + return ( x > 0 ) ? (int) x : (int) ( x - 0.9999999999999999 ); +} +*/ + +/* PDPC code - unreviewed +{ + int y; + + if (x < 0.0) + { + y = (int)fabs(x); + if ((double)y != x) + { + y--; + } + } + else + { + y = (int)x; + } + return ((double)x); +} +*/ + float floorf( float x ) { /* TODO */ }; long double floorl( long double x ) { /* TODO */ }; diff --git a/functions/math/fma.c b/functions/math/fma.c index 626e9aa..873dec1 100644 --- a/functions/math/fma.c +++ b/functions/math/fma.c @@ -15,5 +15,12 @@ long double fma( long double x, long double y, long double z ) { /* TODO */ }; // Standard C double fma( double x, double y, double z ) { /* TODO */ }; + +/* Therx code +{ + return (int) ( ( x * y ) + z + 0.5 ); +} +*/ + float fmaf( float x, float y, float z ) { /* TODO */ }; long double fmal( long double x, long double y, long double z ) { /* TODO */ }; diff --git a/functions/math/fmax.c b/functions/math/fmax.c index a775ae1..42856c5 100644 --- a/functions/math/fmax.c +++ b/functions/math/fmax.c @@ -15,5 +15,12 @@ long double fmax( long double x, long double y ) { /* TODO */ }; // Standard C double fmax( double x, double y ) { /* TODO */ }; + +/* Therx code +{ + return ( x > y ) ? x : y; +} +*/ + float fmaxf( float x, float y ) { /* TODO */ }; long double fmaxl( long double x, long double y ) { /* TODO */ }; diff --git a/functions/math/fmin.c b/functions/math/fmin.c index 212370d..62ff17a 100644 --- a/functions/math/fmin.c +++ b/functions/math/fmin.c @@ -15,5 +15,12 @@ long double fmin( long double x, long double y ) { /* TODO */ }; // Standard C double fmin( double x, double y ) { /* TODO */ }; + +/* Therx code +{ + return ( x < y ) ? x : y; +} +*/ + float fminf( float x, float y ) { /* TODO */ }; long double fminl( long double x, long double y ) { /* TODO */ }; diff --git a/functions/math/hypot.c b/functions/math/hypot.c index 449242d..060f3ce 100644 --- a/functions/math/hypot.c +++ b/functions/math/hypot.c @@ -15,5 +15,12 @@ long double hypot( long double x, long double y ) { /* TODO */ }; // Standard C double hypot( double x, double y ) { /* TODO */ }; + +/* Therx code +{ + return sqrt( x * x + y * y ); +} +*/ + float hypotf( float x, float y ) { /* TODO */ }; long double hypotl( long double x, long double y ) { /* TODO */ }; diff --git a/functions/math/mod.c b/functions/math/mod.c index 9e002cf..70f1ebc 100644 --- a/functions/math/mod.c +++ b/functions/math/mod.c @@ -18,6 +18,19 @@ long double modf( long double x, long double * integer ) { /* TODO */ }; // Standard C double fmod( double x, double y ) { /* TODO */ }; + +/* Therx code +{ + return (int) ( ( ( ( x / y ) - ( (int) ( x / y ) ) ) * y ) + 0.5 ); +} +*/ + +/* PDPC code - unreviewed +{ + return (x / y); +} +*/ + float fmodf( float x, float y ) { /* TODO */ }; long double fmodl( long double x, long double y ) { /* TODO */ }; diff --git a/functions/math/nearbyint.c b/functions/math/nearbyint.c index 675951d..0b4f29c 100644 --- a/functions/math/nearbyint.c +++ b/functions/math/nearbyint.c @@ -15,5 +15,12 @@ long double nearbyint( long double x ) { /* TODO */ }; // Standard C double nearbyint( double x ) { /* TODO */ }; + +/* Therx code +{ + return round( x ); +} +*/ + float nearbyintf( float x ) { /* TODO */ }; long double nearbyintl( long double x ) { /* TODO */ }; diff --git a/functions/math/remainder.c b/functions/math/remainder.c index a12aaa9..8772a8c 100644 --- a/functions/math/remainder.c +++ b/functions/math/remainder.c @@ -15,5 +15,12 @@ long double remainder( long double x, long double y ) { /* TODO */ }; // Standard C double remainder( double x, double y ) { /* TODO */ }; + +/* Therx code +{ + return fmod( x, y ); +} +*/ + float remainderf( float x, float y ) { /* TODO */ }; long double remainderl( long double x, long double y ) { /* TODO */ }; diff --git a/functions/math/rint.c b/functions/math/rint.c index f0a7282..16b3e0b 100644 --- a/functions/math/rint.c +++ b/functions/math/rint.c @@ -25,5 +25,12 @@ long lrint( double x ) { /* TODO */ }; long lrintf( float x ) { /* TODO */ }; long lrintl( long double x ) { /* TODO */ }; double rint( double x ) { /* TODO */ }; + +/* Therx code +{ + return round( x ); +} +*/ + float rintf( float x ) { /* TODO */ }; long double rintl( long double x ) { /* TODO */ }; diff --git a/functions/math/round.c b/functions/math/round.c index bf0a321..e3815e1 100644 --- a/functions/math/round.c +++ b/functions/math/round.c @@ -25,5 +25,12 @@ long lround( double x ) { /* TODO */ }; long lroundf( float x ) { /* TODO */ }; long lroundl( long double x ) { /* TODO */ }; double round( double x ) { /* TODO */ }; + +/* Therx code +{ + return (int) ( x + 0.5 ); +} +*/ + float roundf( float x ) { /* TODO */ }; long double roundl( long double x ) { /* TODO */ }; diff --git a/functions/math/sqrt.c b/functions/math/sqrt.c index 3c6c126..9143170 100644 --- a/functions/math/sqrt.c +++ b/functions/math/sqrt.c @@ -15,5 +15,22 @@ long double sqrt( long double x ) { /* TODO */ }; // Standard C double sqrt( double x ) { /* TODO */ }; + +/* Therx code +{ + double i = x / 2; + if ( x < 0 ) + { + return 0; + } + // (15 DP) HOW GET MORE? + while ( ( fabs( i - ( x / i ) ) / i ) > 0.000000000000001) + { + i = ( i + ( x / i ) ) / 2; + } + return i; +} +*/ + float sqrtf( float x ) { /* TODO */ }; long double sqrtl( long double x ) { /* TODO */ }; diff --git a/functions/math/trunc.c b/functions/math/trunc.c index 4682245..bd17848 100644 --- a/functions/math/trunc.c +++ b/functions/math/trunc.c @@ -15,5 +15,12 @@ long double trunc( long double x ) { /* TODO */ }; // Standard C double trunc( double x ) { /* TODO */ }; + +/* Therx code +{ + return (int) x; +} +*/ + float truncf( float x ) { /* TODO */ }; long double truncl( long double x ) { /* TODO */ }; diff --git a/functions/signal.c b/functions/signal.c index 33535f8..d0fc8b6 100644 --- a/functions/signal.c +++ b/functions/signal.c @@ -5,5 +5,63 @@ // This code is Public Domain. Use, modify, and redistribute at will. // ---------------------------------------------------------------------------- +/* PDPC code - unreviewed +static void (*handlers[6])(int) = { + __sigdfl, + __sigdfl, + __sigdfl, + __sigdfl, + __sigdfl, + __sigdfl }; + +void __sigdfl(int sig) +{ + handlers[sig] = SIG_DFL; + if (sig == SIGABRT) + { + exit(EXIT_FAILURE); + } + return; +} + +void __sigerr(int sig) +{ + (void)sig; + return; +} + +void __sigign(int sig) +{ + (void)sig; + return; +} + +#define SIG_DFL __sigdfl +#define SIG_ERR __sigerr +#define SIG_IGN __sigign + +#define SIGABRT 1 +#define SIGFPE 2 +#define SIGILL 3 +#define SIGINT 4 +#define SIGSEGV 5 +#define SIGTERM 6 +*/ + int raise( int sig ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + (handlers[sig])(sig); + return (0); +} +*/ + void ( * signal( int sig, void ( *func )( int ) ) ) ( int ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + handlers[sig] = func; + return (func); +} +*/ diff --git a/functions/stdio/clearerr.c b/functions/stdio/clearerr.c index 1adce82..d54e559 100644 --- a/functions/stdio/clearerr.c +++ b/functions/stdio/clearerr.c @@ -6,3 +6,11 @@ // ---------------------------------------------------------------------------- void clearerr( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + stream->errorInd = 0; + stream->eofInd = 0; + return; +} +*/ diff --git a/functions/stdio/fclose.c b/functions/stdio/fclose.c index 04a9aa2..446b8ee 100644 --- a/functions/stdio/fclose.c +++ b/functions/stdio/fclose.c @@ -6,3 +6,38 @@ // ---------------------------------------------------------------------------- int fclose( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed. +Read the note in fopen.c. +int fclose(FILE *stream) +{ +#ifdef __OS2__ + APIRET rc; +#endif + + fflush(stream); +#ifdef __OS2__ + rc = DosClose(stream->hfile); +#endif +#ifdef __MSDOS__ + __close(stream->hfile); +#endif +#ifdef __MVS__ + __aclose(stream->hfile); +#endif + __userFiles[stream->intFno] = NULL; + if (!stream->theirBuffer) + { + free(stream->intBuffer); + } + free(stream); +#ifdef __OS2__ + if (rc != 0) + { + errno = rc; + return (EOF); + } +#endif + return (0); +} +*/ diff --git a/functions/stdio/feof.c b/functions/stdio/feof.c index 7467465..dd19dcb 100644 --- a/functions/stdio/feof.c +++ b/functions/stdio/feof.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- int feof( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (stream->eofInd); +} +*/ diff --git a/functions/stdio/ferror.c b/functions/stdio/ferror.c index a1855a3..7006510 100644 --- a/functions/stdio/ferror.c +++ b/functions/stdio/ferror.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- int ferror( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (stream->errorInd); +} +*/ diff --git a/functions/stdio/fflush.c b/functions/stdio/fflush.c index a74f77a..66e97a5 100644 --- a/functions/stdio/fflush.c +++ b/functions/stdio/fflush.c @@ -6,3 +6,50 @@ // ---------------------------------------------------------------------------- int fflush( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +Read the note in fopen.c. +{ +#ifdef __OS2__ + APIRET rc; + ULONG actualWritten; +#endif +#ifdef __MSDOS__ + int errind; + size_t actualWritten; +#endif + + if ((stream->upto != stream->fbuf) && (stream->mode == __WRITE_MODE)) + { +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + (VOID *)stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &actualWritten); + if (rc != 0) + { + stream->errorInd = 1; + errno = rc; + return (EOF); + } +#endif +#ifdef __MSDOS__ + actualWritten = __write(stream->hfile, + stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &errind); + if (errind) + { + stream->errorInd = 1; + errno = actualWritten; + return (EOF); + } +#endif +#ifndef __MVS__ + stream->bufStartR += actualWritten; + stream->upto = stream->fbuf; +#endif + } + return (0); +} +*/ diff --git a/functions/stdio/fgetc.c b/functions/stdio/fgetc.c index 1ca2367..c4f2993 100644 --- a/functions/stdio/fgetc.c +++ b/functions/stdio/fgetc.c @@ -6,3 +6,17 @@ // ---------------------------------------------------------------------------- int fgetc( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + unsigned char x[1]; + size_t ret; + + ret = fread(x, 1, 1, stream); + if (ret == 0) + { + return (EOF); + } + return ((int)x[0]); +} +*/ diff --git a/functions/stdio/fgetpos.c b/functions/stdio/fgetpos.c index b26979b..c97cf01 100644 --- a/functions/stdio/fgetpos.c +++ b/functions/stdio/fgetpos.c @@ -6,3 +6,10 @@ // ---------------------------------------------------------------------------- int fgetpos( FILE * restrict stream, fpos_t * restrict pos ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + *pos = ftell(stream); + return (0); +} +*/ diff --git a/functions/stdio/fgets.c b/functions/stdio/fgets.c index b7e0faa..556e426 100644 --- a/functions/stdio/fgets.c +++ b/functions/stdio/fgets.c @@ -6,3 +6,295 @@ // ---------------------------------------------------------------------------- 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. + +*/ +#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; + + 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; + } + + if (n < 1) + { + return (NULL); + } + if (n < 2) + { + *u = '\0'; + return (s); + } + if (stream->ungetCh != -1) + { + processed++; + *u++ = (char)stream->ungetCh; + stream->ungetCh = -1; + } + 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; + + 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; + } +} +#endif +*/ diff --git a/functions/stdio/fopen.c b/functions/stdio/fopen.c index 04020d9..3bab83a 100644 --- a/functions/stdio/fopen.c +++ b/functions/stdio/fopen.c @@ -6,3 +6,394 @@ // ---------------------------------------------------------------------------- FILE * fopen( const char * restrict filename, const char * restrict mode ) { /* TODO */ }; + +/* PDPC code - unreviewed, verbatim. +NOTE THAT PDPC WAS MEANT TO RUN ON A HOST OS. +I thought the approach to "osfopen()" was close enough to what we have in mind +for pdclib to include the code here. + +{ + fnm = filename; + modus = mode; + err = 0; + findSpareSpot(); + if (!err) + { + myfile = malloc(sizeof(FILE)); + if (myfile == NULL) + { + err = 1; + } + else + { + fopen2(); + if (err) + { + free(myfile); + } + } + } + if (err) + { + myfile = NULL; + } + return (myfile); +} + +static void fopen2(void) +{ + checkMode(); + if (!err) + { + osfopen(); + if (!err) + { + __userFiles[spareSpot] = myfile; + myfile->intFno = spareSpot; + fopen3(); + } + } + return; +} + +static void fopen3(void) +{ + myfile->intBuffer = malloc(BUFSIZ + 8); + if (myfile->intBuffer == NULL) + { + err = 1; + } + else + { + myfile->theirBuffer = 0; + myfile->fbuf = myfile->intBuffer + 2; + *myfile->fbuf++ = '\0'; + *myfile->fbuf++ = '\0'; + myfile->szfbuf = BUFSIZ; +#ifndef __MVS__ + myfile->quickText = 0; +#endif + myfile->noNl = 0; + myfile->endbuf = myfile->fbuf + myfile->szfbuf; + *myfile->endbuf = '\n'; +#ifdef __MVS__ + myfile->upto = myfile->fbuf; + myfile->szfbuf = myfile->lrecl; +#else + myfile->upto = myfile->endbuf; +#endif + myfile->bufStartR = -(long)myfile->szfbuf; + myfile->errorInd = 0; + myfile->eofInd = 0; + myfile->ungetCh = -1; + myfile->update = 0; +#ifndef __MVS__ + if (!myfile->textMode) + { + myfile->quickBin = 1; + } + else + { + myfile->quickBin = 0; + } +#endif + myfile->mode = __READ_MODE; + switch (modeType) + { + case 2: + case 3: + case 5: + case 6: + case 8: + case 9: + case 11: + case 12: + myfile->bufStartR = 0; + myfile->upto = myfile->fbuf; + myfile->mode = __WRITE_MODE; + break; + } + switch (modeType) + { + case 7: + case 8: + case 10: + case 11: + case 12: + myfile->update = 1; + break; + } + } + return; +} + +static void findSpareSpot(void) +{ + int x; + + for (x = 0; x < __NFILE; x++) + { + if (__userFiles[x] == NULL) + { + break; + } + } + if (x == __NFILE) + { + err = 1; + } + else + { + spareSpot = x; + } + return; +} + +/* checkMode - interpret mode string */ +/* r = 1 */ +/* w = 2 */ +/* a = 3 */ +/* rb = 4 */ +/* wb = 5 */ +/* ab = 6 */ +/* r+ = 7 */ +/* w+ = 8 */ +/* a+ = 9 */ +/* r+b or rb+ = 10 */ +/* w+b or wb+ = 11 */ +/* a+b or ab+ = 12 */ + +static void checkMode(void) +{ + if (strncmp(modus, "r+b", 3) == 0) + { + modeType = 10; + } + else if (strncmp(modus, "rb+", 3) == 0) + { + modeType = 10; + } + else if (strncmp(modus, "w+b", 3) == 0) + { + modeType = 11; + } + else if (strncmp(modus, "wb+", 3) == 0) + { + modeType = 11; + } + else if (strncmp(modus, "a+b", 3) == 0) + { + modeType = 12; + } + else if (strncmp(modus, "ab+", 3) == 0) + { + modeType = 12; + } + else if (strncmp(modus, "r+", 2) == 0) + { + modeType = 7; + } + else if (strncmp(modus, "w+", 2) == 0) + { + modeType = 8; + } + else if (strncmp(modus, "a+", 2) == 0) + { + modeType = 9; + } + else if (strncmp(modus, "rb", 2) == 0) + { + modeType = 4; + } + else if (strncmp(modus, "wb", 2) == 0) + { + modeType = 5; + } + else if (strncmp(modus, "ab", 2) == 0) + { + modeType = 6; + } + else if (strncmp(modus, "r", 1) == 0) + { + modeType = 1; + } + else if (strncmp(modus, "w", 1) == 0) + { + modeType = 2; + } + else if (strncmp(modus, "a", 1) == 0) + { + modeType = 3; + } + else + { + err = 1; + return; + } + if ((modeType == 4) + || (modeType == 5) + || (modeType == 6) + || (modeType == 10) + || (modeType == 11) + || (modeType == 12)) + { + myfile->textMode = 0; + } + else + { + myfile->textMode = 1; + } + return; +} + +static void osfopen(void) +{ +#ifdef __OS2__ + APIRET rc; + ULONG action; + ULONG newsize = 0; + ULONG fileAttr = 0; + ULONG openAction = 0; + ULONG openMode = 0; + + if ((modeType == 1) || (modeType == 4) || (modeType == 7) + || (modeType == 10)) + { + openAction |= OPEN_ACTION_FAIL_IF_NEW; + openAction |= OPEN_ACTION_OPEN_IF_EXISTS; + } + else if ((modeType == 2) || (modeType == 5) || (modeType == 8) + || (modeType == 11)) + { + openAction |= OPEN_ACTION_CREATE_IF_NEW; + openAction |= OPEN_ACTION_REPLACE_IF_EXISTS; + } + else if ((modeType == 3) || (modeType == 6) || (modeType == 9) + || (modeType == 12)) + { + openAction |= OPEN_ACTION_CREATE_IF_NEW; + openAction |= OPEN_ACTION_OPEN_IF_EXISTS; + } + openMode |= OPEN_SHARE_DENYWRITE; + if ((modeType == 1) || (modeType == 4)) + { + openMode |= OPEN_ACCESS_READONLY; + } + else if ((modeType == 2) || (modeType == 3) || (modeType == 5) + || (modeType == 6)) + { + openMode |= OPEN_ACCESS_WRITEONLY; + } + else + { + openMode |= OPEN_ACCESS_READWRITE; + } + if ((strlen(fnm) == 2) + && (fnm[1] == ':') + && (openMode == OPEN_ACCESS_READONLY)) + { + openMode |= OPEN_FLAGS_DASD; + } + rc = DosOpen((PSZ)fnm, + &myfile->hfile, + &action, + newsize, + fileAttr, + openAction, + openMode, + NULL); + if (rc != 0) + { + err = 1; + errno = rc; + } +#endif +#ifdef __MSDOS__ + int mode; + int errind; + + if ((modeType == 1) || (modeType == 4)) + { + mode = 0; + } + else if ((modeType == 2) || (modeType == 5)) + { + mode = 1; + } + else + { + mode = 2; + } + myfile->hfile = __open(fnm, mode, &errind); + if (errind) + { + err = 1; + errno = myfile->hfile; + } +#endif +#ifdef __MVS__ + int mode; + char *p; + int len; + + if ((modeType == 1) || (modeType == 4)) + { + mode = 0; + } + else if ((modeType == 2) || (modeType == 5)) + { + mode = 1; + } + else + { + mode = 2; + } + p = strchr(fnm, ':'); + if ((p != NULL) && (strncmp(fnm, "dd", 2) == 0)) + { + p++; + } + else + { + p = (char *)fnm; + } + strcpy(myfile->ddname, " "); + len = strlen(p); + if (len > 8) + { + len = 8; + } + memcpy(myfile->ddname, p, len); + p = myfile->ddname; + while (*p != '\0') + { + *p = toupper(*p); + p++; + } + myfile->hfile = + __aopen(myfile->ddname, mode, &myfile->recfm, &myfile->lrecl); + if ((modeType == 4) || (modeType == 5)) + { + myfile->style = 0; /* binary */ + } + else + { + myfile->style = 2; /* text */ + } + myfile->style += myfile->recfm; + if (myfile->style == VARIABLE_TEXT) + { + myfile->quickText = 1; + } + if (myfile->style == FIXED_BINARY) + { + myfile->quickBin = 1; + } + else + { + myfile->quickBin = 0; + } +#endif + return; +} +*/ diff --git a/functions/stdio/fprintf.c b/functions/stdio/fprintf.c index ea4f97d..d3d4cb6 100644 --- a/functions/stdio/fprintf.c +++ b/functions/stdio/fprintf.c @@ -6,3 +6,15 @@ // ---------------------------------------------------------------------------- int fprintf( FILE * restrict stream, const char * restrict format, ... ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + va_list arg; + int ret; + + va_start(arg, format); + ret = vfprintf(stream, format, arg); + va_end(arg); + return (ret); +} +*/ diff --git a/functions/stdio/fputc.c b/functions/stdio/fputc.c index 4321b30..a89d298 100644 --- a/functions/stdio/fputc.c +++ b/functions/stdio/fputc.c @@ -6,3 +6,53 @@ // ---------------------------------------------------------------------------- int fputc( int c, FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + char buf[1]; + +#ifndef __MVS__ + stream->quickBin = 0; + if ((stream->upto < (stream->endbuf - 2)) + && (stream->bufTech != _IONBF)) + { + if (stream->textMode) + { + if (c == '\n') + { + if (stream->bufTech == _IOFBF) + { + *stream->upto++ = '\r'; + *stream->upto++ = '\n'; + } + else + { + buf[0] = (char)c; + if (fwrite(buf, 1, 1, stream) != 1) + { + return (EOF); + } + } + } + else + { + *stream->upto++ = (char)c; + } + } + else + { + *stream->upto++ = (char)c; + } + } + else +#endif + { + buf[0] = (char)c; + if (fwrite(buf, 1, 1, stream) != 1) + { + return (EOF); + } + } + return (c); +} +*/ diff --git a/functions/stdio/fputs.c b/functions/stdio/fputs.c index 86abe11..e7a04f7 100644 --- a/functions/stdio/fputs.c +++ b/functions/stdio/fputs.c @@ -6,3 +6,16 @@ // ---------------------------------------------------------------------------- int fputs( const char * restrict s, FILE * restrict stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +#ifndef __MVS__ +int fputs(const char *s, FILE *stream) +{ + size_t len; + + len = strlen(s); + fwrite(s, len, 1, stream); + return (0); +} +#endif +*/ diff --git a/functions/stdio/fread.c b/functions/stdio/fread.c index 905ff4d..b580fe5 100644 --- a/functions/stdio/fread.c +++ b/functions/stdio/fread.c @@ -6,3 +6,352 @@ // ---------------------------------------------------------------------------- size_t fread( void * restrict ptr, size_t size, size_t nelem, FILE * restrict stream ) { /* TODO */ }; + +/* PDPC code - unreviewed, verbatim. +Read the note in fopen.c. +{ + size_t toread; + size_t elemRead; + size_t actualRead; +#ifdef __OS2__ + APIRET rc; + ULONG tempRead; +#endif +#ifdef __MSDOS__ + int errind; + size_t tempRead; +#endif + + if (nmemb == 1) + { + toread = size; + } + else if (size == 1) + { + toread = nmemb; + } + else + { + toread = size * nmemb; + } + if (toread < stream->szfbuf) + { + stream->quickBin = 0; + } + if (!stream->quickBin) + { + if (stream->textMode) + { + freadSlowT(ptr, stream, toread, &actualRead); + } + else + { + if (toread <= (stream->endbuf - stream->upto)) + { + memcpy(ptr, stream->upto, toread); + actualRead = toread; + stream->upto += toread; + } + else + { + freadSlowB(ptr, stream, toread, &actualRead); + } + } + if (nmemb == 1) + { + if (actualRead == size) + { + elemRead = 1; + } + else + { + elemRead = 0; + } + } + else if (size == 1) + { + elemRead = actualRead; + } + else + { + elemRead = actualRead / size; + } + return (elemRead); + } + else + { +#ifdef __OS2__ + rc = DosRead(stream->hfile, ptr, toread, &tempRead); + if (rc != 0) + { + actualRead = 0; + stream->errorInd = 1; + errno = rc; + } + else + { + actualRead = tempRead; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, ptr, toread, &errind); + if (errind) + { + errno = tempRead; + actualRead = 0; + stream->errorInd = 1; + } + else + { + actualRead = tempRead; + } +#endif + if (nmemb == 1) + { + if (actualRead == size) + { + elemRead = 1; + } + else + { + elemRead = 0; + stream->eofInd = 1; + } + } + else if (size == 1) + { + elemRead = actualRead; + if (nmemb != actualRead) + { + stream->eofInd = 1; + } + } + else + { + elemRead = actualRead / size; + if (toread != actualRead) + { + stream->eofInd = 1; + } + } + stream->bufStartR += actualRead; + return (elemRead); + } +} + + +/* +while toread has not been satisfied +{ + scan stuff out of buffer, replenishing buffer as required +} +*/ + +static void freadSlowT(void *ptr, + FILE *stream, + size_t toread, + size_t *actualRead) +{ + int finReading = 0; + size_t avail; + size_t need; + char *p; + size_t got; +#ifdef __OS2__ + ULONG tempRead; + APIRET rc; +#endif +#ifdef __MSDOS__ + size_t tempRead; + int errind; +#endif + + *actualRead = 0; + while (!finReading) + { + if (stream->upto == stream->endbuf) + { + stream->bufStartR += (stream->upto - stream->fbuf); +#ifdef __OS2__ + rc = DosRead(stream->hfile, + stream->fbuf, + stream->szfbuf, + &tempRead); + if (rc != 0) + { + tempRead = 0; + stream->errorInd = 1; + errno = rc; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, + stream->fbuf, + stream->szfbuf, + &errind); + if (errind) + { + errno = tempRead; + tempRead = 0; + stream->errorInd = 1; + } +#endif + if (tempRead == 0) + { + stream->eofInd = 1; + break; + } + stream->endbuf = stream->fbuf + tempRead; + *stream->endbuf = '\n'; + stream->upto = stream->fbuf; + } + avail = (size_t)(stream->endbuf - stream->upto) + 1; + need = toread - *actualRead; + p = memchr(stream->upto, '\n', avail); + got = (size_t)(p - stream->upto); + if (need < got) + { + memcpy((char *)ptr + *actualRead, stream->upto, need); + stream->upto += need; + *actualRead += need; + } + else + { + memcpy((char *)ptr + *actualRead, stream->upto, got); + stream->upto += got; + *actualRead += got; + if (p != stream->endbuf) + { + if (*(stream->upto - 1) == '\r') + { + *((char *)ptr + *actualRead - 1) = '\n'; + } + else + { + *((char *)ptr + *actualRead) = '\n'; + *actualRead += 1; + } + stream->upto++; + } + else + { + if (*(stream->upto - 1) == '\r') + { + *actualRead -= 1; + } + } + } + if (*actualRead == toread) + { + finReading = 1; + } + } + return; +} + +static void freadSlowB(void *ptr, + FILE *stream, + size_t toread, + size_t *actualRead) +{ + size_t avail; +#ifdef __OS2__ + ULONG tempRead; + APIRET rc; +#endif +#ifdef __MSDOS__ + size_t tempRead; + int errind; +#endif + + avail = (size_t)(stream->endbuf - stream->upto); + memcpy(ptr, stream->upto, avail); + *actualRead = avail; + stream->bufStartR += (stream->endbuf - stream->fbuf); + if (toread >= stream->szfbuf) + { + stream->upto = stream->endbuf; + stream->quickBin = 1; +#ifdef __OS2__ + rc = DosRead(stream->hfile, + (char *)ptr + *actualRead, + toread - *actualRead, + &tempRead); + if (rc != 0) + { + tempRead = 0; + stream->errorInd = 1; + errno = rc; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, + (char *)ptr + *actualRead, + toread - *actualRead, + &errind); + if (errind) + { + errno = tempRead; + tempRead = 0; + stream->errorInd = 1; + } +#endif + else if (tempRead != (toread - *actualRead)) + { + stream->eofInd = 1; + } + *actualRead += tempRead; + stream->bufStartR += tempRead; + } + else + { + size_t left; + + stream->upto = stream->fbuf; +#ifdef __OS2__ + rc = DosRead(stream->hfile, + stream->fbuf, + stream->szfbuf, + &tempRead); + left = toread - *actualRead; + if (rc != 0) + { + tempRead = 0; + stream->errorInd = 1; + errno = rc; + } +#endif +#ifdef __MSDOS__ + tempRead = __read(stream->hfile, + stream->fbuf, + stream->szfbuf, + &errind); + left = toread - *actualRead; + if (errind) + { + errno = tempRead; + tempRead = 0; + stream->errorInd = 1; + } +#endif + else if (tempRead < left) + { + stream->eofInd = 1; + } + stream->endbuf = stream->fbuf + tempRead; + *stream->endbuf = '\n'; + avail = (size_t)(stream->endbuf - stream->upto); + if (avail > left) + { + avail = left; + } + memcpy((char *)ptr + *actualRead, + stream->upto, + avail); + stream->upto += avail; + *actualRead += avail; + } + return; +} +#endif +*/ diff --git a/functions/stdio/freopen.c b/functions/stdio/freopen.c index 23c12e0..8758814 100644 --- a/functions/stdio/freopen.c +++ b/functions/stdio/freopen.c @@ -6,3 +6,10 @@ // ---------------------------------------------------------------------------- FILE * freopen( const char * restrict filename, const char * restrict mode, FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + fclose(stream); + return (fopen(filename, mode)); +} +*/ diff --git a/functions/stdio/fscanf.c b/functions/stdio/fscanf.c index 1170841..2be1758 100644 --- a/functions/stdio/fscanf.c +++ b/functions/stdio/fscanf.c @@ -6,3 +6,80 @@ // ---------------------------------------------------------------------------- int fscanf( FILE * restrict stream, const char * restrict format, ... ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + va_list arg; + int ret; + + va_start(arg, format); + ret = vvscanf(format, arg, stream, NULL); + va_end(arg); + return (ret); +} + +static int vvscanf(const char *format, va_list arg, FILE *fp, const char *s) +{ + int ch; + int fin = 0; + int cnt = 0; + char *cptr; + int *iptr; + + inch(); + while (!fin) + { + if (*format == '\0') + { + fin = 1; + } + else if (*format == '%') + { + format++; + if (*format == '%') + { + if (ch != '%') return (cnt); + inch(); + } + else if (*format == 's') + { + cptr = va_arg(arg, char *); + *cptr++ = (char)ch; + inch(); + while ((ch >= 0) && (!isspace(ch))) + { + *cptr++ = (char)ch; + inch(); + } + *cptr = '\0'; + if (ch < 0) + { + fin = 1; + } + } + else if (*format == 'd') + { + iptr = va_arg(arg, int *); + if (!isdigit(ch)) return (cnt); + *iptr = ch - '0'; + inch(); + while ((ch >= 0) && (isdigit(ch))) + { + *iptr = *iptr * 10 + (ch - '0'); + inch(); + } + if (ch < 0) + { + fin = 1; + } + } + } + else + { + if (ch != *format) return (cnt); + inch(); + } + } + return (cnt); +} +*/ diff --git a/functions/stdio/fseek.c b/functions/stdio/fseek.c index 7bffffb..b4e76b9 100644 --- a/functions/stdio/fseek.c +++ b/functions/stdio/fseek.c @@ -6,3 +6,60 @@ // ---------------------------------------------------------------------------- int fseek( FILE * stream, long offset, int mode ) { /* TODO */ }; + +/* PDPC code - unreviewed +Read the note in fopen.c. +{ + long newpos; +#ifdef __OS2__ + ULONG retpos; + APIRET rc; +#endif + + if (stream->mode == __WRITE_MODE) + { + fflush(stream); + } + if (whence == SEEK_SET) + { + newpos = offset; + } + else if (whence == SEEK_CUR) + { + newpos = offset + stream->bufStartR + (stream->upto - stream->fbuf); + } + if ((newpos > stream->bufStartR) + && (newpos < (stream->bufStartR + (stream->endbuf - stream->fbuf))) + && stream->update) + { + stream->upto = stream->fbuf + (size_t)(newpos - stream->bufStartR); + } + else + { +#ifdef __OS2__ + rc = DosSetFilePtr(stream->hfile, newpos, FILE_BEGIN, &retpos); + if ((rc != 0) || (retpos != newpos)) + { + errno = rc; + return (-1); + } + else + { + stream->endbuf = stream->fbuf + stream->szfbuf; + stream->upto = stream->endbuf; + stream->bufStartR = newpos - stream->szfbuf; + } +#endif +#ifdef __MSDOS + __seek(stream->hfile, newpos, whence); + stream->endbuf = stream->fbuf + stream->szfbuf; + stream->upto = stream->endbuf; + stream->bufStartR = newpos - stream->szfbuf; +#endif + } + stream->quickBin = 0; + stream->quickText = 0; + stream->ungetCh = -1; + return (0); +} +*/ diff --git a/functions/stdio/fsetpos.c b/functions/stdio/fsetpos.c index ae10039..b771047 100644 --- a/functions/stdio/fsetpos.c +++ b/functions/stdio/fsetpos.c @@ -6,3 +6,10 @@ // ---------------------------------------------------------------------------- int fsetpos( FILE * stream, const fpos_t * pos ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + fseek(stream, *pos, SEEK_SET); + return (0); +} +*/ diff --git a/functions/stdio/ftell.c b/functions/stdio/ftell.c index d531292..f4efecd 100644 --- a/functions/stdio/ftell.c +++ b/functions/stdio/ftell.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- long ftell( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (stream->bufStartR + (stream->upto - stream->fbuf)); +} +*/ diff --git a/functions/stdio/fwrite.c b/functions/stdio/fwrite.c index 4eece02..97bbbd5 100644 --- a/functions/stdio/fwrite.c +++ b/functions/stdio/fwrite.c @@ -6,3 +6,477 @@ // ---------------------------------------------------------------------------- size_t fwrite( const void * restrict ptr, size_t size, size_t nelem, FILE * restrict stream ) { /* TODO */ }; + +/* PDPC code - unreviewed, verbatim. +Read the note in fopen.c. +#ifndef __MVS__ +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t towrite; + size_t elemWritten; +#ifdef __OS2__ + ULONG actualWritten; + APIRET rc; +#endif +#ifdef __MSDOS__ + size_t actualWritten; + int errind; +#endif + + if (nmemb == 1) + { + towrite = size; + } + else if (size == 1) + { + towrite = nmemb; + } + else + { + towrite = size * nmemb; + } + if (towrite < stream->szfbuf) + { + stream->quickBin = 0; + if ((stream->bufTech == _IONBF) && !stream->textMode) + { + stream->quickBin = 1; + } + } + if (!stream->quickBin) + { + fwriteSlow(ptr, size, nmemb, stream, towrite, &elemWritten); + return (elemWritten); + } + else + { +#ifdef __OS2__ + rc = DosWrite(stream->hfile, (VOID *)ptr, towrite, &actualWritten); + if (rc != 0) + { + stream->errorInd = 1; + actualWritten = 0; + errno = rc; + } +#endif +#ifdef __MSDOS__ + actualWritten = __write(stream->hfile, + ptr, + towrite, + &errind); + if (errind) + { + stream->errorInd = 1; + actualWritten = 0; + errno = actualWritten; + } +#endif + if (nmemb == 1) + { + if (actualWritten == size) + { + elemWritten = 1; + } + else + { + elemWritten = 0; + } + } + else if (size == 1) + { + elemWritten = actualWritten; + } + else + { + elemWritten = actualWritten / size; + } + stream->bufStartR += actualWritten; + return (elemWritten); + } +} + +static void fwriteSlow(const void *ptr, + size_t size, + size_t nmemb, + FILE *stream, + size_t towrite, + size_t *elemWritten) +{ + size_t actualWritten; + + /* Normally, on output, there will never be a situation where + the write buffer is full, but it hasn't been written out. + If we find this to be the case, then it is because we have + done an fseek, and didn't know whether we were going to do + a read or a write after it, so now that we know, we switch + the buffer to being set up for write. We could use a flag, + but I thought it would be better to just put some magic + code in with a comment */ + if (stream->upto == stream->endbuf) + { + stream->bufStartR += (stream->endbuf - stream->fbuf); + stream->upto = stream->fbuf; + stream->mode = __WRITE_MODE; + } + if ((stream->textMode) || (stream->bufTech == _IOLBF)) + { + fwriteSlowT(ptr, stream, towrite, &actualWritten); + } + else + { + fwriteSlowB(ptr, stream, towrite, &actualWritten); + } + if (nmemb == 1) + { + if (actualWritten == size) + { + *elemWritten = 1; + } + else + { + *elemWritten = 0; + } + } + else if (size == 1) + { + *elemWritten = actualWritten; + } + else + { + *elemWritten = actualWritten / size; + } + return; +} + + +/* can still be called on binary files, if the binary file is + line buffered */ + +static void fwriteSlowT(const void *ptr, + FILE *stream, + size_t towrite, + size_t *actualWritten) +{ + char *p; + char *tptr; + char *oldp; + size_t diffp; + size_t rem; + int fin; +#ifdef __OS2__ + ULONG tempWritten; + APIRET rc; +#endif +#ifdef __MSDOS__ + size_t tempWritten; + int errind; +#endif + + *actualWritten = 0; + tptr = (char *)ptr; + p = tptr; + oldp = p; + p = (char *)memchr(oldp, '\n', towrite - (size_t)(oldp - tptr)); + while (p != NULL) + { + diffp = (size_t)(p - oldp); + fin = 0; + while (!fin) + { + rem = (size_t)(stream->endbuf - stream->upto); + if (diffp < rem) + { + memcpy(stream->upto, oldp, diffp); + stream->upto += diffp; + *actualWritten += diffp; + fin = 1; + } + else + { + memcpy(stream->upto, oldp, rem); + oldp += rem; + diffp -= rem; +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + stream->fbuf, + stream->szfbuf, + &tempWritten); + if (rc != 0) + { + stream->errorInd = 1; + return; + } +#endif +#ifdef __MSDOS__ + tempWritten = __write(stream->hfile, + stream->fbuf, + stream->szfbuf, + &errind); + if (errind) + { + stream->errorInd = 1; + return; + } +#endif + else + { + *actualWritten += rem; + stream->upto = stream->fbuf; + stream->bufStartR += tempWritten; + } + } + } + rem = (size_t)(stream->endbuf - stream->upto); + if (rem < 2) + { +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &tempWritten); + if (rc != 0) + { + stream->errorInd = 1; + errno = rc; + return; + } +#endif +#ifdef __MSDOS__ + tempWritten = __write(stream->hfile, + stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &errind); + if (errind) + { + stream->errorInd = 1; + errno = tempWritten; + return; + } +#endif + stream->upto = stream->fbuf; + stream->bufStartR += tempWritten; + } + if (stream->textMode) + { + memcpy(stream->upto, "\r\n", 2); + stream->upto += 2; + } + else + { + memcpy(stream->upto, "\n", 1); + stream->upto += 1; + } + *actualWritten += 1; + oldp = p + 1; + p = (char *)memchr(oldp, '\n', towrite - (size_t)(oldp - tptr)); + } + + if ((stream->bufTech == _IOLBF) + && (stream->upto != stream->fbuf) + && (oldp != tptr)) + { +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &tempWritten); + if (rc != 0) + { + stream->errorInd = 1; + errno = rc; + return; + } +#endif +#ifdef __MSDOS__ + tempWritten = __write(stream->hfile, + stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &errind); + if (errind) + { + stream->errorInd = 1; + errno = tempWritten; + return; + } +#endif + stream->upto = stream->fbuf; + stream->bufStartR += tempWritten; + } + + diffp = towrite - *actualWritten; + while (diffp != 0) + { + rem = (size_t)(stream->endbuf - stream->upto); + if (diffp < rem) + { + memcpy(stream->upto, oldp, diffp); + stream->upto += diffp; + *actualWritten += diffp; + } + else + { + memcpy(stream->upto, oldp, rem); +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + stream->fbuf, + stream->szfbuf, + &tempWritten); + if (rc != 0) + { + stream->errorInd = 1; + errno = rc; + return; + } +#endif +#ifdef __MSDOS__ + tempWritten = __write(stream->hfile, + stream->fbuf, + stream->szfbuf, + &errind); + if (errind) + { + stream->errorInd = 1; + errno = tempWritten; + return; + } +#endif + else + { + *actualWritten += rem; + stream->upto = stream->fbuf; + } + stream->bufStartR += tempWritten; + oldp += rem; + } + diffp = towrite - *actualWritten; + } + if ((stream->bufTech == _IONBF) + && (stream->upto != stream->fbuf)) + { +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &tempWritten); + if (rc != 0) + { + stream->errorInd = 1; + errno = rc; + return; + } +#endif +#ifdef __MSDOS__ + tempWritten = __write(stream->hfile, + stream->fbuf, + (size_t)(stream->upto - stream->fbuf), + &errind); + if (errind) + { + stream->errorInd = 1; + errno = tempWritten; + return; + } +#endif + stream->upto = stream->fbuf; + stream->bufStartR += tempWritten; + } + return; +} + +/* whilst write requests are smaller than a buffer, we do not turn + on quickbin */ + +static void fwriteSlowB(const void *ptr, + FILE *stream, + size_t towrite, + size_t *actualWritten) +{ + size_t spare; +#ifdef __OS2__ + ULONG tempWritten; + APIRET rc; +#endif +#ifdef __MSDOS__ + size_t tempWritten; + int errind; +#endif + + spare = (size_t)(stream->endbuf - stream->upto); + if (towrite < spare) + { + memcpy(stream->upto, ptr, towrite); + *actualWritten = towrite; + stream->upto += towrite; + return; + } + memcpy(stream->upto, ptr, spare); +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + stream->fbuf, + stream->szfbuf, + &tempWritten); + if (rc != 0) + { + stream->errorInd = 1; + errno = rc; + return; + } +#endif +#ifdef __MSDOS__ + tempWritten = __write(stream->hfile, + stream->fbuf, + stream->szfbuf, + &errind); + if (errind) + { + stream->errorInd = 1; + errno = tempWritten; + return; + } +#endif + *actualWritten = spare; + stream->upto = stream->fbuf; + stream->bufStartR += tempWritten; + if (towrite > stream->szfbuf) + { + stream->quickBin = 1; +#ifdef __OS2__ + rc = DosWrite(stream->hfile, + (char *)ptr + *actualWritten, + towrite - *actualWritten, + &tempWritten); + if (rc != 0) + { + stream->errorInd = 1; + errno = rc; + return; + } +#endif +#ifdef __MSDOS__ + tempWritten = __write(stream->hfile, + (char *)ptr + *actualWritten, + towrite - *actualWritten, + &errind); + if (errind) + { + stream->errorInd = 1; + errno = tempWritten; + return; + } +#endif + *actualWritten += tempWritten; + stream->bufStartR += tempWritten; + } + else + { + memcpy(stream->fbuf, + (char *)ptr + *actualWritten, + towrite - *actualWritten); + stream->upto += (towrite - *actualWritten); + *actualWritten = towrite; + } + stream->bufStartR += *actualWritten; + return; +} +#endif +*/ diff --git a/functions/stdio/getc.c b/functions/stdio/getc.c index 550e954..f2de070 100644 --- a/functions/stdio/getc.c +++ b/functions/stdio/getc.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- int getc( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (fgetc(stream)); +} +*/ diff --git a/functions/stdio/getchar.c b/functions/stdio/getchar.c index 734e19b..0ba30fc 100644 --- a/functions/stdio/getchar.c +++ b/functions/stdio/getchar.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- int getchar( void ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (getc(stdin)); +} +*/ diff --git a/functions/stdio/gets.c b/functions/stdio/gets.c index beba574..ecba23f 100644 --- a/functions/stdio/gets.c +++ b/functions/stdio/gets.c @@ -6,3 +6,16 @@ // ---------------------------------------------------------------------------- char * gets( char * s ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + char *ret; + + stdin->quickText = 0; + stdin->noNl = 1; + ret = fgets(s, INT_MAX, stdin); + stdin->noNl = 0; + stdin->quickText = 1; + return (ret); +} +*/ diff --git a/functions/stdio/perror.c b/functions/stdio/perror.c index f93a53b..d94746c 100644 --- a/functions/stdio/perror.c +++ b/functions/stdio/perror.c @@ -6,3 +6,21 @@ // ---------------------------------------------------------------------------- void perror( const char * s ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + if ((s != NULL) && (*s != '\0')) + { + printf("%s: "); + } + if (errno == 0) + { + printf("No error has occurred\n"); + } + else + { + printf("An error has occurred\n"); + } + return; +} +*/ diff --git a/functions/stdio/printf.c b/functions/stdio/printf.c index cda5741..440fa5f 100644 --- a/functions/stdio/printf.c +++ b/functions/stdio/printf.c @@ -6,3 +6,15 @@ // ---------------------------------------------------------------------------- int printf( const char * restrict format, ... ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + va_list arg; + int ret; + + va_start(arg, format); + ret = vfprintf(stdout, format, arg); + va_end(arg); + return (ret); +} +*/ diff --git a/functions/stdio/putc.c b/functions/stdio/putc.c index 83b4086..01acfd8 100644 --- a/functions/stdio/putc.c +++ b/functions/stdio/putc.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- int putc( int c, FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (fputc(c, stream)); +} +*/ diff --git a/functions/stdio/putchar.c b/functions/stdio/putchar.c index fab2213..7025698 100644 --- a/functions/stdio/putchar.c +++ b/functions/stdio/putchar.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- int putchar( int c ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (putc(c, stdout)); +} +*/ diff --git a/functions/stdio/puts.c b/functions/stdio/puts.c index 9354351..d4ec498 100644 --- a/functions/stdio/puts.c +++ b/functions/stdio/puts.c @@ -6,3 +6,16 @@ // ---------------------------------------------------------------------------- int puts( const char * s ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + int ret; + + ret = fputs(s, stdout); + if (ret == EOF) + { + return (ret); + } + return (putc('\n', stdout)); +} +*/ diff --git a/functions/stdio/rewind.c b/functions/stdio/rewind.c index 0dd56ae..fdcb430 100644 --- a/functions/stdio/rewind.c +++ b/functions/stdio/rewind.c @@ -6,3 +6,10 @@ // ---------------------------------------------------------------------------- void rewind( FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + fseek(stream, 0L, SEEK_SET); + return; +} +*/ diff --git a/functions/stdio/scanf.c b/functions/stdio/scanf.c index 7ebb31d..e4342ab 100644 --- a/functions/stdio/scanf.c +++ b/functions/stdio/scanf.c @@ -6,3 +6,15 @@ // ---------------------------------------------------------------------------- int scanf( const char * restrict format, ... ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + va_list arg; + int ret; + + va_start(arg, format); + ret = vvscanf(format, arg, stdin, NULL); + va_end(arg); + return (ret); +} +*/ diff --git a/functions/stdio/setbuf.c b/functions/stdio/setbuf.c index 6d689b0..85137af 100644 --- a/functions/stdio/setbuf.c +++ b/functions/stdio/setbuf.c @@ -6,3 +6,19 @@ // ---------------------------------------------------------------------------- void setbuf( FILE * restrict stream, char * restrict buf ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + int ret; + + if (buf == NULL) + { + ret = setvbuf(stream, NULL, _IONBF, 0); + } + else + { + ret = setvbuf(stream, buf, _IOFBF, BUFSIZ); + } + return (ret); +} +*/ diff --git a/functions/stdio/setvbuf.c b/functions/stdio/setvbuf.c index a65dd8e..2f9b4c4 100644 --- a/functions/stdio/setvbuf.c +++ b/functions/stdio/setvbuf.c @@ -6,3 +6,62 @@ // ---------------------------------------------------------------------------- int setvbuf( FILE * restrict stream, char * restrict buf, int mode, size_t size ) { /* TODO */ }; + +/* PDPC code - unreviewed +/* +NULL + F = allocate, setup +NULL + L = allocate, setup +NULL + N = ignore, return success +buf + F = setup +buf + L = setup +buf + N = ignore, return success +*/ + +int setvbuf(FILE *stream, char *buf, int mode, size_t size) +{ + char *mybuf; + + if (mode == _IONBF) + { + stream->bufTech = mode; + return (0); + } + if (buf == NULL) + { + if (size < 2) + { + return (-1); + } + mybuf = malloc(size + 8); + if (mybuf == NULL) + { + return (-1); + } + } + else + { + if (size < 10) + { + return (-1); + } + mybuf = buf; + stream->theirBuffer = 1; + size -= 8; + } + free(stream->intBuffer); + stream->intBuffer = mybuf; + stream->fbuf = stream->intBuffer + 2; + *stream->fbuf++ = '\0'; + *stream->fbuf++ = '\0'; + stream->szfbuf = size; + stream->endbuf = stream->fbuf + stream->szfbuf; + *stream->endbuf = '\n'; + stream->upto = stream->endbuf; + stream->bufTech = mode; + if (!stream->textMode && (stream->bufTech == _IOLBF)) + { + stream->quickBin = 0; + } + return (0); +} +*/ diff --git a/functions/stdio/sprintf.c b/functions/stdio/sprintf.c index 5a06202..2063e78 100644 --- a/functions/stdio/sprintf.c +++ b/functions/stdio/sprintf.c @@ -6,3 +6,15 @@ // ---------------------------------------------------------------------------- int sprintf( char * restrict s, const char * restrict format, ... ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + va_list arg; + int ret; + + va_start(arg, format); + ret = vsprintf(s, format, arg); + va_end(arg); + return (ret); +} +*/ diff --git a/functions/stdio/sscanf.c b/functions/stdio/sscanf.c index ffe1475..0b902ee 100644 --- a/functions/stdio/sscanf.c +++ b/functions/stdio/sscanf.c @@ -6,3 +6,15 @@ // ---------------------------------------------------------------------------- int sscanf( const char * restrict s, const char * restrict format, ... ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + va_list arg; + int ret; + + va_start(arg, format); + ret = vvscanf(format, arg, NULL, s); + va_end(arg); + return (ret); +} +*/ diff --git a/functions/stdio/tmpfile.c b/functions/stdio/tmpfile.c index 90c9ce7..1eb153d 100644 --- a/functions/stdio/tmpfile.c +++ b/functions/stdio/tmpfile.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- FILE * tmpfile( void ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (fopen("ZZZZZZZA.$$$", "wb+")); +} +*/ \ No newline at end of file diff --git a/functions/stdio/tmpnam.c b/functions/stdio/tmpnam.c index fe3a75d..ad642a0 100644 --- a/functions/stdio/tmpnam.c +++ b/functions/stdio/tmpnam.c @@ -6,3 +6,17 @@ // ---------------------------------------------------------------------------- char * tmpnam( char * s ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + static char buf[] = "ZZZZZZZA.$$$"; + + buf[7]++; + if (s == NULL) + { + return (buf); + } + strcpy(s, buf); + return (s); +} +*/ diff --git a/functions/stdio/ungetc.c b/functions/stdio/ungetc.c index c355afc..f15d8a3 100644 --- a/functions/stdio/ungetc.c +++ b/functions/stdio/ungetc.c @@ -6,3 +6,15 @@ // ---------------------------------------------------------------------------- int ungetc( int c, FILE * stream ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + if ((stream->ungetCh != -1) || (c == EOF)) + { + return (EOF); + } + stream->ungetCh = (unsigned char)c; + stream->quickText = 0; + return ((unsigned char)c); +} +*/ diff --git a/functions/stdio/vfprintf.c b/functions/stdio/vfprintf.c index a903d8f..7bbc212 100644 --- a/functions/stdio/vfprintf.c +++ b/functions/stdio/vfprintf.c @@ -6,3 +6,404 @@ // ---------------------------------------------------------------------------- int vfprintf( FILE * restrict stream, const char * restrict format, va_list ap ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + int ret; + + ret = vvprintf(format, arg, stream, NULL); + return (ret); +} + +{ + int fin = 0; + int vint; + char *vcptr; + int chcount = 0; + size_t len; + char numbuf[50]; + char *nptr; + + while (!fin) + { + if (*format == '\0') + { + fin = 1; + } + else if (*format == '%') + { + format++; + if (*format == 'd') + { + int neg = 0; + + vint = va_arg(arg, int); + if (vint < 0) + { + neg = 1; + vint = -vint; + } + nptr = numbuf; + do + { + *nptr++ = (char)('0' + vint % 10); + vint /= 10; + } while (vint > 0); + if (neg) + { + *nptr++ = '-'; + } + do + { + nptr--; + outch(*nptr); + chcount++; + } while (nptr != numbuf); + } + else if (*format == 's') + { + vcptr = va_arg(arg, char *); + if (fq == NULL) + { + len = strlen(vcptr); + memcpy(s, vcptr, len); + s += len; + chcount += len; + } + else + { + fputs(vcptr, fq); + chcount += strlen(vcptr); + } + } + else if (*format == 'c') + { + vint = va_arg(arg, int); + outch(vint); + chcount++; + } + else if (*format == '%') + { + outch('%'); + chcount++; + } + else + { + int extraCh; + + extraCh = examine(&format, fq, s, &arg, chcount); + chcount += extraCh; + if (s != NULL) + { + s += extraCh; + } + } + } + else + { + outch(*format); + chcount++; + } + format++; + } + return (chcount); +} + +static int examine(const char **formt, FILE *fq, char *s, va_list *arg, + int chcount) +{ + int extraCh = 0; + int flagMinus = 0; + int flagPlus = 0; + int flagSpace = 0; + int flagHash = 0; + int flagZero = 0; + int width = 0; + int precision = -1; + int half = 0; + int lng = 0; + int specifier = 0; + int fin; + long lvalue; + unsigned long ulvalue; + char *svalue; + char work[50]; + int x; + int y; + int rem; + const char *format; + int base; + int fillCh; + int neg; + int length; + + unused(chcount); + format = *formt; + /* processing flags */ + fin = 0; + while (!fin) + { + switch (*format) + { + case '-': flagMinus = 1; + break; + case '+': flagPlus = 1; + break; + case ' ': flagSpace = 1; + break; + case '#': flagHash = 1; + break; + case '0': flagZero = 1; + break; + default: fin = 1; + break; + } + if (!fin) + { + format++; + } + else + { + if (flagSpace && flagPlus) + { + flagSpace = 0; + } + if (flagMinus) + { + flagZero = 0; + } + } + } + + /* processing width */ + if (isdigit((unsigned char)*format)) + { + while (isdigit((unsigned char)*format)) + { + width = width * 10 + (*format - '0'); + format++; + } + } + + /* processing precision */ + if (*format == '.') + { + format++; + precision = 0; + while (isdigit((unsigned char)*format)) + { + precision = precision * 10 + (*format - '0'); + format++; + } + } + + /* processing h/l/L */ + if (*format == 'h') + { + half = 1; + } + else if (*format == 'l') + { + lng = 1; + } + else if (*format == 'L') + { + lng = 1; + } + else + { + format--; + } + format++; + + if (precision < 0) + { + precision = 1; + } + /* processing specifier */ + specifier = *format; + + if (strchr("dxXuiop", specifier) != NULL) + { +#if defined(__MSDOS__) && !defined(__PDOS__) + if (specifier == 'p') + { + lng = 1; + } +#endif + if (lng) + { + lvalue = va_arg(*arg, long); + } + else if (half) + { + lvalue = va_arg(*arg, short); + } + else + { + lvalue = va_arg(*arg, int); + } + ulvalue = (unsigned long)lvalue; + if ((lvalue < 0) && ((specifier == 'd') || (specifier == 'i'))) + { + neg = 1; + ulvalue = -lvalue; + } + else + { + neg = 0; + } + if ((specifier == 'X') || (specifier == 'x') || (specifier == 'p')) + { + base = 16; + } + else if (specifier == 'o') + { + base = 8; + } + else + { + base = 10; + } + if (specifier == 'p') + { +#if defined(__OS2__) || defined(__PDOS__) + precision = 8; +#endif +#if defined(__MSDOS__) && !defined(__PDOS__) + precision = 9; +#endif + } + x = 0; + while (ulvalue > 0) + { + rem = (int)(ulvalue % base); + if (rem < 10) + { + work[x] = (char)('0' + rem); + } + else + { + if ((specifier == 'X') || (specifier == 'p')) + { + work[x] = (char)('A' + (rem - 10)); + } + else + { + work[x] = (char)('a' + (rem - 10)); + } + } + x++; +#if defined(__MSDOS__) && !defined(__PDOS__) + if ((x == 4) && (specifier == 'p')) + { + work[x] = ':'; + x++; + } +#endif + ulvalue = ulvalue / base; + } + while (x < precision) + { + work[x] = '0'; + x++; + } + if (neg) + { + work[x++] = '-'; + } + if (flagZero) + { + fillCh = '0'; + } + else + { + fillCh = ' '; + } + y = x; + if (!flagMinus) + { + while (y < width) + { + outch(fillCh); + extraCh++; + y++; + } + } + if (flagHash && (toupper(specifier) == 'X')) + { + outch('0'); + outch('x'); + extraCh += 2; + } + x--; + while (x >= 0) + { + outch(work[x]); + extraCh++; + x--; + } + if (flagMinus) + { + while (y < width) + { + outch(fillCh); + extraCh++; + y++; + } + } + } + else if (specifier == 's') + { + svalue = va_arg(*arg, char *); + fillCh = ' '; + if (precision > 1) + { + char *p; + + p = memchr(svalue, '\0', precision); + if (p != NULL) + { + length = (int)(p - svalue); + } + else + { + length = precision; + } + } + else + { + length = strlen(svalue); + } + if (!flagMinus) + { + if (length < width) + { + extraCh += (width - length); + for (x = 0; x < (width - length); x++) + { + outch(fillCh); + } + } + } + for (x = 0; x < length; x++) + { + outch(svalue[x]); + } + extraCh += length; + if (flagMinus) + { + if (length < width) + { + extraCh += (width - length); + for (x = 0; x < (width - length); x++) + { + outch(fillCh); + } + } + } + } + *formt = format; + return (extraCh); +} +*/ diff --git a/functions/stdio/vscanf.c b/functions/stdio/vscanf.c index ee0087a..14d69f7 100644 --- a/functions/stdio/vscanf.c +++ b/functions/stdio/vscanf.c @@ -6,3 +6,4 @@ // ---------------------------------------------------------------------------- int vscanf( const char * restrict format, va_list ap ) { /* TODO */ }; + diff --git a/functions/stdio/vsprintf.c b/functions/stdio/vsprintf.c index 2cfcdfb..8e21b70 100644 --- a/functions/stdio/vsprintf.c +++ b/functions/stdio/vsprintf.c @@ -6,3 +6,16 @@ // ---------------------------------------------------------------------------- int vsprintf( char * restrict s, const char * restrict format, va_list ap) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + int ret; + + ret = vvprintf(format, arg, NULL, s); + if (ret >= 0) + { + *(s + ret) = '\0'; + } + return (ret); +} +*/ diff --git a/functions/stdlib/abort.c b/functions/stdlib/abort.c index 61d3a01..5f18565 100644 --- a/functions/stdlib/abort.c +++ b/functions/stdlib/abort.c @@ -6,3 +6,10 @@ // ---------------------------------------------------------------------------- void abort( void ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + raise(SIGABRT); + exit(EXIT_FAILURE); +} +*/ \ No newline at end of file diff --git a/functions/stdlib/atexit.c b/functions/stdlib/atexit.c index ac478c9..9792cad 100644 --- a/functions/stdlib/atexit.c +++ b/functions/stdlib/atexit.c @@ -7,3 +7,19 @@ // TODO: C/C++ linkages int atexit( void (*func) ( void ) ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + int x; + + for (x = 0; x < __NATEXIT; x++) + { + if (__userExit[x] == 0) + { + __userExit[x] = func; + return (0); + } + } + return (-1); +} +*/ diff --git a/functions/stdlib/bsearch.c b/functions/stdlib/bsearch.c index 0560286..c03cd45 100644 --- a/functions/stdlib/bsearch.c +++ b/functions/stdlib/bsearch.c @@ -7,3 +7,32 @@ // TODO: C/C++ linkage void * bsearch( const void * key, const void * base, size_t nelem, size_t size, int (*cmp) ( const void * ck, const void * ce) ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + size_t try; + int res; + const void *ptr; + + while (nmemb > 0) + { + try = nmemb / 2; + ptr = (void *)((char *)base + try * size); + res = compar(ptr, key); + if (res == 0) + { + return ((void *)ptr); + } + else if (res < 0) + { + nmemb = nmemb - try - 1; + base = (const void *)((const char *)ptr + size); + } + else + { + nmemb = try; + } + } + return (NULL); +} +*/ diff --git a/functions/stdlib/calloc.c b/functions/stdlib/calloc.c index 5470427..4169f84 100644 --- a/functions/stdlib/calloc.c +++ b/functions/stdlib/calloc.c @@ -6,3 +6,29 @@ // ---------------------------------------------------------------------------- void * calloc( size_t nelem, size_t size ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + void *ptr; + size_t total; + + if (nmemb == 1) + { + total = size; + } + else if (size == 1) + { + total = nmemb; + } + else + { + total = nmemb * size; + } + ptr = malloc(total); + if (ptr != NULL) + { + memset(ptr, '\0', total); + } + return (ptr); +} +*/ \ No newline at end of file diff --git a/functions/stdlib/mblen.c b/functions/stdlib/mblen.c index b9136e4..ae90a98 100644 --- a/functions/stdlib/mblen.c +++ b/functions/stdlib/mblen.c @@ -6,3 +6,20 @@ // ---------------------------------------------------------------------------- int mblen( const char * s, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + if (s == NULL) + { + return (0); + } + if (n == 1) + { + return (1); + } + else + { + return (-1); + } +} +*/ diff --git a/functions/stdlib/mbstowcs.c b/functions/stdlib/mbstowcs.c index e58d9b9..f4ca6d1 100644 --- a/functions/stdlib/mbstowcs.c +++ b/functions/stdlib/mbstowcs.c @@ -6,3 +6,14 @@ // ---------------------------------------------------------------------------- size_t mbstowcs( wchar_t * restrict wcs, const char * restrict s, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + strncpy((char *)pwcs, s, n); + if (strlen(s) >= n) + { + return (n); + } + return (strlen((char *)pwcs)); +} +*/ diff --git a/functions/stdlib/mbtowc.c b/functions/stdlib/mbtowc.c index 89a68ca..7163019 100644 --- a/functions/stdlib/mbtowc.c +++ b/functions/stdlib/mbtowc.c @@ -6,3 +6,24 @@ // ---------------------------------------------------------------------------- int mbtowc( wchar_t * restrict pwc, const char * restrict s, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + if (s == NULL) + { + return (0); + } + if (n == 1) + { + if (pwc != NULL) + { + *pwc = *s; + } + return (1); + } + else + { + return (-1); + } +} +*/ \ No newline at end of file diff --git a/functions/stdlib/qsort.c b/functions/stdlib/qsort.c index 5904975..a1f903c 100644 --- a/functions/stdlib/qsort.c +++ b/functions/stdlib/qsort.c @@ -7,3 +7,153 @@ // TODO: C/C++ linkage void qsort( void * base, size_t nelem, size_t size, int (*cmp) ( const void * e1, const void * e2) ) { /* TODO */ }; + +/* PDPC code - unreviewed +/******************************************************************/ +/* qsort.c -- Non-Recursive ISO C qsort() function */ +/* */ +/* Public domain by Raymond Gardner, Englewood CO February 1991 */ +/* Minor mods by Paul Edwards also public domain */ +/* */ +/* Usage: */ +/* qsort(base, nbr_elements, width_bytes, compare_function); */ +/* void *base; */ +/* size_t nbr_elements, width_bytes; */ +/* int (*compare_function)(const void *, const void *); */ +/* */ +/* Sorts an array starting at base, of length nbr_elements, each */ +/* element of size width_bytes, ordered via compare_function, */ +/* which is called as (*compare_function)(ptr_to_element1, */ +/* ptr_to_element2) and returns < 0 if element1 < element2, */ +/* 0 if element1 = element2, > 0 if element1 > element2. */ +/* Most refinements are due to R. Sedgewick. See "Implementing */ +/* Quicksort Programs", Comm. ACM, Oct. 1978, and Corrigendum, */ +/* Comm. ACM, June 1979. */ +/******************************************************************/ + +/* prototypes */ +static void swap_chars(char *, char *, size_t); + +/* +** Compile with -DSWAP_INTS if your machine can access an int at an +** arbitrary location with reasonable efficiency. (Some machines +** cannot access an int at an odd address at all, so be careful.) +*/ + +#ifdef SWAP_INTS + void swap_ints(char *, char *, size_t); + #define SWAP(a, b) (swap_func((char *)(a), (char *)(b), width)) +#else + #define SWAP(a, b) (swap_chars((char *)(a), (char *)(b), size)) +#endif + +#define COMP(a, b) ((*comp)((void *)(a), (void *)(b))) + +#define T 7 /* subfiles of T or fewer elements will */ + /* be sorted by a simple insertion sort */ + /* Note! T must be at least 3 */ + +void qsort(void *basep, size_t nelems, size_t size, + int (*comp)(const void *, const void *)) +{ + char *stack[40], **sp; /* stack and stack pointer */ + char *i, *j, *limit; /* scan and limit pointers */ + size_t thresh; /* size of T elements in bytes */ + char *base; /* base pointer as char * */ + +#ifdef SWAP_INTS + size_t width; /* width of array element */ + void (*swap_func)(char *, char *, size_t); /* swap func pointer*/ + + width = size; /* save size for swap routine */ + swap_func = swap_chars; /* choose swap function */ + if ( size % sizeof(int) == 0 ) { /* size is multiple of ints */ + width /= sizeof(int); /* set width in ints */ + swap_func = swap_ints; /* use int swap function */ + } +#endif + + base = (char *)basep; /* set up char * base pointer */ + thresh = T * size; /* init threshold */ + sp = stack; /* init stack pointer */ + limit = base + nelems * size;/* pointer past end of array */ + for ( ;; ) { /* repeat until break... */ + if ( limit - base > thresh ) { /* if more than T elements */ + /* swap base with middle */ + SWAP(((((size_t)(limit-base))/size)/2)*size+base, base); + i = base + size; /* i scans left to right */ + j = limit - size; /* j scans right to left */ + if ( COMP(i, j) > 0 ) /* Sedgewick's */ + SWAP(i, j); /* three-element sort */ + if ( COMP(base, j) > 0 ) /* sets things up */ + SWAP(base, j); /* so that */ + if ( COMP(i, base) > 0 ) /* *i <= *base <= *j */ + SWAP(i, base); /* *base is pivot element */ + for ( ;; ) { /* loop until break */ + do /* move i right */ + i += size; /* until *i >= pivot */ + while ( COMP(i, base) < 0 ); + do /* move j left */ + j -= size; /* until *j <= pivot */ + while ( COMP(j, base) > 0 ); + if ( i > j ) /* if pointers crossed */ + break; /* break loop */ + SWAP(i, j); /* else swap elements, keep scanning*/ + } + SWAP(base, j); /* move pivot into correct place */ + if ( j - base > limit - i ) { /* if left subfile larger */ + sp[0] = base; /* stack left subfile base */ + sp[1] = j; /* and limit */ + base = i; /* sort the right subfile */ + } else { /* else right subfile larger*/ + sp[0] = i; /* stack right subfile base */ + sp[1] = limit; /* and limit */ + limit = j; /* sort the left subfile */ + } + sp += 2; /* increment stack pointer */ + } else { /* else subfile is small, use insertion sort */ + for ( j = base, i = j+size; i < limit; j = i, i += size ) + for ( ; COMP(j, j+size) > 0; j -= size ) { + SWAP(j, j+size); + if ( j == base ) + break; + } + if ( sp != stack ) { /* if any entries on stack */ + sp -= 2; /* pop the base and limit */ + base = sp[0]; + limit = sp[1]; + } else /* else stack empty, done */ + break; + } + } +} + +/* +** swap nbytes between a and b +*/ + +static void swap_chars(char *a, char *b, size_t nbytes) +{ + char tmp; + do { + tmp = *a; *a++ = *b; *b++ = tmp; + } while ( --nbytes ); +} + +#ifdef SWAP_INTS + +/* +** swap nints between a and b +*/ + +static void swap_ints(char *ap, char *bp, size_t nints) +{ + int *a = (int *)ap, *b = (int *)bp; + int tmp; + do { + tmp = *a; *a++ = *b; *b++ = tmp; + } while ( --nints ); +} + +#endif +*/ \ No newline at end of file diff --git a/functions/stdlib/rand.c b/functions/stdlib/rand.c index 0821fe4..967ae2f 100644 --- a/functions/stdlib/rand.c +++ b/functions/stdlib/rand.c @@ -7,3 +7,22 @@ int rand( void ) { /* TODO */ }; void srand( unsigned int seed ) { /* TODO */ }; + +/* PDPC code - unreviewed +static unsigned long myseed = 1; + +void srand(unsigned int seed) +{ + myseed = seed; + return; +} + +int rand(void) +{ + int ret; + + myseed = myseed * 1103515245UL + 12345; + ret = (int)((myseed >> 16) & 0x8fff); + return (ret); +} +*/ diff --git a/functions/stdlib/realloc.c b/functions/stdlib/realloc.c index ac615b8..ae11da5 100644 --- a/functions/stdlib/realloc.c +++ b/functions/stdlib/realloc.c @@ -6,3 +6,27 @@ // ---------------------------------------------------------------------------- void * realloc( void * ptr, size_t size ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + char *newptr; + size_t oldsize; + + newptr = malloc(size); + if (newptr == NULL) + { + return (NULL); + } + if (ptr != NULL) + { + oldsize = *(size_t *)((char *)ptr - 4); + if (oldsize < size) + { + size = oldsize; + } + memcpy(newptr, ptr, size); + free(ptr); + } + return (newptr); +} +*/ diff --git a/functions/stdlib/strtox.c b/functions/stdlib/strtox.c index cca9711..1def161 100644 --- a/functions/stdlib/strtox.c +++ b/functions/stdlib/strtox.c @@ -19,3 +19,131 @@ unsigned long long strtoull( const char * restrict s, char * * restrict endptr, long strtol( const char * restrict s, char * * restrict endptr, int base ) { /* TODO */ }; unsigned long strtoul( const char * restrict s, char * * restrict endptr, int base) { /* TODO */ }; + +/* PDPC code - unreviewed, verbatim +double atof(const char *nptr) +{ + return (strtod(nptr, (char **)NULL)); +} + +double strtod(const char *nptr, char **endptr) +{ + double x = 0.0; + + while (1) + { + if (isdigit(*nptr)) + { + x = x * 10 + (*nptr - '0'); + } + else + { + if (endptr != NULL) + { + *endptr = (char *)nptr; + } + break; + } + nptr++; + } + return (x); +} + +int atoi(const char *nptr) +{ + return ((int)strtol(nptr, (char **)NULL, 10)); +} + +long int atol(const char *nptr) +{ + return (strtol(nptr, (char **)NULL, 10)); +} + +long int strtol(const char *nptr, char **endptr, int base) +{ + long x = 0; + int undecided = 0; + + if (base == 0) + { + undecided = 1; + } + while (1) + { + if (isdigit(*nptr)) + { + if (base == 0) + { + if (*nptr == '0') + { + base = 8; + } + else + { + base = 10; + undecided = 0; + } + } + x = x * base + (*nptr - '0'); + nptr++; + } + else if (isalpha(*nptr)) + { + if ((*nptr == 'X') || (*nptr == 'x')) + { + if ((base == 0) || ((base == 8) && undecided)) + { + base = 16; + undecided = 0; + } + else + { + break; + } + } + else + { + x = x * base + (toupper((unsigned char)*nptr) - 'A') + 10; + nptr++; + } + } + else + { + break; + } + } + if (endptr != NULL) + { + *endptr = (char *)nptr; + } + return (x); +} + +unsigned long int strtoul(const char *nptr, char **endptr, int base) +{ + unsigned long x = 0; + + while (1) + { + if (isdigit(*nptr)) + { + x = x * base + (*nptr - '0'); + nptr++; + } + else if (isalpha(*nptr) && (base > 10)) + { + x = x * base + (toupper((unsigned char)*nptr) - 'A') + 10; + nptr++; + } + else + { + break; + } + } + if (endptr != NULL) + { + *endptr = (char *)nptr; + } + return (x); +} +*/ diff --git a/functions/stdlib/wcstombs.c b/functions/stdlib/wcstombs.c index 08a639f..b78ddb7 100644 --- a/functions/stdlib/wcstombs.c +++ b/functions/stdlib/wcstombs.c @@ -6,3 +6,14 @@ // ---------------------------------------------------------------------------- size_t wcstombs( char * restrict s, const wchar_t * restrict wcs, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + strncpy(s, (const char *)pwcs, n); + if (strlen((const char *)pwcs) >= n) + { + return (n); + } + return (strlen(s)); +} +*/ diff --git a/functions/stdlib/wctomb.c b/functions/stdlib/wctomb.c index ba31621..94e6367 100644 --- a/functions/stdlib/wctomb.c +++ b/functions/stdlib/wctomb.c @@ -6,3 +6,17 @@ // ---------------------------------------------------------------------------- int wctomb( char * s, wchar_t wchar ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + if (s != NULL) + { + *s = wchar; + return (1); + } + else + { + return (0); + } +} +*/ diff --git a/functions/string/memchr.c b/functions/string/memchr.c index 83d6f17..6a6440a 100644 --- a/functions/string/memchr.c +++ b/functions/string/memchr.c @@ -15,3 +15,19 @@ void * memchr( void * s, int c, size_t n ) { /* TODO */ }; // Standard C void * memchr( const void * s, int c, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const unsigned char *p; + size_t x = 0; + + p = (const unsigned char *)s; + while (x < n) + { + if (*p == (unsigned char)c) return ((void *)p); + p++; + x++; + } + return (NULL); +} +*/ diff --git a/functions/string/memcmp.c b/functions/string/memcmp.c index 43b7e58..c16d50a 100644 --- a/functions/string/memcmp.c +++ b/functions/string/memcmp.c @@ -6,3 +6,21 @@ // ---------------------------------------------------------------------------- int memcmp( const void * s1, const void * s2, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const unsigned char *p1; + const unsigned char *p2; + size_t x = 0; + + p1 = (const unsigned char *)s1; + p2 = (const unsigned char *)s2; + while (x < n) + { + if (p1[x] < p2[x]) return (-1); + else if (p1[x] > p2[x]) return (1); + x++; + } + return (0); +} +*/ diff --git a/functions/string/memcpy.c b/functions/string/memcpy.c index d0da556..d53b22e 100644 --- a/functions/string/memcpy.c +++ b/functions/string/memcpy.c @@ -6,3 +6,69 @@ // ---------------------------------------------------------------------------- void * memcpy( void * restrict s1, const void * restrict s2, size_t n ) { /* TODO */ }; + +/* Therx code +{ + void * ret = s1; + const char * src = (const char *) s2; + char * dst = (char *) s1; + for( ; n != 0; n-- ) + { + *dst++ = *src++; + } + return ret; +} +*/ + +/* PDPC code - unreviewed +void *memcpy(void *s1, const void *s2, size_t n) +{ + register const unsigned char *f = s2; + register const unsigned char *fe; + register unsigned char *t = s1; + + fe = f + n; + while (f != fe) + { + *t++ = *f++; + } + return (s1); +} +#else +void *memcpy(void *s1, const void *s2, size_t n) +{ + register unsigned int *p = (unsigned int *)s1; + register unsigned int *cs2 = (unsigned int *)s2; + register unsigned int *endi; + + endi = (unsigned int *)((char *)p + (n & ~0x03)); + while (p != endi) + { + *p++ = *cs2++; + } + switch (n & 0x03) + { + case 0: + break; + case 1: + *(char *)p = *(char *)cs2; + break; + case 2: + *(char *)p = *(char *)cs2; + p = (unsigned int *)((char *)p + 1); + cs2 = (unsigned int *)((char *)cs2 + 1); + *(char *)p = *(char *)cs2; + break; + case 3: + *(char *)p = *(char *)cs2; + p = (unsigned int *)((char *)p + 1); + cs2 = (unsigned int *)((char *)cs2 + 1); + *(char *)p = *(char *)cs2; + p = (unsigned int *)((char *)p + 1); + cs2 = (unsigned int *)((char *)cs2 + 1); + *(char *)p = *(char *)cs2; + break; + } + return (s1); +} +*/ diff --git a/functions/string/memmove.c b/functions/string/memmove.c index 9ecce5d..ba73742 100644 --- a/functions/string/memmove.c +++ b/functions/string/memmove.c @@ -6,3 +6,33 @@ // ---------------------------------------------------------------------------- void * memmove( void * s1, const void * s2, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + char *p = s1; + const char *cs2 = s2; + size_t x; + + if (p <= cs2) + { + for (x=0; x < n; x++) + { + *p = *cs2; + p++; + cs2++; + } + } + else + { + if (n != 0) + { + for (x=n-1; x > 0; x--) + { + *(p+x) = *(cs2+x); + } + } + *(p+x) = *(cs2+x); + } + return (s1); +} +*/ \ No newline at end of file diff --git a/functions/string/memset.c b/functions/string/memset.c index 2771ae1..3d4a64e 100644 --- a/functions/string/memset.c +++ b/functions/string/memset.c @@ -6,3 +6,26 @@ // ---------------------------------------------------------------------------- void * memset( void * s, int c, size_t n ) { /* TODO */ }; + +/* Therx code +{ + unsigned short * tmp = (unsigned short *) s; // TODO: unsigned short? + for( ; n != 0; n-- ) + { + *tmp++ = c; + } + return s; +} +*/ + +/* PDPC code - unreviewed +{ + size_t x = 0; + + for (x = 0; x < n; x++) + { + *((char *)s + x) = (unsigned char)c; + } + return (s); +} +*/ diff --git a/functions/string/strcat.c b/functions/string/strcat.c index cb0c0a1..a0cef0e 100644 --- a/functions/string/strcat.c +++ b/functions/string/strcat.c @@ -6,3 +6,31 @@ // ---------------------------------------------------------------------------- char * strcat( char * restrict s1, const char * restrict s2 ) { /* TODO */ }; + +/* Therx code +{ + while (*s1) + { + s1++; + } + while (*s1++ = *s2++) + { + // EMPTY + } + return s1; +} +*/ + +/* PDPC code - unreviewed +{ + char *p = s1; + + while (*p != '\0') p++; + while ((*p = *s2) != '\0') + { + p++; + s2++; + } + return (s1); +} +*/ diff --git a/functions/string/strchr.c b/functions/string/strchr.c index fb16904..dcfc025 100644 --- a/functions/string/strchr.c +++ b/functions/string/strchr.c @@ -15,3 +15,14 @@ char * strchr( char * s, int c ) { /* TODO */ }; // Standard C char * strchr( const char * s, int c ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + while (*s != '\0') + { + if (*s == (char)c) return ((char *)s); + s++; + } + return (NULL); +} +*/ diff --git a/functions/string/strcmp.c b/functions/string/strcmp.c index 9906f49..17e138c 100644 --- a/functions/string/strcmp.c +++ b/functions/string/strcmp.c @@ -6,3 +6,33 @@ // ---------------------------------------------------------------------------- int strcmp( const char * s1, const char * s2 ) { /* TODO */ }; + +/* Therx code +{ + while ((*s1 != '\0') && (*s1 == *s2)) + { + s1++; + s2++; + } + return (*(unsigned char *) s1) - (*(unsigned char *) s2); +} +*/ + +/* PDPC code - unreviewed +{ + const unsigned char *p1; + const unsigned char *p2; + + p1 = (const unsigned char *)s1; + p2 = (const unsigned char *)s2; + while (*p1 != '\0') + { + if (*p1 < *p2) return (-1); + else if (*p1 > *p2) return (1); + p1++; + p2++; + } + if (*p2 == '\0') return (0); + else return (-1); +} +*/ diff --git a/functions/string/strcoll.c b/functions/string/strcoll.c index 898eeb5..80ecbdf 100644 --- a/functions/string/strcoll.c +++ b/functions/string/strcoll.c @@ -6,3 +6,9 @@ // ---------------------------------------------------------------------------- int strcoll( const char * s1, const char * s2 ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + return (strcmp(s1, s2)); +} +*/ diff --git a/functions/string/strcpy.c b/functions/string/strcpy.c index 1cc1c8e..03b8563 100644 --- a/functions/string/strcpy.c +++ b/functions/string/strcpy.c @@ -6,3 +6,23 @@ // ---------------------------------------------------------------------------- char * strcpy( char * restrict s1, const char * restrict s2 ) { /* TODO */ }; + +/* Therx code - unreviewed +{ + while (*s1++ = *s2++) + { + // EMPTY + } + return s1; +} +*/ + +/* PDPC code - unreviewed +char *strcpy(char *s1, const char *s2) +{ + char *p = s1; + + while ((*p++ = *s2++) != '\0') ; + return (s1); +} +*/ \ No newline at end of file diff --git a/functions/string/strcspn.c b/functions/string/strcspn.c index 80c620c..c2db7ab 100644 --- a/functions/string/strcspn.c +++ b/functions/string/strcspn.c @@ -6,3 +6,23 @@ // ---------------------------------------------------------------------------- size_t strcspn( const char * s1, const char * s2 ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const char *p1; + const char *p2; + + p1 = s1; + while (*p1 != '\0') + { + p2 = s2; + while (*p2 != '\0') + { + if (*p1 == *p2) return ((size_t)(p1 - s1)); + p2++; + } + p1++; + } + return ((size_t)(p1 - s1)); +} +*/ diff --git a/functions/string/strerror.c b/functions/string/strerror.c index 48dba0d..2526714 100644 --- a/functions/string/strerror.c +++ b/functions/string/strerror.c @@ -6,3 +6,10 @@ // ---------------------------------------------------------------------------- char * strerror( int errcode ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + if (errnum == 0) return ("No error has occurred\n"); + else return ("An error has occurred\n"); +} +*/ diff --git a/functions/string/strlen.c b/functions/string/strlen.c index 62ab7a1..9dfc38f 100644 --- a/functions/string/strlen.c +++ b/functions/string/strlen.c @@ -6,3 +6,24 @@ // ---------------------------------------------------------------------------- size_t strlen( const char * s ) { /* TODO */ }; + +/* Therx code +{ + const char * start = s1; + while (*s1) + { + s1++; + } + return s1 - start; +} +*/ + +/* PDPC code - unreviewed +{ + const char *p; + + p = s; + while (*p != '\0') p++; + return ((size_t)(p - s)); +} +*/ diff --git a/functions/string/strncat.c b/functions/string/strncat.c index 624ac03..1bc2023 100644 --- a/functions/string/strncat.c +++ b/functions/string/strncat.c @@ -6,3 +6,21 @@ // ---------------------------------------------------------------------------- char * strncat( char * restrict s1, const char * restrict s2, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + char *p = s1; + size_t x = 0; + + while (*p != '\0') p++; + while ((*s2 != '\0') && (x < n)) + { + *p = *s2; + p++; + s2++; + x++; + } + *p = '\0'; + return (s1); +} +*/ diff --git a/functions/string/strncmp.c b/functions/string/strncmp.c index d0434a5..ec9c56f 100644 --- a/functions/string/strncmp.c +++ b/functions/string/strncmp.c @@ -6,3 +6,22 @@ // ---------------------------------------------------------------------------- int strncmp( const char * s1, const char * s2, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const unsigned char *p1; + const unsigned char *p2; + size_t x = 0; + + p1 = (const unsigned char *)s1; + p2 = (const unsigned char *)s2; + while (x < n) + { + if (p1[x] < p2[x]) return (-1); + else if (p1[x] > p2[x]) return (1); + else if (p1[x] == '\0') return (0); + x++; + } + return (0); +} +*/ diff --git a/functions/string/strncpy.c b/functions/string/strncpy.c index 2d865d7..fd6e5d2 100644 --- a/functions/string/strncpy.c +++ b/functions/string/strncpy.c @@ -6,3 +6,24 @@ // ---------------------------------------------------------------------------- char * strncpy( char * restrict s1, const char * restrict s2, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +char *strncpy(char *s1, const char *s2, size_t n) +{ + char *p = s1; + size_t x; + + for (x=0; x < n; x++) + { + *p = *s2; + if (*s2 == '\0') break; + p++; + s2++; + } + for (; x < n; x++) + { + *p++ = '\0'; + } + return (s1); +} +*/ \ No newline at end of file diff --git a/functions/string/strpbrk.c b/functions/string/strpbrk.c index 78e2d65..810e40c 100644 --- a/functions/string/strpbrk.c +++ b/functions/string/strpbrk.c @@ -15,3 +15,23 @@ char * strpbrk( char * s1, const char * s2 ) { /* TODO */ }; // Standard C char * strpbrk( const char *s1, const char * s2 ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const char *p1; + const char *p2; + + p1 = s1; + while (*p1 != '\0') + { + p2 = s2; + while (*p2 != '\0') + { + if (*p1 == *p2) return ((char *)p1); + p2++; + } + p1++; + } + return (NULL); +} +*/ diff --git a/functions/string/strrchr.c b/functions/string/strrchr.c index 4249de3..7750443 100644 --- a/functions/string/strrchr.c +++ b/functions/string/strrchr.c @@ -15,3 +15,17 @@ char * strrchr( char * s, int c ) { /* TODO */ }; // Standard C char * strrchr( const char * s, int c ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const char *p; + + p = s + strlen(s); + while (p >= s) + { + if (*p == (char)c) return ((char *)p); + p--; + } + return (NULL); +} +*/ diff --git a/functions/string/strspn.c b/functions/string/strspn.c index 47b2861..6b0e586 100644 --- a/functions/string/strspn.c +++ b/functions/string/strspn.c @@ -6,3 +6,24 @@ // ---------------------------------------------------------------------------- size_t strspn( const char * s1, const char * s2 ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const char *p1; + const char *p2; + + p1 = s1; + while (*p1 != '\0') + { + p2 = s2; + while (*p2 != '\0') + { + if (*p1 == *p2) break; + p2++; + } + if (*p2 == '\0') return ((size_t)(p1 - s1)); + p1++; + } + return ((size_t)(p1 - s1)); +} +*/ diff --git a/functions/string/strstr.c b/functions/string/strstr.c index b249423..a1f8b74 100644 --- a/functions/string/strstr.c +++ b/functions/string/strstr.c @@ -15,3 +15,25 @@ char * strstr( char * s1, const char * s2 ) { /* TODO */ }; // Standard C char * strstr( const char * s1, const char * s2 ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + const char *p = s1, *p1, *p2 = s2; + + while (*p) + { + if (*p == *s2) + { + p1 = p; + p2 = s2; + while ((*p2 != '\0') && (*p1++ == *p2++)) ; + if (*p2 == '\0') + { + return (char *)p; + } + } + p++; + } + return NULL; +} +*/ diff --git a/functions/string/strtok.c b/functions/string/strtok.c index 1e588e8..1828f39 100644 --- a/functions/string/strtok.c +++ b/functions/string/strtok.c @@ -6,3 +6,26 @@ // ---------------------------------------------------------------------------- char * strtok( char * restrict s1, const char * restrict s2 ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + static char *old = NULL; + char *p; + size_t len; + size_t remain; + + if (s1 != NULL) old = s1; + if (old == NULL) return (NULL); + p = old; + len = strspn(p, s2); + remain = strlen(p); + if (remain <= len) { old = NULL; return (NULL); } + p += len; + len = strcspn(p, s2); + remain = strlen(p); + if (remain <= len) { old = NULL; return (p); } + *(p + len) = '\0'; + old = p + len + 1; + return (p); +} +*/ diff --git a/functions/string/strxfrm.c b/functions/string/strxfrm.c index 6f8a59e..96c29e1 100644 --- a/functions/string/strxfrm.c +++ b/functions/string/strxfrm.c @@ -6,3 +6,17 @@ // ---------------------------------------------------------------------------- size_t strxfrm( char * restrict s1, const char * restrict s2, size_t n ) { /* TODO */ }; + +/* PDPC code - unreviewed +{ + size_t oldlen; + + oldlen = strlen(s2); + if (oldlen < n) + { + memcpy(s1, s2, oldlen); + s1[oldlen] = '\0'; + } + return (oldlen); +} +*/ diff --git a/functions/time.c b/functions/time.c index 997e062..7da9c4b 100644 --- a/functions/time.c +++ b/functions/time.c @@ -15,3 +15,525 @@ time_t mktime( struct tm * tptr ) { /* TODO */ }; size_t strftime( char * restrict s, size_t n, const char * restrict format, const struct tm * restrict tptr ) { /* TODO */ }; time_t time( time_t * tod ) { /* TODO */ }; + +/* PDPC code - unreviewed, verbatim +/* scalar date routines -- public domain by Ray Gardner +** These will work over the range 1-01-01 thru 14699-12-31 +** The functions written by Ray are isleap, months_to_days, +** years_to_days, ymd_to_scalar, scalar_to_ymd. +** modified slightly by Paul Edwards +*/ + +static int isleap(unsigned yr) +{ + return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0); +} + +static unsigned months_to_days(unsigned month) +{ + return (month * 3057 - 3007) / 100; +} + +static long years_to_days (unsigned yr) +{ + return yr * 365L + yr / 4 - yr / 100 + yr / 400; +} + +static long ymd_to_scalar(unsigned yr, unsigned mo, unsigned day) +{ + long scalar; + + scalar = day + months_to_days(mo); + if ( mo > 2 ) /* adjust if past February */ + scalar -= isleap(yr) ? 1 : 2; + yr--; + scalar += years_to_days(yr); + return (scalar); +} + +static void scalar_to_ymd(long scalar, + unsigned *pyr, + unsigned *pmo, + unsigned *pday) +{ + unsigned n; /* compute inverse of years_to_days() */ + + n = (unsigned)((scalar * 400L) / 146097L); + while (years_to_days(n) < scalar) + { + n++; + } + for ( n = (unsigned)((scalar * 400L) / 146097L); years_to_days(n) < scalar; ) + n++; /* 146097 == years_to_days(400) */ + *pyr = n; + n = (unsigned)(scalar - years_to_days(n-1)); + if ( n > 59 ) { /* adjust if past February */ + n += 2; + if ( isleap(*pyr) ) + n -= n > 62 ? 1 : 2; + } + *pmo = (n * 100 + 3007) / 3057; /* inverse of months_to_days() */ + *pday = n - months_to_days(*pmo); + return; +} + +time_t time(time_t *timer) +{ + time_t tt; +#ifdef __OS2__ + DATETIME dt; + APIRET rc; +#endif +#if (defined(__MSDOS__) || defined(__MVS__)) + struct { + int year; + int month; + int day; + int hours; + int minutes; + int seconds; + int hundredths; + } dt; +#endif +#ifdef __MVS__ + unsigned int clk[2]; +#endif + +#ifdef __OS2__ + rc = DosGetDateTime(&dt); + if (rc != 0) + { + tt = (time_t)-1; + } + else +#endif +#ifdef __MSDOS__ + __datetime(&dt); +#endif +#ifdef __MVS__ + tt = __getclk(clk); +#else + + { + tt = ymd_to_scalar(dt.year, dt.month, dt.day) + - ymd_to_scalar(1970, 1, 1); + tt = tt * 24 + dt.hours; + tt = tt * 60 + dt.minutes; + tt = tt * 60 + dt.seconds; + } +#endif + if (timer != NULL) + { + *timer = tt; + } + return (tt); +} + +clock_t clock(void) +{ + return ((clock_t)-1); +} + +double difftime(time_t time1, time_t time0) +{ + return ((double)(time1 - time0)); +} + +time_t mktime(struct tm *timeptr) +{ + time_t tt; + + if ((timeptr->tm_year < 70) || (timeptr->tm_year > 120)) + { + tt = (time_t)-1; + } + else + { + tt = ymd_to_scalar(timeptr->tm_year + 1900, + timeptr->tm_mon, + timeptr->tm_mday) + - ymd_to_scalar(1970, 1, 1); + tt = tt * 24 + timeptr->tm_hour; + tt = tt * 60 + timeptr->tm_min; + tt = tt * 60 + timeptr->tm_sec; + } + return (tt); +} + +char *asctime(const struct tm *timeptr) +{ + static const char wday_name[7][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char mon_name[12][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + static char result[26]; + + sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", + wday_name[timeptr->tm_wday], + mon_name[timeptr->tm_mon], + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec, + 1900 + timeptr->tm_year); + return result; +} + +char *ctime(const time_t *timer) +{ + return (asctime(localtime(timer))); +} + +struct tm *gmtime(const time_t *timer) +{ + return (localtime(timer)); +} + +/* dow - written by Paul Edwards, 1993-01-31 */ +/* Released to the Public Domain */ +/* This routine will work over the range 1-01-01 to 32767-12-31. + It assumes the current calendar system has always been in + place in that time. If you pass 0 or negative years, then + it produces results on the assumption that there is a year + 0. It should always produce a value in the range of 0..6 + if a valid month and day have been passed, no matter what + the year is. However, it has not been tested for negative + years, because the results are meaningless anyway. It is + mainly to stop people playing silly buggers and causing + the macro to crash on negative years. */ + +/* Modified 1994-08-26 by Paul Edwards to make it return + 0..6 for Sunday..Saturday instead of Monday..Sunday */ +/* change the "(d) + 1" to "(d) + 0" to get it back to Monday + to Sunday if you want */ + +#define dow(y,m,d) \ + ((((((m)+9)%12+1)<<4)%27 + (d) + 1 + \ + ((y)%400+400) + ((y)%400+400)/4 - ((y)%400+400)/100 + \ + (((m)<=2) ? ( \ + (((((y)%4)==0) && (((y)%100)!=0)) || (((y)%400)==0)) \ + ? 5 : 6) : 0)) % 7) + +static struct tm tms; + +struct tm *localtime(const time_t *timer) +{ + unsigned yr, mo, da; + unsigned long secs; + unsigned long days; + + days = *timer / (60L*60*24); + secs = *timer % (60L*60*24); + scalar_to_ymd(days + ymd_to_scalar(1970, 1, 1), &yr, &mo, &da); + tms.tm_year = yr - 1900; + tms.tm_mon = mo - 1; + tms.tm_mday = da; + tms.tm_yday = (int)(ymd_to_scalar(tms.tm_year + 1900, 1, 1) + - ymd_to_scalar(tms.tm_year + 1900, mo, da)); + tms.tm_wday = dow(tms.tm_year + 1900, mo, da); + tms.tm_isdst = -1; + tms.tm_sec = (int)(secs % 60); + secs /= 60; + tms.tm_min = (int)(secs % 60); + secs /= 60; + tms.tm_hour = (int)secs; + return (&tms); +} + +/* + * strftime.c + * + * implements the iso c function strftime() + * + * written 1989-09-06 by jim nutt + * released into the public domain by jim nutt + * + * modified 1989-10-21 by Rob Duff + * + * modified 1994-08-26 by Paul Edwards + */ + +static char *aday[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +static char *day[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +}; + +static char *amonth[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +static char *month[] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; + +static char *__tzname[2] = { "" "" }; +static char buf[26]; + +static void strfmt(char *str, const char *fmt, ...); + +/** + * + * size_t strftime(char *str, + * size_t maxs, + * const char *fmt, + * const struct tm *t) + * + * this functions acts much like a sprintf for time/date output. + * given a pointer to an output buffer, a format string and a + * time, it copies the time to the output buffer formatted in + * accordance with the format string. the parameters are used + * as follows: + * + * str is a pointer to the output buffer, there should + * be at least maxs characters available at the address + * pointed to by str. + * + * maxs is the maximum number of characters to be copied + * into the output buffer, included the '\0' terminator + * + * fmt is the format string. a percent sign (%) is used + * to indicate that the following character is a special + * format character. the following are valid format + * characters: + * + * %A full weekday name (Monday) + * %a abbreviated weekday name (Mon) + * %B full month name (January) + * %b abbreviated month name (Jan) + * %c standard date and time representation + * %d day-of-month (01-31) + * %H hour (24 hour clock) (00-23) + * %I hour (12 hour clock) (01-12) + * %j day-of-year (001-366) + * %M minute (00-59) + * %m month (01-12) + * %p local equivalent of AM or PM + * %S second (00-59) + * %U week-of-year, first day sunday (00-53) + * %W week-of-year, first day monday (00-53) + * %w weekday (0-6, sunday is 0) + * %X standard time representation + * %x standard date representation + * %Y year with century + * %y year without century (00-99) + * %Z timezone name + * %% percent sign + * + * the standard date string is equivalent to: + * + * %a %b %d %Y + * + * the standard time string is equivalent to: + * + * %H:%M:%S + * + * the standard date and time string is equivalent to: + * + * %a %b %d %H:%M:%S %Y + * + * strftime returns the number of characters placed in the + * buffer, not including the terminating \0, or zero if more + * than maxs characters were produced. + * +**/ + +size_t strftime(char *s, size_t maxs, const char *f, const struct tm *t) +{ + int w; + char *p, *q, *r; + + p = s; + q = s + maxs - 1; + while ((*f != '\0')) + { + if (*f++ == '%') + { + r = buf; + switch (*f++) + { + case '%' : + r = "%"; + break; + + case 'a' : + r = aday[t->tm_wday]; + break; + + case 'A' : + r = day[t->tm_wday]; + break; + + case 'b' : + r = amonth[t->tm_mon]; + break; + + case 'B' : + r = month[t->tm_mon]; + break; + + case 'c' : + strfmt(r, "%0 %0 %2 %2:%2:%2 %4", + aday[t->tm_wday], amonth[t->tm_mon], + t->tm_mday,t->tm_hour, t->tm_min, + t->tm_sec, t->tm_year+1900); + break; + + case 'd' : + strfmt(r,"%2",t->tm_mday); + break; + + case 'H' : + strfmt(r,"%2",t->tm_hour); + break; + + case 'I' : + strfmt(r,"%2",(t->tm_hour%12)?t->tm_hour%12:12); + break; + + case 'j' : + strfmt(r,"%3",t->tm_yday+1); + break; + + case 'm' : + strfmt(r,"%2",t->tm_mon+1); + break; + + case 'M' : + strfmt(r,"%2",t->tm_min); + break; + + case 'p' : + r = (t->tm_hour>11)?"PM":"AM"; + break; + + case 'S' : + strfmt(r,"%2",t->tm_sec); + break; + + case 'U' : + w = t->tm_yday/7; + if (t->tm_yday%7 > t->tm_wday) + w++; + strfmt(r, "%2", w); + break; + + case 'W' : + w = t->tm_yday/7; + if (t->tm_yday%7 > (t->tm_wday+6)%7) + w++; + strfmt(r, "%2", w); + break; + + case 'w' : + strfmt(r,"%1",t->tm_wday); + break; + + case 'x' : + strfmt(r, "%3s %3s %2 %4", aday[t->tm_wday], + amonth[t->tm_mon], t->tm_mday, t->tm_year+1900); + break; + + case 'X' : + strfmt(r, "%2:%2:%2", t->tm_hour, + t->tm_min, t->tm_sec); + break; + + case 'y' : + strfmt(r,"%2",t->tm_year%100); + break; + + case 'Y' : + strfmt(r,"%4",t->tm_year+1900); + break; + + case 'Z' : + r = (t->tm_isdst) ? __tzname[1] : __tzname[0]; + break; + + default: + buf[0] = '%'; /* reconstruct the format */ + buf[1] = f[-1]; + buf[2] = '\0'; + if (buf[1] == 0) + f--; /* back up if at end of string */ + } + while (*r) + { + if (p == q) + { + *q = '\0'; + return 0; + } + *p++ = *r++; + } + } + else + { + if (p == q) + { + *q = '\0'; + return 0; + } + *p++ = f[-1]; + } + } + *p = '\0'; + return (size_t)(p - s); +} + +static int pow[5] = { 1, 10, 100, 1000, 10000 }; + +/** + * static void strfmt(char *str, char *fmt); + * + * simple sprintf for strftime + * + * each format descriptor is of the form %n + * where n goes from zero to four + * + * 0 -- string %s + * 1..4 -- int %?.?d + * +**/ + +static void strfmt(char *str, const char *fmt, ...) +{ + int ival, ilen; + char *sval; + va_list vp; + + va_start(vp, fmt); + while (*fmt) + { + if (*fmt++ == '%') + { + ilen = *fmt++ - '0'; + if (ilen == 0) /* zero means string arg */ + { + sval = va_arg(vp, char*); + while (*sval) + *str++ = *sval++; + } + else /* always leading zeros */ + { + ival = va_arg(vp, int); + while (ilen) + { + ival %= pow[ilen--]; + *str++ = (char)('0' + ival / pow[ilen]); + } + } + } + else *str++ = fmt[-1]; + } + *str = '\0'; + va_end(vp); +} +*/ \ No newline at end of file -- 2.40.0