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