updates from p9p

This commit is contained in:
Russ Cox 2006-01-17 12:37:52 +00:00
parent c0c120e2d1
commit 001d391fa7
35 changed files with 1126 additions and 483 deletions

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
/* /*
* Reads a floating-point number by interpreting successive characters * 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. * 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 double
charstod(int(*f)(void*), void *vp) fmtcharstod(int(*f)(void*), void *vp)
{ {
char str[400], *s, *e, *start; double num, dem;
int c; 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); c = (*f)(vp);
while(c == ' ' || c == '\t') while(c == ' ' || c == '\t')
c = (*f)(vp); c = (*f)(vp);
if(c == '-' || c == '+'){ if(c == '-' || c == '+'){
ADVANCE; if(c == '-')
neg = 1;
c = (*f)(vp);
} }
start = s;
while(c >= '0' && c <= '9'){ while(c >= '0' && c <= '9'){
ADVANCE; num = num*10 + c-'0';
c = (*f)(vp);
} }
if(c == '.'){ if(c == '.')
ADVANCE; c = (*f)(vp);
while(c >= '0' && c <= '9'){ while(c >= '0' && c <= '9'){
ADVANCE; num = num*10 + c-'0';
} dig++;
c = (*f)(vp);
} }
if(s > start && (c == 'e' || c == 'E')){ if(c == 'e' || c == 'E'){
ADVANCE; c = (*f)(vp);
if(c == '-' || c == '+'){ if(c == '-' || c == '+'){
ADVANCE; if(c == '-'){
dig = -dig;
eneg = 1;
}
c = (*f)(vp);
} }
while(c >= '0' && c <= '9'){ 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; exp -= dig;
return strtod(str, &s); if(exp < 0){
exp = -exp;
eneg = !eneg;
}
dem = __fmtpow10(exp);
if(eneg)
num /= dem;
else
num *= dem;
if(neg)
return -num;
return num;
} }

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
/* format the output into f->to and return the number of characters fmted */ /* 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; nfmt = f->nfmt;
for(;;){ for(;;){
if(f->runes){ if(f->runes){
rt = f->to; rt = (Rune*)f->to;
rs = f->stop; rs = (Rune*)f->stop;
while((r = *(uchar*)fmt) && r != '%'){ while((r = *(uchar*)fmt) && r != '%'){
if(r < Runeself) if(r < Runeself)
fmt++; fmt++;
@ -32,8 +47,8 @@ dofmt(Fmt *f, char *fmt)
return f->nfmt - nfmt; return f->nfmt - nfmt;
f->stop = rs; f->stop = rs;
}else{ }else{
t = f->to; t = (char*)f->to;
s = f->stop; s = (char*)f->stop;
while((r = *(uchar*)fmt) && r != '%'){ while((r = *(uchar*)fmt) && r != '%'){
if(r < Runeself){ if(r < Runeself){
FMTCHAR(f, t, s, r); FMTCHAR(f, t, s, r);
@ -41,9 +56,9 @@ dofmt(Fmt *f, char *fmt)
}else{ }else{
n = chartorune(&rune, fmt); n = chartorune(&rune, fmt);
if(t + n > s){ if(t + n > s){
t = _fmtflush(f, t, n); t = (char*)__fmtflush(f, t, n);
if(t != nil) if(t != nil)
s = f->stop; s = (char*)f->stop;
else else
return -1; return -1;
} }
@ -59,15 +74,14 @@ dofmt(Fmt *f, char *fmt)
f->stop = s; f->stop = s;
} }
fmt = _fmtdispatch(f, fmt, 0); fmt = (char*)__fmtdispatch(f, fmt, 0);
if(fmt == nil) if(fmt == nil)
return -1; return -1;
} }
return 0; /* not reached */
} }
void * void *
_fmtflush(Fmt *f, void *t, int len) __fmtflush(Fmt *f, void *t, int len)
{ {
if(f->runes) if(f->runes)
f->nfmt += (Rune*)t - (Rune*)f->to; 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 * left/right justified in a field of at least f->width charactes
*/ */
int int
_fmtpad(Fmt *f, int n) __fmtpad(Fmt *f, int n)
{ {
char *t, *s; char *t, *s;
int i; int i;
t = f->to; t = (char*)f->to;
s = f->stop; s = (char*)f->stop;
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
FMTCHAR(f, t, s, ' '); FMTCHAR(f, t, s, ' ');
f->nfmt += t - (char *)f->to; f->nfmt += t - (char *)f->to;
@ -101,13 +115,13 @@ _fmtpad(Fmt *f, int n)
} }
int int
_rfmtpad(Fmt *f, int n) __rfmtpad(Fmt *f, int n)
{ {
Rune *t, *s; Rune *t, *s;
int i; int i;
t = f->to; t = (Rune*)f->to;
s = f->stop; s = (Rune*)f->stop;
for(i = 0; i < n; i++) for(i = 0; i < n; i++)
FMTRCHAR(f, t, s, ' '); FMTRCHAR(f, t, s, ' ');
f->nfmt += t - (Rune *)f->to; f->nfmt += t - (Rune *)f->to;
@ -116,24 +130,24 @@ _rfmtpad(Fmt *f, int n)
} }
int int
_fmtcpy(Fmt *f, void *vm, int n, int sz) __fmtcpy(Fmt *f, const void *vm, int n, int sz)
{ {
Rune *rt, *rs, r; Rune *rt, *rs, r;
char *t, *s, *m, *me; char *t, *s, *m, *me;
ulong fl; ulong fl;
int nc, w; int nc, w;
m = vm; m = (char*)vm;
me = m + sz; me = m + sz;
w = f->width; w = f->width;
fl = f->flags; fl = f->flags;
if((fl & FmtPrec) && n > f->prec) if((fl & FmtPrec) && n > f->prec)
n = f->prec; n = f->prec;
if(f->runes){ if(f->runes){
if(!(fl & FmtLeft) && _rfmtpad(f, w - n) < 0) if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
return -1; return -1;
rt = f->to; rt = (Rune*)f->to;
rs = f->stop; rs = (Rune*)f->stop;
for(nc = n; nc > 0; nc--){ for(nc = n; nc > 0; nc--){
r = *(uchar*)m; r = *(uchar*)m;
if(r < Runeself) if(r < Runeself)
@ -146,15 +160,13 @@ _fmtcpy(Fmt *f, void *vm, int n, int sz)
} }
f->nfmt += rt - (Rune *)f->to; f->nfmt += rt - (Rune *)f->to;
f->to = rt; f->to = rt;
if(m < me) if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
return -1;
if(fl & FmtLeft && _rfmtpad(f, w - n) < 0)
return -1; return -1;
}else{ }else{
if(!(fl & FmtLeft) && _fmtpad(f, w - n) < 0) if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
return -1; return -1;
t = f->to; t = (char*)f->to;
s = f->stop; s = (char*)f->stop;
for(nc = n; nc > 0; nc--){ for(nc = n; nc > 0; nc--){
r = *(uchar*)m; r = *(uchar*)m;
if(r < Runeself) if(r < Runeself)
@ -167,48 +179,48 @@ _fmtcpy(Fmt *f, void *vm, int n, int sz)
} }
f->nfmt += t - (char *)f->to; f->nfmt += t - (char *)f->to;
f->to = t; f->to = t;
if(fl & FmtLeft && _fmtpad(f, w - n) < 0) if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
return -1; return -1;
} }
return 0; return 0;
} }
int int
_fmtrcpy(Fmt *f, void *vm, int n) __fmtrcpy(Fmt *f, const void *vm, int n)
{ {
Rune r, *m, *me, *rt, *rs; Rune r, *m, *me, *rt, *rs;
char *t, *s; char *t, *s;
ulong fl; ulong fl;
int w; int w;
m = vm; m = (Rune*)vm;
w = f->width; w = f->width;
fl = f->flags; fl = f->flags;
if((fl & FmtPrec) && n > f->prec) if((fl & FmtPrec) && n > f->prec)
n = f->prec; n = f->prec;
if(f->runes){ if(f->runes){
if(!(fl & FmtLeft) && _rfmtpad(f, w - n) < 0) if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)
return -1; return -1;
rt = f->to; rt = (Rune*)f->to;
rs = f->stop; rs = (Rune*)f->stop;
for(me = m + n; m < me; m++) for(me = m + n; m < me; m++)
FMTRCHAR(f, rt, rs, *m); FMTRCHAR(f, rt, rs, *m);
f->nfmt += rt - (Rune *)f->to; f->nfmt += rt - (Rune *)f->to;
f->to = rt; f->to = rt;
if(fl & FmtLeft && _rfmtpad(f, w - n) < 0) if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)
return -1; return -1;
}else{ }else{
if(!(fl & FmtLeft) && _fmtpad(f, w - n) < 0) if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)
return -1; return -1;
t = f->to; t = (char*)f->to;
s = f->stop; s = (char*)f->stop;
for(me = m + n; m < me; m++){ for(me = m + n; m < me; m++){
r = *m; r = *m;
FMTRUNE(f, t, s, r); FMTRUNE(f, t, s, r);
} }
f->nfmt += t - (char *)f->to; f->nfmt += t - (char *)f->to;
f->to = t; f->to = t;
if(fl & FmtLeft && _fmtpad(f, w - n) < 0) if(fl & FmtLeft && __fmtpad(f, w - n) < 0)
return -1; return -1;
} }
return 0; return 0;
@ -216,47 +228,47 @@ _fmtrcpy(Fmt *f, void *vm, int n)
/* fmt out one character */ /* fmt out one character */
int int
_charfmt(Fmt *f) __charfmt(Fmt *f)
{ {
char x[1]; char x[1];
x[0] = va_arg(f->args, int); x[0] = va_arg(f->args, int);
f->prec = 1; f->prec = 1;
return _fmtcpy(f, x, 1, 1); return __fmtcpy(f, (const char*)x, 1, 1);
} }
/* fmt out one rune */ /* fmt out one rune */
int int
_runefmt(Fmt *f) __runefmt(Fmt *f)
{ {
Rune x[1]; Rune x[1];
x[0] = va_arg(f->args, int); 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 */ /* public helper routine: fmt out a null terminated string already in hand */
int int
fmtstrcpy(Fmt *f, char *s) fmtstrcpy(Fmt *f, char *s)
{ {
int p, i; int i, j;
Rune r;
if(!s) if(!s)
return _fmtcpy(f, "<nil>", 5, 5); return __fmtcpy(f, "<nil>", 5, 5);
/* if precision is specified, make sure we don't wander off the end */ /* if precision is specified, make sure we don't wander off the end */
if(f->flags & FmtPrec){ if(f->flags & FmtPrec){
p = f->prec; i = 0;
for(i = 0; i < p; i++) for(j=0; j<f->prec && s[i]; j++)
if(s[i] == 0) i += chartorune(&r, s+i);
break; return __fmtcpy(f, s, j, i);
return _fmtcpy(f, s, utfnlen(s, i), i); /* BUG?: won't print a partial rune at end */
} }
return __fmtcpy(f, s, utflen(s), strlen(s));
return _fmtcpy(f, s, utflen(s), strlen(s));
} }
/* fmt out a null terminated utf string */ /* fmt out a null terminated utf string */
int int
_strfmt(Fmt *f) __strfmt(Fmt *f)
{ {
char *s; char *s;
@ -272,7 +284,7 @@ fmtrunestrcpy(Fmt *f, Rune *s)
int n, p; int n, p;
if(!s) if(!s)
return _fmtcpy(f, "<nil>", 5, 5); return __fmtcpy(f, "<nil>", 5, 5);
/* if precision is specified, make sure we don't wander off the end */ /* if precision is specified, make sure we don't wander off the end */
if(f->flags & FmtPrec){ if(f->flags & FmtPrec){
p = f->prec; p = f->prec;
@ -284,12 +296,12 @@ fmtrunestrcpy(Fmt *f, Rune *s)
; ;
n = e - s; n = e - s;
} }
return _fmtrcpy(f, s, n); return __fmtrcpy(f, s, n);
} }
/* fmt out a null terminated rune string */ /* fmt out a null terminated rune string */
int int
_runesfmt(Fmt *f) __runesfmt(Fmt *f)
{ {
Rune *s; Rune *s;
@ -299,18 +311,18 @@ _runesfmt(Fmt *f)
/* fmt a % */ /* fmt a % */
int int
_percentfmt(Fmt *f) __percentfmt(Fmt *f)
{ {
Rune x[1]; Rune x[1];
x[0] = f->r; x[0] = f->r;
f->prec = 1; f->prec = 1;
return _fmtrcpy(f, x, 1); return __fmtrcpy(f, (const void*)x, 1);
} }
/* fmt an integer */ /* fmt an integer */
int int
_ifmt(Fmt *f) __ifmt(Fmt *f)
{ {
char buf[70], *p, *conv; char buf[70], *p, *conv;
uvlong vu; uvlong vu;
@ -322,6 +334,21 @@ _ifmt(Fmt *f)
isv = 0; isv = 0;
vu = 0; vu = 0;
u = 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'){ if(f->r == 'p'){
u = (ulong)va_arg(f->args, void*); u = (ulong)va_arg(f->args, void*);
f->r = 'x'; f->r = 'x';
@ -356,6 +383,8 @@ _ifmt(Fmt *f)
conv = "0123456789abcdef"; conv = "0123456789abcdef";
switch(f->r){ switch(f->r){
case 'd': case 'd':
case 'i':
case 'u':
base = 10; base = 10;
break; break;
case 'x': case 'x':
@ -426,7 +455,7 @@ _ifmt(Fmt *f)
n++; n++;
} }
} }
if((fl & FmtZero) && !(fl & FmtLeft)){ if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
for(w = f->width; n < w && p > buf+3; n++) for(w = f->width; n < w && p > buf+3; n++)
*p-- = '0'; *p-- = '0';
f->width = 0; f->width = 0;
@ -444,11 +473,11 @@ _ifmt(Fmt *f)
else if(fl & FmtSpace) else if(fl & FmtSpace)
*p-- = ' '; *p-- = ' ';
f->flags &= ~FmtPrec; f->flags &= ~FmtPrec;
return _fmtcpy(f, p + 1, n, n); return __fmtcpy(f, p + 1, n, n);
} }
int int
_countfmt(Fmt *f) __countfmt(Fmt *f)
{ {
void *p; void *p;
ulong fl; ulong fl;
@ -470,7 +499,7 @@ _countfmt(Fmt *f)
} }
int int
_flagfmt(Fmt *f) __flagfmt(Fmt *f)
{ {
switch(f->r){ switch(f->r){
case ',': case ',':
@ -496,6 +525,9 @@ _flagfmt(Fmt *f)
f->flags |= FmtByte; f->flags |= FmtByte;
f->flags |= FmtShort; f->flags |= FmtShort;
break; break;
case 'L':
f->flags |= FmtLDouble;
break;
case 'l': case 'l':
if(f->flags & FmtLong) if(f->flags & FmtLong)
f->flags |= FmtVLong; f->flags |= FmtVLong;
@ -507,7 +539,7 @@ _flagfmt(Fmt *f)
/* default error format */ /* default error format */
int int
_badfmt(Fmt *f) __badfmt(Fmt *f)
{ {
char x[3]; char x[3];
@ -515,6 +547,6 @@ _badfmt(Fmt *f)
x[1] = f->r; x[1] = f->r;
x[2] = '%'; x[2] = '%';
f->prec = 3; f->prec = 3;
_fmtcpy(f, x, 3, 3); __fmtcpy(f, (const void*)x, 3, 3);
return 0; return 0;
} }

View File

@ -1,11 +1,26 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
/* format the output into f->to and return the number of characters fmted */ /* format the output into f->to and return the number of characters fmted */
int int
dorfmt(Fmt *f, Rune *fmt) dorfmt(Fmt *f, const Rune *fmt)
{ {
Rune *rt, *rs; Rune *rt, *rs;
int r; int r;
@ -38,7 +53,7 @@ dorfmt(Fmt *f, Rune *fmt)
f->stop = s; f->stop = s;
} }
fmt = _fmtdispatch(f, fmt, 1); fmt = __fmtdispatch(f, (Rune*)fmt, 1);
if(fmt == nil) if(fmt == nil)
return -1; return -1;
} }

View File

@ -1,12 +1,28 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <errno.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
int int
errfmt(Fmt *f) __errfmt(Fmt *f)
{ {
char buf[ERRMAX]; char *s;
rerrstr(buf, sizeof buf); s = strerror(errno);
return _fmtcpy(f, buf, utflen(buf), strlen(buf)); return fmtstrcpy(f, s);
} }

View File

@ -1,15 +1,97 @@
#include <u.h> /*
#include <libc.h> * 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 <stdio.h>
#include <math.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <ctype.h> #include <ctype.h>
#include <fmt.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
enum enum
{ {
FDIGIT = 30, FDIGIT = 30,
FDEFLT = 6, 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 static int
xadd(char *a, int n, int v) xadd(char *a, int n, int v)
{ {
@ -27,7 +109,7 @@ xadd(char *a, int n, int v)
*b = '0'; *b = '0';
v = 1; v = 1;
} }
*a = '1'; // overflow adding *a = '1'; /* overflow adding */
return 1; return 1;
} }
@ -46,7 +128,7 @@ xsub(char *a, int n, int v)
*b = '9'; *b = '9';
v = 1; v = 1;
} }
*a = '9'; // underflow subtracting *a = '9'; /* underflow subtracting */
return 1; return 1;
} }
@ -291,22 +373,22 @@ found:
s2[d] = 0; s2[d] = 0;
} }
int static int
_floatfmt(Fmt *fmt, double f) floatfmt(Fmt *fmt, double f)
{ {
char s[FDIGIT+10]; char s[341]; /* precision+exponent+sign+'.'+null */
xdtoa(fmt, s, f); xdtoa(fmt, s, f);
fmt->flags &= FmtWidth|FmtLeft; fmt->flags &= FmtWidth|FmtLeft;
_fmtcpy(fmt, s, strlen(s), strlen(s)); __fmtcpy(fmt, s, strlen(s), strlen(s));
return 0; return 0;
} }
int int
_efgfmt(Fmt *f) __efgfmt(Fmt *f)
{ {
double d; double d;
d = va_arg(f->args, double); d = va_arg(f->args, double);
return _floatfmt(f, d); return floatfmt(f, d);
} }

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
enum enum
@ -16,55 +31,69 @@ struct Convfmt
struct struct
{ {
/* lock by calling _fmtlock, _fmtunlock */ /* lock by calling __fmtlock, __fmtunlock */
int nfmt; int nfmt;
Convfmt fmt[Maxfmt]; Convfmt fmt[Maxfmt];
} fmtalloc; } fmtalloc;
static Convfmt knownfmt[] = { static Convfmt knownfmt[] = {
' ', _flagfmt, ' ', __flagfmt,
'#', _flagfmt, '#', __flagfmt,
'%', _percentfmt, '%', __percentfmt,
'+', _flagfmt, '+', __flagfmt,
',', _flagfmt, ',', __flagfmt,
'-', _flagfmt, '-', __flagfmt,
'C', _runefmt, 'C', __runefmt, /* Plan 9 addition */
'E', _efgfmt, 'E', __efgfmt,
'G', _efgfmt, #ifndef PLAN9PORT
'S', _runesfmt, 'F', __efgfmt, /* ANSI only */
'X', _ifmt, #endif
'b', _ifmt, 'G', __efgfmt,
'c', _charfmt, #ifndef PLAN9PORT
'd', _ifmt, 'L', __flagfmt, /* ANSI only */
'e', _efgfmt, #endif
'f', _efgfmt, 'S', __runesfmt, /* Plan 9 addition */
'g', _efgfmt, 'X', __ifmt,
'h', _flagfmt, 'b', __ifmt, /* Plan 9 addition */
'l', _flagfmt, 'c', __charfmt,
'n', _countfmt, 'd', __ifmt,
'o', _ifmt, 'e', __efgfmt,
'p', _ifmt, 'f', __efgfmt,
/* 'r', errfmt, */ 'g', __efgfmt,
's', _strfmt, 'h', __flagfmt,
'u', _flagfmt, #ifndef PLAN9PORT
'x', _ifmt, '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, 0, nil,
}; };
int (*doquote)(int);
int (*fmtdoquote)(int);
/* /*
* _fmtlock() must be set * __fmtlock() must be set
*/ */
static int static int
_fmtinstall(int c, Fmts f) __fmtinstall(int c, Fmts f)
{ {
Convfmt *p, *ep; Convfmt *p, *ep;
if(c<=0 || c>=65536) if(c<=0 || c>=65536)
return -1; return -1;
if(!f) if(!f)
f = _badfmt; f = __badfmt;
ep = &fmtalloc.fmt[fmtalloc.nfmt]; ep = &fmtalloc.fmt[fmtalloc.nfmt];
for(p=fmtalloc.fmt; p<ep; p++) for(p=fmtalloc.fmt; p<ep; p++)
@ -84,13 +113,13 @@ _fmtinstall(int c, Fmts f)
} }
int int
fmtinstall(int c, Fmts f) fmtinstall(int c, int (*f)(Fmt*))
{ {
int ret; int ret;
_fmtlock(); __fmtlock();
ret = _fmtinstall(c, f); ret = __fmtinstall(c, f);
_fmtunlock(); __fmtunlock();
return ret; return ret;
} }
@ -108,20 +137,20 @@ fmtfmt(int c)
} }
/* is this a predefined format char? */ /* is this a predefined format char? */
_fmtlock(); __fmtlock();
for(p=knownfmt; p->c; p++) for(p=knownfmt; p->c; p++)
if(p->c == c){ if(p->c == c){
_fmtinstall(p->c, p->fmt); __fmtinstall(p->c, p->fmt);
_fmtunlock(); __fmtunlock();
return p->fmt; return p->fmt;
} }
_fmtunlock(); __fmtunlock();
return _badfmt; return __badfmt;
} }
void* void*
_fmtdispatch(Fmt *f, void *fmt, int isrunes) __fmtdispatch(Fmt *f, void *fmt, int isrunes)
{ {
Rune rune, r; Rune rune, r;
int i, n; int i, n;
@ -134,7 +163,7 @@ _fmtdispatch(Fmt *f, void *fmt, int isrunes)
r = *(Rune*)fmt; r = *(Rune*)fmt;
fmt = (Rune*)fmt + 1; fmt = (Rune*)fmt + 1;
}else{ }else{
fmt = (char*)fmt + chartorune(&rune, fmt); fmt = (char*)fmt + chartorune(&rune, (char*)fmt);
r = rune; r = rune;
} }
f->r = r; f->r = r;
@ -179,6 +208,15 @@ _fmtdispatch(Fmt *f, void *fmt, int isrunes)
case '*': case '*':
i = va_arg(f->args, int); i = va_arg(f->args, int);
if(i < 0){ if(i < 0){
/*
* negative precision =>
* ignore the precision.
*/
if(f->flags & FmtPrec){
f->flags &= ~FmtPrec;
f->prec = 0;
continue;
}
i = -i; i = -i;
f->flags |= FmtLeft; f->flags |= FmtLeft;
} }

View File

@ -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 * dofmt -- format to a buffer
* the number of characters formatted is returned, * the number of characters formatted is returned,
@ -18,33 +32,41 @@ struct Quoteinfo
int nbytesout; /* number of bytes that will be generated */ int nbytesout; /* number of bytes that will be generated */
}; };
void *_fmtflush(Fmt*, void*, int); /* Edit .+1,/^$/ |cfn |grep -v static | grep __ */
void *_fmtdispatch(Fmt*, void*, int); double __Inf(int sign);
int _floatfmt(Fmt*, double); double __NaN(void);
int _fmtpad(Fmt*, int); int __badfmt(Fmt *f);
int _rfmtpad(Fmt*, int); int __charfmt(Fmt *f);
int _fmtFdFlush(Fmt*); int __countfmt(Fmt *f);
int __efgfmt(Fmt *fmt);
int _efgfmt(Fmt*); int __errfmt(Fmt *f);
int _charfmt(Fmt*); int __flagfmt(Fmt *f);
int _countfmt(Fmt*); int __fmtFdFlush(Fmt *f);
int _flagfmt(Fmt*); int __fmtcpy(Fmt *f, const void *vm, int n, int sz);
int _percentfmt(Fmt*); void* __fmtdispatch(Fmt *f, void *fmt, int isrunes);
int _ifmt(Fmt*); void * __fmtflush(Fmt *f, void *t, int len);
int _runefmt(Fmt*); void __fmtlock(void);
int _runesfmt(Fmt*); int __fmtpad(Fmt *f, int n);
int _strfmt(Fmt*); double __fmtpow10(int n);
int _badfmt(Fmt*); int __fmtrcpy(Fmt *f, const void *vm, int n);
int _fmtcpy(Fmt*, void*, int, int); void __fmtunlock(void);
int _fmtrcpy(Fmt*, void*, int n); int __ifmt(Fmt *f);
int __isInf(double d, int sign);
void _fmtlock(void); int __isNaN(double d);
void _fmtunlock(void); 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)\ #define FMTCHAR(f, t, s, c)\
do{\ do{\
if(t + 1 > (char*)s){\ if(t + 1 > (char*)s){\
t = _fmtflush(f, t, 1);\ t = __fmtflush(f, t, 1);\
if(t != nil)\ if(t != nil)\
s = f->stop;\ s = f->stop;\
else\ else\
@ -56,7 +78,7 @@ void _fmtunlock(void);
#define FMTRCHAR(f, t, s, c)\ #define FMTRCHAR(f, t, s, c)\
do{\ do{\
if(t + 1 > (Rune*)s){\ if(t + 1 > (Rune*)s){\
t = _fmtflush(f, t, sizeof(Rune));\ t = __fmtflush(f, t, sizeof(Rune));\
if(t != nil)\ if(t != nil)\
s = f->stop;\ s = f->stop;\
else\ else\
@ -70,7 +92,7 @@ void _fmtunlock(void);
Rune _rune;\ Rune _rune;\
int _runelen;\ int _runelen;\
if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\ if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\
t = _fmtflush(f, t, _runelen);\ t = __fmtflush(f, t, _runelen);\
if(t != nil)\ if(t != nil)\
s = f->stop;\ s = f->stop;\
else\ else\
@ -83,3 +105,12 @@ void _fmtunlock(void);
t += runetochar(t, &_rune);\ t += runetochar(t, &_rune);\
}\ }\
}while(0) }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

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
/* /*
@ -9,7 +24,7 @@
int int
fmtfdflush(Fmt *f) fmtfdflush(Fmt *f)
{ {
if(_fmtFdFlush(f) <= 0) if(__fmtFdFlush(f) <= 0)
return -1; return -1;
return f->nfmt; return f->nfmt;
} }
@ -24,8 +39,8 @@ fmtfdinit(Fmt *f, int fd, char *buf, int size)
f->start = buf; f->start = buf;
f->to = buf; f->to = buf;
f->stop = buf + size; f->stop = buf + size;
f->flush = _fmtFdFlush; f->flush = __fmtFdFlush;
f->farg = (void*)fd; f->farg = (void*)(uintptr_t)fd;
f->nfmt = 0; f->nfmt = 0;
return 0; return 0;
} }

View File

@ -1,16 +1,27 @@
#include <u.h> /*
#include <libc.h> * The authors of this software are Rob Pike and Ken Thompson.
* Copyright (c) 2002 by Lucent Technologies.
static Lock fmtl; * 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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
void void
_fmtlock(void) __fmtlock(void)
{ {
lock(&fmtl);
} }
void void
_fmtunlock(void) __fmtunlock(void)
{ {
unlock(&fmtl);
} }

View File

@ -1,8 +1,22 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
/* /*
* format a string into the output buffer * format a string into the output buffer
* designed for formats which themselves call fmt, * designed for formats which themselves call fmt,
@ -17,14 +31,16 @@ fmtprint(Fmt *f, char *fmt, ...)
f->flags = 0; f->flags = 0;
f->width = 0; f->width = 0;
f->prec = 0; f->prec = 0;
va = f->args; VA_COPY(va, f->args);
VA_END(f->args);
va_start(f->args, fmt); va_start(f->args, fmt);
n = dofmt(f, fmt); n = dofmt(f, fmt);
va_end(f->args); va_end(f->args);
f->flags = 0; f->flags = 0;
f->width = 0; f->width = 0;
f->prec = 0; f->prec = 0;
f->args = va; VA_COPY(f->args,va);
VA_END(va);
if(n >= 0) if(n >= 0)
return 0; return 0;
return n; return n;

View File

@ -1,11 +1,26 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
/* /*
* How many bytes of output UTF will be produced by quoting (if necessary) this string? * 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? * 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). * The string may be UTF or Runes (s or r).
* Return count does not include NUL. * Return count does not include NUL.
* Terminate the scan at the first of: * Terminate the scan at the first of:
@ -16,7 +31,7 @@
* nin may be <0 initially, to avoid checking input by count. * nin may be <0 initially, to avoid checking input by count.
*/ */
void 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; int w;
Rune c; 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->nbytesout = 2;
q->nrunesout = 2; q->nrunesout = 2;
} }
for(; nin!=0; nin-=w){ for(; nin!=0; nin--){
if(s) if(s)
w = chartorune(&c, s); w = chartorune(&c, s);
else{ else{
@ -51,7 +66,7 @@ _quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int ru
break; break;
} }
if((c <= L' ') || (c == L'\'') || (doquote!=nil && doquote(c))){ if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){
if(!q->quoted){ if(!q->quoted){
if(runesout){ if(runesout){
if(1+q->nrunesout+1+1 > nout) /* no room for quotes */ 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; w = f->width;
fl = f->flags; fl = f->flags;
if(f->runes){ if(f->runes){
if(!(fl & FmtLeft) && _rfmtpad(f, w - q->nrunesout) < 0) if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
return -1; return -1;
}else{ }else{
if(!(fl & FmtLeft) && _fmtpad(f, w - q->nbytesout) < 0) if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
return -1; return -1;
} }
t = f->to; t = (char*)f->to;
s = f->stop; s = (char*)f->stop;
rt = f->to; rt = (Rune*)f->to;
rs = f->stop; rs = (Rune*)f->stop;
if(f->runes) if(f->runes)
FMTRCHAR(f, rt, rs, '\''); FMTRCHAR(f, rt, rs, '\'');
else else
@ -152,28 +167,30 @@ qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
USED(rs); USED(rs);
f->nfmt += rt - (Rune *)f->to; f->nfmt += rt - (Rune *)f->to;
f->to = rt; f->to = rt;
if(fl & FmtLeft && _rfmtpad(f, w - q->nrunesout) < 0) if(fl & FmtLeft && __rfmtpad(f, w - q->nrunesout) < 0)
return -1; return -1;
}else{ }else{
FMTRUNE(f, t, s, '\''); FMTRUNE(f, t, s, '\'');
USED(s); USED(s);
f->nfmt += t - (char *)f->to; f->nfmt += t - (char *)f->to;
f->to = t; f->to = t;
if(fl & FmtLeft && _fmtpad(f, w - q->nbytesout) < 0) if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
return -1; return -1;
} }
return 0; return 0;
} }
int int
_quotestrfmt(int runesin, Fmt *f) __quotestrfmt(int runesin, Fmt *f)
{ {
int outlen; int nin, outlen;
Rune *r; Rune *r;
char *s; char *s;
Quoteinfo q; 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){ if(runesin){
r = va_arg(f->args, Rune *); r = va_arg(f->args, Rune *);
s = nil; s = nil;
@ -182,7 +199,7 @@ _quotestrfmt(int runesin, Fmt *f)
r = nil; r = nil;
} }
if(!s && !r) if(!s && !r)
return _fmtcpy(f, "<nil>", 5, 5); return __fmtcpy(f, (void*)"<nil>", 5, 5);
if(f->flush) if(f->flush)
outlen = 0x7FFFFFFF; /* if we can flush, no output limit */ outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
@ -191,30 +208,30 @@ _quotestrfmt(int runesin, Fmt *f)
else else
outlen = (char*)f->stop - (char*)f->to; 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); //print("bytes in %d bytes out %d runes in %d runesout %d\n", q.nbytesin, q.nbytesout, q.nrunesin, q.nrunesout);
if(runesin){ if(runesin){
if(!q.quoted) if(!q.quoted)
return _fmtrcpy(f, r, q.nrunesin); return __fmtrcpy(f, r, q.nrunesin);
return qstrfmt(nil, r, &q, f); return qstrfmt(nil, r, &q, f);
} }
if(!q.quoted) 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); return qstrfmt(s, nil, &q, f);
} }
int int
quotestrfmt(Fmt *f) quotestrfmt(Fmt *f)
{ {
return _quotestrfmt(0, f); return __quotestrfmt(0, f);
} }
int int
quoterunestrfmt(Fmt *f) quoterunestrfmt(Fmt *f)
{ {
return _quotestrfmt(1, f); return __quotestrfmt(1, f);
} }
void void
@ -225,22 +242,22 @@ quotefmtinstall(void)
} }
int int
_needsquotes(char *s, int *quotelenp) __needsquotes(char *s, int *quotelenp)
{ {
Quoteinfo q; Quoteinfo q;
_quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0); __quotesetup(s, nil, -1, 0x7FFFFFFF, &q, 0, 0);
*quotelenp = q.nbytesout; *quotelenp = q.nbytesout;
return q.quoted; return q.quoted;
} }
int int
_runeneedsquotes(Rune *r, int *quotelenp) __runeneedsquotes(Rune *r, int *quotelenp)
{ {
Quoteinfo q; Quoteinfo q;
_quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0); __quotesetup(nil, r, -1, 0x7FFFFFFF, &q, 0, 0);
*quotelenp = q.nrunesout; *quotelenp = q.nrunesout;
return q.quoted; return q.quoted;

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
int int
@ -10,12 +25,12 @@ fmtrune(Fmt *f, int r)
int n; int n;
if(f->runes){ if(f->runes){
rt = f->to; rt = (Rune*)f->to;
FMTRCHAR(f, rt, f->stop, r); FMTRCHAR(f, rt, f->stop, r);
f->to = rt; f->to = rt;
n = 1; n = 1;
}else{ }else{
t = f->to; t = (char*)f->to;
FMTRUNE(f, t, f->stop, r); FMTRUNE(f, t, f->stop, r);
n = t - (char*)f->to; n = t - (char*)f->to;
f->to = t; f->to = t;

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdlib.h>
#include <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
char* char*
fmtstrflush(Fmt *f) fmtstrflush(Fmt *f)
@ -7,5 +23,5 @@ fmtstrflush(Fmt *f)
if(f->start == nil) if(f->start == nil)
return nil; return nil;
*(char*)f->to = '\0'; *(char*)f->to = '\0';
return f->start; return (char*)f->start;
} }

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h" #include "fmtdef.h"
@ -17,13 +32,16 @@ fmtvprint(Fmt *f, char *fmt, va_list args)
f->flags = 0; f->flags = 0;
f->width = 0; f->width = 0;
f->prec = 0; f->prec = 0;
va = f->args; VA_COPY(va,f->args);
f->args = args; VA_END(f->args);
VA_COPY(f->args,args);
n = dofmt(f, fmt); n = dofmt(f, fmt);
f->flags = 0; f->flags = 0;
f->width = 0; f->width = 0;
f->prec = 0; f->prec = 0;
f->args = va; VA_END(f->args);
VA_COPY(f->args,va);
VA_END(va);
if(n >= 0) if(n >= 0)
return 0; return 0;
return n; return n;

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
fprint(int fd, char *fmt, ...) fprint(int fd, char *fmt, ...)

View File

@ -5,45 +5,59 @@
* same byte ordering. * same byte ordering.
*/ */
#include <u.h> #include "plan9.h"
#include <libc.h> #include "fmt.h"
#include "nan.h" #include "fmtdef.h"
// typedef unsigned long long uvlong; #if defined (__APPLE__) || (__powerpc__)
// typedef unsigned long ulong; #define _NEEDLL
#endif
static uvlong uvnan = 0x7FF0000000000001ULL; static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001;
static uvlong uvinf = 0x7FF0000000000000ULL; static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000;
static uvlong uvneginf = 0xFFF0000000000000ULL; static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
double double
__NaN(void) __NaN(void)
{ {
return *(double*)(void*)&uvnan; uvlong *p;
/* gcc complains about "return *(double*)&uvnan;" */
p = &uvnan;
return *(double*)p;
} }
int int
__isNaN(double d) __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); return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0);
} }
double double
__Inf(int sign) __Inf(int sign)
{ {
uvlong *p;
if(sign < 0) if(sign < 0)
return *(double*)(void*)&uvinf; p = &uvinf;
else else
return *(double*)(void*)&uvneginf; p = &uvneginf;
return *(double*)p;
} }
int int
__isInf(double d, int sign) __isInf(double d, int sign)
{ {
uvlong x; uvlong x;
double *p;
x = *(uvlong*)(void*)&d; p = &d;
x = *(uvlong*)p;
if(sign == 0) if(sign == 0)
return x==uvinf || x==uvneginf; return x==uvinf || x==uvneginf;
else if(sign > 0) else if(sign > 0)
@ -51,5 +65,3 @@ __isInf(double d, int sign)
else else
return x==uvneginf; return x==uvneginf;
} }

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
/* /*
* this table might overflow 127-bit exponent representations. * this table might overflow 127-bit exponent representations.
@ -9,41 +25,33 @@
* the presumption is that C converts fp numbers better * the presumption is that C converts fp numbers better
* than multipication of lower powers of 10. * than multipication of lower powers of 10.
*/ */
static static
double tab[] = double tab[] =
{ {
1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, 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.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.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.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.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.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.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,
}; };
double double
pow10(int n) __fmtpow10(int n)
{ {
int m; int m;
if(n < 0) { if(n < 0) {
n = -n; n = -n;
if(n < sizeof(tab)/sizeof(tab[0])) if(n < (int)(sizeof(tab)/sizeof(tab[0])))
return 1/tab[n]; return 1/tab[n];
m = n/2; 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]; return tab[n];
m = n/2; m = n/2;
return pow10(m) * pow10(n-m); return __fmtpow10(m) * __fmtpow10(n-m);
} }

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
print(char *fmt, ...) print(char *fmt, ...)

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <stdlib.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
Rune* Rune*
runefmtstrflush(Fmt *f) runefmtstrflush(Fmt *f)

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
Rune* Rune*
runeseprint(Rune *buf, Rune *e, char *fmt, ...) runeseprint(Rune *buf, Rune *e, char *fmt, ...)

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
Rune* Rune*
runesmprint(char *fmt, ...) runesmprint(char *fmt, ...)

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
runesnprint(Rune *buf, int len, char *fmt, ...) runesnprint(Rune *buf, int len, char *fmt, ...)

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
runesprint(Rune *buf, char *fmt, ...) runesprint(Rune *buf, char *fmt, ...)

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
Rune* Rune*
runevseprint(Rune *buf, Rune *e, char *fmt, va_list args) 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.flush = nil;
f.farg = nil; f.farg = nil;
f.nfmt = 0; f.nfmt = 0;
f.args = args; VA_COPY(f.args,args);
dofmt(&f, fmt); dofmt(&f, fmt);
VA_END(f.args);
*(Rune*)f.to = '\0'; *(Rune*)f.to = '\0';
return f.to; return (Rune*)f.to;
} }

View File

@ -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 <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include "fmtdef.h" #include "fmtdef.h"
#else
#include <stdlib.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
#endif
static int static int
runeFmtStrFlush(Fmt *f) runeFmtStrFlush(Fmt *f)
@ -10,9 +36,9 @@ runeFmtStrFlush(Fmt *f)
if(f->start == nil) if(f->start == nil)
return 0; return 0;
n = (int)f->farg; n = (uintptr)f->farg;
n *= 2; n *= 2;
s = f->start; s = (Rune*)f->start;
f->start = realloc(s, sizeof(Rune)*n); f->start = realloc(s, sizeof(Rune)*n);
if(f->start == nil){ if(f->start == nil){
f->farg = nil; f->farg = nil;
@ -21,7 +47,7 @@ runeFmtStrFlush(Fmt *f)
free(s); free(s);
return 0; return 0;
} }
f->farg = (void*)n; f->farg = (void*)(uintptr)n;
f->to = (Rune*)f->start + ((Rune*)f->to - s); f->to = (Rune*)f->start + ((Rune*)f->to - s);
f->stop = (Rune*)f->start + n - 1; f->stop = (Rune*)f->start + n - 1;
return 1; return 1;
@ -41,7 +67,7 @@ runefmtstrinit(Fmt *f)
f->to = f->start; f->to = f->start;
f->stop = (Rune*)f->start + n - 1; f->stop = (Rune*)f->start + n - 1;
f->flush = runeFmtStrFlush; f->flush = runeFmtStrFlush;
f->farg = (void*)n; f->farg = (void*)(uintptr)n;
f->nfmt = 0; f->nfmt = 0;
return 0; return 0;
} }
@ -57,8 +83,9 @@ runevsmprint(char *fmt, va_list args)
if(runefmtstrinit(&f) < 0) if(runefmtstrinit(&f) < 0)
return nil; return nil;
f.args = args; VA_COPY(f.args,args);
n = dofmt(&f, fmt); n = dofmt(&f, fmt);
VA_END(f.args);
if(f.start == nil) if(f.start == nil)
return nil; return nil;
if(n < 0){ if(n < 0){
@ -66,5 +93,5 @@ runevsmprint(char *fmt, va_list args)
return nil; return nil;
} }
*(Rune*)f.to = '\0'; *(Rune*)f.to = '\0';
return f.start; return (Rune*)f.start;
} }

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
runevsnprint(Rune *buf, int len, char *fmt, va_list args) 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.flush = nil;
f.farg = nil; f.farg = nil;
f.nfmt = 0; f.nfmt = 0;
f.args = args; VA_COPY(f.args,args);
dofmt(&f, fmt); dofmt(&f, fmt);
VA_END(f.args);
*(Rune*)f.to = '\0'; *(Rune*)f.to = '\0';
return (Rune*)f.to - buf; return (Rune*)f.to - buf;
} }

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
char* char*
seprint(char *buf, char *e, char *fmt, ...) seprint(char *buf, char *e, char *fmt, ...)

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
char* char*
smprint(char *fmt, ...) smprint(char *fmt, ...)

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
snprint(char *buf, int len, char *fmt, ...) snprint(char *buf, int len, char *fmt, ...)

View File

@ -1,14 +1,39 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include <fmt.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
sprint(char *buf, char *fmt, ...) sprint(char *buf, char *fmt, ...)
{ {
int n; int n;
uint len;
va_list args; 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); 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); va_end(args);
return n; return n;
} }

View File

@ -1,6 +1,36 @@
#include <u.h> /*
#include <libc.h> * 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 <stdlib.h>
#include <math.h>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#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 * This routine will convert to arbitrary precision
@ -17,46 +47,34 @@
*/ */
enum enum
{ {
Nbits = 28, // bits safely represented in a ulong Nbits = 28, /* bits safely represented in a ulong */
Nmant = 53, // bits of precision required Nmant = 53, /* bits of precision required */
Bias = 1022, Prec = (Nmant+Nbits+1)/Nbits, /* words of Nbits each to represent mantissa */
Prec = (Nmant+Nbits+1)/Nbits, // words of Nbits each to represent mantissa Sigbit = 1<<(Prec*Nbits-Nmant), /* first significant bit of Prec-th word */
Sigbit = 1<<(Prec*Nbits-Nmant), // first significant bit of Prec-th word
Ndig = 1500, Ndig = 1500,
One = (ulong)(1<<Nbits), One = (ulong)(1<<Nbits),
Half = (ulong)(One>>1), Half = (ulong)(One>>1),
Maxe = 310, Maxe = 310,
Fsign = 1<<0, // found -
Fesign = 1<<1, // found e-
Fdpoint = 1<<2, // found .
S0 = 0, // _ _S0 +S1 #S2 .S3 Fsign = 1<<0, /* found - */
S1, // _+ #S2 .S3 Fesign = 1<<1, /* found e- */
S2, // _+# #S2 .S4 eS5 Fdpoint = 1<<2, /* found . */
S3, // _+. #S4
S4, // _+#.# #S4 eS5 S0 = 0, /* _ _S0 +S1 #S2 .S3 */
S5, // _+#.#e +S6 #S7 S1, /* _+ #S2 .S3 */
S6, // _+#.#e+ #S7 S2, /* _+# #S2 .S4 eS5 */
S7, // _+#.#e+# #S7 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 xcmp(char*, char*);
static int fpcmp(char*, ulong*); static int fpcmp(char*, ulong*);
static void frnorm(ulong*); static void frnorm(ulong*);
static void divascii(char*, int*, int*, int*); static void divascii(char*, int*, int*, int*);
static void mulascii(char*, int*, int*, int*); static void mulascii(char*, int*, int*, int*);
static void divby(char*, int*, int);
typedef struct Tab Tab; typedef struct Tab Tab;
struct Tab struct Tab
@ -67,20 +85,20 @@ struct Tab
}; };
double double
strtod(char *as, char **aas) fmtstrtod(const char *as, char **aas)
{ {
int na, ona, ex, dp, bp, c, i, flag, state; int na, ex, dp, bp, c, i, flag, state;
ulong low[Prec], hig[Prec], mid[Prec], num, den; ulong low[Prec], hig[Prec], mid[Prec];
double d; double d;
char *s, a[Ndig]; char *s, a[Ndig];
flag = 0; // Fsign, Fesign, Fdpoint flag = 0; /* Fsign, Fesign, Fdpoint */
na = 0; // number of digits of a[] na = 0; /* number of digits of a[] */
dp = 0; // na of decimal point dp = 0; /* na of decimal point */
ex = 0; // exonent ex = 0; /* exonent */
state = S0; state = S0;
for(s=as;; s++) { for(s=(char*)as;; s++) {
c = *s; c = *s;
if(c >= '0' && c <= '9') { if(c >= '0' && c <= '9') {
switch(state) { switch(state) {
@ -131,7 +149,7 @@ strtod(char *as, char **aas)
if(state == S5) if(state == S5)
state = S6; state = S6;
else else
break; // syntax break; /* syntax */
continue; continue;
case '.': case '.':
flag |= Fdpoint; flag |= Fdpoint;
@ -179,12 +197,12 @@ strtod(char *as, char **aas)
} }
case S3: case S3:
if(aas != nil) if(aas != nil)
*aas = as; *aas = (char*)as;
goto ret0; // no digits found goto ret0; /* no digits found */
case S6: case S6:
s--; // back over +- s--; /* back over +- */
case S5: case S5:
s--; // back over e s--; /* back over e */
break; break;
} }
if(aas != nil) if(aas != nil)
@ -194,55 +212,41 @@ strtod(char *as, char **aas)
while(na > 0 && a[na-1] == '0') while(na > 0 && a[na-1] == '0')
na--; na--;
if(na == 0) if(na == 0)
goto ret0; // zero goto ret0; /* zero */
a[na] = 0; a[na] = 0;
if(!(flag & Fdpoint)) if(!(flag & Fdpoint))
dp = na; dp = na;
if(flag & Fesign) if(flag & Fesign)
ex = -ex; ex = -ex;
dp += ex; dp += ex;
if(dp < -Maxe-Nmant/3) /* actually -Nmant*log(2)/log(10), but Nmant/3 close enough */ if(dp < -Maxe){
goto ret0; // underflow by exp errno = ERANGE;
else goto ret0; /* underflow by exp */
} else
if(dp > +Maxe) if(dp > +Maxe)
goto retinf; // overflow by exp goto retinf; /* overflow by exp */
/* /*
* normalize the decimal ascii number * normalize the decimal ascii number
* to range .[5-9][0-9]* e0 * to range .[5-9][0-9]* e0
*/ */
bp = 0; // binary exponent bp = 0; /* binary exponent */
while(dp > 0) while(dp > 0)
divascii(a, &na, &dp, &bp); divascii(a, &na, &dp, &bp);
while(dp < 0 || a[0] < '5') while(dp < 0 || a[0] < '5')
mulascii(a, &na, &dp, &bp); 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 */ /* close approx by naive conversion */
num = 0; mid[0] = 0;
den = 1; mid[1] = 1;
for(i=0; i<9 && (c=a[i]); i++) { for(i=0; c=a[i]; i++) {
num = num*10 + (c-'0'); mid[0] = mid[0]*10 + (c-'0');
den *= 10; mid[1] = mid[1]*10;
if(i >= 8)
break;
} }
low[0] = umuldiv(num, One, den); low[0] = umuldiv(mid[0], One, mid[1]);
hig[0] = umuldiv(num+1, One, den); hig[0] = umuldiv(mid[0]+1, One, mid[1]);
for(i=1; i<Prec; i++) { for(i=1; i<Prec; i++) {
low[i] = 0; low[i] = 0;
hig[i] = One-1; hig[i] = One-1;
@ -271,7 +275,7 @@ strtod(char *as, char **aas)
low[i] = mid[i]; low[i] = mid[i];
} }
if(c) if(c)
break; // between mid and hig break; /* between mid and hig */
continue; continue;
} }
if(c < 0) { if(c < 0) {
@ -284,7 +288,7 @@ strtod(char *as, char **aas)
c = mid[Prec-1] & (Sigbit-1); c = mid[Prec-1] & (Sigbit-1);
if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0) if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0)
mid[Prec-1] -= c; mid[Prec-1] -= c;
break; // exactly mid break; /* exactly mid */
} }
/* normal rounding applies */ /* normal rounding applies */
@ -294,13 +298,7 @@ strtod(char *as, char **aas)
mid[Prec-1] += Sigbit; mid[Prec-1] += Sigbit;
frnorm(mid); frnorm(mid);
} }
d = 0; goto out;
for(i=0; i<Prec; i++)
d = d*One + mid[i];
if(flag & Fsign)
d = -d;
d = ldexp(d, bp - Prec*Nbits);
return d;
ret0: ret0:
return 0; return 0;
@ -309,9 +307,24 @@ retnan:
return __NaN(); return __NaN();
retinf: retinf:
/*
* Unix strtod requires these. Plan 9 would return Inf(0) or Inf(-1). */
errno = ERANGE;
if(flag & Fsign) if(flag & Fsign)
return __Inf(-1); return -HUGE_VAL;
return __Inf(+1); return HUGE_VAL;
out:
d = 0;
for(i=0; i<Prec; i++)
d = d*One + mid[i];
if(flag & Fsign)
d = -d;
d = ldexp(d, bp - Prec*Nbits);
if(d == 0){ /* underflow */
errno = ERANGE;
}
return d;
} }
static void static void
@ -364,11 +377,10 @@ fpcmp(char *a, ulong* f)
a++; a++;
cont:; cont:;
} }
return 0;
} }
static void static void
_divby(char *a, int *na, int b) divby(char *a, int *na, int b)
{ {
int n, c; int n, c;
char *p; char *p;
@ -410,18 +422,6 @@ xx:
*p = 0; *p = 0;
} }
static void
divby(char *a, int *na, int b)
{
while(b > 9){
_divby(a, na, 9);
a[*na] = 0;
b -= 9;
}
if(b > 0)
_divby(a, na, b);
}
static Tab tab1[] = static Tab tab1[] =
{ {
1, 0, "", 1, 0, "",
@ -443,8 +443,8 @@ divascii(char *a, int *na, int *dp, int *bp)
Tab *t; Tab *t;
d = *dp; d = *dp;
if(d >= nelem(tab1)) if(d >= (int)(nelem(tab1)))
d = nelem(tab1)-1; d = (int)(nelem(tab1))-1;
t = tab1 + d; t = tab1 + d;
b = t->bp; b = t->bp;
if(memcmp(a, t->cmp, t->siz) > 0) if(memcmp(a, t->cmp, t->siz) > 0)
@ -483,7 +483,7 @@ mulby(char *a, char *p, char *q, int b)
static Tab tab2[] = static Tab tab2[] =
{ {
1, 1, "", // dp = 0-0 1, 1, "", /* dp = 0-0 */
3, 3, "125", 3, 3, "125",
6, 5, "15625", 6, 5, "15625",
9, 7, "1953125", 9, 7, "1953125",
@ -492,7 +492,7 @@ static Tab tab2[] =
19, 14, "19073486328125", 19, 14, "19073486328125",
23, 17, "11920928955078125", 23, 17, "11920928955078125",
26, 19, "1490116119384765625", 26, 19, "1490116119384765625",
27, 19, "7450580596923828125", // dp 8-9 27, 19, "7450580596923828125", /* dp 8-9 */
}; };
static void static void
@ -503,8 +503,8 @@ mulascii(char *a, int *na, int *dp, int *bp)
Tab *t; Tab *t;
d = -*dp; d = -*dp;
if(d >= nelem(tab2)) if(d >= (int)(nelem(tab2)))
d = nelem(tab2)-1; d = (int)(nelem(tab2))-1;
t = tab2 + d; t = tab2 + d;
b = t->bp; b = t->bp;
if(memcmp(a, t->cmp, t->siz) < 0) if(memcmp(a, t->cmp, t->siz) < 0)

View File

@ -1,22 +1,20 @@
#include <u.h>
#include <libc.h>
#include "fmtdef.h"
/* /*
* generic routine for flushing a formatting buffer * The authors of this software are Rob Pike and Ken Thompson.
* to a file descriptor * 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 #include <stdarg.h>
_fmtFdFlush(Fmt *f) #include "plan9.h"
{ #include "fmt.h"
int n; #include "fmtdef.h"
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;
}
int int
vfprint(int fd, char *fmt, va_list args) vfprint(int fd, char *fmt, va_list args)
@ -26,9 +24,10 @@ vfprint(int fd, char *fmt, va_list args)
int n; int n;
fmtfdinit(&f, fd, buf, sizeof(buf)); fmtfdinit(&f, fd, buf, sizeof(buf));
f.args = args; VA_COPY(f.args,args);
n = dofmt(&f, fmt); n = dofmt(&f, fmt);
if(n > 0 && _fmtFdFlush(&f) == 0) VA_END(f.args);
if(n > 0 && __fmtFdFlush(&f) == 0)
return -1; return -1;
return n; return n;
} }

View File

@ -1,5 +1,20 @@
#include <u.h> /*
#include <libc.h> * 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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
char* char*
vseprint(char *buf, char *e, char *fmt, va_list args) 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.start = buf;
f.to = buf; f.to = buf;
f.stop = e - 1; f.stop = e - 1;
f.flush = nil; f.flush = 0;
f.farg = nil; f.farg = nil;
f.nfmt = 0; f.nfmt = 0;
f.args = args; VA_COPY(f.args,args);
dofmt(&f, fmt); dofmt(&f, fmt);
VA_END(f.args);
*(char*)f.to = '\0'; *(char*)f.to = '\0';
return f.to; return (char*)f.to;
} }

View File

@ -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 <u.h> #include <u.h>
#include <libc.h> #include <libc.h>
#include "fmtdef.h" #include "fmtdef.h"
#else
#include <stdlib.h>
#include <string.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
#endif
static int static int
fmtStrFlush(Fmt *f) fmtStrFlush(Fmt *f)
@ -10,9 +36,9 @@ fmtStrFlush(Fmt *f)
if(f->start == nil) if(f->start == nil)
return 0; return 0;
n = (int)f->farg; n = (uintptr)f->farg;
n *= 2; n *= 2;
s = f->start; s = (char*)f->start;
f->start = realloc(s, n); f->start = realloc(s, n);
if(f->start == nil){ if(f->start == nil){
f->farg = nil; f->farg = nil;
@ -21,7 +47,7 @@ fmtStrFlush(Fmt *f)
free(s); free(s);
return 0; return 0;
} }
f->farg = (void*)n; f->farg = (void*)(uintptr)n;
f->to = (char*)f->start + ((char*)f->to - s); f->to = (char*)f->start + ((char*)f->to - s);
f->stop = (char*)f->start + n - 1; f->stop = (char*)f->start + n - 1;
return 1; return 1;
@ -41,7 +67,7 @@ fmtstrinit(Fmt *f)
f->to = f->start; f->to = f->start;
f->stop = (char*)f->start + n - 1; f->stop = (char*)f->start + n - 1;
f->flush = fmtStrFlush; f->flush = fmtStrFlush;
f->farg = (void*)n; f->farg = (void*)(uintptr)n;
f->nfmt = 0; f->nfmt = 0;
return 0; return 0;
} }
@ -57,14 +83,12 @@ vsmprint(char *fmt, va_list args)
if(fmtstrinit(&f) < 0) if(fmtstrinit(&f) < 0)
return nil; return nil;
f.args = args; VA_COPY(f.args,args);
n = dofmt(&f, fmt); n = dofmt(&f, fmt);
if(f.start == nil) VA_END(f.args);
return nil;
if(n < 0){ if(n < 0){
free(f.start); free(f.start);
return nil; return nil;
} }
*(char*)f.to = '\0'; return fmtstrflush(&f);
return f.start;
} }

View File

@ -1,5 +1,21 @@
#include <u.h> /*
#include <libc.h> * 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 <stdlib.h>
#include <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
int int
vsnprint(char *buf, int len, char *fmt, va_list args) 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.start = buf;
f.to = buf; f.to = buf;
f.stop = buf + len - 1; f.stop = buf + len - 1;
f.flush = nil; f.flush = 0;
f.farg = nil; f.farg = nil;
f.nfmt = 0; f.nfmt = 0;
f.args = args; VA_COPY(f.args,args);
dofmt(&f, fmt); dofmt(&f, fmt);
VA_END(f.args);
*(char*)f.to = '\0'; *(char*)f.to = '\0';
return (char*)f.to - buf; return (char*)f.to - buf;
} }