mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 15:01:03 +08:00
Commonize pattern matching functions
PUBLISHED_FROM=e69e298a51dbe0f9c47184169ecad06eef0676fc
This commit is contained in:
parent
ff078882d5
commit
244e5f67d3
@ -14,10 +14,8 @@ items:
|
||||
- { name: mg_hexdump_connection.md }
|
||||
- { name: mg_hexdumpf.md }
|
||||
- { name: mg_is_big_endian.md }
|
||||
- { name: mg_match_prefix.md }
|
||||
- { name: mg_mbuf_append_base64.md }
|
||||
- { name: mg_mbuf_append_base64_putc.md }
|
||||
- { name: mg_next_comma_list_entry.md }
|
||||
- { name: mg_open.md }
|
||||
- { name: mg_skip.md }
|
||||
- { name: mg_sock_addr_to_str.md }
|
||||
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
title: "mg_match_prefix()"
|
||||
decl_name: "mg_match_prefix"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
|
||||
---
|
||||
|
||||
Matches 0-terminated string (mg_match_prefix) or string with given length
|
||||
mg_match_prefix_n against a glob pattern.
|
||||
|
||||
Match is case-insensitive. Returns number of bytes matched, or -1 if no
|
||||
match.
|
||||
|
@ -1,21 +0,0 @@
|
||||
---
|
||||
title: "mg_next_comma_list_entry()"
|
||||
decl_name: "mg_next_comma_list_entry"
|
||||
symbol_kind: "func"
|
||||
signature: |
|
||||
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
|
||||
struct mg_str *eq_val);
|
||||
---
|
||||
|
||||
A helper function for traversing a comma separated list of values.
|
||||
It returns a list pointer shifted to the next value or NULL if the end
|
||||
of the list found.
|
||||
The value is stored in a val vector. If the value has a form "x=y", then
|
||||
eq_val vector is initialised to point to the "y" part, and val vector length
|
||||
is adjusted to point only to "x".
|
||||
If the list is just a comma separated list of entries, like "aa,bb,cc" then
|
||||
`eq_val` will contain zero-length string.
|
||||
|
||||
The purpose of this function is to parse comma separated string without
|
||||
any copying/memory allocation.
|
||||
|
179
mongoose.c
179
mongoose.c
@ -1858,6 +1858,98 @@ int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap) {
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *mg_next_comma_list_entry(const char *, struct mg_str *,
|
||||
struct mg_str *) WEAK;
|
||||
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
|
||||
struct mg_str *eq_val) {
|
||||
if (list == NULL || *list == '\0') {
|
||||
/* End of the list */
|
||||
list = NULL;
|
||||
} else {
|
||||
val->p = list;
|
||||
if ((list = strchr(val->p, ',')) != NULL) {
|
||||
/* Comma found. Store length and shift the list ptr */
|
||||
val->len = list - val->p;
|
||||
list++;
|
||||
} else {
|
||||
/* This value is the last one */
|
||||
list = val->p + strlen(val->p);
|
||||
val->len = list - val->p;
|
||||
}
|
||||
|
||||
if (eq_val != NULL) {
|
||||
/* Value has form "x=y", adjust pointers and lengths */
|
||||
/* so that val points to "x", and eq_val points to "y". */
|
||||
eq_val->len = 0;
|
||||
eq_val->p = (const char *) memchr(val->p, '=', val->len);
|
||||
if (eq_val->p != NULL) {
|
||||
eq_val->p++; /* Skip over '=' character */
|
||||
eq_val->len = val->p + val->len - eq_val->p;
|
||||
val->len = (eq_val->p - val->p) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int mg_match_prefix_n(const struct mg_str, const struct mg_str) WEAK;
|
||||
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) {
|
||||
const char *or_str;
|
||||
size_t len, i = 0, j = 0;
|
||||
int res;
|
||||
|
||||
if ((or_str = (const char *) memchr(pattern.p, '|', pattern.len)) != NULL ||
|
||||
(or_str = (const char *) memchr(pattern.p, ',', pattern.len)) != NULL) {
|
||||
struct mg_str pstr = {pattern.p, (size_t)(or_str - pattern.p)};
|
||||
res = mg_match_prefix_n(pstr, str);
|
||||
if (res > 0) return res;
|
||||
pstr.p = or_str + 1;
|
||||
pstr.len = (pattern.p + pattern.len) - (or_str + 1);
|
||||
return mg_match_prefix_n(pstr, str);
|
||||
}
|
||||
|
||||
for (; i < pattern.len; i++, j++) {
|
||||
if (pattern.p[i] == '?' && j != str.len) {
|
||||
continue;
|
||||
} else if (pattern.p[i] == '$') {
|
||||
return j == str.len ? (int) j : -1;
|
||||
} else if (pattern.p[i] == '*') {
|
||||
i++;
|
||||
if (i < pattern.len && pattern.p[i] == '*') {
|
||||
i++;
|
||||
len = str.len - j;
|
||||
} else {
|
||||
len = 0;
|
||||
while (j + len != str.len && str.p[j + len] != '/') {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
if (i == pattern.len) {
|
||||
return j + len;
|
||||
}
|
||||
do {
|
||||
const struct mg_str pstr = {pattern.p + i, pattern.len - i};
|
||||
const struct mg_str sstr = {str.p + j + len, str.len - j - len};
|
||||
res = mg_match_prefix_n(pstr, sstr);
|
||||
} while (res == -1 && len-- > 0);
|
||||
return res == -1 ? -1 : (int) (j + res + len);
|
||||
} else if (str_util_lowercase(&pattern.p[i]) !=
|
||||
str_util_lowercase(&str.p[j])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
int mg_match_prefix(const char *, int, const char *) WEAK;
|
||||
int mg_match_prefix(const char *pattern, int pattern_len, const char *str) {
|
||||
const struct mg_str pstr = {pattern, (size_t) pattern_len};
|
||||
struct mg_str s = {str, 0};
|
||||
if (str != NULL) s.len = strlen(str);
|
||||
return mg_match_prefix_n(pstr, s);
|
||||
}
|
||||
|
||||
#endif /* EXCLUDE_COMMON */
|
||||
#ifdef MG_MODULE_LINES
|
||||
#line 1 "mongoose/src/tun.h"
|
||||
@ -9451,10 +9543,6 @@ const char *mg_skip(const char *s, const char *end, const char *delims,
|
||||
return s;
|
||||
}
|
||||
|
||||
static int lowercase(const char *s) {
|
||||
return tolower(*(const unsigned char *) s);
|
||||
}
|
||||
|
||||
#if MG_ENABLE_FILESYSTEM && !defined(MG_USER_FILE_FUNCTIONS)
|
||||
int mg_stat(const char *path, cs_stat_t *st) {
|
||||
#ifdef _WIN32
|
||||
@ -9707,89 +9795,6 @@ int mg_is_big_endian(void) {
|
||||
return ((char *) &n)[0] == 0;
|
||||
}
|
||||
|
||||
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
|
||||
struct mg_str *eq_val) {
|
||||
if (list == NULL || *list == '\0') {
|
||||
/* End of the list */
|
||||
list = NULL;
|
||||
} else {
|
||||
val->p = list;
|
||||
if ((list = strchr(val->p, ',')) != NULL) {
|
||||
/* Comma found. Store length and shift the list ptr */
|
||||
val->len = list - val->p;
|
||||
list++;
|
||||
} else {
|
||||
/* This value is the last one */
|
||||
list = val->p + strlen(val->p);
|
||||
val->len = list - val->p;
|
||||
}
|
||||
|
||||
if (eq_val != NULL) {
|
||||
/* Value has form "x=y", adjust pointers and lengths */
|
||||
/* so that val points to "x", and eq_val points to "y". */
|
||||
eq_val->len = 0;
|
||||
eq_val->p = (const char *) memchr(val->p, '=', val->len);
|
||||
if (eq_val->p != NULL) {
|
||||
eq_val->p++; /* Skip over '=' character */
|
||||
eq_val->len = val->p + val->len - eq_val->p;
|
||||
val->len = (eq_val->p - val->p) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str) {
|
||||
const char *or_str;
|
||||
size_t len, i = 0, j = 0;
|
||||
int res;
|
||||
|
||||
if ((or_str = (const char *) memchr(pattern.p, '|', pattern.len)) != NULL) {
|
||||
struct mg_str pstr = {pattern.p, (size_t)(or_str - pattern.p)};
|
||||
res = mg_match_prefix_n(pstr, str);
|
||||
if (res > 0) return res;
|
||||
pstr.p = or_str + 1;
|
||||
pstr.len = (pattern.p + pattern.len) - (or_str + 1);
|
||||
return mg_match_prefix_n(pstr, str);
|
||||
}
|
||||
|
||||
for (; i < pattern.len; i++, j++) {
|
||||
if (pattern.p[i] == '?' && j != str.len) {
|
||||
continue;
|
||||
} else if (pattern.p[i] == '$') {
|
||||
return j == str.len ? (int) j : -1;
|
||||
} else if (pattern.p[i] == '*') {
|
||||
i++;
|
||||
if (i < pattern.len && pattern.p[i] == '*') {
|
||||
i++;
|
||||
len = str.len - j;
|
||||
} else {
|
||||
len = 0;
|
||||
while (j + len != str.len && str.p[j + len] != '/') {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
if (i == pattern.len) {
|
||||
return j + len;
|
||||
}
|
||||
do {
|
||||
const struct mg_str pstr = {pattern.p + i, pattern.len - i};
|
||||
const struct mg_str sstr = {str.p + j + len, str.len - j - len};
|
||||
res = mg_match_prefix_n(pstr, sstr);
|
||||
} while (res == -1 && len-- > 0);
|
||||
return res == -1 ? -1 : (int) (j + res + len);
|
||||
} else if (lowercase(&pattern.p[i]) != lowercase(&str.p[j])) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
int mg_match_prefix(const char *pattern, int pattern_len, const char *str) {
|
||||
const struct mg_str pstr = {pattern, (size_t) pattern_len};
|
||||
return mg_match_prefix_n(pstr, mg_mk_str(str));
|
||||
}
|
||||
|
||||
DO_NOT_WARN_UNUSED MG_INTERNAL int mg_get_errno(void) {
|
||||
#ifndef WINCE
|
||||
|
53
mongoose.h
53
mongoose.h
@ -1955,6 +1955,7 @@ int cs_base64_decode(const unsigned char *s, int len, char *dst, int *dec_len);
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Amalgamated: #include "common/platform.h" */
|
||||
/* Amalgamated: #include "common/mg_str.h" */
|
||||
|
||||
#ifndef CS_ENABLE_STRDUP
|
||||
#define CS_ENABLE_STRDUP 0
|
||||
@ -2049,6 +2050,32 @@ int mg_asprintf(char **buf, size_t size, const char *fmt, ...);
|
||||
/* Same as mg_asprintf, but takes varargs list. */
|
||||
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
|
||||
|
||||
/*
|
||||
* A helper function for traversing a comma separated list of values.
|
||||
* It returns a list pointer shifted to the next value or NULL if the end
|
||||
* of the list found.
|
||||
* The value is stored in a val vector. If the value has a form "x=y", then
|
||||
* eq_val vector is initialised to point to the "y" part, and val vector length
|
||||
* is adjusted to point only to "x".
|
||||
* If the list is just a comma separated list of entries, like "aa,bb,cc" then
|
||||
* `eq_val` will contain zero-length string.
|
||||
*
|
||||
* The purpose of this function is to parse comma separated string without
|
||||
* any copying/memory allocation.
|
||||
*/
|
||||
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
|
||||
struct mg_str *eq_val);
|
||||
|
||||
/*
|
||||
* Matches 0-terminated string (mg_match_prefix) or string with given length
|
||||
* mg_match_prefix_n against a glob pattern.
|
||||
*
|
||||
* Match is case-insensitive. Returns number of bytes matched, or -1 if no
|
||||
* match.
|
||||
*/
|
||||
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
|
||||
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -4048,32 +4075,6 @@ void mg_hexdump_connection(struct mg_connection *nc, const char *path,
|
||||
*/
|
||||
int mg_is_big_endian(void);
|
||||
|
||||
/*
|
||||
* A helper function for traversing a comma separated list of values.
|
||||
* It returns a list pointer shifted to the next value or NULL if the end
|
||||
* of the list found.
|
||||
* The value is stored in a val vector. If the value has a form "x=y", then
|
||||
* eq_val vector is initialised to point to the "y" part, and val vector length
|
||||
* is adjusted to point only to "x".
|
||||
* If the list is just a comma separated list of entries, like "aa,bb,cc" then
|
||||
* `eq_val` will contain zero-length string.
|
||||
*
|
||||
* The purpose of this function is to parse comma separated string without
|
||||
* any copying/memory allocation.
|
||||
*/
|
||||
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
|
||||
struct mg_str *eq_val);
|
||||
|
||||
/*
|
||||
* Matches 0-terminated string (mg_match_prefix) or string with given length
|
||||
* mg_match_prefix_n against a glob pattern.
|
||||
*
|
||||
* Match is case-insensitive. Returns number of bytes matched, or -1 if no
|
||||
* match.
|
||||
*/
|
||||
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
|
||||
int mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);
|
||||
|
||||
/*
|
||||
* Use with cs_base64_init/update/finish in order to write out base64 in chunks.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user