add -i <include file> and -f <ahtml file> options for awx interpreter (requested by mbm)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@6561 3c298f89-4303-0410-b956-a3cf2f4a3e73
--- a/package/busybox/patches/920-awx.patch
+++ b/package/busybox/patches/920-awx.patch
@@ -97,8 +97,8 @@
switch (c) {
diff -purN bb.old/editors/awx.c bb.dev/editors/awx.c
--- bb.old/editors/awx.c 1970-01-01 01:00:00.000000000 +0100
-+++ bb.dev/editors/awx.c 2007-03-11 19:03:27.417297384 +0100
-@@ -0,0 +1,553 @@
++++ bb.dev/editors/awx.c 2007-03-14 02:03:50.566202928 +0100
+@@ -0,0 +1,588 @@
+/*
+ * awk web extension
+ *
@@ -318,22 +318,22 @@
+static void parse_include(char *p)
+{
+ uint32_t tclass;
-+ chain initseq;
++ chain *initseq = NULL;
++ chain tmp;
+ func *f;
+ var *v, tv;
-+ int has_init = 0;
+
+ pos = p;
+ t.lineno = 1;
-+ memset(&initseq, 0, sizeof(initseq));
+ while ((tclass = next_token(TC_EOF | TC_OPSEQ |
+ TC_OPTERM | TC_BEGIN | TC_FUNCDECL)) != TC_EOF) {
+ if (tclass & TC_OPTERM)
+ continue;
+
-+ seq = &initseq;
++ seq = &tmp;
+ if (tclass & TC_BEGIN) {
-+ has_init = 1;
++ initseq = xzalloc(sizeof(chain));
++ seq = initseq;
+ chain_group();
+ } else if (tclass & TC_FUNCDECL) {
+ next_token(TC_FUNCTION);
@@ -354,38 +354,44 @@
+ clear_array(ahash);
+ }
+ }
-+ if (has_init)
-+ evaluate(initseq.first, &tv);
-+}
++ if (initseq)
++ evaluate(initseq->first, &tv);
++}
++
+
+/* include an awk file and run its BEGIN{} section */
-+static var *include(var *res, var *args, int nargs)
-+{
-+ static xhash *includes = NULL;
++static xhash *includes = NULL;
++static void include_file(char *filename)
++{
+ char *s;
+ var *v;
+
-+ s = getvar_s(args);
-+ if (!s)
-+ return res;
-+
+ if (!includes)
+ includes = hash_init();
+
+ /* find out if the file has been included already */
-+ v = findvar(includes, s);
++ v = findvar(includes, filename);
+ if (istrue(v))
-+ return res;
++ return;
+ setvar_s(v, "1");
+
+ /* read include file */
-+ s = get_file(s);
++ s = get_file(filename);
+ if (!s) {
+ fprintf(stderr, "Could not open file.\n");
-+ return res;
++ return;
+ }
+ parse_include(s+1);
+ free(s);
++}
++
++static var *include(var *res, var *args, int nargs)
++{
++ char *s;
++
++ s = getvar_s(args);
++ if (s && (strlen(s) > 0))
++ include_file(s);
+
+ return res;
+}
@@ -462,31 +468,35 @@
+}
+
+/* awk method render(), which opens a template file and processes all awk ssi calls */
-+static var *render(var *res, var *args, int nargs)
-+{
-+ char *s;
++static void render_file(char *filename)
++{
+ int lnr = 0;
+ FILE *f;
+ char *buf1;
+
++ f = fopen(filename, "r");
++ if (!f)
++ return;
++
+ buf1 = xmalloc(LINE_BUF);
++ while (!feof(f) && (fgets(buf1, LINE_BUF - 1, f) != NULL)) {
++ render_line(filename, ++lnr, buf1);
++ }
++}
++
++static var *render(var *res, var *args, int nargs)
++{
++ char *s;
++
+ s = getvar_s(args);
+ if (!s)
-+ goto done;
-+
-+ f = fopen(s, "r");
-+ if (!f)
-+ goto done;
-+
-+ while (!feof(f) && (fgets(buf1, LINE_BUF - 1, f) != NULL)) {
-+ render_line(s, ++lnr, buf1);
-+ }
-+
-+done:
-+ free(buf1);
++ return res;
++
++ render_file(s);
++
+ return res;
+}
-+
++
+/* Call render, but only if this function hasn't been called already */
+static int layout_rendered = 0;
+static var *render_layout(var *res, var *args, int nargs)
@@ -566,16 +576,61 @@
+}
+
+
++static int run_awxscript(char *name)
++{
++ var tv, *layout, *action;
++ char *tmp, *s = NULL;
++
++ zero_out_var(&tv);
++ programname = name;
++
++ /* read the main controller source */
++ s = get_file(programname);
++ if (!s) {
++ fprintf(stderr, "Could not open file\n");
++ return 1;
++ }
++ parse_program(s+1);
++ free(s);
++
++
++ /* set some defaults for ACTION and LAYOUT, which will have special meaning */
++ layout = newvar("LAYOUT");
++ setvar_s(layout, "views/layout.ahtml");
++
++ /* run the BEGIN {} block */
++ evaluate(beginseq.first, &tv);
++
++ action = newvar("ACTION");
++ if (!(strlen(getvar_s(action)) > 0)) {
++ tmp = cgi_getvar("action");
++ if (!tmp || (strlen(tmp) <= 0))
++ tmp = strdup("default");
++
++ setvar_p(action, tmp);
++ }
++
++ /* call the action (precedence: begin block override > cgi parameter > "default") */
++ tmp = xmalloc(strlen(getvar_s(action)) + 7);
++ sprintf(tmp, "handle_%s", getvar_s(action));
++ setvar_s(action, tmp);
++ call(&tv, action, 1);
++ free(tmp);
++
++ /* render the selected layout, will do nothing if render_layout has been called from awk */
++ render_layout(&tv, layout, 1);
++
++ return 0;
++}
++
++
+/* main awx processing function. called from awk_main() */
+static int do_awx(int argc, char **argv)
+{
+ int ret = -1;
+ var tv;
-+ char *s = NULL;
-+ var *layout;
-+ var *action;
-+ char *tmp;
-+ int i;
++ int i, c;
++ char **args = argv;
+
+ zero_out_var(&tv);
+
@@ -592,57 +647,37 @@
+ return 0;
+
+ /* fill in ARGV array */
-+ programname = argv[1];
+ setvar_i(V[ARGC], argc + 1);
+ setari_u(V[ARGV], 0, "awx");
+ i = 0;
-+ while (*argv)
-+ setari_u(V[ARGV], ++i, *argv++);
-+
-+ if (argc < 2) {
++ while (*args)
++ setari_u(V[ARGV], ++i, *args++);
++
++ while((c = getopt(argc, argv, "i:f:")) != EOF) {
++ switch(c) {
++ case 'i':
++ programname = optarg;
++ include_file(optarg);
++ break;
++ case 'f':
++ ret = 0;
++ programname = optarg;
++ render_file(optarg);
++ goto done;
++ }
++ }
++ argc -= optind;
++ argv += optind;
++
++ if (argc < 1) {
+ fprintf(stderr, "Invalid argument.\n");
+ goto done;
+ }
-+
-+ /* read the main controller source */
-+ s = get_file(programname);
-+ if (!s) {
-+ fprintf(stderr, "Could not open file\n");
-+ goto done;
-+ }
-+ parse_program(s+1);
-+ free(s);
-+
-+
-+ /* set some defaults for ACTION and LAYOUT, which will have special meaning */
-+ layout = newvar("LAYOUT");
-+ setvar_s(layout, "views/layout.ahtml");
-+
-+ /* run the BEGIN {} block */
-+ evaluate(beginseq.first, &tv);
-+
-+ action = newvar("ACTION");
-+ if (!(strlen(getvar_s(action)) > 0)) {
-+ tmp = cgi_getvar("action");
-+ if (!tmp || (strlen(tmp) <= 0))
-+ tmp = strdup("default");
-+
-+ setvar_p(action, tmp);
-+ }
-+
-+ /* call the action (precedence: begin block override > cgi parameter > "default") */
-+ tmp = xmalloc(strlen(getvar_s(action)) + 7);
-+ sprintf(tmp, "handle_%s", getvar_s(action));
-+ setvar_s(action, tmp);
-+ call(&tv, action, 1);
-+ free(tmp);
-+
-+ /* render the selected layout, will do nothing if render_layout has been called from awk */
-+ render_layout(&tv, layout, 1);
-+
-+ ret = 0;
++
++ ret = run_awxscript(*argv);
++
+done:
-+ exit(0);
++ exit(ret);
+}
+
+/* entry point for awx applet */