Added silc_regex and silc_regex_buffer. Deprecated
authorPekka Riikonen <priikone@silcnet.org>
Tue, 1 Jan 2008 16:09:31 +0000 (16:09 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 1 Jan 2008 16:09:31 +0000 (16:09 +0000)
silc_string_regex_match..

lib/silcutil/silcregex.c
lib/silcutil/silcregex.h
lib/silcutil/silcstrutil.c
lib/silcutil/silcstrutil.h

index c11ea8ad726040278e3976e34efaa12e0a3655c2..e422ded5b51aa8b07eccf2bc3b26f0e2d80a9151 100644 (file)
@@ -1601,11 +1601,11 @@ SilcBool silc_regex_compile(SilcRegex regexp, const char *regex,
 /* Match compiled regular expression */
 
 SilcBool silc_regex_match(SilcRegex regexp, const char *string,
-                         SilcUInt32 num_match, SilcRegexMatch match,
-                         SilcRegexFlags flags)
+                         SilcUInt32 string_len, SilcUInt32 num_match,
+                         SilcRegexMatch match, SilcRegexFlags flags)
 {
   struct re_registers regs;
-  int ret, i, len = strlen(string);
+  int ret, i;
 
   if (!regexp || !string) {
     silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
@@ -1622,7 +1622,7 @@ SilcBool silc_regex_match(SilcRegex regexp, const char *string,
     num_match = RE_NREGS;
 
   /* Search */
-  ret = re_search(regexp, (char *)string, len, 0, len,
+  ret = re_search(regexp, (char *)string, string_len, 0, string_len,
                  num_match ? &regs : NULL);
   if (ret < 0) {
     if (ret == -2)
@@ -1648,3 +1648,108 @@ void silc_regex_free(SilcRegex regexp)
 {
   silc_free(regexp->buffer);
 }
+
+/* Match string */
+
+SilcBool silc_regex_va(const char *string, SilcUInt32 string_len,
+                      const char *regex, SilcBuffer match, va_list va)
+{
+  SilcRegexStruct reg;
+  SilcRegexMatch m = NULL;
+  SilcBuffer buf, *rets = NULL;
+  int i, c = 0;
+
+  /* Compile */
+  if (!silc_regex_compile(&reg, regex, 0))
+    return FALSE;
+
+  /* Get match pointers */
+  if (match) {
+    rets = silc_malloc(sizeof(*rets));
+    if (!rets)
+      return FALSE;
+    rets[c++] = match;
+
+    while ((buf = va_arg(va, SilcBuffer))) {
+      rets = silc_realloc(rets, (c + 1) * sizeof(*rets));
+      if (!rets)
+       return FALSE;
+      rets[c++] = buf;
+    }
+
+    m = silc_malloc(c * sizeof(*m));
+    if (!m) {
+      silc_free(rets);
+      return FALSE;
+    }
+  }
+
+  /* Match */
+  if (!silc_regex_match(&reg, string, string_len, c, m, 0)) {
+    silc_free(m);
+    silc_free(rets);
+    return FALSE;
+  }
+
+  /* Return matches */
+  for (i = 0; i < c; i++) {
+    if (m[i].start == -1)
+      continue;
+    silc_buffer_set(rets[i], (unsigned char *)string + m[i].start,
+                   m[i].end - m[i].start);
+  }
+
+  silc_free(m);
+  silc_free(rets);
+
+  return TRUE;
+}
+
+/* Match string */
+
+SilcBool silc_regex(const char *string, const char *regex,
+                   SilcBuffer match, ...)
+{
+  SilcBool ret;
+  va_list va;
+
+  if (!string || !regex) {
+    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+    return FALSE;
+  }
+
+  if (match)
+    va_start(va, match);
+
+  ret = silc_regex_va(string, strlen(string), regex, match, va);
+
+  if (match)
+    va_end(va);
+
+  return ret;
+}
+
+/* Match string */
+
+SilcBool silc_regex_buffer(SilcBuffer buffer, const char *regex,
+                          SilcBuffer match, ...)
+{
+  SilcBool ret;
+  va_list va;
+
+  if (!buffer || !regex) {
+    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
+    return FALSE;
+  }
+
+  if (match)
+    va_start(va, match);
+
+  ret = silc_regex_va((const char *)silc_buffer_data(buffer),
+                     silc_buffer_len(buffer), regex, match, va);
+
+  if (match)
+    va_end(va);
+
+  return ret;
+}
index 217144ab86108f32731c205ddc68254d208c437d..1527a2c57d7cf8127ab71ca13660de28b47c7855 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
 
   regexpr.h
  * DESCRIPTION
  *
  * SILC regular expression interface provides Unix and POSIX compliant
- * regular expression compilation and matching.
+ * regular expression compilation and matching.  The syntax is compliant
+ * with Unix and POSIX regular expression syntax.
+ *
+ * The interface also provides many convenience functions to make the use
+ * of regular expressions easier.
  *
  * EXAMPLE
  *
@@ -59,7 +62,9 @@
  *
  * DESCRIPTION
  *
- *    The regular expression context.
+ *    The regular expression context.  This context is given as argument
+ *    to all silc_regex_* functions.  It is usually statically allocated
+ *    but can be dynamically allocated by silc_malloc.
  *
  ***/
 typedef struct SilcRegexObject {
@@ -82,6 +87,9 @@ typedef struct SilcRegexObject {
  *
  * DESCRIPTION
  *
+ *    The regular expression match context that provides information on the
+ *    found match.  It provides the start offset and end offset of the
+ *    found match.
  *
  * SOURCE
  */
@@ -134,8 +142,8 @@ SilcBool silc_regex_compile(SilcRegex regexp, const char *regex,
  * SYNOPSIS
  *
  *    SilcBool silc_regex_match(SilcRegex regexp, const char *string,
- *                              SilcUInt32 num_match, SilcRegexMatch match,
- *                              SilcRegexFlags flags);
+ *                              SilcUInt32 string_len, SilcUInt32 num_match,
+ *                              SilcRegexMatch match, SilcRegexFlags flags);
  *
  * DESCRIPTION
  *
@@ -160,13 +168,13 @@ SilcBool silc_regex_compile(SilcRegex regexp, const char *regex,
  * EXAMPLE
  *
  *    // Find first match (check if string matches)
- *    if (!silc_regex_match(&reg, "foo20", 0, NULL, 0))
+ *    if (!silc_regex_match(&reg, "foo20", 5, 0, NULL, 0))
  *      no_match;
  *
  *    // Find multiple matches, one by one
  *    SilcRegexMatchStruct match;
  *
- *    while (silc_regex_match(&reg, string, 1, &match, 0)) {
+ *    while (silc_regex_match(&reg, string, len, 1, &match, 0)) {
  *      match_string = silc_memdup(string + match.start,
  *                                 match.end - match.start);
  *      string += match.end;
@@ -177,12 +185,12 @@ SilcBool silc_regex_compile(SilcRegex regexp, const char *regex,
  *    SilcRegexMatchStruct match[7];
  *
  *    silc_regex_compile(&reg, "^(([^:]+)://)?([^:/]+)(:([0-9]+))?(/.*)", 0);
- *    silc_regex_match(&reg, "http://example.com/page.html", 7, match, 0);
+ *    silc_regex_match(&reg, "http://example.com/page.html", len, 7, match, 0);
  *
  ***/
 SilcBool silc_regex_match(SilcRegex regexp, const char *string,
-                         SilcUInt32 num_match, SilcRegexMatch match,
-                         SilcRegexFlags flags);
+                         SilcUInt32 string_len, SilcUInt32 num_match,
+                         SilcRegexMatch match, SilcRegexFlags flags);
 
 /****f* silcutil/SilcRegexAPI/silc_regex_free
  *
@@ -199,4 +207,66 @@ SilcBool silc_regex_match(SilcRegex regexp, const char *string,
  ***/
 void silc_regex_free(SilcRegex regexp);
 
+/****f* silcutil/SilcRegexAPI/silc_regex
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_regex(const char *string, const char *regex,
+ *                        SilcBuffer match, ...);
+ *
+ * DESCRIPTION
+ *
+ *    Matches the `string' to the regular expression `regex'.  Returns TRUE
+ *    if the `string' matches the regular expression or FALSE if it does not
+ *    match.  The silc_errno is also set to SILC_ERR_NOT_FOUND.
+ *
+ *    The first (whole) match is returned to `match' buffer if it is non-NULL.
+ *    The variable argument list are buffers where multiple matches are
+ *    returned in case of group (parenthesized) regular expression.  The caller
+ *    needs to know how many pointers to provide, in order to get all matches.
+ *    If `match' is non-NULL the variable argument list must be ended with
+ *    NULL.  The data in the `match' and in any other buffer is from `string'
+ *    and must not be freed by the caller.
+ *
+ * EXAMPLE
+ *
+ *    // Simple match
+ *    if (!silc_regex("foobar", "foo.", NULL))
+ *      no_match;
+ *
+ *    // Get the pointer to the first match
+ *    if (!silc_regex("foobar", ".bar", &match, NULL))
+ *      no_match;
+ *
+ *    // Group match
+ *    SilcBufferStruct match, sub1, sub2;
+ *
+ *    if (!silc_regex("Hello World", "(H..).(o..)", &match, &sub1, &sub2, NULL))
+ *      no_match;
+ *
+ ***/
+SilcBool silc_regex(const char *string, const char *regex,
+                   SilcBuffer match, ...);
+
+/****f* silcutil/SilcRegexAPI/silc_regex_buffer
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool silc_regex_buffer(SilcBuffer buffer, const char *regex,
+ *                               SilcBuffer match, ...);
+ *
+ * DESCRIPTION
+ *
+ *    Same as silc_regex but the string to match is in `buffer'.  Returns
+ *    TRUE if the string matches and FALSE if it doesn't.  See examples and
+ *    other information in silc_regex.  The `buffer' and `match' may be the
+ *    same buffer.
+ *
+ ***/
+SilcBool silc_regex_buffer(SilcBuffer buffer, const char *regex,
+                          SilcBuffer match, ...);
+
+/* Backwards support */
+#define silc_string_regex_match(regex, string) silc_regex(string, regex, NULL)
+
 #endif /* SILCREGEX_H */
index 914adc98f58659a7cc739afed2a19dbec508827e..3251c2b0a4d47c43255ca71746e17cf899ffedb4 100644 (file)
@@ -249,23 +249,6 @@ char *silc_string_regex_combine(const char *string1, const char *string2)
   return tmp;
 }
 
-/* Matches the two strings and returns TRUE if the strings match. */
-
-int silc_string_regex_match(const char *regex, const char *string)
-{
-  SilcRegexStruct preg;
-  SilcBool ret;
-
-  if (!silc_regex_compile(&preg, regex, 0))
-    return FALSE;
-
-  ret = silc_regex_match(&preg, string, 0, NULL, 0);
-
-  silc_regex_free(&preg);
-
-  return ret;
-}
-
 /* Do regex match to the two strings `string1' and `string2'. If the
    `string2' matches the `string1' this returns TRUE. */
 
index 1236e4fad2d387a40648b95face593ce7dd9de8c..bc692975259bc59632b126fa4b7556d720482ea8 100644 (file)
@@ -99,19 +99,6 @@ char *silc_strncat(char *dest, SilcUInt32 dest_size,
  ***/
 char *silc_string_regexify(const char *string);
 
-/****f* silcutil/SilcStrUtilAPI/silc_string_regex_match
- *
- * SYNOPSIS
- *
- *    int silc_string_regex_match(const char *regex, const char *string);
- *
- * DESCRIPTION
- *
- *    Matches the two strings and returns TRUE if the strings match.
- *
- ***/
-int silc_string_regex_match(const char *regex, const char *string);
-
 /****f* silcutil/SilcStrUtilAPI/silc_string_match
  *
  * SYNOPSIS