version 1.55, 2020/06/10 21:04:40 |
version 1.56, 2020/06/10 21:05:02 |
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <ctype.h> |
#include <ctype.h> |
#include <errno.h> |
#include <errno.h> |
|
#include <fcntl.h> |
#include <setjmp.h> |
#include <setjmp.h> |
#include <limits.h> |
#include <limits.h> |
#include <math.h> |
#include <math.h> |
|
|
Cell *jexit = &exitcell; |
Cell *jexit = &exitcell; |
static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM, NULL }; |
static Cell retcell ={ OJUMP, JRET, 0, 0, 0.0, NUM, NULL }; |
Cell *jret = &retcell; |
Cell *jret = &retcell; |
static Cell tempcell ={ OCELL, CTEMP, 0, "", 0.0, NUM|STR|DONTFREE, NULL }; |
static Cell tempcell ={ OCELL, CTEMP, 0, EMPTY, 0.0, NUM|STR|DONTFREE, NULL }; |
|
|
Node *curnode = NULL; /* the node being executed, for debugging */ |
Node *curnode = NULL; /* the node being executed, for debugging */ |
|
|
|
|
|
|
Cell *call(Node **a, int n) /* function call. very kludgy and fragile */ |
Cell *call(Node **a, int n) /* function call. very kludgy and fragile */ |
{ |
{ |
static Cell newcopycell = { OCELL, CCOPY, 0, "", 0.0, NUM|STR|DONTFREE, NULL }; |
static Cell newcopycell = { OCELL, CCOPY, 0, EMPTY, 0.0, NUM|STR|DONTFREE, NULL }; |
int i, ncall, ndef; |
int i, ncall, ndef; |
int freed = 0; /* handles potential double freeing when fcn & param share a tempcell */ |
int freed = 0; /* handles potential double freeing when fcn & param share a tempcell */ |
Node *x; |
Node *x; |
|
|
{ |
{ |
Cell *x = NULL, *y, *ap; |
Cell *x = NULL, *y, *ap; |
const char *s, *origs, *t; |
const char *s, *origs, *t; |
char *fs = NULL, *origfs = NULL; |
const char *fs = NULL; |
|
char *origfs = NULL; |
int sep; |
int sep; |
char temp, num[50]; |
char temp, num[50]; |
int n, tempstat, arg3type; |
int n, tempstat, arg3type; |
|
|
fs = getsval(fsloc); |
fs = getsval(fsloc); |
else if (arg3type == STRING) { /* split(str,arr,"string") */ |
else if (arg3type == STRING) { /* split(str,arr,"string") */ |
x = execute(a[2]); |
x = execute(a[2]); |
origfs = fs = strdup(getsval(x)); |
fs = origfs = strdup(getsval(x)); |
if (fs == NULL) |
if (fs == NULL) |
FATAL("out of space in split"); |
FATAL("out of space in split"); |
tempfree(x); |
tempfree(x); |
|
|
files[i].fname = tostring(s); |
files[i].fname = tostring(s); |
files[i].fp = fp; |
files[i].fp = fp; |
files[i].mode = m; |
files[i].mode = m; |
|
if (fp != stdin && fp != stdout && fp != stderr) |
|
(void) fcntl(fileno(fp), F_SETFD, FD_CLOEXEC); |
} |
} |
return fp; |
return fp; |
} |
} |
|
|
for (i = 0; i < nfiles; i++) { |
for (i = 0; i < nfiles; i++) { |
if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) { |
if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) { |
if (ferror(files[i].fp)) |
if (ferror(files[i].fp)) |
WARNING( "i/o error occurred on %s", files[i].fname ); |
FATAL( "i/o error occurred on %s", files[i].fname ); |
if (files[i].mode == '|' || files[i].mode == LE) |
if (files[i].mode == '|' || files[i].mode == LE) |
stat = pclose(files[i].fp); |
stat = pclose(files[i].fp); |
else |
else |
stat = fclose(files[i].fp); |
stat = fclose(files[i].fp); |
if (stat == EOF) |
if (stat == EOF) |
WARNING( "i/o error occurred closing %s", files[i].fname ); |
FATAL( "i/o error occurred closing %s", files[i].fname ); |
if (i > 2) /* don't do /dev/std... */ |
if (i > 2) /* don't do /dev/std... */ |
xfree(files[i].fname); |
xfree(files[i].fname); |
files[i].fname = NULL; /* watch out for ref thru this */ |
files[i].fname = NULL; /* watch out for ref thru this */ |
|
|
for (i = 0; i < FOPEN_MAX; i++) { |
for (i = 0; i < FOPEN_MAX; i++) { |
if (files[i].fp) { |
if (files[i].fp) { |
if (ferror(files[i].fp)) |
if (ferror(files[i].fp)) |
WARNING( "i/o error occurred on %s", files[i].fname ); |
FATAL( "i/o error occurred on %s", files[i].fname ); |
if (files[i].mode == '|' || files[i].mode == LE) |
if (files[i].mode == '|' || files[i].mode == LE) |
stat = pclose(files[i].fp); |
stat = pclose(files[i].fp); |
else |
else |
stat = fclose(files[i].fp); |
stat = fclose(files[i].fp); |
if (stat == EOF) |
if (stat == EOF) |
WARNING( "i/o error occurred while closing %s", files[i].fname ); |
FATAL( "i/o error occurred while closing %s", files[i].fname ); |
} |
} |
} |
} |
} |
} |
|
|
{ /* sptr[0] == '\\' */ |
{ /* sptr[0] == '\\' */ |
char *pb = *pb_ptr; |
char *pb = *pb_ptr; |
const char *sptr = *sptr_ptr; |
const char *sptr = *sptr_ptr; |
|
static bool first = true; |
|
static bool do_posix = false; |
|
|
|
if (first) { |
|
first = false; |
|
do_posix = (getenv("POSIXLY_CORRECT") != NULL); |
|
} |
|
|
if (sptr[1] == '\\') { |
if (sptr[1] == '\\') { |
if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ |
if (sptr[2] == '\\' && sptr[3] == '&') { /* \\\& -> \& */ |
*pb++ = '\\'; |
*pb++ = '\\'; |
|
|
} else if (sptr[2] == '&') { /* \\& -> \ + matched */ |
} else if (sptr[2] == '&') { /* \\& -> \ + matched */ |
*pb++ = '\\'; |
*pb++ = '\\'; |
sptr += 2; |
sptr += 2; |
|
} else if (do_posix) { /* \\x -> \x */ |
|
sptr++; |
|
*pb++ = *sptr++; |
} else { /* \\x -> \\x */ |
} else { /* \\x -> \\x */ |
*pb++ = *sptr++; |
*pb++ = *sptr++; |
*pb++ = *sptr++; |
*pb++ = *sptr++; |