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;
|
int i;
|
||||||
if (process)
|
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);
|
preprocess_string(buf, string, codepage);
|
||||||
i = cur_strlist->add(buf, (WORD)codepage, true);
|
i = cur_strlist->add(buf, (WORD)codepage, true);
|
||||||
}
|
}
|
||||||
|
@ -3310,42 +3312,36 @@ bool IsStringASCII(const TCHAR* s)
|
||||||
|
|
||||||
void CEXEBuild::warning(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_list val;
|
||||||
va_start(val,s);
|
va_start(val,s);
|
||||||
#ifdef _WIN32
|
buf.StrFmt(s,val);
|
||||||
_vstprintf(buf,s,val);
|
|
||||||
#else
|
|
||||||
_vsntprintf(buf,NSIS_MAX_STRLEN*10,s,val);
|
|
||||||
#endif
|
|
||||||
va_end(val);
|
va_end(val);
|
||||||
|
|
||||||
m_warnings.add(buf,0);
|
m_warnings.add(buf,0);
|
||||||
notify(MAKENSIS_NOTIFY_WARNING,buf);
|
notify(MAKENSIS_NOTIFY_WARNING,buf.GetPtr());
|
||||||
if (display_warnings)
|
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, ...)
|
void CEXEBuild::warning_fl(const TCHAR *s, ...)
|
||||||
{
|
{
|
||||||
TCHAR buf[NSIS_MAX_STRLEN*10];
|
ExpandoString<TCHAR, NSIS_MAX_STRLEN + 100> buf;
|
||||||
va_list val;
|
va_list val;
|
||||||
va_start(val,s);
|
va_start(val,s);
|
||||||
#ifdef _WIN32
|
size_t cchMsg = buf.StrFmt(s,val);
|
||||||
_vstprintf(buf,s,val);
|
|
||||||
#else
|
|
||||||
_vsntprintf(buf,NSIS_MAX_STRLEN*10,s,val);
|
|
||||||
#endif
|
|
||||||
va_end(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);
|
m_warnings.add(buf,0);
|
||||||
notify(MAKENSIS_NOTIFY_WARNING,buf);
|
notify(MAKENSIS_NOTIFY_WARNING,buf.GetPtr());
|
||||||
if (display_warnings)
|
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)
|
if (display_errors || notify_hwnd)
|
||||||
{
|
{
|
||||||
TCHAR buf[NSIS_MAX_STRLEN*10];
|
ExpandoString<TCHAR, NSIS_MAX_STRLEN + 100> buf;
|
||||||
va_list val;
|
va_list val;
|
||||||
va_start(val,s);
|
va_start(val,s);
|
||||||
#ifdef _WIN32
|
buf.StrFmt(s,val);
|
||||||
_vstprintf(buf,s,val);
|
|
||||||
#else
|
|
||||||
_vsntprintf(buf,NSIS_MAX_STRLEN*10,s,val);
|
|
||||||
#endif
|
|
||||||
va_end(val);
|
va_end(val);
|
||||||
notify(MAKENSIS_NOTIFY_ERROR,buf);
|
|
||||||
|
notify(MAKENSIS_NOTIFY_ERROR,buf.GetPtr());
|
||||||
if (display_errors)
|
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;
|
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) {
|
int sane_system(const TCHAR *command) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,30 @@ tstring lowercase(const tstring&);
|
||||||
tstring get_string_prefix(const tstring& str, const tstring& separator);
|
tstring get_string_prefix(const tstring& str, const tstring& separator);
|
||||||
tstring get_string_suffix(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);
|
int sane_system(const TCHAR *command);
|
||||||
|
|
||||||
void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args);
|
void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue