From f758230f191e06ec5f0256c8c30e4de5ea68bc37 Mon Sep 17 00:00:00 2001 From: ramon18 Date: Mon, 9 Jun 2003 18:59:14 +0000 Subject: [PATCH] Comments like C/C++; Added commands to support VersionInformation (VIProductVersion, VIProductName, VICompanyName, VIComments, VILegalTrademarks, VILegalCopyrights, VIDescription); Support to named user variables (up to 500) but disabled by define git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2623 212acab6-be3b-0410-9dea-997c60f758d6 --- Examples/VersionInfo.nsi | 59 ++++++ Source/ResourceVersionInfo.cpp | 184 ++++++++++++++++++ Source/ResourceVersionInfo.h | 39 ++++ Source/build.cpp | 331 +++++++++++++++++++++++++++------ Source/build.h | 18 ++ Source/exehead/config.h | 15 ++ Source/exehead/fileform.h | 5 + Source/exehead/state.h | 7 +- Source/exehead/util.c | 39 +++- Source/lineparse.h | 34 +++- Source/makenssi.dsp | 8 + Source/script.cpp | 191 +++++++++++++------ Source/tokens.cpp | 12 +- Source/tokens.h | 9 + 14 files changed, 823 insertions(+), 128 deletions(-) create mode 100644 Examples/VersionInfo.nsi create mode 100644 Source/ResourceVersionInfo.cpp create mode 100644 Source/ResourceVersionInfo.h diff --git a/Examples/VersionInfo.nsi b/Examples/VersionInfo.nsi new file mode 100644 index 00000000..37eda532 --- /dev/null +++ b/Examples/VersionInfo.nsi @@ -0,0 +1,59 @@ +;NSIS Modern User Interface version 1.65 +;User variables Example Script +;Written by Ramon + +;-------------------------------- +;Include Modern UI + +!include "MUI.nsh" + +;-------------------------------- +;Product Info + +!define MUI_PRODUCT "User Variables" +!define MUI_VERSION "1.65" + +;-------------------------------- +;Configuration + + ;General + OutFile "VersionInfo.exe" + + ;Folder selection page + InstallDir "$PROGRAMFILES\${MUI_PRODUCT}" + + ;Get install folder from registry if available + InstallDirRegKey HKCU "Software\${MUI_PRODUCT}" "" + + ShowInstDetails nevershow + +;-------------------------------- +;Version Information + VIProductVersion "1.2.3.4" + VIProductName "NSIS" + VIComments "visit us at nsis.sourceforge.net" + VICompanyName "NSIS Team" + VILegalTrademarks "NullSoft Installer System" + VILegalCopyrights "NullSoft Installer System" + VIDescription "NSIS Self-extracting Setup" + +;-------------------------------- +;Pages + + !insertmacro MUI_PAGE_INSTFILES + !insertmacro MUI_PAGE_FINISH + +;-------------------------------- +;Languages + + !insertmacro MUI_LANGUAGE "English" + +;-------------------------------- +;Installer Sections + +Section "Dummy Section" SecCopyUI + + /* Copy your files here */ + +SectionEnd + diff --git a/Source/ResourceVersionInfo.cpp b/Source/ResourceVersionInfo.cpp new file mode 100644 index 00000000..1091c485 --- /dev/null +++ b/Source/ResourceVersionInfo.cpp @@ -0,0 +1,184 @@ +// ResourceVersionInfo.cpp: implementation of the CResourceVersionInfo class. +// +////////////////////////////////////////////////////////////////////// + +#include +#include "build.h" + +#include "ResourceVersionInfo.h" +#ifdef NSIS_SUPPORT_VERSION_INFO +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// +CResourceVersionInfo::CResourceVersionInfo() +{ + memset(&m_FixedInfo, 0, sizeof(VS_FIXEDFILEINFO)); + m_FixedInfo.dwSignature = 0xFEEF04BD; + m_FixedInfo.dwFileOS = VOS__WINDOWS32; + m_FixedInfo.dwFileType = VFT_APP; +} + +CResourceVersionInfo::~CResourceVersionInfo() +{ + +} + +void CResourceVersionInfo::SetFileFlags(int Value) +{ + m_FixedInfo.dwFileFlags = (m_FixedInfo.dwFileFlags & ~(m_FixedInfo.dwFileFlagsMask)) || Value; +} + +void CResourceVersionInfo::SetFileVersion(int HighPart, int LowPart) +{ + m_FixedInfo.dwFileVersionLS = LowPart; + m_FixedInfo.dwFileVersionMS = HighPart; +} + +void CResourceVersionInfo::SetProductVersion(int HighPart, int LowPart) +{ + m_FixedInfo.dwProductVersionLS = LowPart; + m_FixedInfo.dwProductVersionMS = HighPart; +} + +// Util function +wstring StrToWstr(const string& istr) +{ + wstring wstr; + for(string::const_iterator it = istr.begin(); it != istr.end(); ++it) + { + wstr += *it; + } return wstr; +} + +int GetVersionHeader (LPSTR &p, WORD &wLength, WORD &wValueLength, WORD &wType) +{ + WCHAR *szKey; + char * baseP; + + baseP = p; + wLength = *(WORD*)p; + p += sizeof(WORD); + wValueLength = *(WORD*)p; + p += sizeof(WORD); + wType = *(WORD*)p; + p += sizeof(WORD); + szKey = (WCHAR*)p; + p += (wcslen(szKey) + 1) * sizeof (WCHAR); + while ( ((long)p % 4) != 0 ) + p++; + return p - baseP; +} + +DWORD ZEROS = 0; + +void PadStream (GrowBuf &strm) +{ + if ( (strm.getlen() % 4) != 0 ) + strm.add (&ZEROS, 4 - (strm.getlen() % 4)); +} + +void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const wstring &key, void *value) +{ + WORD valueLen; + WORD keyLen; + + strm.add (&wLength, sizeof (wLength)); + + strm.add (&wValueLength, sizeof (wValueLength)); + strm.add (&wType, sizeof (wType)); + keyLen = (key.length() + 1) * sizeof (WCHAR); + strm.add ((void*)key.c_str(), keyLen); + + PadStream(strm); + + if ( wValueLength > 0 ) + { + valueLen = wValueLength; + if ( wType == 1 ) + valueLen = valueLen * sizeof (WCHAR); + strm.add (value, valueLen); + } +} + +void CResourceVersionInfo::ExportToStream(GrowBuf &strm) +{ + DWORD v; + WORD wSize; + int p, p1; + wstring KeyName, KeyValue; + + SaveVersionHeader (strm, 0, sizeof (VS_FIXEDFILEINFO), 0, L"VS_VERSION_INFO", &m_FixedInfo); + + if ( m_ChildStrings.getnum() > 0 ) + { + GrowBuf stringInfoStream; + + SaveVersionHeader (stringInfoStream, 0, 0, 0, VERINFO_LANGUAGE, &ZEROS); + + for ( int i = 0; i < m_ChildStrings.getnum(); i++ ) + { + PadStream (stringInfoStream); + + p = stringInfoStream.getlen(); + KeyName = StrToWstr(m_ChildStrings.getname(i)); + KeyValue = StrToWstr(m_ChildStrings.getvalue(i)); + SaveVersionHeader (stringInfoStream, 0, KeyValue.length() + 1, 1, KeyName.c_str(), (void*)KeyValue.c_str()); + wSize = stringInfoStream.getlen() - p; + + *(WORD*)((PBYTE)stringInfoStream.get()+p)=wSize; + } + + wSize = stringInfoStream.getlen(); + *(WORD*)((PBYTE)stringInfoStream.get())=wSize; + + PadStream (strm); + p = strm.getlen(); + SaveVersionHeader (strm, 0, 0, 0, L"StringFileInfo", &ZEROS); + strm.add (stringInfoStream.get(), stringInfoStream.getlen()); + wSize = strm.getlen() - p; + + *(WORD*)((PBYTE)strm.get()+p)=wSize; + } + + if ( m_Translations.size() > 0 ) + { + PadStream (strm); + p = strm.getlen(); + SaveVersionHeader (strm, 0, 0, 0, L"VarFileInfo", &ZEROS); + PadStream (strm); + + p1 = strm.getlen(); + SaveVersionHeader (strm, 0, 0, 0, L"Translation", &ZEROS); + + for ( int i = 0; i < m_Translations.size(); i++ ) + { + v = m_Translations[i]; + strm.add (&v, sizeof (v)); + } + + wSize = strm.getlen() - p1; + *(WORD*)((PBYTE)strm.get()+p1)=wSize; + wSize = sizeof (int) * m_Translations.size(); + p1+=sizeof(WORD); + *(WORD*)((PBYTE)strm.get()+p1)=wSize; + + wSize = strm.getlen() - p; + *(WORD*)((PBYTE)strm.get()+p)=wSize; + } + + wSize = strm.getlen(); + *(WORD*)((PBYTE)strm.get())=wSize; +} + +void CResourceVersionInfo::SetKeyValue(char* AKeyName, char* AValue) +{ + m_ChildStrings.add(AKeyName, AValue); +} + +void CResourceVersionInfo::AddTranslation(WORD CodePage, WORD LangID ) +{ + DWORD dwTrans = MAKELONG(LangID, CodePage); + if ( find(m_Translations.begin(), m_Translations.end(), dwTrans) == m_Translations.end() ) + m_Translations.push_back(dwTrans); +} +#endif \ No newline at end of file diff --git a/Source/ResourceVersionInfo.h b/Source/ResourceVersionInfo.h new file mode 100644 index 00000000..f20d9060 --- /dev/null +++ b/Source/ResourceVersionInfo.h @@ -0,0 +1,39 @@ +// ResourceVersionInfo.h: interface for the CResourceVersionInfo class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_) +#define AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifdef NSIS_SUPPORT_VERSION_INFO + +#include +using namespace std; + +#define VERINFO_LANGUAGE L"040904b0" // English language and codepage +#define VERINFO_TRANSLATION 0x04B00409 // English language and codepage +///////////////////////////////////////////////////////////////////////////////////////////// +class CResourceVersionInfo +{ + VS_FIXEDFILEINFO m_FixedInfo; + DefineList m_ChildStrings; + vector< DWORD > m_Translations; + +public: + CResourceVersionInfo(); + virtual ~CResourceVersionInfo(); + void SetKeyValue (char *AKeyName, char *AValue); + void AddTranslation(WORD CodePage, WORD LangID ); + void SetFileFlags(int Value); + void SetFileVersion(int HighPart, int LowPart); + void SetProductVersion(int HighPart, int LowPart); + void ExportToStream(GrowBuf &strm); +}; + +#endif + +#endif // !defined(AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_) diff --git a/Source/build.cpp b/Source/build.cpp index c30bdf06..f3052f9f 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -11,6 +11,7 @@ #include "ResourceEditor.h" #include "exehead/resource.h" #include "exehead/lang.h" +#include "ResourceVersionInfo.h" void CEXEBuild::define(const char *p, const char *v) { @@ -238,6 +239,12 @@ CEXEBuild::CEXEBuild() // Added by ramon 23 May 2003 build_allowskipfiles=1; + // Added by ramon 6 jun 2003 +#ifdef NSIS_SUPPORT_VERSION_INFO + szVIProductVersion[0]=szVIProductName[0]=szVICompanyName[0]=0; + szVIComments[0]=szVILegalTrademarks[0]=szVILegalCopyrights[0]=szVIDescription[0]=0; +#endif + build_overwrite=0; build_compress=1; build_crcchk=1; @@ -347,51 +354,51 @@ int CEXEBuild::add_intstring(const int i) // returns offset in stringblock // based on Dave Laundon's code int CEXEBuild::preprocess_string(char *out, const char *in) { - static const char VarNames[] = - "HWNDPARENT\0" // 0 - "0\0" // 1 - "1\0" // 2 - "2\0" // 3 - "3\0" // 4 - "4\0" // 5 - "5\0" // 6 - "6\0" // 7 - "7\0" // 8 - "8\0" // 9 - "9\0" // 10 - "R0\0" // 11 - "R1\0" // 12 - "R2\0" // 13 - "R3\0" // 14 - "R4\0" // 15 - "R5\0" // 16 - "R6\0" // 17 - "R7\0" // 18 - "R8\0" // 19 - "R9\0" // 20 - "CMDLINE\0" // 21 everything before here doesn't have trailing slash removal - - "INSTDIR\0" // 22 - "OUTDIR\0" // 23 - "EXEDIR\0" // 24 - "LANGUAGE\0" // 25 - "PLUGINSDIR\0" // 26 - "PROGRAMFILES\0" // 27 - "SMPROGRAMS\0" // 28 - "SMSTARTUP\0" // 29 - "DESKTOP\0" // 30 - "STARTMENU\0" // 31 - "QUICKLAUNCH\0" // 32 - "TEMP\0" // 33 - "WINDIR\0" // 34 - "SYSDIR\0" // 35 - ; - + static const char VarNames[] = + "HWNDPARENT\0" // 0 + "0\0" // 1 + "1\0" // 2 + "2\0" // 3 + "3\0" // 4 + "4\0" // 5 + "5\0" // 6 + "6\0" // 7 + "7\0" // 8 + "8\0" // 9 + "9\0" // 10 + "R0\0" // 11 + "R1\0" // 12 + "R2\0" // 13 + "R3\0" // 14 + "R4\0" // 15 + "R5\0" // 16 + "R6\0" // 17 + "R7\0" // 18 + "R8\0" // 19 + "R9\0" // 20 + "CMDLINE\0" // 21 everything before here doesn't have trailing slash removal + + "INSTDIR\0" // 22 + "OUTDIR\0" // 23 + "EXEDIR\0" // 24 + "LANGUAGE\0" // 25 + "PLUGINSDIR\0" // 26 + "PROGRAMFILES\0" // 27 + "SMPROGRAMS\0" // 28 + "SMSTARTUP\0" // 29 + "DESKTOP\0" // 30 + "STARTMENU\0" // 31 + "QUICKLAUNCH\0" // 32 + "TEMP\0" // 33 + "WINDIR\0" // 34 + "SYSDIR\0" // 35 + ; + const char *p=in; while (*p) { const char *np=CharNext(p); - + if (np-p > 1) // multibyte char { int l=np-p; @@ -405,11 +412,11 @@ int CEXEBuild::preprocess_string(char *out, const char *in) } continue; } - + int i = (unsigned char)*p; - + p=np; - + // Test for characters extending into the variable codes if (i >= VAR_CODES_START) { *out++ = (char)255; @@ -423,26 +430,86 @@ int CEXEBuild::preprocess_string(char *out, const char *in) const char *pVarName; for ( pVarName = VarNames, i = VAR_CODES_START; - strncmp(pVarName, p, strlen(pVarName)); - pVarName += strlen(pVarName) + 1, i++ - ); + strncmp(pVarName, p, strlen(pVarName)); + pVarName += strlen(pVarName) + 1, i++ + ); // Found? if (*pVarName #ifndef NSIS_CONFIG_PLUGIN_SUPPORT - && i != VAR_CODES_START + 26 + && i != VAR_CODES_START + USER_VARS_COUNT #endif - ) + ) { p += strlen(pVarName); } else // warning should go here { - char tbuf[64]; - strncpy(tbuf,p,63); - tbuf[63]=0; - if (strstr(tbuf," ")) strstr(tbuf," ")[0]=0; - warning("unknown variable \"%s\" detected, ignoring (%s:%d)",tbuf,curfilename,linecnt); - i = '$'; +#ifdef NSIS_SUPPORT_NAMED_USERVARS + bool bProceced=false; + if ( *p == '[' ) + { + char *pUserVarName = (char *)p+1; + while ( *pUserVarName ) + { + if ( *pUserVarName == ']' ) + { + *pUserVarName='\0'; + int idxUserVar = m_UserVarNames.get((char*)p+1); + int varLen = strlen(p)+1; + *pUserVarName=']'; // restore + if ( idxUserVar >= 0 ) + { + *out++=(unsigned int)VAR_CODES_START + 36; // Named user variable; + *(WORD*)out=((WORD)idxUserVar+USER_VARS_COUNT) | 0xF000; + out += sizeof(WORD); + p += varLen; + bProceced = true; + { + for ( WORD i = 0; i < 0x0FFF; i++ ) + { + WORD bb = i | 0xF000; + WORD ok = bb & 0x0FFF; + if ( ok != i ) + { + warning("Problems with %d",i); + } + + } + } + } + break; + } + pUserVarName++; + } + } + if ( bProceced ) + continue; + else +#endif + { + char tbuf[64]; + char cBracket = '\0'; + if ( *p == '[' ) + cBracket = ']'; + else if ( *p == '(' ) + cBracket = ')'; + else if ( *p == '{' ) + cBracket = '}'; + + strncpy(tbuf,p,63); + tbuf[63]=0; + + if ( cBracket != 0 ) + { + if (strchr(tbuf,cBracket)) (strchr(tbuf,cBracket)+1)[0]=0; + } + else + { + if (strstr(tbuf," ")) strstr(tbuf," ")[0]=0; + } + warning("unknown variable \"%s\" detected, ignoring (%s:%d)",tbuf,curfilename,linecnt); + i = '$'; + } } } } @@ -1201,6 +1268,76 @@ int CEXEBuild::resolve_coderefs(const char *str) int CEXEBuild::write_output(void) { +#ifdef NSIS_SUPPORT_VERSION_INFO + CResourceVersionInfo ResourceVersionInfo; + GrowBuf VerInfoStream; + bool bNeedVInfo = false; + + ResourceVersionInfo.SetFileFlags(VS_FF_DEBUG); + + if ( szVIProductVersion[0] ) { + ResourceVersionInfo.SetKeyValue("ProductVersion", szVIProductVersion); + ResourceVersionInfo.SetKeyValue("FileVersion", szVIProductVersion); // this is needed to explorer show version tab with some info + bNeedVInfo = true; + } + + if ( szVIProductName[0] ) { + ResourceVersionInfo.SetKeyValue("ProductName", szVIProductName); + bNeedVInfo = true; + } + + if ( szVICompanyName[0] ) { + ResourceVersionInfo.SetKeyValue("CompanyName", szVICompanyName); + bNeedVInfo = true; + } + + if ( szVIComments[0] ) { + ResourceVersionInfo.SetKeyValue("Comments", szVIComments); + bNeedVInfo = true; + } + + if ( szVILegalTrademarks[0] ) { + ResourceVersionInfo.SetKeyValue("LegalTrademarks", szVILegalTrademarks); + bNeedVInfo = true; + } + + if ( szVILegalCopyrights[0] ) { + ResourceVersionInfo.SetKeyValue("LegalCopyright", szVILegalCopyrights); + bNeedVInfo = true; + } + + if ( szVIDescription[0] ) { + ResourceVersionInfo.SetKeyValue("FileDescription", szVIDescription); + bNeedVInfo = true; + } + + if ( bNeedVInfo ) + { + if ( !szVIProductVersion[0] ) + { + ERROR_MSG("Error: VIProductVersion is required when other version information functions are used.\n"); + return PS_ERROR; + } + else + { + int imm, iml, ilm, ill; + if ( sscanf(szVIProductVersion, "%d.%d.%d.%d", &imm, &iml, &ilm, &ill) != 4 ) + { + ERROR_MSG("Error: invalid VIProductVersion format, should be X.X.X.X\n"); + return PS_ERROR; + } + ResourceVersionInfo.SetFileVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm)); + ResourceVersionInfo.SetProductVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm)); + ResourceVersionInfo.SetKeyValue("InternalName", build_output_filename); + ResourceVersionInfo.AddTranslation(0x0,0x0409); + ResourceVersionInfo.ExportToStream(VerInfoStream); + init_res_editor(); + res_editor->UpdateResource(RT_VERSION, 1, 0, (BYTE*)VerInfoStream.get(), VerInfoStream.getlen()); + } + } + +#endif // NSIS_SUPPORT_VERSION_INFO + #ifndef NSIS_CONFIG_CRC_SUPPORT build_crcchk=0; #endif @@ -2396,3 +2533,87 @@ void CEXEBuild::close_res_editor() delete res_editor; res_editor=0; } + +// Added by ramon 3 jun 2003 +#ifdef NSIS_SUPPORT_NAMED_USERVARS +int CEXEBuild::DeclaredUserVar(const char *szVarName) +{ + int idxUserVar = m_UserVarNames.get((char*)szVarName); + if ( idxUserVar > 0 ) + { + ERROR_MSG("Error: variable \"%s\" already declared\n", szVarName); + return PS_ERROR; + } + const char *pVarName = szVarName; + int iVarLen = strlen(szVarName); + + if ( iVarLen > 60 ) + { + ERROR_MSG("Error: variable name too long!\n"); + return PS_ERROR; + } + else if ( !iVarLen ) + { + ERROR_MSG("Error: variable with empty name!\n"); + return PS_ERROR; + } + else + { + while ( *pVarName ) + { + if ((*pVarName < '0') || + (*pVarName > '9' && *pVarName < 'A' ) || + (*pVarName > 'Z' && *pVarName < 'a' && *pVarName != '_' ) || + (*pVarName > 'z') ) + { + ERROR_MSG("Error: invalid charaters in variable name \"%s\"\n", szVarName); + return PS_ERROR; + } + pVarName++; + } + } + + m_UserVarNames.add(szVarName); + if ( m_UserVarNames.getnum() > MAX_NAMED_USER_VARS ) + { + ERROR_MSG("Error: too many user variables declared!\n"); + return PS_ERROR; + } + return PS_OK; +} +#endif + +int CEXEBuild::GetUserVarIndex(LineParser &line, int token) +{ + static const char *usrvars="$0\0$1\0$2\0$3\0$4\0$5\0$6\0$7\0$8\0$9\0" + "$R0\0$R1\0$R2\0$R3\0$R4\0$R5\0$R6\0$R7\0$R8\0$R9\0" + "$CMDLINE\0$INSTDIR\0$OUTDIR\0$EXEDIR\0$LANGUAGE\0"; + int res = line.gettoken_enum(token, usrvars); +// Added by ramon 3 jun 2003 +#ifdef NSIS_SUPPORT_NAMED_USERVARS + if ( res < 0 ) + { + char *p = line.gettoken_str(token); + if ( *p == '$' && *(p+1) == '[' ) + { + char *pUserVarName = (char *)p+2; + while ( *pUserVarName ) + { + if ( *pUserVarName == ']' ) + { + *pUserVarName='\0'; + int idxUserVar = m_UserVarNames.get((char*)p+2); + *pUserVarName=']'; // restore + if ( idxUserVar >= 0 ) + { + res=idxUserVar+USER_VARS_COUNT; // User named variable; + } + break; + } + pUserVarName++; + } + } + } +#endif + return res; +} diff --git a/Source/build.h b/Source/build.h index fad24fdd..aa1cccd2 100644 --- a/Source/build.h +++ b/Source/build.h @@ -169,6 +169,13 @@ class CEXEBuild { bool next_used, install_used, comppage_used, license_force_radio_used, register_used, unregister_used; + int GetUserVarIndex(LineParser &line, int token); +// Added by ramon 3 jun 2003 +#ifdef NSIS_SUPPORT_NAMED_USERVARS + LangStringList m_UserVarNames; + int DeclaredUserVar(const char *VarName); +#endif + // a whole bunch O data. #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT @@ -203,6 +210,17 @@ class CEXEBuild { char build_output_filename[1024]; char cur_out_path[1024]; + // Added by ramon 6 jun 2003 +#ifdef NSIS_SUPPORT_VERSION_INFO + char szVIProductVersion[1024]; + char szVIProductName[1024]; + char szVICompanyName[1024]; + char szVIComments[1024]; + char szVILegalTrademarks[1024]; + char szVILegalCopyrights[1024]; + char szVIDescription[1024]; +#endif + int subsection_open_cnt; FastStringList m_warnings; GrowBuf m_macros; diff --git a/Source/exehead/config.h b/Source/exehead/config.h index fa366a0d..8fa44513 100644 --- a/Source/exehead/config.h +++ b/Source/exehead/config.h @@ -26,6 +26,13 @@ // really a big deal, but not usually needed). #define NSIS_MAX_STRLEN 1024 +#define USER_VARS_COUNT 26 + +// MAX_NAMED_USER_VARS defines the maximum of named user variables +// the complier also use this value to abort if exceded +// The real maximum is (0x0FFF - USER_VARS_COUNT) = 4069 +// But 500 variables are a more than enough (and only consume more 512kb of memory) +#define MAX_NAMED_USER_VARS 500 // NSIS_MAX_INST_TYPES specified the maximum install types. // note that this should not exceed 32, ever. @@ -195,6 +202,14 @@ // NSIS_SUPPORT_MESSAGEBOX enables support for MessageBox #define NSIS_SUPPORT_MESSAGEBOX +// Added by ramon 3 jun 2003 +// NSIS_SUPPORT_NAMED_USERVARS enables support for user variables +//#define NSIS_SUPPORT_NAMED_USERVARS + +// Added by ramon 5 jun 2003 +// NSIS_SUPPORT_VERSION_INFO enables support for version information on final exe +#define NSIS_SUPPORT_VERSION_INFO + // Added by Ximon Eighteen 5th August 2002 // If this is uncommented the following changes/new features are diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h index 29708e8e..be7f7177 100644 --- a/Source/exehead/fileform.h +++ b/Source/exehead/fileform.h @@ -513,11 +513,16 @@ BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead); DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove, DWORD dwMoveMethod); // $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value. +// Added by ramon 3 jun 2003 +#ifdef NSIS_SUPPORT_NAMED_USERVARS + #define VAR_CODES_START (256 - 38) +#else #ifdef NSIS_CONFIG_PLUGIN_SUPPORT #define VAR_CODES_START (256 - 37) #else #define VAR_CODES_START (256 - 36) #endif +#endif union installer_flags { struct { diff --git a/Source/exehead/state.h b/Source/exehead/state.h index 6b2387a0..acb05354 100644 --- a/Source/exehead/state.h +++ b/Source/exehead/state.h @@ -1,6 +1,9 @@ extern char temp_directory[NSIS_MAX_STRLEN]; - -extern char g_usrvars[26][NSIS_MAX_STRLEN]; +#ifdef NSIS_SUPPORT_NAMED_USERVARS +extern char g_usrvars[MAX_NAMED_USER_VARS+USER_VARS_COUNT][NSIS_MAX_STRLEN]; +#else +extern char g_usrvars[USER_VARS_COUNT][NSIS_MAX_STRLEN]; +#endif extern char *state_command_line; extern char *state_install_directory; extern char *state_output_directory; diff --git a/Source/exehead/util.c b/Source/exehead/util.c index 00c976be..398c7203 100644 --- a/Source/exehead/util.c +++ b/Source/exehead/util.c @@ -16,7 +16,11 @@ char g_log_file[1024]; char temp_directory[NSIS_MAX_STRLEN]; -char g_usrvars[26][NSIS_MAX_STRLEN]; +#ifdef NSIS_SUPPORT_NAMED_USERVARS +char g_usrvars[MAX_NAMED_USER_VARS+USER_VARS_COUNT][NSIS_MAX_STRLEN]; +#else +char g_usrvars[USER_VARS_COUNT][NSIS_MAX_STRLEN]; +#endif char *state_command_line=g_usrvars[20]; char *state_install_directory=g_usrvars[21]; char *state_output_directory=g_usrvars[22]; @@ -398,11 +402,11 @@ char * NSISCALL process_string(const char *in) int nVarIdx = (unsigned char)*in++; if (nVarIdx < VAR_CODES_START) { - *out++ = nVarIdx; + *out++ = nVarIdx; } else if (nVarIdx == 255) { - *out++ = *in++; + *out++ = *in++; } else { @@ -439,9 +443,24 @@ char * NSISCALL process_string(const char *in) case VAR_CODES_START + 24: // EXEDIR case VAR_CODES_START + 25: // LANGUAGE case VAR_CODES_START + 26: // PLUGINSDIR +#ifdef NSIS_SUPPORT_NAMED_USERVARS + case VAR_CODES_START + 36: // NAMED USER VARS + { + if ( nVarIdx == (VAR_CODES_START + 36) ) + { + //char Buf[200]; + nVarIdx = *(WORD*)in & 0x0FFF; in+=sizeof(WORD); + //wsprintf(Buf, "Request var index %d", nVarIdx); + //MessageBox(0,Buf,0,0); + } + else + nVarIdx = nVarIdx - (VAR_CODES_START + 1); + mystrcpy(out, g_usrvars[nVarIdx]); + } +#else mystrcpy(out, g_usrvars[nVarIdx - (VAR_CODES_START + 1)]); break; - +#endif case VAR_CODES_START + 27: // PROGRAMFILES smwcvesf[41]=0; myRegGetStr(HKEY_LOCAL_MACHINE, smwcvesf, "ProgramFilesDir", out); @@ -503,12 +522,22 @@ char * NSISCALL process_string(const char *in) GetSystemDirectory(out, NSIS_MAX_STRLEN); break; +#ifdef NSIS_SUPPORT_NAMED_USERVARS + #if USER_VARS_COUNT + MAX_NAMED_USER_VARS > 0x0FFF + #error "Too many named variables! Decrease MAX_NAMED_USER_VARS" + #endif + + #if VAR_CODES_START + 36 >= 255 + #error "Too many variables! Extend VAR_CODES_START!" + #endif +#else #if VAR_CODES_START + 35 >= 255 #error "Too many variables! Extend VAR_CODES_START!" #endif +#endif } // switch // validate the directory name - if (nVarIdx > 21+VAR_CODES_START) { // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT + if (nVarIdx > 21+VAR_CODES_START && nVarIdx < VAR_CODES_START + 36 ) { // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT // ($LANGUAGE can't have trailing backslash anyway...) validate_filename(out); } diff --git a/Source/lineparse.h b/Source/lineparse.h index fd5ae1e5..9cceb0c6 100644 --- a/Source/lineparse.h +++ b/Source/lineparse.h @@ -4,24 +4,32 @@ class LineParser { public: - LineParser() + LineParser(bool bCommentBlock) { + m_bCommentBlock=bCommentBlock; m_nt=m_eat=0; m_tokens=0; } - + ~LineParser() { freetokens(); } - + + bool InCommentBlock() + { + return m_bCommentBlock; + } + int parse(char *line, int ignore_escaping=0) // returns -1 on error { freetokens(); + bool bPrevCB=m_bCommentBlock; int n=doline(line, ignore_escaping); if (n) return n; if (m_nt) { + m_bCommentBlock=bPrevCB; m_tokens=(char**)malloc(sizeof(char*)*m_nt); n=doline(line, ignore_escaping); if (n) @@ -107,11 +115,30 @@ class LineParser { int doline(char *line, int ignore_escaping=0) { m_nt=0; + if ( m_bCommentBlock ) + { + while ( *line ) + { + if ( *line == '*' && *(line+1) == '/' ) + { + m_bCommentBlock=false; // Found end of comment block + line+=2; + break; + } + line++; + } + } while (*line == ' ' || *line == '\t') line++; while (*line) { int lstate=0; // 1=", 2=`, 4=' if (*line == ';' || *line == '#') break; + if (*line == '/' && *(line+1) == '*') + { + m_bCommentBlock = true; + line+=2; + return doline(line, ignore_escaping); + } if (*line == '\"') lstate=1; else if (*line == '\'') lstate=2; else if (*line == '`') lstate=4; @@ -167,6 +194,7 @@ class LineParser { int m_eat; int m_nt; + bool m_bCommentBlock; char **m_tokens; }; #endif//_LINEPARSE_H_ \ No newline at end of file diff --git a/Source/makenssi.dsp b/Source/makenssi.dsp index bb2312ed..458bd263 100644 --- a/Source/makenssi.dsp +++ b/Source/makenssi.dsp @@ -185,6 +185,10 @@ SOURCE=.\ResourceEditor.cpp # End Source File # Begin Source File +SOURCE=.\ResourceVersionInfo.cpp +# End Source File +# Begin Source File + SOURCE=.\script.cpp # ADD CPP /Ot /Ow /Oy # SUBTRACT CPP /Og @@ -244,6 +248,10 @@ SOURCE=.\ResourceEditor.h # End Source File # Begin Source File +SOURCE=.\ResourceVersionInfo.h +# End Source File +# Begin Source File + SOURCE=.\strlist.h # End Source File # Begin Source File diff --git a/Source/script.cpp b/Source/script.cpp index 1deb03f4..e123905c 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -20,11 +20,6 @@ #define MAX_LINELENGTH 4096 -static const char *usrvars="$0\0$1\0$2\0$3\0$4\0$5\0$6\0$7\0$8\0$9\0" - "$R0\0$R1\0$R2\0$R3\0$R4\0$R5\0$R6\0$R7\0$R8\0$R9\0" - "$CMDLINE\0$INSTDIR\0$OUTDIR\0$EXEDIR\0$LANGUAGE\0"; - - int CEXEBuild::process_script(FILE *filepointer, char *filename) { linecnt = 0; @@ -60,8 +55,9 @@ int CEXEBuild::doParse(const char *str) static int last_line_had_slash; static int ignored_if_count; static int wait_for_endif; + static bool inside_comment=0; - LineParser line; + LineParser line(inside_comment); int res; while (*str == ' ' || *str == '\t') str++; @@ -82,6 +78,8 @@ int CEXEBuild::doParse(const char *str) res=line.parse((char*)m_linebuild.get(),!strnicmp(str,"!define",7)); + inside_comment = line.InCommentBlock(); + m_linebuild.resize(0); if (res) @@ -358,7 +356,7 @@ int CEXEBuild::process_jump(LineParser &line, int wt, int *offs) int v; if (!stricmp(s,"0") || !stricmp(s,"")) *offs=0; - else if ((v=line.gettoken_enum(wt,usrvars))>=0) + else if ((v=GetUserVarIndex(line, wt))>=0) { *offs=-v-1; // to jump to a user variable target, -variable_index-1 is stored. } @@ -463,7 +461,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (p > str) p--; while (p >= str && (*p == '\r' || *p == '\n' || *p == ' ' || *p == '\t')) p--; *++p=0; - LineParser l2; + LineParser l2(false); if (!l2.parse(str)) { if (!stricmp(l2.gettoken_str(0),"!macroend")) @@ -2593,7 +2591,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_CALL: if (!line.gettoken_str(1)[0] || (line.gettoken_str(1)[0]==':' && !line.gettoken_str(1)[1] )) PRINTHELP() #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT - if (uninstall_mode && strnicmp(line.gettoken_str(1),"un.",3) && (line.gettoken_enum(1,usrvars) < 0)) + if (uninstall_mode && strnicmp(line.gettoken_str(1),"un.",3) && (GetUserVarIndex(line,1) < 0)) { ERROR_MSG("Call must be used with function names starting with \"un.\" in the uninstall section.\n"); PRINTHELP() @@ -2608,7 +2606,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.offsets[1]=0; { int v; - if ((v=line.gettoken_enum(1,usrvars))>=0) + if ((v=GetUserVarIndex(line, 1))>=0) { ent.offsets[0]=-v-2; } @@ -2670,7 +2668,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (which_token == TOK_EXECWAIT) { ent.offsets[1]=1; - ent.offsets[2]=line.gettoken_enum(2,usrvars); + ent.offsets[2]=GetUserVarIndex(line, 2); if (line.gettoken_str(2)[0] && ent.offsets[2]<0) PRINTHELP() } SCRIPT_MSG("%s: \"%s\" (->%s)\n",ent.offsets[1]?"ExecWait":"Exec",line.gettoken_str(1),line.gettoken_str(2)); @@ -2918,7 +2916,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_HWNDS case TOK_FINDWINDOW: ent.which=EW_FINDWINDOW; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0] < 0) PRINTHELP() ent.offsets[1]=add_string(line.gettoken_str(2)); ent.offsets[2]=add_string(line.gettoken_str(3)); @@ -2939,7 +2937,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) SCRIPT_MSG("SendMessage:"); { int a=5; - ent.offsets[0]=line.gettoken_enum(5,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 5); if (ent.offsets[0]>=0) { SCRIPT_MSG("(->%s)",line.gettoken_str(5)); @@ -2987,7 +2985,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT case TOK_GETDLGITEM: ent.which=EW_GETDLGITEM; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0]<0) PRINTHELP(); ent.offsets[1]=add_string(line.gettoken_str(2)); ent.offsets[2]=add_string(line.gettoken_str(3)); @@ -2995,7 +2993,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_GETWINTEXT: ent.which=EW_GETWINTEXT; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line,1); if (ent.offsets[0]<0) PRINTHELP(); ent.offsets[1]=add_string(line.gettoken_str(2)); SCRIPT_MSG("GetWindowText: output=%s hwnd=%s\n",line.gettoken_str(1),line.gettoken_str(2)); @@ -3014,7 +3012,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_CREATEFONT: ent.which=EW_CREATEFONT; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=add_string(line.gettoken_str(2)); SCRIPT_MSG("CreateFont: output=%s \"%s\"",line.gettoken_str(1),line.gettoken_str(2)); { @@ -3400,14 +3398,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_STROPTS case TOK_STRLEN: ent.which=EW_STRLEN; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=add_string(line.gettoken_str(2)); if (ent.offsets[0] < 0) PRINTHELP() SCRIPT_MSG("StrLen %s \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_STRCPY: ent.which=EW_ASSIGNVAR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=add_string(line.gettoken_str(2)); ent.offsets[2]=add_string(line.gettoken_str(3)); ent.offsets[3]=add_string(line.gettoken_str(4)); @@ -3417,7 +3415,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_GETFUNCTIONADDR: ent.which=EW_GETFUNCTIONADDR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=ns_func.add(line.gettoken_str(2),0); ent.offsets[2]=0; ent.offsets[3]=0; @@ -3426,7 +3424,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_GETLABELADDR: ent.which=EW_GETLABELADDR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0] < 0 || process_jump(line,2,&ent.offsets[1])) PRINTHELP() ent.offsets[2]=0; ent.offsets[3]=0; @@ -3434,7 +3432,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_GETCURRENTADDR: ent.which=EW_ASSIGNVAR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); { char buf[32]; wsprintf(buf,"%d",1+(uninstall_mode?build_uninst.code_size:build_header.common.num_entries)); @@ -3512,7 +3510,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; } ent.which=EW_ASSIGNVAR; - ent.offsets[0]=line.gettoken_enum(2,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 2); wsprintf(buf,"%u",high); ent.offsets[1]=add_string(buf); ent.offsets[2]=0; @@ -3520,7 +3518,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (ent.offsets[0]<0) PRINTHELP() add_entry(&ent); - ent.offsets[0]=line.gettoken_enum(3,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 3); wsprintf(buf,"%u",low); ent.offsets[1]=add_string(buf); ent.offsets[2]=0; @@ -3554,7 +3552,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } ent.which=EW_ASSIGNVAR; - ent.offsets[0]=line.gettoken_enum(2,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 2); wsprintf(buf,"%u",high); ent.offsets[1]=add_string(buf); ent.offsets[2]=0; @@ -3562,7 +3560,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) if (ent.offsets[0]<0) PRINTHELP() add_entry(&ent); - ent.offsets[0]=line.gettoken_enum(3,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 3); wsprintf(buf,"%u",low); ent.offsets[1]=add_string(buf); ent.offsets[2]=0; @@ -3623,7 +3621,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_READINISTR: ent.which=EW_READINISTR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0] < 0) PRINTHELP() ent.offsets[1]=add_string(line.gettoken_str(3)); ent.offsets[2]=add_string(line.gettoken_str(4)); @@ -3648,7 +3646,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_FNUTIL case TOK_GETTEMPFILENAME: ent.which=EW_GETTEMPFILENAME; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0]<0) PRINTHELP() SCRIPT_MSG("GetTempFileName -> %s\n",line.gettoken_str(1)); return add_entry(&ent); @@ -3658,7 +3656,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_GETFULLPATHNAME; if (line.getnumtokens()==4 && !stricmp(line.gettoken_str(1),"/SHORT")) a++; else if (line.getnumtokens()==4 || *line.gettoken_str(1)=='/') PRINTHELP() - ent.offsets[0]=line.gettoken_enum(1+a,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1+a); ent.offsets[1]=add_string(line.gettoken_str(2+a)); ent.offsets[2]=!a; if (ent.offsets[0]<0) PRINTHELP() @@ -3668,7 +3666,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_SEARCHPATH: ent.which=EW_SEARCHPATH; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0] < 0) PRINTHELP() ent.offsets[1]=add_string(line.gettoken_str(2)); SCRIPT_MSG("SearchPath %s %s\n",line.gettoken_str(1),line.gettoken_str(2)); @@ -3684,8 +3682,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_GETDLLVERSION ent.which=EW_GETDLLVERSION; ent.offsets[0]=add_string(line.gettoken_str(1)); - ent.offsets[1]=line.gettoken_enum(2,usrvars); - ent.offsets[2]=line.gettoken_enum(3,usrvars); + ent.offsets[1]=GetUserVarIndex(line, 2); + ent.offsets[2]=GetUserVarIndex(line, 3); if (ent.offsets[1]<0 || ent.offsets[2]<0) PRINTHELP() SCRIPT_MSG("GetDLLVersion: %s->%s,%s\n", line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); @@ -3698,8 +3696,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_GETFILETIME ent.which=EW_GETFILETIME; ent.offsets[0]=add_string(line.gettoken_str(1)); - ent.offsets[1]=line.gettoken_enum(2,usrvars); - ent.offsets[2]=line.gettoken_enum(3,usrvars); + ent.offsets[1]=GetUserVarIndex(line, 2); + ent.offsets[2]=GetUserVarIndex(line, 3); if (ent.offsets[1]<0 || ent.offsets[2]<0) PRINTHELP() SCRIPT_MSG("GetFileTime: %s->%s,%s\n", line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); @@ -3711,7 +3709,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_INTOPTS case TOK_INTOP: ent.which=EW_INTOP; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[3]=line.gettoken_enum(3,"+\0-\0*\0/\0|\0&\0^\0!\0||\0&&\0%\0~\0"); if (ent.offsets[0] < 0 || ent.offsets[3]<0 || ((ent.offsets[3] == 7 || ent.offsets[3]==11) && line.getnumtokens()>4)) PRINTHELP() ent.offsets[1]=add_string(line.gettoken_str(2)); @@ -3724,7 +3722,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_INTFMT: ent.which=EW_INTFMT; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0]<0) PRINTHELP() ent.offsets[1]=add_string(line.gettoken_str(2)); ent.offsets[2]=add_string(line.gettoken_str(3)); @@ -3755,7 +3753,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_READREGDWORD: { ent.which=EW_READREGSTR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); int k=line.gettoken_enum(2,rootkeys[0]); if (k == -1) k=line.gettoken_enum(2,rootkeys[1]); if (ent.offsets[0] == -1 || k == -1) PRINTHELP() @@ -3873,7 +3871,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_ENUMREGVAL: { ent.which=EW_REGENUM; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); int k=line.gettoken_enum(2,rootkeys[0]); if (k == -1) k=line.gettoken_enum(2,rootkeys[1]); if (ent.offsets[0] == -1 || k == -1) PRINTHELP() @@ -3904,7 +3902,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_EXCH: { int swapitem=1; - int save=line.gettoken_enum(1,usrvars); + int save=GetUserVarIndex(line, 1); ent.which=EW_PUSHPOP; if (line.gettoken_str(1)[0] && save<0) { @@ -3943,7 +3941,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_POP: ent.which=EW_PUSHPOP; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=1; if (ent.offsets[0] < 0) PRINTHELP() SCRIPT_MSG("Pop: %s\n",line.gettoken_str(1)); @@ -3958,7 +3956,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) #ifdef NSIS_SUPPORT_ENVIRONMENT case TOK_READENVSTR: ent.which=EW_READENVSTR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); { ent.offsets[1]=add_string(line.gettoken_str(2)); if (ent.offsets[0] < 0 || strlen(line.gettoken_str(2))<1) PRINTHELP() @@ -3968,7 +3966,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_EXPANDENVSTRS: ent.which=EW_READENVSTR; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=add_string(line.gettoken_str(2)); ent.offsets[2]=0; if (ent.offsets[0] < 0) PRINTHELP() @@ -3984,21 +3982,21 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_FINDFIRST: ent.which=EW_FINDFIRST; ent.offsets[0]=add_string(line.gettoken_str(3)); // filespec - ent.offsets[1]=line.gettoken_enum(2,usrvars); // out - ent.offsets[2]=line.gettoken_enum(1,usrvars); // handleout + ent.offsets[1]=GetUserVarIndex(line, 2); // out + ent.offsets[2]=GetUserVarIndex(line, 1); // handleout if (ent.offsets[1] < 0 || ent.offsets[2] < 0) PRINTHELP() SCRIPT_MSG("FindFirst: spec=\"%s\" handle=%s output=%s\n",line.gettoken_str(3),line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_FINDNEXT: ent.which=EW_FINDNEXT; - ent.offsets[0]=line.gettoken_enum(2,usrvars); - ent.offsets[1]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 2); + ent.offsets[1]=GetUserVarIndex(line, 1); if (ent.offsets[0] < 0 || ent.offsets[1] < 0) PRINTHELP() SCRIPT_MSG("FindNext: handle=%s output=%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); case TOK_FINDCLOSE: ent.which=EW_FINDCLOSE; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); if (ent.offsets[0] < 0) PRINTHELP() SCRIPT_MSG("FindClose: %s\n",line.gettoken_str(1)); return add_entry(&ent); @@ -4016,7 +4014,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) case TOK_FILEOPEN: { ent.which=EW_FOPEN; - ent.offsets[3]=line.gettoken_enum(1,usrvars); // file handle + ent.offsets[3]=GetUserVarIndex(line, 1); // file handle ent.offsets[0]=add_string(line.gettoken_str(2)); ent.offsets[1]=0; //openmode if (!stricmp(line.gettoken_str(3),"r")) @@ -4041,29 +4039,29 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_FILECLOSE: ent.which=EW_FCLOSE; - ent.offsets[0]=line.gettoken_enum(1,usrvars); // file handle + ent.offsets[0]=GetUserVarIndex(line, 1); // file handle if (ent.offsets[0] < 0) PRINTHELP() SCRIPT_MSG("FileClose: %s\n",line.gettoken_str(1)); return add_entry(&ent); case TOK_FILEREAD: ent.which=EW_FGETS; - ent.offsets[0]=line.gettoken_enum(1,usrvars); // file handle - ent.offsets[1]=line.gettoken_enum(2,usrvars); // output string + ent.offsets[0]=GetUserVarIndex(line, 1); // file handle + ent.offsets[1]=GetUserVarIndex(line, 2); // output string ent.offsets[2]=add_string(line.gettoken_str(3)[0]?line.gettoken_str(3):"1023"); if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP() SCRIPT_MSG("FileRead: %s->%s (max:%s)\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3)); return add_entry(&ent); case TOK_FILEWRITE: ent.which=EW_FPUTS; - ent.offsets[0]=line.gettoken_enum(1,usrvars); // file handle + ent.offsets[0]=GetUserVarIndex(line, 1); // file handle ent.offsets[1]=add_string(line.gettoken_str(2)); if (ent.offsets[0]<0) PRINTHELP() SCRIPT_MSG("FileWrite: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1)); return add_entry(&ent); case TOK_FILEREADBYTE: ent.which=EW_FGETS; - ent.offsets[0]=line.gettoken_enum(1,usrvars); // file handle - ent.offsets[1]=line.gettoken_enum(2,usrvars); // output string + ent.offsets[0]=GetUserVarIndex(line, 1); // file handle + ent.offsets[1]=GetUserVarIndex(line, 2); // output string ent.offsets[2]=add_string("1"); ent.offsets[3]=1; if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP() @@ -4071,7 +4069,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return add_entry(&ent); case TOK_FILEWRITEBYTE: ent.which=EW_FPUTS; - ent.offsets[0]=line.gettoken_enum(1,usrvars); // file handle + ent.offsets[0]=GetUserVarIndex(line, 1); // file handle ent.offsets[1]=add_string(line.gettoken_str(2)); ent.offsets[2]=1; if (ent.offsets[0]<0) PRINTHELP() @@ -4083,9 +4081,9 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) int tab[3]={FILE_BEGIN,FILE_CURRENT,FILE_END}; int mode=line.gettoken_enum(3,"SET\0CUR\0END\0"); ent.which=EW_FSEEK; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=add_string(line.gettoken_str(2)); - ent.offsets[3]=line.gettoken_enum(4,usrvars); + ent.offsets[3]=GetUserVarIndex(line, 4); if (mode<0 && !line.gettoken_str(3)[0]) { @@ -4190,7 +4188,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(name_ptr); - ent.offsets[2]=line.gettoken_enum(2,usrvars); + ent.offsets[2]=GetUserVarIndex(line, 2); if (line.gettoken_str(2)[0] && ent.offsets[2]<0) PRINTHELP() SCRIPT_MSG("SectionGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); @@ -4215,7 +4213,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(flags); - ent.offsets[2]=line.gettoken_enum(2,usrvars); + ent.offsets[2]=GetUserVarIndex(line, 2); if (line.gettoken_str(2)[0] && ent.offsets[2]<0) PRINTHELP() SCRIPT_MSG("SectionGetFlags: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); @@ -4239,7 +4237,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) } ent.which=EW_INSTTYPESET; ent.offsets[0]=add_string(line.gettoken_str(1)); - ent.offsets[1]=line.gettoken_enum(2,usrvars); + ent.offsets[1]=GetUserVarIndex(line, 2); ent.offsets[2]=0; if (line.gettoken_str(1)[0] && ent.offsets[1]<0) PRINTHELP() SCRIPT_MSG("InstTypeGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); @@ -4265,7 +4263,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(install_types); - ent.offsets[2]=line.gettoken_enum(2,usrvars); + ent.offsets[2]=GetUserVarIndex(line, 2); if (line.gettoken_str(2)[0] && ent.offsets[2]<0) PRINTHELP() SCRIPT_MSG("SectionGetInstTypes: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); @@ -4290,7 +4288,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) ent.which=EW_SECTIONSET; ent.offsets[0]=add_string(line.gettoken_str(1)); ent.offsets[1]=SECTION_FIELD_GET(size_kb); - ent.offsets[2]=line.gettoken_enum(2,usrvars); + ent.offsets[2]=GetUserVarIndex(line, 2); if (line.gettoken_str(2)[0] && ent.offsets[2]<0) PRINTHELP() SCRIPT_MSG("SectionGetSize: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2)); return add_entry(&ent); @@ -4316,7 +4314,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; } ent.which=EW_GETFLAG; - ent.offsets[0]=line.gettoken_enum(1,usrvars); + ent.offsets[0]=GetUserVarIndex(line, 1); ent.offsets[1]=FLAG_OFFSET(cur_insttype); if (line.gettoken_str(1)[0] && ent.offsets[0]<0) PRINTHELP() SCRIPT_MSG("GetCurInstType: %s\n",line.gettoken_str(1)); @@ -4374,6 +4372,75 @@ int CEXEBuild::doCommand(int which_token, LineParser &line) return PS_ERROR; #endif//!NSIS_SUPPORT_CREATEFONT + // Added by ramon 3 jun 2003 +#ifdef NSIS_SUPPORT_NAMED_USERVARS + case TOK_DEFVAR: + { + return DeclaredUserVar(line.gettoken_str(1)); + SCRIPT_MSG("dim \"%s\"\n",line.gettoken_str(1)); + } + return make_sure_not_in_secorfunc(line.gettoken_str(0)); + +#else //NSIS_SUPPORT_NAMED_USERVARS + case TOK_DEFVAR: + ERROR_MSG("Error: %s specified, case NSIS_SUPPORT_NAMED_USERVARS not defined.\n",line.gettoken_str(0)); + return PS_ERROR; +#endif //NSIS_SUPPORT_NAMED_USERVARS + + // Added by ramon 6 jun 2003 +#ifdef NSIS_SUPPORT_VERSION_INFO + case TOK_VI_PRODUCTVERSION: + case TOK_VI_PRODUCTNAME: + case TOK_VI_COMPANY: + case TOK_VI_COMMENTS: + case TOK_VI_LEGALTRADEMARKS: + case TOK_VI_LEGALCOPYRIGHTS: + case TOK_VI_DESCRIPTION: + { + char *pVI; + switch (which_token) + { + case TOK_VI_PRODUCTVERSION: + pVI = szVIProductVersion; break; + case TOK_VI_PRODUCTNAME: + pVI = szVIProductName; break; + case TOK_VI_COMPANY: + pVI = szVICompanyName; break; + case TOK_VI_COMMENTS: + pVI = szVIComments; break; + case TOK_VI_LEGALTRADEMARKS: + pVI = szVILegalTrademarks; break; + case TOK_VI_LEGALCOPYRIGHTS: + pVI = szVILegalCopyrights; break; + case TOK_VI_DESCRIPTION: + pVI = szVIDescription; break; + } + + if ( pVI[0] ) + { + ERROR_MSG("Error: %s already defined.\n",line.gettoken_str(0)); + return PS_ERROR; + } + else + { + SCRIPT_MSG("%s = \"%s\"\n",line.gettoken_str(0), line.gettoken_str(1)); + strcpy(pVI, line.gettoken_str(1)); + return PS_OK; + } + } + +#else + case TOK_VI_PRODUCTVERSION: + case TOK_VI_PRODUCTNAME: + case TOK_VI_COMPANY: + case TOK_VI_COMMENTS: + case TOK_VI_LEGALTRADEMARKS: + case TOK_VI_LEGALCOPYRIGHTS: + case TOK_VI_DESCRIPTION: + ERROR_MSG("Error: %s specified, NSIS_SUPPORT_VERSION_INFO not defined.\n",line.gettoken_str(0)); + return PS_ERROR; +#endif + // end of instructions /////////////////////////////////////////////////////////////////////////////// diff --git a/Source/tokens.cpp b/Source/tokens.cpp index 581961af..3ed12b11 100644 --- a/Source/tokens.cpp +++ b/Source/tokens.cpp @@ -226,7 +226,17 @@ static tokenType tokenlist[TOK__LAST] = {TOK_PLUGINDIR,"!AddPluginDir",1,0,"new_plugin_directory"}, {TOK_INITPLUGINSDIR,"InitPluginsDir",0,0,""}, // Added by ramon 23 May 2003 -{TOK_ALLOWSKIPFILES,"AllowSkipFiles",1,0,"(off|on)"} +{TOK_ALLOWSKIPFILES,"AllowSkipFiles",1,0,"(off|on)"}, +// Added by ramon 3 jun 2003 +{TOK_DEFVAR,"dim",1,0,"VarName"}, +// Added by ramon 6 jun 2003 +{TOK_VI_PRODUCTVERSION,"VIProductVersion", 1, 0, "product version"}, +{TOK_VI_PRODUCTNAME,"VIProductName", 1, 0, "product name"}, +{TOK_VI_COMPANY,"VICompanyName", 1, 0, "company name"}, +{TOK_VI_COMMENTS,"VIComments", 1, 0, "comments"}, +{TOK_VI_LEGALTRADEMARKS,"VILegalTrademarks", 1, 0, "legal trademarks"}, +{TOK_VI_LEGALCOPYRIGHTS,"VILegalCopyrights", 1, 0, "legal copyrights"}, +{TOK_VI_DESCRIPTION, "VIDescription", 1, 0, "description text"}, }; void CEXEBuild::print_help(char *commandname) diff --git a/Source/tokens.h b/Source/tokens.h index 58827172..332ee2ee 100644 --- a/Source/tokens.h +++ b/Source/tokens.h @@ -214,6 +214,15 @@ enum TOK_SHOWWINDOW, // Added by ramon 23 May 2003 TOK_ALLOWSKIPFILES, + // Added by ramon 3 jun 2003 + TOK_DEFVAR, + TOK_VI_PRODUCTVERSION, + TOK_VI_PRODUCTNAME, + TOK_VI_COMPANY, + TOK_VI_COMMENTS, + TOK_VI_LEGALTRADEMARKS, + TOK_VI_LEGALCOPYRIGHTS, + TOK_VI_DESCRIPTION, TOK__LAST, TOK__PLUGINCOMMAND