1
0
Fork 0
mirror of git://git.psyced.org/git/psyclpc synced 2024-08-15 03:20:16 +00:00

pkg-psyc: parse date & other numeric types, store oper in header mapping

This commit is contained in:
Gabor Adam Toth 2011-05-20 10:36:18 +02:00
parent 1d35e854e3
commit 773c8b6d0d
2 changed files with 133 additions and 84 deletions

View file

@ -8,30 +8,39 @@ string s, s2;
create() { create() {
mixed p, r; mixed p, r;
s = ":_context\ttest\n\n:_topic\ttesting\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
s = "=_context\ttest\n\n:_topic\ttesting\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
psyc_parse(s+s+s); psyc_parse(s+s+s);
psyc_parse(":_context\ttest\n\n:_topic\ttest"); psyc_parse("=_context\ttest\n\n:_topic\ttest");
psyc_parse("ing\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n"); psyc_parse("ing\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n");
p = ({ ([ "_context": "test" ]), ([ "_topic": "testing" ]), p = ({ ([ "_context": "test"; '=' ]), ([ "_topic": "testing" ]),
"_notice_test_libpsyc", "Just [_topic] libpsyc." }); "_notice_test_libpsyc", "Just [_topic] libpsyc." });
r = psyc_render(p); r = psyc_render(p);
debug_message(sprintf("rendering test:\n%s\n", r)); debug_message(sprintf(">> psyc_render returned:\n%s\n", r));
if (r != s) raise_error("FAIL\n"); if (r != s) raise_error(sprintf(">> FAIL, expected:\n%s\n", s));
s = ":_context\ttest\n\n:_list_foo\t|foo|bar|baz\n:_list_bar\t\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n"; s = "=_context\ttest\n\n:_time_foo\t59\n:_time_bar\t-41\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
s2 = ":_context\ttest\n\n:_list_bar\t\n:_list_foo\t|foo|bar|baz\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n"; s2 = "=_context\ttest\n\n:_time_bar\t-41\n:_time_foo\t59\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
psyc_parse(s); psyc_parse(s);
p = ({ ([ "_context": "test" ]), s = "=_context\ttest\n\n:_date_foo\t59\n:_date_bar\t-41\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
s2 = "=_context\ttest\n\n:_date_bar\t-41\n:_date_foo\t59\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
psyc_parse(s);
s = "=_context\ttest\n\n:_list_foo\t|foo|bar|baz\n:_list_bar\t\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
s2 = "=_context\ttest\n\n:_list_bar\t\n:_list_foo\t|foo|bar|baz\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n";
psyc_parse(s);
p = ({ ([ "_context": "test"; '=' ]),
([ "_list_foo": ({ "foo", "bar", "baz" }), "_list_bar": ({}) ]), ([ "_list_foo": ({ "foo", "bar", "baz" }), "_list_bar": ({}) ]),
"_notice_test_libpsyc", "Just [_topic] libpsyc." }); "_notice_test_libpsyc", "Just [_topic] libpsyc." });
r = psyc_render(p); r = psyc_render(p);
debug_message(sprintf("list rendering test:\n%s\n", r)); debug_message(sprintf(">> psyc_render returned:\n%s\n", r));
if (r != s) raise_error("FAIL\n"); if (r != s) raise_error(sprintf(">> FAIL, expected:\n%s\n", s));
debug_message(sprintf(">> SUCCESS\n")); debug_message(sprintf(">> SUCCESS\n"));
} }
@ -41,7 +50,7 @@ psyc_dispatch(mixed p) {
mixed r = psyc_render(p); mixed r = psyc_render(p);
debug_message(sprintf(">> psyc_render returned:\n%s", r)); debug_message(sprintf(">> psyc_render returned:\n%s", r));
if (r != s && r != s2) raise_error("FAIL\n"); if (r != s && r != s2) raise_error(sprintf(">> FAIL, expected:\n%s- or -\n%s\n", s, s2));
} }
*/ */
@ -70,25 +79,42 @@ psyc_dispatch(mixed p) {
void void
fill_header_from_mapping (svalue_t *key, svalue_t *val, void *extra) { fill_header_from_mapping (svalue_t *key, svalue_t *val, void *extra) {
psyc_modifier_t *m = extra; psyc_modifier_t *m = extra;
char *name, *value; char oper;
char *name, *value, buf[32];
size_t namelen, valuelen, i; size_t namelen, valuelen, i;
uint8_t type;
if (key->type != T_STRING) if (key->type != T_STRING)
errorf("fill_header_from_mapping: key type %d not supported\n", key->type); errorf("fill_header_from_mapping: key type %d not supported\n", key->type);
name = get_txt(key->u.str); name = get_txt(key->u.str);
namelen = mstrsize(key->u.str); namelen = mstrsize(key->u.str);
type = psyc_getVarType2(name, namelen);
if (m->num_values > 1)
oper = val[1].u.number;
else
oper = C_GLYPH_OPERATOR_SET;
if (val->type == T_STRING) { if (val->type == T_STRING) {
value = get_txt(val->u.str); value = get_txt(val->u.str);
valuelen = mstrsize(val->u.str); valuelen = mstrsize(val->u.str);
} else if (val->type == T_NUMBER) {
if (type == PSYC_TYPE_DATE)
snprintf(buf, 32, "%ld", val->u.number - PSYC_EPOCH);
else
snprintf(buf, 32, "%ld", val->u.number);
valuelen = strlen(buf);
value = pxalloc(valuelen);
if (!value) errorf("Out of memory in fill_header_from_mapping for number\n");
memcpy(value, buf, valuelen);
} else if (val->type == T_POINTER) { } else if (val->type == T_POINTER) {
psycList list; psycList list;
psycString *elems = NULL; psycString *elems = NULL;
if (VEC_SIZE(val->u.vec)) { if (VEC_SIZE(val->u.vec)) {
elems = pxalloc(sizeof(psycString) * VEC_SIZE(val->u.vec)); elems = pxalloc(sizeof(psycString) * VEC_SIZE(val->u.vec));
if (!elems) errorf("Out of memory in fill_header_from_mapping for elems"); if (!elems) errorf("Out of memory in fill_header_from_mapping for elems\n");
for (i = 0; i < VEC_SIZE(val->u.vec); i++) { for (i = 0; i < VEC_SIZE(val->u.vec); i++) {
if (val->u.vec->item[i].type == T_STRING) if (val->u.vec->item[i].type == T_STRING)
@ -101,14 +127,14 @@ fill_header_from_mapping (svalue_t *key, svalue_t *val, void *extra) {
list = psyc_newList(elems, VEC_SIZE(val->u.vec), PSYC_LIST_CHECK_LENGTH); list = psyc_newList(elems, VEC_SIZE(val->u.vec), PSYC_LIST_CHECK_LENGTH);
valuelen = list.length; valuelen = list.length;
value = pxalloc(valuelen); value = pxalloc(valuelen);
if (!value) errorf("Out of memory in fill_header_from_mapping for list value"); if (!value) errorf("Out of memory in fill_header_from_mapping for list value\n");
psyc_renderList(&list, value, valuelen); psyc_renderList(&list, value, valuelen);
} else } else
errorf("fill_header_from_mapping: value type %d not supported\n", key->type); errorf("fill_header_from_mapping: value type %d not supported\n", key->type);
m->header->modifiers[m->header->lines++] = m->header->modifiers[m->header->lines++] =
psyc_newModifier2(m->oper, name, namelen, value, valuelen, m->flag); psyc_newModifier2(oper, name, namelen, value, valuelen, m->flag);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -143,11 +169,11 @@ f_psyc_render(svalue_t *sp) {
if (i == PACKET_ROUTING) if (i == PACKET_ROUTING)
walk_mapping(map, &fill_header_from_mapping, walk_mapping(map, &fill_header_from_mapping,
&(psyc_modifier_t) {&headers[i], C_GLYPH_OPERATOR_SET, &(psyc_modifier_t) {&headers[i], map->num_values,
PSYC_MODIFIER_ROUTING}); PSYC_MODIFIER_ROUTING});
else else
walk_mapping(map, &fill_header_from_mapping, walk_mapping(map, &fill_header_from_mapping,
&(psyc_modifier_t) {&headers[i], C_GLYPH_OPERATOR_SET, &(psyc_modifier_t) {&headers[i], map->num_values,
PSYC_MODIFIER_CHECK_LENGTH}); PSYC_MODIFIER_CHECK_LENGTH});
} }
} }
@ -209,8 +235,9 @@ f_psyc_parse (svalue_t *sp) {
char oper = 0; char oper = 0;
psycString name = {0,0}, value = {0,0}, elems[MAX_LIST_SIZE], elem; psycString name = {0,0}, value = {0,0}, elems[MAX_LIST_SIZE], elem;
psycParseListState listState; psycParseListState listState;
int ret, retl; int ret, retl, type = -1;
size_t size, i; size_t size, i;
time_t t;
string_t *callback = mstring_new_string("psyc_dispatch"); string_t *callback = mstring_new_string("psyc_dispatch");
assert_shadow_sent(current_object); assert_shadow_sent(current_object);
@ -260,10 +287,10 @@ f_psyc_parse (svalue_t *sp) {
if (!state->packet) errorf("Out of memory for psyc_parse array.\n"); if (!state->packet) errorf("Out of memory for psyc_parse array.\n");
v = state->packet; v = state->packet;
map = allocate_mapping(0, 1); // empty mapping map = allocate_mapping(0, 2); // empty mapping
if (!map) errorf("Out of memory for psyc_parse routing header.\n"); if (!map) errorf("Out of memory for psyc_parse routing header.\n");
put_mapping(&v->item[PACKET_ROUTING], map); put_mapping(&v->item[PACKET_ROUTING], map);
map = allocate_mapping(0, 1); // empty mapping map = allocate_mapping(0, 2); // empty mapping
if (!map) errorf("Out of memory for psyc_parse entity header.\n"); if (!map) errorf("Out of memory for psyc_parse entity header.\n");
put_mapping(&v->item[PACKET_ENTITY], map); put_mapping(&v->item[PACKET_ENTITY], map);
} }
@ -302,15 +329,13 @@ f_psyc_parse (svalue_t *sp) {
switch (ret) { switch (ret) {
case PSYC_PARSE_ROUTING: case PSYC_PARSE_ROUTING:
if (oper != ':') {
puts("_failure_unsupported_state");
continue;
}
sv = pxalloc(sizeof(svalue_t)); sv = pxalloc(sizeof(svalue_t));
// new_n_tabled fetches a reference of a probably existing // new_n_tabled fetches a reference of a probably existing
// shared string // shared string
put_string(sv, new_n_tabled(name.ptr, name.length)); put_string(sv, new_n_tabled(name.ptr, name.length));
sv = get_map_lvalue(v->item[PACKET_ROUTING].u.map, sv); sv = get_map_lvalue(v->item[PACKET_ROUTING].u.map, sv);
put_number(&sv[1], oper);
// strings are capable of containing 0 so we can do this // strings are capable of containing 0 so we can do this
// for binary data too. let's use a tabled string even // for binary data too. let's use a tabled string even
// for values of routing variables as they repeat a lot // for values of routing variables as they repeat a lot
@ -322,31 +347,91 @@ f_psyc_parse (svalue_t *sp) {
break; break;
case PSYC_PARSE_ENTITY_END: case PSYC_PARSE_ENTITY_END:
if (oper != ':') {
puts("_failure_unsupported_state");
continue;
}
sv = pxalloc(sizeof(svalue_t));
put_string(sv, make_tabled(state->name));
sv = get_map_lvalue(v->item[PACKET_ENTITY].u.map, sv);
put_string(sv, state->value);
break;
case PSYC_PARSE_ENTITY: case PSYC_PARSE_ENTITY:
if (oper != ':') { sv = pxalloc(sizeof(svalue_t));
puts("_failure_unsupported_state");
continue; if (ret == PSYC_PARSE_ENTITY)
put_string(sv, new_n_tabled(name.ptr, name.length));
else // PSYC_PARSE_ENTITY_END
put_string(sv, make_tabled(state->name));
sv = get_map_lvalue(v->item[PACKET_ENTITY].u.map, sv);
put_number(&sv[1], oper);
type = psyc_getVarType(&name);
switch (type) {
case PSYC_TYPE_DATE: // number + PSYC_EPOCH
if (psyc_parseDate(&value, &t))
put_number(sv, t);
else
errorf("Error while parsing _date value\n"); // TODO: _error_invalid_value?
break;
case PSYC_TYPE_TIME: // number
if (psyc_parseTime(&value, &t))
put_number(sv, t);
else
errorf("Error while parsing _time value\n");
break;
case PSYC_TYPE_AMOUNT: // number
if (psyc_parseNumber(&value, &t))
put_number(sv, t);
else
errorf("Error while parsing _amount value\n");
break;
case PSYC_TYPE_DEGREE: // first digit
if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '9')
put_number(sv, value.ptr[0] - '0');
else
errorf("Error while parsing _degree value\n");
break;
case PSYC_TYPE_FLAG: // 0 or 1
if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '1')
put_number(sv, value.ptr[0] - '0');
else
errorf("Error while parsing _flag value\n");
break;
case PSYC_TYPE_LIST: // array
size = 0;
if (value.length) {
psyc_initParseListState(&listState);
psyc_setParseListBuffer(&listState, value);
elem = (psycString){0, 0};
do {
retl = psyc_parseList(&listState, &elem);
switch (retl) {
case PSYC_PARSE_LIST_END:
retl = 0;
case PSYC_PARSE_LIST_ELEM:
if (size >= MAX_LIST_SIZE) {
errorf("Error while parsing PSYC list: max list size reached\n");
/* NOTREACHED */
return sp;
}
elems[size++] = elem;
break;
default:
errorf("Error while parsing PSYC list: %i\n", retl);
/* NOTREACHED */
return sp;
}
} while (retl > 0);
} }
sv = pxalloc(sizeof(svalue_t)); list = allocate_array(size);
put_string(sv, new_n_tabled(name.ptr, name.length)); for (i = 0; i < size; i++)
sv = get_map_lvalue(v->item[PACKET_ENTITY].u.map, sv); put_string(&list->item[i], new_n_tabled(elems[i].ptr, elems[i].length));
put_array(sv, list);
break;
default: // string
if (ret == PSYC_PARSE_ENTITY)
// is it good to put entity variable values into the // is it good to put entity variable values into the
// shared string table? probably yes.. but it's a guess // shared string table? probably yes.. but it's a guess
//t_string(sv, new_n_mstring(value.ptr, value.length)); //t_string(sv, new_n_mstring(value.ptr, value.length));
put_string(sv, new_n_tabled(value.ptr, value.length)); put_string(sv, new_n_tabled(value.ptr, value.length));
else // PSYC_PARSE_ENTITY_END
put_string(sv, state->value);
}
break; break;
case PSYC_PARSE_BODY_START: case PSYC_PARSE_BODY_START:
@ -401,42 +486,6 @@ f_psyc_parse (svalue_t *sp) {
state->oper = 0; state->oper = 0;
state->name = NULL; state->name = NULL;
state->value = NULL; state->value = NULL;
if (ret == PSYC_PARSE_BODY_END)
break;
case PSYC_PARSE_ENTITY:
if (psyc_isListVar(&name)) {
size = 0;
if (value.length) {
psyc_initParseListState(&listState);
psyc_setParseListBuffer(&listState, value);
elem = (psycString){0, 0};
do {
retl = psyc_parseList(&listState, &elem);
switch (retl) {
case PSYC_PARSE_LIST_END:
retl = 0;
case PSYC_PARSE_LIST_ELEM:
if (size >= MAX_LIST_SIZE) {
errorf("Error while parsing PSYC list: max list size reached\n");
/* NOTREACHED */
return sp;
}
elems[size++] = elem;
break;
default:
errorf("Error while parsing PSYC list: %i\n", retl);
/* NOTREACHED */
return sp;
}
} while (retl > 0);
}
list = allocate_array(size);
for (i = 0; i < size; i++)
put_string(&list->item[i], new_n_tabled(elems[i].ptr, elems[i].length));
put_array(sv, list);
}
} }
} while (ret); } while (ret);

View file

@ -34,7 +34,7 @@ typedef struct psyc_state_s {
typedef struct psyc_modifier_s { typedef struct psyc_modifier_s {
psycHeader *header; psycHeader *header;
char oper; p_int num_values;
psycModifierFlag flag; psycModifierFlag flag;
} psyc_modifier_t; } psyc_modifier_t;