#include #include #include #include #include #include #include #include "font-info.h" #include "file-dialogs.h" #include "lkb-tree.h" #include "lkb-avm.h" #include "lkb-chart.h" #include "lkb-protocol.h" #include "lui-genchart.h" extern FILE *logger; extern int gDone; extern int passive_mode; #define debug(...) fprintf(stderr, __VA_ARGS__); // easy abstraction points for the LKB <--> GUI interface #define lkb_print printf #define lkb_end_message() { printf(" "); fflush(stdout); } // convenience macro to send command/result and an end-of-message both // C99 standard variadic macros are slightly gross, but useful. #define lkb_send(...) { lkb_print(__VA_ARGS__); lkb_end_message(); } // convenience macro to send a numeric result code #define lkb_send_result(n) // no-op, since the protocol currently // does not use result codes void process_complete_command(char *com); void do_parameter(char *name, void *value, int vtype); void lkb_send_version() { lkb_send("version \"%s\"\n", YZLUI_VERSION_STRING); } void lkb_send_quit() { lkb_send("quit\n"); } void lkb_forget_tree(int id) { lkb_send("tree %d forget\n", id); } void lkb_forget_hierarchy(int id) { lkb_send("hierarchy %d forget\n", id); } void lkb_forget_avm(int id) { lkb_send("avm %d forget\n", id); } void lkb_forget_chart(int id) { lkb_send("chart %d forget\n", id); } void lkb_forget_text(int id) { lkb_send("text %d forget\n", id); } void lkb_send_unify(int avm1, char *path1, int avm2, char *path2) { lkb_send("unify %d [%s] %d [%s]\n", avm1, path1, avm2, path2); } void lkb_browse_tree(int tree_id, int avm_id, char *command) { lkb_send("browse %d %d %s\n", tree_id, avm_id, command); } void lkb_type_command(char *type, char *subcommand) { lkb_send("type %s %s\n", type, subcommand); } void lkb_compare_trees(int count, int *ids) { int i; if(count < 2)return; lkb_print("compare"); for(i=0;i0) { memmove(read_buffer, read_buffer+(i+1), rb_len); goto next_com; } } } if(len>0)goto again; return 0; } printk(char *format, ...) { va_list v, v2; va_start(v, format); va_copy(v2, v); int len = vsnprintf(NULL, 0, format, v); char *str=malloc(len+10); vsnprintf(str, len+8, format, v2); va_end(v); va_end(v2); console_add(str); } do_treebank(int session_id, int remaining_count, lui_list *tokens, lui_list *truth, lui_list *choices) { if(browse_treebank(session_id, remaining_count, tokens, truth, choices))lkb_send_result(-1); else lkb_send_result(0); } static int previous_space = 0; extern int default_collapse; extern char *current_path; // status of pending UPDATE meta-command int update_object_id = -1; // status of pending GROUP meta-command int group_count; // how many remaining in this group char *group_name; // what this GROUP's window title should be char *group_cmd; int group_window_id; int *group_ids; void **group_datas; char **group_names; int ngroup_els; void do_group(int id, int count, char *name) { group_window_id = id; group_count = count; group_name = name; group_cmd = 0; group_ids = 0; group_names = 0; group_datas = 0; ngroup_els = 0; } void add_group_arguments(int argc, void *argv[], int *argt) { assert(!strcmp(group_cmd, "TREE")); assert(argc==3); assert(argt[0]==type_int && argt[1]==type_tree && argt[2]==type_string); ngroup_els++; group_ids = realloc(group_ids, sizeof(int) * ngroup_els); group_names = realloc(group_names, sizeof(char*) * ngroup_els); group_datas = realloc(group_datas, sizeof(void*) * ngroup_els); group_ids[ngroup_els-1] = (int)(long)argv[0]; group_datas[ngroup_els-1] = argv[1]; group_names[ngroup_els-1] = argv[2]; } void display_group() { //printf("should display %d of `%s'\n ", ngroup_els, group_cmd); assert(!strcmp(group_cmd, "TREE")); browse_mtree(group_window_id, ngroup_els, group_ids, group_datas, group_names, group_name); group_cmd = 0; ngroup_els = 0; } void process_complete_command(char *com) { void **argv = 0; int *argt = 0, num; char *cmd, *arg1, *arg2; int rc, argc = 0; // log commands to a log file, if the log file is open if(logger) { fprintf(logger, "process_complete_command(): `%s'\n\n", com); fflush(logger); } previous_space = 1; // skip leading spaces do { argv = realloc(argv, sizeof(void*)*(argc+1)); argt = realloc(argt, sizeof(int)*(argc+1)); default_collapse = 0; current_path = 0; if(!parse_protocol(&com, &argt[argc], &argv[argc])) break; //debug("arg %d type %d data %p\n", argc, argt[argc], argv[argc]); argc++; } while(1);//argc < 16); if(argc==0)goto _ret; if(argt[0] == type_int) { if(argc>1)fprintf(stderr, "Warning: ignoring trailing parameters after result code\n"); num = (int)(long)argv[0]; //if(num != 0)debug("Result code: %d\n", num); //else debug("Success\n"); goto _ret; } else if(argt[0] != type_symbol) { fprintf(stderr, "Don't know how to process command with first argument not a symbol\n"); goto _ret; } cmd = argv[0]; //debug("command %s with %d args type %d %d val %s %s\n", cmd, argc-1, argt[1], argt[2], argv[1], argv[2]); if(group_count) { group_count--; if(group_cmd && strcmp(cmd, group_cmd)) { fprintf(stderr, "Inhomogeneous group (group type %s, command is %s)\n", group_cmd, cmd); goto _ret; } else if(!group_cmd && !strcmp(cmd, "TREE")) { group_cmd = "TREE"; } else if(!group_cmd) { fprintf(stderr, "Sorry, type `%s' is not supported for a group.\n", cmd); goto _ret; } // scoop up the command into the group add_group_arguments(argc-1, argv+1, argt+1); if(!group_count)display_group(); goto _ret; } if(0) {} else if(!strcmp(cmd, "TREE") && argc==4 && argt[1]==type_int && argt[2]==type_tree && argt[3]==type_string) do_browse_tree(argv[1], argv[2], argv[3]); else if(!strcmp(cmd, "AVM") && argc==4 && argt[1]==type_int && argt[2]==type_dag && argt[3]==type_string) do_browse_avm(argv[1], argv[2], argv[3]); else if(!strcmp(cmd, "AVM") && argc==5 && argt[1]==type_int && argt[2]==type_dag && argt[3]==type_string && argt[4]==type_list) do_browse_avm_failures(argv[1], argv[2], argv[3], argv[4]); else if(!strcmp(cmd, "CHART") && argc>=4 && argt[1]==type_int && argt[2]==type_int && argt[3]==type_string) { for(rc=4;rctype==type_string && argt[3]==type_list && ((lui_list*)argv[3])->type==type_genedge && argt[4]==type_string) do_browse_genchart(argv[1], argv[2], argv[3], argv[4]); else if(!strcmp(cmd, "TEXT") && argc>=4 && argt[1]==type_int && argt[2]==type_xtext && argt[argc-1]==type_string) { for(rc=3;rctype==type_hierarchy) do_browse_hierarchy((int)argv[1], argv[2], ((lui_list*)argv[3])->length, (struct lui_hierarchy**)((lui_list*)argv[3])->data); else if(!strcmp(cmd, "STATUS") && argc==2 && argt[1]==type_symbol) do_status(argv[1]); else if(!strcmp(cmd, "MESSAGE") && argc==2 && argt[1]==type_string) do_message(argv[1]); else if(!strcmp(cmd, "PARAMETER") && argc==3 && argt[1]==type_symbol) do_parameter(argv[1], argv[2], argt[2]); else if(!strcmp(cmd, "PARAMETER+") && argc==3 && argt[1]==type_symbol) do_parameter_append(argv[1], argv[2], argt[2]); else if(!strcmp(cmd, "GROUP") && argc==3 && argt[1]==type_int && argt[2]==type_string) do_group(-1, (int)(long)argv[1], argv[2]); else if(!strcmp(cmd, "GROUP") && argc==4 && argt[1]==type_int && argt[2]==type_int && argt[3]==type_string) do_group((int)(long)argv[1], (int)(long)argv[2], argv[3]); else if(!strcmp(cmd, "UPDATE") && argc==2 && argt[1]==type_int) do_update((int)(long)argv[1]); else if(!strcmp(cmd, "CLOSE") && argc==2 && argt[1]==type_int) do_close((int)(long)argv[1]); else if(!strcmp(cmd, "QUIT") && argc==1) do_quit(); // TREEBANK session-id remaining-count token-list truth-list choice-list else if(!strcmp(cmd, "TREEBANK") && argc==6 && argt[1]==type_int && argt[2]==type_int && argt[3]==type_list && argt[4]==type_list && argt[5]==type_list) do_treebank((int)(long)argv[1], (int)(long)argv[2], argv[3], argv[4], argv[5]); else { unknown: fprintf(stderr, "unknown command with %d args\n", argc); console_add("YZLUI: Received unknown lkb-protocol top-level command: "); console_add(cmd); console_add("\n"); lkb_send_result(-1); } _ret: if(argv)free(argv); if(argt)free(argt); } char tokenize(char **INPUT) { if(!previous_space) { if(**INPUT==' ' || **INPUT=='\t' || **INPUT=='\n') { previous_space = 1; (*INPUT)++; return ' '; } } while(previous_space && **INPUT && (**INPUT==' ' || **INPUT=='\t' || **INPUT=='\n')) (*INPUT)++; previous_space = 0; return *((*INPUT)++); } char *list_type = "*LIST*", *empty_list_type = "*NULL*", *non_empty_list_type = "*NE-LIST*"; char *first_feature = "FIRST", *rest_feature = "REST"; lui_list hidden_features, hidden_types; lui_list collapsed_features, collapsed_types; init_parameters() { hidden_features.length = 0; hidden_features.type = type_symbol; hidden_features.data = 0; hidden_types.length = 0; hidden_types.type = type_symbol; hidden_types.data = 0; collapsed_features.length = 1; collapsed_features.type = type_symbol; collapsed_features.data = malloc(sizeof(char*) * 1); collapsed_features.data[0] = strdup("ARGS"); collapsed_types.length = 0; collapsed_types.type = type_symbol; collapsed_types.data = 0; } int parse_protocol(char **INPUT, int *TYPE, void **DATA) { char *p = *INPUT; char c; //debug("asked to parse for an arg at %s\n", *INPUT); do { c = tokenize(&p); //debug("after tokenize, at %s\n", p); if((c>='0' && c<='9') || c=='-' || c=='+') { p--; if(parse_number(&p, TYPE, DATA)) { *INPUT = p; return 1; } else { parse_symbol(&p, TYPE, DATA); *INPUT = p; return 1; } } if(c=='"') { p--; parse_string(&p, TYPE, DATA); *INPUT = p; return 1; } if((c>='a' && c<='z') || (c>='A' && c<='Z') || c=='*' || c=='$' || c=='@' || c=='&' || c=='~' || c=='%' || c=='?' || c=='.' || c=='|' || c=='_' || (unsigned char)c >= 128) { p--; parse_symbol(&p, TYPE, DATA); *INPUT = p; return 1; } if(c=='#') { c = tokenize(&p); if(!c) { fprintf(stderr, "Expected a structure type, but got EOF\n"); return 0; } switch(c) { case 'X': parse_xtext(&p, TYPE, DATA); *INPUT = p; return 1; case 'M': parse_xtext_menu(&p, TYPE, DATA); *INPUT = p; return 1; case 'D': parse_dag(&p, TYPE, DATA); *INPUT = p; return 1; case 'T': parse_tree(&p, TYPE, DATA); *INPUT = p; return 1; case 'C': parse_color(&p, TYPE, DATA); *INPUT = p; return 1; case 'F': parse_font(&p, TYPE, DATA); *INPUT = p; return 1; case 'U': parse_failure(&p, TYPE, DATA); *INPUT = p; return 1; case 'E': parse_edge(&p, TYPE, DATA); *INPUT = p; return 1; case 'G': parse_genedge(&p, TYPE, DATA); *INPUT = p; return 1; case 'H': parse_hierarchy(&p, TYPE, DATA); *INPUT = p; return 1; } } if(c=='[') { parse_list(&p, TYPE, DATA); *INPUT = p; return 1; } } while(c); return 0; } parse_number(char **INPUT, int *TYPE, void **DATA) { char *p = *INPUT; char c, is_float = 0, got_digit = 0, is_first = 1; float n = 0, dec = 1, sign = 1; //debug("parsing number at %s\n", *INPUT); do { c = tokenize(&p); if(!c){p--;break;} if((c>='A' && c<='Z') || (c>='a' && c<='z') || (unsigned char)c >= 128) { // this was a stupid simple, e.g. 3SING... blah. return 0; } if((c<'0' || c>'9') && c!='.' && c!='-' && c!='+') { p--; break; } if((c=='-' || c=='+') && !is_first)return 0; if(c>='0' && c<='9')got_digit = 1; if(c=='-')sign *= -1; else if(c=='+')sign *= 1; else if(c=='.')is_float = 1; else if(is_float) { dec *= 0.1; n += dec*(c - '0'); } else { n *= 10; n += c - '0'; } is_first = 0; } while(c); n *= sign; if(c!=']' && c!=' ' && c!='\t' && c!='\n' && c!=0 && c!='>')return 0; if(!got_digit)return 0; *INPUT = p; if(is_float) { *(float*)DATA = n; *TYPE = type_float; } else { *(int*)DATA = n; *TYPE = type_int; } return 1; } parse_symbol(char **INPUT, int *TYPE, void **DATA) { char *p = *INPUT, *tp = 0; char c; int tl = 0; //debug("parsing symbol at %s\n", *INPUT); do { c = tokenize(&p); if(c==' ')break; if(c==']'){p--;break;} if(c=='>'){p--;break;} if(c==0){p--;break;} tp = realloc(tp, ++tl + 1); tp[tl-1] = toupper(c); tp[tl] = 0; } while(c); //debug("parsed symbol %p %s length %d\n", tp, tp, tl); *INPUT=p; *(char**)DATA = tp; *TYPE = type_symbol; } parse_string(char **INPUT, int *TYPE, void **DATA) { char *p = *INPUT, *tp = 0; char c; int tl = 0, esc = 0; tp = calloc(1,1); //debug("parsing string at %s\n", *INPUT); c = tokenize(&p); // read off first quote do { //c = tokenize(&p); // don't tokenize; we want verbatim input bytes c = *p++; if(esc) { if(c=='n')c='\n'; if(c=='r')c='\r'; esc = 0; } else { if(c=='"')break; if(c=='\\'){esc = 1;continue;} } tp = realloc(tp, ++tl + 1); tp[tl-1] = c; tp[tl] = 0; } while(c); *INPUT=p; *(char**)DATA = tp; *TYPE = type_string; } parse_color(char **INPUT, int *TYPE, void **DATA) { int red_type, green_type, blue_type; int red, green, blue; color_t *col; char *p = *INPUT; char c; *DATA = 0; //debug("parsing color at %s\n", *INPUT); c = tokenize(&p); if(c!='[') { fprintf(stderr, "Expected '[' opening color structure\n"); goto done_color; } parse_protocol(&p, &red_type, (void**)&red); if(red_type != type_int) { fprintf(stderr, "RED of color was not a number (type %d)\n", red_type); goto done_color; } parse_protocol(&p, &green_type, (void**)&green); if(green_type != type_int) { fprintf(stderr, "GREEN of color was not a number (type %d)\n", green_type); goto done_color; } parse_protocol(&p, &blue_type, (void**)&blue); if(blue_type != type_int) { fprintf(stderr, "BLUE of color was not a number (type %d)\n", blue_type); goto done_color; } do { c = tokenize(&p); if(c != ' ' && c != ' ' && c != '\n' && c != ']') { fprintf(stderr, "ERROR: unexpected trailing characters in #C structure!\n"); } } while(c != ']'); col = (color_t*)malloc(sizeof(color_t)); col->r = red; col->g = green; col->b = blue; col->a = 65535; done_color: *TYPE = type_color; *INPUT=p; if(!col) col = (color_t*)calloc(sizeof(color_t), 1); *(color_t**)DATA = col; return 0; } symbol_to_color(char *name, color_t **col, int *type) { #define USE_COLOR(rp,gp,bp) {*col = malloc(sizeof(color_t)); \ (*col)->r = rp; (*col)->g = gp; \ (*col)->b = bp; (*col)->a = 65535; \ *type = type_color; free(name); \ return 0; } if(!strcmp(name, "RED"))USE_COLOR(65535, 0, 0); if(!strcmp(name, "GREEN"))USE_COLOR(0, 65535, 0); if(!strcmp(name, "BLUE"))USE_COLOR(0, 0, 65535); if(!strcmp(name, "YELLOW"))USE_COLOR(65535, 65535, 0); if(!strcmp(name, "CYAN"))USE_COLOR(0, 65535, 65535); if(!strcmp(name, "MAGENTA"))USE_COLOR(65535, 0, 65535); if(!strcmp(name, "PURPLE"))USE_COLOR(50535, 0, 55535); if(!strcmp(name, "ORANGE"))USE_COLOR(60000, 48000, 0); if(!strcmp(name, "BLACK"))USE_COLOR(0, 0, 0); fprintf(stderr, "Unknown color `%s'\n", name); return -1; #undef USE_COLOR } font_style style_to_font_style(char *style) { if(!strcmp(style, "ROMAN"))return fsRoman; if(!strcmp(style, "BOLD"))return fsBold; if(!strcmp(style, "ITALIC"))return fsItalic; if(!strcmp(style, "BOLD-ITALIC"))return fsBoldItalic; if(!strcmp(style, "ITALIC-BOLD"))return fsBoldItalic; fprintf(stderr, "Unknown font style `%s'\n", style); return -1; } convert_font_family(char **Family) { char *of = *Family; if(!strcmp(of, "HELVETICA"))strcpy(of, "helvetica"); else if(!strcmp(of, "COURIER"))strcpy(of, "courier"); else if(!strcmp(of, "ROMAN"))strcpy(of, "roman"); else { fprintf(stderr, "WARNING: non-standard font family `%s' -- passing through.\n", of); downcase_string(of); } } parse_font(char **INPUT, int *TYPE, void **DATA) { int family_type, size_type, style_type, color_type, size; color_t *color; char *family, *style; font_info *font = 0; char *p = *INPUT; char c; *DATA = 0; //debug("parsing font at %s\n", *INPUT); c = tokenize(&p); if(c!='[') { fprintf(stderr, "Expected '[' opening font structure\n"); goto done_font; } parse_protocol(&p, &family_type, (void**)&family); if(family_type != type_symbol && family_type != type_string) { fprintf(stderr, "Family of font was not a string or symbol (type %d)\n", family_type); goto done_font; } else convert_font_family(&family); parse_protocol(&p, &size_type, (void**)&size); if(size_type != type_int) { fprintf(stderr, "Size of font was not a number (type %d)\n", size_type); goto done_font; } parse_protocol(&p, &style_type, (void**)&style); if(style_type != type_symbol) { fprintf(stderr, "Style of font was not a symbol (type %d)\n", style_type); goto done_font; } parse_protocol(&p, &color_type, (void**)&color); if(color_type == type_symbol) if(symbol_to_color((char*)color, &color, &color_type)) goto done_font; if(color_type != type_color) { fprintf(stderr, "Color of font was not a color (type %d)\n", color_type); goto done_font; } do { c = tokenize(&p); if(c != ' ' && c != ' ' && c != '\n' && c != ']') { fprintf(stderr, "ERROR: unexpected trailing characters in #F structure!\n"); } } while(c != ']'); font = (font_info*)malloc(sizeof(font_info)); strcpy(font->family, family); free(family); font->size = size; font->style = style_to_font_style(style); free(style); font->color = *color; font->font = 0; free(color); done_font: *TYPE = type_font; *INPUT=p; if(!font) font = (font_info*)calloc(sizeof(font_info), 1); *(font_info**)DATA = font; return 0; } parse_list(char **INPUT, int *TYPE, void **DATA) { lui_list *list; void *item; int itype; char *p = *INPUT; char c; *DATA = 0; list = (lui_list*)malloc(sizeof(lui_list)); list->length = 0; list->data = 0; list->type = -1; do { c = tokenize(&p); if(c==' ')continue; if(c==']')break; p--; parse_protocol(&p, &itype, (void**)&item); //printf("list parser got type %d item %p\n", itype, item); if(list->type==-1)list->type = itype; else if(itype != list->type) { fprintf(stderr, "Item in list is not homogeneous (list type %d, item type %d)\n", list->type, itype); break; } if(itype == list->type) { list->length++; list->data = realloc(list->data, sizeof(void*) * list->length); list->data[list->length-1] = item; } } while(*p); *TYPE = type_list; *INPUT=p; *(lui_list**)DATA = list; return 0; } do_browse_xtext(int id, lui_xtext *text, char *title, int nmenus, struct lui_xtext_menu **menus) { if(browse_xtext(id, text, nmenus, menus, title))lkb_send_result(-1); else lkb_send_result(0); } do_browse_tree(int id, lkb_tree *tree, char *title) { if(browse_tree(id, tree, title))lkb_send_result(-1); else lkb_send_result(0); } do_browse_avm(int id, lkb_avm *avm, char *title) { if(browse_avm(id, avm, title, 0))lkb_send_result(-1); else lkb_send_result(0); } do_browse_avm_failures(int id, lkb_avm *avm, char *title, lui_list *failures) { if(failures->type != type_failure) { fprintf(stderr, "AVM [failurse] command: list argument was not a list of failures.\n"); lkb_send_result(-1); return -1; } if(browse_avm(id, avm, title, failures))lkb_send_result(-1); else lkb_send_result(0); return 0; } do_browse_chart(int id, int size, char *title, int nedges, lkb_edge **edges) { lkb_chart *chart = build_chart(id, size, nedges, edges); if(!chart)lkb_send_result(-1); else if(browse_chart(id, chart, title))lkb_send_result(-1); else lkb_send_result(0); } do_browse_genchart(int id, lui_list *ep_list, lui_list *edge_list, char *title) { lui_genchart *chart = build_genchart(id, ep_list->length, (char**)ep_list->data, edge_list->length, (lui_genedge**)edge_list->data); if(!chart)lkb_send_result(-1); else if(browse_genchart(id, chart, title))lkb_send_result(-1); else lkb_send_result(0); } do_browse_hierarchy(int id, char *name, int ntypes, struct lui_hierarchy **types) { //fprintf(stderr, "browse a hierarchy `%s' of %d types\n", name, ntypes); browse_hierarchy(id, name, ntypes, types); } int grammar_loaded = 0; char current_grammar_path[1024] = "\0"; extern char *status_bar; int finish_grammar_time; do_status(char *res) { if(!strcmp(res, "READY")) { grammar_loaded = 1; //status_bar = "Grammar is ready."; status_bar = "Loading grammar... done."; finish_grammar_time = time(0)+1; lkb_send_result(0); } else if(!strcmp(res, "NOTREADY")) { grammar_loaded = 0; status_bar = "No grammar is loaded."; finish_grammar_time = 0; lkb_send_result(0); } else if(!strcmp(res, "LOADING")) { grammar_loaded = 1; status_bar = "Loading grammar..."; finish_grammar_time = 0; lkb_send_result(0); } else lkb_send_result(-1); } do_message(char *mess) { console_add(mess); lkb_send_result(0); free(mess); } extern int center_features; extern int color_terminal_types; extern int avm_margin; extern int xtext_leading; extern font_info type_display_font, feature_display_font, tag_display_font, small_tree_font, big_tree_font; extern font_info chart_word_font, chart_edge_font, small_tree_orth_font, big_tree_orth_font; extern font_info chart_bar_font, avm_bar_font, tree_bar_font, mtree_bar_font, xtext_plain_font, xtext_active_font; extern color_t structure_bracket_color, list_bracket_color, tag_box_color, xtext_highlight_color; struct parameter_t { char *name; void **value; // can be interpreted as char**, int*, or font_info* int type; int alloc; } param_table[] = { #define PARAM(name, storage, type) {name, (void**)&storage, type} PARAM("LIST-TYPE", list_type, type_symbol), PARAM("EMPTY-LIST-TYPE", empty_list_type, type_symbol), PARAM("NON-EMPTY-LIST-TYPE",non_empty_list_type, type_symbol), PARAM("LIST-HEAD", first_feature, type_symbol), PARAM("LIST-TAIL", rest_feature, type_symbol), PARAM("AVM-HIDDEN-FEATURES", hidden_features, type_list), PARAM("AVM-COLLAPSED-FEATURES", collapsed_features, type_list), PARAM("AVM-HIDDEN-TYPES", hidden_types, type_list), PARAM("AVM-COLLAPSED-TYPES", collapsed_types, type_list), PARAM("AVM-CENTER-FEATURES", center_features, type_int), PARAM("AVM-COLOR-TERMINAL-TYPES", color_terminal_types, type_int), PARAM("AVM-MARGINS", avm_margin, type_int), PARAM("TEXT-LEADING", xtext_leading, type_int), PARAM("AVM-TYPE-FONT", type_display_font, type_font), PARAM("AVM-FEATURE-FONT", feature_display_font, type_font), PARAM("AVM-ATTRIBUTE-FONT", feature_display_font, type_font), PARAM("AVM-TAG-FONT", tag_display_font, type_font), PARAM("AVM-PATH-FONT", avm_bar_font, type_font), PARAM("AVM-BAR-FONT", avm_bar_font, type_font), PARAM("CHART-BAR-FONT", chart_bar_font, type_font), PARAM("TREE-SUMMARY-BAR-FONT", mtree_bar_font, type_font), PARAM("TREE-DETAIL-BAR-FONT", tree_bar_font, type_font), PARAM("TREE-SUMMARY-FONT", small_tree_font, type_font), PARAM("TREE-DETAIL-FONT", big_tree_font, type_font), PARAM("TREE-SUMMARY-NODE-FONT", small_tree_font, type_font), PARAM("TREE-DETAIL-NODE-FONT", big_tree_font, type_font), PARAM("TREE-SUMMARY-ORTH-FONT", small_tree_orth_font, type_font), PARAM("TREE-DETAIL-ORTH-FONT", big_tree_orth_font, type_font), PARAM("TREE-SUMMARY-SURFACE-FONT", small_tree_orth_font, type_font), PARAM("TREE-DETAIL-SURFACE-FONT", big_tree_orth_font, type_font), PARAM("CHART-WORD-FONT", chart_word_font, type_font), PARAM("CHART-EDGE-FONT", chart_edge_font, type_font), PARAM("TEXT-PLAIN-FONT", xtext_plain_font, type_font), PARAM("TEXT-ACTIVE-FONT", xtext_active_font, type_font), PARAM("AVM-STRUCTURE-BRACKET-COLOR", structure_bracket_color, type_color), PARAM("AVM-LIST-BRACKET-COLOR", list_bracket_color, type_color), PARAM("AVM-TAG-BOX-COLOR", tag_box_color, type_color), PARAM("TEXT-HIGHLIGHT-COLOR", xtext_highlight_color, type_color), }; void do_parameter(char *name, void *value, int vtype) { int ret = -1, i; for(i=0;ifont) yzFreeFont(((font_info*)param_table[i].value)->font); *(font_info*)param_table[i].value = *(font_info*)value; free(value); param_table[i].alloc = 0; } else if(vtype == type_list) { free_lui_list(param_table[i].value); *(lui_list*)param_table[i].value = *(lui_list*)value; free(value); param_table[i].alloc = 0; } else if(vtype == type_int) { *param_table[i].value = value; param_table[i].alloc = 0; } else *param_table[i].value = value; //debug("value of %s now %s\n", param_table[i].name, *param_table[i].value); ret = 0; } } if(ret) { console_add("YZLUI: received unknown parameter: "); console_add(name); console_add("\n"); } lkb_send_result(ret); free(name); } free_lui_list(lui_list *list) { int i; for(i=0;ilength;i++) { switch(list->type) { case type_symbol: case type_string: free(list->data[i]); break; case type_list: free_lui_list(list->data[i]); free(list->data[i]); break; case type_dag: free_avm(list->data[i]); break; default: fprintf(stderr, "Don't know how to free lists of type %d\n", list->type); break; } } free(list->data); list->length = 0; list->data = 0; } do_parameter_append(char *name, void *value, int vtype) { int ret = -1, i, olen, nlen; lui_list *list; for(i=0;itype && list->type!=-1) { console_add("YZLUI: parameter is wrong type to append to list\n"); break; } list->type = vtype; list->length++; list->data = realloc(list->data, sizeof(void*)*list->length); list->data[list->length-1] = value; ret = 0; } } if(ret)console_add("YZLUI: received unknown parameter\n"); lkb_send_result(ret); free(name); } do_close(int id) { close_window_by_object_id(id); } do_update(int id) { update_object_id = id; } do_quit() { if(!passive_mode) fprintf(stderr, "Warning: received `QUIT' command when not in passive mode.\n"); gDone = 1; } void parse_string_cb(char *string) { lkb_send("parse \"%s\" all tree browse\n", string); } void grammar_load_cb(char *path) { if(!path) { return; } strcpy(current_grammar_path, path); lkb_send("grammar \"%s\"\n", path); } void reload_grammar() { if(!current_grammar_path[0]) { if(!grammar_loaded)console_add("No current grammar.\n"); else console_add("Don't know current grammar's path!\n"); return; } grammar_loaded = 0; lkb_send("grammar \"%s\"\n", current_grammar_path); }