diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..035fc62 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + + + +## Version 0.1.0 - 2025-11-05 + +Automated versioning and changelog updates are now available when you commit code. This simplifies release management and ensures accurate changelog entries. + +**Changes:** 1 files, 425 lines +**Languages:** Python (425 lines) diff --git a/url.h b/url.h new file mode 100644 index 0000000..beb9f3a --- /dev/null +++ b/url.h @@ -0,0 +1,93 @@ +#ifndef R_URL_H +#define R_URL_H + +// retoor@molodetz.nl + +#include +#include +#include + +typedef struct { + char scheme[16]; + char hostname[256]; + char port[8]; + char path[512]; + char query[512]; +} url_t; + +int parse_url(const char *url, url_t *parsed_url) { + memset(parsed_url, 0, sizeof(url_t)); + + const char *scheme_delimiter = strstr(url, "://"); + if (!scheme_delimiter) { + return -1; + } + + size_t scheme_length = scheme_delimiter - url; + if (scheme_length >= sizeof(parsed_url->scheme)) { + fprintf(stderr, "Scheme is too long\n"); + return -1; + } + strncpy(parsed_url->scheme, url, scheme_length); + parsed_url->scheme[scheme_length] = '\0'; + + const char *host_start = scheme_delimiter + 3; + const char *port_delimiter = strchr(host_start, ':'); + const char *path_delimiter = strchr(host_start, '/'); + const char *query_delimiter = strchr(host_start, '?'); + + size_t hostname_length; + if (port_delimiter && (!path_delimiter || port_delimiter < path_delimiter) && + (!query_delimiter || port_delimiter < query_delimiter)) { + hostname_length = port_delimiter - host_start; + if (hostname_length >= sizeof(parsed_url->hostname)) { + fprintf(stderr, "Hostname is too long\n"); + return -1; + } + strncpy(parsed_url->hostname, host_start, hostname_length); + parsed_url->hostname[hostname_length] = '\0'; + + const char *port_end = query_delimiter ? query_delimiter : (path_delimiter ? path_delimiter : host_start + strlen(host_start)); + size_t port_length = port_end - (port_delimiter + 1); + if (port_length >= sizeof(parsed_url->port)) { + fprintf(stderr, "Port value is too long\n"); + return -1; + } + strncpy(parsed_url->port, port_delimiter + 1, port_length); + parsed_url->port[port_length] = '\0'; + } else { + const char *hostname_end = path_delimiter ? path_delimiter : (query_delimiter ? query_delimiter : host_start + strlen(host_start)); + hostname_length = hostname_end - host_start; + if (hostname_length >= sizeof(parsed_url->hostname)) { + fprintf(stderr, "Hostname is too long\n"); + return -1; + } + strncpy(parsed_url->hostname, host_start, hostname_length); + parsed_url->hostname[hostname_length] = '\0'; + } + + if (path_delimiter) { + const char *path_end = query_delimiter ? query_delimiter : path_delimiter + strlen(path_delimiter); + size_t path_length = path_end - path_delimiter; + if (path_length >= sizeof(parsed_url->path)) { + fprintf(stderr, "Path is too long\n"); + return -1; + } + strncpy(parsed_url->path, path_delimiter, path_length); + parsed_url->path[path_length] = '\0'; + } + + if (query_delimiter) { + size_t query_length = strlen(query_delimiter + 1); + if (query_length >= sizeof(parsed_url->query)) { + fprintf(stderr, "Query is too long\n"); + return -1; + } + strcpy(parsed_url->query, query_delimiter + 1); + } + + return 0; +} +#endif + +#endif