Language strings inside any other strings, $$ defines fix, both currently disabled by defines, support for /LANG in command VIAddVersionKey

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2652 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
ramon18 2003-06-16 19:58:29 +00:00
parent 45a9eb4ae7
commit a558797625
11 changed files with 200 additions and 21 deletions

View file

@ -7,14 +7,14 @@
#include "ResourceVersionInfo.h"
#ifdef NSIS_SUPPORT_VERSION_INFO
/*
int ValidCodePages[] = {
437, 708, 709, 710, 720, 737, 775, 850, 852, 855, 85, 86, 86, 86, 86, 864,
865, 866, 869, 874, 932, 936, 949, 950, 1200, 1250, 1251, 1252, 1253, 1254,
1255, 1256, 1257, 1258, 20000, 20001, 20002, 20003, 20004, 20005, 20127, 20261,
20269, 20866, 21027, 21866, 28591, 28592, 28593, 28594, 28595, 28596, 28597, 28598,
28599, 29001, 1361, 0 };
*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@ -253,7 +253,7 @@ char *CResourceVersionInfo::FindKey(LANGID LangID, int codepage, char *pKeyName)
DefineList *pStrings = m_ChildStringLists.get_strings(pos);
return pStrings->find(pKeyName);
}
/*
bool CResourceVersionInfo::IsValidCodePage(WORD codePage )
{
int *pCP = ValidCodePages;
@ -266,4 +266,5 @@ bool CResourceVersionInfo::IsValidCodePage(WORD codePage )
}
return false;
}
*/
#endif

View file

@ -91,7 +91,7 @@ public:
LANGID GetLangID(int Index);
int GetCodePage(int Index);
char *FindKey(LANGID LangID, int codepage, char *pKeyName);
bool IsValidCodePage(WORD codePage );
//bool IsValidCodePage(WORD codePage );
};
#endif

View file

@ -415,7 +415,11 @@ int CEXEBuild::add_intstring(const int i) // returns offset in stringblock
}
// based on Dave Laundon's code
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
int CEXEBuild::preprocess_string(char *out, const char *in, bool bUninstall)
#else
int CEXEBuild::preprocess_string(char *out, const char *in)
#endif
{
#ifndef NSIS_SUPPORT_NAMED_USERVARS
static const char VarNames[] =
@ -494,8 +498,12 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
*out++ = (char)255;
}
#else
// Test for characters that equals to control char of variable codes
if (i == VAR_CODES_START || i == 255 ) {
// Test for characters that equals to control char of variable codes or lang strings
if (i == VAR_CODES_START ||
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
i == LANG_CODES_START ||
#endif
i == 255 ) {
*out++ = (char)255;
}
#endif
@ -549,6 +557,57 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
pUserVarName--;
}
}
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
if ( !bProceced && *p == '(' )
{
int idx = -1;
char *cp = strdup(p+1);
char *pos = strchr(cp, ')');
if (pos)
{
*pos = 0;
if ( !bUninstall )
{
if (!strnicmp(cp,"un.",3)) {
warning("Installer language strings can't start with un. (%s)! (%s:%d)", p, curfilename, linecnt);
}
else
{
idx = GetUserString(cp);
if ( idx >= 0 )
{
idx = -((int)(idx+1+(sizeof(common_strings)+sizeof(installer_strings))/sizeof(int)));
*out++=(unsigned int)LANG_CODES_START; // Next word is lang-string Identifier
*(WORD*)out=(WORD)idx;
out += sizeof(WORD);
p += strlen(cp)+2;
bProceced = true;
}
}
}
else
{
if (strnicmp(cp,"un.",3)) {
warning("Uninstaller language strings must start with un. (%s)! (%s:%d)", p, curfilename, linecnt);
}
else
{
idx = GetUserString(cp);
if ( idx >= 0 )
{
idx = -((int)(idx+1+(sizeof(common_strings)+sizeof(uninstall_strings))/sizeof(int)));
*out++=(unsigned int)LANG_CODES_START; // Next word is lang-string Identifier
*(WORD*)out=(WORD)idx;
out += sizeof(WORD);
p += strlen(cp)+2;
bProceced = true;
}
}
}
}
free(cp);
}
#endif
if ( bProceced )
continue;
else
@ -556,6 +615,8 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
{
char tbuf[64];
char cBracket = '\0';
bool bDoWarning = true;
if ( *p == '[' )
cBracket = ']';
else if ( *p == '(' )
@ -569,12 +630,19 @@ int CEXEBuild::preprocess_string(char *out, const char *in)
if ( cBracket != 0 )
{
if (strchr(tbuf,cBracket)) (strchr(tbuf,cBracket)+1)[0]=0;
if ( tbuf[0] == '{' && tbuf[strlen(tbuf)-1] == '}' )
{
char *tstIfDefine = strdup(tbuf+1);
tstIfDefine[strlen(tstIfDefine)-1] = '\0';
bDoWarning = definedlist.find(tstIfDefine) == NULL;
}
}
else
{
if (strstr(tbuf," ")) strstr(tbuf," ")[0]=0;
}
warning("unknown variable \"%s\" detected, ignoring (%s:%d)",tbuf,curfilename,linecnt);
if ( bDoWarning )
warning("unknown variable \"%s\" detected, ignoring (%s:%d)",tbuf,curfilename,linecnt);
i = '$';
}
}
@ -594,7 +662,11 @@ int CEXEBuild::add_string_main(const char *string, int process) // returns offse
int idx = -1;
char *cp = strdup(string+2);
char *p = strchr(cp, ')');
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
if (p && p[1] == '\0' ) { // if string is only a language str identifier
#else
if (p) {
#endif
*p = 0;
if (!strnicmp(cp,"un.",3)) {
warning("Installer language strings can't start with un. (%s)! (%s:%d)", string, curfilename, linecnt);
@ -610,7 +682,11 @@ int CEXEBuild::add_string_main(const char *string, int process) // returns offse
if (!process) return build_strlist.add(string,2);
char buf[4096];
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
preprocess_string(buf,string, false);
#else
preprocess_string(buf,string);
#endif
return build_strlist.add(buf,2);
}
@ -622,7 +698,11 @@ int CEXEBuild::add_string_uninst(const char *string, int process) // returns off
int idx = -1;
char *cp = strdup(string+2);
char *p = strchr(cp, ')');
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
if (p && p[1] == '\0' ) { // if string is only a language str identifier
#else
if (p) {
#endif
*p = 0;
if (strnicmp(cp,"un.",3)) {
warning("Uninstaller language strings must start with un. (%s)! (%s:%d)", string, curfilename, linecnt);
@ -638,7 +718,11 @@ int CEXEBuild::add_string_uninst(const char *string, int process) // returns off
if (!process) return ubuild_strlist.add(string,2);
char buf[4096];
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
preprocess_string(buf,string, true);
#else
preprocess_string(buf,string);
#endif
return ubuild_strlist.add(buf,2);
}

View file

@ -113,7 +113,11 @@ class CEXEBuild {
void restore_line_predefine(char *);
#endif
int parseScript();
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines = false);
#else
void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist);
#endif
int doParse(const char *str);
int doCommand(int which_token, LineParser &line);
int do_add_file(const char *lgss, int attrib, int recurse, int linecnt, int *total_files, const char *name_override=0, int generatecode=1, int *data_handle=0, int rec_depth=0);
@ -144,7 +148,11 @@ class CEXEBuild {
int add_intstring(const int i); // returns offset in stringblock
int add_string_main(const char *string, int process=1); // returns offset (in string table)
int add_string_uninst(const char *string, int process=1); // returns offset (in string table)
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
int preprocess_string(char *out, const char *in, bool bUninstall);
#else
int preprocess_string(char *out, const char *in);
#endif
int make_sure_not_in_secorfunc(const char *str);

View file

@ -210,6 +210,11 @@
// NSIS_SUPPORT_VERSION_INFO enables support for version information on final exe
#define NSIS_SUPPORT_VERSION_INFO
// NSIS_SUPPORT_LANG_IN_STRINGS enables support for language strings inside other strings
//#define NSIS_SUPPORT_LANG_IN_STRINGS
// NSIS_FIX_DEFINES_IN_STRINGS fix defines inside defines and handles chars $ perfectly
//#define NSIS_FIX_DEFINES_IN_STRINGS
// Added by Ximon Eighteen 5th August 2002
// If this is uncommented the following changes/new features are

View file

@ -106,7 +106,11 @@ static int *parms;
static int NSISCALL process_string_fromparm_toint(int id_)
{
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
return myatoi(process_string(GetStringFromStringTab(parms[id_]), 0));
#else
return myatoi(process_string(GetStringFromStringTab(parms[id_])));
#endif
}
// NB - USE CAUTION when rearranging code to make use of the new return value of

View file

@ -524,6 +524,10 @@ DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove, DWORD dwMoveMethod);
#endif
#endif
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
#define LANG_CODES_START 251
#endif
union installer_flags {
struct {
int autoclose;

View file

@ -333,7 +333,11 @@ char ps_tmpbuf[NSIS_MAX_STRLEN*2];
char * NSISCALL process_string_fromtab(char *out, int offs)
{
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
char *p=process_string(GetStringFromStringTab(offs), 0);
#else
char *p=process_string(GetStringFromStringTab(offs));
#endif
if (!out) return p;
return lstrcpyn(out,p,NSIS_MAX_STRLEN);
}
@ -394,9 +398,17 @@ int NSISCALL mystrlen(const char *in)
}
// Dave Laundon's simplified process_string
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
char * NSISCALL process_string(const char *in, int iStartIdx )
#else
char * NSISCALL process_string(const char *in)
#endif
{
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
char *out = ps_tmpbuf+iStartIdx;
#else
char *out = ps_tmpbuf;
#endif
while (*in && out - ps_tmpbuf < NSIS_MAX_STRLEN)
{
int nVarIdx = (unsigned char)*in++;
@ -525,11 +537,7 @@ char * NSISCALL process_string(const char *in)
{
*out++ = *in++;
}
else if (nVarIdx != VAR_CODES_START)
{
*out++ = nVarIdx;
}
else
else if (nVarIdx == VAR_CODES_START)
{
DWORD f;
static char smwcvesf[]="Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
@ -613,6 +621,19 @@ char * NSISCALL process_string(const char *in)
}
out+=mystrlen(out);
} // == VAR_CODES_START
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
else if ( nVarIdx == LANG_CODES_START )
{
char *p;
nVarIdx = *(short*)in; in+=sizeof(WORD);
p = process_string(GetStringFromStringTab(nVarIdx), out-ps_tmpbuf);
out+=mystrlen(out);
}
#endif
else // Normal char
{
*out++ = nVarIdx;
}
#endif
} // while
*out = 0;

View file

@ -1,7 +1,11 @@
#include "config.h"
extern char ps_tmpbuf[NSIS_MAX_STRLEN*2];
#ifdef NSIS_SUPPORT_LANG_IN_STRINGS
char * NSISCALL process_string(const char *in, int iStartIdx);
#else
char * NSISCALL process_string(const char *in);
#endif
char * NSISCALL process_string_fromtab(char *out, int offs);
void NSISCALL myRegGetStr(HKEY root, const char *sub, const char *name, char *out);
int NSISCALL myatoi(char *s);

View file

@ -344,7 +344,11 @@ parse_again:
return PS_OK;
}
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines /*= false*/)
#else
void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist)
#endif
{
// convert $\r, $\n to their literals
// preprocessor replace ${VAR} with whatever value
@ -396,7 +400,11 @@ void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &his
if (*t == '}' && bn-- == 0) break;
t=CharNext(t);
}
if (*t && t!=s)
if (*t && t!=s
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
&& !bIgnoreDefines
#endif
)
{
*t=0;
// check for defines inside the define name - ${bla${blo}}
@ -409,12 +417,47 @@ void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &his
in+=strlen(s)+2;
add=0;
hist.add((char*)defname.get(),0);
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
ps_addtoline(t,linedata,hist, true);
#else
ps_addtoline(t,linedata,hist);
#endif
hist.delbypos(hist.find((char*)defname.get(),0));
}
}
free(s);
}
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
else if (in[0] == '$' )
{
if ( in[1] == '{' ) // Found $$ before - Don't replace this define
{
char *s=strdup(in+2);
char *t=s;
unsigned int bn = 0;
while (*t)
{
if (*t == '{') bn++;
if (*t == '}' && bn-- == 0) break;
t=CharNext(t);
}
if (*t && t!=s )
{
*t=0;
// add text unchanged
GrowBuf defname;
ps_addtoline(s,defname,hist);
in++;
}
free(s);
}
else
{
linedata.add((void*)&c,1);
in++;
}
}
#endif
}
if (add) linedata.add((void*)&c,1);
}
@ -4570,9 +4613,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
#ifdef NSIS_SUPPORT_VERSION_INFO
case TOK_VI_ADDKEY:
{
LANGID LangID = line.gettoken_int(1);
char *pKey = line.gettoken_str(2);
char *pValue = line.gettoken_str(3);
LANGID LangID=0;
int a = 1;
if (!strnicmp(line.gettoken_str(a),"/LANG=",6))
LangID=atoi(line.gettoken_str(a++)+6);
if (line.getnumtokens()!=a+2) PRINTHELP();
char *pKey = line.gettoken_str(a);
char *pValue = line.gettoken_str(a+1);
if ( !(*pKey) )
{
ERROR_MSG("Error: empty name for version info key!\n");
@ -4580,10 +4627,11 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
}
else
{
SCRIPT_MSG("%s: \"%s\" \"%s\" \"%s\"\n", line.gettoken_str(0), line.gettoken_str(1), line.gettoken_str(2), line.gettoken_str(3));
SCRIPT_MSG("%s: \"%s\" \"%s\"\n", line.gettoken_str(0), line.gettoken_str(a), line.gettoken_str(a+1));
LANGID lReaded = LangID;
StringTable *strTable = GetTable(LangID);
if ( line.gettoken_int(1) == 0 && !strTable->nlf )
warning("%s: \"%s\" language not loaded, using default \"1033-English\". (%s:%d)", line.gettoken_str(0), line.gettoken_str(1), curfilename,linecnt);
if ( a > 1 && lReaded == 0 )
warning("%s: %s language not loaded, using default \"1033-English\". (%s:%d)", line.gettoken_str(0), line.gettoken_str(1), curfilename,linecnt);
if ( rVersionInfo.SetKeyValue(LangID, strTable->nlf ? strTable->nlf->m_uCodePage : 1252 /*English US*/, pKey, pValue) )
{
ERROR_MSG("%s: \"%s\" \"%04d-%s\" already defined!\n",line.gettoken_str(0), line.gettoken_str(2), LangID, strTable->nlf ? strTable->nlf->m_szName : LangID == 1033 ? "English" : "???");

View file

@ -230,8 +230,8 @@ static tokenType tokenlist[TOK__LAST] =
// Added by ramon 3 jun 2003
{TOK_DEFVAR,"dim",1,0,"VarName"},
// Added by ramon 6 jun 2003
{TOK_VI_ADDKEY,"VIAddVersionKey", 3, 0, "lang_id keyname value"},
{TOK_VI_SETPRODUCTVERSION,"VIProductVersion", 1, 0, "[version string X.X.X.X]"},
{TOK_VI_ADDKEY,"VIAddVersionKey", 2, 1, "[/LANG=lang_id] keyname value"},
{TOK_VI_SETPRODUCTVERSION,"VIProductVersion", 1, 0, "[version_string_X.X.X.X]"},
};
void CEXEBuild::print_help(char *commandname)