summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/dirlist.c3
-rw-r--r--content/dirlist.h2
-rw-r--r--content/fetchers/file.c19
-rw-r--r--riscos/window.c54
-rw-r--r--utils/nsurl.c114
-rw-r--r--utils/nsurl.h17
-rw-r--r--utils/url.c49
-rw-r--r--utils/url.h1
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, &current);
+ 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);