diff --git a/Examples/makensis.nsi b/Examples/makensis.nsi index 60bd1635..2adc5f72 100644 --- a/Examples/makensis.nsi +++ b/Examples/makensis.nsi @@ -1,5 +1,5 @@ !define VER_MAJOR 2 -!define VER_MINOR 0a2 +!define VER_MINOR 0a3 !ifdef NO_COMPRESSION SetCompress off @@ -145,6 +145,14 @@ Section "Extra UIs" SetOutPath $INSTDIR SectionEnd +Section "Extra UIs" + SectionIn 1 2 + SetOutPath "$INSTDIR\Contrib\Language files" + SetOverwrite try + File "..\Contrib\Language files\*.nlf" + SetOutPath $INSTDIR +SectionEnd + Section "Splash" SectionIn 1 2 SetOutPath $INSTDIR\Contrib\Splash diff --git a/Source/build.cpp b/Source/build.cpp index a1434515..d3d051ac 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -319,6 +319,7 @@ int CEXEBuild::preprocess_string(char *out, const char *in) "TEMP\0" // 31 "WINDIR\0" // 32 "SYSDIR\0" // 33 + "LANGUAGE\0" // 34 ; const char *p=in; diff --git a/Source/build.h b/Source/build.h index 513fd576..e2dd7a2e 100644 --- a/Source/build.h +++ b/Source/build.h @@ -116,8 +116,10 @@ class CEXEBuild { 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) + #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 + #define IsSet(s,lang) _IsSet(string_tables.size()?&(string_tables[0]->s):0,lang) + bool _IsSet(int *str, WORD lang); // Checks if a string is set in a given string table // a whole bunch O data. diff --git a/Source/exehead/Main.c b/Source/exehead/Main.c index e5b9153f..eb8e2a78 100644 --- a/Source/exehead/Main.c +++ b/Source/exehead/Main.c @@ -110,15 +110,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, if (*cmdline == '\"') seekchar = *cmdline++; - while (*cmdline && *cmdline != seekchar) if (*cmdline) cmdline++; - if (*cmdline) cmdline++; + while (*cmdline && *cmdline != seekchar) cmdline=CharNext(cmdline); + if (*cmdline) cmdline=CharNext(cmdline); realcmds=cmdline; do { #ifdef NSIS_CONFIG_CRC_SUPPORT #endif//NSIS_CONFIG_CRC_SUPPORT - while (*cmdline == ' ') if (*cmdline) cmdline++; + while (*cmdline == ' ') cmdline=CharNext(cmdline); if (cmdline[0] != '/') break; cmdline++; #if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT) @@ -147,7 +147,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, lstrcpy(state_install_directory,cmdline+2); cmdline+=lstrlen(cmdline); } - else while (*cmdline && *cmdline != ' ') if (*cmdline) cmdline++; + else while (*cmdline && *cmdline != ' ') cmdline=CharNext(cmdline); } while (*cmdline); diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c index 8b416ff0..4f39303b 100644 --- a/Source/exehead/Ui.c +++ b/Source/exehead/Ui.c @@ -42,7 +42,9 @@ installer_strings *install_strings_tables; common_strings *common_strings_tables; uninstall_strings *uninstall_strings_tables; -int current_lang; +installer_strings *cur_install_strings_table; +common_strings *cur_common_strings_table; +uninstall_strings *cur_uninstall_strings_table; int g_quit_flag; // set when Quit has been called (meaning bail out ASAP) @@ -211,7 +213,6 @@ 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) @@ -234,9 +235,9 @@ int ui_doinstall(void) char *e; if (p[0]=='\"') { - char *p2=*p?p+1:p; + char *p2=CharNext(p); p=p2; - while (*p2 && *p2 != '\"') if (*p2) p2++; + while (*p2 && *p2 != '\"') p2=CharNext(p2); *p2=0; } // p is the path now, check for .exe extension @@ -266,22 +267,6 @@ 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) { @@ -291,6 +276,33 @@ int ui_doinstall(void) #endif } + { + // Added by Amir Szekely 3rd August 2002 + // Multilingual support + LANGID user_lang=GetUserDefaultLangID(); + int size=g_inst_header->common.str_tables_num*sizeof(common_strings); + cur_common_strings_table=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); + cur_install_strings_table=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); + cur_uninstall_strings_table=uninstall_strings_tables=(uninstall_strings*)GlobalAlloc(GPTR,size); + GetCompressedDataFromDataBlockToMemory(g_inst_header->str_tables,(char*)uninstall_strings_tables,size); + } + for (size=0; sizestr_tables_num; size++) { + if (user_lang == common_strings_tables[size].lang_id) { + cur_install_strings_table = &install_strings_tables[size]; + cur_common_strings_table = &common_strings_tables[size]; + cur_uninstall_strings_table = &uninstall_strings_tables[size]; + break; + } + } + } + process_string_fromtab(g_caption,COMMON_STR(caption)); #ifdef NSIS_CONFIG_VISIBLE_SUPPORT diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c index 0be7751d..3239e3d6 100644 --- a/Source/exehead/exec.c +++ b/Source/exehead/exec.c @@ -15,12 +15,6 @@ 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; @@ -399,7 +393,7 @@ static int ExecuteEntry(entry *entries, int pos) lstrcpy(buf3,g_usrvars[0]);//save $0 lstrcpy(g_usrvars[0],buf); - process_string(buf2,LANG_FILEERR); + process_string_fromtab(buf2,COMMON_STR(fileerrtext)); lstrcpy(g_usrvars[0],buf3); // restore $0 switch (MessageBox(g_hwnd,buf2,g_caption,MB_ABORTRETRYIGNORE|MB_ICONSTOP)) @@ -1344,6 +1338,7 @@ static int ExecuteEntry(entry *entries, int pos) case EW_LOG: if (parms[0]) { + if (!g_log_file && parms[1]) build_g_logfile(); log_printf2("settings logging to %d",parms[1]); log_dolog=parms[1]; log_printf2("logging set to %d",parms[1]); diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index bf2f3968..7e00590d 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -400,7 +400,7 @@ int GetCompressedDataFromDataBlock(int offset, HANDLE hFileOut); int GetCompressedDataFromDataBlockToMemory(int offset, char *out, int out_len); // $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value. -#define VAR_CODES_START (256 - 35) +#define VAR_CODES_START (256 - 36) #endif //_FILEFORM_H_ diff --git a/Source/exehead/lang.h b/Source/exehead/lang.h index 5e429921..3e80af16 100644 --- a/Source/exehead/lang.h +++ b/Source/exehead/lang.h @@ -27,7 +27,7 @@ // 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) +#define INSTALL_STR(x) (cur_install_strings_table->x) // Installer specific strings #define LANG_BTN_BACK GetStringFromStringTab(INSTALL_STR(backbutton)) @@ -45,14 +45,14 @@ #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) +#define UNINSTALL_STR(x) (cur_uninstall_strings_table->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) +#define COMMON_STR(x) (cur_common_strings_table->x) // Common strings #define LANG_BRANDING GetStringFromStringTab(COMMON_STR(branding)) diff --git a/Source/exehead/ui.h b/Source/exehead/ui.h index 3c07c0c6..00730f21 100644 --- a/Source/exehead/ui.h +++ b/Source/exehead/ui.h @@ -1,6 +1,11 @@ #ifndef _UI_H_ #define _UI_H_ +// Added by Amir Szekely 3rd August 2002 +extern installer_strings *cur_install_strings_table; +extern common_strings *cur_common_strings_table; +extern uninstall_strings *cur_uninstall_strings_table; + int ui_doinstall(void); void update_status_text(const char *text1, const char *text2); extern int ui_st_updateflag; diff --git a/Source/exehead/util.c b/Source/exehead/util.c index b513338d..1ee5ff44 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -61,7 +61,7 @@ char *scanendslash(const char *str) int validpathspec(char *ubuf) { - return ((ubuf[0]=='\\' && ubuf[1]=='\\') || (ubuf[0] && *(ubuf+1)==':')); + return ((ubuf[0]=='\\' && ubuf[1]=='\\') || (ubuf[0] && *CharNext(ubuf)==':')); } int is_valid_instpath(char *s) @@ -75,7 +75,7 @@ int is_valid_instpath(char *s) while (*s) { if (*s == '\\') ivp++; - if (*s) s++; + s=CharNext(s); } ivp/=5-req; } @@ -83,13 +83,13 @@ int is_valid_instpath(char *s) { if (*s) { - if (*s) s++; + s=CharNext(s); if (*s == ':') { - if (*s) s++; + s=CharNext(s); if (*s == '\\') { - if (*s) s++; + s=CharNext(s); if (req || (*s && *s != '\\')) ivp++; } } @@ -237,24 +237,24 @@ void recursive_create_directory(char *directory) char *tp; char *p; p=directory; - while (*p == ' ') if (*p) p++; + while (*p == ' ') p=CharNext(p); if (!*p) return; - tp=*p?p+1:p; + tp=CharNext(p); if (*tp == ':' && tp[1] == '\\') p=tp+2; else if (p[0] == '\\' && p[1] == '\\') { int x; for (x = 0; x < 2; x ++) { - while (*p != '\\' && *p) if (*p) p++; // skip host then share - if (*p) if (*p) p++; + while (*p != '\\' && *p) p=CharNext(p); // skip host then share + if (*p) p=CharNext(p); } } else return; while (*p) { - while (*p != '\\' && *p) if (*p) p++; + while (*p != '\\' && *p) CharNext(p); if (!*p) CreateDirectory(directory,NULL); else { @@ -452,15 +452,19 @@ void process_string(char *out, const char *in) GetSystemDirectory(out, NSIS_MAX_STRLEN); break; - #if VAR_CODES_START + 33 >= 255 + case VAR_CODES_START + 34: // LANGUAGE + wsprintf(out, "%u", cur_common_strings_table->lang_id); + break; + + #if VAR_CODES_START + 34 >= 255 #error "Too many variables! Extend VAR_CODES_START!" #endif } // switch // remove trailing slash - while (*out && *(out+1)) out++; + while (*out && *CharNext(out)) out++; if (nVarIdx > 21+VAR_CODES_START && *out == '\\') // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT *out = 0; - if (*out) out++; + out=CharNext(out); } // >= VAR_CODES_START } // while *out = 0; diff --git a/Source/lang.cpp b/Source/lang.cpp index 7f365a1d..886d3b8c 100644 --- a/Source/lang.cpp +++ b/Source/lang.cpp @@ -67,7 +67,8 @@ extern char *english_strings[] = { }; 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) + lang = lang?lang:build_nlfs.size()?build_nlfs[build_nlfs.size()-1]->GetLang():0; + lang = lang?lang:string_tables.size()?string_tables[0]->lang_id:1033; // Default is English (1033) StringTable *table = 0; for (int i = 0; i < string_tables.size(); i++) { if (lang == string_tables[i]->lang_id) { @@ -92,9 +93,15 @@ int CEXEBuild::SetString(char *string, int id, int process, WORD lang/*=0*/) { int CEXEBuild::SetString(char *string, int id, int process, StringTable *table) { int *str = 0; int *ustr = 0; +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT #define HANDLE_STRING_C(id,strname) case id: str=&(table->strname); ustr=&(table->u##strname); break; +#else + #define HANDLE_STRING_C(id,strname) HANDLE_STRING_I(id,strname) +#endif #define HANDLE_STRING_I(id,strname) case id: str=&(table->strname); break; +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT #define HANDLE_STRING_U(id,strname) case id: ustr=&(table->strname); break; +#endif switch (id) { HANDLE_STRING_C(NLF_BRANDING, common.branding); HANDLE_STRING_C(NLF_BTN_CANCEL, common.cancelbutton); @@ -149,90 +156,80 @@ int CEXEBuild::SetString(char *string, int id, int process, StringTable *table) return PS_OK; } -int CEXEBuild::WriteStringTables() { - StringTable *table = 0; +bool CEXEBuild::_IsSet(int *str, WORD lang) { + if (!str) return false; + lang = lang?lang:build_nlfs.size()?build_nlfs[build_nlfs.size()-1]->GetLang():0; + lang = lang?lang:string_tables.size()?string_tables[0]->lang_id:1033; // Default is English (1033) 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; - } + for (i = 0; i < string_tables.size(); i++) { + if (lang == string_tables[i]->lang_id) { + 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 (i == string_tables.size()) return false; + if (*(int*)(int(str)-int(string_tables[0])+int(string_tables[i]))>=0) return true; + return false; +} - 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); - } +int CEXEBuild::WriteStringTables() { + int i; - // If no NLFs and no user set strings, use defaults only + // If we have no tables (user didn't set any string and didn't load any NLF) create the default one if (string_tables.size() == 0) { build_header.str_tables_num = 1; - table = (StringTable*)malloc(sizeof(StringTable)); + StringTable *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 + table->lang_id=table->ucommon.lang_id=table->installer.lang_id=table->uninstall.lang_id=1033; // English string_tables.push_back(table); - // Now that we have a table, fill it! - FillDefaultsIfNeeded(table); } + // Fill tables with defaults (if needed) and with instruction strings + int st_num = string_tables.size(); + for (i = 0; i < st_num; i++) + FillDefaultsIfNeeded(string_tables[i]); + // Add string tables into datablock + GrowBuf ist; + for (i = 0; i < st_num; i++) + ist.add(&string_tables[i]->installer, sizeof(installer_strings)); + build_header.str_tables_num = st_num; + build_header.str_tables = add_data((char*)ist.get(), st_num*sizeof(installer_strings), &build_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); + GrowBuf cst; + for (i = 0; i < st_num; i++) + cst.add(&string_tables[i]->common, sizeof(common_strings)); + build_header.common.str_tables_num = st_num; + build_header.common.str_tables = add_data((char*)cst.get(), st_num*sizeof(common_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); + GrowBuf ust; + for (i = 0; i < st_num; i++) + ust.add(&string_tables[i]->uninstall, sizeof(uninstall_strings)); + build_uninst.str_tables_num = st_num; + build_uninst.str_tables = add_data((char*)ust.get(), st_num*sizeof(uninstall_strings), &ubuild_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); + GrowBuf ucst; + for (i = 0; i < st_num; i++) + ucst.add(&string_tables[i]->ucommon, sizeof(common_strings)); + build_uninst.common.str_tables_num = st_num; + build_uninst.common.str_tables = add_data((char*)ucst.get(), st_num*sizeof(common_strings), &ubuild_datablock); return PS_OK; } void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { + if (!nlf) { + for (int i = 0; i < build_nlfs.size(); i++) { + if (build_nlfs[i]->GetLang() == table->lang_id) { + nlf = build_nlfs[i]; + break; + } + } + } + #define str(id) (nlf?nlf->GetString(id):english_strings[id]) #ifdef NSIS_CONFIG_COMPONENTPAGE @@ -250,7 +247,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { { 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); + table->common.subcaptions[1]=add_string_main(str(NLF_SUBCAPTION_OPTIONS)); if (build_header.install_types_ptr[0] < 0) { @@ -290,7 +287,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { if (table->installer.licensedata>=0) { if (table->common.subcaptions[0]<0) - table->common.subcaptions[0]=add_string_main(str(NLF_SUBCAPTION_LICENSE),0); + table->common.subcaptions[0]=add_string_main(str(NLF_SUBCAPTION_LICENSE)); if (table->installer.licensebutton<0) table->installer.licensebutton=add_string_main(str(NLF_BTN_LICENSE),0); } @@ -305,7 +302,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { 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); + table->common.subcaptions[2]=add_string_main(str(NLF_SUBCAPTION_DIR)); 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); } @@ -324,9 +321,9 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { } if (table->common.subcaptions[3]<0) - table->common.subcaptions[3]=add_string_main(str(NLF_SUBCAPTION_INSTFILES),0); + table->common.subcaptions[3]=add_string_main(str(NLF_SUBCAPTION_INSTFILES)); if (table->common.subcaptions[4]<0) - table->common.subcaptions[4]=add_string_main(str(NLF_USUBCAPTION_COMPLETED),0); + table->common.subcaptions[4]=add_string_main(str(NLF_USUBCAPTION_COMPLETED)); if (table->common.branding<0) { @@ -354,16 +351,16 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { 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); + table->ucommon.subcaptions[0]=add_string_uninst(str(NLF_USUBCAPTION_CONFIRM)); if (table->ucommon.subcaptions[1]<0) - table->ucommon.subcaptions[1]=add_string_uninst(str(NLF_USUBCAPTION_INSTFILES),0); + table->ucommon.subcaptions[1]=add_string_uninst(str(NLF_USUBCAPTION_INSTFILES)); if (table->ucommon.subcaptions[2]<0) - table->ucommon.subcaptions[2]=add_string_uninst(str(NLF_USUBCAPTION_COMPLETED),0); + table->ucommon.subcaptions[2]=add_string_uninst(str(NLF_USUBCAPTION_COMPLETED)); 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.caption=add_string_uninst(buf); } 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); @@ -388,7 +385,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { { char buf[1024]; wsprintf(buf,str(NLF_CAPTION),build_strlist.get()+table->common.name); - table->common.caption=add_string_main(buf,0); + table->common.caption=add_string_main(buf); } #define SET_INSTRUCTION(id,s) table->common.s=add_string_main(str(id),0);table->ucommon.s=add_string_uninst(str(id),0) @@ -448,7 +445,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) { 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) { + if (*(int*)(int(str)-int(string_tables[0])+int(string_tables[i])) >= 0) { return false; } } diff --git a/Source/script.cpp b/Source/script.cpp index 25543a23..36f65274 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -517,20 +517,28 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char // header flags /////////////////////////////////////////////////////////////////////////////// case TOK_NAME: - if (!IsNotSet(common.name)) { - warning("Name: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()!=a+1) PRINTHELP(); + if (IsSet(common.name,lang)) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + SetString(line.gettoken_str(a),LANG_NAME,0,lang); + SCRIPT_MSG("Name: \"%s\"\n",line.gettoken_str(a)); } - 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 (!IsNotSet(common.caption)) { - warning("Caption: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()!=a+1) PRINTHELP(); + if (IsSet(common.caption,lang)) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + SetString(line.gettoken_str(a),NLF_CAPTION,1,lang); + SCRIPT_MSG("Caption: \"%s\"\n",line.gettoken_str(a)); } - 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: SCRIPT_MSG("Icon: \"%s\"\n",line.gettoken_str(1)); @@ -575,25 +583,33 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char return PS_ERROR; #endif//!NSIS_CONFIG_COMPONENTPAGE case TOK_DIRTEXT: - if (!IsNotSet(installer.text) && line.gettoken_str(1)[0]) { - warning("DirText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + if (IsSet(installer.text,lang) && line.gettoken_str(a)[0]) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + SetString(line.gettoken_str(a),LANG_DIR_TEXT,0,lang); + if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_DIR_SUBTEXT,0,lang); + if (line.getnumtokens()>a+2) SetString(line.gettoken_str(a+2),NLF_BTN_BROWSE,0,lang); + SCRIPT_MSG("DirText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2)); } - 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 (!IsNotSet(installer.componenttext) && line.gettoken_str(1)[0]) { - warning("ComponentText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + if (IsSet(installer.componenttext,lang) && line.gettoken_str(a)[0]) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + SetString(line.gettoken_str(a),LANG_COMP_TEXT,0,lang); + if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_COMP_SUBTEXT1,0,lang); + if (line.getnumtokens()>a+2) SetString(line.gettoken_str(a+2),NLF_COMP_SUBTEXT2,0,lang); + SCRIPT_MSG("ComponentText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2)); } - 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: { @@ -608,6 +624,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char build_header.no_custom_instmode_flag=2; SCRIPT_MSG("InstType: making components viewable only on custom install type\n"); } + else if (!strnicmp(line.gettoken_str(1),"/LANG=",6)) { + if (!strnicmp(line.gettoken_str(2),"/CUSTOMSTRING=",14)) { + SetString(line.gettoken_str(2)+14,NLF_COMP_CUSTOM,0,atoi(line.gettoken_str(1)+6)); + SCRIPT_MSG("InstType: setting custom text to: /LANG=%d \"%s\"\n",line.gettoken_str(1)+6,line.gettoken_str(2)+14); + } + else PRINTHELP() + } else if (!strnicmp(line.gettoken_str(1),"/CUSTOMSTRING=",14)) { SetString(line.gettoken_str(1)+14,NLF_COMP_CUSTOM,0); @@ -638,19 +661,19 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char #endif//!NSIS_CONFIG_COMPONENTPAGE #ifdef NSIS_CONFIG_LICENSEPAGE case TOK_LICENSETEXT: - if (!IsNotSet(installer.licensetext)) { - warning("LicenseText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + if (IsSet(installer.licensetext,lang)) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + SetString(line.gettoken_str(a),LANG_LICENSE_TEXT,0,lang); + if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_BTN_LICENSE,0,lang); + SCRIPT_MSG("LicenseText: \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1)); } - 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 (!IsNotSet(installer.licensedata)) - { - warning("LicenseData: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); - } #ifdef NSIS_CONFIG_SILENT_SUPPORT if (build_header.common.silent_install) { @@ -658,12 +681,18 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char } #endif { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + if (IsSet(installer.licensedata,lang)) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); FILE *fp; int datalen; - fp=fopen(line.gettoken_str(1),"rb"); + fp=fopen(line.gettoken_str(a),"rb"); if (!fp) { - ERROR_MSG("LicenseData: open failed \"%s\"\n",line.gettoken_str(1)); + ERROR_MSG("LicenseData: open failed \"%s\"\n",line.gettoken_str(a)); PRINTHELP() } fseek(fp,0,SEEK_END); @@ -677,8 +706,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char } fclose(fp); data[datalen]=0; - SetString(data,LANG_LICENSE_DATA,0); - SCRIPT_MSG("LicenseData: \"%s\"\n",line.gettoken_str(1)); + SetString(data,LANG_LICENSE_DATA,0,lang); + SCRIPT_MSG("LicenseData: \"%s\"\n",line.gettoken_str(a)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); // Added by Amir Szekely 30th July 2002 @@ -849,7 +878,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char header_data_new = re.Save((DWORD&)exeheader_size_new); } catch (exception& err) { - ERROR_MSG("Error while changing font: %s\n", err.what()); + ERROR_MSG("Error removing window icon: %s\n", err.what()); return PS_ERROR; } return make_sure_not_in_secorfunc(line.gettoken_str(0)); @@ -1213,16 +1242,20 @@ 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)); + NLF *newNLF = new NLF(line.gettoken_str(1)); for (int i = 0; i < build_nlfs.size(); i++) - if (build_nlfs[i]->GetLang() == newLang->GetLang()) { + if (build_nlfs[i]->GetLang() == newNLF->GetLang()) { ERROR_MSG("Error: Can't add same language twice!\n"); return PS_ERROR; } - build_nlfs.push_back(newLang); + build_nlfs.push_back(newNLF); + StringTable *table = (StringTable*)malloc(sizeof(StringTable)); + memset(table, -1, sizeof(StringTable)); + table->lang_id=table->ucommon.lang_id=table->installer.lang_id=table->uninstall.lang_id=newNLF->GetLang(); + string_tables.push_back(table); } catch (exception &err) { - ERROR_MSG("Error while adding language file: %s", err.what()); + ERROR_MSG("Error while loading language file: %s\n", err.what()); return PS_ERROR; } } @@ -1343,12 +1376,16 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT case TOK_UNINSTCAPTION: - if (!IsNotSet(ucommon.caption)) { - warning("UninstCaption: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + if (IsSet(ucommon.caption,lang)) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + SetString(line.gettoken_str(a),NLF_UCAPTION,1,lang); + SCRIPT_MSG("UninstCaption: \"%s\"\n",line.gettoken_str(a)); } - 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: SCRIPT_MSG("UninstallIcon: \"%s\"\n",line.gettoken_str(1)); @@ -1366,21 +1403,29 @@ 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 (!IsNotSet(uninstall.uninstalltext)) { - warning("UninstallText: specified multiple times, wasting space (%s:%d)",curfilename,linecnt); + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + if (IsSet(uninstall.uninstalltext,lang)) + warning("%s: specified multiple times, wasting space (%s:%d)",line.gettoken_str(0),curfilename,linecnt); + SetString(line.gettoken_str(a),LANG_UNINST_TEXT,1,lang); + if (line.getnumtokens()>a+1) SetString(line.gettoken_str(a+1),NLF_UNINST_SUBTEXT,0,lang); + SCRIPT_MSG("UninstallText: \"%s\" \"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1)); } - 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: { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()!=a+2) PRINTHELP(); int s; - int w=line.gettoken_int(1,&s); + int w=line.gettoken_int(a,&s); if (!s || w < 0 || w > 2) PRINTHELP() - SetString(line.gettoken_str(2),NLF_USUBCAPTION_CONFIRM+w,1); - SCRIPT_MSG("UninstSubCaption: page:%d, text=%s\n",w,line.gettoken_str(2)); + SetString(line.gettoken_str(a+1),NLF_USUBCAPTION_CONFIRM+w,1,lang); + SCRIPT_MSG("UninstSubCaption: page:%d, text=%s\n",w,line.gettoken_str(a+1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_WRITEUNINSTALLER: @@ -1554,60 +1599,113 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char return PS_OK; case TOK_SUBCAPTION: { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()!=a+2) PRINTHELP(); int s; - int w=line.gettoken_int(1,&s); - if (!s || w < 0 || w > 4) PRINTHELP() - SetString(line.gettoken_str(2),NLF_SUBCAPTION_LICENSE+w,1); - SCRIPT_MSG("SubCaption: page:%d, text=%s\n",w,line.gettoken_str(2)); + int w=line.gettoken_int(a,&s); + if (!s || w < 0 || w > 2) PRINTHELP() + SetString(line.gettoken_str(a+1),NLF_SUBCAPTION_LICENSE+w,1,lang); + SCRIPT_MSG("SubCaption: page:%d, text=%s\n",w,line.gettoken_str(a+1)); } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_FILEERRORTEXT: #ifdef NSIS_SUPPORT_FILE - SetString(line.gettoken_str(1),NLF_FILE_ERROR,1); - SCRIPT_MSG("FileErrorText: \"%s\"\n",line.gettoken_str(1)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()!=a+1) PRINTHELP(); + SetString(line.gettoken_str(a),NLF_FILE_ERROR,1,lang); + SCRIPT_MSG("FileErrorText: \"%s\"\n",line.gettoken_str(a)); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); #else ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FILE not defined.\n", line.gettoken_str(0)); return PS_ERROR; #endif case TOK_BRANDINGTEXT: - SetString(line.gettoken_str(1),NLF_BRANDING,0); - SCRIPT_MSG("BrandingText: \"%s\"\n",line.gettoken_str(1)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()!=a+1) PRINTHELP(); + SetString(line.gettoken_str(a),NLF_BRANDING,0,lang); + SCRIPT_MSG("BrandingText: \"%s\"\n",line.gettoken_str(a)); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_MISCBUTTONTEXT: - 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)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + SetString(line.gettoken_str(a),NLF_BTN_BACK,0,lang); + SetString(line.gettoken_str(a+1),NLF_BTN_NEXT,0,lang); + SetString(line.gettoken_str(a+2),NLF_BTN_CANCEL,0,lang); + SetString(line.gettoken_str(a+3),NLF_BTN_CLOSE,0,lang); + SCRIPT_MSG("MiscButtonText: back=\"%s\" next=\"%s\" cancel=\"%s\" close=\"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2),line.gettoken_str(a+3)); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_SPACETEXTS: - if (!lstrcmp(line.gettoken_str(1), "none")) { - no_space_texts=true; - SCRIPT_MSG("SpaceTexts: none\n"); - } - else { - 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)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + + if (!lstrcmp(line.gettoken_str(a), "none")) { + no_space_texts=true; + SCRIPT_MSG("SpaceTexts: none\n"); + } + else { + SetString(line.gettoken_str(a),NLF_SPACE_REQ,0); + SetString(line.gettoken_str(a+1),NLF_SPACE_AVAIL,0); + SCRIPT_MSG("SpaceTexts: required=\"%s\" available=\"%s\"\n",line.gettoken_str(a),line.gettoken_str(a+1)); + } } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_INSTBUTTONTEXT: - SetString(line.gettoken_str(1),NLF_BTN_INSTALL,0); - SCRIPT_MSG("InstallButtonText: \"%s\"\n",line.gettoken_str(1)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + SetString(line.gettoken_str(a),NLF_BTN_INSTALL,0,lang); + SCRIPT_MSG("InstallButtonText: \"%s\"\n",line.gettoken_str(a)); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_DETAILSBUTTONTEXT: - SetString(line.gettoken_str(1),NLF_BTN_DETAILS,0); - SCRIPT_MSG("DetailsButtonText: \"%s\"\n",line.gettoken_str(1)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + SetString(line.gettoken_str(a),NLF_BTN_DETAILS,0,lang); + SCRIPT_MSG("DetailsButtonText: \"%s\"\n",line.gettoken_str(a)); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_COMPLETEDTEXT: - SetString(line.gettoken_str(1),NLF_COMPLETED,0); - SCRIPT_MSG("CompletedText: \"%s\"\n",line.gettoken_str(1)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + SetString(line.gettoken_str(a),NLF_COMPLETED,0,lang); + SCRIPT_MSG("CompletedText: \"%s\"\n",line.gettoken_str(a)); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); case TOK_UNINSTBUTTONTEXT: #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - SetString(line.gettoken_str(1),NLF_BTN_UNINSTALL,0); - SCRIPT_MSG("UninstButtonText: \"%s\"\n",line.gettoken_str(1)); + { + int a = 1; + WORD lang = 0; + if (!strnicmp(line.gettoken_str(a),"/LANG=",6)) lang=atoi(line.gettoken_str(a++)+6); + if (line.getnumtokens()==a) PRINTHELP(); + SetString(line.gettoken_str(a),NLF_BTN_UNINSTALL,0,lang); + SCRIPT_MSG("UninstButtonText: \"%s\"\n",line.gettoken_str(a)); + } return make_sure_not_in_secorfunc(line.gettoken_str(0)); #else ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0)); diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 096ec84c..6a4755e0 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -22,14 +22,14 @@ static tokenType tokenlist[TOK__LAST] = {TOK_ADDSIZE,"AddSize",1,0,"size_to_add_to_section_in_kb"}, {TOK_AUTOCLOSE,"AutoCloseWindow",1,0,"(false|true)"}, {TOK_BGGRADIENT,"BGGradient",0,3,"(off | [top_color [bottom_color [text_color]]])"}, -{TOK_BRANDINGTEXT,"BrandingText",1,0,"installer_text"}, +{TOK_BRANDINGTEXT,"BrandingText",1,1,"[/LANG=lang_id] installer_text"}, {TOK_BRINGTOFRONT,"BringToFront",0,0,""}, {TOK_CALL,"Call",1,0,"function_name | [:label_name]"}, {TOK_CALLINSTDLL,"CallInstDLL",2,0,"dll_path_on_target.dll function"}, -{TOK_CAPTION,"Caption",1,0,"installer_caption"}, +{TOK_CAPTION,"Caption",1,1,"[/LANG=lang_id] installer_caption"}, {TOK_CHANGEUI,"ChangeUI",1,0,"ui_file.exe"}, {TOK_CLEARERRORS,"ClearErrors",0,0,""}, -{TOK_COMPTEXT,"ComponentText",0,3,"[component_page_description] [component_subtext1] [component_subtext2]"}, +{TOK_COMPTEXT,"ComponentText",0,4,"[/LANG=lang_id] [component_page_description] [component_subtext1] [component_subtext2]"}, {TOK_GETDLLVERSION,"GetDLLVersion",3,0,"filename $(user_var: high output) $(user_var: low output)"}, {TOK_GETDLLVERSIONLOCAL,"GetDLLVersionLocal",3,0,"localfilename $(user_var: high output) $(user_var: low output)"}, {TOK_GETFILETIME,"GetFileTime",3,0,"file $(user_var: high output) $(user_var: low output)"}, @@ -45,7 +45,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_DELETEREGVALUE,"DeleteRegValue",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"}, {TOK_DELETE,"Delete",1,1,"[/REBOOTOK] filespec"}, {TOK_DETAILPRINT,"DetailPrint",1,0,"message"}, -{TOK_DIRTEXT,"DirText",0,3,"[directory_page_description] [directory_page_subtext] [browse button text]"}, +{TOK_DIRTEXT,"DirText",0,4,"[/LANG=lang_id] [directory_page_description] [directory_page_subtext] [browse button text]"}, {TOK_DIRSHOW,"DirShow",1,0,"(show|hide)"}, {TOK_ROOTDIRINST,"AllowRootDirInstall",1,0,"(true|false)"}, {TOK_CHECKBITMAP,"CheckBitmap",1,0,"local_bitmap.bmp"}, @@ -62,7 +62,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_FINDNEXT,"FindNext",2,0,"$(user_var: handle input) $(user_var: filename output)"}, {TOK_FILE,"File",1,-1,"([/a] [/r] filespec [...]|/oname=outfile one_file_only)"}, {TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)"}, -{TOK_FILEERRORTEXT,"FileErrorText",0,1,"[text (can contain $0)]"}, +{TOK_FILEERRORTEXT,"FileErrorText",0,2,"[/LANG=lang_id] [text (can contain $0)]"}, {TOK_FILEOPEN,"FileOpen",3,0,"$(user_var: handle output) filename openmode\n openmode=r|w|a"}, {TOK_FILEREAD,"FileRead",2,1,"$(user_var: handle input) $(user_var: text output) [maxlen]"}, {TOK_FILEWRITE,"FileWrite",2,0,"$(user_var: handle input) text"}, @@ -90,8 +90,8 @@ static tokenType tokenlist[TOK__LAST] = {TOK_INTFMT,"IntFmt",3,0,"$(user_var: output) format_string input"}, {TOK_ISWINDOW,"IsWindow",2,1,"hwnd jump_if_window [jump_if_not_window]"}, {TOK_GOTO,"Goto",1,0,"label"}, -{TOK_LICENSEDATA,"LicenseData",1,0,"local_file_that_has_license_text.txt"}, -{TOK_LICENSETEXT,"LicenseText",1,1,"license_page_description [license_button_text]"}, +{TOK_LICENSEDATA,"LicenseData",1,1,"[/LANG=lang_id] local_file_that_has_license_text.txt"}, +{TOK_LICENSETEXT,"LicenseText",1,2,"[/LANG=lang_id] license_page_description [license_button_text]"}, {TOK_LICENSEBKCOLOR,"LicenseBkColor",1,0,"background_color"}, {TOK_LOADNLF,"LoadLanguageFile",1,0,"language.nlf"}, {TOK_LOGSET,"LogSet",1,0,"on|off"}, @@ -99,7 +99,7 @@ static tokenType tokenlist[TOK__LAST] = {TOK_MESSAGEBOX,"MessageBox",2,4,"mode messagebox_text [return_check label_to_goto_if_equal [return_check2 label2]]\n mode=modeflag[|modeflag[|modeflag[...]]]\n " "modeflag=(MB_ABORTRETRYIGNORE|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_YESNO|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_TOPMOST|MB_SETFOREGROUND|MB_RIGHT"}, {TOK_NOP,"Nop",0,0,""}, -{TOK_NAME,"Name",1,0,"installer_name"}, +{TOK_NAME,"Name",1,1,"[/LANG=lang_id] installer_name"}, {TOK_OUTFILE,"OutFile",1,0,"install_output.exe"}, {TOK_POP,"Pop",1,0,"$(user_var: output)"}, {TOK_PUSH,"Push",1,0,"string"}, @@ -146,12 +146,12 @@ static tokenType tokenlist[TOK__LAST] = {TOK_STRCMP,"StrCmp",3,1,"str1 str2 label_to_goto_if_equal [label_to_goto_if_not]"}, {TOK_STRCPY,"StrCpy",2,2,"$(user_var: output) str [maxlen] [startoffset]"}, {TOK_STRLEN,"StrLen",2,0,"$(user_var: length output) str"}, -{TOK_SUBCAPTION,"SubCaption",2,0,"page_number(0-4) new_subcaption"}, +{TOK_SUBCAPTION,"SubCaption",2,1,"[/LANG=lang_id] page_number(0-4) new_subcaption"}, {TOK_UNINSTALLEXENAME,"UninstallExeName",0,0,"no longer supported, use WriteUninstaller from section."}, {TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico"}, -{TOK_UNINSTTEXT,"UninstallText",1,1,"Text_to_go_on_uninstall page [subtext]"}, -{TOK_UNINSTCAPTION,"UninstallCaption",1,0,"uninstaller_caption"}, -{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,0,"page_number(0-2) new_subcaption"}, +{TOK_UNINSTTEXT,"UninstallText",1,2,"[/LANG=lang_id] Text_to_go_on_uninstall page [subtext]"}, +{TOK_UNINSTCAPTION,"UninstallCaption",1,1,"[/LANG=lang_id] uninstaller_caption"}, +{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,1,"[/LANG=lang_id] page_number(0-2) new_subcaption"}, {TOK_UNREGDLL,"UnRegDLL",1,0,"dll_path_on_target.dll"}, {TOK_WINDOWICON,"WindowIcon",1,0,"on|off"}, {TOK_WRITEINISTR,"WriteINIStr",4,0,"ini_file section_name entry_name new_value"}, @@ -182,12 +182,12 @@ static tokenType tokenlist[TOK__LAST] = {TOK_P_INSERTMACRO,"!insertmacro",1,-1,"macroname [parms ...]"}, -{TOK_MISCBUTTONTEXT,"MiscButtonText",0,4,"[back button text] [next button text] [cancel button text] [close button text]"}, -{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,1,"[details button text]"}, -{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,1,"[uninstall button text]"}, -{TOK_INSTBUTTONTEXT,"InstallButtonText",0,1,"[install button text]"}, -{TOK_SPACETEXTS,"SpaceTexts",0,2,"[space required text] [space available text]"}, -{TOK_COMPLETEDTEXT,"CompletedText",0,1,"[completed text]"}, +{TOK_MISCBUTTONTEXT,"MiscButtonText",0,5,"[/LANG=lang_id] [back button text] [next button text] [cancel button text] [close button text]"}, +{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,2,"[/LANG=lang_id] [details button text]"}, +{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,2,"[/LANG=lang_id] [uninstall button text]"}, +{TOK_INSTBUTTONTEXT,"InstallButtonText",0,2,"[/LANG=lang_id] [install button text]"}, +{TOK_SPACETEXTS,"SpaceTexts",0,3,"[/LANG=lang_id] [space required text] [space available text]"}, +{TOK_COMPLETEDTEXT,"CompletedText",0,2,"[/LANG=lang_id] [completed text]"}, {TOK_GETFUNCTIONADDR,"GetFunctionAddress",2,0,"output function"}, {TOK_GETLABELADDR,"GetLabelAddress",2,0,"output label"},