From cce46959774059e198a45ff96a08cc9ca067fdc6 Mon Sep 17 00:00:00 2001 From: anders_k Date: Wed, 24 Oct 2018 19:01:00 +0000 Subject: [PATCH] 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 --- Source/build.cpp | 97 +++++++++++++++++++++++++-------------------- Source/build.h | 3 ++ Source/scriptpp.cpp | 55 ++++++++----------------- Source/tstring.cpp | 2 + Source/util.cpp | 39 +++++++++++++++--- Source/util.h | 2 + 6 files changed, 112 insertions(+), 86 deletions(-) diff --git a/Source/build.cpp b/Source/build.cpp index 2a9ce342..308fbfd8 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -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(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) diff --git a/Source/build.h b/Source/build.h index 5ebc1101..42a5850b 100644 --- a/Source/build.h +++ b/Source/build.h @@ -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]; diff --git a/Source/scriptpp.cpp b/Source/scriptpp.cpp index 55c78726..bc81c7a0 100644 --- a/Source/scriptpp.cpp +++ b/Source/scriptpp.cpp @@ -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 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; } diff --git a/Source/tstring.cpp b/Source/tstring.cpp index f86e7c16..49d0fecb 100644 --- a/Source/tstring.cpp +++ b/Source/tstring.cpp @@ -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 diff --git a/Source/util.cpp b/Source/util.cpp index 2a2e8f4c..a86b62dc 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -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 // 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) diff --git a/Source/util.h b/Source/util.h index fe76bc2d..a14ecb57 100644 --- a/Source/util.h +++ b/Source/util.h @@ -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);