85 |
85 |
86 error: |
86 error: |
87 return -1; |
87 return -1; |
88 } |
88 } |
89 |
89 |
|
90 static struct url_opt *_url_get_opt (struct url *url, int new) { |
|
91 if (!url->opts) { |
|
92 if ((url->opts = malloc(sizeof(struct url_opts) + (1 * sizeof(struct url_opt)))) == NULL) |
|
93 ERROR("malloc"); |
|
94 |
|
95 url->opts->count = 1; |
|
96 |
|
97 } else if (new) { |
|
98 url->opts->count++; |
|
99 |
|
100 if ((url->opts = realloc(url->opts, sizeof(struct url_opts) + url->opts->count * sizeof(struct url_opt))) == NULL) |
|
101 ERROR("realloc"); |
|
102 } |
|
103 |
|
104 // success |
|
105 return &url->opts->list[url->opts->count - 1]; |
|
106 |
|
107 error: |
|
108 return NULL; |
|
109 } |
|
110 |
90 static int _url_append_opt_key (struct url *url, const char *key) { |
111 static int _url_append_opt_key (struct url *url, const char *key) { |
|
112 struct url_opt *opt; |
|
113 |
|
114 if ((opt = _url_get_opt(url, 1)) == NULL) |
|
115 goto error; |
|
116 |
|
117 if ((opt->key = strdup(key)) == NULL) |
|
118 ERROR("strdup"); |
|
119 |
|
120 opt->value = NULL; |
|
121 |
91 return 0; |
122 return 0; |
92 } |
123 |
|
124 error: |
|
125 return -1; |
|
126 } |
93 |
127 |
94 static int _url_append_opt_val (struct url *url, const char *value) { |
128 static int _url_append_opt_val (struct url *url, const char *value) { |
|
129 struct url_opt *opt; |
|
130 |
|
131 if ((opt = _url_get_opt(url, 0)) == NULL) |
|
132 goto error; |
|
133 |
|
134 if ((opt->value = strdup(value)) == NULL) |
|
135 ERROR("strdup"); |
|
136 |
95 return 0; |
137 return 0; |
|
138 |
|
139 error: |
|
140 return -1; |
96 } |
141 } |
97 |
142 |
98 static int url_lex_token (int _this_token, char *token_data, int _next_token, int _prev_token, void *arg); |
143 static int url_lex_token (int _this_token, char *token_data, int _next_token, int _prev_token, void *arg); |
99 |
144 |
100 static struct lex url_lex = { |
145 static struct lex url_lex = { |
113 LEX_END |
158 LEX_END |
114 }, |
159 }, |
115 |
160 |
116 // this can be URL_SCHEME, URL_USERNAME or URL_HOSTNAME |
161 // this can be URL_SCHEME, URL_USERNAME or URL_HOSTNAME |
117 LEX_STATE_END ( URL_BEGIN_ALNUM ) { |
162 LEX_STATE_END ( URL_BEGIN_ALNUM ) { |
118 LEX_ALNUM ( URL_BEGIN_ALNUM ), |
|
119 LEX_CHAR ( '+', URL_SCHEME_SEP ), // it was URL_SCHEME |
163 LEX_CHAR ( '+', URL_SCHEME_SEP ), // it was URL_SCHEME |
120 LEX_CHAR ( ':', URL_BEGIN_COLON ), |
164 LEX_CHAR ( ':', URL_BEGIN_COLON ), |
121 LEX_CHAR ( '@', URL_USERNAME_END ), // it was URL_USERNAME |
165 LEX_CHAR ( '@', URL_USERNAME_END ), // it was URL_USERNAME |
122 LEX_CHAR ( '/', URL_PATH_START ), // it was URL_HOSTNAME |
166 LEX_CHAR ( '/', URL_PATH_START ), // it was URL_HOSTNAME |
123 LEX_CHAR ( '?', URL_OPT_START ), // it was URL_HOSTNAME |
167 LEX_CHAR ( '?', URL_OPT_START ), // it was URL_HOSTNAME |
124 LEX_END |
168 LEX_DEFAULT ( URL_BEGIN_ALNUM ) |
125 }, |
169 }, |
126 |
170 |
127 // this can be URL_SCHEME_END_COL, URL_USERNAME_END or URL_SERVICE_SEP |
171 // this can be URL_SCHEME_END_COL, URL_USERNAME_END or URL_SERVICE_SEP |
128 LEX_STATE ( URL_BEGIN_COLON ) { |
172 LEX_STATE ( URL_BEGIN_COLON ) { |
129 LEX_CHAR ( '/', URL_SCHEME_END_SLASH1 ), // it was URL_SCHEME |
173 LEX_CHAR ( '/', URL_SCHEME_END_SLASH1 ), // it was URL_SCHEME |