diff options
-rw-r--r-- | riscos/gui.c | 114 | ||||
-rw-r--r-- | utils/hashtable.c | 41 | ||||
-rw-r--r-- | utils/messages.c | 33 |
3 files changed, 125 insertions, 63 deletions
diff --git a/riscos/gui.c b/riscos/gui.c index bb2fe3e18..25f54d590 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -299,33 +299,24 @@ void gui_init(int argc, char** argv) while (*help == 9) help++; if (!memcmp(help, "0.55", 4)) #endif - ro_plot_patterned_lines = false; + ro_plot_patterned_lines = false; } - atexit(ro_gui_cleanup); - prev_sigs.sigabrt = signal(SIGABRT, ro_gui_signal); - prev_sigs.sigfpe = signal(SIGFPE, ro_gui_signal); - prev_sigs.sigill = signal(SIGILL, ro_gui_signal); - prev_sigs.sigint = signal(SIGINT, ro_gui_signal); - prev_sigs.sigsegv = signal(SIGSEGV, ro_gui_signal); - prev_sigs.sigterm = signal(SIGTERM, ro_gui_signal); - - if (prev_sigs.sigabrt == SIG_ERR || prev_sigs.sigfpe == SIG_ERR || - prev_sigs.sigill == SIG_ERR || - prev_sigs.sigint == SIG_ERR || - prev_sigs.sigsegv == SIG_ERR || - prev_sigs.sigterm == SIG_ERR) - die("Failed registering signal handlers"); - - filename_initialise(); + /* Read in the options */ + options_read("NetSurf:Choices"); -#ifdef WITH_SAVE_COMPLETE - save_complete_init(); -#endif + /* Choose the interface language to use */ + ro_gui_choose_language(); - options_read("NetSurf:Choices"); + /* Load in our language-specific Messages */ + if ((length = snprintf(path, sizeof(path), + "NetSurf:Resources.%s.Messages", + option_language)) < 0 || length >= (int)sizeof(path)) + die("Failed to locate Messages resource."); + messages_load(path); + messages_load("NetSurf:Resources.LangNames"); - /* set defaults for absent strings */ + /* Set defaults for absent option strings */ if (!option_theme) option_theme = strdup("Aletheia"); if (!option_toolbar_browser) @@ -369,18 +360,31 @@ void gui_init(int argc, char** argv) !option_theme_save) die("Failed initialising string options"); - /* create our choices directories */ + /* Create our choices directories */ ro_gui_create_dirs(); + /* Register exit and signal handlers */ + atexit(ro_gui_cleanup); + prev_sigs.sigabrt = signal(SIGABRT, ro_gui_signal); + prev_sigs.sigfpe = signal(SIGFPE, ro_gui_signal); + prev_sigs.sigill = signal(SIGILL, ro_gui_signal); + prev_sigs.sigint = signal(SIGINT, ro_gui_signal); + prev_sigs.sigsegv = signal(SIGSEGV, ro_gui_signal); + prev_sigs.sigterm = signal(SIGTERM, ro_gui_signal); + + if (prev_sigs.sigabrt == SIG_ERR || prev_sigs.sigfpe == SIG_ERR || + prev_sigs.sigill == SIG_ERR || + prev_sigs.sigint == SIG_ERR || + prev_sigs.sigsegv == SIG_ERR || + prev_sigs.sigterm == SIG_ERR) + die("Failed registering signal handlers"); + + /* Load in UI sprites */ gui_sprites = ro_gui_load_sprite_file("NetSurf:Resources.Sprites"); if (!gui_sprites) die("Unable to load Sprites."); - ro_gui_choose_language(); - - bitmap_initialise_memory(); - urldb_load(option_url_path); - urldb_load_cookies(option_cookie_file); + /* Find NetSurf directory */ nsdir_temp = getenv("NetSurf$Dir"); if (!nsdir_temp) die("Failed to locate NetSurf directory"); @@ -388,18 +392,28 @@ void gui_init(int argc, char** argv) if (!NETSURF_DIR) die("Failed duplicating NetSurf directory string"); - if ((length = snprintf(path, sizeof(path), - "NetSurf:Resources.%s.Messages", - option_language)) < 0 || length >= (int)sizeof(path)) - die("Failed to locate Messages resource."); - messages_load(path); - messages_load("NetSurf:Resources.LangNames"); - + /* Initialise stylesheet URLs */ default_stylesheet_url = strdup("file:///NetSurf:/Resources/CSS"); adblock_stylesheet_url = strdup("file:///NetSurf:/Resources/AdBlock"); if (!default_stylesheet_url || !adblock_stylesheet_url) die("Failed initialising string constants."); + /* Initialise filename allocator */ + filename_initialise(); + + /* Initialise save complete functionality */ +#ifdef WITH_SAVE_COMPLETE + save_complete_init(); +#endif + + /* Initialise bitmap memory pool */ + bitmap_initialise_memory(); + + /* Load in visited URLs and Cookies */ + urldb_load(option_url_path); + urldb_load_cookies(option_cookie_file); + + /* Initialise with the wimp */ error = xwimp_initialise(wimp_VERSION_RO38, task_name, (const wimp_message_list *) &task_messages, 0, &task_handle); @@ -408,7 +422,7 @@ void gui_init(int argc, char** argv) error->errnum, error->errmess)); die(error->errmess); } - /* register our message handlers */ + /* Register message handlers */ ro_message_register_route(message_HELP_REQUEST, ro_gui_interactive_help_request); ro_message_register_route(message_DATA_OPEN, @@ -427,9 +441,11 @@ void gui_init(int argc, char** argv) ro_gui_selection_drag_claim); ro_message_register_route(message_WINDOW_INFO, ro_msg_window_info); - /* end of handler registration */ + /* Initialise the font subsystem */ nsfont_init(); + + /* Initialise global information */ ro_gui_get_screen_properties(); ro_gui_wimp_get_desktop_font(); @@ -437,8 +453,7 @@ void gui_init(int argc, char** argv) if (getenv("NetSurf$Start_URI_Handler")) xwimp_start_task("Desktop", 0); - /* Open the templates - */ + /* Open the templates */ if ((length = snprintf(path, sizeof(path), "NetSurf:Resources.%s.Templates", option_language)) < 0 || length >= (int)sizeof(path)) @@ -449,17 +464,30 @@ void gui_init(int argc, char** argv) error->errnum, error->errmess)); die(error->errmess); } - ro_gui_theme_initialise(); /* initialise themes before dialogs */ - ro_gui_dialog_init(); /* must be done after sprite loading */ + + /* Initialise themes before dialogs */ + ro_gui_theme_initialise(); + /* Initialise dialog windows (must be after UI sprites are loaded) */ + ro_gui_dialog_init(); + /* Initialise download window */ ro_gui_download_init(); + /* Initialise menus */ ro_gui_menu_init(); + /* Initialise query windows */ ro_gui_query_init(); + /* Initialise the history subsystem */ ro_gui_history_init(); + + /* Done with the templates file */ wimp_close_template(); - ro_gui_tree_initialise(); /* must be done after sprite loading */ + /* Initialise tree views (must be after UI sprites are loaded) */ + ro_gui_tree_initialise(); + /* Create Iconbar icon */ ro_gui_icon_bar_create(); + + /* Finally, check Inet$Resolvers for sanity */ ro_gui_check_resolvers(); } @@ -2196,7 +2224,7 @@ void warn_user(const char *warning, const char *detail) * Should only be used during initialisation. */ -void die(const char *error) +void die(const char * const error) { os_error warn_error; diff --git a/utils/hashtable.c b/utils/hashtable.c index f26c9f0e1..62eb415e2 100644 --- a/utils/hashtable.c +++ b/utils/hashtable.c @@ -28,7 +28,7 @@ * \return struct hash_table containing the context of this hash table or NULL * if there is insufficent memory to create it and its chains. */ - + struct hash_table *hash_create(unsigned int chains) { struct hash_table *r = malloc(sizeof(struct hash_table)); @@ -61,11 +61,14 @@ void hash_destroy(struct hash_table *ht) { unsigned int i; + if (ht == NULL) + return; + for (i = 0; i < ht->nchains; i++) { if (ht->chain[i] != NULL) { struct hash_entry *e = ht->chain[i]; while (e) { - struct hash_entry *n = e->next; + struct hash_entry *n = e->next; free(e->key); free(e->value); free(e); @@ -93,22 +96,28 @@ void hash_destroy(struct hash_table *ht) bool hash_add(struct hash_table *ht, const char *key, const char *value) { - unsigned int h = hash_string_fnv(key); - unsigned int c = h % ht->nchains; + unsigned int h; + unsigned int c; struct hash_entry *e = malloc(sizeof(struct hash_entry)); - + + if (ht == NULL || key == NULL || value == NULL) + return false; + if (e == NULL) { LOG(("Not enough memory for hash entry.")); return false; } + h = hash_string_fnv(key); + c = h % ht->nchains; + e->key = strdup(key); if (e->key == NULL) { LOG(("Unable to strdup() key for hash table.")); free(e); return false; } - + e->value = strdup(value); if (e->value == NULL) { LOG(("Unable to strdup() value for hash table.")); @@ -133,10 +142,17 @@ bool hash_add(struct hash_table *ht, const char *key, const char *value) const char *hash_get(struct hash_table *ht, const char *key) { - unsigned int h = hash_string_fnv(key); - unsigned int c = h % ht->nchains; - struct hash_entry *e = ht->chain[c]; - + unsigned int h; + unsigned int c; + struct hash_entry *e; + + if (ht == NULL || key == NULL) + return NULL; + + h = hash_string_fnv(key); + c = h % ht->nchains; + e = ht->chain[c]; + while (e) { if (!strcmp(key, e->key)) return e->value; @@ -160,6 +176,9 @@ unsigned int hash_string_fnv(const char *datum) { unsigned int z = 0x01000193, i = 0; + if (datum == NULL) + return 0; + while (datum[i]) { z *= 0x01000193; z ^= datum[i]; @@ -228,7 +247,7 @@ int main(int argc, char *argv[]) a = hash_create(1031); b = hash_create(7919); - + dict = fopen("/usr/share/dict/words", "r"); if (dict == NULL) { fprintf(stderr, "Unable to open /usr/share/dict/words - extensive testing skipped.\n"); diff --git a/utils/messages.c b/utils/messages.c index a40c2b3bf..e3a8d5c90 100644 --- a/utils/messages.c +++ b/utils/messages.c @@ -41,9 +41,11 @@ struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) { char s[400]; FILE *fp; - + + assert(path != NULL); + ctx = (ctx != NULL) ? ctx : hash_create(HASH_SIZE); - + if (ctx == NULL) { LOG(("Unable to create hash table for messages file %s", path)); return NULL; @@ -70,7 +72,7 @@ struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) continue; *colon = 0; /* terminate key */ value = colon + 1; - + if (hash_add(ctx, s, value) == false) { LOG(("Unable to add %s:%s to hash table of %s", s, value, path)); @@ -80,7 +82,7 @@ struct hash_table *messages_load_ctx(const char *path, struct hash_table *ctx) } fclose(fp); - + return ctx; } @@ -99,15 +101,18 @@ void messages_load(const char *path) { struct hash_table *m; char s[400]; - + + assert(path != NULL); + m = messages_load_ctx(path, messages_hash); if (m == NULL) { LOG(("Unable to open Messages file '%s'. Possible reason: %s", path, strerror(errno))); - snprintf(s, 400, "Unable to open Messages file '%s'.", path); + snprintf(s, sizeof s, + "Unable to open Messages file '%s'.", path); die(s); } - + messages_hash = m; } @@ -121,8 +126,18 @@ void messages_load(const char *path) const char *messages_get_ctx(const char *key, struct hash_table *ctx) { - const char *r = hash_get(ctx, key); - + const char *r; + + assert(key != NULL); + + /* If we're called with no context, it's nicer to return the + * key rather than explode - this allows attempts to get messages + * before messages_hash is set up to fail gracefully, for example */ + if (ctx == NULL) + return key; + + r = hash_get(ctx, key); + return r ? r : key; } |