diff --git a/Contrib/ExDLL/plugin.c b/Contrib/ExDLL/plugin.c index ef60de6a..24b9e3fe 100644 --- a/Contrib/ExDLL/plugin.c +++ b/Contrib/ExDLL/plugin.c @@ -7,6 +7,7 @@ stack_t **g_stacktop; char *g_variables; // utility functions (not required but often useful) + int NSISCALL popstring(char *str) { stack_t *th; @@ -18,6 +19,17 @@ int NSISCALL popstring(char *str) return 0; } +int NSISCALL popstringn(char *str, int maxlen) +{ + stack_t *th; + if (!g_stacktop || !*g_stacktop) return 1; + th=(*g_stacktop); + if (str) lstrcpynA(str,th->text,maxlen?maxlen:g_stringsize); + *g_stacktop = th->next; + GlobalFree((HGLOBAL)th); + return 0; +} + void NSISCALL pushstring(const char *str) { stack_t *th; @@ -39,3 +51,126 @@ void NSISCALL setuservariable(const int varnum, const char *var) if (var != NULL && varnum >= 0 && varnum < __INST_LAST) lstrcpyA(g_variables + varnum*g_stringsize, var); } + +// playing with integers + +int NSISCALL myatoi(const char *s) +{ + int v=0; + if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) + { + s++; + for (;;) + { + int c=*(++s); + if (c >= '0' && c <= '9') c-='0'; + else if (c >= 'a' && c <= 'f') c-='a'-10; + else if (c >= 'A' && c <= 'F') c-='A'-10; + else break; + v<<=4; + v+=c; + } + } + else if (*s == '0' && s[1] <= '7' && s[1] >= '0') + { + for (;;) + { + int c=*(++s); + if (c >= '0' && c <= '7') c-='0'; + else break; + v<<=3; + v+=c; + } + } + else + { + int sign=0; + if (*s == '-') sign++; else s--; + for (;;) + { + int c=*(++s) - '0'; + if (c < 0 || c > 9) break; + v*=10; + v+=c; + } + if (sign) v = -v; + } + + return v; +} + +int NSISCALL myatoi_or(const char *s) +{ + int v=0; + if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) + { + s++; + for (;;) + { + int c=*(++s); + if (c >= '0' && c <= '9') c-='0'; + else if (c >= 'a' && c <= 'f') c-='a'-10; + else if (c >= 'A' && c <= 'F') c-='A'-10; + else break; + v<<=4; + v+=c; + } + } + else if (*s == '0' && s[1] <= '7' && s[1] >= '0') + { + for (;;) + { + int c=*(++s); + if (c >= '0' && c <= '7') c-='0'; + else break; + v<<=3; + v+=c; + } + } + else + { + int sign=0; + if (*s == '-') sign++; else s--; + for (;;) + { + int c=*(++s) - '0'; + if (c < 0 || c > 9) break; + v*=10; + v+=c; + } + if (sign) v = -v; + } + + // Support for simple ORed expressions + if (*s == '|') + { + v |= myatoi_or(s+1); + } + + return v; +} + +int NSISCALL popint() +{ + char buf[128]; + if (popstringn(buf,sizeof(buf))) + return 0; + + return myatoi(buf); +} + +int NSISCALL popint_or() +{ + char buf[128]; + if (popstringn(buf,sizeof(buf))) + return 0; + + return myatoi_or(buf); +} + +void NSISCALL pushint(int value) +{ + char buffer[1024]; + wsprintf(buffer, "%d", value); + pushstring(buffer); +} diff --git a/Contrib/ExDLL/plugin.h b/Contrib/ExDLL/plugin.h index 732322f0..29e1ab84 100644 --- a/Contrib/ExDLL/plugin.h +++ b/Contrib/ExDLL/plugin.h @@ -56,7 +56,13 @@ extern stack_t **g_stacktop; extern char *g_variables; int NSISCALL popstring(char *str); // 0 on success, 1 on empty stack +int NSISCALL popstringn(char *str, int maxlen); // with length limit, pass 0 for g_stringsize +int NSISCALL popint(); // pops an integer +int NSISCALL popint_or(); // with support for or'ing (2|4|8) +int NSISCALL myatoi(const char *s); // converts a string to an integer +int NSISCALL myatoi_or(const char *s); // with support for or'ing (2|4|8) void NSISCALL pushstring(const char *str); +void NSISCALL pushint(int value); char * NSISCALL getuservariable(const int varnum); void NSISCALL setuservariable(const int varnum, const char *var);