version 1.17, 2001/09/08 00:12:40 |
version 1.18, 2002/12/19 21:24:28 |
|
|
|
|
/* buffer memory management */ |
/* buffer memory management */ |
int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, |
int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, |
char *whatrtn) |
const char *whatrtn) |
/* pbuf: address of pointer to buffer being managed |
/* pbuf: address of pointer to buffer being managed |
* psiz: address of buffer size variable |
* psiz: address of buffer size variable |
* minlen: minimum length of buffer needed |
* minlen: minimum length of buffer needed |
|
|
y = execute(x); |
y = execute(x); |
oargs[i] = y; |
oargs[i] = y; |
dprintf( ("args[%d]: %s %f <%s>, t=%o\n", |
dprintf( ("args[%d]: %s %f <%s>, t=%o\n", |
i, y->nval, y->fval, isarr(y) ? "(array)" : y->sval, y->tval) ); |
i, NN(y->nval), y->fval, isarr(y) ? "(array)" : NN(y->sval), y->tval) ); |
if (isfcn(y)) |
if (isfcn(y)) |
FATAL("can't use function %s as argument in %s", y->nval, s); |
FATAL("can't use function %s as argument in %s", y->nval, s); |
if (isarr(y)) |
if (isarr(y)) |
|
|
tempfree(y); |
tempfree(y); |
} |
} |
if (!isarr(x)) { |
if (!isarr(x)) { |
dprintf( ("making %s into an array\n", x->nval) ); |
dprintf( ("making %s into an array\n", NN(x->nval)) ); |
if (freeable(x)) |
if (freeable(x)) |
xfree(x->sval); |
xfree(x->sval); |
x->tval &= ~(STR|NUM|DONTFREE); |
x->tval &= ~(STR|NUM|DONTFREE); |
|
|
char *s, *t; |
char *s, *t; |
int i; |
int i; |
fa *pfa; |
fa *pfa; |
int (*mf)(fa *, char *) = match, mode = 0; |
int (*mf)(fa *, const char *) = match, mode = 0; |
|
|
if (n == MATCHFCN) { |
if (n == MATCHFCN) { |
mf = pmatch; |
mf = pmatch; |
|
|
void tfree(Cell *a) /* free a tempcell */ |
void tfree(Cell *a) /* free a tempcell */ |
{ |
{ |
if (freeable(a)) { |
if (freeable(a)) { |
dprintf( ("freeing %s %s %o\n", a->nval, a->sval, a->tval) ); |
dprintf( ("freeing %s %s %o\n", NN(a->nval), NN(a->sval), a->tval) ); |
xfree(a->sval); |
xfree(a->sval); |
} |
} |
if (a == tmps) |
if (a == tmps) |
|
|
|
|
#define MAXNUMSIZE 50 |
#define MAXNUMSIZE 50 |
|
|
int format(char **pbuf, int *pbufsize, char *s, Node *a) /* printf-like conversions */ |
int format(char **pbuf, int *pbufsize, const char *s, Node *a) /* printf-like conversions */ |
{ |
{ |
char *fmt; |
char *fmt; |
char *p, *t, *os; |
char *p, *t; |
|
const char *os; |
Cell *x; |
Cell *x; |
int flag = 0, n; |
int flag = 0, n; |
int fmtwd; /* format width */ |
int fmtwd; /* format width */ |
|
|
|
|
switch (*s) { |
switch (*s) { |
case 'f': case 'e': case 'g': case 'E': case 'G': |
case 'f': case 'e': case 'g': case 'E': case 'G': |
flag = 1; |
flag = 'f'; |
break; |
break; |
case 'd': case 'i': |
case 'd': case 'i': |
flag = 2; |
flag = 'd'; |
if(*(s-1) == 'l') break; |
if(*(s-1) == 'l') break; |
*(t-1) = 'l'; |
*(t-1) = 'l'; |
*t = 'd'; |
*t = 'd'; |
*++t = '\0'; |
*++t = '\0'; |
break; |
break; |
case 'o': case 'x': case 'X': case 'u': |
case 'o': case 'x': case 'X': case 'u': |
flag = *(s-1) == 'l' ? 2 : 3; |
flag = *(s-1) == 'l' ? 'd' : 'u'; |
break; |
break; |
case 's': |
case 's': |
flag = 4; |
flag = 's'; |
break; |
break; |
case 'c': |
case 'c': |
flag = 5; |
flag = 'c'; |
break; |
break; |
default: |
default: |
WARNING("weird printf conversion %s", fmt); |
WARNING("weird printf conversion %s", fmt); |
flag = 0; |
flag = '?'; |
break; |
break; |
} |
} |
if (a == NULL) |
if (a == NULL) |
|
|
n = fmtwd; |
n = fmtwd; |
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format"); |
adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format"); |
switch (flag) { |
switch (flag) { |
case 0: sprintf(p, "%s", fmt); /* unknown, so dump it too */ |
case '?': sprintf(p, "%s", fmt); /* unknown, so dump it too */ |
t = getsval(x); |
t = getsval(x); |
n = strlen(t); |
n = strlen(t); |
if (fmtwd > n) |
if (fmtwd > n) |
|
|
p += strlen(p); |
p += strlen(p); |
sprintf(p, "%s", t); |
sprintf(p, "%s", t); |
break; |
break; |
case 1: sprintf(p, fmt, getfval(x)); break; |
case 'f': sprintf(p, fmt, getfval(x)); break; |
case 2: sprintf(p, fmt, (long) getfval(x)); break; |
case 'd': sprintf(p, fmt, (long) getfval(x)); break; |
case 3: sprintf(p, fmt, (int) getfval(x)); break; |
case 'u': sprintf(p, fmt, (int) getfval(x)); break; |
case 4: |
case 's': |
t = getsval(x); |
t = getsval(x); |
n = strlen(t); |
n = strlen(t); |
if (fmtwd > n) |
if (fmtwd > n) |
|
|
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); |
FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t); |
sprintf(p, fmt, t); |
sprintf(p, fmt, t); |
break; |
break; |
case 5: |
case 'c': |
if (isnum(x)) { |
if (isnum(x)) { |
if (getfval(x)) |
if (getfval(x)) |
sprintf(p, fmt, (int) getfval(x)); |
sprintf(p, fmt, (int) getfval(x)); |
else |
else { |
*p++ = '\0'; |
*p++ = '\0'; /* explicit null byte */ |
|
*p = '\0'; /* next output will start here */ |
|
} |
} else |
} else |
sprintf(p, fmt, getsval(x)[0]); |
sprintf(p, fmt, getsval(x)[0]); |
break; |
break; |
|
default: |
|
FATAL("can't happen: bad conversion %c in format()", flag); |
} |
} |
tempfree(x); |
tempfree(x); |
p += strlen(p); |
p += strlen(p); |
|
|
sep = *fs; |
sep = *fs; |
ap = execute(a[1]); /* array name */ |
ap = execute(a[1]); /* array name */ |
freesymtab(ap); |
freesymtab(ap); |
dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, ap->nval, fs) ); |
dprintf( ("split: s=|%s|, a=%s, sep=|%s|\n", s, NN(ap->nval), fs) ); |
ap->tval &= ~STR; |
ap->tval &= ~STR; |
ap->tval |= ARR; |
ap->tval |= ARR; |
ap->sval = (char *) makesymtab(NSYMTAB); |
ap->sval = (char *) makesymtab(NSYMTAB); |
|
|
char *p, *buf; |
char *p, *buf; |
Node *nextarg; |
Node *nextarg; |
FILE *fp; |
FILE *fp; |
|
void flush_all(void); |
|
|
t = ptoi(a[0]); |
t = ptoi(a[0]); |
x = execute(a[1]); |
x = execute(a[1]); |
nextarg = a[1]->nnext; |
nextarg = a[1]->nnext; |
switch (t) { |
switch (t) { |
case FLENGTH: |
case FLENGTH: |
u = strlen(getsval(x)); break; |
if (isarr(x)) |
|
u = ((Array *) x->sval)->nelem; /* GROT. should be function*/ |
|
else |
|
u = strlen(getsval(x)); |
|
break; |
case FLOG: |
case FLOG: |
u = errcheck(log(getfval(x)), "log"); break; |
u = errcheck(log(getfval(x)), "log"); break; |
case FINT: |
case FINT: |
|
|
free(buf); |
free(buf); |
return x; |
return x; |
case FFLUSH: |
case FFLUSH: |
if ((fp = openfile(FFLUSH, getsval(x))) == NULL) |
if (isrec(x) || strlen(getsval(x)) == 0) { |
|
flush_all(); /* fflush() or fflush("") -> all */ |
|
u = 0; |
|
} else if ((fp = openfile(FFLUSH, getsval(x))) == NULL) |
u = EOF; |
u = EOF; |
else |
else |
u = fflush(fp); |
u = fflush(fp); |
|
|
fp = redirect(ptoi(a[1]), a[2]); |
fp = redirect(ptoi(a[1]), a[2]); |
for (x = a[0]; x != NULL; x = x->nnext) { |
for (x = a[0]; x != NULL; x = x->nnext) { |
y = execute(x); |
y = execute(x); |
fputs(getsval(y), fp); |
fputs(getpssval(y), fp); |
tempfree(y); |
tempfree(y); |
if (x->nnext == NULL) |
if (x->nnext == NULL) |
fputs(*ORS, fp); |
fputs(*ORS, fp); |
|
|
|
|
struct files { |
struct files { |
FILE *fp; |
FILE *fp; |
char *fname; |
const char *fname; |
int mode; /* '|', 'a', 'w' => LE/LT, GT */ |
int mode; /* '|', 'a', 'w' => LE/LT, GT */ |
} files[FOPEN_MAX] ={ |
} files[FOPEN_MAX] ={ |
{ NULL, "/dev/stdin", LT }, /* watch out: don't free this! */ |
{ NULL, "/dev/stdin", LT }, /* watch out: don't free this! */ |
|
|
files[2].fp = stderr; |
files[2].fp = stderr; |
} |
} |
|
|
FILE *openfile(int a, char *us) |
FILE *openfile(int a, const char *us) |
{ |
{ |
char *s = us; |
const char *s = us; |
int i, m; |
int i, m; |
FILE *fp = 0; |
FILE *fp = 0; |
|
|
|
|
return fp; |
return fp; |
} |
} |
|
|
char *filename(FILE *fp) |
const char *filename(FILE *fp) |
{ |
{ |
int i; |
int i; |
|
|
|
|
WARNING( "i/o error occurred while closing %s", files[i].fname ); |
WARNING( "i/o error occurred while closing %s", files[i].fname ); |
} |
} |
} |
} |
|
} |
|
|
|
void flush_all(void) |
|
{ |
|
int i; |
|
|
|
for (i = 0; i < FOPEN_MAX; i++) |
|
if (files[i].fp) |
|
fflush(files[i].fp); |
} |
} |
|
|
void backsub(char **pb_ptr, char **sptr_ptr); |
void backsub(char **pb_ptr, char **sptr_ptr); |