#include #include #include #include "lkb-protocol.h" static void add_xtext_item(lui_xtext *text, int type, void *item); int parse_xtext(char **INPUT, int *TYPE, void **DATA) { int item_type; void *item_ptr; char *p = *INPUT; char c; lui_xtext *text=0; *DATA = 0; //debug("parsing xtext at %s\n", *INPUT); c = tokenize(&p); if(c!='[') { fprintf(stderr, "Expected '[' opening xtext structure\n"); goto error_text; } text = calloc(sizeof(struct lui_xtext), 1); text->count = 0; text->commands = 0; do { c = tokenize(&p); if(c==' ')continue; if(c==']')break; p--; parse_protocol(&p, &item_type, (void**)&item_ptr); if(item_type != type_string && item_type != type_symbol && item_type != type_xtext && item_type != type_int) { fprintf(stderr, "invalid xtext item (type %d)\n", item_type); goto error_text; } add_xtext_item(text, item_type, item_ptr); } while(*p); if(1) *TYPE = type_xtext; else { error_text: *TYPE = -1; if(text)free(text); text = 0; } *INPUT=p; *(lui_xtext**)DATA = text; return 0; } static void add_xtext_item(lui_xtext *text, int type, void *item) { lui_xtext *subtext; #define PLUS(n) do { text->count+=(n); text->commands = \ realloc(text->commands, sizeof(struct lui_xtext_command)*text->count); \ bzero(text->commands+text->count-(n), sizeof(struct lui_xtext_command)*(n)); } while(0) #define SET(op, str) do { text->commands[text->count-1].opcode = op; \ text->commands[text->count-1].string = str; } while(0) switch(type) { case type_symbol: //printf("xtext symbol `%s'\n", (char*)item); PLUS(1); if(!strcmp((char*)item, "N"))SET(lxt_newline, NULL); else if(!strcmp((char*)item, "NEWLINE"))SET(lxt_newline, NULL); else if(!strcmp((char*)item, "T"))SET(lxt_tab, NULL); else if(!strcmp((char*)item, "TAB"))SET(lxt_tab, NULL); else if(!strcmp((char*)item, "TABULATOR"))SET(lxt_tab, NULL); else if(!strcmp((char*)item, "WRAP"))SET(lxt_wrap, NULL); else { fprintf(stderr, "unknown xtext symbol `%s'\n", (char*)item); text->count--; } break; case type_string: //printf("xtext string \"%s\"\n", (char*)item); PLUS(1); SET(lxt_string, item); break; case type_int: PLUS(1); SET(lxt_set_id, item); break; case type_xtext: subtext = item; //printf("xtext subtext [%d commands]\n", subtext->count); PLUS(1); SET(lxt_push, NULL); PLUS(subtext->count); memcpy(text->commands+text->count-subtext->count, subtext->commands, sizeof(struct lui_xtext_command)*subtext->count); PLUS(1); SET(lxt_pop, NULL); break; } } int parse_xtext_menu(char **INPUT, int *TYPE, void **DATA) { int type, id; void *data; char *show, *send; char *p = *INPUT; char c; struct lui_xtext_menu *menu=NULL; *DATA = NULL; //debug("parsing xtext-menu at %s\n", *INPUT); c = tokenize(&p); if(c!='[') { fprintf(stderr, "Expected '[' opening xtext-menu structure\n"); goto error_menu; } menu = calloc(sizeof(struct lui_xtext_menu), 1); menu->nitems = menu->nids = 0; menu->show = menu->send = NULL; menu->ids = NULL; do { c = tokenize(&p); if(c==' ')continue; if(c==']')break; p--; parse_protocol(&p, &type, (void**)&data); if(type == type_string) { show = data; c = tokenize(&p); while(c==' ')c = tokenize(&p); if(c==']')break; p--; parse_protocol(&p, &type, (void**)&send); if(type != type_string) { fprintf(stderr, "invalid xtext-menu show-send pair (type %d)\n", type); goto error_menu; } menu->nitems++; menu->show = realloc(menu->show, sizeof(char*)*menu->nitems); menu->show[menu->nitems-1] = show; menu->send = realloc(menu->send, sizeof(char*)*menu->nitems); menu->send[menu->nitems-1] = send; } else if(type == type_int) { menu->nids++; menu->ids = realloc(menu->ids, sizeof(int)*menu->nids); menu->ids[menu->nids-1] = (int)(long)data; } else { fprintf(stderr, "invalid xtext-menu item (type %d)\n", type); goto error_menu; } } while(*p); if(1) *TYPE = type_xtext_menu; else { error_menu: *TYPE = -1; if(menu)free(menu); menu = NULL; } *INPUT=p; *(struct lui_xtext_menu**)DATA = menu; return 0; }