diff -bru clearsilver-0.1/cgi/cgi.c clearsilver-0.2/cgi/cgi.c --- clearsilver-0.1/cgi/cgi.c Mon Aug 6 14:28:16 2001 +++ clearsilver-0.2/cgi/cgi.c Mon Aug 20 19:39:16 2001 @@ -81,6 +81,12 @@ static char *Argv0 = ""; +int IgnoreEmptyFormVars = 0; + +static int ExceptionsInit = 0; +NERR_TYPE CGIFinished = -1; +NERR_TYPE CGIUploadCancelled = -1; + static NEOERR *_add_cgi_env_var (CGI *cgi, char *env, char *name) { NEOERR *err; @@ -199,7 +205,10 @@ { v = strtok_r(NULL, "&", &l); } + if (v == NULL) v = ""; snprintf(buf, sizeof(buf), "Query.%s", url_decode(k)); + if (!(cgi->ignore_empty_form_vars && (v == NULL || *v == '\0'))) + { url_decode(v); obj = hdf_get_obj (cgi->hdf, buf); if (obj != NULL) @@ -230,6 +239,7 @@ } err = hdf_set_value (cgi->hdf, buf, v); if (err != STATUS_OK) break; + } k = strtok_r(NULL, "=", &l); } } @@ -246,6 +256,9 @@ l = hdf_get_value (cgi->hdf, "CGI.ContentLength", NULL); if (l == NULL) return STATUS_OK; len = atoi (l); + + cgi->data_expected = len; + query = (char *) malloc (sizeof(char) * (len + 1)); if (query == NULL) return nerr_raise (NERR_NOMEM, @@ -315,12 +328,50 @@ return nerr_pass(err); } -static NEOERR *cgi_parse (CGI *cgi) +static void _launch_debugger (CGI *cgi, char *display) +{ + pid_t myPid, pid; + char buffer[127]; + char *debugger; + HDF *obj; + char *allowed; + + /* Only allow remote debugging from allowed hosts */ + for (obj = hdf_get_child (cgi->hdf, "Config.Displays"); + obj; obj = hdf_obj_next (obj)) + { + allowed = hdf_obj_value (obj); + if (allowed && !strcmp (display, allowed)) break; + } + if (obj == NULL) return; + + myPid = getpid(); + + if ((pid = fork()) < 0) + return; + + if ((debugger = hdf_get_value (cgi->hdf, "Config.Debugger", NULL)) == NULL) + { + debugger = "/usr/local/bin/sudo /usr/local/bin/ddd -display %s %s %d"; + } + + if (!pid) + { + sprintf(buffer, debugger, display, Argv0, myPid); + execl("/bin/sh", "sh", "-c", buffer, NULL); + } + else + { + sleep(60); + } +} + +static NEOERR *cgi_pre_parse (CGI *cgi) { NEOERR *err; int x = 0; char buf[256]; - char *method, *type, *query; + char *query; while (CGIVars[x].env_name) { @@ -349,6 +400,26 @@ if (err != STATUS_OK) return nerr_pass (err); } + { + char *display; + + display = hdf_get_value (cgi->hdf, "Query.xdisplay", NULL); + if (display) + { + fprintf(stderr, "** Got display %s\n", display); + _launch_debugger(cgi, display); + } + } + + return STATUS_OK; +} + +NEOERR *cgi_parse (CGI *cgi) +{ + NEOERR *err; + char *method, *type; + + method = hdf_get_value (cgi->hdf, "CGI.RequestMethod", "GET"); type = hdf_get_value (cgi->hdf, "CGI.ContentType", NULL); if (!strcmp(method, "POST")) @@ -393,52 +464,24 @@ } #endif } - return STATUS_OK; } -static void _launch_debugger (CGI *cgi, char *display) +NEOERR *cgi_init (CGI **cgi, HDF *hdf) { - pid_t myPid, pid; - char buffer[127]; - char *debugger; - HDF *obj; - char *allowed; - - /* Only allow remote debugging from allowed hosts */ - for (obj = hdf_get_child (cgi->hdf, "Config.Displays"); - obj; obj = hdf_obj_next (obj)) - { - allowed = hdf_obj_value (obj); - if (allowed && !strcmp (display, allowed)) break; - } - if (obj == NULL) return; - - myPid = getpid(); - - if ((pid = fork()) < 0) - return; - - if ((debugger = hdf_get_value (cgi->hdf, "Config.Debugger", NULL)) == NULL) - { - debugger = "/usr/local/bin/sudo /usr/local/bin/ddd -display %s %s %d"; - } + NEOERR *err = STATUS_OK; + CGI *mycgi; - if (!pid) + if (ExceptionsInit == 0) { - sprintf(buffer, debugger, display, Argv0, myPid); - execl("/bin/sh", "sh", "-c", buffer, NULL); - } - else - { - sleep(60); + err = nerr_init(); + if (err) return nerr_pass(err); + err = nerr_register(&CGIFinished, "CGIFinished"); + if (err) return nerr_pass(err); + err = nerr_register(&CGIUploadCancelled, "CGIUploadCancelled"); + if (err) return nerr_pass(err); + ExceptionsInit = 1; } -} - -NEOERR *cgi_init (CGI **cgi, char *hdf_file) -{ - NEOERR *err = STATUS_OK; - CGI *mycgi; *cgi = NULL; mycgi = (CGI *) calloc (1, sizeof(CGI)); @@ -447,29 +490,22 @@ mycgi->time_start = ne_timef(); + mycgi->ignore_empty_form_vars = IgnoreEmptyFormVars; + do { - err = hdf_init (&(mycgi->hdf)); - if (err != STATUS_OK) break; - err = cgi_parse (mycgi); - if (err != STATUS_OK) break; - - if (hdf_file != NULL && hdf_file[0] != '\0') + if (hdf == NULL) { - err = hdf_read_file (mycgi->hdf, hdf_file); + err = hdf_init (&(mycgi->hdf)); if (err != STATUS_OK) break; } - - { - char *display; - - display = hdf_get_value (mycgi->hdf, "Query.xdisplay", NULL); - if (display) + else { - fprintf(stderr, "** Got display %s\n", display); - _launch_debugger(mycgi, display); - } + mycgi->hdf = hdf; } + err = cgi_pre_parse (mycgi); + if (err != STATUS_OK) break; + } while (0); if (err == STATUS_OK) @@ -511,7 +547,7 @@ { NEOERR *err = STATUS_OK; HDF *obj, *child; - char *s; + char *s, *charset = NULL; if (hdf_get_int_value (cgi->hdf, "Config.NoCache", 0)) { @@ -547,7 +583,11 @@ child = hdf_obj_next(child); } } + charset = hdf_get_value (obj, "charset", NULL); s = hdf_get_value (obj, "ContentType", "text/html"); + if (charset) + err = cgiwrap_writef ("Content-Type: %s; charset=%s\r\n\r\n", s, charset); + else err = cgiwrap_writef ("Content-Type: %s\r\n\r\n", s); if (err != STATUS_OK) return nerr_pass (err); } @@ -709,7 +749,7 @@ } err = string_append (str, "
");
       if (err != STATUS_OK) return nerr_pass(err);
-      err = hdf_dump_str (cgi->hdf, NULL, str);
+      err = hdf_dump_str (cgi->hdf, NULL, 0, str);
       if (err != STATUS_OK) return nerr_pass(err);
     }
   }
@@ -790,7 +830,7 @@
     if (do_dump)
     {
       cgiwrap_writef("Content-Type: text/plain\n\n");
-      hdf_dump_str(cgi->hdf, "", &str);
+      hdf_dump_str(cgi->hdf, "", 0, &str);
       cs_dump(cs, &str, render_cb);
       cgiwrap_writef("%s", str.buf);
       break;
@@ -888,6 +928,12 @@
   }
   cgiwrap_writevf (fmt, ap);
   cgiwrap_writef ("\r\n\r\n");
+  cgiwrap_writef ("Redirect page

\n"); + cgiwrap_writef (" Destination: "); + cgiwrap_writevf (fmt, ap); + cgiwrap_writef ("
\n
\n"); cgiwrap_writef ("There is nothing to see here, please move along..."); } diff -bru clearsilver-0.1/cgi/cgi.h clearsilver-0.2/cgi/cgi.h --- clearsilver-0.1/cgi/cgi.h Mon Aug 6 14:28:16 2001 +++ clearsilver-0.2/cgi/cgi.h Mon Aug 20 19:39:16 2001 @@ -15,14 +15,31 @@ #include "util/neo_err.h" #include "util/neo_hdf.h" -extern int CGIFinished; +extern NERR_TYPE CGIFinished; +extern NERR_TYPE CGIUploadCancelled; -typedef struct _cgi +/* HACK: Set this value if you want to treat empty CGI Query variables as + * non-existant. + */ +extern int IgnoreEmptyFormVars; + +typedef struct _cgi CGI; + +typedef int (*UPLOAD_CB)(CGI *, int nread, int expected); + +struct _cgi { /* Only public parts of this structure */ void *data; /* you can store your own information here */ HDF *hdf; /* the HDF dataset associated with this CGI */ + BOOL ignore_empty_form_vars; + + UPLOAD_CB upload_cb; + + int data_expected; + int data_read; + /* For line oriented reading of form-data input. Used during cgi_init * only */ char *buf; @@ -39,7 +56,8 @@ /* keep track of the time between cgi_init and cgi_render */ double time_start; double time_end; -} CGI; +}; + /* * Function: cgi_init - Initialize ClearSilver CGI environment @@ -68,7 +86,9 @@ * NERR_IO - error reading HDF file or reading CGI stdin, or * writing data on multipart/form-data file submission */ -NEOERR *cgi_init (CGI **cgi, char *hdf_file); +NEOERR *cgi_init (CGI **cgi, HDF *hdf); + +NEOERR *cgi_parse (CGI *cgi); /* * Function: cgi_destroy - deallocate the data associated with a CGI diff -bru clearsilver-0.1/cgi/html.c clearsilver-0.2/cgi/html.c --- clearsilver-0.1/cgi/html.c Mon Aug 6 14:28:16 2001 +++ clearsilver-0.2/cgi/html.c Fri Aug 10 20:19:25 2001 @@ -309,15 +309,27 @@ { if (parts[i].type == SC_TYPE_URL) { - err = string_append (out, ""); if (err != STATUS_OK) break; - err = string_appendn (out, src + x, parts[i].end - x); + err = string_appendn (out, src + x, parts[i].end - x - suffix); if (err != STATUS_OK) break; err = string_append (out, ""); + if (suffix) { + err = string_appendn(out,src + parts[i].end - 1,1); + if (err != STATUS_OK) break; + } } else /* type == SC_TYPE_EMAIL */ { diff -bru clearsilver-0.1/cgi/rfc2388.c clearsilver-0.2/cgi/rfc2388.c --- clearsilver-0.1/cgi/rfc2388.c Fri Jun 29 20:10:36 2001 +++ clearsilver-0.2/cgi/rfc2388.c Mon Aug 20 19:39:16 2001 @@ -171,6 +171,12 @@ } } cgiwrap_read (cgi->buf + ofs, cgi->buflen - ofs, &(cgi->readlen)); + cgi->data_read += cgi->readlen; + if (cgi->upload_cb) + { + if (cgi->upload_cb (cgi, cgi->data_read, cgi->data_expected)) + return nerr_raise (CGIUploadCancelled, "Upload Cancelled"); + } cgi->readlen += ofs; p = memchr (cgi->buf, '\n', cgi->readlen); if (!p) @@ -441,6 +447,7 @@ str.buf[str.len-1] = '\0'; str.len--; } + if (!(cgi->ignore_empty_form_vars && str.len == 0)) err = hdf_set_value (cgi->hdf, buf, str.buf); } } @@ -466,6 +473,14 @@ if (ct_hdr == NULL) return nerr_raise (NERR_ASSERT, "No content type header?"); + cgi->data_expected = l; + cgi->data_read = 0; + if (cgi->upload_cb) + { + if (cgi->upload_cb (cgi, cgi->data_read, cgi->data_expected)) + return nerr_raise (CGIUploadCancelled, "Upload Cancelled"); + } + err = _header_attr (ct_hdr, "boundary", &boundary); if (err) return nerr_pass (err); err = _find_boundary(cgi, boundary, &done); @@ -492,7 +507,7 @@ err = uListGet(cgi->files, n-1, (void **)&fp); if (err) { - nerr_ignore(err); + nerr_ignore(&err); return NULL; } return fp; diff -bru clearsilver-0.1/cs/test.hdf clearsilver-0.2/cs/test.hdf --- clearsilver-0.1/cs/test.hdf Wed Apr 25 22:58:37 2001 +++ clearsilver-0.2/cs/test.hdf Tue Aug 7 14:58:46 2001 @@ -54,3 +54,5 @@ 6 = 6 6.Abbr = Sun } + +Neg = -1 Only in clearsilver-0.2: man diff -bru clearsilver-0.1/python/neo_cgi.c clearsilver-0.2/python/neo_cgi.c --- clearsilver-0.1/python/neo_cgi.c Mon Aug 6 14:28:17 2001 +++ clearsilver-0.2/python/neo_cgi.c Mon Aug 20 19:39:17 2001 @@ -16,6 +16,7 @@ #include "util/neo_hdf.h" #include "cgi/cgi.h" #include "cgi/cgiwrap.h" +#include "cgi/date.h" #include "cgi/html.h" #include "p_neo_util.h" @@ -28,6 +29,9 @@ PyObject_HEAD CGI *cgi; PyObject *hdf; + PyObject *upload_cb; + PyObject *upload_rock; + int upload_error; } CGIObject; static PyObject *p_cgi_value_get_attr (CGIObject *self, char *name); @@ -87,16 +91,90 @@ { CGI *cgi = NULL; NEOERR *err; - char *file; - - if (!PyArg_ParseTuple(args, "s:CGI(file)", &file)) - return NULL; - err = cgi_init (&cgi, file); + err = cgi_init (&cgi, NULL); if (err) return p_neo_error (err); return p_cgi_to_object (cgi); } +static PyObject * p_cgi_parse (PyObject *self, PyObject *args) +{ + CGI *cgi = ((CGIObject *) self)->cgi; + CGIObject *p_cgi = (CGIObject *) self; + PyObject *rv; + NEOERR *err; + + p_cgi->upload_error = 0; + + err = cgi_parse (cgi); + if (err) return p_neo_error (err); + + if (p_cgi->upload_error) + { + p_cgi->upload_error = 0; + return NULL; + } + + rv = Py_None; + Py_INCREF(rv); + return rv; +} + +static int python_upload_cb (CGI *cgi, int nread, int expected) +{ + CGIObject *self = (CGIObject *)(cgi->data); + PyObject *cb, *rock; + PyObject *args, *result; + int r; + + /* fprintf(stderr, "upload_cb: %d/%d\n", nread, expected); */ + cb = self->upload_cb; + rock = self->upload_rock; + + if (cb == NULL) return 0; + args = Py_BuildValue("(Oii)", rock, nread, expected); + + if (args == NULL) { + self->upload_error = 1; + return 1; + } + result = PyEval_CallObject(cb, args); + Py_DECREF(args); + if (result != NULL && !PyInt_Check(result)) { + Py_DECREF(result); + result = NULL; + PyErr_SetString(PyExc_TypeError, + "upload_cb () returned non-integer"); + self->upload_error = 1; + return 1; + } + r = PyInt_AsLong(result); + Py_DECREF(result); + result = NULL; + return r; +} + +static PyObject * p_cgi_set_upload_cb (PyObject *self, PyObject *args) +{ + CGI *cgi = ((CGIObject *) self)->cgi; + CGIObject *p_cgi = (CGIObject *) self; + PyObject *rock, *cb; + + if (!PyArg_ParseTuple(args, "OO:setUploadCB(rock, func)", &rock, &cb)) + return NULL; + + cgi->data = self; + cgi->upload_cb = python_upload_cb; + p_cgi->upload_cb = cb; + p_cgi->upload_rock = rock; + p_cgi->upload_error = 0; + Py_INCREF(cb); + Py_INCREF(rock); + + Py_INCREF(Py_None); + return Py_None; +} + static PyObject * p_cgi_error (PyObject *self, PyObject *args) { CGI *cgi = ((CGIObject *) self)->cgi; @@ -238,6 +316,8 @@ {"debugInit", p_cgi_debug_init, METH_VARARGS, NULL}, {"wrapInit", p_cgi_wrap_init, METH_VARARGS, NULL}, #endif + {"parse", p_cgi_parse, METH_VARARGS, NULL}, + {"setUploadCB", p_cgi_set_upload_cb, METH_VARARGS, NULL}, {"error", p_cgi_error, METH_VARARGS, NULL}, {"display", p_cgi_display, METH_VARARGS, NULL}, {"redirect", p_cgi_redirect, METH_VARARGS, NULL}, @@ -673,6 +753,44 @@ } } +static PyObject * p_ignore (PyObject *self, PyObject *args) +{ + int i = 0; + + if (!PyArg_ParseTuple(args, "i:IgnoreEmptyFormVars(bool)", &i)) + return NULL; + + IgnoreEmptyFormVars = i; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * p_export_date (PyObject *self, PyObject *args) +{ + NEOERR *err; + PyObject *ho; + int i = 0; + char *prefix; + char *timezone; + HDF *hdf; + + if (!PyArg_ParseTuple(args, "Ossi:exportDate(hdf, prefix, timezone, time_t)", &ho, &prefix, &timezone, &i)) + return NULL; + + hdf = p_object_to_hdf (ho); + if (hdf == NULL) + { + PyErr_SetString(PyExc_TypeError, "First argument must be an HDF Object"); + return NULL; + } + + err = export_date_time_t (hdf, prefix, timezone, i); + if (err) return p_neo_error (err); + + Py_INCREF(Py_None); + return Py_None; +} + static PyMethodDef ModuleMethods[] = { {"CGI", p_cgi_init, METH_VARARGS, NULL}, @@ -680,6 +798,8 @@ {"htmlEscape", p_html_escape, METH_VARARGS, NULL}, {"text2html", p_text_html, METH_VARARGS, NULL}, {"cgiWrap", cgiwrap, METH_VARARGS, cgiwrap_doc}, + {"IgnoreEmptyFormVars", p_ignore, METH_VARARGS, NULL}, + {"exportDate", p_export_date, METH_VARARGS, NULL}, {NULL, NULL} }; diff -bru clearsilver-0.1/python/neo_util.c clearsilver-0.2/python/neo_util.c --- clearsilver-0.1/python/neo_util.c Mon Aug 6 14:28:17 2001 +++ clearsilver-0.2/python/neo_util.c Tue Aug 7 14:58:46 2001 @@ -330,13 +330,42 @@ string_init (&str); - err = hdf_dump_str (ho->data, NULL, &str); + err = hdf_dump_str (ho->data, NULL, 0, &str); if (err) return p_neo_error(err); rv = Py_BuildValue ("s", str.buf); string_clear (&str); return rv; } +static PyObject * p_hdf_write_string (PyObject *self, PyObject *args) +{ + HDFObject *ho = (HDFObject *)self; + PyObject *rv; + NEOERR *err; + char *s = NULL; + + err = hdf_write_string (ho->data, &s); + if (err) return p_neo_error(err); + rv = Py_BuildValue ("s", s); + if (s) free(s); + return rv; +} + +static PyObject * p_hdf_read_string (PyObject *self, PyObject *args) +{ + HDFObject *ho = (HDFObject *)self; + NEOERR *err; + char *s = NULL; + + if (!PyArg_ParseTuple(args, "s:readString(string)", &s)) + return NULL; + + err = hdf_read_string (ho->data, s); + if (err) return p_neo_error(err); + Py_INCREF (Py_None); + return Py_None; +} + static PyMethodDef HDFMethods[] = { {"getIntValue", p_hdf_get_int_value, METH_VARARGS, NULL}, @@ -350,6 +379,8 @@ {"setValue", p_hdf_set_value, METH_VARARGS, NULL}, {"readFile", p_hdf_read_file, METH_VARARGS, NULL}, {"writeFile", p_hdf_write_file, METH_VARARGS, NULL}, + {"readString", p_hdf_read_string, METH_VARARGS, NULL}, + {"writeString", p_hdf_write_string, METH_VARARGS, NULL}, {"removeTree", p_hdf_remove_tree, METH_VARARGS, NULL}, {"dump", p_hdf_dump, METH_VARARGS, NULL}, {NULL, NULL} diff -bru clearsilver-0.1/util/neo_hdf.c clearsilver-0.2/util/neo_hdf.c --- clearsilver-0.1/util/neo_hdf.c Mon Aug 6 14:28:17 2001 +++ clearsilver-0.2/util/neo_hdf.c Tue Aug 7 14:58:46 2001 @@ -574,41 +574,64 @@ return STATUS_OK; } -NEOERR* hdf_dump_str(HDF *hdf, char *prefix, STRING *str) +NEOERR* hdf_dump_str(HDF *hdf, char *prefix, int compact, STRING *str) { NEOERR *err; char *p; if (hdf->value) { - if (prefix) + if (prefix && !compact) { - err = string_appendf (str, "%s.%s = %s\n", prefix, hdf->name, hdf->value); + err = string_appendf (str, "%s.%s", prefix, hdf->name); } else { - err = string_appendf (str, "%s = %s\n", hdf->name, hdf->value); + err = string_append (str, hdf->name); + } + if (err) return nerr_pass (err); + if (strchr (hdf->value, '\n')) + { + if (hdf->value[strlen(hdf->value)-1] != '\n') + err = string_appendf (str, " << EOM\n%s\nEOM\n", hdf->value); + else + err = string_appendf (str, " << EOM\n%sEOM\n", hdf->value); + } + else + { + err = string_appendf (str, " = %s\n", hdf->value); } if (err) return nerr_pass (err); } if (hdf->child) { - if (prefix) + if (prefix && !compact) { p = (char *) malloc (strlen(hdf->name) + strlen(prefix) + 2); sprintf (p, "%s.%s", prefix, hdf->name); - err = hdf_dump_str (hdf->child, p, str); + err = hdf_dump_str (hdf->child, p, compact, str); free(p); } else { - err = hdf_dump_str (hdf->child, hdf->name, str); + if (compact && hdf->name) + { + err = string_appendf(str, "%s {\n", hdf->name); + if (err) return nerr_pass (err); + err = hdf_dump_str (hdf->child, hdf->name, compact, str); + if (err) return nerr_pass (err); + err = string_append(str, "}\n"); + } + else + { + err = hdf_dump_str (hdf->child, hdf->name, compact, str); + } } if (err) return nerr_pass (err); } if (hdf->next) { - err = hdf_dump_str (hdf->next, prefix, str); + err = hdf_dump_str (hdf->next, prefix, compact, str); if (err) return nerr_pass (err); } return STATUS_OK; @@ -671,8 +694,190 @@ return STATUS_OK; } +NEOERR *hdf_write_string (HDF *hdf, char **s) +{ + STRING str; + NEOERR *err; + + *s = NULL; + + string_init (&str); + + err = hdf_dump_str (hdf, NULL, 1, &str); + if (err) + { + string_clear (&str); + return nerr_pass(err); + } + + *s = str.buf; + + return STATUS_OK; +} + + /* HDF file looks like the following: */ #define SKIPWS(s) while (*s && isspace(*s)) s++; + +static int _copy_line (char **s, char *buf, size_t buf_len) +{ + int x = 0; + char *st = *s; + + while (*st && x < buf_len) + { + buf[x++] = *st; + if (*st++ == '\n') break; + } + buf[x] = '\0'; + *s = st; + + return x; +} + +static NEOERR* _hdf_read_string (HDF *hdf, char **str, int *line) +{ + NEOERR *err; + HDF *lower; + char buf[4096]; + char *s; + char *name, *value; + + while (_copy_line(str, buf, sizeof(buf)) != 0) + { + (*line)++; + s = buf; + SKIPWS(s); + if (!strncmp(s, "#include ", 9)) + { + return nerr_raise (NERR_PARSE, "[%d]: #include not supported in string parse", *line); + } + else if (s[0] == '#') + { + /* comment: pass */ + } + else if (s[0] == '}') /* up */ + { + s = neos_strip(s); + if (strcmp(s, "}")) + { + return nerr_raise(NERR_PARSE, + "[%d] Trailing garbage on line following }: %s", *line, + buf); + } + return STATUS_OK; + } + else if (s[0]) + { + /* Valid hdf name is [0-9a-zA-Z_.]+ */ + name = s; + while (*s && (isalnum(*s) || *s == '_' || *s == '.')) s++; + /* + if (*s != '\0') + { + *s++ = '\0'; + } + */ + SKIPWS(s); + + if (s[0] == '=') /* assignment */ + { + *s = '\0'; + name = neos_strip(name); + s++; + value = neos_strip(s); + err = hdf_set_value (hdf, name, value); + if (err != STATUS_OK) + return nerr_pass_ctx(err, "In String %d", *line); + } + else if (s[0] == ':') /* copy */ + { + *s = '\0'; + name = neos_strip(name); + s++; + value = neos_strip(s); + err = hdf_set_copy (hdf, name, value); + if (err != STATUS_OK) + return nerr_pass_ctx(err, "In string %d", *line); + } + else if (s[0] == '{') /* deeper */ + { + *s = '\0'; + name = neos_strip(name); + lower = hdf_get_obj (hdf, name); + if (lower == NULL) + { + err = hdf_set_value (hdf, name, NULL); + if (err != STATUS_OK) + return nerr_pass_ctx(err, "In string %d", *line); + lower = hdf_get_obj (hdf, name); + } + err = _hdf_read_string (lower, str, line); + if (err != STATUS_OK) + return nerr_pass_ctx(err, "In string %d", *line); + } + else if (s[0] == '<' && s[1] == '<') /* multi-line assignment */ + { + char *m; + int msize = 0; + int mmax = 128; + int l; + + *s = '\0'; + name = neos_strip(name); + s+=2; + value = neos_strip(s); + l = strlen(value); + if (l == 0) + return nerr_raise(NERR_PARSE, + "[%d] No multi-assignment terminator given: %s", *line, + buf); + m = (char *) malloc (mmax * sizeof(char)); + if (m == NULL) + return nerr_raise(NERR_NOMEM, + "[%d] Unable to allocate memory for multi-line assignment to %s", + *line, name); + while (_copy_line (str, m+msize, mmax-msize) != 0) + { + if (!strncmp(value, m+msize, l) && isspace(m[msize+l])) + { + m[msize] = '\0'; + break; + } + msize += strlen(m+msize); + if (msize + l + 10 > mmax) + { + mmax += 128; + m = (char *) realloc (m, mmax * sizeof(char)); + if (m == NULL) + return nerr_raise(NERR_NOMEM, + "[%d] Unable to allocate memory for multi-line assignment to %s: size=%d", + *line, name, mmax); + } + } + err = hdf_set_buf(hdf, name, m); + if (err != STATUS_OK) + { + free (m); + return nerr_pass_ctx(err, "In string %d", *line); + } + + } + else + { + return nerr_raise(NERR_PARSE, "[%d] Unable to parse line %s", + *line, buf); + } + } + } + return STATUS_OK; +} + +NEOERR * hdf_read_string (HDF *hdf, char *str) +{ + int line = 0; + return nerr_pass (_hdf_read_string (hdf, &str, &line)); +} static NEOERR* hdf_read_file_fp (HDF *hdf, FILE *fp, char *path, int *line) { diff -bru clearsilver-0.1/util/neo_hdf.h clearsilver-0.2/util/neo_hdf.h --- clearsilver-0.1/util/neo_hdf.h Mon Aug 6 14:28:17 2001 +++ clearsilver-0.2/util/neo_hdf.h Tue Aug 7 14:58:46 2001 @@ -50,9 +50,12 @@ NEOERR* hdf_read_file (HDF *hdf, char *path); NEOERR* hdf_write_file (HDF *hdf, char *path); +NEOERR* hdf_read_string (HDF *hdf, char *s); +NEOERR* hdf_write_string (HDF *hdf, char **s); + NEOERR* hdf_dump (HDF *hdf, char *prefix); NEOERR* hdf_dump_format (HDF *hdf, int lvl, FILE *fp); -NEOERR* hdf_dump_str(HDF *hdf, char *prefix, STRING *str); +NEOERR* hdf_dump_str(HDF *hdf, char *prefix, int compact, STRING *str); NEOERR* hdf_remove_tree (HDF *hdf, char *name); NEOERR* hdf_copy (HDF *dest_hdf, char *name, HDF *src);