/** * Takes delimiter tags and sets the delimiter for the parser. * * @param sds tag The tag * * @retval sdsempty() Emtpy sds string. */ static sds tag_delimiter(sds tag) { puts("tag_delimiter"); printf("tag found: '%s'\n",tag); sds re = sdsempty(); sds oldl = sdsdup(ldelim), oldr = sdsdup(rdelim); re = sdscatprintf(re, "(%s=\\S+)\\s+(\\S+=%s)", oldl, oldr); struct slre_cap caps[2]; int i; if ((i = slre_match(re, tag, sdslen(tag), caps, 2)) > 0) { ldelim = sdscpylen(ldelim, caps[0].ptr, caps[0].len); rdelim = sdscpylen(rdelim, caps[1].ptr, caps[1].len); oldl = sdscatprintf(sdsempty(), "%s=", oldl); oldr = sdscatprintf(sdsempty(), "=%s", oldr); ldelim = sdsreplace(ldelim, oldl, NULL); rdelim = sdsreplace(rdelim, oldr, NULL); printf("ldelim: '%s'\n", ldelim); printf("rdelim: '%s'\n", rdelim); } printf("Matched: %d\n",i); puts("free oldl); sdsfree(oldr); sdsfree(re"); sdsfree(oldl); sdsfree(oldr); sdsfree(re); return sdsempty(); }
void handle_request(char* client_message, int sock) { struct slre_cap caps[4], params[2]; parse_http_request(client_message, caps); char *path = malloc(caps[1].len + 1); memcpy(path, caps[1].ptr, caps[1].len); path[caps[1].len] = '\0'; if (!slre_match("^/([a-z]+)/([a-z]+)", path, strlen(path), params, 2, 0) > 0) { printf("Error parsing [%s]\n", path); exit(1); } else { char *service = malloc(params[0].len + 1); memcpy(service, params[0].ptr, params[0].len); service[params[0].len] = '\0'; char *username = malloc(params[1].len + 1); memcpy(username, params[1].ptr, params[1].len); username[params[1].len] = '\0'; char *image_url; if (strcmp(service, "instagram") == 0) { image_url = get_instagram_url_for(username); } else if (strcmp(service, "facebook") == 0) { image_url = get_facebook_url_for(username); } else if (strcmp(service, "twitter") == 0) { image_url = get_twitter_url_for(username); } else if (strcmp(service, "gravatar") == 0) { image_url = get_gravatar_url_for(username); } download_jpeg(image_url, sock); } }
void parse_http_request(char* request, struct slre_cap *caps) { if (!slre_match("^\\s*(\\S+)\\s+(\\S+)\\s+HTTP/(\\d)\\.(\\d)", request, strlen(request), caps, 4, 0) > 0) { printf("Error parsing [%s]\n", request); exit(1); } }
/** * Wrapper for slre_match that returns all matches as an array. * * @param const char *re The regular expression to be matched. * @param const char *buf The buffer to search in. * @param int bl Length of buffer. * @param struct slre_cap *caps Array to store subpatterns in. * @param int num_caps Number of subpatterns in regular expression. * * @retval struct slre_cap* Array of slre_cap structures. */ static struct slre_cap* slre_match_all( const char *re, const char *buf, int bl, struct slre_cap *caps, int num_caps) { puts("slre_match_all"); int count = 0, i = 0, j = 0; struct slre_cap* buffer; buffer = (struct slre_cap*)malloc(1024*sizeof(struct slre_cap)); while (j < bl && (i = slre_match(re, buf+j, bl-j, caps, num_caps)) > 0) { buffer[count]=caps[0]; count++; j += i; } struct slre_cap *res = (struct slre_cap*)malloc(count*sizeof(struct slre_cap)); for (i=0; i<count; i++) { res[i] = buffer[i]; } free((void*) buffer); return res; }
int main(int argc, char **argv) { Stopif(argc < 2, "Supply bignum value in argv[1]!\n"); slre_cap SlreCaps[3]; u8 InputBuffer[128]; i32 MatchedStringLength = slre_match("((\\d|[a-f])*)", argv[1], strlen(argv[1]), SlreCaps, ARRAY_LENGTH(SlreCaps), SLRE_IGNORE_CASE); if (MatchedStringLength > 0) { Stopif(SlreCaps[0].len % 2, "Invalid hex digit match!\n"); HexStringToByteArray(InputBuffer, (char *)SlreCaps[0].ptr, SlreCaps[0].len); u32 InputBuffLengthBytes = MatchedStringLength/2; ByteSwap(InputBuffer, InputBuffLengthBytes); for (u32 ArrayIndex = 0; ArrayIndex < InputBuffLengthBytes; ++ArrayIndex) { printf("0x%02x, ", InputBuffer[ArrayIndex]); } printf("\n"); } }
/* Regex must have exactly one bracket pair */ static char *slre_replace(const char *regex, const char *buf, const char *sub) { char *s = NULL; int n, n1, n2, n3, s_len, len = strlen(buf); struct slre_cap cap = { NULL, 0 }; do { s_len = s == NULL ? 0 : strlen(s); if ((n = slre_match(regex, buf, len, &cap, 1)) > 0) { n1 = cap.ptr - buf, n2 = strlen(sub), n3 = &buf[n] - &cap.ptr[cap.len]; } else { n1 = len, n2 = 0, n3 = 0; } s = (char *) realloc(s, s_len + n1 + n2 + n3 + 1); memcpy(s + s_len, buf, n1); memcpy(s + s_len + n1, sub, n2); memcpy(s + s_len + n1 + n2, cap.ptr + cap.len, n3); s[s_len + n1 + n2 + n3] = '\0'; buf += n > 0 ? n : len; len -= n > 0 ? n : len; } while (len > 0); return s; }
/** * Takes partial tags and replaces them with a parsed partial template. * * @param sds tag The tag * * @retval sds buff Partial template buffer. */ static sds tag_partial(sds tag) { puts("tag_partial"); printf("tag found: '%s'\n",tag); sds re = sdsempty(); sds f = sdsempty(); sds buff = sdsempty(); re = sdscatprintf(re, "%s>([^}]+)%s", ldelim, rdelim); struct slre_cap caps[1]; if (slre_match(re, tag, strlen(tag), caps, 1) > 0) { f = sdscatprintf(f,"%.*s", caps[0].len, caps[0].ptr); sdstrim(f," "); sds fname = sdscatprintf(sdsempty(),"%s%s", tpldir, f); fname = sdscat(fname,tplext); //puts(fname); FILE * fp; if ((fp = fopen(fname, "r")) != NULL) { fclose(fp); buff = render_template(f); } puts("free fname"); sdsfree(fname); } puts("free f"); sdsfree(f); // //sdsfree(buff); puts("free re"); sdsfree(re); return buff; }
static int match_string(int flag, const char *str, const char *pat, void *priv) { switch (flag & H_MATCH_METHOD) { case H_MATCH_IDENT: if (strcmp(str, pat) == 0) return 1; break; case H_MATCH_SUBSTR: if (strstr(str, pat)) return 1; break; #ifdef CONFIG_REGEX case H_MATCH_REGEX: { struct slre *slrep = (struct slre *)priv; struct cap caps[slrep->num_caps + 2]; if (slre_match(slrep, str, strlen(str), caps)) return 1; } break; #endif default: printf("## ERROR: unsupported match method: 0x%02x\n", flag & H_MATCH_METHOD); break; } return 0; }
int my_bind_cr(int count, int key) { struct slre_cap caps[4]; if (my_eoq == 1 || slre_match("(\\\\G|;)\\s*$", rl_line_buffer, strlen(rl_line_buffer), caps, 4, SLRE_IGNORE_CASE) > 0){ rl_done = 1; return 1; } else if( slre_match("^(\\\\q|exit)$", rl_line_buffer, strlen(rl_line_buffer), caps, 4, 0) > 0) { rl_done = 1;exit_flag=1; return 1; } if (strcmp( rl_line_buffer , "") == 0 || slre_match("^\\s+$", rl_line_buffer, strlen(rl_line_buffer), caps, 4, 0) > 0) { printf("\n"); rl_on_new_line(); }else{ rl_insert_text(" \n"); } return 1; }
static void Str_split(struct v7_c_func_arg *cfa) { const struct v7_string *s = &cfa->this_obj->v.str; const char *p1, *p2, *e = s->buf + s->len; int limit = cfa->num_args == 2 && cfa->args[1]->type == V7_TYPE_NUM ? cfa->args[1]->v.num : -1; int num_elems = 0; v7_set_class(cfa->result, V7_CLASS_ARRAY); if (cfa->num_args == 0) { v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, s->buf, s->len, 1)); } else if (cfa->args[0]->type == V7_TYPE_STR) { const struct v7_string *sep = &cfa->args[0]->v.str; if (sep->len == 0) { // Separator is empty. Split string by characters. for (p1 = s->buf; p1 < e; p1++) { if (limit >= 0 && limit <= num_elems) return; v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, p1, 1, 1)); num_elems++; } } else { p1 = s->buf; while ((p2 = memstr(p1, e - p1, sep->buf, sep->len)) != NULL) { if (limit >= 0 && limit <= num_elems) return; v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, p1, p2 - p1, 1)); p1 = p2 + sep->len; num_elems++; } if (limit < 0 || limit > num_elems) { v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, p1, e - p1, 1)); } } } else if (instanceof(cfa->args[0], &s_constructors[V7_CLASS_REGEXP])) { char regex[200]; struct slre_cap caps[20]; int n = 0; snprintf(regex, sizeof(regex), "(%s)", cfa->args[0]->v.regex); p1 = s->buf; while ((n = slre_match(regex, p1, e - p1, caps, ARRAY_SIZE(caps), 0)) > 0) { if (limit >= 0 && limit <= num_elems) return; v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, p1, caps[0].ptr - p1, 1)); p1 += n; num_elems++; } if (limit < 0 || limit > num_elems) { v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, p1, e - p1, 1)); } } }
/******************************************************************** parseCmds loops through a list of hear functions and tries to match queries and execute reply response functions ********************************************************************/ void ArduinoSlackBot::parseCmds() { struct slre_cap matches[4]; //you must reference the bot to get a response if (slre_match(botID, slackMsg.text, strlen(slackMsg.text), matches, 4, 0) > 0) { PRINTLN(ESP.getFreeHeap()); for (int i=0; i <= qrListLength-1; i++) { //match the provided regex if (slre_match(qrList[i]->query, slackMsg.text, strlen(slackMsg.text), matches, 4, 0) > 0) { PRINTLN(matches[0].ptr); qrList[i]->resp(); //execute provided bot response return; //stop matching if match is found } } replyMsg(failMsg); } }
int benchmark() { int i; int len = strlen(text); struct slre_cap captures; volatile int ret=0; for(i = 0; i < 4; ++i) { ret += slre_match(regexes[i], text, len, &captures, 1); } return ret; }
static int match_re(string source, int start, struct slre_cap* groups, string* match_start){ int len = strlen(source) - start; struct slre_cap groups_with_doc[2]; struct slre_cap groups_without_doc[2]; int withdoc = slre_match(RE_PUBLIC_DOC, source + start, len, groups_with_doc, 2, 0); int withoutdoc = slre_match(RE_PUBLIC, source + start, len, groups_without_doc, 2, 0); if ((0 <= withdoc && 0 > withoutdoc) || (0 <= withdoc && groups_with_doc[0].ptr < groups_without_doc[0].ptr)) { //With doc groups[0].ptr = groups_with_doc[0].ptr; groups[0].len = groups_with_doc[0].len; groups[1].ptr = groups_with_doc[1].ptr; groups[1].len = groups_with_doc[1].len; *match_start = (string) groups[0].ptr; return withdoc; } else if ((0 <= withoutdoc && 0 > withdoc) || (0 <= withoutdoc && groups_without_doc[0].ptr < groups_with_doc[0].ptr)) { //Without doc groups[0].ptr = NULL; groups[0].len = 0; groups[1].ptr = groups_without_doc[1].ptr; groups[1].len = groups_without_doc[1].len; *match_start = (string) groups_without_doc[0].ptr; return withoutdoc; } else { return -1; } }
/* * Check if "requestLine" is a bad request * Uses a regular expression library see --> https://github.com/cesanta/slre */ bool isBadRequest(char* requestLine) { bool isBad = false; struct slre_cap caps[4]; if (slre_match("^\\s*(\\S+)\\s+(\\S+)\\s+HTTP/(\\d)\\.(\\d)", requestLine, strlen(requestLine), caps, 4, 0) <= 0) { isBad = true; }else{ //printf("Method: [%.*s], URI: [%.*s]\n",caps[0].len, caps[0].ptr,caps[1].len, caps[1].ptr); } return isBad; }
std::vector<std::string> NP::Regex::match_groups(const std::string &re, const std::string &string, int ncaps, int flags) { std::vector<std::string> result; slre_cap *caps = new slre_cap[ncaps]; if (slre_match(re.c_str(), string.c_str(), string.length(), caps, ncaps, flags) > 0) { for (int i=0; i<ncaps; i++) { result.push_back(std::string(caps[i].ptr, caps[i].len)); } } delete [] caps; return result; }
int re_match( int nPossCaptures, struct cap* captures, char* mExpression, char* mString ) { struct slre slre; int len = strlen(mString); init_captures(nPossCaptures, captures); if (!slre_compile(&slre, mExpression )) { printf("Error compiling RE: %s\n", slre.err_str); return 0; } else if (slre_match(&slre, mString, len, captures)) { return 1; } else return 0; }
/** * Wrapper for slre_match that counts the matches. * * @param const char *re The regular expression to be matched. * @param const char *buf The buffer to search in. * @param int bl Length of buffer. * @param struct slre_cap *caps Array to store subpatterns in. * @param int num_caps Number of subpatterns in regular expression. * * @retval int count The number of matches in regular expression. */ static int slre_match_count( const char *re, const char *buf, int bl, struct slre_cap *caps, int num_caps) { puts("slre_match_count"); int count = 0, i = 0, j = 0; while (j < bl && (i = slre_match(re, buf+j, bl-j, caps, num_caps)) > 0) { count++; j += i; } return count; }
int pedirStringConFormato(char* dato,char* formato,char* msg, int max, int min, char*errorMsg) { char buff[4000]; struct slre_cap caps[4]; short int hayError = 0; short int continuar = 1; do { hayError = 0; printf("%s",msg); fflush(stdin); scanf("%[a-zA-Z0-9 ]",buff); if (slre_match(formato,buff, strlen(buff), caps, 4, 0) == SLRE_NO_MATCH) { printf("No cumple el formato\n"); hayError = 1; } if(strlen(buff) > max) { hayError = 1; } if(!hayError && strlen(buff) < min) { hayError = 1; } if(hayError) { printf("%s",errorMsg); continuar = confirmacionSinReintentos("Desea intentar otra vez?\n",'s','n'); } }while(continuar && hayError); if(!hayError) { strcpy(dato,buff); return 0; } return -1; }
bool zrex_matches (zrex_t *self, const char *text) { assert (self); assert (text); // Free any previously-allocated hits self->hits = 0; bool matches = slre_match (&self->slre, text, strlen (text), self->caps) != 0; if (matches) { // Count number of captures plus whole string self->hits = self->slre.num_caps + 1; if (self->hits > MAX_HITS) self->hits = MAX_HITS; // Collect hits and prepare hit array, which is a single block of // memory holding all hits as null-terminated strings uint index; // First count total length of hit strings size_t hit_set_len = 0; for (index = 0; index < self->hits; index++) hit_set_len += self->caps [index].len + 1; if (hit_set_len > self->hit_set_len) { zstr_free (&self->hit_set); self->hit_set = (char *) zmalloc (hit_set_len); self->hit_set_len = hit_set_len; } // FIXME: no way to return an error assert (self->hit_set); // Now prepare hit strings for access by caller char *hit_set_ptr = self->hit_set; for (index = 0; index < self->hits; index++) { memcpy (hit_set_ptr, self->caps [index].ptr, self->caps [index].len); self->hit [index] = hit_set_ptr; hit_set_ptr += self->caps [index].len + 1; } } return matches; }
static void Str_match(struct v7_c_func_arg *cfa) { struct slre_cap caps[100]; const struct v7_string *s = &cfa->this_obj->v.str; int i, n; cfa->result->type = V7_TYPE_NULL; memset(caps, 0, sizeof(caps)); if (cfa->num_args == 1 && v7_is_class(cfa->args[0], V7_CLASS_REGEXP) && (n = slre_match(cfa->args[0]->v.regex, s->buf, s->len, caps, ARRAY_SIZE(caps) - 1, 0)) > 0) { v7_set_class(cfa->result, V7_CLASS_ARRAY); v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, s->buf, (long) n, 1)); for (i = 0; i < (int) ARRAY_SIZE(caps); i++) { if (caps[i].len == 0) break; v7_append(cfa->v7, cfa->result, v7_mkv(cfa->v7, V7_TYPE_STR, caps[i].ptr, (long) caps[i].len, 1)); } } }
int mapper_get_mapperid_unif(char *str) { int ret,i; const char *err; char tmpstr[4][256]; ret = B_UNSUPPORTED; for(i=0;boards[i].boardid != -1;i++) { err = slre_match(SLRE_CASE_INSENSITIVE,boards[i].name,str,strlen(str), SLRE_STRING,sizeof(tmpstr[0]),tmpstr[0], SLRE_STRING,sizeof(tmpstr[1]),tmpstr[1], SLRE_STRING,sizeof(tmpstr[2]),tmpstr[2], SLRE_STRING,sizeof(tmpstr[3]),tmpstr[3]); if(err == NULL) { if(ret != B_UNSUPPORTED) log_printf("mapper_get_mapperid_unif: duplicate match for board '%s'\n",str); ret = boards[i].boardid; } else if(stricmp(err,"no match") != 0) log_printf("mapper_get_mapperid_unif: slre error: %s ('%s' -- '%s')\n",err,boards[i].name,str); } return(ret); }
static int32_t command_matches (const char *input, char *output, uint8_t show_ambiguous, uint8_t show_complete, uint8_t execute_command, void *context) { char cand_expand_to[MAXSTR]; command_t *matched_command; char completes_to[MAXSTR]; char expands_to[MAXSTR]; tokens_t input_tokens; char match[MAXSTR]; char match2[MAXSTR]; int32_t longest_match; int32_t common_len; command_t *command; int32_t matches; int32_t cnt; int32_t t; matched_command = 0; longest_match = -1; matches = 0; /* * Convert the input into tokens for matching. */ tokens_tostring(input, &input_tokens); /* * Find the command(s) with the most number of matching tokens. */ TREE_WALK(commands, command) { for (t = 0; t < (int32_t)min(command->tokens.cnt, input_tokens.cnt); t++) { cnt = strncmp(command->tokens.args[t], input_tokens.args[t], strlen(input_tokens.args[t])); if (slre_match(&command->tokens.regexp[t], input_tokens.args[t], (int) strlen(input_tokens.args[t]), 0 /* captures */)) { /* * Success */ cnt = 0; } if (cnt) { t = -1; break; } } longest_match = max(t, longest_match); } if (longest_match == -1) { return (0); } /* * Repeat and optionally dump other possibilities if the command is * not complete. */ { TREE_WALK(commands, command) { for (t = 0; t < (int32_t)min(command->tokens.cnt, input_tokens.cnt); t++) { cnt = strncmp(command->tokens.args[t], input_tokens.args[t], strlen(input_tokens.args[t])); if (slre_match(&command->tokens.regexp[t], input_tokens.args[t], (int) strlen(input_tokens.args[t]), 0 /* captures */)) { /* * Success */ cnt = 0; } if (cnt) { break; } } // tokens_print_to(&command->readable_tokens, match, sizeof(match)); if (t == longest_match) { matches++; // CON(" MATCH \"%s\" [%d] longest %d", match,t,longest_match); matched_command = command; if (show_complete) { completes_to[0] = '\0'; for (t = 0; t < longest_match; t++) { strlcat(completes_to, command->tokens.args[t], sizeof(completes_to)); strlcat(completes_to, " ", sizeof(completes_to)); } if (output) { strlcpy(output, completes_to, MAXSTR); } } tokens_print_to(&command->input_tokens, match, sizeof(match)); tokens_print_to(&command->readable_tokens, match2, sizeof(match2)); if (show_ambiguous) { CON(" %-40s -- %s", match, match2); } } else { // CON(" NO MATCH \"%s\" [%d] longest %d", match,t,longest_match); } } } /* * Repeat and complete the command to any full matches. */ { expands_to[0] = '\0'; { TREE_WALK(commands, command) { for (t = 0; t < (int32_t)min(command->tokens.cnt, input_tokens.cnt); t++) { cnt = strncmp(command->tokens.args[t], input_tokens.args[t], strlen(input_tokens.args[t])); if (slre_match(&command->tokens.regexp[t], input_tokens.args[t], (int) strlen(input_tokens.args[t]), 0 /* captures */)) { /* * Success */ cnt = 0; } if (cnt) { break; } } if (t == longest_match) { cand_expand_to[0] = '\0'; for (t = 0; t < longest_match; t++) { if (strisregexp(command->tokens.args[t])) { strlcat(cand_expand_to, input_tokens.args[t], sizeof(cand_expand_to)); strlcat(cand_expand_to, " ", sizeof(cand_expand_to)); continue; } strlcat(cand_expand_to, command->tokens.args[t], sizeof(cand_expand_to)); strlcat(cand_expand_to, " ", sizeof(cand_expand_to)); } if (expands_to[0] != '\0') { common_len = strcommon(expands_to, cand_expand_to); expands_to[common_len] = '\0'; } else { strlcpy(expands_to, cand_expand_to, sizeof(expands_to)); } } } /* * Expands to: */ if (output) { strlcpy(output, expands_to, MAXSTR); } } } if (execute_command && matched_command && (matches == 1)) { (*matched_command->callback)(&input_tokens, context); } return (matches); }
void _ortc_parse_message(ortc_context *context, char *message){ char *messageId, *messageCount, *messageTotal, *messagePart, *channelNameStr, *messageStr, *params, *permissionsStr, *exceptionStr, *validateString, *operationType; struct cap pmatch[3], pmatch2[5]; int iMessageTotal, wsSock, opt; size_t len, hbLen; ortc_dnode *ch; char hbStr[24]; if(message[0] == 'a') { if (slre_match(&context->reMessage, message, (int)strlen(message), pmatch)) { //is message channelNameStr = _ortc_get_from_slre(1, pmatch); messageStr = _ortc_get_from_slre(2, pmatch); if(slre_match(&context->reMultipart, messageStr, (int)strlen(messageStr), pmatch2)){ messageId = _ortc_get_from_slre(1, pmatch2); messageCount = _ortc_get_from_slre(2, pmatch2); messageTotal = _ortc_get_from_slre(3, pmatch2); messagePart = _ortc_get_from_slre(4, pmatch2); iMessageTotal = atoi(messageTotal); if(iMessageTotal > 1){ //multipart message _ortc_dlist_insert(context->multiparts, messageId, channelNameStr, messagePart, atoi(messageCount), NULL); _ortc_check_if_got_all_parts(context, messageId, iMessageTotal); } else { _ortc_fire_onMessage(context, channelNameStr, messagePart); } free(messageId); free(messageCount); free(messageTotal); free(messagePart); } else { _ortc_fire_onMessage(context, channelNameStr, messageStr); } free(channelNameStr); free(messageStr); } else if (slre_match(&context->reOperation, message, (int)strlen(message), pmatch)) { params = _ortc_get_from_slre(2, pmatch); operationType = _ortc_get_from_slre(1, pmatch); if(strncmp(operationType, "ortc-validated", 14)==0){ if(slre_match(&context->rePermissions, params, (int)strlen(params), pmatch2)){ permissionsStr = _ortc_get_from_slre(1, pmatch2); _ortc_save_permissions(context, permissionsStr); free(permissionsStr); } _ortc_change_state(context, CONNECTED); } else if(strncmp(operationType, "ortc-subscribed", 15)==0){ if(slre_match(&context->reChannel, params, (int)strlen(params), pmatch2)){ channelNameStr = _ortc_get_from_slre(1, pmatch2); ch = _ortc_dlist_search(context->channels, channelNameStr); if(ch != NULL) ch->num += 2; //isSubscribed if(context->onSubscribed != NULL) context->onSubscribed(context, channelNameStr); free(channelNameStr); } } else if(strncmp(operationType, "ortc-unsubscribed", 17)==0){ if(slre_match(&context->reChannel, params, (int)strlen(params), pmatch2)){ channelNameStr = _ortc_get_from_slre(1, pmatch2); _ortc_dlist_delete(context->channels, channelNameStr); if(context->onUnsubscribed != NULL) context->onUnsubscribed(context, channelNameStr); free(channelNameStr); } } else if(strncmp(operationType, "ortc-error", 10)==0){ if(slre_match(&context->reException, params, (int)strlen(params), pmatch2)){ _ortc_cancel_connecting(context); exceptionStr = _ortc_get_from_slre(1, pmatch2); _ortc_exception(context, exceptionStr); free(exceptionStr); } } free(params); free(operationType); } } else if(message[0] == 'o' && strlen(message)==1){ wsSock = libwebsocket_get_socket_fd(context->wsi); opt = ORTC_SNDBUF_SIZE; setsockopt(wsSock, SOL_SOCKET, SO_SNDBUF, (const char*)&opt, sizeof(opt)); if(context->heartbeatActive){ snprintf(hbStr, sizeof(hbStr), "%d;%d;", context->heartbeatTime, context->heartbeatFails); hbLen = strlen(hbStr); } else { hbLen = 0; } len = 17 + strlen(context->appKey) + strlen(context->authToken) + strlen(context->announcementSubChannel) + strlen(context->sessionId) + strlen(context->metadata) + hbLen; validateString = malloc(len+1); if(validateString == NULL){ _ortc_exception(context, "malloc() failed in ortc parese message"); return; } if(context->heartbeatActive) snprintf(validateString, len, "\"validate;%s;%s;%s;%s;%s;%s\"", context->appKey, context->authToken, context->announcementSubChannel, context->sessionId, context->metadata, hbStr); else snprintf(validateString, len, "\"validate;%s;%s;%s;%s;%s;\"", context->appKey, context->authToken, context->announcementSubChannel, context->sessionId, context->metadata); _ortc_send_command(context, validateString); } else if(strncmp(message, "c[1000,\"Normal closure\"]", 20)==0){ _ortc_exception(context, "Server is about to close the websocket!"); } }
bool static isVertexShader(char const* str) { return slre_match(&moduleData.vertexShaderDetectRegex, str, strlen(str), NULL); }
int main(void) { struct slre_cap caps[10]; /* Metacharacters */ ASSERT(slre_match("$", "abcd", 4, NULL, 0) == 4); ASSERT(slre_match("^", "abcd", 4, NULL, 0) == 0); ASSERT(slre_match("x|^", "abcd", 4, NULL, 0) == 0); ASSERT(slre_match("x|$", "abcd", 4, NULL, 0) == 4); ASSERT(slre_match("x", "abcd", 4, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match(".", "abcd", 4, NULL, 0) == 1); ASSERT(slre_match("(?i)^.*\\\\.*$", "c:\\Tools", 8, NULL, 0) == 8); ASSERT(slre_match("\\", "a", 1, NULL, 0) == SLRE_INVALID_METACHARACTER); ASSERT(slre_match("\\x", "a", 1, NULL, 0) == SLRE_INVALID_METACHARACTER); ASSERT(slre_match("\\x1", "a", 1, NULL, 0) == SLRE_INVALID_METACHARACTER); ASSERT(slre_match("\\x20", " ", 1, NULL, 0) == 1); ASSERT(slre_match("^.+$", "", 0, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("^(.+)$", "", 0, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("(?i)^([\\+-]?)([\\d]+)$", "+", 1, caps, 10) == SLRE_NO_MATCH); ASSERT(slre_match("(?i)^([\\+-]?)([\\d]+)$", "+27", 3, caps, 10) == 3); ASSERT(caps[0].len == 1); ASSERT(caps[0].ptr[0] == '+'); ASSERT(caps[1].len == 2); ASSERT(memcmp(caps[1].ptr, "27", 2) == 0); ASSERT(slre_match("tel:\\+(\\d+[\\d-]+\\d)", "tel:+1-201-555-0123;a=b", 23, caps, 10) == 19); ASSERT(caps[0].len == 14); ASSERT(memcmp(caps[0].ptr, "1-201-555-0123", 14) == 0); /* Character sets */ ASSERT(slre_match("[abc]", "1c2", 3, NULL, 0) == 2); ASSERT(slre_match("[abc]", "1C2", 3, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("(?i)[abc]", "1C2", 3, NULL, 0) == 2); ASSERT(slre_match("[.2]", "1C2", 3, NULL, 0) == 1); ASSERT(slre_match("[\\S]+", "ab cd", 5, NULL, 0) == 2); ASSERT(slre_match("[\\S]+\\s+[tyc]*", "ab cd", 5, NULL, 0) == 4); ASSERT(slre_match("[\\d]", "ab cd", 5, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("[^\\d]", "ab cd", 5, NULL, 0) == 1); ASSERT(slre_match("[^\\d]+", "abc123", 6, NULL, 0) == 3); ASSERT(slre_match("[1-5]+", "123456789", 9, NULL, 0) == 5); ASSERT(slre_match("[1-5a-c]+", "123abcdef", 9, NULL, 0) == 6); ASSERT(slre_match("[1-5a-]+", "123abcdef", 9, NULL, 0) == 4); ASSERT(slre_match("[1-5a-]+", "123a--2oo", 9, NULL, 0) == 7); ASSERT(slre_match("[htps]+://", "https://", 8, NULL, 0) == 8); ASSERT(slre_match("[^\\s]+", "abc def", 7, NULL, 0) == 3); ASSERT(slre_match("[^fc]+", "abc def", 7, NULL, 0) == 2); ASSERT(slre_match("[^d\\sf]+", "abc def", 7, NULL, 0) == 3); /* Flags - case sensitivity */ ASSERT(slre_match("FO", "foo", 3, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("(?i)FO", "foo", 3, NULL, 0) == 2); ASSERT(slre_match("(?m)FO", "foo", 3, NULL, 0) == SLRE_UNEXPECTED_QUANTIFIER); ASSERT(slre_match("(?m)x", "foo", 3, NULL, 0) == SLRE_UNEXPECTED_QUANTIFIER); ASSERT(slre_match("fo", "foo", 3, NULL, 0) == 2); ASSERT(slre_match(".+", "foo", 3, NULL, 0) == 3); ASSERT(slre_match(".+k", "fooklmn", 7, NULL, 0) == 4); ASSERT(slre_match(".+k.", "fooklmn", 7, NULL, 0) == 5); ASSERT(slre_match("p+", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("ok", "fooklmn", 7, NULL, 0) == 4); ASSERT(slre_match("lmno", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("mn.", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("o", "fooklmn", 7, NULL, 0) == 2); ASSERT(slre_match("^o", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("^", "fooklmn", 7, NULL, 0) == 0); ASSERT(slre_match("n$", "fooklmn", 7, NULL, 0) == 7); ASSERT(slre_match("n$k", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("l$", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match(".$", "fooklmn", 7, NULL, 0) == 7); ASSERT(slre_match("a?", "fooklmn", 7, NULL, 0) == 0); ASSERT(slre_match("^a*CONTROL", "CONTROL", 7, NULL, 0) == 7); ASSERT(slre_match("^[a]*CONTROL", "CONTROL", 7, NULL, 0) == 7); ASSERT(slre_match("^(a*)CONTROL", "CONTROL", 7, NULL, 0) == 7); ASSERT(slre_match("^(a*)?CONTROL", "CONTROL", 7, NULL, 0) == 7); ASSERT(slre_match("\\_", "abc", 3, NULL, 0) == SLRE_INVALID_METACHARACTER); ASSERT(slre_match("+", "fooklmn", 7, NULL, 0) == SLRE_UNEXPECTED_QUANTIFIER); ASSERT(slre_match("()+", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); ASSERT(slre_match("\\x", "12", 2, NULL, 0) == SLRE_INVALID_METACHARACTER); ASSERT(slre_match("\\xhi", "12", 2, NULL, 0) == SLRE_INVALID_METACHARACTER); ASSERT(slre_match("\\x20", "_ J", 3, NULL, 0) == 2); ASSERT(slre_match("\\x4A", "_ J", 3, NULL, 0) == 3); ASSERT(slre_match("\\d+", "abc123def", 9, NULL, 0) == 6); /* Balancing brackets */ ASSERT(slre_match("(x))", "fooklmn", 7, NULL, 0) == SLRE_UNBALANCED_BRACKETS); ASSERT(slre_match("(", "fooklmn", 7, NULL, 0) == SLRE_UNBALANCED_BRACKETS); ASSERT(slre_match("klz?mn", "fooklmn", 7, NULL, 0) == 7); ASSERT(slre_match("fa?b", "fooklmn", 7, NULL, 0) == SLRE_NO_MATCH); /* Brackets & capturing */ ASSERT(slre_match("^(te)", "tenacity subdues all", 20, caps, 10) == 2); ASSERT(slre_match("(bc)", "abcdef", 6, caps, 10) == 3); ASSERT(slre_match(".(d.)", "abcdef", 6, caps, 10) == 5); ASSERT(slre_match(".(d.)\\)?", "abcdef", 6, caps, 10) == 5); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "de", 2) == 0); ASSERT(slre_match("(.+)", "123", 3, caps, 10) == 3); ASSERT(slre_match("(2.+)", "123", 3, caps, 10) == 3); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "23", 2) == 0); ASSERT(slre_match("(.+2)", "123", 3, caps, 10) == 2); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "12", 2) == 0); ASSERT(slre_match("(.*(2.))", "123", 3, caps, 10) == 3); ASSERT(slre_match("(.)(.)", "123", 3, caps, 10) == 2); ASSERT(slre_match("(\\d+)\\s+(\\S+)", "12 hi", 5, caps, 10) == 5); ASSERT(slre_match("ab(cd)+ef", "abcdcdef", 8, NULL, 0) == 8); ASSERT(slre_match("ab(cd)*ef", "abcdcdef", 8, NULL, 0) == 8); ASSERT(slre_match("ab(cd)+?ef", "abcdcdef", 8, NULL, 0) == 8); ASSERT(slre_match("ab(cd)+?.", "abcdcdef", 8, NULL, 0) == 5); ASSERT(slre_match("ab(cd)?", "abcdcdef", 8, NULL, 0) == 4); ASSERT(slre_match("a(b)(cd)", "abcdcdef", 8, caps, 1) == SLRE_CAPS_ARRAY_TOO_SMALL); ASSERT(slre_match("(.+/\\d+\\.\\d+)\\.jpg$", "/foo/bar/12.34.jpg", 18, caps, 1) == 18); ASSERT(slre_match("(ab|cd).*\\.(xx|yy)", "ab.yy", 5, NULL, 0) == 5); ASSERT(slre_match(".*a", "abcdef", 6, NULL, 0) == 1); ASSERT(slre_match("(.+)c", "abcdef", 6, NULL, 0) == 3); /* Greedy vs non-greedy */ ASSERT(slre_match(".+c", "abcabc", 6, NULL, 0) == 6); ASSERT(slre_match(".+?c", "abcabc", 6, NULL, 0) == 3); ASSERT(slre_match(".*?c", "abcabc", 6, NULL, 0) == 3); ASSERT(slre_match(".*c", "abcabc", 6, NULL, 0) == 6); ASSERT(slre_match("bc.d?k?b+", "abcabc", 6, NULL, 0) == 5); /* Branching */ ASSERT(slre_match("|", "abc", 3, NULL, 0) == 0); ASSERT(slre_match("|.", "abc", 3, NULL, 0) == 1); ASSERT(slre_match("x|y|b", "abc", 3, NULL, 0) == 2); ASSERT(slre_match("k(xx|yy)|ca", "abcabc", 6, NULL, 0) == 4); ASSERT(slre_match("k(xx|yy)|ca|bc", "abcabc", 6, NULL, 0) == 3); ASSERT(slre_match("(|.c)", "abc", 3, caps, 10) == 3); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "bc", 2) == 0); ASSERT(slre_match("a|b|c", "a", 1, NULL, 0) == 1); ASSERT(slre_match("a|b|c", "b", 1, NULL, 0) == 1); ASSERT(slre_match("a|b|c", "c", 1, NULL, 0) == 1); ASSERT(slre_match("a|b|c", "d", 1, NULL, 0) == SLRE_NO_MATCH); /* Optional match at the end of the string */ ASSERT(slre_match("^.*c.?$", "abc", 3, NULL, 0) == 3); ASSERT(slre_match("(?i)^.*C.?$", "abc", 3, NULL, 0) == 3); ASSERT(slre_match("bk?", "ab", 2, NULL, 0) == 2); ASSERT(slre_match("b(k?)", "ab", 2, NULL, 0) == 2); ASSERT(slre_match("b[k-z]*", "ab", 2, NULL, 0) == 2); ASSERT(slre_match("ab(k|z|y)*", "ab", 2, NULL, 0) == 2); ASSERT(slre_match("[b-z].*", "ab", 2, NULL, 0) == 2); ASSERT(slre_match("(b|z|u).*", "ab", 2, NULL, 0) == 2); ASSERT(slre_match("ab(k|z|y)?", "ab", 2, NULL, 0) == 2); ASSERT(slre_match(".*", "ab", 2, NULL, 0) == 2); ASSERT(slre_match(".*$", "ab", 2, NULL, 0) == 2); ASSERT(slre_match("a+$", "aa", 2, NULL, 0) == 2); ASSERT(slre_match("a*$", "aa", 2, NULL, 0) == 2); ASSERT(slre_match( "a+$" ,"Xaa", 3, NULL, 0) == 3); ASSERT(slre_match( "a*$" ,"Xaa", 3, NULL, 0) == 3); { /* Example: HTTP request */ const char *request = " GET /index.html HTTP/1.0\r\n\r\n"; struct slre_cap caps[4]; if (slre_match("^\\s*(\\S+)\\s+(\\S+)\\s+HTTP/(\\d)\\.(\\d)", request, strlen(request), caps, 4) > 0) { printf("Method: [%.*s], URI: [%.*s]\n", caps[0].len, caps[0].ptr, caps[1].len, caps[1].ptr); } else { printf("Error parsing [%s]\n", request); } ASSERT(caps[1].len == 11); ASSERT(memcmp(caps[1].ptr, "/index.html", caps[1].len) == 0); } { /* Example: string replacement */ char *s = slre_replace("({{.+?}})", "Good morning, {{foo}}. How are you, {{bar}}?", "Bob"); printf("%s\n", s); ASSERT(strcmp(s, "Good morning, Bob. How are you, Bob?") == 0); free(s); } { /* Example: find all URLs in a string */ static const char *str = "<img src=\"HTTPS://FOO.COM/x?b#c=tab1\"/> " " <a href=\"http://cesanta.com\">some link</a>"; static const char *regex = "(?i)((https?://)[^\\s/'\"<>]+/?[^\\s'\"<>]*)"; struct slre_cap caps[2]; int i, j = 0, str_len = strlen(str); while (j < str_len && (i = slre_match(regex, str + j, str_len - j, caps, 2)) > 0) { printf("Found URL: [%.*s]\n", caps[0].len, caps[0].ptr); j += i; } } printf("Unit test %s (total test: %d, failed tests: %d)\n", static_failed_tests > 0 ? "FAILED" : "PASSED", static_total_tests, static_failed_tests); return static_failed_tests == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }
bool static isSingleFragmentShader(char const* str) { return slre_match(&moduleData.fragmentSingleShaderDetectRegex, str, strlen(str), NULL); }
int main(void) { const char *msg = ""; struct slre_cap caps[10]; /* Character sets */ ASSERT(slre_match("[abc]", "1c2", 3, NULL, &msg) == 2); ASSERT(slre_match("[abc]", "1C2", 3, NULL, &msg) == 0); ASSERT(slre_match("(?i)[abc]", "1C2", 3, NULL, &msg) == 2); ASSERT(slre_match("[.2]", "1C2", 3, NULL, &msg) == 1); ASSERT(slre_match("[\\S]+", "ab cd", 5, NULL, &msg) == 2); ASSERT(slre_match("[\\S]+\\s+[tyc]*", "ab cd", 5, NULL, &msg) == 4); ASSERT(slre_match("[\\d]", "ab cd", 5, NULL, &msg) == 0); ASSERT(slre_match("[^\\d]", "ab cd", 5, NULL, &msg) == 1); ASSERT(slre_match("[^\\d]+", "abc123", 6, NULL, &msg) == 3); ASSERT(slre_match("[1-5]+", "123456789", 9, NULL, &msg) == 5); ASSERT(slre_match("[1-5a-c]+", "123abcdef", 9, NULL, &msg) == 6); ASSERT(slre_match("[1-5a-]+", "123abcdef", 9, NULL, &msg) == 4); ASSERT(slre_match("[1-5a-]+", "123a--2oo", 9, NULL, &msg) == 7); ASSERT(slre_match("[htps]+://", "https://", 8, NULL, &msg) == 8); /* Flags - case sensitivity */ ASSERT(slre_match("FO", "foo", 3, NULL, &msg) == 0); ASSERT(slre_match("(?i)FO", "foo", 3, NULL, &msg) == 2); ASSERT(slre_match("(?m)FO", "foo", 3, NULL, &msg) == 0); ASSERT(slre_match("(?m)x", "foo", 3, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_unexpected_quantifier) == 0); ASSERT(slre_match("fo", "foo", 3, NULL, &msg) == 2); ASSERT(slre_match(".+", "foo", 3, NULL, &msg) == 3); ASSERT(slre_match(".+k", "fooklmn", 7, NULL, &msg) == 4); ASSERT(slre_match(".+k.", "fooklmn", 7, NULL, &msg) == 5); ASSERT(slre_match("p+", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match("ok", "fooklmn", 7, NULL, &msg) == 4); ASSERT(slre_match("lmno", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match("mn.", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match("o", "fooklmn", 7, NULL, &msg) == 2); ASSERT(slre_match("^o", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match("^", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match("n$", "fooklmn", 7, NULL, &msg) == 7); ASSERT(slre_match("n$k", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match("l$", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match(".$", "fooklmn", 7, NULL, &msg) == 7); ASSERT(slre_match("a?", "fooklmn", 7, NULL, &msg) == 0); ASSERT(slre_match("\\_", "fooklmn", 7, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_invalid_metacharacter) == 0); ASSERT(slre_match("+", "fooklmn", 7, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_unexpected_quantifier) == 0); ASSERT(slre_match("()+", "fooklmn", 7, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_no_match) == 0); ASSERT(slre_match("\\x", "12", 2, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_invalid_metacharacter) == 0); ASSERT(slre_match("\\xhi", "12", 2, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_invalid_metacharacter) == 0); ASSERT(slre_match("\\x20", "_ J", 3, NULL, &msg) == 2); ASSERT(slre_match("\\x4A", "_ J", 3, NULL, &msg) == 3); ASSERT(slre_match("\\d+", "abc123def", 9, NULL, &msg) == 6); /* Balancing brackets */ ASSERT(slre_match("(x))", "fooklmn", 7, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_unbalanced_brackets) == 0); ASSERT(slre_match("(", "fooklmn", 7, NULL, &msg) == 0); ASSERT(strcmp(msg, static_error_unbalanced_brackets) == 0); ASSERT(slre_match("klz?mn", "fooklmn", 7, NULL, &msg) == 7); ASSERT(slre_match("fa?b", "fooklmn", 7, NULL, &msg) == 0); /* Brackets & capturing */ ASSERT(slre_match("^(te)", "tenacity subdues all", 20, caps, &msg) == 2); ASSERT(slre_match("(bc)", "abcdef", 6, caps, &msg) == 3); ASSERT(slre_match(".(d.)", "abcdef", 6, caps, &msg) == 5); ASSERT(slre_match(".(d.)\\)?", "abcdef", 6, caps, &msg) == 5); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "de", 2) == 0); ASSERT(slre_match("(.+)", "123", 3, caps, &msg) == 3); ASSERT(slre_match("(2.+)", "123", 3, caps, &msg) == 3); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "23", 2) == 0); ASSERT(slre_match("(.+2)", "123", 3, caps, &msg) == 2); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "12", 2) == 0); ASSERT(slre_match("(.*(2.))", "123", 3, caps, &msg) == 3); ASSERT(slre_match("(.)(.)", "123", 3, caps, &msg) == 2); ASSERT(slre_match("(\\d+)\\s+(\\S+)", "12 hi", 5, caps, &msg) == 5); ASSERT(slre_match("ab(cd)+ef", "abcdcdef", 8, NULL, &msg) == 8); ASSERT(slre_match("ab(cd)*ef", "abcdcdef", 8, NULL, &msg) == 8); ASSERT(slre_match("ab(cd)+?ef", "abcdcdef", 8, NULL, &msg) == 8); ASSERT(slre_match("ab(cd)+?.", "abcdcdef", 8, NULL, &msg) == 5); ASSERT(slre_match("ab(cd)?", "abcdcdef", 8, NULL, &msg) == 4); /* Greedy vs non-greedy */ ASSERT(slre_match(".+c", "abcabc", 6, NULL, &msg) == 6); ASSERT(slre_match(".+?c", "abcabc", 6, NULL, &msg) == 3); ASSERT(slre_match(".*?c", "abcabc", 6, NULL, &msg) == 3); ASSERT(slre_match(".*c", "abcabc", 6, NULL, &msg) == 6); ASSERT(slre_match("bc.d?k?b+", "abcabc", 6, NULL, &msg) == 5); /* Branching */ ASSERT(slre_match("|", "abc", 3, NULL, &msg) == 0); ASSERT(slre_match("|.", "abc", 3, NULL, &msg) == 1); ASSERT(slre_match("x|y|b", "abc", 3, NULL, &msg) == 2); ASSERT(slre_match("k(xx|yy)|ca", "abcabc", 6, NULL, &msg) == 4); ASSERT(slre_match("k(xx|yy)|ca|bc", "abcabc", 6, NULL, &msg) == 3); ASSERT(slre_match("(|.c)", "abc", 3, caps, &msg) == 3); ASSERT(caps[0].len == 2); ASSERT(memcmp(caps[0].ptr, "bc", 2) == 0); /* Example: HTTP request */ { const char *error_msg, *request = " GET /index.html HTTP/1.0\r\n\r\n"; struct slre_cap caps[4]; if (slre_match("^\\s*(\\S+)\\s+(\\S+)\\s+HTTP/(\\d)\\.(\\d)", request, strlen(request), caps, &error_msg)) { printf("Method: [%.*s], URI: [%.*s]\n", caps[0].len, caps[0].ptr, caps[1].len, caps[1].ptr); } else { printf("Error parsing [%s]: [%s]\n", request, error_msg); } ASSERT(caps[1].len == 11); ASSERT(memcmp(caps[1].ptr, "/index.html", caps[1].len) == 0); } { char *s = slre_replace("({{.+?}})", "Good morning, {{foo}}. How are you, {{bar}}?", "Bob"); printf("%s\n", s); ASSERT(strcmp(s, "Good morning, Bob. How are you, Bob?") == 0); free(s); } printf("Unit test %s (total test: %d, failed tests: %d)\n", static_failed_tests > 0 ? "FAILED" : "PASSED", static_total_tests, static_failed_tests); return static_failed_tests == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }