231 #ifndef OPTIONPARSER_H_
232 #define OPTIONPARSER_H_
241 #pragma intrinsic(_BitScanReverse)
242 struct MSC_Builtin_CLZ
244 static int builtin_clz(
unsigned x)
247 _BitScanReverse(&index, x);
251 #define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x)
302 typedef ArgStatus (*CheckArg)(
const Option& option,
bool msg);
347 const unsigned index;
369 const char*
const shortopt;
404 const char*
const longopt;
416 const CheckArg check_arg;
476 const Descriptor* desc;
546 return desc == 0 ? 0 : desc->type;
555 return desc == 0 ? -1 : desc->index;
572 int c = (desc == 0 ? 0 : 1);
592 return isTagged(prev_);
605 return isTagged(next_);
622 while (!p->isFirst())
645 return first()->prevwrap();
658 return isFirst() ? 0 : prev_;
684 return isLast() ? 0 : next_;
710 void append(Option* new_last)
716 new_last->next_ = tag(f);
717 f->prev_ = tag(new_last);
736 operator const Option*()
const
738 return desc ?
this : 0;
759 return desc ?
this : 0;
767 desc(0), name(0), arg(0), namelen(0)
781 Option(
const Descriptor* desc_,
const char* name_,
const char* arg_)
783 init(desc_, name_, arg_);
792 Option& operator=(
const Option& orig)
794 init(orig.desc, orig.name, orig.arg);
803 Option(
const Option& orig)
805 init(orig.desc, orig.name, orig.arg);
817 void init(
const Descriptor* desc_,
const char* name_,
const char* arg_)
830 while (name[namelen] != 0 && name[namelen] !=
'=')
834 static Option* tag(Option* ptr)
836 return (Option*) ((
unsigned long long) ptr | 1);
839 static Option* untag(Option* ptr)
841 return (Option*) ((
unsigned long long) ptr & ~1ull);
844 static bool isTagged(Option* ptr)
846 return ((
unsigned long long) ptr & 1);
907 static ArgStatus None(
const Option&,
bool)
913 static ArgStatus Optional(
const Option& option,
bool)
915 if (option.arg && option.name[option.namelen] != 0)
955 unsigned options_max;
961 buffer_max(1), options_max(1)
974 Stats(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
975 bool single_minus_longopt =
false) :
976 buffer_max(1), options_max(1)
978 add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
982 Stats(
bool gnu,
const Descriptor usage[],
int argc,
char** argv,
int min_abbr_len = 0,
983 bool single_minus_longopt =
false) :
984 buffer_max(1), options_max(1)
986 add(gnu, usage, argc, const_cast<const char**>(argv), min_abbr_len, single_minus_longopt);
990 Stats(
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
991 bool single_minus_longopt =
false) :
992 buffer_max(1), options_max(1)
994 add(
false, usage, argc, argv, min_abbr_len, single_minus_longopt);
998 Stats(
const Descriptor usage[],
int argc,
char** argv,
int min_abbr_len = 0,
999 bool single_minus_longopt =
false) :
1000 buffer_max(1), options_max(1)
1002 add(
false, usage, argc, const_cast<const char**>(argv), min_abbr_len, single_minus_longopt);
1014 void add(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
1015 bool single_minus_longopt =
false);
1018 void add(
bool gnu,
const Descriptor usage[],
int argc,
char** argv,
int min_abbr_len = 0,
1019 bool single_minus_longopt =
false)
1021 add(gnu, usage, argc, const_cast<const char**>(argv), min_abbr_len, single_minus_longopt);
1025 void add(
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len = 0,
1026 bool single_minus_longopt =
false)
1028 add(
false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1032 void add(
const Descriptor usage[],
int argc,
char** argv,
int min_abbr_len = 0,
1033 bool single_minus_longopt =
false)
1035 add(
false, usage, argc, const_cast<const char**>(argv), min_abbr_len, single_minus_longopt);
1038 class CountOptionsAction;
1065 const char** nonop_args;
1073 op_count(0), nonop_count(0), nonop_args(0), err(false)
1081 Parser(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv, Option options[], Option buffer[],
1082 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1) :
1083 op_count(0), nonop_count(0), nonop_args(0), err(false)
1085 parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1089 Parser(
bool gnu,
const Descriptor usage[],
int argc,
char** argv, Option options[], Option buffer[],
1090 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1) :
1091 op_count(0), nonop_count(0), nonop_args(0), err(false)
1093 parse(gnu, usage, argc, const_cast<const char**>(argv), options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1097 Parser(
const Descriptor usage[],
int argc,
const char** argv, Option options[], Option buffer[],
int min_abbr_len = 0,
1098 bool single_minus_longopt =
false,
int bufmax = -1) :
1099 op_count(0), nonop_count(0), nonop_args(0), err(false)
1101 parse(
false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1105 Parser(
const Descriptor usage[],
int argc,
char** argv, Option options[], Option buffer[],
int min_abbr_len = 0,
1106 bool single_minus_longopt =
false,
int bufmax = -1) :
1107 op_count(0), nonop_count(0), nonop_args(0), err(false)
1109 parse(
false, usage, argc, const_cast<const char**>(argv), options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1168 void parse(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv, Option options[], Option buffer[],
1169 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1);
1172 void parse(
bool gnu,
const Descriptor usage[],
int argc,
char** argv, Option options[], Option buffer[],
1173 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1)
1175 parse(gnu, usage, argc, const_cast<const char**>(argv), options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1179 void parse(
const Descriptor usage[],
int argc,
const char** argv, Option options[], Option buffer[],
1180 int min_abbr_len = 0,
bool single_minus_longopt =
false,
int bufmax = -1)
1182 parse(
false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1186 void parse(
const Descriptor usage[],
int argc,
char** argv, Option options[], Option buffer[],
int min_abbr_len = 0,
1187 bool single_minus_longopt =
false,
int bufmax = -1)
1189 parse(
false, usage, argc, const_cast<const char**>(argv), options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1220 int nonOptionsCount()
1236 const char** nonOptions()
1244 const char* nonOption(
int i)
1246 return nonOptions()[i];
1270 friend struct Stats;
1271 class StoreOptionAction;
1279 static bool workhorse(
bool gnu,
const Descriptor usage[],
int numargs,
const char** args, Action& action,
1280 bool single_minus_longopt,
bool print_errors,
int min_abbr_len);
1296 static bool streq(
const char* st1,
const char* st2)
1299 if (*st1++ != *st2++)
1301 return (*st2 == 0 || *st2 ==
'=');
1328 static bool streqabbr(
const char* st1,
const char* st2,
long long min)
1330 const char* st1start = st1;
1331 while (*st1 != 0 && (*st1 == *st2))
1337 return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 ==
'=');
1346 static bool instr(
char ch,
const char* st)
1348 while (*st != 0 && *st != ch)
1358 static void shift(
const char** args,
int count)
1360 for (
int i = 0; i > -count; --i)
1362 const char* temp = args[i];
1363 args[i] = args[i - 1];
1374 struct Parser::Action
1384 virtual bool perform(Option&)
1397 virtual bool finished(
int numargs,
const char** args)
1404 virtual ~Action() =
default;
1412 class Stats::CountOptionsAction:
public Parser::Action
1414 unsigned* buffer_max;
1420 CountOptionsAction(
unsigned* buffer_max_) :
1421 buffer_max(buffer_max_)
1425 bool perform(Option&)
1427 if (*buffer_max == 0x7fffffff)
1439 class Parser::StoreOptionAction:
public Parser::Action
1453 StoreOptionAction(Parser& parser_, Option options_[], Option buffer_[],
int bufmax_) :
1454 parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)
1458 while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])
1462 parser.op_count = bufidx;
1465 bool perform(Option& option)
1467 if (bufmax < 0 || parser.op_count < bufmax)
1469 if (parser.op_count == 0x7fffffff)
1472 buffer[parser.op_count] = option;
1473 int idx = buffer[parser.op_count].desc->index;
1476 options[idx].append(buffer[parser.op_count]);
1478 options[idx] = buffer[parser.op_count];
1485 bool finished(
int numargs,
const char** args)
1492 parser.nonop_count = numargs;
1493 parser.nonop_args = args;
1500 inline void Parser::parse(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv, Option options[],
1501 Option buffer[],
int min_abbr_len,
bool single_minus_longopt,
int bufmax)
1503 StoreOptionAction action(*
this, options, buffer, bufmax);
1504 err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt,
true, min_abbr_len);
1507 inline void Stats::add(
bool gnu,
const Descriptor usage[],
int argc,
const char** argv,
int min_abbr_len,
1508 bool single_minus_longopt)
1512 while (usage[i].shortopt != 0)
1514 if (usage[i].index + 1 >= options_max)
1515 options_max = (usage[i].index + 1) + 1;
1520 CountOptionsAction action(&buffer_max);
1521 Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt,
false, min_abbr_len);
1524 inline bool Parser::workhorse(
bool gnu,
const Descriptor usage[],
int numargs,
const char** args, Action& action,
1525 bool single_minus_longopt,
bool print_errors,
int min_abbr_len)
1533 while (numargs != 0 && *args != 0)
1535 const char* param = *args;
1539 if (param[0] !=
'-' || param[1] == 0)
1554 if (param[1] ==
'-' && param[2] == 0)
1556 shift(args, nonops);
1563 bool handle_short_options;
1564 const char* longopt_name;
1565 if (param[1] ==
'-')
1567 handle_short_options =
false;
1568 longopt_name = param + 2;
1572 handle_short_options =
true;
1573 longopt_name = param + 1;
1576 bool try_single_minus_longopt = single_minus_longopt;
1577 bool have_more_args = (numargs > 1 || numargs < 0);
1583 const char* optarg=
nullptr;
1586 if (handle_short_options ==
false || try_single_minus_longopt)
1589 while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))
1592 if (usage[idx].longopt == 0 && min_abbr_len > 0)
1595 while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))
1597 if (usage[i1].longopt != 0)
1600 while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))
1603 if (usage[i2].longopt == 0)
1609 if (usage[idx].longopt != 0)
1610 handle_short_options =
false;
1612 try_single_minus_longopt =
false;
1614 optarg = longopt_name;
1615 while (*optarg != 0 && *optarg !=
'=')
1621 optarg = (have_more_args ? args[1] : 0);
1625 if (handle_short_options)
1631 while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))
1635 optarg = (have_more_args ? args[1] : 0);
1641 const Descriptor* descriptor = &usage[idx];
1643 if (descriptor->shortopt == 0)
1647 while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))
1649 descriptor = (usage[idx].shortopt == 0 ? 0 : &usage[idx]);
1652 if (descriptor != 0)
1654 Option option(descriptor, param, optarg);
1655 switch (descriptor->check_arg(option, print_errors))
1661 if (optarg != 0 && have_more_args && optarg == args[1])
1663 shift(args, nonops);
1670 handle_short_options =
false;
1679 if (!action.perform(option))
1683 }
while (handle_short_options);
1685 shift(args, nonops);
1692 if (numargs > 0 && *args == 0)
1698 while (args[numargs] != 0)
1702 return action.finished(numargs + nonops, args - nonops);
1709 struct PrintUsageImplementation
1715 struct IStringWriter
1720 virtual void operator()(
const char*,
int)
1724 virtual ~IStringWriter() =
default;
1732 template<
typename Function>
1733 struct FunctionWriter:
public IStringWriter
1737 virtual void operator()(
const char* str,
int size)
1739 (*write)(str, size);
1742 FunctionWriter(Function* w) :
1753 template<
typename OStream>
1754 struct OStreamWriter:
public IStringWriter
1758 virtual void operator()(
const char* str,
int size)
1760 ostream.write(str, size);
1763 OStreamWriter(OStream& o) :
1774 template<
typename Temporary>
1775 struct TemporaryWriter:
public IStringWriter
1777 const Temporary& userstream;
1779 virtual void operator()(
const char* str,
int size)
1781 userstream.write(str, size);
1784 TemporaryWriter(
const Temporary& u) :
1796 template<
typename Syscall>
1797 struct SyscallWriter:
public IStringWriter
1802 virtual void operator()(
const char* str,
int size)
1804 (*write)(fd, str, size);
1807 SyscallWriter(Syscall* w,
int f) :
1817 template<
typename Function,
typename Stream>
1818 struct StreamWriter:
public IStringWriter
1823 virtual void operator()(
const char* str,
int size)
1825 (*fwrite)(str, size, 1, stream);
1828 StreamWriter(Function* w, Stream* s) :
1829 fwrite(w), stream(s)
1838 static void upmax(
int& i1,
int i2)
1840 i1 = (i1 >= i2 ? i1 : i2);
1854 static void indent(IStringWriter& write,
int& x,
int want_x)
1856 int indent = want_x - x;
1866 for (
int i = 0; i < indent; ++i)
1890 static bool isWideChar(
unsigned ch)
1895 return ((0x1100 <= ch && ch <= 0x115F) || (0x2329 <= ch && ch <= 0x232A) || (0x2E80 <= ch && ch <= 0xA4C6)
1896 || (0xA960 <= ch && ch <= 0xA97C) || (0xAC00 <= ch && ch <= 0xD7FB) || (0xF900 <= ch && ch <= 0xFAFF)
1897 || (0xFE10 <= ch && ch <= 0xFE6B) || (0xFF01 <= ch && ch <= 0xFF60) || (0xFFE0 <= ch && ch <= 0xFFE6)
1898 || (0x1B000 <= ch));
1937 class LinePartIterator
1939 const Descriptor* tablestart;
1940 const Descriptor* rowdesc;
1941 const char* rowstart;
1946 int max_line_in_block;
1948 int target_line_in_block;
1949 bool hit_target_line;
1955 void update_length()
1958 for (len = 0; ptr[len] != 0 && ptr[len] !=
'\v' && ptr[len] !=
'\t' && ptr[len] !=
'\n'; ++len)
1961 unsigned ch = (
unsigned char) ptr[len];
1966 unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
1968 while (((
unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F)
1970 ch = (ch << 6) ^ (
unsigned char) ptr[len + 1] ^ 0x80;
1974 if (ch >= 0x1100 && isWideChar(ch))
1982 LinePartIterator(
const Descriptor usage[]) :
1983 tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), screenlen(0), max_line_in_block(0), line_in_block(0),
1984 target_line_in_block(0), hit_target_line(true)
1999 while (tablestart->help != 0 && tablestart->shortopt != 0)
2004 while (tablestart->help == 0 && tablestart->shortopt != 0)
2008 return rowstart != 0;
2016 rowdesc = tablestart;
2017 rowstart = tablestart->help;
2031 return rowstart != 0;
2034 while (*ptr != 0 && *ptr !=
'\n')
2039 if ((rowdesc + 1)->help == 0)
2043 rowstart = rowdesc->help;
2063 max_line_in_block = 0;
2065 target_line_in_block = 0;
2066 hit_target_line =
true;
2094 upmax(max_line_in_block, ++line_in_block);
2098 if (!hit_target_line)
2101 hit_target_line =
true;
2105 hit_target_line =
false;
2112 if (!hit_target_line)
2115 hit_target_line =
true;
2119 if (++target_line_in_block > max_line_in_block)
2125 hit_target_line =
false;
2135 if (line_in_block == target_line_in_block)
2138 hit_target_line =
true;
2159 return target_line_in_block;
2214 static const int bufmask = 15;
2218 int lenbuf[bufmask + 1];
2222 const char* datbuf[bufmask + 1];
2244 bool wrote_something;
2248 return ((tail + 1) & bufmask) == head;
2253 return tail == head;
2256 void buf_store(
const char* data,
int len)
2259 datbuf[head] = data;
2260 head = (head + 1) & bufmask;
2266 tail = (tail + 1) & bufmask;
2273 void output(IStringWriter& write,
const char* data,
int len)
2276 write_one_line(write);
2278 buf_store(data, len);
2284 void write_one_line(IStringWriter& write)
2286 if (wrote_something)
2290 indent(write, _, x);
2296 write(datbuf[tail], lenbuf[tail]);
2299 wrote_something =
true;
2308 void flush(IStringWriter& write)
2313 indent(write, _, x);
2314 wrote_something =
false;
2315 while (!buf_empty())
2316 write_one_line(write);
2338 void process(IStringWriter& write,
const char* data,
int len)
2340 wrote_something =
false;
2346 output(write, data, len);
2353 while (maxi < len && utf8width < width)
2356 unsigned ch = (
unsigned char) data[maxi];
2361 unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
2363 while ((maxi + charbytes < len) &&
2364 (((
unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F))
2366 ch = (ch << 6) ^ (
unsigned char) data[maxi + charbytes] ^ 0x80;
2370 if (ch >= 0x1100 && isWideChar(ch))
2372 if (utf8width + 2 > width)
2386 output(write, data, len);
2392 for (i = maxi; i >= 0; --i)
2398 output(write, data, i);
2404 output(write, data, maxi);
2411 if (!wrote_something)
2412 write_one_line(write);
2421 LineWrapper(
int x1,
int x2) :
2422 lenbuf(), datbuf(), x(x1), width(x2 - x1), head(0), tail(bufmask), wrote_something(false)
2434 static void printUsage(IStringWriter& write,
const Descriptor usage[],
int width = 80,
2435 int last_column_min_percent = 50,
int last_column_own_line_max_percent = 75)
2443 int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;
2444 int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;
2445 if (last_column_own_line_max_width == 0)
2446 last_column_own_line_max_width = 1;
2448 LinePartIterator part(usage);
2449 while (part.nextTable())
2454 const int maxcolumns = 8;
2455 int col_width[maxcolumns];
2458 int overlong_column_threshold = 10000;
2462 for (
int i = 0; i < maxcolumns; ++i)
2465 part.restartTable();
2466 while (part.nextRow())
2470 if (part.column() < maxcolumns)
2472 upmax(lastcolumn, part.column());
2473 if (part.screenLength() < overlong_column_threshold)
2477 if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] ==
'\t'
2478 || part.data()[part.length()] ==
'\v')
2479 upmax(col_width[part.column()], part.screenLength());
2496 overlong_column_threshold = 0;
2497 for (
int i = 0; i < lastcolumn; ++i)
2499 leftwidth += col_width[i];
2500 upmax(overlong_column_threshold, col_width[i]);
2503 }
while (leftwidth > width);
2507 int tabstop[maxcolumns];
2509 for (
int i = 1; i < maxcolumns; ++i)
2510 tabstop[i] = tabstop[i - 1] + col_width[i - 1];
2512 int rightwidth = width - tabstop[lastcolumn];
2513 bool print_last_column_on_own_line =
false;
2514 if (rightwidth < last_column_min_width && rightwidth < col_width[lastcolumn])
2516 print_last_column_on_own_line =
true;
2517 rightwidth = last_column_own_line_max_width;
2528 if (lastcolumn == 0)
2529 print_last_column_on_own_line =
false;
2531 LineWrapper lastColumnLineWrapper(width - rightwidth, width);
2532 LineWrapper interjectionLineWrapper(0, width);
2534 part.restartTable();
2538 while (part.nextRow())
2543 if (part.column() > lastcolumn)
2546 if (part.column() == 0)
2553 indent(write, x, tabstop[part.column()]);
2555 if ((part.column() < lastcolumn)
2556 && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] ==
'\t'
2557 || part.data()[part.length()] ==
'\v'))
2559 write(part.data(), part.length());
2560 x += part.screenLength();
2568 LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
2570 if (!print_last_column_on_own_line)
2571 lineWrapper.process(write, part.data(), part.length());
2575 if (print_last_column_on_own_line)
2580 if (part.column() == lastcolumn)
2584 indent(write, _, width - rightwidth);
2585 lastColumnLineWrapper.process(write, part.data(), part.length());
2591 lastColumnLineWrapper.flush(write);
2592 interjectionLineWrapper.flush(write);
2797 template<
typename OStream>
2798 void printUsage(OStream& prn,
const Descriptor usage[],
int width = 80,
int last_column_min_percent = 50,
2799 int last_column_own_line_max_percent = 75)
2801 PrintUsageImplementation::OStreamWriter<OStream> write(prn);
2802 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2805 template<
typename Function>
2806 void printUsage(Function* prn,
const Descriptor usage[],
int width = 80,
int last_column_min_percent = 50,
2807 int last_column_own_line_max_percent = 75)
2809 PrintUsageImplementation::FunctionWriter<Function> write(prn);
2810 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2813 template<
typename Temporary>
2814 void printUsage(
const Temporary& prn,
const Descriptor usage[],
int width = 80,
int last_column_min_percent = 50,
2815 int last_column_own_line_max_percent = 75)
2817 PrintUsageImplementation::TemporaryWriter<Temporary> write(prn);
2818 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2821 template<
typename Syscall>
2822 void printUsage(Syscall* prn,
int fd,
const Descriptor usage[],
int width = 80,
int last_column_min_percent = 50,
2823 int last_column_own_line_max_percent = 75)
2825 PrintUsageImplementation::SyscallWriter<Syscall> write(prn, fd);
2826 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2829 template<
typename Function,
typename Stream>
2830 void printUsage(Function* prn, Stream* stream,
const Descriptor usage[],
int width = 80,
int last_column_min_percent =
2832 int last_column_own_line_max_percent = 75)
2834 PrintUsageImplementation::StreamWriter<Function, Stream> write(prn, stream);
2835 PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2838 struct FullArg:
public Arg
2840 static void printError(
const char* msg1,
const option::Option& opt,
const char* msg2)
2842 fprintf(stderr,
"%s", msg1);
2843 fwrite(opt.name, opt.namelen, 1, stderr);
2844 fprintf(stderr,
"%s", msg2);
2847 static option::ArgStatus Unknown(
const option::Option& option,
bool msg)
2849 if (msg) printError(
"Unknown option '", option,
"'\n");
2850 return option::ARG_ILLEGAL;
2853 static option::ArgStatus Required(
const option::Option& option,
bool msg)
2855 if (option.arg != 0)
2856 return option::ARG_OK;
2858 if (msg) printError(
"Option '", option,
"' requires an argument\n");
2859 return option::ARG_ILLEGAL;
2862 static option::ArgStatus NonEmpty(
const option::Option& option,
bool msg)
2864 if (option.arg != 0 && option.arg[0] != 0)
2865 return option::ARG_OK;
2867 if (msg) printError(
"Option '", option,
"' requires a non-empty argument\n");
2868 return option::ARG_ILLEGAL;
2871 static option::ArgStatus Numeric(
const option::Option& option,
bool msg)
2874 if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
2875 if (endptr != option.arg && *endptr == 0)
2876 return option::ARG_OK;
2878 if (msg) printError(
"Option '", option,
"' requires a numeric argument\n");
2879 return option::ARG_ILLEGAL;