diff --git a/Contrib/nsDialogs/example.nsi b/Contrib/nsDialogs/example.nsi index ef704089..ea8e3bc8 100644 --- a/Contrib/nsDialogs/example.nsi +++ b/Contrib/nsDialogs/example.nsi @@ -11,6 +11,7 @@ LicenseText "All the action takes place on the next page..." Page license Page custom nsDialogsPage +!pragma warning disable 8000 ; "Page instfiles not used, no sections will be executed!" Var BUTTON Var EDIT diff --git a/Contrib/nsDialogs/timer.nsi b/Contrib/nsDialogs/timer.nsi index 907f7bb0..c24ef2c0 100644 --- a/Contrib/nsDialogs/timer.nsi +++ b/Contrib/nsDialogs/timer.nsi @@ -16,6 +16,7 @@ Var BUTTON Var BUTTON2 Page custom nsDialogsPage +!pragma warning disable 8000 ; "Page instfiles not used, no sections will be executed!" Function OnTimer diff --git a/Docs/src/compiler.but b/Docs/src/compiler.but index 5cf9fa85..eb36fa7f 100644 --- a/Docs/src/compiler.but +++ b/Docs/src/compiler.but @@ -173,6 +173,16 @@ This command will issue a warning to the script compiler. You can also add a mes \c !warning "using dangerous stuff" \c !endif +\S1{pragma} !pragma + +\c warning code +\c warning + +The pragma commands allows you to change compiler features and behavior. + +\c !pragma warning disable 9000 ; Disable warning about using "Setup.exe" as the name +\c OutFile "Setup.exe" + \S1{verbose} !verbose \c level | push | pop diff --git a/Docs/src/history.but b/Docs/src/history.but index a5f71029..64f04dab 100644 --- a/Docs/src/history.but +++ b/Docs/src/history.but @@ -12,6 +12,8 @@ Released on ? ?th, 2017 \b Added \R{writeregmultistr}{WriteRegMultiStr} (\W{http://sf.net/p/nsis/feature-requests/382}{RFE #382}, \W{http://sf.net/p/nsis/patches/219}{patch #219}) +\b Added \R{pragma}{!pragma warning} (\W{http://sf.net/p/nsis/patches/267}{patch #267}) + \S2{} Minor Changes \b MultiUser now supports $ProgramFiles64 (\W{http://sf.net/p/nsis/bugs/843}{bug #843}) diff --git a/Source/build.cpp b/Source/build.cpp index 673262a1..0855d5a7 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -713,7 +713,7 @@ int CEXEBuild::preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage/*=CP if (_tcsstr(tbuf,_T(" "))) _tcsstr(tbuf,_T(" "))[0]=0; } if ( bDoWarning ) - warning_fl(_T("unknown variable/constant \"%") NPRIs _T("\" detected, ignoring"),tbuf); + warning_fl(DW_VAR_IGNORED_UNKNOWN, _T("unknown variable/constant \"%") NPRIs _T("\" detected, ignoring"),tbuf); i = _T('$'); // redundant since i is already '$' and has not changed. } } // else @@ -1680,7 +1680,7 @@ int CEXEBuild::resolve_coderefs(const TCHAR *str) { if (sec->code_size>0) { - warning(_T("%") NPRIs _T(" function \"%") NPRIs _T("\" not referenced - zeroing code (%d-%d) out\n"),str, + warning(DW_UNUSED_FUNCTION, _T("%") NPRIs _T(" function \"%") NPRIs _T("\" not referenced - zeroing code (%d-%d) out\n"),str, ns_func.get()+sec->name_ptr, sec->code,sec->code+sec->code_size); memset(w+sec->code,0,sec->code_size*sizeof(entry)); @@ -1700,8 +1700,8 @@ int CEXEBuild::resolve_coderefs(const TCHAR *str) if (!t->flags) { TCHAR *n=(TCHAR*)ns_label.get()+t->name_ptr; - if (*n == _T('.')) warning(_T("global label \"%") NPRIs _T("\" not used"),n); - else warning(_T("label \"%") NPRIs _T("\" not used"),n); + if (*n == _T('.')) warning(DW_UNUSED_GLOBALLABEL, _T("global label \"%") NPRIs _T("\" not used"),n); + else warning(DW_UNUSED_LABEL, _T("label \"%") NPRIs _T("\" not used"),n); } t++; } @@ -1834,7 +1834,7 @@ int CEXEBuild::AddVersionInfo() { if ( !*recverkeys ) break; if ( !rVersionInfo.FindKey(lang_id, code_page, recverkeys) ) - warning(_T("Generating version information for language \"%04d-%") NPRIs _T("\" without standard key \"%") NPRIs _T("\""), lang_id, lang_name, recverkeys); + warning(DW_VI_MISSINGSTDKEY, _T("Generating version information for language \"%04d-%") NPRIs _T("\" without standard key \"%") NPRIs _T("\""), lang_id, lang_name, recverkeys); recverkeys += _tcsclen(recverkeys) + 1; } @@ -2160,7 +2160,7 @@ again: } if (!instlog_used) { - warning(_T("%") NPRIs _T("age instfiles not used, no sections will be executed!"), uninstall_mode ? _T("Uninstall p") : _T("P")); + warning(DW_INSTFILESPAGE_NOT_USED, _T("%") NPRIs _T("age instfiles not used, no sections will be executed!"), uninstall_mode ? _T("Uninstall p") : _T("P")); } } } @@ -2487,7 +2487,7 @@ int CEXEBuild::prepare_uninstaller() { { if (!uninstaller_writes_used) { - warning(_T("Uninstaller script code found but WriteUninstaller never used - no uninstaller will be created.")); + warning(DW_UNCODE_WITHOUT_UNEXE, _T("Uninstaller script code found but WriteUninstaller never used - no uninstaller will be created.")); return PS_OK; } @@ -2544,7 +2544,7 @@ int CEXEBuild::pack_exe_header() return PS_ERROR; } if (ec != 0) - warning(_T("Packer returned %d, \"%") NPRIs _T("\" might still be unpacked\n"),ec,build_packname); + warning(DW_PACKHDR_RETNONZERO, _T("Packer returned %d, \"%") NPRIs _T("\" might still be unpacked\n"),ec,build_packname); int result = update_exehead(build_packname); _tremove(build_packname); @@ -2646,7 +2646,7 @@ int CEXEBuild::write_output(void) { const bool orgdispwarn = display_warnings; display_warnings = false; // Don't display warning inline in the middle of our statistics output. - warning(_T("Insecure filename \"%") NPRIs _T("\", Windows will unsafely load compatibility shims into the process."), fname); + warning(DW_INSECURE_OUTFILENAME, _T("Insecure filename \"%") NPRIs _T("\", Windows will unsafely load compatibility shims into the process."), fname); display_warnings = orgdispwarn; } } @@ -3406,23 +3406,83 @@ void CEXEBuild::set_verbosity(int lvl) g_display_errors = display_errors; } -void CEXEBuild::warninghelper(const TCHAR *msg) +int CEXEBuild::parse_pragma(LineParser &line) { - m_warnings.add(msg,0); + if (line.gettoken_enum(1, _T("warning\0")) == -1) + return (warning_fl(DW_PP_PRAGMA_UNKNOWN, _T("Unknown pragma")), PS_ERROR); + int warnOp = line.gettoken_enum(2, _T("disable\0enable\0default\0push\0pop\0")), ret = PS_OK; + if (warnOp < 0) + ret = PS_ERROR, warning_fl(DW_PP_PRAGMA_UNKNOWN, _T("Unknown pragma")); // Unknown warning pragma action + else if (warnOp == 3) + diagstate.Push(); + else if (warnOp == 4) + { + if (!diagstate.Pop()) + ret = PS_WARNING, warning_fl(DW_PP_PRAGMA_INVALID, _T("Unexpected")); + } + else // warning: disable/enable/default + { + for (int ti = 3; ti < line.getnumtokens(); ++ti) + { + DIAGCODE code = static_cast(line.gettoken_int(ti)); + if (!diagstate.IsValidCode(code)) + ret = PS_WARNING, warning_fl(DW_PP_PRAGMA_INVALID, _T("Invalid number: \"%") NPRIs _T("\""), line.gettoken_str(ti)); + else if (warnOp == 0) + diagstate.Disable(code); + else // if ((warnOp == 1) | (warnOp == 2)) All warnings currently default to enabled + diagstate.Enable(code); + } + } + return ret; +} + +void CEXEBuild::DiagState::Push() +{ + CEXEBuild::DiagState *p = new DiagState(); + p->m_Disabled = m_Disabled; // Copy current state + p->m_pStack = m_pStack, m_pStack = p; +} +bool CEXEBuild::DiagState::Pop() +{ + if (!m_pStack) return false; + CEXEBuild::DiagState *pPop = m_pStack; + m_pStack = pPop->m_pStack, pPop->m_pStack = 0; + m_Disabled.swap(pPop->m_Disabled); + delete pPop; + return true; +} + +void CEXEBuild::warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list args) +{ extern bool g_warnaserror; - MakensisAPI::notify_e hostnotifyevnt = MakensisAPI::NOTIFY_WARNING; - if (g_warnaserror) - { - hostnotifyevnt = MakensisAPI::NOTIFY_ERROR; - display_warnings = display_errors; - } - notify(hostnotifyevnt, msg); + bool showcode = dc != DIAGCODE_INTERNAL_HIDEDIAGCODE; + if (diagstate.IsDisabled(dc)) return ; - if (display_warnings) + TCHAR codbuf[11+2+!0]; + _stprintf(codbuf, showcode ? _T("%u: ") : _T(""), static_cast(dc)); + ExpandoString msgbuf; + ExpandoString fmtbuf; + fmtbuf.StrFmt(_T("%") NPRIs _T("%") NPRIs, codbuf, fmt); + size_t cchMsg = msgbuf.StrVFmt(fmtbuf.GetPtr(), args); + if (fl) { - PrintColorFmtMsg_WARN(_T("warning: %") NPRIs _T("\n"), msg); + msgbuf.Reserve(cchMsg+2+_tcslen(curfilename)+1+11+1+!0); + _stprintf(&msgbuf[cchMsg], _T(" (%") NPRIs _T(":%u)"), curfilename, linecnt); } + const TCHAR *msg = msgbuf.GetPtr(); + + m_warnings.add(msg,0); // Add to list of warnings to display at the end + + MakensisAPI::notify_e hostevent = MakensisAPI::NOTIFY_WARNING; + if (g_warnaserror) + hostevent = MakensisAPI::NOTIFY_ERROR, display_warnings = display_errors; + + notify(hostevent, msg); // Notify the host + + if (display_warnings) // Print "warning %msgwithcodeprefix%" or "warning: %msg%" + PrintColorFmtMsg_WARN(_T("warning%") NPRIs _T("%") NPRIs _T("\n"), showcode ? _T(" ") : _T(": "), msg); + if (g_warnaserror) { ERROR_MSG(_T("Error: warning treated as error\n")); @@ -3432,28 +3492,20 @@ void CEXEBuild::warninghelper(const TCHAR *msg) } } -void CEXEBuild::warning(const TCHAR *s, ...) +void CEXEBuild::warning(DIAGCODE dc, const TCHAR *s, ...) { - ExpandoString buf; va_list val; - va_start(val,s); - buf.StrFmt(s,val); + va_start(val, s); + warninghelper(dc, false, s, val); va_end(val); - - warninghelper(buf.GetPtr()); } -void CEXEBuild::warning_fl(const TCHAR *s, ...) +void CEXEBuild::warning_fl(DIAGCODE dc, const TCHAR *s, ...) { - ExpandoString buf; va_list val; - va_start(val,s); - size_t cchMsg = buf.StrFmt(s, val); + va_start(val, s); + warninghelper(dc, true, s, val); va_end(val); - - buf.Reserve(cchMsg+2+_tcslen(curfilename)+50+1+!0); - _stprintf(&buf[cchMsg], _T(" (%") NPRIs _T(":%u)"), curfilename, linecnt); - warninghelper(buf.GetPtr()); } void CEXEBuild::ERROR_MSG(const TCHAR *s, ...) const @@ -3463,7 +3515,7 @@ void CEXEBuild::ERROR_MSG(const TCHAR *s, ...) const ExpandoString buf; va_list val; va_start(val,s); - buf.StrFmt(s,val); + buf.StrVFmt(s,val); va_end(val); notify(MakensisAPI::NOTIFY_ERROR, buf.GetPtr()); @@ -3763,7 +3815,7 @@ void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList) { if (!pVarsStringList->get_reference(i)) { - warning(_T("Variable \"%") NPRIs _T("\" not referenced or never set, wasting memory!"), pVarsStringList->idx2name(i)); + warning(DW_VAR_NOREF, _T("Variable \"%") NPRIs _T("\" not referenced or never set, wasting memory!"), pVarsStringList->idx2name(i)); } } } diff --git a/Source/build.h b/Source/build.h index efa99854..778e53b7 100644 --- a/Source/build.h +++ b/Source/build.h @@ -50,11 +50,75 @@ #include "czlib.h" #include "cbzip2.h" #include "clzma.h" -#endif//NSIS_CONFIG_COMPRESSION_SUPPORT +#endif //~ NSIS_CONFIG_COMPRESSION_SUPPORT #ifdef NSIS_CONFIG_PLUGIN_SUPPORT # include "Plugins.h" -#endif //NSIS_CONFIG_PLUGIN_SUPPORT +#endif //~ NSIS_CONFIG_PLUGIN_SUPPORT + +// 1000..4999 Errors +// 5000..5999 Important generic warnings +// 6000..6999 Script warnings +// 7000..7499 Recovered from bad input etc. warnings +// 7500..7999 Discouraged usage warnings (allocated top to bottom to reserve as much space as possible for more bad input codes) +// 8000..8999 Generic warnings +// 9000..9999 Breaking our and/or MS guidelines warnings +typedef enum { + //DE_OOM = 1000?, // Generic out of memory + //DE_MMAP = 1001?, + //DE_STUB_SECTION = 1100?, + //DE_PP_VERBOSE_BAD_LEVEL = 4000?, + //DW_STALE_TEMP = 5020?, TODO: There is currently no way to disable this + DW_PACKHDR_RETNONZERO = 5021, + DW_UNSUPP_STORE_FILE_ATT = 5050, + //DW_CMDLINE_UNSUPP = 5200?, + //DW_CMDLINE_UNSUPP_WIN = 5201?, + DW_CMDLINE_UNSUPP_NIX = 5202, + DW_CMDLINE_BAD_INPUTENC = 5210, // reserved ..5229 + DW_VAR_IGNORED_UNKNOWN = 6000, // reserved ..6009 + DW_VAR_NOREF = 6001, + DW_UNUSED_FUNCTION = 6010, // reserved ..6019 + DW_UNUSED_GLOBALLABEL = 6011, + DW_UNUSED_LABEL = 6012, + DW_UNCODE_WITHOUT_UNEXE = 6020, + DW_INNERSTRING_MULTISETWASTE = 6029, + DW_STRING_MULTISETWASTE = DW_INNERSTRING_MULTISETWASTE, + DW_LANGSTRING_MULTISETWASTE = 6030, // reserved ..6049 + DW_LANGSTRING_NOTSETINLANG = 6040, + DW_LANGSTRING_SILENTLICENSE = 6049, + DW_COMMENT_NEWLINE = 6050, // reserved ..6079 + DW_PLUGIN_NOUNLOAD_PLACEMENT = 6080, // reserved ..6099 + DW_PP_PRAGMA_UNKNOWN = 6100, // reserved ..6199 + DW_PP_PRAGMA_INVALID = 6101, + DW_PP_VERBOSE_POP_EMPTY_STACK = 6150, + //DW_PP_VERBOSE_BAD_LEVEL = 6151?, // 2.x failed to issue a warning. 3.x currently aborts with hard error. + DW_INCLUDE_NONFATAL_NOT_FOUND = 7000, // reserved ..7009 + DW_FILE_NONFATAL_NOT_FOUND = 7010, // reserved ..7019 + DW_LANGSTRING_OVERLONGLENGTH = 7020, // reserved ..7024 + DW_BAD_LANGID = 7025, // reserved ..7029 + DW_NLF_OLDVERSION = 7030, // reserved ..7049 + DW_NLF_SYSCP = 7031, + DW_NLF_UNSUPPORTED_CP = 7032, + DW_NLF_NOT_PREFERRED_ENC = 7033, + DW_LICENSE_EMPTY = 7050, + DW_ATTRIBUTE_OVERLONGSTRING = 7060, + DW_PARSE_BADNUMBER = 7070, + DW_PARSE_LNK_HK = 7075, + DW_PARSE_REGPATHPREFIX = 7999, + DW_INSTFILESPAGE_NOT_USED = 8000, // reserved ..8019 + DW_COMP_FINAL = 8020, // reserved ..8059 + DW_COMP_WHOLE_IGNORE_OFF = 8021, + DW_COMP_LEVEL_IGNORE = 8025, + DW_COMP_DICT_IGNORE = 8026, + DW_COMP_DICTWHOLE = 8030, + DW_CMDLINE_HIGHPRIORITY = 8499, + DW_INSECURE_OUTFILENAME = 9000, + DW_VI_MISSINGSTDKEY = 9100, + + DIAGCODE_INTERNAL_HIDEDIAGCODE = 9999, + DIAGCODE_INTERNAL_FIRST = 1000, DIAGCODE_INTERNAL_LAST = 9999 +} DIAGCODE; + #define PS_OK 0 #define PS_EOF 1 @@ -112,11 +176,25 @@ class CEXEBuild { MAX_MACRORECURSION = 50 }; - void warning(const TCHAR *s, ...); // to add a warning to the compiler's warning list. - void warning_fl(const TCHAR *s, ...); // warning with file name and line count + void warning(DIAGCODE dc, const TCHAR *s, ...); // to add a warning to the compiler's warning list. + void warning_fl(DIAGCODE dc, const TCHAR *s, ...); // warning with file name and line number void ERROR_MSG(const TCHAR *s, ...) const; void SCRIPT_MSG(const TCHAR *s, ...) const; void INFO_MSG(const TCHAR *s, ...) const; + class DiagState { + public: + DiagState() : m_pStack(0) { assert(DIAGCODE_INTERNAL_LAST <= 0xffff); } + ~DiagState() { delete m_pStack; } + void Enable(DIAGCODE n) { m_Disabled.erase(static_cast(n)); } + void Disable(DIAGCODE n) { m_Disabled.insert(static_cast(n)); } + bool IsDisabled(DIAGCODE n) { return m_Disabled.find(static_cast(n)) != m_Disabled.end(); } + void Push(); + bool Pop(); + static bool IsValidCode(unsigned int n) { return n >= DIAGCODE_INTERNAL_FIRST && n <= DIAGCODE_INTERNAL_LAST; } + protected: + DiagState *m_pStack; + std::set m_Disabled; + } diagstate; typedef enum { TARGETFIRST, @@ -277,6 +355,7 @@ class CEXEBuild { int preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage=CP_ACP); void init_shellconstantvalues(); + int parse_pragma(LineParser &line); #ifdef NSIS_CONFIG_PLUGIN_SUPPORT int add_plugins_dir_initializer(void); @@ -308,7 +387,7 @@ class CEXEBuild { int resolve_coderefs(const TCHAR *str); void print_warnings(); - void warninghelper(const TCHAR *msg); + void warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list args); int uninstall_generate(); /** Are we defining an uninstall version of the code? diff --git a/Source/lang.cpp b/Source/lang.cpp index dd3a0f35..26dde9e2 100644 --- a/Source/lang.cpp +++ b/Source/lang.cpp @@ -494,7 +494,7 @@ int CEXEBuild::SetLangString(const TCHAR *name, LANGID lang, const TCHAR *str, B int sn; if (!LicenseData && _tcsclen(str) > NSIS_MAX_STRLEN-1) - warning_fl(_T("LangString \"%") NPRIs _T("\" longer than NSIS_MAX_STRLEN!"), name); + warning_fl(DW_LANGSTRING_OVERLONGLENGTH, _T("LangString \"%") NPRIs _T("\" longer than NSIS_MAX_STRLEN!"), name); int pos = build_langstrings.get(name, &sn); if (pos < 0) @@ -589,9 +589,9 @@ int CEXEBuild::GenerateLangTable(LanguageTable *lt, int num_lang_tables) { if (lsn[0] != _T('^')) { if (lt[i].nlf.m_bLoaded) - warning(_T("LangString \"%") NPRIs _T("\" is not set in language table of language %") NPRIs, lsn, lt[i].nlf.m_szName); + warning(DW_LANGSTRING_NOTSETINLANG, _T("LangString \"%") NPRIs _T("\" is not set in language table of language %") NPRIs, lsn, lt[i].nlf.m_szName); else - warning(_T("LangString \"%") NPRIs _T("\" is not set in language table of language %d"), lsn, lt[i].lang_id); + warning(DW_LANGSTRING_NOTSETINLANG, _T("LangString \"%") NPRIs _T("\" is not set in language table of language %d"), lsn, lt[i].lang_id); } } else @@ -1009,7 +1009,7 @@ l_readerr: if (p) *p = t; if (nlf_version != NLF_VERSION) { - warning_fl(_T("%") NPRIs _T(" language file version doesn't match. Using default English texts for missing strings."), nlf->m_szName); + warning_fl(DW_NLF_OLDVERSION, _T("%") NPRIs _T(" language file version doesn't match. Using default English texts for missing strings."), nlf->m_szName); } // set ^Language @@ -1049,11 +1049,11 @@ l_readerr: } if ((unsigned)nlf->m_uCodePage <= 1 && !lr.IsUnicode()) // Warn if someone uses a system specific codepage { - warning_fl(_T("%") NPRIs _T(" language file uses the system default codepage!"), nlf->m_szName); + warning_fl(DW_NLF_SYSCP, _T("%") NPRIs _T(" language file uses the system default codepage!"), nlf->m_szName); } if (CP_ACP != nlf->m_uCodePage && !isnlfdataucp && !IsValidCodePage(nlf->m_uCodePage)) { - warning_fl(_T("%") NPRIs _T(" language file uses a codepage (%d) that is not supported on this system, using ACP!"), nlf->m_szName, nlf->m_uCodePage); + warning_fl(DW_NLF_UNSUPPORTED_CP, _T("%") NPRIs _T(" language file uses a codepage (%d) that is not supported on this system, using ACP!"), nlf->m_szName, nlf->m_uCodePage); nlf->m_uCodePage = CP_ACP; } } @@ -1061,7 +1061,7 @@ l_readerr: // SVN is not a big fan of UTF16 so we should always use UTF8SIG if (isnlfdataucp && !lr.StreamEncoding().IsUTF8()) { - warning_fl(_T("%") NPRIs _T(" Unicode language file is not UTF8SIG."), nlf->m_szName); + warning_fl(DW_NLF_NOT_PREFERRED_ENC, _T("%") NPRIs _T(" Unicode language file is not UTF8SIG."), nlf->m_szName); } #ifdef _UNICODE diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp index a25cb946..94674773 100644 --- a/Source/makenssi.cpp +++ b/Source/makenssi.cpp @@ -439,9 +439,9 @@ static inline int makensismain(int argc, TCHAR **argv) #else const TCHAR*const badnonwinswitchfmt=OPT_STR _T("%") NPRIs _T(" is disabled for non Win32 platforms."); if (hostnotifyhandle) - build.warning(badnonwinswitchfmt,_T("NOTIFYHWND")); + build.warning(DW_CMDLINE_UNSUPP_NIX,badnonwinswitchfmt,_T("NOTIFYHWND")); if (NStreamEncoding::UNKNOWN==outputenc.GetCodepage()) - build.warning(badnonwinswitchfmt,_T("OUTPUTCHARSET")); + build.warning(DW_CMDLINE_UNSUPP_NIX,badnonwinswitchfmt,_T("OUTPUTCHARSET")); #endif // ~_WIN32 if (!argc) @@ -491,7 +491,7 @@ static inline int makensismain(int argc, TCHAR **argv) if (NStreamEncoding::UNKNOWN == cp) { if (_tcsicmp(argv[argpos], _T("AUTO"))) - build.warning(OPT_STR _T("INPUTCHARSET: Ignoring invalid charset %") NPRIs , argv[argpos]); + build.warning(DW_CMDLINE_BAD_INPUTENC, OPT_STR _T("INPUTCHARSET: Ignoring invalid charset %") NPRIs , argv[argpos]); cp = NStreamEncoding::AUTO; } inputenc.SafeSetCodepage(cp); @@ -522,9 +522,9 @@ static inline int makensismain(int argc, TCHAR **argv) }; if (!SetPriorityClass(hProc, classes[p].priority)) SetPriorityClass(hProc, classes[p].fallback); - if (p == 5) build.warning(_T("makensis is running in REALTIME priority mode!")); + if (p == 5) build.warning(DW_CMDLINE_HIGHPRIORITY,_T("makensis is running in REALTIME priority mode!")); #else - build.warning(badnonwinswitchfmt,_T("Px")); + build.warning(DW_CMDLINE_UNSUPP_NIX,badnonwinswitchfmt,_T("Px")); #endif } // Already parsed these (must adjust argpos) diff --git a/Source/script.cpp b/Source/script.cpp index 8e58530e..d361afa8 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -368,7 +368,7 @@ int CEXEBuild::doParse(const TCHAR *str) if (prevline.inComment() && !thisline.inComment()) { - warning_fl(_T("comment contains line-continuation character, following line will be ignored")); + warning_fl(DW_COMMENT_NEWLINE, _T("comment contains line-continuation character, following line will be ignored")); } } @@ -614,7 +614,7 @@ parse_again: PRINTHELPEX(cmdnam) } if (!cnv1 || !cnv2) { - warning_fl(_T("Invalid number: \"%") NPRIs _T("\""), line.gettoken_str(!cnv1 ? 1 : 3)); + warning_fl(DW_PARSE_BADNUMBER, _T("Invalid number: \"%") NPRIs _T("\""), line.gettoken_str(!cnv1 ? 1 : 3)); } } else PRINTHELPEX(cmdnam) @@ -1014,7 +1014,7 @@ int CEXEBuild::LoadLicenseFile(const TCHAR *file, TCHAR** pdata, const TCHAR *cm if (!cbFileData) { - warning_fl(_T("%") NPRIs _T(": empty license file \"%") NPRIs _T("\"\n"),cmdname,file); + warning_fl(DW_LICENSE_EMPTY, _T("%") NPRIs _T(": empty license file \"%") NPRIs _T("\"\n"),cmdname,file); } else build_lockedunicodetarget=true; @@ -1815,7 +1815,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) TCHAR *str = line.gettoken_str(3); const int ret = SetLangString(name, lang, str); if (ret == PS_WARNING) - warning_fl(_T("LangString \"%") NPRIs _T("\" set multiple times for %d, wasting space"), name, lang); + warning_fl(DW_LANGSTRING_MULTISETWASTE, _T("LangString \"%") NPRIs _T("\" set multiple times for %d, wasting space"), name, lang); else if (ret == PS_ERROR) { ERROR_MSG(_T("Error: can't set LangString \"%") NPRIs _T("\"!\n"), name); return PS_ERROR; @@ -1832,7 +1832,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_CONFIG_SILENT_SUPPORT if (build_header.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) { - warning_fl(_T("%") NPRIs _T(": SilentInstall enabled, wasting space"), cmdnam); + warning_fl(DW_LANGSTRING_SILENTLICENSE, _T("%") NPRIs _T(": SilentInstall enabled, wasting space"), cmdnam); } #endif TCHAR *name = line.gettoken_str(1); @@ -1850,7 +1850,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ret = SetLangString(name, lang, data, true); if (ret == PS_WARNING) - warning_fl(_T("%") NPRIs _T(" \"%") NPRIs _T("\" set multiple times for %d, wasting space"), cmdnam, name, lang); + warning_fl(DW_LANGSTRING_MULTISETWASTE, _T("%") NPRIs _T(" \"%") NPRIs _T("\" set multiple times for %d, wasting space"), cmdnam, name, lang); else if (ret == PS_ERROR) { ERROR_MSG(_T("Error: can't set %") NPRIs _T(" \"%") NPRIs _T("\"!\n"), cmdnam, name); @@ -1864,7 +1864,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_NAME: { if (SetInnerString(NLF_NAME,line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); SetInnerString(NLF_NAME_DA,line.gettoken_str(2)); SCRIPT_MSG(_T("Name: \"%") NPRIs _T("\""),line.gettoken_str(1)); if (*line.gettoken_str(2)) @@ -1877,7 +1877,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (!cur_page) { if (SetInnerString(NLF_CAPTION,line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); } else { @@ -1936,7 +1936,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (!cur_page) { if (SetInnerString(NLF_DIR_TEXT, line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); if (line.getnumtokens() > 2) SetInnerString(NLF_DIR_SUBTEXT, line.gettoken_str(2)); if (line.getnumtokens() > 3) @@ -2000,7 +2000,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (!cur_page) { if (SetInnerString(NLF_COMP_TEXT, line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); if (line.getnumtokens() > 2) SetInnerString(NLF_COMP_SUBTEXT1, line.gettoken_str(2)); if (line.getnumtokens() > 3) @@ -2037,7 +2037,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { SCRIPT_MSG(_T("InstType: setting custom text to: \"%") NPRIs _T("\"\n"),line.gettoken_str(1)+14); if (SetInnerString(NLF_COMP_CUSTOM,line.gettoken_str(1)+14) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),_T("InstType /CUSTOMSTRING")); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),_T("InstType /CUSTOMSTRING")); } else if (line.gettoken_str(1)[0]==_T('/')) { @@ -2079,7 +2079,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (!cur_page) { if (SetInnerString(NLF_LICENSE_TEXT, line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); SetInnerString(NLF_LICENSE_TEXT_FSRB, line.gettoken_str(1)); SetInnerString(NLF_LICENSE_TEXT_FSCB, line.gettoken_str(1)); if (line.getnumtokens() > 2) @@ -2126,7 +2126,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (!cur_page) { if (SetInnerString(NLF_LICENSE_DATA,data) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),cmdnam); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),cmdnam); } else { if (cur_page_type != PAGE_LICENSE) { @@ -2240,7 +2240,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_CONFIG_LICENSEPAGE if (k && HasUserDefined(NLF_LICENSE_DATA)) { - warning_fl(_T("SilentInstall: LicenseData already specified. wasting space")); + warning_fl(DW_LANGSTRING_SILENTLICENSE, _T("SilentInstall: LicenseData already specified. wasting space")); } if (k) { build_header.flags|=CH_FLAGS_SILENT; @@ -2305,7 +2305,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) TCHAR *p = line.gettoken_str(1); if (build_header.install_directory_ptr) { - warning_fl(_T("%") NPRIs _T(": specified multiple times. wasting space"),line.gettoken_str(0)); + warning_fl(DW_STRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times. wasting space"),line.gettoken_str(0)); } build_header.install_directory_ptr = add_string(p); build_header.install_directory_auto_append = 0; @@ -2327,7 +2327,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_INSTALLDIRREGKEY: // InstallDirRegKey { if (build_header.install_reg_key_ptr) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_STRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); int k=line.gettoken_enum(1,rootkeys[0]); if (k == -1) k=line.gettoken_enum(1,rootkeys[1]); @@ -2336,7 +2336,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (!build_header.install_reg_rootkey) PRINTHELP() // SHCTX is invalid here build_header.install_reg_key_ptr = add_string(line.gettoken_str(2),0); if (line.gettoken_str(2)[0] == _T('\\')) - warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); + warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); build_header.install_reg_value_ptr = add_string(line.gettoken_str(3),0); SCRIPT_MSG(_T("InstallRegKey: \"%") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("\"\n"),line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); } @@ -2985,7 +2985,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } if (build_compressor_final) { - warning_fl(_T("SetCompressor ignored due to previous call with the /FINAL switch")); + warning_fl(DW_COMP_FINAL, _T("SetCompressor ignored due to previous call with the /FINAL switch")); return PS_OK; } build_compress_whole = false; @@ -3354,7 +3354,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ERROR_MSG(_T("!include: could not find: \"%") NPRIs _T("\"\n"),f); return PS_ERROR; } else { - warning_fl(_T("!include: could not find: \"%") NPRIs _T("\""),f); + warning_fl(DW_INCLUDE_NONFATAL_NOT_FOUND, _T("!include: could not find: \"%") NPRIs _T("\""),f); } } } @@ -3366,11 +3366,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; } return PS_OK; + case TOK_P_PRAGMA: + parse_pragma(line); // Never abort with ERROR_MSG, even if the pragma is unknown/invalid + return PS_OK; case TOK_P_ERROR: ERROR_MSG(_T("!error: %") NPRIs _T("\n"),line.gettoken_str(1)); return PS_ERROR; case TOK_P_WARNING: - warning_fl(_T("!warning: %") NPRIs,line.gettoken_str(1)); + warning_fl(DIAGCODE_INTERNAL_HIDEDIAGCODE, _T("!warning: %") NPRIs,line.gettoken_str(1)); return PS_OK; case TOK_P_ECHO: SCRIPT_MSG(_T("%") NPRIs _T(" (%") NPRIs _T(":%d)\n"), line.gettoken_str(1),curfilename,linecnt); @@ -3531,11 +3534,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { for(int argi=1; argi 4 ) { @@ -3546,9 +3547,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } else { - if (k) + if (k) // pop { - // pop int l=verbose_stack.getlen(); if (l) { @@ -3557,13 +3557,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } else { - warning_fl(_T("!verbose: Pop failed, stack is empty")); + warning_fl(DW_PP_VERBOSE_POP_EMPTY_STACK, _T("!verbose: Pop failed, stack is empty")); continue; // Pop failed, should still process the next parameter } } - else + else // push { - // push v=get_verbosity(); verbose_stack.add(&v,sizeof(int)); continue; @@ -3580,7 +3579,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_UNINSTCAPTION: { if (SetInnerString(NLF_UCAPTION,line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); SCRIPT_MSG(_T("UninstCaption: \"%") NPRIs _T("\"\n"),line.gettoken_str(1)); } return PS_OK; @@ -3599,7 +3598,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (!cur_page) { if (SetInnerString(NLF_UNINST_TEXT, line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); SetInnerString(NLF_UNINST_SUBTEXT, line.gettoken_str(2)); } else { @@ -3793,7 +3792,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) build_compress=line.gettoken_enum(1,_T("off\0auto\0force\0")); if (build_compress==-1) PRINTHELP() if (build_compress==0 && build_compress_whole) - warning_fl(_T("'SetCompress off' encountered, and in whole compression mode. Effectively ignored.")); + warning_fl(DW_COMP_WHOLE_IGNORE_OFF, _T("'SetCompress off' encountered, and in whole compression mode. Effectively ignored.")); SCRIPT_MSG(_T("SetCompress: %") NPRIs _T("\n"),line.gettoken_str(1)); return PS_OK; case TOK_DBOPTIMIZE: @@ -3815,9 +3814,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_SETCOMPRESSIONLEVEL: { if (compressor == &lzma_compressor) - warning_fl(_T("SetCompressionLevel: compressor is set to LZMA. Effectively ignored.")); + warning_fl(DW_COMP_LEVEL_IGNORE, _T("SetCompressionLevel: compressor is set to LZMA. Effectively ignored.")); if (build_compressor_set && build_compress_whole) - warning_fl(_T("SetCompressionLevel: data already compressed in compress whole mode. Effectively ignored.")); + warning_fl(DW_COMP_LEVEL_IGNORE, _T("SetCompressionLevel: data already compressed in compress whole mode. Effectively ignored.")); int s; build_compress_level=line.gettoken_int(1,&s); @@ -3828,9 +3827,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_SETCOMPRESSORDICTSIZE: { if (compressor != &lzma_compressor) - warning_fl(_T("SetCompressorDictSize: compressor is not set to LZMA. Effectively ignored.")); + warning_fl(DW_COMP_DICT_IGNORE, _T("SetCompressorDictSize: compressor is not set to LZMA. Effectively ignored.")); if (build_compressor_set && build_compress_whole) - warning_fl(_T("SetCompressorDictSize: data already compressed in compress whole mode. Effectively ignored.")); + warning_fl(DW_COMP_DICT_IGNORE, _T("SetCompressorDictSize: data already compressed in compress whole mode. Effectively ignored.")); int s; build_compress_dict_size=line.gettoken_int(1,&s); @@ -3913,7 +3912,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } if (td.GetItem(IDC_VERSTR)->sWidth > old_width) - warning_fl(_T("BrandingText: \"%") NPRIs _T("\" is too long, trimming has expanded the label"), str); + warning_fl(DW_ATTRIBUTE_OVERLONGSTRING, _T("BrandingText: \"%") NPRIs _T("\" is too long, trimming has expanded the label"), str); } DWORD dwSize; @@ -3968,7 +3967,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (!cur_page) { if (SetInnerString(NLF_BTN_DETAILS,line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); } else { if (cur_page_type != PAGE_INSTFILES) { @@ -3984,7 +3983,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { if (!cur_page) { if (SetInnerString(NLF_COMPLETED,line.gettoken_str(1)) == PS_WARNING) - warning_fl(_T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); + warning_fl(DW_INNERSTRING_MULTISETWASTE, _T("%") NPRIs _T(": specified multiple times, wasting space"),line.gettoken_str(0)); } else { if (cur_page_type != PAGE_INSTFILES) { @@ -4380,14 +4379,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) { c=VK_F1-1+_ttoi(s+1); if (_ttoi(s+1) < 1 || _ttoi(s+1) > 24) - warning_fl(_T("CreateShortcut: F-key \"%") NPRIs _T("\" out of range"),s); + warning_fl(DW_PARSE_LNK_HK, _T("CreateShortcut: F-key \"%") NPRIs _T("\" out of range"),s); } else if (((s[0] >= _T('A') && s[0] <= _T('Z')) || (s[0] >= _T('0') && s[0] <= _T('9'))) && !s[1]) c=s[0]; else { c=s[0]; - warning_fl(_T("CreateShortcut: unrecognized hotkey \"%") NPRIs _T("\""),s); + warning_fl(DW_PARSE_LNK_HK, _T("CreateShortcut: unrecognized hotkey \"%") NPRIs _T("\""),s); } ent.offsets[4] |= ((c) << CS_HK_SHIFT) & CS_HK_MASK; } @@ -4725,7 +4724,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef _WIN32 attrib=1; #else - warning_fl(_T("%") NPRIs _T("File /a is disabled for non Win32 platforms."),(which_token == TOK_FILE)?_T(""):_T("Reserve")); + warning_fl(DW_UNSUPP_STORE_FILE_ATT, _T("%") NPRIs _T("File /a is disabled for non Win32 platforms."),(which_token == TOK_FILE)?_T(""):_T("Reserve")); #endif a++; } @@ -4760,7 +4759,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } else { - warning_fl(_T("%") NPRIs _T("File: \"%") NPRIs _T("\" -> no files found"),(which_token == TOK_FILE)?_T(""):_T("Reserve"),line.gettoken_str(a)); + warning_fl(DW_FILE_NONFATAL_NOT_FOUND, _T("%") NPRIs _T("File: \"%") NPRIs _T("\" -> no files found"),(which_token == TOK_FILE)?_T(""):_T("Reserve"),line.gettoken_str(a)); // workaround for bug #1299100 // add a nop opcode so relative jumps will work as expected @@ -4825,7 +4824,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } else { - warning_fl(_T("%") NPRIs _T("File: \"%") NPRIs _T("\" -> no files found."),(which_token == TOK_FILE)?_T(""):_T("Reserve"),t); + warning_fl(DW_FILE_NONFATAL_NOT_FOUND, _T("%") NPRIs _T("File: \"%") NPRIs _T("\" -> no files found."),(which_token == TOK_FILE)?_T(""):_T("Reserve"),t); } } } @@ -5351,7 +5350,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (which_token == TOK_READREGDWORD) ent.offsets[4]=1; else ent.offsets[4]=0; if (line.gettoken_str(3)[0] == _T('\\')) - warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); + warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); SCRIPT_MSG(_T("%") NPRIs _T(" %") NPRIs _T(" %") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("\n"),line.gettoken_str(0), line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); @@ -5381,7 +5380,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[2]=add_string(line.gettoken_str(a+1)); ent.offsets[3]=(which_token==TOK_DELETEREGKEY)?0:add_string(line.gettoken_str(a+2)); if (line.gettoken_str(a+1)[0] == _T('\\')) - warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); + warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); if (which_token==TOK_DELETEREGKEY) SCRIPT_MSG(_T("DeleteRegKey: %") NPRIs _T("\\%") NPRIs _T("\n"),line.gettoken_str(a),line.gettoken_str(a+1)); else @@ -5404,7 +5403,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[0]=REGROOTKEYTOINT(rootkey_tab[k]); ent.offsets[1]=add_string(line.gettoken_str(2)); if (line.gettoken_str(2)[0] == _T('\\')) - warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),cmdname); + warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),cmdname); ent.offsets[2]=add_string(line.gettoken_str(3)); if (which_token == TOK_WRITEREGSTR || which_token == TOK_WRITEREGEXPANDSTR) { @@ -5455,7 +5454,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[2]=add_string(line.gettoken_str(3)); ent.offsets[3]=add_string(line.gettoken_str(4)); ent.offsets[4]=which_token == TOK_ENUMREGKEY; - if (line.gettoken_str(3)[0] == _T('\\')) warning_fl(_T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); + if (line.gettoken_str(3)[0] == _T('\\')) warning_fl(DW_PARSE_REGPATHPREFIX, _T("%") NPRIs _T(": registry path name begins with \'\\\', may cause problems"),line.gettoken_str(0)); SCRIPT_MSG(_T("%") NPRIs _T(" %") NPRIs _T(" %") NPRIs _T("\\%") NPRIs _T("\\%") NPRIs _T("\n"),which_token == TOK_ENUMREGKEY ? _T("EnumRegKey") : _T("EnumRegValue"), line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); } @@ -6212,7 +6211,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } SCRIPT_MSG(_T("\n")); if (nounloadmisused) - warning_fl(_T("/NOUNLOAD must come first before any plugin parameter. Unless the plugin you are trying to use has a parameter /NOUNLOAD, you are doing something wrong")); + warning_fl(DW_PLUGIN_NOUNLOAD_PLACEMENT, _T("/NOUNLOAD must come first before any plugin parameter. Unless the plugin you are trying to use has a parameter /NOUNLOAD, you are doing something wrong")); // next, call it ent.which=EW_REGISTERDLL; @@ -6644,6 +6643,6 @@ LANGID CEXEBuild::ParseLangIdParameter(const LineParser&line, int token) int succ, lid = line.gettoken_int(token, &succ); if (!lid) lid = last_used_lang; if (!succ) - warning_fl(_T("\"%") NPRIs _T("\" is not a valid language id, using language id %u!"), line.gettoken_str(token), lid); + warning_fl(DW_BAD_LANGID, _T("\"%") NPRIs _T("\" is not a valid language id, using language id %u!"), line.gettoken_str(token), lid); return lid; } diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 98514e55..be12c92c 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -268,6 +268,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_P_ERROR,_T("!error"),0,1,_T("[error_message]"),TP_ALL}, {TOK_P_VERBOSE,_T("!verbose"),1,-1,_T("verbose_level | push | pop [...]"),TP_ALL}, +{TOK_P_PRAGMA,_T("!pragma"),2,-1,_T("warning number | warning "),TP_ALL}, {TOK_P_MACRO,_T("!macro"),1,-1,_T("macroname [parms ...]"),TP_ALL}, {TOK_P_MACROEND,_T("!macroend"),0,0,_T(""),TP_ALL}, diff --git a/Source/tokens.h b/Source/tokens.h index e454d322..0def5abe 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -120,6 +120,7 @@ enum TOK_P_ERROR, TOK_P_VERBOSE, + TOK_P_PRAGMA, TOK_P_MACRO, TOK_P_MACROEND, diff --git a/Source/util.cpp b/Source/util.cpp index 7b1f0bf8..c71fbb1b 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -1092,7 +1092,7 @@ int WINAPI WinStdIO_vfwprintf(FILE*strm, const wchar_t*Fmt, va_list val) { ExpandoString buf; errno = ENOMEM; - const size_t cchfmt = buf.StrFmt(Fmt, val, false); + const size_t cchfmt = buf.StrVFmt(Fmt, val, false); UINT cch = (UINT) cchfmt; assert(sizeof(size_t) <= 4 || cchfmt == cch); if (cch && !WinStdIO_OStreamWrite(*pOSD, buf, cch)) diff --git a/Source/util.h b/Source/util.h index 8dafb87d..15f7b92a 100644 --- a/Source/util.h +++ b/Source/util.h @@ -77,7 +77,8 @@ public: if (!p) throw std::bad_alloc(); m_heap = (T*) p; } - size_t StrFmt(const T*FmtStr, va_list Args, bool throwonerr = true) + size_t StrFmt(const T*f, ...) { va_list v; va_start(v, f); size_t r = StrVFmt(f, v); va_end(v); return r; } + size_t StrVFmt(const T*FmtStr, va_list Args, bool throwonerr = true) { size_t n = ExpandoStrFmtVaList(m_stack, COUNTOF(m_stack), &m_heap, FmtStr, Args); if (throwonerr && !n && *FmtStr) throw std::bad_alloc();