218 #ifndef OPTIONPARSER_H_ 219 #define OPTIONPARSER_H_ 223 #pragma intrinsic(_BitScanReverse) 231 struct MSC_Builtin_CLZ
233 static int builtin_clz(
unsigned x)
236 _BitScanReverse(&index, x);
240 #define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x) 535 return desc == 0 ? 0 : desc->
type;
544 return desc == 0 ? -1 : (int)desc->
index;
561 int c = (desc == 0 ? 0 : 1);
562 const Option* p = first();
581 return isTagged(prev_);
594 return isTagged(next_);
621 return const_cast<Option*
>(
this)->first();
663 return isFirst() ? 0 : prev_;
697 return isLast() ? 0 : next_;
705 return isLast() ? 0 : next_;
737 new_last->next_ = tag(f);
738 f->prev_ = tag(new_last);
759 return desc ?
this : 0;
780 return desc ?
this : 0;
788 desc(0), name(0), arg(0), namelen(0)
804 init(desc_, name_, arg_);
836 void init(
const Descriptor* desc_,
const char* name_,
const char* arg_)
849 while (name[namelen] != 0 && name[namelen] !=
'=')
855 return (
Option*) ((
unsigned long long) ptr | 1);
860 return (
Option*) ((
unsigned long long) ptr & ~1ull);
863 static bool isTagged(
Option* ptr)
865 return ((
unsigned long long) ptr & 1);
980 buffer_max(1), options_max(1)
993 Stats(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
994 bool single_minus_longopt =
false) :
995 buffer_max(1), options_max(1)
997 add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
1002 bool single_minus_longopt =
false) :
1003 buffer_max(1), options_max(1)
1005 add(gnu, usage, argc, (
const char**) argv, min_abbr_len, single_minus_longopt);
1010 bool single_minus_longopt =
false) :
1011 buffer_max(1), options_max(1)
1013 add(
false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1018 bool single_minus_longopt =
false) :
1019 buffer_max(1), options_max(1)
1021 add(
false, usage, argc, (
const char**) argv, min_abbr_len, single_minus_longopt);
1033 void add(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
1034 bool single_minus_longopt =
false);
1037 void add(
bool gnu,
const Descriptor usage[],
int argc,
char** argv,
int min_abbr_len = 0,
1038 bool single_minus_longopt =
false)
1040 add(gnu, usage, argc, (
const char**) argv, min_abbr_len, single_minus_longopt);
1044 void add(
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
1045 bool single_minus_longopt =
false)
1047 add(
false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1052 bool single_minus_longopt =
false)
1054 add(
false, usage, argc, (
const char**) argv, min_abbr_len, single_minus_longopt);
1057 class CountOptionsAction;
1084 const char** nonop_args;
1092 op_count(0), nonop_count(0), nonop_args(0), err(false)
1101 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1) :
1102 op_count(0), nonop_count(0), nonop_args(0), err(false)
1104 parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1109 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1) :
1110 op_count(0), nonop_count(0), nonop_args(0), err(false)
1112 parse(gnu, usage, argc, (
const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1117 bool single_minus_longopt =
false,
int bufmax = -1) :
1118 op_count(0), nonop_count(0), nonop_args(0), err(false)
1120 parse(
false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1125 bool single_minus_longopt =
false,
int bufmax = -1) :
1126 op_count(0), nonop_count(0), nonop_args(0), err(false)
1128 parse(
false, usage, argc, (
const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1187 void parse(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv,
Option options[],
Option buffer[],
1188 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1);
1192 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1)
1194 parse(gnu, usage, argc, (
const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1199 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1)
1201 parse(
false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1206 bool single_minus_longopt =
false,
int bufmax = -1)
1208 parse(
false, usage, argc, (
const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1265 return nonOptions()[i];
1289 friend struct Stats;
1290 class StoreOptionAction;
1298 static bool workhorse(
bool gnu,
const Descriptor usage[],
int numargs,
const char** args, Action& action,
1299 bool single_minus_longopt,
bool print_errors,
int min_abbr_len);
1315 static bool streq(
const char* st1,
const char* st2)
1318 if (*st1++ != *st2++)
1320 return (*st2 == 0 || *st2 ==
'=');
1347 static bool streqabbr(
const char* st1,
const char* st2,
long long min)
1349 const char* st1start = st1;
1350 while (*st1 != 0 && (*st1 == *st2))
1356 return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 ==
'=');
1365 static bool instr(
char ch,
const char* st)
1367 while (*st != 0 && *st != ch)
1377 static void shift(
const char** args,
int count)
1379 for (
int i = 0; i > -count; --i)
1381 const char* temp = args[i];
1382 args[i] = args[i - 1];
1393 struct Parser::Action
1403 virtual bool perform(
Option&)
1416 virtual bool finished(
int numargs,
const char** args)
1429 class Stats::CountOptionsAction:
public Parser::Action
1431 unsigned* buffer_max;
1437 CountOptionsAction(
unsigned* buffer_max_) :
1438 buffer_max(buffer_max_)
1444 if (*buffer_max == 0x7fffffff)
1456 class Parser::StoreOptionAction:
public Parser::Action
1470 StoreOptionAction(
Parser& parser_,
Option options_[],
Option buffer_[],
int bufmax_) :
1471 parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)
1475 while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])
1479 parser.op_count = bufidx;
1482 bool perform(
Option& option)
1484 if (bufmax < 0 || parser.op_count < bufmax)
1486 if (parser.op_count == 0x7fffffff)
1489 buffer[parser.op_count] = option;
1490 int idx = buffer[parser.op_count].
desc->
index;
1492 options[idx].
append(buffer[parser.op_count]);
1494 options[idx] = buffer[parser.op_count];
1500 bool finished(
int numargs,
const char** args)
1507 parser.nonop_count = numargs;
1508 parser.nonop_args = args;
1516 Option buffer[],
int min_abbr_len,
bool single_minus_longopt,
int bufmax)
1518 StoreOptionAction action(*
this, options, buffer, bufmax);
1519 err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt,
true, min_abbr_len);
1523 bool single_minus_longopt)
1527 while (usage[i].shortopt != 0)
1529 if (usage[i].index + 1 >= options_max)
1530 options_max = (usage[i].
index + 1) + 1;
1535 CountOptionsAction action(&buffer_max);
1536 Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt,
false, min_abbr_len);
1539 inline bool Parser::workhorse(
bool gnu,
const Descriptor usage[],
int numargs,
const char** args, Action& action,
1540 bool single_minus_longopt,
bool print_errors,
int min_abbr_len)
1548 while (numargs != 0 && *args != 0)
1550 const char* param = *args;
1554 if (param[0] !=
'-' || param[1] == 0)
1569 if (param[1] ==
'-' && param[2] == 0)
1571 shift(args, nonops);
1578 bool handle_short_options;
1579 const char* longopt_name;
1580 if (param[1] ==
'-')
1582 handle_short_options =
false;
1583 longopt_name = param + 2;
1587 handle_short_options =
true;
1588 longopt_name = param + 1;
1591 bool try_single_minus_longopt = single_minus_longopt;
1592 bool have_more_args = (numargs > 1 || numargs < 0);
1598 const char* optarg = 0;
1601 if (handle_short_options ==
false || try_single_minus_longopt)
1604 while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))
1607 if (usage[idx].longopt == 0 && min_abbr_len > 0)
1610 while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))
1612 if (usage[i1].longopt != 0)
1615 while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))
1618 if (usage[i2].longopt == 0)
1624 if (usage[idx].longopt != 0)
1625 handle_short_options =
false;
1627 try_single_minus_longopt =
false;
1629 optarg = longopt_name;
1630 while (*optarg != 0 && *optarg !=
'=')
1636 optarg = (have_more_args ? args[1] : 0);
1640 if (handle_short_options)
1646 while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))
1650 optarg = (have_more_args ? args[1] : 0);
1662 while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))
1664 descriptor = (usage[idx].
shortopt == 0 ? 0 : &usage[idx]);
1667 if (descriptor != 0)
1669 Option option(descriptor, param, optarg);
1670 switch (descriptor->
check_arg(option, print_errors))
1676 if (optarg != 0 && have_more_args && optarg == args[1])
1678 shift(args, nonops);
1685 handle_short_options =
false;
1694 if (!action.perform(option))
1698 }
while (handle_short_options);
1700 shift(args, nonops);
1707 if (numargs > 0 && *args == 0)
1713 while (args[numargs] != 0)
1717 return action.finished(numargs + nonops, args - nonops);
1724 struct PrintUsageImplementation
1730 struct IStringWriter
1735 virtual void operator()(
const char*,
int)
1745 template<
typename Function>
1746 struct FunctionWriter:
public IStringWriter
1750 virtual void operator()(
const char* str,
int size)
1752 (*write)(str, size);
1755 FunctionWriter(Function* w) :
1766 template<
typename OStream>
1767 struct OStreamWriter:
public IStringWriter
1771 virtual void operator()(
const char* str,
int size)
1773 ostream.write(str, size);
1776 OStreamWriter(OStream& o) :
1787 template<
typename Temporary>
1788 struct TemporaryWriter:
public IStringWriter
1790 const Temporary& userstream;
1792 virtual void operator()(
const char* str,
int size)
1794 userstream.write(str, size);
1797 TemporaryWriter(
const Temporary& u) :
1809 template<
typename Syscall>
1810 struct SyscallWriter:
public IStringWriter
1815 virtual void operator()(
const char* str,
int size)
1817 (*write)(fd, str, size);
1820 SyscallWriter(Syscall* w,
int f) :
1830 template<
typename Function,
typename Stream>
1831 struct StreamWriter:
public IStringWriter
1836 virtual void operator()(
const char* str,
int size)
1838 (*fwrite)(str, size, 1, stream);
1841 StreamWriter(Function* w, Stream* s) :
1842 fwrite(w), stream(s)
1851 static void upmax(
int& i1,
int i2)
1853 i1 = (i1 >= i2 ? i1 : i2);
1867 static void indent(IStringWriter& write,
int& x,
int want_x)
1869 int indent = want_x - x;
1879 for (
int i = 0; i < indent; ++i)
1903 static bool isWideChar(
unsigned ch)
1908 return ((0x1100 <= ch && ch <= 0x115F) || (0x2329 <= ch && ch <= 0x232A) || (0x2E80 <= ch && ch <= 0xA4C6)
1909 || (0xA960 <= ch && ch <= 0xA97C) || (0xAC00 <= ch && ch <= 0xD7FB) || (0xF900 <= ch && ch <= 0xFAFF)
1910 || (0xFE10 <= ch && ch <= 0xFE6B) || (0xFF01 <= ch && ch <= 0xFF60) || (0xFFE0 <= ch && ch <= 0xFFE6)
1911 || (0x1B000 <= ch));
1950 class LinePartIterator
1954 const char* rowstart;
1959 int max_line_in_block;
1961 int target_line_in_block;
1962 bool hit_target_line;
1968 void update_length()
1971 for (len = 0; ptr[len] != 0 && ptr[len] !=
'\v' && ptr[len] !=
'\t' && ptr[len] !=
'\n'; ++len)
1974 unsigned ch = (
unsigned char) ptr[len];
1979 unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
1981 while (((
unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F)
1983 ch = (ch << 6) ^ (
unsigned char) ptr[len + 1] ^ 0x80;
1987 if (ch >= 0x1100 && isWideChar(ch))
1996 tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), max_line_in_block(0), line_in_block(0),
1997 target_line_in_block(0), hit_target_line(
true)
2012 while (tablestart->
help != 0 && tablestart->
shortopt != 0)
2017 while (tablestart->
help == 0 && tablestart->
shortopt != 0)
2021 return rowstart != 0;
2029 rowdesc = tablestart;
2030 rowstart = tablestart->
help;
2044 return rowstart != 0;
2047 while (*ptr != 0 && *ptr !=
'\n')
2052 if ((rowdesc + 1)->help == 0)
2056 rowstart = rowdesc->
help;
2076 max_line_in_block = 0;
2078 target_line_in_block = 0;
2079 hit_target_line =
true;
2107 upmax(max_line_in_block, ++line_in_block);
2111 if (!hit_target_line)
2114 hit_target_line =
true;
2118 hit_target_line =
false;
2125 if (!hit_target_line)
2128 hit_target_line =
true;
2132 if (++target_line_in_block > max_line_in_block)
2138 hit_target_line =
false;
2148 if (line_in_block == target_line_in_block)
2151 hit_target_line =
true;
2172 return target_line_in_block;
2227 static const int bufmask = 15;
2231 int lenbuf[bufmask + 1];
2235 const char* datbuf[bufmask + 1];
2257 bool wrote_something;
2261 return ((tail + 1) & bufmask) == head;
2266 return tail == head;
2269 void buf_store(
const char* data,
int len)
2272 datbuf[head] = data;
2273 head = (head + 1) & bufmask;
2279 tail = (tail + 1) & bufmask;
2286 void output(IStringWriter& write,
const char* data,
int len)
2289 write_one_line(write);
2291 buf_store(data, len);
2297 void write_one_line(IStringWriter& write)
2299 if (wrote_something)
2303 indent(write, _, x);
2309 write(datbuf[tail], lenbuf[tail]);
2312 wrote_something =
true;
2321 void flush(IStringWriter& write)
2326 indent(write, _, x);
2327 wrote_something =
false;
2328 while (!buf_empty())
2329 write_one_line(write);
2351 void process(IStringWriter& write,
const char* data,
int len)
2353 wrote_something =
false;
2359 output(write, data, len);
2366 while (maxi < len && utf8width < width)
2369 unsigned ch = (
unsigned char) data[maxi];
2374 unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
2376 while ((maxi + charbytes < len) &&
2377 (((
unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F))
2379 ch = (ch << 6) ^ (
unsigned char) data[maxi + charbytes] ^ 0x80;
2383 if (ch >= 0x1100 && isWideChar(ch))
2385 if (utf8width + 2 > width)
2399 output(write, data, len);
2405 for (i = maxi; i >= 0; --i)
2411 output(write, data, i);
2417 output(write, data, maxi);
2424 if (!wrote_something)
2425 write_one_line(write);
2434 LineWrapper(
int x1,
int x2) :
2435 x(x1), width(x2 - x1), head(0), tail(bufmask)
2448 int last_column_min_percent = 50,
int last_column_own_line_max_percent = 75)
2456 int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;
2457 int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;
2458 if (last_column_own_line_max_width == 0)
2459 last_column_own_line_max_width = 1;
2461 LinePartIterator part(usage);
2462 while (part.nextTable())
2467 const int maxcolumns = 8;
2468 int col_width[maxcolumns];
2471 int overlong_column_threshold = 10000;
2475 for (
int i = 0; i < maxcolumns; ++i)
2478 part.restartTable();
2479 while (part.nextRow())
2483 if (part.column() < maxcolumns)
2485 upmax(lastcolumn, part.column());
2486 if (part.screenLength() < overlong_column_threshold)
2490 if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] ==
'\t' 2491 || part.data()[part.length()] ==
'\v')
2492 upmax(col_width[part.column()], part.screenLength());
2509 overlong_column_threshold = 0;
2510 for (
int i = 0; i < lastcolumn; ++i)
2512 leftwidth += col_width[i];
2513 upmax(overlong_column_threshold, col_width[i]);
2516 }
while (leftwidth > width);
2520 int tabstop[maxcolumns];
2522 for (
int i = 1; i < maxcolumns; ++i)
2523 tabstop[i] = tabstop[i - 1] + col_width[i - 1];
2525 int rightwidth = width - tabstop[lastcolumn];
2526 bool print_last_column_on_own_line =
false;
2527 if (rightwidth < last_column_min_width &&
2528 ( col_width[lastcolumn] == 0 ||
2529 rightwidth < col_width[lastcolumn]
2533 print_last_column_on_own_line =
true;
2534 rightwidth = last_column_own_line_max_width;
2545 if (lastcolumn == 0)
2546 print_last_column_on_own_line =
false;
2548 LineWrapper lastColumnLineWrapper(width - rightwidth, width);
2549 LineWrapper interjectionLineWrapper(0, width);
2551 part.restartTable();
2555 while (part.nextRow())
2560 if (part.column() > lastcolumn)
2563 if (part.column() == 0)
2570 indent(write, x, tabstop[part.column()]);
2572 if ((part.column() < lastcolumn)
2573 && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] ==
'\t' 2574 || part.data()[part.length()] ==
'\v'))
2576 write(part.data(), part.length());
2577 x += part.screenLength();
2585 LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
2587 if (!print_last_column_on_own_line || part.column() != lastcolumn)
2588 lineWrapper.process(write, part.data(), part.length());
2592 if (print_last_column_on_own_line)
2597 if (part.column() == lastcolumn)
2601 indent(write, _, width - rightwidth);
2602 lastColumnLineWrapper.process(write, part.data(), part.length());
2608 lastColumnLineWrapper.flush(write);
2609 interjectionLineWrapper.flush(write);
2814 template<
typename OStream>
2816 int last_column_own_line_max_percent = 75)
2818 PrintUsageImplementation::OStreamWriter<OStream> write(prn);
2819 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2822 template<
typename Function>
2823 void printUsage(Function* prn,
const Descriptor usage[],
int width = 80,
int last_column_min_percent = 50,
2824 int last_column_own_line_max_percent = 75)
2826 PrintUsageImplementation::FunctionWriter<Function> write(prn);
2827 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2830 template<
typename Temporary>
2831 void printUsage(
const Temporary& prn,
const Descriptor usage[],
int width = 80,
int last_column_min_percent = 50,
2832 int last_column_own_line_max_percent = 75)
2834 PrintUsageImplementation::TemporaryWriter<Temporary> write(prn);
2835 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2838 template<
typename Syscall>
2839 void printUsage(Syscall* prn,
int fd,
const Descriptor usage[],
int width = 80,
int last_column_min_percent = 50,
2840 int last_column_own_line_max_percent = 75)
2842 PrintUsageImplementation::SyscallWriter<Syscall> write(prn, fd);
2843 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2846 template<
typename Function,
typename Stream>
2847 void printUsage(Function* prn, Stream* stream,
const Descriptor usage[],
int width = 80,
int last_column_min_percent =
2849 int last_column_own_line_max_percent = 75)
2851 PrintUsageImplementation::StreamWriter<Function, Stream> write(prn, stream);
2852 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
Determines the minimum lengths of the buffer and options arrays used for Parser.
Option(const Option &orig)
Makes *this a copy of orig except for the linked list pointers.
void add(const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX add() (gnu==false).
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
void operator=(const Option &orig)
Makes *this a copy of orig except for the linked list pointers.
bool error()
Returns true if an unrecoverable error occurred while parsing options.
const Option * last() const
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
Option * nextwrap()
Returns a pointer to the next element of the linked list with wrap-around from last() to first()...
const char *const shortopt
Each char in this string will be accepted as a short option character.
const char * help
The usage text associated with the options in this Descriptor.
Parser(bool gnu, const Descriptor usage[], int argc, const char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
Creates a new Parser and immediately parses the given argument vector.
Stats(bool gnu, const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
Stats(...) with non-const argv.
void parse(const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX parse() (gnu==false) with non-const argv.
Option(const Descriptor *desc_, const char *name_, const char *arg_)
Creates a new Option that is a one-element linked list and has the given values for desc...
const char *const longopt
The long option name (without the leading – ).
const char * name
The name of the option as used on the command line.
bool isLast() const
Returns true iff this is the last element of the linked list.
int nonOptionsCount()
Returns the number of non-option arguments that remained at the end of the most recent parse() that a...
Parser(bool gnu, const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
Parser(...) with non-const argv.
void add(bool gnu, const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
Updates this Stats object for the given usage and argument vector. You may pass 0 for argc and/or arg...
bool isFirst() const
Returns true iff this is the first element of the linked list.
const char * nonOption(int i)
Returns nonOptions()[i] (without checking if i is in range!).
A parsed option from the command line together with its argument if it has one.
Functions for checking the validity of option arguments.
const unsigned index
Index of this option's linked list in the array filled in by the parser.
Option * next()
Returns a pointer to the next element of the linked list or NULL if called on last().
const CheckArg check_arg
For each option that matches shortopt or longopt this function will be called to check a potential ar...
void append(Option *new_last)
Makes new_last the new last() by chaining it into the list after last().
void add(const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX add() (gnu==false) with non-const argv.
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
const char ** nonOptions()
Returns a pointer to an array of non-option arguments (only valid if nonOptionsCount() >0 )...
Option()
Creates a new Option that is a one-element linked list and has NULL desc, name, arg and namelen...
Option * prevwrap()
Returns a pointer to the previous element of the linked list with wrap-around from first() to last()...
Describes an option, its help text (usage) and how it should be parsed.
Stats(bool gnu, const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
Creates a new Stats object and immediately updates it for the given usage and argument vector...
const int type
Used to distinguish between options with the same index. See index for details.
void parse(const Descriptor usage[], int argc, const char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX parse() (gnu==false).
int index() const
Returns Descriptor::index of this Option's Descriptor, or -1 if this Option is invalid (unused)...
The argument is acceptable for the option.
The namespace of The Lean Mean C++ Option Parser.
const char * arg
Pointer to this Option's argument (if any).
int optionsCount()
Returns the number of valid Option objects in buffer[].
int type() const
Returns Descriptor::type of this Option's Descriptor, or 0 if this Option is invalid (unused)...
static ArgStatus Optional(const Option &option, bool)
Returns ARG_OK if the argument is attached and ARG_IGNORE otherwise.
void parse(bool gnu, const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
parse() with non-const argv.
Option * first()
Returns a pointer to the first element of the linked list.
ArgStatus(* CheckArg)(const Option &option, bool msg)
Signature of functions that check if an argument is valid for a certain type of option.
int count() const
Returns the number of times this Option (or others with the same Descriptor::index) occurs in the arg...
int namelen
The length of the option name.
const Option * prevwrap() const
Stats(const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX Stats(...) (gnu==false).
Parser()
Creates a new Parser.
void add(bool gnu, const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
add() with non-const argv.
Option * last()
Returns a pointer to the last element of the linked list.
unsigned buffer_max
Number of elements needed for a buffer[] array to be used for parsing the same argument vectors that ...
The argument is not acceptable and that's fatal.
The option does not take an argument.
const Option * first() const
Stats(const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX Stats(...) (gnu==false) with non-const argv.
Parser(const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX Parser(...) (gnu==false) with non-const argv.
Stats()
Creates a Stats object with counts set to 1 (for the sentinel element).
void printUsage(OStream &prn, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
Outputs a nicely formatted usage string with support for multi-column formatting and line-wrapping...
Option * prev()
Returns a pointer to the previous element of the linked list or NULL if called on first()...
const Descriptor * desc
Pointer to this Option's Descriptor.
const Option * next() const
The argument is not acceptable but that's non-fatal because the option's argument is optional...
ArgStatus
Possible results when checking if an argument is valid for a certain option.
Parser(const Descriptor usage[], int argc, const char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX Parser(...) (gnu==false).
void parse(bool gnu, const Descriptor usage[], int argc, const char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
Parses the given argument vector.