Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!lll-lcc!lll-winken!uunet!munnari!gwydir!gara!wtoomey From: wtoomey@gara.une.oz (Warren Toomey) Newsgroups: comp.os.minix Subject: Official Patch #1 to Clam (3 of 5) Message-ID: <613@gara.une.oz> Date: 27 Mar 89 04:28:29 GMT Organization: University of New England, Armidale, Australia Lines: 1100 # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # idoprint.c iscanf.c echo x - idoprint.c cat > "idoprint.c" << '//E*O*F idoprint.c//' #ifdef __RCS_ID__ static char rcsid[] = "$Header: /u5/mnx/gnu/lib/RCS/doprintf.c,v 1.6 89/03/04 04:16:09 bammi Exp $"; #endif /* __RCS_ID__ */ /* * Log and Header added (03/03/89) * * $Log: doprintf.c,v $ * Revision 1.6 89/03/04 04:16:09 bammi * Fourth release of Gcc Gnulib for MinixST (03/03/89) * */ #include /* * three compile time options: * STACKUP fetch arguments using *p-- instead of *p++ * NO_LONGD %d and %ld/%D are equal * NO_FLOAT abort on %e, %f and %g */ #ifndef __GNUC__ /* __GNUC__ handles doubles all right */ #define NO_FLOAT #else #ifdef __INT_PRINTF__ /* we want an integer only doprintf() in gnu */ #define NO_FLOAT #endif #endif #ifdef NO_FLOAT #define MAXDIG 11 /* 32 bits in radix 8 */ #else #define MAXDIG 128 /* this must be enough */ #endif static char * _itoa(p, num, radix) register char *p; register unsigned num; register radix; { register i; register char *q; q = p + MAXDIG; do { i = (int)(num % radix); i += '0'; if (i > '9') i += 'A' - '0' - 10; *--q = i; } while (num = num / radix); /* bug bug buggy code i = p + MAXDIG - q; */ i = (int)(p - q) + MAXDIG; do *p++ = *q++; while (--i); return(p); } #ifndef NO_LONGD static char * _ltoa(p, num, radix) register char *p; register unsigned long num; register radix; { register i; register char *q; q = p + MAXDIG; do { i = (int)(num % radix); i += '0'; if (i > '9') i += 'A' - '0' - 10; *--q = i; } while (num = num / radix); i = (int)(p - q) + MAXDIG; do *p++ = *q++; while (--i); return(p); } #endif #ifndef NO_FLOAT #ifndef __GNUC__ extern char *_ecvt(); extern char *_fcvt(); extern char *_gcvt(); #else /* * deal with floating point formatting * ++jrb bammi@dsrgsun.ces.cwru.edu * * code below does not deal with rounding off digit at precision * and is probably not as precise as some would want, but its * good enough for rock & roll. * * 12/10/88 added rounding ++jrb * 02/01/89 corrected buggy rounding code ++jrb * */ #define MAXWIDTH 30 /* chosen arb. */ typedef enum { EFORMAT, FFORMAT, GFORMAT } FORMAT_TYPE; #ifdef __STDC__ static void _flofmt(char *, double, double, int); char *itoa(int); #else static void _flofmt(); extern char *itoa(); #endif /* return 5.0E-p */ static double _fleast(p) register int p; { double least = 5.0; while(--p >= 0) least /= 10.0; return least; } /* #define KLUDGEDIV no longer needed */ static char *_cvt(buf, val, precision, fmt) char *buf; double val; int precision; FORMAT_TYPE fmt; { char mybuf[MAXWIDTH+1]; int pow; int sign; double least; #ifdef KLUDGEDIV long l; int i; #endif #ifndef __STDC__ extern double _fleast(); #else double _fleast(int); #endif #ifdef DDD printf("_cvt called\n"); #endif /* make val +ve record sign */ if(val < 0) { sign = 1; val = -val; } else sign = 0; /* round it off at precision -- add 5.0E-(precision+1) */ least = _fleast(precision+1); if(least > val) { least = 0.0; precision = MAXWIDTH; } else val += least; #ifdef DDD printf("sign %d\n", sign); #endif /* convert val to 0.nnn form -- record pow */ pow = 0; while(val >= 1.0) { val /= 10.0; pow++; } #ifdef DDD puts("pow determined\n"); printf("pow %d precision+pow %d\n", pow, precision+pow); #endif if((precision + pow) > MAXWIDTH) precision -= ((precision + pow) - MAXWIDTH); _flofmt(mybuf, val, least, precision+pow); #ifdef DDD printf("back from flofmt mybuf :%s:\n", mybuf); #endif switch(fmt) { case EFORMAT: efmt: { register char *p = mybuf, *q = buf; if(sign) *q++ = '-'; while((*p != '\0') && (*p == '0')) { pow -= 1; p++; } if(*p == '\0') { while(precision-- > 0) *q++ = '0'; *q = '\0'; return q; } pow -= 1; *q++ = *p++; *q++ = '.'; if(*p == '\0') *q++ = '0'; while(*p != '\0') *q++ = *p++; *q++ = 'e'; if(pow >= 0) *q++ = '+'; else { *q++ = '-'; pow = -pow; } if(pow < 10) *q++ = '0'; p = itoa(pow); while(*p != '\0') *q++ = *p++; *q = '\0'; return q; } case FFORMAT: ffmt: { register char *p = mybuf, *q = buf; if(sign) *q++ = '-'; while(pow-- > 0) *q++ = *p++; if(*p != '\0') { *q++ = '.'; while(*p != '\0') *q++ = *p++; } *q = '\0'; return q; } case GFORMAT: { register int leading = 0; register char *p = mybuf; while(*p != '\0') if (*p++ == '0') leading++; /* anyone have a good heuristic to decide between F and E */ /* formats ??? */ if((leading > 6) || (precision > 6) || ((pow+precision) > 10)) goto efmt; goto ffmt; } } } /* the formatter for flona -- basic body from pfgutc.c Tos Gcc lib */ static void _flofmt(buf, val, least, precision) char * buf; double val, least; int precision; { long int_part; int i, ndigits; char digit[MAXWIDTH+2]; #ifdef DDD printf("\t_flofmt\n"); #endif for (i = 0 ; i < MAXWIDTH ; i++) digit[i] = 0; for (i = 0, ndigits = 0 ; ((val > least) && (ndigits < precision) && (i < MAXWIDTH)); i++) { val = val * 10.0; int_part = val; val = val - int_part; digit[i] = int_part; /* kludge till we get doubles accurate... */ /* -- probably not needed now */ if ((digit[i] > 9) || (digit[i] < 0)) digit[i] = 0; if (int_part > 0) ndigits = i + 1; } #ifdef DDD printf("\t_loop done ndigits %d precision %d\n", ndigits, precision); #endif if(ndigits < precision) ndigits = precision; /* we have already zero'ed the rest */ if (ndigits > 0) /* were there any? */ { for (i = 0 ; i < ndigits ; i++) { *buf++ = digit[i] + '0'; } } *buf = '\0'; } #endif /* __GNUC__ */ #endif /* NO_FLOAT */ #ifdef STACKUP #define GETARG(typ) *((typ *)args)-- #else #define GETARG(typ) *((typ *)args)++ #endif STACKUP #ifndef TEST int _doprintf(iop, fmt, args) #else int __Ddoprintf(iop, fmt, args) #endif FILE *iop; register char *fmt; register int *args; { char buf[MAXDIG+1]; /* +1 for sign */ register char *p; register char *s; register c; register i; register short width; register short ndigit; register ndfnd; register ljust; register zfill; #ifndef NO_LONGD register lflag; register long l; #endif register int n_written = 0; for (;;) { c = *fmt++; if (c == 0) return n_written; if (c != '%') { if(putc(c, iop) == EOF) return EOF; else n_written++; continue; } p = buf; s = buf; ljust = 0; if (*fmt == '-') { fmt++; ljust++; } zfill = ' '; if (*fmt == '0') { fmt++; zfill = '0'; } for (width = 0;;) { c = *fmt++; if (c >= '0' && c <= '9') c -= '0'; else if (c == '*') c = GETARG(int); else break; width *= 10; width += c; } ndfnd = 0; ndigit = 0; if (c == '.') { for (;;) { c = *fmt++; if (c >= '0' && c <= '9') c -= '0'; else if (c == '*') c = GETARG(int); else break; ndigit *= 10; ndigit += c; ndfnd++; } } #ifndef NO_LONGD lflag = 0; #endif if (c == 'l' || c == 'L') { #ifndef NO_LONGD lflag++; #endif if (*fmt) c = *fmt++; } switch (c) { case 'X': #ifndef NO_LONGD lflag++; #endif case 'x': c = 16; goto oxu; case 'U': #ifndef NO_LONGD lflag++; #endif case 'u': c = 10; goto oxu; case 'O': #ifndef NO_LONGD lflag++; #endif case 'o': c = 8; oxu: #ifndef NO_LONGD if (lflag) { p = _ltoa(p, GETARG(long), c); break; } #endif p = _itoa(p, GETARG(int), c); break; case 'D': #ifndef NO_LONGD lflag++; #endif case 'd': #ifndef NO_LONGD if (lflag) { if ((l = GETARG(long)) < 0) { *p++ = '-'; l = -l; } p = _ltoa(p, l, 10); break; } #endif if ((i = GETARG(int)) < 0) { *p++ = '-'; i = -i; } p = _itoa(p, i, 10); break; #ifdef NO_FLOAT case 'e': case 'f': case 'g': zfill = ' '; *p++ = '?'; break; #else #ifdef __GNUC__ #ifndef __INT_PRINTF__ case 'e': if (ndfnd == 0) ndigit = 6; ndigit++; p = _cvt(p, (double)GETARG(double), ndigit, EFORMAT); break; case 'f': if (ndfnd == 0) ndigit = 6; p = _cvt(p, (double)GETARG(double), ndigit, FFORMAT); break; case 'g': if (ndfnd == 0) ndigit = 6; p = _cvt(p, (double)GETARG(double), ndigit, GFORMAT); break; #endif /* __INT_PRINTF__ */ #else case 'e': if (ndfnd == 0) ndigit = 6; ndigit++; p = _ecvt(p, GETARG(double), ndigit); break; case 'f': if (ndfnd == 0) ndigit = 6; p = _fcvt(p, GETARG(double), ndigit); break; case 'g': if (ndfnd == 0) ndigit = 6; p = _gcvt(p, GETARG(double), ndigit); break; #endif /* __GNUC__ */ #endif /* NO_FLOAT */ case 'c': zfill = ' '; *p++ = GETARG(int); break; case 's': zfill = ' '; if ((s = GETARG(char *)) == 0) s = "(null)"; if (ndigit == 0) ndigit = 32767; for (p = s; *p && --ndigit >= 0; p++) ; break; default: *p++ = c; break; } i = p - s; if ((width -= i) < 0) width = 0; if (ljust == 0) width = -width; if (width < 0) { if (*s == '-' && zfill == '0') { if(putc(*s++, iop) == EOF) return EOF; else n_written++; i--; } do if(putc(zfill, iop) == EOF) return EOF; else n_written++; while (++width != 0); } while (--i >= 0) if(putc(*s++, iop) == EOF) return EOF; else n_written++; while (width) { if(putc(zfill, iop) == EOF) return EOF; else n_written++; width--; } } return n_written; } #ifdef TEST char b[128]; main() { extern long rand(); int i, prec; double val = 10.624624624624; for(i = 1; i < 11; i++) { _cvt(b, val, i, FFORMAT); printf("%f %2d %s (%.*f)\n", val, i, b, i, val); } } #ifndef ATARI_ST char *itoa(i) int i; { static char x[32]; sprintf(x, "%d", i); return x; } #endif #endif //E*O*F idoprint.c// echo x - iscanf.c cat > "iscanf.c" << '//E*O*F iscanf.c//' #ifdef __RCS_ID__ static char rcsid[] = "$Header: /u5/mnx/gnu/lib/RCS/scanf.c,v 1.5 89/03/04 04:19:25 bammi Exp $"; #endif /* __RCS_ID__ */ /* * Log and Header added (03/03/89) * * $Log: scanf.c,v $ * Revision 1.5 89/03/04 04:19:25 bammi * Fourth release of Gcc Gnulib for MinixST (03/03/89) * */ /* scanf - formatted input conversion Author: Patrick van Kleef */ #define __SRC__ /* * - added %f,%e,%g * - [scanset] implementation wrote into format string, which is * obviously a no-no. Changed that real quick. * - added [0-9] style scansets * ++jrb bammi@dsrgsun.ces.cwru.edu * * 12/10/88 minor bugfix to accept floating #'s of the for .nnnn * ++jrb */ #include int scanf (format, args) CONST char *format; #ifdef __GNUC__ unsigned long args; #else unsigned args; #endif { return _doscanf (0, stdin, format, &args); } int fscanf (fp, format, args) FILE *fp; CONST char *format; #ifdef __GNUC__ unsigned long args; #else unsigned args; #endif { return _doscanf (0, fp, format, &args); } int sscanf (string, format, args) CONST char *string; /* source of data */ CONST char *format; /* control string */ #ifdef __GNUC__ unsigned long args; #else unsigned args; #endif { return _doscanf (1, string, format, &args); } union ptr_union { char *chr_p; unsigned int *uint_p; unsigned long *ulong_p; #ifndef __INT_SCANF__ float *float_p; double *double_p; #endif }; static int ic; /* the current character */ static char *rnc_arg; /* the string or the filepointer */ static rnc_code; /* 1 = read from string, else from FILE */ /* get the next character */ static void rnc () { if (rnc_code) { if (!(ic = *rnc_arg++)) ic = EOF; } else ic = getc ((FILE *) rnc_arg); } /* * unget the current character */ static void ugc () { if (rnc_code) --rnc_arg; else ungetc (ic, (FILE *)rnc_arg); } /* [01234] style scanset */ static int scn1index(ch, string, endmarker) char ch; char *string, *endmarker; { while (*string++ != ch) if (string >= endmarker) return 0; return 1; } static int scnindex(ch, string, endmarker) char ch; char *string, *endmarker; { if(((endmarker - string) == 3) && (string[1] == '-')) /* [0-9] style scanset */ return ((string[0] <= ch) && (ch <= string[2])); else return scn1index(ch, string, endmarker); } /* * this is cheaper than iswhite from */ static int iswhite (ch) int ch; { return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); } static int isdigit (ch) int ch; { return (ch >= '0' && ch <= '9'); } static int __tolower (ch) int ch; { if (ch >= 'A' && ch <= 'Z') ch = ch + 'a' - 'A'; return ch; } #ifndef __INT_SCANF__ #ifdef __GNUC__ /* eval f * 10**p */ static double _fraise(f, p) double f; int p; { if(p > 0) while(p--) f *= 10.0; else while(p++) f /= 10.0; return f; } #endif #endif /* * the routine that does the job */ int _doscanf (code, funcarg, format, argp) int code; /* function to get a character */ char *funcarg; /* an argument for the function */ char *format; /* the format control string */ union ptr_union *argp; /* our argument list */ { int done = 0; /* number of items done */ int base; /* conversion base */ long val; /* an integer value */ int sign; /* sign flag */ int do_assign; /* assignment suppression flag */ unsigned width; /* width of field */ int widflag; /* width was specified */ int longflag; /* true if long */ int done_some; /* true if we have seen some data */ int reverse; /* reverse the checking in [...] */ char *endbracket; /* position of the ] in format string */ #ifndef __INT_SCANF__ #ifdef __GNUC__ double fval; /* a double value */ #endif #endif rnc_arg = funcarg; rnc_code = code; rnc (); /* read the next character */ if (ic == EOF) { done = EOF; goto quit; } while (1) { while (iswhite (*format)) ++format; /* skip whitespace */ if (!*format) goto all_done; /* end of format */ if (ic < 0) goto quit; /* seen an error */ if (*format != '%') { while (iswhite (ic)) rnc (); if (ic != *format) goto all_done; ++format; rnc (); ++done; continue; } ++format; do_assign = 1; if (*format == '*') { ++format; do_assign = 0; } if (isdigit (*format)) { widflag = 1; for (width = 0; isdigit (*format);) width = width * 10 + *format++ - '0'; } else widflag = 0; /* no width spec */ if (longflag = (__tolower (*format) == 'l')) ++format; if (*format != 'c') while (iswhite (ic)) rnc (); done_some = 0; /* nothing yet */ switch (*format) { case 'o': base = 8; goto decimal; case 'u': case 'd': base = 10; goto decimal; case 'x': base = 16; if (((!widflag) || width >= 2) && ic == '0') { rnc (); if (__tolower (ic) == 'x') { width -= 2; done_some = 1; rnc (); } else { ugc (); ic = '0'; } } decimal: val = 0L; /* our result value */ sign = 0; /* assume positive */ if (!widflag) width = 0xffff; /* very wide */ if (width && ic == '+') rnc (); else if (width && ic == '-') { sign = 1; rnc (); } while (width--) { if (isdigit (ic) && ic - '0' < base) ic -= '0'; else if (base == 16 && __tolower (ic) >= 'a' && __tolower (ic) <= 'f') ic = 10 + __tolower (ic) - 'a'; else break; val = val * base + ic; rnc (); done_some = 1; } if (do_assign) { if (sign) val = -val; if (longflag) *(argp++)->ulong_p = (unsigned long) val; else *(argp++)->uint_p = (unsigned) val; } if (done_some) ++done; else goto all_done; break; case 'c': if (!widflag) width = 1; while (width-- && ic >= 0) { if (do_assign) *(argp)->chr_p++ = (char) ic; rnc (); done_some = 1; } if (do_assign) argp++; /* done with this one */ if (done_some) ++done; break; case 's': if (!widflag) width = 0xffff; while (width-- && !iswhite (ic) && ic > 0) { if (do_assign) *(argp)->chr_p++ = (char) ic; rnc (); done_some = 1; } if (do_assign) /* terminate the string */ *(argp++)->chr_p = '\0'; if (done_some) ++done; else goto all_done; break; #ifndef __INT_SCANF__ #ifdef __GNUC__ case 'e': case 'f': case 'g': fval = 0.0; /* our result value */ sign = 0; /* assume positive */ if (!widflag) width = 0xffff; /* very wide */ if (width && ic == '+') rnc (); else if (width && ic == '-') { sign = 1; rnc (); } while (width && isdigit(ic)) { width--; fval = fval * 10.0 + (ic - '0'); rnc (); done_some = 1; } if(ic == '.') { double factor = 1.0/10.0; rnc (); while (--width && isdigit(ic)) { fval = fval + ((ic - '0') * factor); factor = factor/10.0; done_some = 1; rnc(); } } if(sign) fval = -fval; sign = 0; if(((ic == 'E') || (ic == 'e')) && done_some) { int pow = 0; rnc (); if((ic == '+') || (ic == '-')) { if(ic == '-') sign = 1; width--; rnc(); } while(--width && isdigit(ic)) { pow = pow * 10 + (ic -'0'); rnc(); } fval = _fraise(fval, (sign == 1)? -pow : pow); } if (do_assign) { if (longflag) *(argp++)->double_p = fval; else *(argp++)->float_p = (float) fval; } if (done_some) ++done; else goto all_done; break; #endif /* __GNUC__ */ #endif /* __INT_SCANF__ */ case '[': if (!widflag) width = 0xffff; if ( *(++format) == '^' ) { reverse = 1; format++; } else reverse = 0; endbracket = format; while ( *endbracket != ']' && *endbracket != '\0') endbracket++; if (!*endbracket) goto quit; while (width-- && !iswhite (ic) && ic > 0 && (scnindex(ic, format, endbracket) ^ reverse)) { if (do_assign) *(argp)->chr_p++ = (char) ic; rnc (); done_some = 1; } if (do_assign) /* terminate the string */ *(argp++)->chr_p = '\0'; if (done_some) ++done; else goto all_done; break; } /* end switch */ ++format; } all_done: if (ic >= 0) ugc (); /* restore the character */ quit: return done; } #if 0 /* TEST ONLY */ main() { int i, n; float x; char name[50]; n = scanf("%d%f%s", &i, &x, name); printf("n = %d i = %d x = %f name = :%s:\n", n, i, x, name); /* input: 54.32E-1 thompson */ /* output: n = 3 i = 25 x = 5.432000 name = :thompson: */ n = scanf("%2d%f%*d %[0-9]", &i, &x, name); printf("n = %d i = %d x = %f name = :%s:\n", n, i, x, name); /* input: 56789 0123 56a72 */ /* output: n = 4 i = 56 x = 789.000000 name = :56: */ n = scanf("%s", name); printf("n = %d name = :%s:\n", n, name); /* output: n = 1 name = :a72: */ n = scanf("%2d%f%*d %[0123456789]", &i, &x, name); printf("n = %d i = %d x = %f name = :%s:\n", n, i, x, name); /* input: 56789 0123 56a72 */ /* output: n = 4 i = 56 x = 789.000000 name = :56: */ /* 'a72' left over */ n = scanf("%s", name); printf("n = %d name = :%s:\n", n, name); /* output: n = 1 name = :a72: */ } #endif /* test only */ //E*O*F iscanf.c// exit 0