Use dynamic buffer sizes for formated CEXEBuild warning/error methods
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6292 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a0cd389c78
commit
0d2edb2f1b
3 changed files with 104 additions and 26 deletions
|
@ -492,7 +492,9 @@ int CEXEBuild::add_string(const TCHAR *string, int process/*=1*/, UINT codepage/
|
|||
int i;
|
||||
if (process)
|
||||
{
|
||||
TCHAR buf[NSIS_MAX_STRLEN*4];
|
||||
ExpandoString<TCHAR, NSIS_MAX_STRLEN*4> buf;
|
||||
// NOTE: It is impossible to know how much preprocessing will increase the size, we have to guess
|
||||
buf.Reserve(_tcsclen(string) * 2);
|
||||
preprocess_string(buf, string, codepage);
|
||||
i = cur_strlist->add(buf, (WORD)codepage, true);
|
||||
}
|
||||
|
@ -3310,42 +3312,36 @@ bool IsStringASCII(const TCHAR* s)
|
|||
|
||||
void CEXEBuild::warning(const TCHAR *s, ...)
|
||||
{
|
||||
TCHAR buf[NSIS_MAX_STRLEN*10];
|
||||
ExpandoString<TCHAR, NSIS_MAX_STRLEN + 100> buf;
|
||||
va_list val;
|
||||
va_start(val,s);
|
||||
#ifdef _WIN32
|
||||
_vstprintf(buf,s,val);
|
||||
#else
|
||||
_vsntprintf(buf,NSIS_MAX_STRLEN*10,s,val);
|
||||
#endif
|
||||
buf.StrFmt(s,val);
|
||||
va_end(val);
|
||||
|
||||
m_warnings.add(buf,0);
|
||||
notify(MAKENSIS_NOTIFY_WARNING,buf);
|
||||
notify(MAKENSIS_NOTIFY_WARNING,buf.GetPtr());
|
||||
if (display_warnings)
|
||||
{
|
||||
PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf);
|
||||
PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf.GetPtr());
|
||||
}
|
||||
}
|
||||
|
||||
void CEXEBuild::warning_fl(const TCHAR *s, ...)
|
||||
{
|
||||
TCHAR buf[NSIS_MAX_STRLEN*10];
|
||||
ExpandoString<TCHAR, NSIS_MAX_STRLEN + 100> buf;
|
||||
va_list val;
|
||||
va_start(val,s);
|
||||
#ifdef _WIN32
|
||||
_vstprintf(buf,s,val);
|
||||
#else
|
||||
_vsntprintf(buf,NSIS_MAX_STRLEN*10,s,val);
|
||||
#endif
|
||||
size_t cchMsg = buf.StrFmt(s,val);
|
||||
va_end(val);
|
||||
_stprintf(buf+_tcslen(buf),_T(" (%s:%d)"),curfilename,linecnt);
|
||||
|
||||
buf.Reserve(cchMsg+2+_tcslen(curfilename)+50+1+1);
|
||||
_stprintf(&buf[cchMsg],_T(" (%s:%u)"),curfilename,linecnt);
|
||||
|
||||
m_warnings.add(buf,0);
|
||||
notify(MAKENSIS_NOTIFY_WARNING,buf);
|
||||
notify(MAKENSIS_NOTIFY_WARNING,buf.GetPtr());
|
||||
if (display_warnings)
|
||||
{
|
||||
PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf);
|
||||
PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf.GetPtr());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3353,19 +3349,16 @@ void CEXEBuild::ERROR_MSG(const TCHAR *s, ...) const
|
|||
{
|
||||
if (display_errors || notify_hwnd)
|
||||
{
|
||||
TCHAR buf[NSIS_MAX_STRLEN*10];
|
||||
ExpandoString<TCHAR, NSIS_MAX_STRLEN + 100> buf;
|
||||
va_list val;
|
||||
va_start(val,s);
|
||||
#ifdef _WIN32
|
||||
_vstprintf(buf,s,val);
|
||||
#else
|
||||
_vsntprintf(buf,NSIS_MAX_STRLEN*10,s,val);
|
||||
#endif
|
||||
buf.StrFmt(s,val);
|
||||
va_end(val);
|
||||
notify(MAKENSIS_NOTIFY_ERROR,buf);
|
||||
|
||||
notify(MAKENSIS_NOTIFY_ERROR,buf.GetPtr());
|
||||
if (display_errors)
|
||||
{
|
||||
PrintColorFmtMsg_ERR(_T("%s"),buf);
|
||||
PrintColorFmtMsg_ERR(_T("%s"),buf.GetPtr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -552,6 +552,67 @@ tstring lowercase(const tstring &str) {
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ExpandoStrFmtVaList returns the number of characters written excluding
|
||||
* the \0 terminator or 0 on error.
|
||||
* realloc() is used on *ppMalloc if cchStack is not
|
||||
* large enough to hold the formated string.
|
||||
*/
|
||||
size_t ExpandoStrFmtVaList(wchar_t*Stack, size_t cchStack, wchar_t**ppMalloc, const wchar_t*FmtStr, va_list Args)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// For _vsnwprintf, the \0 terminator is not part of the size
|
||||
#define ExpandoStrFmtVaList_vsnwprintf(d,c,f,v) _vsnwprintf((d),(c)?(c)-1:0,(f),(v))
|
||||
#else
|
||||
#define ExpandoStrFmtVaList_vsnwprintf vswprintf
|
||||
#endif
|
||||
#if defined(_ISOC99_SOURCE) || _POSIX_C_SOURCE >= 200112L
|
||||
const bool cansizecalc = true, msvcbackdoor = false;
|
||||
#else
|
||||
static char testedsizecalc = 0;
|
||||
if (!testedsizecalc)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
size_t cch = ExpandoStrFmtVaList_vsnwprintf(0, INT_MAX, L"333", Args);
|
||||
#else
|
||||
wchar_t testbuf[1+1];
|
||||
size_t cch = ExpandoStrFmtVaList_vsnwprintf(testbuf, COUNTOF(testbuf), L"333", Args);
|
||||
#endif
|
||||
testedsizecalc = (3 == cch) + 1;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
const bool msvcbackdoor = !!(testedsizecalc - 1), cansizecalc = false;
|
||||
#else
|
||||
const bool cansizecalc = !!(testedsizecalc - 1), msvcbackdoor = false;
|
||||
#endif
|
||||
#endif
|
||||
size_t &cchAvail = cchStack, cch;
|
||||
wchar_t *&dest = Stack, *mem = *ppMalloc;
|
||||
for(;;)
|
||||
{
|
||||
cch = ExpandoStrFmtVaList_vsnwprintf(dest, cchAvail, FmtStr, Args);
|
||||
if (-1 == cch)
|
||||
{
|
||||
cch = 0;
|
||||
if (cansizecalc) break; // vswprintf error, abort!
|
||||
if (msvcbackdoor)
|
||||
cchAvail = ExpandoStrFmtVaList_vsnwprintf(0, INT_MAX, FmtStr, Args) + 1;
|
||||
else
|
||||
cchAvail = 4 * STD_MAX(cchAvail, (size_t)500);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cch < cchAvail) break; // We are done.
|
||||
cchAvail = ++cch; // cch from vswprintf did not include the \0 terminator
|
||||
}
|
||||
dest = mem = (wchar_t*) realloc(mem, cchAvail * sizeof(wchar_t));
|
||||
if (!mem) return 0;
|
||||
}
|
||||
*ppMalloc = mem;
|
||||
return cch;
|
||||
}
|
||||
|
||||
|
||||
int sane_system(const TCHAR *command) {
|
||||
#ifdef _WIN32
|
||||
|
||||
|
|
|
@ -56,6 +56,30 @@ tstring lowercase(const tstring&);
|
|||
tstring get_string_prefix(const tstring& str, const tstring& separator);
|
||||
tstring get_string_suffix(const tstring& str, const tstring& separator);
|
||||
|
||||
size_t ExpandoStrFmtVaList(wchar_t*Stack, size_t cchStack, wchar_t**ppMalloc, const wchar_t*FmtStr, va_list Args);
|
||||
|
||||
template<typename T, size_t S> class ExpandoString {
|
||||
T m_stack[S ? S : 1], *m_heap;
|
||||
public:
|
||||
ExpandoString() : m_heap(0) {}
|
||||
~ExpandoString() { free(m_heap); }
|
||||
void Reserve(size_t cch)
|
||||
{
|
||||
if (S && cch <= S) return ;
|
||||
void *p = realloc(m_heap, cch * sizeof(T));
|
||||
if (!p) throw std::bad_alloc();
|
||||
m_heap = (T*) p;
|
||||
}
|
||||
size_t StrFmt(const T*FmtStr, va_list Args)
|
||||
{
|
||||
size_t n = ExpandoStrFmtVaList(m_stack, COUNTOF(m_stack), &m_heap, FmtStr, Args);
|
||||
if (!n && *FmtStr) throw std::bad_alloc();
|
||||
return n;
|
||||
}
|
||||
T* GetPtr() { return m_heap ? m_heap : m_stack; }
|
||||
operator T*() { return GetPtr(); }
|
||||
};
|
||||
|
||||
int sane_system(const TCHAR *command);
|
||||
|
||||
void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue