uncrustify as demanded.
[oweals/gnunet.git] / src / regex / regex_test_lib.c
index bc4f78ba8c16c4fde4c1c462bb9a87551673087e..d8eb22370f5617768754e745c5344b2b573e1fd4 100644 (file)
@@ -1,21 +1,21 @@
 /*
  *  This file is part of GNUnet
- *  Copyright (C) 2012 Christian Grothoff (and other contributing authors)
+ *  Copyright (C) 2012-2017 GNUnet e.V.
  *
- *  GNUnet is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published
- *  by the Free Software Foundation; either version 3, or (at your
- *  option) any later version.
+ *  GNUnet is free software: you can redistribute it and/or modify it
+ *  under the terms of the GNU Affero General Public License as published
+ *  by the Free Software Foundation, either version 3 of the License,
+ *  or (at your option) any later version.
  *
  *  GNUnet is distributed in the hope that it will be useful, but
  *  WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
+ *  Affero General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with GNUnet; see the file COPYING.  If not, write to the
- *  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- *  Boston, MA 02111-1307, USA.
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
  */
 /**
  * @file src/regex/regex_test_lib.c
  * Struct to hold the tree formed by prefix-combining the regexes.
  */
 struct RegexCombineCtx {
-
-  /**
-   * Next node with same prefix but different token.
-   */
-  struct RegexCombineCtx *next;
-
   /**
-   * Prev node with same prefix but different token.
+   * Child nodes with same prefix and token.
    */
-  struct RegexCombineCtx *prev;
+  struct RegexCombineCtx **children;
 
   /**
-   * First child node with same prefix and token.
+   * Alphabet size (how many @a children there are)
    */
-  struct RegexCombineCtx *head;
-
-  /**
-   * Last child node.
-   */
-  struct RegexCombineCtx *tail;
+  unsigned int size;
 
   /**
    * Token.
@@ -60,30 +49,139 @@ struct RegexCombineCtx {
   char *s;
 };
 
-/*
+
+/**
+ * Char 2 int
+ *
+ * Convert a character into its int value depending on the base used
+ *
+ * @param c Char
+ * @param size base (2, 8 or 16(hex))
+ *
+ * @return Int in range [0, (base-1)]
+ */
+static int
+c2i(char c, int size)
+{
+  switch (size)
+    {
+    case 2:
+    case 8:
+      return c - '0';
+      break;
+
+    case 16:
+      if (c >= '0' && c <= '9')
+        return c - '0';
+      else if (c >= 'A' && c <= 'F')
+        return c - 'A' + 10;
+      else if (c >= 'a' && c <= 'f')
+        return c - 'a' + 10;
+      else
+        {
+          GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
+                     "Cannot convert char %c in base %u\n",
+                     c, size);
+          GNUNET_assert(0);
+        }
+      break;
+
+    default:
+      GNUNET_assert(0);
+    }
+}
+
+
+/**
+ * Printf spaces to indent the regex tree
+ *
+ * @param n Indentation level
+ */
 static void
-space (int n)
+space(int n)
 {
-  int i;
-  for (i = 0; i < n; i++)
-    printf ("  ");
+  for (int i = 0; i < n; i++)
+    fprintf(stderr, "| ");
 }
 
+
+/**
+ * Printf the combined regex ctx.
+ *
+ * @param ctx The ctx to printf
+ * @param level Indentation level to start with
+ */
 static void
-debugctx (struct RegexCombineCtx *ctx, int level)
+debugctx(struct RegexCombineCtx *ctx, int level)
 {
-  struct RegexCombineCtx *p;
-  space (level);
+#if DEBUG_REGEX
   if (NULL != ctx->s)
-    printf ("'%s'\n", ctx->s);
+    {
+      space(level - 1);
+      fprintf(stderr, "%u:'%s'\n", c2i(ctx->s[0], ctx->size), ctx->s);
+    }
   else
-    printf ("NULL\n");
-  for (p = ctx->head; NULL != p; p = p->next)
-  {
-    debugctx (p, level + 1);
-  }
+    fprintf(stderr, "ROOT (base %u)\n", ctx->size);
+  for (unsigned int i = 0; i < ctx->size; i++)
+    {
+      if (NULL != ctx->children[i])
+        {
+          space(level);
+          debugctx(ctx->children[i], level + 1);
+        }
+    }
+  fflush(stderr);
+#endif
+}
+
+
+/**
+ * Add a single regex to a context, combining with exisiting regex by-prefix.
+ *
+ * @param ctx Context with 0 or more regexes.
+ * @param regex Regex to add.
+ */
+static void
+regex_add(struct RegexCombineCtx *ctx,
+          const char *regex);
+
+
+/**
+ * Create and initialize a new RegexCombineCtx.
+ *
+ * @param alphabet_size Size of the alphabet (and the Trie array)
+ */
+static struct RegexCombineCtx *
+new_regex_ctx(unsigned int alphabet_size)
+{
+  struct RegexCombineCtx *ctx;
+  size_t array_size;
+
+  array_size = sizeof(struct RegexCombineCtx *) * alphabet_size;
+  ctx = GNUNET_new(struct RegexCombineCtx);
+  ctx->children = GNUNET_malloc(array_size);
+  ctx->size = alphabet_size;
+
+  return ctx;
 }
-*/
+
+
+static void
+move_children(struct RegexCombineCtx *dst,
+              const struct RegexCombineCtx *src)
+{
+  size_t array_size;
+
+  array_size = sizeof(struct RegexCombineCtx *) * src->size;
+  GNUNET_memcpy(dst->children,
+                src->children,
+                array_size);
+  for (unsigned int i = 0; i < src->size; i++)
+    {
+      src->children[i] = NULL;
+    }
+}
+
 
 /**
  * Extract a string from all prefix-combined regexes.
@@ -93,60 +191,66 @@ debugctx (struct RegexCombineCtx *ctx, int level)
  * @return Regex that matches any of the added regexes.
  */
 static char *
-regex_combine (struct RegexCombineCtx *ctx)
+regex_combine(struct RegexCombineCtx *ctx)
 {
   struct RegexCombineCtx *p;
+  unsigned int i;
   size_t len;
   char *regex;
   char *tmp;
   char *s;
   int opt;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new combine %s\n", ctx->s);
-  regex = GNUNET_strdup ("");
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "new combine %s\n", ctx->s);
+  regex = GNUNET_strdup("");
   opt = GNUNET_NO;
-  for (p = ctx->head; NULL != p; p = p->next)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "adding '%s' to innner %s\n", p->s, ctx->s);
-    s = regex_combine (p);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  total '%s'\n", s);
-    if (strlen(s) == 0)
-    {
-      opt = GNUNET_YES;
-    }
-    else
+  for (i = 0; i < ctx->size; i++)
     {
-      GNUNET_asprintf (&tmp, "%s%s|", regex, s);
-      GNUNET_free_non_null (regex);
-      regex = tmp;
+      p = ctx->children[i];
+      if (NULL == p)
+        continue;
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+                 "adding '%s' to innner %s\n",
+                 p->s, ctx->s);
+      s = regex_combine(p);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "  total '%s'\n", s);
+      if (strlen(s) == 0)
+        {
+          opt = GNUNET_YES;
+        }
+      else
+        {
+          GNUNET_asprintf(&tmp, "%s%s|", regex, s);
+          GNUNET_free_non_null(regex);
+          regex = tmp;
+        }
+      GNUNET_free_non_null(s);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "  so far '%s' for inner %s\n", regex, ctx->s);
     }
-    GNUNET_free_non_null (s);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  so far '%s' for inner %s\n", regex, ctx->s);
-  }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "opt: %d, innner: '%s'\n", opt, regex);
-  len = strlen (regex);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "opt: %d, innner: '%s'\n", opt, regex);
+  len = strlen(regex);
   if (0 == len)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "empty, returning ''\n");
-    GNUNET_free (regex);
-    return NULL == ctx->s ? NULL : GNUNET_strdup (ctx->s);
-  }
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "empty, returning ''\n");
+      GNUNET_free(regex);
+      return NULL == ctx->s ? NULL : GNUNET_strdup(ctx->s);
+    }
 
   if ('|' == regex[len - 1])
     regex[len - 1] = '\0';
 
   if (NULL != ctx->s)
-  {
-    if (opt)
-      GNUNET_asprintf (&s, "%s(%s)?", ctx->s, regex);
-    else
-      GNUNET_asprintf (&s, "%s(%s)", ctx->s, regex);
-    GNUNET_free (regex);
-    regex = s;
-  }
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "partial: %s\n", regex);
+    {
+      if (opt)
+        GNUNET_asprintf(&s, "%s(%s)?", ctx->s, regex);
+      else
+        GNUNET_asprintf(&s, "%s(%s)", ctx->s, regex);
+      GNUNET_free(regex);
+      regex = s;
+    }
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "partial: %s\n", regex);
   return regex;
 }
 
@@ -160,22 +264,22 @@ regex_combine (struct RegexCombineCtx *ctx)
  * @return Number of characters of matching prefix.
  */
 static unsigned int
-get_prefix_length (const char *s1, const char *s2)
+get_prefix_length(const char *s1, const char *s2)
 {
   unsigned int l1;
   unsigned int l2;
   unsigned int limit;
   unsigned int i;
 
-  l1 = strlen (s1);
-  l2 = strlen (s2);
+  l1 = strlen(s1);
+  l2 = strlen(s2);
   limit = l1 > l2 ? l2 : l1;
 
-  for (i = 1; i <= limit; i++)
-  {
-    if (0 != strncmp (s1, s2, i))
-      return i - 1;
-  }
+  for (i = 0; i < limit; i++)
+    {
+      if (s1[i] != s2[i])
+        return i;
+    }
   return limit;
 }
 
@@ -190,28 +294,137 @@ get_prefix_length (const char *s1, const char *s2)
  * @return Child with the longest prefix, NULL if no child matches.
  */
 static struct RegexCombineCtx *
-get_longest_prefix (struct RegexCombineCtx *ctx, const char *regex)
+get_longest_prefix(struct RegexCombineCtx *ctx, const char *regex)
 {
   struct RegexCombineCtx *p;
   struct RegexCombineCtx *best;
+  unsigned int i;
   unsigned int l;
   unsigned int best_l;
 
   best_l = 0;
   best = NULL;
-  for (p = ctx->head; NULL != p; p = p->next)
-  {
-    l = get_prefix_length (p->s, regex);
-    if (l > best_l)
+
+  for (i = 0; i < ctx->size; i++)
     {
-      GNUNET_break (0 == best_l);
-      best = p;
-      best_l = l;
+      p = ctx->children[i];
+      if (NULL == p)
+        continue;
+
+      l = get_prefix_length(p->s, regex);
+      if (l > best_l)
+        {
+          GNUNET_break(0 == best_l);
+          best = p;
+          best_l = l;
+        }
     }
-  }
   return best;
 }
 
+static void
+regex_add_multiple(struct RegexCombineCtx *ctx,
+                   const char *regex,
+                   struct RegexCombineCtx **children)
+{
+  char tmp[2];
+  long unsigned int i;
+  size_t l;
+  struct RegexCombineCtx *newctx;
+  unsigned int count;
+
+  if ('(' != regex[0])
+    {
+      GNUNET_assert(0);
+    }
+
+  /* Does the regex cover *all* possible children? Then don't add any,
+   * as it will be covered by the post-regex "(a-z)*"
+   */
+  l = strlen(regex);
+  count = 0;
+  for (i = 1UL; i < l; i++)
+    {
+      if (regex[i] != '|' && regex[i] != ')')
+        {
+          count++;
+        }
+    }
+  if (count == ctx->size)
+    {
+      return;
+    }
+
+  /* Add every component as a child node */
+  tmp[1] = '\0';
+  for (i = 1UL; i < l; i++)
+    {
+      if (regex[i] != '|' && regex[i] != ')')
+        {
+          tmp[0] = regex[i];
+          newctx = new_regex_ctx(ctx->size);
+          newctx->s = GNUNET_strdup(tmp);
+          if (children != NULL)
+            GNUNET_memcpy(newctx->children,
+                          children,
+                          sizeof(*children) * ctx->size);
+          ctx->children[c2i(tmp[0], ctx->size)] = newctx;
+        }
+    }
+}
+
+/**
+ * Add a single regex to a context, splitting the exisiting state.
+ *
+ * We only had a partial match, split existing state, truncate the current node
+ * so it only contains the prefix, add suffix(es) as children.
+ *
+ * @param ctx Context to split.
+ * @param len Lenght of ctx->s
+ * @param prefix_l Lenght of common prefix of the new regex and @a ctx->s
+ */
+static void
+regex_split(struct RegexCombineCtx *ctx,
+            unsigned int len,
+            unsigned int prefix_l)
+{
+  struct RegexCombineCtx *newctx;
+  unsigned int idx;
+  char *suffix;
+
+  suffix = GNUNET_malloc(len - prefix_l + 1);
+  /*
+   * We can use GNUNET_strlcpy because ctx->s is null-terminated
+   */
+  GNUNET_strlcpy(suffix, &ctx->s[prefix_l], len - prefix_l + 1);
+
+  /* Suffix saved, truncate current node so it only contains the prefix,
+   * copy any children nodes to put as grandchildren and initialize new empty
+   * children array.
+   */
+  ctx->s[prefix_l] = '\0';
+
+  /* If the suffix is an OR expression, add multiple children */
+  if ('(' == suffix[0])
+    {
+      struct RegexCombineCtx **tmp;
+
+      tmp = ctx->children;
+      ctx->children = GNUNET_malloc(sizeof(*tmp) * ctx->size);
+      regex_add_multiple(ctx, suffix, tmp);
+      GNUNET_free(suffix);
+      GNUNET_free(tmp);
+      return;
+    }
+
+  /* The suffix is a normal string, add as one node */
+  newctx = new_regex_ctx(ctx->size);
+  newctx->s = suffix;
+  move_children(newctx, ctx);
+  idx = c2i(suffix[0], ctx->size);
+  ctx->children[idx] = newctx;
+}
+
 
 /**
  * Add a single regex to a context, combining with exisiting regex by-prefix.
@@ -220,58 +433,66 @@ get_longest_prefix (struct RegexCombineCtx *ctx, const char *regex)
  * @param regex Regex to add.
  */
 static void
-regex_add (struct RegexCombineCtx *ctx, const char *regex)
+regex_add(struct RegexCombineCtx *ctx, const char *regex)
 {
   struct RegexCombineCtx *p;
   struct RegexCombineCtx *newctx;
+  long unsigned int l;
   unsigned int prefix_l;
   const char *rest_r;
   const char *rest_s;
   size_t len;
+  int idx;
 
-  if (0 == strlen (regex))
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+             "regex_add '%s' into '%s'\n",
+             regex, ctx->s);
+  l = strlen(regex);
+  if (0UL == l)
     return;
 
-  p = get_longest_prefix (ctx, regex);
-  if (NULL != p) /* There is some prefix match, reduce regex and try again */
-  {
-    prefix_l = get_prefix_length (p->s, regex);
-    rest_s = &p->s[prefix_l];
-    rest_r = &regex[prefix_l];
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "chosen '%s' [%u]\n", p->s, prefix_l);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "prefix r '%.*s'\n", prefix_l, p->s);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "rest r '%s'\n", rest_r);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "rest s '%s'\n", rest_s);
-    len = strlen (p->s);
-    if (prefix_l < len) /* only partial match, split existing state */
+  /* If the regex is in the form of (a|b|c), add every character separately */
+  if ('(' == regex[0])
     {
-      newctx = GNUNET_new (struct RegexCombineCtx);
-      newctx->head = p->head;
-      newctx->tail = p->tail;
-      newctx->s = GNUNET_malloc(len - prefix_l + 1);
-      strncpy (newctx->s, rest_s, len - prefix_l + 1);
-
-      p->head = newctx;
-      p->tail = newctx;
-      p->s[prefix_l] = '\0';
+      regex_add_multiple(ctx, regex, NULL);
+      return;
     }
-    regex_add (p, rest_r);
-    return;
-  }
+
+  p = get_longest_prefix(ctx, regex);
+  if (NULL != p)
+    {
+      /* There is some prefix match, reduce regex and try again */
+      prefix_l = get_prefix_length(p->s, regex);
+      rest_s = &p->s[prefix_l];
+      rest_r = &regex[prefix_l];
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "chosen '%s' [%u]\n", p->s, prefix_l);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "prefix r '%.*s'\n", prefix_l, p->s);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "rest r '%s'\n", rest_r);
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "rest s '%s'\n", rest_s);
+      len = strlen(p->s);
+      if (prefix_l < len)
+        {
+          regex_split(p, len, prefix_l);
+        }
+      regex_add(p, rest_r);
+      return;
+    }
+
   /* There is no prefix match, add new */
-  if (NULL == ctx->head && NULL != ctx->s)
-  {
-    /* this was the end before, add empty string */
-    newctx = GNUNET_new (struct RegexCombineCtx);
-    newctx->s = GNUNET_strdup ("");
-    GNUNET_CONTAINER_DLL_insert (ctx->head, ctx->tail, newctx);
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " no match\n");
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " new state %s\n", regex);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " under %s\n", ctx->s);
-  newctx = GNUNET_new (struct RegexCombineCtx);
-  newctx->s = GNUNET_strdup (regex);
-  GNUNET_CONTAINER_DLL_insert (ctx->head, ctx->tail, newctx);
+  idx = c2i(regex[0], ctx->size);
+  if (NULL == ctx->children[idx] && NULL != ctx->s)
+    {
+      /* this was the end before, add empty string */
+      newctx = new_regex_ctx(ctx->size);
+      newctx->s = GNUNET_strdup("");
+      ctx->children[idx] = newctx;
+    }
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, " no match\n");
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, " new state %s\n", regex);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, " under %s\n", ctx->s);
+  newctx = new_regex_ctx(ctx->size);
+  newctx->s = GNUNET_strdup(regex);
+  ctx->children[idx] = newctx;
 }
 
 
@@ -281,51 +502,59 @@ regex_add (struct RegexCombineCtx *ctx, const char *regex)
  * @param ctx Context to free.
  */
 static void
-regex_ctx_destroy (struct RegexCombineCtx *ctx)
+regex_ctx_destroy(struct RegexCombineCtx *ctx)
 {
-  struct RegexCombineCtx *p;
-  struct RegexCombineCtx *next;
-
-  for (p = ctx->head; NULL != p; p = next)
-  {
-    next = p->next;
-    regex_ctx_destroy (p);
-  }
-  GNUNET_free_non_null (ctx->s); /* 's' on root node is null */
-  GNUNET_free (ctx);
+  unsigned int i;
+
+  if (NULL == ctx)
+    return;
+
+  for (i = 0; i < ctx->size; i++)
+    {
+      regex_ctx_destroy(ctx->children[i]);
+    }
+  GNUNET_free_non_null(ctx->s);  /* 's' on root node is null */
+  GNUNET_free(ctx->children);
+  GNUNET_free(ctx);
 }
 
 
 /**
- * Return a prefix-combine regex that matches the same strings as
+ * Combine an array of regexes into a single prefix-shared regex.
+ * Returns a prefix-combine regex that matches the same strings as
  * any of the original regexes.
  *
  * WARNING: only useful for reading specific regexes for specific applications,
  *          namely the gnunet-regex-profiler / gnunet-regex-daemon.
  *          This function DOES NOT support arbitrary regex combining.
+ *
+ * @param regexes A NULL-terminated array of regexes.
+ * @param alphabet_size Size of the alphabet the regex uses.
+ *
+ * @return A string with a single regex that matches any of the original regexes
  */
 char *
-REGEX_TEST_combine (char * const regexes[])
+REGEX_TEST_combine(char * const regexes[], unsigned int alphabet_size)
 {
   unsigned int i;
   char *combined;
   const char *current;
   struct RegexCombineCtx *ctx;
 
-  ctx = GNUNET_new (struct RegexCombineCtx);
+  ctx = new_regex_ctx(alphabet_size);
   for (i = 0; regexes[i]; i++)
-  {
-    current = regexes[i];
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Regex %u: %s\n", i, current);
-    regex_add (ctx, current);
-    /* debugctx (ctx, 0); */
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\nCombining...\n");
-  /* debugctx (ctx, 0); */
+    {
+      current = regexes[i];
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Regex %u: %s\n", i, current);
+      regex_add(ctx, current);
+      debugctx(ctx, 0);
+    }
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "\nCombining...\n");
+  debugctx(ctx, 0);
 
-  combined = regex_combine (ctx);
+  combined = regex_combine(ctx);
 
-  regex_ctx_destroy (ctx);
+  regex_ctx_destroy(ctx);
 
   return combined;
 }
@@ -341,7 +570,7 @@ REGEX_TEST_combine (char * const regexes[])
  * @return A newly allocated, NULL terminated array of regexes.
  */
 char **
-REGEX_TEST_read_from_file (const char *filename)
+REGEX_TEST_read_from_file(const char *filename)
 {
   struct GNUNET_DISK_FileHandle *f;
   unsigned int nr;
@@ -352,54 +581,55 @@ REGEX_TEST_read_from_file (const char *filename)
   char *regex;
   char **regexes;
 
-  f = GNUNET_DISK_file_open (filename,
-                             GNUNET_DISK_OPEN_READ,
-                             GNUNET_DISK_PERM_NONE);
+  f = GNUNET_DISK_file_open(filename,
+                            GNUNET_DISK_OPEN_READ,
+                            GNUNET_DISK_PERM_NONE);
   if (NULL == f)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Can't open file %s for reading\n", filename);
-    return NULL;
-  }
-  if (GNUNET_OK != GNUNET_DISK_file_handle_size (f, &size))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Can't get size of file %s\n", filename);
-    GNUNET_DISK_file_close (f);
-    return NULL;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "using file %s, size %llu\n",
-              filename, (unsigned long long) size);
-
-  buffer = GNUNET_malloc (size + 1);
-  GNUNET_DISK_file_read (f, buffer, size);
-  GNUNET_DISK_file_close (f);
-  regexes = GNUNET_malloc (sizeof (char *));
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
+                 "Can't open file %s for reading\n", filename);
+      return NULL;
+    }
+  if (GNUNET_OK != GNUNET_DISK_file_handle_size(f, &size))
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
+                 "Can't get size of file %s\n", filename);
+      GNUNET_DISK_file_close(f);
+      return NULL;
+    }
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+             "using file %s, size %llu\n",
+             filename, (unsigned long long)size);
+
+  buffer = GNUNET_malloc(size + 1);
+  GNUNET_DISK_file_read(f, buffer, size);
+  GNUNET_DISK_file_close(f);
+  regexes = GNUNET_malloc(sizeof(char *));
   nr = 1;
   offset = 0;
   regex = NULL;
   do
-  {
-    if (NULL == regex)
-      regex = GNUNET_malloc (size + 1);
-    len = (size_t) sscanf (&buffer[offset], "%s", regex);
-    if (0 == len)
-      break;
-    len = strlen (regex);
-    offset += len + 1;
-    if (len < 1)
-      continue;
-    regex[len] = '\0';
-    regex = GNUNET_realloc (regex, len + 1);
-    GNUNET_array_grow (regexes, nr, nr + 1);
-    GNUNET_assert (NULL == regexes[nr - 2]);
-    regexes[nr - 2] = regex;
-    regexes[nr - 1] = NULL;
-    regex = NULL;
-  } while (offset < size);
-  GNUNET_free_non_null (regex);
-  GNUNET_free (buffer);
+    {
+      if (NULL == regex)
+        regex = GNUNET_malloc(size + 1);
+      len = (size_t)sscanf(&buffer[offset], "%s", regex);
+      if (0 == len)
+        break;
+      len = strlen(regex);
+      offset += len + 1;
+      if (len < 1)
+        continue;
+      regex[len] = '\0';
+      regex = GNUNET_realloc(regex, len + 1);
+      GNUNET_array_grow(regexes, nr, nr + 1);
+      GNUNET_assert(NULL == regexes[nr - 2]);
+      regexes[nr - 2] = regex;
+      regexes[nr - 1] = NULL;
+      regex = NULL;
+    }
+  while (offset < size);
+  GNUNET_free_non_null(regex);
+  GNUNET_free(buffer);
 
   return regexes;
 }
@@ -411,13 +641,13 @@ REGEX_TEST_read_from_file (const char *filename)
  * @param regexes NULL-terminated array of regexes.
  */
 void
-REGEX_TEST_free_from_file (char **regexes)
+REGEX_TEST_free_from_file(char **regexes)
 {
   unsigned int i;
 
   for (i = 0; regexes[i]; i++)
-    GNUNET_free (regexes[i]);
-  GNUNET_free (regexes);
+    GNUNET_free(regexes[i]);
+  GNUNET_free(regexes);
 }
 
 /* end of regex_test_lib.c */