diff options
-rw-r--r-- | content/dirlist.c | 3 | ||||
-rw-r--r-- | content/dirlist.h | 2 | ||||
-rw-r--r-- | content/fetchers/file.c | 19 | ||||
-rw-r--r-- | riscos/window.c | 54 | ||||
-rw-r--r-- | utils/nsurl.c | 114 | ||||
-rw-r--r-- | utils/nsurl.h | 17 | ||||
-rw-r--r-- | utils/url.c | 49 | ||||
-rw-r--r-- | utils/url.h | 1 |
8 files changed, 165 insertions, 94 deletions
diff --git a/content/dirlist.c b/content/dirlist.c index 8ed977239..433e21026 100644 --- a/content/dirlist.c +++ b/content/dirlist.c @@ -177,7 +177,8 @@ bool dirlist_generate_title(const char *title, char *buffer, int buffer_length) * dirlist_generate_bottom() */ -bool dirlist_generate_parent_link(char *parent, char *buffer, int buffer_length) +bool dirlist_generate_parent_link(const char *parent, char *buffer, + int buffer_length) { int error = snprintf(buffer, buffer_length, "<p><a href=\"%s\">%s</a></p>", diff --git a/content/dirlist.h b/content/dirlist.h index 7228ae231..bf90ec6d4 100644 --- a/content/dirlist.h +++ b/content/dirlist.h @@ -36,7 +36,7 @@ bool dirlist_generate_top(char *buffer, int buffer_length); bool dirlist_generate_hide_columns(int flags, char *buffer, int buffer_length); bool dirlist_generate_title(const char *title, char *buffer, int buffer_length); -bool dirlist_generate_parent_link(char *parent, char *buffer, +bool dirlist_generate_parent_link(const char *parent, char *buffer, int buffer_length); bool dirlist_generate_headings(char *buffer, int buffer_length); bool dirlist_generate_row(bool even, bool directory, char *url, char *name, diff --git a/content/fetchers/file.c b/content/fetchers/file.c index 73bfbdb3b..4c02c0c60 100644 --- a/content/fetchers/file.c +++ b/content/fetchers/file.c @@ -48,6 +48,7 @@ #include "content/urldb.h" #include "desktop/netsurf.h" #include "desktop/options.h" +#include "utils/errors.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/url.h" @@ -493,10 +494,9 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx, char buffer[1024]; /* Output buffer */ bool even = false; /* formatting flag */ char *title; /* pretty printed title */ - url_func_result res; /* result from url routines */ - char *up; /* url of parent */ + nserror err; /* result from url routines */ + nsurl *up; /* url of parent */ char *path; /* url for list entries */ - bool compare; /* result of url compare */ DIR *scandir; /* handle for enumerating the directory */ struct dirent* ent; /* leaf directory entry */ @@ -541,16 +541,17 @@ static void fetch_file_process_dir(struct fetch_file_context *ctx, goto fetch_file_process_dir_aborted; /* Print parent directory link */ - res = url_parent(nsurl_access(ctx->url), &up); - if (res == URL_FUNC_OK) { - res = url_compare(nsurl_access(ctx->url), up, false, &compare); - if ((res == URL_FUNC_OK) && compare == false) { - dirlist_generate_parent_link(up, buffer, sizeof buffer); + err = nsurl_parent(ctx->url, &up); + if (err == NSERROR_OK) { + if (nsurl_compare(ctx->url, up, NSURL_COMPLETE) == false) { + /* different URL; have parent */ + dirlist_generate_parent_link(nsurl_access(up), + buffer, sizeof buffer); msg.data.header_or_data.len = strlen(buffer); fetch_file_send_callback(&msg, ctx); } - free(up); + nsurl_unref(up); if (ctx->aborted) goto fetch_file_process_dir_aborted; diff --git a/riscos/window.c b/riscos/window.c index b7fffd66b..535105459 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -3709,23 +3709,18 @@ bool ro_gui_window_content_export_types(hlcache_handle *h, bool ro_gui_window_up_available(struct browser_window *bw) { - bool result = false, compare; - char *parent; - url_func_result res; + bool result = false; + nsurl *parent; + nserror err; if (bw != NULL && bw->current_content != NULL) { - res = url_parent(nsurl_access(hlcache_handle_get_url( - bw->current_content)), &parent); - - if (res == URL_FUNC_OK) { - res = url_compare(nsurl_access(hlcache_handle_get_url( - bw->current_content)), - parent, false, &compare); - if (res == URL_FUNC_OK) - result = !compare; - free(parent); - } else { - result = false; + err = nsurl_parent(hlcache_handle_get_url( + bw->current_content), &parent); + if (err == NSERROR_OK) { + result = nsurl_compare(hlcache_handle_get_url( + bw->current_content), parent, + NSURL_COMPLETE) == false; + nsurl_unref(parent); } } @@ -3863,21 +3858,30 @@ void ro_gui_window_launch_url(struct gui_window *g, const char *url) * \param g the gui_window to open the parent link in * \param url the URL to open the parent of */ -bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) { - char *parent; - url_func_result res; - bool compare; +bool ro_gui_window_navigate_up(struct gui_window *g, const char *url) +{ + nsurl *current, *parent; + nserror err; if (!g || (!g->bw)) return false; - res = url_parent(url, &parent); - if (res == URL_FUNC_OK) { - res = url_compare(url, parent, false, &compare); - if ((res == URL_FUNC_OK) && !compare) - browser_window_go(g->bw, parent, 0, true); - free(parent); + err = nsurl_create(url, ¤t); + if (err != NSERROR_OK) + return false; + + err = nsurl_parent(current, &parent); + if (err != NSERROR_OK) { + nsurl_unref(current); + return false; + } + + if (nsurl_compare(current, parent, NSURL_COMPLETE) == false) { + browser_window_go(g->bw, nsurl_access(parent), 0, true); } + + nsurl_unref(current); + nsurl_unref(parent); return true; } diff --git a/utils/nsurl.c b/utils/nsurl.c index 80c364654..7236fcba4 100644 --- a/utils/nsurl.c +++ b/utils/nsurl.c @@ -1184,28 +1184,31 @@ static void nsurl_get_string(const struct nsurl_components *url, char *url_s, static void nsurl__dump(const nsurl *url) { if (url->components.scheme) - LOG((" Scheme: %s", lwc_string_data(url->scheme))); + LOG((" Scheme: %s", lwc_string_data(url->components.scheme))); if (url->components.username) - LOG(("Username: %s", lwc_string_data(url->username))); + LOG(("Username: %s", + lwc_string_data(url->components.username))); if (url->components.password) - LOG(("Password: %s", lwc_string_data(url->password))); + LOG(("Password: %s", + lwc_string_data(url->components.password))); if (url->components.host) - LOG((" Host: %s", lwc_string_data(url->host))); + LOG((" Host: %s", lwc_string_data(url->components.host))); if (url->components.port) - LOG((" Port: %s", lwc_string_data(url->port))); + LOG((" Port: %s", lwc_string_data(url->components.port))); if (url->components.path) - LOG((" Path: %s", lwc_string_data(url->path))); + LOG((" Path: %s", lwc_string_data(url->components.path))); if (url->components.query) - LOG((" Query: %s", lwc_string_data(url->query))); + LOG((" Query: %s", lwc_string_data(url->components.query))); if (url->components.fragment) - LOG(("Fragment: %s", lwc_string_data(url->fragment))); + LOG(("Fragment: %s", + lwc_string_data(url->components.fragment))); } #endif @@ -1893,3 +1896,98 @@ nserror nsurl_refragment(const nsurl *url, lwc_string *frag, nsurl **new_url) return NSERROR_OK; } + +/* exported interface, documented in nsurl.h */ +nserror nsurl_parent(const nsurl *url, nsurl **new_url) +{ + lwc_string *lwc_path; + size_t old_path_len, new_path_len; + size_t len; + const char* path = NULL; + char *pos; + + assert(url != NULL); + + old_path_len = (url->components.path == NULL) ? 0 : + lwc_string_length(url->components.path); + + /* Find new path length */ + if (old_path_len == 0) { + new_path_len = old_path_len; + } else { + path = lwc_string_data(url->components.path); + + new_path_len = old_path_len; + if (old_path_len > 1) { + /* Skip over any trailing / */ + if (path[new_path_len - 1] == '/') + new_path_len--; + + /* Work back to next / */ + while (new_path_len > 0 && + path[new_path_len - 1] != '/') + new_path_len--; + } + } + + /* Find the length of new_url */ + len = url->length; + if (url->components.query != NULL) { + len -= lwc_string_length(url->components.query); + } + if (url->components.fragment != NULL) { + len -= 1; /* # */ + len -= lwc_string_length(url->components.fragment); + } + len -= old_path_len - new_path_len; + + /* Create NetSurf URL object */ + *new_url = malloc(sizeof(nsurl) + len + 1); /* Add 1 for \0 */ + if (*new_url == NULL) { + return NSERROR_NOMEM; + } + + /* Make new path */ + if (old_path_len == 0) { + lwc_path = NULL; + } else if (old_path_len == new_path_len) { + lwc_path = lwc_string_ref(url->components.path); + } else { + if (lwc_intern_string(path, old_path_len - new_path_len, + &lwc_path) != lwc_error_ok) { + free(*new_url); + return NSERROR_NOMEM; + } + } + + (*new_url)->length = len; + + /* Set string */ + pos = (*new_url)->string; + memcpy(pos, url->string, len); + pos += len; + *pos = '\0'; + + /* Copy components */ + (*new_url)->components.scheme = + nsurl__component_copy(url->components.scheme); + (*new_url)->components.username = + nsurl__component_copy(url->components.username); + (*new_url)->components.password = + nsurl__component_copy(url->components.password); + (*new_url)->components.host = + nsurl__component_copy(url->components.host); + (*new_url)->components.port = + nsurl__component_copy(url->components.port); + (*new_url)->components.path = lwc_path; + (*new_url)->components.query = NULL; + (*new_url)->components.fragment = NULL; + + (*new_url)->components.scheme_type = url->components.scheme_type; + + /* Give the URL a reference */ + (*new_url)->count = 1; + + return NSERROR_OK; +} + diff --git a/utils/nsurl.h b/utils/nsurl.h index 96e7a76f8..3b140e7ac 100644 --- a/utils/nsurl.h +++ b/utils/nsurl.h @@ -241,4 +241,21 @@ nserror nsurl_defragment(const nsurl *url, nsurl **no_frag); */ nserror nsurl_refragment(const nsurl *url, lwc_string *frag, nsurl **new_url); + +/** + * Create a NetSurf URL object for URL with parent location of an existing URL. + * + * \param url NetSurf URL to create new NetSurf URL from + * \param new_url Returns new NetSurf URL with parent URL path + * \return NSERROR_OK on success, appropriate error otherwise + * + * If return value != NSERROR_OK, nothing will be returned in new_url. + * + * It is up to the client to call nsurl_destroy when they are finished with + * the created object. + * + * As well as stripping top most path segment, query and fragments are stripped. + */ +nserror nsurl_parent(const nsurl *url, nsurl **new_url); + #endif diff --git a/utils/url.c b/utils/url.c index d0be77bce..84c62882a 100644 --- a/utils/url.c +++ b/utils/url.c @@ -483,55 +483,6 @@ url_func_result url_canonical_root(const char *url, char **result) /** - * Strip the topmost segment of the path - * - * \param url an absolute URL - * \param result pointer to pointer to buffer to hold result - * \return URL_FUNC_OK on success - */ - -url_func_result url_parent(const char *url, char **result) -{ - url_func_result status; - struct url_components components; - int len, path_len; - - assert(url); - - status = url_get_components(url, &components); - if (status == URL_FUNC_OK) { - if ((!components.scheme) || (!components.authority) || - (!components.path)) { - status = URL_FUNC_FAILED; - } else { - if (strcmp(components.path, "/")) { - path_len = strlen(components.path); - if (components.path[path_len - 1] == '/') - path_len--; - while (components.path[path_len - 1] != '/') - path_len--; - } else { - path_len = 1; - } - len = strlen(components.scheme) + - strlen(components.authority) + - path_len + 4; - *result = malloc(len); - if (!(*result)) - status = URL_FUNC_NOMEM; - else - snprintf((*result), len, "%s://%s%s", - components.scheme, - components.authority, - components.path); - } - } - url_destroy_components(&components); - return status; -} - - -/** * Extract path segment from an URL * * \param url an absolute URL diff --git a/utils/url.h b/utils/url.h index e0509ffdb..95790335c 100644 --- a/utils/url.h +++ b/utils/url.h @@ -57,7 +57,6 @@ url_func_result url_escape(const char *unescaped, size_t toskip, bool sptoplus, const char *escexceptions, char **result); url_func_result url_unescape(const char *str, char **result); url_func_result url_canonical_root(const char *url, char **result); -url_func_result url_parent(const char *url, char **result); url_func_result url_path(const char *url, char **result); url_func_result url_compare(const char *url1, const char *url2, bool nofrag, bool *result); |