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

190 lines
5.1 KiB
C
Raw Normal View History

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"
#include "mapping.h"
2011-04-25 20:59:53 +00:00
#include "mstrings.h"
#include "simulate.h"
#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) {
string_t *str = NULL;
vector_t *v;
mapping_t *map;
svalue_t *sv;
2011-04-25 20:59:53 +00:00
mp_int i;
psycString name, value, elem;
psycParseState state;
psycParseListState listState;
2011-04-25 20:59:53 +00:00
char oper;
int ret;
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;
}
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) {
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)));
}
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 {
ret = psyc_parse(&state, &oper, &name, &value);
2011-04-25 20:59:53 +00:00
switch (ret) {
case PSYC_PARSE_ROUTING:
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:
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);
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;
}
}
}
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);
// 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 */