Refactored postbuild_cmd and !tempfile handling to help patch #280
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7025 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
1d937a6abb
commit
cce4695977
6 changed files with 112 additions and 86 deletions
|
@ -96,16 +96,11 @@ CEXEBuild::~CEXEBuild()
|
|||
int nlt = lang_tables.getlen() / sizeof(LanguageTable);
|
||||
LanguageTable *nla = (LanguageTable*)lang_tables.get();
|
||||
|
||||
for (int i = 0; i < nlt; i++) {
|
||||
for (int i = 0; i < nlt; i++)
|
||||
DeleteLangTable(nla+i);
|
||||
}
|
||||
|
||||
for (;postbuild_cmds;)
|
||||
{
|
||||
struct postbuild_cmd * tmp = postbuild_cmds;
|
||||
postbuild_cmds = postbuild_cmds->next;
|
||||
delete [] tmp;
|
||||
}
|
||||
if (postbuild_cmds)
|
||||
postbuild_cmds->delete_all();
|
||||
}
|
||||
|
||||
CEXEBuild::CEXEBuild(signed char pponly, bool warnaserror) :
|
||||
|
@ -3006,40 +3001,7 @@ int CEXEBuild::write_output(void)
|
|||
fileend,total_usize,pc/10,pc%10);
|
||||
}
|
||||
fclose(fp);
|
||||
if (postbuild_cmds)
|
||||
{
|
||||
for (struct postbuild_cmd *cmd=postbuild_cmds; cmd; cmd = cmd->next)
|
||||
{
|
||||
TCHAR *cmdstr = cmd->cmd, *cmdstrbuf = NULL;
|
||||
TCHAR *arg = _tcsstr(cmdstr, _T("%1"));
|
||||
if (arg) // if found, replace %1 by build_output_filename
|
||||
{
|
||||
const size_t cchbldoutfile = _tcslen(build_output_filename);
|
||||
cmdstrbuf = (TCHAR*) malloc( (_tcslen(cmdstr) + cchbldoutfile + 1)*sizeof(TCHAR) );
|
||||
if (!cmdstrbuf)
|
||||
{
|
||||
ERROR_MSG(_T("Error: can't allocate memory for finalize command\n"));
|
||||
return PS_ERROR;
|
||||
}
|
||||
arg -= ((UINT_PTR)cmdstr)/sizeof(TCHAR), arg += ((UINT_PTR)cmdstrbuf)/sizeof(TCHAR);
|
||||
_tcscpy(cmdstrbuf,cmdstr);
|
||||
cmdstr = cmdstrbuf;
|
||||
memmove(arg+cchbldoutfile, arg+2, (_tcslen(arg+2)+1)*sizeof(TCHAR));
|
||||
memmove(arg, build_output_filename, cchbldoutfile*sizeof(TCHAR));
|
||||
//BUGBUG: Should we call PathConvertWinToPosix on build_output_filename?
|
||||
}
|
||||
|
||||
SCRIPT_MSG(_T("\nFinalize command: %") NPRIs _T("\n"),cmdstr);
|
||||
int ret = sane_system(cmdstr);
|
||||
if (!check_external_exitcode(ret, cmd->cmpop, cmd->cmpval))
|
||||
{
|
||||
ERROR_MSG(_T("%") NPRIs _T(" %d, aborting\n"), _T("Finalize command returned"), ret);
|
||||
return PS_ERROR;
|
||||
}
|
||||
if (ret != 0) INFO_MSG(_T("%") NPRIs _T(" %d\n"), _T("Finalize command returned"), ret);
|
||||
free(cmdstrbuf);
|
||||
}
|
||||
}
|
||||
RET_UNLESS_OK(run_postbuild_cmds(postbuild_cmds, build_output_filename, _T("Finalize")));
|
||||
print_warnings();
|
||||
return PS_OK;
|
||||
}
|
||||
|
@ -4029,6 +3991,57 @@ void CEXEBuild::set_code_type_predefines(const TCHAR *value)
|
|||
}
|
||||
}
|
||||
|
||||
void CEXEBuild::postbuild_cmd::delete_all()
|
||||
{
|
||||
for (struct postbuild_cmd *p = this, *tmp; p;)
|
||||
{
|
||||
tmp = p, p = p->next;
|
||||
delete [] tmp;
|
||||
}
|
||||
}
|
||||
|
||||
CEXEBuild::postbuild_cmd* CEXEBuild::postbuild_cmd::make(const TCHAR *cmdstr, int cmpop, int cmpval)
|
||||
{
|
||||
postbuild_cmd *p = (postbuild_cmd*) (new BYTE[FIELD_OFFSET(postbuild_cmd, cmd[_tcsclen(cmdstr)+!0])]);
|
||||
p->next = NULL, _tcscpy(p->cmd, cmdstr);
|
||||
p->cmpop = cmpop, p->cmpval = cmpval;
|
||||
return p;
|
||||
}
|
||||
|
||||
int CEXEBuild::run_postbuild_cmds(const postbuild_cmd *cmds, const TCHAR *templatearg_pc1, const TCHAR* commandname)
|
||||
{
|
||||
for (const postbuild_cmd *cmd = cmds; cmd; cmd = cmd->next)
|
||||
{
|
||||
const TCHAR *cmdstr = cmd->cmd;
|
||||
TCHAR *arg = _tcsstr(const_cast<TCHAR*>(cmdstr), _T("%1")), *cmdstrbuf = NULL;
|
||||
if (arg) // If found, replace %1 with templatearg_pc1
|
||||
{
|
||||
const size_t cchtpc1 = _tcslen(templatearg_pc1);
|
||||
cmdstrbuf = (TCHAR*) malloc((_tcslen(cmdstr) + cchtpc1 + 1) * sizeof(TCHAR));
|
||||
if (!cmdstrbuf)
|
||||
{
|
||||
ERROR_MSG(_T("Error: Can't allocate memory for %") NPRIs _T(" command\n"), commandname);
|
||||
return PS_ERROR;
|
||||
}
|
||||
arg -= ((UINT_PTR)cmdstr)/sizeof(TCHAR), arg += ((UINT_PTR)cmdstrbuf)/sizeof(TCHAR);
|
||||
_tcscpy(cmdstrbuf, cmdstr), cmdstr = cmdstrbuf;
|
||||
memmove(arg+cchtpc1, arg+2, (_tcslen(arg+2)+1)*sizeof(TCHAR));
|
||||
memmove(arg, templatearg_pc1, cchtpc1*sizeof(TCHAR));
|
||||
//BUGBUG: Should we call PathConvertWinToPosix on templatearg_pc1?
|
||||
}
|
||||
SCRIPT_MSG(_T("\n%") NPRIs _T(" command: %") NPRIs _T("\n"), commandname, cmdstr);
|
||||
int ret = sane_system(cmdstr);
|
||||
if (!check_external_exitcode(ret, cmd->cmpop, cmd->cmpval))
|
||||
{
|
||||
ERROR_MSG(_T("%") NPRIs _T(" command returned %d, aborting\n"), commandname, ret);
|
||||
return PS_ERROR;
|
||||
}
|
||||
if (ret != 0) INFO_MSG(_T("%") NPRIs _T(" command returned %d\n"), commandname, ret);
|
||||
free(cmdstrbuf);
|
||||
}
|
||||
return PS_OK;
|
||||
}
|
||||
|
||||
int CEXEBuild::check_external_exitcode(int exitcode, int op, int val)
|
||||
{
|
||||
switch(op)
|
||||
|
|
|
@ -583,7 +583,10 @@ class CEXEBuild {
|
|||
struct postbuild_cmd*next;
|
||||
int cmpop, cmpval;
|
||||
TCHAR cmd[1];
|
||||
void delete_all();
|
||||
static postbuild_cmd* make(const TCHAR *cmdstr, int cmpop, int cmpval);
|
||||
} *postbuild_cmds;
|
||||
int run_postbuild_cmds(const postbuild_cmd *cmds, const TCHAR *templatearg_pc1, const TCHAR* commandname);
|
||||
int check_external_exitcode(int exitcode, int op, int val);
|
||||
|
||||
TCHAR build_packname[1024], build_packcmd[1024];
|
||||
|
|
|
@ -449,43 +449,19 @@ int CEXEBuild::pp_insertmacro(LineParser&line)
|
|||
int CEXEBuild::pp_tempfile(LineParser&line)
|
||||
{
|
||||
TCHAR *symbol = line.gettoken_str(1);
|
||||
const TCHAR *fpath;
|
||||
#ifdef _WIN32
|
||||
TCHAR buf[MAX_PATH], buf2[MAX_PATH];
|
||||
GetTempPath(MAX_PATH, buf);
|
||||
if (!GetTempFileName(buf, _T("nst"), 0, buf2))
|
||||
TCHAR *tfpath = create_tempfile_path();
|
||||
if (!tfpath)
|
||||
{
|
||||
ERROR_MSG(_T("!tempfile: unable to create temporary file.\n"));
|
||||
ERROR_MSG(_T("!tempfile: Unable to create temporary file!\n"));
|
||||
return PS_ERROR;
|
||||
}
|
||||
fpath = buf2;
|
||||
#else // !_WIN32
|
||||
char t[] = ("/tmp/makensisXXXXXX");
|
||||
const mode_t old_umask = umask(0077);
|
||||
int fd = mkstemp(t);
|
||||
umask(old_umask);
|
||||
if (fd == -1)
|
||||
{ L_tok_p_tempfile_oom:
|
||||
ERROR_MSG(_T("!tempfile: unable to create temporary file.\n"));
|
||||
return PS_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
#ifdef _UNICODE
|
||||
if (!(fpath = NSISRT_mbtowc(t))) goto L_tok_p_tempfile_oom;
|
||||
#else
|
||||
fpath = t;
|
||||
#endif
|
||||
#endif // ~_WIN32
|
||||
|
||||
if (definedlist.add(symbol, fpath))
|
||||
int symexisted = definedlist.add(symbol, tfpath);
|
||||
free(tfpath);
|
||||
if (symexisted)
|
||||
{
|
||||
ERROR_MSG(_T("!tempfile: \"%") NPRIs _T("\" already defined!\n"), symbol);
|
||||
return PS_ERROR;
|
||||
}
|
||||
SCRIPT_MSG(_T("!tempfile: \"%") NPRIs _T("\"=\"%") NPRIs _T("\"\n"), symbol, fpath);
|
||||
#if !defined(_WIN32) && defined(_UNICODE)
|
||||
NSISRT_free(fpath);
|
||||
#endif
|
||||
return PS_OK;
|
||||
}
|
||||
|
||||
|
@ -1054,21 +1030,24 @@ int CEXEBuild::pp_packhdr(LineParser&line)
|
|||
return bufOf ? PS_ERROR : PS_OK;
|
||||
}
|
||||
|
||||
template<class T> void slist_append(T&list, T&item)
|
||||
{
|
||||
T prev;
|
||||
for (prev = list; prev && prev->next;)
|
||||
prev = prev->next;
|
||||
(prev ? prev->next : list) = item;
|
||||
}
|
||||
|
||||
int CEXEBuild::pp_finalize(LineParser&line)
|
||||
{
|
||||
TCHAR* cmdstr = line.gettoken_str(1);
|
||||
int validparams = false;
|
||||
struct postbuild_cmd *newcmd, *prevcmd;
|
||||
newcmd = (struct postbuild_cmd*) (new BYTE[FIELD_OFFSET(struct postbuild_cmd, cmd[_tcsclen(cmdstr)+1])]);
|
||||
newcmd->next = NULL, _tcscpy(newcmd->cmd, cmdstr);
|
||||
newcmd->cmpop = line.gettoken_enum(2, _T("<\0>\0<>\0=\0ignore\0")), newcmd->cmpval = line.gettoken_int(3, &validparams);
|
||||
postbuild_cmd *newcmd = postbuild_cmd::make(cmdstr, line.gettoken_enum(2, _T("<\0>\0<>\0=\0ignore\0")), line.gettoken_int(3, &validparams));
|
||||
if (line.getnumtokens() == 1+1)
|
||||
newcmd->cmpop = 4, validparams = true; // just a command, ignore the exit code
|
||||
newcmd->cmpop = 4, validparams = true; // Just a command, ignore the exit code
|
||||
if (newcmd->cmpop == -1 || !validparams)
|
||||
PRINTHELP();
|
||||
for (prevcmd = postbuild_cmds; prevcmd && prevcmd->next;)
|
||||
prevcmd = prevcmd->next;
|
||||
if (prevcmd) prevcmd->next = newcmd; else postbuild_cmds = newcmd;
|
||||
slist_append(postbuild_cmds, newcmd);
|
||||
SCRIPT_MSG(_T("!finalize: \"%") NPRIs _T("\"\n"), cmdstr);
|
||||
return PS_OK;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ void CtoTString::Init(const char* str, UINT cp)
|
|||
#if defined(_UNICODE) && !defined(_WIN32)
|
||||
if (CP_ACP == cp)
|
||||
{
|
||||
assert(NSISRT_free_is_STDC_free());
|
||||
m_wStr = NSISRT_mbtowc(str); // Should be faster than iconv
|
||||
return ;
|
||||
}
|
||||
|
@ -45,6 +46,7 @@ CtoTString::~CtoTString() { free(m_wStr); m_wStr = 0; }
|
|||
void TtoCString::Init(const wchar_t* str)
|
||||
{
|
||||
#if defined(_UNICODE) && !defined(_WIN32)
|
||||
assert(NSISRT_free_is_STDC_free());
|
||||
m_cStr = NSISRT_wctomb(str); // Should be faster than iconv
|
||||
return ;
|
||||
#endif
|
||||
|
|
|
@ -740,6 +740,33 @@ char* create_file_view_readonly(const TCHAR *filepath, FILEVIEW&mmfv)
|
|||
#endif
|
||||
}
|
||||
|
||||
TCHAR* create_tempfile_path()
|
||||
{
|
||||
TCHAR *tfpath = NULL;
|
||||
#ifdef _WIN32
|
||||
TCHAR buftmpdir[MAX_PATH], buf[MAX_PATH];
|
||||
DWORD cch = GetTempPath(COUNTOF(buftmpdir), buftmpdir);
|
||||
if (cch && cch < COUNTOF(buftmpdir) && GetTempFileName(buftmpdir, _T("nst"), 0, buf))
|
||||
tfpath = _tcsdup(buf);
|
||||
#else //! _WIN32
|
||||
char narrowpath[] = ("/tmp/makensisXXXXXX");
|
||||
const mode_t org_umask = umask(0077);
|
||||
int fd = mkstemp(narrowpath);
|
||||
umask(org_umask);
|
||||
if (fd != -1)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
assert(NSISRT_free_is_STDC_free());
|
||||
tfpath = NSISRT_mbtowc(narrowpath);
|
||||
#else
|
||||
tfpath = _tcsdup(narrowpath);
|
||||
#endif
|
||||
close(fd);
|
||||
}
|
||||
#endif //~ _WIN32
|
||||
return tfpath;
|
||||
}
|
||||
|
||||
tstring get_full_path(const tstring &path) {
|
||||
#ifdef _WIN32
|
||||
TCHAR real_path[1024], *fnpart;
|
||||
|
@ -1156,12 +1183,6 @@ bool GetFileSize64(HANDLE hFile, ULARGE_INTEGER &uli)
|
|||
uli.LowPart = GetFileSize(hFile, &uli.HighPart);
|
||||
return INVALID_FILE_SIZE != uli.LowPart || !GetLastError();
|
||||
}
|
||||
static HANDLE NSISRT_GetConsoleScreenHandle()
|
||||
{
|
||||
DWORD cm;
|
||||
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
return GetConsoleMode(hCon, &cm) ? hCon : GetStdHandle(STD_ERROR_HANDLE);
|
||||
}
|
||||
#endif //~ _WIN32
|
||||
#if defined(_WIN32) && defined(_UNICODE) && defined(MAKENSIS)
|
||||
#include <io.h> // for _get_osfhandle
|
||||
|
@ -1272,6 +1293,12 @@ bool NSISRT_Initialize() // Init function for MakeNSIS Win32
|
|||
#elif defined(_WIN32)
|
||||
#define NSISRT_FastGetConsoleScreenHandle NSISRT_GetConsoleScreenHandle
|
||||
bool NSISRT_Initialize() { return true; } // Init function for non-MakeNSIS Win32 (NSISRT_DEFINEGLOBALS sets g_output and g_errout)
|
||||
static HANDLE NSISRT_GetConsoleScreenHandle()
|
||||
{
|
||||
DWORD cm;
|
||||
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
return GetConsoleMode(hCon, &cm) ? hCon : GetStdHandle(STD_ERROR_HANDLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PrintColorFmtErrMsg(const TCHAR *fmtstr, va_list args)
|
||||
|
|
|
@ -41,6 +41,7 @@ size_t my_strftime(TCHAR *s, size_t max, const TCHAR *fmt, const struct tm *tm)
|
|||
// If width or height are specified it will also make sure the bitmap is in that size
|
||||
int update_bitmap(CResourceEditor* re, WORD id, const TCHAR* filename, int width=0, int height=0, int maxbpp=0);
|
||||
|
||||
TCHAR* create_tempfile_path();
|
||||
tstring get_full_path(const tstring& path);
|
||||
tstring get_dir_name(const tstring& path);
|
||||
tstring get_file_name(const tstring& path);
|
||||
|
@ -237,6 +238,7 @@ BOOL IsValidCodePage(UINT CodePage);
|
|||
#else
|
||||
#define CharNext CharNextA
|
||||
#endif
|
||||
#define NSISRT_free_is_STDC_free() 1 // NSISRT_free == free
|
||||
#define NSISRT_free(p) ( free((void*)(p)) )
|
||||
wchar_t* NSISRT_mbtowc(const char *Str);
|
||||
char* NSISRT_wctomb(const wchar_t *Str);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue