## diffname port/print.c 1990/0227
## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/print.c
0a
#include "u.h"
#include "lib.h"
#define PTR sizeof(char*)
#define SHORT sizeof(int)
#define INT sizeof(int)
#define LONG sizeof(long)
#define IDIGIT 30
#define MAXCON 30
static int convcount = { 10 };
#define PUT(o, c) if((o)->p < (o)->ep) *(o)->p++ = c
static int noconv(Op*);
static int cconv(Op*);
static int dconv(Op*);
static int hconv(Op*);
static int lconv(Op*);
static int oconv(Op*);
static int sconv(Op*);
static int uconv(Op*);
static int xconv(Op*);
static int percent(Op*);
static
int (*fmtconv[MAXCON])(Op*) =
{
noconv,
cconv, dconv, hconv, lconv,
oconv, sconv, uconv, xconv,
percent,
};
static
char fmtindex[128] =
{
['c'] 1,
['d'] 2,
['h'] 3,
['l'] 4,
['o'] 5,
['s'] 6,
['u'] 7,
['x'] 8,
['%'] 9,
};
int
fmtinstall(char c, int (*f)(Op*))
{
c &= 0177;
if(fmtindex[c] == 0) {
if(convcount >= MAXCON)
return 1;
fmtindex[c] = convcount++;
}
fmtconv[fmtindex[c]] = f;
return 0;
}
char*
donprint(char *p, char *ep, char *fmt, void *argp)
{
int sf1, c;
Op o;
o.p = p;
o.ep = ep;
o.argp = argp;
loop:
c = *fmt++;
if(c != '%') {
if(c == 0) {
if(o.p < o.ep)
*o.p = 0;
return o.p;
}
PUT(&o, c);
goto loop;
}
o.f1 = 0;
o.f2 = -1;
o.f3 = 0;
c = *fmt++;
sf1 = 0;
if(c == '-') {
sf1 = 1;
c = *fmt++;
}
while(c >= '0' && c <= '9') {
o.f1 = o.f1*10 + c-'0';
c = *fmt++;
}
if(sf1)
o.f1 = -o.f1;
if(c != '.')
goto l1;
c = *fmt++;
while(c >= '0' && c <= '9') {
if(o.f2 < 0)
o.f2 = 0;
o.f2 = o.f2*10 + c-'0';
c = *fmt++;
}
l1:
if(c == 0)
fmt--;
c = (*fmtconv[fmtindex[c&0177]])(&o);
if(c < 0) {
o.f3 |= -c;
c = *fmt++;
goto l1;
}
o.argp = (char*)o.argp + c;
goto loop;
}
int
numbconv(Op *op, int base)
{
char b[IDIGIT];
int i, f, n, r;
long v;
short h;
f = 0;
switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) {
case FLONG:
v = *(long*)op->argp;
r = LONG;
break;
case FUNSIGN|FLONG:
v = *(unsigned long*)op->argp;
r = LONG;
break;
case FSHORT:
h = *(int*)op->argp;
v = h;
r = SHORT;
break;
case FUNSIGN|FSHORT:
h = *(int*)op->argp;
v = (unsigned short)h;
r = SHORT;
break;
default:
v = *(int*)op->argp;
r = INT;
break;
case FUNSIGN:
v = *(unsigned*)op->argp;
r = INT;
break;
}
if(!(op->f3 & FUNSIGN) && v < 0) {
v = -v;
f = 1;
}
b[IDIGIT-1] = 0;
for(i = IDIGIT-2;; i--) {
n = (unsigned long)v % base;
n += '0';
if(n > '9')
n += 'a' - ('9'+1);
b[i] = n;
if(i < 2)
break;
v = (unsigned long)v / base;
if(op->f2 >= 0 && i >= IDIGIT-op->f2)
continue;
if(v <= 0)
break;
}
sout:
if(f)
b[--i] = '-';
strconv(b+i, op, op->f1, -1);
return r;
}
void
strconv(char *o, Op *op, int f1, int f2)
{
int n, c;
char *p;
n = strlen(o);
if(f1 >= 0)
while(n < f1) {
PUT(op, ' ');
n++;
}
for(p=o; c = *p++;)
if(f2 != 0) {
PUT(op, c);
f2--;
}
if(f1 < 0) {
f1 = -f1;
while(n < f1) {
PUT(op, ' ');
n++;
}
}
}
static int
noconv(Op *op)
{
strconv("***", op, 0, -1);
return 0;
}
static int
cconv(Op *op)
{
char b[2];
b[0] = *(int*)op->argp;
b[1] = 0;
strconv(b, op, op->f1, -1);
return INT;
}
static int
dconv(Op *op)
{
return numbconv(op, 10);
}
static int
hconv(Op *op)
{
return -FSHORT;
}
static int
lconv(Op *op)
{
return -FLONG;
}
static int
oconv(Op *op)
{
return numbconv(op, 8);
}
static int
sconv(Op *op)
{
strconv(*(char**)op->argp, op, op->f1, op->f2);
return PTR;
}
static int
uconv(Op *op)
{
return -FUNSIGN;
}
static int
xconv(Op *op)
{
return numbconv(op, 16);
}
static int
percent(Op *op)
{
PUT(op, '%');
return 0;
}
.
## diffname port/print.c 1990/06111
## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/print.c /n/bootesdump/1990/06111/sys/src/9/mips/print.c
63c
doprint(char *p, char *ep, char *fmt, void *argp)
.
## diffname port/print.c 1991/1115
## diff -e /n/bootesdump/1990/1210/sys/src/9/mips/print.c /n/bootesdump/1991/1115/sys/src/9/port/print.c
270a
USED(op);
.
249a
USED(op);
.
242a
USED(op);
.
## diffname port/print.c 1992/0321
## diff -e /n/bootesdump/1991/1115/sys/src/9/port/print.c /n/bootesdump/1992/0321/sys/src/9/port/print.c
2c
#include "../port/lib.h"
.
## diffname port/print.c 1992/1024
## diff -e /n/bootesdump/1992/0321/sys/src/9/port/print.c /n/bootesdump/1992/1024/sys/src/9/port/print.c
290,291c
case 'u':
f = FUNSIGN;
break;
}
return -f;
.
286,288c
case 'l':
f = FLONG;
if(fp->f3 & FLONG)
f = FVLONG;
break;
.
283,284c
case 'h':
f = FSHORT;
break;
.
279,281c
case '#':
f = FSHARP;
break;
.
275,277c
case '-':
f = FMINUS;
break;
.
271,273c
f = 0;
switch(fp->chr) {
case '+':
f = FPLUS;
break;
.
267,269c
USED(o);
.
265a
int f;
.
263,264c
static
int
flags(void *o, Fconv *fp)
.
260c
USED(o);
if(fp->out < fp->eout)
*fp->out++ = '%';
return 0;
.
256,257c
static
int
percent(void *o, Fconv *fp)
.
252,253c
if(fp->chr == 's') {
s = *(char**)o;
if(s == 0)
s = "<null>";
strconv(s, fp);
} else {
r = *(Rune**)o;
if(r == 0)
r = L"<null>";
Strconv(r, fp);
}
return PTR;
.
250a
char *s;
Rune *r;
.
248,249c
static
int
sconv(void *o, Fconv *fp)
.
240,245c
fp->f2 = NONE;
strconv(s, fp);
return INT;
.
237,238c
rune = *(int*)o;
if(fp->chr == 'c')
rune &= 0xff;
s[runetochar(s, &rune)] = 0;
.
235a
char s[10];
Rune rune;
.
233,234c
static
int
cconv(void *o, Fconv *fp)
.
227,230c
if(convcount == 0) {
initfmt();
n = 0;
if(fp->chr >= 0 && fp->chr < MAXFMT)
n = fmtindex[fp->chr];
return (*fmtconv[n])(o, fp);
}
sprint(s, "*%c*", fp->chr);
fp->f1 = 0;
fp->f2 = NONE;
fp->f3 = 0;
strconv(s, fp);
return 0;
.
225c
int n;
char s[10];
.
222,223c
static
int
noconv(void *o, Fconv *fp)
.
218,219c
if(fp->f3 & FMINUS)
fp->f1 = -fp->f1;
n = 0;
if(fp->f1 != NONE && fp->f1 >= 0) {
n = utflen(s);
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
n++;
}
}
for(;;) {
c = *s & 0xff;
if(c >= Runeself) {
i = chartorune(&rune, s);
s += i;
c = rune;
} else
s++;
if(c == 0)
break;
n++;
if(fp->f2 == NONE || fp->f2 > 0) {
if(fp->out < fp->eout)
if(c >= Runeself) {
rune = c;
i = runetochar(fp->out, &rune);
fp->out += i;
} else
*fp->out++ = c;
if(fp->f2 != NONE)
fp->f2--;
switch(c) {
default:
printcol++;
break;
case '\n':
printcol = 0;
break;
case '\t':
printcol = (printcol+8) & ~7;
break;
}
}
}
if(fp->f1 != NONE && fp->f1 < 0) {
fp->f1 = -fp->f1;
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
n++;
}
}
.
216a
int n, c, i;
Rune rune;
.
214,215c
void
strconv(char *s, Fconv *fp)
.
205,208c
}
if(fp->f1 != NONE && fp->f1 < 0) {
fp->f1 = -fp->f1;
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
.
200,203c
}
for(;;) {
c = *s++;
if(c == 0)
break;
n++;
if(fp->f2 == NONE || fp->f2 > 0) {
if(fp->out < fp->eout)
if(c >= Runeself) {
rune = c;
i = runetochar(fp->out, &rune);
fp->out += i;
} else
*fp->out++ = c;
if(fp->f2 != NONE)
fp->f2--;
switch(c) {
default:
printcol++;
break;
case '\n':
printcol = 0;
break;
case '\t':
printcol = (printcol+8) & ~7;
break;
}
.
194,197c
if(fp->f3 & FMINUS)
fp->f1 = -fp->f1;
n = 0;
if(fp->f1 != NONE && fp->f1 >= 0) {
for(; s[n]; n++)
;
while(n < fp->f1) {
if(fp->out < fp->eout)
*fp->out++ = ' ';
printcol++;
.
191,192c
int n, c, i;
Rune rune;
.
189c
Strconv(Rune *s, Fconv *fp)
.
183,184c
s[--i] = '-';
fp->f2 = NONE;
strconv(s+i, fp);
.
181c
if(fp->f3 & FSHARP)
if(s[i] != '0') {
if(b == 8)
s[--i] = '0';
else
if(b == 16) {
if(ucase)
s[--i] = 'X';
else
s[--i] = 'x';
s[--i] = '0';
}
}
.
177a
if(fp->f3 & FVLONG)
if(vl <= 0)
break;
.
175,176c
if(fp->f3 & FVLONG)
vl = vl / b;
else
v = (ulong)v / b;
if(fp->f2 != NONE && i >= IDIGIT-fp->f2)
.
172c
if(ucase)
n += 'A'-'a';
}
s[i] = n;
.
170c
if(n > '9') {
.
168c
if(fp->f3 & FVLONG)
n = vl % b;
else
n = (ulong)v % b;
.
166c
s[IDIGIT-1] = 0;
.
162c
if(!(fp->f3 & FUNSIGN) && v < 0) {
.
158c
v = *(unsigned*)o;
.
153c
v = *(int*)o;
.
147,148c
h = *(int*)o;
v = (ushort)h;
.
141c
h = *(int*)o;
.
136c
v = *(ulong*)o;
.
131c
v = *(long*)o;
.
129c
switch(fp->f3 & (FVLONG|FLONG|FSHORT|FUNSIGN)) {
case FVLONG|FLONG:
vl = *(vlong*)o;
r = VLONG;
break;
.
127a
SET(v);
SET(vl);
ucase = 0;
b = fp->chr;
switch(fp->chr) {
case 'u':
fp->f3 |= FUNSIGN;
case 'd':
b = 10;
break;
case 'o':
b = 8;
break;
case 'X':
ucase = 1;
case 'x':
b = 16;
break;
}
.
126a
long v;
vlong vl;
.
123,125c
char s[IDIGIT];
int i, f, n, r, b, ucase;
.
121c
numbconv(void *o, Fconv *fp)
.
116c
n = 0;
if(c >= 0 && c < MAXFMT)
n = fmtindex[c];
local.chr = c;
n = (*fmtconv[n])(argp, &local);
if(n < 0) {
local.f3 |= -n;
goto l0;
}
argp = (char*)argp + n;
.
107,114c
if(c == '*') {
n = *(int*)argp;
argp = (char*)argp + INT;
if(local.f1 == NONE)
local.f1 = n;
else
local.f2 = n;
goto l0;
.
100,105d
96,98c
if((c >= '1' && c <= '9') ||
(c == '0' && local.f1 != NONE)) { /* '0' is a digit for f2 */
n = 0;
while(c >= '0' && c <= '9') {
n = n*10 + c-'0';
c = *fmt++;
}
if(local.f1 == NONE)
local.f1 = n;
else
local.f2 = n;
.
92,94c
if(c == '.') {
if(local.f1 == NONE)
local.f1 = 0;
local.f2 = 0;
goto l0;
.
83,90c
local.f1 = NONE;
local.f2 = NONE;
local.f3 = 0;
/*
* read one of the following
* 1. number, => f1, f2 in order.
* 2. '*' same as number (from args)
* 3. '.' ignored (separates numbers)
* 4. flag => f3
* 5. verb and terminate
*/
l0:
c = *fmt & 0xff;
if(c >= Runeself) {
n = chartorune(&rune, fmt);
fmt += n;
c = rune;
} else
fmt++;
l1:
if(c == 0) {
fmt--;
goto loop;
.
81a
case '%':
break;
.
73,80c
c = *fmt & 0xff;
if(c >= Runeself) {
n = chartorune(&rune, fmt);
fmt += n;
c = rune;
} else
fmt++;
switch(c) {
case 0:
*local.out = 0;
return local.out;
default:
printcol++;
goto common;
case '\n':
printcol = 0;
goto common;
case '\t':
printcol = (printcol+8) & ~7;
goto common;
common:
if(local.out < local.eout)
if(c >= Runeself) {
rune = c;
n = runetochar(local.out, &rune); /* BUG */
local.out += n;
} else
*local.out++ = c;
.
68,70c
local.out = s;
local.eout = es-4; /* room for multi-byte character and 0 */
.
65,66c
int n, c;
Rune rune;
Fconv local;
.
63c
doprint(char *s, char *es, char *fmt, void *argp)
.
52,58c
if(convcount == 0)
initfmt();
if(c < 0 || c >= MAXFMT)
return 1;
if(convcount >= MAXCONV)
return 1;
fmtconv[convcount] = f;
fmtindex[c] = convcount;
convcount++;
.
49c
fmtinstall(int c, int (*f)(void*, Fconv*))
.
47a
cc = 0;
fmtconv[cc] = noconv;
cc++;
fmtconv[cc] = flags;
fmtindex['+'] = cc;
fmtindex['-'] = cc;
fmtindex['#'] = cc;
fmtindex['h'] = cc;
fmtindex['l'] = cc;
fmtindex['u'] = cc;
cc++;
fmtconv[cc] = numbconv;
fmtindex['d'] = cc;
fmtindex['o'] = cc;
fmtindex['x'] = cc;
fmtindex['X'] = cc;
cc++;
fmtconv[cc] = cconv;
fmtindex['c'] = cc;
fmtindex['C'] = cc;
cc++;
fmtconv[cc] = sconv;
fmtindex['s'] = cc;
fmtindex['S'] = cc;
cc++;
fmtconv[cc] = percent;
fmtindex['%'] = cc;
cc++;
convcount = cc;
}
.
37,46c
int cc;
.
35c
void
initfmt(void)
.
33a
.
29,32c
noconv
.
27c
int (*fmtconv[MAXCONV])(void*, Fconv*) =
.
25a
static int cconv(void*, Fconv*);
static int sconv(void*, Fconv*);
static int percent(void*, Fconv*);
int numbconv(void*, Fconv*);
.
15,24c
static int noconv(void*, Fconv*);
static int flags(void*, Fconv*);
.
13c
static int convcount;
static char fmtindex[MAXFMT];
.
11c
int printcol;
.
8,9c
#define VLONG sizeof(vlong)
.
3a
enum
{
SIZE = 1024,
IDIGIT = 30,
MAXCONV = 40,
FDIGIT = 30,
FDEFLT = 6,
NONE = -1000,
MAXFMT = 512,
FPLUS = (1<<0),
FMINUS = (1<<1),
FSHARP = (1<<2),
FLONG = (1<<3),
FSHORT = (1<<4),
FUNSIGN = (1<<5),
FVLONG = (1<<6),
};
.
## diffname port/print.c 1995/0804
## diff -e /n/bootesdump/1992/1024/sys/src/9/port/print.c /n/fornaxdump/1995/0804/sys/src/brazil/port/print.c
542,543d
539c
flags(void*, Fconv *fp)
.
531d
528c
percent(void*, Fconv *fp)
.
## diffname port/print.c 1996/0214
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/print.c /n/fornaxdump/1996/0214/sys/src/brazil/port/print.c
540a
USED(arg);
.
538c
flags(va_list *arg, Fconv *fp)
.
532a
printcol++;
.
530a
USED(arg);
.
528c
percent(va_list *arg, Fconv *fp)
.
523c
return 0;
.
518c
r = va_arg(*arg, Rune*);
.
513c
s = va_arg(*arg, char*);
.
507c
sconv(va_list *arg, Fconv *fp)
.
502c
return 0;
.
495c
rune = va_arg(*arg, int);
.
490c
cconv(va_list *arg, Fconv *fp)
.
480c
s[0] = '*';
s[1] = fp->chr;
s[2] = '*';
s[3] = 0;
.
478c
return (*fmtconv[n])(arg, fp);
.
468c
noconv(va_list *arg, Fconv *fp)
.
342c
return 0;
.
329d
325,327c
if(fp->f3 & FSHARP) {
if(b == 8 && s[i] != '0')
.
319,321d
313,316c
v = (ulong)v / b;
.
300,303c
n = (ulong)v % b;
.
290,291c
v = va_arg(*arg, unsigned);
.
285,286c
v = va_arg(*arg, int);
.
281d
279c
h = va_arg(*arg, int);
.
275d
273c
h = va_arg(*arg, int);
.
268,269c
v = va_arg(*arg, ulong);
.
263,264c
v = va_arg(*arg, long);
.
256,261c
switch(fp->f3 & (FLONG|FSHORT|FUNSIGN)) {
.
232,234d
230d
227c
int i, f, n, b, ucase;
.
224c
numbconv(va_list *arg, Fconv *fp)
.
219d
214c
n = (*fmtconv[n])(&argp, &local);
.
202,203c
n = va_arg(argp, int);
.
147c
n = runetochar(local.out, &rune);
.
116c
local.eout = es-UTFmax-1;
.
109c
doprint(char *s, char *es, char *fmt, va_list argp)
.
101c
return -1;
.
99c
return -1;
.
93c
fmtinstall(int c, int (*f)(va_list*, Fconv*))
.
44c
int (*fmtconv[MAXCONV])(va_list*, Fconv*) =
.
41c
int numbconv(va_list*, Fconv*);
.
37,39c
static int cconv(va_list*, Fconv*);
static int sconv(va_list*, Fconv*);
static int percent(va_list*, Fconv*);
.
34,35c
static int noconv(va_list*, Fconv*);
static int flags(va_list*, Fconv*);
.
23,28d
14,20c
FPLUS = 1<<0,
FMINUS = 1<<1,
FSHARP = 1<<2,
FLONG = 1<<3,
FSHORT = 1<<4,
FUNSIGN = 1<<5,
FVLONG = 1<<6,
.
## diffname port/print.c 1998/0327
## diff -e /n/fornaxdump/1996/0214/sys/src/brazil/port/print.c /n/emeliedump/1998/0327/sys/src/brazil/port/print.c
289a
if(fp->f3 & FVLONG) {
if(vl <= 0)
break;
continue;
}
.
287c
if(fp->f3 & FVLONG)
vl = (uvlong)vl / b;
else
v = (ulong)v / b;
.
277c
if(fp->f3 & FVLONG)
n = (uvlong)vl % b;
else
n = (ulong)v % b;
.
271,273c
if(fp->f3 & FVLONG) {
if(!(fp->f3 & FUNSIGN) && vl < 0) {
vl = -vl;
f = 1;
}
} else {
if(!(fp->f3 & FUNSIGN) && v < 0) {
v = -v;
f = 1;
}
.
244c
switch(fp->f3 & (FVLONG|FLONG|FSHORT|FUNSIGN)) {
case FVLONG|FLONG:
vl = va_arg(*arg, vlong);
break;
case FUNSIGN|FVLONG|FLONG:
vl = va_arg(*arg, uvlong);
break;
.
222a
SET(v);
SET(vl);
.
221a
vlong vl;
.
## diffname port/print.c 1998/0512
## diff -e /n/emeliedump/1998/0327/sys/src/brazil/port/print.c /n/emeliedump/1998/0512/sys/src/brazil/port/print.c
124c
.
## diffname port/print.c 1999/0517
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/print.c /n/emeliedump/1999/0517/sys/src/brazil/port/print.c
272a
break;
case FUNSIGN|FPOINTER:
v = (ulong)va_arg(*arg, void*);
.
244a
case 'p':
fp->f3 |= FPOINTER|FUNSIGN;
b = 16;
break;
.
66a
fmtindex['p'] = cc;
.
20a
FPOINTER = 1<<7,
.
## diffname port/print.c 1999/0810
## diff -e /n/emeliedump/1999/0517/sys/src/brazil/port/print.c /n/emeliedump/1999/0810/sys/src/brazil/port/print.c
6d
## diffname port/print.c 1999/0819
## diff -e /n/emeliedump/1999/0810/sys/src/brazil/port/print.c /n/emeliedump/1999/0819/sys/src/brazil/port/print.c
584a
#ifdef NOTDEF
int
fltconv(va_list *arg, Fconv *fp)
{
char s1[FDIGIT+10], s2[FDIGIT+10];
double f, g, h;
int e, d, i, n, s;
int c1, c2, c3, f2, ucase;
f2 = fp->f2;
fp->f2 = NONE;
f = va_arg(*arg, double);
if(isNaN(f)){
strconv("NaN", fp);
return 0;
}
if(isInf(f, 1)){
strconv("+Inf", fp);
return 0;
}
if(isInf(f, -1)){
strconv("-Inf", fp);
return 0;
}
s = 0;
if(f < 0) {
f = -f;
s++;
}
ucase = 0;
if(fp->chr >= 'A' && fp->chr <= 'Z') {
ucase = 1;
fp->chr += 'a'-'A';
}
loop:
e = 0;
if(f != 0) {
frexp(f, &e);
e = e * .30103;
d = e/2;
h = f * pow10(-d); /* 10**-e in 2 parts */
g = h * pow10(d-e);
while(g < 1) {
e--;
g = h * pow10(d-e);
}
while(g >= 10) {
e++;
g = h * pow10(d-e);
}
}
if(f2 == NONE)
f2 = FDEFLT;
if(fp->chr == 'g' && f2 > 0)
f2--;
if(f2 > FDIGIT)
f2 = FDIGIT;
/*
* n is number of digits to convert
* 1 before, f2 after, 1 extra for rounding
*/
n = f2 + 2;
if(fp->chr == 'f') {
/*
* e+1 before, f2 after, 1 extra
*/
n += e;
if(n <= 0)
n = 1;
}
if(n >= FDIGIT+2) {
if(fp->chr == 'e')
f2 = -1;
fp->chr = 'e';
goto loop;
}
/*
* convert n digits
*/
g = f;
if(e < 0) {
if(e < -55) {
g *= pow10(50);
g *= pow10(-e-51);
} else
g *= pow10(-e-1);
}
for(i=0; i<n; i++) {
d = e-i;
if(d >= 0) {
h = pow10(d);
d = floor(g/h);
g -= d * h;
} else {
g *= 10;
d = floor(g);
g -= d;
}
s1[i+1] = d + '0';
}
/*
* round by adding .5 into extra digit
*/
d = 5;
for(i=n-1; i>=0; i--) {
s1[i+1] += d;
d = 0;
if(s1[i+1] > '9') {
s1[i+1] -= 10;
d++;
}
}
i = 1;
if(d) {
s1[0] = '1';
e++;
i = 0;
}
/*
* copy into final place
* c1 digits of leading '0'
* c2 digits from conversion
* c3 digits after '.'
*/
d = 0;
if(s)
s2[d++] = '-';
else
if(fp->f3 & FPLUS)
s2[d++] = '+';
c1 = 0;
c2 = f2 + 1;
c3 = f2;
if(fp->chr == 'g')
if(e >= -5 && e <= f2) {
c1 = -e - 1;
if(c1 < 0)
c1 = 0;
c3 = f2 - e;
fp->chr = 'h';
}
if(fp->chr == 'f') {
c1 = -e;
if(c1 < 0)
c1 = 0;
if(c1 > f2)
c1 = c2;
c2 += e;
if(c2 < 0)
c2 = 0;
}
while(c1 > 0) {
if(c1+c2 == c3)
s2[d++] = '.';
s2[d++] = '0';
c1--;
}
while(c2 > 0) {
if(c1+c2 == c3)
s2[d++] = '.';
s2[d++] = s1[i++];
c2--;
}
/*
* strip trailing '0' on g conv
*/
if(fp->f3 & FSHARP) {
if(c1+c2 == c3)
s2[d++] = '.';
} else
if(fp->chr == 'g' || fp->chr == 'h') {
for(n=d-1; n>=0; n--)
if(s2[n] != '0')
break;
for(i=n; i>=0; i--)
if(s2[i] == '.') {
d = n;
if(i != n)
d++;
break;
}
}
if(fp->chr == 'e' || fp->chr == 'g') {
if(ucase)
s2[d++] = 'E';
else
s2[d++] = 'e';
c1 = e;
if(c1 < 0) {
s2[d++] = '-';
c1 = -c1;
} else
s2[d++] = '+';
if(c1 >= 100) {
s2[d++] = c1/100 + '0';
c1 = c1%100;
}
s2[d++] = c1/10 + '0';
s2[d++] = c1%10 + '0';
}
s2[d] = 0;
strconv(s2, fp);
return 0;
}
#endif
.
569,572d
554a
static int
flags(va_list*, Fconv *fp)
{
int f;
.
553c
col = va_arg(*arg, int);
while(printcol < col) {
pc = (printcol+8) & ~7;
if(pc <= col) {
pchar('\t', fp);
printcol = pc;
} else {
pchar(' ', fp);
printcol++;
}
}
return 0;
}
#endif
.
551c
int col, pc;
.
547,549c
#ifdef NOTDEF
static int
column(va_list *arg, Fconv *fp)
.
539,542c
pchar('%', fp);
.
535,537c
static int
percent(va_list*, Fconv *fp)
.
514,515c
static int
.
497,498c
#ifdef NOTDEF
static int
rconv(va_list*, Fconv *fp)
{
char s[ERRLEN];
s[0] = 0;
errstr(s);
fp->f2 = NONE;
strconv(s, fp);
return 0;
}
#endif
static int
.
479,485d
476d
472,474c
static int
noconv(va_list*, Fconv *fp)
.
464,465c
pchar(' ', fp);
.
439,445c
pchar(c, fp);
.
421,422c
pchar(' ', fp);
.
401,402c
pchar(' ', fp);
.
376,382c
pchar(c, fp);
.
364,365c
pchar(' ', fp);
.
354,355c
int n, c;
.
270,283d
261a
case FUNSIGN|FPOINTER:
v = (ulong)va_arg(*arg, void*);
break;
.
253c
switch(fp->f3 & (FVLONG|FLONG|FUNSIGN|FPOINTER)) {
.
236a
case 'b':
b = 2;
break;
.
221d
208c
n = (*fmtalloc.conv[n])(&argp, &local);
.
206c
n = fmtalloc.index[c];
.
139,145c
pchar(c, &local);
.
125c
.
111c
local.eout = es-1;
.
109a
if(fmtalloc.convcount <= 0)
initfmt();
if(s >= es)
return s;
.
102a
static void
pchar(Rune c, Fconv *fp)
{
int n;
n = fp->eout - fp->out;
if(n > 0) {
if(c < Runeself) {
*fp->out++ = c;
return;
}
if(n >= UTFmax || n >= runelen(c)) {
n = runetochar(fp->out, &c);
fp->out += n;
return;
}
fp->eout = fp->out;
}
}
.
97,99c
}
fmtalloc.conv[fmtalloc.convcount] = f;
fmtalloc.index[c] = fmtalloc.convcount;
fmtalloc.convcount++;
unlock(&fmtalloc);
.
95c
}
if(fmtalloc.convcount >= MAXCONV){
unlock(&fmtalloc);
.
93c
if(c < 0 || c >= MAXFMT){
unlock(&fmtalloc);
.
91c
lock(&fmtalloc);
if(fmtalloc.convcount <= 0)
.
84c
fmtalloc.conv[cc] = sconv;
fmtalloc.index['s'] = cc;
fmtalloc.index['S'] = cc;
cc++;
fmtalloc.conv[cc] = percent;
fmtalloc.index['%'] = cc;
cc++;
/*
fmtalloc.conv[cc] = column;
fmtalloc.index['|'] = cc;
cc++;
*/
fmtalloc.convcount = cc;
.
82a
*/
.
80,81c
/*
fmtalloc.conv[cc] = rconv;
fmtalloc.index['r'] = cc;
.
75,77c
fmtalloc.conv[cc] = cconv;
fmtalloc.index['c'] = cc;
fmtalloc.index['C'] = cc;
.
73a
*/
.
70,72c
/*
fmtalloc.conv[cc] = fltconv;
fmtalloc.index['e'] = cc;
fmtalloc.index['f'] = cc;
fmtalloc.index['g'] = cc;
fmtalloc.index['E'] = cc;
fmtalloc.index['G'] = cc;
.
62,67c
fmtalloc.conv[cc] = numbconv;
fmtalloc.index['d'] = cc;
fmtalloc.index['o'] = cc;
fmtalloc.index['x'] = cc;
fmtalloc.index['X'] = cc;
fmtalloc.index['p'] = cc;
.
53,59c
fmtalloc.conv[cc] = flags;
fmtalloc.index['+'] = cc;
fmtalloc.index['-'] = cc;
fmtalloc.index['#'] = cc;
fmtalloc.index['l'] = cc;
fmtalloc.index['u'] = cc;
.
50c
fmtalloc.conv[cc] = noconv;
.
43,44c
static void
.
37,41d
35c
extern int numbconv(va_list*, Fconv*);
/* extern int fltconv(va_list*, Fconv*); */
.
33a
/* static int column(va_list*, Fconv*); */
.
31a
/* static int rconv(va_list*, Fconv*); */
.
25,26c
static struct
{
Lock;
int convcount;
char index[MAXFMT];
int (*conv[MAXCONV])(va_list*, Fconv*);
} fmtalloc;
.
20c
FPOINTER= 1<<7,
.
17d
2a
#include "mem.h"
#include "dat.h"
#include "fns.h"
.
## diffname port/print.c 2001/0316
## diff -e /n/emeliedump/1999/0819/sys/src/brazil/port/print.c /n/emeliedump/2001/0316/sys/src/9/port/print.c
624a
}
static void
qchar(Rune c, Fconv *fp, int hold, int *closed)
{
int n;
if(*closed)
return;
n = fp->eout - fp->out - hold;
if(n > 0) {
if(c < Runeself) {
*fp->out++ = c;
return;
}
if(n >= UTFmax || n >= runelen(c)) {
n = runetochar(fp->out, &c);
fp->out += n;
return;
}
}
if(hold)
*closed = 1;
else
fp->eout = fp->out;
}
static int
needsquotes(char *s, int *quotelenp)
{
char *t;
int nextra, ok, w;
Rune r;
nextra = 0;
ok = 1;
for(t=s; *t; t+=w){
w = chartorune(&r, t);
if(r <= L' ')
ok = 0;
else if(r == L'\''){
ok = 0;
nextra++; /* ' becomes '' */
}
}
if(ok){
*quotelenp = t-s;
return 0;
}
*quotelenp = 1+ t-s + nextra +1;
return 1;
}
static int
runeneedsquotes(Rune *s, int *quotelenp)
{
Rune *t;
int nextra, ok;
Rune r;
nextra = 0;
ok = 1;
for(t=s; *t; t++){
r = *t;
if(r <= L' ')
ok = 0;
else if(r == L'\''){
ok = 0;
nextra++; /* ' becomes '' */
}
}
if(ok){
*quotelenp = t-s;
return 0;
}
*quotelenp = 1+ t-s + nextra +1;
return 1;
}
void
qadv(Rune c, Fconv *fp, int hold, int *np, int *closedp)
{
if(fp->f2 == NONE || fp->f2 > 0) {
qchar(c, fp, hold, closedp);
(*np)++;
if(fp->f2 != NONE)
fp->f2--;
switch(c) {
default:
printcol++;
break;
case '\n':
printcol = 0;
break;
case '\t':
printcol = (printcol+8) & ~7;
break;
}
}
}
static int
qstrconv(char *s, Rune *r, int quotelen, Fconv *fp)
{
int closed, i, n, c;
Rune rune;
closed = 0;
if(fp->f3 & FMINUS)
fp->f1 = -fp->f1;
n = 0;
if(fp->f1 != NONE && fp->f1 >= 0) {
n = quotelen;
while(n < fp->f1) {
qchar(' ', fp, 0, &closed);
printcol++;
n++;
}
}
if(fp->eout - fp->out < 2) /* 2 because need at least '' */
return 0;
qchar('\'', fp, 0, &closed);
n++;
for(;;) {
if(s){
c = *s & 0xff;
if(c >= Runeself) {
i = chartorune(&rune, s);
s += i;
c = rune;
} else
s++;
}else
c = *r++;
if(c == 0)
break;
if(c == '\'')
qadv(c, fp, 2, &n, &closed); /* '' plus closing quote */
qadv(c, fp, 1, &n, &closed);
}
closed = 0; /* there will always be room for closing quote */
qchar('\'', fp, 0, &closed);
n++;
if(fp->f1 != NONE && fp->f1 < 0) {
fp->f1 = -fp->f1;
while(n < fp->f1) {
qchar(' ', fp, 0, &closed);
printcol++;
n++;
}
}
return 0;
}
int
quotestrconv(va_list *arg, Fconv *fp)
{
char *s;
int quotelen;
s = va_arg(*arg, char*);
if(s == nil){
strconv("<null>", fp);
return 0;
}
if(needsquotes(s, "elen) == 0){
strconv(s, fp);
va_end(arg);
return 0;
}
qstrconv(s, nil, quotelen, fp);
va_end(arg);
return 0;
}
int
quoterunestrconv(va_list *arg, Fconv *fp)
{
Rune *r;
int quotelen;
r = va_arg(*arg, Rune*);
if(r == nil){
strconv("<null>", fp);
return 0;
}
if(runeneedsquotes(r, "elen) == 0){
Strconv(r, fp);
va_end(arg);
return 0;
}
qstrconv(nil, r, quotelen, fp);
va_end(arg);
return 0;
}
void
quotefmtinstall(void)
{
fmtinstall('q', quotestrconv);
fmtinstall('Q', quoterunestrconv);
.
93a
fmtalloc.conv[cc] = quoterunestrconv;
fmtalloc.index['Q'] = cc;
cc++;
.
92a
fmtalloc.conv[cc] = quotestrconv;
fmtalloc.index['q'] = cc;
cc++;
.
45a
extern int quotestrconv(va_list*, Fconv*);
extern int quoterunestrconv(va_list*, Fconv*);
.
## diffname port/print.c 2001/0819
## diff -e /n/emeliedump/2001/0316/sys/src/9/port/print.c /n/emeliedump/2001/0819/sys/src/9/port/print.c
694a
if(*s == L'\0')
return 1;
.
667a
if(*s == '\0')
return 1;
.
## diffname port/print.c 2002/0217
## diff -e /n/emeliedump/2001/0819/sys/src/9/port/print.c /n/emeliedump/2002/0217/sys/src/9/port/print.c
824,1068d
804,822c
return -1;
.
802c
_efgfmt(Fmt*)
.
509,800d
457,506c
unlock(&fmtl);
.
455c
_fmtunlock(void)
.
408,451c
lock(&fmtl);
.
406c
_fmtlock(void)
.
16,404d
7,14c
static Lock fmtl;
.
1,5c
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
.
|