summaryrefslogtreecommitdiff
path: root/old-extension/sparr.c
diff options
context:
space:
mode:
Diffstat (limited to 'old-extension/sparr.c')
-rw-r--r--old-extension/sparr.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/old-extension/sparr.c b/old-extension/sparr.c
new file mode 100644
index 00000000..a3d06e66
--- /dev/null
+++ b/old-extension/sparr.c
@@ -0,0 +1,163 @@
+/*
+ * sparr.c - Example of changing behavior of arrays in gawk.
+ * See testsparr.awk for usage.
+ */
+
+/*
+ * Copyright (C) 2012 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+#include "awk.h"
+#include "spec_array.h"
+
+int plugin_is_GPL_compatible;
+
+typedef struct {
+ int load_file;
+ NODE *filename;
+} sdata_t;
+
+/* install_array --- install an array in the symbol table */
+
+static NODE *
+install_array(const char *name)
+{
+ NODE *r;
+
+ r = lookup(name);
+ if (r == NULL)
+ r = install_symbol(estrdup(name, strlen(name)), Node_var_array);
+ switch (r->type) {
+ case Node_var_new:
+ r = force_array(r, false);
+ /* fall through */
+ case Node_var_array:
+ assoc_clear(r);
+ break;
+ default:
+ fatal(_("`%s' is not an array"), name);
+ }
+ return r;
+}
+
+/* fetch_SYS --- fetch routine for the array `SYS' */
+
+static NODE *
+fetch_SYS(NODE *symbol, NODE *subs, void *data)
+{
+ force_string(subs);
+ if (strcmp(subs->stptr, "time") == 0)
+ return do_strftime(0);
+ return NULL;
+}
+
+/* store_SYS --- store routine for the array `SYS' */
+
+static void
+store_SYS(NODE *symbol, NODE *subs, NODE *val, void *data)
+{
+ sdata_t *sd = (sdata_t *) data;
+
+ if (subs != NULL && val != NULL && val->type == Node_val) {
+ force_string(subs);
+ if (strcmp(subs->stptr, "readline") == 0) {
+ sd->load_file = true;
+ unref(sd->filename);
+ sd->filename = dupnode(val);
+ }
+ }
+}
+
+/* load_READLINE --- load routine for the array `READLINE' */
+
+static void
+load_READLINE(NODE *symbol, void *data)
+{
+ sdata_t *sd = (sdata_t *) data;
+ NODE *file, *tmp;
+ FILE *fp;
+ static char linebuf[BUFSIZ];
+ int i;
+ bool long_line = false;
+
+ if (! sd->load_file) /* non-existent SYS["readline"] or already loaded */
+ return;
+
+ file = sd->filename;
+ force_string(file);
+
+ if (file->stlen == 0)
+ return;
+
+ assoc_clear(symbol);
+
+ if ((fp = fopen(file->stptr, "r" )) == NULL) {
+ warning(_("READLINE (%s): %s"), file->stptr, strerror(errno));
+ return;
+ }
+
+ for (i = 1; fgets(linebuf, sizeof(linebuf), fp ) != NULL; i++) {
+ NODE **lhs;
+ size_t sz;
+
+ sz = strlen(linebuf);
+ if (sz > 0 && linebuf[sz - 1] == '\n') {
+ linebuf[sz - 1] = '\0';
+ sz--;
+ if (long_line) {
+ long_line = false;
+ i--;
+ continue;
+ }
+ } else if (long_line) {
+ i--;
+ continue;
+ } else {
+ if (do_lint)
+ lintwarn(_("file `%s' does not end in newline or line # `%d' is too long"),
+ file->stptr, i);
+ long_line = true;
+ }
+
+ tmp = make_number(i);
+ lhs = assoc_lookup(symbol, tmp);
+ unref(tmp);
+ unref(*lhs);
+ *lhs = make_string(linebuf, sz);
+ }
+ fclose(fp);
+ sd->load_file = false; /* don't load this file again */
+}
+
+/* dlload --- load this library */
+
+NODE *
+dlload(NODE *obj, void *dl)
+{
+ NODE *a1, *a2;
+ static sdata_t data;
+
+ a1 = install_array("SYS");
+ register_dyn_array(a1, fetch_SYS, store_SYS, & data);
+ a2 = install_array("READLINE");
+ register_deferred_array(a2, load_READLINE, & data);
+ return make_number((AWKNUM) 0);
+}