www.delorie.com/gnu/docs/avl/libavl_275.html   search  
 
Buy GNU books!


GNU libavl 2.0.1

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

B.2 Command-Line Parser

The option parser in the previous section handles the general form of command-line options. The code in this section applies that option parser to the specific options used by the BST test program. It has helper functions for argument parsing and advice to users. Here is all of it together:

 
/* Command line parser. */
/* If a is a prefix for b or vice versa, returns the length of the 
match. Otherwise, returns 0. */ size_t
match_len (const char *a, const char *b)
{ size_t cnt; for (cnt = 0; *a == *b && *a != '\0'; a++, b++) cnt++; return (*a != *b && *a != '\0' && *b != '\0') ? 0 : cnt; } /* s should point to a decimal representation of an integer. Returns the value of s, if successful, or 0 on failure. */ static int
stoi (const char *s)
{ long x = strtol (s, NULL, 10); return x >= INT_MIN && x <= INT_MAX ? x : 0; } /* Print helpful syntax message and exit. */ static void
usage (void)
{ static const char *help[] =
{ "bst-test,unittestforGNUlibavl.\n\n", "Usage:%s[OPTION]...\n\n", "Intheoptiondescriptionsbelow,CAPITALdenotearguments.\n", "Ifalongoptionshowsanargumentasmandatory,thenitis\n", "mandatoryfortheequivalentshortoptionalso.SeetheGNU\n", "libavlmanualformoreinformation.\n\n", "-t,--test=TESTSetstesttoperform.TESTisoneof:\n", "correctnessinsert/delete/...(default)\n", "overflowstackoverflowtest\n", "benchmarkbenchmarktest\n", "nullnotest\n", "-s,--size=TREE-SIZESetstreesizeinnodes(default16).\n", "-r,--repeat=COUNTRepeatsoperationCOUNTtimes(default16).\n", "-i,--insert=ORDERSetstheinsertionorder.ORDERisoneof:\n", "randomrandompermutation(default)\n", "ascendingascendingorder0...n-1\n", "descendingdescendingordern-1...0\n", "balancedbalancedtreeorder\n", "zigzagzig-zagtree\n", "asc-shiftedn/2...n-1,0...n/2-1\n", "customcustom,readfromstdin\n", "-d,--delete=ORDERSetsthedeletionorder.ORDERisoneof:\n", "randomrandompermutation(default)\n", "reversereverseorderofinsertion\n", "samesameasinsertionorder\n", "customcustom,readfromstdin\n", "-a,--alloc=POLICYSetsallocationpolicy.POLICYisoneof:\n", "tracktrackmemoryleaks(default)\n", "no-trackturnoffleakdetection\n", "fail-CNTfailafterCNTallocations\n", "fail%%PCTfailrandomPCT%%ofallocations\n", "sub-B,AdivideB-byteblocksinA-byteunits\n", "(Ignoredfor`benchmark'test.)\n", "-A,--incr=INCFailpolicies:argincrementperrepetition.\n", "-S,--seed=SEEDSetsinitialnumberseedtoSEED.\n", "(defaultbasedonsystemtime)\n", "-n,--nonstopDon'tstopafterasingleerror.\n", "-q,--quietTurnsdownverbositylevel.\n", "-v,--verboseTurnsupverbositylevel.\n", "-h,--helpDisplaysthishelpscreen.\n", "-V,--versionReportsversionandcopyrightinformation.\n", NULL, }; const char **p; for (p = help; *p != NULL; p++) printf (*p, pgm_name); exit (EXIT_SUCCESS); } /* Parses command-line arguments from null-terminated array args. Sets up options appropriately to correspond. */ static void
parse_command_line (char **args, struct test_options *options)
{ static const struct option option_tab[] =
{ {"test", 't', 1},
{"insert", 'i', 1},
{"delete", 'd', 1}, {"alloc", 'a', 1},
{"incr", 'A', 1},
{"size", 's', 1}, {"repeat", 'r', 1},
{"operation", 'o', 1},
{"seed", 'S', 1}, {"nonstop", 'n', 0},
{"quiet", 'q', 0},
{"verbose", 'v', 0}, {"help", 'h', 0},
{"version", 'V', 0},
{NULL, 0, 0}, }; struct option_state *state; /* Default options. */ options-&#62;test = TST_CORRECTNESS;
options-&#62;insert_order = INS_RANDOM; options-&#62;delete_order = DEL_RANDOM;
options-&#62;alloc_policy = MT_TRACK; options-&#62;alloc_arg[0] = 0;
options-&#62;alloc_arg[1] = 0; options-&#62;alloc_incr = 0;
options-&#62;node_cnt = 15; options-&#62;iter_cnt = 15;
options-&#62;seed_given = 0; options-&#62;verbosity = 0;
options-&#62;nonstop = 0; if (*args == NULL) return; state = option_init (option_tab, args + 1); for (;;)
{ char *arg; int id = option_get (state, &arg); if (id == -1) break; switch (id)
{ case 't': if (match_len (arg, "correctness") >= 3) options-&#62;test = TST_CORRECTNESS; else if (match_len (arg, "overflow") >= 3) options-&#62;test = TST_OVERFLOW; else if (match_len (arg, "null") >= 3) options-&#62;test = TST_NULL; else fail ("unknowntest\"%s\"", arg); break; case 'i':
{ static const char *orders[INS_CNT] =
{ "random", "ascending", "descending", "balanced", "zigzag", "asc-shifted", "custom", }; const char **iter; assert (sizeof orders / sizeof *orders == INS_CNT); for (iter = orders; ; iter++) if (iter >= orders + INS_CNT) fail ("unknownorder\"%s\"", arg); else if (match_len (*iter, arg) >= 3)
{ options-&#62;insert_order = iter - orders; break; } } break; case 'd':
{ static const char *orders[DEL_CNT] =
{ "random", "reverse", "same", "custom", }; const char **iter; assert (sizeof orders / sizeof *orders == DEL_CNT); for (iter = orders; ; iter++) if (iter >= orders + DEL_CNT) fail ("unknownorder\"%s\"", arg); else if (match_len (*iter, arg) >= 3)
{ options-&#62;delete_order = iter - orders; break; } } break; case 'a': if (match_len (arg, "track") >= 3) options-&#62;alloc_policy = MT_TRACK; else if (match_len (arg, "no-track") >= 3) options-&#62;alloc_policy = MT_NO_TRACK; else if (!strncmp (arg, "fail", 3))
{ const char *p = arg + strcspn (arg, "-%"); if (*p == '-')
options-&#62;alloc_policy = MT_FAIL_COUNT; else if (*p == '%')
options-&#62;alloc_policy = MT_FAIL_PERCENT; else
fail ("invalidallocationpolicy\"%s\"", arg); options-&#62;alloc_arg[0] = stoi (p + 1); } else if (!strncmp (arg, "suballoc", 3))
{ const char *p = strchr (arg, '-'); const char *q = strchr (arg, ','); if (p == NULL || q == NULL) fail ("invalidallocationpolicy\"%s\"", arg); options-&#62;alloc_policy = MT_SUBALLOC; options-&#62;alloc_arg[0] = stoi (p + 1); options-&#62;alloc_arg[1] = stoi (q + 1); if (options-&#62;alloc_arg[MT_BLOCK_SIZE] < 32) fail ("blocksizetoosmall"); else if (options-&#62;alloc_arg[MT_ALIGN] > options-&#62;alloc_arg[MT_BLOCK_SIZE]) fail ("alignmentcannotbegreaterthanblocksize"); else if (options-&#62;alloc_arg[MT_ALIGN] < 1) fail ("alignmentmustbeatleast1"); } break; case 'A':
options-&#62;alloc_incr = stoi (arg);
break; case 's': options-&#62;node_cnt = stoi (arg); if (options-&#62;node_cnt < 1) fail ("badtreesize\"%s\"", arg); break; case 'r': options-&#62;iter_cnt = stoi (arg); if (options-&#62;iter_cnt < 1) fail ("badrepeatcount\"%s\"", arg); break; case 'S': options-&#62;seed_given = 1; options-&#62;seed = strtoul (arg, NULL, 0); break; case 'n':
options-&#62;nonstop = 1;
break; case 'q':
options-&#62;verbosity--;
break; case 'v':
options-&#62;verbosity++;
break; case 'h':
usage ();
break; case 'V': fputs ("GNUlibavl2.0.1\n" "Copyright(C)1998-2002FreeSoftwareFoundation,Inc.\n" "ThisprogramcomeswithNOWARRANTY,notevenfor\n" "MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.\n" "Youmayredistributecopiesunderthetermsofthe\n" "GNUGeneralPublicLicense.Formoreinformationon\n" "thesematters,seethefilenamedCOPYING.\n", stdout); exit (EXIT_SUCCESS); default:
assert (0); } } }
This code is included in @refalso{97


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003