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
@ -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;
}

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"
/* 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, "<nil>", 5, 5);
return __fmtcpy(f, "<nil>", 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; j<f->prec && 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, "<nil>", 5, 5);
return __fmtcpy(f, "<nil>", 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;
}

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"
/* 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;
}

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"
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);
}

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 <fmt.h>
#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);
}

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"
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; p<ep; p++)
@ -84,13 +113,13 @@ _fmtinstall(int c, Fmts f)
}
int
fmtinstall(int c, Fmts f)
fmtinstall(int c, int (*f)(Fmt*))
{
int ret;
_fmtlock();
ret = _fmtinstall(c, f);
_fmtunlock();
__fmtlock();
ret = __fmtinstall(c, f);
__fmtunlock();
return ret;
}
@ -108,20 +137,20 @@ fmtfmt(int c)
}
/* is this a predefined format char? */
_fmtlock();
__fmtlock();
for(p=knownfmt; p->c; 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;
}

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
* 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

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"
/*
@ -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;
}

View File

@ -1,16 +1,27 @@
#include <u.h>
#include <libc.h>
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 <stdarg.h>
#include "plan9.h"
#include "fmt.h"
#include "fmtdef.h"
void
_fmtlock(void)
__fmtlock(void)
{
lock(&fmtl);
}
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"
/*
* 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;

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"
/*
* 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, "<nil>", 5, 5);
return __fmtcpy(f, (void*)"<nil>", 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;

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"
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;

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*
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;
}

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"
@ -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;

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
fprint(int fd, char *fmt, ...)

View File

@ -5,45 +5,59 @@
* same byte ordering.
*/
#include <u.h>
#include <libc.h>
#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;
}

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.
@ -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);
}

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
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*
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*
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*
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
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
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*
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;
}

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 <libc.h>
#include "fmtdef.h"
#else
#include <stdlib.h>
#include <string.h>
#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;
}

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
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;
}

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*
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*
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
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
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;
}

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 <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
@ -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<<Nbits),
Half = (ulong)(One>>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<Prec; i++) {
low[i] = 0;
hig[i] = One-1;
@ -271,7 +275,7 @@ strtod(char *as, char **aas)
low[i] = mid[i];
}
if(c)
break; // between mid and hig
break; /* between mid and hig */
continue;
}
if(c < 0) {
@ -284,7 +288,7 @@ strtod(char *as, char **aas)
c = mid[Prec-1] & (Sigbit-1);
if(c == Sigbit/2 && (mid[Prec-1]&Sigbit) == 0)
mid[Prec-1] -= c;
break; // exactly mid
break; /* exactly mid */
}
/* normal rounding applies */
@ -294,13 +298,7 @@ strtod(char *as, char **aas)
mid[Prec-1] += Sigbit;
frnorm(mid);
}
d = 0;
for(i=0; i<Prec; i++)
d = d*One + mid[i];
if(flag & Fsign)
d = -d;
d = ldexp(d, bp - Prec*Nbits);
return d;
goto out;
ret0:
return 0;
@ -309,9 +307,24 @@ retnan:
return __NaN();
retinf:
/*
* Unix strtod requires these. Plan 9 would return Inf(0) or Inf(-1). */
errno = ERANGE;
if(flag & Fsign)
return __Inf(-1);
return __Inf(+1);
return -HUGE_VAL;
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
@ -364,11 +377,10 @@ fpcmp(char *a, ulong* f)
a++;
cont:;
}
return 0;
}
static void
_divby(char *a, int *na, int b)
divby(char *a, int *na, int b)
{
int n, c;
char *p;
@ -410,18 +422,6 @@ xx:
*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[] =
{
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)

View File

@ -1,22 +1,20 @@
#include <u.h>
#include <libc.h>
#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 <stdarg.h>
#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;
}

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*
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;
}

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 <libc.h>
#include "fmtdef.h"
#else
#include <stdlib.h>
#include <string.h>
#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);
}

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
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;
}