wftk_value_isnull
and wftk_value_makenull
functions.
WFTK_EXPORT XML * wftk_value_find (void * session, XML * datasheet, const char * name) { if (!datasheet) return NULL; return xml_locf (datasheet, ".data[%s]", name); } WFTK_EXPORT XML * wftk_value_make (void * session, XML * datasheet, const char * name) { XML * data; if (!datasheet) return NULL; data = xml_locf (datasheet, ".data[%s]", name); if (!data) { data = xml_create ("data"); xml_set (data, "id", name); xml_append (datasheet, data); } return data; } WFTK_EXPORT const char * wftk_value_get (void * session, XML * datasheet, const char * name) { XML * data; WFTK_ADAPTOR * ad; if (!name) return ""; if (*name == '!') return _wftk_value_special (session, datasheet, name); if (strchr (name, ':')) { ad = wftk_get_adaptor (session, DATASTORE, name); if (!ad) return ""; data = wftk_call_adaptor (ad, "get", datasheet, name); wftk_free_adaptor (session, ad); return (xml_attrval (data, "value")); } data = wftk_value_find (session, datasheet, name); if (!data) return ""; if (!strcmp (xml_attrval (data, "null"), "yes")) return ""; return (xml_attrval (data, "value")); } WFTK_EXPORT int wftk_value_get_num (void * session, XML * datasheet, const char * name) { const char * value; if (!name) return 0; value = wftk_value_get (session, datasheet, name); if (!value) return 0; return (atoi (value)); } WFTK_EXPORT int wftk_value_isnull (void * session, XML * datasheet, const char * name) { XML * data; WFTK_ADAPTOR * ad; if (!name) return 1; /* Null name is, well, null. Logical, right? */ if (*name == '!') return 0; /* Special value is never null. Why? Because I say so. */ data = wftk_value_find (session, datasheet, name); if (!data) return 1; if (!strcmp (xml_attrval (data, "null"), "yes")) return 1; return 0; } WFTK_EXPORT int wftk_value_set (void * session, XML * datasheet, const char * name, const char * value) { XML * data; char * stuff; WFTK_ADAPTOR * ad; if (!name) return 0; if (*name == '!') return 0; /* Refuse to set special values. */ if (strchr (name, ':')) { ad = wftk_get_adaptor (session, DATASTORE, name); if (!ad) return 0; wftk_call_adaptor (ad, "set", datasheet, name, value); wftk_free_adaptor (session, ad); return 1; } data = wftk_value_make (session, datasheet, name); if (!data) return 0; if (strcmp (wftk_value_get (session, datasheet, name), value)) { wftk_enactment_write (session, datasheet, data, "was", wftk_value_get (session, datasheet, name)); xml_set (data, "value", value); } if (!strcmp (xml_attrval (data, "null"), "yes")) xml_set (data, "null", ""); /* 07/22/01 - implementing data aliasing (local cache of remote data) with write-though. */ if (*xml_attrval (data, "storage")) { ad = wftk_get_adaptor (session, DATASTORE, xml_attrval (data, "storage")); if (ad) { wftk_call_adaptor (ad, "store", data); wftk_free_adaptor (session, ad); } } return 1; } WFTK_EXPORT int wftk_value_set_num (void * session, XML * datasheet, const char * name, int value) { XML * data; WFTK_ADAPTOR * ad; char valbuf[sizeof(int) * 3 + 1]; if (!name) return 0; if (*name == '!') return 0; sprintf (valbuf, "%d", value); return (wftk_value_set (session, datasheet, name, valbuf)); } WFTK_EXPORT int wftk_value_makenull (void * session, XML * datasheet, const char * name) { XML * data; WFTK_ADAPTOR * ad; if (!name) return 0; if (*name == '!') return 0; /* Refuse to set special values. */ if (strchr (name, ':')) { ad = wftk_get_adaptor (session, DATASTORE, name); if (!ad) return 0; wftk_call_adaptor (ad, "makenull", datasheet, name); wftk_free_adaptor (session, ad); return 1; } data = wftk_value_make (session, datasheet, name); if (!data) return 0; wftk_enactment_write (session, datasheet, data, "was", wftk_value_get (session, datasheet, name)); xml_set (data, "null", "yes"); return 1; } |
sprintf
-like affair, which
takes a string and replaces named values in it which are marked like ${this}
. Later we'll need boolean
expressions and stuff, and that will also probably fall into this value area.
July 18, 2001: Finally got around to building a version of the interpreter which builds
its value as it goes (via malloc, or more specifically, via XMLAPI's xml_attrcat). This resolves
a lot of the fixed-buffer issues I had with the earlier code.
wftk_value_interpret
returns the number of bytes it copied to the buffer.wftk_value_interpreta
returns a new buffer. You're on your own for deallocation.
WFTK_EXPORT int wftk_value_interpret (void * session, XML * datasheet, const char * spec, char * buffer, int bufsize) { int count = 0; const char *value; char namebuf[256]; int i; bufsize--; /* Leave room for the null. */ while (*spec) { if (spec[0] == '$' && spec[1] == '{') { i = 0; spec += 2; while (*spec && *spec != '}' && i < sizeof(namebuf) - 1) { namebuf[i++] = *spec++; } if (*spec == '}') spec++; namebuf[i] = '\0'; value = wftk_value_get (session, datasheet, namebuf); while (*value && bufsize) { *buffer++ = *value++; count++; bufsize--; } } else { *buffer++ = *spec++; count++; bufsize--; } if (!bufsize) break; } *buffer = '\0'; return count; } WFTK_EXPORT char * wftk_value_interpreta (void * session, XML * datasheet, const char * spec) { int count = 0; char *value; char * mark; char namebuf[256]; int len; int i; XML * val; mark = strstr (spec, "${"); if (!mark) return strdup (spec); /* Easy case! No interpretation! */ val = xml_create ("value"); xml_set (val, "value", ""); while (mark) { xml_attrncat (val, "value", spec, mark - spec); spec = mark + 2; mark = strchr (spec, '}'); if (mark) { len = mark - spec; } else { len = strlen (spec); } if (len > sizeof (namebuf) - 1) len = sizeof (namebuf) - 1; xml_attrcat (val, "value", wftk_value_get (session, datasheet, namebuf)); if (mark) { spec = mark + 1; mark = strstr (spec, "${"); } } value = strdup (xml_attrval (val, "value")); xml_free (val); return value; } |
const char * _wftk_value_special (void * session, XML * datasheet, const char * name) { struct tm * timeptr; time_t julian; static char value[64]; /* Boy, this is dangerous. TODO: there's gotta be a better way. */ if (!strcmp (name, "!now")) { time (&julian); timeptr = localtime (&julian); sprintf (value, "%04d-%02d-%02d %02d:%02d:%02d", timeptr->tm_year + 1900, timeptr->tm_mon + 1, timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); return (value); } return (""); } |
WFTK_EXPORT int wftk_value_settype (void * session, XML * datasheet, const char * name, const char * type) { XML * data; WFTK_ADAPTOR * ad; if (!name) return 0; if (*name == '!') return 0; /* Refuse to set special values. */ if (strchr (name, ':')) return 0; /* Can't set types for alternate stores -- the answer will be aliases, later. */ data = wftk_value_make (session, datasheet, name); if (!data) return 0; xml_set (data, "type", type); return 1; } WFTK_EXPORT int wftk_value_define (void * session, XML * datasheet, const char * name, const char * storage) { XML * data; data = wftk_value_make (session, datasheet, name); if (data) { xml_set (data, "storage", storage); } } |
wftk_value_calc
just runs wftk_value_interpret
on its incoming value and sets the named value accordingly.
WFTK_EXPORT int wftk_value_calc (void * session, XML * datasheet, const char * name, const char * value) { return 0; } |
WFTK_EXPORT XML * wftk_value_html (void * session, XML * datasheet, const char * name) { XML * field; XML * data; WFTK_ADAPTOR * ad; if (!name) return 0; if (*name == '!') return (xml_createtext (_wftk_value_special (session, datasheet, name))); if (strchr (name, ':')) { ad = wftk_get_adaptor (session, DATASTORE, name); if (!ad) return 0; data = wftk_call_adaptor (ad, "get", datasheet, name); wftk_free_adaptor (session, ad); field = xml_create ("input"); xml_set (field, "name", name); xml_set (field, "value", xml_attrval (data, "value")); xml_delete (data); return (field); } data = wftk_value_find (session, datasheet, name); if (!data) { field = xml_create ("input"); xml_set (field, "name", name); xml_set (field, "value", ""); return (field); } if (*xml_attrval (data, "type")) { ad = wftk_get_adaptor (session, DATATYPE, xml_attrval (data, "type")); if (ad) { field = wftk_call_adaptor (ad, "html", datasheet, data); wftk_free_adaptor (session, ad); return (field); } } field = xml_create ("input"); xml_set (field, "name", name); if (*xml_attrval (data, "size")) { xml_set (field, "size", xml_attrval (data, "size")); } if (!strcmp (xml_attrval (data, "null"), "yes")) { xml_set (field, "value", ""); } else { xml_set (field, "value", wftk_value_get (session, datasheet, name)); } return (field); } WFTK_EXPORT XML * wftk_value_htmlblank (void * session, XML * datasheet, const char * name) { XML * field; XML * data; WFTK_ADAPTOR * ad; if (!name) return 0; if (*name == '!') return (xml_createtext (_wftk_value_special (session, datasheet, name))); if (strchr (name, ':')) { field = xml_create ("input"); xml_set (field, "name", name); xml_set (field, "value", ""); return (field); } data = wftk_value_find (session, datasheet, name); if (!data) { field = xml_create ("input"); xml_set (field, "name", name); xml_set (field, "value", ""); return (field); } if (*xml_attrval (data, "type")) { ad = wftk_get_adaptor (session, DATATYPE, xml_attrval (data, "type")); if (ad) { field = wftk_call_adaptor (ad, "htmlblank", datasheet, data); wftk_free_adaptor (session, ad); return (field); } } field = xml_create ("input"); xml_set (field, "name", name); if (*xml_attrval (data, "size")) { xml_set (field, "size", xml_attrval (data, "size")); } xml_set (field, "value", ""); return (field); } |
WFTK_EXPORT int wftk_value_list (void * session, XML * datasheet, XML * list) { int counter = 0; XML * pointer = xml_firstelem (datasheet); XML * value; if (!list) return 0; while (pointer) { if (xml_is (pointer, "data")) { counter++; value = xml_create ("data"); xml_set (value, "id", xml_attrval (pointer, "id")); xml_set (value, "value", wftk_value_get (session, datasheet, xml_attrval (pointer, "id"))); /* OK, not the most efficient method..*/ xml_set (value, "type", xml_attrval (pointer, "type")); xml_append (list, value); } pointer = xml_nextelem (pointer); } xml_setnum (list, "count", counter); return counter; } WFTK_EXPORT XML * wftk_value_info (void * session, XML * datasheet, const char * name) { return 0; } |
This code and documentation are released under the terms of the GNU license. They are additionally copyright (c) 2000, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. |