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:
parent
51fea526ac
commit
3b11963c76
3 changed files with 62 additions and 17 deletions
|
@ -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,6 +153,17 @@ 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 != ':') {
|
||||
|
@ -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;
|
||||
}
|
||||
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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue