Bug 1145882 - Part 2/2 - Add -v and --version. r=evilpie
authorSean Stangl <sstangl@mozilla.com>
Fri, 20 Mar 2015 15:51:42 -0700
changeset 264883 96aef1037d394e92815c29220b5e80441660dcbd
parent 264882 4f8bbef857155fbee1d064e014b22dd72512b389
child 264884 2b7ca45e09681b15fb67163b93998dbd06fe4e71
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1145882
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1145882 - Part 2/2 - Add -v and --version. r=evilpie
js/src/shell/js.cpp
js/src/shell/jsoptparse.cpp
js/src/shell/jsoptparse.h
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -6240,17 +6240,17 @@ main(int argc, char **argv, char **envp)
     {
         return EXIT_FAILURE;
     }
 
     op.setArgTerminatesOptions("script", true);
     op.setArgCapturesRest("scriptArgs");
 
     switch (op.parseArgs(argc, argv)) {
-      case OptionParser::ParseHelp:
+      case OptionParser::EarlyExit:
         return EXIT_SUCCESS;
       case OptionParser::ParseError:
         op.printHelp(argv[0]);
         return EXIT_FAILURE;
       case OptionParser::Fail:
         return EXIT_FAILURE;
       case OptionParser::Okay:
         break;
--- a/js/src/shell/jsoptparse.cpp
+++ b/js/src/shell/jsoptparse.cpp
@@ -180,18 +180,18 @@ OptionParser::printHelp(const char *prog
     }
 
     if (descr) {
         putchar('\n');
         PrintParagraph(descr, 2, descrWidth, true);
         putchar('\n');
     }
 
-    if (ver)
-        printf("\nVersion: %s\n\n", ver);
+    if (version)
+        printf("\nVersion: %s\n\n", version);
 
     if (!arguments.empty()) {
         printf("Arguments:\n");
 
         static const char fmt[] = "  %s ";
         size_t fmtChars = sizeof(fmt) - 2;
         size_t lhsLen = 0;
         for (Option **it = arguments.begin(), **end = arguments.end(); it != end; ++it)
@@ -245,17 +245,25 @@ OptionParser::printHelp(const char *prog
             }
             for (; chars < lhsLen; ++chars)
                 putchar(' ');
             PrintParagraph(opt->help, lhsLen, helpWidth, false);
             putchar('\n');
         }
     }
 
-    return ParseHelp;
+    return EarlyExit;
+}
+
+OptionParser::Result
+OptionParser::printVersion()
+{
+    MOZ_ASSERT(version);
+    printf("%s\n", version);
+    return EarlyExit;
 }
 
 OptionParser::Result
 OptionParser::extractValue(size_t argc, char **argv, size_t *i, char **value)
 {
     MOZ_ASSERT(*i < argc);
     char *eq = strchr(argv[*i], '=');
     if (eq) {
@@ -279,16 +287,18 @@ OptionParser::handleOption(Option *opt, 
     if (opt->getTerminatesOptions())
         *optionsAllowed = false;
 
     switch (opt->kind) {
       case OptionKindBool:
       {
         if (opt == &helpOption)
             return printHelp(argv[0]);
+        if (opt == &versionOption)
+            return printVersion();
         opt->asBoolOption()->value = true;
         return Okay;
       }
       /*
        * Valued options are allowed to specify their values either via
        * successive arguments or a single --longflag=value argument.
        */
       case OptionKindString:
@@ -468,16 +478,19 @@ OptionParser::~OptionParser()
 Option *
 OptionParser::findOption(char shortflag)
 {
     for (Option **it = options.begin(), **end = options.end(); it != end; ++it) {
         if ((*it)->shortflag == shortflag)
             return *it;
     }
 
+    if (versionOption.shortflag == shortflag)
+        return &versionOption;
+
     return helpOption.shortflag == shortflag ? &helpOption : nullptr;
 }
 
 const Option *
 OptionParser::findOption(char shortflag) const
 {
     return const_cast<OptionParser *>(this)->findOption(shortflag);
 }
@@ -498,16 +511,19 @@ OptionParser::findOption(const char *lon
                 return *it;
         } else {
             if (strcmp(target, longflag) == 0)
                 return *it;
         }
   no_match:;
     }
 
+    if (strcmp(versionOption.longflag, longflag) == 0)
+        return &versionOption;
+
     return strcmp(helpOption.longflag, longflag) ? nullptr : &helpOption;
 }
 
 const Option *
 OptionParser::findOption(const char *longflag) const
 {
     return const_cast<OptionParser *>(this)->findOption(longflag);
 }
--- a/js/src/shell/jsoptparse.h
+++ b/js/src/shell/jsoptparse.h
@@ -188,29 +188,31 @@ class MultiStringRange
 class OptionParser
 {
   public:
     enum Result
     {
         Okay = 0,
         Fail,       /* As in, allocation fail. */
         ParseError, /* Successfully parsed but with an error. */
-        ParseHelp   /* Aborted on help flag. */
+        EarlyExit   /* Successfully parsed but exits the program,
+                     * for example with --help and --version. */
     };
 
   private:
     typedef Vector<detail::Option *, 0, SystemAllocPolicy> Options;
     typedef detail::Option Option;
     typedef detail::BoolOption BoolOption;
 
     Options     options;
     Options     arguments;
     BoolOption  helpOption;
+    BoolOption  versionOption;
     const char  *usage;
-    const char  *ver;
+    const char  *version;
     const char  *descr;
     size_t      descrWidth;
     size_t      helpWidth;
     size_t      nextArgument;
 
     // If '--' is passed, all remaining arguments should be interpreted as the
     // argument at index 'restArgument'. Defaults to the next unassigned
     // argument.
@@ -229,28 +231,30 @@ class OptionParser
     Result error(const char *fmt, ...);
     Result extractValue(size_t argc, char **argv, size_t *i, char **value);
     Result handleArg(size_t argc, char **argv, size_t *i, bool *optsAllowed);
     Result handleOption(Option *opt, size_t argc, char **argv, size_t *i, bool *optsAllowed);
 
   public:
     explicit OptionParser(const char *usage)
       : helpOption('h', "help", "Display help information"),
-        usage(usage), ver(nullptr), descr(nullptr), descrWidth(80), helpWidth(80),
+        versionOption('v', "version", "Display version information and exit"),
+        usage(usage), version(nullptr), descr(nullptr), descrWidth(80), helpWidth(80),
         nextArgument(0), restArgument(-1)
     {}
 
     ~OptionParser();
 
     Result parseArgs(int argc, char **argv);
     Result printHelp(const char *progname);
+    Result printVersion();
 
     /* Metadata */
 
-    void setVersion(const char *version) { ver = version; }
+    void setVersion(const char *v) { version = v; }
     void setHelpWidth(size_t width) { helpWidth = width; }
     void setDescriptionWidth(size_t width) { descrWidth = width; }
     void setDescription(const char *description) { descr = description; }
     void setHelpOption(char shortflag, const char *longflag, const char *help);
     void setArgTerminatesOptions(const char *name, bool enabled);
     void setArgCapturesRest(const char *name);
 
     /* Arguments: no further arguments may be added after a variadic argument. */