cleanup: arguments

This commit is contained in:
Zeno Rogue 2018-02-26 13:14:20 +01:00
parent bf108b671b
commit 283c6bba39
5 changed files with 91 additions and 67 deletions

View File

@ -9,31 +9,32 @@ string picfile = "hyperrogue.pic";
const char *musicfile = ""; const char *musicfile = "";
const char *loadlevel = NULL; const char *loadlevel = NULL;
eLand readland(const char *s) { bool appears(const string& haystack, const string& needle) {
string ss = s; return haystack.find(needle) != string::npos;
}
eLand readland(const string& ss) {
if(ss == "II") return laCrossroads2; if(ss == "II") return laCrossroads2;
if(ss == "III") return laCrossroads3; if(ss == "III") return laCrossroads3;
if(ss == "IV") return laCrossroads4; if(ss == "IV") return laCrossroads4;
if(ss == "V") return laCrossroads5; if(ss == "V") return laCrossroads5;
for(int l=0; l<landtypes; l++) if(strstr(linf[l].name, s) != NULL) { for(int l=0; l<landtypes; l++) if(appears(linf[l].name, ss)) {
return eLand(l); return eLand(l);
break; break;
} }
return laNone; return laNone;
} }
eItem readItem(const char *s) { eItem readItem(const string& ss) {
string ss = s; for(int i=0; i<ittypes; i++) if(appears(iinf[i].name, ss)) {
for(int i=0; i<ittypes; i++) if(strstr(iinf[i].name, s) != NULL) {
return eItem(i); return eItem(i);
break; break;
} }
return itNone; return itNone;
} }
eMonster readMonster(const char *s) { eMonster readMonster(const string& ss) {
string ss = s; for(int i=0; i<motypes; i++) if(appears(minf[i].name, ss)) {
for(int i=0; i<motypes; i++) if(strstr(minf[i].name, s) != NULL) {
return eMonster(i); return eMonster(i);
break; break;
} }
@ -59,10 +60,36 @@ void initializeCLI() {
#endif #endif
} }
namespace arg {
vector<string> argument;
int pos;
void lshift() { pos++; }
void shift() {
lshift(); if(pos >= size(argument)) { printf("Missing parameter\n"); exit(1); }
}
const string& args() { return argument[pos]; }
const char* argcs() { return args().c_str(); }
int argi() { return atoi(argcs()); }
int arghex() { return strtol(argcs(), NULL, 16); }
ld argf() { return atof(argcs()); }
bool argis(const string& s) { return args() == s; }
void init(int argc, char **argv) { for(int i=0; i<argc; i++) argument.push_back(argv[i]); shift(); }
void phaseerror(int x) {
printf("Command line error: cannot read command '%s' from phase %d in phase %d\n", args().c_str(), x, curphase);
exit(1);
}
}
int arg::readCommon() { int arg::readCommon() {
if(argis("-c")) { PHASE(1); shift(); conffile = args(); } if(argis("-c")) { PHASE(1); shift(); conffile = argcs(); }
else if(argis("-s")) { PHASE(1); shift(); scorefile = args(); } else if(argis("-s")) { PHASE(1); shift(); scorefile = argcs(); }
else if(argis("-m")) { PHASE(1); shift(); musicfile = args(); } else if(argis("-m")) { PHASE(1); shift(); musicfile = argcs(); }
#if CAP_SDLAUDIO #if CAP_SDLAUDIO
else if(argis("-se")) { PHASE(1); shift(); wheresounds = args(); } else if(argis("-se")) { PHASE(1); shift(); wheresounds = args(); }
#endif #endif
@ -82,15 +109,15 @@ int arg::readCommon() {
PHASE(2); PHASE(2);
firstland = specialland = laCanvas; firstland = specialland = laCanvas;
shift(); shift();
if(args()[1] == 0) patterns::whichCanvas = args()[0]; if(args().size() == 1) patterns::whichCanvas = args()[0];
else patterns::canvasback = strtol(args(), NULL, 16); else patterns::canvasback = arghex();
} }
else if(argis("-noplayer")) else if(argis("-noplayer"))
mapeditor::drawplayer = !mapeditor::drawplayer; mapeditor::drawplayer = !mapeditor::drawplayer;
else if(argis("-pattern")) { else if(argis("-pattern")) {
PHASE(3); PHASE(3);
shift(); shift();
const char *c = args(); const char *c = argcs();
using namespace patterns; using namespace patterns;
subpattern_flags = 0; subpattern_flags = 0;
whichPattern = 0; whichPattern = 0;
@ -118,13 +145,13 @@ int arg::readCommon() {
showstartmenu = false; showstartmenu = false;
} }
else if(argis("-back")) { else if(argis("-back")) {
shift(); backcolor = strtol(args(), NULL, 16); shift(); backcolor = arghex();
} }
else if(argis("-borders")) { else if(argis("-borders")) {
shift(); bordcolor = strtol(args(), NULL, 16); shift(); bordcolor = arghex();
} }
else if(argis("-fore")) { else if(argis("-fore")) {
shift(); forecolor = strtol(args(), NULL, 16); shift(); forecolor = arghex();
} }
else if(argis("-W2")) { else if(argis("-W2")) {
shift(); cheatdest = readland(args()); autocheat = true; shift(); cheatdest = readland(args()); autocheat = true;
@ -280,7 +307,7 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
} }
else if(argis("-qpar")) { else if(argis("-qpar")) {
int p; int p;
shift(); sscanf(args(), "%d,%d,%d", shift(); sscanf(argcs(), "%d,%d,%d",
&p, &quotientspace::rvadd, &quotientspace::rvdir &p, &quotientspace::rvadd, &quotientspace::rvdir
); );
autocheat = true; autocheat = true;
@ -297,7 +324,7 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
} }
if(geometry == gQuotient2) restartGame('g'); if(geometry == gQuotient2) restartGame('g');
int a, b; int a, b;
shift(); sscanf(args(), "%d,%d", &a, &b); shift(); sscanf(argcs(), "%d,%d", &a, &b);
using namespace fieldpattern; using namespace fieldpattern;
current_extra = a; current_extra = a;
fgeomextras[current_extra].current_prime_id = b; fgeomextras[current_extra].current_prime_id = b;
@ -310,14 +337,14 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
} }
else if(argis("-tpar")) { else if(argis("-tpar")) {
torusconfig::torus_mode = torusconfig::tmSingle; torusconfig::torus_mode = torusconfig::tmSingle;
shift(); sscanf(args(), "%d,%d,%d", shift(); sscanf(argcs(), "%d,%d,%d",
&torusconfig::qty, &torusconfig::qty,
&torusconfig::dx, &torusconfig::dx,
&torusconfig::dy &torusconfig::dy
); );
} }
else if(argis("-tparx")) { else if(argis("-tparx")) {
shift(); sscanf(args(), "%d,%d,%d", shift(); sscanf(argcs(), "%d,%d,%d",
(int*) &torusconfig::torus_mode, (int*) &torusconfig::torus_mode,
&torusconfig::sdx, &torusconfig::sdx,
&torusconfig::sdy &torusconfig::sdy
@ -383,7 +410,7 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
PHASEFROM(2); PHASEFROM(2);
shift(); shift();
int clWidth=0, clHeight=0, clFont=0; int clWidth=0, clHeight=0, clFont=0;
sscanf(args(), "%dx%dx%d", &clWidth, &clHeight, &clFont); sscanf(argcs(), "%dx%dx%d", &clWidth, &clHeight, &clFont);
if(clWidth) vid.xres = clWidth; if(clWidth) vid.xres = clWidth;
if(clHeight) vid.yres = clHeight; if(clHeight) vid.yres = clHeight;
if(clFont) vid.fsize = clFont; if(clFont) vid.fsize = clFont;
@ -452,12 +479,12 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
#if CAP_SDL #if CAP_SDL
else if(argis("-pngshot")) { else if(argis("-pngshot")) {
PHASE(3); shift(); PHASE(3); shift();
printf("saving PNG screenshot to %s\n", args()); printf("saving PNG screenshot to %s\n", argcs());
saveHighQualityShot(args()); saveHighQualityShot(argcs());
} }
#endif #endif
else if(argis("-svgsize")) { else if(argis("-svgsize")) {
shift(); sscanf(args(), "%d/%d", &svg::svgsize, &svg::divby); shift(); sscanf(argcs(), "%d/%d", &svg::svgsize, &svg::divby);
} }
else if(argis("-svgfont")) { else if(argis("-svgfont")) {
shift(); svg::font = args(); shift(); svg::font = args();
@ -465,18 +492,18 @@ else if(args()[0] == '-' && args()[1] == x && args()[2] == '0') { showstartmenu
// (this is helpful with Inkscape's PDF+TeX output feature; define \myfont yourself) // (this is helpful with Inkscape's PDF+TeX output feature; define \myfont yourself)
} }
else if(argis("-pngsize")) { else if(argis("-pngsize")) {
shift(); sscanf(args(), "%d", &pngres); shift(); pngres = argi();
} }
else if(argis("-pngformat")) { else if(argis("-pngformat")) {
shift(); sscanf(args(), "%d", &pngformat); shift(); pngformat = argi();
} }
else if(argis("-svggamma")) { else if(argis("-svggamma")) {
shift(); svg::gamma = argf(); shift(); svg::gamma = argf();
} }
else if(argis("-svgshot")) { else if(argis("-svgshot")) {
PHASE(3); shift(); PHASE(3); shift();
printf("saving SVG screenshot to %s\n", args()); printf("saving SVG screenshot to %s\n", argcs());
svg::render(args()); svg::render(argcs());
} }
else if(argis("--help") || argis("-h")) { else if(argis("--help") || argis("-h")) {
printf("Press F1 while playing to get ingame options.\n\n"); printf("Press F1 while playing to get ingame options.\n\n");
@ -532,7 +559,6 @@ purehookset hooks_config;
hookset<int()> *hooks_args; hookset<int()> *hooks_args;
namespace arg { namespace arg {
int argc; const char **argv;
int curphase; int curphase;
auto ah = addHook(hooks_args, 0, readCommon); auto ah = addHook(hooks_args, 0, readCommon);
@ -540,11 +566,11 @@ namespace arg {
void read(int phase) { void read(int phase) {
curphase = phase; curphase = phase;
callhooks(hooks_config); callhooks(hooks_config);
while(argc) { while(pos < size(argument)) {
for(auto& h: *hooks_args) { for(auto& h: *hooks_args) {
int r = h.second(); if(r == 2) return; if(r == 0) { lshift(); goto cont; } int r = h.second(); if(r == 2) return; if(r == 0) { lshift(); goto cont; }
} }
printf("Unknown option: %s\n", args()); printf("Unknown option: %s\n", argcs());
exit(3); exit(3);
cont: ; cont: ;
} }

View File

@ -40,12 +40,14 @@ void moreStack() {
} }
#endif #endif
hookset<bool(int argc, const char** argv)> *hooks_main; hookset<bool(int argc, char** argv)> *hooks_main;
#ifndef NOMAIN #ifndef NOMAIN
int main(int argc, const char **argv) { int main(int argc, char **argv) {
#if ISWEB #if ISWEB
emscripten_get_commandline(argc, argv); emscripten_get_commandline();
#else
arg::init(argc, argv);
#endif #endif
if(callhandlers(false, hooks_main, argc, argv)) return 0; if(callhandlers(false, hooks_main, argc, argv)) return 0;
#if !ISWEB #if !ISWEB
@ -54,7 +56,6 @@ int main(int argc, const char **argv) {
#endif #endif
#endif #endif
#if CAP_COMMANDLINE #if CAP_COMMANDLINE
arg::init(argc, argv);
initializeCLI(); initializeCLI();
#endif #endif
initAll(); initAll();

27
hyper.h
View File

@ -1503,29 +1503,22 @@ extern int cshpos;
namespace arg { namespace arg {
#if CAP_COMMANDLINE #if CAP_COMMANDLINE
extern int argc; extern const char **argv;
inline void lshift() { void lshift();
argc--; argv++;
}
inline void shift() { void shift();
lshift(); if(!argc) { printf("Missing parameter\n"); exit(1); }
}
inline const char* args() { return *argv; } const string& args();
inline int argi() { return atoi(*argv); } int argi();
inline ld argf() { return atof(*argv); } ld argf();
inline bool argis(const char *s) { return strcmp(*argv, s) == 0; } bool argis(const string& s);
int arghex();
inline void init(int _argc, const char **_argv) { argc=_argc-1; argv=_argv+1; } void init(int _argc, char **_argv);
extern int curphase; extern int curphase;
inline void phaseerror(int x) { void phaseerror(int x);
printf("Command line error: cannot read command '%s' from phase %d in phase %d\n", args(), x, curphase);
exit(1);
}
// returned values: 0 = ok, 1 = not recognized, 2 = shift phase // returned values: 0 = ok, 1 = not recognized, 2 = shift phase
int readCommon(); int readCommon();
@ -1758,7 +1751,7 @@ template<class T, class V, class... U> V callhandlers(V zero, hookset<T> *h, U&.
extern hookset<bool(int sym, int uni)> *hooks_handleKey; extern hookset<bool(int sym, int uni)> *hooks_handleKey;
extern hookset<void(cell *c, const transmatrix& V)> *hooks_drawcell; extern hookset<void(cell *c, const transmatrix& V)> *hooks_drawcell;
extern hookset<bool(int argc, const char** argv)> *hooks_main; extern hookset<bool(int argc, char** argv)> *hooks_main;
extern hookset<int()> *hooks_args; extern hookset<int()> *hooks_args;
extern hookset<eLand(eLand)> *hooks_nextland; extern hookset<eLand(eLand)> *hooks_nextland;

View File

@ -24,7 +24,7 @@ template<class A, class B, class C> void emscripten_set_main_loop(A a, B b, C c)
#endif #endif
void initweb(); void initweb();
void emscripten_get_commandline(int& argc, const char **& argv); void emscripten_get_commandline();
void loadCompressedChar(int &otwidth, int &otheight, int *tpix); void loadCompressedChar(int &otwidth, int &otheight, int *tpix);
@ -151,10 +151,10 @@ transmatrix getOrientation() {
rotmatrix(0, 2, gamma * M_PI / 180); rotmatrix(0, 2, gamma * M_PI / 180);
} }
vector<string> emscripten_args; void emscripten_get_commandline() {
vector<const char*> emscripten_args_c; #ifdef EMSCRIPTEN_FIXED_ARG
string s = EMSCRIPTEN_FIXED_ARG;
void emscripten_get_commandline(int& argc, const char **& argv) { #else
char *str = (char*)EM_ASM_INT({ char *str = (char*)EM_ASM_INT({
var jsString = document.location.href; var jsString = document.location.href;
var lengthBytes = lengthBytesUTF8(jsString)+1; var lengthBytes = lengthBytesUTF8(jsString)+1;
@ -163,14 +163,17 @@ void emscripten_get_commandline(int& argc, const char **& argv) {
return stringOnWasmHeap; return stringOnWasmHeap;
}); });
string s = str; string s = str;
#endif
s += "+xxxxxx"; s += "+xxxxxx";
for(int i=0; i<size(s); i++) if(s[i] == '?') { for(int i=0; i<size(s); i++) if(s[i] == '?') {
#ifndef EMSCRIPTEN_FIXED_ARG
printf("HREF: %s\n", str); printf("HREF: %s\n", str);
emscripten_args.push_back("hyperweb"); #endif
arg::argument.push_back("hyperweb"); arg::lshift();
string next = ""; i += 3; string next = ""; i += 3;
for(; i<size(s); i++) { for(; i<size(s); i++) {
if(s[i] == '+') { if(s[i] == '+') {
emscripten_args.push_back(next); arg::argument.push_back(next);
next = ""; next = "";
} }
else if(s[i] == '%') { else if(s[i] == '%') {
@ -182,11 +185,12 @@ void emscripten_get_commandline(int& argc, const char **& argv) {
} }
else next += s[i]; else next += s[i];
} }
argc = size(emscripten_args); printf("Arguments:"); for(string s: arg::argument) printf(" %s", s.c_str()); printf("\n");
for(string& s: emscripten_args) emscripten_args_c.push_back(s.c_str()); break;
argv = &(emscripten_args_c[0]);
printf("Arguments:"); for(int i=0; i<argc; i++) printf(" %s", argv[i]); printf("\n");
} }
#ifndef EMSCRIPTEN_FIXED_ARG
free(str); free(str);
#endif
} }

View File

@ -196,8 +196,8 @@ namespace mapstream {
return dir; return dir;
} }
bool loadMap(const char *fname) { bool loadMap(const string& fname) {
f = fopen(fname, "rb"); f = fopen(fname.c_str(), "rb");
if(!f) return false; if(!f) return false;
clearMemory(); clearMemory();
int vernum = loadInt(); int vernum = loadInt();