diff --git a/docs/README.md b/docs/README.md index bb1b3dc3..3334ef31 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1152,7 +1152,47 @@ void mg_timer_poll(unsigned long uptime_ms); Traverse list of timers, and call them if current timestamp `uptime_ms` is past the timer's expiration time. -## Utility functions +## String + +### mg\_globmatch() + +```c +bool mg_globmatch(const char *pattern, int plen, const char *s, int n); +``` + +Return true if string `s`, `n` matches glob pattern `pattern`, `plen`. +The glob pattern matching rules are as follows: + +- `?` matches any single character +- `*` matches zero or more characters except `/` +- `#` matches zero or more characters +- any other character matches itself + + +### mg\_commalist() + +```c +bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v); +``` + +Parse string `s`, which is a comma-separated list of entries. An entry could be +either an arbitrary string, which gets stored in `v`, or a `KEY=VALUE` which +gets stored in `k` and `v` respectively. + +IMPORTANT: this function modifies `s` by pointing to the next entry. Usage +example: + +```c +struct mg_str k, v, s = mg_str("a=333,b=777"); +while (mg_commalist(&s, &k, &v)) // This loop output: + printf("[%.*s] set to [%.*s]\n", // [a] set to [333] + (int) k.len, k.ptr, (int) v.len, v.ptr); // [b] set to [777] +``` + + + + +## Utility ### mg\_file\_read() @@ -1196,41 +1236,6 @@ void mg_random(void *buf, size_t len); Fill in buffer `buf`, `len` with random data. -### mg\_globmatch() - -```c -bool mg_globmatch(const char *pattern, int plen, const char *s, int n); -``` - -Return true if string `s`, `n` matches glob pattern `pattern`, `plen`. -The glob pattern matching rules are as follows: - -- `?` matches any single character -- `*` matches zero or more characters except `/` -- `#` matches zero or more characters -- any other character matches itself - - -### mg\_comma() - -```c -bool mg_comma(struct mg_str *s, struct mg_str *k, struct mg_str *v); -``` - -Parse string `s`, which is a comma-separated list of entries. An entry could be -either an arbitrary string, which gets stored in `v`, or a `KEY=VALUE` which -gets stored in `k` and `v` respectively. - -IMPORTANT: this function modifies `s` by pointing to the next entry. Usage -example: - -```c -struct mg_str k, v, s = mg_str("a=333,b=777"); -while (mg_comma(&s, &k, &v)) // This loop output: - printf("[%.*s] set to [%.*s]\n", // [a] set to [333] - (int) k.len, k.ptr, (int) v.len, v.ptr); // [b] set to [777] -``` - ### mg\_ntohs() ```c diff --git a/mongoose.c b/mongoose.c index e808e6b7..d45e1037 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1260,7 +1260,7 @@ static struct mg_str guess_content_type(struct mg_str path, const char *extra) { path.len = i; // Process user-provided mime type overrides, if any - while (mg_comma(&s, &k, &v)) { + while (mg_commalist(&s, &k, &v)) { if (mg_strcmp(path, k) == 0) return v; } @@ -1825,7 +1825,7 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) { if (p == NULL) p = strrchr(file, '\\'); p = p == NULL ? file : p + 1; - while (mg_comma(&s, &k, &v)) { + while (mg_commalist(&s, &k, &v)) { if (v.len == 0) max = atoi(k.ptr); if (v.len > 0 && strncmp(p, k.ptr, k.len) == 0) max = atoi(v.ptr); } @@ -4235,7 +4235,7 @@ static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff, return ofs > n ? n : ofs; } -bool mg_comma(struct mg_str *s, struct mg_str *k, struct mg_str *v) { +bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) { size_t koff = 0, klen = 0, voff = 0, vlen = 0; size_t off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen); if (k != NULL) *k = mg_str_n(s->ptr + koff, klen); @@ -4413,7 +4413,7 @@ static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) { int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip) { struct mg_str k, v; int allowed = acl.len == 0 ? '+' : '-'; // If any ACL is set, deny by default - while (mg_comma(&acl, &k, &v)) { + while (mg_commalist(&acl, &k, &v)) { uint32_t net, mask; if (k.ptr[0] != '+' && k.ptr[0] != '-') return -1; if (parse_net(&k.ptr[1], &net, &mask) == 0) return -2; diff --git a/mongoose.h b/mongoose.h index e2430d06..bbeedc67 100644 --- a/mongoose.h +++ b/mongoose.h @@ -537,7 +537,7 @@ bool mg_file_write(const char *path, const void *buf, size_t len); bool mg_file_printf(const char *path, const char *fmt, ...); void mg_random(void *buf, size_t len); bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n); -bool mg_comma(struct mg_str *s, struct mg_str *k, struct mg_str *v); +bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v); uint16_t mg_ntohs(uint16_t net); uint32_t mg_ntohl(uint32_t net); uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len); diff --git a/src/http.c b/src/http.c index 097a48a1..47d62e88 100644 --- a/src/http.c +++ b/src/http.c @@ -489,7 +489,7 @@ static struct mg_str guess_content_type(struct mg_str path, const char *extra) { path.len = i; // Process user-provided mime type overrides, if any - while (mg_comma(&s, &k, &v)) { + while (mg_commalist(&s, &k, &v)) { if (mg_strcmp(path, k) == 0) return v; } diff --git a/src/log.c b/src/log.c index c8b1473c..f6e3c0d5 100644 --- a/src/log.c +++ b/src/log.c @@ -27,7 +27,7 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) { if (p == NULL) p = strrchr(file, '\\'); p = p == NULL ? file : p + 1; - while (mg_comma(&s, &k, &v)) { + while (mg_commalist(&s, &k, &v)) { if (v.len == 0) max = atoi(k.ptr); if (v.len > 0 && strncmp(p, k.ptr, k.len) == 0) max = atoi(v.ptr); } diff --git a/src/util.c b/src/util.c index e098212e..8e3626a8 100644 --- a/src/util.c +++ b/src/util.c @@ -108,7 +108,7 @@ static size_t mg_nce(const char *s, size_t n, size_t ofs, size_t *koff, return ofs > n ? n : ofs; } -bool mg_comma(struct mg_str *s, struct mg_str *k, struct mg_str *v) { +bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v) { size_t koff = 0, klen = 0, voff = 0, vlen = 0; size_t off = mg_nce(s->ptr, s->len, 0, &koff, &klen, &voff, &vlen); if (k != NULL) *k = mg_str_n(s->ptr + koff, klen); @@ -286,7 +286,7 @@ static int parse_net(const char *spec, uint32_t *net, uint32_t *mask) { int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip) { struct mg_str k, v; int allowed = acl.len == 0 ? '+' : '-'; // If any ACL is set, deny by default - while (mg_comma(&acl, &k, &v)) { + while (mg_commalist(&acl, &k, &v)) { uint32_t net, mask; if (k.ptr[0] != '+' && k.ptr[0] != '-') return -1; if (parse_net(&k.ptr[1], &net, &mask) == 0) return -2; diff --git a/src/util.h b/src/util.h index 0dd10d3b..c89bbf68 100644 --- a/src/util.h +++ b/src/util.h @@ -8,7 +8,7 @@ bool mg_file_write(const char *path, const void *buf, size_t len); bool mg_file_printf(const char *path, const char *fmt, ...); void mg_random(void *buf, size_t len); bool mg_globmatch(const char *pattern, size_t plen, const char *s, size_t n); -bool mg_comma(struct mg_str *s, struct mg_str *k, struct mg_str *v); +bool mg_commalist(struct mg_str *s, struct mg_str *k, struct mg_str *v); uint16_t mg_ntohs(uint16_t net); uint32_t mg_ntohl(uint32_t net); uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len); diff --git a/test/fuzz.c b/test/fuzz.c index 2d1471d2..4da95b98 100644 --- a/test/fuzz.c +++ b/test/fuzz.c @@ -41,7 +41,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { mg_globmatch((char *) data, size, (char *) data, size); struct mg_str k, v, s = mg_str_n((char *) data, size); - while (mg_comma(&s, &k, &v)) k.len = v.len = 0; + while (mg_commalist(&s, &k, &v)) k.len = v.len = 0; return 0; } diff --git a/test/unit_test.c b/test/unit_test.c index b9e9f4d5..003101e1 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -41,28 +41,28 @@ static void test_globmatch(void) { static void test_commalist(void) { struct mg_str k, v, s1 = mg_str(""), s2 = mg_str("a"), s3 = mg_str("a,b"); struct mg_str s4 = mg_str("a=123"), s5 = mg_str("a,b=123"); - ASSERT(mg_comma(&s1, &k, &v) == false); + ASSERT(mg_commalist(&s1, &k, &v) == false); - ASSERT(mg_comma(&s2, &k, &v) == true); + ASSERT(mg_commalist(&s2, &k, &v) == true); ASSERT(v.len == 0 && mg_vcmp(&k, "a") == 0); - ASSERT(mg_comma(&s2, &k, &v) == false); + ASSERT(mg_commalist(&s2, &k, &v) == false); - ASSERT(mg_comma(&s3, &k, &v) == true); + ASSERT(mg_commalist(&s3, &k, &v) == true); ASSERT(v.len == 0 && mg_vcmp(&k, "a") == 0); - ASSERT(mg_comma(&s3, &k, &v) == true); + ASSERT(mg_commalist(&s3, &k, &v) == true); ASSERT(v.len == 0 && mg_vcmp(&k, "b") == 0); - ASSERT(mg_comma(&s3, &k, &v) == false); + ASSERT(mg_commalist(&s3, &k, &v) == false); - ASSERT(mg_comma(&s4, &k, &v) == true); + ASSERT(mg_commalist(&s4, &k, &v) == true); ASSERT(mg_vcmp(&k, "a") == 0 && mg_vcmp(&v, "123") == 0); - ASSERT(mg_comma(&s4, &k, &v) == false); - ASSERT(mg_comma(&s4, &k, &v) == false); + ASSERT(mg_commalist(&s4, &k, &v) == false); + ASSERT(mg_commalist(&s4, &k, &v) == false); - ASSERT(mg_comma(&s5, &k, &v) == true); + ASSERT(mg_commalist(&s5, &k, &v) == true); ASSERT(v.len == 0 && mg_vcmp(&k, "a") == 0); - ASSERT(mg_comma(&s5, &k, &v) == true); + ASSERT(mg_commalist(&s5, &k, &v) == true); ASSERT(mg_vcmp(&k, "b") == 0 && mg_vcmp(&v, "123") == 0); - ASSERT(mg_comma(&s4, &k, &v) == false); + ASSERT(mg_commalist(&s4, &k, &v) == false); } static void test_http_get_var(void) {