Merge branch 'master' of https://github.com/liuruoze/EasyPR into linux_dev
Conflicts: src/test/accuracy_test.cpp src/util/general_test_prepare.cpp1.3
commit
374557fdaf
Before Width: | Height: | Size: 212 KiB |
@ -0,0 +1,127 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Name: CParser Header
|
||||
// Date: 2015-02-05
|
||||
// Author: Micooz
|
||||
// Copyright: Micooz
|
||||
// Desciption:
|
||||
// Defines OptionError, CParseItem, CParser
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#ifndef __CPARSER_H__
|
||||
#define __CPARSER_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace easypr {
|
||||
|
||||
// class OptionError
|
||||
|
||||
class OptionError : public std::exception
|
||||
{
|
||||
public:
|
||||
|
||||
explicit OptionError(const std::string &msg);
|
||||
|
||||
const char *what() const throw();
|
||||
|
||||
~OptionError() throw();
|
||||
|
||||
private:
|
||||
std::string _msg;
|
||||
};
|
||||
|
||||
// class CParseItem
|
||||
|
||||
class CParseItem
|
||||
{
|
||||
public:
|
||||
|
||||
explicit CParseItem(const std::string &val);
|
||||
|
||||
/*
|
||||
* dynamic type cast, support base data types including std::string
|
||||
* return T
|
||||
*/
|
||||
template<typename T> T as()
|
||||
{
|
||||
T r;
|
||||
std::stringstream buf;
|
||||
buf << _val;
|
||||
buf >> r;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* alias of as<std::string>()
|
||||
* return std::string
|
||||
*/
|
||||
std::string val() const;
|
||||
|
||||
private:
|
||||
std::string _val;
|
||||
};
|
||||
|
||||
// class CParser
|
||||
|
||||
typedef std::vector<std::string> ArgList;
|
||||
typedef std::map<std::string, CParseItem *> ParseResult;
|
||||
|
||||
class CParser
|
||||
{
|
||||
public:
|
||||
|
||||
explicit CParser(int argc, char *argv[]);
|
||||
|
||||
/*
|
||||
* parse the cmd line
|
||||
* return ParseResult*
|
||||
*/
|
||||
ParseResult *parse();
|
||||
|
||||
/*
|
||||
* check whether a cretain option exist
|
||||
* return bool
|
||||
*/
|
||||
bool has(const char *key);
|
||||
|
||||
/*
|
||||
* check whether a sequence of options exist
|
||||
* example: has_or(3, "he", "or", "she");
|
||||
* return bool
|
||||
*/
|
||||
bool has_or(int n, ...);
|
||||
|
||||
/*
|
||||
* check whether a sequence of options exist
|
||||
* example: has_and(3, "he", "and", "she");
|
||||
* return bool
|
||||
*/
|
||||
bool has_and(int n, ...);
|
||||
|
||||
/*
|
||||
* get the certain option's value
|
||||
* return ParseItem*
|
||||
*/
|
||||
CParseItem *get(const std::string &key);
|
||||
|
||||
/*
|
||||
* output all ParseResult
|
||||
*/
|
||||
void dump();
|
||||
|
||||
/*
|
||||
* release memory allocated in parse()
|
||||
*/
|
||||
~CParser();
|
||||
|
||||
private:
|
||||
ArgList _args;
|
||||
ParseResult *_pr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __CPARSER_H__
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,242 @@
|
||||
#include <iostream>
|
||||
#include <stdarg.h>
|
||||
#include "../include/CParser.h"
|
||||
|
||||
using namespace easypr;
|
||||
using namespace std;
|
||||
|
||||
// class OptionError
|
||||
|
||||
OptionError::OptionError(const string &msg)
|
||||
: _msg(msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char *
|
||||
OptionError::what() const throw()
|
||||
{
|
||||
string msg;
|
||||
msg.append("Command line parse error: ").append(_msg).push_back('.');
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
OptionError::~OptionError() throw()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// class CCParseItem
|
||||
|
||||
CParseItem::CParseItem(const string &val)
|
||||
: _val(val)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CParseItem *
|
||||
CParser::get(const string &key)
|
||||
{
|
||||
if (_pr->count(key)) {
|
||||
return (*_pr)[key];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string
|
||||
CParseItem::val() const
|
||||
{
|
||||
return _val;
|
||||
}
|
||||
|
||||
|
||||
// class CParser
|
||||
|
||||
CParser::CParser(int argc, char *argv[])
|
||||
: _pr(NULL)
|
||||
{
|
||||
_args.reserve(argc);
|
||||
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
_args.push_back(argv[i]);
|
||||
}
|
||||
// to make it easier, parse automatically
|
||||
this->parse();
|
||||
}
|
||||
|
||||
ParseResult *
|
||||
CParser::parse()
|
||||
{
|
||||
if (_pr) {
|
||||
return _pr;
|
||||
}
|
||||
|
||||
ArgList::iterator ibegin = _args.begin() + 1; // ignore the first cmd name
|
||||
ArgList::iterator iend = _args.end();
|
||||
ArgList::iterator it = ibegin;
|
||||
|
||||
_pr = new ParseResult;
|
||||
|
||||
string block;
|
||||
string previous(*ibegin);
|
||||
|
||||
for ( ; it != iend; ++it) {
|
||||
block.assign(*it);
|
||||
|
||||
switch (block.size()) {
|
||||
case 1:
|
||||
if (block == "-") {
|
||||
throw OptionError("single '-' is not allowed");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (block[0] == '-' ) {
|
||||
if (block[1] == '-') {
|
||||
throw OptionError("option '--' is incomplete");
|
||||
} else {
|
||||
// single option
|
||||
// etc: ./exec -s
|
||||
(*_pr)[block.substr(1)] = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // >=3
|
||||
if (block[0] == '-') {
|
||||
if (block[1] == '-') {
|
||||
// a long format option
|
||||
// etc: ./exec --option
|
||||
(*_pr)[block.substr(2)] = NULL;
|
||||
} else {
|
||||
// a conbination options
|
||||
// etc: ./exec -ab[...]
|
||||
string::iterator tbegin = block.begin() + 1; // ignore the first '-'
|
||||
string::iterator tend = block.end();
|
||||
string::iterator t = tbegin;
|
||||
|
||||
for (; t != tend; ++t) {
|
||||
string key;
|
||||
key.push_back(*t);
|
||||
(*_pr)[key] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}// switch
|
||||
|
||||
if (block[0] != '-'
|
||||
&& previous != block //not the first option
|
||||
) {
|
||||
// it's the value of previous option.
|
||||
// etc: ./exec -o [...]
|
||||
// etc: ./exec -opq [...]
|
||||
|
||||
if (previous[0] != '-') {
|
||||
// previous is not an option, error occur
|
||||
// etc: ./exec abc def
|
||||
throw OptionError("'" + block + "' is not allowed here");
|
||||
}
|
||||
|
||||
string key;
|
||||
key.push_back(*(previous.end() - 1));
|
||||
|
||||
if (_pr->count(key)) {
|
||||
(*_pr)[key] = new CParseItem(block);
|
||||
}
|
||||
}
|
||||
|
||||
previous = block;
|
||||
}// for
|
||||
|
||||
return _pr;
|
||||
}
|
||||
|
||||
bool
|
||||
CParser::has(const char *key)
|
||||
{
|
||||
string skey(key);
|
||||
|
||||
if (_pr && !skey.empty()) {
|
||||
if (skey[0] == '-') {
|
||||
//check conbination options, etc: CParser::has("-xyz")
|
||||
for (size_t i = 1; i < skey.size(); ++i) {
|
||||
string tkey;
|
||||
tkey.push_back(skey[i]);
|
||||
if (!_pr->count(tkey)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// check single option, etc: CParser::has("x")
|
||||
return _pr->count(skey);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CParser::has_or(int n, ...)
|
||||
{
|
||||
va_list keys;
|
||||
va_start(keys, n);
|
||||
while (n--) {
|
||||
const char *key = va_arg(keys, const char *);
|
||||
if (this->has(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
va_end(keys);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CParser::has_and(int n, ...)
|
||||
{
|
||||
va_list keys;
|
||||
va_start(keys, n);
|
||||
while (n--) {
|
||||
const char *key = va_arg(keys, const char *);
|
||||
if (!this->has(key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
va_end(keys);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CParser::dump()
|
||||
{
|
||||
if (_pr) {
|
||||
ParseResult::iterator ibegin = _pr->begin();
|
||||
ParseResult::iterator iend = _pr->end();
|
||||
ParseResult::iterator it = ibegin;
|
||||
for (; it != iend; ++it) {
|
||||
cout << it->first;
|
||||
if (it->second) {
|
||||
cout << " = " << it->second->val() << endl;
|
||||
} else {
|
||||
cout << " set" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CParser::~CParser()
|
||||
{
|
||||
if (_pr) {
|
||||
ParseResult::iterator ibegin = _pr->begin();
|
||||
ParseResult::iterator iend = _pr->end();
|
||||
ParseResult::iterator it = ibegin;
|
||||
for (; it != iend; ++it) {
|
||||
CParseItem *item = it->second;
|
||||
if (item) {
|
||||
delete item;
|
||||
item = NULL;
|
||||
}
|
||||
}
|
||||
delete _pr;
|
||||
_pr = NULL;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue