From ce05175372a9ddca1a225db0765ace1127a39293 Mon Sep 17 00:00:00 2001 From: Nicholas Date: Fri, 12 Nov 2021 09:22:01 -0800 Subject: chore: simplified organizational structure --- sys/libfmt/do.c | 730 -------------------------------------------------------- 1 file changed, 730 deletions(-) delete mode 100644 sys/libfmt/do.c (limited to 'sys/libfmt/do.c') diff --git a/sys/libfmt/do.c b/sys/libfmt/do.c deleted file mode 100644 index eaac0a3..0000000 --- a/sys/libfmt/do.c +++ /dev/null @@ -1,730 +0,0 @@ -#include "internal.h" -#include - -#define atomic _Atomic -#define MaxFmt 128 -#define atomic·load atomic_load -#define atomic·store atomic_store - -// ----------------------------------------------------------------------- -// globals - -/* built in verbs */ -static int fmtflag(fmt·State *); -static int fmtpercent(fmt·State *); -static int fmtrune(fmt·State *); -static int fmtfloat(fmt·State *); -static int fmtutf8(fmt·State *); -static int fmtint(fmt·State *); -static int fmtchar(fmt·State *); -static int fmtcount(fmt·State *); -static int fmtstring(fmt·State *); -static int fmterror(fmt·State *); - -static int badfmt(fmt·State *); - -static struct -{ - atomic int len; - Verb verb[MaxFmt]; -} formatter = -{ - ATOMIC_VAR_INIT(30), - { - {' ', fmtflag}, - {'#', fmtflag}, - {'%', fmtpercent}, - {'\'',fmtflag}, - {'+', fmtflag}, - {',', fmtflag}, - {'-', fmtflag}, - {'C', fmtrune}, - {'E', fmtfloat}, - {'F', fmtfloat}, - {'G', fmtfloat}, - {'L', fmtflag}, - {'S', fmtutf8}, - {'X', fmtint}, - {'b', fmtint}, - {'c', fmtchar}, - {'d', fmtint}, - {'e', fmtfloat}, - {'f', fmtfloat}, - {'g', fmtfloat}, - {'h', fmtflag}, - {'i', fmtint}, - {'l', fmtflag}, - {'n', fmtcount}, - {'o', fmtint}, - {'p', fmtint}, - {'r', fmterror}, - {'s', fmtstring}, - {'U', fmtflag}, - {'u', fmtint}, - {'x', fmtint}, - } -}; - -// ----------------------------------------------------------------------- -// internal functions - -static Formatter -format(int c) -{ - Verb *v, *e; - e = &formatter.verb[atomic·load(&formatter.len)]; - for(v=e; v > formatter.verb; --v){ - if(v->c == c) - return v->fmt; - } - - return badfmt; -} - -static char * -dispatch(fmt·State *io, char *fmt) -{ - rune r; - int i, n; - - io->flag = 0; - io->width = io->prec = 0; - - /* - * the form of each print verb: - * % [flags] verb - * + the verb is a single character - * + each flag is either - * - a single character - * - a decimal numeric string - * - up to 2 decimal strings can be used - * - [width|*].[prec|*] - * - if missing, set to 0 - * - if *, grab from varargs - */ - for(;;){ - fmt += utf8·decode(fmt, &r); - io->verb = r; - switch(r){ - case 0: - return nil; - case '.': - io->flag |= fmt·Width|fmt·Prec; - continue; - case '0': - if(!(io->flag & fmt·Width)){ - io->flag |= fmt·Zero; - continue; - } - /* fallthrough */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - i = 0; - while('0' <= r && r <= '9'){ - i = 10*i + (r-'0'); - r = *fmt++; - } - fmt--; - number: - if(io->flag & fmt·Width){ - io->flag |= fmt·Prec; - io->prec = i; - }else{ - io->flag |= fmt·Width; - io->width = i; - } - continue; - case '*': - i = va_arg(io->args, int); - if(i < 0){ - if(io->flag&fmt·Prec){ - io->flag &= ~fmt·Prec; - io->prec = 0; - continue; - } - i = -i; - io->flag |= fmt·Left; - } - goto number; - } - n = format(r)(io); - if(n < 0) - return nil; - if(!n) - return fmt; - } -} - -static char * -flush(fmt·State *io, char *b, int len) -{ - io->n += b - io->buffer.cur; - io->buffer.cur = b; - if(!io->flush || !(*io->flush)(io) || io->buffer.cur + len >= io->buffer.end) { - io->buffer.end = io->buffer.cur; - return nil; - } - return io->buffer.cur; -} - -static int -pad(fmt·State *io, int n) -{ - int i; - char *b=io->buffer.cur, *e=io->buffer.end; - - for(i=0; i=e){ - if(!(b=flush(io, b, 1))) - return -1; - e = io->buffer.end; - } - *b++ = ' '; - } - - io->n += b - io->buffer.cur; - io->buffer.cur = b; - return 0; -} - -static int -copy(fmt·State *io, char *m, int sz, int n) -{ - ulong f; - rune r; - int nc, w, nb; - char *b, *e, *me; - - w = 0; - f = io->flag; - me = m + sz; - - if(f&fmt·Width) - w = io->width; - if(f&fmt·Prec && n > io->prec) - n = io->prec; - if(!(f&fmt·Left) && pad(io, w-n)<0) - return -1; - - b = io->buffer.cur; - e = io->buffer.end; - - for(nc=n; nc>0; nc--){ - r = *(uchar *)m; - if(utf8·onebyte(r)){ - nb=1; - m++; - }else if((me-m) >= UTFmax || utf8·canfit(m, me-m)){ - nb=utf8·decode(m, &r); - m+=n; - }else - break; - - if(b+n>e){ - if(!(b=flush(io, b, nb))) - return -1; - e = io->buffer.end; - } - b += utf8·encode(&r, b); - } - - io->n += b - io->buffer.cur; - io->buffer.cur = b; - if(f&fmt·Left && pad(io, w-n)<0) - return -1; - - return 0; -} - -static int -copyrune(fmt·State *io, rune *m, int n) -{ - ulong f; - rune r, *me; - int w, nb; - char *b, *e; - - w = 0; - f = io->flag; - - if(f&fmt·Width) - w = io->width; - if(f&fmt·Prec && n > io->prec) - n = io->prec; - - if(!(f&fmt·Left) && pad(io, w-n)<0) - return -1; - - b = io->buffer.cur; - e = io->buffer.end; - - for(me=m+n; m < me; m++){ - r = *m; - nb = utf8·runelen(r); - if(b + nb > e){ - if(!(b=flush(io, b, nb))) - return -1; - e = io->buffer.end; - } - b += utf8·encode(&r, b); - } - - io->n += b - io->buffer.cur; - io->buffer.cur = b; - if(f&fmt·Left && pad(io, w-n)<0) - return -1; - - return 0; -} - -static int -copystring(fmt·State *io, char *s) -{ - rune r; - int i,j; - - if(!s) - return copy(io, "", 5, 5); - - if(io->flag&fmt·Prec){ - i = 0; - for(j=0; j < io->prec && s[i]; j++) - i += utf8·decode(s+i, &r); - - return copy(io, s, i, j); - } - return copy(io, s, strlen(s), utf8·len(s)); -} - -static int -copyutf8(fmt·State *io, rune *s) -{ - rune *e; - int n,p; - - if(!s) - return copy(io, "", 5, 5); - - if(io->flag & fmt·Prec){ - p = io->prec; - for(n=0; n group){ - if((*groups)[1] != 0) - (*groups)++; - *digits = 1; - return 1; - } - return 0; -} - -// ----------------------------------------------------------------------- -// formatters - -static int -fmtchar(fmt·State *io) -{ - char x[1]; - x[0] = va_arg(io->args, int); - io->prec = 1; - - return copy(io, x, 1, 1); -} - -static int -fmtstring(fmt·State *io) -{ - char *s; - s = va_arg(io->args, char *); - return copystring(io, s); -} - -static int -fmterror(fmt·State *io) -{ - char *s; - s = strerror(errno); - return copystring(io, s); -} - -static int -fmtrune(fmt·State *io) -{ - rune x[1]; - - x[0] = va_arg(io->args, int); - return copyrune(io, x, 1); -} - -static int -fmtutf8(fmt·State *io) -{ - rune *s; - - s = va_arg(io->args, rune *); - return copyutf8(io, s); -} - -static int -fmtpercent(fmt·State *io) -{ - rune x[1]; - - x[0] = io->verb; - io->prec = 1; - return copyrune(io, x, 1); -} - -static int -fmtint(fmt·State *io) -{ - union{ - ulong u; - uvlong v; - } val; - int neg, base, i, n, f, w, isv; - int digits, bytes, runes, excess; - char *groups, *thousands; - char *p, *conv, buf[140]; - - f = io->flag; - neg = 0; - isv = 0; - val.u = 0; - - switch(io->verb){ - case 'o': case 'p': case 'u': case 'x': case 'X': - f |= fmt·Unsigned; - f &= ~(fmt·Sign|fmt·Space); - } - - /* set flags */ - if(io->verb=='p'){ - val.u = (ulong)va_arg(io->args, void*); - io->verb = 'x'; - f |= fmt·Unsigned; - }else if(f&fmt·Vlong){ - isv=1; - if(f&fmt·Unsigned) - val.v = va_arg(io->args, uvlong); - else - val.v = va_arg(io->args, vlong); - }else if(f&fmt·Long){ - if(f&fmt·Unsigned) - val.u = va_arg(io->args, ulong); - else - val.u = va_arg(io->args, long); - }else if(f&fmt·Byte){ - if(f&fmt·Unsigned) - val.u = (uchar)va_arg(io->args, int); - else - val.u = (char)va_arg(io->args, int); - }else if(f&fmt·Short){ - if(f&fmt·Unsigned) - val.u = (ushort)va_arg(io->args, int); - else - val.u = (short)va_arg(io->args, int); - }else{ - if(f&fmt·Unsigned) - val.u = va_arg(io->args, uint); - else - val.u = va_arg(io->args, int); - } - - conv = "0123456789abcdef"; - groups = "\4"; - thousands = io->thousands; - /* get base */ - switch(io->verb){ - case 'd': case 'i': case 'u': - base = 10; - groups = io->groups; - break; - case 'X': - conv = "0123456789ABCDEF"; - /*fallthrough*/ - case 'x': - base = 16; - thousands = ":"; - break; - case 'b': - base = 2; - thousands = ":"; - break; - case 'o': - base = 8; - break; - default: - return -1; - } - - /* check for negativity */ - if(!(f&fmt·Unsigned)){ - if(isv && (vlong)val.v < 0){ - val.v = -(vlong)val.v; - neg = 1; - }else if(!isv && (long)val.u < 0){ - val.u = -(long)val.u; - neg = 1; - } - } - - p = buf + sizeof(buf) - 1; - n = 0; - digits = 0; - excess = 0; - runes = utf8·len(thousands); - bytes = strlen(thousands); - -#define PARSE(VALUE) \ - while((VALUE)){ \ - i = (VALUE) % base; \ - (VALUE) /= base; \ - if((f&fmt·Comma) && n%4 == 3){ \ - *p-- = ','; \ - n++; \ - } \ - if((f&fmt·Apost) && needseperate(&digits, &groups)){ \ - n += runes; \ - excess += bytes - runes; \ - p -= bytes; \ - memmove(p+1, thousands, bytes); \ - } \ - *p-- = conv[i]; \ - n++; \ - } - if(isv) - PARSE(val.v) - else - PARSE(val.u) -#undef PARSE - - if(!n){ - if(!(f&fmt·Prec) || io->prec != 0 || (io->verb == 'o' && (f&fmt·Sharp))){ - *p-- = '0'; - n = 1; - if(f&fmt·Apost) - needseperate(&digits,&groups); - } - - if(io->verb == 'x' || io->verb == 'X') - f &= ~fmt·Sharp; - } - - for(w = io->prec; n < w && p > buf+3; n++){ - if((f&fmt·Apost) && needseperate(&digits, &groups)){ - n += runes; - excess += bytes - runes; - p -= bytes; - memmove(p+1, thousands, bytes); - } - *p-- = '0'; - } - - if(neg || (f&(fmt·Sign|fmt·Space))) - n++; - - if(f&fmt·Sharp){ - if(base==16) - n += 2; - else if(base == 8){ - if(p[1] == '0') - f &= ~fmt·Sharp; - else - n++; - } - } - - if(f&fmt·Zero && !(f & (fmt·Left|fmt·Prec))){ - w = 0; - if(f & fmt·Width) - w = io->width; - for(; n < w && p > buf+3; n++){ - if((f & fmt·Apost) && needseperate(&digits, &groups)){ - n += runes; - excess += bytes - runes; - p -= bytes; - memmove(p+1, thousands, bytes); - } - *p-- = '0'; - } - io->flag &= ~fmt·Width; - } - - if(f&fmt·Sharp){ - if(base==16) - *p-- = io->verb; - if(base==16 || base == 8) - *p-- = '0'; - } - - if(neg) - *p-- = '-'; - else if(f & fmt·Sign) - *p-- = '+'; - else if (f & fmt·Space) - *p-- = ' '; - - io->flag &= ~fmt·Prec; - return copy(io, p+1, n+excess, n); -} - -static int -fmtcount(fmt·State *io) -{ - void *p; - ulong f; - - f = io->flag; - p = va_arg(io->args, void*); - - if(f&fmt·Vlong) - *(vlong*)p = io->n; - else if(f&fmt·Long) - *(long*)p = io->n; - else if(f&fmt·Byte) - *(char*)p = io->n; - else if(f&fmt·Short) - *(short*)p = io->n; - else - *(int*)p = io->n; - - return 0; -} - -static int -fmtflag(fmt·State *io) -{ - switch(io->verb){ - case ',': io->flag |= fmt·Comma; break; - case '-': io->flag |= fmt·Left; break; - case '+': io->flag |= fmt·Sign; break; - case '#': io->flag |= fmt·Sharp; break; - case '\'': io->flag |= fmt·Apost; break; - case ' ': io->flag |= fmt·Space; break; - case 'u': io->flag |= fmt·Unsigned; break; - case 'L': io->flag |= fmt·Ldouble; break; - case 'h': - if(io->flag&fmt·Short) - io->flag |= fmt·Byte; - io->flag |= fmt·Short; - break; - case 'l': - if(io->flag&fmt·Long) - io->flag |= fmt·Vlong; - io->flag |= fmt·Long; - break; - } - return 1; -} - -static int -badfmt(fmt·State *io) -{ - int n; - char x[UTFmax+2]; - - x[0] = '%'; - n = 1 + utf8·encode(&io->verb, x+1); - x[n++] = '%'; - io->prec = n; - copy(io, x, n, n); - - return 0; -} - -#include "float.c" - -// ----------------------------------------------------------------------- -// exports - -int -fmt·do(fmt·State *io, char *fmt) -{ - rune r; - int c, n; - char *b, *e; - - for(;;){ - b = io->buffer.cur; - e = io->buffer.end; - while((c = *(uchar *)fmt) && c != '%'){ - if(utf8·onebyte(c)){ - if(b >= e){ - if(!(b=flush(io, b, 1))) - return -1; - e = io->buffer.end; - } - *b++ = *fmt++; - }else{ - n = utf8·decode(fmt, &r); - if(b + n > e){ - if(!(b=flush(io, b, n))) - return -1; - e = io->buffer.end; - } - while(n--) - *b++ = *fmt++; - } - } - fmt++; - io->n += b - io->buffer.cur; - io->buffer.cur = b; - if(!c) /* we hit our nul terminator */ - return io->n - n; - io->buffer.end = e; - - if(!(fmt=dispatch(io, fmt))) - return -1; - } -} - -int -fmt·install(int verb, Formatter func) -{ - Verb *v; - int i, ret; - -lock: - if(verb <= 0 || verb >= 65536){ - ret = -1; - goto unlock; - } - if(!func) - func = badfmt; - - if((i = atomic·load(&formatter.len))==MaxFmt) - return -1; - - v = &formatter.verb[i]; - v->c = verb; - v->fmt = func; - - atomic·store(&formatter.len, i+1); - ret = 0; -unlock: - return ret; -} -- cgit v1.2.1