diff --git a/Source/lineparse.cpp b/Source/lineparse.cpp index 71491071..2af369cf 100644 --- a/Source/lineparse.cpp +++ b/Source/lineparse.cpp @@ -75,39 +75,23 @@ void LineParser::eattoken() m_eat++; } -double LineParser::gettoken_float(int token, int *success/*=0*/) const +static unsigned int number_has_base_prefix(const TCHAR *str) { - token+=m_eat; - if (token < 0 || token >= m_nt) + unsigned int hasbase = false; + if (_T('-') == *str || _T('+') == *str) ++str; + if (_T('0') == str[0]) { - if (success) *success=0; - return 0.0; + if (_T('x') == (str[1]|32)) ++hasbase; + if (_T('n') == (str[1]|32)) ++hasbase; + if (_T('b') == (str[1]|32) || _T('y') == (str[1]|32)) ++hasbase; + if (_T('o') == (str[1]|32) || _T('t') == (str[1]|32)) ++hasbase; } - if (success) - { - TCHAR *t=m_tokens[token]; - if (_T('-') == *t || _T('+') == *t) ++t; - *success=*t?1:0; - unsigned int dotcount = 0; - while (*t) - { - if (_T('.') == *t && ++dotcount > 1) *success=0; - if ((*t < _T('0') || *t > _T('9'))&&*t != _T('.')) *success=0; - t++; - } - } - return _tstof(m_tokens[token]); + return hasbase; } -int LineParser::gettoken_int(int token, int *success/*=0*/) const +int LineParser::parse_int(const TCHAR *str, int *success/*=0*/) { - token+=m_eat; - if (token < 0 || token >= m_nt || !m_tokens[token][0]) - { - if (success) *success=0; - return 0; - } - const TCHAR *p=m_tokens[token], *parse=p; + const TCHAR *p=str, *parse=p; TCHAR *end; int neg=0, base=0, num; if (_T('+') == *p) @@ -134,18 +118,56 @@ int LineParser::gettoken_int(int token, int *success/*=0*/) const return num; } +int LineParser::gettoken_int(int token, int *success/*=0*/) const +{ + token+=m_eat; + if (token < 0 || token >= m_nt || !m_tokens[token][0]) + { + if (success) *success=0; + return 0; + } + return parse_int(m_tokens[token], success); +} + +double LineParser::parse_float(const TCHAR *str, int *success/*=0*/) +{ + if (success) + { + const TCHAR *t=str; + if (_T('-') == *t || _T('+') == *t) ++t; + *success=*t ? 1 : 0; + unsigned int dotcount = 0; + while (*t) + { + if (_T('.') == *t && ++dotcount > 1) *success=0; + if ((*t < _T('0') || *t > _T('9')) && *t != _T('.')) *success=0; + t++; + } + } + return _tstof(str); +} + +double LineParser::gettoken_float(int token, int *success/*=0*/) const +{ + token+=m_eat; + if (token < 0 || token >= m_nt) + { + if (success) *success=0; + return 0.0; + } + return parse_float(m_tokens[token], success); +} + +double LineParser::parse_number(const TCHAR *str, int *success/*=0*/) +{ + const unsigned int forceint = number_has_base_prefix(str); + return forceint ? parse_int(str,success) : parse_float(str,success); +} + double LineParser::gettoken_number(int token, int *success/*=0*/) const { const TCHAR*str=gettoken_str(token); - if (_T('-') == *str || _T('+') == *str) ++str; - unsigned int forceint = false; - if (_T('0') == str[0]) - { - if (_T('x') == (str[1]|32)) ++forceint; - if (_T('n') == (str[1]|32)) ++forceint; - if (_T('b') == (str[1]|32) || _T('y') == (str[1]|32)) ++forceint; - if (_T('o') == (str[1]|32) || _T('t') == (str[1]|32)) ++forceint; - } + const unsigned int forceint = number_has_base_prefix(str); return forceint ? gettoken_int(token,success) : gettoken_float(token,success); } diff --git a/Source/lineparse.h b/Source/lineparse.h index 70fcb292..0160f757 100644 --- a/Source/lineparse.h +++ b/Source/lineparse.h @@ -32,13 +32,17 @@ class LineParser { int parse(TCHAR *line, int ignore_escaping=0); // returns -1 on error int getnumtokens(); void eattoken(); - double gettoken_float(int token, int *success=0) const; int gettoken_int(int token, int *success=0) const; + double gettoken_float(int token, int *success=0) const; double gettoken_number(int token, int *success=0) const; int gettoken_binstrdata(int token, char*buffer, int bufcap) const; TCHAR *gettoken_str(int token) const; int gettoken_enum(int token, const TCHAR *strlist); // null separated list + static int parse_int(const TCHAR *str, int *success=0); + static double parse_float(const TCHAR *str, int *success=0); + static double parse_number(const TCHAR *str, int *success=0); + private: void freetokens(); diff --git a/Source/script.cpp b/Source/script.cpp index fcc2e557..5a9ee0a4 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -80,6 +80,13 @@ static UINT ParseCtlColor(const TCHAR*Str, int&CCFlags, int CCFlagmask) } #endif //~ NSIS_CONFIG_ENHANCEDUI_SUPPORT +static LANGID ParseLangId(const TCHAR*Str) +{ + const TCHAR *p = Str; + if (_T('+') == *p || _T('-') == *p) ++p; + return _T('0') == p[0] && _T('x') == (p[1]|32) ? LineParser::parse_int(Str) : _ttoi(Str); +} + int CEXEBuild::process_script(NIStream&Strm, const TCHAR *filename) { NStreamLineReader linereader(Strm); @@ -2162,7 +2169,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) unsigned char failed = 0; if (!_tcsnicmp(line.gettoken_str(1), _T("/LANG="), 6)) { - LANGID lang_id = _ttoi(line.gettoken_str(1) + 6); + LANGID lang_id = ParseLangId(line.gettoken_str(1) + 6); LanguageTable *table = GetLangTable(lang_id); const TCHAR*facename = line.gettoken_str(2); table->nlf.m_szFont = _tcsdup(facename); @@ -4815,7 +4822,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) const bool forceneutrallang = !_tcsicmp(line.gettoken_str(a),_T("/LANG=0")); if (!_tcsnicmp(line.gettoken_str(a),_T("/LANG="),6)) - LangID=_ttoi(line.gettoken_str(a++)+6); + LangID=ParseLangId(line.gettoken_str(a++)+6); if (line.getnumtokens()!=a+2) PRINTHELP(); TCHAR *pKey = line.gettoken_str(a); TCHAR *pValue = line.gettoken_str(a+1);