--- a/src/lib/url.c Thu Oct 09 00:49:32 2008 +0300
+++ b/src/lib/url.c Sat Oct 11 20:45:28 2008 +0300
@@ -87,12 +87,57 @@
return -1;
}
-static int _url_append_opt_key (struct url *url, const char *key) {
- return 0;
+static struct url_opt *_url_get_opt (struct url *url, int new) {
+ if (!url->opts) {
+ if ((url->opts = malloc(sizeof(struct url_opts) + (1 * sizeof(struct url_opt)))) == NULL)
+ ERROR("malloc");
+
+ url->opts->count = 1;
+
+ } else if (new) {
+ url->opts->count++;
+
+ if ((url->opts = realloc(url->opts, sizeof(struct url_opts) + url->opts->count * sizeof(struct url_opt))) == NULL)
+ ERROR("realloc");
+ }
+
+ // success
+ return &url->opts->list[url->opts->count - 1];
+
+error:
+ return NULL;
}
+static int _url_append_opt_key (struct url *url, const char *key) {
+ struct url_opt *opt;
+
+ if ((opt = _url_get_opt(url, 1)) == NULL)
+ goto error;
+
+ if ((opt->key = strdup(key)) == NULL)
+ ERROR("strdup");
+
+ opt->value = NULL;
+
+ return 0;
+
+error:
+ return -1;
+}
+
static int _url_append_opt_val (struct url *url, const char *value) {
+ struct url_opt *opt;
+
+ if ((opt = _url_get_opt(url, 0)) == NULL)
+ goto error;
+
+ if ((opt->value = strdup(value)) == NULL)
+ ERROR("strdup");
+
return 0;
+
+error:
+ return -1;
}
static int url_lex_token (int _this_token, char *token_data, int _next_token, int _prev_token, void *arg);
@@ -115,13 +160,12 @@
// this can be URL_SCHEME, URL_USERNAME or URL_HOSTNAME
LEX_STATE_END ( URL_BEGIN_ALNUM ) {
- LEX_ALNUM ( URL_BEGIN_ALNUM ),
LEX_CHAR ( '+', URL_SCHEME_SEP ), // it was URL_SCHEME
LEX_CHAR ( ':', URL_BEGIN_COLON ),
LEX_CHAR ( '@', URL_USERNAME_END ), // it was URL_USERNAME
LEX_CHAR ( '/', URL_PATH_START ), // it was URL_HOSTNAME
LEX_CHAR ( '?', URL_OPT_START ), // it was URL_HOSTNAME
- LEX_END
+ LEX_DEFAULT ( URL_BEGIN_ALNUM )
},
// this can be URL_SCHEME_END_COL, URL_USERNAME_END or URL_SERVICE_SEP
--- a/src/url_test.c Thu Oct 09 00:49:32 2008 +0300
+++ b/src/url_test.c Sat Oct 11 20:45:28 2008 +0300
@@ -9,7 +9,15 @@
struct url_schema
basic_http = { 1, { "http" } },
- svn_ssh = { 2, { "svn", "ssh" } };
+ svn_ssh = { 2, { "svn", "ssh" } },
+ schema_unix = { 1, { "unix" } }
+ ;
+
+struct url_opts
+ opts_single = { 1, { { "key0", "val0" } } },
+ opts_multi = { 2, { { "key0", "val0" }, { "key1", "val1" } } },
+ opts_nullval = { 1, { { "keyN", NULL } } }
+ ;
struct url_test {
const char *url;
@@ -30,7 +38,31 @@
{ "user@:service/", {
NULL, "user", NULL, NULL, "service", NULL
} },
-
+
+ { "unix:////tmp/foo.sock", {
+ &schema_unix, NULL, NULL, NULL, NULL, "/tmp/foo.sock"
+ } },
+
+ { "unix:///tmp/foo.sock", {
+ &schema_unix, NULL, NULL, NULL, NULL, "tmp/foo.sock"
+ } },
+
+ { "/tmp/foo.sock", {
+ NULL, NULL, NULL, NULL, NULL, "tmp/foo.sock"
+ } },
+
+ { "?key0=val0", {
+ NULL, NULL, NULL, NULL, NULL, NULL, &opts_single
+ } },
+
+ { "http://foo.com/index.php?key0=val0&key1=val1", {
+ &basic_http, NULL, NULL, "foo.com", NULL, "index.php", &opts_multi
+ } },
+
+ { "example.org:81/?keyN", {
+ NULL, NULL, NULL, "example.org", "81", NULL, &opts_nullval
+ } },
+
{ NULL, { } },
};
@@ -105,11 +137,11 @@
FAIL("inconsistent opts count");
for (i = 0; i < test->opts->count; i++) {
- if (strcmp(test->opts->list[i].key, real->opts->list[i].key) != 0)
- FAIL("differing scheme key #%d", i);
+ if (cmp_url_str("opt key", test->opts->list[i].key, real->opts->list[i].key))
+ FAIL("differing opt key #%d", i);
- if (strcmp(test->opts->list[i].value, real->opts->list[i].value) != 0)
- FAIL("differing scheme value #%d", i);
+ if (cmp_url_str("opt value", test->opts->list[i].value, real->opts->list[i].value))
+ FAIL("differing opt value #%d", i);
}
}
@@ -159,6 +191,8 @@
printf("OK\n\t");
url_dump(&url, stdout);
}
+
+ printf("\n");
}
}