Skip to content

Instantly share code, notes, and snippets.

@alex-s168
Created February 14, 2024 21:33
Show Gist options
  • Save alex-s168/0593391388f95134b0e83a8ce216db18 to your computer and use it in GitHub Desktop.
Save alex-s168/0593391388f95134b0e83a8ce216db18 to your computer and use it in GitHub Desktop.
GET parameter parsing in C
/*
Example usage:
```
char *url;
char *params[2] = { "name", "mail" };
urlGETAll(url, params, 2);
printf("name: %s\n", params[0]);
printf("mail: %s\n", params[1]);
```
*/
#include <string.h>
#ifndef HTTP_GET_PARAMS
#define HTTP_GET_PARAMS
// "/a/b?x=y" -> "x=y"
static char *urlGETStart(char *path) {
while (*path != '\0') {
if (*path == '?')
return path + 1;
path ++;
}
return path;
}
#define INTERNAL /* internal: */
struct urlGETParam {
char *k;
char *v;
INTERNAL
char *next;
};
static void urlGETPrepare(struct urlGETParam *ptr) {
ptr->next = NULL;
}
// Returns 1 if was success
// should not be called again after 0 was returned
static int urlGETNext(struct urlGETParam *ptr, char *start) {
char *r = strtok(ptr->next ? NULL : start, "&");
if (r == NULL)
return 0;
ptr->next = r;
ptr->k = r;
char *v = strchr(r, '=');
*v = '\0';
ptr->v = v + 1;
return 1;
}
// "temp" needs to be the size of "len" and initialized with zeros
static void urlGETAll(char *path, char **dest, int len, int *temp) {
char *start = urlGETStart(path);
struct urlGETParam param;
urlGETPrepare(&param);
while (urlGETNext(&param, start)) {
for (int i = 0; i < len; i ++) {
if (temp[i])
continue;
if (!strcmp(dest[i], param.k)) {
dest[i] = param.v;
temp[i] = 1;
}
}
}
for (int i = 0; i < len; i ++)
if (!temp[i])
dest[i] = NULL;
}
#define urlGETAll(path, dest, count) \
urlGETAll(path, dest, count, (int[count]) { 0 });
#endif//HTTP_GET_PARAMS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment