summaryrefslogtreecommitdiffstats
path: root/contrib/awk/extension
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2001-11-02 21:06:08 +0000
committerobrien <obrien@FreeBSD.org>2001-11-02 21:06:08 +0000
commit223f0286ad0612783e0da01de3b5bfdc52e3b25c (patch)
treecd2c7fd87952f47d303b90e49b90c14bccf7e292 /contrib/awk/extension
parent4e5281d00b8fa7447d70020d36660157e7e43626 (diff)
downloadFreeBSD-src-223f0286ad0612783e0da01de3b5bfdc52e3b25c.zip
FreeBSD-src-223f0286ad0612783e0da01de3b5bfdc52e3b25c.tar.gz
Update vendor branch to gawk-3.1.0.
Diffstat (limited to 'contrib/awk/extension')
-rw-r--r--contrib/awk/extension/dl.c96
-rwxr-xr-xcontrib/awk/extension/doit1
-rw-r--r--contrib/awk/extension/filefuncs.c339
-rw-r--r--contrib/awk/extension/foo.awk9
-rw-r--r--contrib/awk/extension/fork.c106
-rwxr-xr-xcontrib/awk/extension/steps9
-rw-r--r--contrib/awk/extension/testff.awk30
-rw-r--r--contrib/awk/extension/testfork.awk20
8 files changed, 610 insertions, 0 deletions
diff --git a/contrib/awk/extension/dl.c b/contrib/awk/extension/dl.c
new file mode 100644
index 0000000..0f1e1c5
--- /dev/null
+++ b/contrib/awk/extension/dl.c
@@ -0,0 +1,96 @@
+/*
+ * dl.c - Example of adding a new builtin function to gawk.
+ *
+ * Christos Zoulas, Thu Jun 29 17:40:41 EDT 1995
+ * Arnold Robbins, update for 3.1, Wed Sep 13 09:38:56 2000
+ */
+
+/*
+ * Copyright (C) 1995 - 2001 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "awk.h"
+#include <dlfcn.h>
+
+static void *sdl = NULL;
+
+static NODE *
+zaxxon(tree)
+NODE *tree;
+{
+ NODE *obj;
+ int i;
+ int comma = 0;
+
+ /*
+ * Print the arguments
+ */
+ printf("External linkage %s(", tree->param);
+
+ for (i = 0; i < tree->param_cnt; i++) {
+
+ obj = get_argument(tree, i);
+
+ if (obj == NULL)
+ break;
+
+ force_string(obj);
+
+ printf(comma ? ", %s" : "%s", obj->stptr);
+ free_temp(obj);
+ comma = 1;
+ }
+
+ printf(");\n");
+
+ /*
+ * Do something useful
+ */
+ obj = get_argument(tree, 0);
+
+ if (obj != NULL) {
+ force_string(obj);
+ if (strcmp(obj->stptr, "unload") == 0 && sdl) {
+ /*
+ * XXX: How to clean up the function?
+ * I would like the ability to remove a function...
+ */
+ 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);
+}
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ sdl = dl;
+ make_builtin("zaxxon", zaxxon, 4);
+ return tmp_number((AWKNUM) 0);
+}
diff --git a/contrib/awk/extension/doit b/contrib/awk/extension/doit
new file mode 100755
index 0000000..29dff7d
--- /dev/null
+++ b/contrib/awk/extension/doit
@@ -0,0 +1 @@
+../gawk -f foo.awk
diff --git a/contrib/awk/extension/filefuncs.c b/contrib/awk/extension/filefuncs.c
new file mode 100644
index 0000000..12badb5
--- /dev/null
+++ b/contrib/awk/extension/filefuncs.c
@@ -0,0 +1,339 @@
+/*
+ * filefuncs.c - Builtin functions that provide initial minimal iterface
+ * to the file system.
+ *
+ * Arnold Robbins, update for 3.1, Mon Nov 23 12:53:39 EST 1998
+ */
+
+/*
+ * Copyright (C) 2001 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "awk.h"
+
+#include <sys/sysmacros.h>
+
+/* do_chdir --- provide dynamically loaded chdir() builtin for gawk */
+
+static NODE *
+do_chdir(tree)
+NODE *tree;
+{
+ NODE *newdir;
+ int ret = -1;
+
+ if (do_lint && tree->param_cnt > 1)
+ lintwarn("chdir: called with too many arguments");
+
+ newdir = get_argument(tree, 0);
+ if (newdir != NULL) {
+ (void) force_string(newdir);
+ ret = chdir(newdir->stptr);
+ if (ret < 0)
+ update_ERRNO();
+
+ free_temp(newdir);
+ } else if (do_lint)
+ lintwarn("chdir: 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);
+}
+
+/* format_mode --- turn a stat mode field into something readable */
+
+static char *
+format_mode(fmode)
+unsigned long fmode;
+{
+ static char outbuf[12];
+ int i;
+
+ strcpy(outbuf, "----------");
+ /* first, get the file type */
+ i = 0;
+ switch (fmode & S_IFMT) {
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+ outbuf[i] = 's';
+ break;
+#endif
+#ifdef S_IFLNK
+ case S_IFLNK:
+ outbuf[i] = 'l';
+ break;
+#endif
+ case S_IFREG:
+ outbuf[i] = '-'; /* redundant */
+ break;
+ case S_IFBLK:
+ outbuf[i] = 'b';
+ break;
+ case S_IFDIR:
+ outbuf[i] = 'd';
+ break;
+#ifdef S_IFDOOR /* Solaris weirdness */
+ case S_IFDOOR:
+ outbuf[i] = 'D';
+ break;
+#endif /* S_IFDOOR */
+ case S_IFCHR:
+ outbuf[i] = 'c';
+ break;
+#ifdef S_IFIFO
+ case S_IFIFO:
+ outbuf[i] = 'p';
+ break;
+#endif
+ }
+
+ i++;
+ if ((fmode & S_IRUSR) != 0)
+ outbuf[i] = 'r';
+ i++;
+ if ((fmode & S_IWUSR) != 0)
+ outbuf[i] = 'w';
+ i++;
+ if ((fmode & S_IXUSR) != 0)
+ outbuf[i] = 'x';
+ i++;
+
+ if ((fmode & S_IRGRP) != 0)
+ outbuf[i] = 'r';
+ i++;
+ if ((fmode & S_IWGRP) != 0)
+ outbuf[i] = 'w';
+ i++;
+ if ((fmode & S_IXGRP) != 0)
+ outbuf[i] = 'x';
+ i++;
+
+ if ((fmode & S_IROTH) != 0)
+ outbuf[i] = 'r';
+ i++;
+ if ((fmode & S_IWOTH) != 0)
+ outbuf[i] = 'w';
+ i++;
+ if ((fmode & S_IXOTH) != 0)
+ outbuf[i] = 'x';
+ i++;
+
+ outbuf[i] = '\0';
+
+ if ((fmode & S_ISUID) != 0) {
+ if (outbuf[3] == 'x')
+ outbuf[3] = 's';
+ else
+ outbuf[3] = 'S';
+ }
+
+ /* setgid without execute == locking */
+ if ((fmode & S_ISGID) != 0) {
+ if (outbuf[6] == 'x')
+ outbuf[6] = 's';
+ else
+ outbuf[6] = 'l';
+ }
+
+ if ((fmode & S_ISVTX) != 0) {
+ if (outbuf[9] == 'x')
+ outbuf[9] = 't';
+ else
+ outbuf[9] = 'T';
+ }
+
+ return outbuf;
+}
+
+/* do_stat --- provide a stat() function for gawk */
+
+static NODE *
+do_stat(tree)
+NODE *tree;
+{
+ NODE *file, *array;
+ struct stat sbuf;
+ int ret;
+ NODE **aptr;
+ char *pmode; /* printable mode */
+ char *type = "unknown";
+
+ /* check arg count */
+ if (tree->param_cnt != 2)
+ fatal(
+ "stat: called with incorrect number of arguments (%d), should be 2",
+ tree->param_cnt);
+
+ /* directory is first arg, array to hold results is second */
+ file = get_argument(tree, 0);
+ array = get_argument(tree, 1);
+
+ /* empty out the array */
+ assoc_clear(array);
+
+ /* lstat the file, if error, set ERRNO and return */
+ (void) force_string(file);
+ ret = lstat(file->stptr, & sbuf);
+ if (ret < 0) {
+ update_ERRNO();
+
+ set_value(tmp_number((AWKNUM) ret));
+
+ free_temp(file);
+ return tmp_number((AWKNUM) 0);
+ }
+
+ /* fill in the array */
+ aptr = assoc_lookup(array, tmp_string("name", 4), FALSE);
+ *aptr = dupnode(file);
+
+ aptr = assoc_lookup(array, tmp_string("dev", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_dev);
+
+ aptr = assoc_lookup(array, tmp_string("ino", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_ino);
+
+ aptr = assoc_lookup(array, tmp_string("mode", 4), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_mode);
+
+ aptr = assoc_lookup(array, tmp_string("nlink", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_nlink);
+
+ aptr = assoc_lookup(array, tmp_string("uid", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_uid);
+
+ aptr = assoc_lookup(array, tmp_string("gid", 3), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_gid);
+
+ aptr = assoc_lookup(array, tmp_string("size", 4), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_size);
+
+ aptr = assoc_lookup(array, tmp_string("blocks", 6), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_blocks);
+
+ aptr = assoc_lookup(array, tmp_string("atime", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_atime);
+
+ aptr = assoc_lookup(array, tmp_string("mtime", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_mtime);
+
+ aptr = assoc_lookup(array, tmp_string("ctime", 5), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_ctime);
+
+ /* 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 = make_number((AWKNUM) sbuf.st_rdev);
+
+ aptr = assoc_lookup(array, tmp_string("major", 5), FALSE);
+ *aptr = make_number((AWKNUM) major(sbuf.st_rdev));
+
+ aptr = assoc_lookup(array, tmp_string("minor", 5), FALSE);
+ *aptr = make_number((AWKNUM) minor(sbuf.st_rdev));
+ }
+
+#ifdef HAVE_ST_BLKSIZE
+ aptr = assoc_lookup(array, tmp_string("blksize", 7), FALSE);
+ *aptr = make_number((AWKNUM) sbuf.st_blksize);
+#endif /* HAVE_ST_BLKSIZE */
+
+ aptr = assoc_lookup(array, tmp_string("pmode", 5), FALSE);
+ pmode = format_mode(sbuf.st_mode);
+ *aptr = make_string(pmode, strlen(pmode));
+
+ /* for symbolic links, add a linkval field */
+ if (S_ISLNK(sbuf.st_mode)) {
+ char buf[BUFSIZ*2];
+ int linksize;
+
+ linksize = readlink(file->stptr, buf, sizeof buf);
+ /* should make this smarter */
+ if (linksize == sizeof(buf))
+ fatal("size of symbolic link too big");
+ buf[linksize] = '\0';
+
+ aptr = assoc_lookup(array, tmp_string("linkval", 7), FALSE);
+ *aptr = make_string(buf, linksize);
+ }
+
+ /* add a type field */
+ switch (sbuf.st_mode & S_IFMT) {
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+ type = "socket";
+ break;
+#endif
+#ifdef S_IFLNK
+ case S_IFLNK:
+ type = "symlink";
+ break;
+#endif
+ case S_IFREG:
+ type = "file";
+ break;
+ case S_IFBLK:
+ type = "blockdev";
+ break;
+ case S_IFDIR:
+ type = "directory";
+ break;
+#ifdef S_IFDOOR
+ case S_IFDOOR:
+ type = "door";
+ break;
+#endif
+ case S_IFCHR:
+ type = "chardev";
+ break;
+#ifdef S_IFIFO
+ case S_IFIFO:
+ type = "fifo";
+ break;
+#endif
+ }
+
+ aptr = assoc_lookup(array, tmp_string("type", 4), FALSE);
+ *aptr = make_string(type, strlen(type));
+
+ free_temp(file);
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("chdir", do_chdir, 1);
+ make_builtin("stat", do_stat, 2);
+
+ return tmp_number((AWKNUM) 0);
+}
diff --git a/contrib/awk/extension/foo.awk b/contrib/awk/extension/foo.awk
new file mode 100644
index 0000000..00a89e5
--- /dev/null
+++ b/contrib/awk/extension/foo.awk
@@ -0,0 +1,9 @@
+BEGIN {
+ extension("./dl.so","dlload")
+ zaxxon("hi there", "this is", "a test", "of argument passing")
+ zaxxon(1)
+ zaxxon(1,2)
+ z = zaxxon(1,2,3,4)
+ z = zaxxon(1,zaxxon(zaxxon("foo")),3,4)
+ print z
+}
diff --git a/contrib/awk/extension/fork.c b/contrib/awk/extension/fork.c
new file mode 100644
index 0000000..038a168
--- /dev/null
+++ b/contrib/awk/extension/fork.c
@@ -0,0 +1,106 @@
+/*
+ * fork.c - Provide fork and waitpid functions for gawk.
+ */
+
+/*
+ * Copyright (C) 2001 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "awk.h"
+#include <sys/wait.h>
+
+/* do_fork --- provide dynamically loaded fork() builtin for gawk */
+
+static NODE *
+do_fork(tree)
+NODE *tree;
+{
+ int ret = -1;
+ NODE **aptr;
+
+ if (do_lint && tree->param_cnt > 0)
+ lintwarn("fork: called with too many arguments");
+
+ ret = fork();
+
+ if (ret < 0)
+ update_ERRNO();
+ else if (ret == 0) {
+ /* update PROCINFO in the child */
+
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("pid", 3), FALSE);
+ (*aptr)->numbr = (AWKNUM) getpid();
+
+ aptr = assoc_lookup(PROCINFO_node, tmp_string("ppid", 4), FALSE);
+ (*aptr)->numbr = (AWKNUM) getppid();
+ }
+
+ /* Set the return value */
+ set_value(tmp_number((AWKNUM) ret));
+
+ /* Just to make the interpreter happy */
+ return tmp_number((AWKNUM) 0);
+}
+
+
+/* do_waitpid --- provide dynamically loaded waitpid() builtin for gawk */
+
+static NODE *
+do_waitpid(tree)
+NODE *tree;
+{
+ NODE *pidnode;
+ int ret = -1;
+ double pidval;
+ pid_t pid;
+ int options = 0;
+
+ if (do_lint && tree->param_cnt > 1)
+ lintwarn("waitpid: called with too many arguments");
+
+ pidnode = get_argument(tree, 0);
+ if (pidnode != NULL) {
+ pidval = force_number(pidnode);
+ pid = (int) pidval;
+ options = WNOHANG|WUNTRACED;
+ ret = waitpid(pid, NULL, options);
+ if (ret < 0)
+ update_ERRNO();
+ } else if (do_lint)
+ 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);
+}
+
+/* dlload --- load new builtins in this library */
+
+NODE *
+dlload(tree, dl)
+NODE *tree;
+void *dl;
+{
+ make_builtin("fork", do_fork, 0);
+ make_builtin("waitpid", do_waitpid, 1);
+ return tmp_number((AWKNUM) 0);
+}
diff --git a/contrib/awk/extension/steps b/contrib/awk/extension/steps
new file mode 100755
index 0000000..61a9e6e
--- /dev/null
+++ b/contrib/awk/extension/steps
@@ -0,0 +1,9 @@
+# what to do under linux to make dl.so
+# Tue Nov 24 15:04:14 EST 1998
+
+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
+ld -o dl.so -shared dl.o
+ld -o filefuncs.so -shared filefuncs.o
+ld -o fork.so -shared fork.o
diff --git a/contrib/awk/extension/testff.awk b/contrib/awk/extension/testff.awk
new file mode 100644
index 0000000..0a0a9b2
--- /dev/null
+++ b/contrib/awk/extension/testff.awk
@@ -0,0 +1,30 @@
+BEGIN {
+ extension("./filefuncs.so", "dlload")
+
+# printf "before: "
+# fflush()
+# system("pwd")
+#
+# chdir("..")
+#
+# printf "after: "
+# fflush()
+# system("pwd")
+
+ chdir(".")
+
+ data[1] = 1
+ print "Info for testff.awk"
+ ret = stat("testff.awk", data)
+ print "ret =", ret
+ for (i in data)
+ printf "data[\"%s\"] = %s\n", i, data[i]
+ print "testff.awk modified:", strftime("%m %d %y %H:%M:%S", data["mtime"])
+
+ print "\nInfo for JUNK"
+ ret = stat("JUNK", data)
+ print "ret =", ret
+ for (i in data)
+ printf "data[\"%s\"] = %s\n", i, data[i]
+ print "JUNK modified:", strftime("%m %d %y %H:%M:%S", data["mtime"])
+}
diff --git a/contrib/awk/extension/testfork.awk b/contrib/awk/extension/testfork.awk
new file mode 100644
index 0000000..ca00dca
--- /dev/null
+++ b/contrib/awk/extension/testfork.awk
@@ -0,0 +1,20 @@
+BEGIN {
+ extension("./fork.so", "dlload")
+
+ printf "before fork, pid = %d, ppid = %d\n", PROCINFO["pid"],
+ PROCINFO["ppid"]
+
+ fflush()
+ ret = fork()
+ if (ret < 0)
+ printf("ret = %d, ERRNO = %s\n", ret, ERRNO)
+ else if (ret == 0)
+ printf "child, pid = %d, ppid = %d\n", PROCINFO["pid"],
+ PROCINFO["ppid"]
+ else {
+ system("sleep 3")
+ printf "parent, ret = %d\n", ret
+ printf "parent, pid = %d, ppid = %d\n", PROCINFO["pid"],
+ PROCINFO["ppid"]
+ }
+}
OpenPOWER on IntegriCloud