mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-10-16 22:56:09 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
477
third_party/f2c/fmt.c
vendored
Normal file
477
third_party/f2c/fmt.c
vendored
Normal file
|
@ -0,0 +1,477 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "third_party/f2c/f2c.h"
|
||||
#include "third_party/f2c/fio.h"
|
||||
#include "third_party/f2c/fmt.h"
|
||||
|
||||
#define SYLMX 300
|
||||
#define GLITCH '\2'
|
||||
#define Const const
|
||||
#define STKSZ 10
|
||||
|
||||
#define skip(s) \
|
||||
while (*s == ' ') s++
|
||||
|
||||
/* special quote character for stu */
|
||||
static struct syl f__syl[SYLMX];
|
||||
int f__parenlvl, f__pc, f__revloc;
|
||||
int f__cnt[STKSZ], f__ret[STKSZ], f__cp, f__rp;
|
||||
flag f__workdone, f__nonl;
|
||||
|
||||
static const char *ap_end(const char *s) {
|
||||
char quote;
|
||||
quote = *s++;
|
||||
for (; *s; s++) {
|
||||
if (*s != quote) continue;
|
||||
if (*++s != quote) return (s);
|
||||
}
|
||||
if (f__elist->cierr) {
|
||||
errno = 100;
|
||||
return (NULL);
|
||||
}
|
||||
f__fatal(100, "bad string");
|
||||
/*NOTREACHED*/ return 0;
|
||||
}
|
||||
|
||||
static int op_gen(int a, int b, int c, int d) {
|
||||
struct syl *p = &f__syl[f__pc];
|
||||
if (f__pc >= SYLMX) {
|
||||
fprintf(stderr, "format too complicated:\n");
|
||||
sig_die(f__fmtbuf, 1);
|
||||
}
|
||||
p->op = a;
|
||||
p->p1 = b;
|
||||
p->p2.i[0] = c;
|
||||
p->p2.i[1] = d;
|
||||
return (f__pc++);
|
||||
}
|
||||
|
||||
static const char *f_list(const char *);
|
||||
static const char *gt_num(const char *s, int *n, int n1) {
|
||||
int m = 0, f__cnt = 0;
|
||||
char c;
|
||||
for (c = *s;; c = *s) {
|
||||
if (c == ' ') {
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if (c > '9' || c < '0') break;
|
||||
m = 10 * m + c - '0';
|
||||
f__cnt++;
|
||||
s++;
|
||||
}
|
||||
if (f__cnt == 0) {
|
||||
if (!n1) s = 0;
|
||||
*n = n1;
|
||||
} else
|
||||
*n = m;
|
||||
return (s);
|
||||
}
|
||||
|
||||
static const char *f_s(const char *s, int curloc) {
|
||||
skip(s);
|
||||
if (*s++ != '(') {
|
||||
return (NULL);
|
||||
}
|
||||
if (f__parenlvl++ == 1) f__revloc = curloc;
|
||||
if (op_gen(RET1, curloc, 0, 0) < 0 || (s = f_list(s)) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
skip(s);
|
||||
return (s);
|
||||
}
|
||||
|
||||
static int ne_d(const char *s, const char **p) {
|
||||
int n, x, sign = 0;
|
||||
struct syl *sp;
|
||||
switch (*s) {
|
||||
default:
|
||||
return (0);
|
||||
case ':':
|
||||
(void)op_gen(COLON, 0, 0, 0);
|
||||
break;
|
||||
case '$':
|
||||
(void)op_gen(NONL, 0, 0, 0);
|
||||
break;
|
||||
case 'B':
|
||||
case 'b':
|
||||
if (*++s == 'z' || *s == 'Z')
|
||||
(void)op_gen(BZ, 0, 0, 0);
|
||||
else
|
||||
(void)op_gen(BN, 0, 0, 0);
|
||||
break;
|
||||
case 'S':
|
||||
case 's':
|
||||
if (*(s + 1) == 's' || *(s + 1) == 'S') {
|
||||
x = SS;
|
||||
s++;
|
||||
} else if (*(s + 1) == 'p' || *(s + 1) == 'P') {
|
||||
x = SP;
|
||||
s++;
|
||||
} else
|
||||
x = S;
|
||||
(void)op_gen(x, 0, 0, 0);
|
||||
break;
|
||||
case '/':
|
||||
(void)op_gen(SLASH, 0, 0, 0);
|
||||
break;
|
||||
case '-':
|
||||
sign = 1;
|
||||
case '+':
|
||||
s++; /*OUTRAGEOUS CODING TRICK*/
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (!(s = gt_num(s, &n, 0))) {
|
||||
bad:
|
||||
*p = 0;
|
||||
return 1;
|
||||
}
|
||||
switch (*s) {
|
||||
default:
|
||||
return (0);
|
||||
case 'P':
|
||||
case 'p':
|
||||
if (sign) n = -n;
|
||||
(void)op_gen(P, n, 0, 0);
|
||||
break;
|
||||
case 'X':
|
||||
case 'x':
|
||||
(void)op_gen(X, n, 0, 0);
|
||||
break;
|
||||
case 'H':
|
||||
case 'h':
|
||||
sp = &f__syl[op_gen(H, n, 0, 0)];
|
||||
sp->p2.s = (char *)s + 1;
|
||||
s += n;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GLITCH:
|
||||
case '"':
|
||||
case '\'':
|
||||
sp = &f__syl[op_gen(APOS, 0, 0, 0)];
|
||||
sp->p2.s = (char *)s;
|
||||
if ((*p = ap_end(s)) == NULL) return (0);
|
||||
return (1);
|
||||
case 'T':
|
||||
case 't':
|
||||
if (*(s + 1) == 'l' || *(s + 1) == 'L') {
|
||||
x = TL;
|
||||
s++;
|
||||
} else if (*(s + 1) == 'r' || *(s + 1) == 'R') {
|
||||
x = TR;
|
||||
s++;
|
||||
} else
|
||||
x = T;
|
||||
if (!(s = gt_num(s + 1, &n, 0))) goto bad;
|
||||
s--;
|
||||
(void)op_gen(x, n, 0, 0);
|
||||
break;
|
||||
case 'X':
|
||||
case 'x':
|
||||
(void)op_gen(X, 1, 0, 0);
|
||||
break;
|
||||
case 'P':
|
||||
case 'p':
|
||||
(void)op_gen(P, 1, 0, 0);
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
*p = s;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int e_d(const char *s, const char **p) {
|
||||
int i, im, n, w, d, e, found = 0, x = 0;
|
||||
Const char *sv = s;
|
||||
s = gt_num(s, &n, 1);
|
||||
(void)op_gen(STACK, n, 0, 0);
|
||||
switch (*s++) {
|
||||
default:
|
||||
break;
|
||||
case 'E':
|
||||
case 'e':
|
||||
x = 1;
|
||||
case 'G':
|
||||
case 'g':
|
||||
found = 1;
|
||||
if (!(s = gt_num(s, &w, 0))) {
|
||||
bad:
|
||||
*p = 0;
|
||||
return 1;
|
||||
}
|
||||
if (w == 0) break;
|
||||
if (*s == '.') {
|
||||
if (!(s = gt_num(s + 1, &d, 0))) goto bad;
|
||||
} else
|
||||
d = 0;
|
||||
if (*s != 'E' && *s != 'e')
|
||||
(void)op_gen(x == 1 ? E : G, w, d, 0); /* default is Ew.dE2 */
|
||||
else {
|
||||
if (!(s = gt_num(s + 1, &e, 0))) goto bad;
|
||||
(void)op_gen(x == 1 ? EE : GE, w, d, e);
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
case 'o':
|
||||
i = O;
|
||||
im = OM;
|
||||
goto finish_I;
|
||||
case 'Z':
|
||||
case 'z':
|
||||
i = Z;
|
||||
im = ZM;
|
||||
goto finish_I;
|
||||
case 'L':
|
||||
case 'l':
|
||||
found = 1;
|
||||
if (!(s = gt_num(s, &w, 0))) goto bad;
|
||||
if (w == 0) break;
|
||||
(void)op_gen(L, w, 0, 0);
|
||||
break;
|
||||
case 'A':
|
||||
case 'a':
|
||||
found = 1;
|
||||
skip(s);
|
||||
if (*s >= '0' && *s <= '9') {
|
||||
s = gt_num(s, &w, 1);
|
||||
if (w == 0) break;
|
||||
(void)op_gen(AW, w, 0, 0);
|
||||
break;
|
||||
}
|
||||
(void)op_gen(A, 0, 0, 0);
|
||||
break;
|
||||
case 'F':
|
||||
case 'f':
|
||||
if (!(s = gt_num(s, &w, 0))) goto bad;
|
||||
found = 1;
|
||||
if (w == 0) break;
|
||||
if (*s == '.') {
|
||||
if (!(s = gt_num(s + 1, &d, 0))) goto bad;
|
||||
} else
|
||||
d = 0;
|
||||
(void)op_gen(F, w, d, 0);
|
||||
break;
|
||||
case 'D':
|
||||
case 'd':
|
||||
found = 1;
|
||||
if (!(s = gt_num(s, &w, 0))) goto bad;
|
||||
if (w == 0) break;
|
||||
if (*s == '.') {
|
||||
if (!(s = gt_num(s + 1, &d, 0))) goto bad;
|
||||
} else
|
||||
d = 0;
|
||||
(void)op_gen(D, w, d, 0);
|
||||
break;
|
||||
case 'I':
|
||||
case 'i':
|
||||
i = I;
|
||||
im = IM;
|
||||
finish_I:
|
||||
if (!(s = gt_num(s, &w, 0))) goto bad;
|
||||
found = 1;
|
||||
if (w == 0) break;
|
||||
if (*s != '.') {
|
||||
(void)op_gen(i, w, 0, 0);
|
||||
break;
|
||||
}
|
||||
if (!(s = gt_num(s + 1, &d, 0))) goto bad;
|
||||
(void)op_gen(im, w, d, 0);
|
||||
break;
|
||||
}
|
||||
if (found == 0) {
|
||||
f__pc--; /*unSTACK*/
|
||||
*p = sv;
|
||||
return (0);
|
||||
}
|
||||
*p = s;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static const char *i_tem(const char *s) {
|
||||
const char *t;
|
||||
int n, curloc;
|
||||
if (*s == ')') return (s);
|
||||
if (ne_d(s, &t)) return (t);
|
||||
if (e_d(s, &t)) return (t);
|
||||
s = gt_num(s, &n, 1);
|
||||
if ((curloc = op_gen(STACK, n, 0, 0)) < 0) return (NULL);
|
||||
return (f_s(s, curloc));
|
||||
}
|
||||
|
||||
static const char *f_list(const char *s) {
|
||||
for (; *s != 0;) {
|
||||
skip(s);
|
||||
if ((s = i_tem(s)) == NULL) return (NULL);
|
||||
skip(s);
|
||||
if (*s == ',')
|
||||
s++;
|
||||
else if (*s == ')') {
|
||||
if (--f__parenlvl == 0) {
|
||||
(void)op_gen(REVERT, f__revloc, 0, 0);
|
||||
return (++s);
|
||||
}
|
||||
(void)op_gen(GOTO, 0, 0, 0);
|
||||
return (++s);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int pars_f(const char *s) {
|
||||
f__parenlvl = f__revloc = f__pc = 0;
|
||||
if (f_s(s, 0) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int type_f(int n) {
|
||||
switch (n) {
|
||||
default:
|
||||
return (n);
|
||||
case RET1:
|
||||
return (RET1);
|
||||
case REVERT:
|
||||
return (REVERT);
|
||||
case GOTO:
|
||||
return (GOTO);
|
||||
case STACK:
|
||||
return (STACK);
|
||||
case X:
|
||||
case SLASH:
|
||||
case APOS:
|
||||
case H:
|
||||
case T:
|
||||
case TL:
|
||||
case TR:
|
||||
return (NED);
|
||||
case F:
|
||||
case I:
|
||||
case IM:
|
||||
case A:
|
||||
case AW:
|
||||
case O:
|
||||
case OM:
|
||||
case L:
|
||||
case E:
|
||||
case EE:
|
||||
case D:
|
||||
case G:
|
||||
case GE:
|
||||
case Z:
|
||||
case ZM:
|
||||
return (ED);
|
||||
}
|
||||
}
|
||||
#ifdef KR_headers
|
||||
integer do_fio(number, ptr, len) ftnint *number;
|
||||
ftnlen len;
|
||||
char *ptr;
|
||||
#else
|
||||
integer do_fio(ftnint *number, char *ptr, ftnlen len)
|
||||
#endif
|
||||
{
|
||||
struct syl *p;
|
||||
int n, i;
|
||||
for (i = 0; i < *number; i++, ptr += len) {
|
||||
loop:
|
||||
switch (type_f((p = &f__syl[f__pc])->op)) {
|
||||
default:
|
||||
fprintf(stderr, "unknown code in do_fio: %d\n%s\n", p->op, f__fmtbuf);
|
||||
err(f__elist->cierr, 100, "do_fio");
|
||||
case NED:
|
||||
if ((*f__doned)(p)) {
|
||||
f__pc++;
|
||||
goto loop;
|
||||
}
|
||||
f__pc++;
|
||||
continue;
|
||||
case ED:
|
||||
if (f__cnt[f__cp] <= 0) {
|
||||
f__cp--;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
}
|
||||
if (ptr == NULL) return ((*f__doend)());
|
||||
f__cnt[f__cp]--;
|
||||
f__workdone = 1;
|
||||
if ((n = (*f__doed)(p, ptr, len)) > 0)
|
||||
errfl(f__elist->cierr, errno, "fmt");
|
||||
if (n < 0) err(f__elist->ciend, (EOF), "fmt");
|
||||
continue;
|
||||
case STACK:
|
||||
f__cnt[++f__cp] = p->p1;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case RET1:
|
||||
f__ret[++f__rp] = p->p1;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case GOTO:
|
||||
if (--f__cnt[f__cp] <= 0) {
|
||||
f__cp--;
|
||||
f__rp--;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
}
|
||||
f__pc = 1 + f__ret[f__rp--];
|
||||
goto loop;
|
||||
case REVERT:
|
||||
f__rp = f__cp = 0;
|
||||
f__pc = p->p1;
|
||||
if (ptr == NULL) return ((*f__doend)());
|
||||
if (!f__workdone) return (0);
|
||||
if ((n = (*f__dorevert)()) != 0) return (n);
|
||||
goto loop;
|
||||
case COLON:
|
||||
if (ptr == NULL) return ((*f__doend)());
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case NONL:
|
||||
f__nonl = 1;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case S:
|
||||
case SS:
|
||||
f__cplus = 0;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case SP:
|
||||
f__cplus = 1;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case P:
|
||||
f__scale = p->p1;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case BN:
|
||||
f__cblank = 0;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
case BZ:
|
||||
f__cblank = 1;
|
||||
f__pc++;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int en_fio(Void) {
|
||||
ftnint one = 1;
|
||||
return (do_fio(&one, (char *)NULL, (ftnint)0));
|
||||
}
|
||||
|
||||
VOID fmt_bg(Void) {
|
||||
f__workdone = f__cp = f__rp = f__pc = f__cursor = 0;
|
||||
f__cnt[0] = f__ret[0] = 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue