⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 args2.cc

📁 一个用MATLAB语言编写的摄像机标定工具箱,内容丰富
💻 CC
字号:
//
// args.cc
//
// $Id: args2.cc,v 1.1.1.1 2001/02/28 00:28:35 cstolte Exp $
//

#include <iostream>
#include <sgl/args2.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

static char *
Strdup(const char *c2) {
    char *ret = 0;
    if (c2) {
	ret = new char[strlen(c2) + 1];
	strcpy(ret, c2);
    }
    return ret;
}

class Arg {
  public:
    Arg(const char *sw, const char *helpstr, bool req, int n);
    virtual ~Arg();

    virtual void printVal(std::ostream &os) const = 0;
    virtual void set(int index, const char *str) = 0;

    virtual bool process(char **&argv);

    void help(std::ostream &os) const;
    void print(std::ostream &os) const;
    const char *get_switch() const { return c_switch; }
    bool requiredButNotSet() const { return required && !valSet; }
    
    Arg *next;

  protected:
    char *helpstr;
    char *c_switch;
    int num;
    bool required, valSet;
};

Arg::Arg(const char *sw, const char *hstr, bool req, int n)
{
    if (!strcmp(sw, "help")) {
	std::cerr << "sgl/args: sorry. '-help' switch is reserved." << std::endl;
	exit(1);
    }

    c_switch = new char[strlen(sw) + 2];
    c_switch[0] = '\0';
    strcat(c_switch, "-");
    strcat(c_switch, sw);
    helpstr = Strdup(hstr);
    required = req;
    valSet = false;
    num = n;
    next = 0;
}

Arg::~Arg()
{
    delete[] helpstr;
    delete[] c_switch;
}

void
Arg::help(std::ostream &os) const
{
    os << "[" << c_switch << " (" << helpstr << ")";
    if (num != 1)
	os << " x " << num;
    os << "]";
}

void
Arg::print(std::ostream &os) const
{
    help(os);
    os << " = ";
    printVal(os);
}

bool
Arg::process(char **&argv) {
    if (!strcmp(argv[0], get_switch())) {
	for (int i = 0; i < num; ++i) {
	    ++argv;
	    if (!argv[0]) {
		std::cerr << "sgl/args: not enough arguments for '" <<
		    get_switch() << "' switch." << std::endl;
		exit(1);
	    }
	    set(i, *argv);
	}
	++argv;
	valSet = true;
	return true;
    }
    return false;
}

class IntArg : public Arg {
  public:
    IntArg(const char *sw, const char *helps, bool req, int num, int *i)
	: Arg(sw, helps, req, num), ptr(i) { }

    void printVal(std::ostream &os) const 
      { for (int i = 0; i < num; ++i) os << ptr[i] << " "; }
    void set(int index, const char *str) { ptr[index] = atoi(str); }

  private:
    int *ptr;
};

class DoubleArg : public Arg {
  public:
    DoubleArg(const char *sw, const char *helps, bool req,
	      int num, double *d)
	: Arg(sw, helps, req, num), ptr(d) { }

    void printVal(std::ostream &os) const
      { for (int i = 0; i < num; ++i) os << ptr[i] << " "; }
    void set(int index, const char *str) { ptr[index] = atof(str); }

  private:
    double *ptr;
};

class FloatArg : public Arg {
  public:
    FloatArg(const char *sw, const char *helps, bool req,
	     int num, float *f)
	: Arg(sw, helps, req, num), ptr(f) { }

    void printVal(std::ostream &os) const
      { for (int i = 0; i < num; ++i) os << ptr[i] << " "; }
    void set(int index, const char *str) { ptr[index] = atof(str); }

  private:
    float *ptr;
};

class StringArg : public Arg {
  public:
    StringArg(const char *sw, const char *helps, bool req, 
	      int num, char **str)
	: Arg(sw, helps, req, num), ptr(str) { } 

    void printVal(std::ostream &os) const
      { for (int i = 0; i < num; ++i) os << ptr[i] << " "; }
    void set(int index, const char *str) 
      { ptr[index] = Strdup(str); }

  private:
    char **ptr;
};

class BoolArg : public Arg {
  public:
    BoolArg(const char *sw, const char *helps, bool *b)
	: Arg(sw, helps, false, 1), ptr(b) { }

    bool process(char **&argv);
    void printVal(std::ostream &os) const
      { os << *ptr ? "true" : "false"; }
    void set(int , const char *) { *ptr = !*ptr; }

  private:
    bool *ptr;
};

bool
BoolArg::process(char **&argv) {
    if (!strcmp(argv[0], get_switch())) {
	*ptr = !*ptr;
	++argv;
	valSet = true;
	return true;
    }
    return false;
}

////////////
// ArgParser2

ArgParser2::ArgParser2() {
    item_list = 0;
    added_floaters = false;
    floaters_required = false;
    wanted_floaters = floaters_pos = 0;
    floaters = 0;
    floater_help = 0;
}

ArgParser2::~ArgParser2() {
    delete[] floater_help;
    Arg *arg = item_list;
    while (arg) {
	Arg *next = arg->next;
	delete arg;
	arg = next;
    }
}

void
ArgParser2::optional(const char *c, const char *helpstr, 
		    int *i, int num) {
    Arg *a = new IntArg(c, helpstr, false, num, i);
    add_arg(a);
}

void
ArgParser2::optional(const char *c, const char *helpstr,
		    double *d, int num) {
    Arg *a = new DoubleArg(c, helpstr, false, num, d);
    add_arg(a);
}

void
ArgParser2::optional(const char *c, const char *helpstr,
		    float *f, int num) {
    Arg *a = new FloatArg(c, helpstr, false, num, f);
    add_arg(a);
}

void
ArgParser2::optional(const char *c, const char *helpstr,
		    char **str, int num) {
    Arg *a = new StringArg(c, helpstr, false, num, str);
    add_arg(a);
}

void
ArgParser2::optional(const char *c, const char *helpstr, bool *b) {
    Arg *a = new BoolArg(c, helpstr, b);
    add_arg(a);
}

void
ArgParser2::optional(char ***fl, const char *helpstr, int num) {
    if (added_floaters) {
	std::cerr << "sgl/args: you've already added floating string arguments."
	    << std::endl;
	exit(1);
    }
    added_floaters = true;
    wanted_floaters = num;
    floaters = new char *[wanted_floaters];
    for (int i = 0; i < wanted_floaters; ++i)
	floaters[i] = 0;
    *fl = floaters;
    floater_help = Strdup(helpstr);
    floaters_required = false;
}
 
void
ArgParser2::optional(char **floater, const char *helpstr) {
    if (added_floaters) {
	std::cerr << "sgl/args: you've already added floating string arguments."
	    << std::endl;
	exit(1);
    }
    floaters = floater;
    added_floaters = true;
    wanted_floaters = 1;
    floater_help = Strdup(helpstr);
    floaters_required = false;
}

void
ArgParser2::required(const char *c, const char *helpstr, 
		    int *i, int num) {
    Arg *a = new IntArg(c, helpstr, true, num, i);
    add_arg(a);
}

void
ArgParser2::required(const char *c, const char *helpstr, 
		    double *d, int num) {
    Arg *a = new DoubleArg(c, helpstr, true, num, d);
    add_arg(a);
}

void
ArgParser2::required(const char *c, const char *helpstr, 
		    float *f, int num) {
    Arg *a = new FloatArg(c, helpstr, true, num, f);
    add_arg(a);
}

void
ArgParser2::required(const char *c, const char *helpstr,
		    char **str, int num) {
    Arg *a = new StringArg(c, helpstr, true, num, str);
    add_arg(a);
}

void
ArgParser2::required(char ***fl, const char *helpstr, int num) {
    if (added_floaters) {
	std::cerr << "sgl/args: you've already added floating string arguments."
	    << std::endl;
	exit(1);
    }
    added_floaters = true;
    wanted_floaters = num;
    floaters = new char *[wanted_floaters];
    for (int i = 0; i < wanted_floaters; ++i)
	floaters[i] = 0;
    *fl = floaters;
    floater_help = Strdup(helpstr);
    floaters_required = true;
}

void
ArgParser2::required(char **floater, const char *helpstr) {
    if (added_floaters) {
	std::cerr << "sgl/args: you've already added floating string arguments."
	    << std::endl;
	exit(1);
    }
    floaters = floater;
    added_floaters = true;
    wanted_floaters = 1;
    floater_help = Strdup(helpstr);
    floaters_required = true;
}

void 
ArgParser2::add_arg(Arg *a) {
    Arg *arg = item_list;
    while (arg) {
	if (!strcmp(a->get_switch(), arg->get_switch())) {
	    std::cerr << "sgl/args: switch '" << a->get_switch() << 
		"' is already taken." << std::endl;
	    exit(1);
	}
	arg = arg->next;
    }
    a->next = item_list;
    item_list = a;
}

void 
ArgParser2::process(const char *prog_name, int, char **argv) {
    ++argv;
    while (*argv) {
	if (!strcmp(*argv, "-help")) {
	    print_help(prog_name);
	    exit(1);
	}

	Arg *arg = item_list;
	while (arg) {
	    if (arg->process(argv))
		break;
	    arg = arg->next;
	}
	if (!arg) {
	    // nothing matched. floating arg?
	    if (wanted_floaters == 0 || wanted_floaters == floaters_pos) {
		// no floaters wanted or we already got as many of
		// them as we want
		std::cerr << prog_name << ": unrecognized argument " << *argv
		    << std::endl;
		print_help(prog_name);
		exit(1);
	    }
	    else {
		floaters[floaters_pos++] = Strdup(*argv);
		++argv;
	    }
	}
    }

    Arg *arg = item_list;
    bool some_missing = false;
    while (arg) {
	if (arg->requiredButNotSet()) {
	    some_missing = true;
	    std::cerr << prog_name << ": '-" << arg->get_switch() 
		<< "' switch must be set." << std::endl;
	}
	arg = arg->next;
    }
    if (floaters_required && floaters_pos < wanted_floaters) {
	some_missing = true;
	std::cerr << prog_name << ": " << wanted_floaters << " " <<
	    floater_help << " must be specified." << std::endl;
    }
    if (some_missing == true) {
	print_help(prog_name);
	exit(1);
    }
}

void
ArgParser2::print_help(const char *prog_name) const {
    std::cerr << "usage: " << prog_name << " ";
    if (added_floaters) {
	std::cerr << "[" << floater_help;
	if (wanted_floaters > 1)
	    std::cerr << " x " << wanted_floaters;
	std::cerr << "] ";
    }

    Arg *a = item_list;
    while (a) {
	a->help(std::cerr);
	std::cerr << ' ';
	a = a->next;
    }
    std::cerr << std::endl;
}

std::ostream &
operator<<(std::ostream &os, const ArgParser2 &ap) {
    Arg *a = ap.item_list;
    while (a) {
	a->print(os);
	os << std::endl;
	a = a->next;
    }
    if (ap.floaters && ap.floaters_pos) {
	os << ap.floater_help << ": ";
	for (int i = 0; i < ap.floaters_pos; ++i)
	    std::cerr << ap.floaters[i] << " ";
	os << std::endl;
    }
    return os;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -