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 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 
214 #ifndef OPTIONPARSER_H_
215 #define OPTIONPARSER_H_
216 
218 namespace OptionParser {
219 
220 #ifdef _MSC_VER
221 #include <intrin.h>
222 #pragma intrinsic(_BitScanReverse)
223 struct MSC_Builtin_CLZ
224 {
225  static int builtin_clz(unsigned x)
226  {
227  unsigned long index;
228  _BitScanReverse(&index, x);
229  return 32-index; // int is always 32bit on Windows, even for target x64
230  }
231 };
232 #define __builtin_clz(x) MSC_Builtin_CLZ::builtin_clz(x)
233 #endif
234 
235 class Option;
236 
244 {
253 };
254 
283 typedef ArgStatus (*CheckArg)(const Option& option, bool msg);
284 
308 {
328  const unsigned index;
329 
337  const int type;
338 
350  const char* const shortopt;
351 
385  const char* const longopt;
386 
398 
414  const char* help;
415 };
416 
434 class Option
435 {
436  Option* next_;
437  Option* prev_;
438 public:
457  const Descriptor* desc;
458 
473  const char* name;
474 
481  const char* arg;
482 
502  int namelen;
503 
525  int type() const
526  {
527  return desc == 0 ? 0 : desc->type;
528  }
529 
534  int index() const
535  {
536  return desc == 0 ? -1 : desc->index;
537  }
538 
551  int count()
552  {
553  int c = (desc == 0 ? 0 : 1);
554  Option* p = first();
555  while (!p->isLast())
556  {
557  ++c;
558  p = p->next_;
559  };
560  return c;
561  }
562 
571  bool isFirst() const
572  {
573  return isTagged(prev_);
574  }
575 
584  bool isLast() const
585  {
586  return isTagged(next_);
587  }
588 
601  {
602  Option* p = this;
603  while (!p->isFirst())
604  p = p->prev_;
605  return p;
606  }
607 
625  {
626  return first()->prevwrap();
627  }
628 
638  {
639  return isFirst() ? 0 : prev_;
640  }
641 
651  {
652  return untag(prev_);
653  }
654 
664  {
665  return isLast() ? 0 : next_;
666  }
667 
677  {
678  return untag(next_);
679  }
680 
691  void append(Option* new_last)
692  {
693  Option* p = last();
694  Option* f = first();
695  p->next_ = new_last;
696  new_last->prev_ = p;
697  new_last->next_ = tag(f);
698  f->prev_ = tag(new_last);
699  }
700 
717  operator const Option*() const
718  {
719  return desc ? this : 0;
720  }
721 
738  operator Option*()
739  {
740  return desc ? this : 0;
741  }
742 
747  Option() :
748  desc(0), name(0), arg(0), namelen(0)
749  {
750  prev_ = tag(this);
751  next_ = tag(this);
752  }
753 
762  Option(const Descriptor* desc_, const char* name_, const char* arg_)
763  {
764  init(desc_, name_, arg_);
765  }
766 
772  void operator=(const Option& orig)
773  {
774  init(orig.desc, orig.name, orig.arg);
775  }
776 
782  Option(const Option& orig)
783  {
784  init(orig.desc, orig.name, orig.arg);
785  }
786 
787 private:
796  void init(const Descriptor* desc_, const char* name_, const char* arg_)
797  {
798  desc = desc_;
799  name = name_;
800  arg = arg_;
801  prev_ = tag(this);
802  next_ = tag(this);
803  namelen = 0;
804  if (name == 0)
805  return;
806  namelen = 1;
807  if (name[0] != '-')
808  return;
809  while (name[namelen] != 0 && name[namelen] != '=')
810  ++namelen;
811  }
812 
813  static Option* tag(Option* ptr)
814  {
815  return (Option*) ((unsigned long long) ptr | 1);
816  }
817 
818  static Option* untag(Option* ptr)
819  {
820  return (Option*) ((unsigned long long) ptr & ~1ull);
821  }
822 
823  static bool isTagged(Option* ptr)
824  {
825  return ((unsigned long long) ptr & 1);
826  }
827 };
828 
883 struct Arg
884 {
885 
886 
888  static ArgStatus None(const Option&, bool)
889  {
890  return ARG_NONE;
891  }
892 
894  static ArgStatus Optional(const Option& option, bool)
895  {
896  if (option.arg && option.name[option.namelen] != 0)
897  return ARG_OK;
898  else
899  return ARG_IGNORE;
900  }
901 
902 
903  static ArgStatus Required(const OptionParser::Option& option, bool msg)
904  {
905  if (option.arg != 0)
906  return OptionParser::ARG_OK;
907 
908  if (msg) {
909  std::cout << "Option '" << option << "' requires an argument\n";
910  }
912  }
913 };
914 
924 struct Stats
925 {
935  unsigned buffer_max;
936 
948  unsigned options_max;
949 
953  Stats() :
954  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
955  {
956  }
957 
967  Stats(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
968  bool single_minus_longopt = false) :
969  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
970  {
971  add(gnu, usage, argc, argv, min_abbr_len, single_minus_longopt);
972  }
973 
975  Stats(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
976  bool single_minus_longopt = false) :
977  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
978  {
979  add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
980  }
981 
983  Stats(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
984  bool single_minus_longopt = false) :
985  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
986  {
987  add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
988  }
989 
991  Stats(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
992  bool single_minus_longopt = false) :
993  buffer_max(1), options_max(1) // 1 more than necessary as sentinel
994  {
995  add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
996  }
997 
1007  void add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1008  bool single_minus_longopt = false);
1009 
1011  void add(bool gnu, const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1012  bool single_minus_longopt = false)
1013  {
1014  add(gnu, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1015  }
1016 
1018  void add(const Descriptor usage[], int argc, const char** argv, int min_abbr_len = 0, //
1019  bool single_minus_longopt = false)
1020  {
1021  add(false, usage, argc, argv, min_abbr_len, single_minus_longopt);
1022  }
1023 
1025  void add(const Descriptor usage[], int argc, char** argv, int min_abbr_len = 0, //
1026  bool single_minus_longopt = false)
1027  {
1028  add(false, usage, argc, (const char**) argv, min_abbr_len, single_minus_longopt);
1029  }
1030 private:
1031  class CountOptionsAction;
1032 };
1033 
1054 class Parser
1055 {
1056  int op_count;
1057  int nonop_count;
1058  const char** nonop_args;
1059  bool err;
1060 public:
1061 
1066  op_count(0), nonop_count(0), nonop_args(0), err(false)
1067  {
1068  }
1069 
1074  Parser(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
1075  int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
1076  op_count(0), nonop_count(0), nonop_args(0), err(false)
1077  {
1078  parse(gnu, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1079  }
1080 
1082  Parser(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
1083  int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1) :
1084  op_count(0), nonop_count(0), nonop_args(0), err(false)
1085  {
1086  parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1087  }
1088 
1090  Parser(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1091  bool single_minus_longopt = false, int bufmax = -1) :
1092  op_count(0), nonop_count(0), nonop_args(0), err(false)
1093  {
1094  parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1095  }
1096 
1098  Parser(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1099  bool single_minus_longopt = false, int bufmax = -1) :
1100  op_count(0), nonop_count(0), nonop_args(0), err(false)
1101  {
1102  parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1103  }
1104 
1161  void parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
1162  int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1);
1163 
1165  void parse(bool gnu, const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[],
1166  int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
1167  {
1168  parse(gnu, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1169  }
1170 
1172  void parse(const Descriptor usage[], int argc, const char** argv, Option options[], Option buffer[],
1173  int min_abbr_len = 0, bool single_minus_longopt = false, int bufmax = -1)
1174  {
1175  parse(false, usage, argc, argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1176  }
1177 
1179  void parse(const Descriptor usage[], int argc, char** argv, Option options[], Option buffer[], int min_abbr_len = 0,
1180  bool single_minus_longopt = false, int bufmax = -1)
1181  {
1182  parse(false, usage, argc, (const char**) argv, options, buffer, min_abbr_len, single_minus_longopt, bufmax);
1183  }
1184 
1195  {
1196  return op_count;
1197  }
1198 
1214  {
1215  return nonop_count;
1216  }
1217 
1229  const char** nonOptions()
1230  {
1231  return nonop_args;
1232  }
1233 
1237  const char* nonOption(int i)
1238  {
1239  return nonOptions()[i];
1240  }
1241 
1257  bool error()
1258  {
1259  return err;
1260  }
1261 
1262 private:
1263  friend struct Stats;
1264  class StoreOptionAction;
1265  struct Action;
1266 
1272  static bool workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
1273  bool single_minus_longopt, bool print_errors, int min_abbr_len);
1274 
1289  static bool streq(const char* st1, const char* st2)
1290  {
1291  while (*st1 != 0)
1292  if (*st1++ != *st2++)
1293  return false;
1294  return (*st2 == 0 || *st2 == '=');
1295  }
1296 
1321  static bool streqabbr(const char* st1, const char* st2, long long min)
1322  {
1323  const char* st1start = st1;
1324  while (*st1 != 0 && (*st1 == *st2))
1325  {
1326  ++st1;
1327  ++st2;
1328  }
1329 
1330  return (*st1 == 0 || (min > 0 && (st1 - st1start) >= min)) && (*st2 == 0 || *st2 == '=');
1331  }
1332 
1339  static bool instr(char ch, const char* st)
1340  {
1341  while (*st != 0 && *st != ch)
1342  ++st;
1343  return *st == ch;
1344  }
1345 
1351  static void shift(const char** args, int count)
1352  {
1353  for (int i = 0; i > -count; --i)
1354  {
1355  const char* temp = args[i];
1356  args[i] = args[i - 1];
1357  args[i - 1] = temp;
1358  }
1359  }
1360 };
1361 
1368 {
1377  virtual bool perform(Option&)
1378  {
1379  return true;
1380  }
1381 
1390  virtual bool finished(int numargs, const char** args)
1391  {
1392  (void) numargs;
1393  (void) args;
1394  return true;
1395  }
1396 };
1397 
1404 {
1405  unsigned* buffer_max;
1406 public:
1411  CountOptionsAction(unsigned* buffer_max_) :
1412  buffer_max(buffer_max_)
1413  {
1414  }
1415 
1417  {
1418  if (*buffer_max == 0x7fffffff)
1419  return false; // overflow protection: don't accept number of options that doesn't fit signed int
1420  ++*buffer_max;
1421  return true;
1422  }
1423 };
1424 
1431 {
1432  Parser& parser;
1433  Option* options;
1434  Option* buffer;
1435  int bufmax;
1436 public:
1444  StoreOptionAction(Parser& parser_, Option options_[], Option buffer_[], int bufmax_) :
1445  parser(parser_), options(options_), buffer(buffer_), bufmax(bufmax_)
1446  {
1447  // find first empty slot in buffer (if any)
1448  int bufidx = 0;
1449  while ((bufmax < 0 || bufidx < bufmax) && buffer[bufidx])
1450  ++bufidx;
1451 
1452  // set parser's optionCount
1453  parser.op_count = bufidx;
1454  }
1455 
1456  bool perform(Option& option)
1457  {
1458  if (bufmax < 0 || parser.op_count < bufmax)
1459  {
1460  if (parser.op_count == 0x7fffffff)
1461  return false; // overflow protection: don't accept number of options that doesn't fit signed int
1462 
1463  buffer[parser.op_count] = option;
1464  int idx = buffer[parser.op_count].desc->index;
1465  if (options[idx])
1466  options[idx].append(buffer[parser.op_count]);
1467  else
1468  options[idx] = buffer[parser.op_count];
1469  ++parser.op_count;
1470  }
1471  return true; // NOTE: an option that is discarded because of a full buffer is not fatal
1472  }
1473 
1474  bool finished(int numargs, const char** args)
1475  {
1476  // only overwrite non-option argument list if there's at least 1
1477  // new non-option argument. Otherwise we keep the old list. This
1478  // makes it easy to use default non-option arguments.
1479  if (numargs > 0)
1480  {
1481  parser.nonop_count = numargs;
1482  parser.nonop_args = args;
1483  }
1484 
1485  return true;
1486  }
1487 };
1488 
1489 inline void Parser::parse(bool gnu, const Descriptor usage[], int argc, const char** argv, Option options[],
1490  Option buffer[], int min_abbr_len, bool single_minus_longopt, int bufmax)
1491 {
1492  StoreOptionAction action(*this, options, buffer, bufmax);
1493  err = !workhorse(gnu, usage, argc, argv, action, single_minus_longopt, true, min_abbr_len);
1494 }
1495 
1496 inline void Stats::add(bool gnu, const Descriptor usage[], int argc, const char** argv, int min_abbr_len,
1497  bool single_minus_longopt)
1498 {
1499  // determine size of options array. This is the greatest index used in the usage + 1
1500  int i = 0;
1501  while (usage[i].shortopt != 0)
1502  {
1503  if (usage[i].index + 1 >= options_max)
1504  options_max = (usage[i].index + 1) + 1; // 1 more than necessary as sentinel
1505 
1506  ++i;
1507  }
1508 
1509  CountOptionsAction action(&buffer_max);
1510  Parser::workhorse(gnu, usage, argc, argv, action, single_minus_longopt, false, min_abbr_len);
1511 }
1512 
1513 inline bool Parser::workhorse(bool gnu, const Descriptor usage[], int numargs, const char** args, Action& action,
1514  bool single_minus_longopt, bool print_errors, int min_abbr_len)
1515 {
1516  // protect against NULL pointer
1517  if (args == 0)
1518  numargs = 0;
1519 
1520  int nonops = 0;
1521 
1522  while (numargs != 0 && *args != 0)
1523  {
1524  const char* param = *args; // param can be --long-option, -srto or non-option argument
1525 
1526  // in POSIX mode the first non-option argument terminates the option list
1527  // a lone minus character is a non-option argument
1528  if (param[0] != '-' || param[1] == 0)
1529  {
1530  if (gnu)
1531  {
1532  ++nonops;
1533  ++args;
1534  if (numargs > 0)
1535  --numargs;
1536  continue;
1537  }
1538  else
1539  break;
1540  }
1541 
1542  // -- terminates the option list. The -- itself is skipped.
1543  if (param[1] == '-' && param[2] == 0)
1544  {
1545  shift(args, nonops);
1546  ++args;
1547  if (numargs > 0)
1548  --numargs;
1549  break;
1550  }
1551 
1552  bool handle_short_options;
1553  const char* longopt_name;
1554  if (param[1] == '-') // if --long-option
1555  {
1556  handle_short_options = false;
1557  longopt_name = param + 2;
1558  }
1559  else
1560  {
1561  handle_short_options = true;
1562  longopt_name = param + 1; //for testing a potential -long-option
1563  }
1564 
1565  bool try_single_minus_longopt = single_minus_longopt;
1566  bool have_more_args = (numargs > 1 || numargs < 0); // is referencing argv[1] valid?
1567 
1568  do // loop over short options in group, for long options the body is executed only once
1569  {
1570  int idx;
1571 
1572  const char* optarg;
1573 
1574  /******************** long option **********************/
1575  if (handle_short_options == false || try_single_minus_longopt)
1576  {
1577  idx = 0;
1578  while (usage[idx].longopt != 0 && !streq(usage[idx].longopt, longopt_name))
1579  ++idx;
1580 
1581  if (usage[idx].longopt == 0 && min_abbr_len > 0) // if we should try to match abbreviated long options
1582  {
1583  int i1 = 0;
1584  while (usage[i1].longopt != 0 && !streqabbr(usage[i1].longopt, longopt_name, min_abbr_len))
1585  ++i1;
1586  if (usage[i1].longopt != 0)
1587  { // now test if the match is unambiguous by checking for another match
1588  int i2 = i1 + 1;
1589  while (usage[i2].longopt != 0 && !streqabbr(usage[i2].longopt, longopt_name, min_abbr_len))
1590  ++i2;
1591 
1592  if (usage[i2].longopt == 0) // if there was no second match it's unambiguous, so accept i1 as idx
1593  idx = i1;
1594  }
1595  }
1596 
1597  // if we found something, disable handle_short_options (only relevant if single_minus_longopt)
1598  if (usage[idx].longopt != 0)
1599  handle_short_options = false;
1600 
1601  try_single_minus_longopt = false; // prevent looking for longopt in the middle of shortopt group
1602 
1603  optarg = longopt_name;
1604  while (*optarg != 0 && *optarg != '=')
1605  ++optarg;
1606  if (*optarg == '=') // attached argument
1607  ++optarg;
1608  else
1609  // possibly detached argument
1610  optarg = (have_more_args ? args[1] : 0);
1611  }
1612 
1613  /************************ short option ***********************************/
1614  if (handle_short_options)
1615  {
1616  if (*++param == 0) // point at the 1st/next option character
1617  break; // end of short option group
1618 
1619  idx = 0;
1620  while (usage[idx].shortopt != 0 && !instr(*param, usage[idx].shortopt))
1621  ++idx;
1622 
1623  if (param[1] == 0) // if the potential argument is separate
1624  optarg = (have_more_args ? args[1] : 0);
1625  else
1626  // if the potential argument is attached
1627  optarg = param + 1;
1628  }
1629 
1630  const Descriptor* descriptor = &usage[idx];
1631 
1632  if (descriptor->shortopt == 0) /************** unknown option ********************/
1633  {
1634  // look for dummy entry (shortopt == "" and longopt == "") to use as Descriptor for unknown options
1635  idx = 0;
1636  while (usage[idx].shortopt != 0 && (usage[idx].shortopt[0] != 0 || usage[idx].longopt[0] != 0))
1637  ++idx;
1638  descriptor = (usage[idx].shortopt == 0 ? 0 : &usage[idx]);
1639  }
1640 
1641  if (descriptor != 0)
1642  {
1643  Option option(descriptor, param, optarg);
1644  switch (descriptor->check_arg(option, print_errors))
1645  {
1646  case ARG_ILLEGAL:
1647  return false; // fatal
1648  case ARG_OK:
1649  // skip one element of the argument vector, if it's a separated argument
1650  if (optarg != 0 && have_more_args && optarg == args[1])
1651  {
1652  shift(args, nonops);
1653  if (numargs > 0)
1654  --numargs;
1655  ++args;
1656  }
1657 
1658  // No further short options are possible after an argument
1659  handle_short_options = false;
1660 
1661  break;
1662  case ARG_IGNORE:
1663  case ARG_NONE:
1664  option.arg = 0;
1665  break;
1666  }
1667 
1668  if (!action.perform(option))
1669  return false;
1670  }
1671 
1672  } while (handle_short_options);
1673 
1674  shift(args, nonops);
1675  ++args;
1676  if (numargs > 0)
1677  --numargs;
1678 
1679  } // while
1680 
1681  if (numargs > 0 && *args == 0) // It's a bug in the caller if numargs is greater than the actual number
1682  numargs = 0; // of arguments, but as a service to the user we fix this if we spot it.
1683 
1684  if (numargs < 0) // if we don't know the number of remaining non-option arguments
1685  { // we need to count them
1686  numargs = 0;
1687  while (args[numargs] != 0)
1688  ++numargs;
1689  }
1690 
1691  return action.finished(numargs + nonops, args - nonops);
1692 }
1693 
1699 {
1705  {
1709  virtual void operator()(const char*, int)
1710  {
1711  }
1712  };
1713 
1719  template<typename Function>
1721  {
1722  Function* write;
1723 
1724  virtual void operator()(const char* str, int size)
1725  {
1726  (*write)(str, size);
1727  }
1728 
1729  FunctionWriter(Function* w) :
1730  write(w)
1731  {
1732  }
1733  };
1734 
1740  template<typename OStream>
1742  {
1743  OStream& ostream;
1744 
1745  virtual void operator()(const char* str, int size)
1746  {
1747  ostream.write(str, size);
1748  }
1749 
1750  OStreamWriter(OStream& o) :
1751  ostream(o)
1752  {
1753  }
1754  };
1755 
1761  template<typename Temporary>
1763  {
1764  const Temporary& userstream;
1765 
1766  virtual void operator()(const char* str, int size)
1767  {
1768  userstream.write(str, size);
1769  }
1770 
1771  TemporaryWriter(const Temporary& u) :
1772  userstream(u)
1773  {
1774  }
1775  };
1776 
1783  template<typename Syscall>
1785  {
1786  Syscall* write;
1787  int fd;
1788 
1789  virtual void operator()(const char* str, int size)
1790  {
1791  (*write)(fd, str, size);
1792  }
1793 
1794  SyscallWriter(Syscall* w, int f) :
1795  write(w), fd(f)
1796  {
1797  }
1798  };
1799 
1804  template<typename Function, typename Stream>
1806  {
1807  Function* fwrite;
1808  Stream* stream;
1809 
1810  virtual void operator()(const char* str, int size)
1811  {
1812  (*fwrite)(str, size, 1, stream);
1813  }
1814 
1815  StreamWriter(Function* w, Stream* s) :
1816  fwrite(w), stream(s)
1817  {
1818  }
1819  };
1820 
1825  static void upmax(int& i1, int i2)
1826  {
1827  i1 = (i1 >= i2 ? i1 : i2);
1828  }
1829 
1841  static void indent(IStringWriter& write, int& x, int want_x)
1842  {
1843  int indent = want_x - x;
1844  if (indent < 0)
1845  {
1846  write("\n", 1);
1847  indent = want_x;
1848  }
1849 
1850  if (indent > 0)
1851  {
1852  char space = ' ';
1853  for (int i = 0; i < indent; ++i)
1854  write(&space, 1);
1855  x = want_x;
1856  }
1857  }
1858 
1877  static bool isWideChar(unsigned ch)
1878  {
1879  if (ch == 0x303F)
1880  return false;
1881 
1882  return ((0x1100 <= ch && ch <= 0x115F) || (0x2329 <= ch && ch <= 0x232A) || (0x2E80 <= ch && ch <= 0xA4C6)
1883  || (0xA960 <= ch && ch <= 0xA97C) || (0xAC00 <= ch && ch <= 0xD7FB) || (0xF900 <= ch && ch <= 0xFAFF)
1884  || (0xFE10 <= ch && ch <= 0xFE6B) || (0xFF01 <= ch && ch <= 0xFF60) || (0xFFE0 <= ch && ch <= 0xFFE6)
1885  || (0x1B000 <= ch));
1886  }
1887 
1925  {
1926  const Descriptor* tablestart;
1927  const Descriptor* rowdesc;
1928  const char* rowstart;
1929  const char* ptr;
1930  int col;
1931  int len;
1932  int screenlen;
1933  int max_line_in_block;
1934  int line_in_block;
1935  int target_line_in_block;
1936  bool hit_target_line;
1937 
1942  void update_length()
1943  {
1944  screenlen = 0;
1945  for (len = 0; ptr[len] != 0 && ptr[len] != '\v' && ptr[len] != '\t' && ptr[len] != '\n'; ++len)
1946  {
1947  ++screenlen;
1948  unsigned ch = (unsigned char) ptr[len];
1949  if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
1950  {
1951  // int __builtin_clz (unsigned int x)
1952  // Returns the number of leading 0-bits in x, starting at the most significant bit
1953  unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
1954  ch = ch & mask; // mask out length bits, we don't verify their correctness
1955  while (((unsigned char) ptr[len + 1] ^ 0x80) <= 0x3F) // while next byte is continuation byte
1956  {
1957  ch = (ch << 6) ^ (unsigned char) ptr[len + 1] ^ 0x80; // add continuation to char code
1958  ++len;
1959  }
1960  // ch is the decoded unicode code point
1961  if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
1962  ++screenlen;
1963  }
1964  }
1965  }
1966 
1967  public:
1969  LinePartIterator(const Descriptor usage[]) :
1970  tablestart(usage), rowdesc(0), rowstart(0), ptr(0), col(-1), len(0), max_line_in_block(0), line_in_block(0),
1971  target_line_in_block(0), hit_target_line(true)
1972  {
1973  }
1974 
1980  bool nextTable()
1981  {
1982  // If this is NOT the first time nextTable() is called after the constructor,
1983  // then skip to the next table break (i.e. a Descriptor with help == 0)
1984  if (rowdesc != 0)
1985  {
1986  while (tablestart->help != 0 && tablestart->shortopt != 0)
1987  ++tablestart;
1988  }
1989 
1990  // Find the next table after the break (if any)
1991  while (tablestart->help == 0 && tablestart->shortopt != 0)
1992  ++tablestart;
1993 
1994  restartTable();
1995  return rowstart != 0;
1996  }
1997 
2002  {
2003  rowdesc = tablestart;
2004  rowstart = tablestart->help;
2005  ptr = 0;
2006  }
2007 
2013  bool nextRow()
2014  {
2015  if (ptr == 0)
2016  {
2017  restartRow();
2018  return rowstart != 0;
2019  }
2020 
2021  while (*ptr != 0 && *ptr != '\n')
2022  ++ptr;
2023 
2024  if (*ptr == 0)
2025  {
2026  if ((rowdesc + 1)->help == 0) // table break
2027  return false;
2028 
2029  ++rowdesc;
2030  rowstart = rowdesc->help;
2031  }
2032  else // if (*ptr == '\n')
2033  {
2034  rowstart = ptr + 1;
2035  }
2036 
2037  restartRow();
2038  return true;
2039  }
2040 
2044  void restartRow()
2045  {
2046  ptr = rowstart;
2047  col = -1;
2048  len = 0;
2049  screenlen = 0;
2050  max_line_in_block = 0;
2051  line_in_block = 0;
2052  target_line_in_block = 0;
2053  hit_target_line = true;
2054  }
2055 
2063  bool next()
2064  {
2065  if (ptr == 0)
2066  return false;
2067 
2068  if (col == -1)
2069  {
2070  col = 0;
2071  update_length();
2072  return true;
2073  }
2074 
2075  ptr += len;
2076  while (true)
2077  {
2078  switch (*ptr)
2079  {
2080  case '\v':
2081  upmax(max_line_in_block, ++line_in_block);
2082  ++ptr;
2083  break;
2084  case '\t':
2085  if (!hit_target_line) // if previous column did not have the targetline
2086  { // then "insert" a 0-length part
2087  update_length();
2088  hit_target_line = true;
2089  return true;
2090  }
2091 
2092  hit_target_line = false;
2093  line_in_block = 0;
2094  ++col;
2095  ++ptr;
2096  break;
2097  case 0:
2098  case '\n':
2099  if (!hit_target_line) // if previous column did not have the targetline
2100  { // then "insert" a 0-length part
2101  update_length();
2102  hit_target_line = true;
2103  return true;
2104  }
2105 
2106  if (++target_line_in_block > max_line_in_block)
2107  {
2108  update_length();
2109  return false;
2110  }
2111 
2112  hit_target_line = false;
2113  line_in_block = 0;
2114  col = 0;
2115  ptr = rowstart;
2116  continue;
2117  default:
2118  ++ptr;
2119  continue;
2120  } // switch
2121 
2122  if (line_in_block == target_line_in_block)
2123  {
2124  update_length();
2125  hit_target_line = true;
2126  return true;
2127  }
2128  } // while
2129  }
2130 
2135  int column()
2136  {
2137  return col;
2138  }
2139 
2144  int line()
2145  {
2146  return target_line_in_block; // NOT line_in_block !!! It would be wrong if !hit_target_line
2147  }
2148 
2152  int length()
2153  {
2154  return len;
2155  }
2156 
2162  {
2163  return screenlen;
2164  }
2165 
2169  const char* data()
2170  {
2171  return ptr;
2172  }
2173  };
2174 
2200  {
2201  static const int bufmask = 15;
2202 
2205  int lenbuf[bufmask + 1];
2209  const char* datbuf[bufmask + 1];
2216  int x;
2220  int width;
2221  int head;
2222  int tail;
2223 
2231  bool wrote_something;
2232 
2233  bool buf_empty()
2234  {
2235  return ((tail + 1) & bufmask) == head;
2236  }
2237 
2238  bool buf_full()
2239  {
2240  return tail == head;
2241  }
2242 
2243  void buf_store(const char* data, int len)
2244  {
2245  lenbuf[head] = len;
2246  datbuf[head] = data;
2247  head = (head + 1) & bufmask;
2248  }
2249 
2251  void buf_next()
2252  {
2253  tail = (tail + 1) & bufmask;
2254  }
2255 
2260  void output(IStringWriter& write, const char* data, int len)
2261  {
2262  if (buf_full())
2263  write_one_line(write);
2264 
2265  buf_store(data, len);
2266  }
2267 
2271  void write_one_line(IStringWriter& write)
2272  {
2273  if (wrote_something) // if we already wrote something, we need to start a new line
2274  {
2275  write("\n", 1);
2276  int _ = 0;
2277  indent(write, _, x);
2278  }
2279 
2280  if (!buf_empty())
2281  {
2282  buf_next();
2283  write(datbuf[tail], lenbuf[tail]);
2284  }
2285 
2286  wrote_something = true;
2287  }
2288  public:
2289 
2295  void flush(IStringWriter& write)
2296  {
2297  if (buf_empty())
2298  return;
2299  int _ = 0;
2300  indent(write, _, x);
2301  wrote_something = false;
2302  while (!buf_empty())
2303  write_one_line(write);
2304  write("\n", 1);
2305  }
2306 
2325  void process(IStringWriter& write, const char* data, int len)
2326  {
2327  wrote_something = false;
2328 
2329  while (len > 0)
2330  {
2331  if (len <= width) // quick test that works because utf8width <= len (all wide chars have at least 2 bytes)
2332  {
2333  output(write, data, len);
2334  len = 0;
2335  }
2336  else // if (len > width) it's possible (but not guaranteed) that utf8len > width
2337  {
2338  int utf8width = 0;
2339  int maxi = 0;
2340  while (maxi < len && utf8width < width)
2341  {
2342  int charbytes = 1;
2343  unsigned ch = (unsigned char) data[maxi];
2344  if (ch > 0xC1) // everything <= 0xC1 (yes, even 0xC1 itself) is not a valid UTF-8 start byte
2345  {
2346  // int __builtin_clz (unsigned int x)
2347  // Returns the number of leading 0-bits in x, starting at the most significant bit
2348  unsigned mask = (unsigned) -1 >> __builtin_clz(ch ^ 0xff);
2349  ch = ch & mask; // mask out length bits, we don't verify their correctness
2350  while ((maxi + charbytes < len) && //
2351  (((unsigned char) data[maxi + charbytes] ^ 0x80) <= 0x3F)) // while next byte is continuation byte
2352  {
2353  ch = (ch << 6) ^ (unsigned char) data[maxi + charbytes] ^ 0x80; // add continuation to char code
2354  ++charbytes;
2355  }
2356  // ch is the decoded unicode code point
2357  if (ch >= 0x1100 && isWideChar(ch)) // the test for 0x1100 is here to avoid the function call in the Latin case
2358  {
2359  if (utf8width + 2 > width)
2360  break;
2361  ++utf8width;
2362  }
2363  }
2364  ++utf8width;
2365  maxi += charbytes;
2366  }
2367 
2368  // data[maxi-1] is the last byte of the UTF-8 sequence of the last character that fits
2369  // onto the 1st line. If maxi == len, all characters fit on the line.
2370 
2371  if (maxi == len)
2372  {
2373  output(write, data, len);
2374  len = 0;
2375  }
2376  else // if (maxi < len) at least 1 character (data[maxi] that is) doesn't fit on the line
2377  {
2378  int i;
2379  for (i = maxi; i >= 0; --i)
2380  if (data[i] == ' ')
2381  break;
2382 
2383  if (i >= 0)
2384  {
2385  output(write, data, i);
2386  data += i + 1;
2387  len -= i + 1;
2388  }
2389  else // did not find a space to split at => split before data[maxi]
2390  { // data[maxi] is always the beginning of a character, never a continuation byte
2391  output(write, data, maxi);
2392  data += maxi;
2393  len -= maxi;
2394  }
2395  }
2396  }
2397  }
2398  if (!wrote_something) // if we didn't already write something to make space in the buffer
2399  write_one_line(write); // write at most one line of actual output
2400  }
2401 
2408  LineWrapper(int x1, int x2) :
2409  x(x1), width(x2 - x1), head(0), tail(bufmask)
2410  {
2411  if (width < 2) // because of wide characters we need at least width 2 or the code breaks
2412  width = 2;
2413  }
2414  };
2415 
2421  static void printUsage(IStringWriter& write, const Descriptor usage[], int width = 80, //
2422  int last_column_min_percent = 50, int last_column_own_line_max_percent = 75)
2423  {
2424  if (width < 1) // protect against nonsense values
2425  width = 80;
2426 
2427  if (width > 10000) // protect against overflow in the following computation
2428  width = 10000;
2429 
2430  int last_column_min_width = ((width * last_column_min_percent) + 50) / 100;
2431  int last_column_own_line_max_width = ((width * last_column_own_line_max_percent) + 50) / 100;
2432  if (last_column_own_line_max_width == 0)
2433  last_column_own_line_max_width = 1;
2434 
2435  LinePartIterator part(usage);
2436  while (part.nextTable())
2437  {
2438 
2439  /***************** Determine column widths *******************************/
2440 
2441  const int maxcolumns = 8; // 8 columns are enough for everyone
2442  int col_width[maxcolumns];
2443  int lastcolumn;
2444  int leftwidth;
2445  int overlong_column_threshold = 10000;
2446  do
2447  {
2448  lastcolumn = 0;
2449  for (int i = 0; i < maxcolumns; ++i)
2450  col_width[i] = 0;
2451 
2452  part.restartTable();
2453  while (part.nextRow())
2454  {
2455  while (part.next())
2456  {
2457  if (part.column() < maxcolumns)
2458  {
2459  upmax(lastcolumn, part.column());
2460  if (part.screenLength() < overlong_column_threshold)
2461  // We don't let rows that don't use table separators (\t or \v) influence
2462  // the width of column 0. This allows the user to interject section headers
2463  // or explanatory paragraphs that do not participate in the table layout.
2464  if (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
2465  || part.data()[part.length()] == '\v')
2466  upmax(col_width[part.column()], part.screenLength());
2467  }
2468  }
2469  }
2470 
2471  /*
2472  * If the last column doesn't fit on the same
2473  * line as the other columns, we can fix that by starting it on its own line.
2474  * However we can't do this for any of the columns 0..lastcolumn-1.
2475  * If their sum exceeds the maximum width we try to fix this by iteratively
2476  * ignoring the widest line parts in the width determination until
2477  * we arrive at a series of column widths that fit into one line.
2478  * The result is a layout where everything is nicely formatted
2479  * except for a few overlong fragments.
2480  * */
2481 
2482  leftwidth = 0;
2483  overlong_column_threshold = 0;
2484  for (int i = 0; i < lastcolumn; ++i)
2485  {
2486  leftwidth += col_width[i];
2487  upmax(overlong_column_threshold, col_width[i]);
2488  }
2489 
2490  } while (leftwidth > width);
2491 
2492  /**************** Determine tab stops and last column handling **********************/
2493 
2494  int tabstop[maxcolumns];
2495  tabstop[0] = 0;
2496  for (int i = 1; i < maxcolumns; ++i)
2497  tabstop[i] = tabstop[i - 1] + col_width[i - 1];
2498 
2499  int rightwidth = width - tabstop[lastcolumn];
2500  bool print_last_column_on_own_line = false;
2501  if (rightwidth < last_column_min_width && rightwidth < col_width[lastcolumn])
2502  {
2503  print_last_column_on_own_line = true;
2504  rightwidth = last_column_own_line_max_width;
2505  }
2506 
2507  // If lastcolumn == 0 we must disable print_last_column_on_own_line because
2508  // otherwise 2 copies of the last (and only) column would be output.
2509  // Actually this is just defensive programming. It is currently not
2510  // possible that lastcolumn==0 and print_last_column_on_own_line==true
2511  // at the same time, because lastcolumn==0 => tabstop[lastcolumn] == 0 =>
2512  // rightwidth==width => rightwidth>=last_column_min_width (unless someone passes
2513  // a bullshit value >100 for last_column_min_percent) => the above if condition
2514  // is false => print_last_column_on_own_line==false
2515  if (lastcolumn == 0)
2516  print_last_column_on_own_line = false;
2517 
2518  LineWrapper lastColumnLineWrapper(width - rightwidth, width);
2519  LineWrapper interjectionLineWrapper(0, width);
2520 
2521  part.restartTable();
2522 
2523  /***************** Print out all rows of the table *************************************/
2524 
2525  while (part.nextRow())
2526  {
2527  int x = -1;
2528  while (part.next())
2529  {
2530  if (part.column() > lastcolumn)
2531  continue; // drop excess columns (can happen if lastcolumn == maxcolumns-1)
2532 
2533  if (part.column() == 0)
2534  {
2535  if (x >= 0)
2536  write("\n", 1);
2537  x = 0;
2538  }
2539 
2540  indent(write, x, tabstop[part.column()]);
2541 
2542  if ((part.column() < lastcolumn)
2543  && (part.column() > 0 || part.line() > 0 || part.data()[part.length()] == '\t'
2544  || part.data()[part.length()] == '\v'))
2545  {
2546  write(part.data(), part.length());
2547  x += part.screenLength();
2548  }
2549  else // either part.column() == lastcolumn or we are in the special case of
2550  // an interjection that doesn't contain \v or \t
2551  {
2552  // NOTE: This code block is not necessarily executed for
2553  // each line, because some rows may have fewer columns.
2554 
2555  LineWrapper& lineWrapper = (part.column() == 0) ? interjectionLineWrapper : lastColumnLineWrapper;
2556 
2557  if (!print_last_column_on_own_line)
2558  lineWrapper.process(write, part.data(), part.length());
2559  }
2560  } // while
2561 
2562  if (print_last_column_on_own_line)
2563  {
2564  part.restartRow();
2565  while (part.next())
2566  {
2567  if (part.column() == lastcolumn)
2568  {
2569  write("\n", 1);
2570  int _ = 0;
2571  indent(write, _, width - rightwidth);
2572  lastColumnLineWrapper.process(write, part.data(), part.length());
2573  }
2574  }
2575  }
2576 
2577  write("\n", 1);
2578  lastColumnLineWrapper.flush(write);
2579  interjectionLineWrapper.flush(write);
2580  }
2581  }
2582  }
2583 
2584 }
2585 ;
2586 
2784 template<typename OStream>
2785 void printUsage(OStream& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2786  int last_column_own_line_max_percent = 75)
2787 {
2789  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2790 }
2791 
2792 template<typename Function>
2793 void printUsage(Function* prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2794  int last_column_own_line_max_percent = 75)
2795 {
2797  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2798 }
2799 
2800 template<typename Temporary>
2801 void printUsage(const Temporary& prn, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2802  int last_column_own_line_max_percent = 75)
2803 {
2805  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2806 }
2807 
2808 template<typename Syscall>
2809 void printUsage(Syscall* prn, int fd, const Descriptor usage[], int width = 80, int last_column_min_percent = 50,
2810  int last_column_own_line_max_percent = 75)
2811 {
2813  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2814 }
2815 
2816 template<typename Function, typename Stream>
2817 void printUsage(Function* prn, Stream* stream, const Descriptor usage[], int width = 80, int last_column_min_percent =
2818  50,
2819  int last_column_own_line_max_percent = 75)
2820 {
2822  PrintUsageImplementation::printUsage(write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
2823 }
2824 
2825 }
2826 // namespace option
2827 
2828 #endif /* OPTIONPARSER_H_ */
const Descriptor * desc
Pointer to this Option's Descriptor.
Definition: optionparser.h:457
bool isLast() const
Returns true iff this is the last element of the linked list.
Definition: optionparser.h:584
void parse(const Descriptor usage[], int argc, const char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX parse() (gnu==false).
Definition: optionparser.h:1172
const char *const shortopt
Each char in this string will be accepted as a short option character.
Definition: optionparser.h:350
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
Definition: optionparser.h:1766
int index() const
Returns Descriptor::index of this Option's Descriptor, or -1 if this Option is invalid (unused)...
Definition: optionparser.h:534
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.
Definition: optionparser.h:1489
Parser()
Creates a new Parser.
Definition: optionparser.h:1065
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.
Definition: optionparser.h:1496
Function * fwrite
Definition: optionparser.h:1807
unsigned options_max
Number of elements needed for an options[] array to be used for parsing the same argument vectors tha...
Definition: optionparser.h:948
int optionsCount()
Returns the number of valid Option objects in buffer[].
Definition: optionparser.h:1194
void restartTable()
Reset iteration to the beginning of the current table.
Definition: optionparser.h:2001
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)
Definition: optionparser.h:2421
NetworKit::index index
Definition: BloomFilter.h:16
Functions for checking the validity of option arguments.
Definition: optionparser.h:883
bool nextTable()
Moves iteration to the next table (if any).
Definition: optionparser.h:1980
const Temporary & userstream
Definition: optionparser.h:1764
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.
Definition: optionparser.h:1074
const unsigned index
Index of this option's linked list in the array filled in by the parser.
Definition: optionparser.h:328
static void indent(IStringWriter &write, int &x, int want_x)
Definition: optionparser.h:1841
static ArgStatus Required(const OptionParser::Option &option, bool msg)
Definition: optionparser.h:903
Stats(const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX Stats(...) (gnu==false).
Definition: optionparser.h:983
static void upmax(int &i1, int i2)
Definition: optionparser.h:1825
int count()
Returns the number of times this Option (or others with the same Descriptor::index) occurs in the arg...
Definition: optionparser.h:551
bool error()
Returns true if an unrecoverable error occurred while parsing options.
Definition: optionparser.h:1257
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:397
void parse(const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX parse() (gnu==false) with non-const argv.
Definition: optionparser.h:1179
void operator=(const Option &orig)
Makes *this a copy of orig except for the linked list pointers.
Definition: optionparser.h:772
const OptionParser::Descriptor usage[]
Definition: Unittests-X.cpp:54
TemporaryWriter(const Temporary &u)
Definition: optionparser.h:1771
Stats(const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX Stats(...) (gnu==false) with non-const argv.
Definition: optionparser.h:991
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
Definition: optionparser.h:1724
int length()
Returns the length of the part pointed to by data() in raw chars (not UTF-8 characters).
Definition: optionparser.h:2152
NetworKit::count count
Definition: BloomFilter.h:17
Function * write
Definition: optionparser.h:1722
Option * last()
Returns a pointer to the last element of the linked list.
Definition: optionparser.h:624
const char ** nonOptions()
Returns a pointer to an array of non-option arguments (only valid if nonOptionsCount() >0 )...
Definition: optionparser.h:1229
static ArgStatus None(const Option &, bool)
For options that don't take an argument: Returns ARG_NONE.
Definition: optionparser.h:888
FunctionWriter(Function *w)
Definition: optionparser.h:1729
Option * nextwrap()
Returns a pointer to the next element of the linked list with wrap-around from last() to first()...
Definition: optionparser.h:676
const char *const longopt
The long option name (without the leading – ).
Definition: optionparser.h:385
Stats()
Creates a Stats object with counts set to 1 (for the sentinel element).
Definition: optionparser.h:953
Syscall * write
Definition: optionparser.h:1786
virtual void operator()(const char *, int)
Writes the given number of chars beginning at the given pointer somewhere.
Definition: optionparser.h:1709
Definition: optionparser.h:1698
bool finished(int numargs, const char **args)
Called by Parser::workhorse() after finishing the parse.
Definition: optionparser.h:1474
void add(const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX add() (gnu==false) with non-const argv.
Definition: optionparser.h:1025
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:967
unsigned buffer_max
Number of elements needed for a buffer[] array to be used for parsing the same argument vectors that ...
Definition: optionparser.h:935
Parser(const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX Parser(...) (gnu==false) with non-const argv.
Definition: optionparser.h:1098
Stats(bool gnu, const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
Stats(...) with non-const argv.
Definition: optionparser.h:975
int screenLength()
Returns the width in screen columns of the part pointed to by data().
Definition: optionparser.h:2161
bool isFirst() const
Returns true iff this is the first element of the linked list.
Definition: optionparser.h:571
The argument is acceptable for the option.
Definition: optionparser.h:248
OStreamWriter(OStream &o)
Definition: optionparser.h:1750
SyscallWriter(Syscall *w, int f)
Definition: optionparser.h:1794
StreamWriter(Function *w, Stream *s)
Definition: optionparser.h:1815
ArgStatus
Possible results when checking if an argument is valid for a certain option.
Definition: optionparser.h:243
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
Definition: optionparser.h:1810
void append(Option *new_last)
Makes new_last the new last() by chaining it into the list after last().
Definition: optionparser.h:691
A parsed option from the command line together with its argument if it has one.
Definition: optionparser.h:434
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
Definition: optionparser.h:1745
int type() const
Returns Descriptor::type of this Option's Descriptor, or 0 if this Option is invalid (unused)...
Definition: optionparser.h:525
bool perform(Option &option)
Called by Parser::workhorse() for each Option that has been successfully parsed (including unknown op...
Definition: optionparser.h:1456
static bool isWideChar(unsigned ch)
Returns true if ch is the unicode code point of a wide character.
Definition: optionparser.h:1877
const char * data()
Returns the current part of the iteration.
Definition: optionparser.h:2169
void add(const Descriptor usage[], int argc, const char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
POSIX add() (gnu==false).
Definition: optionparser.h:1018
void process(IStringWriter &write, const char *data, int len)
Process, wrap and output the next piece of data.
Definition: optionparser.h:2325
Definition: optionparser.h:1367
Option()
Creates a new Option that is a one-element linked list and has NULL desc, name, arg and namelen...
Definition: optionparser.h:747
LineWrapper(int x1, int x2)
Constructs a LineWrapper that wraps its output to fit into screen columns x1 (incl.) to x2 (excl.).
Definition: optionparser.h:2408
StoreOptionAction(Parser &parser_, Option options_[], Option buffer_[], int bufmax_)
Number of slots in buffer. -1 means "large enough".
Definition: optionparser.h:1444
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:283
Definition: optionparser.h:1403
The argument is not acceptable but that's non-fatal because the option's argument is optional...
Definition: optionparser.h:250
Determines the minimum lengths of the buffer and options arrays used for Parser.
Definition: optionparser.h:924
int column()
Returns the index (counting from 0) of the column in which the part pointed to by data() is located...
Definition: optionparser.h:2135
int line()
Returns the index (counting from 0) of the line within the current column this part belongs to...
Definition: optionparser.h:2144
Parser(const Descriptor usage[], int argc, const char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
POSIX Parser(...) (gnu==false).
Definition: optionparser.h:1090
OStream & ostream
Definition: optionparser.h:1743
CountOptionsAction(unsigned *buffer_max_)
Creates a new CountOptionsAction that will increase *buffer_max_ for each parsed Option.
Definition: optionparser.h:1411
Describes an option, its help text (usage) and how it should be parsed.
Definition: optionparser.h:307
virtual bool finished(int numargs, const char **args)
Called by Parser::workhorse() after finishing the parse.
Definition: optionparser.h:1390
Stream * stream
Definition: optionparser.h:1808
Definition: optionparser.h:1430
LinePartIterator(const Descriptor usage[])
Creates an iterator for usage.
Definition: optionparser.h:1969
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:762
int nonOptionsCount()
Returns the number of non-option arguments that remained at the end of the most recent parse() that a...
Definition: optionparser.h:1213
const char * help
The usage text associated with the options in this Descriptor.
Definition: optionparser.h:414
const char * nonOption(int i)
Returns nonOptions()[i] (without checking if i is in range!).
Definition: optionparser.h:1237
void flush(IStringWriter &write)
Writes out all remaining data from the LineWrapper using write.
Definition: optionparser.h:2295
bool perform(Option &)
Called by Parser::workhorse() for each Option that has been successfully parsed (including unknown op...
Definition: optionparser.h:1416
const char * name
The name of the option as used on the command line.
Definition: optionparser.h:473
Option * first()
Returns a pointer to the first element of the linked list.
Definition: optionparser.h:600
Checks argument vectors for validity and parses them into data structures that are easier to work wit...
Definition: optionparser.h:1054
void parse(bool gnu, const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
parse() with non-const argv.
Definition: optionparser.h:1165
virtual bool perform(Option &)
Called by Parser::workhorse() for each Option that has been successfully parsed (including unknown op...
Definition: optionparser.h:1377
Option * next()
Returns a pointer to the next element of the linked list or NULL if called on last().
Definition: optionparser.h:663
int namelen
The length of the option name.
Definition: optionparser.h:502
bool next()
Moves iteration to the next part (if any).
Definition: optionparser.h:2063
The argument is not acceptable and that's fatal.
Definition: optionparser.h:252
Option(const Option &orig)
Makes *this a copy of orig except for the linked list pointers.
Definition: optionparser.h:782
bool nextRow()
Moves iteration to the next row (if any).
Definition: optionparser.h:2013
Option * prevwrap()
Returns a pointer to the previous element of the linked list with wrap-around from first() to last()...
Definition: optionparser.h:650
void restartRow()
Reset iteration to the beginning of the current row.
Definition: optionparser.h:2044
Parser(bool gnu, const Descriptor usage[], int argc, char **argv, Option options[], Option buffer[], int min_abbr_len=0, bool single_minus_longopt=false, int bufmax=-1)
Parser(...) with non-const argv.
Definition: optionparser.h:1082
const int type
Used to distinguish between options with the same NetworKit C++ mainpage.
Definition: optionparser.h:337
static ArgStatus Optional(const Option &option, bool)
Returns ARG_OK if the argument is attached and ARG_IGNORE otherwise.
Definition: optionparser.h:894
virtual void operator()(const char *str, int size)
Writes the given number of chars beginning at the given pointer somewhere.
Definition: optionparser.h:1789
const char * arg
Pointer to this Option's argument (if any).
Definition: optionparser.h:481
void add(bool gnu, const Descriptor usage[], int argc, char **argv, int min_abbr_len=0, bool single_minus_longopt=false)
add() with non-const argv.
Definition: optionparser.h:1011
Option * prev()
Returns a pointer to the previous element of the linked list or NULL if called on first()...
Definition: optionparser.h:637
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...
Definition: optionparser.h:2785
The option does not take an argument.
Definition: optionparser.h:246