Another cool plug-in by brainsucker, a calculator :)

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2920 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2003-09-15 23:20:36 +00:00
parent de0104cc39
commit 754af5bd4b
15 changed files with 3113 additions and 0 deletions

190
Contrib/Math/Math.txt Normal file
View file

@ -0,0 +1,190 @@
Math::Script NSIS plugin.
Another huge, undocumented, bug-full, but "might be useful" plugin.
C-like style scripting (operators at least).
Tip1: plugin watches the case of the letters.
Tip2: plugin makes almost no error checks. So YOU should check your script
twice before run :)
New HOW TO USE: run the MathTest.Exe, and try yourself. After spending
some minutes your should be able to write your script by yourself.
To include it to your NSIS script just insert that (don't forget /NOUNLOAD
in case of multiple calls):
Math::Script /NOUNLOAD "YourScript1"
Math::Script /NOUNLOAD "YourScript2"
Math::Script "YourScriptFinal"
How to use it? Simple:
Strcpy $0 "Brainsucker"
Math::Script "a = 'Math'; B = 'Script'; r0 += ' wants to use ' + a + '::' + b +'!'"
DetailPrint "$0"
That string will fill r0 with some shit.
Here are some other samples:
10! (factorial, r0 will contain '10! = 362880'):
r0 = '10! = ' + (1*2*3*4*5*6*7*8*9)
the same:
a = b = 1; #{++a <= 10, b = b*a}; r0 = (a-1) + '! = ' + b
Some floating point:
Strcpy $R0 "1e1"
Math::Script "pi = 3.14159; R1 = 2*pi*R0; r0 = 'Length of circle with radius ' + R0 + ' is equal to ' + R1 + '.'"
Detailprint "$0"
Ok. Variables.
NSIS: r0-r9 -> $0-$9. R0-R9 -> $R0-$R9.
Also CL ($CMDLINE), ID ($INSTDIR), OD ($OUTDIR), LG ($LANG), ED ($EXEDIR).
User definable: name starting from character, up to 28 letters long.
Stacks. Two stacks are supported: NSIS stack and plugin's own stack. I see no
reasons for using plugin stack, but if you will, remember - the plugin stores
variables used at function to that stack before function execution, and restores
after execution. Even less I recommend you to use NSIS stack. You should use it
only for input/output.
How to use? It's variable styled. Plugins stack is associated with S variable,
and NSIS stack associated with NS variable. To push to stack just do "S=0" or
"NS=0", to pop from stack "a=S" or "b=NS". Combined operations supported too:
"S += 1.5" will increment value at the top of stack by 1.5.
Supported types: int (in fact that is __int64), float (double in fact),
string.
Int: just numbers, may include sign.
Float: -123.456, 123.456e-78, 123e-45
String: something in quotes ("", '', ``).
There is also an array type. It is actually a reference type, so if b is array
and you will perform "a=b", the a and b will reference a single array.
To create a copy of array, use ca func: dest = ca(source). Btw - you couldn't
control dimensions of arrays - they are autosized.
To declare array:
a = {};
To declare array and initialize some items with values:
{"Hello!", "Use", "mixed types", 1.01e23, "like that" ,1234};
To access array:
a[index] = "Cool";
Also [] operation could be used to strings. str[x] gives you a single char with
index x (zero-based) as new string. str[-x] - the same, but x counts from the
string end (so the last char is -1). str[x,y] gives you characters in range x-y
(inclusive), both x and y could be <0 - in this case they counted from the end
of the string.
The function could be useful - is conversion of arrays to strings and back.
Example:
a = a("Hello"); str = s(a);
After running such script array a will contain 6 integers (chars and last zero
- end of string), and str will contain your string back.
Operators (some binary, some unary):
>>= <<= -= += /= *= |= &= ^= %= -- ++ >> << && || <= =< >= => != ==
= + - * / % < > & | ^ ~ !
Only some are applicable to float (logic & arithmetic) and string (+ and logic)
of course.
Script is set of expressions (mathematical in general) delimeted with ';'.
Processing is not mathematicaly right (2+2*2 will give 8, not 6), so use round
brakes (for ex: 2+(2*2) ).
Flow control:
if-then-else like: #[if-expression, then-expr, else-expr]
example:
#[a==0, b=1; c=2, b *= (--c); c/=10]
C eq:
if (a==0) { b=1; c=2;} else { b*=(c++);c-=10; }
while (expr) do; like #{expr, do}
example:
#{(c<1.1e25)&&(b < 10), b++; c*=1.23}
C eq:
while ((c<1.1e25)&&(b<10)) { b++; c*=1.23; }
WATCH OUT! Comma (,) separates if-expr, then-expr, and else-expr from each
other. All sub-expressions separated by (;) are the part of one expression,
and the result of the last one of these sub-exprs gives you the result of
expression.
All the shit (like variables and functions) will be saved between calls if
you'll use /NOUNLOAD or setpluginunload alwaysoff.
Functions:
type conversions:
l(string) returns the length of string or array argument
s(source) converts source to string type
i(source) converts source to int type
f(source) converts source to float type
c(source) if source is string, returns int value of first
char, if source is int, returns string which consists
of a single char (source) (+0 terminator).
a(source) converts source to array (only string supported)
ff(float, format) converts float to string, with format
options.
options = precision + flags.
Precision shows how many digits after decimal point
will be shown. Flags:
16 (or 0x10) - No Exponential View
(number will be shown as 123.123)
32 (or 0x20) - Only exponential view
(number will be shown as 123.12e123)
64 (or 0x40) - use 'E' character instead of 'e'
By default the plugin decides itself how to show your
number.
math (description of all these functions is available at MSDN, use the
second given name for search):
sin(x), sin Sine of argument
cos(x), cos Cosine of argument
cel(x), ceil Ceil of argument (no fract. part)
csh(x), cosh Hyperbolic Cosine of Argument
exp(x), exp Exponential
abs(x), abs Absolute value (warning: float)
flr(x), floor Floor of argument (no fract. part)
asn(x), asin ArcSine of argument
acs(x), acos ArcCosine of argument
atn(x), atan ArcTangent of argument
ln(x), log Exponential Logarithm
log(x), log10 Decimal logarithm
snh(x), sinh Hyperbolic Sine of Argument
sqt(x), sqrt Square root of argument
tan(x), tan Tangent of argument
tnh(x), tanh Hyperbolic tangent of argument
functions taking two arguments
at2(x, y) atan2 Arctangent of the value (y/x)
pow(x, y) pow power, x^y
fmd(x, y) fmod floating point remainder
fex(x, o) frexp Gets the mantissa (result = r)
and exponent (o) of floating-point
number (x): x = r*(2^o)
mdf(x, o) modf Splits a floating-point value into
fractional and integer parts.
User-defined functions.
It's very simple. Example:
test(a,b)a+b;
After that test(1,2) will give you 3. If you need more than one expression, use
round brakes:
test2(a,b) (a=a+b; b *= a);
The result of function is always the result of last expression.
As said before it better not to use stack (S) in between function calls.
It will be better to develop variable-safe functions, i.e. functions which will
not corrupt variables. For this you should either push/pop them to stack, or
declare as additional arguments, which will never be used. Example:
test3(a,b,c) (c=10; #{--c > 0, a=sqrt(a*b)}; a)
No matter how many arguments will be passed to function all three vars will be
saved.
Such variable-safe functions could be recursive:
Math::Script /NOUNLOAD 'rec(a) (#[a > 0, rec(a-1), 0]+a);'
Math::Script 'R1 = rec(10)'
will set R1 to right result 55.
Sometimes functions will need to return more than one value, in this case you
could declare argument as referent (b at example):
test4(a, &b) (*b = a*a; a*a*a)
In this case test4 will return a^3, and if we will call it like that test4(a,c),
it will place a^2 to c. BUT! Note: you should use de-referencer (*) with variable,
at example *b. CAUTION: never use the same variable as function internal reference
variable and external argument variable (for example test4(a,b)). It will surely
fail. Also: if you declared argument as reference - you should never supply
a constant expression to it. It could be either array item (array[1]), NSIS
register R0, any of the user variables (beside the variable with the same name:)
, but never the constant.
(c) Nik Medved (brainsucker)

1518
Contrib/Math/Source/Math.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,87 @@
#pragma once
#ifdef _DEBUG
//#define _DEBUG_LEAKS
#endif
#ifdef _DEBUG_LEAKS
#define dbgGlobalAlloc(a, b) watchGlobalAlloc(a, b)
#define dbgGlobalFree(a) watchGlobalFree(a)
#define dbgGlobalCheck() watchGlobal();
void watchGlobal();
void watchGlobalFree(HGLOBAL block);
HGLOBAL watchGlobalAlloc(UINT Flags, UINT size);
#else
#define dbgGlobalAlloc(a, b) GlobalAlloc(a, b)
#define dbgGlobalFree(a) GlobalFree(a)
#define dbgGlobalCheck() {};
#endif
// only include this file from one place in your DLL.
// (it is all static, if you use it in two places it will fail)
#define Math_INIT() { \
g_stringsize=string_size; \
g_stacktop=stacktop; \
g_variables=variables; }
// For page showing plug-ins
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
#define NOTIFY_BYE_BYE 'x'
typedef struct _stack_t {
struct _stack_t *next;
char text[1]; // this should be the length of string_size
} stack_t;
extern unsigned int g_stringsize;
extern stack_t **g_stacktop;
extern char *g_variables;
enum
{
INST_0, // $0
INST_1, // $1
INST_2, // $2
INST_3, // $3
INST_4, // $4
INST_5, // $5
INST_6, // $6
INST_7, // $7
INST_8, // $8
INST_9, // $9
INST_R0, // $R0
INST_R1, // $R1
INST_R2, // $R2
INST_R3, // $R3
INST_R4, // $R4
INST_R5, // $R5
INST_R6, // $R6
INST_R7, // $R7
INST_R8, // $R8
INST_R9, // $R9
INST_CMDLINE, // $CMDLINE
INST_INSTDIR, // $INSTDIR
INST_OUTDIR, // $OUTDIR
INST_EXEDIR, // $EXEDIR
INST_LANG, // $LANGUAGE
__INST_LAST
};
// utility functions (not required but often useful)
int popstring(char *str);
void pushstring(char *str);
char *getuservariable(int varnum);
void setuservariable(int varnum, char *var);
char *AllocString();
ExpressionItem *AllocItem();
ExpressionItem *AllocArray(int size);
ExpressionItem *CopyItem(ExpressionItem *item, int NeedConst = 0);

View file

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Math", "Math.vcproj", "{0825E168-A8AD-4110-B35A-52B078C39C2A}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{0825E168-A8AD-4110-B35A-52B078C39C2A}.Debug.ActiveCfg = Debug|Win32
{0825E168-A8AD-4110-B35A-52B078C39C2A}.Debug.Build.0 = Debug|Win32
{0825E168-A8AD-4110-B35A-52B078C39C2A}.Release.ActiveCfg = Release|Win32
{0825E168-A8AD-4110-B35A-52B078C39C2A}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,240 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="Math"
RootNamespace="Math"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;Math_EXPORTS"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/Math.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"
CommandLine="d:
cd &quot;D:\Program Files\NSIS\&quot;
makensis.exe math.nsi
"
AdditionalDependencies="D:\Program Files\NSIS\math.nsi"
Outputs="D:\Program Files\NSIS\math.exe "/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="mathcrt.lib kernel32.lib user32.lib RunTmChk.lib libcd.lib"
OutputFile="d:\Program Files\NSIS\Plugins\Math.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
IgnoreAllDefaultLibraries="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/Math.pdb"
ImportLibrary=".\Debug/Math.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Debug/Math.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="0"
WholeProgramOptimization="TRUE">
<Tool
Name="VCCLCompilerTool"
Optimization="1"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
ImproveFloatingPointConsistency="FALSE"
FavorSizeOrSpeed="2"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;Math_EXPORTS"
StringPooling="TRUE"
ExceptionHandling="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="4"
StructMemberAlignment="0"
BufferSecurityCheck="FALSE"
EnableFunctionLevelLinking="FALSE"
DefaultCharIsUnsigned="TRUE"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/Math.pch"
AssemblerOutput="2"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="mathcrt.lib "
ShowProgress="2"
OutputFile="d:\Program Files\NSIS\Plugins\Math.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
IgnoreAllDefaultLibraries="TRUE"
ProgramDatabaseFile=".\Release/Math.pdb"
GenerateMapFile="TRUE"
MapFileName="math.map"
MapExports="TRUE"
MapLines="TRUE"
OptimizeForWindows98="1"
EntryPointSymbol="_DllMainCRTStartup"
ImportLibrary=".\Release/Math.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Release/Math.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="Math.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;Math_EXPORTS;$(NoInherit)"
BasicRuntimeChecks="3"
CompileAs="2"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="1"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;Math_EXPORTS;$(NoInherit)"
CompileAs="2"/>
</FileConfiguration>
</File>
<File
RelativePath=".\MyMath.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
CompileAs="2"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
CompileAs="2"/>
</FileConfiguration>
</File>
<File
RelativePath=".\plugin.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
CompileAs="2"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
CompileAs="2"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="Math.h">
</File>
<File
RelativePath=".\MyMath.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,353 @@
#include <windows.h>
#include "Mathcrt.h"
#include "MyMath.h"
#include "Math.h"
// Converts String to Int (Dec, Hex) or Float value
void StringToItem(char *&s, ExpressionItem *item, int options)
{
item->type = IT_CONST | ITC_INT;
__int64 &v=*((__int64*)&(item->param1));
v = 0;
// Check for right input
if (!s) return;
// String-value
if ((((options & (STI_FLOAT | STI_INT)) == 0) || *s == '\'' || *s == '\"' || *s == '`' ||
((*s != '+') && (*s != '-') && ((*s < '0') || (*s > '9'))))
&& (options & STI_STRING))
{
// end of string char
char eol = 0;
if (*s == '\'' || *s == '\"' || *s == '`') eol = *s;
else s--;
item->type = IT_CONST | ITC_STRING;
// allocate memory buffer for string
char *sp;
sp = *((char**)&(item->param1)) = AllocString();
while (*(++s) && (*s != eol))
{
*(sp++) = *s;
}
if (*s == eol) s++;
*sp = 0;
} else
{
// strip leading spaces and tabs
while ((*s == ' ') || (*s == '\t')) s++;
// Hex-value
if ((options & STI_INT) && *s == '0' && (s[1] == 'x' || s[1] == 'X'))
{
s++;
while (*(s+1) == '0') *s++;
for (;;)
{
int c=*(++s);
if (c >= '0' && c <= '9') c-='0';
else if (c >= 'a' && c <= 'f') c-='a'-10;
else if (c >= 'A' && c <= 'F') c-='A'-10;
else break;
v<<=4;
v+=c;
}
}
// Dec-value, possible floating-point
else
{
int sign=0, numsignif = 0;
if (*s == '-') sign++; else s--;
while (*(s+1) == '0') *s++;
for (;;)
{
int c=*(++s) - '0'; numsignif++;
if ((options & STI_FLOAT) &&
((c == ('e'-'0')) || (c==('E'-'0')) || (c==('.'-'0'))
|| (numsignif > 18)))
{
// Switch to floating point conversion rountine
item->type = IT_CONST | ITC_FLOAT;
double& d = *((double*)&(item->param1));
d = (double) v;
while ((c >= 0) && (c <= 9))
{
d = d*10.0 + (double) c;
c=*(++s) - '0';
}
// sub-decimal part
if (c == ('.'-'0'))
{
double pwr = 1.0, dec = 0.0;
for (;;)
{
c=*(++s) - '0';
if ((c < 0) || (c > 9)) break;
dec = dec*10.0 + (double) c;
pwr *= 10.0;
}
d += dec/pwr;
}
// exponental part
if ((c == ('E'-'0')) || (c == ('e'-'0')))
{
int expc = 0, esign = 0;
s++;
// detect exponential sign
if ((*s == '+') || (*s == '-'))
esign = (*s == '-');
else s--;
// detect exp value
for (;;)
{
c=*(++s) - '0';
if ((c < 0) || (c > 9)) break;
expc = expc*10 + c;
}
if (expc >= DBL_MAX_EXP)
{
d = HUGE_VAL;
expc = 0;
}
double pwr = 1;
while (expc > 99) { pwr *= 1.0e100; expc -= 100; }
while (expc > 9) { pwr *= 1.0e10; expc -= 10; }
while (expc) { pwr *= 10.0; expc--; }
if (esign) d /= pwr;
else d *= pwr;
}
if (sign) d = -d;
return;
}
if (c < 0 || c > 9) break;
v*=10;
v+=c;
}
if (sign) v = -v;
if ((options & STI_FLOAT) && ((options & STI_INT) == 0))
{
double& d = *((double*)&(item->param1));
d = (double) v;
item->type = IT_CONST | ITC_FLOAT;
}
}
}
}
void ItemToString(char *sbuf, ExpressionItem *item)
{
if ((item == NULL) || ((item->type & ITEMTYPE) != IT_CONST))
{
*sbuf = 0;
return;
}
switch (item->type & ITEMSUBTYPE)
{
case ITC_STRING:
{
char *ptr = *((char**)&(item->param1));
while (*(sbuf++) = *(ptr++));
}
break;
case ITC_ARRAY:
{
ArrayDesc *ad = (ArrayDesc *) item->param1;
for (int index = 0; index < ad->count; index++)
if ((ad->array[index]) &&
((ad->array[index]->type & (ITEMTYPE|ITEMSUBTYPE)) == (IT_CONST | ITC_INT)))
if ((*(sbuf++) = (char) *((__int64*)&(ad->array[index]->param1))) == 0)
break;
}
break;
case ITC_FLOAT:
FloatFormat(sbuf, *((double*)&(item->param1)), 6);
break;
case ITC_INT:
itoa64(*((__int64*)&(item->param1)), sbuf);
break;
}
}
void itoa64(__int64 i, char *buffer)
{
char buf[128], *b = buf;
if (i < 0)
{
*(buffer++) = '-';
i = -i;
}
if (i == 0) *(buffer++) = '0';
else
{
while (i > 0)
{
*(b++) = '0' + ((char) (i%10));
i /= 10;
}
while (b > buf) *(buffer++) = *(--b);
}
*buffer = 0;
}
#define _FLOAT_ROUND_ADJUST (double)5e-15
extern "C"
int _floatp10(double *fnum, int *fsign, int prec);
extern "C"
int _ftol(double num);
#define POS_INFINITY "#INF"
#define NEG_INFINITY "-#INF"
void FloatFormatF(char *s, double value, int prec)
{
int fpower, fsign, fdigit, fprec = 0, fzfill = 0;
fpower = _floatp10(&value, &fsign, prec);
if(fsign < 0) *s++ = '-';
if(fpower < 0)
{
*s++ = '0';
fpower++;
fzfill++;
} else {
while(fpower >= 0)
{
if(fprec < 16)
{
fdigit = (int)value;
*s++ = (char)((char)fdigit + (char)48);
value -= (double)fdigit;
value *= (double)10;
value += _FLOAT_ROUND_ADJUST;
fprec++;
} else {
*s++ = '0';
}
fpower--;
}
fpower = 0;
}
if(prec)
{
*s++ = '.';
while(prec)
{
if(fzfill && fpower < 0)
{
*s++ = '0';
fpower++;
} else {
if(fprec < 16)
{
fdigit = (int)value;
*s++ = (unsigned char)((unsigned char)fdigit +
(unsigned char)48);
value -= (double)fdigit;
value *= (double)10;
value += _FLOAT_ROUND_ADJUST;
fprec++;
} else {
*s++ = '0';
}
}
prec--;
}
}
*s = '\0';
}
void FloatFormatE(char *s, double fnum, int options)
{
int fpower, fsign, fdigit, fprec = 0, prec, fzfill = 0;
double sfnum;
prec = options & 0xF;
sfnum = fnum;
fpower = _floatp10(&sfnum, &fsign, -999);
fpower = _floatp10(&fnum, &fsign, prec - fpower);
if(fsign < 0) *s++ = '-';
fdigit = (int)fnum;
*s++ = (char)((char)fdigit + (char)48);
fnum -= (double)fdigit;
fnum *= (double)10;
fnum += _FLOAT_ROUND_ADJUST;
if(prec)
{
*s++ = '.';
while(prec)
{
if(fprec < 16)
{
fdigit = (int)fnum;
*s++ = (unsigned char)((unsigned char)fdigit +
(unsigned char)48);
fnum -= (double)fdigit;
fnum *= (double)10;
fnum += _FLOAT_ROUND_ADJUST;
fprec++;
} else *s++ = '0';
prec--;
}
}
*s++ = ((options & FF_LEXP)?('E'):('e'));
if(fpower >= 0)
{
*s++ = '+';
} else {
*s++ = '-';
fpower = -fpower;
}
if(fpower < 10) *s++ = '0';
itoa64(fpower, s);
}
void FloatFormat(char *s, double value, int options)
{
int prec = options & 0xF;
if(value == HUGE_VAL)
{
lstrcpy(s, POS_INFINITY);
return;
} else if(value == -HUGE_VAL) {
lstrcpy(s, NEG_INFINITY);
return;
}
if (options & FF_NOEXP) FloatFormatF(s, value, prec);
else
if (options & FF_EXP) FloatFormatE(s, value, options);
else
{
double sfnum = value;
int fsign, fpower;
fpower = _floatp10(&sfnum, &fsign, -999);
sfnum = value;
fpower = _floatp10(&sfnum, &fsign, prec - fpower);
if((value != 0.0) && ((fpower < -4) || (fpower >= prec)))
FloatFormatE(s, value, options);
else
{
prec -= (fpower + 1);
if(prec <= 0) prec = 1;
FloatFormatF(s, value, prec);
}
}
}
int lstrcmpn(char *s1, const char *s2, int chars)
{
while ((chars > 0) && (*s1) && (*s2) && (*(s1) == *(s2))) chars--, s1++, s2++;
if ((chars == 0) || (*s1 == *s2)) return 0;
return (*s1 - *s2);
}

View file

@ -0,0 +1,164 @@
#pragma once
#define DEFAULT_ARRAY_SIZE 1024
#define ITEMTYPE 0xFF0000
// items classes
#define IT_CONST 0x000000
#define IT_EXPRESSION 0x010000
#define IT_OPERATOR 0x020000
#define IT_VARIABLE 0x030000
#define IT_LOGIC 0x040000 // flow control items
#define IT_FUNCTION 0x050000
#define IT_ARRAY 0x060000 // array operation
#define ITEMSUBTYPE 0x00FF00
// const items
#define ITC_STRING 0x000100
#define ITC_FLOAT 0x000200
#define ITC_INT 0x000400
#define ITC_ARRAY 0x000800
#define ITC_VARPTR 0x001000
#define ITC_UNKNOWN 0x002000
// type function
#define FTT_FLOATF (ITC_UNKNOWN << 0)
#define FTT_LEN (ITC_UNKNOWN << 1)
#define FTT_CHAR (ITC_UNKNOWN << 2)
// additional option - for "ca" function
#define ITFA_COPY 0x000001
// ops items
#define ITO_MINUS 0x000100
#define ITO_PLUS 0x000200
#define ITO_SHL 0x000300
#define ITO_SHR 0x000400
#define ITO_MUL 0x000500
#define ITO_DIV 0x000600
#define ITO_SET 0x000700
#define ITO_LAND 0x000800
#define ITO_LOR 0x000900
#define ITO_INC 0x000A00
#define ITO_DEC 0x000B00
#define ITO_LE 0x000C00
#define ITO_GE 0x000D00
#define ITO_NE 0x000E00
#define ITO_EQ 0x000F00
#define ITO_LS 0x001000
#define ITO_GR 0x001100
#define ITO_AND 0x001200
#define ITO_MOD 0x001300
#define ITO_OR 0x001400
#define ITO_XOR 0x001500
#define ITO_NOT 0x001600
#define ITO_LNOT 0x001700
// variables sub-types
#define ITV_NSIS 0x000100
#define ITV_USER 0x000200
#define ITV_ARRITEM 0x000400
#define ITV_STACK 0x000800 // plugin specific stack
#define ITV_NSTACK 0x001000 // nsis stack
// logic sub-types
#define ITL_IF 0x000100
#define ITL_WHILE 0x000200
// function sub-types
#define ITF_MATH1 0x000100
#define ITF_MATH2 0x000200
#define ITF_TYPE 0x000300
#define ITF_USER 0x000400
// array items sub-types
#define ITA_DEFINE 0x000100
#define ITA_ACCESS 0x000200
#define ITEMOPTIONS 0x0000FF
// 16 bytes structure
typedef struct __ExpressionItem ExpressionItem;
typedef struct __ExpressionItem
{
int type;
int param1;
int param2;
ExpressionItem *next;
} ExpressionItem;
typedef struct __ParseInfo
{
int SetupNewRoot;
ExpressionItem *item;
ExpressionItem *OpsStack;
ExpressionItem* &place;
ExpressionItem **root;
char valbuf[108];
} ParseInfo;
typedef struct __OpStruct
{
char name[4];
unsigned short int type;
} OpStruct;
#define MAX_USER_VARS 256
typedef struct __UserVar
{
char name[28];
ExpressionItem *item;
} UserVar;
#define MAX_USER_FUNCS 256
typedef struct __UserFunc
{
char name[20];
unsigned char vars[31];
unsigned char varsnum;
unsigned int varflags;
ExpressionItem *root;
} UserFunc;
typedef struct __ArrayDesc
{
ExpressionItem **array;
int size; // size of allocated items pool
int count; // max number of item accessed
int references; // array will be killed at CleanupItems only when references == 0
} ArrayDesc;
typedef double (*Math1FuncPtr)(double arg);
typedef double (*Math2FuncPtr)(double arg, double arg2);
typedef double (*Math2iFuncPtr)(double arg, int *arg2);
typedef double (*Math2dFuncPtr)(double arg, double *arg2);
typedef struct __MathFunction
{
char name[3];
unsigned char type;
Math1FuncPtr fptr;
} MathFunction;
#define STI_STRING 0x0100
#define STI_FLOAT 0x0200
#define STI_INT 0x0400
#define FF_DEFAULT 0x00 // uses default mode: if available noexp, else exp
#define FF_NOEXP 0x10 // uses noexp mode
#define FF_EXP 0x20 // uses exp mode (small e)
#define FF_LEXP 0x40 // uses exp mode (large E)
// parsestring options
#define PSO_STOPATDELIMETER 0x1
// RunTree options
#define RTO_NEEDCONST 0x0001
#define RTO_PREFFEREDTYPE 0xFF00
void RunTree(ExpressionItem *from, ExpressionItem* &result, int type);
void StringToItem(char *&sbuf, ExpressionItem *item, int options);
void ItemToString(char *sbuf, ExpressionItem *item);
void FloatFormat(char *sbuf, double value, int options);
void itoa64(__int64 i, char *buffer);
int lstrcmpn(char *s1, const char *s2, int chars);

View file

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------*/
/* math.h - mathematics header file */
/*---------------------------------------------------------------------------*/
#pragma once
extern "C"
{
extern double _infinity;
#define HUGE_VAL _infinity
#define acos(x) _facos(x)
#define asin(x) _fasin(x)
#define atan(x) _fatan(x)
#define atan2(x, y) _fatan2(x, y)
#define ceil(x) _fceil(x)
#define cos(x) _fcos(x)
#define cosh(x) _fcosh(x)
#define exp(x) _fexp(x)
#define fabs(x) _fabs(x)
#define floor(x) _floor(x)
#define fmod(x, y) _fmod(x, y)
#define frexp(x, n) _frexp(x, n)
#define ldexp(x, n) _fldexp(x, n)
#define log(x) _flog(x)
#define log10(x) _flog10(x)
#define modf(x, y) _fmodf(x, y)
#define pow(x, y) _fpow(x, y)
#define sin(x) _fsin(x)
#define sinh(x) _fsinh(x)
#define sqrt(x) _fsqrt(x)
#define tan(x) _ftan(x)
#define tanh(x) _ftanh(x)
/*---------------------------------------------------------------------------*/
/* function prototpes */
/*---------------------------------------------------------------------------*/
double acos(double x);
double asin(double x);
double atan(double x);
double atan2(double x, double y);
double ceil(double x);
double cos(double x);
double cosh(double x);
double exp(double x);
double fabs(double x);
double floor(double x);
double fmod(double x, double y);
double frexp(double x, int *n);
double ldexp(double x, int n);
double log(double x);
double log10(double x);
double modf(double x, double *y);
double pow(double x, double y);
double sin(double x);
double sinh(double x);
double sqrt(double x);
double tan(double x);
double tanh(double x);
/*---------------------------------------------------------------------------*/
/* float.h - floating point include file */
/*---------------------------------------------------------------------------*/
#define FLT_RADIX 2
#define FLT_ROUNDS 1
#define FLT_DIG 6
#define FLT_EPSILON 1.192092896e-07F
#define FLT_MANT_DIG 24
#define FLT_MAX 3.402823466e+38F
#define FLT_MAX_EXP 38
#define FLT_MIN 1.175494351e-38F
#define FLT_MIN_EXP (-37)
#define DBL_DIG 15
#define DBL_EPSILON 2.2204460492503131e-016
#define DBL_MANT_DIG 53
#define DBL_MAX 1.7976931348623158e+308
#define DBL_MAX_EXP 308
#define DBL_MIN 2.2250738585072014e-308
#define DBL_MIN_EXP (-307)
/*---------------------------------------------------------------------------*/
/* function prototpes */
/*---------------------------------------------------------------------------*/
void _fpreset(void);
}

Binary file not shown.

View file

@ -0,0 +1,135 @@
#include <windows.h>
#include <crtdbg.h>
#include "MyMath.h"
#include "Math.h"
unsigned int g_stringsize;
stack_t **g_stacktop;
char *g_variables;
#ifdef _DEBUG_LEAKS
int blocksnum = 0;
HGLOBAL blocks[100000];
HGLOBAL watchGlobalAlloc(UINT Flags, UINT size)
{
HGLOBAL block = GlobalAlloc(Flags, size);
blocks[blocksnum++] = block;
return block;
}
void watchGlobalFree(HGLOBAL block)
{
for (int i = 0; i < blocksnum; i++)
if (blocks[i] == block) blocks[i] = NULL;
GlobalFree(block);
}
void watchGlobal()
{
for (int i = 0; i < blocksnum; i++)
if (blocks[i] != NULL)
{
_RPT2(_CRT_WARN, "Memory leak %d at %8X\n", i, blocks[i]);
}
}
#endif
// utility functions (not required but often useful)
int popstring(char *str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
lstrcpy(str,th->text);
*g_stacktop = th->next;
dbgGlobalFree((HGLOBAL)th);
return 0;
}
void pushstring(char *str)
{
stack_t *th;
if (!g_stacktop) return;
th=(stack_t*)dbgGlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
lstrcpyn(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}
char *getuservariable(int varnum)
{
if (varnum < 0 || varnum >= __INST_LAST) return NULL;
return g_variables+varnum*g_stringsize;
}
void setuservariable(int varnum, char *var)
{
if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
lstrcpy(g_variables + varnum*g_stringsize, var);
}
char *AllocString()
{
return (char*) dbgGlobalAlloc(GPTR,g_stringsize);
}
ExpressionItem *AllocItem()
{
ExpressionItem *item = (ExpressionItem*)dbgGlobalAlloc(GPTR,sizeof(ExpressionItem));
item->next = NULL;
item->type = IT_CONST | ITC_INT;
item->param1 = item->param2 = 0;
return item;
}
ExpressionItem *AllocArray(int s)
{
int size = DEFAULT_ARRAY_SIZE;
while (s > size) size*=2;
ExpressionItem *ai = (ExpressionItem*)dbgGlobalAlloc(GPTR,sizeof(ExpressionItem));
ai->type = IT_CONST | ITC_ARRAY;
ai->param1 = (int) dbgGlobalAlloc(GPTR, sizeof(ArrayDesc));
ArrayDesc *ad = *((ArrayDesc**)&(ai->param1));
// initialize and clear the array memory
ad->array = (ExpressionItem**) dbgGlobalAlloc(GPTR, size*sizeof(ExpressionItem*));
ad->size = size;
ad->count = 0;
ad->references = 1;
return ai;
}
ExpressionItem *CopyItem(ExpressionItem *citem, int NeedConst)
{
if (!citem) return NULL;
ExpressionItem *item = NULL;
if ((NeedConst) && ((citem->type & ITEMTYPE) != IT_CONST))
{
// in case of non constant expression - flat it to const
RunTree(citem, item, RTO_NEEDCONST | ITC_INT | ITC_STRING | ITC_FLOAT | ITC_ARRAY);
if (item) return item;
}
item = AllocItem();
item->type = citem->type;
if ((item->type & (ITEMTYPE | ITEMSUBTYPE)) == (IT_CONST | ITC_STRING))
{
item->param1 = (int) AllocString();
lstrcpy((LPSTR) item->param1, (LPSTR) citem->param1);
} else if (((item->type & (ITEMTYPE | ITEMSUBTYPE)) == (IT_CONST | ITC_ARRAY))
||
((item->type & (ITEMTYPE | ITEMSUBTYPE)) == (IT_VARIABLE | ITV_ARRITEM)))
{
item->param1 = citem->param1;
ArrayDesc *ad = (ArrayDesc*) item->param1;
ad->references++;
}
else item->param1 = citem->param1;
item->param2 = citem->param2;
item->next = NULL;
return item;
}

39
Contrib/Math/math.nsi Normal file
View file

@ -0,0 +1,39 @@
; This is just an example of Math plugin
;
; (c) brainsucker, 2002
; (r) BSForce
Name "Math Plugin Example"
OutFile "math.exe"
SetPluginUnload alwaysoff
ShowInstDetails show
XPStyle on
Section "ThisNameIsIgnoredSoWhyBother?"
Math::Script 'SaR(s,fa,ra, i,f,r,e,p) (i=0;#{i<l(fa),e=l(f=fa[i]);r=ra[i];p=0;#{p<l(s),#[s[p,p+e-1]==f,s=(s[,p-1])+r+(s[p+e,]);p+=l(r), p++]}; i++}; s);'
Math::Script "TQ(s) (s = s(NS); #[s[0]=='$\"',s=s[1,]]; #[s[-1]=='$\"',s=s[,-2]]; NS = s)"
Math::Script "P(s,e, p,i) (p=-1;i=0; #{(i<l(s))&&(p<0), #[s[i,i+l(e)-1]==e, p=i]; i++}; p)"
Math::Script "DL(s) (s=s(NS); p=P(s,'\r\n'); #[p>=0, (NS=s[p+4,]; NS=#[p>0,s[,p-1],'']), (NS='';NS=s)])"
Math::Script "a = 'Hello \r\n World \r\n!!!'; a = SaR(a,{'\r','\n'},{'$\r','$\n'}); R0 = a"
Math::Script "NS = '$\"In quotes$\"'; TQ(); R1=NS; R3=P(s(R1),'qu')"
Math::Script "NS = 'No quotes'; TQ(); R2=NS"
Math::Script "NS='123\r\n456\r\n789'; DL(); R4=NS; DL(); R5=NS; DL(); R6=NS; R7=NS"
DetailPrint "'$R0'"
DetailPrint "'$R1'"
DetailPrint "'$R2'"
DetailPrint "'$R3'"
DetailPrint "'$R4'"
DetailPrint "'$R5'"
DetailPrint "'$R6'"
DetailPrint "'$R7'"
; last plugin call must not have /NOUNLOAD so NSIS will be able to delete the temporary DLL
SetPluginUnload manual
; do nothing
Math::Script ""
SectionEnd
; eof

101
Contrib/Math/mathtest.ini Normal file
View file

@ -0,0 +1,101 @@
[Settings]
NumFields=10
NextButtonText=Execute
CancelButtonText=Quit
BackButtonText=Readme
[Field 1]
Type=label
Text=Enter your script here:
Left=0
Right=-1
Top=0
Bottom=8
[Field 2]
Type=text
Left=0
Right=-1
Top=9
Bottom=55
flags=MULTILINE|WANTRETURN|HSCROLL|VSCROLL
State=""
[Field 3]
Type=text
Left=53
Right=175
Top=56
Bottom=140
flags=MULTILINE|READONLY
State=""
[Field 4]
Type=text
Left=175
Right=-1
Top=56
Bottom=140
flags=MULTILINE|READONLY
State=""
[Field 5]
Type=RadioButton
Left=0
Right=-1
Top=70
Bottom=80
flags=GROUP
Text="Your script"
State=1
[Field 6]
Type=RadioButton
Left=0
Right=-1
Top=80
Bottom=90
flags=
Text="Sample 1"
State=0
[Field 7]
Type=RadioButton
Left=0
Right=-1
Top=90
Bottom=100
flags=
Text="Sample 2"
State=0
[Field 8]
Type=RadioButton
Left=0
Right=-1
Top=100
Bottom=110
flags=
Text="Sample 3"
State=0
[Field 9]
Type=RadioButton
Left=0
Right=-1
Top=110
Bottom=120
flags=
Text="Sample 4"
State=0
[Field 10]
Type=RadioButton
Left=0
Right=-1
Top=120
Bottom=130
flags=
Text="Sample 5"
State=0

171
Contrib/Math/mathtest.nsi Normal file
View file

@ -0,0 +1,171 @@
;NSIS Modern User Interface version 1.65
;InstallOptions Example Script
;Written by Joost Verburg
!define MUI_BUTTONTEXT_NEXT "Execute"
;---------------------
;Include Modern UI
!include "MUI.nsh"
;--------------------------------
;Product Info
Name "Math::Script Test"
;--------------------------------
;Configuration
;General
OutFile "MathTest.exe"
;--------------------------------
;Variables
Var TEMP1
Var TEMP2
Var TEMP3
;--------------------------------
;Pages
!insertmacro MUI_PAGE_LICENSE "mathtest.txt"
Page custom ScriptPageEnter
Page instfiles
;--------------------------------
;Modern UI Configuration
; !define MUI_ABORTWARNING
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Reserve Files
;Things that need to be extracted on first (keep these lines before any File command!)
;Only for BZIP2 compression
ReserveFile "MathTest.ini"
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
;--------------------------------
;Installer Functions
LangString SCRIPTSAMPLE0 ${LANG_ENGLISH} "r0 = 'Hello'; r1 = 'Math::Script'\r\nr0 += ' from the ' + r1 + '!'; r1=''"
LangString SCRIPTSAMPLE1 ${LANG_ENGLISH} "a =0; b=1.0\r\n#{a++ < 100, b *= a}\r\nr0 = a; R0 = b; R1 = ff(b, 15)\r\nr1 = (a-1) + '! = ' + b"
LangString SCRIPTSAMPLE2 ${LANG_ENGLISH} 'pi=3.14159; \r\nangle = pi/4;\r\ntext = "x = " + ff(angle,16+3) \r\nr0 = text += ", sin x = " + sin(angle)'
LangString SCRIPTSAMPLE3 ${LANG_ENGLISH} "v1 = 123.456; v2 = 123456789.1011\r\nr0 = v1; r1 = v2\r\nr2 = ff(v1, 3); r3 = ff(v2, 3); r4 = ff(v1, 3+16); r5 = ff(v2, 3+16)\r\nr6 = ff(v1, 3+32); r7 = ff(v2, 3+32); r8 = ff(v1, 3+32+64); r9 = ff(v2, 3+32+64)\r\n"
LangString SCRIPTSAMPLE4 ${LANG_ENGLISH} "a = 10000; b = 0; #{--a > 0, b+= a}; r0 = a; r1 = b\r\nz = 1.55; r2 = #[z > 1.5, 'Its greater', 'Its lower']\r\nz = 1.45; r3 = #[z > 1.5, 'Its greater', 'Its lower']"
LangString SCRIPTSAMPLE5 ${LANG_ENGLISH} 'r0 = "123a123"\r\nr1 = r0; \r\nr2 = s(r0); r3 = f(r0); r4 = i(r0); r5 = len(r0)'
Function .onInit
;Extract InstallOptions INI files
!insertmacro MUI_INSTALLOPTIONS_EXTRACT "MathTest.ini"
Strcpy "$TEMP1" "$(SCRIPTSAMPLE0)"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 2" "State" $TEMP1
FunctionEnd
LangString TEXT_IO_TITLE ${LANG_ENGLISH} "MathTest Script Page"
LangString TEXT_IO_SUBTITLE ${LANG_ENGLISH} "Try your scripting capapibilites or test one of sample scripts"
Function DumpVariables
Strcpy "$TEMP1" "$$0='$0'\r\n$$1='$1'\r\n$$2='$2'\r\n$$3='$3'\r\n$$4='$4'\r\n$$5='$5'\r\n$$6='$6'\r\n$$7='$7'\r\n$$8='$8'\r\n$$9='$9'"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 3" "State" $TEMP1
Strcpy "$TEMP1" "$$R0='$R0'\r\n$$R1='$R1'\r\n$$R2='$R2'\r\n$$R3='$R3'\r\n$$R4='$R4'\r\n$$R5='$R5'\r\n$$R6='$R6'\r\n$$R7='$R7'\r\n$$R8='$R8'\r\n$$R9='$R9'"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 4" "State" $TEMP1
FunctionEnd
Function ClearVariables
Math::Script "r0=r1=r2=r3=r4=r5=r6=r7=r8=r9=R0=R1=R2=R3=R4=R5=R6=R7=R8=R9=''"
FunctionEnd
Function GetLine
push $TEMP1
Math::Script /NOUNLOAD "DL()"
pop $TEMP2
pop $TEMP1
FunctionEnd
Function ExecuteScript
!insertmacro MUI_INSTALLOPTIONS_READ $TEMP1 "MathTest.ini" "Field 2" "State"
Math::Script /NOUNLOAD "TQ(s) (s = s(NS); #[s[0]=='$\"',s=s[1,]]; #[s[-1]=='$\"',s=s[,-2]]; NS = s)"
Math::Script /NOUNLOAD "P(s,e, p,i) (p=-1;i=0; #{(i<l(s))&&(p<0), #[s[i,i+l(e)-1]==e, p=i]; i++}; p)"
Math::Script /NOUNLOAD "DL(s) (s=s(NS); p=P(s,'\r\n'); #[p>=0, (NS=s[p+4,]; NS=#[p>0,s[,p-1],'']), (NS='';NS=s)])"
push $TEMP1
; remove ""
Math::Script /NOUNLOAD "TQ()"
pop $TEMP1
; script at $TEMP1
Go:
StrLen $TEMP3 $TEMP1
IntCmp $TEMP3 0 End
; get single line to $TEMP2
Call GetLine
; MessageBox MB_OK "'$TEMP2' '$TEMP1'"
Math::Script /NOUNLOAD "$TEMP2"
goto Go
End:
Math::Script ""
FunctionEnd
Function ScriptPageEnter
!insertmacro MUI_HEADER_TEXT "$(TEXT_IO_TITLE)" "$(TEXT_IO_SUBTITLE)"
Again:
Call ClearVariables
Call ExecuteScript
Call DumpVariables
!insertmacro MUI_INSTALLOPTIONS_DISPLAY_RETURN "mathtest.ini"
pop $TEMP3
!insertmacro MUI_INSTALLOPTIONS_READ $TEMP1 "MathTest.ini" "Field 5" "State"
IntCmp $TEMP1 1 Test
Strcpy "$TEMP2" "$(SCRIPTSAMPLE1)"
!insertmacro MUI_INSTALLOPTIONS_READ $TEMP1 "MathTest.ini" "Field 6" "State"
IntCmp $TEMP1 1 Write
Strcpy "$TEMP2" "$(SCRIPTSAMPLE2)"
!insertmacro MUI_INSTALLOPTIONS_READ $TEMP1 "MathTest.ini" "Field 7" "State"
IntCmp $TEMP1 1 Write
Strcpy "$TEMP2" "$(SCRIPTSAMPLE3)"
!insertmacro MUI_INSTALLOPTIONS_READ $TEMP1 "MathTest.ini" "Field 8" "State"
IntCmp $TEMP1 1 Write
Strcpy "$TEMP2" "$(SCRIPTSAMPLE4)"
!insertmacro MUI_INSTALLOPTIONS_READ $TEMP1 "MathTest.ini" "Field 9" "State"
IntCmp $TEMP1 1 Write
Strcpy "$TEMP2" "$(SCRIPTSAMPLE5)"
Write:
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 2" "State" "$TEMP2"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 5" "State" "1"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 6" "State" "0"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 7" "State" "0"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 8" "State" "0"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 9" "State" "0"
!insertmacro MUI_INSTALLOPTIONS_WRITE "MathTest.ini" "Field 10" "State" "0"
Test:
Strcmp $TEMP3 "success" Again
FunctionEnd
Section "Dummy Section" SecDummy
SectionEnd

View file

@ -0,0 +1,7 @@
Math Tester.
This demo allows you to test your Math::Script expressions without need to compile anything. Just enter your expressions into multiline editbox (every single line is a separate call to Math::Script) or select one of sample expressions and press Execute.
Every call to Math::Script can accept up to 1kb of script, but this demo is limited to the summ of 1 kb at all lines. And... watch your scripts. No.... Watch your errors at scripts!
(c) Brainsucker, 2003.

BIN
Plugins/Math.dll Normal file

Binary file not shown.