Merge pull request #1 from Hojun-Cho/fix-fmt

fix fmt,print
This commit is contained in:
O_WRONLY 2024-12-12 17:24:26 +09:00 committed by GitHub
commit bc671ff92b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 110 additions and 101 deletions

View File

@ -11,19 +11,19 @@ enum{
FUNSIGN = (1<<3), FUNSIGN = (1<<3),
}; };
static Op put(Op, int); static void put(Op*, int);
static Op noconv(Op); static int noconv(Op*);
static Op cconv(Op); static int cconv(Op*);
static Op dconv(Op); static int dconv(Op*);
static Op hconv(Op); static int hconv(Op*);
static Op lconv(Op); static int lconv(Op*);
static Op sconv(Op); static int sconv(Op*);
static Op uconv(Op); static int uconv(Op*);
static Op xconv(Op); static int xconv(Op*);
static Op Xconv(Op); static int Xconv(Op*);
static Op percent(Op); static int percent(Op*);
static Op (*fmtconv[MAXCON])(Op) = { static int (*fmtconv[MAXCON])(Op*) = {
noconv, noconv,
cconv, dconv, hconv, lconv, cconv, dconv, hconv, lconv,
sconv, uconv, xconv, Xconv, sconv, uconv, xconv, Xconv,
@ -54,7 +54,7 @@ strlen(char *s)
} }
int int
fmtinstall(int c, Op (*f)(Op)) fmtinstall(int c, int (*f)(Op*))
{ {
c &= 0177; c &= 0177;
if(fmtindex[c] == 0){ if(fmtindex[c] == 0){
@ -67,88 +67,87 @@ fmtinstall(int c, Op (*f)(Op))
} }
char* char*
doprint(char *p, char *ep, char *fmt, va_list ap) dofmt(Op *op, char *fmt)
{ {
int sf1, c; int sf1, c;
Op o = { .p = p, .ep = ep, .ap = ap };
while(1){ while(1){
c = *fmt++; c = *fmt++;
if(c != '%'){ if(c != '%'){
if(c == 0){ if(c == 0){
if(o.p < o.ep) if(op->p < op->ep)
*o.p = 0; *op->p = 0;
return o.p; return op->p;
} }
o = put(o, c); put(op, c);
continue; continue;
} }
o.f2 = -1; op->f2 = -1;
o.f1 = o.f3 = 0; op->f1 = op->f3 = 0;
o.padch = sf1 = 0; op->padch = sf1 = 0;
c = *fmt++; c = *fmt++;
if(c == '-'){ if(c == '-'){
sf1 = 1; sf1 = 1;
c = *fmt++; c = *fmt++;
}else if(c == '0' || c == ' '){ }else if(c == '0' || c == ' '){
o.padch = c; op->padch = c;
c = *fmt++; c = *fmt++;
} }
while(c >= '0' && c <= '9'){ while(c >= '0' && c <= '9'){
o.f1 = o.f1*10 + c-'0'; op->f1 = op->f1*10 + c-'0';
c = *fmt++; c = *fmt++;
} }
if(sf1) if(sf1)
o.f1 = -o.f1; op->f1 = -op->f1;
if(c != '.') if(c != '.')
goto conv; goto conv;
c = *fmt++; c = *fmt++;
while(c >= '0' && c <= '9'){ while(c >= '0' && c <= '9'){
if(o.f2 < 0) if(op->f2 < 0)
o.f2 = 0; op->f2 = 0;
o.f2 = o.f2*10 + c-'0'; op->f2 = op->f2*10 + c-'0';
c = *fmt++; c = *fmt++;
} }
conv: conv:
if(c == 0) if(c == 0)
fmt -= 1; fmt -= 1;
o = (*fmtconv[fmtindex[c&0177]])(o); c = (*fmtconv[fmtindex[c&0177]])(op);
if(o.f3){ if(c < 0){
op->f3 |= -c;
c = *fmt++; c = *fmt++;
goto conv; goto conv;
} }
} }
} }
static Op static void
strconv(char *o, Op op, int f1, int f2) strconv(char *s, Op *op, int f1, int f2)
{ {
int n, c; int n, c;
char *p; char *p;
n = strlen(o); n = strlen(s);
if(f1 >= 0) if(f1 >= 0)
while(n < f1){ while(n < f1){
op = put(op, op.padch); put(op, op->padch);
n += 1; n += 1;
} }
for(p=o; (c = *p++);) for(p=s; (c = *p++);)
if(f2){ if(f2){
op = put(op, c); put(op, c);
f2 -= 1; f2 -= 1;
} }
if(f1 < 0){ if(f1 < 0){
f1 = -f1; f1 = -f1;
while(n < f1){ while(n < f1){
op = put(op, ' '); put(op, ' ');
n += 1; n += 1;
} }
} }
return op;
} }
static Op static void
numconv(Op op, int base) numconv(Op *op, int base)
{ {
char b[IDIGIT]; char b[IDIGIT];
int i,f,n; int i,f,n;
@ -158,28 +157,28 @@ numconv(Op op, int base)
i = IDIGIT-1; i = IDIGIT-1;
f = 0; f = 0;
b[i] = 0; b[i] = 0;
switch(op.f3 & (FLONG|FSHORT|FUNSIGN)){ switch(op->f3 & (FLONG|FSHORT|FUNSIGN)){
case FLONG: case FLONG:
v = va_arg(op.ap, long); v = va_arg(op->ap, long);
break; break;
case FUNSIGN|FLONG: case FUNSIGN|FLONG:
v = va_arg(op.ap, ulong); v = va_arg(op->ap, ulong);
break; break;
case FSHORT: case FSHORT:
v = h = va_arg(op.ap, short); v = h = va_arg(op->ap, short);
break; break;
case FUNSIGN|FSHORT: case FUNSIGN|FSHORT:
h = va_arg(op.ap, ushort); h = va_arg(op->ap, ushort);
v = (ushort)h; v = (ushort)h;
break; break;
case FUNSIGN: case FUNSIGN:
v = va_arg(op.ap, unsigned); v = va_arg(op->ap, unsigned);
break; break;
default: default:
v = va_arg(op.ap, long); v = va_arg(op->ap, int);
break; break;
} }
if((op.f3 & FUNSIGN) && v < 0){ if((op->f3 & FUNSIGN) && v < 0){
v = -v; v = -v;
f = 1; f = 1;
} }
@ -188,117 +187,118 @@ numconv(Op op, int base)
n += '0'; n += '0';
if(n > '9'){ if(n > '9'){
n += 'a' - ('9'+1); n += 'a' - ('9'+1);
if(op.ucase) if(op->ucase)
n += 'A'-'a'; n += 'A'-'a';
} }
b[i] = n; b[i] = n;
v = (ulong)v / base; v = (ulong)v / base;
if(i < 2) if(i < 2)
break; break;
if(op.f2 >= 0 && i >= IDIGIT - op.f2) if(op->f2 >= 0 && i >= IDIGIT - op->f2)
continue; continue;
if(v <= 0) if(v <= 0)
break; break;
} }
if(f) if(f)
b[--i] = '-'; b[--i] = '-';
op.f3 = 0; strconv(b+i, op, op->f1, -1);
return strconv(b+i, op, op.f1, -1);
} }
static Op static int
noconv(Op op) noconv(Op *op)
{ {
return strconv("***ERROR: noconv***", op, 0, -1); strconv("***ERROR: noconv***", op, 0, -1);
return 0;
} }
static Op static int
cconv(Op op) cconv(Op *op)
{ {
char b[2]; char b[2];
b[0] = va_arg(op.ap, char); b[0] = va_arg(op->ap, char);
b[1] = 0; b[1] = 0;
return strconv(b, op, op.f1, -1); strconv(b, op, op->f1, -1);
return 0;
} }
static Op static int
dconv(Op op) dconv(Op *op)
{ {
return numconv(op, 10); numconv(op, 10);
return 0;
} }
static Op static int
hconv(Op op) hconv(Op *op)
{ {
op.f3 |= FSHORT; return -FSHORT;
return op;
} }
static Op static int
lconv(Op op) lconv(Op *op)
{ {
op.f3 |= FLONG; return -FLONG;
return op;
} }
static Op static int
uconv(Op op) uconv(Op *op)
{ {
op.f3 |= FUNSIGN; return -FUNSIGN;
return op;
} }
static Op static int
sconv(Op op) sconv(Op *op)
{ {
char *p; char *p;
p = va_arg(op.ap, char*); p = va_arg(op->ap, char*);
return strconv(p?p:"<nil>", op, op.f1, op.f2); strconv(p?p:"<nil>", op, op->f1, op->f2);
return 0;
} }
static Op static int
xconv(Op op) xconv(Op *op)
{ {
return numconv(op, 16); numconv(op, 16);
return 0;
} }
static Op static int
Xconv(Op op) Xconv(Op *op)
{ {
op.ucase = 1; op->ucase = 1;
op = numconv(op, 16); numconv(op, 16);
op.ucase = 0; op->ucase = 0;
return op; return 0;
} }
static Op static int
percent(Op op) percent(Op *op)
{ {
return put(op, '%'); put(op, '%');
return 0;
} }
static Op static void
put(Op o, int c) put(Op *op, int c)
{ {
static int pos; static int pos;
int opos; int opos;
if(c == 0) if(c == 0)
return o; return;
if(c == '\t'){ if(c == '\t'){
opos = pos; opos = pos;
pos = (opos+TABWIDTH) & (~(TABWIDTH-1)); pos = (opos+TABWIDTH) & (~(TABWIDTH-1));
while(opos++ < pos && o.p < o.ep) while(opos++ < pos && op->p < op->ep)
*o.p++ = ' '; *op->p++ = ' ';
return o; return;
} }
if(o.p < o.ep){ if(op->p < op->ep){
*o.p++ = c; *op->p++ = c;
pos++; pos++;
} }
if(c == '\n') if(c == '\n')
pos = 0; pos = 0;
return o;
} }

View File

@ -12,7 +12,8 @@ int comgetc(int dev);
void computc(int dev, int c); void computc(int dev, int c);
// fmt.c // fmt.c
int fmtinstall(int c, Op (*f)(Op)); char* dofmt(Op *op, char *fmt);
int fmtinstall(int c, int (*f)(Op*));
char *doprint(char *p, char *ep, char *fmt, va_list ap); char *doprint(char *p, char *ep, char *fmt, va_list ap);
int strlen(char *s); int strlen(char *s);
@ -20,6 +21,7 @@ int strlen(char *s);
void putchar(int c); void putchar(int c);
void putstr(char *s, int l); void putstr(char *s, int l);
int getchar(void); int getchar(void);
char* doprint(char *p, char *ep, char *fmt, va_list);
int print(char *fmt, ...); int print(char *fmt, ...);
int snprint(char *buf, int len, char *fmt, ...); int snprint(char *buf, int len, char *fmt, ...);

View File

@ -7,6 +7,13 @@
static void conputc(int); static void conputc(int);
static int congetc(void); static int congetc(void);
char*
doprint(char *p, char *ep, char *fmt, va_list ap)
{
Op op = { .p = p, .ep = ep, .ap = ap };
return dofmt(&op, fmt);
}
int int
print(char *fmt, ...) print(char *fmt, ...)
{ {