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