diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2013-05-07 14:56:42 +0100 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2013-05-07 14:56:42 +0100 |
commit | 8b6665fe0383fd565ac7d7cd6a2bf6243ebc9937 (patch) | |
tree | ffa2ae68c2f87f19cbbd13b7e79a632a682202ee | |
parent | 3afd9c97310d58c0c6588d18887244328590731e (diff) | |
parent | f4af0d86e240948bb37a1d318d4e2559f04c6a79 (diff) | |
download | netsurf-8b6665fe0383fd565ac7d7cd6a2bf6243ebc9937.tar.gz netsurf-8b6665fe0383fd565ac7d7cd6a2bf6243ebc9937.tar.bz2 |
Merge branch 'master' of git://git.netsurf-browser.org/netsurf into tlsa/selection-search-refactor
-rw-r--r-- | Docs/env.sh | 11 | ||||
-rw-r--r-- | Makefile.defaults | 4 | ||||
-rw-r--r-- | content/content.c | 32 | ||||
-rw-r--r-- | content/llcache.c | 1 | ||||
-rw-r--r-- | css/dump.c | 4 | ||||
-rw-r--r-- | desktop/browser.c | 2 | ||||
-rw-r--r-- | desktop/cookies.c | 48 | ||||
-rw-r--r-- | desktop/history_global_core.c | 23 | ||||
-rw-r--r-- | desktop/hotlist.c | 40 | ||||
-rw-r--r-- | desktop/sslcert.c | 15 | ||||
-rw-r--r-- | desktop/tree.c | 106 | ||||
-rw-r--r-- | desktop/tree.h | 27 | ||||
-rw-r--r-- | desktop/tree_url_node.c | 47 | ||||
-rw-r--r-- | gtk/res/cookies.gtk3.ui | 1 | ||||
-rw-r--r-- | gtk/res/hotlist.gtk3.ui | 1 | ||||
-rw-r--r-- | gtk/res/tabcontents.gtk2.ui | 4 | ||||
-rw-r--r-- | gtk/window.c | 112 | ||||
-rw-r--r-- | resources/FatMessages | 6 | ||||
-rw-r--r-- | utils/fetch-transifex.pl | 124 | ||||
-rw-r--r-- | utils/filepath.c | 10 | ||||
-rw-r--r-- | utils/import-messages.pl | 301 | ||||
-rw-r--r-- | utils/utils.c | 38 |
22 files changed, 681 insertions, 276 deletions
diff --git a/Docs/env.sh b/Docs/env.sh index 5d6096353..db2729c0c 100644 --- a/Docs/env.sh +++ b/Docs/env.sh @@ -43,8 +43,10 @@ NS_GIT="git://git.netsurf-browser.org" NS_INTERNAL_LIBS="buildsystem libwapcaplet libparserutils libhubbub libdom libcss libnsgif libnsbmp libsvgtiny librosprite" # internal libraries only required by some frontends NS_FRONTEND_LIBS="libnsfb" +# internal libraries required for the risc os target abi +NS_RISCOS_LIBS="librufl libpencil" # tools required to build the browser -NS_TOOLS="nsgenjsbind" +NS_TOOLS="nsgenbind" # The browser itself NS_BROWSER="netsurf" @@ -53,6 +55,11 @@ NS_DEV_DEB="build-essential pkg-config git gperf" NS_TOOL_DEB="flex bison" NS_GTK_DEB="libgtk2.0-dev libcurl3-dev libmng-dev librsvg2-dev liblcms1-dev libjpeg-dev libmozjs-dev" +#add target specific libraries +if [ "x${TARGET_ABI}" = "xriscos" ]; then + NS_FRONTEND_LIBS="${NS_FRONTEND_LIBS} ${NS_RISCOS_LIBS}" +fi + # apt get commandline to install necessary dev packages ns-apt-get-install() { @@ -76,7 +83,7 @@ ns-pull() ns-clone() { mkdir -p ${TARGET_WORKSPACE} - for REPO in $(echo ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS} ${NS_TOOLS} ${NS_BROWSER}) ; do + for REPO in $(echo ${NS_INTERNAL_LIBS} ${NS_FRONTEND_LIBS} ${NS_RISCOS_LIBS} ${NS_TOOLS} ${NS_BROWSER}) ; do echo -n " GIT: Cloning ${REPO}: " if [ -f ${TARGET_WORKSPACE}/${REPO}/.git/config ]; then echo "Repository already present" diff --git a/Makefile.defaults b/Makefile.defaults index d8f5b9b0c..515f4a042 100644 --- a/Makefile.defaults +++ b/Makefile.defaults @@ -63,9 +63,9 @@ NETSURF_USE_VIDEO := NO # Enable NetSurf's use of spidermonkey for javascript # Valid options: YES, NO, AUTO -NETSURF_USE_JS := NO +NETSURF_USE_JS := AUTO # Javascript support in older debian/ubuntu versions -NETSURF_USE_MOZJS := NO +NETSURF_USE_MOZJS := AUTO # Enable NetSurf's use of libharu for PDF export and GTK printing support. # There is no auto-detection available for this, as it does not have a diff --git a/content/content.c b/content/content.c index 74abdbfab..9bf4312ef 100644 --- a/content/content.c +++ b/content/content.c @@ -92,6 +92,7 @@ nserror content__init(struct content *c, const content_handler *handler, if (fallback_charset != NULL) { c->fallback_charset = strdup(fallback_charset); if (c->fallback_charset == NULL) { + free(user_sentinel); return NSERROR_NOMEM; } } @@ -1349,39 +1350,33 @@ struct content *content_clone(struct content *c) */ nserror content__clone(const struct content *c, struct content *nc) { - struct content_user *user_sentinel; nserror error; - user_sentinel = calloc(1, sizeof(struct content_user)); - if (user_sentinel == NULL) { - return NSERROR_NOMEM; - } - error = llcache_handle_clone(c->llcache, &(nc->llcache)); if (error != NSERROR_OK) { return error; } - - llcache_handle_change_callback(nc->llcache, - content_llcache_callback, nc); + + llcache_handle_change_callback(nc->llcache, + content_llcache_callback, nc); nc->mime_type = lwc_string_ref(c->mime_type); nc->handler = c->handler; nc->status = c->status; - + nc->width = c->width; nc->height = c->height; nc->available_width = c->available_width; nc->quirks = c->quirks; - + if (c->fallback_charset != NULL) { nc->fallback_charset = strdup(c->fallback_charset); if (nc->fallback_charset == NULL) { return NSERROR_NOMEM; } } - + if (c->refresh != NULL) { nc->refresh = nsurl_ref(c->refresh); if (nc->refresh == NULL) { @@ -1392,21 +1387,24 @@ nserror content__clone(const struct content *c, struct content *nc) nc->time = c->time; nc->reformat_time = c->reformat_time; nc->size = c->size; - + if (c->title != NULL) { nc->title = strdup(c->title); if (nc->title == NULL) { return NSERROR_NOMEM; } } - + nc->active = c->active; - nc->user_list = user_sentinel; - + nc->user_list = calloc(1, sizeof(struct content_user)); + if (nc->user_list == NULL) { + return NSERROR_NOMEM; + } + memcpy(&(nc->status_message), &(c->status_message), 120); memcpy(&(nc->sub_status), &(c->sub_status), 80); - + nc->locked = c->locked; nc->total_size = c->total_size; nc->http_code = c->http_code; diff --git a/content/llcache.c b/content/llcache.c index 171ae15fc..938f1e8f6 100644 --- a/content/llcache.c +++ b/content/llcache.c @@ -1185,6 +1185,7 @@ static nserror llcache_object_add_user(llcache_object *object, { assert(user->next == NULL); assert(user->prev == NULL); + assert(user->handle != NULL); user->handle->object = object; diff --git a/css/dump.c b/css/dump.c index 1fe887400..fa34284e0 100644 --- a/css/dump.c +++ b/css/dump.c @@ -576,7 +576,7 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style) /* counter-increment */ val = css_computed_counter_increment(style, &counter); - if (counter == NULL) { + if ((val == CSS_COUNTER_INCREMENT_NONE) || (counter == NULL)) { fprintf(stream, "counter-increment: none "); } else { fprintf(stream, "counter-increment:"); @@ -596,7 +596,7 @@ void nscss_dump_computed_style(FILE *stream, const css_computed_style *style) /* counter-reset */ val = css_computed_counter_reset(style, &counter); - if (counter == NULL) { + if ((val == CSS_COUNTER_RESET_NONE) || (counter == NULL)) { fprintf(stream, "counter-reset: none "); } else { fprintf(stream, "counter-reset:"); diff --git a/desktop/browser.c b/desktop/browser.c index a02807eeb..12cc9c830 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -2889,6 +2889,8 @@ void browser_window_redraw_rect(struct browser_window *bw, int x, int y, void browser_window_page_drag_start(struct browser_window *bw, int x, int y) { + assert(bw != NULL); + browser_window_set_drag_type(bw, DRAGGING_PAGE_SCROLL, NULL); bw->drag_start_x = x; diff --git a/desktop/cookies.c b/desktop/cookies.c index 581e1cc5b..197b3fbd1 100644 --- a/desktop/cookies.c +++ b/desktop/cookies.c @@ -264,19 +264,12 @@ static struct node *cookies_create_cookie_node(struct node *parent, const struct cookie_data *data) { struct node *node; - char *name; - name = strdup(data->name); - if (name == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - return NULL; - } - - node = tree_create_leaf_node(cookies_tree, NULL, name, + node = tree_create_leaf_node(cookies_tree, + NULL, + data->name, false, false, false); if (node == NULL) { - free(name); return NULL; } @@ -329,44 +322,33 @@ static void cookies_schedule_callback(const void *scheduled_data) const struct cookie_data *data = scheduled_data; struct node *node = NULL; struct node *cookie_node = NULL; - char *domain_cp; assert(data != NULL); node = cookies_find(cookies_tree_root, data->domain); if (node == NULL) { - domain_cp = strdup(data->domain); - if (domain_cp == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - return; - } - /* ownership of domain_cp passed to tree, if node creation - * does not fail */ node = tree_create_folder_node(cookies_tree, - cookies_tree_root, domain_cp, + cookies_tree_root, + data->domain, false, false, false); if (node != NULL) { - tree_set_node_user_callback(node, cookies_node_callback, + tree_set_node_user_callback(node, + cookies_node_callback, NULL); tree_set_node_icon(cookies_tree, node, folder_icon); - - } else { - free(domain_cp); } } - if (node == NULL) - return; - - cookie_node = cookies_find(node, data->name); - if (cookie_node == NULL) - cookies_create_cookie_node(node, data); - else - cookies_update_cookie_node(cookie_node, data); + if (node != NULL) { + cookie_node = cookies_find(node, data->name); + if (cookie_node == NULL) { + cookies_create_cookie_node(node, data); + } else { + cookies_update_cookie_node(cookie_node, data); + } - return; + } } /** diff --git a/desktop/history_global_core.c b/desktop/history_global_core.c index 3222dc7b8..2a941e05d 100644 --- a/desktop/history_global_core.c +++ b/desktop/history_global_core.c @@ -175,33 +175,24 @@ static bool history_global_initialise_node(const char *title, time_t base, int days_back) { struct tm *full_time; - char *buffer; struct node *node; base += days_back * 60 * 60 * 24; if (title == NULL) { full_time = localtime(&base); - buffer = strdup(messages_get(weekday_msg_name[full_time->tm_wday])); - } else { - buffer = strdup(title); + title = messages_get(weekday_msg_name[full_time->tm_wday]); } - if (buffer == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - return false; - } - - node = tree_create_folder_node(NULL, NULL, buffer, - false, true, true); + node = tree_create_folder_node(NULL, NULL, title, false, true, true); if (node == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - free(buffer); + warn_user(messages_get_errorcode(NSERROR_NOMEM), 0); return false; } - if (folder_icon != NULL) + + if (folder_icon != NULL) { tree_set_node_icon(global_history_tree, node, folder_icon); + } + tree_set_node_user_callback(node, history_global_node_callback, NULL); global_history_base_node[global_history_base_node_count] = node; diff --git a/desktop/hotlist.c b/desktop/hotlist.c index e2386fc8e..20cc8ea26 100644 --- a/desktop/hotlist.c +++ b/desktop/hotlist.c @@ -121,7 +121,6 @@ bool hotlist_initialise(struct tree *tree, const char *hotlist_path, { struct node *node; const struct url_data *url_data; - char *name; int hlst_loop; /* Either load or create a hotlist */ @@ -143,18 +142,15 @@ bool hotlist_initialise(struct tree *tree, const char *hotlist_path, return true; } - /* failed to load hotlist file, use default list */ - name = strdup("NetSurf"); - if (name == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - return false; - } - node = tree_create_folder_node(hotlist_tree, hotlist_tree_root, - name, true, false, false); + node = tree_create_folder_node(hotlist_tree, + hotlist_tree_root, + messages_get("NetSurf"), + true, + false, + false); if (node == NULL) { - free(name); + warn_user(messages_get_errorcode(NSERROR_NOMEM), 0); return false; } @@ -373,14 +369,7 @@ void hotlist_collapse_addresses(void) void hotlist_add_folder(bool selected) { struct node *node, *parent = NULL; - struct node_element *element; - char *title = strdup("Untitled"); - if (title == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - return; - } creating_node = true; if (selected == true) { @@ -394,16 +383,21 @@ void hotlist_add_folder(bool selected) parent = tree_get_default_folder_node(hotlist_tree); } - node = tree_create_folder_node(hotlist_tree, parent, title, - true, false, false); + node = tree_create_folder_node(hotlist_tree, + parent, + messages_get("Untitled"), + true, + false, + false); if (node == NULL) { - free(title); + warn_user(messages_get_errorcode(NSERROR_NOMEM), 0); return; } + tree_set_node_user_callback(node, hotlist_node_callback, NULL); tree_set_node_icon(hotlist_tree, node, folder_icon); - element = tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL); - tree_start_edit(hotlist_tree, element); + tree_start_edit(hotlist_tree, + tree_node_find_element(node, TREE_ELEMENT_TITLE, NULL)); } /** diff --git a/desktop/sslcert.c b/desktop/sslcert.c index b7a424465..2b4d726e0 100644 --- a/desktop/sslcert.c +++ b/desktop/sslcert.c @@ -119,19 +119,22 @@ static node_callback_resp sslcert_node_callback(void *user_data, static struct node *sslcert_create_node(const struct ssl_cert_info *cert) { - struct node *node; + struct node *node = NULL; struct node_element *element; char *text; text = messages_get_buff("SSL_Certificate_Subject", cert->subject); - if (text == NULL) - return NULL; - - node = tree_create_leaf_node(NULL, NULL, text, false, false, false); - if (node == NULL) { + if (text != NULL) { + node = tree_create_leaf_node(NULL, + NULL, + text, + false, false, false); free(text); + } + if (node == NULL) { return NULL; } + tree_set_node_user_callback(node, sslcert_node_callback, NULL); /* add issuer node */ diff --git a/desktop/tree.c b/desktop/tree.c index af64be83b..c62793e02 100644 --- a/desktop/tree.c +++ b/desktop/tree.c @@ -117,7 +117,7 @@ struct node_element { struct node *parent; /**< Parent node */ node_element_type type; /**< Element type */ struct node_element_box box; /**< Element bounding box */ - const char *text; /**< Text for the element */ + char *text; /**< Text for the element */ void *bitmap; /**< Bitmap for the element */ struct node_element *next; /**< Next node element */ unsigned int flag; /**< Client specified flag for data @@ -233,26 +233,19 @@ struct tree *tree_create(unsigned int flags, const struct treeview_table *callbacks, void *client_data) { struct tree *tree; - char *title; tree = calloc(sizeof(struct tree), 1); if (tree == NULL) { LOG(("calloc failed")); - warn_user("NoMemory", 0); + warn_user(messages_get_errorcode(NSERROR_NOMEM), 0); return NULL; } - title = strdup("Root"); - if (title == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - free(tree); - return NULL; - } - tree->root = tree_create_folder_node(NULL, NULL, title, + tree->root = tree_create_folder_node(NULL, + NULL, + messages_get("Root"), false, false, false); if (tree->root == NULL) { - free(title); free(tree); return NULL; } @@ -553,18 +546,7 @@ static void tree_recalculate_node_sizes(struct tree *tree, struct node *node, } -/** - * Creates a folder node with the specified title, and optionally links it into - * the tree. - * - * \param tree the owner tree of 'parent', may be NULL - * \param parent the parent node, or NULL not to link - * \param title the node title (not copied, used directly) - * \param editable if true, the node title will be editable - * \param retain_in_memory if true, the node will stay in memory after deletion - * \param deleted if true, the node is created with the deleted flag - * \return the newly created node. - */ +/* exported interface documented in desktop/tree.h */ struct node *tree_create_folder_node(struct tree *tree, struct node *parent, const char *title, bool editable, bool retain_in_memory, bool deleted) @@ -575,16 +557,20 @@ struct node *tree_create_folder_node(struct tree *tree, struct node *parent, node = calloc(sizeof(struct node), 1); if (node == NULL) { - LOG(("calloc failed")); - warn_user("NoMemory", 0); return NULL; } + + node->data.text = strdup(title); + if (node->data.text == NULL) { + free(node); + return NULL; + } + node->folder = true; node->retain_in_memory = retain_in_memory; node->deleted = deleted; node->data.parent = node; node->data.type = NODE_ELEMENT_TEXT; - node->data.text = title; node->data.flag = TREE_ELEMENT_TITLE; node->data.editable = editable; node->sort = NULL; @@ -592,25 +578,14 @@ struct node *tree_create_folder_node(struct tree *tree, struct node *parent, node->previous = NULL; tree_recalculate_node_sizes(tree, node, true); - if (parent != NULL) + if (parent != NULL) { tree_link_node(tree, parent, node, false); + } return node; } - -/** - * Creates a leaf node with the specified title, and optionally links it into - * the tree. - * - * \param tree the owner tree of 'parent', may be NULL - * \param parent the parent node, or NULL not to link - * \param title the node title (not copied, used directly) - * \param editable if true, the node title will be editable - * \param retain_in_memory if true, the node will stay in memory after deletion - * \param deleted if true, the node is created with the deleted flag - * \return the newly created node. - */ +/* exported interface documented in desktop/tree.h */ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent, const char *title, bool editable, bool retain_in_memory, bool deleted) @@ -621,8 +596,12 @@ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent, node = calloc(sizeof(struct node), 1); if (node == NULL) { - LOG(("calloc failed")); - warn_user("NoMemory", 0); + return NULL; + } + + node->data.text = strdup(title); + if (node->data.text == NULL) { + free(node); return NULL; } @@ -631,7 +610,6 @@ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent, node->deleted = deleted; node->data.parent = node; node->data.type = NODE_ELEMENT_TEXT; - node->data.text = title; node->data.flag = TREE_ELEMENT_TITLE; node->data.editable = editable; node->sort = NULL; @@ -639,8 +617,9 @@ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent, node->previous = NULL; tree_recalculate_node_sizes(tree, node, true); - if (parent != NULL) + if (parent != NULL) { tree_link_node(tree, parent, node, false); + } return node; } @@ -1502,18 +1481,20 @@ void tree_update_node_element(struct tree *tree, struct node_element *element, assert(element != NULL); - if (tree != NULL && element == tree->editing) + if ((tree != NULL) && (element == tree->editing)) { tree_stop_edit(tree, false); + } - if (text != NULL && (element->type == NODE_ELEMENT_TEXT || - element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) { + if ((text != NULL) && + (element->type == NODE_ELEMENT_TEXT || + element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) { if (element->text != NULL) { - if(strcmp(element->text, text) == 0) text_changed = true; - + if (strcmp(element->text, text) == 0) { + text_changed = true; + } response = NODE_CALLBACK_NOT_HANDLED; - if (!element->editable && - element->parent->user_callback != - NULL) { + if ((!element->editable) && + (element->parent->user_callback != NULL)) { msg_data.msg = NODE_DELETE_ELEMENT_TXT; msg_data.flag = element->flag; msg_data.node = element->parent; @@ -1522,14 +1503,16 @@ void tree_update_node_element(struct tree *tree, struct node_element *element, element->parent->callback_data, &msg_data); } - if (response != NODE_CALLBACK_HANDLED) - free((void *)element->text); + if (response != NODE_CALLBACK_HANDLED) { + free(element->text); + } } - element->text = text; + element->text = (char *)text; } - if (bitmap != NULL && (element->type == NODE_ELEMENT_BITMAP || - element->type == NODE_ELEMENT_TEXT_PLUS_ICON)) { + if ((bitmap != NULL) && + ((element->type == NODE_ELEMENT_BITMAP) || + (element->type == NODE_ELEMENT_TEXT_PLUS_ICON))) { if (element->bitmap != NULL) { response = NODE_CALLBACK_NOT_HANDLED; if (element->parent->user_callback != NULL) { @@ -1541,10 +1524,11 @@ void tree_update_node_element(struct tree *tree, struct node_element *element, element->parent->callback_data, &msg_data); } - if (response != NODE_CALLBACK_HANDLED) + + if (response != NODE_CALLBACK_HANDLED) { free(element->bitmap); - } - else { + } + } else { /* Increase the box width to accomodate the new icon */ element->box.width += NODE_INSTEP; } diff --git a/desktop/tree.h b/desktop/tree.h index 8ac505783..00ac99984 100644 --- a/desktop/tree.h +++ b/desktop/tree.h @@ -137,12 +137,39 @@ void tree_setup_colours(void); struct tree *tree_create(unsigned int flags, const struct treeview_table *callbacks, void *client_data); + +/** + * Creates a folder node with the specified title, and optionally links it into + * the tree. + * + * \param tree the owner tree of 'parent', may be NULL + * \param parent the parent node, or NULL not to link + * \param title the node title + * \param editable if true, the node title will be editable + * \param retain_in_memory if true, the node will stay in memory after deletion + * \param deleted if true, the node is created with the deleted flag + * \return the newly created node or NULL on error. + */ struct node *tree_create_folder_node(struct tree *tree, struct node *parent, const char *title, bool editable, bool retain_in_memory, bool deleted); + +/** + * Creates a leaf node with the specified title, and optionally links it into + * the tree. + * + * \param tree the owner tree of 'parent', may be NULL + * \param parent the parent node, or NULL not to link + * \param title the node title. + * \param editable if true, the node title will be editable + * \param retain_in_memory if true, the node will stay in memory after deletion + * \param deleted if true, the node is created with the deleted flag + * \return the newly created node or NULL on error. + */ struct node *tree_create_leaf_node(struct tree *tree, struct node *parent, const char *title, bool editable, bool retain_in_memory, bool deleted); + struct node_element *tree_create_node_element(struct node *parent, node_element_type type, unsigned int flag, bool editable); void tree_link_node(struct tree *tree, struct node *link, struct node *node, diff --git a/desktop/tree_url_node.c b/desktop/tree_url_node.c index 76bc8a47c..938cd1d69 100644 --- a/desktop/tree_url_node.c +++ b/desktop/tree_url_node.c @@ -126,35 +126,41 @@ void tree_url_node_cleanup() * \param parent the node to link to * \param url the URL (copied) * \param data the URL data to use - * \param title the custom title to use + * \param title custom title to use or NULL to use url * \return the node created, or NULL for failure */ struct node *tree_create_URL_node(struct tree *tree, struct node *parent, nsurl *url, const char *title, tree_node_user_callback user_callback, void *callback_data) { - struct node *node; + struct node *node = NULL; struct node_element *element; - char *text_cp, *squashed; - squashed = squash_whitespace(title ? title : nsurl_access(url)); - text_cp = strdup(squashed); - if (text_cp == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - return NULL; + if (title == NULL) { + node = tree_create_leaf_node(tree, + parent, + nsurl_access(url), + true, false, false); + } else { + char *squashed; + + squashed = squash_whitespace(title); + if (squashed != NULL) { + node = tree_create_leaf_node(tree, + parent, + squashed, + true, false, false); + free(squashed); + } } - free(squashed); - node = tree_create_leaf_node(tree, parent, text_cp, true, false, - false); if (node == NULL) { - free(text_cp); return NULL; } - if (user_callback != NULL) + if (user_callback != NULL) { tree_set_node_user_callback(node, user_callback, callback_data); + } tree_create_node_element(node, NODE_ELEMENT_BITMAP, TREE_ELEMENT_THUMBNAIL, false); @@ -165,7 +171,7 @@ struct node *tree_create_URL_node(struct tree *tree, struct node *parent, element = tree_create_node_element(node, NODE_ELEMENT_TEXT, TREE_ELEMENT_URL, true); if (element != NULL) { - text_cp = strdup(nsurl_access(url)); + char *text_cp = strdup(nsurl_access(url)); if (text_cp == NULL) { tree_delete_node(tree, node, false); LOG(("malloc failed")); @@ -194,22 +200,18 @@ struct node *tree_create_URL_node_readonly(struct tree *tree, { struct node *node; struct node_element *element; - char *title; + const char *title; assert(url && data); if (data->title != NULL) { - title = strdup(data->title); + title = data->title; } else { - title = strdup(nsurl_access(url)); + title = nsurl_access(url); } - if (title == NULL) - return NULL; - node = tree_create_leaf_node(tree, parent, title, false, false, false); if (node == NULL) { - free(title); return NULL; } @@ -683,6 +685,7 @@ static bool tree_url_load_directory_cb(dom_node *node, void *ctx) dir = tree_create_folder_node(tctx->tree, tctx->directory, title, true, false, false); + free(title); if (dir == NULL) { dom_string_unref(name); return false; diff --git a/gtk/res/cookies.gtk3.ui b/gtk/res/cookies.gtk3.ui index 3ccc04bce..44dcb80b8 100644 --- a/gtk/res/cookies.gtk3.ui +++ b/gtk/res/cookies.gtk3.ui @@ -188,6 +188,7 @@ <property name="visible">True</property> <property name="app_paintable">True</property> <property name="can_focus">False</property> + <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property> </object> </child> </object> diff --git a/gtk/res/hotlist.gtk3.ui b/gtk/res/hotlist.gtk3.ui index 78a81672b..b0e075c4b 100644 --- a/gtk/res/hotlist.gtk3.ui +++ b/gtk/res/hotlist.gtk3.ui @@ -237,6 +237,7 @@ <object class="GtkDrawingArea" id="hotlistDrawingArea"> <property name="visible">True</property> <property name="can_focus">False</property> + <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property> </object> </child> </object> diff --git a/gtk/res/tabcontents.gtk2.ui b/gtk/res/tabcontents.gtk2.ui index e87249e74..63e290e8b 100644 --- a/gtk/res/tabcontents.gtk2.ui +++ b/gtk/res/tabcontents.gtk2.ui @@ -79,13 +79,13 @@ </object> <object class="GtkAdjustment" id="layouthadjustment"> <property name="upper">100</property> - <property name="step_increment">1</property> + <property name="step_increment">30</property> <property name="page_increment">10</property> <property name="page_size">10</property> </object> <object class="GtkAdjustment" id="layoutvadjustment"> <property name="upper">100</property> - <property name="step_increment">1</property> + <property name="step_increment">30</property> <property name="page_increment">10</property> <property name="page_size">10</property> </object> diff --git a/gtk/window.c b/gtk/window.c index 7642e3b82..663ff32a3 100644 --- a/gtk/window.c +++ b/gtk/window.c @@ -384,105 +384,91 @@ static gboolean nsgtk_window_button_release_event(GtkWidget *widget, return TRUE; } -static gboolean nsgtk_window_scroll_event(GtkWidget *widget, - GdkEventScroll *event, gpointer data) +static gboolean +nsgtk_window_scroll_event(GtkWidget *widget, + GdkEventScroll *event, + gpointer data) { struct gui_window *g = data; double value; + double deltax = 0; + double deltay = 0; GtkAdjustment *vscroll = nsgtk_layout_get_vadjustment(g->layout); GtkAdjustment *hscroll = nsgtk_layout_get_hadjustment(g->layout); GtkAllocation alloc; - LOG(("%d", event->direction)); switch (event->direction) { case GDK_SCROLL_LEFT: - if (browser_window_scroll_at_point(g->bw, - event->x / g->bw->scale, - event->y / g->bw->scale, - -100, 0) != true) { - /* core did not handle event do horizontal scroll */ - - value = gtk_adjustment_get_value(hscroll) - - (nsgtk_adjustment_get_step_increment(hscroll) *2); - - if (value < nsgtk_adjustment_get_lower(hscroll)) { - value = nsgtk_adjustment_get_lower(hscroll); - } - - gtk_adjustment_set_value(hscroll, value); - } + deltax = -1.0; break; case GDK_SCROLL_UP: - if (browser_window_scroll_at_point(g->bw, - event->x / g->bw->scale, - event->y / g->bw->scale, - 0, -100) != true) { - /* core did not handle event change vertical - * adjustment. - */ + deltay = -1.0; + break; - value = gtk_adjustment_get_value(vscroll) - - (nsgtk_adjustment_get_step_increment(vscroll) * 2); + case GDK_SCROLL_RIGHT: + deltax = 1.0; + break; - if (value < nsgtk_adjustment_get_lower(vscroll)) { - value = nsgtk_adjustment_get_lower(vscroll); - } + case GDK_SCROLL_DOWN: + deltay = 1.0; + break; - gtk_adjustment_set_value(vscroll, value); - } +#if GTK_CHECK_VERSION(3,4,0) + case GDK_SCROLL_SMOOTH: + gdk_event_get_scroll_deltas((GdkEvent *)event, &deltax, &deltay); break; +#endif + default: + LOG(("Unhandled mouse scroll direction")); + return TRUE; + } - case GDK_SCROLL_RIGHT: - if (browser_window_scroll_at_point(g->bw, - event->x / g->bw->scale, - event->y / g->bw->scale, - 100, 0) != true) { + deltax *= nsgtk_adjustment_get_step_increment(hscroll); + deltay *= nsgtk_adjustment_get_step_increment(vscroll); + + LOG(("Scrolling %f, %f", deltax, deltay)); - /* core did not handle event change horizontal - * adjustment. - */ + if (browser_window_scroll_at_point(g->bw, + event->x / g->bw->scale, + event->y / g->bw->scale, + deltax, deltay) != true) { - value = gtk_adjustment_get_value(hscroll) + - (nsgtk_adjustment_get_step_increment(hscroll) * 2); + /* core did not handle event so change adjustments */ + + /* Horizontal */ + if (deltax != 0) { + value = gtk_adjustment_get_value(hscroll) + deltax; /* @todo consider gtk_widget_get_allocated_width() */ nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); if (value > nsgtk_adjustment_get_upper(hscroll) - alloc.width) { - value = nsgtk_adjustment_get_upper(hscroll) - - alloc.width; + value = nsgtk_adjustment_get_upper(hscroll) - alloc.width; + } + if (value < nsgtk_adjustment_get_lower(hscroll)) { + value = nsgtk_adjustment_get_lower(hscroll); } gtk_adjustment_set_value(hscroll, value); } - break; - case GDK_SCROLL_DOWN: - if (browser_window_scroll_at_point(g->bw, - event->x / g->bw->scale, - event->y / g->bw->scale, - 0, 100) != true) { - /* core did not handle event change vertical - * adjustment. - */ - - value = gtk_adjustment_get_value(vscroll) + - (nsgtk_adjustment_get_step_increment(vscroll) * 2); + /* Vertical */ + if (deltay != 0) { + value = gtk_adjustment_get_value(vscroll) + deltay; + /* @todo consider gtk_widget_get_allocated_height */ nsgtk_widget_get_allocation(GTK_WIDGET(g->layout), &alloc); - if (value > nsgtk_adjustment_get_upper(vscroll) - alloc.height) { - value = nsgtk_adjustment_get_upper(vscroll) - - alloc.height; + if (value > (nsgtk_adjustment_get_upper(vscroll) - alloc.height)) { + value = nsgtk_adjustment_get_upper(vscroll) - alloc.height; + } + if (value < nsgtk_adjustment_get_lower(vscroll)) { + value = nsgtk_adjustment_get_lower(vscroll); } gtk_adjustment_set_value(vscroll, value); } - break; - - default: - break; } return TRUE; diff --git a/resources/FatMessages b/resources/FatMessages index 32acda877..82c64ce9c 100644 --- a/resources/FatMessages +++ b/resources/FatMessages @@ -2334,7 +2334,7 @@ nl.all.SSLCerts:SSL certificates en.all.SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below. de.all.SSLError:NetSurf konnte ein SSL Zertifikat nicht prüfen. Bitte die Details unten beachten. fr.all.SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below. -it.all.SSLError:NetSurf non è stato in grado di verificare l'autenticità di questo certificato SSL, per favore verifica i dettagli presenti di seguito +it.all.SSLError:NetSurf non è stato in grado di verificare l'autenticità di questo certificato SSL, per favore verifica i dettagli presenti di seguito nl.all.SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below. en.all.SSL_Certificate_Subject:Subject: %s de.all.SSL_Certificate_Subject:Subject: %s @@ -2744,7 +2744,7 @@ nl.all.HotlistSaveError:The hotlist was unable to be correctly saved. en.all.TreeLoadError:The tree was unable to be correctly loaded. de.all.TreeLoadError:The tree was unable to be correctly loaded. fr.all.TreeLoadError:The tree was unable to be correctly loaded. -it.all.TreeLoadError:L'albero non è stato caricato correttamente. +it.all.TreeLoadError:L'albero non è stato caricato correttamente. nl.all.TreeLoadError:The tree was unable to be correctly loaded. en.all.NoDirError:%s is not a directory de.all.NoDirError:%s ist kein Verzeichnis. @@ -5011,7 +5011,7 @@ nl.ro.HelpInterfaceConfig13:\Ssave these settings and close the \w.|M\Asave thes en.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist. de.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist. fr.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist. -it.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist. +it.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist. nl.ro.HelpInterfaceConfig16:This indicates whether NetSurf will use an external hotlist client if available, in preference to the internal hotlist. en.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist. de.ro.HelpInterfaceConfig18:\Tthe path to a hotlist application which will be used to display the hotlist. diff --git a/utils/fetch-transifex.pl b/utils/fetch-transifex.pl new file mode 100644 index 000000000..d8d588285 --- /dev/null +++ b/utils/fetch-transifex.pl @@ -0,0 +1,124 @@ +#!/usr/bin/perl +# +# Copyright © 2013 Vincent Sanders <vince@netsurf-browser.org> +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# * The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +=head1 + +retrive resource from transifex service + +=cut + +use strict; +use Getopt::Long (); +use LWP::UserAgent; +use JSON qw( decode_json ); +use Data::Dumper; +use Fcntl qw( O_CREAT O_EXCL O_WRONLY O_APPEND O_RDONLY O_WRONLY ); + +use constant GETOPT_OPTS => qw( auto_abbrev no_getopt_compat bundling ); +use constant GETOPT_SPEC => + qw( output|o=s + lang|l=s + resource|res|r=s + project|prj|p=s + user|u=s + password|w=s + help|h|? ); + +# default option values: +my %opt = qw( resource messagesany project netsurf user netsurf ); + +sub output_stream (); +sub usage (); + +sub main () +{ + my $output; + my $opt_ok; + + # option parsing: + Getopt::Long::Configure( GETOPT_OPTS ); + $opt_ok = Getopt::Long::GetOptions( \%opt, GETOPT_SPEC ); + + if( $opt_ok ) + { + $output = output_stream(); + } + + # double check the options are sane (and we weren't asked for the help) + if( !$opt_ok || $opt{help} || $opt{lang} !~ /^[a-z]{2}$/ ) + { + usage(); + } + + my $transifexurl = "https://www.transifex.com/api/2/project/" . $opt{project} . "/resource/" . $opt{resource} . "/translation/" . $opt{lang} . "/"; + + my $ua = LWP::UserAgent->new; + $ua->credentials( + 'www.transifex.com:443', + 'Transifex API', + $opt{user} => $opt{password} + ); + + my $response = $ua->get( $transifexurl ); + if (!$response->is_success) { + die $response->status_line . " When fetching " . $transifexurl; + } + + # Decode the entire JSON + my $decoded_json = decode_json( $response->decoded_content ); + + print ( $output $decoded_json->{'content'} ); +} + +main(); + +sub usage () +{ + print(STDERR <<TXT ); +usage: + $0 -l lang-code \ + [-o output-file] [-r resource] [-p project] [-u user] [-w password] + + lang-code : en fr ko ... (no default) + project : transifex project (default 'netsurf') + resource : transifex resource (default 'messagesany') + user : transifex resource (default 'netsurf') + password : transifex resource (no default) + output-file: defaults to standard output +TXT + exit(1); +} + +sub output_stream () +{ + if( $opt{output} ) + { + my $ofh; + + sysopen( $ofh, $opt{output}, O_CREAT|O_EXCL|O_APPEND|O_WRONLY ) || + die( "$0: Failed to open output file $opt{output}: $!\n" ); + + return $ofh; + } + + return \*STDOUT; +} diff --git a/utils/filepath.c b/utils/filepath.c index 21a965949..f0aa19585 100644 --- a/utils/filepath.c +++ b/utils/filepath.c @@ -89,21 +89,13 @@ char *filepath_sfindfile(char *str, const char *format, ...) /* exported interface documented in filepath.h */ char *filepath_findfile(const char *format, ...) { - char *str; char *ret; va_list ap; - str = malloc(PATH_MAX); - if (str == NULL) - return NULL; /* unable to allocate memory */ - va_start(ap, format); - ret = filepath_vsfindfile(str, format, ap); + ret = filepath_vsfindfile(NULL, format, ap); va_end(ap); - if (ret == NULL) - free(str); - return ret; } diff --git a/utils/import-messages.pl b/utils/import-messages.pl new file mode 100644 index 000000000..1c30e7fce --- /dev/null +++ b/utils/import-messages.pl @@ -0,0 +1,301 @@ +#!/usr/bin/perl +# +# Copyright © 2013 Vivek Dasmohapatra <vivek@collabora.co.uk> +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# * The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +=head1 + +Take a single-language messages file and merge it back in to the +NetSurf master messaged (i10n) file. + +=cut + +use strict; + +use Getopt::Long (); +use Fcntl qw( O_CREAT O_EXCL O_WRONLY O_APPEND O_RDONLY O_WRONLY O_TRUNC ); + +use constant GETOPT_OPTS => qw( auto_abbrev no_getopt_compat bundling ); +use constant GETOPT_SPEC => + qw( output|o=s + input|i=s + lang|l=s + plat|platform|p=s + format|fmt|f=s + import|I=s + help|h|? ); + +# default option values: +my %opt = qw( plat any format messages ); + +sub input_stream ($;$); +sub output_stream (); +sub usage (); +sub parser (); + +sub main () +{ + my $input; + my $output; + my $import; + my $parser; + my $opt_ok; + my @input; + my %message; + + # option parsing: + Getopt::Long::Configure( GETOPT_OPTS ); + $opt_ok = Getopt::Long::GetOptions( \%opt, GETOPT_SPEC ); + + # allow input, import & output to be specified as non-option arguments: + if( @ARGV ) { $opt{input } ||= shift( @ARGV ) } + if( @ARGV ) { $opt{import} ||= shift( @ARGV ) } + if( @ARGV ) { $opt{output} ||= shift( @ARGV ) } + + # open the appropriate streams and get the formatter and headers: + if( $opt_ok ) + { + $input = input_stream( $opt{input} ); + $import = input_stream( $opt{import}, 'import-file' ); + $parser = parser(); + $opt{plat} ||= 'any'; + } + + # double check the options are sane (and we weren't asked for the help) + if( !$opt_ok || $opt{help} || $opt{lang} !~ /^[a-z]{2}$/ ) + { + usage(); + } + + @input = <$input>; + $output = output_stream(); + + $parser->( \%message, $import ); + + foreach ( @input ) + { + use bytes; + + if( !/#/ && + !/^\s*$/ && + /^([a-z]{2})\.([^.]+)\.([^:]+):/ ) + { + my( $lang, $plat, $key ) = ( $1, $2, $3 ); + + if( $lang eq $opt{lang} ) + { + my $val = $message{ $key }; + if( $val && + ( $opt{plat} eq 'any' || # all platforms ok + $opt{plat} eq $plat ) ) # specified platform matched + { + print( $output $val ? qq|$1.$2.$3:$val\n| : $_ ); + next; + } + } + } + + print( $output $_ ); + } +} + +main(); + +sub usage () +{ + my @fmt = map { s/::$//; $_ } keys(%{$::{'msgfmt::'}}); + print( STDERR <<TXT ); +usage: + $0 -l lang-code \ + [-p platform] [-f format] \ + [-o output-file] [-i input-file] [-I import-file] + + $0 -l lang-code … [input-file [import-file [output-file]]] + + lang-code : en fr ko … (no default) + platform : any gtk ami (default 'any') + format : @fmt (default 'messages') + input-file : defaults to standard input + output-file: defaults to standard output + import-file: no default + + The input-file may be the same as the output-file, in which case + it will be altered in place. +TXT + exit(1); +} + +sub input_stream ($;$) +{ + my $file = shift(); + my $must_exist = shift(); + + if( $file ) + { + my $ifh; + + sysopen( $ifh, $file, O_RDONLY ) || + die( "$0: Failed to open input file $file: $!\n" ); + + return $ifh; + } + + if( $must_exist ) + { + print( STDERR "No file specified for $must_exist\n" ); + usage(); + } + + return \*STDIN; +} + +sub output_stream () +{ + if( $opt{output} ) + { + my $ofh; + + sysopen( $ofh, $opt{output}, O_CREAT|O_TRUNC|O_WRONLY ) || + die( "$0: Failed to open output file $opt{output}: $!\n" ); + + return $ofh; + } + + return \*STDOUT; +} + +sub parser () +{ + my $name = $opt{format}; + my $func = "msgfmt::$name"->UNIVERSAL::can("parse"); + + return $func || die( "No handler found for format '$name'\n" ); +} + +# format implementations: +{ + package msgfmt::java; + + sub unescape { $_[0] =~ s/\\([\\':])/$1/g; $_[0] } + sub parse + { + my $cache = shift(); + my $stream = shift(); + + while ( <$stream> ) + { + if( /(\S+)\s*=\s?(.*)/ ) + { + my $key = $1; + my $val = $2; + $cache->{ $key } = unescape( $val ); + } + } + } +} + +{ + package msgfmt::messages; # native netsurf format + + sub parse + { + my $cache = shift(); + my $stream = shift(); + + while ( <$stream> ) + { + if( /^([a-z]{2})\.([^.]+)\.([^:]+):(.*)/ ) + { + my( $lang, $plat, $key, $val ) = ( $1, $2, $3, $4 ); + + if( $lang ne $opt{lang} ) { next } + if( $opt{plat} ne 'any' && + $opt{plat} ne $plat && + 'all' ne $plat ) { next } + + $cache->{ $key } = $val; + } + } + } +} + +{ + package msgfmt::transifex; + use base 'msgfmt::java'; + + # the differences between transifex and java properties only matter in + # the outward direction: During import they can be treated the same way +} + +{ + package msgfmt::android; + + ANDROID_XML: + { + package msgfmt::android::xml; + + my @stack; + my $data; + my $key; + our $cache; + + sub StartDocument ($) { @stack = (); $key = '' } + sub Text ($) { if( $key ) { $data .= $_ } } + sub PI ($$$) { } + sub EndDocument ($) { } + + sub EndTag ($$) + { + pop( @stack ); + + if( !$key ) { return; } + + $cache->{ $key } = $data; + $data = $key = ''; + } + + sub StartTag ($$) + { + push( @stack, $_[1] ); + + if( "@stack" eq "resources string" ) + { + $data = ''; + $key = $_{ name }; + } + } + } + + sub parse + { + require XML::Parser; + + if( !$XML::Parser::VERSION ) + { + die("XML::Parser required for android format support\n"); + } + + $msgfmt::android::xml::cache = shift(); + my $stream = shift(); + my $parser = XML::Parser->new( Style => 'Stream', + Pkg => 'msgfmt::android::xml' ); + $parser->parse( $stream ); + } +} diff --git a/utils/utils.c b/utils/utils.c index 3398a7df8..8155f4af1 100644 --- a/utils/utils.c +++ b/utils/utils.c @@ -98,26 +98,34 @@ char *remove_underscores(const char *s, bool replacespace) /** * Replace consecutive whitespace with a single space. * + * @todo determine if squash_whitespace utf-8 safe and that it needs to be + * * \param s source string - * \return heap allocated result, or 0 on memory exhaustion + * \return heap allocated result, or NULL on memory exhaustion */ -char * squash_whitespace(const char *s) +char *squash_whitespace(const char *s) { - char *c = malloc(strlen(s) + 1); + char *c; int i = 0, j = 0; - if (!c) - return 0; - do { - if (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' || - s[i] == '\t') { - c[j++] = ' '; - while (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' || - s[i] == '\t') - i++; - } - c[j++] = s[i++]; - } while (s[i - 1] != 0); + + c = malloc(strlen(s) + 1); + if (c != NULL) { + do { + if (s[i] == ' ' || + s[i] == '\n' || + s[i] == '\r' || + s[i] == '\t') { + c[j++] = ' '; + while (s[i] == ' ' || + s[i] == '\n' || + s[i] == '\r' || + s[i] == '\t') + i++; + } + c[j++] = s[i++]; + } while (s[i - 1] != 0); + } return c; } |