mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 12:12:35 +03:00
Store URLs explicitly in URL database for faster access.
Iteration callbacks now passed url_data struct to remove need to look up svn path=/trunk/netsurf/; revision=2522
This commit is contained in:
parent
c3da525dbc
commit
e0ba508992
341
content/urldb.c
341
content/urldb.c
@ -119,6 +119,7 @@ struct url_internal_data {
|
||||
};
|
||||
|
||||
struct path_data {
|
||||
char *url; /**< Full URL */
|
||||
char *scheme; /**< URL scheme for data */
|
||||
unsigned int port; /**< Port number for data */
|
||||
char *segment; /**< Path segment for this node */
|
||||
@ -126,7 +127,7 @@ struct path_data {
|
||||
char **fragment; /**< Array of fragments */
|
||||
|
||||
struct bitmap *thumb; /**< Thumbnail image of resource */
|
||||
struct url_internal_data url; /**< URL data for resource */
|
||||
struct url_internal_data urld; /**< URL data for resource */
|
||||
struct auth_data auth; /**< Authentication data for resource */
|
||||
struct cookie *cookies; /**< Cookies associated with resource */
|
||||
|
||||
@ -173,17 +174,17 @@ static void urldb_write_paths(const struct path_data *parent,
|
||||
|
||||
/* Iteration */
|
||||
static bool urldb_iterate_partial_host(struct search_node *root,
|
||||
const char *prefix, bool (*callback)(const char *url));
|
||||
const char *prefix, bool (*callback)(const char *url,
|
||||
const struct url_data *data));
|
||||
static bool urldb_iterate_partial_path(const struct path_data *parent,
|
||||
const char *host, const char *prefix,
|
||||
char **path, int *path_alloc, int *path_used,
|
||||
bool (*callback)(const char *url));
|
||||
const char *prefix, bool (*callback)(const char *url,
|
||||
const struct url_data *data));
|
||||
static bool urldb_iterate_entries_host(struct search_node *parent,
|
||||
bool (*callback)(const char *url));
|
||||
static bool urldb_iterate_entries_path(const char *host, char **path,
|
||||
int *path_alloc, int *path_used,
|
||||
const struct path_data *parent,
|
||||
bool (*callback)(const char *url));
|
||||
bool (*callback)(const char *url,
|
||||
const struct url_data *data));
|
||||
static bool urldb_iterate_entries_path(const struct path_data *parent,
|
||||
bool (*callback)(const char *url,
|
||||
const struct url_data *data));
|
||||
|
||||
/* Insertion */
|
||||
static struct host_part *urldb_add_host_node(const char *part,
|
||||
@ -194,7 +195,8 @@ static struct path_data *urldb_add_path_node(const char *scheme,
|
||||
struct path_data *parent);
|
||||
static struct path_data *urldb_add_path(const char *scheme,
|
||||
unsigned int port, const struct host_part *host,
|
||||
const char *path, const char *fragment);
|
||||
const char *path, const char *fragment,
|
||||
const char *url_no_frag);
|
||||
static int urldb_add_path_fragment_cmp(const void *a, const void *b);
|
||||
static struct path_data *urldb_add_path_fragment(struct path_data *segment,
|
||||
const char *fragment);
|
||||
@ -251,6 +253,7 @@ void urldb_load(const char *filename)
|
||||
{
|
||||
#define MAXIMUM_URL_LENGTH 4096
|
||||
char s[MAXIMUM_URL_LENGTH];
|
||||
char host[256];
|
||||
struct host_part *h;
|
||||
int urls;
|
||||
int i;
|
||||
@ -280,10 +283,10 @@ void urldb_load(const char *filename)
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(s, MAXIMUM_URL_LENGTH, fp)) {
|
||||
while (fgets(host, sizeof host, fp)) {
|
||||
/* get the hostname */
|
||||
length = strlen(s) - 1;
|
||||
s[length] = '\0';
|
||||
length = strlen(host) - 1;
|
||||
host[length] = '\0';
|
||||
|
||||
/* skip data that has ended up with a host of '' */
|
||||
if (length == 0) {
|
||||
@ -297,7 +300,7 @@ void urldb_load(const char *filename)
|
||||
continue;
|
||||
}
|
||||
|
||||
h = urldb_add_host(s);
|
||||
h = urldb_add_host(host);
|
||||
if (!h)
|
||||
die("Memory exhausted whilst loading URL file");
|
||||
|
||||
@ -318,7 +321,8 @@ void urldb_load(const char *filename)
|
||||
urldb_add_url(s);
|
||||
p = urldb_find_url(s);
|
||||
} else {
|
||||
char scheme[64];
|
||||
char scheme[64], ports[6];
|
||||
char url[64 + 3 + 256 + 6 + 4096 + 1];
|
||||
unsigned int port;
|
||||
|
||||
if (!fgets(scheme, sizeof scheme, fp))
|
||||
@ -326,32 +330,40 @@ void urldb_load(const char *filename)
|
||||
length = strlen(scheme) - 1;
|
||||
scheme[length] = '\0';
|
||||
|
||||
if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
|
||||
if (!fgets(ports, sizeof ports, fp))
|
||||
break;
|
||||
port = atoi(s);
|
||||
length = strlen(ports) - 1;
|
||||
ports[length] = '\0';
|
||||
port = atoi(ports);
|
||||
|
||||
if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
|
||||
break;
|
||||
length = strlen(s) - 1;
|
||||
s[length] = '\0';
|
||||
|
||||
p = urldb_add_path(scheme, port, h, s, NULL);
|
||||
sprintf(url, "%s://%s%s%s%s", scheme, host,
|
||||
(port ? ":" : ""),
|
||||
(port ? ports : ""),
|
||||
s);
|
||||
|
||||
p = urldb_add_path(scheme, port, h, s, NULL,
|
||||
url);
|
||||
}
|
||||
|
||||
if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
|
||||
break;
|
||||
if (p)
|
||||
p->url.visits = (unsigned int)atoi(s);
|
||||
p->urld.visits = (unsigned int)atoi(s);
|
||||
|
||||
if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
|
||||
break;
|
||||
if (p)
|
||||
p->url.last_visit = (time_t)atoi(s);
|
||||
p->urld.last_visit = (time_t)atoi(s);
|
||||
|
||||
if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
|
||||
break;
|
||||
if (p)
|
||||
p->url.type = (content_type)atoi(s);
|
||||
p->urld.type = (content_type)atoi(s);
|
||||
|
||||
if (!fgets(s, MAXIMUM_URL_LENGTH, fp))
|
||||
break;
|
||||
@ -371,9 +383,9 @@ void urldb_load(const char *filename)
|
||||
length = strlen(s) - 1;
|
||||
if (p && length > 0) {
|
||||
s[length] = '\0';
|
||||
p->url.title = malloc(length + 1);
|
||||
if (p->url.title)
|
||||
memcpy(p->url.title, s, length + 1);
|
||||
p->urld.title = malloc(length + 1);
|
||||
if (p->urld.title)
|
||||
memcpy(p->urld.title, s, length + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -476,8 +488,8 @@ void urldb_count_urls(const struct path_data *root, time_t expiry,
|
||||
const struct path_data *p;
|
||||
|
||||
if (!root->children) {
|
||||
if ((root->url.last_visit > expiry) &&
|
||||
(root->url.visits > 0))
|
||||
if ((root->urld.last_visit > expiry) &&
|
||||
(root->urld.visits > 0))
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
@ -506,8 +518,8 @@ void urldb_write_paths(const struct path_data *parent, const char *host,
|
||||
|
||||
if (!parent->children) {
|
||||
/* leaf node */
|
||||
if (!((parent->url.last_visit > expiry) &&
|
||||
(parent->url.visits > 0)))
|
||||
if (!((parent->urld.last_visit > expiry) &&
|
||||
(parent->urld.visits > 0)))
|
||||
/* expired */
|
||||
return;
|
||||
|
||||
@ -522,9 +534,9 @@ void urldb_write_paths(const struct path_data *parent, const char *host,
|
||||
|
||||
/** \todo handle fragments? */
|
||||
|
||||
fprintf(fp, "%i\n%i\n%i\n", parent->url.visits,
|
||||
(int)parent->url.last_visit,
|
||||
(int)parent->url.type);
|
||||
fprintf(fp, "%i\n%i\n%i\n", parent->urld.visits,
|
||||
(int)parent->urld.last_visit,
|
||||
(int)parent->urld.type);
|
||||
|
||||
#ifdef riscos
|
||||
if (parent->thumb)
|
||||
@ -535,14 +547,14 @@ void urldb_write_paths(const struct path_data *parent, const char *host,
|
||||
fprintf(fp, "\n");
|
||||
#endif
|
||||
|
||||
if (parent->url.title) {
|
||||
char *s = parent->url.title;
|
||||
if (parent->urld.title) {
|
||||
char *s = parent->urld.title;
|
||||
for (i = 0; s[i] != '\0'; i++)
|
||||
if (s[i] < 32)
|
||||
s[i] = ' ';
|
||||
for (--i; ((i > 0) && (s[i] == ' ')); i--)
|
||||
s[i] = '\0';
|
||||
fprintf(fp, "%s\n", parent->url.title);
|
||||
fprintf(fp, "%s\n", parent->urld.title);
|
||||
} else
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
@ -586,30 +598,42 @@ bool urldb_add_url(const char *url)
|
||||
{
|
||||
struct host_part *h;
|
||||
struct path_data *p;
|
||||
char *fragment = NULL, *host, *plq, *scheme, *colon;
|
||||
char *fragment = NULL, *host, *plq, *scheme, *colon, *urlt;
|
||||
unsigned short port;
|
||||
url_func_result ret;
|
||||
|
||||
assert(url);
|
||||
|
||||
/** \todo consider file: URLs */
|
||||
|
||||
host = strchr(url, '#');
|
||||
urlt = strdup(url);
|
||||
if (!urlt)
|
||||
return false;
|
||||
|
||||
host = strchr(urlt, '#');
|
||||
if (host) {
|
||||
*host = '\0';
|
||||
fragment = strdup(host+1);
|
||||
if (!fragment)
|
||||
if (!fragment) {
|
||||
free(urlt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* extract host */
|
||||
ret = url_host(url, &host);
|
||||
if (ret != URL_FUNC_OK)
|
||||
if (ret != URL_FUNC_OK) {
|
||||
free(fragment);
|
||||
free(urlt);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* extract path, leafname, query */
|
||||
ret = url_plq(url, &plq);
|
||||
if (ret != URL_FUNC_OK) {
|
||||
free(host);
|
||||
free(fragment);
|
||||
free(urlt);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -619,6 +643,7 @@ bool urldb_add_url(const char *url)
|
||||
free(plq);
|
||||
free(host);
|
||||
free(fragment);
|
||||
free(urlt);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -637,19 +662,23 @@ bool urldb_add_url(const char *url)
|
||||
free(plq);
|
||||
free(host);
|
||||
free(fragment);
|
||||
free(urlt);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Get path entry */
|
||||
p = urldb_add_path(scheme, port, h, plq, fragment);
|
||||
p = urldb_add_path(scheme, port, h, plq, fragment, urlt);
|
||||
if (!p) {
|
||||
free(scheme);
|
||||
free(plq);
|
||||
free(host);
|
||||
free(fragment);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
free(scheme);
|
||||
free(plq);
|
||||
free(host);
|
||||
free(fragment);
|
||||
free(urlt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -674,8 +703,8 @@ void urldb_set_url_title(const char *url, const char *title)
|
||||
if (!temp)
|
||||
return;
|
||||
|
||||
free(p->url.title);
|
||||
p->url.title = temp;
|
||||
free(p->urld.title);
|
||||
p->urld.title = temp;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -694,7 +723,7 @@ void urldb_set_url_content_type(const char *url, content_type type)
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
p->url.type = type;
|
||||
p->urld.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -712,8 +741,8 @@ void urldb_update_url_visit_data(const char *url)
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
p->url.last_visit = time(NULL);
|
||||
p->url.visits++;
|
||||
p->urld.last_visit = time(NULL);
|
||||
p->urld.visits++;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -731,8 +760,8 @@ void urldb_reset_url_visit_data(const char *url)
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
p->url.last_visit = (time_t)0;
|
||||
p->url.visits = 0;
|
||||
p->urld.last_visit = (time_t)0;
|
||||
p->urld.visits = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -752,7 +781,7 @@ const struct url_data *urldb_get_url_data(const char *url)
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
return (struct url_data *)&p->url;
|
||||
return (struct url_data *)&p->urld;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -937,7 +966,8 @@ const struct bitmap *urldb_get_thumbnail(const char *url)
|
||||
* \param callback Callback function
|
||||
*/
|
||||
void urldb_iterate_partial(const char *prefix,
|
||||
bool (*callback)(const char *url))
|
||||
bool (*callback)(const char *url,
|
||||
const struct url_data *data))
|
||||
{
|
||||
char host[256];
|
||||
char buf[260]; /* max domain + "www." */
|
||||
@ -959,8 +989,7 @@ void urldb_iterate_partial(const char *prefix,
|
||||
if (slash) {
|
||||
/* if there's a slash in the input, then we can
|
||||
* assume that we're looking for a path */
|
||||
char *path, *domain = host;
|
||||
int path_alloc = 64, path_used = 2;
|
||||
char *domain = host;
|
||||
|
||||
snprintf(host, sizeof host, "%.*s", slash - prefix, prefix);
|
||||
|
||||
@ -984,17 +1013,8 @@ void urldb_iterate_partial(const char *prefix,
|
||||
return;
|
||||
}
|
||||
|
||||
path = malloc(path_alloc);
|
||||
if (!path)
|
||||
return;
|
||||
urldb_iterate_partial_path(&h->paths, slash + 1, callback);
|
||||
|
||||
path[0] = '/';
|
||||
path[1] = '\0';
|
||||
|
||||
urldb_iterate_partial_path(&h->paths, domain, slash + 1,
|
||||
&path, &path_alloc, &path_used, callback);
|
||||
|
||||
free(path);
|
||||
} else {
|
||||
int len = strlen(prefix);
|
||||
|
||||
@ -1026,13 +1046,10 @@ void urldb_iterate_partial(const char *prefix,
|
||||
* \return true to continue, false otherwise
|
||||
*/
|
||||
bool urldb_iterate_partial_host(struct search_node *root, const char *prefix,
|
||||
bool (*callback)(const char *url))
|
||||
bool (*callback)(const char *url,
|
||||
const struct url_data *data))
|
||||
{
|
||||
int c;
|
||||
const struct host_part *h;
|
||||
char domain[256], *p, *end;
|
||||
char *path;
|
||||
int path_alloc = 64, path_used = 2;
|
||||
|
||||
assert(root && prefix && callback);
|
||||
|
||||
@ -1055,34 +1072,12 @@ bool urldb_iterate_partial_host(struct search_node *root, const char *prefix,
|
||||
callback))
|
||||
return false;
|
||||
|
||||
/* Generate host string */
|
||||
for (h = root->data, p = domain,
|
||||
end = domain + sizeof domain;
|
||||
h && h != &db_root && p < end;
|
||||
h = h->parent) {
|
||||
int written = snprintf(p, end - p, "%s%s", h->part,
|
||||
(h->parent && h->parent->parent) ? "." : "");
|
||||
if (written < 0)
|
||||
return false;
|
||||
p += written;
|
||||
}
|
||||
|
||||
path = malloc(path_alloc);
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
path[0] = '/';
|
||||
path[1] = '\0';
|
||||
|
||||
/* and extract all paths attached to this host */
|
||||
if (!urldb_iterate_entries_path(domain, &path, &path_alloc,
|
||||
&path_used, &root->data->paths, callback)) {
|
||||
free(path);
|
||||
if (!urldb_iterate_entries_path(&root->data->paths,
|
||||
callback)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
free(path);
|
||||
|
||||
if (!urldb_iterate_partial_host(root->right, prefix,
|
||||
callback))
|
||||
return false;
|
||||
@ -1095,22 +1090,16 @@ bool urldb_iterate_partial_host(struct search_node *root, const char *prefix,
|
||||
* Partial path iterator (internal)
|
||||
*
|
||||
* \param parent Root of (sub)tree to traverse
|
||||
* \param host Host string
|
||||
* \param prefix Prefix to match
|
||||
* \param path The built path up to this point
|
||||
* \param path_alloc Allocated size of path
|
||||
* \param path_used Used size of path
|
||||
* \param callback Callback function
|
||||
* \return true to continue, false otherwise
|
||||
*/
|
||||
bool urldb_iterate_partial_path(const struct path_data *parent,
|
||||
const char *host, const char *prefix,
|
||||
char **path, int *path_alloc, int *path_used,
|
||||
bool (*callback)(const char *url))
|
||||
const char *prefix, bool (*callback)(const char *url,
|
||||
const struct url_data *data))
|
||||
{
|
||||
const struct path_data *p;
|
||||
const char *slash, *end = prefix + strlen(prefix);
|
||||
int pused = *path_used;
|
||||
int c;
|
||||
|
||||
slash = strchr(prefix, '/');
|
||||
@ -1130,41 +1119,17 @@ bool urldb_iterate_partial_path(const struct path_data *parent,
|
||||
break;
|
||||
|
||||
/* prefix matches so far */
|
||||
int len = *path_used + strlen(p->segment) + 1;
|
||||
if (*path_alloc < len) {
|
||||
char *temp = realloc(*path,
|
||||
(len > 64) ? len : *path_alloc + 64);
|
||||
if (!temp)
|
||||
return false;
|
||||
*path = temp;
|
||||
*path_alloc = (len > 64) ? len : *path_alloc + 64;
|
||||
}
|
||||
|
||||
strcat(*path, p->segment);
|
||||
if (p->children)
|
||||
strcat(*path, "/");
|
||||
else
|
||||
len -= 1;
|
||||
|
||||
*path_used = len;
|
||||
|
||||
if (slash == end) {
|
||||
/* we've run out of prefix, so all
|
||||
* paths below this one match */
|
||||
if (!urldb_iterate_entries_path(host, path,
|
||||
path_alloc, path_used, p, callback))
|
||||
if (!urldb_iterate_entries_path(p, callback))
|
||||
return false;
|
||||
} else {
|
||||
/* more prefix to go => recurse */
|
||||
if (!urldb_iterate_partial_path(p, host, slash + 1,
|
||||
path, path_alloc, path_used,
|
||||
if (!urldb_iterate_partial_path(p, slash + 1,
|
||||
callback))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* restore path to that from input for next child */
|
||||
*path_used = pused;
|
||||
(*path)[pused - 1] = '\0';
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1175,7 +1140,8 @@ bool urldb_iterate_partial_path(const struct path_data *parent,
|
||||
*
|
||||
* \param callback Function to callback for each entry
|
||||
*/
|
||||
void urldb_iterate_entries(bool (*callback)(const char *url))
|
||||
void urldb_iterate_entries(bool (*callback)(const char *url,
|
||||
const struct url_data *data))
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1196,43 +1162,19 @@ void urldb_iterate_entries(bool (*callback)(const char *url))
|
||||
* \return true to continue, false otherwise
|
||||
*/
|
||||
bool urldb_iterate_entries_host(struct search_node *parent,
|
||||
bool (*callback)(const char *url))
|
||||
bool (*callback)(const char *url,
|
||||
const struct url_data *data))
|
||||
{
|
||||
char domain[256], *p, *end;
|
||||
const struct host_part *h;
|
||||
char *path;
|
||||
int path_alloc = 64, path_used = 2;
|
||||
|
||||
if (parent == &empty)
|
||||
return true;
|
||||
|
||||
if (!urldb_iterate_entries_host(parent->left, callback))
|
||||
return false;
|
||||
|
||||
for (h = parent->data, p = domain, end = domain + sizeof domain;
|
||||
h && h != &db_root && p < end; h = h->parent) {
|
||||
int written = snprintf(p, end - p, "%s%s", h->part,
|
||||
(h->parent && h->parent->parent) ? "." : "");
|
||||
if (written < 0)
|
||||
return false;
|
||||
p += written;
|
||||
}
|
||||
|
||||
path = malloc(path_alloc);
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
path[0] = '/';
|
||||
path[1] = '\0';
|
||||
|
||||
if (!urldb_iterate_entries_path(domain, &path, &path_alloc,
|
||||
&path_used, &parent->data->paths, callback)) {
|
||||
free(path);
|
||||
if (!urldb_iterate_entries_path(&parent->data->paths, callback)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
free(path);
|
||||
|
||||
if (!urldb_iterate_entries_host(parent->right, callback))
|
||||
return false;
|
||||
|
||||
@ -1242,92 +1184,31 @@ bool urldb_iterate_entries_host(struct search_node *parent,
|
||||
/**
|
||||
* Path data iterator (internal)
|
||||
*
|
||||
* \param host Host component of output URI
|
||||
* \param path The built path up to this point
|
||||
* \param path_alloc Allocated size of path
|
||||
* \param path_used Used size of path
|
||||
* \param parent Root of subtree to iterate over
|
||||
* \param callback Callback function to call
|
||||
* \return true to continue, false otherwise
|
||||
*/
|
||||
bool urldb_iterate_entries_path(const char *host, char **path,
|
||||
int *path_alloc, int *path_used,
|
||||
const struct path_data *parent,
|
||||
bool (*callback)(const char *url))
|
||||
bool urldb_iterate_entries_path(const struct path_data *parent,
|
||||
bool (*callback)(const char *url,
|
||||
const struct url_data *data))
|
||||
{
|
||||
const struct path_data *p;
|
||||
int pused = *path_used;
|
||||
|
||||
if (!parent->children) {
|
||||
/* leaf node */
|
||||
int schemelen = strlen(parent->scheme);
|
||||
int hostlen = strlen(host);
|
||||
int prefixlen = schemelen + 3 /* :// */ +
|
||||
hostlen + 6 /* :NNNNN */;
|
||||
static char *url;
|
||||
static int url_alloc;
|
||||
int written;
|
||||
|
||||
if (url_alloc < *path_used + prefixlen + 2) {
|
||||
char *temp = realloc(url, *path_used + prefixlen + 2);
|
||||
if (!temp)
|
||||
return false;
|
||||
url = temp;
|
||||
url_alloc = *path_used + prefixlen + 2;
|
||||
}
|
||||
|
||||
written = sprintf(url, "%s://%s", parent->scheme, host);
|
||||
if (written < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parent->port) {
|
||||
written = sprintf(url + schemelen + 3 + hostlen,
|
||||
":%d", parent->port);
|
||||
if (written < 0) {
|
||||
return false;
|
||||
}
|
||||
written += schemelen + 3 + hostlen;
|
||||
}
|
||||
|
||||
written = sprintf(url + written, "%s", *path);
|
||||
if (written < 0) {
|
||||
return false;
|
||||
}
|
||||
assert(parent->url);
|
||||
|
||||
/** \todo handle fragments? */
|
||||
|
||||
if (!callback(url))
|
||||
if (!callback(parent->url,
|
||||
(const struct url_data *) &parent->urld))
|
||||
return false;
|
||||
}
|
||||
|
||||
for (p = parent->children; p; p = p->next) {
|
||||
int len = *path_used + strlen(p->segment) + 1;
|
||||
if (*path_alloc < len) {
|
||||
char *temp = realloc(*path,
|
||||
(len > 64) ? len : *path_alloc + 64);
|
||||
if (!temp)
|
||||
return false;
|
||||
*path = temp;
|
||||
*path_alloc = (len > 64) ? len : *path_alloc + 64;
|
||||
}
|
||||
|
||||
strcat(*path, p->segment);
|
||||
if (p->children) {
|
||||
strcat(*path, "/");
|
||||
} else {
|
||||
len -= 1;
|
||||
}
|
||||
|
||||
*path_used = len;
|
||||
|
||||
if (!urldb_iterate_entries_path(host, path, path_alloc,
|
||||
path_used, p, callback))
|
||||
if (!urldb_iterate_entries_path(p, callback))
|
||||
return false;
|
||||
|
||||
/* restore path to its state on entry to this function */
|
||||
*path_used = pused;
|
||||
(*path)[pused - 1] = '\0';
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1540,17 +1421,18 @@ struct path_data *urldb_add_path_node(const char *scheme, unsigned int port,
|
||||
* \param host Host tree node to attach to
|
||||
* \param path Absolute path to add
|
||||
* \param fragment URL fragment, or NULL
|
||||
* \param url_no_frag URL, without fragment
|
||||
* \return Pointer to leaf node, or NULL on memory exhaustion
|
||||
*/
|
||||
struct path_data *urldb_add_path(const char *scheme, unsigned int port,
|
||||
const struct host_part *host, const char *path,
|
||||
const char *fragment)
|
||||
const char *fragment, const char *url_no_frag)
|
||||
{
|
||||
struct path_data *d, *e;
|
||||
char *buf;
|
||||
char *segment, *slash;
|
||||
|
||||
assert(scheme && host && path);
|
||||
assert(scheme && host && path && url_no_frag);
|
||||
|
||||
d = (struct path_data *) &host->paths;
|
||||
|
||||
@ -1602,6 +1484,13 @@ struct path_data *urldb_add_path(const char *scheme, unsigned int port,
|
||||
|
||||
free(buf);
|
||||
|
||||
if (d && !d->url) {
|
||||
/* Insert URL */
|
||||
d->url = strdup(url_no_frag);
|
||||
if (!d->url)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
@ -54,10 +54,12 @@ const struct bitmap *urldb_get_thumbnail(const char *url);
|
||||
|
||||
/* URL completion */
|
||||
void urldb_iterate_partial(const char *prefix,
|
||||
bool (*callback)(const char *url));
|
||||
bool (*callback)(const char *url,
|
||||
const struct url_data *data));
|
||||
|
||||
/* Iteration */
|
||||
void urldb_iterate_entries(bool (*callback)(const char *url));
|
||||
void urldb_iterate_entries(bool (*callback)(const char *url,
|
||||
const struct url_data *data));
|
||||
|
||||
/* Debug */
|
||||
void urldb_dump(void);
|
||||
|
@ -894,7 +894,7 @@ void tree_delete_node(struct tree *tree, struct node *node, bool siblings) {
|
||||
f = e->next;
|
||||
|
||||
if (e->text) {
|
||||
/* we don't free non-editable titles */
|
||||
/* we don't free non-editable titles or URLs */
|
||||
if (node->editable)
|
||||
free(e->text);
|
||||
else {
|
||||
@ -903,7 +903,8 @@ void tree_delete_node(struct tree *tree, struct node *node, bool siblings) {
|
||||
urldb_reset_url_visit_data(e->text);
|
||||
}
|
||||
|
||||
if (e->data != TREE_ELEMENT_TITLE)
|
||||
if (e->data != TREE_ELEMENT_TITLE &&
|
||||
e->data != TREE_ELEMENT_URL)
|
||||
free(e->text);
|
||||
}
|
||||
}
|
||||
@ -1033,7 +1034,7 @@ struct node *tree_create_URL_node(struct node *parent,
|
||||
* edited and should never be freed.
|
||||
*
|
||||
* \param parent the node to link to
|
||||
* \param url the URL (copied)
|
||||
* \param url the URL
|
||||
* \param data the URL data to use
|
||||
* \return the node created, or NULL for failure
|
||||
*/
|
||||
@ -1043,16 +1044,12 @@ struct node *tree_create_URL_node_shared(struct node *parent,
|
||||
struct node_element *element;
|
||||
char *title;
|
||||
|
||||
assert(data);
|
||||
|
||||
/* If title isn't set, set it to the URL */
|
||||
if (!data->title)
|
||||
urldb_set_url_title(url, url);
|
||||
assert(url && data);
|
||||
|
||||
if (data->title)
|
||||
title = data->title;
|
||||
else
|
||||
return NULL;
|
||||
title = url;
|
||||
node = tree_create_leaf_node(parent, title);
|
||||
if (!node)
|
||||
return NULL;
|
||||
@ -1067,7 +1064,7 @@ struct node *tree_create_URL_node_shared(struct node *parent,
|
||||
tree_create_node_element(node, TREE_ELEMENT_LAST_VISIT);
|
||||
element = tree_create_node_element(node, TREE_ELEMENT_URL);
|
||||
if (element)
|
||||
element->text = strdup(url);
|
||||
element->text = url;
|
||||
|
||||
tree_update_URL_node(node, url, data);
|
||||
tree_recalculate_node(node, false);
|
||||
|
@ -50,7 +50,8 @@ static void ro_gui_global_history_initialise_nodes(void);
|
||||
static void ro_gui_global_history_initialise_node(const char *title,
|
||||
time_t base, int days_back);
|
||||
static struct node *ro_gui_global_history_find(const char *url);
|
||||
static bool global_history_iterate_callback(const char *url);
|
||||
static bool global_history_add_internal(const char *url,
|
||||
const struct url_data *data);
|
||||
|
||||
/* The history window, toolbar and plot origins */
|
||||
static wimp_w global_history_window;
|
||||
@ -119,23 +120,10 @@ void ro_gui_global_history_initialise(void)
|
||||
}
|
||||
|
||||
global_history_init = true;
|
||||
urldb_iterate_entries(global_history_iterate_callback);
|
||||
urldb_iterate_entries(global_history_add_internal);
|
||||
global_history_init = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for urldb_iterate_entries
|
||||
*
|
||||
* \param url The URL
|
||||
* \return true to continue iteration, false otherwise
|
||||
*/
|
||||
bool global_history_iterate_callback(const char *url)
|
||||
{
|
||||
global_history_add(url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the base nodes
|
||||
*/
|
||||
@ -267,19 +255,33 @@ int ro_gui_global_history_help(int x, int y)
|
||||
*/
|
||||
void global_history_add(const char *url)
|
||||
{
|
||||
int i, j;
|
||||
const struct url_data *data;
|
||||
|
||||
data = urldb_get_url_data(url);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
global_history_add_internal(url, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal routine to actually perform global history addition
|
||||
*
|
||||
* \param url The URL to add
|
||||
* \param data URL data associated with URL
|
||||
* \return true (for urldb_iterate_entries)
|
||||
*/
|
||||
bool global_history_add_internal(const char *url,
|
||||
const struct url_data *data)
|
||||
{
|
||||
int i, j;
|
||||
struct node *parent = NULL;
|
||||
struct node *link;
|
||||
struct node *node;
|
||||
bool before = false;
|
||||
int visit_date;
|
||||
|
||||
assert(url);
|
||||
|
||||
data = urldb_get_url_data(url);
|
||||
if (!data)
|
||||
return;
|
||||
assert(url && data);
|
||||
|
||||
visit_date = data->last_visit;
|
||||
|
||||
@ -309,7 +311,7 @@ void global_history_add(const char *url)
|
||||
|
||||
/* the entry is too old to care about */
|
||||
if (!parent)
|
||||
return;
|
||||
return true;
|
||||
|
||||
/* find any previous occurance */
|
||||
if (!global_history_init) {
|
||||
@ -326,7 +328,7 @@ void global_history_add(const char *url)
|
||||
node, false, true);
|
||||
/* ro_gui_tree_scroll_visible(hotlist_tree,
|
||||
&node->data);
|
||||
*/ return;
|
||||
*/ return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,6 +341,8 @@ void global_history_add(const char *url)
|
||||
tree_handle_node_changed(global_history_tree, node,
|
||||
true, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,7 +363,7 @@ struct node *ro_gui_global_history_find(const char *url)
|
||||
node; node = node->next) {
|
||||
element = tree_find_element(node,
|
||||
TREE_ELEMENT_URL);
|
||||
if ((element) && !strcmp(url, element->text))
|
||||
if ((element) && (url == element->text))
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#define MAXIMUM_VISIBLE_LINES 7
|
||||
|
||||
static char **url_complete_matches = NULL;
|
||||
static const char **url_complete_matches = NULL;
|
||||
static int url_complete_matches_allocated = 0;
|
||||
static int url_complete_matches_available = 0;
|
||||
static char *url_complete_matched_string = NULL;
|
||||
@ -38,7 +38,7 @@ static bool url_complete_matches_reset = false;
|
||||
static char *url_complete_original_url = NULL;
|
||||
static bool url_complete_memory_exhausted = false;
|
||||
|
||||
static char *url_complete_redraw[MAXIMUM_VISIBLE_LINES];
|
||||
static const char *url_complete_redraw[MAXIMUM_VISIBLE_LINES];
|
||||
static char url_complete_icon_null[] = "\0";
|
||||
static char url_complete_icon_sprite[12];
|
||||
static wimp_icon url_complete_icon;
|
||||
@ -160,14 +160,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key)
|
||||
free(url_complete_matched_string);
|
||||
url_complete_matched_string = match_url;
|
||||
url_complete_original_url = NULL;
|
||||
if (url_complete_matches) {
|
||||
for (; url_complete_matches_available > 0;
|
||||
url_complete_matches_available--)
|
||||
free(url_complete_matches[
|
||||
url_complete_matches_available - 1]);
|
||||
} else {
|
||||
url_complete_matches_available = 0;
|
||||
}
|
||||
url_complete_matches_available = 0;
|
||||
url_complete_matches_selection = -1;
|
||||
url_complete_keypress_selection = -1;
|
||||
|
||||
@ -338,17 +331,16 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key)
|
||||
*/
|
||||
bool url_complete_callback(const char *url)
|
||||
{
|
||||
char **array_extend;
|
||||
char *temp;
|
||||
const char **array_extend;
|
||||
|
||||
url_complete_matches_available++;
|
||||
|
||||
if (url_complete_matches_available >
|
||||
url_complete_matches_allocated) {
|
||||
|
||||
array_extend = (char **)realloc(url_complete_matches,
|
||||
array_extend = (const char **)realloc(url_complete_matches,
|
||||
(url_complete_matches_allocated + 64) *
|
||||
sizeof(struct url_content *));
|
||||
sizeof(char *));
|
||||
if (!array_extend) {
|
||||
url_complete_memory_exhausted = true;
|
||||
return false;
|
||||
@ -357,13 +349,7 @@ bool url_complete_callback(const char *url)
|
||||
url_complete_matches_allocated += 64;
|
||||
}
|
||||
|
||||
temp = strdup(url);
|
||||
if (!temp) {
|
||||
url_complete_memory_exhausted = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
url_complete_matches[url_complete_matches_available - 1] = temp;
|
||||
url_complete_matches[url_complete_matches_available - 1] = url;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -496,12 +482,6 @@ bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i)
|
||||
currently_open = ((url_complete_parent) &&
|
||||
(url_complete_matches_available > 0));
|
||||
|
||||
if (url_complete_matches) {
|
||||
for (; url_complete_matches_available > 0;
|
||||
url_complete_matches_available--)
|
||||
free(url_complete_matches[
|
||||
url_complete_matches_available - 1]);
|
||||
}
|
||||
free(url_complete_matches);
|
||||
free(url_complete_matched_string);
|
||||
free(url_complete_original_url);
|
||||
|
Loading…
Reference in New Issue
Block a user