Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcli.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include <ctype.h></ctype.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
using namespace TCli;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Release
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void printToonzRelease(ostream &out) { out << "Toonz 7.1" << endl; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void printLibRelease(ostream &out) { out << "Tnzcore 1.0 - " __DATE__ << endl; }
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// local UsageError
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// local UsageElements
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class SpecialUsageElement : public UsageElement {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  SpecialUsageElement(std::string name) : UsageElement(name, " "){};
Shinya Kitaoka 473e70
  void dumpValue(ostream &) const override {};
Shinya Kitaoka 473e70
  void resetValue() override {};
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static SpecialUsageElement bra("[");
Toshihiro Shimizu 890ddd
static SpecialUsageElement ket("]");
Toshihiro Shimizu 890ddd
static Switcher help("-help", "Print this help page");
Toshihiro Shimizu 890ddd
static Switcher release("-release", "Print the current Toonz version");
Toshihiro Shimizu 890ddd
static Switcher libRelease("-librelease", "");
Toshihiro Shimizu 890ddd
// hidden: print the lib version
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// helper function
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void fetchElement(int index, int &argc, char *argv[]) {
Shinya Kitaoka 120a6e
  if (index >= argc) throw UsageError("missing argument");
Shinya Kitaoka 120a6e
  for (int i = index; i < argc - 1; i++) argv[i] = argv[i + 1];
Shinya Kitaoka 120a6e
  argc--;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void fetchElement(int &dst, int index, int &argc, char *argv[]) {
Shinya Kitaoka 120a6e
  string s = argv[index];
Shinya Kitaoka 120a6e
  if (isInt(s))
Shinya Kitaoka 120a6e
    dst = std::stoi(s);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    throw UsageError("expected int");
Shinya Kitaoka 120a6e
  fetchElement(index, argc, argv);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void fetchElement(string &dst, int index, int &argc, char *argv[]) {
Shinya Kitaoka 120a6e
  char *s = argv[index];
Shinya Kitaoka 120a6e
  fetchElement(index, argc, argv);
Shinya Kitaoka 120a6e
  if (*s == '-') throw UsageError("expected argument");
Shinya Kitaoka 120a6e
  dst = string(s);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// UsageElement
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UsageElement::UsageElement(string name, string help)
Shinya Kitaoka 120a6e
    : m_name(name), m_help(help), m_selected(false) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void UsageElement::print(ostream &out) const { out << m_name; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void UsageElement::printHelpLine(ostream &out) const {
Shinya Kitaoka 120a6e
  out << "  " << m_name << endl;
Shinya Kitaoka 120a6e
  out << "       " << m_help << endl;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Qualifier
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Qualifier::print(ostream &out) const {
Shinya Kitaoka 120a6e
  if (isSwitcher())
Shinya Kitaoka 120a6e
    out << m_name;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    out << "[ " << m_name << " ]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SimpleQualifier::fetch(int index, int &argc, char *argv[]) {
Shinya Kitaoka 120a6e
  fetchElement(index, argc, argv);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SimpleQualifier::dumpValue(ostream &out) const {
Shinya Kitaoka 120a6e
  out << m_name << " = " << (isSelected() ? "on" : "off") << endl;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SimpleQualifier::resetValue() { m_selected = false; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Argument & MultiArgument
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Argument::fetch(int index, int &argc, char *argv[]) {
Shinya Kitaoka 120a6e
  if (index >= argc) throw UsageError("missing argument");
Shinya Kitaoka 120a6e
  if (!assign(argv[index]))
Shinya Kitaoka 120a6e
    throw UsageError(string("bad argument type :") + argv[index]);
Shinya Kitaoka 120a6e
  for (int i = index; i < argc - 1; i++) argv[i] = argv[i + 1];
Shinya Kitaoka 120a6e
  argc--;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MultiArgument::fetch(int index, int &argc, char *argv[]) {
Shinya Kitaoka 120a6e
  if (index >= argc) throw UsageError("missing argument(s)");
Shinya Kitaoka 120a6e
  allocate(argc - index);
Shinya Kitaoka 120a6e
  for (m_index = 0; m_index < m_count; m_index++)
Shinya Kitaoka 120a6e
    if (!assign(argv[index + m_index]))
Shinya Kitaoka 120a6e
      throw UsageError(string("bad argument type :") + argv[index + m_index]);
Shinya Kitaoka 120a6e
  argc -= m_count;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// UsageLine<t></t>
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine::UsageLine() : m_count(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine::~UsageLine() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine::UsageLine(const UsageLine &src) {
Shinya Kitaoka 120a6e
  m_count = src.m_count;
Shinya Kitaoka 120a6e
  m_elements.reset(new UsageElementPtr[m_count]);
Shinya Kitaoka 120a6e
  ::memcpy(m_elements.get(), src.m_elements.get(),
Shinya Kitaoka 120a6e
           m_count * sizeof(m_elements[0]));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine &UsageLine::operator=(const UsageLine &src) {
Shinya Kitaoka 120a6e
  if (src.m_elements != m_elements) {
Shinya Kitaoka 120a6e
    m_elements.reset(new UsageElementPtr[src.m_count]);
Shinya Kitaoka 120a6e
    ::memcpy(m_elements.get(), src.m_elements.get(),
Shinya Kitaoka 120a6e
             src.m_count * sizeof(m_elements[0]));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_count = src.m_count;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine::UsageLine(const UsageLine &src, UsageElement &elem) {
Shinya Kitaoka 120a6e
  m_count = src.m_count;
Shinya Kitaoka 120a6e
  m_elements.reset(new UsageElementPtr[m_count + 1]);
Shinya Kitaoka 120a6e
  ::memcpy(m_elements.get(), src.m_elements.get(),
Shinya Kitaoka 120a6e
           m_count * sizeof(m_elements[0]));
Shinya Kitaoka 120a6e
  m_elements[m_count++] = &elem;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine::UsageLine(int count) {
Shinya Kitaoka 120a6e
  m_count = count;
Shinya Kitaoka 120a6e
  m_elements.reset(new UsageElementPtr[m_count]);
Shinya Kitaoka 120a6e
  ::memset(m_elements.get(), 0, m_count * sizeof(m_elements[0]));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine::UsageLine(UsageElement &elem) {
Shinya Kitaoka 120a6e
  m_count = 1;
Shinya Kitaoka 120a6e
  m_elements.reset(new UsageElementPtr[m_count]);
Shinya Kitaoka 120a6e
  m_elements[0] = &elem;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine::UsageLine(UsageElement &a, UsageElement &b) {
Shinya Kitaoka 120a6e
  m_count = 2;
Shinya Kitaoka 120a6e
  m_elements.reset(new UsageElementPtr[m_count]);
Shinya Kitaoka 120a6e
  m_elements[0] = &a;
Shinya Kitaoka 120a6e
  m_elements[1] = &b;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine TCli::UsageLine::operator+(UsageElement &elem) {
Shinya Kitaoka 120a6e
  return UsageLine(*this, elem);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine TCli::operator+(UsageElement &a, UsageElement &b) {
Shinya Kitaoka 120a6e
  return UsageLine(a, b);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UsageLine TCli::operator+(const UsageLine &a, const Optional &b) {
Shinya Kitaoka 120a6e
  UsageLine ul(a.getCount() + b.getCount());
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < a.getCount(); i++) ul[i] = a[i];
Shinya Kitaoka 120a6e
  for (int j = 0; j < b.getCount(); j++) ul[i++] = b[j];
Shinya Kitaoka 120a6e
  return ul;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Optional::Optional(const UsageLine &ul) : UsageLine(ul.getCount() + 2) {
Shinya Kitaoka 120a6e
  m_elements[0]           = &bra;
Shinya Kitaoka 120a6e
  m_elements[m_count - 1] = &ket;
Shinya Kitaoka 120a6e
  for (int i = 0; i < ul.getCount(); i++) m_elements[i + 1] = ul[i];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// UsageImp
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TCli::UsageImp {
Shinya Kitaoka 120a6e
  string m_progName;
Shinya Kitaoka 120a6e
  vector<usageline> m_usageLines;</usageline>
Shinya Kitaoka 120a6e
  std::map<std::string, *="" qualifier=""> m_qtable;</std::string,>
Shinya Kitaoka 120a6e
  vector<qualifier *=""> m_qlist;</qualifier>
Shinya Kitaoka 120a6e
  vector<argument *=""> m_args;</argument>
Shinya Kitaoka 120a6e
  typedef std::map<std::string, *="" qualifier="">::iterator qiterator;</std::string,>
Shinya Kitaoka 120a6e
  typedef std::map<std::string, *="" qualifier="">::const_iterator const_qiterator;</std::string,>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UsageLine *m_selectedUsageLine;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UsageImp(string progName);
Shinya Kitaoka 120a6e
  ~UsageImp(){};
Shinya Kitaoka 120a6e
  void add(const UsageLine &);
Shinya Kitaoka 120a6e
  void addStandardUsages();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void registerQualifier(Qualifier *q);
Shinya Kitaoka 120a6e
  void registerQualifier(string name, Qualifier *q);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void registerArgument(Argument *arg);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void printUsageLine(ostream &out, const UsageLine &ul) const;
Shinya Kitaoka 120a6e
  void printUsageLines(ostream &out) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void print(ostream &out) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void resetValues();
Shinya Kitaoka 120a6e
  void clear();
Shinya Kitaoka 120a6e
  void parse(int argc, char *argv[]);
Shinya Kitaoka 120a6e
  void fetchArguments(UsageLine &ul, int a, int b, int &argc, char *argv[]);
Shinya Kitaoka 120a6e
  bool matchSwitcher(const UsageLine &ul) const;
Shinya Kitaoka 120a6e
  bool hasSwitcher(const UsageLine &ul) const;
Shinya Kitaoka 120a6e
  bool matchArgCount(const UsageLine &ul, int a, int b, int argc) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void dumpValues(ostream &out) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void getArgCountRange(const UsageLine &ul, int a, int b, int &min,
Shinya Kitaoka 120a6e
                        int &max) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static const int InfiniteArgCount;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int UsageImp::InfiniteArgCount = 2048;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UsageImp::UsageImp(string progName)
Shinya Kitaoka 120a6e
    : m_progName(progName), m_selectedUsageLine(0) {
Shinya Kitaoka 120a6e
  addStandardUsages();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void UsageImp::addStandardUsages() {
Shinya Kitaoka 120a6e
  add(help);
Shinya Kitaoka 120a6e
  add(release);
Shinya Kitaoka 120a6e
  add(libRelease);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::clear() {
Shinya Kitaoka 120a6e
  m_usageLines.clear();
Shinya Kitaoka 120a6e
  m_qtable.clear();
Shinya Kitaoka 120a6e
  m_qlist.clear();
Shinya Kitaoka 120a6e
  m_args.clear();
Shinya Kitaoka 120a6e
  m_selectedUsageLine = 0;
Shinya Kitaoka 120a6e
  addStandardUsages();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void UsageImp::registerArgument(Argument *arg) {
Shinya Kitaoka 120a6e
  unsigned int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_args.size() && m_args[i] != arg; i++) {
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i == m_args.size()) m_args.push_back(arg);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void UsageImp::registerQualifier(string name, Qualifier *q) {
Shinya Kitaoka 120a6e
  m_qtable[name] = q;
Shinya Kitaoka 120a6e
  unsigned int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_qlist.size() && m_qlist[i] != q; i++) {
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i == m_qlist.size()) m_qlist.push_back(q);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::registerQualifier(Qualifier *q) {
Shinya Kitaoka 120a6e
  string str     = q->getName();
Shinya Kitaoka 120a6e
  const char *s0 = str.c_str();
Shinya Kitaoka 120a6e
  while (*s0 == ' ') s0++;
Shinya Kitaoka 120a6e
  const char *s = s0;
Shinya Kitaoka 120a6e
  for (;;) {
Shinya Kitaoka 120a6e
    if (*s != '-') {
Shinya Kitaoka 120a6e
      assert(!"Qualifier name must start with '-'");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    do
Shinya Kitaoka 120a6e
      s++;
Shinya Kitaoka 120a6e
    while (isalnum(*s));
Shinya Kitaoka 120a6e
    if (s == s0 + 1) {
Shinya Kitaoka 120a6e
      assert(!"Empty qualifier name");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    std::string name(s0, s - s0);
Shinya Kitaoka 120a6e
    registerQualifier(name, q);
Shinya Kitaoka 120a6e
    while (*s == ' ') s++;
Shinya Kitaoka 120a6e
    // ignoro gli eventuali parametri
Shinya Kitaoka 120a6e
    while (isalnum(*s)) {
Shinya Kitaoka 120a6e
      while (isalnum(*s)) s++;
Shinya Kitaoka 120a6e
      while (*s == ' ') s++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (*s != '|') break;
Shinya Kitaoka 120a6e
    s++;
Shinya Kitaoka 120a6e
    while (*s == ' ') s++;
Shinya Kitaoka 120a6e
    s0 = s;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (*s != '\0') {
Shinya Kitaoka 120a6e
    assert(!"Unexpected character");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::add(const UsageLine &ul) {
Shinya Kitaoka 120a6e
  m_usageLines.push_back(ul);
Shinya Kitaoka 120a6e
  for (int i = 0; i < ul.getCount(); i++) {
Shinya Kitaoka 120a6e
    Qualifier *q = dynamic_cast<qualifier *="">(ul[i]);</qualifier>
Shinya Kitaoka 120a6e
    if (q) registerQualifier(q);
Shinya Kitaoka 120a6e
    Argument *a = dynamic_cast<argument *="">(ul[i]);</argument>
Shinya Kitaoka 120a6e
    if (a) registerArgument(a);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::printUsageLine(ostream &out, const UsageLine &ul) const {
Shinya Kitaoka 120a6e
  out << m_progName;
Shinya Kitaoka 120a6e
  for (int j = 0; j < ul.getCount(); j++)
Shinya Kitaoka 120a6e
    if (!ul[j]->isHidden()) {
Shinya Kitaoka 120a6e
      out << " ";
Shinya Kitaoka 120a6e
      ul[j]->print(out);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  out << endl;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::printUsageLines(std::ostream &out) const {
Shinya Kitaoka 120a6e
  bool first = true;
Shinya Kitaoka 120a6e
  for (unsigned int i = 0; i < m_usageLines.size(); i++) {
Shinya Kitaoka 120a6e
    const UsageLine &ul = m_usageLines[i];
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = 0; j < ul.getCount(); j++)
Shinya Kitaoka 120a6e
      if (!ul[j]->isHidden()) break;
Shinya Kitaoka 120a6e
    if (j == ul.getCount()) continue;
Shinya Kitaoka 120a6e
    out << (first ? "usage: " : "       ");
Shinya Kitaoka 120a6e
    printUsageLine(out, ul);
Shinya Kitaoka 120a6e
    first = false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  out << endl;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::print(std::ostream &out) const {
Shinya Kitaoka 120a6e
  printUsageLines(out);
Shinya Kitaoka 120a6e
  out << endl;
Shinya Kitaoka 120a6e
  unsigned int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_qlist.size(); i++)
Shinya Kitaoka 120a6e
    if (!m_qlist[i]->isHidden()) m_qlist[i]->printHelpLine(out);
Shinya Kitaoka 120a6e
  for (i = 0; i < m_args.size(); i++) m_args[i]->printHelpLine(out);
Shinya Kitaoka 120a6e
  out << endl;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::parse(int argc, char *argv[]) {
Shinya Kitaoka 120a6e
  resetValues();
Shinya Kitaoka 120a6e
  if (argc == 0 || argv[0] == 0) throw UsageError("missing program name");
Shinya Kitaoka 120a6e
  m_progName = string(argv[0]);
Shinya Kitaoka 120a6e
  unsigned int i;
Shinya Kitaoka 120a6e
  for (i = 1; i < (unsigned int)argc;)
Shinya Kitaoka 120a6e
    if (argv[i][0] == '-') {
Shinya Kitaoka 120a6e
      string qname(argv[i]);
Shinya Kitaoka 120a6e
      qiterator qit = m_qtable.find(qname);
Shinya Kitaoka 120a6e
      if (qit == m_qtable.end()) {
Shinya Kitaoka 120a6e
        string msg = "unknown qualifier '" + qname + "'";
Shinya Kitaoka 120a6e
        throw UsageError(msg);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      Qualifier *qualifier = qit->second;
Shinya Kitaoka 120a6e
      qualifier->fetch(i, argc, argv);
Shinya Kitaoka 120a6e
      qualifier->select();
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  vector<usageline *=""> usages;</usageline>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < m_usageLines.size(); i++)
Shinya Kitaoka 120a6e
    if (hasSwitcher(m_usageLines[i]) && matchSwitcher(m_usageLines[i]))
Shinya Kitaoka 120a6e
      usages.push_back(&m_usageLines[i]);
Shinya Kitaoka 120a6e
  if (usages.empty())
Shinya Kitaoka 120a6e
    for (i = 0; i < m_usageLines.size(); i++)
Shinya Kitaoka 120a6e
      if (!hasSwitcher(m_usageLines[i])) usages.push_back(&m_usageLines[i]);
Shinya Kitaoka 120a6e
  if (usages.size() == 0) throw UsageError("unrecognized syntax");
Shinya Kitaoka 120a6e
  if (usages.size() > 1) {
Shinya Kitaoka 120a6e
    int min = InfiniteArgCount;
Shinya Kitaoka 120a6e
    int max = 0;
Shinya Kitaoka 120a6e
    std::vector<usageline *="">::iterator it;</usageline>
Shinya Kitaoka 120a6e
    for (it = usages.begin(); it != usages.end();) {
Shinya Kitaoka 120a6e
      UsageLine &ul = **it;
Shinya Kitaoka 120a6e
      int lmin, lmax;
Shinya Kitaoka 120a6e
      getArgCountRange(ul, 0, ul.getCount() - 1, lmin, lmax);
Shinya Kitaoka 120a6e
      min = std::min(min, lmin);
Shinya Kitaoka 120a6e
      max = std::max(max, lmax);
Shinya Kitaoka 120a6e
      if (matchArgCount(ul, 0, ul.getCount() - 1, argc - 1) == false)
Shinya Kitaoka 120a6e
        it = usages.erase(it);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        it++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (usages.size() == 0) {
Shinya Kitaoka 120a6e
      if (argc - 1 < min)
Shinya Kitaoka 120a6e
        throw UsageError("missing argument(s)");
Shinya Kitaoka 120a6e
      else if (argc - 1 > max)
Shinya Kitaoka 120a6e
        throw UsageError("too many arguments");
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        throw UsageError("bad argument number");
Shinya Kitaoka 120a6e
    } else if (usages.size() > 1)
Shinya Kitaoka 120a6e
      throw UsageError("ambiguous syntax");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (usages.size() == 1) {
Shinya Kitaoka 120a6e
    UsageLine *found = usages[0];
Shinya Kitaoka 120a6e
    if (found->getCount() > 0)
Shinya Kitaoka 120a6e
      fetchArguments(*found, 0, found->getCount() - 1, argc, argv);
Shinya Kitaoka 120a6e
    if (argc > 1) throw UsageError("too many arguments");
Shinya Kitaoka 120a6e
    m_selectedUsageLine = found;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::fetchArguments(UsageLine &ul, int a, int b, int &argc,
Shinya Kitaoka 120a6e
                              char *argv[]) {
Shinya Kitaoka 120a6e
  assert(0 <= a && a <= b && b < ul.getCount());
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = a; i <= b; i++) {
Shinya Kitaoka 120a6e
    if (ul[i] == &bra || ul[i]->isMultiArgument()) break;
Shinya Kitaoka 120a6e
    if (ul[i]->isArgument()) {
Shinya Kitaoka 120a6e
      Argument *argument = dynamic_cast<argument *="">(ul[i]);</argument>
Shinya Kitaoka 120a6e
      assert(argument);
Shinya Kitaoka 120a6e
      argument->fetch(1, argc, argv);
Shinya Kitaoka 120a6e
      argument->select();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i > b) {
Shinya Kitaoka 120a6e
  } else if (ul[i] == &bra) {
Shinya Kitaoka 120a6e
    int n = 0;
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = b; j > i && ul[j] != &ket; j--)
Shinya Kitaoka 120a6e
      if (ul[j]->isArgument()) n++;
Shinya Kitaoka 120a6e
    assert(j > i + 1);
Shinya Kitaoka 120a6e
    if (argc - 1 > n) fetchArguments(ul, i + 1, j - 1, argc, argv);
Shinya Kitaoka 120a6e
    if (j + 1 <= b) fetchArguments(ul, j + 1, b, argc, argv);
Shinya Kitaoka 120a6e
  } else if (ul[i]->isMultiArgument()) {
Shinya Kitaoka 120a6e
    MultiArgument *argument = dynamic_cast<multiargument *="">(ul[i]);</multiargument>
Shinya Kitaoka 120a6e
    assert(argument);
Shinya Kitaoka 120a6e
    int n = 0;
Shinya Kitaoka 120a6e
    for (int j = i + 1; j <= b; j++)
Shinya Kitaoka 120a6e
      if (ul[j]->isArgument()) n++;
Shinya Kitaoka 120a6e
    int oldArgc = argc;
Shinya Kitaoka 120a6e
    argc -= n;
Shinya Kitaoka 120a6e
    argument->fetch(1, argc, argv);
Shinya Kitaoka 120a6e
    argument->select();
Shinya Kitaoka 120a6e
    argc += n;
Shinya Kitaoka 120a6e
    if (n > 0) {
Shinya Kitaoka 120a6e
      if (argc < oldArgc)
Shinya Kitaoka 120a6e
        for (int j = n; j > 0; j--) argv[argc - j] = argv[oldArgc - j];
Shinya Kitaoka 120a6e
      fetchArguments(ul, i + 1, b, argc, argv);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool UsageImp::matchSwitcher(const UsageLine &ul) const {
Shinya Kitaoka 120a6e
  for (int i = 0; i < ul.getCount(); i++)
Shinya Kitaoka 120a6e
    if (ul[i]->isSwitcher() && !ul[i]->isSelected()) return false;
Shinya Kitaoka 120a6e
  return true;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool UsageImp::hasSwitcher(const UsageLine &ul) const {
Shinya Kitaoka 120a6e
  for (int i = 0; i < ul.getCount(); i++)
Shinya Kitaoka 120a6e
    if (ul[i]->isSwitcher()) return true;
Shinya Kitaoka 120a6e
  return false;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
bool UsageImp::matchArgCount(const UsageLine &ul, int a, int b,
Shinya Kitaoka 120a6e
                             int argc) const {
Shinya Kitaoka 120a6e
  int n = 0;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = a; i <= b; i++) {
Shinya Kitaoka 120a6e
    if (ul[i] == &bra || ul[i]->isMultiArgument()) break;
Shinya Kitaoka 120a6e
    if (ul[i]->isArgument()) n++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i > b)
Shinya Kitaoka 120a6e
    return argc == n;
Shinya Kitaoka 120a6e
  else if (ul[i] == &bra) {
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = b; j > i && ul[j] != &ket; j--)
Shinya Kitaoka 120a6e
      if (ul[j]->isArgument()) n++;
Shinya Kitaoka 120a6e
    assert(j > i + 1);
Shinya Kitaoka 120a6e
    if (n == argc)
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    else if (n > argc)
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return matchArgCount(ul, i + 1, j - 1, argc - n);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(ul[i]->isMultiArgument());
Shinya Kitaoka 120a6e
    n++;
Shinya Kitaoka 120a6e
    for (i++; i <= b; i++)
Shinya Kitaoka 120a6e
      if (ul[i]->isArgument()) n++;
Shinya Kitaoka 120a6e
    return argc >= n;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::getArgCountRange(const UsageLine &ul, int a, int b, int &min,
Shinya Kitaoka 120a6e
                                int &max) const {
Shinya Kitaoka 120a6e
  min = max = 0;
Shinya Kitaoka 120a6e
  int n     = 0;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = a; i <= b; i++) {
Shinya Kitaoka 120a6e
    if (ul[i] == &bra || ul[i]->isMultiArgument()) break;
Shinya Kitaoka 120a6e
    if (ul[i]->isArgument()) n++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i > b) {
Shinya Kitaoka 120a6e
    min = max = n;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  } else if (ul[i] == &bra) {
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = b; j > i && ul[j] != &ket; j--)
Shinya Kitaoka 120a6e
      if (ul[j]->isArgument()) n++;
Shinya Kitaoka 120a6e
    assert(j > i + 1);
Shinya Kitaoka 120a6e
    min = max = n;
Shinya Kitaoka 120a6e
    int lmin, lmax;
Shinya Kitaoka 120a6e
    getArgCountRange(ul, i + 1, j - 1, lmin, lmax);
Shinya Kitaoka 120a6e
    if (lmax == InfiniteArgCount)
Shinya Kitaoka 120a6e
      max = InfiniteArgCount;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      max += lmax;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(ul[i]->isMultiArgument());
Shinya Kitaoka 120a6e
    n++;
Shinya Kitaoka 120a6e
    for (i++; i <= b; i++)
Shinya Kitaoka 120a6e
      if (ul[i]->isArgument()) n++;
Shinya Kitaoka 120a6e
    min = n;
Shinya Kitaoka 120a6e
    max = InfiniteArgCount;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::dumpValues(std::ostream &out) const {
Shinya Kitaoka 120a6e
  if (m_selectedUsageLine == 0) return;
Shinya Kitaoka 120a6e
  cout << "selected usage: ";
Shinya Kitaoka 120a6e
  printUsageLine(out, *m_selectedUsageLine);
Shinya Kitaoka 120a6e
  unsigned int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_qlist.size(); i++) m_qlist[i]->dumpValue(out);
Shinya Kitaoka 120a6e
  for (i = 0; i < m_args.size(); i++) m_args[i]->dumpValue(out);
Shinya Kitaoka 120a6e
  out << endl << endl;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void UsageImp::resetValues() {
Shinya Kitaoka 120a6e
  unsigned int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_qlist.size(); i++) m_qlist[i]->resetValue();
Shinya Kitaoka 120a6e
  for (i = 0; i < m_args.size(); i++) m_args[i]->resetValue();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// Usage
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Usage::Usage(string progName) : m_imp(new UsageImp(progName)) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Usage::~Usage() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Usage::add(const UsageLine &ul) { m_imp->add(ul); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Usage::print(std::ostream &out) const { m_imp->print(out); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Usage::dumpValues(std::ostream &out) const { m_imp->dumpValues(out); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Usage::clear() { m_imp->clear(); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Usage::parse(const char *argvString, std::ostream &err) {
Shinya Kitaoka 120a6e
  string s = string(argvString);
Shinya Kitaoka 120a6e
  std::vector<char *=""> argv;</char>
Shinya Kitaoka 120a6e
  int len = s.size();
Shinya Kitaoka 120a6e
  for (int i = 0; i < len;) {
Shinya Kitaoka 120a6e
    while (s[i] == ' ' || s[i] == '\t') i++;
Shinya Kitaoka 120a6e
    if (i < len) argv.push_back(&s[i]);
Shinya Kitaoka 120a6e
    while (i < len && !(s[i] == ' ' || s[i] == '\t')) i++;
Shinya Kitaoka 120a6e
    if (i < len) s[i++] = '\0';
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return parse(argv.size(), &argv[0], err);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Usage::parse(int argc, char *argv[], std::ostream &err) {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    m_imp->parse(argc, argv);
Shinya Kitaoka 120a6e
    if (help) {
Shinya Kitaoka 120a6e
      print(err);
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (release) {
Shinya Kitaoka 120a6e
      printToonzRelease(err);
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (libRelease) {
Shinya Kitaoka 120a6e
      printLibRelease(err);
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } catch (UsageError e) {
Shinya Kitaoka 120a6e
    err << "Usage error: " << e.getError() << endl;
Shinya Kitaoka 120a6e
    m_imp->printUsageLines(err);
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// RangeQualifier
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RangeQualifier::RangeQualifier()
Shinya Kitaoka 120a6e
    : Qualifier("-range from to | -frame fr", "frame range")
Shinya Kitaoka 120a6e
    , m_from(0)
Shinya Kitaoka 120a6e
    , m_to(-1) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RangeQualifier::fetch(int index, int &argc, char *argv[]) {
Shinya Kitaoka 120a6e
  assert(index < argc);
Shinya Kitaoka 120a6e
  string qname(argv[index]);
Shinya Kitaoka 120a6e
  fetchElement(index, argc, argv);
Shinya Kitaoka 120a6e
  if (qname == "-range") {
Shinya Kitaoka 120a6e
    fetchElement(m_from, index, argc, argv);
Shinya Kitaoka 120a6e
    fetchElement(m_to, index, argc, argv);
Shinya Kitaoka 120a6e
  } else if (qname == "-frame") {
Shinya Kitaoka 120a6e
    fetchElement(m_from, index, argc, argv);
Shinya Kitaoka 120a6e
    m_to = m_from;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::ostream &operator<<(std::ostream &out, const RangeQualifier &range) {
Shinya Kitaoka 120a6e
  return out << "[" << range.getFrom() << ", " << range.getTo() << "]";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RangeQualifier::dumpValue(std::ostream &out) const {
Shinya Kitaoka 120a6e
  out << m_name << " = ";
Shinya Kitaoka 120a6e
  if (m_from <= m_to)
Shinya Kitaoka 120a6e
    out << m_from << ", " << m_to;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    out << "undefined";
Shinya Kitaoka 120a6e
  out << endl;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RangeQualifier::resetValue() {
Shinya Kitaoka 120a6e
  m_from     = 0;
Shinya Kitaoka 120a6e
  m_to       = -1;
Shinya Kitaoka 120a6e
  m_selected = false;
Toshihiro Shimizu 890ddd
}