2011-04-25 20:59:53 +00:00
|
|
|
/*------------------------------------------------------------------
|
|
|
|
* Glue for libpsyc.
|
|
|
|
*------------------------------------------------------------------
|
|
|
|
* func_spec for this:
|
|
|
|
*
|
|
|
|
mixed psyc_parse(int* | string);
|
|
|
|
string psyc_render(mapping, mapping, string, int* | string);
|
|
|
|
*
|
|
|
|
*------------------------------------------------------------------
|
|
|
|
* test LPC code:
|
|
|
|
|
|
|
|
// doesn't work with (int *) yet
|
|
|
|
mixed x = psyc_parse(":_context\ttest\n\n:_topic\ttesting\n_notice_test_libpsyc\nJust [_topic] libpsyc.\n|\n");
|
|
|
|
mixed y = psyc_render(([ "_context": "test" ]), ([ "_topic": "testing" ]), "_notice_test_libpsyc", "Just [_topic] libpsyc.");
|
|
|
|
debug_message(sprintf("libpsyc returned %O and %O\n", x, y));
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "array.h"
|
|
|
|
#include "interpret.h"
|
2011-04-26 00:42:01 +00:00
|
|
|
#include "mapping.h"
|
2011-04-25 20:59:53 +00:00
|
|
|
#include "mstrings.h"
|
|
|
|
#include "simulate.h"
|
2011-04-26 00:42:01 +00:00
|
|
|
#include "xalloc.h"
|
2011-04-25 20:59:53 +00:00
|
|
|
|
|
|
|
#include <psyc.h>
|
|
|
|
#include <psyc/parser.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#ifdef USE_PSYC
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
// string psyc_render(mapping, mapping, string, int* | string);
|
|
|
|
|
|
|
|
svalue_t *
|
|
|
|
f_psyc_render(svalue_t *sp) {
|
|
|
|
|
|
|
|
free_svalue(sp--);
|
|
|
|
free_svalue(sp--);
|
|
|
|
free_svalue(sp--);
|
|
|
|
free_svalue(sp--);
|
|
|
|
/*
|
|
|
|
printf("rendering... not yet\n");
|
|
|
|
string_t *out;
|
|
|
|
memsafe(
|
|
|
|
// out = alloc_mstring(5), 5,
|
|
|
|
out = new_mstring("PSYC"), 5,
|
|
|
|
"f_psyc_render test");
|
|
|
|
put_string(sp, out);
|
|
|
|
*/
|
|
|
|
put_c_string(++sp, "PSYC");
|
|
|
|
return sp;
|
|
|
|
|
|
|
|
} /* f_psyc_render */
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
// mixed psyc_parse(int* | string);
|
|
|
|
|
|
|
|
svalue_t *
|
|
|
|
f_psyc_parse (svalue_t *sp) {
|
2011-04-26 00:42:01 +00:00
|
|
|
string_t *str = NULL;
|
|
|
|
vector_t *v;
|
|
|
|
mapping_t *map;
|
|
|
|
svalue_t *sv;
|
2011-04-25 20:59:53 +00:00
|
|
|
mp_int i;
|
2011-04-26 00:42:01 +00:00
|
|
|
psycString name, value, elem;
|
|
|
|
psycParseState state;
|
|
|
|
psycParseListState listState;
|
2011-04-25 20:59:53 +00:00
|
|
|
char oper;
|
|
|
|
int ret;
|
|
|
|
|
2011-04-26 00:42:01 +00:00
|
|
|
psyc_initParseState(&state);
|
2011-04-25 20:59:53 +00:00
|
|
|
i = 0;
|
|
|
|
if (sp->type == T_POINTER) {
|
|
|
|
if ((i = (mp_int)VEC_SIZE(sp->u.vec)) > 32) {
|
|
|
|
errorf("Bad arg 1 to psyc_parse(): int[] too long (%"PRIdMPINT")\n"
|
|
|
|
, i);
|
|
|
|
/* NOTREACHED */
|
|
|
|
return sp;
|
|
|
|
}
|
2011-04-26 00:42:01 +00:00
|
|
|
printf("\npsyc_parse got %ld int* bytes... not supported yet\n", i);
|
2011-04-25 20:59:53 +00:00
|
|
|
}
|
|
|
|
else if (sp->type == T_STRING) {
|
2011-04-26 00:42:01 +00:00
|
|
|
printf("\npsyc_parse got a %d bytes long string...\n", mstrsize(sp->u.str));
|
|
|
|
psyc_nextParseBuffer(&state, psyc_newString(get_txt(sp->u.str),
|
2011-04-25 20:59:53 +00:00
|
|
|
mstrsize(sp->u.str)));
|
|
|
|
}
|
|
|
|
|
2011-04-26 00:42:01 +00:00
|
|
|
v = allocate_array(4);
|
|
|
|
if (!v) errorf("Out of memory for psyc_parse array.\n");
|
|
|
|
map = allocate_mapping( 0, 1 ); // empty mapping
|
|
|
|
if (!map) errorf("Out of memory for psyc_parse routing header.\n");
|
|
|
|
put_mapping(&v->item[0], map);
|
|
|
|
map = allocate_mapping( 0, 1 ); // empty mapping
|
|
|
|
if (!map) errorf("Out of memory for psyc_parse entity header.\n");
|
|
|
|
put_mapping(&v->item[1], map);
|
|
|
|
|
2011-04-25 20:59:53 +00:00
|
|
|
do {
|
2011-04-26 00:42:01 +00:00
|
|
|
ret = psyc_parse(&state, &oper, &name, &value);
|
2011-04-25 20:59:53 +00:00
|
|
|
switch (ret) {
|
|
|
|
case PSYC_PARSE_ROUTING:
|
2011-04-26 00:42:01 +00:00
|
|
|
if (oper != ':') {
|
|
|
|
puts("_failure_unsupported_state");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// not sure if the following code is good.. TODO
|
|
|
|
sv = pxalloc( sizeof( svalue_t ) );
|
|
|
|
put_string(sv, new_n_mstring(name.ptr, name.length));
|
|
|
|
sv = get_map_lvalue(v->item[0].u.map, sv);
|
|
|
|
put_string(sv, new_n_mstring(value.ptr, value.length));
|
|
|
|
break;
|
2011-04-25 20:59:53 +00:00
|
|
|
case PSYC_PARSE_ENTITY:
|
2011-04-26 00:42:01 +00:00
|
|
|
if (oper != ':') {
|
|
|
|
puts("_failure_unsupported_state");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// not sure if the following code is good.. TODO
|
|
|
|
sv = pxalloc( sizeof( svalue_t ) );
|
|
|
|
put_string(sv, new_n_mstring(name.ptr, name.length));
|
|
|
|
sv = get_map_lvalue(v->item[1].u.map, sv);
|
|
|
|
put_string(sv, new_n_mstring(value.ptr, value.length));
|
|
|
|
|
2011-04-25 20:59:53 +00:00
|
|
|
if (memcmp(name.ptr, "_list", 5) == 0)
|
|
|
|
{
|
|
|
|
write(1, ">>> LIST START\n", 15);
|
2011-04-26 00:42:01 +00:00
|
|
|
psyc_initParseListState(&listState);
|
|
|
|
psyc_nextParseListBuffer(&listState, value);
|
|
|
|
while ((ret = psyc_parseList(&listState, &name, &value, &elem)))
|
2011-04-25 20:59:53 +00:00
|
|
|
{
|
|
|
|
switch (ret)
|
|
|
|
{
|
|
|
|
case PSYC_PARSE_LIST_END:
|
|
|
|
case PSYC_PARSE_LIST_ELEM:
|
|
|
|
write(1, "|", 1);
|
|
|
|
write(1, elem.ptr, elem.length);
|
|
|
|
write(1, "\n", 1);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
errorf("Error while parsing PSYC list: %i\n", ret);
|
|
|
|
/* NOTREACHED */
|
|
|
|
return sp;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret == PSYC_PARSE_LIST_END)
|
|
|
|
{
|
|
|
|
write(1, ">>> LIST END\n", 13);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-04-26 00:42:01 +00:00
|
|
|
break;
|
|
|
|
case PSYC_PARSE_BODY:
|
|
|
|
if (str) errorf("Got two PSYC methods in the same packet!?\n");
|
|
|
|
// not sure if new_n_mstring is the right thing here.. TODO
|
|
|
|
str = new_n_mstring(name.ptr, name.length);
|
|
|
|
// make_tabled gets the shared string for the method
|
|
|
|
put_string(&v->item[2], make_tabled(str));
|
|
|
|
|
|
|
|
// not sure if new_n_mstring is the right thing here.. TODO
|
|
|
|
str = new_n_mstring(value.ptr, value.length);
|
|
|
|
put_string(&v->item[3], str);
|
|
|
|
|
2011-04-25 20:59:53 +00:00
|
|
|
break;
|
|
|
|
case PSYC_PARSE_COMPLETE:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
case PSYC_PARSE_INSUFFICIENT:
|
|
|
|
errorf("Insufficient PSYC data.\n");
|
|
|
|
/* NOTREACHED */
|
|
|
|
return sp;
|
|
|
|
default:
|
|
|
|
errorf("Error while parsing PSYC: %i\n", ret);
|
|
|
|
/* NOTREACHED */
|
|
|
|
return sp;
|
|
|
|
}
|
|
|
|
} while (ret);
|
|
|
|
|
|
|
|
free_svalue(sp);
|
2011-04-26 00:42:01 +00:00
|
|
|
// push_string(sp, str);
|
|
|
|
// put_number(sp, 4404); // push a test rc
|
|
|
|
put_array(sp, v);
|
2011-04-25 20:59:53 +00:00
|
|
|
return sp;
|
|
|
|
|
|
|
|
} /* f_psyc_parse */
|
|
|
|
|
|
|
|
#endif /* USE_PSYC */
|