From c8e7f137422bd223509ec72912b2d2cbb48f0ce2 Mon Sep 17 00:00:00 2001 From: kichik Date: Thu, 30 Sep 2004 20:25:33 +0000 Subject: [PATCH] more refactoring git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3683 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/build.cpp | 255 +++++++++++++++++++++++++---------------------- Source/build.h | 10 +- Source/util.cpp | 24 ++++- Source/util.h | 4 + 4 files changed, 168 insertions(+), 125 deletions(-) diff --git a/Source/build.cpp b/Source/build.cpp index 32a81675..a068e529 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -21,6 +21,12 @@ # include #endif +#define RET_UNLESS_OK( function_rc ) do { \ + int rc = (function_rc); \ + if ( rc != PS_OK) \ + return rc; \ +} while (false) + int MMapFile::m_iAllocationGranularity = 0; #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT @@ -39,11 +45,15 @@ void *lzmaCompressThread(void *lpParameter) } #endif +namespace { // begin anonymous namespace + bool isSimpleChar(char ch) { return (ch == '.' ) || (ch == '_' ) || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } +} // end of anonymous namespace + void CEXEBuild::define(const char *p, const char *v) { definedlist.add(p,v); @@ -80,7 +90,7 @@ CEXEBuild::CEXEBuild() build_include_depth=0; - has_called_write_output=0; + has_called_write_output=false; ns_func.add("",0); // make sure offset 0 is special on these (i.e. never used by a label) ns_label.add("",0); @@ -478,23 +488,41 @@ definedlist.add("NSIS_SUPPORT_LANG_IN_STRINGS"); m_ShellConstants.add("CDBURN_AREA", CSIDL_CDBURN_AREA, CSIDL_CDBURN_AREA); } -void CEXEBuild::setdirs(char *argv0) -{ - char szNSISDir[NSIS_MAX_STRLEN*2],*fn2; - int len = sizeof(szNSISDir) - sizeof(PLATFORM_PATH_SEPARATOR_STR "Include") - 1; +namespace { +string get_executable_path(const char* argv0) { #ifdef _WIN32 - GetModuleFileName(NULL,szNSISDir,len); + char temp_buf[1024]; + temp_buf[0] = '\0'; + int rc = GetModuleFileName(NULL,temp_buf,1024); + assert(rc != 0); + return string(temp_buf); #else - char *buffer = my_realpath(argv0); - strncpy(szNSISDir, buffer, len); - szNSISDir[sizeof(szNSISDir)-1] = 0; - my_free_realpath(argv0, buffer); + return get_full_path(argv0); #endif - fn2=strrchr(szNSISDir,PLATFORM_PATH_SEPARATOR_C); - if(fn2!=NULL) *fn2=0; - definedlist.add("NSISDIR",(char*)szNSISDir); - strcat(szNSISDir, PLATFORM_PATH_SEPARATOR_STR "Include"); - include_dirs.add(szNSISDir,0); +} + +string get_dirname(const string& path) { + string::size_type last_separator_pos = path.rfind(PLATFORM_PATH_SEPARATOR_C); + if (last_separator_pos == string::npos) + return path; + return path.substr(0, last_separator_pos); +} + +string get_executable_dir(const char *argv0) { + return get_dirname(get_executable_path(argv0)); +} + +} // end anonymous namespace + +void CEXEBuild::setdirs(const char *argv0) +{ + string nsis_dir = get_executable_dir(argv0); + + definedlist.add("NSISDIR",nsis_dir.c_str()); + + nsis_dir += PLATFORM_PATH_SEPARATOR_STR; + nsis_dir += "Include"; + include_dirs.add(nsis_dir.c_str(),0); } @@ -2262,61 +2290,107 @@ int CEXEBuild::check_write_output_errors() const return PS_OK; } -int CEXEBuild::write_output(void) -{ -#ifndef NSIS_CONFIG_CRC_SUPPORT - build_crcchk=0; -#endif - - int err; - - err = check_write_output_errors(); - if (err != PS_OK) - return err; - - has_called_write_output++; - -#ifdef NSIS_CONFIG_PLUGIN_SUPPORT - err = add_plugins_dir_initializer(); - if (err != PS_OK) - return err; -#endif //NSIS_CONFIG_PLUGIN_SUPPORT - -#ifdef NSIS_SUPPORT_VERSION_INFO - err = AddVersionInfo(); - if (err != PS_OK) - return err; -#endif //NSIS_SUPPORT_VERSION_INFO - +int CEXEBuild::prepare_uninstaller() { #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (ubuild_entries.getlen()) { if (!uninstaller_writes_used) { warning("Uninstall section found but WriteUninstaller never used - no uninstaller will be created."); + return PS_OK; } - else - { - build_uninst.flags|=build_header.flags&(CH_FLAGS_PROGRESS_COLORED|CH_FLAGS_NO_ROOT_DIR); - set_uninstall_mode(1); - DefineInnerLangString(NLF_UCAPTION); - if (resolve_coderefs("uninstall")) - return PS_ERROR; + build_uninst.flags|=build_header.flags&(CH_FLAGS_PROGRESS_COLORED|CH_FLAGS_NO_ROOT_DIR); + + set_uninstall_mode(1); + DefineInnerLangString(NLF_UCAPTION); + if (resolve_coderefs("uninstall")) + return PS_ERROR; #ifdef NSIS_CONFIG_COMPONENTPAGE - // set sections to the first insttype - PrepareInstTypes(); + // set sections to the first insttype + PrepareInstTypes(); #endif - set_uninstall_mode(0); - } + set_uninstall_mode(0); } else if (uninstaller_writes_used) { ERROR_MSG("Error: no Uninstall section specified, but WriteUninstaller used %d time(s)\n",uninstaller_writes_used); return PS_ERROR; } +#endif//NSIS_CONFIG_UNINSTALL_SUPPORT + return PS_OK; +} + +int CEXEBuild::pack_exe_header() +{ + if (!(build_packname[0] && build_packcmd[0])) { + // header not asked to be packed + return PS_OK; + } + + // write out exe header, pack, read back in, align to 512, and + // update the header info + FILE *tmpfile=FOPEN(build_packname,"wb"); + if (!tmpfile) + { + ERROR_MSG("Error: writing temporary file \"%s\" for pack\n",build_packname); + return PS_ERROR; + } + fwrite(header_data_new,1,exeheader_size_new,tmpfile); + fclose(tmpfile); + if (system(build_packcmd) == -1) + { + remove(build_packname); + ERROR_MSG("Error: calling packer on \"%s\"\n",build_packname); + return PS_ERROR; + } + tmpfile=FOPEN(build_packname,"rb"); + if (!tmpfile) + { + remove(build_packname); + ERROR_MSG("Error: reading temporary file \"%s\" after pack\n",build_packname); + return PS_ERROR; + } + fseek(tmpfile,0,SEEK_END); + exeheader_size_new=ftell(tmpfile); + fseek(tmpfile,0,SEEK_SET); + unsigned char *header_data_older=header_data_new; + header_data_new=(unsigned char *)malloc(exeheader_size_new); + if (!header_data_new) + { + free(header_data_older); + fclose(tmpfile); + ERROR_MSG("Error: malloc(%d) failed (exepack)\n",exeheader_size_new); + return PS_ERROR; + } + memset(header_data_new,0,exeheader_size_new); + fread(header_data_new,1,exeheader_size_new,tmpfile); + fclose(tmpfile); + remove(build_packname); + + return PS_OK; +} + +int CEXEBuild::write_output(void) +{ +#ifndef NSIS_CONFIG_CRC_SUPPORT + build_crcchk=0; #endif + RET_UNLESS_OK( check_write_output_errors() ); + + has_called_write_output=true; + +#ifdef NSIS_CONFIG_PLUGIN_SUPPORT + RET_UNLESS_OK( add_plugins_dir_initializer() ); +#endif //NSIS_CONFIG_PLUGIN_SUPPORT + +#ifdef NSIS_SUPPORT_VERSION_INFO + RET_UNLESS_OK( AddVersionInfo() ); +#endif //NSIS_SUPPORT_VERSION_INFO + + RET_UNLESS_OK( prepare_uninstaller() ); + DefineInnerLangString(NLF_CAPTION); if (resolve_coderefs("install")) return PS_ERROR; @@ -2327,15 +2401,11 @@ int CEXEBuild::write_output(void) #endif #ifdef NSIS_CONFIG_VISIBLE_SUPPORT - err = ProcessPages(); - if (err != PS_OK) - return err; + RET_UNLESS_OK( ProcessPages() ); #endif //NSIS_CONFIG_VISIBLE_SUPPORT // Generate language tables - err = GenerateLangTables(); - if (err != PS_OK) - return err; + RET_UNLESS_OK( GenerateLangTables() ); init_res_editor(); VerifyDeclaredUserVarRefs(&m_UserVarNames); @@ -2356,76 +2426,23 @@ int CEXEBuild::write_output(void) return PS_ERROR; } - // Pack exe header if asked for - if (build_packname[0] && build_packcmd[0]) - { - FILE *tmpfile=FOPEN(build_packname,"wb"); - if (!tmpfile) - { - ERROR_MSG("Error: writing temporary file \"%s\" for pack\n",build_packname); - return PS_ERROR; - } - fwrite(header_data_new,1,exeheader_size_new,tmpfile); - fclose(tmpfile); - if (system(build_packcmd) == -1) - { - remove(build_packname); - ERROR_MSG("Error: calling packer on \"%s\"\n",build_packname); - return PS_ERROR; - } - tmpfile=FOPEN(build_packname,"rb"); - if (!tmpfile) - { - remove(build_packname); - ERROR_MSG("Error: reading temporary file \"%s\" after pack\n",build_packname); - return PS_ERROR; - } - fseek(tmpfile,0,SEEK_END); - exeheader_size_new=ftell(tmpfile); - fseek(tmpfile,0,SEEK_SET); - unsigned char *header_data_older=header_data_new; - header_data_new=(unsigned char *)malloc(exeheader_size_new); - if (!header_data_new) - { - free(header_data_older); - fclose(tmpfile); - ERROR_MSG("Error: malloc(%d) failed (exepack)\n",exeheader_size_new); - return PS_ERROR; - } - memset(header_data_new,0,exeheader_size_new); - fread(header_data_new,1,exeheader_size_new,tmpfile); - fclose(tmpfile); - remove(build_packname); + RET_UNLESS_OK( pack_exe_header() ); - // write out exe header, pack, read back in, align to 512, and - // update the header info - } build_optimize_datablock=0; int data_block_size_before_uninst = build_datablock.getlen(); - if (uninstall_generate() != PS_OK) - { - return PS_ERROR; - } + RET_UNLESS_OK( uninstall_generate() ); int crc=0; { -#ifdef _WIN32 - char buffer[1024]; - char *p; - GetFullPathName(build_output_filename,1024,buffer,&p); -#else - char *buffer = my_realpath(build_output_filename); -#endif - notify(MAKENSIS_NOTIFY_OUTPUT, buffer); - INFO_MSG("\nOutput: \"%s\"\n", buffer); -#ifndef _WIN32 - my_free_realpath(build_output_filename, buffer); -#endif + string full_path = get_full_path(build_output_filename); + notify(MAKENSIS_NOTIFY_OUTPUT, full_path.c_str()); + INFO_MSG("\nOutput: \"%s\"\n", full_path.c_str()); } + FILE *fp = FOPEN(build_output_filename,"w+b"); if (!fp) { @@ -3191,11 +3208,11 @@ void CEXEBuild::print_warnings() } #ifdef _WIN32 -void CEXEBuild::notify(notify_e code, char *data) const +void CEXEBuild::notify(notify_e code, const char *data) const { if (notify_hwnd) { - COPYDATASTRUCT cds = {(DWORD)code, strlen(data)+1, data}; + COPYDATASTRUCT cds = {(DWORD)code, strlen(data)+1, (void *) data}; SendMessage(notify_hwnd, WM_COPYDATA, 0, (LPARAM)&cds); } } diff --git a/Source/build.h b/Source/build.h index b1354cb8..f6152377 100644 --- a/Source/build.h +++ b/Source/build.h @@ -65,7 +65,7 @@ enum notify_e { class CEXEBuild { public: CEXEBuild(); - void CEXEBuild::setdirs(char *argv0); + void setdirs(const char *argv0); ~CEXEBuild(); // to add a warning to the compiler's warning list. @@ -106,13 +106,15 @@ class CEXEBuild { #ifdef _WIN32 HWND notify_hwnd; - void notify(notify_e code, char *data) const; + void notify(notify_e code, const char *data) const; #else - void notify(notify_e code, char *data) const { } + void notify(notify_e code, const char *data) const { } #endif private: int check_write_output_errors() const; + int prepare_uninstaller(); + int pack_exe_header(); // tokens.cpp int get_commandtoken(char *s, int *np, int *op, int *pos); @@ -284,7 +286,7 @@ class CEXEBuild { bool no_space_texts; - int has_called_write_output; + bool has_called_write_output; char build_packname[1024], build_packcmd[1024]; int build_overwrite, build_last_overwrite, build_crcchk, diff --git a/Source/util.cpp b/Source/util.cpp index d8fbee46..0d24e512 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -12,6 +12,8 @@ # include #endif +using std::string; + int g_dopause=0; extern int g_display_errors; extern FILE *g_output; @@ -415,12 +417,13 @@ char *my_realpath(char *path) void my_free_realpath(char *path, char *buffer) { -#if !defined(_WIN32) && !defined(PATH_MAX) +#ifndef PATH_MAX if (buffer != path) free(buffer); #endif } + #define MY_ERROR_MSG(x) {if (g_display_errors) {fprintf(g_output,"%s", x);}} char *my_convert(const char *path) @@ -491,7 +494,7 @@ int my_glob(const char *pattern, int flags, my_convert_free(converted_pattern); return result; } -#endif +#endif//!_WIN32 void *operator new(size_t size) { void *p = malloc(size); @@ -511,3 +514,20 @@ void operator delete [](void *p) { size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) { return strftime(s, max, fmt, tm); } + +string get_full_path(const string &path) { +#ifdef _WIN32 + char *throwaway; + char real_path[1024]; + int rc = GetFullPathName(path.c_str(),1024,real_path,&throwaway); + assert(rc <= 1024); // path size is limited by MAX_PATH (260) + assert(rc != 0); // rc==0 in case of error + return string(real_path); +#else + // TODO: inline my_{,free_}realpath + char *real_path = my_realpath(path.c_str()); + string result(real_path); + my_free_realpath(real_path); + return result; +#endif//_WIN32 +} diff --git a/Source/util.h b/Source/util.h index 6e678f61..cbd78c77 100644 --- a/Source/util.h +++ b/Source/util.h @@ -8,6 +8,8 @@ #endif #include "ResourceEditor.h" +#include + // these are the standard pause-before-quit shit. extern int g_dopause; extern void dopause(void); @@ -42,6 +44,8 @@ size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm); (((x)&0x0000FF00) << 8) | \ (((x)&0x000000FF) << 24) ) +std::string get_full_path(const std::string &path); + #ifndef _WIN32 char *CharPrev(const char *s, const char *p); char *CharNext(const char *s);