GNUnet  0.20.0
regex_test_lib.h File Reference

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

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.

117 {
122 
128 
133 };
@ REGEX_TEST_GRAPH_COLORING
Enable graph coloring.
@ REGEX_TEST_GRAPH_VERBOSE
The generated graph will include extra information such as the NFA states that were used to generate ...
@ REGEX_TEST_GRAPH_DEFAULT
Default.

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 545 of file regex_test_lib.c.

546 {
547  unsigned int i;
548  char *combined;
549  const char *current;
550  struct RegexCombineCtx *ctx;
551 
552  ctx = new_regex_ctx (alphabet_size);
553  for (i = 0; regexes[i]; i++)
554  {
555  current = regexes[i];
556  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Regex %u: %s\n", i, current);
557  regex_add (ctx, current);
558  debugctx (ctx, 0);
559  }
560  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\nCombining...\n");
561  debugctx (ctx, 0);
562 
563  combined = regex_combine (ctx);
564 
566 
567  return combined;
568 }
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
static struct RegexCombineCtx * new_regex_ctx(unsigned int alphabet_size)
Create and initialize a new RegexCombineCtx.
static void regex_ctx_destroy(struct RegexCombineCtx *ctx)
Free all resources used by the context node and all its children.
static void regex_add(struct RegexCombineCtx *ctx, const char *regex)
Add a single regex to a context, combining with existing regex by-prefix.
static void debugctx(struct RegexCombineCtx *ctx, int level)
Printf the combined regex ctx.
static char * regex_combine(struct RegexCombineCtx *ctx)
Extract a string from all prefix-combined regexes.
Struct to hold the tree formed by prefix-combining the regexes.

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().

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 581 of file regex_test_lib.c.

582 {
583  struct GNUNET_DISK_FileHandle *f;
584  unsigned int nr;
585  unsigned int offset;
586  off_t size;
587  size_t len;
588  char *buffer;
589  char *regex;
590  char **regexes;
591 
595  if (NULL == f)
596  {
598  "Can't open file %s for reading\n", filename);
599  return NULL;
600  }
602  {
604  "Can't get size of file %s\n", filename);
606  return NULL;
607  }
609  "using file %s, size %llu\n",
610  filename, (unsigned long long) size);
611 
612  buffer = GNUNET_malloc (size + 1);
613  GNUNET_DISK_file_read (f, buffer, size);
615  regexes = GNUNET_malloc (sizeof(char *));
616  nr = 1;
617  offset = 0;
618  regex = NULL;
619  do
620  {
621  if (NULL == regex)
622  regex = GNUNET_malloc (size + 1);
623  len = (size_t) sscanf (&buffer[offset], "%s", regex);
624  if (0 == len)
625  break;
626  len = strlen (regex);
627  offset += len + 1;
628  if (len < 1)
629  continue;
630  regex[len] = '\0';
631  regex = GNUNET_realloc (regex, len + 1);
632  GNUNET_array_grow (regexes, nr, nr + 1);
633  GNUNET_assert (NULL == regexes[nr - 2]);
634  regexes[nr - 2] = regex;
635  regexes[nr - 1] = NULL;
636  regex = NULL;
637  }
638  while (offset < size);
639  GNUNET_free (regex);
640  GNUNET_free (buffer);
641 
642  return regexes;
643 }
static char * filename
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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:1237
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1308
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:622
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:192
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
@ GNUNET_OK
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_realloc(ptr, size)
Wrapper around realloc.
#define GNUNET_free(ptr)
Wrapper around free.
static unsigned int size
Size of the "table".
Definition: peer.c:68
Handle used to access files (and pipes).

References removetrailingwhitespace::f, filename, 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_log, GNUNET_malloc, GNUNET_OK, GNUNET_realloc, len, and size.

Referenced by main(), and run().

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 652 of file regex_test_lib.c.

653 {
654  unsigned int i;
655 
656  for (i = 0; regexes[i]; i++)
657  GNUNET_free (regexes[i]);
658  GNUNET_free (regexes);
659 }

References GNUNET_free.

Referenced by main(), and run().

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 string.
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.

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  '?') &&
128  (current_char != '|') ))
129  {
130  *matching_strp = current_char;
131  matching_strp++;
132  }
133 
134  *rx_p = current_char;
135  rx_p++;
136  }
137  *rx_p = '\0';
138  if (NULL != matching_strp)
139  *matching_strp = '\0';
140 
141  return rx;
142 }
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
static char get_random_literal()
Get a (pseudo) random valid literal for building a regular expression.

References get_random_literal(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), and GNUNET_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 155 of file regex_test_random.c.

156 {
157  unsigned int i;
158  char *str;
159  size_t len;
160 
161  if (1 > max_len)
162  return GNUNET_strdup ("");
163 
165  str = GNUNET_malloc (len + 1);
166 
167  for (i = 0; i < len; i++)
168  {
169  str[i] = get_random_literal ();
170  }
171 
172  str[i] = '\0';
173 
174  return str;
175 }
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.

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

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.

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 }
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
@ GNUNET_YES
@ GNUNET_NO
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's start state,...
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.
struct REGEX_INTERNAL_State * start
First state of the automaton.
Context for graph creation.

References ctx, end, filename, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NO, GNUNET_YES, options, REGEX_INTERNAL_automaton_traverse(), REGEX_TEST_automaton_save_graph_step(), REGEX_TEST_GRAPH_COLORING, REGEX_TEST_GRAPH_VERBOSE, scc_tarjan(), start, and REGEX_INTERNAL_Automaton::start.

Here is the call graph for this function: