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)
561 int c = (
desc == 0 ? 0 : 1);
759 return desc ?
this : 0;
780 return desc ?
this : 0;
804 init(desc_, name_, arg_);
855 return (
Option*) ((
unsigned long long) ptr | 1);
860 return (
Option*) ((
unsigned long long) ptr & ~1ull);
865 return ((
unsigned long long) ptr & 1);
993 Stats(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
994 bool single_minus_longopt =
false) :
997 add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
1002 bool single_minus_longopt =
false) :
1005 add(gnu, usage, argc, (
const char**) argv, min_abbr_len, single_minus_longopt);
1010 bool single_minus_longopt =
false) :
1013 add(
false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1018 bool single_minus_longopt =
false) :
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;
1101 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1) :
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) :
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) :
1120 parse(
false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1125 bool single_minus_longopt =
false,
int bufmax = -1) :
1128 parse(
false, usage, argc, (
const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
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);
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 ==
'=');
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];
1516 Option buffer[],
int min_abbr_len,
bool single_minus_longopt,
int 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)
1536 Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt,
false, min_abbr_len);
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;
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);
1745 template<
typename Function>
1752 (*write)(str,
size);
1766 template<
typename OStream>
1787 template<
typename Temporary>
1809 template<
typename Syscall>
1830 template<
typename Function,
typename Stream>
1853 i1 = (i1 >= i2 ? i1 : i2);
1879 for (
int i = 0; i <
indent; ++i)
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));
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;
2047 while (*
ptr != 0 && *
ptr !=
'\n')
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;
2385 if (utf8width + 2 >
width)
2399 output(write, data, len);
2405 for (i = maxi; i >= 0; --i)
2417 output(write, data, maxi);
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;
2467 const int maxcolumns = 8;
2468 int col_width[maxcolumns];
2471 int overlong_column_threshold = 10000;
2475 for (
int i = 0; i < maxcolumns; ++i)
2483 if (part.
column() < maxcolumns)
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);
2560 if (part.
column() > lastcolumn)
2572 if ((part.
column() < lastcolumn)
2585 LineWrapper& lineWrapper = (part.
column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
2587 if (!print_last_column_on_own_line || part.
column() != lastcolumn)
2592 if (print_last_column_on_own_line)
2597 if (part.
column() == lastcolumn)
2601 indent(write, _, width - rightwidth);
2608 lastColumnLineWrapper.
flush(write);
2609 interjectionLineWrapper.
flush(write);
2814 template<
typename OStream>
2816 int last_column_own_line_max_percent = 75)
2822 template<
typename Function>
2824 int last_column_own_line_max_percent = 75)
2830 template<
typename Temporary>
2832 int last_column_own_line_max_percent = 75)
2838 template<
typename Syscall>
2840 int last_column_own_line_max_percent = 75)
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)
void add(const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
!
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.
Determines the minimum lengths of the buffer and options arrays used for Parser.
const char * data()
Returns the current part of the iteration.
int index() const
Returns Descriptor::index of this Option's Descriptor, or -1 if this Option is invalid (unused)...
int screenLength()
Returns the width in screen columns of the part pointed to by data().
void process(IStringWriter &write, const char *data, int len)
Process, wrap and output the next piece of data.
void add(bool gnu, const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
!
! The argument is acceptable for the option.
bool isLast() const
Returns true iff this is the last element of the linked list.
int count() const
Returns the number of times this Option (or others with the same Descriptor::index) occurs in the arg...
const char ** nonOptions()
Returns a pointer to an array of non-option arguments (only valid if nonOptionsCount() >0 )...
static ArgStatus None(const Option &, bool)
!
LatticeExprNode mask(const LatticeExprNode &expr)
This function returns the mask of the given expression.
static bool instr(char ch, const char *st)
static bool streqabbr(const char *st1, const char *st2, long long min)
const char * help
The usage text associated with the options in this Descriptor.
static bool streq(const char *st1, const char *st2)
int width
The width of the column to line wrap.
static ArgStatus Optional(const Option &option, bool)
!
int line_in_block
Line index within the current cell of the current part.
int screenlen
Length of the current part in screen columns (taking narrow/wide chars into account).
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)
!
Option * next()
Returns a pointer to the next element of the linked list or NULL if called on last().
void update_length()
Determines the byte and character lengths of the part at ptr and stores them in len and screenlen res...
const unsigned index
Index of this option's linked list in the array filled in by the parser.
StreamWriter(Function *w, Stream *s)
int length()
Returns the length of the part pointed to by data() in raw chars (not UTF-8 characters).
! The option does not take an argument.
int nonOptionsCount()
Returns the number of non-option arguments that remained at the end of the most recent parse() that a...
unsigned buffer_max
Number of elements needed for a buffer[] array to be used for parsing the same argument vectors that ...
const Descriptor * tablestart
The 1st descriptor of the current table.
const Option * last() const
const version of Option::last().
static void printUsage(IStringWriter &write, const Descriptor usage[], int width=80, int last_column_min_percent=50, int last_column_own_line_max_percent=75)
static void shift(const char **args, int count)
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
virtual bool finished(int numargs, const char **args)
Called by Parser::workhorse() after finishing the parse.
const char * arg
Pointer to this Option's argument (if any).
TemporaryWriter(const Temporary &u)
Option * nextwrap()
Returns a pointer to the next element of the linked list with wrap-around from last() to first()...
! The argument is not acceptable but that's non-fatal because the option's argument is optional...
const int type
Used to distinguish between options with the same CASA.
CountOptionsAction(unsigned *buffer_max_)
Creates a new CountOptionsAction that will increase *buffer_max_ for each parsed Option.
A parsed option from the command line together with its argument if it has one.
ArgStatus(* CheckArg)(const Option &option, bool msg)
Signature of functions that check if an argument is valid for a certain type of option.
Functions for checking the validity of option arguments.
void output(IStringWriter &write, const char *data, int len)
Writes (data,len) into the ring buffer.
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.
OStreamWriter(OStream &o)
bool perform(Option &option)
Called by Parser::workhorse() for each Option that has been successfully parsed (including unknown op...
int col
Index of current column.
int target_line_in_block
Line index of the parts we should return to the user on this iteration.
const Option * next() const
const version of Option::next().
const CheckArg check_arg
For each option that matches shortopt or longopt this function will be called to check a potential ar...
void buf_store(const char *data, int len)
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)
!
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
void write_one_line(IStringWriter &write)
Writes a single line of output from the buffer to write.
bool hit_target_line
Flag whether we encountered a part with line index target_line_in_block in the current cell...
Parser()
Creates a new Parser.
ABSTRACT CLASSES Deliberately vague to be general enough to allow for many different types of data
Stats()
Creates a Stats object with counts set to 1 (for the sentinel element).
const char *const longopt
The long option name (without the leading – ).
int tail
index for next read - 1 (i.e. increment tail BEFORE read)
Describes an option, its help text (usage) and how it should be parsed.
int optionsCount()
Returns the number of valid Option objects in buffer[].
Option * prev()
Returns a pointer to the previous element of the linked list or NULL if called on first()...
void restartRow()
Reset iteration to the beginning of the current row.
bool nextRow()
Moves iteration to the next row (if any).
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)
!
int line()
Returns the index (counting from 0) of the line within the current column this part belongs to...
static Option * tag(Option *ptr)
int namelen
The length of the option name.
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
LineWrapper(int x1, int x2)
Constructs a LineWrapper that wraps its output to fit into screen columns x1 (incl.) to x2 (excl.).
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
void operator=(const Option &orig)
Makes *this a copy of orig except for the linked list pointers.
Stats(const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
!
StoreOptionAction(Parser &parser_, Option options_[], Option buffer_[], int bufmax_)
Number of slots in buffer. -1 means "large enough".
LinePartIterator(const Descriptor usage[])
!
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)
!
bool write(const std::vector< RegionShape * > &shapes) const
Implements RegionFileWriter::write.
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
bool error()
Returns true if an unrecoverable error occurred while parsing options.
const char * ptr
Ptr to current part within the current row.
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...
Stats(const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
!
const Option * prevwrap() const
const version of Option::prevwrap().
const char * rowstart
Ptr to 1st character of current row within rowdesc->help.
int head
index for next write
const Temporary & userstream
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
int lenbuf[bufmask+1]
Ring buffer for length component of pair (data, length).
void append(Option *new_last)
Makes new_last the new last() by chaining it into the list after last().
const Descriptor * desc
Pointer to this Option's Descriptor.
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...
virtual void operator()(const char *, int)
Writes the given number of chars beginning at the given pointer somewhere.
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)
!
ArgStatus
Possible results when checking if an argument is valid for a certain option.
virtual bool perform(Option &)
Called by Parser::workhorse() for each Option that has been successfully parsed (including unknown op...
Option * first()
Returns a pointer to the first element of the linked list.
void restartTable()
Reset iteration to the beginning of the current table.
static bool isTagged(Option *ptr)
static void indent(IStringWriter &write, int &x, int want_x)
static const int bufmask
Must be a power of 2 minus 1.
bool isFirst() const
Returns true iff this is the first element of the linked list.
static Option * untag(Option *ptr)
! The argument is not acceptable and that's fatal.
const char *const shortopt
Each char in this string will be accepted as a short option character.
int max_line_in_block
Greatest index of a line within the block. This is the number of \v within the cell with the most \vs...
const char * name
The name of the option as used on the command line.
const Double c
Fundamental physical constants (SI units):
Stats(bool gnu, const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
!
const char * datbuf[bufmask+1]
Ring buffer for data component of pair (data, length).
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
void init(const Descriptor *desc_, const char *name_, const char *arg_)
FunctionWriter(Function *w)
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...
int column()
Returns the index (counting from 0) of the column in which the part pointed to by data() is located...
const Descriptor * rowdesc
The Descriptor that contains the current row.
int len
Length of the current part (that ptr points at) in BYTES.
const Option * first() const
const version of Option::first().
bool perform(Option &)
Called by Parser::workhorse() for each Option that has been successfully parsed (including unknown op...
void flush(IStringWriter &write)
Writes out all remaining data from the LineWrapper using write.
SyscallWriter(Syscall *w, int f)
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)
!
static void upmax(int &i1, int i2)
void add(const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
!
bool nextTable()
Moves iteration to the next table (if any).
Option * last()
Returns a pointer to the last element of the linked list.
int type() const
Returns Descriptor::type of this Option's Descriptor, or 0 if this Option is invalid (unused)...
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.
static bool isWideChar(unsigned ch)
Returns true if ch is the unicode code point of a wide character.
bool wrote_something
Multiple methods of LineWrapper may decide to flush part of the buffer to free up space...
const char * nonOption(int i)
Returns nonOptions()[i] (without checking if i is in range!).
static bool workhorse(bool gnu, const Descriptor usage[], int numargs, const char **args, Action &action, bool single_minus_longopt, bool print_errors, int min_abbr_len)
bool finished(int numargs, const char **args)
Called by Parser::workhorse() after finishing the parse.
bool next()
Moves iteration to the next part (if any).
int x
The indentation of the column to which the LineBuffer outputs.
Option()
Creates a new Option that is a one-element linked list and has NULL desc, name, arg and namelen...
Option(const Option &orig)
Makes *this a copy of orig except for the linked list pointers.
Option * prevwrap()
Returns a pointer to the previous element of the linked list with wrap-around from first() to last()...