summaryrefslogtreecommitdiff
path: root/usr.bin/awk/run.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/awk/run.c')
-rw-r--r--usr.bin/awk/run.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/usr.bin/awk/run.c b/usr.bin/awk/run.c
index dbe0878469a..692801e11c5 100644
--- a/usr.bin/awk/run.c
+++ b/usr.bin/awk/run.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: run.c,v 1.32 2011/04/20 22:28:39 millert Exp $ */
+/* $OpenBSD: run.c,v 1.33 2011/09/28 19:27:18 millert Exp $ */
/****************************************************************
Copyright (C) Lucent Technologies 1997
All Rights Reserved
@@ -68,6 +68,7 @@ void tempfree(Cell *p) {
jmp_buf env;
int use_arc4 = 1;
extern int pairstack[];
+extern Awkfloat srand_seed;
Node *winner = NULL; /* root of parse tree */
Cell *tmps; /* free temporary cells for execution */
@@ -1243,6 +1244,12 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
ap->sval = (char *) makesymtab(NSYMTAB);
n = 0;
+ if (arg3type == REGEXPR && strlen((char*)((fa*)a[2])->restr) == 0) {
+ /* split(s, a, //); have to arrange that it looks like empty sep */
+ arg3type = 0;
+ fs = "";
+ sep = 0;
+ }
if (*s != '\0' && (strlen(fs) > 1 || arg3type == REGEXPR)) { /* reg expr */
fa *pfa;
if (arg3type == REGEXPR) { /* it's ready already */
@@ -1474,10 +1481,10 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
Cell *x, *y;
Awkfloat u;
int t;
+ Awkfloat tmp;
char *p, *buf;
Node *nextarg;
FILE *fp;
- static Awkfloat old_seed = 1;
t = ptoi(a[0]);
x = execute(a[1]);
@@ -1581,13 +1588,15 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis
u = (Awkfloat) (random() % RAND_MAX) / RAND_MAX;
break;
case FSRAND:
- u = old_seed;
if (isrec(x)) /* no argument provided, want arc4random() */
use_arc4 = 1;
else {
- old_seed = getfval(x);
- srandom((unsigned int) old_seed);
use_arc4 = 0;
+ u = getfval(x);
+ tmp = u;
+ srandom((unsigned int) u);
+ u = srand_seed;
+ srand_seed = tmp;
}
break;
case FTOUPPER:
@@ -1684,17 +1693,25 @@ struct files {
FILE *fp;
const char *fname;
int mode; /* '|', 'a', 'w' => LE/LT, GT */
-} files[FOPEN_MAX] ={
- { NULL, "/dev/stdin", LT }, /* watch out: don't free this! */
- { NULL, "/dev/stdout", GT },
- { NULL, "/dev/stderr", GT }
-};
+} *files;
+
+int nfiles;
void stdinit(void) /* in case stdin, etc., are not constants */
{
- files[0].fp = stdin;
- files[1].fp = stdout;
- files[2].fp = stderr;
+ nfiles = FOPEN_MAX;
+ files = calloc(nfiles, sizeof(*files));
+ if (files == NULL)
+ FATAL("can't allocate file memory for %u files", nfiles);
+ files[0].fp = stdin;
+ files[0].fname = "/dev/stdin";
+ files[0].mode = LT;
+ files[1].fp = stdout;
+ files[1].fname = "/dev/stdout";
+ files[1].mode = GT;
+ files[2].fp = stderr;
+ files[2].fname = "/dev/stderr";
+ files[2].mode = GT;
}
FILE *openfile(int a, const char *us)
@@ -1705,7 +1722,7 @@ FILE *openfile(int a, const char *us)
if (*s == '\0')
FATAL("null file name in print or getline");
- for (i=0; i < FOPEN_MAX; i++)
+ for (i=0; i < nfiles; i++)
if (files[i].fname && strcmp(s, files[i].fname) == 0) {
if (a == files[i].mode || (a==APPEND && files[i].mode==GT))
return files[i].fp;
@@ -1715,11 +1732,19 @@ FILE *openfile(int a, const char *us)
if (a == FFLUSH) /* didn't find it, so don't create it! */
return NULL;
- for (i=0; i < FOPEN_MAX; i++)
+ for (i=0; i < nfiles; i++)
if (files[i].fp == 0)
break;
- if (i >= FOPEN_MAX)
- FATAL("%s makes too many open files", s);
+ if (i >= nfiles) {
+ struct files *nf;
+ int nnf = nfiles + FOPEN_MAX;
+ nf = realloc(files, nnf * sizeof(*nf));
+ if (nf == NULL)
+ FATAL("cannot grow files for %s and %d files", s, nnf);
+ memset(&nf[nfiles], 0, FOPEN_MAX * sizeof(*nf));
+ nfiles = nnf;
+ files = nf;
+ }
fflush(stdout); /* force a semblance of order */
m = a;
if (a == GT) {
@@ -1747,7 +1772,7 @@ const char *filename(FILE *fp)
{
int i;
- for (i = 0; i < FOPEN_MAX; i++)
+ for (i = 0; i < nfiles; i++)
if (fp == files[i].fp)
return files[i].fname;
return "???";
@@ -1762,7 +1787,7 @@ Cell *closefile(Node **a, int n)
x = execute(a[0]);
getsval(x);
stat = -1;
- for (i = 0; i < FOPEN_MAX; i++) {
+ for (i = 0; i < nfiles; i++) {
if (files[i].fname && strcmp(x->sval, files[i].fname) == 0) {
if (ferror(files[i].fp))
WARNING( "i/o error occurred on %s", files[i].fname );
@@ -1806,7 +1831,7 @@ void flush_all(void)
{
int i;
- for (i = 0; i < FOPEN_MAX; i++)
+ for (i = 0; i < nfiles; i++)
if (files[i].fp)
fflush(files[i].fp);
}