diff -Nbru clearsilver-0.3/Makefile clearsilver-0.4/Makefile
--- clearsilver-0.3/Makefile Tue Aug 7 14:57:45 2001
+++ clearsilver-0.4/Makefile Fri Jan 11 15:45:44 2002
@@ -3,8 +3,6 @@
#
# Copyright (C) 2001 Neotonic and Brandon Long
#
-# This file is licensed under the terms of the FSF's LGPL, or
-# Library General Public License.
#
@@ -71,14 +69,22 @@
mkdir -p $$mdir; \
done
-CS_DISTDIR = clearsilver-0.1
-CS_LABEL = CLEARSILVER-0_1
-CS_FILES = LICENSE CS_LICENSE rules.mk Makefile util cs cgi python scripts
-cs_dist: distclean
+CS_DISTDIR = clearsilver-0.3
+CS_LABEL = CLEARSILVER-0_3
+CS_FILES = LICENSE CS_LICENSE rules.mk Makefile util cs cgi python scripts mod_ecs
+cs_dist:
rm -rf $(CS_DISTDIR)
cvs -q tag -F $(CS_LABEL) $(CS_FILES)
mkdir -p $(CS_DISTDIR)
cvs -z3 -q export -r $(CS_LABEL) -d $(CS_DISTDIR) neotonic
$(MAKE) -C $(CS_DISTDIR) man
- tar chozf clearsilver-0.1.tar.gz $(CS_DISTDIR)
+ tar chozf $(CS_DISTDIR).tar.gz $(CS_DISTDIR)
+TRAKKEN_DISTDIR = trakken-0.55
+TRAKKEN_LABEL = TRAKKEN_0_55
+trakken_dist:
+ rm -rf $(TRAKKEN_DISTDIR)
+ cvs -q tag -F $(TRAKKEN_LABEL)
+ mkdir -p $(TRAKKEN_DISTDIR)
+ cvs -z3 -q export -r $(TRAKKEN_LABEL) -d $(TRAKKEN_DISTDIR) neotonic
+ tar chozf $(TRAKKEN_DISTDIR).tar.gz $(TRAKKEN_DISTDIR)
diff -Nbru clearsilver-0.3/cgi/Makefile clearsilver-0.4/cgi/Makefile
--- clearsilver-0.3/cgi/Makefile Sun Sep 9 16:53:10 2001
+++ clearsilver-0.4/cgi/Makefile Fri Jan 11 15:42:08 2002
@@ -13,12 +13,13 @@
STATIC_EXE = static.cgi
STATIC_SRC = static.c
STATIC_OBJ = $(STATIC_SRC:%.c=%.o)
+STATIC_CSO = $(STATIC_EXE:%.cgi=%.cso)
CFLAGS += -I$(NEOTONIC_ROOT) -DHTML_COMPRESSION
DLIBS += -lneo_cgi -lneo_cs -lneo_utl # -lefence
LIBS += -L$(LIB_DIR) $(DLIBS)
-TARGETS = $(CGI_LIB) $(STATIC_EXE)
+TARGETS = $(CGI_LIB) $(STATIC_EXE) $(STATIC_CSO)
all: $(TARGETS)
@@ -27,6 +28,9 @@
$(STATIC_EXE): $(STATIC_OBJ) $(DEP_LIBS)
$(LD) $@ $(STATIC_OBJ) $(LIBS)
+
+$(STATIC_CSO): $(STATIC_OBJ) $(DEP_LIBS)
+ $(LDSHARED) -o $@ $(STATIC_OBJ) $(LIBS)
clean:
$(RM) *.o
diff -Nbru clearsilver-0.3/cgi/cgiwrap.c clearsilver-0.4/cgi/cgiwrap.c
--- clearsilver-0.3/cgi/cgiwrap.c Mon Aug 6 14:28:16 2001
+++ clearsilver-0.4/cgi/cgiwrap.c Fri Jan 11 15:42:08 2002
@@ -30,9 +30,10 @@
ITERENV_FUNC iterenv_cb;
void *data;
+ int emu_init;
} CGIWRAPPER;
-static CGIWRAPPER GlobalWrapper;
+static CGIWRAPPER GlobalWrapper = {0, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0};
static void cgiwrap_init (void)
{
@@ -51,6 +52,9 @@
void cgiwrap_init_std (int argc, char **argv, char **envp)
{
+ /* so you can compile the same code for embedded without mods */
+ if (GlobalWrapper.emu_init) return;
+
cgiwrap_init();
GlobalWrapper.argc = argc;
GlobalWrapper.argv = argv;
@@ -70,6 +74,7 @@
GlobalWrapper.getenv_cb = getenv_cb;
GlobalWrapper.putenv_cb = putenv_cb;
GlobalWrapper.iterenv_cb = iterenv_cb;
+ GlobalWrapper.emu_init = 1;
}
NEOERR *cgiwrap_getenv (char *k, char **v)
diff -Nbru clearsilver-0.3/cgi/html.c clearsilver-0.4/cgi/html.c
--- clearsilver-0.3/cgi/html.c Fri Sep 14 18:23:03 2001
+++ clearsilver-0.4/cgi/html.c Tue Nov 6 16:23:01 2001
@@ -131,11 +131,21 @@
email_match.rm_so = -1;
email_match.rm_eo = -1;
}
+ else
+ {
+ email_match.rm_so += x;
+ email_match.rm_eo += x;
+ }
if (regexec (&url_re, src+x, 1, &url_match, 0) != 0)
{
url_match.rm_so = -1;
url_match.rm_eo = -1;
}
+ else
+ {
+ url_match.rm_so += x;
+ url_match.rm_eo += x;
+ }
while ((x < slen) && !((email_match.rm_so == -1) && (url_match.rm_so == -1)))
{
if (part >= part_count)
@@ -145,8 +155,8 @@
}
if ((url_match.rm_so != -1) && ((email_match.rm_so == -1) || (url_match.rm_so <= email_match.rm_so)))
{
- parts[part].begin = x + url_match.rm_so;
- parts[part].end = x + url_match.rm_eo;
+ parts[part].begin = url_match.rm_so;
+ parts[part].end = url_match.rm_eo;
parts[part].type = SC_TYPE_URL;
x = parts[part].end + 1;
part++;
@@ -157,6 +167,11 @@
url_match.rm_so = -1;
url_match.rm_eo = -1;
}
+ else
+ {
+ url_match.rm_so += x;
+ url_match.rm_eo += x;
+ }
if ((email_match.rm_so != -1) && (x > email_match.rm_so))
{
if (regexec (&email_re, src+x, 1, &email_match, 0) != 0)
@@ -164,13 +179,18 @@
email_match.rm_so = -1;
email_match.rm_eo = -1;
}
+ else
+ {
+ email_match.rm_so += x;
+ email_match.rm_eo += x;
+ }
}
}
}
else
{
- parts[part].begin = x + email_match.rm_so;
- parts[part].end = x + email_match.rm_eo;
+ parts[part].begin = email_match.rm_so;
+ parts[part].end = email_match.rm_eo;
parts[part].type = SC_TYPE_EMAIL;
x = parts[part].end + 1;
part++;
@@ -181,6 +201,11 @@
email_match.rm_so = -1;
email_match.rm_eo = -1;
}
+ else
+ {
+ email_match.rm_so += x;
+ email_match.rm_eo += x;
+ }
if ((url_match.rm_so != -1) && (x > url_match.rm_so))
{
if (regexec (&url_re, src+x, 1, &url_match, 0) != 0)
@@ -188,6 +213,11 @@
url_match.rm_so = -1;
url_match.rm_eo = -1;
}
+ else
+ {
+ url_match.rm_so += x;
+ url_match.rm_eo += x;
+ }
}
}
}
@@ -276,9 +306,9 @@
err = string_append (out, ">");
else if (src[x] == '\n')
if (newlines)
- err = string_append (out, "
");
+ err = string_append (out, "
");
else if (x && src[x-1] == '\n')
- err = string_append (out, "
"); + err = string_append (out, "
");
else
err = string_append_char (out, '\n');
else if (src[x] != '\r')
@@ -312,7 +342,7 @@
char last_char = src[parts[i].end-1];
int suffix=0;
if (last_char == '.' || last_char == ',') { suffix=1; }
- err = string_append (out, " ");
+ err = string_append (out, "");
if (suffix) {
err = string_appendn(out,src + parts[i].end - 1,1);
if (err != STATUS_OK) break;
@@ -333,7 +363,7 @@
}
else /* type == SC_TYPE_EMAIL */
{
- err = string_append (out, "");
+ err = string_append (out, "");
}
x = parts[i].end;
i++;
diff -Nbru clearsilver-0.3/cgi/rfc2388.c clearsilver-0.4/cgi/rfc2388.c
--- clearsilver-0.3/cgi/rfc2388.c Sun Sep 9 16:53:10 2001
+++ clearsilver-0.4/cgi/rfc2388.c Tue Oct 16 15:39:59 2001
@@ -392,12 +392,12 @@
if (filename)
{
if (last) fwrite (last, sizeof(char), strlen(last), fp);
- if (l > 2 && s[l-1] == '\n' && s[l-2] == '\r')
+ if (l > 1 && s[l-1] == '\n' && s[l-2] == '\r')
{
last = "\r\n";
l-=2;
}
- else if (l > 1 && s[l-1] == '\n')
+ else if (l > 0 && s[l-1] == '\n')
{
last = "\n";
l--;
diff -Nbru clearsilver-0.3/cgi/static.c clearsilver-0.4/cgi/static.c
--- clearsilver-0.3/cgi/static.c Mon Aug 6 14:28:16 2001
+++ clearsilver-0.4/cgi/static.c Wed Oct 10 17:26:13 2001
@@ -47,6 +47,7 @@
{
*p = '\0';
err = hdf_set_value (cgi->hdf, "hdf.loadpaths.0", cs_file);
+ chdir(cs_file);
*p = '/';
if (err)
{
diff -Nbru clearsilver-0.3/cs/Makefile clearsilver-0.4/cs/Makefile
--- clearsilver-0.3/cs/Makefile Sat Sep 15 17:08:55 2001
+++ clearsilver-0.4/cs/Makefile Tue Nov 13 13:58:15 2001
@@ -23,7 +23,7 @@
TARGETS = $(CS_LIB) $(CSTEST_EXE) test
-CS_TESTS = test.cs test2.cs test3.cs test4.cs test5.cs test6.cs
+CS_TESTS = test.cs test2.cs test3.cs test4.cs test5.cs test6.cs test7.cs
all: $(TARGETS)
@@ -43,7 +43,7 @@
./cstest test.hdf $$test > $$test.gold; \
done
-test: $(CSTEST_EXE)
+test: $(CSTEST_EXE) $(CS_TESTS)
@echo "Running cs regression tests"
@for test in $(CS_TESTS); do \
rm -f $$test.out; \
diff -Nbru clearsilver-0.3/cs/cs.h clearsilver-0.4/cs/cs.h
--- clearsilver-0.3/cs/cs.h Sat Sep 15 16:38:40 2001
+++ clearsilver-0.4/cs/cs.h Tue Nov 13 13:58:15 2001
@@ -15,13 +15,15 @@
* CS_OPEN :=
* COMMAND := (CMD_IF | CMD_VAR | CMD_EVAR | CMD_INCLUDE | CMD_EACH
- * | CMD_DEF | CMD_CALL | CMD_SET )
+ * | CMD_DEF | CMD_CALL | CMD_SET | CMD_LOOP )
* CMD_IF := CS_OPEN IF CS_CLOSE CS CMD_ENDIF
* CMD_ENDIF := CS_OPEN ENDIF CS_CLOSE
* CMD_INCLUDE := CS_OPEN INCLUDE CS_CLOSE
* CMD_DEF := CS_OPEN DEF CS_CLOSE
* CMD_CALL := CS_OPEN CALL CS_CLOSE
* CMD_SET := CS_OPEN SET CS_CLOSE
+ * CMD_LOOP := CS_OPEN LOOP CS_CLOSE
+ * LOOP := loop:VAR = EXPR, EXPR, EXPR
* SET := set:VAR = EXPR
* EXPR := (ARG | ARG OP EXPR)
* CALL := call:VAR LPAREN ARG (,ARG)* RPAREN
diff -Nbru clearsilver-0.3/cs/csparse.c clearsilver-0.4/cs/csparse.c
--- clearsilver-0.3/cs/csparse.c Sat Sep 15 17:22:56 2001
+++ clearsilver-0.4/cs/csparse.c Thu Jan 10 15:11:39 2002
@@ -34,9 +34,10 @@
ST_EACH = 1<<3,
ST_POP = 1<<4,
ST_DEF = 1<<5,
+ ST_LOOP = 1<<6,
} CS_STATE;
-#define ST_ANYWHERE (ST_EACH | ST_ELSE | ST_IF | ST_GLOBAL | ST_DEF)
+#define ST_ANYWHERE (ST_EACH | ST_ELSE | ST_IF | ST_GLOBAL | ST_DEF | ST_LOOP)
typedef struct _stack_entry
{
@@ -70,6 +71,9 @@
static NEOERR *call_eval (CSPARSE *parse, CSTREE *node, CSTREE **next);
static NEOERR *set_parse (CSPARSE *parse, int cmd, char *arg);
static NEOERR *set_eval (CSPARSE *parse, CSTREE *node, CSTREE **next);
+static NEOERR *loop_parse (CSPARSE *parse, int cmd, char *arg);
+static NEOERR *loop_eval (CSPARSE *parse, CSTREE *node, CSTREE **next);
+static NEOERR *endloop_parse (CSPARSE *parse, int cmd, char *arg);
static NEOERR *render_node (CSPARSE *parse, CSTREE *node);
@@ -109,7 +113,7 @@
endeach_parse, skip_eval, 0},
{"include", sizeof("include")-1, ST_ANYWHERE, ST_SAME,
include_parse, skip_eval, 1},
- {"def", sizeof("def")-1, ST_GLOBAL, ST_DEF,
+ {"def", sizeof("def")-1, ST_ANYWHERE, ST_DEF,
def_parse, skip_eval, 1},
{"/def", sizeof("/def")-1, ST_DEF, ST_POP,
enddef_parse, skip_eval, 0},
@@ -117,6 +121,10 @@
call_parse, call_eval, 1},
{"set", sizeof("set")-1, ST_ANYWHERE, ST_SAME,
set_parse, set_eval, 1},
+ {"loop", sizeof("loop")-1, ST_ANYWHERE, ST_LOOP,
+ loop_parse, loop_eval, 1},
+ {"/loop", sizeof("/loop")-1, ST_LOOP, ST_POP,
+ endloop_parse, skip_eval, 1},
{NULL},
};
@@ -435,7 +443,7 @@
if (!strncasecmp(token, Commands[i].cmd, n))
{
if ((Commands[i].has_arg && ((token[n] == ':') || (token[n] == '!')))
- || (token[n] == ' ' || token[n] == '\0'))
+ || (token[n] == ' ' || token[n] == '\0' || token[n] == '\r' || token[n] == '\n'))
{
err = uListGet (parse->stack, -1, (void **)&entry);
if (err != STATUS_OK) goto cs_parse_done;
@@ -639,193 +647,6 @@
return atoi(vs);
}
-static NEOERR *literal_parse (CSPARSE *parse, int cmd, char *arg)
-{
- NEOERR *err;
- CSTREE *node;
-
- /* ne_warn ("literal: %s", arg); */
- err = alloc_node (&node);
- if (err) return nerr_pass(err);
- node->cmd = cmd;
- node->arg1.op_type = CS_TYPE_STRING;
- node->arg1.s = arg;
- *(parse->next) = node;
- parse->next = &(node->next);
- parse->current = node;
-
- return STATUS_OK;
-}
-
-static NEOERR *literal_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
-{
- NEOERR *err = STATUS_OK;
-
- if (node->arg1.s != NULL)
- err = parse->output_cb (parse->output_ctx, node->arg1.s);
- *next = node->next;
- return nerr_pass(err);
-}
-
-static NEOERR *name_parse (CSPARSE *parse, int cmd, char *arg)
-{
- NEOERR *err;
- CSTREE *node;
- char *a, *s;
- char tmp[256];
-
- /* ne_warn ("name: %s", arg); */
- err = alloc_node (&node);
- if (err) return nerr_pass(err);
- node->cmd = cmd;
- if (arg[0] == '!')
- node->flags |= CSF_REQUIRED;
- arg++;
- /* Validate arg is a var (regex /^[#" ]$/) */
- a = neos_strip(arg);
- s = strpbrk(a, "#\" <>");
- if (s != NULL)
- {
- dealloc_node(&node);
- return nerr_raise (NERR_PARSE, "%s Invalid character in var name %s: %c",
- find_context(parse, -1, tmp, sizeof(tmp)),
- a, s[0]);
- }
-
- node->arg1.op_type = CS_TYPE_VAR;
- node->arg1.s = a;
- *(parse->next) = node;
- parse->next = &(node->next);
- parse->current = node;
-
- return STATUS_OK;
-}
-
-static NEOERR *name_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
-{
- NEOERR *err = STATUS_OK;
- HDF *obj;
- char *v;
-
- if (node->arg1.op_type == CS_TYPE_VAR && node->arg1.s != NULL)
- {
- obj = var_lookup_obj (parse, node->arg1.s);
- if (obj != NULL)
- {
- v = hdf_obj_name(obj);
- err = parse->output_cb (parse->output_ctx, v);
- }
- }
- *next = node->next;
- return nerr_pass(err);
-}
-
-static NEOERR *var_parse (CSPARSE *parse, int cmd, char *arg)
-{
- NEOERR *err;
- CSTREE *node;
- char *a, *s;
- char tmp[256];
-
- /* ne_warn ("var: %s", arg); */
- err = alloc_node (&node);
- if (err) return nerr_pass(err);
- node->cmd = cmd;
- if (arg[0] == '!')
- node->flags |= CSF_REQUIRED;
- arg++;
- /* Validate arg is a var (regex /^[#" ]$/) */
- a = neos_strip(arg);
- s = strpbrk(a, "#\" <>");
- if (s != NULL)
- {
- dealloc_node(&node);
- return nerr_raise (NERR_PARSE, "%s Invalid character in var name %s: %c",
- find_context(parse, -1, tmp, sizeof(tmp)),
- a, s[0]);
- }
-
- node->arg1.op_type = CS_TYPE_VAR;
- node->arg1.s = a;
- *(parse->next) = node;
- parse->next = &(node->next);
- parse->current = node;
-
- return STATUS_OK;
-}
-
-static NEOERR *var_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
-{
- NEOERR *err = STATUS_OK;
- char *v;
-
- if (node->arg1.op_type == CS_TYPE_VAR && node->arg1.s != NULL)
- {
- v = var_lookup (parse, node->arg1.s);
- if (v != NULL)
- err = parse->output_cb (parse->output_ctx, v);
- }
- *next = node->next;
- return nerr_pass(err);
-}
-
-static NEOERR *evar_parse (CSPARSE *parse, int cmd, char *arg)
-{
- NEOERR *err;
- CSTREE *node;
- char *a, *s;
- char *save_context;
- int save_infile;
- char tmp[256];
-
- /* ne_warn ("evar: %s", arg); */
- err = alloc_node (&node);
- if (err) return nerr_pass(err);
- node->cmd = cmd;
- if (arg[0] == '!')
- node->flags |= CSF_REQUIRED;
- arg++;
- /* Validate arg is a var (regex /^[#" ]$/) */
- a = neos_strip(arg);
- s = strpbrk(a, "#\" <>");
- if (s != NULL)
- {
- dealloc_node(&node);
- return nerr_raise (NERR_PARSE, "%s Invalid character in var name %s: %c",
- find_context(parse, -1, tmp, sizeof(tmp)),
- a, s[0]);
- }
-
- err = hdf_get_copy (parse->hdf, a, &s, NULL);
- if (err)
- {
- dealloc_node(&node);
- return nerr_pass (err);
- }
- if (node->flags & CSF_REQUIRED && s == NULL)
- {
- dealloc_node(&node);
- return nerr_raise (NERR_NOT_FOUND, "%s Unable to evar empty variable %s",
- find_context(parse, -1, tmp, sizeof(tmp)), a);
- }
-
- node->arg1.op_type = CS_TYPE_VAR;
- node->arg1.s = a;
- *(parse->next) = node;
- parse->next = &(node->next);
- parse->current = node;
-
- save_context = parse->context;
- save_infile = parse->in_file;
- parse->context = a;
- parse->in_file = 0;
- if (s) err = cs_parse_string (parse, s, strlen(s));
- parse->context = save_context;
- parse->in_file = save_infile;
-
- return nerr_pass (err);
-}
-
typedef struct _token
{
CSTOKEN_TYPE type;
@@ -987,52 +808,217 @@
}
else
{
- return nerr_raise (NERR_PARSE,
- "%s Terminal token is not an argument, type is %d",
- find_context(parse, -1, tmp, sizeof(tmp)), tokens[0].type);
- }
+ return nerr_raise (NERR_PARSE,
+ "%s Terminal token is not an argument, type is %d",
+ find_context(parse, -1, tmp, sizeof(tmp)), tokens[0].type);
+ }
+ }
+
+ while (BinaryOpOrder[op])
+ {
+ x = ntokens-1;
+ while (x >= 0)
+ {
+ if (tokens[x].type & BinaryOpOrder[op])
+ {
+ arg->op_type = tokens[x].type;
+ arg->expr2 = (CSARG *) calloc (1, sizeof (CSARG));
+ arg->expr1 = (CSARG *) calloc (1, sizeof (CSARG));
+ if (arg->expr1 == NULL || arg->expr2 == NULL)
+ return nerr_raise (NERR_NOMEM,
+ "%s Unable to allocate memory for expression",
+ find_context(parse, -1, tmp, sizeof(tmp)));
+ err = parse_expr2(parse, tokens + x + 1, ntokens-x-1, arg->expr2);
+ if (err) return nerr_pass (err);
+ err = parse_expr2(parse, tokens, x, arg->expr1);
+ if (err) return nerr_pass (err);
+ return STATUS_OK;
+ }
+ x--;
+ }
+ op++;
+ }
+ return nerr_raise (NERR_PARSE, "%s Bad Expression",
+ find_context(parse, -1, tmp, sizeof(tmp)));
+}
+
+static NEOERR *parse_expr (CSPARSE *parse, char *arg, CSARG *expr)
+{
+ NEOERR *err;
+ CSTOKEN tokens[MAX_TOKENS];
+ int ntokens = 0;
+
+ memset(tokens, 0, sizeof(CSTOKEN) * MAX_TOKENS);
+ err = parse_tokens (parse, arg, tokens, &ntokens);
+ if (err) return nerr_pass(err);
+ err = parse_expr2 (parse, tokens, ntokens, expr);
+ if (err) return nerr_pass(err);
+ return STATUS_OK;
+}
+
+static NEOERR *literal_parse (CSPARSE *parse, int cmd, char *arg)
+{
+ NEOERR *err;
+ CSTREE *node;
+
+ /* ne_warn ("literal: %s", arg); */
+ err = alloc_node (&node);
+ if (err) return nerr_pass(err);
+ node->cmd = cmd;
+ node->arg1.op_type = CS_TYPE_STRING;
+ node->arg1.s = arg;
+ *(parse->next) = node;
+ parse->next = &(node->next);
+ parse->current = node;
+
+ return STATUS_OK;
+}
+
+static NEOERR *literal_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
+{
+ NEOERR *err = STATUS_OK;
+
+ if (node->arg1.s != NULL)
+ err = parse->output_cb (parse->output_ctx, node->arg1.s);
+ *next = node->next;
+ return nerr_pass(err);
+}
+
+static NEOERR *name_parse (CSPARSE *parse, int cmd, char *arg)
+{
+ NEOERR *err;
+ CSTREE *node;
+ char *a, *s;
+ char tmp[256];
+
+ /* ne_warn ("name: %s", arg); */
+ err = alloc_node (&node);
+ if (err) return nerr_pass(err);
+ node->cmd = cmd;
+ if (arg[0] == '!')
+ node->flags |= CSF_REQUIRED;
+ arg++;
+ /* Validate arg is a var (regex /^[#" ]$/) */
+ a = neos_strip(arg);
+ s = strpbrk(a, "#\" <>");
+ if (s != NULL)
+ {
+ dealloc_node(&node);
+ return nerr_raise (NERR_PARSE, "%s Invalid character in var name %s: %c",
+ find_context(parse, -1, tmp, sizeof(tmp)),
+ a, s[0]);
+ }
+
+ node->arg1.op_type = CS_TYPE_VAR;
+ node->arg1.s = a;
+ *(parse->next) = node;
+ parse->next = &(node->next);
+ parse->current = node;
+
+ return STATUS_OK;
+}
+
+static NEOERR *name_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
+{
+ NEOERR *err = STATUS_OK;
+ HDF *obj;
+ char *v;
+
+ if (node->arg1.op_type == CS_TYPE_VAR && node->arg1.s != NULL)
+ {
+ obj = var_lookup_obj (parse, node->arg1.s);
+ if (obj != NULL)
+ {
+ v = hdf_obj_name(obj);
+ err = parse->output_cb (parse->output_ctx, v);
+ }
+ }
+ *next = node->next;
+ return nerr_pass(err);
+}
+
+static NEOERR *var_parse (CSPARSE *parse, int cmd, char *arg)
+{
+ NEOERR *err;
+ CSTREE *node;
+
+ /* ne_warn ("var: %s", arg); */
+ err = alloc_node (&node);
+ if (err) return nerr_pass(err);
+ node->cmd = cmd;
+ if (arg[0] == '!')
+ node->flags |= CSF_REQUIRED;
+ arg++;
+ /* Validate arg is a var (regex /^[#" ]$/) */
+ err = parse_expr (parse, arg, &(node->arg1));
+ if (err)
+ {
+ dealloc_node(&node);
+ return nerr_pass(err);
+ }
+
+ *(parse->next) = node;
+ parse->next = &(node->next);
+ parse->current = node;
+
+ return STATUS_OK;
+}
+
+static NEOERR *evar_parse (CSPARSE *parse, int cmd, char *arg)
+{
+ NEOERR *err;
+ CSTREE *node;
+ char *a, *s;
+ char *save_context;
+ int save_infile;
+ char tmp[256];
+
+ /* ne_warn ("evar: %s", arg); */
+ err = alloc_node (&node);
+ if (err) return nerr_pass(err);
+ node->cmd = cmd;
+ if (arg[0] == '!')
+ node->flags |= CSF_REQUIRED;
+ arg++;
+ /* Validate arg is a var (regex /^[#" ]$/) */
+ a = neos_strip(arg);
+ s = strpbrk(a, "#\" <>");
+ if (s != NULL)
+ {
+ dealloc_node(&node);
+ return nerr_raise (NERR_PARSE, "%s Invalid character in var name %s: %c",
+ find_context(parse, -1, tmp, sizeof(tmp)),
+ a, s[0]);
}
- while (BinaryOpOrder[op])
- {
- x = ntokens-1;
- while (x >= 0)
- {
- if (tokens[x].type & BinaryOpOrder[op])
+ err = hdf_get_copy (parse->hdf, a, &s, NULL);
+ if (err)
{
- arg->op_type = tokens[x].type;
- arg->expr2 = (CSARG *) calloc (1, sizeof (CSARG));
- arg->expr1 = (CSARG *) calloc (1, sizeof (CSARG));
- if (arg->expr1 == NULL || arg->expr2 == NULL)
- return nerr_raise (NERR_NOMEM,
- "%s Unable to allocate memory for expression",
- find_context(parse, -1, tmp, sizeof(tmp)));
- err = parse_expr2(parse, tokens + x + 1, ntokens-x-1, arg->expr2);
- if (err) return nerr_pass (err);
- err = parse_expr2(parse, tokens, x, arg->expr1);
- if (err) return nerr_pass (err);
- return STATUS_OK;
- }
- x--;
+ dealloc_node(&node);
+ return nerr_pass (err);
}
- op++;
+ if (node->flags & CSF_REQUIRED && s == NULL)
+ {
+ dealloc_node(&node);
+ return nerr_raise (NERR_NOT_FOUND, "%s Unable to evar empty variable %s",
+ find_context(parse, -1, tmp, sizeof(tmp)), a);
}
- return nerr_raise (NERR_PARSE, "%s Bad Expression",
- find_context(parse, -1, tmp, sizeof(tmp)));
-}
-static NEOERR *parse_expr (CSPARSE *parse, char *arg, CSARG *expr)
-{
- NEOERR *err;
- CSTOKEN tokens[MAX_TOKENS];
- int ntokens = 0;
+ node->arg1.op_type = CS_TYPE_VAR;
+ node->arg1.s = a;
+ *(parse->next) = node;
+ parse->next = &(node->next);
+ parse->current = node;
- memset(tokens, 0, sizeof(CSTOKEN) * MAX_TOKENS);
- err = parse_tokens (parse, arg, tokens, &ntokens);
- if (err) return nerr_pass(err);
- err = parse_expr2 (parse, tokens, ntokens, expr);
- if (err) return nerr_pass(err);
- return STATUS_OK;
+ save_context = parse->context;
+ save_infile = parse->in_file;
+ parse->context = a;
+ parse->in_file = 0;
+ if (s) err = cs_parse_string (parse, s, strlen(s));
+ parse->context = save_context;
+ parse->in_file = save_infile;
+
+ return nerr_pass (err);
}
static NEOERR *if_parse (CSPARSE *parse, int cmd, char *arg)
@@ -1117,9 +1103,13 @@
static NEOERR *eval_expr (CSPARSE *parse, CSARG *expr, CSARG *result)
{
+ memset(result, 0, sizeof(CSARG));
if (expr->op_type & CS_TYPES)
{
*result = *expr;
+ /* we transfer ownership of the string here.. ugh */
+ if (expr->op_type == CS_TYPE_STRING_ALLOC)
+ expr->op_type = CS_TYPE_STRING;
return STATUS_OK;
}
else
@@ -1223,11 +1213,18 @@
result->n = (s2 == NULL) ? 1 : 0;
break;
case CS_OP_ADD:
- result->op_type = CS_TYPE_STRING;
if (s1 == NULL)
+ {
result->s = s2;
+ result->op_type = arg2.op_type;
+ arg2.op_type = CS_TYPE_STRING;
+ }
else
+ {
result->s = s1;
+ result->op_type = arg1.op_type;
+ arg1.op_type = CS_TYPE_STRING;
+ }
break;
default:
ne_warn ("Unsupported op %d in eval_expr", expr->op_type);
@@ -1262,7 +1259,7 @@
result->s = (char *) calloc ((strlen(s1) + strlen(s2) + 1), sizeof(char));
if (result->s == NULL)
return nerr_raise (NERR_NOMEM, "Unable to allocate memory to concatenate strings in expression: %s + %s", s1, s2);
- strcat(result->s, s1);
+ strcpy(result->s, s1);
strcat(result->s, s2);
break;
default:
@@ -1271,6 +1268,7 @@
}
}
}
+
if (arg1.op_type == CS_TYPE_STRING_ALLOC)
free(arg1.s);
if (arg2.op_type == CS_TYPE_STRING_ALLOC)
@@ -1279,6 +1277,39 @@
return STATUS_OK;
}
+static NEOERR *var_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
+{
+ NEOERR *err = STATUS_OK;
+ CSARG val;
+
+ err = eval_expr(parse, &(node->arg1), &val);
+ if (err) return nerr_pass(err);
+ if (val.op_type & (CS_TYPE_NUM | CS_TYPE_VAR_NUM))
+ {
+ char buf[256];
+ long int n_val;
+
+ n_val = arg_eval_num (parse, &val);
+ snprintf (buf, sizeof(buf), "%ld", n_val);
+ err = parse->output_cb (parse->output_ctx, buf);
+ }
+ else
+ {
+ char *s = arg_eval (parse, &val);
+ /* Do we set it to blank if s == NULL? */
+ if (s)
+ {
+ err = parse->output_cb (parse->output_ctx, s);
+ }
+ }
+ if (val.op_type == CS_TYPE_STRING_ALLOC)
+ free(val.s);
+
+ *next = node->next;
+ return nerr_pass(err);
+}
+
+
static NEOERR *if_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
{
NEOERR *err = STATUS_OK;
@@ -1926,6 +1957,194 @@
*next = node->next;
return nerr_pass (err);
+}
+
+static NEOERR *loop_parse (CSPARSE *parse, int cmd, char *arg)
+{
+ NEOERR *err;
+ CSTREE *node;
+ CSARG *carg, *larg = NULL;
+ BOOL last = FALSE;
+ char *lvar;
+ char *p, *a;
+ char tmp[256];
+ int x;
+
+ err = alloc_node (&node);
+ if (err) return nerr_pass(err);
+ node->cmd = cmd;
+ if (arg[0] == '!')
+ node->flags |= CSF_REQUIRED;
+ arg++;
+
+ p = lvar = neos_strip(arg);
+ while (*p && !isspace(*p) && *p != '=') p++;
+ if (*p == '\0')
+ {
+ dealloc_node(&node);
+ return nerr_raise (NERR_PARSE,
+ "%s Improperly formatted loop directive: %s",
+ find_context(parse, -1, tmp, sizeof(tmp)), arg);
+ }
+ if (*p != '=')
+ {
+ *p++ = '\0';
+ while (*p && *p != '=') p++;
+ if (*p == '\0')
+ {
+ dealloc_node(&node);
+ return nerr_raise (NERR_PARSE,
+ "%s Improperly formatted loop directive: %s",
+ find_context(parse, -1, tmp, sizeof(tmp)), arg);
+ }
+ p++;
+ }
+ else
+ {
+ *p++ = '\0';
+ }
+ while (*p && isspace(*p)) p++;
+ if (*p == '\0')
+ {
+ dealloc_node(&node);
+ return nerr_raise (NERR_PARSE,
+ "%s Improperly formatted loop directive: %s",
+ find_context(parse, -1, tmp, sizeof(tmp)), arg);
+ }
+ node->arg1.op_type = CS_TYPE_VAR;
+ node->arg1.s = lvar;
+
+ x = 0;
+ while (*p)
+ {
+ carg = (CSARG *) calloc (1, sizeof(CSARG));
+ if (carg == NULL)
+ {
+ err = nerr_raise (NERR_NOMEM,
+ "%s Unable to allocate memory for CSARG in loop %s",
+ find_context(parse, -1, tmp, sizeof(tmp)), arg);
+ break;
+ }
+ if (larg == NULL)
+ {
+ node->vargs = carg;
+ larg = carg;
+ }
+ else
+ {
+ larg->next = carg;
+ larg = carg;
+ }
+ x++;
+ a = strpbrk(p, ",");
+ if (a == NULL) last = TRUE;
+ else *a = '\0';
+ err = parse_expr (parse, p, carg);
+ if (err) break;
+ if (last == TRUE) break;
+ p = a+1;
+ }
+ if (!err && ((x < 1) || (x > 3)))
+ {
+ err = nerr_raise (NERR_PARSE,
+ "%s Incorrect number of arguments, expected 1, 2, or 3 got %d in loop: %s",
+ find_context(parse, -1, tmp, sizeof(tmp)), x, arg);
+ }
+
+ /* ne_warn ("loop %s %s", lvar, p); */
+
+ *(parse->next) = node;
+ parse->next = &(node->case_0);
+ parse->current = node;
+
+ return STATUS_OK;
+}
+
+static NEOERR *loop_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
+{
+ NEOERR *err = STATUS_OK;
+ CS_LOCAL_MAP each_map;
+ int var;
+ int start = 0, end = 0, step = 1;
+ int x, iter = 1;
+ CSARG *carg;
+ CSARG val;
+
+ carg = node->vargs;
+ if (carg == NULL) return nerr_raise (NERR_ASSERT, "No arguments in loop eval?");
+ err = eval_expr(parse, carg, &val);
+ if (err) return nerr_pass(err);
+ end = arg_eval_num(parse, &val);
+ if (val.op_type == CS_TYPE_STRING_ALLOC) free(val.s);
+ if (carg->next)
+ {
+ start = end;
+ carg = carg->next;
+ err = eval_expr(parse, carg, &val);
+ if (err) return nerr_pass(err);
+ end = arg_eval_num(parse, &val);
+ if (val.op_type == CS_TYPE_STRING_ALLOC) free(val.s);
+ if (carg->next)
+ {
+ carg = carg->next;
+ err = eval_expr(parse, carg, &val);
+ if (err) return nerr_pass(err);
+ step = arg_eval_num(parse, &val);
+ if (val.op_type == CS_TYPE_STRING_ALLOC) free(val.s);
+ }
+ }
+ /* automatically handle cases where the step is backwards */
+ if (((step < 0) && (start < end)) ||
+ ((step > 0) && (end < start)))
+ {
+ x = start;
+ start = end;
+ end = x;
+ }
+ if (step == 0)
+ {
+ if (start == end) iter = 1;
+ else iter = 0;
+ }
+ else
+ {
+ iter = abs((end - start) / step + 1);
+ }
+
+ if (iter > 0)
+ {
+ /* Init and install local map */
+ each_map.type = CS_TYPE_NUM;
+ each_map.name = node->arg1.s;
+ each_map.next = parse->locals;
+ parse->locals = &each_map;
+
+ var = start;
+ for (x = 0, var = start; x < iter; x++, var += step)
+ {
+ each_map.value.n = var;
+ err = render_node (parse, node->case_0);
+ if (err != STATUS_OK) break;
+ }
+
+ /* Remove local map */
+ parse->locals = each_map.next;
+ }
+
+ *next = node->next;
+ return nerr_pass (err);
+}
+static NEOERR *endloop_parse (CSPARSE *parse, int cmd, char *arg)
+{
+ NEOERR *err;
+ STACK_ENTRY *entry;
+
+ err = uListGet (parse->stack, -1, (void **)&entry);
+ if (err != STATUS_OK) return nerr_pass(err);
+
+ parse->next = &(entry->tree->next);
+ parse->current = entry->tree;
+ return STATUS_OK;
}
static NEOERR *skip_eval (CSPARSE *parse, CSTREE *node, CSTREE **next)
diff -Nbru clearsilver-0.3/cs/test7.cs clearsilver-0.4/cs/test7.cs
--- clearsilver-0.3/cs/test7.cs Wed Dec 31 16:00:00 1969
+++ clearsilver-0.4/cs/test7.cs Tue Nov 13 13:58:15 2001
@@ -0,0 +1,14 @@
+
+LOOP Test
+
+1, 3, 5
+,
+
+1, 3, 5... 205
+,
+
+backwards
+,
+
+broken
+,
diff -Nbru clearsilver-0.3/cs/test7.cs.gold clearsilver-0.4/cs/test7.cs.gold
--- clearsilver-0.3/cs/test7.cs.gold Wed Dec 31 16:00:00 1969
+++ clearsilver-0.4/cs/test7.cs.gold Tue Nov 13 13:58:15 2001
@@ -0,0 +1,15 @@
+Parsing test7.cs
+
+LOOP Test
+
+1, 3, 5
+1, 3, 5,
+
+1, 3, 5... 205
+1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205,
+
+backwards
+205, 203, 201, 199, 197, 195, 193, 191, 189, 187, 185, 183, 181, 179, 177, 175, 173, 171, 169, 167, 165, 163, 161, 159, 157, 155, 153, 151, 149, 147, 145, 143, 141, 139, 137, 135, 133, 131, 129, 127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 99, 97, 95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1,
+
+broken
+205, 203, 201, 199, 197, 195, 193, 191, 189, 187, 185, 183, 181, 179, 177, 175, 173, 171, 169, 167, 165, 163, 161, 159, 157, 155, 153, 151, 149, 147, 145, 143, 141, 139, 137, 135, 133, 131, 129, 127, 125, 123, 121, 119, 117, 115, 113, 111, 109, 107, 105, 103, 101, 99, 97, 95, 93, 91, 89, 87, 85, 83, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 61, 59, 57, 55, 53, 51, 49, 47, 45, 43, 41, 39, 37, 35, 33, 31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1,
diff -Nbru clearsilver-0.3/mod_ecs/Makefile.tmpl clearsilver-0.4/mod_ecs/Makefile.tmpl
--- clearsilver-0.3/mod_ecs/Makefile.tmpl Wed Dec 31 16:00:00 1969
+++ clearsilver-0.4/mod_ecs/Makefile.tmpl Fri Jan 11 15:32:32 2002
@@ -0,0 +1 @@
+# Makefile for mod_ecs
diff -Nbru clearsilver-0.3/mod_ecs/README clearsilver-0.4/mod_ecs/README
--- clearsilver-0.3/mod_ecs/README Wed Dec 31 16:00:00 1969
+++ clearsilver-0.4/mod_ecs/README Fri Jan 11 15:42:27 2002
@@ -0,0 +1,83 @@
+mod_ecs - Apache Embedded ClearSilver CGI Module
+-------------------------------------------------------
+mod_ecs is based on a heavily modified version of mod_ecgi from:
+http://www.webthing.com/software/mod_ecgi.html
+
+This directory contains an Apache module which is designed to work with
+the ClearSilver CGI Kit. The point of this Apache module is
+performance, if your server is under sufficient load that the overhead
+of forking and execing the CGI for every request is too much, this
+module is for you. This module is also useful if you want some of the
+benefits of having a long-lived program: ie, the CGI can maintain
+connections to data sources such as databases or cache data in memory.
+The chief disadvantage is the same thing: your CGI becomes a long lived
+process, and you have to watch that you don't hold connections or memory
+that you don't want to. You might want to look into the Apache
+configuration directives for limiting the number of connections that
+each child process handles: MaxRequestsPerChild.
+
+If you are already using the full ClearSilver CGI Kit, all you need to
+do to compile for the embedded ClearSilver is compile to a shared
+library instead of to an executable. For instance, under Linux:
+
+ Executable: ld -o static.cgi -lneo_cgi -lneo_cs -lneo_util
+ Shared Library: ld -shared -fPic -o static.cso -lneo_cgi -lneo_cs -lneo_util
+
+Also, remember not to call exit(), as this will cause the entire Apache
+child to exit.
+
+There are two extra functions you can have in your CGI that the embedded
+ClearSilver module will try to find and call if they exist. They are:
+void ECSInit(void);
+and
+void ECSCleanup(void);
+
+The first is called when the embedded CGI is loaded, the second before
+the embedded CGI is unloaded.
+
+This module supports the following three Apache configuration
+directives:
+ECSReload