From 4c1780d9f0e32797ea018ed1b7fdc065014b9302 Mon Sep 17 00:00:00 2001 From: kichik Date: Sat, 3 Aug 2002 23:06:10 +0000 Subject: [PATCH] no message git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@638 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/Language files/English.nlf | 4 +- Source/build.cpp | 166 +-------- Source/build.h | 18 + Source/exehead/Ui.c | 96 ++++-- Source/exehead/exec.c | 58 ++-- Source/exehead/fileform.h | 160 ++++++--- Source/exehead/lang.h | 94 ++++-- Source/lang.cpp | 524 +++++++++++++++++++++++++++++ Source/lang.h | 103 ++++++ Source/makenssi.dsp | 8 + Source/script.cpp | 89 +++-- 11 files changed, 987 insertions(+), 333 deletions(-) create mode 100644 Source/lang.cpp create mode 100644 Source/lang.h diff --git a/Contrib/Language files/English.nlf b/Contrib/Language files/English.nlf index 2d890478..3d409798 100644 --- a/Contrib/Language files/English.nlf +++ b/Contrib/Language files/English.nlf @@ -1,5 +1,6 @@ -# DON'T EVER EDIT THIS TWO LINES! +# Header, don't edit NLF v1 +# Language ID 1033 # Start editing here Nullsoft Install System %s @@ -33,7 +34,6 @@ Space available: Space required: Uninstalling from: Error opening file for writing: $\r$\n$\t"$0"$\r$\nHit abort to abort installation,$\r$\nretry to retry writing the file, or$\r$\nignore to skip this file -verifying installer: %d%% Can't write: Copy failed Copy to diff --git a/Source/build.cpp b/Source/build.cpp index 60dbcf3d..a1434515 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -11,8 +11,6 @@ #include "ResourceEditor.h" #include "exehead/resource.h" -extern const char *NSIS_VERSION; - void CEXEBuild::define(const char *p, const char *v) { definedlist.add(p,v); @@ -270,6 +268,8 @@ CEXEBuild::CEXEBuild() m_uninst_fileused=0; branding_image_found=false; // Added by Amir Szekely 22nd July 2002 + + no_space_texts=false; } int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); } @@ -1047,7 +1047,10 @@ int CEXEBuild::write_output(void) return PS_ERROR; } -#ifdef NSIS_CONFIG_COMPONENTPAGE + // Added by Amir Szekely 3rd August 2002 + if (WriteStringTables() == PS_ERROR) return PS_ERROR; + +/*#ifdef NSIS_CONFIG_COMPONENTPAGE if (build_header.componenttext_ptr < 0 && ns > 1 #ifdef NSIS_CONFIG_SILENT_SUPPORT @@ -1057,57 +1060,15 @@ int CEXEBuild::write_output(void) { build_header.componenttext_ptr=-1; } -#endif +#endif*/ } -#ifdef NSIS_CONFIG_COMPONENTPAGE - // if component page, do component strings: - if (build_header.componenttext_ptr>=0) - { - int x; - int iscp=0; - for (x = 1; x < build_header.num_sections&&!iscp; x ++) - { - char c=build_strlist.get()[((section*)build_sections.get())[x].name_ptr]; - if (c && c != '-') iscp++; - } - if (iscp) - { - if (build_header.custom_ptr<0) build_header.custom_ptr=add_string_main("Custom",0); - if (build_header.common.subcaption_ptrs[1]<0) - build_header.common.subcaption_ptrs[1]=add_string_main(": Installation Options",0); - - if (build_header.install_types_ptr[0] < 0) - { - if (build_header.componentsubtext_ptr[1]<0) - build_header.componentsubtext_ptr[1]=add_string_main("Select components to install:",0); - } - else - { - if (build_header.componentsubtext_ptr[0]<0) - build_header.componentsubtext_ptr[0]=add_string_main("Select the type of install:",0); - if (build_header.no_custom_instmode_flag!=1 && build_header.componentsubtext_ptr[1]<0) - build_header.componentsubtext_ptr[1]=add_string_main("Or, select the optional components you wish to install:",0); - } - } - else build_header.componenttext_ptr=-1; - } -#endif - - if (!build_entries.getlen()) { ERROR_MSG("Error: invalid script: no entries specified\n"); return PS_ERROR; } - if (build_header.common.name_ptr < 0) - { - warning("Name command not specified. Assuming default."); - build_header.common.name_ptr=add_string_main("Name",0); - build_uninst.common.name_ptr=add_string_uninst("Name",0); - } - if (build_cursection || uninstall_mode) { ERROR_MSG("Error: Section left open at EOF\n"); @@ -1128,80 +1089,10 @@ int CEXEBuild::write_output(void) } #ifdef NSIS_CONFIG_LICENSEPAGE - if (build_header.licensedata_ptr<0 || build_header.licensetext_ptr<0) - { - build_header.licensedata_ptr=-1; - build_header.licensetext_ptr=-1; - } - - if (build_header.licensedata_ptr>=0) - { - if (build_header.common.subcaption_ptrs[0]<0) - build_header.common.subcaption_ptrs[0]=add_string_main(": License Agreement",0); - if (build_header.licensebutton_ptr<0) - build_header.licensebutton_ptr=add_string_main("I Agree",0); - } - if (build_header.license_bg<0) build_header.license_bg=GetSysColor(COLOR_BTNFACE); #endif - if (build_header.text_ptr >= 0) - { - if (build_header.dirsubtext_ptr<0) - { - char buf[2048]; - wsprintf(buf,"Select the directory to install %s in:",build_strlist.get()+build_header.common.name_ptr); - build_header.dirsubtext_ptr=add_string_main(buf,0); - } - if (build_header.common.subcaption_ptrs[2]<0) - build_header.common.subcaption_ptrs[2]=add_string_main(": Installation Directory",0); - if (build_header.browse_ptr<0) build_header.browse_ptr=add_string_main("Browse...",0); - if (build_header.spaceavailable_ptr<0) build_header.spaceavailable_ptr=add_string_main("Space available: ",0); - } - - if (build_header.text_ptr >= 0 -#ifdef NSIS_CONFIG_COMPONENTPAGE - || build_header.componenttext_ptr>=0 -#endif - ) - { - // Changed by Amir Szekely 22nd July 2002 - // Adds the ability to disable space texts - if (build_header.spacerequired_ptr==-1) build_header.spacerequired_ptr=add_string_main("Space required: ",0); - if (build_header.nextbutton_ptr<0) build_header.nextbutton_ptr=add_string_main("Next >",0); - if (build_header.installbutton_ptr<0) build_header.installbutton_ptr=add_string_main("Install",0); - } - - if (build_header.common.subcaption_ptrs[3]<0) - build_header.common.subcaption_ptrs[3]=add_string_main(": Installing Files",0); - if (build_header.common.subcaption_ptrs[4]<0) - build_header.common.subcaption_ptrs[4]=add_string_main(": Completed",0); - - if (build_header.common.branding_ptr<0) - { - char buf[256]; - wsprintf(buf,"Nullsoft Install System %s",NSIS_VERSION); - build_header.common.branding_ptr=add_string_main(buf,0); - } - if (build_header.backbutton_ptr<0) build_header.backbutton_ptr=add_string_main("< Back",0); - if (build_header.common.cancelbutton_ptr<0) build_header.common.cancelbutton_ptr=add_string_main("Cancel",0); - if (build_header.common.showdetailsbutton_ptr<0) build_header.common.showdetailsbutton_ptr=add_string_main("Show details",0); - - if (build_header.common.closebutton_ptr<0) build_header.common.closebutton_ptr=add_string_main("Close",0); - if (build_header.common.completed_ptr<0) build_header.common.completed_ptr=add_string_main("Completed",0); -#ifdef NSIS_SUPPORT_FILE - if (m_inst_fileused && build_header.common.fileerrtext_ptr<0) - { - build_header.common.fileerrtext_ptr=add_string_main( - "Error opening file for writing: \r\n\t\"$0\"\r\n" - "Hit abort to abort installation,\r\n" - "retry to retry writing the file, or\r\n" - "ignore to skip this file"); - } -#endif - - #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (ubuild_entries.getlen()) { @@ -1211,30 +1102,8 @@ int CEXEBuild::write_output(void) } else { - if (build_uninst.uninstalltext2_ptr<0) - build_uninst.uninstalltext2_ptr=add_string_uninst("Uninstalling from:",0); - if (build_uninst.common.subcaption_ptrs[0]<0) - build_uninst.common.subcaption_ptrs[0]=add_string_uninst(": Confirmation",0); - if (build_uninst.common.subcaption_ptrs[1]<0) - build_uninst.common.subcaption_ptrs[1]=add_string_uninst(": Uninstalling Files",0); - if (build_uninst.common.subcaption_ptrs[2]<0) - build_uninst.common.subcaption_ptrs[2]=add_string_uninst(": Completed",0); - if (build_uninst.common.caption_ptr < 0) - { - char buf[1024]; - wsprintf(buf,"%s Uninstall",ubuild_strlist.get()+build_uninst.common.name_ptr); - build_uninst.common.caption_ptr=add_string_uninst(buf,0); - } - build_uninst.common.branding_ptr=add_string_uninst(build_strlist.get() + build_header.common.branding_ptr,0); - build_uninst.common.cancelbutton_ptr=add_string_uninst(build_strlist.get() + build_header.common.cancelbutton_ptr,0); - build_uninst.common.showdetailsbutton_ptr=add_string_uninst(build_strlist.get() + build_header.common.showdetailsbutton_ptr,0); - build_uninst.common.closebutton_ptr=add_string_uninst(build_strlist.get() + build_header.common.closebutton_ptr,0); - build_uninst.common.completed_ptr=add_string_uninst(build_strlist.get() + build_header.common.completed_ptr,0); - build_uninst.common.progress_flags=build_header.common.progress_flags; build_uninst.common.misc_flags|=build_header.common.misc_flags&(4|8); - - if (build_uninst.uninstbutton_ptr<0) build_uninst.uninstbutton_ptr=add_string_uninst("Uninstall",0); set_uninstall_mode(1); #ifdef NSIS_SUPPORT_CODECALLBACKS @@ -1253,14 +1122,6 @@ int CEXEBuild::write_output(void) ERROR_MSG("Error: no Uninstall section specified, but WriteUninstaller used %d time(s)\n",uninstaller_writes_used); return PS_ERROR; } - -#ifdef NSIS_SUPPORT_FILE - if (m_uninst_fileused && build_uninst.common.fileerrtext_ptr<0) - { - build_uninst.common.fileerrtext_ptr=add_string_uninst(build_strlist.get() + build_header.common.fileerrtext_ptr,0); - } -#endif - #endif @@ -1286,7 +1147,7 @@ int CEXEBuild::write_output(void) SCRIPT_MSG("Removing unused resources... "); CResourceEditor re(header_data_new, exeheader_size_new); #ifdef NSIS_CONFIG_LICENSEPAGE - if (build_header.licensedata_ptr < 0 + if (IsNotSet(installer.licensedata) #ifdef NSIS_CONFIG_SILENT_SUPPORT || build_header.common.silent_install #endif // NSIS_CONFIG_SILENT_SUPPORT @@ -1296,7 +1157,7 @@ int CEXEBuild::write_output(void) } #endif // NSIS_CONFIG_LICENSEPAGE #ifdef NSIS_CONFIG_COMPONENTPAGE - if (build_header.componenttext_ptr < 0 + if (IsNotSet(installer.componenttext) #ifdef NSIS_CONFIG_SILENT_SUPPORT || build_header.common.silent_install #endif // NSIS_CONFIG_SILENT_SUPPORT @@ -1306,7 +1167,7 @@ int CEXEBuild::write_output(void) re.UpdateResource(RT_BITMAP, IDB_BITMAP1, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0); } #endif // NSIS_CONFIG_COMPONENTPAGE - if (build_header.text_ptr < 0 + if (IsNotSet(installer.text) #ifdef NSIS_CONFIG_SILENT_SUPPORT || build_header.common.silent_install #endif // NSIS_CONFIG_SILENT_SUPPORT @@ -1350,13 +1211,6 @@ int CEXEBuild::write_output(void) } #endif // NSIS_CONFIG_VISIBLE_SUPPORT - if (build_header.common.caption_ptr < 0) - { - char buf[1024]; - wsprintf(buf,"%s Setup",build_strlist.get()+build_header.common.name_ptr); - build_header.common.caption_ptr=add_string_main(buf,0); - } - // Pack exe header if asked for if (build_packname[0] && build_packcmd[0]) { diff --git a/Source/build.h b/Source/build.h index ff53789e..513fd576 100644 --- a/Source/build.h +++ b/Source/build.h @@ -1,8 +1,12 @@ #ifndef _BUILD_H_ #define _BUILD_H_ +#include +using namespace std; + #include "strlist.h" #include "lineparse.h" +#include "lang.h" #include "exehead/fileform.h" #include "exehead/config.h" @@ -107,6 +111,14 @@ class CEXEBuild { int uninstall_generate(); void set_uninstall_mode(int un); + // lang.cpp by Amir Szekely 3rd August 2002 + int SetString(char *string, int id, int process, WORD lang=0); + int SetString(char *string, int id, int process, StringTable *table); + int WriteStringTables(); + void FillDefaultsIfNeeded(StringTable *table, NLF *nlf=0); + #define IsNotSet(s) _IsNotSet(string_tables.size()?&(string_tables[0]->##s):0) + bool _IsNotSet(int *str); // Checks if a string is not set in all of the string tables + // a whole bunch O data. // Added by Amir Szekely 31st July 2002 @@ -116,6 +128,12 @@ class CEXEBuild { bool build_compressor_set; bool build_compress_whole; + // Added by Amir Szekely 2nd August 2002 + vector build_nlfs; + vector string_tables; + + bool no_space_texts; + int has_called_write_output; char build_packname[1024], build_packcmd[1024]; diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index 0ca0e20f..8b416ff0 100644 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -33,10 +33,17 @@ #include "util.h" #include "ui.h" #include "exec.h" +#include "lang.h" #define LB_ICONWIDTH 20 #define LB_ICONHEIGHT 20 +// Added by Amir Szekely 3rd August 2002 +installer_strings *install_strings_tables; +common_strings *common_strings_tables; +uninstall_strings *uninstall_strings_tables; +int current_lang; + int g_quit_flag; // set when Quit has been called (meaning bail out ASAP) #if NSIS_MAX_INST_TYPES >= 31 || NSIS_MAX_INST_TYPES < 1 @@ -204,6 +211,7 @@ static void CheckTreeItem(HWND hWnd, TV_ITEM *pItem, int checked) { int ui_doinstall(void) { + int size; g_autoclose=g_inst_cmnheader->misc_flags&1; #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (!g_is_uninstaller) @@ -258,6 +266,22 @@ int ui_doinstall(void) process_string_fromtab(state_install_directory,g_inst_header->install_directory_ptr); } + // Added by Amir Szekely 3rd August 2002 + // Multilingual support + size=g_inst_header->common.str_tables_num*sizeof(common_strings); + common_strings_tables=(common_strings*)GlobalAlloc(GPTR,size); + GetCompressedDataFromDataBlockToMemory(g_inst_header->common.str_tables,(char*)common_strings_tables,size); + if (!g_is_uninstaller) { + size=g_inst_header->str_tables_num*sizeof(installer_strings); + install_strings_tables=(installer_strings*)GlobalAlloc(GPTR,size); + GetCompressedDataFromDataBlockToMemory(g_inst_header->str_tables,(char*)install_strings_tables,size); + } + else { + size=g_inst_header->str_tables_num*sizeof(uninstall_strings); + uninstall_strings_tables=(uninstall_strings*)GlobalAlloc(GPTR,size); + GetCompressedDataFromDataBlockToMemory(g_inst_header->str_tables,(char*)uninstall_strings_tables,size); + } + #ifdef NSIS_CONFIG_LOG if (g_inst_cmnheader->silent_install==2) { @@ -267,7 +291,7 @@ int ui_doinstall(void) #endif } - process_string_fromtab(g_caption,g_inst_cmnheader->caption_ptr); + process_string_fromtab(g_caption,COMMON_STR(caption)); #ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_SILENT_SUPPORT @@ -362,33 +386,33 @@ static BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l if (uMsg == WM_INITDIALOG) { g_hwnd=hwndDlg; - SetDlgItemText(hwndDlg,IDC_VERSTR,GetStringFromStringTab(g_inst_cmnheader->branding_ptr)); + SetDlgItemText(hwndDlg,IDC_VERSTR,LANG_BRANDING); hIcon=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON2)); SetClassLong(hwndDlg,GCL_HICON,(long)hIcon); - SetDlgItemText(hwndDlg,IDCANCEL,GetStringFromStringTab(g_inst_cmnheader->cancelbutton_ptr)); + SetDlgItemText(hwndDlg,IDCANCEL,LANG_BTN_CANCEL); #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (!g_is_uninstaller) #endif - SetDlgItemText(hwndDlg,IDC_BACK,GetStringFromStringTab(g_inst_header->backbutton_ptr)); + SetDlgItemText(hwndDlg,IDC_BACK,LANG_BTN_BACK); ShowWindow(hwndDlg,SW_SHOW); } #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT if (g_is_uninstaller) { - islp=(g_inst_uninstheader->uninstalltext_ptr>=0); + islp=UNINSTALL_STR(uninstalltext)>=0; iscp++; } else #endif//NSIS_CONFIG_UNINSTALL_SUPPORT { #ifdef NSIS_CONFIG_LICENSEPAGE - if (g_inst_header->licensedata_ptr>=0) islp++; + if (INSTALL_STR(licensedata)>=0) islp++; #endif//NSIS_CONFIG_LICENSEPAGE #ifdef NSIS_CONFIG_COMPONENTPAGE - if (g_inst_header->componenttext_ptr>=0) iscp++; + if (INSTALL_STR(componenttext)>=0) iscp++; #endif//NSIS_CONFIG_COMPONENTPAGE - if (g_inst_header->text_ptr>=0) ispotentiallydp++; + if (INSTALL_STR(text)>=0) ispotentiallydp++; if (ispotentiallydp && !((g_inst_cmnheader->misc_flags&2) && is_valid_instpath(state_install_directory) @@ -436,19 +460,19 @@ static BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l else if (!m_curwnd) { HWND hwndtmp; - SetDlgItemText(hwndDlg,IDOK,GetStringFromStringTab( - (m_page == g_max_page) ? g_inst_cmnheader->closebutton_ptr : + SetDlgItemText(hwndDlg,IDOK, + (m_page == g_max_page) ? LANG_BTN_CLOSE : #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - g_is_uninstaller ? g_inst_uninstheader->uninstbutton_ptr : + g_is_uninstaller ? LANG_BTN_UNINST : #endif #ifdef NSIS_CONFIG_LICENSEPAGE - (m_page == 0) ? g_inst_header->licensebutton_ptr : + (m_page == 0) ? LANG_BTN_LICENSE : #endif - (m_page == 2 || (m_page == 1 && !isdp)) ? g_inst_header->installbutton_ptr : - g_inst_header->nextbutton_ptr - )); + (m_page == 2 || (m_page == 1 && !isdp)) ? LANG_BTN_INSTALL : + LANG_BTN_NEXT + ); lstrcpy(g_tmp,g_caption); - process_string_fromtab(g_tmp+lstrlen(g_tmp),g_inst_cmnheader->subcaption_ptrs[m_page]); + process_string_fromtab(g_tmp+lstrlen(g_tmp),COMMON_STR(subcaptions[m_page])); SetWindowText(hwndDlg,g_tmp); @@ -534,8 +558,8 @@ static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0); SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,g_inst_header->license_bg); SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK); - SetWindowText(hwLicense,GetStringFromStringTab(g_inst_header->licensedata_ptr)); - SetDlgItemText(hwndDlg,IDC_INTROTEXT,GetStringFromStringTab(g_inst_header->licensetext_ptr)); + SetWindowText(hwLicense,LANG_LICENSE_DATA); + SetDlgItemText(hwndDlg,IDC_INTROTEXT,LANG_LICENSE_TEXT); } else if (uMsg == WM_NOTIFY) { ENLINK *enlink=(ENLINK *)lParam; @@ -571,8 +595,8 @@ static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l { if (uMsg == WM_INITDIALOG) { - SetDlgItemText(hwndDlg,IDC_UNINSTFROM,GetStringFromStringTab(g_inst_uninstheader->uninstalltext2_ptr)); - SetDlgItemText(hwndDlg,IDC_INTROTEXT,GetStringFromStringTab(g_inst_uninstheader->uninstalltext_ptr)); + SetDlgItemText(hwndDlg,IDC_UNINSTFROM,LANG_UNINST_SUBTEXT); + SetDlgItemText(hwndDlg,IDC_INTROTEXT,LANG_UNINST_TEXT); SetDlgItemText(hwndDlg,IDC_EDIT1,state_install_directory); } return 0; @@ -609,9 +633,9 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar } #endif SetDlgItemText(hwndDlg,IDC_DIR,state_install_directory); - SetDlgItemText(hwndDlg,IDC_INTROTEXT,GetStringFromStringTab(g_inst_header->text_ptr)); - SetDlgItemText(hwndDlg,IDC_BROWSE,GetStringFromStringTab(g_inst_header->browse_ptr)); - SetDlgItemText(hwndDlg,IDC_SELDIRTEXT,GetStringFromStringTab(g_inst_header->dirsubtext_ptr)); + SetDlgItemText(hwndDlg,IDC_INTROTEXT,LANG_DIR_TEXT); + SetDlgItemText(hwndDlg,IDC_BROWSE,LANG_BTN_BROWSE); + SetDlgItemText(hwndDlg,IDC_SELDIRTEXT,LANG_DIR_SUBTEXT); SendMessage(hwndDlg,WM_IN_UPDATEMSG,0,0); } if (uMsg == WM_COMMAND) @@ -707,13 +731,13 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar // Added by Amir Szekely 24th July 2002 // Allows 'SpaceTexts none' - if (g_inst_header->spacerequired_ptr != -2) { - lstrcpy(s,GetStringFromStringTab(g_inst_header->spacerequired_ptr)); + if (INSTALL_STR(spacerequired) >= 0) { + lstrcpy(s,LANG_SPACE_REQ); inttosizestr(total,s); SetDlgItemText(hwndDlg,IDC_SPACEREQUIRED,s); if (available != -1) { - lstrcpy(s,GetStringFromStringTab(g_inst_header->spaceavailable_ptr)); + lstrcpy(s,LANG_SPACE_AVAIL); inttosizestr(available,s); SetDlgItemText(hwndDlg,IDC_SPACEAVAILABLE,s); } @@ -762,9 +786,9 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar hTreeItems=(HTREEITEM*)GlobalAlloc(GPTR,sizeof(HTREEITEM)*g_inst_header->num_sections); hBMcheck1=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1)); - SetDlgItemText(hwndDlg,IDC_INTROTEXT,GetStringFromStringTab(g_inst_header->componenttext_ptr)); - SetDlgItemText(hwndDlg,IDC_TEXT1,GetStringFromStringTab(g_inst_header->componentsubtext_ptr[0])); - SetDlgItemText(hwndDlg,IDC_TEXT2,GetStringFromStringTab(g_inst_header->componentsubtext_ptr[1])); + SetDlgItemText(hwndDlg,IDC_INTROTEXT,LANG_COMP_TEXT); + SetDlgItemText(hwndDlg,IDC_TEXT1,LANG_COMP_SUBTEXT(0)); + SetDlgItemText(hwndDlg,IDC_TEXT2,LANG_COMP_SUBTEXT(1)); oldTreeWndProc=GetWindowLong(hwndTree1,GWL_WNDPROC); SetWindowLong(hwndTree1,GWL_WNDPROC,(DWORD)newTreeWndProc); @@ -790,7 +814,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar { SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)GetStringFromStringTab(g_inst_header->install_types_ptr[m_num_insttypes])); } - if (g_inst_header->no_custom_instmode_flag!=1) SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)GetStringFromStringTab(g_inst_header->custom_ptr)); + if (g_inst_header->no_custom_instmode_flag!=1) SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)LANG_COMP_CUSTOM); SendMessage(hwndCombo1,CB_SETCURSEL,m_whichcfg,0); } @@ -1051,7 +1075,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar ShowWindow(GetDlgItem(hwndDlg,IDC_TEXT2),c); } - if (g_inst_header->spacerequired_ptr > 0) { + if (INSTALL_STR(spacerequired) >= 0) { int x,total; char s[128]; for (total=x=0; x < g_inst_header->num_sections; x ++) @@ -1059,7 +1083,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar if (g_inst_section[x].default_state&DFS_SET) total+=g_inst_section[x].size_kb; } - lstrcpy(s,GetStringFromStringTab(g_inst_header->spacerequired_ptr)); + lstrcpy(s,LANG_SPACE_REQ); inttosizestr(total,s); SetDlgItemText(hwndDlg,IDC_SPACEREQUIRED,s); } @@ -1162,7 +1186,7 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa else #endif { - log_printf3("New install of \"%s\" to \"%s\"",GetStringFromStringTab(g_inst_cmnheader->name_ptr),state_install_directory); + log_printf3("New install of \"%s\" to \"%s\"",LANG_NAME,state_install_directory); for (; x < g_inst_header->num_sections; x ++) { #ifdef NSIS_CONFIG_COMPONENTPAGE @@ -1178,7 +1202,7 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa ListView_SetBkColor(insthwnd, g_inst_cmnheader->lb_bg); ListView_SetTextBkColor(insthwnd, g_inst_cmnheader->lb_bg); ListView_SetTextColor(insthwnd, g_inst_cmnheader->lb_fg); - SetWindowText(insthwndbutton,GetStringFromStringTab(g_inst_cmnheader->showdetailsbutton_ptr)); + SetWindowText(insthwndbutton,LANG_BTN_DETAILS); if (g_inst_cmnheader->show_details) { ShowWindow(insthwndbutton,SW_HIDE); @@ -1221,8 +1245,8 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa { ShowWindow(g_hwnd,SW_SHOWNA); lstrcpy(g_tmp,g_caption); - process_string_fromtab(g_tmp+lstrlen(g_caption),g_inst_cmnheader->subcaption_ptrs[g_max_page+1]); - update_status_text(GetStringFromStringTab(g_inst_cmnheader->completed_ptr),""); + process_string_fromtab(g_tmp+lstrlen(g_caption),COMMON_STR(subcaptions[g_max_page+1])); + update_status_text(LANG_COMPLETED,""); SetWindowText(h2,g_tmp); SetFocus(h); } diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index a4b39afc..0be7751d 100644 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -15,6 +15,12 @@ HWND g_SectionHack; #endif +// Added by Amir Szekely 3rd August 2002 +extern installer_strings *install_strings_tables; +extern common_strings *common_strings_tables; +extern uninstall_strings *uninstall_strings_tables; +extern int current_lang; + #ifdef NSIS_SUPPORT_STACK typedef struct _stack_t { struct _stack_t *next; @@ -67,7 +73,7 @@ static void doRMDir(char *buf, int recurse) if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) doRMDir(buf,recurse); else { - update_status_text(LANG_STR(LANG_DELETEFILE),buf); + update_status_text(LANG_DELETEFILE,buf); if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) SetFileAttributes(buf,fd.dwFileAttributes^FILE_ATTRIBUTE_READONLY); DeleteFile(buf); @@ -79,7 +85,7 @@ static void doRMDir(char *buf, int recurse) buf[i]=0; // fix buffer } log_printf2("RMDir: RemoveDirectory(\"%s\")",buf); - update_status_text(LANG_STR(LANG_REMOVEDIR),buf); + update_status_text(LANG_REMOVEDIR,buf); RemoveDirectory(buf); } #endif//NSIS_SUPPORT_RMDIR @@ -234,10 +240,10 @@ static int ExecuteEntry(entry *entries, int pos) log_printf3("CreateDirectory: \"%s\" (%d)",buf2,parms[1]); if (parms[1]) { - update_status_text(LANG_STR(LANG_OUTPUTDIR),buf2); + update_status_text(LANG_OUTPUTDIR,buf2); lstrcpy(state_output_directory,buf2); } - else update_status_text(LANG_STR(LANG_CREATEDIR),buf2); + else update_status_text(LANG_CREATEDIR,buf2); recursive_create_directory(buf2); return 0; case EW_IFFILEEXISTS: @@ -273,7 +279,7 @@ static int ExecuteEntry(entry *entries, int pos) log_printf2("Rename: %s",buf4); if (MoveFile(buf,buf2)) { - update_status_text(LANG_STR(LANG_RENAME),buf4); + update_status_text(LANG_RENAME,buf4); } else { @@ -284,7 +290,7 @@ static int ExecuteEntry(entry *entries, int pos) exec_rebootflag++; #endif MoveFileOnReboot(buf,buf2); - update_status_text(LANG_STR(LANG_RENAMEONREBOOT),buf4); + update_status_text(LANG_RENAMEONREBOOT,buf4); log_printf2("Rename on reboot: %s",buf4); } else @@ -384,7 +390,7 @@ static int ExecuteEntry(entry *entries, int pos) { if (overwriteflag) { - update_status_text(LANG_STR(LANG_SKIPPED),buf4); + update_status_text(LANG_SKIPPED,buf4); if (overwriteflag==2) exec_errorflag++; log_printf3("File: skipped: \"%s\" (overwriteflag=%d)",buf,overwriteflag); return 0; @@ -393,7 +399,7 @@ static int ExecuteEntry(entry *entries, int pos) lstrcpy(buf3,g_usrvars[0]);//save $0 lstrcpy(g_usrvars[0],buf); - process_string_fromtab(buf2,g_inst_cmnheader->fileerrtext_ptr); + process_string(buf2,LANG_FILEERR); lstrcpy(g_usrvars[0],buf3); // restore $0 switch (MessageBox(g_hwnd,buf2,g_caption,MB_ABORTRETRYIGNORE|MB_ICONSTOP)) @@ -407,12 +413,12 @@ static int ExecuteEntry(entry *entries, int pos) return 0; default: log_printf("File: error, user abort"); - update_status_text(LANG_STR(LANG_CANTWRITE),buf); + update_status_text(LANG_CANTWRITE,buf); return EXEC_ERROR; } } - update_status_text(LANG_STR(LANG_EXTRACT),buf4); + update_status_text(LANG_EXTRACT,buf4); ret=GetCompressedDataFromDataBlock(parms[2],hOut); log_printf3("File: wrote %d to \"%s\"",ret,buf); @@ -426,12 +432,12 @@ static int ExecuteEntry(entry *entries, int pos) { if (ret == -2) { - lstrcpy(buf,LANG_STR(LANG_ERRORWRITING)); + lstrcpy(buf,LANG_ERRORWRITING); lstrcat(buf,buf4); } else { - lstrcpy(buf,LANG_STR(LANG_ERRORDECOMPRESSING)); + lstrcpy(buf,LANG_ERRORDECOMPRESSING); } log_printf2("%s",buf); MessageBox(g_hwnd,buf,g_caption,MB_OK|MB_ICONSTOP); @@ -462,7 +468,7 @@ static int ExecuteEntry(entry *entries, int pos) if (DeleteFile(buf2)) { log_printf2("Delete: DeleteFile(\"%s\")",buf2); - update_status_text(LANG_STR(LANG_DELETEFILE),buf2); + update_status_text(LANG_DELETEFILE,buf2); } else { @@ -473,7 +479,7 @@ static int ExecuteEntry(entry *entries, int pos) exec_rebootflag++; #endif log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf2); - update_status_text(LANG_STR(LANG_DELETEONREBOOT),buf2); + update_status_text(LANG_DELETEONREBOOT,buf2); MoveFileOnReboot(buf2,NULL); } else @@ -708,7 +714,7 @@ static int ExecuteEntry(entry *entries, int pos) lstrcpy(buf4,buf); lstrcat(buf4," "); lstrcat(buf4,buf2); - update_status_text(LANG_STR(LANG_EXECSHELL), buf4); + update_status_text(LANG_EXECSHELL, buf4); x=(int)ShellExecute(g_hwnd,buf[0]?buf:NULL,buf2,buf3[0]?buf3:NULL,state_output_directory,parms[3]); if (x < 33) { @@ -728,7 +734,7 @@ static int ExecuteEntry(entry *entries, int pos) HANDLE hProc; process_string_fromtab(buf,parms[0]); log_printf2("Exec: command=\"%s\"",buf); - update_status_text(LANG_STR(LANG_EXECUTE),buf); + update_status_text(LANG_EXECUTE,buf); hProc=myCreateProcess(buf,*state_output_directory?state_output_directory:NULL); @@ -855,21 +861,21 @@ static int ExecuteEntry(entry *entries, int pos) } else { - update_status_text(LANG_STR(LANG_CANNOTFINDSYMBOL),buf2); + update_status_text(LANG_CANNOTFINDSYMBOL,buf2); log_printf3("Error registering DLL: %s not found in %s",buf2,buf); } FreeLibrary(h); } else { - update_status_text(LANG_STR(LANG_COULDNOTLOAD),buf); + update_status_text(LANG_COULDNOTLOAD,buf); log_printf2("Error registering DLL: Could not load %s",buf); } OleUninitialize(); } else { - update_status_text(LANG_STR(LANG_NOOLE),buf); + update_status_text(LANG_NOOLE,buf); log_printf("Error registering DLL: Could not initialize OLE"); } } @@ -889,11 +895,11 @@ static int ExecuteEntry(entry *entries, int pos) state_output_directory,(parms[4]&0xff00)>>8,parms[4]>>16)) { exec_errorflag++; - update_status_text(LANG_STR(LANG_ERRORCREATINGSHORTCUT),buf3); + update_status_text(LANG_ERRORCREATINGSHORTCUT,buf3); } else { - update_status_text(LANG_STR(LANG_CREATESHORTCUT),buf3); + update_status_text(LANG_CREATESHORTCUT,buf3); } return 0; #endif//NSIS_SUPPORT_CREATESHORTCUT @@ -910,7 +916,7 @@ static int ExecuteEntry(entry *entries, int pos) buf[lstrlen(buf)+1]=0; buf2[lstrlen(buf2)+1]=0; - lstrcpy(buf3,LANG_STR(LANG_COPYTO)); + lstrcpy(buf3,LANG_COPYTO); lstrcat(buf3,buf2); op.pFrom=buf; @@ -921,7 +927,7 @@ static int ExecuteEntry(entry *entries, int pos) res=SHFileOperation(&op); if (res) { // some of these changes were from Edgewise (wiked_edge@yahoo.com) - update_status_text(LANG_STR(LANG_COPYFAILED),""); + update_status_text(LANG_COPYFAILED,""); exec_errorflag++; } } @@ -1326,11 +1332,11 @@ static int ExecuteEntry(entry *entries, int pos) log_printf3("created uninstaller: %d, \"%s\"",ret,buf2); if (ret < 0) { - update_status_text(LANG_STR(LANG_ERRORCREATING),buf); + update_status_text(LANG_ERRORCREATING,buf); DeleteFile(buf2); } else - update_status_text(LANG_STR(LANG_CREATEDUNINST),buf); + update_status_text(LANG_CREATEDUNINST,buf); } return 0; #endif//NSIS_CONFIG_UNINSTALL_SUPPORT @@ -1418,6 +1424,6 @@ static int ExecuteEntry(entry *entries, int pos) return 0; #endif //NSIS_CONFIG_VISIBLE_SUPPORT } - MessageBox(g_hwnd,LANG_STR(LANG_INSTCORRUPTED),g_caption,MB_OK|MB_ICONSTOP); + MessageBox(g_hwnd,LANG_INSTCORRUPTED,g_caption,MB_OK|MB_ICONSTOP); return EXEC_ERROR; } diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index dbbd42ab..bf2f3968 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -146,24 +146,85 @@ typedef struct int length_of_all_following_data; } firstheader; +// Strings common to both installers and uninstallers +typedef struct +{ + WORD lang_id; + + // unprocessed strings + int branding; + int cancelbutton; + int showdetailsbutton; + int completed; + int closebutton; // "Close" + int name; // name of installer + + // processed strings + int caption; // name of installer + " Setup" or whatever. + int subcaptions[5]; + +#ifdef NSIS_SUPPORT_FILE + int fileerrtext; +#endif + +#if defined(NSIS_SUPPORT_DELETE) || defined(NSIS_SUPPORT_RMDIR) || defined(NSIS_SUPPORT_FILE) + int cant_write; +#endif +#ifdef NSIS_SUPPORT_RMDIR + int remove_dir; +#endif +#ifdef NSIS_SUPPORT_COPYFILES + int copy_failed; + int copy_to; +#endif +#ifdef NSIS_SUPPORT_ACTIVEXREG + int symbol_not_found; + int could_not_load; + int no_ole; + // not used anywhere - int err_reg_dll; +#endif +#ifdef NSIS_SUPPORT_CREATESHORTCUT + int create_shortcut; + int err_creating_shortcut; +#endif +#ifdef NSIS_SUPPORT_DELETE + int del_file; +#ifdef NSIS_SUPPORT_MOVEONREBOOT + int del_on_reboot; +#endif +#endif +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + int created_uninst; + int err_creating; +#endif +#ifdef NSIS_SUPPORT_SHELLEXECUTE + int exec_shell; +#endif +#ifdef NSIS_SUPPORT_EXECUTE + int exec; +#endif +#ifdef NSIS_SUPPORT_MOVEONREBOOT + int rename_on_reboot; +#endif +#ifdef NSIS_SUPPORT_RENAME + int rename; +#endif +#ifdef NSIS_SUPPORT_FILE + int extract; + int err_writing; + int err_decompressing; + int skipped; +#endif + int inst_corrupted; + int output_dir; + int create_dir; +} common_strings; + // Settings common to both installers and uninstallers typedef struct { - // unprocessed strings - int branding_ptr; - int cancelbutton_ptr; - int showdetailsbutton_ptr; - int completed_ptr; - int closebutton_ptr; // "Close" - int name_ptr; // name of installer - - // processed strings - int caption_ptr; // name of installer + " Setup" or whatever. - int subcaption_ptrs[5]; - -#ifdef NSIS_SUPPORT_FILE - int fileerrtext_ptr; -#endif + int str_tables_num; // number of strings tables in array + int str_tables; // offset to tables array int num_entries; // total number of entries @@ -191,32 +252,40 @@ typedef struct } common_header; +// Strings specific to installers +typedef struct +{ + WORD lang_id; + + // these first strings are literals (should not be encoded) + int backbutton; + int nextbutton; + int browse; // "Browse..." + int installbutton; // "Install" + int spacerequired; // "Space required: " + int spaceavailable; // "Space available: " + int custom; // Custom + int text; // directory page text + int dirsubtext; // directory text2 +#ifdef NSIS_CONFIG_COMPONENTPAGE + int componenttext; // component page text + int componentsubtext[2]; +#endif +#ifdef NSIS_CONFIG_LICENSEPAGE + int licensetext; // license page text + int licensedata; // license text + int licensebutton; // license button text +#endif//NSIS_CONFIG_LICENSEPAGE +} installer_strings; + // Settings specific to installers typedef struct { // common settings common_header common; - // these first strings are literals (should not be encoded) - int backbutton_ptr; - int nextbutton_ptr; - int browse_ptr; // "Browse..." - int installbutton_ptr; // "Install" - int spacerequired_ptr; // "Space required: " - int spaceavailable_ptr; // "Space available: " - int custom_ptr; // Custom - int text_ptr; // directory page text - int dirsubtext_ptr; // directory text2 -#ifdef NSIS_CONFIG_COMPONENTPAGE - int componenttext_ptr; // component page text - int componentsubtext_ptr[2]; -#endif -#ifdef NSIS_CONFIG_LICENSEPAGE - int licensetext_ptr; // license page text - int licensedata_ptr; // license text - int licensebutton_ptr; // license button text - int license_bg; // license background color -#endif//NSIS_CONFIG_LICENSEPAGE + int str_tables_num; // number of strings tables in array + int str_tables; // offset to tables array int install_reg_rootkey, install_reg_key_ptr, install_reg_value_ptr; @@ -224,6 +293,10 @@ typedef struct int install_types_ptr[NSIS_MAX_INST_TYPES]; // -1 if not used. can describe as lite, normal, full, etc. #endif +#ifdef NSIS_CONFIG_LICENSEPAGE + int license_bg; // license background color +#endif//NSIS_CONFIG_LICENSEPAGE + // below here, the strings are processed (can have variables etc) int install_directory_ptr; // default install dir. @@ -249,16 +322,25 @@ typedef struct } header; +// Strings specific to uninstallers +typedef struct +{ + WORD lang_id; + + // unprocessed strings + int uninstbutton; + int uninstalltext; + int uninstalltext2; +} uninstall_strings; + // Settings specific to uninstallers typedef struct { // common settings common_header common; - // unprocessed strings - int uninstbutton_ptr; - int uninstalltext_ptr; - int uninstalltext2_ptr; + int str_tables_num; // number of strings tables in array + int str_tables; // offset to tables array int code; int code_size; diff --git a/Source/exehead/lang.h b/Source/exehead/lang.h index d17bbce0..5e429921 100644 --- a/Source/exehead/lang.h +++ b/Source/exehead/lang.h @@ -21,37 +21,75 @@ #define _LANG_GENERIC_ERROR "NSIS ERROR" -#define LANG_STR(x) (x) +// Changed by Amir Szekely 3rd August 2002 +// Now supports more than one language in each installer -// instruction strings (these may someday be stored in the datablock or string table, and accessed -// via LANG_STR() -#define LANG_DELETEFILE "Delete file: " -#define LANG_DLLREGERROR "Error registering DLL" -#define LANG_REMOVEDIR "Remove directory: " -#define LANG_OUTPUTDIR "Output directory: " -#define LANG_CREATEDIR "Create directory: " -#define LANG_RENAME "Rename: " -#define LANG_RENAMEONREBOOT "Rename on reboot: " -#define LANG_SKIPPED "Skipped: " -#define LANG_CANTWRITE "Can't write: " -#define LANG_EXTRACT "Extract: " -#define LANG_ERRORWRITING "Extract: error writing to file " -#define LANG_ERRORDECOMPRESSING "Error decompressing data! Corrupted installer?" -#define LANG_DELETEONREBOOT "Delete on reboot: " -#define LANG_EXECSHELL "ExecShell: " -#define LANG_EXECUTE "Execute: " -#define LANG_CANNOTFINDSYMBOL "Could not find symbol: " -#define LANG_COULDNOTLOAD "Could not load: " -#define LANG_NOOLE "No OLE for: " -#define LANG_ERRORCREATINGSHORTCUT "Error creating shortcut: " -#define LANG_CREATESHORTCUT "Create shortcut: " -#define LANG_COPYTO "Copy to " -#define LANG_COPYFAILED "Copy failed" -#define LANG_ERRORCREATING "Error creating: " -#define LANG_CREATEDUNINST "Created uninstaller: " -#define LANG_INSTCORRUPTED "Install corrupted: invalid opcode" +// Please note that all of these define the offset not the string itself. +// To get the string it self use process_string_fromtab or GetStringFromStringTab. +#define INSTALL_STR(x) (install_strings_tables[current_lang].x) +// Installer specific strings +#define LANG_BTN_BACK GetStringFromStringTab(INSTALL_STR(backbutton)) +#define LANG_BTN_NEXT GetStringFromStringTab(INSTALL_STR(nextbutton)) +#define LANG_BTN_BROWSE GetStringFromStringTab(INSTALL_STR(browse)) +#define LANG_BTN_INSTALL GetStringFromStringTab(INSTALL_STR(installbutton)) +#define LANG_SPACE_REQ GetStringFromStringTab(INSTALL_STR(spacerequired)) +#define LANG_SPACE_AVAIL GetStringFromStringTab(INSTALL_STR(spaceavailable)) +#define LANG_COMP_CUSTOM GetStringFromStringTab(INSTALL_STR(custom)) +#define LANG_DIR_TEXT GetStringFromStringTab(INSTALL_STR(text)) +#define LANG_DIR_SUBTEXT GetStringFromStringTab(INSTALL_STR(dirsubtext)) +#define LANG_COMP_TEXT GetStringFromStringTab(INSTALL_STR(componenttext)) +#define LANG_COMP_SUBTEXT(x) GetStringFromStringTab(INSTALL_STR(componentsubtext[x])) +#define LANG_LICENSE_TEXT GetStringFromStringTab(INSTALL_STR(licensetext)) +#define LANG_LICENSE_DATA GetStringFromStringTab(INSTALL_STR(licensedata)) +#define LANG_BTN_LICENSE GetStringFromStringTab(INSTALL_STR(licensebutton)) +#define UNINSTALL_STR(x) (uninstall_strings_tables[current_lang].x) + +// Uninstall specific strings +#define LANG_BTN_UNINST GetStringFromStringTab(UNINSTALL_STR(uninstbutton)) +#define LANG_UNINST_TEXT GetStringFromStringTab(UNINSTALL_STR(uninstalltext)) +#define LANG_UNINST_SUBTEXT GetStringFromStringTab(UNINSTALL_STR(uninstalltext2)) + +#define COMMON_STR(x) (common_strings_tables[current_lang].x) + +// Common strings +#define LANG_BRANDING GetStringFromStringTab(COMMON_STR(branding)) +#define LANG_BTN_CANCEL GetStringFromStringTab(COMMON_STR(cancelbutton)) +#define LANG_BTN_DETAILS GetStringFromStringTab(COMMON_STR(showdetailsbutton)) +#define LANG_COMPLETED GetStringFromStringTab(COMMON_STR(completed)) +#define LANG_BTN_CLOSE GetStringFromStringTab(COMMON_STR(closebutton)) +#define LANG_NAME GetStringFromStringTab(COMMON_STR(name)) +#define LANG_CAPTION GetStringFromStringTab(COMMON_STR(caption)) +#define LANG_SUBCAPTION(x) GetStringFromStringTab(COMMON_STR(subcaptions[x])) + +// instruction strings +#define LANG_FILEERR GetStringFromStringTab(COMMON_STR(fileerrtext)) +#define LANG_DELETEFILE GetStringFromStringTab(COMMON_STR(del_file)) +#define LANG_DLLREGERROR GetStringFromStringTab(COMMON_STR(err_reg_dll)) +#define LANG_REMOVEDIR GetStringFromStringTab(COMMON_STR(remove_dir)) +#define LANG_OUTPUTDIR GetStringFromStringTab(COMMON_STR(output_dir)) +#define LANG_CREATEDIR GetStringFromStringTab(COMMON_STR(create_dir)) +#define LANG_RENAME GetStringFromStringTab(COMMON_STR(rename)) +#define LANG_RENAMEONREBOOT GetStringFromStringTab(COMMON_STR(rename_on_reboot)) +#define LANG_SKIPPED GetStringFromStringTab(COMMON_STR(skipped)) +#define LANG_CANTWRITE GetStringFromStringTab(COMMON_STR(cant_write)) +#define LANG_EXTRACT GetStringFromStringTab(COMMON_STR(extract)) +#define LANG_ERRORWRITING GetStringFromStringTab(COMMON_STR(err_writing)) +#define LANG_ERRORDECOMPRESSING GetStringFromStringTab(COMMON_STR(err_decompressing)) +#define LANG_DELETEONREBOOT GetStringFromStringTab(COMMON_STR(del_on_reboot)) +#define LANG_EXECSHELL GetStringFromStringTab(COMMON_STR(exec_shell)) +#define LANG_EXECUTE GetStringFromStringTab(COMMON_STR(exec)) +#define LANG_CANNOTFINDSYMBOL GetStringFromStringTab(COMMON_STR(symbol_not_found)) +#define LANG_COULDNOTLOAD GetStringFromStringTab(COMMON_STR(could_not_load)) +#define LANG_NOOLE GetStringFromStringTab(COMMON_STR(no_ole)) +#define LANG_ERRORCREATINGSHORTCUT GetStringFromStringTab(COMMON_STR(err_creating_shortcut)) +#define LANG_CREATESHORTCUT GetStringFromStringTab(COMMON_STR(create_shortcut)) +#define LANG_COPYTO GetStringFromStringTab(COMMON_STR(copy_to)) +#define LANG_COPYFAILED GetStringFromStringTab(COMMON_STR(copy_failed)) +#define LANG_ERRORCREATING GetStringFromStringTab(COMMON_STR(err_creating)) +#define LANG_CREATEDUNINST GetStringFromStringTab(COMMON_STR(created_uninst)) +#define LANG_INSTCORRUPTED GetStringFromStringTab(COMMON_STR(inst_corrupted)) #endif//_NSIS_LANG_H_ \ No newline at end of file diff --git a/Source/lang.cpp b/Source/lang.cpp new file mode 100644 index 00000000..7f365a1d --- /dev/null +++ b/Source/lang.cpp @@ -0,0 +1,524 @@ +// Lang.cpp by Amir Szekely 3rd August 2002 + +#include +#include +#include +#include "build.h" + +extern const char *NSIS_VERSION; + +extern char *english_strings[] = { + "Nullsoft Install System %s", + "%s Setup", + "%s Uninstall", + ": License Agreement", + ": Installation Options", + ": Installation Directory", + ": Installing Files", + ": Completed", + ": Confirmation", + ": Uninstalling Files", + ": Completed", + "< Back", + "Next >", + "I Agree", + "Install", + "Uninstall", + "Cancel", + "Close", + "Browse...", + "Show details", + "Name", + "Completed", + "Custom", + "Select the type of install:", + "Select components to install:", + "Or, select the optional components you wish to install:", + "Select the directory to install %s in:", + "Space available: ", + "Space required: ", + "Uninstalling from:", + "Error opening file for writing: \r\n\t\"$0\"\r\nHit abort to abort installation,\r\nretry to retry writing the file, or\r\nignore to skip this file", + "Can't write: ", + "Copy failed", + "Copy to ", + "Could not find symbol: ", + "Could not load: ", + "Create directory: ", + "Create shortcut: ", + "Created uninstaller: ", + "Delete file:", + "Delete on reboot: ", + "Error creating shortcut: ", + "Error creating: ", + "Error decompressing data! Corrupted installer?", + "Error registering DLL", + "ExecShell: ", + "Execute: ", + "Extract: ", + "Extract: error writing to file ", + "Install corrupted: invalid opcode", + "No OLE for: ", + "Output directory: ", + "Remove directory: ", + "Rename on reboot: ", + "Rename: ", + "Skipped: " +}; + +int CEXEBuild::SetString(char *string, int id, int process, WORD lang/*=0*/) { + if (!lang) lang = build_nlfs.size()?build_nlfs[0]->GetLang():1033; // Default is English (1033) + StringTable *table = 0; + for (int i = 0; i < string_tables.size(); i++) { + if (lang == string_tables[i]->lang_id) { + table = string_tables[i]; + break; + } + } + if (!table) { + table = (StringTable*)malloc(sizeof(StringTable)); + if (!table) { + ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",sizeof(StringTable)); + return PS_ERROR; + } + memset(table, -1, sizeof(StringTable)); + table->lang_id = table->ucommon.lang_id = table->installer.lang_id = table->uninstall.lang_id = lang; + string_tables.push_back(table); + } + + return SetString(string, id, process, table); +} + +int CEXEBuild::SetString(char *string, int id, int process, StringTable *table) { + int *str = 0; + int *ustr = 0; + #define HANDLE_STRING_C(id,strname) case id: str=&(table->strname); ustr=&(table->u##strname); break; + #define HANDLE_STRING_I(id,strname) case id: str=&(table->strname); break; + #define HANDLE_STRING_U(id,strname) case id: ustr=&(table->strname); break; + switch (id) { + HANDLE_STRING_C(NLF_BRANDING, common.branding); + HANDLE_STRING_C(NLF_BTN_CANCEL, common.cancelbutton); + HANDLE_STRING_C(NLF_BTN_CLOSE, common.closebutton); + HANDLE_STRING_C(NLF_BTN_DETAILS, common.showdetailsbutton); + HANDLE_STRING_C(NLF_COMPLETED, common.completed); + HANDLE_STRING_C(NLF_FILE_ERROR, common.fileerrtext); + + HANDLE_STRING_I(NLF_CAPTION, common.caption); + HANDLE_STRING_I(NLF_SUBCAPTION_LICENSE, common.subcaptions[0]); + HANDLE_STRING_I(NLF_SUBCAPTION_OPTIONS, common.subcaptions[1]); + HANDLE_STRING_I(NLF_SUBCAPTION_DIR, common.subcaptions[2]); + HANDLE_STRING_I(NLF_SUBCAPTION_INSTFILES, common.subcaptions[3]); + HANDLE_STRING_I(NLF_SUBCAPTION_COMPLETED, common.subcaptions[4]); + HANDLE_STRING_I(NLF_BTN_NEXT, installer.nextbutton); + HANDLE_STRING_I(NLF_BTN_BACK, installer.backbutton); + HANDLE_STRING_I(NLF_BTN_LICENSE, installer.licensebutton); + HANDLE_STRING_I(NLF_BTN_INSTALL, installer.installbutton); + HANDLE_STRING_I(NLF_BTN_BROWSE, installer.browse); + HANDLE_STRING_I(NLF_COMP_SUBTEXT1, installer.componentsubtext[0]); + HANDLE_STRING_I(NLF_COMP_SUBTEXT2, installer.componentsubtext[1]); + HANDLE_STRING_I(NLF_DIR_SUBTEXT, installer.dirsubtext); + HANDLE_STRING_I(NLF_SPACE_AVAIL, installer.spaceavailable); + HANDLE_STRING_I(NLF_SPACE_REQ, installer.spacerequired); + + HANDLE_STRING_U(NLF_UCAPTION, ucommon.caption); + HANDLE_STRING_U(NLF_USUBCAPTION_CONFIRM, ucommon.subcaptions[0]); + HANDLE_STRING_U(NLF_USUBCAPTION_INSTFILES, ucommon.subcaptions[1]); + HANDLE_STRING_U(NLF_USUBCAPTION_COMPLETED, ucommon.subcaptions[2]); + HANDLE_STRING_U(NLF_BTN_UNINSTALL, uninstall.uninstbutton); + HANDLE_STRING_U(NLF_UNINST_SUBTEXT, uninstall.uninstalltext2); + + HANDLE_STRING_C(LANG_NAME, common.name); + + HANDLE_STRING_I(LANG_COMP_TEXT, installer.componenttext); + HANDLE_STRING_I(LANG_LICENSE_TEXT, installer.licensetext); + HANDLE_STRING_I(LANG_LICENSE_DATA, installer.licensedata); + HANDLE_STRING_I(LANG_DIR_TEXT, installer.text); + + HANDLE_STRING_U(LANG_UNINST_TEXT, uninstall.uninstalltext); + + default: + ERROR_MSG("Error: string doesn't exist or is not changeable (%d)\n", id); + return PS_ERROR; + } + + if (str) *str = add_string_main(string,process); +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (ustr) *ustr = add_string_uninst(string,process); +#endif + + return PS_OK; +} + +int CEXEBuild::WriteStringTables() { + StringTable *table = 0; + int i; + // Set strings that are unsetable from the script and make sure each NLF has a string table + for (i = 0; i < build_nlfs.size(); i++) { + table = 0; + for (int j = 0; j < string_tables.size(); j++) { + if (build_nlfs[i]->GetLang() == string_tables[j]->lang_id) { + table = string_tables[j]; + break; + } + } + if (!table) { + table = (StringTable*)malloc(sizeof(StringTable)); + if (!table) { + ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",sizeof(StringTable)); + return PS_ERROR; + } + memset(table, -1, sizeof(StringTable)); + table->lang_id=table->ucommon.lang_id=table->installer.lang_id=table->uninstall.lang_id=build_nlfs[i]->GetLang(); + string_tables.push_back(table); + } + // Now that we have a table, fill it! + FillDefaultsIfNeeded(table, build_nlfs[i]); + } + + if (!build_nlfs.size()) { + if (string_tables.size() == 0) { + build_header.str_tables_num = 1; + table = (StringTable*)malloc(sizeof(StringTable)); + if (!table) { + ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",sizeof(StringTable)); + return PS_ERROR; + } + memset(table, -1, sizeof(StringTable)); + table->lang_id=table->ucommon.lang_id=table->installer.lang_id=table->uninstall.lang_id=1033; + string_tables.push_back(table); + // Now that we have a table, fill it! + } + else table = string_tables[0]; + FillDefaultsIfNeeded(table); + } + + // If no NLFs and no user set strings, use defaults only + if (string_tables.size() == 0) { + build_header.str_tables_num = 1; + table = (StringTable*)malloc(sizeof(StringTable)); + if (!table) { + ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n",sizeof(StringTable)); + return PS_ERROR; + } + memset(table, -1, sizeof(StringTable)); + table->lang_id=table->ucommon.lang_id=table->installer.lang_id=table->uninstall.lang_id=1033; // Default is English + string_tables.push_back(table); + // Now that we have a table, fill it! + FillDefaultsIfNeeded(table); + } + + // Add string tables into datablock + + build_header.str_tables_num = string_tables.size(); + build_header.str_tables = add_data((char*)&string_tables[0]->installer, sizeof(installer_strings), &build_datablock); + for (i = 1; i < string_tables.size(); i++) + add_data((char*)&string_tables[i]->installer, sizeof(installer_strings), &build_datablock); + + build_header.common.str_tables_num = string_tables.size(); + build_header.common.str_tables = add_data((char*)&string_tables[0]->common, sizeof(common_strings), &build_datablock); + for (i = 1; i < string_tables.size(); i++) + add_data((char*)&string_tables[i]->common, sizeof(common_strings), &build_datablock); + + build_uninst.str_tables_num = string_tables.size(); + build_uninst.str_tables = add_data((char*)&string_tables[0]->uninstall, sizeof(uninstall_strings), &ubuild_datablock); + for (i = 1; i < string_tables.size(); i++) + add_data((char*)&string_tables[i]->uninstall, sizeof(uninstall_strings), &ubuild_datablock); + + build_uninst.common.str_tables_num = string_tables.size(); + build_uninst.common.str_tables = add_data((char*)&string_tables[0]->ucommon, sizeof(common_strings), &ubuild_datablock); + for (i = 1; i < string_tables.size(); i++) + add_data((char*)&string_tables[i]->ucommon, sizeof(common_strings), &ubuild_datablock); + + return PS_OK; +} + +void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { +#define str(id) (nlf?nlf->GetString(id):english_strings[id]) + +#ifdef NSIS_CONFIG_COMPONENTPAGE + // if component page, do component strings: + if (table->installer.componenttext>=0) + { + int x; + int iscp=0; + for (x = 1; x < build_header.num_sections&&!iscp; x ++) + { + char c=build_strlist.get()[((section*)build_sections.get())[x].name_ptr]; + if (c && c != '-') iscp++; + } + if (iscp) + { + if (table->installer.custom<0) table->installer.custom=add_string_main(str(NLF_COMP_CUSTOM),0); + if (table->common.subcaptions[1]<0) + table->common.subcaptions[1]=add_string_main(str(NLF_SUBCAPTION_OPTIONS),0); + + if (build_header.install_types_ptr[0] < 0) + { + if (table->installer.componentsubtext[1]<0) + table->installer.componentsubtext[1]=add_string_main(str(NLF_COMP_SUBTEXT1_NO_INST_TYPES),0); + } + else + { + if (table->installer.componentsubtext[0]<0) + table->installer.componentsubtext[0]=add_string_main(str(NLF_COMP_SUBTEXT1),0); + if (build_header.no_custom_instmode_flag!=1 && table->installer.componentsubtext[1]<0) + table->installer.componentsubtext[1]=add_string_main(str(NLF_COMP_SUBTEXT2),0); + } + } + else table->installer.componenttext=-1; + } +#endif + + static bool nameWarned = false; + if (table->common.name < 0) + { + if (!nameWarned) { + warning("Name command not specified. Assuming default."); + nameWarned = true; + } + table->common.name=add_string_main(str(NLF_DEF_NAME),0); + table->ucommon.name=add_string_uninst(str(NLF_DEF_NAME),0); + } + +#ifdef NSIS_CONFIG_LICENSEPAGE + if (table->installer.licensedata<0 || table->installer.licensetext<0) + { + table->installer.licensedata=-1; + table->installer.licensetext=-1; + } + + if (table->installer.licensedata>=0) + { + if (table->common.subcaptions[0]<0) + table->common.subcaptions[0]=add_string_main(str(NLF_SUBCAPTION_LICENSE),0); + if (table->installer.licensebutton<0) + table->installer.licensebutton=add_string_main(str(NLF_BTN_LICENSE),0); + } +#endif //NSIS_CONFIG_LICENSEPAGE + + if (table->installer.text >= 0) + { + if (table->installer.dirsubtext<0) + { + char buf[2048]; + wsprintf(buf,str(NLF_DIR_SUBTEXT),build_strlist.get()+table->common.name); + table->installer.dirsubtext=add_string_main(buf,0); + } + if (table->common.subcaptions[2]<0) + table->common.subcaptions[2]=add_string_main(str(NLF_SUBCAPTION_DIR),0); + if (table->installer.browse<0) table->installer.browse=add_string_main(str(NLF_BTN_BROWSE),0); + if (table->installer.spaceavailable<0 && !no_space_texts) table->installer.spaceavailable=add_string_main(str(NLF_SPACE_REQ),0); + } + + if (table->installer.text >= 0 +#ifdef NSIS_CONFIG_COMPONENTPAGE + || table->installer.componenttext>=0 +#endif + ) + { + // Changed by Amir Szekely 22nd July 2002 + // Adds the ability to disable space texts + if (table->installer.spacerequired<0 && !no_space_texts) table->installer.spacerequired=add_string_main(str(NLF_SPACE_AVAIL),0); + if (table->installer.nextbutton<0) table->installer.nextbutton=add_string_main(str(NLF_BTN_NEXT),0); + if (table->installer.installbutton<0) table->installer.installbutton=add_string_main(str(NLF_BTN_INSTALL),0); + } + + if (table->common.subcaptions[3]<0) + table->common.subcaptions[3]=add_string_main(str(NLF_SUBCAPTION_INSTFILES),0); + if (table->common.subcaptions[4]<0) + table->common.subcaptions[4]=add_string_main(str(NLF_USUBCAPTION_COMPLETED),0); + + if (table->common.branding<0) + { + char buf[256]; + wsprintf(buf,str(NLF_BRANDING),NSIS_VERSION); + table->common.branding=add_string_main(buf,0); + } + if (table->installer.backbutton<0) table->installer.backbutton=add_string_main(str(NLF_BTN_BACK),0); + if (table->common.cancelbutton<0) table->common.cancelbutton=add_string_main(str(NLF_BTN_CANCEL),0); + if (table->common.showdetailsbutton<0) table->common.showdetailsbutton=add_string_main(str(NLF_BTN_DETAILS),0); + + if (table->common.closebutton<0) table->common.closebutton=add_string_main(str(NLF_BTN_CLOSE),0); + if (table->common.completed<0) table->common.completed=add_string_main(str(NLF_COMPLETED),0); +#ifdef NSIS_SUPPORT_FILE + if (m_inst_fileused && table->common.fileerrtext<0) + { + table->common.fileerrtext=add_string_main(str(NLF_FILE_ERROR)); + } +#endif + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + if (ubuild_entries.getlen()) + { + if (uninstaller_writes_used) { + if (table->uninstall.uninstalltext2<0) + table->uninstall.uninstalltext2=add_string_uninst(str(NLF_UNINST_SUBTEXT),0); + if (table->ucommon.subcaptions[0]<0) + table->ucommon.subcaptions[0]=add_string_uninst(str(NLF_USUBCAPTION_CONFIRM),0); + if (table->ucommon.subcaptions[1]<0) + table->ucommon.subcaptions[1]=add_string_uninst(str(NLF_USUBCAPTION_INSTFILES),0); + if (table->ucommon.subcaptions[2]<0) + table->ucommon.subcaptions[2]=add_string_uninst(str(NLF_USUBCAPTION_COMPLETED),0); + if (table->ucommon.caption < 0) + { + char buf[1024]; + wsprintf(buf,str(NLF_UCAPTION),ubuild_strlist.get()+table->ucommon.name); + table->ucommon.caption=add_string_uninst(buf,0); + } + table->ucommon.branding=add_string_uninst(build_strlist.get() + table->common.branding,0); + table->ucommon.cancelbutton=add_string_uninst(build_strlist.get() + table->common.cancelbutton,0); + table->ucommon.showdetailsbutton=add_string_uninst(build_strlist.get() + table->common.showdetailsbutton,0); + table->ucommon.closebutton=add_string_uninst(build_strlist.get() + table->common.closebutton,0); + table->ucommon.completed=add_string_uninst(build_strlist.get() + table->common.completed,0); + + if (table->uninstall.uninstbutton<0) table->uninstall.uninstbutton=add_string_uninst(str(NLF_BTN_UNINSTALL),0); + } + } + +#ifdef NSIS_SUPPORT_FILE + if (m_uninst_fileused && table->ucommon.fileerrtext<0) + { + table->ucommon.fileerrtext=add_string_uninst(build_strlist.get() + table->common.fileerrtext,0); + } +#endif + +#endif + + if (table->common.caption < 0) + { + char buf[1024]; + wsprintf(buf,str(NLF_CAPTION),build_strlist.get()+table->common.name); + table->common.caption=add_string_main(buf,0); + } + +#define SET_INSTRUCTION(id,s) table->common.s=add_string_main(str(id),0);table->ucommon.s=add_string_uninst(str(id),0) +#if defined(NSIS_SUPPORT_DELETE) || defined(NSIS_SUPPORT_RMDIR) || defined(NSIS_SUPPORT_FILE) + SET_INSTRUCTION(NLF_CANT_WRITE, cant_write); +#endif +#ifdef NSIS_SUPPORT_RMDIR + SET_INSTRUCTION(NLF_REMOVE_DIR, remove_dir); +#endif +#ifdef NSIS_SUPPORT_COPYFILES + SET_INSTRUCTION(NLF_COPY_FAILED, copy_failed); + SET_INSTRUCTION(NLF_COPY_TO, copy_to); +#endif +#ifdef NSIS_SUPPORT_ACTIVEXREG + SET_INSTRUCTION(NLF_SYMBOL_NOT_FOUND, symbol_not_found); + SET_INSTRUCTION(NLF_COULD_NOT_LOAD, could_not_load); + SET_INSTRUCTION(NLF_NO_OLE, no_ole); + // not used anywhere - SET_INSTRUCTION(NLF_ERR_REG_DLL, err_reg_dll); +#endif +#ifdef NSIS_SUPPORT_CREATESHORTCUT + SET_INSTRUCTION(NLF_CREATE_SHORTCUT, create_shortcut); + SET_INSTRUCTION(NLF_ERR_CREATING_SHORTCUT, err_creating_shortcut); +#endif +#ifdef NSIS_SUPPORT_DELETE + SET_INSTRUCTION(NLF_DEL_FILE, del_file); +#ifdef NSIS_SUPPORT_MOVEONREBOOT + SET_INSTRUCTION(NLF_DEL_ON_REBOOT, del_on_reboot); +#endif +#endif +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT + SET_INSTRUCTION(NLF_CREATED_UNINST, created_uninst); + SET_INSTRUCTION(NLF_ERR_CREATING, err_creating); +#endif +#ifdef NSIS_SUPPORT_SHELLEXECUTE + SET_INSTRUCTION(NLF_EXEC_SHELL, exec_shell); +#endif +#ifdef NSIS_SUPPORT_EXECUTE + SET_INSTRUCTION(NLF_EXEC, exec); +#endif +#ifdef NSIS_SUPPORT_MOVEONREBOOT + SET_INSTRUCTION(NLF_RENAME_ON_REBOOT, rename_on_reboot); +#endif +#ifdef NSIS_SUPPORT_RENAME + SET_INSTRUCTION(NLF_RENAME, rename); +#endif +#ifdef NSIS_SUPPORT_FILE + SET_INSTRUCTION(NLF_EXTRACT, extract); + SET_INSTRUCTION(NLF_ERR_WRITING, err_writing); + SET_INSTRUCTION(NLF_ERR_DECOMPRESSING, err_decompressing); + SET_INSTRUCTION(NLF_SKIPPED, skipped); +#endif + SET_INSTRUCTION(NLF_INST_CORRUPTED, inst_corrupted); + SET_INSTRUCTION(NLF_OUTPUT_DIR, output_dir); + SET_INSTRUCTION(NLF_CREATE_DIR, create_dir); +} + +bool CEXEBuild::_IsNotSet(int *str) { + if (!str) return true; + for (int i = 0; i < string_tables.size(); i++) { + if (*(int*)((char*)str+sizeof(StringTable)*i) >= 0) { + return false; + } + } + return true; +} + +char SkipComments(FILE *f) { + char c; + while (c = fgetc(f)) { + while (c == '\n' || c == '\r') { + c = fgetc(f); // Skip empty lines + } + if (c == '#' || c == ';') { + while (c = fgetc(f)) { + if (c == '\n') break; + } + } + else break; + } + return c; +} + +// NSIS Language File parser +NLF::NLF(char *filename) { + FILE *f = fopen(filename, "r"); + if (!f) throw runtime_error("Can't open language file!"); + + char buf[1024]; + buf[0] = SkipComments(f); + fgets(buf+1, 1024, f); + + // Check header + if (strncmp(buf, "NLF v", 5)) throw runtime_error("Invalid language file!"); + if (atoi(buf+5) != NLF_VERSION) throw runtime_error("Language file version doesn't match NSIS version!"); + + // Get language ID + buf[0] = SkipComments(f); + fgets(buf+1, 1024, f); + m_wLangId = atoi(buf); + + // Read strings + for (int i = 0; i < NLF_STRINGS; i++) { + buf[0] = SkipComments(f); + fgets(buf+1, 1024, f); + if (lstrlen(buf) == 1023) { + wsprintf(buf, "String too long (string #%d)!", i); + throw runtime_error(buf); + } + while (buf[lstrlen(buf)-1] == '\n' || buf[lstrlen(buf)-1] == '\r') { + buf[lstrlen(buf)-1] = 0; + } + m_szStrings[i] = new char[lstrlen(buf)+1]; + lstrcpy(m_szStrings[i], buf); + } + + fclose(f); +} + +NLF::~NLF() { + MessageBox(0, "destructor", "info", MB_OK); + for (int i = 0; i < NLF_STRINGS; i++) { + delete [] m_szStrings[i]; + } +} + +WORD NLF::GetLang() { + return m_wLangId; +} + +char* NLF::GetString(int idx) { + if (idx < 0 || idx >= NLF_STRINGS) return 0; + return m_szStrings[idx]; +} \ No newline at end of file diff --git a/Source/lang.h b/Source/lang.h new file mode 100644 index 00000000..672f4093 --- /dev/null +++ b/Source/lang.h @@ -0,0 +1,103 @@ +// Lang.h by Amir Szekely 3rd August 2002 + +#ifndef ___NLF___H_____ +#define ___NLF___H_____ + +#include "exehead/fileform.h" +#include +using namespace std; + +struct StringTable { + union { + WORD lang_id; + common_strings common; + }; + common_strings ucommon; + installer_strings installer; + uninstall_strings uninstall; +}; + +#define NLF_VERSION 1 +#define NLF_STRINGS 56 + +#define NLF_BRANDING 0 +#define NLF_CAPTION 1 +#define NLF_UCAPTION 2 +#define NLF_SUBCAPTION_LICENSE 3 +#define NLF_SUBCAPTION_OPTIONS 4 +#define NLF_SUBCAPTION_DIR 5 +#define NLF_SUBCAPTION_INSTFILES 6 +#define NLF_SUBCAPTION_COMPLETED 7 +#define NLF_USUBCAPTION_CONFIRM 8 +#define NLF_USUBCAPTION_INSTFILES 9 +#define NLF_USUBCAPTION_COMPLETED 10 +#define NLF_BTN_BACK 11 +#define NLF_BTN_NEXT 12 +#define NLF_BTN_LICENSE 13 +#define NLF_BTN_INSTALL 14 +#define NLF_BTN_UNINSTALL 15 +#define NLF_BTN_CANCEL 16 +#define NLF_BTN_CLOSE 17 +#define NLF_BTN_BROWSE 18 +#define NLF_BTN_DETAILS 19 +#define NLF_DEF_NAME 20 +#define NLF_COMPLETED 21 +#define NLF_COMP_CUSTOM 22 +#define NLF_COMP_SUBTEXT1_NO_INST_TYPES 23 +#define NLF_COMP_SUBTEXT1 24 +#define NLF_COMP_SUBTEXT2 25 +#define NLF_DIR_SUBTEXT 26 +#define NLF_SPACE_AVAIL 27 +#define NLF_SPACE_REQ 28 +#define NLF_UNINST_SUBTEXT 29 +#define NLF_FILE_ERROR 30 +#define NLF_CANT_WRITE 31 +#define NLF_COPY_FAILED 32 +#define NLF_COPY_TO 33 +#define NLF_SYMBOL_NOT_FOUND 34 +#define NLF_COULD_NOT_LOAD 35 +#define NLF_CREATE_DIR 36 +#define NLF_CREATE_SHORTCUT 37 +#define NLF_CREATED_UNINST 38 +#define NLF_DEL_FILE 39 +#define NLF_DEL_ON_REBOOT 40 +#define NLF_ERR_CREATING_SHORTCUT 41 +#define NLF_ERR_CREATING 42 +#define NLF_ERR_DECOMPRESSING 43 +#define NLF_ERR_REG_DLL 44 +#define NLF_EXEC_SHELL 45 +#define NLF_EXEC 46 +#define NLF_EXTRACT 47 +#define NLF_ERR_WRITING 48 +#define NLF_INST_CORRUPTED 49 +#define NLF_NO_OLE 50 +#define NLF_OUTPUT_DIR 51 +#define NLF_REMOVE_DIR 52 +#define NLF_RENAME_ON_REBOOT 53 +#define NLF_RENAME 54 +#define NLF_SKIPPED 55 + +#define LANG_NAME 56 +#define LANG_COMP_TEXT 57 +#define LANG_LICENSE_TEXT 58 +#define LANG_LICENSE_DATA 59 +#define LANG_DIR_TEXT 60 +#define LANG_UNINST_TEXT 61 + +extern char *english_strings[NLF_STRINGS]; + +// NSIS Language File parser +class NLF { + public: + NLF(char *filename); + ~NLF(); + + WORD GetLang(); + char* GetString(int idx); + + private: + WORD m_wLangId; + char *m_szStrings[NLF_STRINGS]; +}; + +#endif \ No newline at end of file diff --git a/Source/makenssi.dsp b/Source/makenssi.dsp index 1597ffd9..8976889a 100644 --- a/Source/makenssi.dsp +++ b/Source/makenssi.dsp @@ -152,6 +152,10 @@ SOURCE=.\exedata.cpp # End Source File # Begin Source File +SOURCE=.\lang.cpp +# End Source File +# Begin Source File + SOURCE=.\makenssi.cpp # ADD CPP /G6 # End Source File @@ -204,6 +208,10 @@ SOURCE=.\exedata.h # End Source File # Begin Source File +SOURCE=.\lang.h +# End Source File +# Begin Source File + SOURCE=.\lineparse.h # End Source File # Begin Source File diff --git a/Source/script.cpp b/Source/script.cpp index 90395ba0..25543a23 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -8,7 +8,7 @@ #include "ResourceEditor.h" #include "DialogTemplate.h" #include "exehead/resource.h" -#include "nlf.h" +#include "lang.h" #ifndef FOF_NOERRORUI #define FOF_NOERRORUI 0x0400 @@ -517,22 +517,19 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char // header flags /////////////////////////////////////////////////////////////////////////////// case TOK_NAME: - if (build_header.common.name_ptr >= 0) + if (!IsNotSet(common.name)) { warning("Name: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } - build_header.common.name_ptr=add_string_main(line.gettoken_str(1),0); -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - build_uninst.common.name_ptr=add_string_uninst(line.gettoken_str(1),0); -#endif + SetString(line.gettoken_str(1),LANG_NAME,0); SCRIPT_MSG("Name: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_CAPTION: - if (build_header.common.caption_ptr >= 0) + if (!IsNotSet(common.caption)) { warning("Caption: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } - build_header.common.caption_ptr=add_string_main(line.gettoken_str(1)); + SetString(line.gettoken_str(1),NLF_CAPTION,1); SCRIPT_MSG("Caption: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_ICON: @@ -578,24 +575,24 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char return PS_ERROR; #endif//!NSIS_CONFIG_COMPONENTPAGE case TOK_DIRTEXT: - if (build_header.text_ptr >= 0 && line.gettoken_str(1)[0]) + if (!IsNotSet(installer.text) && line.gettoken_str(1)[0]) { warning("DirText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } - build_header.text_ptr=add_string_main(line.gettoken_str(1),0); - if (line.getnumtokens()>2) build_header.dirsubtext_ptr=add_string_main(line.gettoken_str(2),0); - if (line.getnumtokens()>3) build_header.browse_ptr=add_string_main(line.gettoken_str(3),0); + SetString(line.gettoken_str(1),LANG_DIR_TEXT,0); + if (line.getnumtokens()>2) SetString(line.gettoken_str(2),NLF_DIR_SUBTEXT,0); + if (line.getnumtokens()>3) SetString(line.gettoken_str(3),NLF_BTN_BROWSE,0); SCRIPT_MSG("DirText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); #ifdef NSIS_CONFIG_COMPONENTPAGE case TOK_COMPTEXT: - if (build_header.componenttext_ptr >= 0 && line.gettoken_str(1)[0]) + if (!IsNotSet(installer.componenttext) && line.gettoken_str(1)[0]) { warning("ComponentText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } - build_header.componenttext_ptr=add_string_main(line.gettoken_str(1),0); - if (line.getnumtokens()>2) build_header.componentsubtext_ptr[0]=add_string_main(line.gettoken_str(2),0); - if (line.getnumtokens()>3) build_header.componentsubtext_ptr[1]=add_string_main(line.gettoken_str(3),0); + SetString(line.gettoken_str(1),LANG_COMP_TEXT,0); + if (line.getnumtokens()>2) SetString(line.gettoken_str(2),NLF_COMP_SUBTEXT1,0); + if (line.getnumtokens()>3) SetString(line.gettoken_str(3),NLF_COMP_SUBTEXT2,0); SCRIPT_MSG("ComponentText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_INSTTYPE: @@ -613,7 +610,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char } else if (!strnicmp(line.gettoken_str(1),"/CUSTOMSTRING=",14)) { - build_header.custom_ptr=add_string_main(line.gettoken_str(1)+14,0); + SetString(line.gettoken_str(1)+14,NLF_COMP_CUSTOM,0); SCRIPT_MSG("InstType: setting custom text to: \"%s\"\n",line.gettoken_str(1)+14); } else if (line.gettoken_str(1)[0]=='/') PRINTHELP() @@ -641,16 +638,16 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char #endif//!NSIS_CONFIG_COMPONENTPAGE #ifdef NSIS_CONFIG_LICENSEPAGE case TOK_LICENSETEXT: - if (build_header.licensetext_ptr >= 0) + if (!IsNotSet(installer.licensetext)) { warning("LicenseText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } - build_header.licensetext_ptr=add_string_main(line.gettoken_str(1),0); - if (line.getnumtokens()>2) build_header.licensebutton_ptr=add_string_main(line.gettoken_str(2),0); + SetString(line.gettoken_str(1),LANG_LICENSE_TEXT,0); + if (line.getnumtokens()>2) SetString(line.gettoken_str(2),NLF_BTN_LICENSE,0); SCRIPT_MSG("LicenseText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_LICENSEDATA: - if (build_header.licensedata_ptr != -1) + if (!IsNotSet(installer.licensedata)) { warning("LicenseData: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } @@ -680,7 +677,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char } fclose(fp); data[datalen]=0; - build_header.licensedata_ptr=add_string_main(data,0); + SetString(data,LANG_LICENSE_DATA,0); SCRIPT_MSG("LicenseData: \"%s\"\n",line.gettoken_str(1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -713,7 +710,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char #endif//NSIS_CONFIG_LOG SCRIPT_MSG("SilentInstall: %s\n",line.gettoken_str(1)); #ifdef NSIS_CONFIG_LICENSEPAGE - if (build_header.common.silent_install && build_header.licensedata_ptr != -1) + if (build_header.common.silent_install && !IsNotSet(installer.licensedata)) { warning("SilentInstall: LicenseData already specified. wasting space (%s:%d)",curfilename,linecnt); } @@ -1217,12 +1214,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char SCRIPT_MSG("LoadLanguageFile: %s\n", line.gettoken_str(1)); try { NLF *newLang = new NLF(line.gettoken_str(1)); - for (int i = 0; i < build_langs.size(); i++) - if (build_langs[i]->GetLang() == newLang->GetLang()) { + for (int i = 0; i < build_nlfs.size(); i++) + if (build_nlfs[i]->GetLang() == newLang->GetLang()) { ERROR_MSG("Error: Can't add same language twice!\n"); return PS_ERROR; } - build_langs.push_back(newLang); + build_nlfs.push_back(newLang); } catch (exception &err) { ERROR_MSG("Error while adding language file: %s", err.what()); @@ -1346,11 +1343,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT case TOK_UNINSTCAPTION: - if (build_uninst.common.caption_ptr >= 0) + if (!IsNotSet(ucommon.caption)) { warning("UninstCaption: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } - build_uninst.common.caption_ptr=add_string_uninst(line.gettoken_str(1)); + SetString(line.gettoken_str(1),NLF_UCAPTION,1); SCRIPT_MSG("UninstCaption: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTICON: @@ -1369,12 +1366,12 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTTEXT: - if (build_uninst.uninstalltext_ptr >= 0) + if (!IsNotSet(uninstall.uninstalltext)) { warning("UninstallText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); } - build_uninst.uninstalltext_ptr=add_string_uninst(line.gettoken_str(1),0); - if (line.getnumtokens()>2) build_uninst.uninstalltext2_ptr=add_string_uninst(line.gettoken_str(2),0); + SetString(line.gettoken_str(1),LANG_UNINST_TEXT,0); + if (line.getnumtokens()>2) SetString(line.gettoken_str(2),NLF_UNINST_SUBTEXT,0); SCRIPT_MSG("UninstallText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTSUBCAPTION: @@ -1382,7 +1379,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char int s; int w=line.gettoken_int(1,&s); if (!s || w < 0 || w > 2) PRINTHELP() - build_uninst.common.subcaption_ptrs[w]=add_string_uninst(line.gettoken_str(2)); + SetString(line.gettoken_str(2),NLF_USUBCAPTION_CONFIRM+w,1); SCRIPT_MSG("UninstSubCaption: page:%d, text=%s\n",w,line.gettoken_str(2)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1560,13 +1557,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char int s; int w=line.gettoken_int(1,&s); if (!s || w < 0 || w > 4) PRINTHELP() - build_header.common.subcaption_ptrs[w]=add_string_main(line.gettoken_str(2)); + SetString(line.gettoken_str(2),NLF_SUBCAPTION_LICENSE+w,1); SCRIPT_MSG("SubCaption: page:%d, text=%s\n",w,line.gettoken_str(2)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_FILEERRORTEXT: #ifdef NSIS_SUPPORT_FILE - build_header.common.fileerrtext_ptr=add_string_main(line.gettoken_str(1)); + SetString(line.gettoken_str(1),NLF_FILE_ERROR,1); SCRIPT_MSG("FileErrorText: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); #else @@ -1574,42 +1571,42 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char return PS_ERROR; #endif case TOK_BRANDINGTEXT: - build_header.common.branding_ptr=add_string_main(line.gettoken_str(1),0); + SetString(line.gettoken_str(1),NLF_BRANDING,0); SCRIPT_MSG("BrandingText: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_MISCBUTTONTEXT: - build_header.backbutton_ptr=add_string_main(line.gettoken_str(1),0); - build_header.nextbutton_ptr=add_string_main(line.gettoken_str(2),0); - build_header.common.cancelbutton_ptr=add_string_main(line.gettoken_str(3),0); - build_header.common.closebutton_ptr=add_string_main(line.gettoken_str(4),0); + SetString(line.gettoken_str(1),NLF_BTN_BACK,0); + SetString(line.gettoken_str(2),NLF_BTN_NEXT,0); + SetString(line.gettoken_str(3),NLF_BTN_CANCEL,0); + SetString(line.gettoken_str(4),NLF_BTN_CLOSE,0); SCRIPT_MSG("MiscButtonText: back=\"%s\" next=\"%s\" cancel=\"%s\" close=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_SPACETEXTS: if (!lstrcmp(line.gettoken_str(1), "none")) { - build_header.spacerequired_ptr=-2; // No space text + no_space_texts=true; SCRIPT_MSG("SpaceTexts: none\n"); } else { - build_header.spacerequired_ptr=add_string_main(line.gettoken_str(1),0); - build_header.spaceavailable_ptr=add_string_main(line.gettoken_str(2),0); + SetString(line.gettoken_str(1),NLF_SPACE_REQ,0); + SetString(line.gettoken_str(2),NLF_SPACE_AVAIL,0); SCRIPT_MSG("SpaceTexts: required=\"%s\" available=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_INSTBUTTONTEXT: - build_header.installbutton_ptr=add_string_main(line.gettoken_str(1),0); + SetString(line.gettoken_str(1),NLF_BTN_INSTALL,0); SCRIPT_MSG("InstallButtonText: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_DETAILSBUTTONTEXT: - build_header.common.showdetailsbutton_ptr=add_string_main(line.gettoken_str(1),0); + SetString(line.gettoken_str(1),NLF_BTN_DETAILS,0); SCRIPT_MSG("DetailsButtonText: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_COMPLETEDTEXT: - build_header.common.completed_ptr=add_string_main(line.gettoken_str(1),0); + SetString(line.gettoken_str(1),NLF_COMPLETED,0); SCRIPT_MSG("CompletedText: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTBUTTONTEXT: #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - build_uninst.uninstbutton_ptr=add_string_uninst(line.gettoken_str(1),0); + SetString(line.gettoken_str(1),NLF_BTN_UNINSTALL,0); SCRIPT_MSG("UninstButtonText: \"%s\"\n",line.gettoken_str(1)); return make_sure_not_in_secorfunc(line.gettoken_str(0)); #else