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);