GNUnet  0.10.x
Enumerations | Functions
regex_test_lib.h File Reference

library to read regexes representing IP networks from a file. More...

#include "regex_internal_lib.h"
Include dependency graph for regex_test_lib.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  REGEX_TEST_GraphSavingOptions { REGEX_TEST_GRAPH_DEFAULT = 0, REGEX_TEST_GRAPH_VERBOSE = 1, REGEX_TEST_GRAPH_COLORING = 2 }
 Options for graph creation function REGEX_TEST_automaton_save_graph. More...
 

Functions

char * REGEX_TEST_combine (char *const regexes[], unsigned int alphabet_size)
 Combine an array of regexes into a single prefix-shared regex. More...
 
char ** REGEX_TEST_read_from_file (const char *filename)
 Read a set of regexes from a file, one per line and return them in an array suitable for REGEX_TEST_combine. More...
 
void REGEX_TEST_free_from_file (char **regexes)
 Free all memory reserved for a set of regexes created by read_from_file. More...
 
char * REGEX_TEST_generate_random_regex (size_t rx_length, char *matching_str)
 Generate a (pseudo) random regular expression of length 'rx_length', as well as a (optional) string that will be matched by the generated regex. More...
 
char * REGEX_TEST_generate_random_string (size_t max_len)
 Generate a random string of maximum length 'max_len' that only contains literals allowed in a regular expression. More...
 
void REGEX_TEST_automaton_save_graph (struct REGEX_INTERNAL_Automaton *a, const char *filename, enum REGEX_TEST_GraphSavingOptions options)
 Save the given automaton as a GraphViz dot file. More...
 

Detailed Description

library to read regexes representing IP networks from a file.

and simplifying the into one big regex, in order to run tests (regex performance, regex profiler).

Author
Bertlomiej Polot

Definition in file regex_test_lib.h.

Enumeration Type Documentation

◆ REGEX_TEST_GraphSavingOptions

Options for graph creation function REGEX_TEST_automaton_save_graph.

Enumerator
REGEX_TEST_GRAPH_DEFAULT 

Default.

Do nothing special.

REGEX_TEST_GRAPH_VERBOSE 

The generated graph will include extra information such as the NFA states that were used to generate the DFA state.

REGEX_TEST_GRAPH_COLORING 

Enable graph coloring.

Will color each SCC in a different color.

Definition at line 116 of file regex_test_lib.h.

116  {
121 
127 
132 };
The generated graph will include extra information such as the NFA states that were used to generate ...
Enable graph coloring.

Function Documentation

◆ REGEX_TEST_combine()

char* REGEX_TEST_combine ( char *const  regexes[],
unsigned int  alphabet_size 
)

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.

Parameters
regexesA NULL-terminated array of regexes.
alphabet_sizeSize of the alphabet the regex uses.
Returns
A string with a single regex that matches any of the original regexes

Definition at line 537 of file regex_test_lib.c.

References ctx, debugctx(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, new_regex_ctx(), regex_add(), regex_combine(), and regex_ctx_destroy().

Referenced by main(), and run().

538 {
539  unsigned int i;
540  char *combined;
541  const char *current;
542  struct RegexCombineCtx *ctx;
543 
544  ctx = new_regex_ctx(alphabet_size);
545  for (i = 0; regexes[i]; i++)
546  {
547  current = regexes[i];
548  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Regex %u: %s\n", i, current);
549  regex_add(ctx, current);
550  debugctx(ctx, 0);
551  }
552  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "\nCombining...\n");
553  debugctx(ctx, 0);
554 
555  combined = regex_combine(ctx);
556 
557  regex_ctx_destroy(ctx);
558 
559  return combined;
560 }
Struct to hold the tree formed by prefix-combining the regexes.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static void debugctx(struct RegexCombineCtx *ctx, int level)
Printf the combined regex ctx.
static void regex_ctx_destroy(struct RegexCombineCtx *ctx)
Free all resources used by the context node and all its children.
static char * regex_combine(struct RegexCombineCtx *ctx)
Extract a string from all prefix-combined regexes.
#define GNUNET_log(kind,...)
static struct RegexCombineCtx * new_regex_ctx(unsigned int alphabet_size)
Create and initialize a new RegexCombineCtx.
static void regex_add(struct RegexCombineCtx *ctx, const char *regex)
Add a single regex to a context, combining with exisiting regex by-prefix.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ REGEX_TEST_read_from_file()

char** REGEX_TEST_read_from_file ( const char *  filename)

Read a set of regexes from a file, one per line and return them in an array suitable for REGEX_TEST_combine.

The array must be free'd using REGEX_TEST_free_from_file.

Parameters
filenameName of the file containing the regexes.
Returns
A newly allocated, NULL terminated array of regexes.

Definition at line 573 of file regex_test_lib.c.

References removetrailingwhitespace::f, GNUNET_array_grow, GNUNET_assert, GNUNET_DISK_file_close(), GNUNET_DISK_file_handle_size(), GNUNET_DISK_file_open(), GNUNET_DISK_file_read(), GNUNET_DISK_OPEN_READ, GNUNET_DISK_PERM_NONE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_free_non_null, GNUNET_log, GNUNET_malloc, GNUNET_OK, GNUNET_realloc, len, and RegexCombineCtx::size.

Referenced by main(), and run().

574 {
575  struct GNUNET_DISK_FileHandle *f;
576  unsigned int nr;
577  unsigned int offset;
578  off_t size;
579  size_t len;
580  char *buffer;
581  char *regex;
582  char **regexes;
583 
587  if (NULL == f)
588  {
590  "Can't open file %s for reading\n", filename);
591  return NULL;
592  }
593  if (GNUNET_OK != GNUNET_DISK_file_handle_size(f, &size))
594  {
596  "Can't get size of file %s\n", filename);
598  return NULL;
599  }
601  "using file %s, size %llu\n",
602  filename, (unsigned long long)size);
603 
604  buffer = GNUNET_malloc(size + 1);
605  GNUNET_DISK_file_read(f, buffer, size);
607  regexes = GNUNET_malloc(sizeof(char *));
608  nr = 1;
609  offset = 0;
610  regex = NULL;
611  do
612  {
613  if (NULL == regex)
614  regex = GNUNET_malloc(size + 1);
615  len = (size_t)sscanf(&buffer[offset], "%s", regex);
616  if (0 == len)
617  break;
618  len = strlen(regex);
619  offset += len + 1;
620  if (len < 1)
621  continue;
622  regex[len] = '\0';
623  regex = GNUNET_realloc(regex, len + 1);
624  GNUNET_array_grow(regexes, nr, nr + 1);
625  GNUNET_assert(NULL == regexes[nr - 2]);
626  regexes[nr - 2] = regex;
627  regexes[nr - 1] = NULL;
628  regex = NULL;
629  }
630  while (offset < size);
631  GNUNET_free_non_null(regex);
632  GNUNET_free(buffer);
633 
634  return regexes;
635 }
Open the file for reading.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1339
ssize_t GNUNET_DISK_file_read(const struct GNUNET_DISK_FileHandle *h, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:729
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Nobody is allowed to do anything to the file.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
static char * filename
static unsigned int size
Size of the "table".
Definition: peer.c:66
int GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:203
#define GNUNET_log(kind,...)
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1262
Handle used to access files (and pipes).
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:
Here is the caller graph for this function:

◆ REGEX_TEST_free_from_file()

void REGEX_TEST_free_from_file ( char **  regexes)

Free all memory reserved for a set of regexes created by read_from_file.

Parameters
regexesNULL-terminated array of regexes.

Definition at line 644 of file regex_test_lib.c.

References GNUNET_free.

Referenced by main(), and run().

645 {
646  unsigned int i;
647 
648  for (i = 0; regexes[i]; i++)
649  GNUNET_free(regexes[i]);
650  GNUNET_free(regexes);
651 }
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ REGEX_TEST_generate_random_regex()

char* REGEX_TEST_generate_random_regex ( size_t  rx_length,
char *  matching_str 
)

Generate a (pseudo) random regular expression of length 'rx_length', as well as a (optional) string that will be matched by the generated regex.

The returned regex needs to be freed.

Parameters
rx_lengthlength of the random regex.
matching_str(optional) pointer to a string that will contain a string that will be matched by the generated regex, if 'matching_str' pointer was not NULL.
Returns
NULL if 'rx_length' is 0, a random regex of length 'rx_length', which needs to be freed, otherwise.

The returned regex needs to be freed.

Parameters
rx_lengthlength of the random regex.
matching_str(optional) pointer to a string that will contain a string that will be matched by the generated regex, if 'matching_str' pointer was not NULL. Make sure you allocated at least rx_length+1 bytes for this sting.
Returns
NULL if 'rx_length' is 0, a random regex of length 'rx_length', which needs to be freed, otherwise.

Definition at line 64 of file regex_test_random.c.

References get_random_literal(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), and GNUNET_malloc.

65 {
66  char *rx;
67  char *rx_p;
68  char *matching_strp;
69  unsigned int i;
70  unsigned int char_op_switch;
71  unsigned int last_was_op;
72  int rx_op;
73  char current_char;
74 
75  if (0 == rx_length)
76  return NULL;
77 
78  if (NULL != matching_str)
79  matching_strp = matching_str;
80  else
81  matching_strp = NULL;
82 
83  rx = GNUNET_malloc(rx_length + 1);
84  rx_p = rx;
85  current_char = 0;
86  last_was_op = 1;
87 
88  for (i = 0; i < rx_length; i++)
89  {
91 
92  if (0 == char_op_switch && !last_was_op)
93  {
94  last_was_op = 1;
96 
97  switch (rx_op)
98  {
99  case 0:
100  current_char = '+';
101  break;
102 
103  case 1:
104  current_char = '*';
105  break;
106 
107  case 2:
108  current_char = '?';
109  break;
110 
111  case 3:
112  if (i < rx_length - 1) /* '|' cannot be at the end */
113  current_char = '|';
114  else
115  current_char = get_random_literal();
116  break;
117  }
118  }
119  else
120  {
121  current_char = get_random_literal();
122  last_was_op = 0;
123  }
124 
125  if (NULL != matching_strp &&
126  (current_char != '+' && current_char != '*' && current_char != '?' &&
127  current_char != '|'))
128  {
129  *matching_strp = current_char;
130  matching_strp++;
131  }
132 
133  *rx_p = current_char;
134  rx_p++;
135  }
136  *rx_p = '\0';
137  if (NULL != matching_strp)
138  *matching_strp = '\0';
139 
140  return rx;
141 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
static char get_random_literal()
Get a (pseudo) random valid literal for building a regular expression.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the call graph for this function:

◆ REGEX_TEST_generate_random_string()

char* REGEX_TEST_generate_random_string ( size_t  max_len)

Generate a random string of maximum length 'max_len' that only contains literals allowed in a regular expression.

The string might be 0 chars long but is garantueed to be shorter or equal to 'max_len'.

Parameters
max_lenmaximum length of the string that should be generated.
Returns
random string that needs to be freed.

Definition at line 154 of file regex_test_random.c.

References get_random_literal(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_malloc, GNUNET_strdup, and len.

155 {
156  unsigned int i;
157  char *str;
158  size_t len;
159 
160  if (1 > max_len)
161  return GNUNET_strdup("");
162 
164  str = GNUNET_malloc(len + 1);
165 
166  for (i = 0; i < len; i++)
167  {
168  str[i] = get_random_literal();
169  }
170 
171  str[i] = '\0';
172 
173  return str;
174 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static char get_random_literal()
Get a (pseudo) random valid literal for building a regular expression.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_malloc(size)
Wrapper around malloc.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
Here is the call graph for this function:

◆ REGEX_TEST_automaton_save_graph()

void REGEX_TEST_automaton_save_graph ( struct REGEX_INTERNAL_Automaton a,
const char *  filename,
enum REGEX_TEST_GraphSavingOptions  options 
)

Save the given automaton as a GraphViz dot file.

Parameters
athe automaton to be saved.
filenamewhere to save the file.
optionsoptions for graph generation that include coloring or verbose mode

Definition at line 270 of file regex_test_graph.c.

References REGEX_TEST_Graph_Context::coloring, end, REGEX_TEST_Graph_Context::filep, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_YES, REGEX_INTERNAL_automaton_traverse(), REGEX_TEST_automaton_save_graph_step(), REGEX_TEST_GRAPH_COLORING, REGEX_TEST_GRAPH_VERBOSE, scc_tarjan(), start, REGEX_INTERNAL_Automaton::start, and REGEX_TEST_Graph_Context::verbose.

273 {
274  char *start;
275  char *end;
277 
278  if (NULL == a)
279  {
280  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not print NFA, was NULL!");
281  return;
282  }
283 
284  if (NULL == filename || strlen(filename) < 1)
285  {
286  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No Filename given!");
287  return;
288  }
289 
290  ctx.filep = fopen(filename, "w");
291  ctx.verbose =
293  ctx.coloring =
295 
296  if (NULL == ctx.filep)
297  {
298  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not open file for writing: %s",
299  filename);
300  return;
301  }
302 
303  /* First add the SCCs to the automaton, so we can color them nicely */
304  if (GNUNET_YES == ctx.coloring)
305  scc_tarjan(a);
306 
307  start = "digraph G {\nrankdir=LR\n";
308  fwrite(start, strlen(start), 1, ctx.filep);
309 
310  REGEX_INTERNAL_automaton_traverse(a, a->start, NULL, NULL,
312  &ctx);
313 
314  end = "\n}\n";
315  fwrite(end, strlen(end), 1, ctx.filep);
316  fclose(ctx.filep);
317 }
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
Context for graph creation.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
The generated graph will include extra information such as the NFA states that were used to generate ...
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
#define GNUNET_NO
Definition: gnunet_common.h:78
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void REGEX_INTERNAL_automaton_traverse(const struct REGEX_INTERNAL_Automaton *a, struct REGEX_INTERNAL_State *start, REGEX_INTERNAL_traverse_check check, void *check_cls, REGEX_INTERNAL_traverse_action action, void *action_cls)
Traverses the given automaton using depth-first-search (DFS) from it&#39;s start state, visiting all reachable states and calling &#39;action&#39; on each one of them.
static char * filename
Enable graph coloring.
struct REGEX_INTERNAL_State * start
First state of the automaton.
void REGEX_TEST_automaton_save_graph_step(void *cls, unsigned int count, struct REGEX_INTERNAL_State *s)
Save a state to an open file pointer.
static void scc_tarjan(struct REGEX_INTERNAL_Automaton *a)
Detect all SCCs (Strongly Connected Components) inside the given automaton.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the call graph for this function: