diff -Nrbu clearsilver-0.9.12/cgi/cgi.c clearsilver-0.9.13/cgi/cgi.c --- clearsilver-0.9.12/cgi/cgi.c Wed Sep 29 17:26:02 2004 +++ clearsilver-0.9.13/cgi/cgi.c Wed Nov 24 14:55:25 2004 @@ -1018,7 +1018,16 @@ /* This ws strip function is Dave's version, designed to make debug * easier, and the output a bit smaller... but not as small as it could * be: essentially, it strips all empty lines, all extra space at the - * end of the line, except in pre/textarea tags */ + * end of the line, except in pre/textarea tags. + * + * Ok, expanding to 3 levels: + * 0 - No stripping + * 1 - Dave's debug stripper (as above) + * 2 - strip all extra white space + * + * We don't currently strip white space in a tag + * + * */ #if 0 static void debug_output(char *header, char *s, int n) @@ -1033,14 +1042,17 @@ } #endif -void cgi_html_ws_strip(STRING *str) +void cgi_html_ws_strip(STRING *str, int level) { int ws = 0; - int seen_nonws = 0; + int seen_nonws = level > 1; int i, o, l; unsigned char *ch; i = o = 0; + if (str->len) { + ws = isspace(str->buf[0]); + } while (i < str->len) { if (str->buf[i] == '<') @@ -1116,8 +1128,8 @@ * erasing all blank lines */ while (o && isspace(str->buf[o-1])) o--; str->buf[o++] = str->buf[i++]; - ws = 0; - seen_nonws = 0; + ws = level > 1; + seen_nonws = level > 1; } else if (seen_nonws && isspace(str->buf[i])) { @@ -1152,14 +1164,14 @@ int use_gzip = 0; int do_debug = 0; int do_timefooter = 0; - int do_ws_strip = 0; + int ws_strip_level = 0; char *s, *e; s = hdf_get_value (cgi->hdf, "Query.debug", NULL); e = hdf_get_value (cgi->hdf, "Config.DebugPassword", NULL); if (s && e && !strcmp(s, e)) do_debug = 1; do_timefooter = hdf_get_int_value (cgi->hdf, "Config.TimeFooter", 1); - do_ws_strip = hdf_get_int_value (cgi->hdf, "Config.WhiteSpaceStrip", 1); + ws_strip_level = hdf_get_int_value (cgi->hdf, "Config.WhiteSpaceStrip", 1); dis = ne_timef(); s = hdf_get_value (cgi->hdf, "cgiout.ContentType", "text/html"); @@ -1246,9 +1258,9 @@ if (err != STATUS_OK) return nerr_pass(err); } - if (do_ws_strip) + if (ws_strip_level) { - cgi_html_ws_strip(str); + cgi_html_ws_strip(str, ws_strip_level); } if (do_debug) @@ -1365,6 +1377,23 @@ return nerr_pass(convert_text_html_alloc(str, strlen(str), ret)); } +NEOERR *cgi_register_strfuncs(CSPARSE *cs) +{ + NEOERR *err; + + err = cs_register_strfunc(cs, "url_escape", cgi_url_escape); + if (err != STATUS_OK) return nerr_pass(err); + err = cs_register_strfunc(cs, "html_escape", cgi_html_escape_strfunc); + if (err != STATUS_OK) return nerr_pass(err); + err = cs_register_strfunc(cs, "text_html", cgi_text_html_strfunc); + if (err != STATUS_OK) return nerr_pass(err); + err = cs_register_strfunc(cs, "js_escape", cgi_js_escape); + if (err != STATUS_OK) return nerr_pass(err); + err = cs_register_strfunc(cs, "html_strip", cgi_html_strip_strfunc); + if (err != STATUS_OK) return nerr_pass(err); + return STATUS_OK; +} + NEOERR *cgi_cs_init(CGI *cgi, CSPARSE **cs) { NEOERR *err; @@ -1375,15 +1404,7 @@ { err = cs_init (cs, cgi->hdf); if (err != STATUS_OK) break; - err = cs_register_strfunc(*cs, "url_escape", cgi_url_escape); - if (err != STATUS_OK) break; - err = cs_register_strfunc(*cs, "html_escape", cgi_html_escape_strfunc); - if (err != STATUS_OK) break; - err = cs_register_strfunc(*cs, "text_html", cgi_text_html_strfunc); - if (err != STATUS_OK) break; - err = cs_register_strfunc(*cs, "js_escape", cgi_js_escape); - if (err != STATUS_OK) break; - err = cs_register_strfunc(*cs, "html_strip", cgi_html_strip_strfunc); + err = cgi_register_strfuncs(*cs); if (err != STATUS_OK) break; } while (0); @@ -1410,15 +1431,7 @@ { err = cs_init (&cs, cgi->hdf); if (err != STATUS_OK) break; - err = cs_register_strfunc(cs, "url_escape", cgi_url_escape); - if (err != STATUS_OK) break; - err = cs_register_strfunc(cs, "html_escape", cgi_html_escape_strfunc); - if (err != STATUS_OK) break; - err = cs_register_strfunc(cs, "text_html", cgi_text_html_strfunc); - if (err != STATUS_OK) break; - err = cs_register_strfunc(cs, "js_escape", cgi_js_escape); - if (err != STATUS_OK) break; - err = cs_register_strfunc(cs, "html_strip", cgi_html_strip_strfunc); + err = cgi_register_strfuncs(cs); if (err != STATUS_OK) break; err = cs_parse_file (cs, cs_file); if (err != STATUS_OK) break; diff -Nrbu clearsilver-0.9.12/cgi/cgi.h clearsilver-0.9.13/cgi/cgi.h --- clearsilver-0.9.12/cgi/cgi.h Wed Jul 28 15:17:51 2004 +++ clearsilver-0.9.13/cgi/cgi.h Wed Nov 24 14:55:25 2004 @@ -453,7 +453,8 @@ NEOERR *cgi_html_strip_strfunc(unsigned char *str, unsigned char **ret); NEOERR *cgi_html_escape_strfunc(unsigned char *str, unsigned char **ret); NEOERR *cgi_js_escape (unsigned char *buf, unsigned char **esc); -void cgi_html_ws_strip(STRING *str); +void cgi_html_ws_strip_level(STRING *str, int level); +NEOERR *cgi_register_strfuncs(CSPARSE *cs); /* internal use only */ NEOERR * parse_rfc2388 (CGI *cgi); diff -Nrbu clearsilver-0.9.12/java-jni/j_neo_cs.c clearsilver-0.9.13/java-jni/j_neo_cs.c --- clearsilver-0.9.12/java-jni/j_neo_cs.c Wed Sep 29 17:23:16 2004 +++ clearsilver-0.9.13/java-jni/j_neo_cs.c Wed Nov 24 14:55:27 2004 @@ -42,15 +42,7 @@ err = cs_init(&cs, hdf); if (err != STATUS_OK) return jNeoErr(env,err); - err = cs_register_strfunc(cs, "url_escape", cgi_url_escape); - if (err != STATUS_OK) return jNeoErr(env,err); - err = cs_register_strfunc(cs, "html_escape", cgi_html_escape_strfunc); - if (err != STATUS_OK) return jNeoErr(env,err); - err = cs_register_strfunc(cs, "text_html", cgi_text_html_strfunc); - if (err != STATUS_OK) return jNeoErr(env,err); - err = cs_register_strfunc(cs, "js_escape", cgi_js_escape); - if (err != STATUS_OK) return jNeoErr(env,err); - err = cs_register_strfunc(cs, "html_strip", cgi_html_strip_strfunc); + err = cgi_register_strfuncs(cs); if (err != STATUS_OK) return jNeoErr(env,err); return (jint) cs; @@ -122,12 +114,12 @@ STRING str; NEOERR *err; jstring retval; - int do_ws_strip = 0; + int ws_strip_level = 0; int do_debug = 0; // TODO: perhaps we should pass in whether this is html as well... do_debug = hdf_get_int_value(cs->hdf, "ClearSilver.DisplayDebug", 0); - do_ws_strip = hdf_get_int_value(cs->hdf, "ClearSilver.WhiteSpaceStrip", 0); + ws_strip_level = hdf_get_int_value(cs->hdf, "ClearSilver.WhiteSpaceStrip", 0); string_init(&str); err = cs_render(cs, &str, render_cb); @@ -137,8 +129,8 @@ return NULL; } - if (do_ws_strip) { - cgi_html_ws_strip(&str); + if (ws_strip_level) { + cgi_html_ws_strip(&str, ws_strip_level); } if (do_debug) { diff -Nrbu clearsilver-0.9.12/perl/ClearSilver.xs clearsilver-0.9.13/perl/ClearSilver.xs --- clearsilver-0.9.12/perl/ClearSilver.xs Tue Mar 16 00:44:19 2004 +++ clearsilver-0.9.13/perl/ClearSilver.xs Wed Nov 24 14:55:28 2004 @@ -327,6 +327,9 @@ RETVAL = NULL; } else { cs->err = cs_init(&(cs->cs), hdf->hdf); + if (cs->err == STATUS_OK) { + cs->err = cgi_register_strfuncs(cs->cs); + } RETVAL = cs; } OUTPUT: diff -Nrbu clearsilver-0.9.12/python/neo_cs.c clearsilver-0.9.13/python/neo_cs.c --- clearsilver-0.9.12/python/neo_cs.c Wed Jul 28 15:17:41 2004 +++ clearsilver-0.9.13/python/neo_cs.c Wed Nov 24 14:55:30 2004 @@ -96,6 +96,8 @@ err = cs_init (&cs, hdf); if (err) return p_neo_error (err); + err = cgi_register_strfuncs(cs); + if (err) return p_neo_error (err); return p_cs_to_object (cs); } diff -Nrbu clearsilver-0.9.12/ruby/ext/hdf/neo_cs.c clearsilver-0.9.13/ruby/ext/hdf/neo_cs.c --- clearsilver-0.9.12/ruby/ext/hdf/neo_cs.c Wed Jul 28 15:17:45 2004 +++ clearsilver-0.9.13/ruby/ext/hdf/neo_cs.c Wed Nov 24 14:55:31 2004 @@ -41,7 +41,8 @@ if (hdf == NULL) rb_raise(eHdfError, "must include an Hdf object"); err = cs_init (&cs, hdf); - + if (err) Srb_raise(r_neo_error(err)); + err = cgi_register_strfuncs(cs); if (err) Srb_raise(r_neo_error(err)); r_cs = Data_Wrap_Struct(class, 0, c_free, cs); diff -Nrbu clearsilver-0.9.12/rules.mk.in clearsilver-0.9.13/rules.mk.in --- clearsilver-0.9.12/rules.mk.in Mon Jan 5 02:38:28 2004 +++ clearsilver-0.9.13/rules.mk.in Tue Nov 16 15:05:10 2004 @@ -73,7 +73,7 @@ PERL = @PERL@ RUBY = @RUBY@ -CFLAGS = @CFLAGS@ -Wall -c -I$(NEOTONIC_ROOT) @CPPFLAGS@ +CFLAGS = @CFLAGS@ -Wall -I$(NEOTONIC_ROOT) @CPPFLAGS@ CPPFLAGS = -I$(NEOTONIC_ROOT) @CPPFLAGS@ OUTPUT_OPTION = -o $@ LD = $(CC) -o @@ -128,7 +128,7 @@ ## endif .c.o: - $(CC) $(CFLAGS) $(OUTPUT_OPTION) $< + $(CC) $(CFLAGS) $(OUTPUT_OPTION) -c $< everything: depend all diff -Nrbu clearsilver-0.9.12/util/neo_err.c clearsilver-0.9.13/util/neo_err.c --- clearsilver-0.9.12/util/neo_err.c Wed Jul 28 15:17:42 2004 +++ clearsilver-0.9.13/util/neo_err.c Wed Oct 27 14:09:56 2004 @@ -348,14 +348,14 @@ *err = STATUS_OK; } -int nerr_handle (NEOERR **err, int type) +int nerr_handle (NEOERR **err, int etype) { NEOERR *walk = *err; while (walk != STATUS_OK && walk != INTERNAL_ERR) { - if (walk->error == type) + if (walk->error == etype) { _err_free(*err); *err = STATUS_OK; @@ -364,12 +364,12 @@ walk = walk->next; } - if (walk == STATUS_OK && (NEOERR *)type == STATUS_OK) + if (walk == STATUS_OK && etype == STATUS_OK_INT) return 1; if (walk == STATUS_OK) return 0; - if (walk == INTERNAL_ERR && (NEOERR *)type == INTERNAL_ERR) + if (walk == INTERNAL_ERR && etype == INTERNAL_ERR_INT) { *err = STATUS_OK; return 1; @@ -380,22 +380,22 @@ return 0; } -int nerr_match (NEOERR *err, int type) +int nerr_match (NEOERR *err, int etype) { while (err != STATUS_OK && err != INTERNAL_ERR) { - if (err->error == type) + if (err->error == etype) return 1; err = err->next; } - if (err == STATUS_OK && (NEOERR *)type == STATUS_OK) + if (err == STATUS_OK && etype == STATUS_OK_INT) return 1; if (err == STATUS_OK) return 0; - if (err == INTERNAL_ERR && (NEOERR *)type == INTERNAL_ERR) + if (err == INTERNAL_ERR && etype == INTERNAL_ERR_INT) return 1; if (err == INTERNAL_ERR) return 0; diff -Nrbu clearsilver-0.9.12/util/neo_err.h clearsilver-0.9.13/util/neo_err.h --- clearsilver-0.9.12/util/neo_err.h Wed Jul 28 15:17:42 2004 +++ clearsilver-0.9.13/util/neo_err.h Wed Nov 10 16:45:46 2004 @@ -14,15 +14,19 @@ __BEGIN_DECLS +/* For 64 bit systems which don't like mixing ints and pointers, we have the + * _INT version for doing that comparison */ #define STATUS_OK ((NEOERR *)0) +#define STATUS_OK_INT 0 #define INTERNAL_ERR ((NEOERR *)1) +#define INTERNAL_ERR_INT 1 /* NEOERR flags */ #define NE_IN_USE (1<<0) typedef int NERR_TYPE; -/* Types */ +/* Predefined Error Types - These are all registered in nerr_init */ extern NERR_TYPE NERR_PASS; extern NERR_TYPE NERR_ASSERT; extern NERR_TYPE NERR_NOT_FOUND; @@ -111,7 +115,21 @@ void nerr_log_error (NEOERR *err); #include "util/neo_str.h" +/* function: nerr_error_string + * description: returns the string associated with an error (the bottom + * level of the error chain) + * arguments: err - error + * str - string to which the data is appended + * returns: None - errors appending to the string are ignored + */ void nerr_error_string (NEOERR *err, STRING *str); + +/* function: nerr_error_traceback + * description: returns the full traceback of the error chain + * arguments: err - error + * str - string to which the data is appended + * returns: None - errors appending to the string are ignored + */ void nerr_error_traceback (NEOERR *err, STRING *str); /* function: nerr_ignore @@ -120,12 +138,47 @@ */ void nerr_ignore (NEOERR **err); +/* function: nerr_register + * description: register an error type. This will assign a numeric value + * to the type, and keep track of the "pretty name" for it. + * arguments: err - pointer to a NERR_TYPE + * name - pretty name for the error type + * returns: NERR_NOMEM on no memory + */ NEOERR *nerr_register (NERR_TYPE *err, const char *name); +/* function: nerr_init + * description: initialize the NEOERR system. Can be called more than once. + * Is not thread safe. This registers all of the built in + * error types as defined at the top of this file. If you don't + * call this, all exceptions will be returned as UnknownError. + * arguments: None + * returns: possibly NERR_NOMEM, but somewhat unlikely. Possibly an + * UnknownError if NERR_NOMEM hasn't been registered yet. + */ NEOERR *nerr_init (void); -int nerr_handle (NEOERR **err, NERR_TYPE type); +/* function: nerr_match + * description: nerr_match is used to walk the NEOERR chain and match + * the error against a specific error type. In exception + * parlance, this would be the equivalent of "catch". + * Typically, you can just compare a NEOERR against STATUS_OK + * or just test for true if you are checking for any error. + * arguments: err - the NEOERR that has an error. + * type - the NEOERR type, as registered with nerr_register + * returns: true on match + */ int nerr_match (NEOERR *err, NERR_TYPE type); + +/* function: nerr_handle + * description: nerr_handle is a convenience function. It is the equivalent + * of nerr_match, but it will also deallocate the error chain + * on a match. + * arguments: err - pointer to a pointer NEOERR + * type - the NEOERR type, as registered with nerr_register + * returns: true on match + */ +int nerr_handle (NEOERR **err, NERR_TYPE type); __END_DECLS diff -Nrbu clearsilver-0.9.12/util/neo_hdf.c clearsilver-0.9.13/util/neo_hdf.c --- clearsilver-0.9.12/util/neo_hdf.c Wed Jul 28 15:17:42 2004 +++ clearsilver-0.9.13/util/neo_hdf.c Fri Nov 5 02:00:21 2004 @@ -118,31 +118,43 @@ static void _dealloc_hdf (HDF **hdf) { - if (*hdf == NULL) return; - if ((*hdf)->child != NULL) - _dealloc_hdf(&((*hdf)->child)); - if ((*hdf)->next != NULL) - _dealloc_hdf(&((*hdf)->next)); - if ((*hdf)->name != NULL) + HDF *myhdf = *hdf; + HDF *next = NULL; + + if (myhdf == NULL) return; + if (myhdf->child != NULL) + _dealloc_hdf(&(myhdf->child)); + + /* This was easier recursively, but dangerous on long lists, so we + * walk it ourselves */ + next = myhdf->next; + while (next != NULL) { - free ((*hdf)->name); - (*hdf)->name = NULL; + myhdf->next = next->next; + next->next = NULL; + _dealloc_hdf(&next); + next = myhdf->next; } - if ((*hdf)->value != NULL) + if (myhdf->name != NULL) { - if ((*hdf)->alloc_value) - free ((*hdf)->value); - (*hdf)->value = NULL; + free (myhdf->name); + myhdf->name = NULL; } - if ((*hdf)->attr != NULL) + if (myhdf->value != NULL) { - _dealloc_hdf_attr(&((*hdf)->attr)); + if (myhdf->alloc_value) + free (myhdf->value); + myhdf->value = NULL; } - if ((*hdf)->hash != NULL) + if (myhdf->attr != NULL) { - ne_hash_destroy(&(*hdf)->hash); + _dealloc_hdf_attr(&(myhdf->attr)); } - free (*hdf); + if (myhdf->hash != NULL) + { + ne_hash_destroy(&myhdf->hash); + } + free(myhdf); *hdf = NULL; } diff -Nrbu clearsilver-0.9.12/util/test/Makefile clearsilver-0.9.13/util/test/Makefile --- clearsilver-0.9.12/util/test/Makefile Fri Jun 18 19:11:20 2004 +++ clearsilver-0.9.13/util/test/Makefile Fri Nov 5 02:00:28 2004 @@ -26,6 +26,10 @@ HDFCOPYTEST_SRC = hdf_copy_test.c HDFCOPYTEST_OBJ = $(HDFCOPYTEST_SRC:%.c=%.o) +HDFDEALLOCTEST_EXE = hdf_dealloc_test +HDFDEALLOCTEST_SRC = hdf_dealloc_test.c +HDFDEALLOCTEST_OBJ = $(HDFDEALLOCTEST_SRC:%.c=%.o) + NETTEST_EXE = net_test NETTEST_SRC = net_test.c NETTEST_OBJ = $(NETTEST_SRC:%.c=%.o) @@ -46,7 +50,7 @@ LIBS += -L$(LIB_DIR) -lneo_utl TARGETS = $(HDFTEST_EXE) $(LISTDIRTEST_EXE) $(HDFCOPYTEST_EXE) \ - $(HDFSORTTEST_EXE) \ + $(HDFSORTTEST_EXE) $(HDFDEALLOCTEST_EXE) \ $(HDFLOADTEST_EXE) $(NETTEST_EXE) $(DATETEST_EXE) \ $(HASHTEST_EXE) $(ULISTTEST_EXE) @@ -60,6 +64,9 @@ $(HDFSORTTEST_EXE): $(HDFSORTTEST_OBJ) $(NTR_LIB) $(LD) $@ $(HDFSORTTEST_OBJ) $(LIBS) + +$(HDFDEALLOCTEST_EXE): $(HDFDEALLOCTEST_OBJ) $(NTR_LIB) + $(LD) $@ $(HDFDEALLOCTEST_OBJ) $(LIBS) $(HDFLOADTEST_EXE): $(HDFLOADTEST_OBJ) $(NTR_LIB) $(LD) $@ $(HDFLOADTEST_OBJ) $(LIBS) # -lefence diff -Nrbu clearsilver-0.9.12/util/test/hdf_dealloc_test.c clearsilver-0.9.13/util/test/hdf_dealloc_test.c --- clearsilver-0.9.12/util/test/hdf_dealloc_test.c Wed Dec 31 16:00:00 1969 +++ clearsilver-0.9.13/util/test/hdf_dealloc_test.c Fri Nov 5 02:00:28 2004 @@ -0,0 +1,28 @@ + + +#include "cs_config.h" +#include +#include "util/neo_misc.h" +#include "util/neo_hdf.h" +#include "util/neo_rand.h" + +int main(int argc, char *argv[]) +{ + HDF *hdf = NULL; + int i, j; + + hdf_init(&hdf); + + ne_warn("creating 100000x10 nodes"); + for (i = 0; i < 100000; i++) { + char buffer[64]; + for (j = 0; j < 10; j++) { + snprintf(buffer, sizeof(buffer), "node.%d.test.%d", i, j); + hdf_set_value(hdf, buffer, "test"); + } + } + + ne_warn("calling dealloc"); + hdf_destroy(&hdf); // <-- this takes forever to return with a hugely + return 0; +}