LCOV - app.info - js/src/shell/jsoptparse.h

LCOV - code coverage report
| Current view: | directory - js/src/shell - jsoptparse.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 52 | 44 | 84.6 %
| Date: | 2012-04-07 | Functions: | 37 | 27 | 73.0 %

           1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=8 sw=4 et tw=99:
           3                 :  *
           4                 :  * ***** BEGIN LICENSE BLOCK *****
           5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           6                 :  *
           7                 :  * The contents of this file are subject to the Mozilla Public License Version
           8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           9                 :  * the License. You may obtain a copy of the License at
          10                 :  * http://www.mozilla.org/MPL/
          11                 :  *
          12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          14                 :  * for the specific language governing rights and limitations under the
          15                 :  * License.
          16                 :  *
          17                 :  * The Original Code is SpiderMonkey JavaScript shell.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * Mozilla Corporation.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 2010
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *   Christopher D. Leary <cdleary@mozilla.com>
          26                 :  *
          27                 :  * Alternatively, the contents of this file may be used under the terms of
          28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          31                 :  * of those above. If you wish to allow use of your version of this file only
          32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          33                 :  * use your version of this file under the terms of the MPL, indicate your
          34                 :  * decision by deleting the provisions above and replace them with the notice
          35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          36                 :  * the provisions above, a recipient may use your version of this file under
          37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          38                 :  *
          39                 :  * ***** END LICENSE BLOCK ***** */
          40                 :
          41                 : #ifndef jsoptparse_h__
          42                 : #define jsoptparse_h__
          43                 :
          44                 : #include <stdio.h>
          45                 :
          46                 : #include "js/Vector.h"
          47                 : #include "jsalloc.h"
          48                 :
          49                 : namespace js {
          50                 : namespace cli {
          51                 :
          52                 : namespace detail {
          53                 :
          54                 : struct BoolOption;
          55                 : struct MultiStringOption;
          56                 : struct ValuedOption;
          57                 : struct StringOption;
          58                 : struct IntOption;
          59                 :
          60                 : enum OptionKind
          61                 : {
          62                 :     OptionKindBool,
          63                 :     OptionKindString,
          64                 :     OptionKindInt,
          65                 :     OptionKindMultiString,
          66                 :     OptionKindInvalid
          67                 : };
          68                 :
          69                 : struct Option
          70                 : {
          71                 :     const char  *longflag;
          72                 :     const char  *help;
          73                 :     OptionKind  kind;
          74                 :     char        shortflag;
          75                 :     bool        terminatesOptions;
          76                 :
          77          317322 :     Option(OptionKind kind, char shortflag, const char *longflag, const char *help)
          78          317322 :       : longflag(longflag), help(help), kind(kind), shortflag(shortflag), terminatesOptions(false)
          79          317322 :     {}
          80                 :
          81                 :     virtual ~Option() = 0;
          82                 :
          83           18666 :     void setTerminatesOptions(bool enabled) { terminatesOptions = enabled; }
          84           95918 :     bool getTerminatesOptions() const { return terminatesOptions; }
          85                 :
          86               0 :     virtual bool isValued() const { return false; }
          87                 :
          88                 :     /* Only some valued options are variadic (like MultiStringOptions). */
          89           18666 :     virtual bool isVariadic() const { return false; }
          90                 :
          91                 :     /*
          92                 :      * For arguments, the shortflag field is used to indicate whether the
          93                 :      * argument is optional.
          94                 :      */
          95                 :     bool isOptional() { return shortflag; }
          96                 :
          97               0 :     void setFlagInfo(char shortflag, const char *longflag, const char *help) {
          98               0 :         this->shortflag = shortflag;
          99               0 :         this->longflag = longflag;
         100               0 :         this->help = help;
         101               0 :     }
         102                 :
         103                 :     ValuedOption *asValued();
         104                 :     const ValuedOption *asValued() const;
         105                 :
         106                 : #define OPTION_CONVERT_DECL(__cls) \
         107                 :     bool is##__cls##Option() const; \
         108                 :     __cls##Option *as##__cls##Option(); \
         109                 :     const __cls##Option *as##__cls##Option() const;
         110                 :
         111                 :     OPTION_CONVERT_DECL(Bool)
         112                 :     OPTION_CONVERT_DECL(String)
         113                 :     OPTION_CONVERT_DECL(Int)
         114                 :     OPTION_CONVERT_DECL(MultiString)
         115                 : };
         116                 :
         117          317322 : inline Option::~Option() {}
         118                 :
         119                 : struct BoolOption : public Option
         120                 : {
         121                 :     size_t  argno;
         122                 :     bool    value;
         123                 :
         124          205326 :     BoolOption(char shortflag, const char *longflag, const char *help)
         125          205326 :       : Option(OptionKindBool, shortflag, longflag, help), value(false)
         126          205326 :     {}
         127                 :
         128          205326 :     virtual ~BoolOption() {}
         129                 : };
         130                 :
         131                 : struct ValuedOption : public Option
         132                 : {
         133                 :     const char *metavar;
         134                 :
         135          111996 :     ValuedOption(OptionKind kind, char shortflag, const char *longflag, const char *help,
         136                 :                  const char *metavar)
         137          111996 :       : Option(kind, shortflag, longflag, help), metavar(metavar)
         138          111996 :     {}
         139                 :
         140                 :     virtual ~ValuedOption() = 0;
         141               0 :     virtual bool isValued() const { return true; }
         142                 : };
         143                 :
         144          111996 : inline ValuedOption::~ValuedOption() {}
         145                 :
         146                 : struct StringOption : public ValuedOption
         147                 : {
         148                 :     const char *value;
         149                 :
         150           37332 :     StringOption(char shortflag, const char *longflag, const char *help, const char *metavar)
         151           37332 :       : ValuedOption(OptionKindString, shortflag, longflag, help, metavar), value(NULL)
         152           37332 :     {}
         153                 :
         154           37332 :     virtual ~StringOption() {}
         155                 : };
         156                 :
         157                 : struct IntOption : public ValuedOption
         158                 : {
         159                 :     int value;
         160                 :
         161           18666 :     IntOption(char shortflag, const char *longflag, const char *help, const char *metavar,
         162                 :               int defaultValue)
         163           18666 :       : ValuedOption(OptionKindInt, shortflag, longflag, help, metavar), value(defaultValue)
         164           18666 :     {}
         165                 :
         166           18666 :     virtual ~IntOption() {}
         167                 : };
         168                 :
         169                 : struct StringArg
         170           74664 : {
         171                 :     char    *value;
         172                 :     size_t  argno;
         173                 :
         174           55998 :     StringArg(char *value, size_t argno) : value(value), argno(argno) {}
         175                 : };
         176                 :
         177                 : struct MultiStringOption : public ValuedOption
         178                 : {
         179                 :     Vector<StringArg, 0, SystemAllocPolicy> strings;
         180                 :
         181           55998 :     MultiStringOption(char shortflag, const char *longflag, const char *help, const char *metavar)
         182           55998 :       : ValuedOption(OptionKindMultiString, shortflag, longflag, help, metavar)
         183           55998 :     {}
         184                 :
         185           55998 :     virtual ~MultiStringOption() {}
         186                 :
         187               0 :     virtual bool isVariadic() const { return true; }
         188                 : };
         189                 :
         190                 : } /* namespace detail */
         191                 :
         192                 : class MultiStringRange
         193                 : {
         194                 :     typedef detail::StringArg StringArg;
         195                 :     const StringArg *cur;
         196                 :     const StringArg *end;
         197                 :
         198                 :   public:
         199           55998 :     explicit MultiStringRange(const StringArg *cur, const StringArg *end)
         200           55998 :       : cur(cur), end(end) {
         201           55998 :         JS_ASSERT(end - cur >= 0);
         202           55998 :     }
         203                 :
         204          426753 :     bool empty() const { return cur == end; }
         205           55143 :     void popFront() { JS_ASSERT(!empty()); ++cur; }
         206           55998 :     char *front() const { JS_ASSERT(!empty()); return cur->value; }
         207           74664 :     size_t argno() const { JS_ASSERT(!empty()); return cur->argno; }
         208                 : };
         209                 :
         210                 : /*
         211                 :  * Builder for describing a command line interface and parsing the resulting
         212                 :  * specification.
         213                 :  *
         214                 :  * - A multi-option is an option that can appear multiple times and still
         215                 :  *   parse as valid command line arguments.
         216                 :  * - An "optional argument" is supported for backwards compatibility with prior
         217                 :  *   command line interface usage. Once one optional argument has been added,
         218                 :  *   *only* optional arguments may be added.
         219                 :  */
         220                 : class OptionParser
         221                 : {
         222                 :   public:
         223                 :     enum Result
         224                 :     {
         225                 :         Okay = 0,
         226                 :         Fail,       /* As in, allocation fail. */
         227                 :         ParseError, /* Successfully parsed but with an error. */
         228                 :         ParseHelp   /* Aborted on help flag. */
         229                 :     };
         230                 :
         231                 :   private:
         232                 :     typedef Vector<detail::Option *, 0, SystemAllocPolicy> Options;
         233                 :     typedef detail::Option Option;
         234                 :     typedef detail::BoolOption BoolOption;
         235                 :
         236                 :     Options     options;
         237                 :     Options     arguments;
         238                 :     BoolOption  helpOption;
         239                 :     const char  *usage;
         240                 :     const char  *ver;
         241                 :     const char  *descr;
         242                 :     size_t      descrWidth;
         243                 :     size_t      helpWidth;
         244                 :     size_t      nextArgument;
         245                 :
         246                 :     static const char prognameMeta[];
         247                 :
         248                 :     Option *findOption(char shortflag);
         249                 :     const Option *findOption(char shortflag) const;
         250                 :     Option *findOption(const char *longflag);
         251                 :     const Option *findOption(const char *longflag) const;
         252                 :     Option *findArgument(const char *name);
         253                 :     const Option *findArgument(const char *name) const;
         254                 :
         255                 :     Result error(const char *fmt, ...);
         256                 :     Result extractValue(size_t argc, char **argv, size_t *i, char **value);
         257                 :     Result handleArg(size_t argc, char **argv, size_t *i, bool *optsAllowed);
         258                 :     Result handleOption(Option *opt, size_t argc, char **argv, size_t *i, bool *optsAllowed);
         259                 :
         260                 :   public:
         261           18666 :     explicit OptionParser(const char *usage)
         262                 :       : helpOption('h', "help", "Display help information"),
         263           18666 :         usage(usage), ver(NULL), descr(NULL), descrWidth(80), helpWidth(80), nextArgument(0)
         264           18666 :     {}
         265                 :
         266                 :     ~OptionParser();
         267                 :
         268                 :     Result parseArgs(int argc, char **argv);
         269                 :     Result printHelp(const char *progname);
         270                 :
         271                 :     /* Metadata */
         272                 :
         273           18666 :     void setVersion(const char *version) { ver = version; }
         274           18666 :     void setHelpWidth(size_t width) { helpWidth = width; }
         275           18666 :     void setDescriptionWidth(size_t width) { descrWidth = width; }
         276           18666 :     void setDescription(const char *description) { descr = description; }
         277                 :     void setHelpOption(char shortflag, const char *longflag, const char *help);
         278                 :     void setArgTerminatesOptions(const char *name, bool enabled);
         279                 :
         280                 :     /* Arguments: no further arguments may be added after a variadic argument. */
         281                 :
         282                 :     bool addOptionalStringArg(const char *name, const char *help);
         283                 :     bool addOptionalMultiStringArg(const char *name, const char *help);
         284                 :
         285                 :     const char *getStringArg(const char *name) const;
         286                 :     MultiStringRange getMultiStringArg(const char *name) const;
         287                 :
         288                 :     /* Options */
         289                 :
         290                 :     bool addBoolOption(char shortflag, const char *longflag, const char *help);
         291                 :     bool addStringOption(char shortflag, const char *longflag, const char *help,
         292                 :                          const char *metavar);
         293                 :     bool addIntOption(char shortflag, const char *longflag, const char *help,
         294                 :                       const char *metavar, int defaultValue);
         295                 :     bool addMultiStringOption(char shortflag, const char *longflag, const char *help,
         296                 :                               const char *metavar);
         297                 :     bool addOptionalVariadicArg(const char *name);
         298                 :
         299                 :     int getIntOption(char shortflag) const;
         300                 :     int getIntOption(const char *longflag) const;
         301                 :     const char *getStringOption(char shortflag) const;
         302                 :     const char *getStringOption(const char *longflag) const;
         303                 :     bool getBoolOption(char shortflag) const;
         304                 :     bool getBoolOption(const char *longflag) const;
         305                 :     MultiStringRange getMultiStringOption(char shortflag) const;
         306                 :     MultiStringRange getMultiStringOption(const char *longflag) const;
         307                 :
         308                 :     /*
         309                 :      * Return whether the help option was present (and thus help was already
         310                 :      * displayed during parse_args).
         311                 :      */
         312                 :     bool getHelpOption() const;
         313                 : };
         314                 :
         315                 : } /* namespace cli */
         316                 : } /* namespace js */
         317                 :
         318                 : #endif /* jsoptparse_h__ */

Generated by: LCOV version 1.7