From b5749a5238df68056e19c65c1d6a8afc1eecd58d Mon Sep 17 00:00:00 2001 From: Gabriel Dos Reis Date: Tue, 26 Dec 2023 18:03:12 -0800 Subject: [PATCH] Replace `setjmp/longjmp` with `try/catch` in Hyper (#34) Also, remove the global variable `env` of type `jmp_buf` which was never used in the Hyper component. --- src/hyper/event.c | 2 - src/hyper/htadd.c | 1 - src/hyper/htinp.c | 10 ++-- src/hyper/hyper.c | 4 -- src/hyper/initx.c | 1 - src/hyper/lex.c | 23 ++------- src/hyper/macro.c | 22 +++++---- src/hyper/parse-aux.c | 4 +- src/hyper/parse-input.c | 4 +- src/hyper/parse-paste.c | 105 ++++++++++++++++++++-------------------- src/hyper/parse-types.c | 22 +++------ src/hyper/parse.c | 73 +++++++++++++--------------- src/hyper/parse.h | 3 -- src/hyper/token.h | 5 ++ 14 files changed, 123 insertions(+), 156 deletions(-) diff --git a/src/hyper/event.c b/src/hyper/event.c index b22178059..1b15b639e 100644 --- a/src/hyper/event.c +++ b/src/hyper/event.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include "debug.h" @@ -60,7 +59,6 @@ #include "lex.h" #include "sockio.h" -jmp_buf env; Window gActiveWindow; int motion = 0; int gNeedIconName = 0; diff --git a/src/hyper/htadd.c b/src/hyper/htadd.c index 21321ae76..1079cf828 100644 --- a/src/hyper/htadd.c +++ b/src/hyper/htadd.c @@ -39,7 +39,6 @@ #include "openaxiom-c-macros.h" #include -#include #include #include #include diff --git a/src/hyper/htinp.c b/src/hyper/htinp.c index 7799c194c..6d0c63074 100644 --- a/src/hyper/htinp.c +++ b/src/hyper/htinp.c @@ -35,7 +35,6 @@ #include #include -#include #include "openaxiom-c-macros.h" #include "debug.h" @@ -54,7 +53,6 @@ extern char **input_file_list; extern int input_file_count; extern int make_patch_files; extern int kill_spad; -extern jmp_buf jmpbuf; static void make_input_file_list(void ); static char * make_input_file_name(char * buf , char * filename); @@ -178,13 +176,13 @@ make_the_input_file(UnloadedPage *page) b = make_input_file_name(buf, page->fpos.name); if (inListAndNewer(b, page->fpos.name)) { printf("parsing: %s\n", page->name); - if (setjmp(jmpbuf)) { - printf("Syntax error!\n"); - } - else { + try { load_page((HyperDocPage *)page); make_input_file_from_page(gWindow->page); } + catch(const HyperError&) { + printf("Syntax error!\n"); + } } } diff --git a/src/hyper/hyper.c b/src/hyper/hyper.c index 207c16ff7..8e781aefc 100644 --- a/src/hyper/hyper.c +++ b/src/hyper/hyper.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -176,9 +175,6 @@ sigcld_handler(int sig) } -extern jmp_buf env; - - /* Clean up spad sockets on exit */ void clean_socket(void ) diff --git a/src/hyper/initx.c b/src/hyper/initx.c index 0ee4afa08..5697a480c 100644 --- a/src/hyper/initx.c +++ b/src/hyper/initx.c @@ -47,7 +47,6 @@ #include #include -#include #include #include #include diff --git a/src/hyper/lex.c b/src/hyper/lex.c index d5bee4a65..1ddf34cc7 100644 --- a/src/hyper/lex.c +++ b/src/hyper/lex.c @@ -55,7 +55,6 @@ #include "openaxiom-c-macros.h" #include -#include #include #include @@ -71,7 +70,6 @@ using namespace OpenAxiom; -static void spad_error_handler(void ); static int keyword_type(void ); extern int gTtFontIs850; @@ -81,7 +79,6 @@ extern HDWindow *gWindow; StateNode *top_state_node; HyperDocPage *gPageBeingParsed; /* page currently being parsed */ -jmp_buf jmpbuf; char ebuffer[128]; short int gInSpadsrc = 0; short int gInVerbatim; @@ -362,7 +359,7 @@ int get_char() if (cmd == EndOfPage) return EOF; if (cmd == SpadError) - spad_error_handler(); + throw HyperError{}; } get_string_buf(spad_socket, sock_buf, 1023); /* this will be null if this is the last time*/ @@ -582,9 +579,7 @@ jump() { if (gWindow == NULL) exit(-1); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Long Jump failed, Exiting\n"); - exit(-1); + throw HyperError{}; } void @@ -995,18 +990,6 @@ get_expected_token(int type) print_page_and_filename(); print_next_ten_tokens(); } - longjmp(jmpbuf, 1); - fprintf(stderr, "Could not jump to Error Page\n"); - exit(-1); + throw HyperError{}; } } - -static void -spad_error_handler() -{ - /* fprintf(stderr, "got a spad error\n"); */ - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Fatal Error: Could not jump to Error Page.\n"); - exit(-1); -} - diff --git a/src/hyper/macro.c b/src/hyper/macro.c index 0b0d18895..0caad1d84 100644 --- a/src/hyper/macro.c +++ b/src/hyper/macro.c @@ -41,6 +41,8 @@ #include "hyper.h" #include "lex.h" +using namespace OpenAxiom; + static char * load_macro(MacroStore * macro); static void get_parameter_strings(int number , char * macro_name); @@ -62,7 +64,7 @@ scan_HyperDoc() ret_val = get_token(); if (ret_val == EOF && number_of_left_braces) { fprintf(stderr, "Scan_Hypertex: Unexpected End of File\n"); - longjmp(jmpbuf, 1); + throw HyperError{}; } switch (token.type) { case openaxiom_Page_token: @@ -121,7 +123,7 @@ load_macro(MacroStore *macro) /** WOW, Somehow I had the location of the wrong macro **/ fprintf(stderr, "Expected macro name %s got insted %s in load_macro\n", macro->name, token.id); - longjmp(jmpbuf, 1); + throw HyperError{}; } get_expected_token(openaxiom_Rbrace_token); @@ -133,7 +135,7 @@ load_macro(MacroStore *macro) if (!number(token.id)) { fprintf(stderr, "load_macro: Expected A Value Instead Got %s\n", token.id); - longjmp(jmpbuf, 1); + throw HyperError{}; } /** if it is a number, then I should store it in the parameter number member of the macro structure **/ @@ -154,7 +156,7 @@ load_macro(MacroStore *macro) /** The macro is not in a group, uh oh **/ fprintf(stderr, "load_macro:Expected a Left Brace got type %d\n", token.type); - longjmp(jmpbuf, 1); + throw HyperError{}; } start_fpos = fpos; scan_HyperDoc(); @@ -200,7 +202,7 @@ push_parameters(ParameterList parms) if (parms == NULL) { fprintf(stderr, "Tried pushing a null list onto the parameter stack\n"); - longjmp(jmpbuf, 1); + throw HyperError{}; } parms->next = parameters; @@ -269,12 +271,12 @@ parse_macro() else { fprintf(stderr, "parse_macro: Tried to pop an empty parameter stack\n"); - longjmp(jmpbuf, 1); + throw HyperError{}; } } else { fprintf(stderr, "parse_macro: Unknown keyword %s\n", token.id); - longjmp(jmpbuf, 1); + throw HyperError{}; } } @@ -311,7 +313,7 @@ get_parameter_strings(int number,char * macro_name) switch (c = get_char()) { case EOF: fprintf(stderr, "GetParameterStrings: Unexpected EOF\n"); - longjmp(jmpbuf, 1); + throw HyperError{}; case '}': lbrace_counter--; if (lbrace_counter) @@ -374,14 +376,14 @@ parse_parameters() if (!number(token.id)) { fprintf(stderr, "Parse_parameter: Error Expected a number, got %s instead\n", token.id); - longjmp(jmpbuf, 1); + throw HyperError{}; } if ((value = atoi(token.id)) > parameters->number) { /** had a bad parameter number **/ fprintf(stderr, "Parse_parameter: Had a bad parameter number %d\n", value); - longjmp(jmpbuf, 1); + throw HyperError{}; } parse_from_string((parameters->list)[value - 1]); diff --git a/src/hyper/parse-aux.c b/src/hyper/parse-aux.c index 4c7600b9c..548babeb1 100644 --- a/src/hyper/parse-aux.c +++ b/src/hyper/parse-aux.c @@ -42,6 +42,8 @@ #include "lex.h" #include "hyper.h" +using namespace OpenAxiom; + static void read_ht_file(HashTable * page_hash , HashTable * macro_hash , HashTable * patch_hash , FILE * db_fp , char * db_file); static HyperDocPage * make_special_page(int type , const char * name); @@ -625,7 +627,7 @@ find_fp(FilePosition fp) ret_val = fseek(lfile, fp.pos, 0); if (ret_val == -1) { perror("fseeking to a page"); - longjmp(jmpbuf, 1); + throw HyperError{}; } /* now set some global values */ diff --git a/src/hyper/parse-input.c b/src/hyper/parse-input.c index 1c6191516..77c4c1782 100644 --- a/src/hyper/parse-input.c +++ b/src/hyper/parse-input.c @@ -47,6 +47,8 @@ #include "lex.h" #include "hyper.h" +using namespace OpenAxiom; + static void insert_item(InputItem * item); static void add_box_to_rb_list(char * name , InputBox * box); static int check_others(InputBox * list); @@ -186,7 +188,7 @@ parse_inputstring() size = atoi(token.id); if (size < 0) { fprintf(stderr, "Illegal size in Input string\n"); - longjmp(jmpbuf, 1); + throw HyperError{}; } /* get the default value */ diff --git a/src/hyper/parse-paste.c b/src/hyper/parse-paste.c index 06d84fa19..eb06bd8ed 100644 --- a/src/hyper/parse-paste.c +++ b/src/hyper/parse-paste.c @@ -51,6 +51,8 @@ #include "group.h" #include "lex.h" +using namespace OpenAxiom; + static void load_patch(PatchStore * patch); short int gInPaste; @@ -276,68 +278,65 @@ parse_patch(PasteNode *paste) paste->haspaste = 0; paste->paste_item = 0; + try { + end_node->next = 0; + free_node(old, 1); - /* set the jump buffer in case it is needed */ - if (setjmp(jmpbuf)) { - /*** OOOPS, an error occurred ****/ - fprintf(stderr, "(HyperDoc) Had an error parsing a patch: Goodbye!\n"); - exit(-1); - } - - - end_node->next = 0; - free_node(old, 1); - - init_parse_patch(gWindow->page); - init_paste_item(paste_item); - get_token(); - if (token.type != openaxiom_Patch_token) { - fprintf(stderr, "(HyperDoc) Pastebutton %s was expecting a patch\n", - paste->name); - jump(); - } - if (input_type == SourceInputKind::String) { + init_parse_patch(gWindow->page); + init_paste_item(paste_item); get_token(); - if (token.type != openaxiom_Lbrace_token) { - token_name(token.type); - fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); - print_page_and_filename(); + if (token.type != openaxiom_Patch_token) { + fprintf(stderr, "(HyperDoc) Pastebutton %s was expecting a patch\n", + paste->name); jump(); } - - get_token(); - if (token.type != openaxiom_Word_token) { - token_name(token.type); - fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); - print_page_and_filename(); - jump(); + if (input_type == SourceInputKind::String) { + get_token(); + if (token.type != openaxiom_Lbrace_token) { + token_name(token.type); + fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); + print_page_and_filename(); + jump(); + } + + get_token(); + if (token.type != openaxiom_Word_token) { + token_name(token.type); + fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); + print_page_and_filename(); + jump(); + } + + get_token(); + if (token.type != openaxiom_Rbrace_token) { + token_name(token.type); + fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); + print_page_and_filename(); + jump(); + } } + new_paste = alloc_node(); + curr_node = new_paste; + parse_HyperDoc(); - get_token(); - if (token.type != openaxiom_Rbrace_token) { - token_name(token.type); - fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer); - print_page_and_filename(); - jump(); - } - } - new_paste = alloc_node(); - curr_node = new_paste; - parse_HyperDoc(); + /* Once I am back, I need only reallign all the text structures */ + curr_node->type = openaxiom_Noop_token; + curr_node->next = next_node; + begin_node->next = new_paste; + begin_node->type = openaxiom_Noop_token; + free(begin_node->data.text); + begin_node->data.text = 0; - /* Once I am back, I need only reallign all the text structures */ - curr_node->type = openaxiom_Noop_token; - curr_node->next = next_node; - begin_node->next = new_paste; - begin_node->type = openaxiom_Noop_token; - free(begin_node->data.text); - begin_node->data.text = 0; + gWindow->fDisplayedWindow = gWindow->fScrollWindow; - gWindow->fDisplayedWindow = gWindow->fScrollWindow; - - repaste_item(); + repaste_item(); - paste_page(begin_node); + paste_page(begin_node); + } + catch(const HyperError&) { + fprintf(stderr, "(HyperDoc) Had an error parsing a patch: Goodbye!\n"); + exit(-1); + } /* so now I should just be able to disappear */ return gWindow->page; diff --git a/src/hyper/parse-types.c b/src/hyper/parse-types.c index f5a42cd9f..75bb7eaaa 100644 --- a/src/hyper/parse-types.c +++ b/src/hyper/parse-types.c @@ -114,9 +114,7 @@ parse_ifcond() if (gInIf) { curr_node->type = openaxiom_Noop_token; fprintf(stderr, "\\if found within \\if \n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "Longjump failed, Exiting\n"); - exit(-1); + throw HyperError{}; } gInIf = true; curr_node->type = openaxiom_Ifcond_token; @@ -150,9 +148,7 @@ parse_ifcond() token_name(token.type); curr_node->type = openaxiom_Noop_token; fprintf(stderr, "Expected a \\fi not a %s", ebuffer); - longjmp(jmpbuf, 1); - fprintf(stderr, "Longjump failed, Exiting\n"); - exit(-1); + throw HyperError{}; } curr_node->type = openaxiom_Fi_token; curr_node->next = endif; @@ -161,9 +157,7 @@ parse_ifcond() curr_node->type = openaxiom_Noop_token; token_name(token.type); fprintf(stderr, "Expected a \\fi not a %s", ebuffer); - longjmp(jmpbuf, 1); - fprintf(stderr, "Longjump failed, Exiting\n"); - exit(-1); + throw HyperError{}; } ifnode->next = ifnode->data.ifnode->thennode; ifnode->width = -1; /* A flag for compute if extents */ @@ -385,7 +379,7 @@ parse_verbatim(int type) } if (c == EOF) { fprintf(stderr, "parse_verbatim: Unexpected EOF found\n"); - longjmp(jmpbuf, 1); + throw HyperError{}; } resizeVbuf(); if (*end_string == '\n') @@ -461,7 +455,7 @@ parse_centerline() fprintf(stderr, "(HyperdDoc) \\centerline was expecting a }\n"); print_page_and_filename(); print_next_ten_tokens(); - longjmp(jmpbuf, 1); + throw HyperError{}; } curr_node->type = openaxiom_Endcenter_token; } @@ -476,7 +470,7 @@ parse_command() curr_node->type = openaxiom_Noop_token; fprintf(stderr, "Parser Error token %s unexpected\n", token_table[token.type]); - longjmp(jmpbuf, 1); + throw HyperError{}; } gStringValueOk = 1; @@ -513,7 +507,7 @@ parse_button() curr_node->type = openaxiom_Noop_token; fprintf(stderr, "Parser Error token %s unexpected\n", token_table[token.type]); - longjmp(jmpbuf, 1); + throw HyperError{}; } /* fill the node */ curr_node->type = token.type; @@ -714,7 +708,7 @@ parse_table() curr_node->type = openaxiom_Noop_token; fprintf(stderr, "Parser Error token %s unexpected\n", token_table[token.type]); - longjmp(jmpbuf, 1); + throw HyperError{}; } curr_node->type = openaxiom_Table_token; get_expected_token(openaxiom_Lbrace_token); diff --git a/src/hyper/parse.c b/src/hyper/parse.c index 1ca0f77e6..0db81b573 100644 --- a/src/hyper/parse.c +++ b/src/hyper/parse.c @@ -168,9 +168,18 @@ display_page(HyperDocPage *page) XUnmapSubwindows(gXDisplay, gWindow->fMainWindow); XUnmapSubwindows(gXDisplay, gWindow->fScrollWindow); XFlush(gXDisplay); - - if (setjmp(jmpbuf)) { - + try { + if (page->type == UnloadedPageType || page->type == ErrorPage) { + /* Gack! (page should be a union!) */ + init_scanner(); + new_page = format_page((UnloadedPage *)page); + gWindow->page = new_page; + /* free(page); */ + page = new_page; + } + show_page(page); + } + catch(const HyperError&) { /* * since I did not finish formatting the page, let me get rid of what * I had @@ -189,15 +198,6 @@ display_page(HyperDocPage *page) } reset_connection(); } - if (page->type == UnloadedPageType || page->type == ErrorPage) { - /* Gack! (page should be a union!) */ - init_scanner(); - new_page = format_page((UnloadedPage *)page); - gWindow->page = new_page; - /* free(page); */ - page = new_page; - } - show_page(page); } @@ -447,9 +447,7 @@ parse_HyperDoc() curr_node->type = openaxiom_Noop_token; /* Oops I had a problem parsing this puppy */ fprintf(stderr, "(HyperDoc) \\fi found without macthing if?\n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjmp failed -- Exiting \n"); - exit(-1); + throw HyperError{}; } case openaxiom_Else_token: if (gInIf) @@ -458,9 +456,7 @@ parse_HyperDoc() /* Oops I had a problem parsing this puppy */ curr_node->type = openaxiom_Noop_token; fprintf(stderr, "(HyperDoc) \\else found without macthing if?\n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjmp failed -- Exiting \n"); - exit(-1); + throw HyperError{}; } case openaxiom_Macro_token: parse_macro(); @@ -519,7 +515,7 @@ parse_HyperDoc() if (gParserMode != AllMode) { curr_node->type = openaxiom_Noop_token; fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); - longjmp(jmpbuf, 1); + throw HyperError{}; } else { curr_node->type = token.type; @@ -536,7 +532,7 @@ parse_HyperDoc() if (gParserMode != AllMode) { curr_node->type = openaxiom_Noop_token; fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); - longjmp(jmpbuf, 1); + throw HyperError{}; } else { curr_node->type = token.type; @@ -547,7 +543,7 @@ parse_HyperDoc() if (gParserMode != AllMode) { curr_node->type = openaxiom_Noop_token; fprintf(stderr, "(HyperDoc) Found a bad token %s\n", token_table[token.type]); - longjmp(jmpbuf, 1); + throw HyperError{}; } else { parse_begin_items(); @@ -657,7 +653,7 @@ parse_HyperDoc() parser_error(ebuffer); curr_node->type = openaxiom_Noop_token; - longjmp(jmpbuf, 1); + throw HyperError{}; } curr_node->type = token.type; curr_node->space = token.id[-1]; @@ -722,13 +718,7 @@ parse_page_from_socket() (HashcodeFunction) window_code); gPageBeingParsed = page; replace_page = NULL; - if (setjmp(jmpbuf)) { - /* Ooops, somewhere I had an error */ - free_page(page); - page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); - reset_connection(); - } - else { + try { parse_page(page); page->type = SpadGen; page->filename = NULL; @@ -740,6 +730,12 @@ parse_page_from_socket() hash_insert(gWindow->fPageHashTable, (char *)page, page->name); } } + catch(const HyperError&) { + /* Ooops, somewhere I had an error */ + free_page(page); + page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); + reset_connection(); + } if (replace_page != NULL) { free_page(page); page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, replace_page); @@ -764,19 +760,18 @@ parse_page_from_unixfd() (EqualFunction) window_equal, (HashcodeFunction) window_code); gPageBeingParsed = page; - if (setjmp(jmpbuf)) { + try { + parse_page(page); + page->type = Unixfd; + page->filename = NULL; + } + catch (const HyperError&) { /* Ooops, somewhere I had an error */ free_page(page); page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, "ErrorPage"); reset_connection(); } - else { - parse_page(page); - page->type = Unixfd; - page->filename = NULL; - } return page; - } static void @@ -791,8 +786,7 @@ start_scrolling() if (gParserRegion != Header) { curr_node->type = openaxiom_Noop_token; fprintf(stderr, "(HyperDoc) Parser Error: Unexpected BeginScrollFound\n"); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjump failed exiting\n"); + throw HyperError{}; } curr_node->type = openaxiom_Endheader_token; curr_node->next = NULL; @@ -818,8 +812,7 @@ start_footer() curr_node->type = openaxiom_Noop_token; fprintf(stderr, "(HyperDoc) Parser Error: Unexpected Endscroll Found\n"); print_page_and_filename(); - longjmp(jmpbuf, 1); - fprintf(stderr, "(HyperDoc) Longjump failed exiting\n"); + throw HyperError{}; } curr_node->type = openaxiom_Endscrolling_token; diff --git a/src/hyper/parse.h b/src/hyper/parse.h index 3e2c04b4c..7cabbbcb9 100644 --- a/src/hyper/parse.h +++ b/src/hyper/parse.h @@ -48,8 +48,6 @@ #include #include "hyper.h" -#include - extern void display_page(HyperDocPage * page); extern void init_parse_patch(HyperDocPage * page); extern void load_page(HyperDocPage * page); @@ -90,7 +88,6 @@ extern int pop_parameters(); extern int parse_macro(); extern void parse_parameters(); -extern jmp_buf jmpbuf; extern int vbuff; extern TextNode *cur_spadcom; /* spad command being parsed *** */ diff --git a/src/hyper/token.h b/src/hyper/token.h index b40d069a4..e4394d242 100644 --- a/src/hyper/token.h +++ b/src/hyper/token.h @@ -252,6 +252,11 @@ enum class SourceInputKind { UnixFD = 4 }; +namespace OpenAxiom { + // Basic error type in the Hyper component. + struct HyperError { }; +} + extern FILE *unixfd; #endif