106 lines
1.9 KiB
C++
106 lines
1.9 KiB
C++
#pragma once
|
|
|
|
/*
|
|
TODO:
|
|
- implement setopt_long and setopt_long_only
|
|
- add support repeated options
|
|
- add support for embeding format strings
|
|
*/
|
|
|
|
#include <unordered_map>
|
|
#include <string>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
|
|
#define OPTPREFIX "-"
|
|
#define OPTLONGPREFIX "--"
|
|
#define OPTGAP " "
|
|
|
|
enum {
|
|
SETOPTINVALIDOPTSTRING = 1,
|
|
SETOPTMISSINGREQUIRED,
|
|
SETOPTUNKNOWNOPT
|
|
};
|
|
|
|
struct option {
|
|
const char *name;
|
|
int has_arg;
|
|
int *flag;
|
|
int val;
|
|
};
|
|
|
|
enum {
|
|
no_argument = 0,
|
|
required_argument = 1,
|
|
optional_argument = 2
|
|
};
|
|
|
|
int optc, optred, opterrno = 0;
|
|
|
|
static inline void setopt_init(){
|
|
optc = 0;
|
|
}
|
|
|
|
char* setopt(const char* optstring, std::unordered_map<char, std::string> argv){
|
|
setopt_init();
|
|
|
|
std::string rs;
|
|
|
|
for(const char* i = optstring; *i; i++){
|
|
if(not isgraph(*i) or
|
|
*i == '-' or
|
|
*i == ':' or
|
|
*i == ';'
|
|
){
|
|
opterrno = SETOPTINVALIDOPTSTRING;
|
|
continue;
|
|
}
|
|
|
|
auto h = argv.find(*i);
|
|
if(h != argv.end()){
|
|
const char &opt = h->first;
|
|
const std::string &optarg = h->second;
|
|
rs += OPTGAP;
|
|
rs += OPTPREFIX;
|
|
rs += opt;
|
|
++optc;
|
|
if(*(i+1) == ':'){
|
|
if(optarg != ""){
|
|
rs += OPTGAP;
|
|
rs += optarg;
|
|
}else if(*(i+2) == ':'){
|
|
++i;
|
|
}else{
|
|
opterrno = SETOPTMISSINGREQUIRED;
|
|
}
|
|
++i;
|
|
}
|
|
argv.erase(h);
|
|
}else{
|
|
for(int j = 0; j < 2; j++){
|
|
if(*(i+1) == ':'){
|
|
++i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(argv.size()){
|
|
opterrno = SETOPTUNKNOWNOPT;
|
|
}
|
|
|
|
char* r;
|
|
if(rs.size()){
|
|
r = new char[rs.size()-1];
|
|
strcpy(r, rs.c_str()+sizeof(OPTGAP)-1);
|
|
}else{
|
|
r = new char[1];
|
|
r[0] = '\00';
|
|
}
|
|
return r;
|
|
}
|
|
|
|
char* setopt_long(const char* optstring, std::unordered_map<std::string, std::string> argv, const struct option* longopts){ return NULL; }
|
|
char* setopt_long_only(const char* optstring, std::unordered_map<std::string, std::string> argv, const struct option* longopts){ return NULL; }
|