Post by jeeswg » 21 Aug 2018, 01:13
Code: Select all
==================================================
for AHK v1: function names and parameters:
Add(Num1, Num2)
EmptyFloat()
EmptyInteger()
EmptyString()
ReturnFloat()
ReturnInteger()
ReturnString()
StrConcat(Text1, Text2)
StrLeft(Text, Num)
StrRight(Text, Num)
StrTrimLeft(Text, Num)
StrTrimRight(Text, Num)
Sum(Params*)
note: Add could be easily modified to become Sub/Mult/Div
note: Sum could be easily modified to become Product
==================================================
[script.h]
BIF_DECL(BIF_Add);
BIF_DECL(BIF_EmptyFloat);
BIF_DECL(BIF_EmptyInteger);
BIF_DECL(BIF_EmptyString);
BIF_DECL(BIF_ReturnFloat);
BIF_DECL(BIF_ReturnInteger);
BIF_DECL(BIF_ReturnString);
BIF_DECL(BIF_StrConcat);
BIF_DECL(BIF_StrLeft);
BIF_DECL(BIF_StrRight);
BIF_DECL(BIF_StrTrimLeft);
BIF_DECL(BIF_StrTrimRight);
BIF_DECL(BIF_Sum);
==================================================
[script.cpp]
else if (!_tcsicmp(func_name, _T("Add")))
{
bif = BIF_Add;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("EmptyFloat")))
{
bif = BIF_EmptyFloat;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("EmptyInteger")))
{
bif = BIF_EmptyInteger;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("EmptyString")))
{
bif = BIF_EmptyString;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("ReturnFloat")))
{
bif = BIF_ReturnFloat;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("ReturnInteger")))
{
bif = BIF_ReturnInteger;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("ReturnString")))
{
bif = BIF_ReturnString;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("StrConcat")))
{
bif = BIF_StrConcat;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrLeft")))
{
bif = BIF_StrLeft;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrRight")))
{
bif = BIF_StrRight;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrTrimLeft")))
{
bif = BIF_StrTrimLeft;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrTrimRight")))
{
bif = BIF_StrTrimRight;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("Sum")))
{
bif = BIF_Sum;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
==================================================
[script2.cpp]
BIF_DECL(BIF_Add)
{
ExprTokenType param0, param1;
if (!ParamIndexToNumber(0, param0) || !ParamIndexToNumber(1, param1)) // Non-operand or non-numeric string.
{
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
return;
}
if (param0.symbol == SYM_INTEGER && param1.symbol == SYM_INTEGER)
{
aResultToken.symbol = SYM_INTEGER;
aResultToken.value_int64 = param0.value_int64 + param1.value_int64;
}
else // At least one is a floating point number.
{
double double1 = TokenToDouble(param0);
double double2 = TokenToDouble(param1);
aResultToken.symbol = SYM_FLOAT;
aResultToken.value_double = double1 + double2;
}
}
BIF_DECL(BIF_EmptyFloat)
{
//returns 0
aResultToken.symbol = SYM_FLOAT;
}
BIF_DECL(BIF_EmptyInteger)
{
//returned a 17-digit positive integer during my tests
aResultToken.symbol = SYM_INTEGER; //line not needed
}
BIF_DECL(BIF_EmptyString)
{
//returns the function name
aResultToken.symbol = SYM_STRING;
}
BIF_DECL(BIF_ReturnFloat)
{
aResultToken.symbol = SYM_FLOAT;
aResultToken.value_double = 42;
}
BIF_DECL(BIF_ReturnInteger)
{
aResultToken.symbol = SYM_INTEGER; //line not needed
aResultToken.value_int64 = 42;
}
BIF_DECL(BIF_ReturnString)
{
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("hello world");
}
BIF_DECL(BIF_StrConcat)
{
aResultToken.symbol = SYM_STRING;
int len0 = (int)_tcslen(ParamIndexToString(0));
int len1 = (int)_tcslen(ParamIndexToString(1));
if (len0 + len1 == 0)
{
aResultToken.marker = _T("");
return;
}
TCHAR *output = new TCHAR[len0+len1+1];
tmemcpy(output, ParamIndexToString(0), len0);
tmemcpy(output+len0, ParamIndexToString(1), len1+1);
aResultToken.marker = output;
}
BIF_DECL(BIF_StrLeft)
{
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR extract_length = (INT_PTR)ParamIndexToInt64(1);
if (extract_length < 1)
return;
if (!TokenSetResult(aResultToken, haystack, extract_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_StrRight)
{
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR extract_length = (INT_PTR)ParamIndexToInt64(1);
if (extract_length < 1)
return;
if (extract_length > haystack_length)
extract_length = haystack_length;
LPTSTR result = haystack + haystack_length - extract_length; // This is the result except for the possible need to truncate it below.
if (!TokenSetResult(aResultToken, result, extract_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_StrTrimLeft)
{
//causing crashes (check if 2nd param looks numeric)
//if (!TokenToDoubleOrInt64(*aParam[1], aResultToken)) // "Cast" token to Int64/Double depending on whether it has a decimal point.
// return;
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR crop_length = (INT_PTR)ParamIndexToInt64(1);
if (crop_length >= haystack_length)
return;
LPTSTR result = haystack + crop_length; // This is the result except for the possible need to truncate it below.
if (!TokenSetResult(aResultToken, result, haystack_length - crop_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_StrTrimRight)
{
//causing crashes (check if 2nd param looks numeric)
//if (!TokenToDoubleOrInt64(*aParam[1], aResultToken)) // "Cast" token to Int64/Double depending on whether it has a decimal point.
// return;
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR crop_length = (INT_PTR)ParamIndexToInt64(1);
if (crop_length < 0 || crop_length >= haystack_length)
return;
if (!TokenSetResult(aResultToken, haystack, haystack_length-crop_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_Sum)
{
// Supports one or more parameters.
// Load-time validation has already ensured there is at least one parameter.
ExprTokenType param;
__int64 i_sum = 0;
double d_sum = 0;
bool d_empty = TRUE;
for (int i = 0; i < aParamCount; ++i)
{
ParamIndexToNumber(i, param);
switch (param.symbol)
{
case SYM_INTEGER:
i_sum += param.value_int64;
break;
case SYM_FLOAT:
d_sum += param.value_double;
if (d_empty)
d_empty = FALSE;
break;
default: // Non-operand or non-numeric string.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
return; // Return a blank value to indicate the problem.
}
}
if (d_empty)
{
aResultToken.symbol = SYM_INTEGER;
aResultToken.value_int64 = i_sum;
}
else
{
aResultToken.symbol = SYM_FLOAT;
aResultToken.value_double = d_sum + (double)i_sum;
}
}
==================================================
[code=cpp]
==================================================
for AHK v1: function names and parameters:
Add(Num1, Num2)
EmptyFloat()
EmptyInteger()
EmptyString()
ReturnFloat()
ReturnInteger()
ReturnString()
StrConcat(Text1, Text2)
StrLeft(Text, Num)
StrRight(Text, Num)
StrTrimLeft(Text, Num)
StrTrimRight(Text, Num)
Sum(Params*)
note: Add could be easily modified to become Sub/Mult/Div
note: Sum could be easily modified to become Product
==================================================
[script.h]
BIF_DECL(BIF_Add);
BIF_DECL(BIF_EmptyFloat);
BIF_DECL(BIF_EmptyInteger);
BIF_DECL(BIF_EmptyString);
BIF_DECL(BIF_ReturnFloat);
BIF_DECL(BIF_ReturnInteger);
BIF_DECL(BIF_ReturnString);
BIF_DECL(BIF_StrConcat);
BIF_DECL(BIF_StrLeft);
BIF_DECL(BIF_StrRight);
BIF_DECL(BIF_StrTrimLeft);
BIF_DECL(BIF_StrTrimRight);
BIF_DECL(BIF_Sum);
==================================================
[script.cpp]
else if (!_tcsicmp(func_name, _T("Add")))
{
bif = BIF_Add;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("EmptyFloat")))
{
bif = BIF_EmptyFloat;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("EmptyInteger")))
{
bif = BIF_EmptyInteger;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("EmptyString")))
{
bif = BIF_EmptyString;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("ReturnFloat")))
{
bif = BIF_ReturnFloat;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("ReturnInteger")))
{
bif = BIF_ReturnInteger;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("ReturnString")))
{
bif = BIF_ReturnString;
min_params = 0;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
else if (!_tcsicmp(func_name, _T("StrConcat")))
{
bif = BIF_StrConcat;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrLeft")))
{
bif = BIF_StrLeft;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrRight")))
{
bif = BIF_StrRight;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrTrimLeft")))
{
bif = BIF_StrTrimLeft;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("StrTrimRight")))
{
bif = BIF_StrTrimRight;
min_params = 2;
max_params = 2;
}
else if (!_tcsicmp(func_name, _T("Sum")))
{
bif = BIF_Sum;
max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
}
==================================================
[script2.cpp]
BIF_DECL(BIF_Add)
{
ExprTokenType param0, param1;
if (!ParamIndexToNumber(0, param0) || !ParamIndexToNumber(1, param1)) // Non-operand or non-numeric string.
{
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
return;
}
if (param0.symbol == SYM_INTEGER && param1.symbol == SYM_INTEGER)
{
aResultToken.symbol = SYM_INTEGER;
aResultToken.value_int64 = param0.value_int64 + param1.value_int64;
}
else // At least one is a floating point number.
{
double double1 = TokenToDouble(param0);
double double2 = TokenToDouble(param1);
aResultToken.symbol = SYM_FLOAT;
aResultToken.value_double = double1 + double2;
}
}
BIF_DECL(BIF_EmptyFloat)
{
//returns 0
aResultToken.symbol = SYM_FLOAT;
}
BIF_DECL(BIF_EmptyInteger)
{
//returned a 17-digit positive integer during my tests
aResultToken.symbol = SYM_INTEGER; //line not needed
}
BIF_DECL(BIF_EmptyString)
{
//returns the function name
aResultToken.symbol = SYM_STRING;
}
BIF_DECL(BIF_ReturnFloat)
{
aResultToken.symbol = SYM_FLOAT;
aResultToken.value_double = 42;
}
BIF_DECL(BIF_ReturnInteger)
{
aResultToken.symbol = SYM_INTEGER; //line not needed
aResultToken.value_int64 = 42;
}
BIF_DECL(BIF_ReturnString)
{
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("hello world");
}
BIF_DECL(BIF_StrConcat)
{
aResultToken.symbol = SYM_STRING;
int len0 = (int)_tcslen(ParamIndexToString(0));
int len1 = (int)_tcslen(ParamIndexToString(1));
if (len0 + len1 == 0)
{
aResultToken.marker = _T("");
return;
}
TCHAR *output = new TCHAR[len0+len1+1];
tmemcpy(output, ParamIndexToString(0), len0);
tmemcpy(output+len0, ParamIndexToString(1), len1+1);
aResultToken.marker = output;
}
BIF_DECL(BIF_StrLeft)
{
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR extract_length = (INT_PTR)ParamIndexToInt64(1);
if (extract_length < 1)
return;
if (!TokenSetResult(aResultToken, haystack, extract_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_StrRight)
{
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR extract_length = (INT_PTR)ParamIndexToInt64(1);
if (extract_length < 1)
return;
if (extract_length > haystack_length)
extract_length = haystack_length;
LPTSTR result = haystack + haystack_length - extract_length; // This is the result except for the possible need to truncate it below.
if (!TokenSetResult(aResultToken, result, extract_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_StrTrimLeft)
{
//causing crashes (check if 2nd param looks numeric)
//if (!TokenToDoubleOrInt64(*aParam[1], aResultToken)) // "Cast" token to Int64/Double depending on whether it has a decimal point.
// return;
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR crop_length = (INT_PTR)ParamIndexToInt64(1);
if (crop_length >= haystack_length)
return;
LPTSTR result = haystack + crop_length; // This is the result except for the possible need to truncate it below.
if (!TokenSetResult(aResultToken, result, haystack_length - crop_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_StrTrimRight)
{
//causing crashes (check if 2nd param looks numeric)
//if (!TokenToDoubleOrInt64(*aParam[1], aResultToken)) // "Cast" token to Int64/Double depending on whether it has a decimal point.
// return;
// Set default return value in case of early return.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
TCHAR haystack_buf[MAX_NUMBER_SIZE]; // A separate buf because aResultToken.buf is sometimes used to store the result.
LPTSTR haystack = ParamIndexToString(0, haystack_buf); // Remember that aResultToken.buf is part of a union, though in this case there's no danger of overwriting it since our result will always be of STRING type (not int or float).
INT_PTR haystack_length = (INT_PTR)ParamIndexLength(0, haystack);
INT_PTR crop_length = (INT_PTR)ParamIndexToInt64(1);
if (crop_length < 0 || crop_length >= haystack_length)
return;
if (!TokenSetResult(aResultToken, haystack, haystack_length-crop_length))
{
// Yield the empty string (a default set higher above).
}
}
BIF_DECL(BIF_Sum)
{
// Supports one or more parameters.
// Load-time validation has already ensured there is at least one parameter.
ExprTokenType param;
__int64 i_sum = 0;
double d_sum = 0;
bool d_empty = TRUE;
for (int i = 0; i < aParamCount; ++i)
{
ParamIndexToNumber(i, param);
switch (param.symbol)
{
case SYM_INTEGER:
i_sum += param.value_int64;
break;
case SYM_FLOAT:
d_sum += param.value_double;
if (d_empty)
d_empty = FALSE;
break;
default: // Non-operand or non-numeric string.
aResultToken.symbol = SYM_STRING;
aResultToken.marker = _T("");
return; // Return a blank value to indicate the problem.
}
}
if (d_empty)
{
aResultToken.symbol = SYM_INTEGER;
aResultToken.value_int64 = i_sum;
}
else
{
aResultToken.symbol = SYM_FLOAT;
aResultToken.value_double = d_sum + (double)i_sum;
}
}
==================================================
[/code]