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:
anders_k 2018-10-24 19:01:00 +00:00
parent 1d937a6abb
commit cce4695977
6 changed files with 112 additions and 86 deletions

View file

@ -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)

View file

@ -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];

View file

@ -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;
}

View file

@ -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

View file

@ -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)

View file

@ -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);