casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
optionparser.h
Go to the documentation of this file.
1 /*
2  * The Lean Mean C++ Option Parser
3  *
4  * Copyright (C) 2012-2017 Matthias S. Benkmann
5  *
6  * The "Software" in the following 2 paragraphs refers to this file containing
7  * the code to The Lean Mean C++ Option Parser.
8  * The "Software" does NOT refer to any other files which you
9  * may have received alongside this file (e.g. as part of a larger project that
10  * incorporates The Lean Mean C++ Option Parser).
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a copy
13  * of this software, to deal in the Software without restriction, including
14  * without limitation the rights to use, copy, modify, merge, publish,
15  * distribute, sublicense, and/or sell copies of the Software, and to permit
16  * persons to whom the Software is furnished to do so, subject to the following
17  * conditions:
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  */
29 
30 /*
31  * NOTE: It is recommended that you read the processed HTML doxygen documentation
32  * rather than this source. If you don't know doxygen, it's like javadoc for C++.
33  * If you don't want to install doxygen you can find a copy of the processed
34  * documentation at
35  *
36  * http://optionparser.sourceforge.net/
37  *
38  */
39 
218 #ifndef OPTIONPARSER_H_
219 #define OPTIONPARSER_H_
220 
221 #ifdef _MSC_VER
222 #include <intrin.h>
223 #pragma intrinsic(_BitScanReverse)
224 #endif
225 
227 namespace option
228 {
229 
230 #ifdef _MSC_VER
231 struct MSC_Builtin_CLZ
232 {
233  static int builtin_clz(unsigned x)
234  {
235  unsigned long index;
236  _BitScanReverse(&index, x);
237  return 32-index; // int is always 32bit on Windows, even for target x64
238  }
239 };
240 #define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x)
241 #endif
242 
243 class Option;
244 
252 {
261 };
262 
291 typedef ArgStatus (*CheckArg)(const Option& option, bool msg);
292 
316 {
336  const unsigned index;
337 
345  const int type;
346 
358  const char* const shortopt;
359 
393  const char* const longopt;
394 
406 
422  const char* help;
423 };
424 
442 class Option
443 {
446 public:
465  const Descriptor* desc;
466 
481  const char* name;
482 
489  const char* arg;
490 
510  int namelen;
511 
533  int type() const
534  {
535  return desc == 0 ? 0 : desc->type;
536  }
537 
542  int index() const
543  {
544  return desc == 0 ? -1 : (int)desc->index;
545  }
546 
559  int count() const
560  {
561  int c = (desc == 0 ? 0 : 1);
562  const Option* p = first();
563  while (!p->isLast())
564  {
565  ++c;
566  p = p->next_;
567  };
568  return c;
569  }
570 
579  bool isFirst() const
580  {
581  return isTagged(prev_);
582  }
583 
592  bool isLast() const
593  {
594  return isTagged(next_);
595  }
596 
609  {
610  Option* p = this;
611  while (!p->isFirst())
612  p = p->prev_;
613  return p;
614  }
615 
619  const Option* first() const
620  {
621  return const_cast<Option*>(this)->first();
622  }
623 
641  {
642  return first()->prevwrap();
643  }
644 
648  const Option* last() const
649  {
650  return first()->prevwrap();
651  }
652 
662  {
663  return isFirst() ? 0 : prev_;
664  }
665 
675  {
676  return untag(prev_);
677  }
678 
682  const Option* prevwrap() const
683  {
684  return untag(prev_);
685  }
686 
696  {
697  return isLast() ? 0 : next_;
698  }
699 
703  const Option* next() const
704  {
705  return isLast() ? 0 : next_;
706  }
707 
717  {
718  return untag(next_);
719  }
720 
731  void append(Option* new_last)
732  {
733  Option* p = last();
734  Option* f = first();
735  p->next_ = new_last;
736  new_last->prev_ = p;
737  new_last->next_ = tag(f);
738  f->prev_ = tag(new_last);
739  }
740 
757  operator const Option*() const
758  {
759  return desc ? this : 0;
760  }
761 
778  operator Option*()
779  {
780  return desc ? this : 0;
781  }
782 
787  Option() :
788  desc(0), name(0), arg(0), namelen(0)
789  {
790  prev_ = tag(this);
791  next_ = tag(this);
792  }
793 
802  Option(const Descriptor* desc_, const char* name_, const char* arg_)
803  {
804  init(desc_, name_, arg_);
805  }
806 
812  void operator=(const Option& orig)
813  {
814  init(orig.desc, orig.name, orig.arg);
815  }
816 
822  Option(const Option& orig)
823  {
824  init(orig.desc, orig.name, orig.arg);
825  }
826 
827 private:
836  void init(const Descriptor* desc_, const char* name_, const char* arg_)
837  {
838  desc = desc_;
839  name = name_;
840  arg = arg_;
841  prev_ = tag(this);
842  next_ = tag(this);
843  namelen = 0;
844  if (name == 0)
845  return;
846  namelen = 1;
847  if (name[0] != '-')
848  return;
849  while (name[namelen] != 0 && name[namelen] != '=')
850  ++namelen;
851  }
852 
853  static Option* tag(Option* ptr)
854  {
855  return (Option*) ((unsigned long long) ptr | 1);
856  }
857 
858  static Option* untag(Option* ptr)
859  {
860  return (Option*) ((unsigned long long) ptr & ~1ull);
861  }
862 
863  static bool isTagged(Option* ptr)
864  {
865  return ((unsigned long long) ptr & 1);
866  }
867 };
868 
923 struct Arg
924 {
926  static ArgStatus None(const Option&, bool)
927  {
928  return ARG_NONE;
929  }
930 
932  static ArgStatus Optional(const Option& option, bool)
933  {
934  if (option.arg && option.name[option.namelen] != 0)
935  return ARG_OK;
936  else
937  return ARG_IGNORE;
938  }
939 };
940 
950 struct Stats
951 {
961  unsigned buffer_max;
962 
974  unsigned options_max;
975 
979  Stats() :
980  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
981  {
982  }
983 
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) // 1 more than necessary as sentinel
996  {
997  add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
998  }
999 
1001  Stats(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1002  bool single_minus_longopt = false) :
1003  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
1004  {
1005  add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1006  }
1007 
1009  Stats(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1010  bool single_minus_longopt = false) :
1011  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
1012  {
1013  add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1014  }
1015 
1017  Stats(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1018  bool single_minus_longopt = false) :
1019  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
1020  {
1021  add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1022  }
1023 
1033  void add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1034  bool single_minus_longopt = false);
1035 
1037  void add(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1038  bool single_minus_longopt = false)
1039  {
1040  add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1041  }
1042 
1044  void add(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1045  bool single_minus_longopt = false)
1046  {
1047  add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1048  }
1049 
1051  void add(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1052  bool single_minus_longopt = false)
1053  {
1054  add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1055  }
1056 private:
1057  class CountOptionsAction;
1058 };
1059 
1080 class Parser
1081 {
1082  int op_count;
1084  const char** nonop_args;
1085  bool err;
1086 public:
1087 
1092  op_count(0), nonop_count(0), nonop_args(0), err(false)
1093  {
1094  }
1095 
1100  Parser(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
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)
1103  {
1104  parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1105  }
1106 
1108  Parser(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
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)
1111  {
1112  parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1113  }
1114 
1116  Parser(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1117  bool single_minus_longopt = false, int bufmax = -1) :
1118  op_count(0), nonop_count(0), nonop_args(0), err(false)
1119  {
1120  parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1121  }
1122 
1124  Parser(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1125  bool single_minus_longopt = false, int bufmax = -1) :
1126  op_count(0), nonop_count(0), nonop_args(0), err(false)
1127  {
1128  parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1129  }
1130 
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);
1189 
1191  void parse(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
1192  int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
1193  {
1194  parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1195  }
1196 
1198  void parse(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
1199  int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
1200  {
1201  parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1202  }
1203 
1205  void parse(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1206  bool single_minus_longopt = false, int bufmax = -1)
1207  {
1208  parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1209  }
1210 
1221  {
1222  return op_count;
1223  }
1224 
1240  {
1241  return nonop_count;
1242  }
1243 
1255  const char** nonOptions()
1256  {
1257  return nonop_args;
1258  }
1259 
1263  const char* nonOption(int i)
1264  {
1265  return nonOptions()[i];
1266  }
1267 
1283  bool error()
1284  {
1285  return err;
1286  }
1287 
1288 private:
1289  friend struct Stats;
1290  class StoreOptionAction;
1291  struct Action;
1292 
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);
1300 
1315  static bool streq(const char* st1, const char* st2)
1316  {
1317  while (*st1 != 0)
1318  if (*st1++ != *st2++)
1319  return false;
1320  return (*st2 == 0 || *st2 == '=');
1321  }
1322 
1347  static bool streqabbr(const char* st1, const char* st2, long long min)
1348  {
1349  const char* st1start = st1;
1350  while (*st1 != 0 && (*st1 == *st2))
1351  {
1352  ++st1;
1353  ++st2;
1354  }
1355 
1356  return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 == '=');
1357  }
1358 
1365  static bool instr(char ch, const char* st)
1366  {
1367  while (*st != 0 && *st != ch)
1368  ++st;
1369  return *st == ch;
1370  }
1371 
1377  static void shift(const char** args, int count)
1378  {
1379  for (int i = 0; i > -count; --i)
1380  {
1381  const char* temp = args[i];
1382  args[i] = args[i - 1];
1383  args[i - 1] = temp;
1384  }
1385  }
1386 };
1387 
1394 {
1403  virtual bool perform(Option&)
1404  {
1405  return true;
1406  }
1407 
1416  virtual bool finished(int numargs, const char** args)
1417  {
1418  (void) numargs;
1419  (void) args;
1420  return true;
1421  }
1422 };
1423 
1430 {
1431  unsigned* buffer_max;
1432 public:
1437  CountOptionsAction(unsigned* buffer_max_) :
1438  buffer_max(buffer_max_)
1439  {
1440  }
1441 
1443  {
1444  if (*buffer_max == 0x7fffffff)
1445  return false; // overflow protection: don't accept number of options that doesn't fit signed int
1446  ++*buffer_max;
1447  return true;
1448  }
1449 };
1450 
1457 {
1461  int bufmax;
1462 public:
1470  StoreOptionAction(Parser& parser_, Option options_[], Option buffer_[], int bufmax_) :
1471  parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)
1472  {
1473  // find first empty slot in buffer (if any)
1474  int bufidx = 0;
1475  while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])
1476  ++bufidx;
1477 
1478  // set parser's optionCount
1479  parser.op_count = bufidx;
1480  }
1481 
1482  bool perform(Option& option)
1483  {
1484  if (bufmax < 0 || parser.op_count < bufmax)
1485  {
1486  if (parser.op_count == 0x7fffffff)
1487  return false; // overflow protection: don't accept number of options that doesn't fit signed int
1488 
1489  buffer[parser.op_count] = option;
1490  int idx = buffer[parser.op_count].desc->index;
1491  if (options[idx])
1493  else
1494  options[idx] = buffer[parser.op_count];
1495  ++parser.op_count;
1496  }
1497  return true; // NOTE: an option that is discarded because of a full buffer is not fatal
1498  }
1499 
1500  bool finished(int numargs, const char** args)
1501  {
1502  // only overwrite non-option argument list if there's at least 1
1503  // new non-option argument. Otherwise we keep the old list. This
1504  // makes it easy to use default non-option arguments.
1505  if (numargs > 0)
1506  {
1507  parser.nonop_count = numargs;
1508  parser.nonop_args = args;
1509  }
1510 
1511  return true;
1512  }
1513 };
1514 
1515 inline void Parser::parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[],
1516  Option buffer[], int min_abbr_len, bool single_minus_longopt, int bufmax)
1517 {
1518  StoreOptionAction action(*this, options, buffer, bufmax);
1519  err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt, true, min_abbr_len);
1520 }
1521 
1522 inline void Stats::add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len,
1523  bool single_minus_longopt)
1524 {
1525  // determine size of options array. This is the greatest index used in the usage + 1
1526  int i = 0;
1527  while (usage[i].shortopt != 0)
1528  {
1529  if (usage[i].index + 1 >= options_max)
1530  options_max = (usage[i].index + 1) + 1; // 1 more than necessary as sentinel
1531 
1532  ++i;
1533  }
1534 
1535  CountOptionsAction action(&buffer_max);
1536  Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt, false, min_abbr_len);
1537 }
1538 
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)
1541 {
1542  // protect against NULL pointer
1543  if (args == 0)
1544  numargs = 0;
1545 
1546  int nonops = 0;
1547 
1548  while (numargs != 0 && *args != 0)
1549  {
1550  const char* param = *args; // param can be --long-option, -srto or non-option argument
1551 
1552  // in POSIX mode the first non-option argument terminates the option list
1553  // a lone minus character is a non-option argument
1554  if (param[0] != '-' || param[1] == 0)
1555  {
1556  if (gnu)
1557  {
1558  ++nonops;
1559  ++args;
1560  if (numargs > 0)
1561  --numargs;
1562  continue;
1563  }
1564  else
1565  break;
1566  }
1567 
1568  // -- terminates the option list. The -- itself is skipped.
1569  if (param[1] == '-' && param[2] == 0)
1570  {
1571  shift(args, nonops);
1572  ++args;
1573  if (numargs > 0)
1574  --numargs;
1575  break;
1576  }
1577 
1578  bool handle_short_options;
1579  const char* longopt_name;
1580  if (param[1] == '-') // if --long-option
1581  {
1582  handle_short_options = false;
1583  longopt_name = param + 2;
1584  }
1585  else
1586  {
1587  handle_short_options = true;
1588  longopt_name = param + 1; //for testing a potential -long-option
1589  }
1590 
1591  bool try_single_minus_longopt = single_minus_longopt;
1592  bool have_more_args = (numargs > 1 || numargs < 0); // is referencing argv[1] valid?
1593 
1594  do // loop over short options in group, for long options the body is executed only once
1595  {
1596  int idx = 0;
1597 
1598  const char* optarg = 0;
1599 
1600  /******************** long option **********************/
1601  if (handle_short_options == false || try_single_minus_longopt)
1602  {
1603  idx = 0;
1604  while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))
1605  ++idx;
1606 
1607  if (usage[idx].longopt == 0 && min_abbr_len > 0) // if we should try to match abbreviated long options
1608  {
1609  int i1 = 0;
1610  while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))
1611  ++i1;
1612  if (usage[i1].longopt != 0)
1613  { // now test if the match is unambiguous by checking for another match
1614  int i2 = i1 + 1;
1615  while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))
1616  ++i2;
1617 
1618  if (usage[i2].longopt == 0) // if there was no second match it's unambiguous, so accept i1 as idx
1619  idx = i1;
1620  }
1621  }
1622 
1623  // if we found something, disable handle_short_options (only relevant if single_minus_longopt)
1624  if (usage[idx].longopt != 0)
1625  handle_short_options = false;
1626 
1627  try_single_minus_longopt = false; // prevent looking for longopt in the middle of shortopt group
1628 
1629  optarg = longopt_name;
1630  while (*optarg != 0 && *optarg != '=')
1631  ++optarg;
1632  if (*optarg == '=') // attached argument
1633  ++optarg;
1634  else
1635  // possibly detached argument
1636  optarg = (have_more_args ? args[1] : 0);
1637  }
1638 
1639  /************************ short option ***********************************/
1640  if (handle_short_options)
1641  {
1642  if (*++param == 0) // point at the 1st/next option character
1643  break; // end of short option group
1644 
1645  idx = 0;
1646  while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))
1647  ++idx;
1648 
1649  if (param[1] == 0) // if the potential argument is separate
1650  optarg = (have_more_args ? args[1] : 0);
1651  else
1652  // if the potential argument is attached
1653  optarg = param + 1;
1654  }
1655 
1656  const Descriptor* descriptor = &usage[idx];
1657 
1658  if (descriptor->shortopt == 0) /************** unknown option ********************/
1659  {
1660  // look for dummy entry (shortopt == "" and longopt == "") to use as Descriptor for unknown options
1661  idx = 0;
1662  while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))
1663  ++idx;
1664  descriptor = (usage[idx].shortopt == 0 ? 0 : &usage[idx]);
1665  }
1666 
1667  if (descriptor != 0)
1668  {
1669  Option option(descriptor, param, optarg);
1670  switch (descriptor->check_arg(option, print_errors))
1671  {
1672  case ARG_ILLEGAL:
1673  return false; // fatal
1674  case ARG_OK:
1675  // skip one element of the argument vector, if it's a separated argument
1676  if (optarg != 0 && have_more_args && optarg == args[1])
1677  {
1678  shift(args, nonops);
1679  if (numargs > 0)
1680  --numargs;
1681  ++args;
1682  }
1683 
1684  // No further short options are possible after an argument
1685  handle_short_options = false;
1686 
1687  break;
1688  case ARG_IGNORE:
1689  case ARG_NONE:
1690  option.arg = 0;
1691  break;
1692  }
1693 
1694  if (!action.perform(option))
1695  return false;
1696  }
1697 
1698  } while (handle_short_options);
1699 
1700  shift(args, nonops);
1701  ++args;
1702  if (numargs > 0)
1703  --numargs;
1704 
1705  } // while
1706 
1707  if (numargs > 0 && *args == 0) // It's a bug in the caller if numargs is greater than the actual number
1708  numargs = 0; // of arguments, but as a service to the user we fix this if we spot it.
1709 
1710  if (numargs < 0) // if we don't know the number of remaining non-option arguments
1711  { // we need to count them
1712  numargs = 0;
1713  while (args[numargs] != 0)
1714  ++numargs;
1715  }
1716 
1717  return action.finished(numargs + nonops, args - nonops);
1718 }
1719 
1725 {
1731  {
1735  virtual void operator()(const char*, int)
1736  {
1737  }
1738  };
1739 
1745  template<typename Function>
1747  {
1748  Function* write;
1749 
1750  virtual void operator()(const char* str, int size)
1751  {
1752  (*write)(str, size);
1753  }
1754 
1755  FunctionWriter(Function* w) :
1756  write(w)
1757  {
1758  }
1759  };
1760 
1766  template<typename OStream>
1768  {
1769  OStream& ostream;
1770 
1771  virtual void operator()(const char* str, int size)
1772  {
1773  ostream.write(str, size);
1774  }
1775 
1776  OStreamWriter(OStream& o) :
1777  ostream(o)
1778  {
1779  }
1780  };
1781 
1787  template<typename Temporary>
1789  {
1790  const Temporary& userstream;
1791 
1792  virtual void operator()(const char* str, int size)
1793  {
1794  userstream.write(str, size);
1795  }
1796 
1797  TemporaryWriter(const Temporary& u) :
1798  userstream(u)
1799  {
1800  }
1801  };
1802 
1809  template<typename Syscall>
1811  {
1812  Syscall* write;
1813  int fd;
1814 
1815  virtual void operator()(const char* str, int size)
1816  {
1817  (*write)(fd, str, size);
1818  }
1819 
1820  SyscallWriter(Syscall* w, int f) :
1821  write(w), fd(f)
1822  {
1823  }
1824  };
1825 
1830  template<typename Function, typename Stream>
1832  {
1833  Function* fwrite;
1834  Stream* stream;
1835 
1836  virtual void operator()(const char* str, int size)
1837  {
1838  (*fwrite)(str, size, 1, stream);
1839  }
1840 
1841  StreamWriter(Function* w, Stream* s) :
1842  fwrite(w), stream(s)
1843  {
1844  }
1845  };
1846 
1851  static void upmax(int& i1, int i2)
1852  {
1853  i1 = (i1 >= i2 ? i1 : i2);
1854  }
1855 
1867  static void indent(IStringWriter& write, int& x, int want_x)
1868  {
1869  int indent = want_x - x;
1870  if (indent < 0)
1871  {
1872  write("\n", 1);
1873  indent = want_x;
1874  }
1875 
1876  if (indent > 0)
1877  {
1878  char space = ' ';
1879  for (int i = 0; i < indent; ++i)
1880  write(&space, 1);
1881  x = want_x;
1882  }
1883  }
1884 
1903  static bool isWideChar(unsigned ch)
1904  {
1905  if (ch == 0x303F)
1906  return false;
1907 
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));
1912  }
1913 
1951  {
1954  const char* rowstart;
1955  const char* ptr;
1956  int col;
1957  int len;
1963 
1969  {
1970  screenlen = 0;
1971  for (len = 0; ptr[len] != 0 && ptr[len] != '\v' && ptr[len] != '\t' && ptr[len] != '\n'; ++len)
1972  {
1973  ++screenlen;
1974  unsigned ch = (unsigned char) ptr[len];
1975  if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
1976  {
1977  // int __builtin_clz (unsigned int x)
1978  // Returns the number of leading 0-bits in x, starting at the most significant bit
1979  unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
1980  ch = ch & mask; // mask out length bits, we don't verify their correctness
1981  while (((unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F) // while next byte is continuation byte
1982  {
1983  ch = (ch << 6) ^ (unsigned char) ptr[len + 1] ^ 0x80; // add continuation to char code
1984  ++len;
1985  }
1986  // ch is the decoded unicode code point
1987  if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
1988  ++screenlen;
1989  }
1990  }
1991  }
1992 
1993  public:
1995  LinePartIterator(const Descriptor usage[]) :
1996  tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), max_line_in_block(0), line_in_block(0),
1998  {
1999  }
2000 
2006  bool nextTable()
2007  {
2008  // If this is NOT the first time nextTable() is called after the constructor,
2009  // then skip to the next table break (i.e. a Descriptor with help == 0)
2010  if (rowdesc != 0)
2011  {
2012  while (tablestart->help != 0 && tablestart->shortopt != 0)
2013  ++tablestart;
2014  }
2015 
2016  // Find the next table after the break (if any)
2017  while (tablestart->help == 0 && tablestart->shortopt != 0)
2018  ++tablestart;
2019 
2020  restartTable();
2021  return rowstart != 0;
2022  }
2023 
2028  {
2029  rowdesc = tablestart;
2031  ptr = 0;
2032  }
2033 
2039  bool nextRow()
2040  {
2041  if (ptr == 0)
2042  {
2043  restartRow();
2044  return rowstart != 0;
2045  }
2046 
2047  while (*ptr != 0 && *ptr != '\n')
2048  ++ptr;
2049 
2050  if (*ptr == 0)
2051  {
2052  if ((rowdesc + 1)->help == 0) // table break
2053  return false;
2054 
2055  ++rowdesc;
2056  rowstart = rowdesc->help;
2057  }
2058  else // if (*ptr == '\n')
2059  {
2060  rowstart = ptr + 1;
2061  }
2062 
2063  restartRow();
2064  return true;
2065  }
2066 
2070  void restartRow()
2071  {
2072  ptr = rowstart;
2073  col = -1;
2074  len = 0;
2075  screenlen = 0;
2076  max_line_in_block = 0;
2077  line_in_block = 0;
2079  hit_target_line = true;
2080  }
2081 
2089  bool next()
2090  {
2091  if (ptr == 0)
2092  return false;
2093 
2094  if (col == -1)
2095  {
2096  col = 0;
2097  update_length();
2098  return true;
2099  }
2100 
2101  ptr += len;
2102  while (true)
2103  {
2104  switch (*ptr)
2105  {
2106  case '\v':
2108  ++ptr;
2109  break;
2110  case '\t':
2111  if (!hit_target_line) // if previous column did not have the targetline
2112  { // then "insert" a 0-length part
2113  update_length();
2114  hit_target_line = true;
2115  return true;
2116  }
2117 
2118  hit_target_line = false;
2119  line_in_block = 0;
2120  ++col;
2121  ++ptr;
2122  break;
2123  case 0:
2124  case '\n':
2125  if (!hit_target_line) // if previous column did not have the targetline
2126  { // then "insert" a 0-length part
2127  update_length();
2128  hit_target_line = true;
2129  return true;
2130  }
2131 
2133  {
2134  update_length();
2135  return false;
2136  }
2137 
2138  hit_target_line = false;
2139  line_in_block = 0;
2140  col = 0;
2141  ptr = rowstart;
2142  continue;
2143  default:
2144  ++ptr;
2145  continue;
2146  } // switch
2147 
2149  {
2150  update_length();
2151  hit_target_line = true;
2152  return true;
2153  }
2154  } // while
2155  }
2156 
2161  int column()
2162  {
2163  return col;
2164  }
2165 
2170  int line()
2171  {
2172  return target_line_in_block; // NOT line_in_block !!! It would be wrong if !hit_target_line
2173  }
2174 
2178  int length()
2179  {
2180  return len;
2181  }
2182 
2188  {
2189  return screenlen;
2190  }
2191 
2195  const char* data()
2196  {
2197  return ptr;
2198  }
2199  };
2200 
2226  {
2227  static const int bufmask = 15;
2228 
2231  int lenbuf[bufmask + 1];
2235  const char* datbuf[bufmask + 1];
2242  int x;
2246  int width;
2247  int head;
2248  int tail;
2249 
2258 
2259  bool buf_empty()
2260  {
2261  return ((tail + 1) & bufmask) == head;
2262  }
2263 
2264  bool buf_full()
2265  {
2266  return tail == head;
2267  }
2268 
2269  void buf_store(const char* data, int len)
2270  {
2271  lenbuf[head] = len;
2272  datbuf[head] = data;
2273  head = (head + 1) & bufmask;
2274  }
2275 
2277  void buf_next()
2278  {
2279  tail = (tail + 1) & bufmask;
2280  }
2281 
2286  void output(IStringWriter& write, const char* data, int len)
2287  {
2288  if (buf_full())
2289  write_one_line(write);
2290 
2291  buf_store(data, len);
2292  }
2293 
2298  {
2299  if (wrote_something) // if we already wrote something, we need to start a new line
2300  {
2301  write("\n", 1);
2302  int _ = 0;
2303  indent(write, _, x);
2304  }
2305 
2306  if (!buf_empty())
2307  {
2308  buf_next();
2309  write(datbuf[tail], lenbuf[tail]);
2310  }
2311 
2312  wrote_something = true;
2313  }
2314  public:
2315 
2322  {
2323  if (buf_empty())
2324  return;
2325  int _ = 0;
2326  indent(write, _, x);
2327  wrote_something = false;
2328  while (!buf_empty())
2329  write_one_line(write);
2330  write("\n", 1);
2331  }
2332 
2351  void process(IStringWriter& write, const char* data, int len)
2352  {
2353  wrote_something = false;
2354 
2355  while (len > 0)
2356  {
2357  if (len <= width) // quick test that works because utf8width <= len (all wide chars have at least 2 bytes)
2358  {
2359  output(write, data, len);
2360  len = 0;
2361  }
2362  else // if (len > width) it's possible (but not guaranteed) that utf8len > width
2363  {
2364  int utf8width = 0;
2365  int maxi = 0;
2366  while (maxi < len && utf8width < width)
2367  {
2368  int charbytes = 1;
2369  unsigned ch = (unsigned char) data[maxi];
2370  if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
2371  {
2372  // int __builtin_clz (unsigned int x)
2373  // Returns the number of leading 0-bits in x, starting at the most significant bit
2374  unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
2375  ch = ch & mask; // mask out length bits, we don't verify their correctness
2376  while ((maxi + charbytes < len) && //
2377  (((unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F)) // while next byte is continuation byte
2378  {
2379  ch = (ch << 6) ^ (unsigned char) data[maxi + charbytes] ^ 0x80; // add continuation to char code
2380  ++charbytes;
2381  }
2382  // ch is the decoded unicode code point
2383  if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
2384  {
2385  if (utf8width + 2 > width)
2386  break;
2387  ++utf8width;
2388  }
2389  }
2390  ++utf8width;
2391  maxi += charbytes;
2392  }
2393 
2394  // data[maxi-1] is the last byte of the UTF-8 sequence of the last character that fits
2395  // onto the 1st line. If maxi == len, all characters fit on the line.
2396 
2397  if (maxi == len)
2398  {
2399  output(write, data, len);
2400  len = 0;
2401  }
2402  else // if (maxi < len) at least 1 character (data[maxi] that is) doesn't fit on the line
2403  {
2404  int i;
2405  for (i = maxi; i >= 0; --i)
2406  if (data[i] == ' ')
2407  break;
2408 
2409  if (i >= 0)
2410  {
2411  output(write, data, i);
2412  data += i + 1;
2413  len -= i + 1;
2414  }
2415  else // did not find a space to split at => split before data[maxi]
2416  { // data[maxi] is always the beginning of a character, never a continuation byte
2417  output(write, data, maxi);
2418  data += maxi;
2419  len -= maxi;
2420  }
2421  }
2422  }
2423  }
2424  if (!wrote_something) // if we didn't already write something to make space in the buffer
2425  write_one_line(write); // write at most one line of actual output
2426  }
2427 
2434  LineWrapper(int x1, int x2) :
2435  x(x1), width(x2 - x1), head(0), tail(bufmask)
2436  {
2437  if (width < 2) // because of wide characters we need at least width 2 or the code breaks
2438  width = 2;
2439  }
2440  };
2441 
2447  static void printUsage(IStringWriter& write, const Descriptor usage[], int width = 80, //
2448  int last_column_min_percent = 50, int last_column_own_line_max_percent = 75)
2449  {
2450  if (width < 1) // protect against nonsense values
2451  width = 80;
2452 
2453  if (width > 10000) // protect against overflow in the following computation
2454  width = 10000;
2455 
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;
2460 
2461  LinePartIterator part(usage);
2462  while (part.nextTable())
2463  {
2464 
2465  /***************** Determine column widths *******************************/
2466 
2467  const int maxcolumns = 8; // 8 columns are enough for everyone
2468  int col_width[maxcolumns];
2469  int lastcolumn;
2470  int leftwidth;
2471  int overlong_column_threshold = 10000;
2472  do
2473  {
2474  lastcolumn = 0;
2475  for (int i = 0; i < maxcolumns; ++i)
2476  col_width[i] = 0;
2477 
2478  part.restartTable();
2479  while (part.nextRow())
2480  {
2481  while (part.next())
2482  {
2483  if (part.column() < maxcolumns)
2484  {
2485  upmax(lastcolumn, part.column());
2486  if (part.screenLength() < overlong_column_threshold)
2487  // We don't let rows that don't use table separators (\t or \v) influence
2488  // the width of column 0. This allows the user to interject section headers
2489  // or explanatory paragraphs that do not participate in the table layout.
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());
2493  }
2494  }
2495  }
2496 
2497  /*
2498  * If the last column doesn't fit on the same
2499  * line as the other columns, we can fix that by starting it on its own line.
2500  * However we can't do this for any of the columns 0..lastcolumn-1.
2501  * If their sum exceeds the maximum width we try to fix this by iteratively
2502  * ignoring the widest line parts in the width determination until
2503  * we arrive at a series of column widths that fit into one line.
2504  * The result is a layout where everything is nicely formatted
2505  * except for a few overlong fragments.
2506  * */
2507 
2508  leftwidth = 0;
2509  overlong_column_threshold = 0;
2510  for (int i = 0; i < lastcolumn; ++i)
2511  {
2512  leftwidth += col_width[i];
2513  upmax(overlong_column_threshold, col_width[i]);
2514  }
2515 
2516  } while (leftwidth > width);
2517 
2518  /**************** Determine tab stops and last column handling **********************/
2519 
2520  int tabstop[maxcolumns];
2521  tabstop[0] = 0;
2522  for (int i = 1; i < maxcolumns; ++i)
2523  tabstop[i] = tabstop[i - 1] + col_width[i - 1];
2524 
2525  int rightwidth = width - tabstop[lastcolumn];
2526  bool print_last_column_on_own_line = false;
2527  if (rightwidth < last_column_min_width && // if we don't have the minimum requested width for the last column
2528  ( col_width[lastcolumn] == 0 || // and all last columns are > overlong_column_threshold
2529  rightwidth < col_width[lastcolumn] // or there is at least one last column that requires more than the space available
2530  )
2531  )
2532  {
2533  print_last_column_on_own_line = true;
2534  rightwidth = last_column_own_line_max_width;
2535  }
2536 
2537  // If lastcolumn == 0 we must disable print_last_column_on_own_line because
2538  // otherwise 2 copies of the last (and only) column would be output.
2539  // Actually this is just defensive programming. It is currently not
2540  // possible that lastcolumn==0 and print_last_column_on_own_line==true
2541  // at the same time, because lastcolumn==0 => tabstop[lastcolumn] == 0 =>
2542  // rightwidth==width => rightwidth>=last_column_min_width (unless someone passes
2543  // a bullshit value >100 for last_column_min_percent) => the above if condition
2544  // is false => print_last_column_on_own_line==false
2545  if (lastcolumn == 0)
2546  print_last_column_on_own_line = false;
2547 
2548  LineWrapper lastColumnLineWrapper(width - rightwidth, width);
2549  LineWrapper interjectionLineWrapper(0, width);
2550 
2551  part.restartTable();
2552 
2553  /***************** Print out all rows of the table *************************************/
2554 
2555  while (part.nextRow())
2556  {
2557  int x = -1;
2558  while (part.next())
2559  {
2560  if (part.column() > lastcolumn)
2561  continue; // drop excess columns (can happen if lastcolumn == maxcolumns-1)
2562 
2563  if (part.column() == 0)
2564  {
2565  if (x >= 0)
2566  write("\n", 1);
2567  x = 0;
2568  }
2569 
2570  indent(write, x, tabstop[part.column()]);
2571 
2572  if ((part.column() < lastcolumn)
2573  && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
2574  || part.data()[part.length()] == '\v'))
2575  {
2576  write(part.data(), part.length());
2577  x += part.screenLength();
2578  }
2579  else // either part.column() == lastcolumn or we are in the special case of
2580  // an interjection that doesn't contain \v or \t
2581  {
2582  // NOTE: This code block is not necessarily executed for
2583  // each line, because some rows may have fewer columns.
2584 
2585  LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
2586 
2587  if (!print_last_column_on_own_line || part.column() != lastcolumn)
2588  lineWrapper.process(write, part.data(), part.length());
2589  }
2590  } // while
2591 
2592  if (print_last_column_on_own_line)
2593  {
2594  part.restartRow();
2595  while (part.next())
2596  {
2597  if (part.column() == lastcolumn)
2598  {
2599  write("\n", 1);
2600  int _ = 0;
2601  indent(write, _, width - rightwidth);
2602  lastColumnLineWrapper.process(write, part.data(), part.length());
2603  }
2604  }
2605  }
2606 
2607  write("\n", 1);
2608  lastColumnLineWrapper.flush(write);
2609  interjectionLineWrapper.flush(write);
2610  }
2611  }
2612  }
2613 
2614 }
2615 ;
2616 
2814 template<typename OStream>
2815 void printUsage(OStream& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2816  int last_column_own_line_max_percent = 75)
2817 {
2819  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2820 }
2821 
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)
2825 {
2827  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2828 }
2829 
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)
2833 {
2835  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2836 }
2837 
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)
2841 {
2843  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2844 }
2845 
2846 template<typename Function, typename Stream>
2847 void printUsage(Function* prn, Stream* stream, const Descriptor usage[], int width = 80, int last_column_min_percent =
2848  50,
2849  int last_column_own_line_max_percent = 75)
2850 {
2852  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2853 }
2854 
2855 }
2856 // namespace option
2857 
2858 #endif /* OPTIONPARSER_H_ */
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.
Definition: optionparser.h:950
const char * data()
Returns the current part of the iteration.
std::string help(std::string tool)
int index() const
Returns Descriptor::index of this Option&#39;s Descriptor, or -1 if this Option is invalid (unused)...
Definition: optionparser.h:542
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.
Definition: optionparser.h:256
bool isLast() const
Returns true iff this is the last element of the linked list.
Definition: optionparser.h:592
int count() const
Returns the number of times this Option (or others with the same Descriptor::index) occurs in the arg...
Definition: optionparser.h:559
const char ** nonOptions()
Returns a pointer to an array of non-option arguments (only valid if nonOptionsCount() &gt;0 )...
static ArgStatus None(const Option &, bool)
!
Definition: optionparser.h:926
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)
#define min(a, b)
Definition: hio.h:45
const char * help
The usage text associated with the options in this Descriptor.
Definition: optionparser.h:422
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)
!
Definition: optionparser.h:932
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().
Definition: optionparser.h:695
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&#39;s linked list in the array filled in by the parser.
Definition: optionparser.h:336
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.
Definition: optionparser.h:254
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 ...
Definition: optionparser.h:961
const Descriptor * tablestart
The 1st descriptor of the current table.
const Option * last() const
const version of Option::last().
Definition: optionparser.h:648
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&#39;s argument (if any).
Definition: optionparser.h:489
Option * nextwrap()
Returns a pointer to the next element of the linked list with wrap-around from last() to first()...
Definition: optionparser.h:716
! The argument is not acceptable but that&#39;s non-fatal because the option&#39;s argument is optional...
Definition: optionparser.h:258
const int type
Used to distinguish between options with the same CASA.
Definition: optionparser.h:345
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.
Definition: optionparser.h:442
ArgStatus(* CheckArg)(const Option &option, bool msg)
Signature of functions that check if an argument is valid for a certain type of option.
Definition: optionparser.h:291
Functions for checking the validity of option arguments.
Definition: optionparser.h:923
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.
size_t size() const
bool perform(Option &option)
Called by Parser::workhorse() for each Option that has been successfully parsed (including unknown op...
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().
Definition: optionparser.h:703
const CheckArg check_arg
For each option that matches shortopt or longopt this function will be called to check a potential ar...
Definition: optionparser.h:405
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
Definition: PlotData.h:48
Stats()
Creates a Stats object with counts set to 1 (for the sentinel element).
Definition: optionparser.h:979
const char *const longopt
The long option name (without the leading – ).
Definition: optionparser.h:393
Options options
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.
Definition: optionparser.h:315
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()...
Definition: optionparser.h:661
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)
Definition: optionparser.h:853
int namelen
The length of the option name.
Definition: optionparser.h:510
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.
Definition: optionparser.h:812
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 &quot;large enough&quot;.
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...
Definition: optionparser.h:993
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().
Definition: optionparser.h:682
const char * rowstart
Ptr to 1st character of current row within rowdesc-&gt;help.
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
Definition: optionparser.h:974
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().
Definition: optionparser.h:731
const Descriptor * desc
Pointer to this Option&#39;s Descriptor.
Definition: optionparser.h:465
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...
Definition: optionparser.h:802
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.
Definition: optionparser.h:251
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.
Definition: optionparser.h:608
void restartTable()
Reset iteration to the beginning of the current table.
static bool isTagged(Option *ptr)
Definition: optionparser.h:863
static void indent(IStringWriter &write, int &x, int want_x)
Option * prev_
Definition: optionparser.h:445
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.
Definition: optionparser.h:579
static Option * untag(Option *ptr)
Definition: optionparser.h:858
! The argument is not acceptable and that&#39;s fatal.
Definition: optionparser.h:260
const char *const shortopt
Each char in this string will be accepted as a short option character.
Definition: optionparser.h:358
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.
Definition: optionparser.h:481
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_)
Definition: optionparser.h:836
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().
Definition: optionparser.h:619
const char ** nonop_args
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.
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.
Definition: optionparser.h:640
int type() const
Returns Descriptor::type of this Option&#39;s Descriptor, or 0 if this Option is invalid (unused)...
Definition: optionparser.h:533
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 * next_
Definition: optionparser.h:444
Option()
Creates a new Option that is a one-element linked list and has NULL desc, name, arg and namelen...
Definition: optionparser.h:787
Option(const Option &orig)
Makes *this a copy of orig except for the linked list pointers.
Definition: optionparser.h:822
Option * prevwrap()
Returns a pointer to the previous element of the linked list with wrap-around from first() to last()...
Definition: optionparser.h:674