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
This commit is contained in:
ramon18 2003-06-09 18:59:14 +00:00
parent c5c57c0fdb
commit f758230f19
14 changed files with 823 additions and 128 deletions

59
Examples/VersionInfo.nsi Normal file
View file

@ -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

View file

@ -0,0 +1,184 @@
// ResourceVersionInfo.cpp: implementation of the CResourceVersionInfo class.
//
//////////////////////////////////////////////////////////////////////
#include <windows.h>
#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

View file

@ -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 <algorithm>
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_)

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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 {

View file

@ -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;

View file

@ -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);
}

View file

@ -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_

View file

@ -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

View file

@ -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
///////////////////////////////////////////////////////////////////////////////

View file

@ -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)

View file

@ -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