|
|
researchv10 Norman
#define NEXT(p) (*(p) ? *(p)++ : 0)
char fmtbuf[128];
double fnum; long lnum;
main(argc, argv)
char **argv;
{
char *format = *++argv, **Argv;
register char *fmt, *p;
register c, i;
++argv;
if (argc >= 2) do {
Argv = argv;
fmt = format;
while (c = NEXT(fmt)) switch (c) {
case '\\':
switch (c = NEXT(fmt)) {
case 'n':
putchar('\n'); break;
case 'r':
putchar('\r'); break;
case 't':
putchar('\t'); break;
case 'b':
putchar('\b'); break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
c -= '0';
for (i=0; i<2; i++)
if (*fmt >= '0' && *fmt <= '7')
c = (c << 3) + *fmt++ - '0';
default:
putchar(c); break;
}
break;
case '%':
p = fmtbuf;
*p++ = c;
while (c && (c = NEXT(fmt))) switch (c) {
case '*':
atonum(NEXT(argv));
p += sprintf(p, "%d", lnum);
break;
case 'h': case 'l':
break;
case 'd': case 'o': case 'x':
case 'D': case 'O': case 'X':
case 'f': case 'e': case 'g':
case 'c': case 'u': case 'U':
*p++ = c; *p = 0;
if (atonum(NEXT(argv)))
printf(fmtbuf, fnum);
else
printf(fmtbuf, lnum);
c = 0; break;
case 's':
*p++ = c; *p = 0;
printf(fmtbuf, NEXT(argv));
c = 0; break;
case '%':
*p++ = c; *p = 0;
printf(fmtbuf);
c = 0; break;
default:
*p++ = c;
}
break;
default:
putchar(c);
break;
}
} while (*argv && argv > Argv);
exit(0);
}
double
pwrten(exp)
register exp;
{
register double d;
if (exp < 0) return 1.0/pwrten(-exp);
if (exp == 0) return 1.0;
if (exp == 1) return 10.0;
d = pwrten(exp/2), d *= d;
if (exp & 1) d *= 10.0;
return d;
}
lexconst(n, ftype, exp)
register n, ftype, exp;
{
if (ftype)
fnum = (double)n * pwrten(exp);
else
lnum = n;
return ftype;
}
enum States { start, intscan, hexscan, fracscan, expstart, expscan};
atonum(p)
register char *p;
{
register state = (int)start, c;
unsigned int i = 0, ioct = 0;
unsigned int sign = 1, octal = 0, fexp = 0, sexp = 1, exp = 0;
switch (c = *p++) {
case '+':
c = *p++; break;
case '-':
sign = -1, c = *p++; break;
case '0':
++octal, c = *p++; break;
case '1': case '2': case '3': case '4': case '5': case '6':
case '7': case '8': case '9': case '.': case 'e': case 'E':
break;
case '\'': case '"':
return lexconst(*p++, 0, 0);
default:
return lexconst(c, 0, 0);
}
for (;; c = *p++) switch (state) {
case start:
if (octal && (c == 'x' || c == 'X')) {
state = (int)hexscan;
break;
}
state = (int)intscan; /* fall through */
case intscan:
if (c >= '0' && c <= '9') {
i = 10*i + (c -= '0');
if (octal) ioct = 8*ioct + c;
} else if (c == 'e' || c == 'E') {
state = (int)expstart;
} else if (c == '.') {
state = (int)fracscan;
} else {
return lexconst(sign*(octal ? ioct : i), 0, 0);
}
break;
case hexscan:
if (c >= '0' && c <= '9') {
i = 16*i + (c -= '0');
} else if (c >= 'a' && c <= 'f') {
i = 16*i + (c -= 'a' - 10);
} else if (c >= 'A' && c <= 'F') {
i = 16*i + (c -= 'A' - 10);
} else {
return lexconst(sign*i, 0, 0);
}
break;
case fracscan:
if (c >= '0' && c <= '9') {
i = 10*i + (c -= '0');
--fexp;
} else if (c == 'e' || c == 'E') {
state = (int)expstart;
} else {
return lexconst(sign*i, 1, fexp);
}
break;
case expstart:
state = (int)expscan;
if (c == '+') {
break;
} else if (c == '-') {
sexp = -1;
break;
}
case expscan:
if (c >= '0' && c <= '9') {
exp = 10*exp + (c -= '0');
} else {
return lexconst(sign*i, 1, fexp + sexp*exp);
}
break;
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.