open-axiom repository from github
/*1Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.2All rights reserved.3Copyright (C) 2007-2010, Gabriel Dos Reis.4All rights reserved.56Redistribution and use in source and binary forms, with or without7modification, are permitted provided that the following conditions are8met:910- Redistributions of source code must retain the above copyright11notice, this list of conditions and the following disclaimer.1213- Redistributions in binary form must reproduce the above copyright14notice, this list of conditions and the following disclaimer in15the documentation and/or other materials provided with the16distribution.1718- Neither the name of The Numerical Algorithms Group Ltd. nor the19names of its contributors may be used to endorse or promote products20derived from this software without specific prior written permission.2122THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS23IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED24TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A25PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER26OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,27EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,28PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR29PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF30LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING31NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS32SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.33*/3435#include "openaxiom-c-macros.h"36/***37Contains all the code needed to parse input items,38InputString39SimpleBox40RadioBox.41****/42#include "debug.h"43#include "halloc.h"44#include "sockio.h"45#include "parse.h"46#include "lex.h"47#include "hyper.h"4849static void insert_item(InputItem * item);50static void add_box_to_rb_list(char * name , InputBox * box);51static int check_others(InputBox * list);5253/* create an unmapped input window for getting strings * */54extern int make_input_file;5556HyperLink *57make_input_window(InputItem * item)58{59HyperLink *link;60XSetWindowAttributes at;6162if (!make_input_file) {63link = (HyperLink *) halloc(sizeof(HyperLink), "HyperLink");64if (link == NULL) {65fprintf(stderr, "Ran out of memory allocating a hyper link!\n");66exit(-1);67}68at.cursor = gActiveCursor;69at.background_pixel = gInputBackgroundColor;70at.border_pixel = gActiveColor;71link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow, 0, 0, 100, 100, 0,720, InputOutput, CopyFromParent,73CWCursor | CWBackPixel | CWBorderPixel, &at);74XSelectInput(gXDisplay, link->win, ButtonPressMask);75link->type = openaxiom_Inputstring_token;76link->x = link->y = 0;77/** This way when I click in an input window, I need only use reference78to get a pointer to the item ***/79link->reference.string = item;80hash_insert(gLinkHashTable,(char *) link,(char *) &link->win);8182return link;83}84return 0;85}8687/* create an unmapped input window for boxes */88HyperLink *89make_box_window(InputBox * box, int type)90{91HyperLink *link = 0;92XSetWindowAttributes at;9394if (!make_input_file) {95link = (HyperLink *) halloc(sizeof(HyperLink), "Make_box_window");96if (link == NULL) {97fprintf(stderr, "Ran out of memory allocating a hyper link!\n");98exit(-1);99}100at.cursor = gActiveCursor;101at.background_pixel = gInputBackgroundColor;102link->win = XCreateWindow(gXDisplay, gWindow->fDisplayedWindow,1030, 0, 100, 100, 0,1040, InputOutput, CopyFromParent,105CWCursor | CWBackPixel, &at);106XSelectInput(gXDisplay, link->win, ButtonPressMask);107link->type = type;108link->x = link->y = 0;109/** This way when I click in an input window, I need only use reference110to get a pointer to the item ***/111link->reference.box = box;112hash_insert(gLinkHashTable, (char *)link,(char *) &link->win);113}114115return link;116}117118void119initialize_default(InputItem *item,char * buff)120{121LineStruct *newline;122LineStruct *curr_line;123int size = item->size;124int bp;125126item->curr_line = item->lines = alloc_inputline(size);127curr_line = item->lines;128item->num_lines = 1;129curr_line->line_number = 1;130/* while I still have lines to fill */131for (bp = 0; *buff;) {132if (*buff == '\n') {133curr_line->len = bp;134curr_line->buffer[bp] = 0;135newline = alloc_inputline(size);136newline->line_number = ++(item->num_lines);137curr_line->next = newline;138newline->prev = curr_line;139curr_line = newline;140bp = 0;141buff++;142}143else if (bp == size) {144curr_line->len = size + 1;145curr_line->buffer[size] = '_';146curr_line->buffer[size + 1] = 0;147newline = alloc_inputline(size);148newline->line_number = ++(item->num_lines);149curr_line->next = newline;150newline->prev = curr_line;151bp = 0;152curr_line = newline;153}154else {155curr_line->buffer[bp++] = *buff++;156}157}158curr_line->buff_pntr = curr_line->len = bp;159item->curr_line = curr_line;160}161162163164/* Parse the input string statement * */165void166parse_inputstring()167{168TextNode *input_node = curr_node;169char *name;170InputItem *item;171int size;172char *default_value;173174gStringValueOk = 0;175176/* first get the name */177input_node->type = token.type;178get_expected_token(openaxiom_Lbrace_token);179name = get_input_string();180input_node->data.text = alloc_string(name);181/* now get the width */182get_expected_token(openaxiom_Lbrace_token);183get_expected_token(openaxiom_Word_token);184get_expected_token(openaxiom_Rbrace_token);185size = atoi(token.id);186if (size < 0) {187fprintf(stderr, "Illegal size in Input string\n");188longjmp(jmpbuf, 1);189}190191/* get the default value */192get_expected_token(openaxiom_Lbrace_token);193default_value = get_input_string();194195/** now I need to malloc space for the input stuff **/196item = (InputItem *) halloc(sizeof(InputItem), "InputItem");197198/* Now store all the string info */199item->name = (char *)200halloc((strlen(input_node->data.text) + 1) * (sizeof(char)),"parse_inputstring");201strcpy(item->name, input_node->data.text);202item->size = size;203item->entered = 0;204item->next = NULL;205initialize_default(item, default_value);206207/** Now that I have all the structures made, lets make the window, and208add the item to the list ****/209210input_node->link = make_input_window(item);211if (!make_input_file)212item->win = input_node->link->win; /* TTT */213insert_item(item);214gStringValueOk = 1;215curr_node = input_node;216return ;217}218219void220parse_simplebox()221{222InputBox *box;223char *name;224short int picked = 0;225char *filename;226TextNode *input_box = curr_node;227228gStringValueOk = 0;229230/* set the type and space fields */231input_box->type = openaxiom_SimpleBox_token;232input_box->space = token.id[-1];233234/* IS it selected? */235get_token();236if (token.type == openaxiom_Lsquarebrace_token) {237get_expected_token(openaxiom_Word_token);238if (!is_number(token.id)) {239fprintf(stderr,240"parse_simple_box: Expected a value not %s\n", token.id);241print_page_and_filename();242jump();243}244else if (!strcmp(token.id, "1"))245picked = 1;246else if (!strcmp(token.id, "0"))247picked = 0;248else {249fprintf(stderr, "parse_simple_box: Unexpected Value %s\n", token.id);250print_page_and_filename();251jump();252}253get_expected_token(openaxiom_Rsquarebrace_token);254get_token();255}256257if (token.type != openaxiom_Lbrace_token) {258token_name(token.type);259fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer);260print_page_and_filename();261jump();262}263264name = get_input_string();265if (gPageBeingParsed->box_hash && hash_find(gPageBeingParsed->box_hash, name)) {266fprintf(stderr, "Input box name %s is not unique \n", name);267print_page_and_filename();268jump();269}270271box = alloc_inputbox();272box->name = alloc_string(name);273input_box->data.text = alloc_string(name);274box->picked = picked;275276/* Get the filename for the selected and unselected bitmaps */277get_expected_token(openaxiom_Lbrace_token);278filename = get_input_string();279if (!make_input_file)280box->selected = insert_image_struct(filename);281get_expected_token(openaxiom_Lbrace_token);282filename = get_input_string();283if (!make_input_file) {284box->unselected = insert_image_struct(filename);285/* set the width and height for the maximaum of the two */286input_box->height = max(box->selected->height, box->unselected->height);287input_box->width = max(box->selected->width, box->unselected->width);288/* Make the window and stuff */289input_box->link = make_box_window(box, openaxiom_SimpleBox_token);290box->win = input_box->link->win;291292/* Now add the box to the box_has table for this window */293if (gPageBeingParsed->box_hash == NULL) {294gPageBeingParsed->box_hash = (HashTable *) halloc(sizeof(HashTable),295"Box Hash");296hash_init(297gPageBeingParsed->box_hash,298BoxHashSize,299(EqualFunction) string_equal,300(HashcodeFunction) string_hash);301}302hash_insert(gPageBeingParsed->box_hash, (char *)box, box->name);303}304305/* reset the curr_node and then return */306curr_node = input_box;307gStringValueOk = 1;308return;309}310void311parse_radiobox()312{313InputBox *box;314char *name;315char *group_name;316short int picked = 0;317TextNode *input_box = curr_node;318319gStringValueOk = 0;320321/* set the type and space fields */322input_box->type = openaxiom_Radiobox_token;323input_box->space = token.id[-1];324325/* IS it selected? */326get_token();327if (token.type == openaxiom_Lsquarebrace_token) {328get_expected_token(openaxiom_Word_token);329if (!is_number(token.id)) {330fprintf(stderr,331"parse_simple_box: Expected a value not %s\n", token.id);332print_page_and_filename();333jump();334}335else if (!strcmp(token.id, "1"))336picked = 1;337else if (!strcmp(token.id, "0"))338picked = 0;339else {340fprintf(stderr, "parse_simple_box: Unexpected Value %s\n", token.id);341print_page_and_filename();342jump();343}344get_expected_token(openaxiom_Rsquarebrace_token);345get_token();346}347348if (token.type != openaxiom_Lbrace_token) {349token_name(token.type);350fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer);351print_page_and_filename();352jump();353}354355name = get_input_string();356if (gPageBeingParsed->box_hash && hash_find(gPageBeingParsed->box_hash, name)) {357fprintf(stderr, "Input box name %s is not unique \n", name);358print_page_and_filename();359jump();360}361362box = alloc_inputbox();363box->name = alloc_string(name);364input_box->data.text = alloc_string(name);365box->picked = picked;366367/* Now what I need to do is get the group name */368get_token();369if (token.type != openaxiom_Lbrace_token) {370token_name(token.type);371fprintf(stderr, "parse_inputbox was expecting a { not a %s\n", ebuffer);372print_page_and_filename();373jump();374}375group_name = get_input_string();376377/*378* Now call a routine which searches the radio box list for the current379* group name, and if found adds this box to it380*/381add_box_to_rb_list(group_name, box);382383input_box->width = box->rbs->width;384input_box->height = box->rbs->height;385/* Make the window and stuff */386input_box->link = make_box_window(box, openaxiom_Radiobox_token);387if (!make_input_file)388box->win = input_box->link->win; /* TTT */389390391/* Now add the box to the box_has table for this window */392if (gPageBeingParsed->box_hash == NULL) {393gPageBeingParsed->box_hash = (HashTable *) halloc(sizeof(HashTable),394"Box Hash");395hash_init(396gPageBeingParsed->box_hash,397BoxHashSize,398(EqualFunction) string_equal,399(HashcodeFunction) string_hash);400}401hash_insert(gPageBeingParsed->box_hash, (char *)box, box->name);402403/* reset the curr_node and then return */404curr_node = input_box;405gStringValueOk = 1;406return;407}408static void409add_box_to_rb_list(char *name,InputBox *box)410{411RadioBoxes *trace = gPageBeingParsed->radio_boxes;412InputBox *list;413/*int found = 0;*/414415while (trace != NULL && strcmp(trace->name, name))416trace = trace->next;417418if (!trace) {419fprintf(stderr, "Tried to add a radio box to a non-existent group %s\n",420name);421print_page_and_filename();422jump();423}424425/* now add the box to the list */426list = trace->boxes;427box->next = list;428trace->boxes = box;429430if (box->picked && check_others(box->next)) {431fprintf(stderr, "Only a single radio button can be picked\n");432print_page_and_filename();433box->picked = 0;434}435box->selected = trace->selected;436box->unselected = trace->unselected;437box->rbs = trace;438439return;440}441static int442check_others(InputBox *list)443{444InputBox *trace = list;445446while (trace != NULL && !trace->picked)447trace = trace->next;448449if (trace != NULL)450return 1;451else452return 0;453}454455456/* inserts an item into the current input list */457static void458insert_item(InputItem *item)459{460InputItem *trace = gPageBeingParsed->input_list;461462if (gPageBeingParsed->current_item == NULL) {463gPageBeingParsed->current_item = item;464}465if (trace == NULL) {466/** Insert at the front of the list **/467gPageBeingParsed->input_list = item;468return;469}470else {471/** find the end of the list **/472while (trace->next != NULL)473trace = trace->next;474trace->next = item;475return;476}477}478479InputItem *save_item;480481void482init_paste_item(InputItem *item)483{484InputItem *trace = gPageBeingParsed->input_list;485486if (!item) {487gPageBeingParsed->input_list = NULL;488gPageBeingParsed->current_item = NULL;489save_item = NULL;490}491else {492save_item = item->next;493trace->next = NULL;494}495}496void497repaste_item()498{499InputItem *trace;500501if (save_item) {502for (trace = gPageBeingParsed->input_list; trace && trace->next != NULL;503trace = trace->next);504if (trace) {505trace->next = save_item;506}507else {508gWindow->page->input_list = save_item;509gWindow->page->current_item = save_item;510}511}512save_item = NULL;513}514515InputItem *516current_item()517{518InputItem *trace = gPageBeingParsed->input_list;519520if (trace) {521for (; trace->next != NULL; trace = trace->next);522return trace;523}524else525return NULL;526}527int528already_there(char *name)529{530RadioBoxes *trace = gPageBeingParsed->radio_boxes;531532while (trace && strcmp(trace->name, name))533trace = trace->next;534535if (trace)536return 1;537else538return 0;539}540void541parse_radioboxes()542{543TextNode *return_node = curr_node;544RadioBoxes *newrb;545char *fname;546547/* I really don't need this node, it just sets up some parsing stuff */548return_node->type = openaxiom_Noop_token;549550newrb = alloc_rbs();551552get_token();553if (token.type != openaxiom_Lbrace_token) {554token_name(token.type);555fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer);556print_page_and_filename();557jump();558}559560newrb->name = alloc_string(get_input_string());561562/* quick search for the name in the current list */563if (already_there(newrb->name)) {564free(newrb->name);565free(newrb);566fprintf(stderr, "Tried to redefine radioboxes %s\n", newrb->name);567print_page_and_filename();568jump();569}570/* now I have to get the selected and unslected bitmaps */571get_token();572if (token.type != openaxiom_Lbrace_token) {573token_name(token.type);574fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer);575print_page_and_filename();576jump();577}578fname = get_input_string();579if (!make_input_file)580newrb->selected = insert_image_struct(fname);581582get_token();583if (token.type != openaxiom_Lbrace_token) {584token_name(token.type);585fprintf(stderr, "\\radioboxes was expecting a name not %s\n", ebuffer);586print_page_and_filename();587jump();588}589fname = get_input_string();590if (!make_input_file) {591newrb->unselected = insert_image_struct(fname);592newrb->height = max(newrb->selected->height, newrb->unselected->height);593newrb->width = max(newrb->selected->width, newrb->unselected->width);594/* now add the thing to the current list of radio boxes */595}596newrb->next = gPageBeingParsed->radio_boxes;597gPageBeingParsed->radio_boxes = newrb;598599curr_node = return_node;600return;601}602603604