removed code duplication for installer/uninstaller in GenerateLangTables
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@5128 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
8a8844bcb8
commit
eee3006998
2 changed files with 163 additions and 225 deletions
|
@ -266,6 +266,7 @@ class CEXEBuild {
|
||||||
int DefineInnerLangString(int id, int process=-1);
|
int DefineInnerLangString(int id, int process=-1);
|
||||||
int SetLangString(char *name, LANGID lang, char *string);
|
int SetLangString(char *name, LANGID lang, char *string);
|
||||||
int SetInnerString(int id, char *string);
|
int SetInnerString(int id, char *string);
|
||||||
|
int GenerateLangTable(LanguageTable *lt, int num_lang_tables);
|
||||||
int GenerateLangTables();
|
int GenerateLangTables();
|
||||||
void FillLanguageTable(LanguageTable *table);
|
void FillLanguageTable(LanguageTable *table);
|
||||||
int HasUserDefined(int id) {
|
int HasUserDefined(int id) {
|
||||||
|
|
387
Source/lang.cpp
387
Source/lang.cpp
|
@ -482,6 +482,158 @@ int CEXEBuild::SetInnerString(int id, char *string) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CEXEBuild::GenerateLangTable(LanguageTable *lt, int num_lang_tables) {
|
||||||
|
// Add all installer language strings
|
||||||
|
int i, j, l, tabsset;
|
||||||
|
struct langstring* lang_strings = NULL;
|
||||||
|
TinyGrowBuf *string_ptrs = new TinyGrowBuf[num_lang_tables];
|
||||||
|
|
||||||
|
tabsset = 1;
|
||||||
|
while (tabsset)
|
||||||
|
{
|
||||||
|
tabsset = 0;
|
||||||
|
for (i = num_lang_tables; i--; )
|
||||||
|
{
|
||||||
|
// Fill in default values for all used language strings that we can
|
||||||
|
FillLanguageTable(<[i]);
|
||||||
|
// Make sure the string lists are large enough
|
||||||
|
string_ptrs[i].set_zeroing(1);
|
||||||
|
if (!uninstall_mode)
|
||||||
|
string_ptrs[i].resize(build_langstring_num * sizeof(int));
|
||||||
|
else
|
||||||
|
string_ptrs[i].resize(ubuild_langstring_num * sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
// For all current language strings
|
||||||
|
if (!uninstall_mode)
|
||||||
|
lang_strings = build_langstrings.sort_index(&l);
|
||||||
|
else
|
||||||
|
lang_strings = build_langstrings.sort_uindex(&l);
|
||||||
|
|
||||||
|
for (j = 0; j < l; j++)
|
||||||
|
{
|
||||||
|
int lang_string_index;
|
||||||
|
|
||||||
|
if (!uninstall_mode)
|
||||||
|
lang_string_index = lang_strings[j].index;
|
||||||
|
else
|
||||||
|
lang_string_index = lang_strings[j].uindex;
|
||||||
|
|
||||||
|
// Is this language string used (in the installer)?
|
||||||
|
if (lang_string_index >= 0)
|
||||||
|
{
|
||||||
|
// For each language
|
||||||
|
for (i = num_lang_tables; i--; )
|
||||||
|
{
|
||||||
|
// Get the current string pointer
|
||||||
|
int *ptr = (int *)string_ptrs[i].get() + lang_string_index;
|
||||||
|
// Not already set?
|
||||||
|
if (!*ptr)
|
||||||
|
{
|
||||||
|
// Get the language string and its name
|
||||||
|
const char *str = lt[i].lang_strings->get(lang_strings[j].sn);
|
||||||
|
const char *lsn = build_langstrings.offset2name(lang_strings[j].name);
|
||||||
|
if (!str || !*str)
|
||||||
|
{
|
||||||
|
// No string is defined; give a warning (for user strings only)
|
||||||
|
if (lsn[0] != '^')
|
||||||
|
{
|
||||||
|
if (lt[i].nlf.m_bLoaded)
|
||||||
|
warning("LangString \"%s\" is not set in language table of language %s", lsn, lt[i].nlf.m_szName);
|
||||||
|
else
|
||||||
|
warning("LangString \"%s\" is not set in language table of language %d", lsn, lt[i].lang_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add the language string to the string data block
|
||||||
|
char fn[1024];
|
||||||
|
sprintf(fn, "LangString %s", lsn);
|
||||||
|
curfilename = fn;
|
||||||
|
linecnt = lt[i].lang_id;
|
||||||
|
*ptr = add_string(str, lang_strings[j].process, (WORD) lt[i].nlf.m_uCodePage);
|
||||||
|
curfilename = 0;
|
||||||
|
// Indicate that we should check again for any newly referenced language strings
|
||||||
|
tabsset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optimize langstrings and check for recursion
|
||||||
|
for (i = num_lang_tables; i--; )
|
||||||
|
{
|
||||||
|
TinyGrowBuf rec;
|
||||||
|
int *lst = (int *)string_ptrs[i].get();
|
||||||
|
|
||||||
|
int langstring_num;
|
||||||
|
|
||||||
|
if (!uninstall_mode)
|
||||||
|
langstring_num = build_langstring_num;
|
||||||
|
else
|
||||||
|
langstring_num = ubuild_langstring_num;
|
||||||
|
|
||||||
|
for (j = 0; j < langstring_num; j++)
|
||||||
|
{
|
||||||
|
// Does this string reference another language string directly?
|
||||||
|
while (lst[j] < 0)
|
||||||
|
{
|
||||||
|
// Search through list of language string references
|
||||||
|
for (l = 0; (unsigned int)l < rec.getlen() / sizeof(int); l++)
|
||||||
|
{
|
||||||
|
if (((int*)rec.get())[l] == lst[j])
|
||||||
|
{
|
||||||
|
// We have the index of a recursive language string; now find the name
|
||||||
|
const char *name = "(unnamed)";
|
||||||
|
for (l = 0; l < langstring_num; l++)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
if (!uninstall_mode)
|
||||||
|
index = lang_strings[l].index;
|
||||||
|
else
|
||||||
|
index = lang_strings[l].uindex;
|
||||||
|
|
||||||
|
if (lang_strings[l].index == j)
|
||||||
|
{
|
||||||
|
name = build_langstrings.offset2name(lang_strings[l].name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ERROR_MSG("Error: LangString %s is recursive!\n", name);
|
||||||
|
delete [] string_ptrs;
|
||||||
|
return PS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add this reference to the list
|
||||||
|
rec.add(&lst[j], sizeof(int));
|
||||||
|
// and dereference it
|
||||||
|
lst[j] = lst[-lst[j] - 1];
|
||||||
|
}
|
||||||
|
rec.resize(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add language tables into their datablock
|
||||||
|
for (i = num_lang_tables; i--; )
|
||||||
|
{
|
||||||
|
cur_langtables->add(<[i].lang_id, sizeof(LANGID));
|
||||||
|
cur_langtables->add(<[i].dlg_offset, sizeof(int));
|
||||||
|
int rtl = lt[i].nlf.m_bRTL ? 1 : 0;
|
||||||
|
cur_langtables->add(&rtl, sizeof(int));
|
||||||
|
cur_langtables->add(string_ptrs[i].get(), string_ptrs[i].getlen());
|
||||||
|
string_ptrs[i].resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_header->blocks[NB_LANGTABLES].num = num_lang_tables;
|
||||||
|
cur_header->langtable_size = cur_langtables->getlen() / num_lang_tables;
|
||||||
|
|
||||||
|
delete [] string_ptrs;
|
||||||
|
|
||||||
|
return PS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int CEXEBuild::GenerateLangTables() {
|
int CEXEBuild::GenerateLangTables() {
|
||||||
int i;
|
int i;
|
||||||
LanguageTable *lt = (LanguageTable*)lang_tables.get();
|
LanguageTable *lt = (LanguageTable*)lang_tables.get();
|
||||||
|
@ -618,237 +770,22 @@ int CEXEBuild::GenerateLangTables() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all installer language strings
|
int orig_uninstall_mode = uninstall_mode;
|
||||||
int j, l, tabsset;
|
|
||||||
struct langstring* lang_strings = NULL;
|
|
||||||
TinyGrowBuf *string_ptrs = new TinyGrowBuf[num_lang_tables];
|
|
||||||
|
|
||||||
tabsset = 1;
|
|
||||||
while (tabsset)
|
|
||||||
{
|
|
||||||
tabsset = 0;
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
// Fill in default values for all used language strings that we can
|
|
||||||
FillLanguageTable(<[i]);
|
|
||||||
// Make sure the string lists are large enough
|
|
||||||
string_ptrs[i].set_zeroing(1);
|
|
||||||
string_ptrs[i].resize(build_langstring_num * sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
// For all current language strings
|
|
||||||
lang_strings = build_langstrings.sort_index(&l);
|
|
||||||
for (j = 0; j < l; j++)
|
|
||||||
{
|
|
||||||
// Is this language string used (in the installer)?
|
|
||||||
if (lang_strings[j].index >= 0)
|
|
||||||
{
|
|
||||||
// For each language
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
// Get the current string pointer
|
|
||||||
int *ptr = (int *)string_ptrs[i].get() + lang_strings[j].index;
|
|
||||||
// Not already set?
|
|
||||||
if (!*ptr)
|
|
||||||
{
|
|
||||||
// Get the language string and its name
|
|
||||||
const char *str = lt[i].lang_strings->get(lang_strings[j].sn);
|
|
||||||
const char *lsn = build_langstrings.offset2name(lang_strings[j].name);
|
|
||||||
if (!str || !*str)
|
|
||||||
{
|
|
||||||
// No string is defined; give a warning (for user strings only)
|
|
||||||
if (lsn[0] != '^')
|
|
||||||
{
|
|
||||||
if (lt[i].nlf.m_bLoaded)
|
|
||||||
warning("LangString \"%s\" is not set in language table of language %s", lsn, lt[i].nlf.m_szName);
|
|
||||||
else
|
|
||||||
warning("LangString \"%s\" is not set in language table of language %d", lsn, lt[i].lang_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Add the language string to the string data block
|
|
||||||
char fn[1024];
|
|
||||||
sprintf(fn, "LangString %s", lsn);
|
|
||||||
curfilename = fn;
|
|
||||||
linecnt = lt[i].lang_id;
|
|
||||||
*ptr = add_string(str, lang_strings[j].process, (WORD) lt[i].nlf.m_uCodePage);
|
|
||||||
curfilename = 0;
|
|
||||||
// Indicate that we should check again for any newly referenced language strings
|
|
||||||
tabsset++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimize langstrings and check for recursion
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
TinyGrowBuf rec;
|
|
||||||
int *lst = (int *)string_ptrs[i].get();
|
|
||||||
for (j = 0; j < build_langstring_num; j++)
|
|
||||||
{
|
|
||||||
// Does this string reference another language string directly?
|
|
||||||
while (lst[j] < 0)
|
|
||||||
{
|
|
||||||
// Search through list of language string references
|
|
||||||
for (l = 0; (unsigned int)l < rec.getlen() / sizeof(int); l++)
|
|
||||||
{
|
|
||||||
if (((int*)rec.get())[l] == lst[j])
|
|
||||||
{
|
|
||||||
// We have the index of a recursive language string; now find the name
|
|
||||||
const char *name = "(unnamed)";
|
|
||||||
for (l = 0; l < build_langstring_num; l++)
|
|
||||||
if (lang_strings[l].index == j)
|
|
||||||
name = build_langstrings.offset2name(lang_strings[l].name);
|
|
||||||
ERROR_MSG("Error: LangString %s is recursive!\n", name);
|
|
||||||
delete [] string_ptrs;
|
|
||||||
return PS_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Add this reference to the list
|
|
||||||
rec.add(&lst[j], sizeof(int));
|
|
||||||
// and dereference it
|
|
||||||
lst[j] = lst[-lst[j] - 1];
|
|
||||||
}
|
|
||||||
rec.resize(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add language tables into their datablock
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
build_langtables.add(<[i].lang_id, sizeof(LANGID));
|
|
||||||
build_langtables.add(<[i].dlg_offset, sizeof(int));
|
|
||||||
int rtl = lt[i].nlf.m_bRTL ? 1 : 0;
|
|
||||||
build_langtables.add(&rtl, sizeof(int));
|
|
||||||
build_langtables.add(string_ptrs[i].get(), string_ptrs[i].getlen());
|
|
||||||
string_ptrs[i].resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
build_header.blocks[NB_LANGTABLES].num = num_lang_tables;
|
|
||||||
build_header.langtable_size = build_langtables.getlen() / num_lang_tables;
|
|
||||||
|
|
||||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
|
||||||
// Now do it all again, this time for the uninstaller
|
|
||||||
set_uninstall_mode(1);
|
|
||||||
|
|
||||||
tabsset = 1;
|
|
||||||
while (tabsset)
|
|
||||||
{
|
|
||||||
tabsset = 0;
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
// Fill in default values for all used language strings that we can
|
|
||||||
FillLanguageTable(<[i]);
|
|
||||||
// Make sure the string lists are large enough
|
|
||||||
string_ptrs[i].set_zeroing(1);
|
|
||||||
string_ptrs[i].resize(ubuild_langstring_num * sizeof(int));
|
|
||||||
}
|
|
||||||
|
|
||||||
// For all current language strings
|
|
||||||
lang_strings = build_langstrings.sort_uindex(&l);
|
|
||||||
for (j = 0; j < l; j++)
|
|
||||||
{
|
|
||||||
// Is this language string used (in the uninstaller)?
|
|
||||||
if (lang_strings[j].uindex >= 0)
|
|
||||||
{
|
|
||||||
// For each language
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
// Get the current string pointer
|
|
||||||
int *ptr = (int *)string_ptrs[i].get() + lang_strings[j].uindex;
|
|
||||||
// Not already set?
|
|
||||||
if (!*ptr)
|
|
||||||
{
|
|
||||||
// Get the language string and its name
|
|
||||||
const char *str = lt[i].lang_strings->get(lang_strings[j].sn);
|
|
||||||
const char *lsn = build_langstrings.offset2name(lang_strings[j].name);
|
|
||||||
if (!str || !*str)
|
|
||||||
{
|
|
||||||
// No string is defined; give a warning (for user strings only)
|
|
||||||
if (lsn[0] != '^')
|
|
||||||
{
|
|
||||||
if (lt[i].nlf.m_bLoaded)
|
|
||||||
warning("LangString \"%s\" is not set in language table of language %s", lsn, lt[i].nlf.m_szName);
|
|
||||||
else
|
|
||||||
warning("LangString \"%s\" is not set in language table of language %d", lsn, lt[i].lang_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Add the language string to the string data block
|
|
||||||
char fn[1024];
|
|
||||||
sprintf(fn, "LangString %s", lsn);
|
|
||||||
curfilename = fn;
|
|
||||||
linecnt = lt[i].lang_id;
|
|
||||||
*ptr = add_string(str, lang_strings[j].process, (WORD) lt[i].nlf.m_uCodePage);
|
|
||||||
curfilename = 0;
|
|
||||||
// Indicate that we should check again for any newly referenced language strings
|
|
||||||
tabsset++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimize langstrings and check for recursion
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
TinyGrowBuf rec;
|
|
||||||
int *lst = (int *)string_ptrs[i].get();
|
|
||||||
for (j = 0; j < ubuild_langstring_num; j++)
|
|
||||||
{
|
|
||||||
// Does this string reference another language string directly?
|
|
||||||
while (lst[j] < 0)
|
|
||||||
{
|
|
||||||
// Search through list of language string references
|
|
||||||
for (l = 0; (unsigned int)l < rec.getlen() / sizeof(int); l++)
|
|
||||||
{
|
|
||||||
if (((int*)rec.get())[l] == lst[j])
|
|
||||||
{
|
|
||||||
// We have the index of a recursive language string; now find the name
|
|
||||||
const char *name = "(unnamed)";
|
|
||||||
for (l = 0; l < ubuild_langstring_num; l++)
|
|
||||||
if (lang_strings[l].uindex == j)
|
|
||||||
name = build_langstrings.offset2name(lang_strings[l].name);
|
|
||||||
ERROR_MSG("Error: LangString %s is recursive!\n", name);
|
|
||||||
delete [] string_ptrs;
|
|
||||||
return PS_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Add this reference to the list
|
|
||||||
rec.add(&lst[j], sizeof(int));
|
|
||||||
// and dereference it
|
|
||||||
lst[j] = lst[-lst[j] - 1];
|
|
||||||
}
|
|
||||||
rec.resize(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add language tables into their datablock
|
|
||||||
for (i = num_lang_tables; i--; )
|
|
||||||
{
|
|
||||||
ubuild_langtables.add(<[i].lang_id, sizeof(LANGID));
|
|
||||||
ubuild_langtables.add(<[i].dlg_offset, sizeof(int));
|
|
||||||
int rtl = lt[i].nlf.m_bRTL ? 1 : 0;
|
|
||||||
ubuild_langtables.add(&rtl, sizeof(int));
|
|
||||||
ubuild_langtables.add(string_ptrs[i].get(), string_ptrs[i].getlen());
|
|
||||||
string_ptrs[i].resize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
build_uninst.blocks[NB_LANGTABLES].num = num_lang_tables;
|
|
||||||
build_uninst.langtable_size = ubuild_langtables.getlen() / num_lang_tables;
|
|
||||||
|
|
||||||
set_uninstall_mode(0);
|
set_uninstall_mode(0);
|
||||||
|
if (GenerateLangTable(lt, num_lang_tables) != PS_OK)
|
||||||
|
return PS_ERROR;
|
||||||
|
|
||||||
|
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||||
|
set_uninstall_mode(1);
|
||||||
|
if (GenerateLangTable(lt, num_lang_tables) != PS_OK)
|
||||||
|
return PS_ERROR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
set_uninstall_mode(orig_uninstall_mode);
|
||||||
|
|
||||||
SCRIPT_MSG("Done!\n");
|
SCRIPT_MSG("Done!\n");
|
||||||
|
|
||||||
delete [] string_ptrs;
|
|
||||||
return PS_OK;
|
return PS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue