aboutsummaryrefslogtreecommitdiff
path: root/src/regex/gnunet-regex-simulation-profiler.c
diff options
context:
space:
mode:
authorMaximilian Szengel <gnunet@maxsz.de>2012-11-16 13:08:51 +0000
committerMaximilian Szengel <gnunet@maxsz.de>2012-11-16 13:08:51 +0000
commitb6908a90bf1a1f8008bffa8bfb0416da3c7bc1d5 (patch)
treeb0768f32b98c4e04588577508b4316a41ac4156b /src/regex/gnunet-regex-simulation-profiler.c
parent58857960c4d0329b1e19636b07672db320b24ec0 (diff)
downloadgnunet-b6908a90bf1a1f8008bffa8bfb0416da3c7bc1d5.tar.gz
gnunet-b6908a90bf1a1f8008bffa8bfb0416da3c7bc1d5.zip
Cleaup, indentation, comments etc.
Diffstat (limited to 'src/regex/gnunet-regex-simulation-profiler.c')
-rw-r--r--src/regex/gnunet-regex-simulation-profiler.c277
1 files changed, 207 insertions, 70 deletions
diff --git a/src/regex/gnunet-regex-simulation-profiler.c b/src/regex/gnunet-regex-simulation-profiler.c
index 4bb033ea6..32b09eaee 100644
--- a/src/regex/gnunet-regex-simulation-profiler.c
+++ b/src/regex/gnunet-regex-simulation-profiler.c
@@ -32,26 +32,53 @@
32#include "gnunet_mysql_lib.h" 32#include "gnunet_mysql_lib.h"
33#include <mysql/mysql.h> 33#include <mysql/mysql.h>
34 34
35/**
36 * MySQL statement to insert an edge.
37 */
35#define INSERT_EDGE_STMT "INSERT IGNORE INTO `%s` "\ 38#define INSERT_EDGE_STMT "INSERT IGNORE INTO `%s` "\
36 "(`key`, `label`, `to_key`, `accepting`) "\ 39 "(`key`, `label`, `to_key`, `accepting`) "\
37 "VALUES (?, ?, ?, ?);" 40 "VALUES (?, ?, ?, ?);"
38 41
39/** 42/**
43 * MySQL statement to select a key count.
44 */
45#define SELECT_KEY_STMT "SELECT COUNT(*) FROM `%s` "\
46 "WHERE `key` = ? AND `label` = ?;"
47
48/**
40 * Simple struct to keep track of progress, and print a 49 * Simple struct to keep track of progress, and print a
41 * nice little percentage meter for long running tasks. 50 * nice little percentage meter for long running tasks.
42 */ 51 */
43struct ProgressMeter 52struct ProgressMeter
44{ 53{
54 /**
55 * Total number of elements.
56 */
45 unsigned int total; 57 unsigned int total;
46 58
59 /**
60 * Intervall for printing percentage.
61 */
47 unsigned int modnum; 62 unsigned int modnum;
48 63
64 /**
65 * Number of dots to print.
66 */
49 unsigned int dotnum; 67 unsigned int dotnum;
50 68
69 /**
70 * Completed number.
71 */
51 unsigned int completed; 72 unsigned int completed;
52 73
74 /**
75 * Should the meter be printed?
76 */
53 int print; 77 int print;
54 78
79 /**
80 * String to print on startup.
81 */
55 char *startup_string; 82 char *startup_string;
56}; 83};
57 84
@@ -67,6 +94,11 @@ static struct ProgressMeter *meter;
67static GNUNET_SCHEDULER_TaskIdentifier abort_task; 94static GNUNET_SCHEDULER_TaskIdentifier abort_task;
68 95
69/** 96/**
97 * Shutdown task identifier.
98 */
99static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
100
101/**
70 * Scan task identifier; 102 * Scan task identifier;
71 */ 103 */
72static GNUNET_SCHEDULER_TaskIdentifier scan_task; 104static GNUNET_SCHEDULER_TaskIdentifier scan_task;
@@ -87,6 +119,11 @@ static struct GNUNET_MYSQL_Context *mysql_ctx;
87static struct GNUNET_MYSQL_StatementHandle *stmt_handle; 119static struct GNUNET_MYSQL_StatementHandle *stmt_handle;
88 120
89/** 121/**
122 * MySQL prepared statement handle for `key` select.
123 */
124static struct GNUNET_MYSQL_StatementHandle *select_stmt_handle;
125
126/**
90 * MySQL table name. 127 * MySQL table name.
91 */ 128 */
92static char *table_name; 129static char *table_name;
@@ -111,6 +148,21 @@ static unsigned int num_policies;
111 */ 148 */
112static unsigned int max_path_compression; 149static unsigned int max_path_compression;
113 150
151/**
152 * Number of merged transitions.
153 */
154static unsigned long long num_merged_transitions;
155
156/**
157 * Number of merged states from different policies.
158 */
159static unsigned long long num_merged_states;
160
161/**
162 * Prefix to add before every regex we're announcing.
163 */
164static char *regex_prefix;
165
114 166
115/** 167/**
116 * Create a meter to keep track of the progress of some task. 168 * Create a meter to keep track of the progress of some task.
@@ -167,7 +219,7 @@ update_meter (struct ProgressMeter *meter)
167 (int) (((float) meter->completed / meter->total) * 100)); 219 (int) (((float) meter->completed / meter->total) * 100));
168 } 220 }
169 else if (meter->completed % meter->dotnum == 0) 221 else if (meter->completed % meter->dotnum == 0)
170 FPRINTF (stdout, "%s", "."); 222 FPRINTF (stdout, "%s", ".");
171 223
172 if (meter->completed + 1 == meter->total) 224 if (meter->completed + 1 == meter->total)
173 FPRINTF (stdout, "%d%%]\n", 100); 225 FPRINTF (stdout, "%d%%]\n", 100);
@@ -224,12 +276,15 @@ free_meter (struct ProgressMeter *meter)
224static void 276static void
225do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 277do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
226{ 278{
279 shutdown_task = GNUNET_SCHEDULER_NO_TASK;
280 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
281 GNUNET_SCHEDULER_cancel (abort_task);
227 if (NULL != mysql_ctx) 282 if (NULL != mysql_ctx)
228 GNUNET_MYSQL_context_destroy (mysql_ctx); 283 GNUNET_MYSQL_context_destroy (mysql_ctx);
229 if (NULL != meter) 284 if (NULL != meter)
230 free_meter (meter); 285 free_meter (meter);
231 286
232 GNUNET_SCHEDULER_shutdown (); /* Stop scheduler to shutdown testbed run */ 287 GNUNET_SCHEDULER_shutdown (); /* Stop scheduler to shutdown testbed run */
233} 288}
234 289
235 290
@@ -252,6 +307,22 @@ do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
252 307
253 308
254/** 309/**
310 * Dummy function for prepared select. Always return GNUNET_OK.
311 *
312 * @param cls closure
313 * @param num_values number of values.
314 * @param values returned values from select stmt.
315 *
316 * @return GNUNET_OK
317 */
318static int
319return_ok (void *cls, unsigned int num_values, MYSQL_BIND * values)
320{
321 return GNUNET_OK;
322}
323
324
325/**
255 * Iterator over all states that inserts each state into the MySQL db. 326 * Iterator over all states that inserts each state into the MySQL db.
256 * 327 *
257 * @param cls closure. 328 * @param cls closure.
@@ -262,11 +333,8 @@ do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
262 * @param edges edges leaving current state. 333 * @param edges edges leaving current state.
263 */ 334 */
264static void 335static void
265regex_iterator (void *cls, 336regex_iterator (void *cls, const struct GNUNET_HashCode *key, const char *proof,
266 const struct GNUNET_HashCode *key, 337 int accepting, unsigned int num_edges,
267 const char *proof,
268 int accepting,
269 unsigned int num_edges,
270 const struct GNUNET_REGEX_Edge *edges) 338 const struct GNUNET_REGEX_Edge *edges)
271{ 339{
272 unsigned int i; 340 unsigned int i;
@@ -274,6 +342,8 @@ regex_iterator (void *cls,
274 unsigned long k_length; 342 unsigned long k_length;
275 unsigned long e_length; 343 unsigned long e_length;
276 unsigned long d_length; 344 unsigned long d_length;
345 MYSQL_BIND rbind[1];
346 unsigned long long total;
277 347
278 GNUNET_assert (NULL != mysql_ctx); 348 GNUNET_assert (NULL != mysql_ctx);
279 349
@@ -282,19 +352,69 @@ regex_iterator (void *cls,
282 k_length = sizeof (struct GNUNET_HashCode); 352 k_length = sizeof (struct GNUNET_HashCode);
283 e_length = strlen (edges[i].label); 353 e_length = strlen (edges[i].label);
284 d_length = sizeof (struct GNUNET_HashCode); 354 d_length = sizeof (struct GNUNET_HashCode);
355 memset (rbind, 0, sizeof (rbind));
356 total = -1;
357 rbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
358 rbind[0].buffer = &total;
359 rbind[0].is_unsigned = GNUNET_YES;
360
361 result =
362 GNUNET_MYSQL_statement_run_prepared_select (mysql_ctx,
363 select_stmt_handle, 1,
364 rbind, &return_ok, NULL,
365 MYSQL_TYPE_BLOB, key,
366 sizeof (struct
367 GNUNET_HashCode),
368 &k_length,
369 MYSQL_TYPE_STRING,
370 edges[i].label,
371 strlen (edges[i].label),
372 &e_length, -1);
373
374 if (GNUNET_SYSERR == result)
375 {
376 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
377 "Error executing prepared mysql select statement\n");
378 GNUNET_SCHEDULER_add_now (&do_abort, NULL);
379 return;
380 }
381
382 if (-1 != total && total > 0)
383 {
384 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Total: %llu (%s, %s)\n", total,
385 GNUNET_h2s (key), edges[i].label);
386 }
285 387
286 result = 388 result =
287 GNUNET_MYSQL_statement_run_prepared ( 389 GNUNET_MYSQL_statement_run_prepared (mysql_ctx, stmt_handle, NULL,
288 mysql_ctx, 390 MYSQL_TYPE_BLOB, key,
289 stmt_handle, 391 sizeof (struct GNUNET_HashCode),
290 NULL, 392 &k_length, MYSQL_TYPE_STRING,
291 MYSQL_TYPE_BLOB, key, sizeof (struct GNUNET_HashCode), &k_length, 393 edges[i].label,
292 MYSQL_TYPE_STRING, edges[i].label, strlen (edges[i].label), &e_length, 394 strlen (edges[i].label), &e_length,
293 MYSQL_TYPE_BLOB, &edges[i].destination, sizeof (struct GNUNET_HashCode), &d_length, 395 MYSQL_TYPE_BLOB,
294 MYSQL_TYPE_LONG, &accepting, GNUNET_YES, 396 &edges[i].destination,
295 -1); 397 sizeof (struct GNUNET_HashCode),
398 &d_length, MYSQL_TYPE_LONG,
399 &accepting, GNUNET_YES, -1);
400
401 if (0 == result)
402 {
403 char *key_str = GNUNET_strdup (GNUNET_h2s (key));
404 char *to_key_str = GNUNET_strdup (GNUNET_h2s (&edges[i].destination));
405
406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Merged (%s, %s, %s, %i)\n", key_str,
407 edges[i].label, to_key_str, accepting);
408 GNUNET_free (key_str);
409 GNUNET_free (to_key_str);
410 num_merged_transitions++;
411 }
412 else if (-1 != total)
413 {
414 num_merged_states++;
415 }
296 416
297 if (1 != result && 0 != result) 417 if (GNUNET_SYSERR == result || (1 != result && 0 != result))
298 { 418 {
299 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 419 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
300 "Error executing prepared mysql statement for edge: Affected rows: %i, expected 0 or 1!\n", 420 "Error executing prepared mysql statement for edge: Affected rows: %i, expected 0 or 1!\n",
@@ -310,15 +430,14 @@ regex_iterator (void *cls,
310 d_length = 0; 430 d_length = 0;
311 431
312 result = 432 result =
313 GNUNET_MYSQL_statement_run_prepared ( 433 GNUNET_MYSQL_statement_run_prepared (mysql_ctx, stmt_handle, NULL,
314 mysql_ctx, 434 MYSQL_TYPE_BLOB, key,
315 stmt_handle, 435 sizeof (struct GNUNET_HashCode),
316 NULL, 436 &k_length, MYSQL_TYPE_STRING, NULL,
317 MYSQL_TYPE_BLOB, key, sizeof (struct GNUNET_HashCode), &k_length, 437 0, &e_length, MYSQL_TYPE_BLOB,
318 MYSQL_TYPE_STRING, NULL, 0, &e_length, 438 NULL, 0, &d_length,
319 MYSQL_TYPE_BLOB, NULL, 0, &d_length, 439 MYSQL_TYPE_LONG, &accepting,
320 MYSQL_TYPE_LONG, &accepting, GNUNET_YES, 440 GNUNET_YES, -1);
321 -1);
322 441
323 if (1 != result && 0 != result) 442 if (1 != result && 0 != result)
324 { 443 {
@@ -343,12 +462,13 @@ announce_regex (const char *regex)
343{ 462{
344 struct GNUNET_REGEX_Automaton *dfa; 463 struct GNUNET_REGEX_Automaton *dfa;
345 464
346 dfa = GNUNET_REGEX_construct_dfa (regex, strlen (regex), max_path_compression); 465 dfa =
466 GNUNET_REGEX_construct_dfa (regex, strlen (regex), max_path_compression);
347 467
348 if (NULL == dfa) 468 if (NULL == dfa)
349 { 469 {
350 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 470 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create DFA for regex %s\n",
351 "Failed to create DFA for regex %s\n", regex); 471 regex);
352 abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL); 472 abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);
353 return GNUNET_SYSERR; 473 return GNUNET_SYSERR;
354 } 474 }
@@ -380,21 +500,22 @@ policy_filename_cb (void *cls, const char *filename)
380 500
381 GNUNET_assert (NULL != filename); 501 GNUNET_assert (NULL != filename);
382 502
383 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 503 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Announcing regexes from file %s\n",
384 "Announcing regexes from file %s\n",
385 filename); 504 filename);
386 505
387 if (GNUNET_YES != GNUNET_DISK_file_test (filename)) 506 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
388 { 507 {
389 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 508 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Could not find policy file %s\n",
390 "Could not find policy file %s\n", filename); 509 filename);
391 return GNUNET_OK; 510 return GNUNET_OK;
392 } 511 }
393 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &filesize, GNUNET_YES, GNUNET_YES)) 512 if (GNUNET_OK !=
513 GNUNET_DISK_file_size (filename, &filesize, GNUNET_YES, GNUNET_YES))
394 filesize = 0; 514 filesize = 0;
395 if (0 == filesize) 515 if (0 == filesize)
396 { 516 {
397 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Policy file %s is empty.\n", filename); 517 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Policy file %s is empty.\n",
518 filename);
398 return GNUNET_OK; 519 return GNUNET_OK;
399 } 520 }
400 data = GNUNET_malloc (filesize); 521 data = GNUNET_malloc (filesize);
@@ -416,24 +537,24 @@ policy_filename_cb (void *cls, const char *filename)
416 offset++; 537 offset++;
417 if (((data[offset] == '\n')) && (buf != &data[offset])) 538 if (((data[offset] == '\n')) && (buf != &data[offset]))
418 { 539 {
419 data[offset] = '\0'; 540 data[offset] = '|';
420 regex = buf;
421 GNUNET_assert (NULL != regex);
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Announcing regex: %s\n",
423 regex);
424 num_policies++; 541 num_policies++;
425
426 if (GNUNET_OK != announce_regex (regex))
427 {
428 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
429 "Could not announce regex %s\n", regex);
430 }
431
432 buf = &data[offset + 1]; 542 buf = &data[offset + 1];
433 } 543 }
434 else if ((data[offset] == '\n') || (data[offset] == '\0')) 544 else if ((data[offset] == '\n') || (data[offset] == '\0'))
435 buf = &data[offset + 1]; 545 buf = &data[offset + 1];
436 } 546 }
547 data[offset] = '\0';
548 GNUNET_asprintf (&regex, "%s(%s)", regex_prefix, data);
549 GNUNET_assert (NULL != regex);
550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Announcing regex: %s\n", regex);
551
552 if (GNUNET_OK != announce_regex (regex))
553 {
554 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not announce regex %s\n",
555 regex);
556 }
557 GNUNET_free (regex);
437 GNUNET_free (data); 558 GNUNET_free (data);
438 return GNUNET_OK; 559 return GNUNET_OK;
439} 560}
@@ -452,32 +573,34 @@ do_directory_scan (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
452 struct GNUNET_TIME_Relative duration; 573 struct GNUNET_TIME_Relative duration;
453 char *stmt; 574 char *stmt;
454 575
455 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
456 GNUNET_SCHEDULER_cancel (abort_task);
457
458 /* Create an MySQL prepared statement for the inserts */ 576 /* Create an MySQL prepared statement for the inserts */
459 GNUNET_asprintf (&stmt, INSERT_EDGE_STMT, table_name); 577 GNUNET_asprintf (&stmt, INSERT_EDGE_STMT, table_name);
460 stmt_handle = GNUNET_MYSQL_statement_prepare (mysql_ctx, stmt); 578 stmt_handle = GNUNET_MYSQL_statement_prepare (mysql_ctx, stmt);
461 GNUNET_free (stmt); 579 GNUNET_free (stmt);
462 580
581 GNUNET_asprintf (&stmt, SELECT_KEY_STMT, table_name);
582 select_stmt_handle = GNUNET_MYSQL_statement_prepare (mysql_ctx, stmt);
583 GNUNET_free (stmt);
584
463 GNUNET_assert (NULL != stmt_handle); 585 GNUNET_assert (NULL != stmt_handle);
464 586
465 meter = create_meter (num_policy_files, "Announcing policy files\n", GNUNET_YES); 587 meter =
588 create_meter (num_policy_files, "Announcing policy files\n", GNUNET_YES);
466 start_time = GNUNET_TIME_absolute_get (); 589 start_time = GNUNET_TIME_absolute_get ();
467 GNUNET_DISK_directory_scan (policy_dir, 590 GNUNET_DISK_directory_scan (policy_dir, &policy_filename_cb, stmt_handle);
468 &policy_filename_cb,
469 stmt_handle);
470 duration = GNUNET_TIME_absolute_get_duration (start_time); 591 duration = GNUNET_TIME_absolute_get_duration (start_time);
471 reset_meter (meter); 592 reset_meter (meter);
472 free_meter (meter); 593 free_meter (meter);
473 meter = NULL; 594 meter = NULL;
474 595
475 printf ("Announced %u files containing %u policies in %s\n", 596 printf ("Announced %u files containing %u policies in %s\n"
597 "Duplicate transitions: %llu\nMerged states: %llu\n",
476 num_policy_files, num_policies, 598 num_policy_files, num_policies,
477 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_NO)); 599 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_NO),
600 num_merged_transitions, num_merged_states);
478 601
479 result = GNUNET_OK; 602 result = GNUNET_OK;
480 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); 603 shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
481} 604}
482 605
483 606
@@ -495,26 +618,27 @@ run (void *cls, char *const *args, const char *cfgfile,
495{ 618{
496 if (NULL == args[0]) 619 if (NULL == args[0])
497 { 620 {
498 fprintf (stderr, _("No policy directory specified on command line. Exiting.\n")); 621 fprintf (stderr,
622 _("No policy directory specified on command line. Exiting.\n"));
499 result = GNUNET_SYSERR; 623 result = GNUNET_SYSERR;
500 return; 624 return;
501 } 625 }
502 if (GNUNET_YES != GNUNET_DISK_directory_test (args[0], GNUNET_YES)) 626 if (GNUNET_YES != GNUNET_DISK_directory_test (args[0], GNUNET_YES))
503 { 627 {
504 fprintf (stderr, _("Specified policies directory does not exist. Exiting.\n")); 628 fprintf (stderr,
629 _("Specified policies directory does not exist. Exiting.\n"));
505 result = GNUNET_SYSERR; 630 result = GNUNET_SYSERR;
506 return; 631 return;
507 } 632 }
508 policy_dir = args[0]; 633 policy_dir = args[0];
509 634
510 num_policy_files = GNUNET_DISK_directory_scan (policy_dir, 635 num_policy_files = GNUNET_DISK_directory_scan (policy_dir, NULL, NULL);
511 NULL,
512 NULL);
513 meter = NULL; 636 meter = NULL;
514 637
515 if (NULL == table_name) 638 if (NULL == table_name)
516 { 639 {
517 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "No table name specified, using default \"NFA\".\n"); 640 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
641 "No table name specified, using default \"NFA\".\n");
518 table_name = "NFA"; 642 table_name = "NFA";
519 } 643 }
520 644
@@ -526,14 +650,27 @@ run (void *cls, char *const *args, const char *cfgfile,
526 return; 650 return;
527 } 651 }
528 652
653 if (GNUNET_OK !=
654 GNUNET_CONFIGURATION_get_value_string (config, "regex-mysql",
655 "REGEX_PREFIX", &regex_prefix))
656 {
657 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
658 _
659 ("%s service is lacking key configuration settings (%s). Exiting.\n"),
660 "regexprofiler", "regex_prefix");
661 result = GNUNET_SYSERR;
662 return;
663 }
664
665
529 result = GNUNET_OK; 666 result = GNUNET_OK;
530 667
531 scan_task = GNUNET_SCHEDULER_add_now (&do_directory_scan, NULL); 668 scan_task = GNUNET_SCHEDULER_add_now (&do_directory_scan, NULL);
532 669
533 abort_task = 670 /* Scheduled the task to clean up when shutdown is called */
534 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 671 shutdown_task =
535 (GNUNET_TIME_UNIT_SECONDS, 10), &do_abort, 672 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown,
536 NULL); 673 NULL);
537} 674}
538 675
539 676
@@ -563,9 +700,9 @@ main (int argc, char *const *argv)
563 700
564 result = GNUNET_SYSERR; 701 result = GNUNET_SYSERR;
565 ret = 702 ret =
566 GNUNET_PROGRAM_run (argc, argv, "gnunet-regex-simulationprofiler [OPTIONS] policy-dir", 703 GNUNET_PROGRAM_run (argc, argv,
567 _("Profiler for regex library"), 704 "gnunet-regex-simulationprofiler [OPTIONS] policy-dir",
568 options, &run, NULL); 705 _("Profiler for regex library"), options, &run, NULL);
569 if (GNUNET_OK != ret) 706 if (GNUNET_OK != ret)
570 return ret; 707 return ret;
571 if (GNUNET_OK != result) 708 if (GNUNET_OK != result)