summaryrefslogtreecommitdiff
path: root/extension
diff options
context:
space:
mode:
Diffstat (limited to 'extension')
-rw-r--r--extension/arrayparm.c21
-rw-r--r--extension/dl.c20
-rw-r--r--extension/filefuncs.c94
-rw-r--r--extension/fork.c27
-rw-r--r--extension/ordchr.c25
-rw-r--r--extension/readfile.c20
-rw-r--r--extension/rwarray.c181
-rwxr-xr-xextension/steps16
-rw-r--r--extension/testarg.c22
9 files changed, 210 insertions, 216 deletions
diff --git a/extension/arrayparm.c b/extension/arrayparm.c
index ddf1c8c4..281b50a2 100644
--- a/extension/arrayparm.c
+++ b/extension/arrayparm.c
@@ -41,8 +41,7 @@
*/
static NODE *
-do_mkarray(tree)
-NODE *tree;
+do_mkarray(int args)
{
int ret = -1;
NODE *var, *sub, *val;
@@ -51,13 +50,9 @@ NODE *tree;
if (do_lint && get_curfunc_arg_count() > 3)
lintwarn("mkarray: called with too many arguments");
- var = get_argument(tree, 0);
- if (var == NULL)
- var = stack_ptr[0];
-
- var = get_array(var);
- sub = get_argument(tree, 1);
- val = get_argument(tree, 2);
+ var = get_array_argument(0, FALSE);
+ sub = get_scalar_argument(1, FALSE);
+ val = get_scalar_argument(2, FALSE);
printf("var->type = %s\n", nodetype2str(var->type));
printf("sub->type = %s\n", nodetype2str(sub->type));
@@ -69,12 +64,8 @@ NODE *tree;
*elemval = dupnode(val);
ret = 0;
-
/* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) ret);
}
/* dlload --- load new builtins in this library */
@@ -86,5 +77,5 @@ void *dl;
{
make_builtin("mkarray", do_mkarray, 3);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
diff --git a/extension/dl.c b/extension/dl.c
index 60f104fa..49938fc8 100644
--- a/extension/dl.c
+++ b/extension/dl.c
@@ -32,8 +32,7 @@
static void *sdl = NULL;
static NODE *
-zaxxon(tree)
-NODE *tree;
+zaxxon(int nargs)
{
NODE *obj;
int i;
@@ -42,11 +41,11 @@ NODE *tree;
/*
* Print the arguments
*/
- printf("External linkage %s(", tree->param);
+ printf("External linkage zaxxon(");
- for (i = 0; i < tree->param_cnt; i++) {
+ for (i = 0; i < nargs; i++) {
- obj = get_argument(tree, i);
+ obj = get_scalar_argument(i, TRUE);
if (obj == NULL)
break;
@@ -54,7 +53,6 @@ NODE *tree;
force_string(obj);
printf(comma ? ", %s" : "%s", obj->stptr);
- free_temp(obj);
comma = 1;
}
@@ -63,7 +61,7 @@ NODE *tree;
/*
* Do something useful
*/
- obj = get_argument(tree, 0);
+ obj = get_scalar_argument(0, FALSE);
if (obj != NULL) {
force_string(obj);
@@ -75,14 +73,10 @@ NODE *tree;
dlclose(sdl);
sdl = NULL;
}
- free_temp(obj);
}
/* Set the return value */
- set_value(tmp_number((AWKNUM) 3.14));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 3.14);
}
NODE *
@@ -92,5 +86,5 @@ void *dl;
{
sdl = dl;
make_builtin("zaxxon", zaxxon, 4);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index 5dfd1228..35b1ae62 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -34,8 +34,7 @@
/* do_chdir --- provide dynamically loaded chdir() builtin for gawk */
static NODE *
-do_chdir(tree)
-NODE *tree;
+do_chdir(int nargs)
{
NODE *newdir;
int ret = -1;
@@ -43,18 +42,13 @@ NODE *tree;
if (do_lint && get_curfunc_arg_count() != 1)
lintwarn("chdir: called with incorrect number of arguments");
- newdir = get_scalar_argument(tree, 0, FALSE);
+ newdir = get_scalar_argument(0, FALSE);
(void) force_string(newdir);
ret = chdir(newdir->stptr);
if (ret < 0)
update_ERRNO();
- free_temp(newdir);
-
- /* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) ret);
}
/* format_mode --- turn a stat mode field into something readable */
@@ -165,10 +159,9 @@ unsigned long fmode;
/* do_stat --- provide a stat() function for gawk */
static NODE *
-do_stat(tree)
-NODE *tree;
+do_stat(int nargs)
{
- NODE *file, *array;
+ NODE *file, *array, *tmp;
struct stat sbuf;
int ret;
NODE **aptr;
@@ -179,8 +172,8 @@ NODE *tree;
lintwarn("stat: called with too many arguments");
/* directory is first arg, array to hold results is second */
- file = get_scalar_argument(tree, 0, FALSE);
- array = get_array_argument(tree, 1, FALSE);
+ file = get_scalar_argument(0, FALSE);
+ array = get_array_argument(1, FALSE);
/* empty out the array */
assoc_clear(array);
@@ -190,70 +183,83 @@ NODE *tree;
ret = lstat(file->stptr, & sbuf);
if (ret < 0) {
update_ERRNO();
-
- set_value(tmp_number((AWKNUM) ret));
-
- free_temp(file);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
/* fill in the array */
- aptr = assoc_lookup(array, tmp_string("name", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("name", 4), FALSE);
*aptr = dupnode(file);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("dev", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("dev", 3), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_dev);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("ino", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("ino", 3), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_ino);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("mode", 4), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_mode);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("nlink", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("nlink", 5), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_nlink);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("uid", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("uid", 3), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_uid);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("gid", 3), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("gid", 3), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_gid);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("size", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("size", 4), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_size);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("blocks", 6), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("blocks", 6), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_blocks);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("atime", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("atime", 5), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_atime);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("mtime", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("mtime", 5), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_mtime);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("ctime", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("ctime", 5), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_ctime);
+ unref(tmp);
/* for block and character devices, add rdev, major and minor numbers */
if (S_ISBLK(sbuf.st_mode) || S_ISCHR(sbuf.st_mode)) {
- aptr = assoc_lookup(array, tmp_string("rdev", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("rdev", 4), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_rdev);
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("major", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("major", 5), FALSE);
*aptr = make_number((AWKNUM) major(sbuf.st_rdev));
+ unref(tmp);
- aptr = assoc_lookup(array, tmp_string("minor", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("minor", 5), FALSE);
*aptr = make_number((AWKNUM) minor(sbuf.st_rdev));
+ unref(tmp);
}
#ifdef HAVE_ST_BLKSIZE
- aptr = assoc_lookup(array, tmp_string("blksize", 7), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("blksize", 7), FALSE);
*aptr = make_number((AWKNUM) sbuf.st_blksize);
+ unref(tmp);
#endif /* HAVE_ST_BLKSIZE */
- aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("pmode", 5), FALSE);
pmode = format_mode(sbuf.st_mode);
*aptr = make_string(pmode, strlen(pmode));
+ unref(tmp);
/* for symbolic links, add a linkval field */
if (S_ISLNK(sbuf.st_mode)) {
@@ -267,8 +273,9 @@ NODE *tree;
fatal("size of symbolic link too big");
buf[linksize] = '\0';
- aptr = assoc_lookup(array, tmp_string("linkval", 7), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("linkval", 7), FALSE);
*aptr = make_string(buf, linksize);
+ unref(tmp);
}
}
@@ -308,16 +315,11 @@ NODE *tree;
#endif
}
- aptr = assoc_lookup(array, tmp_string("type", 4), FALSE);
+ aptr = assoc_lookup(array, tmp = make_string("type", 4), FALSE);
*aptr = make_string(type, strlen(type));
+ unref(tmp);
- free_temp(file);
-
- /* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) ret);
}
/* dlload --- load new builtins in this library */
@@ -330,5 +332,5 @@ void *dl;
make_builtin("chdir", do_chdir, 1);
make_builtin("stat", do_stat, 2);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
diff --git a/extension/fork.c b/extension/fork.c
index 7ffe857a..c5458c60 100644
--- a/extension/fork.c
+++ b/extension/fork.c
@@ -30,11 +30,11 @@
/* do_fork --- provide dynamically loaded fork() builtin for gawk */
static NODE *
-do_fork(tree)
-NODE *tree;
+do_fork(int nargs)
{
int ret = -1;
NODE **aptr;
+ NODE *tmp;
if (do_lint && get_curfunc_arg_count() > 0)
lintwarn("fork: called with too many arguments");
@@ -46,26 +46,24 @@ NODE *tree;
else if (ret == 0) {
/* update PROCINFO in the child */
- aptr = assoc_lookup(PROCINFO_node, tmp_string("pid", 3), FALSE);
+ aptr = assoc_lookup(PROCINFO_node, tmp = make_string("pid", 3), FALSE);
(*aptr)->numbr = (AWKNUM) getpid();
+ unref(tmp);
- aptr = assoc_lookup(PROCINFO_node, tmp_string("ppid", 4), FALSE);
+ aptr = assoc_lookup(PROCINFO_node, tmp = make_string("ppid", 4), FALSE);
(*aptr)->numbr = (AWKNUM) getppid();
+ unref(tmp);
}
/* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) ret);
}
/* do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */
static NODE *
-do_waitpid(tree)
-NODE *tree;
+do_waitpid(int nargs)
{
NODE *pidnode;
int ret = -1;
@@ -76,7 +74,7 @@ NODE *tree;
if (do_lint && get_curfunc_arg_count() > 1)
lintwarn("waitpid: called with too many arguments");
- pidnode = get_argument(tree, 0);
+ pidnode = get_scalar_argument(0, FALSE);
if (pidnode != NULL) {
pidval = force_number(pidnode);
pid = (int) pidval;
@@ -88,10 +86,7 @@ NODE *tree;
lintwarn("wait: called with no arguments");
/* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) ret);
}
/* dlload --- load new builtins in this library */
@@ -103,5 +98,5 @@ void *dl;
{
make_builtin("fork", do_fork, 0);
make_builtin("waitpid", do_waitpid, 1);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
diff --git a/extension/ordchr.c b/extension/ordchr.c
index 723edc70..c5a1375f 100644
--- a/extension/ordchr.c
+++ b/extension/ordchr.c
@@ -33,8 +33,7 @@
/* do_ord --- return numeric value of first char of string */
static NODE *
-do_ord(tree)
-NODE *tree;
+do_ord(int nargs)
{
NODE *str;
int ret = -1;
@@ -42,27 +41,22 @@ NODE *tree;
if (do_lint && get_curfunc_arg_count() > 1)
lintwarn("ord: called with too many arguments");
- str = get_argument(tree, 0);
+ str = get_scalar_argument(0, FALSE);
if (str != NULL) {
(void) force_string(str);
ret = str->stptr[0];
- free_temp(str);
} else if (do_lint)
lintwarn("ord: called with no arguments");
/* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) ret);
}
/* do_chr --- turn numeric value into a string */
static NODE *
-do_chr(tree)
-NODE *tree;
+do_chr(int nargs)
{
NODE *num;
unsigned int ret = 0;
@@ -74,23 +68,18 @@ NODE *tree;
if (do_lint && get_curfunc_arg_count() > 1)
lintwarn("chr: called with too many arguments");
- num = get_argument(tree, 0);
+ num = get_scalar_argument(0, FALSE);
if (num != NULL) {
val = force_number(num);
ret = val; /* convert to int */
- free_temp(num);
ret &= 0xff;
str[0] = ret;
str[1] = '\0';
} else if (do_lint)
lintwarn("chr: called with no arguments");
-
/* Set the return value */
- set_value(tmp_string(str, 1));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_string(str, 1);
}
/* dlload --- load new builtins in this library */
@@ -103,5 +92,5 @@ void *dl;
make_builtin("ord", do_ord, 1);
make_builtin("chr", do_chr, 1);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
diff --git a/extension/readfile.c b/extension/readfile.c
index 37f39a2c..edab20f8 100644
--- a/extension/readfile.c
+++ b/extension/readfile.c
@@ -40,8 +40,7 @@
/* do_readfile --- read a file into memory */
NODE *
-do_readfile(tree)
-NODE *tree;
+do_readfile(int nargs)
{
NODE *filename;
int ret = -1;
@@ -52,27 +51,24 @@ NODE *tree;
if (do_lint && get_curfunc_arg_count() > 1)
lintwarn("readfile: called with too many arguments");
- filename = get_argument(tree, 0);
+ filename = get_scalar_argument(0, FALSE);
if (filename != NULL) {
(void) force_string(filename);
ret = stat(filename->stptr, & sbuf);
if (ret < 0) {
update_ERRNO();
- free_temp(filename);
goto done;
} else if ((sbuf.st_mode & S_IFMT) != S_IFREG) {
errno = EINVAL;
ret = -1;
update_ERRNO();
- free_temp(filename);
goto done;
}
if ((fd = open(filename->stptr, O_RDONLY|O_BINARY)) < 0) {
ret = -1;
update_ERRNO();
- free_temp(filename);
goto done;
}
@@ -83,24 +79,18 @@ NODE *tree;
(void) close(fd);
ret = -1;
update_ERRNO();
- free_temp(filename);
goto done;
}
close(fd);
- free_temp(filename);
- set_value(tmp_string(text, sbuf.st_size));
- return tmp_number((AWKNUM) 0);
+ return make_string(text, sbuf.st_size);
} else if (do_lint)
lintwarn("filename: called with no arguments");
done:
/* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) ret);
}
@@ -113,5 +103,5 @@ void *dl;
{
make_builtin("readfile", do_readfile, 1);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
diff --git a/extension/rwarray.c b/extension/rwarray.c
index 72a331c3..ace5c84e 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -37,11 +37,13 @@
#define MAJOR 1
#define MINOR 0
+static int write_array(int fd, NODE *array);
static int write_elem(int fd, int index, NODE *item);
static int write_chain(int fd, int index, NODE *item);
static int write_value(int fd, NODE *val);
-static NODE *read_elem(int fd, int *index, int *eof);
+static int read_array(int fd, NODE *array);
+static NODE *read_elem(int fd, int *index, NODE *array);
static NODE *read_value(int fd);
/*
@@ -59,7 +61,7 @@ static NODE *read_value(int fd);
* Hash of index val: 4 bytes - network order
* Length of index val: 4 bytes - network order
* Index val as characters (N bytes)
- * Value type 1 byte (0 = string, 1 = number)
+ * Value type 1 byte (0 = string, 1 = number, 2 = array)
* IF string:
* Length of value 4 bytes
* Value as characters (N bytes)
@@ -70,24 +72,20 @@ static NODE *read_value(int fd);
/* do_writea --- write an array */
static NODE *
-do_writea(tree)
-NODE *tree;
+do_writea(int nargs)
{
NODE *file, *array;
int ret;
int fd;
uint32_t major = MAJOR;
uint32_t minor = MINOR;
- uint32_t count;
- uint32_t array_sz;
- int i;
if (do_lint && get_curfunc_arg_count() > 2)
lintwarn("writea: called with too many arguments");
/* directory is first arg, array to dump is second */
- file = get_scalar_argument(tree, 0, FALSE);
- array = get_array_argument(tree, 1, TRUE);
+ file = get_scalar_argument(0, FALSE);
+ array = get_array_argument(1, FALSE);
/* open the file, if error, set ERRNO and return */
(void) force_string(file);
@@ -107,20 +105,9 @@ NODE *tree;
if (write(fd, & minor, sizeof(minor)) != sizeof(minor))
goto done1;
- count = htonl(array->table_size);
- if (write(fd, & count, sizeof(count)) != sizeof(count))
- goto done1;
-
- array_sz = htonl(array->array_size);
- if (write(fd, & array_sz, sizeof(array_sz)) != sizeof(array_sz))
+ ret = write_array(fd, array);
+ if (ret != 0)
goto done1;
-
- for (i = 0; i < array->array_size; i++) {
- ret = write_chain(fd, i, array->var_array[i]);
- if (ret != 0)
- goto done1;
- }
-
ret = 0;
goto done0;
@@ -130,16 +117,40 @@ done1:
unlink(file->stptr);
done0:
- free_temp(file);
close(fd);
/* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
+ return make_number((AWKNUM) ret);
+}
+
+
+/* write_array --- write out an array or a sub-array */
+
+static int
+write_array(int fd, NODE *array)
+{
+ int ret;
+ uint32_t count;
+ uint32_t array_sz;
+ int i;
+
+ count = htonl(array->table_size);
+ if (write(fd, & count, sizeof(count)) != sizeof(count))
+ return -1;
+
+ array_sz = htonl(array->array_size);
+ if (write(fd, & array_sz, sizeof(array_sz)) != sizeof(array_sz))
+ return -1;
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ for (i = 0; i < array->array_size; i++) {
+ ret = write_chain(fd, i, array->var_array[i]);
+ if (ret != 0)
+ return ret;
+ }
+ return 0;
}
+
/* write_chain --- write out a whole hash chain */
/*
@@ -188,13 +199,20 @@ write_elem(int fd, int index, NODE *item)
return write_value(fd, item->ahvalue);
}
-/* write_value --- write a number or a string */
+/* write_value --- write a number or a string or a array */
static int
write_value(int fd, NODE *val)
{
int code, len;
+ if (val->type == Node_var_array) {
+ code = htonl(2);
+ if (write(fd, & code, sizeof(code)) != sizeof(code))
+ return -1;
+ return write_array(fd, val);
+ }
+
if ((val->flags & NUMBER) != 0) {
code = htonl(1);
if (write(fd, & code, sizeof(code)) != sizeof(code))
@@ -221,27 +239,21 @@ write_value(int fd, NODE *val)
/* do_reada --- read an array */
static NODE *
-do_reada(tree)
-NODE *tree;
+do_reada(int nargs)
{
NODE *file, *array;
int ret;
int fd;
uint32_t major;
uint32_t minor;
- uint32_t count;
- uint32_t array_sz;
char magic_buf[30];
- int index;
- NODE *new_elem;
- int eof;
if (do_lint && get_curfunc_arg_count() > 2)
lintwarn("reada: called with too many arguments");
/* directory is first arg, array to dump is second */
- file = get_scalar_argument(tree, 0, FALSE);
- array = get_array_argument(tree, 1, TRUE);
+ file = get_scalar_argument(0, FALSE);
+ array = get_array_argument(1, FALSE);
(void) force_string(file);
fd = open(file->stptr, O_RDONLY);
@@ -277,13 +289,40 @@ NODE *tree;
assoc_clear(array);
+ ret = read_array(fd, array);
+ if (ret == 0)
+ goto done0;
+
+done1:
+ ret = -1;
+ update_ERRNO();
+
+done0:
+ close(fd);
+
+ /* Set the return value */
+ return make_number((AWKNUM) ret);
+}
+
+
+/* read_array --- read in an array or sub-array */
+
+static int
+read_array(int fd, NODE *array)
+{
+ int i;
+ uint32_t count;
+ uint32_t array_sz;
+ int index;
+ NODE *new_elem;
+
if (read(fd, & count, sizeof(count)) != sizeof(count)) {
- goto done1;
+ return -1;
}
array->table_size = ntohl(count);
if (read(fd, & array_sz, sizeof(array_sz)) != sizeof(array_sz)) {
- goto done1;
+ return -1;
}
array->array_size = ntohl(array_sz);
@@ -291,47 +330,32 @@ NODE *tree;
array->var_array = (NODE **) malloc(array->array_size * sizeof(NODE *));
memset(array->var_array, '\0', array->array_size * sizeof(NODE *));
- while ((new_elem = read_elem(fd, & index, & eof)) != NULL) {
- new_elem->ahnext = array->var_array[index];
- array->var_array[index] = new_elem;
- }
-
- if (eof) {
- ret = 0;
- goto done0;
+ for (i = 0; i < array->table_size; i++) {
+ if ((new_elem = read_elem(fd, & index, array)) != NULL) {
+ new_elem->ahnext = array->var_array[index];
+ array->var_array[index] = new_elem;
+ } else
+ break;
}
-
-done1:
- ret = -1;
- update_ERRNO();
-
-done0:
- free_temp(file);
- close(fd);
-
- /* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
-
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ if (i != array->table_size)
+ return -1;
+ return 0;
}
+
/* read_elem --- read in a single element */
static NODE *
-read_elem(int fd, int *the_index, int *eof)
+read_elem(int fd, int *the_index, NODE *array)
{
uint32_t hashval, indexval_len, index;
NODE *item;
+ NODE *val;
int ret;
*the_index = 0;
- *eof = FALSE;
if ((ret = read(fd, & index, sizeof(index))) != sizeof(index)) {
- if (ret == 0) {
- *eof = TRUE;
- }
return NULL;
}
*the_index = index = ntohl(index);
@@ -359,10 +383,20 @@ read_elem(int fd, int *the_index, int *eof)
item->ahname_str[item->ahname_len] = '\0';
item->ahname_ref = 1;
- item->ahvalue = read_value(fd);
- if (item->ahvalue == NULL) {
+ item->ahvalue = val = read_value(fd);
+ if (val == NULL) {
return NULL;
}
+ if (val->type == Node_var_array) {
+ char *aname;
+ size_t aname_len;
+
+ /* construct the sub-array name */
+ aname_len = strlen(array->vname) + item->ahname_len + 4;
+ emalloc(aname, char *, aname_len + 2, "read_elem");
+ sprintf(aname, "%s[\"%.*s\"]", array->vname, (int) item->ahname_len, item->ahname_str);
+ val->vname = aname;
+ }
return item;
}
@@ -384,14 +418,15 @@ read_value(int fd)
}
code = ntohl(code);
- /*
- * Very very early versions of this did not write out the code using htonl.
- * Thus this check for `!= 0' instead of '== 1'.
- */
- if (code != 0) {
+ if (code == 2) {
+ val->type = Node_var_array;
+ if (read_array(fd, val) != 0)
+ return NULL;
+ } else if (code == 1) {
if (read(fd, & val->numbr, sizeof(val->numbr)) != sizeof(val->numbr)) {
return NULL;
}
+
val->flags = NUMBER|NUMCUR|MALLOC;
} else {
if (read(fd, & len, sizeof(len)) != sizeof(len)) {
@@ -421,5 +456,5 @@ void *dl;
make_builtin("writea", do_writea, 2);
make_builtin("reada", do_reada, 2);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}
diff --git a/extension/steps b/extension/steps
index 0ced6657..a6696ddc 100755
--- a/extension/steps
+++ b/extension/steps
@@ -5,14 +5,14 @@
# Mon Jun 21 17:03:37 IDT 2004
# Fri May 15 15:48:45 IDT 2009
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. dl.c
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. filefuncs.c
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. fork.c
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. ordchr.c
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. arrayparm.c
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. readfile.c
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. testarg.c
-gcc -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. rwarray.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. dl.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. filefuncs.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. fork.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. ordchr.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. arrayparm.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. readfile.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. testarg.c
+gcc -fPIC -shared -Wall -DHAVE_CONFIG_H -c -O -g -I.. rwarray.c
ld -o dl.so -shared dl.o
ld -o filefuncs.so -shared filefuncs.o
ld -o fork.so -shared fork.o
diff --git a/extension/testarg.c b/extension/testarg.c
index 747dd515..42fd4dd6 100644
--- a/extension/testarg.c
+++ b/extension/testarg.c
@@ -1,31 +1,29 @@
#include "awk.h"
static NODE *
-do_check_arg(tree)
-NODE *tree;
+do_check_arg(int nargs)
{
int ret = 0, argc;
NODE *arg1, *arg2, *arg3;
argc = get_curfunc_arg_count();
- printf("arg count: defined = %d, supplied = %d\n", tree->param_cnt, argc);
+ printf("arg count: defined = %d, supplied = %d\n",
+ nargs, argc);
- arg1 = get_scalar_argument(tree, 0, FALSE);
- arg2 = get_array_argument(tree, 1, FALSE);
- arg3 = get_scalar_argument(tree, 2, TRUE); /* optional */
+ arg1 = get_scalar_argument(0, FALSE);
+ arg2 = get_array_argument(1, FALSE);
+ arg3 = get_scalar_argument(2, TRUE); /* optional */
if (argc > 3) { /* try to use an extra arg */
NODE *arg4;
- arg4 = get_array_argument(tree, 3, TRUE);
+ arg4 = get_array_argument(3, TRUE);
}
if (arg3 != NULL)
printf("3rd arg present\n\n");
else
printf("no 3rd arg\n\n");
- /* Set the return value */
- set_value(tmp_number((AWKNUM) ret));
- /* Just to make the interpreter happy */
- return tmp_number((AWKNUM) 0);
+ /* Set the return value */
+ return make_number((AWKNUM) ret);
}
/* dlload --- load new builtins in this library */
@@ -36,5 +34,5 @@ NODE *tree;
void *dl;
{
make_builtin("check_arg", do_check_arg, 3);
- return tmp_number((AWKNUM) 0);
+ return make_number((AWKNUM) 0);
}