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

pkg-psyc: parser

This commit is contained in:
Gabor Adam Toth 2011-05-08 16:58:35 +02:00
parent 51fea526ac
commit 3b11963c76
3 changed files with 62 additions and 17 deletions

View file

@ -113,16 +113,24 @@ f_psyc_parse (svalue_t *sp) {
mapping_t *map;
svalue_t *sv;
mp_int i;
psycString name, value, elem;
psycParseState state;
char oper = 0;
psycString name = {0,0}, value = {0,0}, elem = {0,0};
psycParseListState listState;
char oper;
int ret;
psyc_initParseState(&state);
psycState *state = O_GET_PSYC_STATE(current_object);
if (!state) {
state = pxalloc(sizeof(psycState));
if (!state) errorf("Out of memory for psyc state struct.\n");
O_GET_PSYC_STATE(current_object) = state;
state->parser = pxalloc(sizeof(psycParseState));
if (!state->parser) errorf("Out of memory for psyc parse state struct.\n");
psyc_initParseState(state->parser);
}
i = 0;
if (sp->type == T_POINTER) {
printf("\npsyc_parse got %ld int* bytes... not supported yet\n", i);
errorf("\npsyc_parse got %ld int* bytes... not supported yet\n", i);
}
else if (sp->type == T_STRING) {
printf("\npsyc_parse got a %d bytes long string...\n", mstrsize(sp->u.str));
@ -130,8 +138,12 @@ f_psyc_parse (svalue_t *sp) {
mstrsize(sp->u.str)));
}
v = allocate_array(4);
if (!v) errorf("Out of memory for psyc_parse array.\n");
if (!state->packet) {
state->packet = allocate_array(4);
if (!state->packet) errorf("Out of memory for psyc_parse array.\n");
}
v = state->packet;
map = allocate_mapping( 0, 1 ); // empty mapping
if (!map) errorf("Out of memory for psyc_parse routing header.\n");
put_mapping(&v->item[PSYC_ROUTING], map);
@ -141,13 +153,24 @@ f_psyc_parse (svalue_t *sp) {
do {
ret = psyc_parse(&state, &oper, &name, &value);
switch (ret) {
case PSYC_PARSE_ENTITY_START: case PSYC_PARSE_BODY_START:
if ((len = psyc_getParseValueLength(state->parser)))
state->tmp = pxalloc(len);
case PSYC_PARSE_ENTITY_CONT: case PSYC_PARSE_BODY_CONT:
case PSYC_PARSE_ENTITY_END: case PSYC_PARSE_BODY_END:
memcpy(state->tmp + state->tmplen, value.ptr, value.length);
state->tmplen += value.length;
}
switch (ret) {
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
// shared string
put_string(sv, new_n_tabled(name.ptr, name.length));
@ -157,21 +180,27 @@ f_psyc_parse (svalue_t *sp) {
// for values of routing variables as they repeat a lot
put_string(sv, new_n_tabled(value.ptr, value.length));
break;
case PSYC_PARSE_ENTITY_START:
case PSYC_PARSE_ENTITY_CONT:
case PSYC_PARSE_ENTITY_END:
case PSYC_PARSE_ENTITY:
if (oper != ':') {
if (oper && oper != ':') {
puts("_failure_unsupported_state");
continue;
}
sv = pxalloc( sizeof( svalue_t ) );
put_string(sv, new_n_tabled(name.ptr, name.length));
sv = get_map_lvalue(v->item[PSYC_ENTITY].u.map, sv);
if (name.length) {
sv = pxalloc(sizeof(svalue_t));
put_string(sv, new_n_tabled(name.ptr, name.length));
sv = get_map_lvalue(v->item[PSYC_ENTITY].u.map, sv);
}
// is it good to put entity variable values into the
// shared string table? probably yes.. but it's a guess
//t_string(sv, new_n_mstring(value.ptr, value.length));
put_string(sv, new_n_tabled(value.ptr, value.length));
// list parsing not supported yet.. TODO
if (memcmp(name.ptr, "_list", 5) == 0)
if (name.length >= 5 && memcmp(name.ptr, "_list", 5) == 0)
{
write(1, ">>> LIST START\n", 15);
psyc_initParseListState(&listState);
@ -200,6 +229,9 @@ f_psyc_parse (svalue_t *sp) {
}
}
break;
case PSYC_PARSE_BODY_START:
case PSYC_PARSE_BODY_CONT:
case PSYC_PARSE_BODY_END:
case PSYC_PARSE_BODY:
if (str) errorf("Got two PSYC methods in the same packet!?\n");
// new_n_tabled gets the shared string for the method
@ -227,6 +259,7 @@ f_psyc_parse (svalue_t *sp) {
free_svalue(sp);
put_array(sp, v);
state->packet = 0;
return sp;
} /* f_psyc_parse */

View file

@ -12,9 +12,21 @@
# include <psyc/parser.h>
typedef struct {
psycParseState *parser;
vector_t *packet;
char *tmp;
size_t tmplen;
} psycState;
static inline void
psyc_free_parser (psycParseState *ps) {
/* if (ps) xfree((void *) ps); */
psyc_free_parser (psycState *ps) {
if (!ps)
return;
if (ps->state)
pxfree((void *) ps->state);
if (ps->packet)
free_array(ps->packet);
}
#endif

View file

@ -132,7 +132,7 @@ struct shadow_s
#endif
interactive_t *ip; /* the information for interactive objects */
#ifdef USE_PSYC
psycParseState *psyc_parser; /* in case this objects parses PSYC data */
psycState *psyc_state; /* in case this objects parses PSYC data */
#endif
};
@ -141,7 +141,7 @@ struct shadow_s
#define O_GET_SHADOW(ob) ((shadow_t *)(ob)->sent)
#define O_GET_INTERACTIVE(ob) (O_GET_SHADOW(ob)->ip)
#define O_GET_EDBUFFER(ob) (O_GET_SHADOW(ob)->ed_buffer)
#define O_GET_PSYC_PARSER(ob) (O_GET_SHADOW(ob)->psyc_parser)
#define O_GET_PSYC_STATE(ob) (O_GET_SHADOW(ob)->psyc_state)
/* Expand to an expression suitable to query or set the
* indicated attribute. No checks are performed.