more refactoring

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3683 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2004-09-30 20:25:33 +00:00
parent 0ba42540df
commit c8e7f13742
4 changed files with 168 additions and 125 deletions

View file

@ -21,6 +21,12 @@
# include <stdarg.h> # include <stdarg.h>
#endif #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; int MMapFile::m_iAllocationGranularity = 0;
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
@ -39,11 +45,15 @@ void *lzmaCompressThread(void *lpParameter)
} }
#endif #endif
namespace { // begin anonymous namespace
bool isSimpleChar(char ch) bool isSimpleChar(char ch)
{ {
return (ch == '.' ) || (ch == '_' ) || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); 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) void CEXEBuild::define(const char *p, const char *v)
{ {
definedlist.add(p,v); definedlist.add(p,v);
@ -80,7 +90,7 @@ CEXEBuild::CEXEBuild()
build_include_depth=0; 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_func.add("",0); // make sure offset 0 is special on these (i.e. never used by a label)
ns_label.add("",0); 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); m_ShellConstants.add("CDBURN_AREA", CSIDL_CDBURN_AREA, CSIDL_CDBURN_AREA);
} }
void CEXEBuild::setdirs(char *argv0) namespace {
{ string get_executable_path(const char* argv0) {
char szNSISDir[NSIS_MAX_STRLEN*2],*fn2;
int len = sizeof(szNSISDir) - sizeof(PLATFORM_PATH_SEPARATOR_STR "Include") - 1;
#ifdef _WIN32 #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 #else
char *buffer = my_realpath(argv0); return get_full_path(argv0);
strncpy(szNSISDir, buffer, len);
szNSISDir[sizeof(szNSISDir)-1] = 0;
my_free_realpath(argv0, buffer);
#endif #endif
fn2=strrchr(szNSISDir,PLATFORM_PATH_SEPARATOR_C); }
if(fn2!=NULL) *fn2=0;
definedlist.add("NSISDIR",(char*)szNSISDir); string get_dirname(const string& path) {
strcat(szNSISDir, PLATFORM_PATH_SEPARATOR_STR "Include"); string::size_type last_separator_pos = path.rfind(PLATFORM_PATH_SEPARATOR_C);
include_dirs.add(szNSISDir,0); 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; return PS_OK;
} }
int CEXEBuild::write_output(void) int CEXEBuild::prepare_uninstaller() {
{
#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
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if (ubuild_entries.getlen()) if (ubuild_entries.getlen())
{ {
if (!uninstaller_writes_used) if (!uninstaller_writes_used)
{ {
warning("Uninstall section found but WriteUninstaller never used - no uninstaller will be created."); 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); build_uninst.flags|=build_header.flags&(CH_FLAGS_PROGRESS_COLORED|CH_FLAGS_NO_ROOT_DIR);
DefineInnerLangString(NLF_UCAPTION);
if (resolve_coderefs("uninstall")) set_uninstall_mode(1);
return PS_ERROR; DefineInnerLangString(NLF_UCAPTION);
if (resolve_coderefs("uninstall"))
return PS_ERROR;
#ifdef NSIS_CONFIG_COMPONENTPAGE #ifdef NSIS_CONFIG_COMPONENTPAGE
// set sections to the first insttype // set sections to the first insttype
PrepareInstTypes(); PrepareInstTypes();
#endif #endif
set_uninstall_mode(0); set_uninstall_mode(0);
}
} }
else if (uninstaller_writes_used) else if (uninstaller_writes_used)
{ {
ERROR_MSG("Error: no Uninstall section specified, but WriteUninstaller used %d time(s)\n",uninstaller_writes_used); ERROR_MSG("Error: no Uninstall section specified, but WriteUninstaller used %d time(s)\n",uninstaller_writes_used);
return PS_ERROR; 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 #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); DefineInnerLangString(NLF_CAPTION);
if (resolve_coderefs("install")) if (resolve_coderefs("install"))
return PS_ERROR; return PS_ERROR;
@ -2327,15 +2401,11 @@ int CEXEBuild::write_output(void)
#endif #endif
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
err = ProcessPages(); RET_UNLESS_OK( ProcessPages() );
if (err != PS_OK)
return err;
#endif //NSIS_CONFIG_VISIBLE_SUPPORT #endif //NSIS_CONFIG_VISIBLE_SUPPORT
// Generate language tables // Generate language tables
err = GenerateLangTables(); RET_UNLESS_OK( GenerateLangTables() );
if (err != PS_OK)
return err;
init_res_editor(); init_res_editor();
VerifyDeclaredUserVarRefs(&m_UserVarNames); VerifyDeclaredUserVarRefs(&m_UserVarNames);
@ -2356,76 +2426,23 @@ int CEXEBuild::write_output(void)
return PS_ERROR; return PS_ERROR;
} }
// Pack exe header if asked for RET_UNLESS_OK( pack_exe_header() );
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);
// write out exe header, pack, read back in, align to 512, and
// update the header info
}
build_optimize_datablock=0; build_optimize_datablock=0;
int data_block_size_before_uninst = build_datablock.getlen(); int data_block_size_before_uninst = build_datablock.getlen();
if (uninstall_generate() != PS_OK) RET_UNLESS_OK( uninstall_generate() );
{
return PS_ERROR;
}
int crc=0; int crc=0;
{ {
#ifdef _WIN32 string full_path = get_full_path(build_output_filename);
char buffer[1024]; notify(MAKENSIS_NOTIFY_OUTPUT, full_path.c_str());
char *p; INFO_MSG("\nOutput: \"%s\"\n", full_path.c_str());
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
} }
FILE *fp = FOPEN(build_output_filename,"w+b"); FILE *fp = FOPEN(build_output_filename,"w+b");
if (!fp) if (!fp)
{ {
@ -3191,11 +3208,11 @@ void CEXEBuild::print_warnings()
} }
#ifdef _WIN32 #ifdef _WIN32
void CEXEBuild::notify(notify_e code, char *data) const void CEXEBuild::notify(notify_e code, const char *data) const
{ {
if (notify_hwnd) 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); SendMessage(notify_hwnd, WM_COPYDATA, 0, (LPARAM)&cds);
} }
} }

View file

@ -65,7 +65,7 @@ enum notify_e {
class CEXEBuild { class CEXEBuild {
public: public:
CEXEBuild(); CEXEBuild();
void CEXEBuild::setdirs(char *argv0); void setdirs(const char *argv0);
~CEXEBuild(); ~CEXEBuild();
// to add a warning to the compiler's warning list. // to add a warning to the compiler's warning list.
@ -106,13 +106,15 @@ class CEXEBuild {
#ifdef _WIN32 #ifdef _WIN32
HWND notify_hwnd; HWND notify_hwnd;
void notify(notify_e code, char *data) const; void notify(notify_e code, const char *data) const;
#else #else
void notify(notify_e code, char *data) const { } void notify(notify_e code, const char *data) const { }
#endif #endif
private: private:
int check_write_output_errors() const; int check_write_output_errors() const;
int prepare_uninstaller();
int pack_exe_header();
// tokens.cpp // tokens.cpp
int get_commandtoken(char *s, int *np, int *op, int *pos); int get_commandtoken(char *s, int *np, int *op, int *pos);
@ -284,7 +286,7 @@ class CEXEBuild {
bool no_space_texts; bool no_space_texts;
int has_called_write_output; bool has_called_write_output;
char build_packname[1024], build_packcmd[1024]; char build_packname[1024], build_packcmd[1024];
int build_overwrite, build_last_overwrite, build_crcchk, int build_overwrite, build_last_overwrite, build_crcchk,

View file

@ -12,6 +12,8 @@
# include <ctype.h> # include <ctype.h>
#endif #endif
using std::string;
int g_dopause=0; int g_dopause=0;
extern int g_display_errors; extern int g_display_errors;
extern FILE *g_output; extern FILE *g_output;
@ -415,12 +417,13 @@ char *my_realpath(char *path)
void my_free_realpath(char *path, char *buffer) void my_free_realpath(char *path, char *buffer)
{ {
#if !defined(_WIN32) && !defined(PATH_MAX) #ifndef PATH_MAX
if (buffer != path) if (buffer != path)
free(buffer); free(buffer);
#endif #endif
} }
#define MY_ERROR_MSG(x) {if (g_display_errors) {fprintf(g_output,"%s", x);}} #define MY_ERROR_MSG(x) {if (g_display_errors) {fprintf(g_output,"%s", x);}}
char *my_convert(const char *path) char *my_convert(const char *path)
@ -491,7 +494,7 @@ int my_glob(const char *pattern, int flags,
my_convert_free(converted_pattern); my_convert_free(converted_pattern);
return result; return result;
} }
#endif #endif//!_WIN32
void *operator new(size_t size) { void *operator new(size_t size) {
void *p = malloc(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) { size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) {
return strftime(s, max, fmt, 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
}

View file

@ -8,6 +8,8 @@
#endif #endif
#include "ResourceEditor.h" #include "ResourceEditor.h"
#include <string>
// these are the standard pause-before-quit shit. // these are the standard pause-before-quit shit.
extern int g_dopause; extern int g_dopause;
extern void dopause(void); 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)&0x0000FF00) << 8) | \
(((x)&0x000000FF) << 24) ) (((x)&0x000000FF) << 24) )
std::string get_full_path(const std::string &path);
#ifndef _WIN32 #ifndef _WIN32
char *CharPrev(const char *s, const char *p); char *CharPrev(const char *s, const char *p);
char *CharNext(const char *s); char *CharNext(const char *s);