From: Pekka Riikonen Date: Sun, 13 Jan 2008 15:24:26 +0000 (+0000) Subject: Added silc_subst, regex matching and substitution with the X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=10c399ae1a586f5c82b96da137bd88f8e015b659 Added silc_subst, regex matching and substitution with the familiar Sed syntax. --- diff --git a/lib/silcutil/silcerrno.c b/lib/silcutil/silcerrno.c index ff809c5f..5f415e94 100644 --- a/lib/silcutil/silcerrno.c +++ b/lib/silcutil/silcerrno.c @@ -350,7 +350,7 @@ const char *silc_errno_strings[] = "Interrupted", "Not valid", "Limit reached", - "", + "Syntax error", "", "", "", diff --git a/lib/silcutil/silcerrno.h b/lib/silcutil/silcerrno.h index f8e8f15f..ebf32928 100644 --- a/lib/silcutil/silcerrno.h +++ b/lib/silcutil/silcerrno.h @@ -94,6 +94,7 @@ typedef enum { SILC_ERR_INTERRUPTED = 23, /* Interrupted */ SILC_ERR_NOT_VALID = 24, /* Not valid */ SILC_ERR_LIMIT = 25, /* Limit reached */ + SILC_ERR_SYNTAX = 26, /* Syntax error */ /* File, directory and device errors */ SILC_ERR_NO_SUCH_FILE = 40, /* No such file */ diff --git a/lib/silcutil/silcregex.c b/lib/silcutil/silcregex.c index f08c1b61..dba552b7 100644 --- a/lib/silcutil/silcregex.c +++ b/lib/silcutil/silcregex.c @@ -1193,7 +1193,7 @@ SilcResult silc_re_compile_pattern(unsigned char *regex, int size, int op; int current_level; int level; - int opcode; + int opcode = 0; int pattern_offset = 0, alloc; int starts[NUM_LEVELS * MAX_NESTING]; int starts_base; @@ -2444,8 +2444,10 @@ SilcBool silc_regex_va(const char *string, SilcUInt32 string_len, /* Return matches */ for (i = 0; i < c; i++) { - if (m[i].start == -1) + if (m[i].start == -1) { + silc_buffer_set(rets[i], NULL, 0); continue; + } silc_buffer_set(rets[i], (unsigned char *)string + m[i].start, m[i].end - m[i].start); } @@ -2506,3 +2508,224 @@ SilcBool silc_regex_buffer(SilcBuffer buffer, const char *regex, return ret; } + +/***************************** Substitution API *****************************/ + +/* Regexp to parse sed substitution command syntax */ +#define SILC_REGEXP_SUBST \ + "^(/?.+/?[^!s]|[0-9]+|\\$)?(!?s)(/)(.*[^\\])?(/)(.*[^\\])?(/)(!?.+)?" + +/* Substitution context */ +typedef struct { + SilcInt32 addr_number; /* Line number to match, -1 for last line */ + SilcUInt32 line; /* Current line number */ + char *str_regexp; /* REGEXP to match */ + SilcBufferRegexFlags match_flags; /* Match flags */ + SilcBufferRegexFlags addr_flags; /* ADDR flags */ + SilcBuffer rep; /* REPLACEMENT */ +} SilcSubstContext; + +/* Function to check the ADDR match and do rest of the match and + substitution. */ + +static int silc_subst_addr(SilcStack stack, SilcBuffer buffer, void *value, + void *context) +{ + SilcSubstContext *ctx = context; + + ctx->line++; + + /* If NUMBER was set in ADDR, match for specific line number */ + if (ctx->addr_number > 0 && ctx->addr_number != ctx->line && + !(ctx->addr_flags & SILC_STR_REGEX_NOT)) + return 0; + if (ctx->addr_number > 0 && ctx->addr_number == ctx->line && + ctx->addr_flags & SILC_STR_REGEX_NOT) + return 0; + + /* Check for last line if ADDR was '$' */ + if (buffer->tail != buffer->end && ctx->addr_number == -1 && + !(ctx->addr_flags & SILC_STR_REGEX_NOT)) + return 0; + if (buffer->tail == buffer->end && ctx->addr_number == -1 && + ctx->addr_flags & SILC_STR_REGEX_NOT) + return 0; + + /* Match and replace */ + return silc_buffer_format(buffer, + SILC_STR_REGEX(ctx->str_regexp, ctx->match_flags), + SILC_STR_REPLACE(silc_buffer_data(ctx->rep) ? + silc_buffer_data(ctx->rep) : + (unsigned char *)"", + silc_buffer_len(ctx->rep)), + SILC_STR_END, SILC_STR_END); +} + +/* Matching and substitution ala sed. */ + +SilcBool silc_subst(SilcBuffer buffer, const char *subst) +{ + SilcSubstContext ctx; + SilcBufferStruct match, addr, command, exp_start, exp, exp_end; + SilcBufferStruct rep, rep_end, flags; + SilcBufferRegexFlags addr_flags = 0, match_flags = 0; + char *str_addr = ""; + int ret = -1; + + memset(&ctx, 0, sizeof(ctx)); + + if (!buffer || !subst) { + silc_set_errno(SILC_ERR_INVALID_ARGUMENT); + goto out; + } + + SILC_LOG_DEBUG(("Substitution '%s'", subst)); + + /* Parse the expression syntax */ + if (!silc_regex(subst, SILC_REGEXP_SUBST, &match, &addr, &command, + &exp_start, &exp, &exp_end, &rep, &rep_end, &flags, NULL)) { + silc_set_errno_reason(SILC_ERR_SYNTAX, "Invalid substitution expression"); + goto out; + } + + /* Check address syntax */ + if (silc_buffer_len(&addr)) { + if (*silc_buffer_data(&addr) == '/') { + silc_buffer_pull(&addr, 1); + if (addr.tail[-1] != '/') { + silc_set_errno_reason(SILC_ERR_SYNTAX, + "Invalid address syntax, missing '/'"); + goto out; + } + silc_buffer_push_tail(&addr, 1); + + if (!silc_buffer_len(&addr)) { + silc_set_errno_reason(SILC_ERR_SYNTAX, + "Invalid address syntax, missing regular " + "expression"); + goto out; + } + str_addr = silc_memdup(silc_buffer_data(&addr), + silc_buffer_len(&addr)); + + } else if (*silc_buffer_data(&addr) == '$' && + silc_buffer_len(&addr) == 1) { + ctx.addr_number = -1; + + } else if (isdigit((int)*silc_buffer_data(&addr))) { + ctx.addr_number = *silc_buffer_data(&addr) - '0'; + silc_buffer_pull(&addr, 1); + while (silc_buffer_len(&addr) && + isdigit((int)*silc_buffer_data(&addr))) { + ctx.addr_number *= 10; + ctx.addr_number += *silc_buffer_data(&addr) - '0'; + silc_buffer_pull(&addr, 1); + } + + if (silc_buffer_len(&addr)) { + silc_set_errno_reason(SILC_ERR_SYNTAX, + "Invalid address syntax, not a number"); + goto out; + } + + if (ctx.addr_number == 0) { + silc_set_errno_reason(SILC_ERR_SYNTAX, + "Invalid address syntax, line address is 0"); + goto out; + } + + } else { + silc_set_errno_reason(SILC_ERR_SYNTAX, "Unsupported address syntax"); + goto out; + } + } + + /* Check command syntax */ + if (!silc_buffer_len(&command) || silc_buffer_len(&command) > 2) { + silc_set_errno_reason(SILC_ERR_SYNTAX, "Invalid commmand"); + goto out; + } + if ((silc_buffer_len(&command) == 1 && + !silc_buffer_memcmp(&command, "s", 1)) || + (silc_buffer_len(&command) == 2 && + !silc_buffer_memcmp(&command, "!s", 2))) { + silc_set_errno_reason(SILC_ERR_SYNTAX, "Invalid command"); + goto out; + } + if (silc_buffer_len(&command) == 2) + addr_flags |= SILC_STR_REGEX_NOT; + + /* Check REGEXP syntax */ + if (!silc_buffer_len(&exp_start) || + !silc_buffer_memcmp(&exp_start, "/", 1)) { + silc_set_errno_reason(SILC_ERR_SYNTAX, + "Invalid substitution syntax, missing '/'"); + goto out; + } + if (!silc_buffer_len(&exp_end) || + !silc_buffer_memcmp(&exp_end, "/", 1)) { + silc_set_errno_reason(SILC_ERR_SYNTAX, + "Invalid substitution syntax, missing '/'"); + goto out; + } + + /* Check FLAGS syntax */ + if (silc_buffer_len(&flags)) { + if (silc_buffer_len(&flags) > 1) { + silc_set_errno_reason(SILC_ERR_SYNTAX, "Invalid flags"); + goto out; + } + + /* Check supported flags */ + if (silc_buffer_len(&flags) == 1) { + if (silc_buffer_memcmp(&flags, "g", 1)) { + match_flags |= SILC_STR_REGEX_ALL; + } else { + silc_set_errno_reason(SILC_ERR_SYNTAX, "Unsupported flag"); + goto out; + } + } + } + + /* Set flags */ + match_flags |= SILC_STR_REGEX_INCLUSIVE; + addr_flags |= SILC_STR_REGEX_NL | SILC_STR_REGEX_NO_ADVANCE; + + ctx.str_regexp = silc_memdup(silc_buffer_data(&exp), + silc_buffer_len(&exp)); + ctx.addr_flags = addr_flags; + ctx.match_flags = match_flags; + + /* Unescape escapes from REPLACEMENT */ + ctx.rep = silc_buffer_copy(&rep); + if (!ctx.rep) + goto out; + if (silc_buffer_len(ctx.rep)) + silc_buffer_format(ctx.rep, + SILC_STR_REGEX("\\\\/", (SILC_STR_REGEX_ALL | + SILC_STR_REGEX_INCLUSIVE)), + SILC_STR_REPLACE("/", 1), + SILC_STR_END, SILC_STR_END); + + /* If NUMBER or $ is specified, handle NOT flag in the silc_subst_addr */ + if (ctx.addr_number) + addr_flags &= ~SILC_STR_REGEX_NOT; + + SILC_LOG_DEBUG(("ADDR '%s' flags 0x%x, NUMBER %d", str_addr, addr_flags, + ctx.addr_number)); + SILC_LOG_DEBUG(("REGEXP '%s' flags 0x%x", ctx.str_regexp, match_flags)); + + /* Match and replace */ + ret = silc_buffer_format(buffer, + SILC_STR_REGEX(str_addr, addr_flags), + SILC_STR_FUNC(silc_subst_addr, NULL, &ctx), + SILC_STR_END, SILC_STR_END); + + out: + if (str_addr && strlen(str_addr)) + silc_free(str_addr); + silc_free(ctx.str_regexp); + silc_buffer_free(ctx.rep); + + return ret >= 0 ? TRUE : FALSE; +} diff --git a/lib/silcutil/silcregex.h b/lib/silcutil/silcregex.h index 8b5a6654..4047088f 100644 --- a/lib/silcutil/silcregex.h +++ b/lib/silcutil/silcregex.h @@ -370,11 +370,6 @@ SilcBool silc_regex_buffer(SilcBuffer buffer, const char *regex, * using the SILC_STR_REGEX in SILC Buffer Format API directly. This * function only provides basic matching and substitution. * - * EXAMPLE - * - * // Replace all foos with bar on all lines in the buffer - * silc_subst(buffer, "s/foo/bar/g"); - * ***/ SilcBool silc_subst(SilcBuffer buffer, const char *subst); diff --git a/lib/silcutil/tests/test_silcbuffmt.c b/lib/silcutil/tests/test_silcbuffmt.c index 052be536..44bac0ac 100644 --- a/lib/silcutil/tests/test_silcbuffmt.c +++ b/lib/silcutil/tests/test_silcbuffmt.c @@ -46,7 +46,7 @@ int main(int argc, char **argv) if (silc_buffer_format(&buf, SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL | SILC_STR_REGEX_INCLUSIVE), - SILC_STR_STRING_APPEND("barbar"), + SILC_STR_REPLACE("barbar", 6), SILC_STR_END, SILC_STR_END) < 0) goto err; @@ -63,7 +63,7 @@ int main(int argc, char **argv) if (silc_buffer_format(&buf, SILC_STR_REGEX("foo", SILC_STR_REGEX_ALL | SILC_STR_REGEX_INCLUSIVE), - SILC_STR_DELETE(-1), + SILC_STR_REPLACE("", 0), SILC_STR_END, SILC_STR_END) < 0) goto err; diff --git a/lib/silcutil/tests/test_silcregex.c b/lib/silcutil/tests/test_silcregex.c index 41c51ad3..c1c6b44b 100644 --- a/lib/silcutil/tests/test_silcregex.c +++ b/lib/silcutil/tests/test_silcregex.c @@ -6,8 +6,8 @@ int main(int argc, char **argv) { SilcBool success = FALSE; SilcRegexStruct reg; - SilcRegexMatchStruct match[10]; - int i, num_match = 10; + SilcRegexMatchStruct match[20]; + int i, num_match = 20; char *regex, *string, *sub; SilcBufferStruct bmatch; @@ -15,9 +15,261 @@ int main(int argc, char **argv) silc_log_debug(TRUE); silc_log_quick(TRUE); silc_log_debug_hexdump(TRUE); - silc_log_set_debug_string("*regex*,*errno*"); + silc_log_set_debug_string("*regex*,*errno*,*buffmt*"); } + string = silc_strdup("foobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo/bar/")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "barbar", 6)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar foobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo/bar/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "barbar barbar", 13)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar foobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo/bar/")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "barbar foobar", 13)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar foobar\nfoobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "BARBARbar\nBARBARbar BARBARbar\nBARBARbar", + 39)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar foobar\nfoobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo/BARBAR/")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "BARBARbar\nBARBARbar foobar\nBARBARbar", + 36)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar foobar\nfoobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo//")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "bar\nbar foobar\nbar", + 18)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar foobar\nfoobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo/B/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "Bbar\nBbar Bbar\nBbar", + 19)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar foobar\nfoobar"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/foo/B/")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "Bbar\nBbar foobar\nBbar", + 21)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nBfoobar foobar\nBfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "/^B/s/foo/B/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, "foobar\nBBbar Bbar\nBBbar\nfoo", + 27)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "/baz/s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nBARBARbar baz BARBARbar\nbazBARBARbar\nfoo", + 47)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "/baz/s/foo/BARBAR/")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nBARBARbar baz foobar\nbazBARBARbar\nfoo", + 44)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "/baz/!s/foo/BARBAR/")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "BARBARbar\nfoobar baz foobar\nbazfoobar\nBARBAR", + 44)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "2s/foo/BARBAR/")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nBARBARbar baz foobar\nbazfoobar\nfoo", + 41)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "2s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nBARBARbar baz BARBARbar\nbazfoobar\nfoo", + 44)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "200s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nfoobar baz foobar\nbazfoobar\nfoo", + 38)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "2!s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "BARBARbar\nfoobar baz foobar\nbazBARBARbar\nBARBAR", + 47)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "/xxx/s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nfoobar baz foobar\nbazfoobar\nfoo", + 38)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "!s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nfoobar baz foobar\nbazfoobar\nfoo", + 38)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "$s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nfoobar baz foobar\nbazfoobar\nBARBAR", + 41)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar baz foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "$!s/foo/BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "BARBARbar\nBARBARbar baz BARBARbar\nbazBARBARbar\nfoo", + 50)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar /baz/ foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/\\//BARBAR/g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nfoobar BARBARbazBARBAR foobar\nbazfoobar\nfoo", + 50)) + goto err; + silc_buffer_purge(&bmatch); + + string = silc_strdup("foobar\nfoobar /baz/ foobar\nbazfoobar\nfoo"); + SILC_LOG_DEBUG(("Replace %s", string)); + silc_buffer_set(&bmatch, string, strlen(string)); + if (!silc_subst(&bmatch, "s/\\//\\/\\//g")) + goto err; + silc_buffer_printf(&bmatch, TRUE); + if (!silc_buffer_memcmp(&bmatch, + "foobar\nfoobar //baz// foobar\nbazfoobar\nfoo", + 42)) + goto err; + silc_buffer_purge(&bmatch); + regex = ".{5}"; SILC_LOG_DEBUG(("Regex %s", regex)); string = "abcdefghijklmn"; @@ -199,7 +451,6 @@ int main(int argc, char **argv) if (silc_regex(string, regex, &bmatch, NULL)) goto err; - regex = "(H..).(o..)"; SILC_LOG_DEBUG(("Regex %s", regex)); if (!silc_regex_compile(®, regex, 0)) @@ -213,7 +464,7 @@ int main(int argc, char **argv) if (match[i].start != -1) { SILC_LOG_DEBUG(("Match start %d, end %d", match[i].start, match[i].end)); - sub = silc_memdup(string + match[i].start, match[i].end - + sub = silc_memdup(string + match[i].start, match[i].end - match[i].start); SILC_LOG_DEBUG(("Match substring '%s'", sub)); silc_free(sub); @@ -255,7 +506,7 @@ int main(int argc, char **argv) for (i = 0; i < num_match; i++) { if (match[i].start != -1) { SILC_LOG_DEBUG(("Match start %d", match[i].start)); - sub = silc_memdup(string + match[i].start, match[i].end - + sub = silc_memdup(string + match[i].start, match[i].end - match[i].start); SILC_LOG_DEBUG(("Match substring '%s'", sub)); silc_free(sub); @@ -277,7 +528,7 @@ int main(int argc, char **argv) for (i = 0; i < num_match; i++) { if (match[i].start != -1) { SILC_LOG_DEBUG(("Match start %d", match[i].start)); - sub = silc_memdup(string + match[i].start, match[i].end - + sub = silc_memdup(string + match[i].start, match[i].end - match[i].start); SILC_LOG_DEBUG(("Match substring '%s'", sub)); silc_free(sub); @@ -292,7 +543,7 @@ int main(int argc, char **argv) for (i = 0; i < num_match; i++) { if (match[i].start != -1) { SILC_LOG_DEBUG(("Match start %d", match[i].start)); - sub = silc_memdup(string + match[i].start, match[i].end - + sub = silc_memdup(string + match[i].start, match[i].end - match[i].start); SILC_LOG_DEBUG(("Match substring '%s'", sub)); silc_free(sub); @@ -314,7 +565,7 @@ int main(int argc, char **argv) for (i = 0; i < num_match; i++) { if (match[i].start != -1) { SILC_LOG_DEBUG(("Match start %d", match[i].start)); - sub = silc_memdup(string + match[i].start, match[i].end - + sub = silc_memdup(string + match[i].start, match[i].end - match[i].start); SILC_LOG_DEBUG(("Match substring '%s'", sub)); silc_free(sub); @@ -363,4 +614,3 @@ int main(int argc, char **argv) return success; } -