Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/shell/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  jsoptparse.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef shell_jsoptparse_h
#define shell_jsoptparse_h

#include <stdio.h>

#include "js/AllocPolicy.h"
#include "js/Utility.h"
#include "js/Vector.h"

namespace js {
namespace cli {

namespace detail {

// We want to use the shell's option parser before initializing the JS engine.
// The JS malloc arena isn't available yet at this point, so we use a custom
// allocation policy that uses the system malloc instead.
class OptionAllocPolicy {
 public:
  template <typename T>
  T* pod_malloc(size_t numElems) {
    size_t bytes;
    if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) {
      return nullptr;
    }
    return static_cast<T*>(malloc(bytes));
  }

  template <typename T>
  T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
    size_t bytes;
    if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(newSize, &bytes))) {
      return nullptr;
    }
    return static_cast<T*>(realloc(p, bytes));
  }

  void reportAllocOverflow() const {}
  bool checkSimulatedOOM() const { return !js::oom::ShouldFailWithOOM(); }

  template <typename T>
  void free_(T* p, size_t numElems = 0) {
    free(p);
  }
};

struct BoolOption;
struct MultiStringOption;
struct ValuedOption;
struct StringOption;
struct IntOption;

enum OptionKind {
  OptionKindBool,
  OptionKindString,
  OptionKindInt,
  OptionKindMultiString,
  OptionKindInvalid
};

struct Option {
  const char* longflag;
  const char* help;
  OptionKind kind;
  char shortflag;
  bool terminatesOptions = false;
  bool ignoresUnknownOptions = false;

  Option(OptionKind kind, char shortflag, const char* longflag,
         const char* help)
      : longflag(longflag), help(help), kind(kind), shortflag(shortflag) {}

  virtual ~Option() = 0;

  void setTerminatesOptions(bool enabled) { terminatesOptions = enabled; }
  bool getTerminatesOptions() const { return terminatesOptions; }

  void setIgnoresUnknownOptions(bool enabled) {
    ignoresUnknownOptions = enabled;
  }
  bool getIgnoresUnknownOptions() const { return ignoresUnknownOptions; }

  virtual bool isValued() const { return false; }

  /* Only some valued options are variadic (like MultiStringOptions). */
  virtual bool isVariadic() const { return false; }

  /*
   * For arguments, the shortflag field is used to indicate whether the
   * argument is optional.
   */

  bool isOptional() { return shortflag; }

  void setFlagInfo(char shortflag, const char* longflag, const char* help) {
    this->shortflag = shortflag;
    this->longflag = longflag;
    this->help = help;
  }

  ValuedOption* asValued();
  const ValuedOption* asValued() const;

#define OPTION_CONVERT_DECL(__cls)    \
  bool is##__cls##Option() const;     \
  __cls##Option* as##__cls##Option(); \
  const __cls##Option* as##__cls##Option() const;

  OPTION_CONVERT_DECL(Bool)
  OPTION_CONVERT_DECL(String)
  OPTION_CONVERT_DECL(Int)
  OPTION_CONVERT_DECL(MultiString)
};

inline Option::~Option() {}

struct BoolOption : public Option {
  size_t argno;
  bool value;

  BoolOption(char shortflag, const char* longflag, const char* help)
      : Option(OptionKindBool, shortflag, longflag, help), value(false) {}

  virtual ~BoolOption() {}
};

struct ValuedOption : public Option {
  const char* metavar;

  ValuedOption(OptionKind kind, char shortflag, const char* longflag,
               const char* help, const char* metavar)
      : Option(kind, shortflag, longflag, help), metavar(metavar) {}

  virtual ~ValuedOption() = 0;
  virtual bool isValued() const override { return true; }
};

inline ValuedOption::~ValuedOption() {}

struct StringOption : public ValuedOption {
  const char* value;

  StringOption(char shortflag, const char* longflag, const char* help,
               const char* metavar)
      : ValuedOption(OptionKindString, shortflag, longflag, help, metavar),
        value(nullptr) {}

  virtual ~StringOption() {}
};

struct IntOption : public ValuedOption {
  int value;

  IntOption(char shortflag, const char* longflag, const char* help,
            const char* metavar, int defaultValue)
      : ValuedOption(OptionKindInt, shortflag, longflag, help, metavar),
        value(defaultValue) {}

  virtual ~IntOption() {}
};

struct StringArg {
  char* value;
  size_t argno;

  StringArg(char* value, size_t argno) : value(value), argno(argno) {}
};

struct MultiStringOption : public ValuedOption {
  Vector<StringArg, 0, detail::OptionAllocPolicy> strings;

  MultiStringOption(char shortflag, const char* longflag, const char* help,
                    const char* metavar)
      : ValuedOption(OptionKindMultiString, shortflag, longflag, help,
                     metavar) {}

  virtual ~MultiStringOption() {}

  virtual bool isVariadic() const override { return true; }
};

/* namespace detail */

class MultiStringRange {
  using StringArg = detail::StringArg;
  const StringArg* cur;
  const StringArg* end;

 public:
  explicit MultiStringRange(const StringArg* cur, const StringArg* end)
      : cur(cur), end(end) {
    MOZ_ASSERT(end - cur >= 0);
  }

  bool empty() const { return cur == end; }
  void popFront() {
    MOZ_ASSERT(!empty());
    ++cur;
  }
  char* front() const {
    MOZ_ASSERT(!empty());
    return cur->value;
  }
  size_t argno() const {
    MOZ_ASSERT(!empty());
    return cur->argno;
  }
};

/*
 * Builder for describing a command line interface and parsing the resulting
 * specification.
 *
 * - A multi-option is an option that can appear multiple times and still
 *   parse as valid command line arguments.
 * - An "optional argument" is supported for backwards compatibility with prior
 *   command line interface usage. Once one optional argument has been added,
 *   *only* optional arguments may be added.
 */

class OptionParser {
 public:
  enum Result {
    Okay = 0,
    Fail,       /* As in, allocation fail. */
    ParseError, /* Successfully parsed but with an error. */
    EarlyExit   /* Successfully parsed but exits the program,
                 * for example with --help and --version. */

  };

 private:
  using Options = Vector<detail::Option*, 0, detail::OptionAllocPolicy>;
  using Option = detail::Option;
  using BoolOption = detail::BoolOption;

  Options options;
  Options arguments;
  BoolOption helpOption;
  BoolOption versionOption;
  const char* usage;
  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.
  int restArgument;

  Option* findOption(char shortflag);
  const Option* findOption(char shortflag) const;
  const Option* tryFindOption(char shortflag) const;
  Option* findOption(const char* longflag);
  const Option* findOption(const char* longflag) const;
  const Option* tryFindOption(const char* longflag) const;
  int findArgumentIndex(const char* name) const;
  Option* findArgument(const char* name);
  const Option* findArgument(const char* name) const;

  Result error(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
  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"),
        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* 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 setIgnoresUnknownOptions(const char* name, bool enabled);
  void setArgCapturesRest(const char* name);

  /* Arguments: no further arguments may be added after a variadic argument. */

  bool addOptionalStringArg(const char* name, const char* help);
  bool addOptionalMultiStringArg(const char* name, const char* help);

  const char* getStringArg(const char* name) const;
  MultiStringRange getMultiStringArg(const char* name) const;

  /* Options */

  bool addBoolOption(char shortflag, const char* longflag, const char* help);
  bool addStringOption(char shortflag, const char* longflag, const char* help,
                       const char* metavar);
  bool addIntOption(char shortflag, const char* longflag, const char* help,
                    const char* metavar, int defaultValue);
  bool addMultiStringOption(char shortflag, const char* longflag,
                            const char* help, const char* metavar);
  bool addOptionalVariadicArg(const char* name);

  int getIntOption(char shortflag) const;
  int getIntOption(const char* longflag) const;
  const char* getStringOption(char shortflag) const;
  const char* getStringOption(const char* longflag) const;
  bool getBoolOption(char shortflag) const;
  bool getBoolOption(const char* longflag) const;
  MultiStringRange getMultiStringOption(char shortflag) const;
  MultiStringRange getMultiStringOption(const char* longflag) const;

  /*
   * Return whether the help option was present (and thus help was already
   * displayed during parse_args).
   */

  bool getHelpOption() const;
};

/* namespace cli */
/* namespace js */

#endif /* shell_jsoptparse_h */

100%


¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.