Added !pragma warning error <#|all>, warning #, disable all, enable all, default all

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6898 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2017-09-01 23:06:48 +00:00
parent 52e1c24f30
commit ca009c196b
9 changed files with 116 additions and 40 deletions

View file

@ -106,12 +106,13 @@ CEXEBuild::~CEXEBuild()
}
}
CEXEBuild::CEXEBuild(signed char pponly) :
CEXEBuild::CEXEBuild(signed char pponly, bool warnaserror) :
preprocessonly(pponly),
m_exehead(0),
m_exehead_size(0)
{
set_verbosity(3);
if (warnaserror) diagstate.set_warning_as_error();
curlinereader=0;
curfilename=0, linecnt=0;
@ -3410,6 +3411,7 @@ void CEXEBuild::set_verbosity(int lvl)
int CEXEBuild::parse_pragma(LineParser &line)
{
const int rvSucc = PS_OK, rvWarn = PS_WARNING, rvErr = PS_WARNING; // rvErr is not PS_ERROR because we want !pragma parsing to be very forgiving.
const TCHAR badParamMsg[] = _T("Unknown pragma");
// 2.47 shipped with a corrupted CHM file (bug #1129). This minimal verification command exists because the !searchparse hack we added does not work with codepage 936!
if (line.gettoken_enum(1, _T("verifychm\0")) == 0)
@ -3425,53 +3427,72 @@ int CEXEBuild::parse_pragma(LineParser &line)
if (line.gettoken_enum(1, _T("warning\0")) == -1)
return (warning_fl(DW_PP_PRAGMA_UNKNOWN, _T("Unknown pragma")), rvErr);
int warnOp = line.gettoken_enum(2, _T("disable\0enable\0default\0push\0pop\0")), ret = rvSucc;
enum { woperr = 0, wopwar, wopdis, wopena, wopdef, woppus, woppop, invalidwop };
int warnOp = line.gettoken_enum(2, _T("error\0warning\0disable\0enable\0default\0push\0pop\0")), ret = rvSucc;
if (warnOp < 0)
ret = rvErr, warning_fl(DW_PP_PRAGMA_UNKNOWN, _T("Unknown pragma")); // Unknown warning pragma action
else if (warnOp == 3)
diagstate.Push();
else if (warnOp == 4)
ret = rvErr, warning_fl(DW_PP_PRAGMA_UNKNOWN, badParamMsg); // Unknown warning pragma action
else if (warnOp == woppus) // warning: push
diagstate.push();
else if (warnOp == woppop) // warning: pop
{
if (!diagstate.Pop())
if (!diagstate.pop())
ret = rvWarn, warning_fl(DW_PP_PRAGMA_INVALID, _T("Unexpected"));
}
else // warning: disable/enable/default
else // warning: error/warning/disable/enable/default
{
for (int ti = 3; ti < line.getnumtokens(); ++ti)
{
DIAGCODE code = static_cast<DIAGCODE>(line.gettoken_int(ti));
if (!diagstate.IsValidCode(code))
ret = rvWarn, 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);
bool all = 0 == line.gettoken_enum(ti, _T("all\0"));
if (diagstate.is_valid_code(code))
{
switch(warnOp)
{
case woperr: diagstate.error(code); break;
case wopwar: diagstate.warning(code); break;
case wopdis: diagstate.disable(code); break;
case wopena: diagstate.enable(code); break;
case wopdef: diagstate.def(code); break;
default: assert(0);
}
}
else
{
switch(all ? warnOp : invalidwop)
{
case woperr: diagstate.set_all(diagstate.werror); break;
case wopdis: diagstate.set_all(DiagState::wdisabled); break;
case wopena: diagstate.set_all(DiagState::wenabled); break;
case wopdef: diagstate.set_all(DiagState::get_default_state()); break;
default: ret = rvWarn, warning_fl(DW_PP_PRAGMA_INVALID, _T("Invalid number: \"%") NPRIs _T("\""), line.gettoken_str(ti));
}
}
}
}
return ret;
}
void DiagState::Push()
void DiagState::push()
{
DiagState *p = new DiagState();
p->m_Disabled = m_Disabled; // Copy current state
p->m_pStack = m_pStack, m_pStack = p;
*p = *this; // Copy the current state
p->m_pStack = m_pStack, m_pStack = p; // ...and push it on the stack
}
bool DiagState::Pop()
bool DiagState::pop()
{
if (!m_pStack) return false;
DiagState *pPop = m_pStack;
m_pStack = pPop->m_pStack, pPop->m_pStack = 0;
m_Disabled.swap(pPop->m_Disabled);
DiagState *pPop = m_pStack; // Get the item on the top of the stack
*this = *pPop; // ...and assign it as the current state
pPop->m_pStack = 0; // The pop'ed item no longer owns the next item on the stack
delete pPop;
return true;
}
void CEXEBuild::warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list args)
{
extern bool g_warnaserror;
bool showcode = dc != DIAGCODE_INTERNAL_HIDEDIAGCODE;
if (diagstate.IsDisabled(dc)) return ;
if (diagstate.is_disabled(dc)) return ;
bool aserror = diagstate.is_error(dc);
TCHAR codbuf[11+2+!0];
_stprintf(codbuf, showcode ? _T("%u: ") : _T(""), static_cast<unsigned int>(dc));
@ -3489,7 +3510,7 @@ void CEXEBuild::warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list ar
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)
if (aserror)
hostevent = MakensisAPI::NOTIFY_ERROR, display_warnings = display_errors;
notify(hostevent, msg); // Notify the host
@ -3497,7 +3518,7 @@ void CEXEBuild::warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list ar
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)
if (aserror)
{
ERROR_MSG(_T("Error: warning treated as error\n"));
extern int g_display_errors;