diff --git a/libc/charstod.c b/libc/charstod.c index 2a4399a..cbe6d3d 100644 --- a/libc/charstod.c +++ b/libc/charstod.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" /* * Reads a floating-point number by interpreting successive characters @@ -8,74 +24,62 @@ * necessary to back up the input stream up one byte after calling charstod. */ -#define ADVANCE *s++ = c; if(s>=e) return __NaN(); c = (*f)(vp) - double -charstod(int(*f)(void*), void *vp) +fmtcharstod(int(*f)(void*), void *vp) { - char str[400], *s, *e, *start; - int c; + double num, dem; + int neg, eneg, dig, exp, c; + + num = 0; + neg = 0; + dig = 0; + exp = 0; + eneg = 0; - s = str; - e = str + sizeof str - 1; c = (*f)(vp); while(c == ' ' || c == '\t') c = (*f)(vp); if(c == '-' || c == '+'){ - ADVANCE; + if(c == '-') + neg = 1; + c = (*f)(vp); } - start = s; while(c >= '0' && c <= '9'){ - ADVANCE; + num = num*10 + c-'0'; + c = (*f)(vp); } - if(c == '.'){ - ADVANCE; - while(c >= '0' && c <= '9'){ - ADVANCE; - } + if(c == '.') + c = (*f)(vp); + while(c >= '0' && c <= '9'){ + num = num*10 + c-'0'; + dig++; + c = (*f)(vp); } - if(s > start && (c == 'e' || c == 'E')){ - ADVANCE; + if(c == 'e' || c == 'E'){ + c = (*f)(vp); if(c == '-' || c == '+'){ - ADVANCE; + if(c == '-'){ + dig = -dig; + eneg = 1; + } + c = (*f)(vp); } while(c >= '0' && c <= '9'){ - ADVANCE; + exp = exp*10 + c-'0'; + c = (*f)(vp); } - }else if(s == start && (c == 'i' || c == 'I')){ - ADVANCE; - if(c != 'n' && c != 'N') - return __NaN(); - ADVANCE; - if(c != 'f' && c != 'F') - return __NaN(); - ADVANCE; - if(c != 'i' && c != 'I') - return __NaN(); - ADVANCE; - if(c != 'n' && c != 'N') - return __NaN(); - ADVANCE; - if(c != 'i' && c != 'I') - return __NaN(); - ADVANCE; - if(c != 't' && c != 'T') - return __NaN(); - ADVANCE; - if(c != 'y' && c != 'Y') - return __NaN(); - ADVANCE; /* so caller can back up uniformly */ - USED(c); - }else if(s == str && (c == 'n' || c == 'N')){ - ADVANCE; - if(c != 'a' && c != 'A') - return __NaN(); - ADVANCE; - if(c != 'n' && c != 'N') - return __NaN(); - ADVANCE; /* so caller can back up uniformly */ - USED(c); } - *s = 0; - return strtod(str, &s); + exp -= dig; + if(exp < 0){ + exp = -exp; + eneg = !eneg; + } + dem = __fmtpow10(exp); + if(eneg) + num /= dem; + else + num *= dem; + if(neg) + return -num; + return num; } diff --git a/libc/dofmt.c b/libc/dofmt.c index cdf40a3..97bbc92 100644 --- a/libc/dofmt.c +++ b/libc/dofmt.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" /* format the output into f->to and return the number of characters fmted */ @@ -14,8 +29,8 @@ dofmt(Fmt *f, char *fmt) nfmt = f->nfmt; for(;;){ if(f->runes){ - rt = f->to; - rs = f->stop; + rt = (Rune*)f->to; + rs = (Rune*)f->stop; while((r = *(uchar*)fmt) && r != '%'){ if(r < Runeself) fmt++; @@ -32,8 +47,8 @@ dofmt(Fmt *f, char *fmt) return f->nfmt - nfmt; f->stop = rs; }else{ - t = f->to; - s = f->stop; + t = (char*)f->to; + s = (char*)f->stop; while((r = *(uchar*)fmt) && r != '%'){ if(r < Runeself){ FMTCHAR(f, t, s, r); @@ -41,9 +56,9 @@ dofmt(Fmt *f, char *fmt) }else{ n = chartorune(&rune, fmt); if(t + n > s){ - t = _fmtflush(f, t, n); + t = (char*)__fmtflush(f, t, n); if(t != nil) - s = f->stop; + s = (char*)f->stop; else return -1; } @@ -59,15 +74,14 @@ dofmt(Fmt *f, char *fmt) f->stop = s; } - fmt = _fmtdispatch(f, fmt, 0); + fmt = (char*)__fmtdispatch(f, fmt, 0); if(fmt == nil) return -1; } - return 0; /* not reached */ } void * -_fmtflush(Fmt *f, void *t, int len) +__fmtflush(Fmt *f, void *t, int len) { if(f->runes) f->nfmt += (Rune*)t - (Rune*)f->to; @@ -86,13 +100,13 @@ _fmtflush(Fmt *f, void *t, int len) * left/right justified in a field of at least f->width charactes */ int -_fmtpad(Fmt *f, int n) +__fmtpad(Fmt *f, int n) { char *t, *s; int i; - t = f->to; - s = f->stop; + t = (char*)f->to; + s = (char*)f->stop; for(i = 0; i < n; i++) FMTCHAR(f, t, s, ' '); f->nfmt += t - (char *)f->to; @@ -101,13 +115,13 @@ _fmtpad(Fmt *f, int n) } int -_rfmtpad(Fmt *f, int n) +__rfmtpad(Fmt *f, int n) { Rune *t, *s; int i; - t = f->to; - s = f->stop; + t = (Rune*)f->to; + s = (Rune*)f->stop; for(i = 0; i < n; i++) FMTRCHAR(f, t, s, ' '); f->nfmt += t - (Rune *)f->to; @@ -116,24 +130,24 @@ _rfmtpad(Fmt *f, int n) } int -_fmtcpy(Fmt *f, void *vm, int n, int sz) +__fmtcpy(Fmt *f, const void *vm, int n, int sz) { Rune *rt, *rs, r; char *t, *s, *m, *me; ulong fl; int nc, w; - m = vm; + m = (char*)vm; me = m + sz; w = f->width; fl = f->flags; if((fl & FmtPrec) && n > f->prec) n = f->prec; if(f->runes){ - if(!(fl & FmtLeft) && _rfmtpad(f, w - n) < 0) + if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0) return -1; - rt = f->to; - rs = f->stop; + rt = (Rune*)f->to; + rs = (Rune*)f->stop; for(nc = n; nc > 0; nc--){ r = *(uchar*)m; if(r < Runeself) @@ -146,15 +160,13 @@ _fmtcpy(Fmt *f, void *vm, int n, int sz) } f->nfmt += rt - (Rune *)f->to; f->to = rt; - if(m < me) - return -1; - if(fl & FmtLeft && _rfmtpad(f, w - n) < 0) + if(fl & FmtLeft && __rfmtpad(f, w - n) < 0) return -1; }else{ - if(!(fl & FmtLeft) && _fmtpad(f, w - n) < 0) + if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0) return -1; - t = f->to; - s = f->stop; + t = (char*)f->to; + s = (char*)f->stop; for(nc = n; nc > 0; nc--){ r = *(uchar*)m; if(r < Runeself) @@ -167,48 +179,48 @@ _fmtcpy(Fmt *f, void *vm, int n, int sz) } f->nfmt += t - (char *)f->to; f->to = t; - if(fl & FmtLeft && _fmtpad(f, w - n) < 0) + if(fl & FmtLeft && __fmtpad(f, w - n) < 0) return -1; } return 0; } int -_fmtrcpy(Fmt *f, void *vm, int n) +__fmtrcpy(Fmt *f, const void *vm, int n) { Rune r, *m, *me, *rt, *rs; char *t, *s; ulong fl; int w; - m = vm; + m = (Rune*)vm; w = f->width; fl = f->flags; if((fl & FmtPrec) && n > f->prec) n = f->prec; if(f->runes){ - if(!(fl & FmtLeft) && _rfmtpad(f, w - n) < 0) + if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0) return -1; - rt = f->to; - rs = f->stop; + rt = (Rune*)f->to; + rs = (Rune*)f->stop; for(me = m + n; m < me; m++) FMTRCHAR(f, rt, rs, *m); f->nfmt += rt - (Rune *)f->to; f->to = rt; - if(fl & FmtLeft && _rfmtpad(f, w - n) < 0) + if(fl & FmtLeft && __rfmtpad(f, w - n) < 0) return -1; }else{ - if(!(fl & FmtLeft) && _fmtpad(f, w - n) < 0) + if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0) return -1; - t = f->to; - s = f->stop; + t = (char*)f->to; + s = (char*)f->stop; for(me = m + n; m < me; m++){ r = *m; FMTRUNE(f, t, s, r); } f->nfmt += t - (char *)f->to; f->to = t; - if(fl & FmtLeft && _fmtpad(f, w - n) < 0) + if(fl & FmtLeft && __fmtpad(f, w - n) < 0) return -1; } return 0; @@ -216,47 +228,47 @@ _fmtrcpy(Fmt *f, void *vm, int n) /* fmt out one character */ int -_charfmt(Fmt *f) +__charfmt(Fmt *f) { char x[1]; x[0] = va_arg(f->args, int); f->prec = 1; - return _fmtcpy(f, x, 1, 1); + return __fmtcpy(f, (const char*)x, 1, 1); } /* fmt out one rune */ int -_runefmt(Fmt *f) +__runefmt(Fmt *f) { Rune x[1]; x[0] = va_arg(f->args, int); - return _fmtrcpy(f, x, 1); + return __fmtrcpy(f, (const void*)x, 1); } /* public helper routine: fmt out a null terminated string already in hand */ int fmtstrcpy(Fmt *f, char *s) { - int p, i; + int i, j; + Rune r; + if(!s) - return _fmtcpy(f, "", 5, 5); + return __fmtcpy(f, "", 5, 5); /* if precision is specified, make sure we don't wander off the end */ if(f->flags & FmtPrec){ - p = f->prec; - for(i = 0; i < p; i++) - if(s[i] == 0) - break; - return _fmtcpy(f, s, utfnlen(s, i), i); /* BUG?: won't print a partial rune at end */ + i = 0; + for(j=0; jprec && s[i]; j++) + i += chartorune(&r, s+i); + return __fmtcpy(f, s, j, i); } - - return _fmtcpy(f, s, utflen(s), strlen(s)); + return __fmtcpy(f, s, utflen(s), strlen(s)); } /* fmt out a null terminated utf string */ int -_strfmt(Fmt *f) +__strfmt(Fmt *f) { char *s; @@ -272,7 +284,7 @@ fmtrunestrcpy(Fmt *f, Rune *s) int n, p; if(!s) - return _fmtcpy(f, "", 5, 5); + return __fmtcpy(f, "", 5, 5); /* if precision is specified, make sure we don't wander off the end */ if(f->flags & FmtPrec){ p = f->prec; @@ -284,12 +296,12 @@ fmtrunestrcpy(Fmt *f, Rune *s) ; n = e - s; } - return _fmtrcpy(f, s, n); + return __fmtrcpy(f, s, n); } /* fmt out a null terminated rune string */ int -_runesfmt(Fmt *f) +__runesfmt(Fmt *f) { Rune *s; @@ -299,18 +311,18 @@ _runesfmt(Fmt *f) /* fmt a % */ int -_percentfmt(Fmt *f) +__percentfmt(Fmt *f) { Rune x[1]; x[0] = f->r; f->prec = 1; - return _fmtrcpy(f, x, 1); + return __fmtrcpy(f, (const void*)x, 1); } /* fmt an integer */ int -_ifmt(Fmt *f) +__ifmt(Fmt *f) { char buf[70], *p, *conv; uvlong vu; @@ -322,6 +334,21 @@ _ifmt(Fmt *f) isv = 0; vu = 0; u = 0; +#ifndef PLAN9PORT + /* + * Unsigned verbs for ANSI C + */ + switch(f->r){ + case 'x': + case 'X': + case 'o': + case 'u': + case 'p': + fl |= FmtUnsigned; + fl &= ~(FmtSign|FmtSpace); + break; + } +#endif if(f->r == 'p'){ u = (ulong)va_arg(f->args, void*); f->r = 'x'; @@ -356,6 +383,8 @@ _ifmt(Fmt *f) conv = "0123456789abcdef"; switch(f->r){ case 'd': + case 'i': + case 'u': base = 10; break; case 'x': @@ -426,7 +455,7 @@ _ifmt(Fmt *f) n++; } } - if((fl & FmtZero) && !(fl & FmtLeft)){ + if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){ for(w = f->width; n < w && p > buf+3; n++) *p-- = '0'; f->width = 0; @@ -444,11 +473,11 @@ _ifmt(Fmt *f) else if(fl & FmtSpace) *p-- = ' '; f->flags &= ~FmtPrec; - return _fmtcpy(f, p + 1, n, n); + return __fmtcpy(f, p + 1, n, n); } int -_countfmt(Fmt *f) +__countfmt(Fmt *f) { void *p; ulong fl; @@ -470,7 +499,7 @@ _countfmt(Fmt *f) } int -_flagfmt(Fmt *f) +__flagfmt(Fmt *f) { switch(f->r){ case ',': @@ -496,6 +525,9 @@ _flagfmt(Fmt *f) f->flags |= FmtByte; f->flags |= FmtShort; break; + case 'L': + f->flags |= FmtLDouble; + break; case 'l': if(f->flags & FmtLong) f->flags |= FmtVLong; @@ -507,7 +539,7 @@ _flagfmt(Fmt *f) /* default error format */ int -_badfmt(Fmt *f) +__badfmt(Fmt *f) { char x[3]; @@ -515,6 +547,6 @@ _badfmt(Fmt *f) x[1] = f->r; x[2] = '%'; f->prec = 3; - _fmtcpy(f, x, 3, 3); + __fmtcpy(f, (const void*)x, 3, 3); return 0; } diff --git a/libc/dorfmt.c b/libc/dorfmt.c index 582c4ac..034dea1 100644 --- a/libc/dorfmt.c +++ b/libc/dorfmt.c @@ -1,11 +1,26 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" /* format the output into f->to and return the number of characters fmted */ int -dorfmt(Fmt *f, Rune *fmt) +dorfmt(Fmt *f, const Rune *fmt) { Rune *rt, *rs; int r; @@ -38,7 +53,7 @@ dorfmt(Fmt *f, Rune *fmt) f->stop = s; } - fmt = _fmtdispatch(f, fmt, 1); + fmt = __fmtdispatch(f, (Rune*)fmt, 1); if(fmt == nil) return -1; } diff --git a/libc/errfmt.c b/libc/errfmt.c index 5b29b16..b0eae73 100644 --- a/libc/errfmt.c +++ b/libc/errfmt.c @@ -1,12 +1,28 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" int -errfmt(Fmt *f) +__errfmt(Fmt *f) { - char buf[ERRMAX]; + char *s; - rerrstr(buf, sizeof buf); - return _fmtcpy(f, buf, utflen(buf), strlen(buf)); + s = strerror(errno); + return fmtstrcpy(f, s); } diff --git a/libc/fltfmt.c b/libc/fltfmt.c index 80ab472..14ad867 100644 --- a/libc/fltfmt.c +++ b/libc/fltfmt.c @@ -1,15 +1,97 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include +#include +#include +#include +#include #include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" enum { FDIGIT = 30, FDEFLT = 6, - NSIGNIF = 17, + NSIGNIF = 17 }; +/* + * first few powers of 10, enough for about 1/2 of the + * total space for doubles. + */ +static double pows10[] = +{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, + 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, + 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, + 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59, + 1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, + 1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79, + 1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89, + 1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99, + 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, + 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, + 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, + 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, + 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, + 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, +}; + +#define pow10(x) fmtpow10(x) + +static double +pow10(int n) +{ + double d; + int neg; + + neg = 0; + if(n < 0){ + if(n < DBL_MIN_10_EXP){ + return 0.; + } + neg = 1; + n = -n; + }else if(n > DBL_MAX_10_EXP){ + return HUGE_VAL; + } + if(n < (int)(sizeof(pows10)/sizeof(pows10[0]))) + d = pows10[n]; + else{ + d = pows10[sizeof(pows10)/sizeof(pows10[0]) - 1]; + for(;;){ + n -= sizeof(pows10)/sizeof(pows10[0]) - 1; + if(n < (int)(sizeof(pows10)/sizeof(pows10[0]))){ + d *= pows10[n]; + break; + } + d *= pows10[sizeof(pows10)/sizeof(pows10[0]) - 1]; + } + } + if(neg){ + return 1./d; + } + return d; +} + static int xadd(char *a, int n, int v) { @@ -27,7 +109,7 @@ xadd(char *a, int n, int v) *b = '0'; v = 1; } - *a = '1'; // overflow adding + *a = '1'; /* overflow adding */ return 1; } @@ -46,7 +128,7 @@ xsub(char *a, int n, int v) *b = '9'; v = 1; } - *a = '9'; // underflow subtracting + *a = '9'; /* underflow subtracting */ return 1; } @@ -291,22 +373,22 @@ found: s2[d] = 0; } -int -_floatfmt(Fmt *fmt, double f) +static int +floatfmt(Fmt *fmt, double f) { - char s[FDIGIT+10]; + char s[341]; /* precision+exponent+sign+'.'+null */ xdtoa(fmt, s, f); fmt->flags &= FmtWidth|FmtLeft; - _fmtcpy(fmt, s, strlen(s), strlen(s)); + __fmtcpy(fmt, s, strlen(s), strlen(s)); return 0; } int -_efgfmt(Fmt *f) +__efgfmt(Fmt *f) { double d; d = va_arg(f->args, double); - return _floatfmt(f, d); + return floatfmt(f, d); } diff --git a/libc/fmt.c b/libc/fmt.c index 5d36dac..642de8c 100644 --- a/libc/fmt.c +++ b/libc/fmt.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" enum @@ -16,55 +31,69 @@ struct Convfmt struct { - /* lock by calling _fmtlock, _fmtunlock */ + /* lock by calling __fmtlock, __fmtunlock */ int nfmt; Convfmt fmt[Maxfmt]; } fmtalloc; static Convfmt knownfmt[] = { - ' ', _flagfmt, - '#', _flagfmt, - '%', _percentfmt, - '+', _flagfmt, - ',', _flagfmt, - '-', _flagfmt, - 'C', _runefmt, - 'E', _efgfmt, - 'G', _efgfmt, - 'S', _runesfmt, - 'X', _ifmt, - 'b', _ifmt, - 'c', _charfmt, - 'd', _ifmt, - 'e', _efgfmt, - 'f', _efgfmt, - 'g', _efgfmt, - 'h', _flagfmt, - 'l', _flagfmt, - 'n', _countfmt, - 'o', _ifmt, - 'p', _ifmt, -/* 'r', errfmt, */ - 's', _strfmt, - 'u', _flagfmt, - 'x', _ifmt, + ' ', __flagfmt, + '#', __flagfmt, + '%', __percentfmt, + '+', __flagfmt, + ',', __flagfmt, + '-', __flagfmt, + 'C', __runefmt, /* Plan 9 addition */ + 'E', __efgfmt, +#ifndef PLAN9PORT + 'F', __efgfmt, /* ANSI only */ +#endif + 'G', __efgfmt, +#ifndef PLAN9PORT + 'L', __flagfmt, /* ANSI only */ +#endif + 'S', __runesfmt, /* Plan 9 addition */ + 'X', __ifmt, + 'b', __ifmt, /* Plan 9 addition */ + 'c', __charfmt, + 'd', __ifmt, + 'e', __efgfmt, + 'f', __efgfmt, + 'g', __efgfmt, + 'h', __flagfmt, +#ifndef PLAN9PORT + 'i', __ifmt, /* ANSI only */ +#endif + 'l', __flagfmt, + 'n', __countfmt, + 'o', __ifmt, + 'p', __ifmt, + 'r', __errfmt, + 's', __strfmt, +#ifdef PLAN9PORT + 'u', __flagfmt, +#else + 'u', __ifmt, +#endif + 'x', __ifmt, 0, nil, }; -int (*doquote)(int); + +int (*fmtdoquote)(int); /* - * _fmtlock() must be set + * __fmtlock() must be set */ static int -_fmtinstall(int c, Fmts f) +__fmtinstall(int c, Fmts f) { Convfmt *p, *ep; if(c<=0 || c>=65536) return -1; if(!f) - f = _badfmt; + f = __badfmt; ep = &fmtalloc.fmt[fmtalloc.nfmt]; for(p=fmtalloc.fmt; pc; p++) if(p->c == c){ - _fmtinstall(p->c, p->fmt); - _fmtunlock(); + __fmtinstall(p->c, p->fmt); + __fmtunlock(); return p->fmt; } - _fmtunlock(); + __fmtunlock(); - return _badfmt; + return __badfmt; } void* -_fmtdispatch(Fmt *f, void *fmt, int isrunes) +__fmtdispatch(Fmt *f, void *fmt, int isrunes) { Rune rune, r; int i, n; @@ -134,7 +163,7 @@ _fmtdispatch(Fmt *f, void *fmt, int isrunes) r = *(Rune*)fmt; fmt = (Rune*)fmt + 1; }else{ - fmt = (char*)fmt + chartorune(&rune, fmt); + fmt = (char*)fmt + chartorune(&rune, (char*)fmt); r = rune; } f->r = r; @@ -179,6 +208,15 @@ _fmtdispatch(Fmt *f, void *fmt, int isrunes) case '*': i = va_arg(f->args, int); if(i < 0){ + /* + * negative precision => + * ignore the precision. + */ + if(f->flags & FmtPrec){ + f->flags &= ~FmtPrec; + f->prec = 0; + continue; + } i = -i; f->flags |= FmtLeft; } diff --git a/libc/fmtdef.h b/libc/fmtdef.h index d8f3680..5a63f9b 100644 --- a/libc/fmtdef.h +++ b/libc/fmtdef.h @@ -1,3 +1,17 @@ +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ + /* * dofmt -- format to a buffer * the number of characters formatted is returned, @@ -18,33 +32,41 @@ struct Quoteinfo int nbytesout; /* number of bytes that will be generated */ }; -void *_fmtflush(Fmt*, void*, int); -void *_fmtdispatch(Fmt*, void*, int); -int _floatfmt(Fmt*, double); -int _fmtpad(Fmt*, int); -int _rfmtpad(Fmt*, int); -int _fmtFdFlush(Fmt*); - -int _efgfmt(Fmt*); -int _charfmt(Fmt*); -int _countfmt(Fmt*); -int _flagfmt(Fmt*); -int _percentfmt(Fmt*); -int _ifmt(Fmt*); -int _runefmt(Fmt*); -int _runesfmt(Fmt*); -int _strfmt(Fmt*); -int _badfmt(Fmt*); -int _fmtcpy(Fmt*, void*, int, int); -int _fmtrcpy(Fmt*, void*, int n); - -void _fmtlock(void); -void _fmtunlock(void); +/* Edit .+1,/^$/ |cfn |grep -v static | grep __ */ +double __Inf(int sign); +double __NaN(void); +int __badfmt(Fmt *f); +int __charfmt(Fmt *f); +int __countfmt(Fmt *f); +int __efgfmt(Fmt *fmt); +int __errfmt(Fmt *f); +int __flagfmt(Fmt *f); +int __fmtFdFlush(Fmt *f); +int __fmtcpy(Fmt *f, const void *vm, int n, int sz); +void* __fmtdispatch(Fmt *f, void *fmt, int isrunes); +void * __fmtflush(Fmt *f, void *t, int len); +void __fmtlock(void); +int __fmtpad(Fmt *f, int n); +double __fmtpow10(int n); +int __fmtrcpy(Fmt *f, const void *vm, int n); +void __fmtunlock(void); +int __ifmt(Fmt *f); +int __isInf(double d, int sign); +int __isNaN(double d); +int __needsquotes(char *s, int *quotelenp); +int __percentfmt(Fmt *f); +void __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout); +int __quotestrfmt(int runesin, Fmt *f); +int __rfmtpad(Fmt *f, int n); +int __runefmt(Fmt *f); +int __runeneedsquotes(Rune *r, int *quotelenp); +int __runesfmt(Fmt *f); +int __strfmt(Fmt *f); #define FMTCHAR(f, t, s, c)\ do{\ if(t + 1 > (char*)s){\ - t = _fmtflush(f, t, 1);\ + t = __fmtflush(f, t, 1);\ if(t != nil)\ s = f->stop;\ else\ @@ -56,7 +78,7 @@ void _fmtunlock(void); #define FMTRCHAR(f, t, s, c)\ do{\ if(t + 1 > (Rune*)s){\ - t = _fmtflush(f, t, sizeof(Rune));\ + t = __fmtflush(f, t, sizeof(Rune));\ if(t != nil)\ s = f->stop;\ else\ @@ -70,7 +92,7 @@ void _fmtunlock(void); Rune _rune;\ int _runelen;\ if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\ - t = _fmtflush(f, t, _runelen);\ + t = __fmtflush(f, t, _runelen);\ if(t != nil)\ s = f->stop;\ else\ @@ -83,3 +105,12 @@ void _fmtunlock(void); t += runetochar(t, &_rune);\ }\ }while(0) + +#ifdef va_copy +# define VA_COPY(a,b) va_copy(a,b) +# define VA_END(a) va_end(a) +#else +# define VA_COPY(a,b) (a) = (b) +# define VA_END(a) +#endif + diff --git a/libc/fmtfd.c b/libc/fmtfd.c index db42eba..9f35f02 100644 --- a/libc/fmtfd.c +++ b/libc/fmtfd.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" /* @@ -9,7 +24,7 @@ int fmtfdflush(Fmt *f) { - if(_fmtFdFlush(f) <= 0) + if(__fmtFdFlush(f) <= 0) return -1; return f->nfmt; } @@ -24,8 +39,8 @@ fmtfdinit(Fmt *f, int fd, char *buf, int size) f->start = buf; f->to = buf; f->stop = buf + size; - f->flush = _fmtFdFlush; - f->farg = (void*)fd; + f->flush = __fmtFdFlush; + f->farg = (void*)(uintptr_t)fd; f->nfmt = 0; return 0; } diff --git a/libc/fmtlock.c b/libc/fmtlock.c index 02ae963..5c7afbc 100644 --- a/libc/fmtlock.c +++ b/libc/fmtlock.c @@ -1,16 +1,27 @@ -#include -#include - -static Lock fmtl; +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" void -_fmtlock(void) +__fmtlock(void) { - lock(&fmtl); } void -_fmtunlock(void) +__fmtunlock(void) { - unlock(&fmtl); } diff --git a/libc/fmtprint.c b/libc/fmtprint.c index 4c858b9..5ba59d3 100644 --- a/libc/fmtprint.c +++ b/libc/fmtprint.c @@ -1,8 +1,22 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" - /* * format a string into the output buffer * designed for formats which themselves call fmt, @@ -17,14 +31,16 @@ fmtprint(Fmt *f, char *fmt, ...) f->flags = 0; f->width = 0; f->prec = 0; - va = f->args; + VA_COPY(va, f->args); + VA_END(f->args); va_start(f->args, fmt); n = dofmt(f, fmt); va_end(f->args); f->flags = 0; f->width = 0; f->prec = 0; - f->args = va; + VA_COPY(f->args,va); + VA_END(va); if(n >= 0) return 0; return n; diff --git a/libc/fmtquote.c b/libc/fmtquote.c index 68e3b1f..b6f2e17 100644 --- a/libc/fmtquote.c +++ b/libc/fmtquote.c @@ -1,11 +1,26 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" /* * How many bytes of output UTF will be produced by quoting (if necessary) this string? * How many runes? How much of the input will be consumed? - * The parameter q is filled in by _quotesetup. + * The parameter q is filled in by __quotesetup. * The string may be UTF or Runes (s or r). * Return count does not include NUL. * Terminate the scan at the first of: @@ -16,7 +31,7 @@ * nin may be <0 initially, to avoid checking input by count. */ void -_quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout) +__quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout) { int w; Rune c; @@ -33,7 +48,7 @@ _quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int ru q->nbytesout = 2; q->nrunesout = 2; } - for(; nin!=0; nin-=w){ + for(; nin!=0; nin--){ if(s) w = chartorune(&c, s); else{ @@ -51,7 +66,7 @@ _quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int ru break; } - if((c <= L' ') || (c == L'\'') || (doquote!=nil && doquote(c))){ + if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){ if(!q->quoted){ if(runesout){ if(1+q->nrunesout+1+1 > nout) /* no room for quotes */ @@ -108,16 +123,16 @@ qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f) w = f->width; fl = f->flags; if(f->runes){ - if(!(fl & FmtLeft) && _rfmtpad(f, w - q->nrunesout) < 0) + if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0) return -1; }else{ - if(!(fl & FmtLeft) && _fmtpad(f, w - q->nbytesout) < 0) + if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0) return -1; } - t = f->to; - s = f->stop; - rt = f->to; - rs = f->stop; + t = (char*)f->to; + s = (char*)f->stop; + rt = (Rune*)f->to; + rs = (Rune*)f->stop; if(f->runes) FMTRCHAR(f, rt, rs, '\''); else @@ -152,28 +167,30 @@ qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f) USED(rs); f->nfmt += rt - (Rune *)f->to; f->to = rt; - if(fl & FmtLeft && _rfmtpad(f, w - q->nrunesout) < 0) + if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0) return -1; }else{ FMTRUNE(f, t, s, '\''); USED(s); f->nfmt += t - (char *)f->to; f->to = t; - if(fl & FmtLeft && _fmtpad(f, w - q->nbytesout) < 0) + if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0) return -1; } return 0; } int -_quotestrfmt(int runesin, Fmt *f) +__quotestrfmt(int runesin, Fmt *f) { - int outlen; + int nin, outlen; Rune *r; char *s; Quoteinfo q; - f->flags &= ~FmtPrec; /* ignored for %q %Q, so disable for %s %S in easy case */ + nin = -1; + if(f->flags&FmtPrec) + nin = f->prec; if(runesin){ r = va_arg(f->args, Rune *); s = nil; @@ -182,7 +199,7 @@ _quotestrfmt(int runesin, Fmt *f) r = nil; } if(!s && !r) - return _fmtcpy(f, "", 5, 5); + return __fmtcpy(f, (void*)"", 5, 5); if(f->flush) outlen = 0x7FFFFFFF; /* if we can flush, no output limit */ @@ -191,30 +208,30 @@ _quotestrfmt(int runesin, Fmt *f) else outlen = (char*)f->stop - (char*)f->to; - _quotesetup(s, r, -1, outlen, &q, f->flags&FmtSharp, f->runes); + __quotesetup(s, r, nin, outlen, &q, f->flags&FmtSharp, f->runes); //print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout); if(runesin){ if(!q.quoted) - return _fmtrcpy(f, r, q.nrunesin); + return __fmtrcpy(f, r, q.nrunesin); return qstrfmt(nil, r, &q, f); } if(!q.quoted) - return _fmtcpy(f, s, q.nrunesin, q.nbytesin); + return __fmtcpy(f, s, q.nrunesin, q.nbytesin); return qstrfmt(s, nil, &q, f); } int quotestrfmt(Fmt *f) { - return _quotestrfmt(0, f); + return __quotestrfmt(0, f); } int quoterunestrfmt(Fmt *f) { - return _quotestrfmt(1, f); + return __quotestrfmt(1, f); } void @@ -225,22 +242,22 @@ quotefmtinstall(void) } int -_needsquotes(char *s, int *quotelenp) +__needsquotes(char *s, int *quotelenp) { Quoteinfo q; - _quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0); + __quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0); *quotelenp = q.nbytesout; return q.quoted; } int -_runeneedsquotes(Rune *r, int *quotelenp) +__runeneedsquotes(Rune *r, int *quotelenp) { Quoteinfo q; - _quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0); + __quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0); *quotelenp = q.nrunesout; return q.quoted; diff --git a/libc/fmtrune.c b/libc/fmtrune.c index e2db137..b1ddd3b 100644 --- a/libc/fmtrune.c +++ b/libc/fmtrune.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" int @@ -10,12 +25,12 @@ fmtrune(Fmt *f, int r) int n; if(f->runes){ - rt = f->to; + rt = (Rune*)f->to; FMTRCHAR(f, rt, f->stop, r); f->to = rt; n = 1; }else{ - t = f->to; + t = (char*)f->to; FMTRUNE(f, t, f->stop, r); n = t - (char*)f->to; f->to = t; diff --git a/libc/fmtstr.c b/libc/fmtstr.c index 6f58213..a5f8f8d 100644 --- a/libc/fmtstr.c +++ b/libc/fmtstr.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" char* fmtstrflush(Fmt *f) @@ -7,5 +23,5 @@ fmtstrflush(Fmt *f) if(f->start == nil) return nil; *(char*)f->to = '\0'; - return f->start; + return (char*)f->start; } diff --git a/libc/fmtvprint.c b/libc/fmtvprint.c index 1d6493e..cb7ffbe 100644 --- a/libc/fmtvprint.c +++ b/libc/fmtvprint.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" #include "fmtdef.h" @@ -17,13 +32,16 @@ fmtvprint(Fmt *f, char *fmt, va_list args) f->flags = 0; f->width = 0; f->prec = 0; - va = f->args; - f->args = args; + VA_COPY(va,f->args); + VA_END(f->args); + VA_COPY(f->args,args); n = dofmt(f, fmt); f->flags = 0; f->width = 0; f->prec = 0; - f->args = va; + VA_END(f->args); + VA_COPY(f->args,va); + VA_END(va); if(n >= 0) return 0; return n; diff --git a/libc/fprint.c b/libc/fprint.c index b1376a0..043202c 100644 --- a/libc/fprint.c +++ b/libc/fprint.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int fprint(int fd, char *fmt, ...) diff --git a/libc/nan64.c b/libc/nan64.c index 45a1921..6e355a2 100644 --- a/libc/nan64.c +++ b/libc/nan64.c @@ -5,45 +5,59 @@ * same byte ordering. */ -#include -#include -#include "nan.h" +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" -// typedef unsigned long long uvlong; -// typedef unsigned long ulong; +#if defined (__APPLE__) || (__powerpc__) +#define _NEEDLL +#endif -static uvlong uvnan = 0x7FF0000000000001ULL; -static uvlong uvinf = 0x7FF0000000000000ULL; -static uvlong uvneginf = 0xFFF0000000000000ULL; +static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001; +static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000; +static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000; double __NaN(void) { - return *(double*)(void*)&uvnan; + uvlong *p; + + /* gcc complains about "return *(double*)&uvnan;" */ + p = &uvnan; + return *(double*)p; } int __isNaN(double d) { - uvlong x = *(uvlong*)(void*)&d; + uvlong x; + double *p; + + p = &d; + x = *(uvlong*)p; return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0); } double __Inf(int sign) { + uvlong *p; + if(sign < 0) - return *(double*)(void*)&uvinf; + p = &uvinf; else - return *(double*)(void*)&uvneginf; + p = &uvneginf; + return *(double*)p; } int __isInf(double d, int sign) { uvlong x; + double *p; - x = *(uvlong*)(void*)&d; + p = &d; + x = *(uvlong*)p; if(sign == 0) return x==uvinf || x==uvneginf; else if(sign > 0) @@ -51,5 +65,3 @@ __isInf(double d, int sign) else return x==uvneginf; } - - diff --git a/libc/pow10.c b/libc/pow10.c index 7e09f3c..5d578f9 100644 --- a/libc/pow10.c +++ b/libc/pow10.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" /* * this table might overflow 127-bit exponent representations. @@ -9,41 +25,33 @@ * the presumption is that C converts fp numbers better * than multipication of lower powers of 10. */ + static double tab[] = { - 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, - 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19, - 1.0e20, 1.0e21, 1.0e22, 1.0e23, 1.0e24, 1.0e25, 1.0e26, 1.0e27, 1.0e28, 1.0e29, - 1.0e30, 1.0e31, 1.0e32, 1.0e33, 1.0e34, 1.0e35, 1.0e36, 1.0e37, 1.0e38, 1.0e39, - 1.0e40, 1.0e41, 1.0e42, 1.0e43, 1.0e44, 1.0e45, 1.0e46, 1.0e47, 1.0e48, 1.0e49, - 1.0e50, 1.0e51, 1.0e52, 1.0e53, 1.0e54, 1.0e55, 1.0e56, 1.0e57, 1.0e58, 1.0e59, - 1.0e60, 1.0e61, 1.0e62, 1.0e63, 1.0e64, 1.0e65, 1.0e66, 1.0e67, 1.0e68, 1.0e69, - 1.0e70, 1.0e71, 1.0e72, 1.0e73, 1.0e74, 1.0e75, 1.0e76, 1.0e77, 1.0e78, 1.0e79, - 1.0e80, 1.0e81, 1.0e82, 1.0e83, 1.0e84, 1.0e85, 1.0e86, 1.0e87, 1.0e88, 1.0e89, - 1.0e90, 1.0e91, 1.0e92, 1.0e93, 1.0e94, 1.0e95, 1.0e96, 1.0e97, 1.0e98, 1.0e99, - 1.0e100,1.0e101,1.0e102,1.0e103,1.0e104,1.0e105,1.0e106,1.0e107,1.0e108,1.0e109, - 1.0e110,1.0e111,1.0e112,1.0e113,1.0e114,1.0e115,1.0e116,1.0e117,1.0e118,1.0e119, - 1.0e120,1.0e121,1.0e122,1.0e123,1.0e124,1.0e125,1.0e126,1.0e127,1.0e128,1.0e129, - 1.0e130,1.0e131,1.0e132,1.0e133,1.0e134,1.0e135,1.0e136,1.0e137,1.0e138,1.0e139, - 1.0e140,1.0e141,1.0e142,1.0e143,1.0e144,1.0e145,1.0e146,1.0e147,1.0e148,1.0e149, - 1.0e150,1.0e151,1.0e152,1.0e153,1.0e154,1.0e155,1.0e156,1.0e157,1.0e158,1.0e159, + 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, + 1.0e10,1.0e11,1.0e12,1.0e13,1.0e14,1.0e15,1.0e16,1.0e17,1.0e18,1.0e19, + 1.0e20,1.0e21,1.0e22,1.0e23,1.0e24,1.0e25,1.0e26,1.0e27,1.0e28,1.0e29, + 1.0e30,1.0e31,1.0e32,1.0e33,1.0e34,1.0e35,1.0e36,1.0e37,1.0e38,1.0e39, + 1.0e40,1.0e41,1.0e42,1.0e43,1.0e44,1.0e45,1.0e46,1.0e47,1.0e48,1.0e49, + 1.0e50,1.0e51,1.0e52,1.0e53,1.0e54,1.0e55,1.0e56,1.0e57,1.0e58,1.0e59, + 1.0e60,1.0e61,1.0e62,1.0e63,1.0e64,1.0e65,1.0e66,1.0e67,1.0e68,1.0e69, }; double -pow10(int n) +__fmtpow10(int n) { int m; if(n < 0) { n = -n; - if(n < sizeof(tab)/sizeof(tab[0])) + if(n < (int)(sizeof(tab)/sizeof(tab[0]))) return 1/tab[n]; m = n/2; - return 1/(pow10(m) * pow10(n-m)); + return __fmtpow10(-m) * __fmtpow10(m-n); } - if(n < sizeof(tab)/sizeof(tab[0])) + if(n < (int)(sizeof(tab)/sizeof(tab[0]))) return tab[n]; m = n/2; - return pow10(m) * pow10(n-m); + return __fmtpow10(m) * __fmtpow10(n-m); } diff --git a/libc/print.c b/libc/print.c index fdbb522..d038cee 100644 --- a/libc/print.c +++ b/libc/print.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int print(char *fmt, ...) diff --git a/libc/runefmtstr.c b/libc/runefmtstr.c index 9ce9c13..e17bc16 100644 --- a/libc/runefmtstr.c +++ b/libc/runefmtstr.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" Rune* runefmtstrflush(Fmt *f) diff --git a/libc/runeseprint.c b/libc/runeseprint.c index 77a761e..8e01c07 100644 --- a/libc/runeseprint.c +++ b/libc/runeseprint.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" Rune* runeseprint(Rune *buf, Rune *e, char *fmt, ...) diff --git a/libc/runesmprint.c b/libc/runesmprint.c index 1f8b220..03143a9 100644 --- a/libc/runesmprint.c +++ b/libc/runesmprint.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" Rune* runesmprint(char *fmt, ...) diff --git a/libc/runesnprint.c b/libc/runesnprint.c index ac15ec0..2e6ad6c 100644 --- a/libc/runesnprint.c +++ b/libc/runesnprint.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int runesnprint(Rune *buf, int len, char *fmt, ...) diff --git a/libc/runesprint.c b/libc/runesprint.c index 5eca8cd..1dad4df 100644 --- a/libc/runesprint.c +++ b/libc/runesprint.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int runesprint(Rune *buf, char *fmt, ...) diff --git a/libc/runevseprint.c b/libc/runevseprint.c index 43c601e..2359c81 100644 --- a/libc/runevseprint.c +++ b/libc/runevseprint.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" Rune* runevseprint(Rune *buf, Rune *e, char *fmt, va_list args) @@ -15,9 +31,10 @@ runevseprint(Rune *buf, Rune *e, char *fmt, va_list args) f.flush = nil; f.farg = nil; f.nfmt = 0; - f.args = args; + VA_COPY(f.args,args); dofmt(&f, fmt); + VA_END(f.args); *(Rune*)f.to = '\0'; - return f.to; + return (Rune*)f.to; } diff --git a/libc/runevsmprint.c b/libc/runevsmprint.c index 41326dd..f83dce2 100644 --- a/libc/runevsmprint.c +++ b/libc/runevsmprint.c @@ -1,6 +1,32 @@ +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +/* + * Plan 9 port version must include libc.h in order to + * get Plan 9 debugging malloc, which sometimes returns + * different pointers than the standard malloc. + */ +#ifdef PLAN9PORT #include #include #include "fmtdef.h" +#else +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" +#endif static int runeFmtStrFlush(Fmt *f) @@ -10,9 +36,9 @@ runeFmtStrFlush(Fmt *f) if(f->start == nil) return 0; - n = (int)f->farg; + n = (uintptr)f->farg; n *= 2; - s = f->start; + s = (Rune*)f->start; f->start = realloc(s, sizeof(Rune)*n); if(f->start == nil){ f->farg = nil; @@ -21,7 +47,7 @@ runeFmtStrFlush(Fmt *f) free(s); return 0; } - f->farg = (void*)n; + f->farg = (void*)(uintptr)n; f->to = (Rune*)f->start + ((Rune*)f->to - s); f->stop = (Rune*)f->start + n - 1; return 1; @@ -41,7 +67,7 @@ runefmtstrinit(Fmt *f) f->to = f->start; f->stop = (Rune*)f->start + n - 1; f->flush = runeFmtStrFlush; - f->farg = (void*)n; + f->farg = (void*)(uintptr)n; f->nfmt = 0; return 0; } @@ -57,8 +83,9 @@ runevsmprint(char *fmt, va_list args) if(runefmtstrinit(&f) < 0) return nil; - f.args = args; + VA_COPY(f.args,args); n = dofmt(&f, fmt); + VA_END(f.args); if(f.start == nil) return nil; if(n < 0){ @@ -66,5 +93,5 @@ runevsmprint(char *fmt, va_list args) return nil; } *(Rune*)f.to = '\0'; - return f.start; + return (Rune*)f.start; } diff --git a/libc/runevsnprint.c b/libc/runevsnprint.c index 61fe4af..431868a 100644 --- a/libc/runevsnprint.c +++ b/libc/runevsnprint.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int runevsnprint(Rune *buf, int len, char *fmt, va_list args) @@ -15,8 +31,9 @@ runevsnprint(Rune *buf, int len, char *fmt, va_list args) f.flush = nil; f.farg = nil; f.nfmt = 0; - f.args = args; + VA_COPY(f.args,args); dofmt(&f, fmt); + VA_END(f.args); *(Rune*)f.to = '\0'; return (Rune*)f.to - buf; } diff --git a/libc/seprint.c b/libc/seprint.c index 519c1aa..38bdf5f 100644 --- a/libc/seprint.c +++ b/libc/seprint.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" char* seprint(char *buf, char *e, char *fmt, ...) diff --git a/libc/smprint.c b/libc/smprint.c index bc1b545..f46c964 100644 --- a/libc/smprint.c +++ b/libc/smprint.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" char* smprint(char *fmt, ...) diff --git a/libc/snprint.c b/libc/snprint.c index 8a46813..17ce0e2 100644 --- a/libc/snprint.c +++ b/libc/snprint.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int snprint(char *buf, int len, char *fmt, ...) diff --git a/libc/sprint.c b/libc/sprint.c index 2da6d92..1ab5ce6 100644 --- a/libc/sprint.c +++ b/libc/sprint.c @@ -1,14 +1,39 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int sprint(char *buf, char *fmt, ...) { int n; + uint len; va_list args; + len = 1<<30; /* big number, but sprint is deprecated anyway */ + /* + * on PowerPC, the stack is near the top of memory, so + * we must be sure not to overflow a 32-bit pointer. + */ + if(buf+len < buf) + len = -(uintptr)buf-1; + va_start(args, fmt); - n = vsnprint(buf, 65536, fmt, args); /* big number, but sprint is deprecated anyway */ + n = vsnprint(buf, len, fmt, args); va_end(args); return n; } diff --git a/libc/strtod.c b/libc/strtod.c index 6fb7879..1621483 100644 --- a/libc/strtod.c +++ b/libc/strtod.c @@ -1,6 +1,36 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include #include +#include +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" + +static ulong +umuldiv(ulong a, ulong b, ulong c) +{ + double d; + + d = ((double)a * (double)b) / (double)c; + if(d >= 4294967295.) + d = 4294967295.; + return (ulong)d; +} /* * This routine will convert to arbitrary precision @@ -17,46 +47,34 @@ */ enum { - Nbits = 28, // bits safely represented in a ulong - Nmant = 53, // bits of precision required - Bias = 1022, - Prec = (Nmant+Nbits+1)/Nbits, // words of Nbits each to represent mantissa - Sigbit = 1<<(Prec*Nbits-Nmant), // first significant bit of Prec-th word + Nbits = 28, /* bits safely represented in a ulong */ + Nmant = 53, /* bits of precision required */ + Prec = (Nmant+Nbits+1)/Nbits, /* words of Nbits each to represent mantissa */ + Sigbit = 1<<(Prec*Nbits-Nmant), /* first significant bit of Prec-th word */ Ndig = 1500, One = (ulong)(1<>1), Maxe = 310, - Fsign = 1<<0, // found - - Fesign = 1<<1, // found e- - Fdpoint = 1<<2, // found . - S0 = 0, // _ _S0 +S1 #S2 .S3 - S1, // _+ #S2 .S3 - S2, // _+# #S2 .S4 eS5 - S3, // _+. #S4 - S4, // _+#.# #S4 eS5 - S5, // _+#.#e +S6 #S7 - S6, // _+#.#e+ #S7 - S7, // _+#.#e+# #S7 + Fsign = 1<<0, /* found - */ + Fesign = 1<<1, /* found e- */ + Fdpoint = 1<<2, /* found . */ + + S0 = 0, /* _ _S0 +S1 #S2 .S3 */ + S1, /* _+ #S2 .S3 */ + S2, /* _+# #S2 .S4 eS5 */ + S3, /* _+. #S4 */ + S4, /* _+#.# #S4 eS5 */ + S5, /* _+#.#e +S6 #S7 */ + S6, /* _+#.#e+ #S7 */ + S7, /* _+#.#e+# #S7 */ }; -static ulong -umuldiv(ulong a, ulong b, ulong c) -{ - double d; - - d = ((double)a * (double)b) / (double)c; - if(d >= 4294967295.) - d = 4294967295.; - return d; -} - static int xcmp(char*, char*); static int fpcmp(char*, ulong*); static void frnorm(ulong*); static void divascii(char*, int*, int*, int*); static void mulascii(char*, int*, int*, int*); -static void divby(char*, int*, int); typedef struct Tab Tab; struct Tab @@ -67,20 +85,20 @@ struct Tab }; double -strtod(char *as, char **aas) +fmtstrtod(const char *as, char **aas) { - int na, ona, ex, dp, bp, c, i, flag, state; - ulong low[Prec], hig[Prec], mid[Prec], num, den; + int na, ex, dp, bp, c, i, flag, state; + ulong low[Prec], hig[Prec], mid[Prec]; double d; char *s, a[Ndig]; - flag = 0; // Fsign, Fesign, Fdpoint - na = 0; // number of digits of a[] - dp = 0; // na of decimal point - ex = 0; // exonent + flag = 0; /* Fsign, Fesign, Fdpoint */ + na = 0; /* number of digits of a[] */ + dp = 0; /* na of decimal point */ + ex = 0; /* exonent */ state = S0; - for(s=as;; s++) { + for(s=(char*)as;; s++) { c = *s; if(c >= '0' && c <= '9') { switch(state) { @@ -131,7 +149,7 @@ strtod(char *as, char **aas) if(state == S5) state = S6; else - break; // syntax + break; /* syntax */ continue; case '.': flag |= Fdpoint; @@ -179,12 +197,12 @@ strtod(char *as, char **aas) } case S3: if(aas != nil) - *aas = as; - goto ret0; // no digits found + *aas = (char*)as; + goto ret0; /* no digits found */ case S6: - s--; // back over +- + s--; /* back over +- */ case S5: - s--; // back over e + s--; /* back over e */ break; } if(aas != nil) @@ -194,55 +212,41 @@ strtod(char *as, char **aas) while(na > 0 && a[na-1] == '0') na--; if(na == 0) - goto ret0; // zero + goto ret0; /* zero */ a[na] = 0; if(!(flag & Fdpoint)) dp = na; if(flag & Fesign) ex = -ex; dp += ex; - if(dp < -Maxe-Nmant/3) /* actually -Nmant*log(2)/log(10), but Nmant/3 close enough */ - goto ret0; // underflow by exp - else + if(dp < -Maxe){ + errno = ERANGE; + goto ret0; /* underflow by exp */ + } else if(dp > +Maxe) - goto retinf; // overflow by exp + goto retinf; /* overflow by exp */ /* * normalize the decimal ascii number * to range .[5-9][0-9]* e0 */ - bp = 0; // binary exponent + bp = 0; /* binary exponent */ while(dp > 0) divascii(a, &na, &dp, &bp); while(dp < 0 || a[0] < '5') mulascii(a, &na, &dp, &bp); - a[na] = 0; - - /* - * very small numbers are represented using - * bp = -Bias+1. adjust accordingly. - */ - if(bp < -Bias+1){ - ona = na; - divby(a, &na, -bp-Bias+1); - if(na < ona){ - memmove(a+ona-na, a, na); - memset(a, '0', ona-na); - na = ona; - } - a[na] = 0; - bp = -Bias+1; - } /* close approx by naive conversion */ - num = 0; - den = 1; - for(i=0; i<9 && (c=a[i]); i++) { - num = num*10 + (c-'0'); - den *= 10; + mid[0] = 0; + mid[1] = 1; + for(i=0; c=a[i]; i++) { + mid[0] = mid[0]*10 + (c-'0'); + mid[1] = mid[1]*10; + if(i >= 8) + break; } - low[0] = umuldiv(num, One, den); - hig[0] = umuldiv(num+1, One, den); + low[0] = umuldiv(mid[0], One, mid[1]); + hig[0] = umuldiv(mid[0]+1, One, mid[1]); for(i=1; i 9){ - _divby(a, na, 9); - a[*na] = 0; - b -= 9; - } - if(b > 0) - _divby(a, na, b); -} - static Tab tab1[] = { 1, 0, "", @@ -443,8 +443,8 @@ divascii(char *a, int *na, int *dp, int *bp) Tab *t; d = *dp; - if(d >= nelem(tab1)) - d = nelem(tab1)-1; + if(d >= (int)(nelem(tab1))) + d = (int)(nelem(tab1))-1; t = tab1 + d; b = t->bp; if(memcmp(a, t->cmp, t->siz) > 0) @@ -483,7 +483,7 @@ mulby(char *a, char *p, char *q, int b) static Tab tab2[] = { - 1, 1, "", // dp = 0-0 + 1, 1, "", /* dp = 0-0 */ 3, 3, "125", 6, 5, "15625", 9, 7, "1953125", @@ -492,7 +492,7 @@ static Tab tab2[] = 19, 14, "19073486328125", 23, 17, "11920928955078125", 26, 19, "1490116119384765625", - 27, 19, "7450580596923828125", // dp 8-9 + 27, 19, "7450580596923828125", /* dp 8-9 */ }; static void @@ -503,8 +503,8 @@ mulascii(char *a, int *na, int *dp, int *bp) Tab *t; d = -*dp; - if(d >= nelem(tab2)) - d = nelem(tab2)-1; + if(d >= (int)(nelem(tab2))) + d = (int)(nelem(tab2))-1; t = tab2 + d; b = t->bp; if(memcmp(a, t->cmp, t->siz) < 0) diff --git a/libc/vfprint.c b/libc/vfprint.c index 9312915..e5a7da3 100644 --- a/libc/vfprint.c +++ b/libc/vfprint.c @@ -1,22 +1,20 @@ -#include -#include -#include "fmtdef.h" - /* - * generic routine for flushing a formatting buffer - * to a file descriptor + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */ -int -_fmtFdFlush(Fmt *f) -{ - int n; - - n = (char*)f->to - (char*)f->start; - if(n && write((int)f->farg, f->start, n) != n) - return 0; - f->to = f->start; - return 1; -} +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int vfprint(int fd, char *fmt, va_list args) @@ -26,9 +24,10 @@ vfprint(int fd, char *fmt, va_list args) int n; fmtfdinit(&f, fd, buf, sizeof(buf)); - f.args = args; + VA_COPY(f.args,args); n = dofmt(&f, fmt); - if(n > 0 && _fmtFdFlush(&f) == 0) + VA_END(f.args); + if(n > 0 && __fmtFdFlush(&f) == 0) return -1; return n; } diff --git a/libc/vseprint.c b/libc/vseprint.c index 72d02f7..b6dfee6 100644 --- a/libc/vseprint.c +++ b/libc/vseprint.c @@ -1,5 +1,20 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" char* vseprint(char *buf, char *e, char *fmt, va_list args) @@ -12,12 +27,13 @@ vseprint(char *buf, char *e, char *fmt, va_list args) f.start = buf; f.to = buf; f.stop = e - 1; - f.flush = nil; + f.flush = 0; f.farg = nil; f.nfmt = 0; - f.args = args; + VA_COPY(f.args,args); dofmt(&f, fmt); + VA_END(f.args); *(char*)f.to = '\0'; - return f.to; + return (char*)f.to; } diff --git a/libc/vsmprint.c b/libc/vsmprint.c index 865c2dd..6f49373 100644 --- a/libc/vsmprint.c +++ b/libc/vsmprint.c @@ -1,6 +1,32 @@ +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +/* + * Plan 9 port version must include libc.h in order to + * get Plan 9 debugging malloc, which sometimes returns + * different pointers than the standard malloc. + */ +#ifdef PLAN9PORT #include #include #include "fmtdef.h" +#else +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" +#endif static int fmtStrFlush(Fmt *f) @@ -10,9 +36,9 @@ fmtStrFlush(Fmt *f) if(f->start == nil) return 0; - n = (int)f->farg; + n = (uintptr)f->farg; n *= 2; - s = f->start; + s = (char*)f->start; f->start = realloc(s, n); if(f->start == nil){ f->farg = nil; @@ -21,7 +47,7 @@ fmtStrFlush(Fmt *f) free(s); return 0; } - f->farg = (void*)n; + f->farg = (void*)(uintptr)n; f->to = (char*)f->start + ((char*)f->to - s); f->stop = (char*)f->start + n - 1; return 1; @@ -41,7 +67,7 @@ fmtstrinit(Fmt *f) f->to = f->start; f->stop = (char*)f->start + n - 1; f->flush = fmtStrFlush; - f->farg = (void*)n; + f->farg = (void*)(uintptr)n; f->nfmt = 0; return 0; } @@ -57,14 +83,12 @@ vsmprint(char *fmt, va_list args) if(fmtstrinit(&f) < 0) return nil; - f.args = args; + VA_COPY(f.args,args); n = dofmt(&f, fmt); - if(f.start == nil) - return nil; + VA_END(f.args); if(n < 0){ free(f.start); return nil; } - *(char*)f.to = '\0'; - return f.start; + return fmtstrflush(&f); } diff --git a/libc/vsnprint.c b/libc/vsnprint.c index bd20496..ed70325 100644 --- a/libc/vsnprint.c +++ b/libc/vsnprint.c @@ -1,5 +1,21 @@ -#include -#include +/* + * The authors of this software are Rob Pike and Ken Thompson. + * Copyright (c) 2002 by Lucent Technologies. + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE + * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + */ +#include +#include +#include "plan9.h" +#include "fmt.h" +#include "fmtdef.h" int vsnprint(char *buf, int len, char *fmt, va_list args) @@ -12,11 +28,12 @@ vsnprint(char *buf, int len, char *fmt, va_list args) f.start = buf; f.to = buf; f.stop = buf + len - 1; - f.flush = nil; + f.flush = 0; f.farg = nil; f.nfmt = 0; - f.args = args; + VA_COPY(f.args,args); dofmt(&f, fmt); + VA_END(f.args); *(char*)f.to = '\0'; return (char*)f.to - buf; }