#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; }