diff --git a/Library/ConfigParser.cpp b/Library/ConfigParser.cpp index 37df624c..efe4935e 100644 --- a/Library/ConfigParser.cpp +++ b/Library/ConfigParser.cpp @@ -18,6 +18,7 @@ #include "StdAfx.h" #include "ConfigParser.h" +#include "MathParser.h" #include "Litestep.h" #include "Rainmeter.h" #include "System.h" @@ -37,7 +38,6 @@ std::unordered_map CConfigParser::c_MonitorVariables ** */ CConfigParser::CConfigParser() : - m_Parser(MathParser_Create(NULL)), m_LastReplaced(false), m_LastDefaultUsed(false), m_LastValueDefined(false), @@ -53,7 +53,6 @@ CConfigParser::CConfigParser() : */ CConfigParser::~CConfigParser() { - MathParser_Destroy(m_Parser); } /* @@ -757,7 +756,7 @@ double CConfigParser::ReadFormula(LPCTSTR section, LPCTSTR key, double defValue) if (!result.empty() && result[0] == L'(' && result[result.size() - 1] == L')') { double resultValue = defValue; - char* errMsg = MathParser_Parse(m_Parser, ConvertToAscii(result.c_str()).c_str(), &resultValue); + char* errMsg = MathParser::CheckParse(ConvertToAscii(result.c_str()).c_str(), &resultValue); if (errMsg != NULL) { std::wstring error = L"ReadFormula: "; @@ -783,7 +782,7 @@ bool CConfigParser::ParseFormula(const std::wstring& result, double* resultValue // Formulas must be surrounded by parenthesis if (!result.empty() && result[0] == L'(' && result[result.size() - 1] == L')') { - char* errMsg = MathParser_Parse(m_Parser, ConvertToAscii(result.c_str()).c_str(), resultValue); + char* errMsg = MathParser::CheckParse(ConvertToAscii(result.c_str()).c_str(), resultValue); if (errMsg != NULL) { std::wstring error = L"ParseFormula: "; diff --git a/Library/ConfigParser.h b/Library/ConfigParser.h index 35be657d..ffabc9b5 100644 --- a/Library/ConfigParser.h +++ b/Library/ConfigParser.h @@ -28,7 +28,6 @@ #include #include #include -#include "ccalc-0.5.1/mparser.h" class CRainmeter; class CMeterWindow; @@ -122,7 +121,6 @@ private: std::wstring m_Filename; - hqMathParser* m_Parser; std::unordered_map m_Measures; std::vector m_StyleTemplate; diff --git a/Library/Library.vcxproj b/Library/Library.vcxproj index 85d52179..5c8529ec 100644 --- a/Library/Library.vcxproj +++ b/Library/Library.vcxproj @@ -333,6 +333,17 @@ MaxSpeed Use + + Disabled + EnableFastChecks + Use + Disabled + EnableFastChecks + MaxSpeed + Use + MaxSpeed + Use + Disabled EnableFastChecks @@ -721,30 +732,6 @@ MaxSpeed Use - - Disabled - EnableFastChecks - Disabled - EnableFastChecks - MaxSpeed - MaxSpeed - - - Disabled - EnableFastChecks - Disabled - EnableFastChecks - MaxSpeed - MaxSpeed - - - Disabled - EnableFastChecks - Disabled - EnableFastChecks - MaxSpeed - MaxSpeed - Use ../StdAfx.h @@ -855,6 +842,7 @@ + @@ -896,10 +884,6 @@ - - - - diff --git a/Library/Library.vcxproj.filters b/Library/Library.vcxproj.filters index 51b05101..1e0885cb 100644 --- a/Library/Library.vcxproj.filters +++ b/Library/Library.vcxproj.filters @@ -13,9 +13,6 @@ {2d6bf39d-48e1-4de3-8924-46c5666cb141} ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - {1d914071-7b9c-400c-b7ab-76ac461a16f3} - {6570e2b7-2e40-4fba-a051-01de85760fea} @@ -144,15 +141,6 @@ Source Files - - CCalc - - - CCalc - - - CCalc - Lua @@ -354,6 +342,9 @@ Source Files + + Source Files + @@ -476,18 +467,6 @@ Header Files - - CCalc - - - CCalc - - - CCalc - - - CCalc - Lua @@ -596,6 +575,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/Library/MathParser.cpp b/Library/MathParser.cpp new file mode 100644 index 00000000..5c20876e --- /dev/null +++ b/Library/MathParser.cpp @@ -0,0 +1,877 @@ +/* + Copyright (C) 2011 Birunthan Mohanathas + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNEstring FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// Heavily based on ccalc 0.5.1 by Walery Studennikov + +#include "StdAfx.h" +#include "MathParser.h" + +static const int MAX_STACK_SIZE = 32; +static const double M_E = 2.7182818284590452354; +static const double M_PI = 3.14159265358979323846; + +typedef double (*OneArgProc)(double arg); +typedef char* (*MultiArgProc)(int paramcnt, double* args, double* result); +typedef double (*FunctionProc)(double); + +typedef enum +{ + OP_SHL, + OP_SHR, + OP_POW, + OP_LOGIC_NEQ, + OP_LOGIC_GEQ, + OP_LOGIC_LEQ, + OP_LOGIC_AND, + OP_LOGIC_OR, + OP_OBR, + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_UNK, + OP_XOR, + OP_NOT, + OP_AND, + OP_OR, + OP_EQU, + OP_GREATER, + OP_SMALLER, + OP_LOGIC, + OP_LOGIC_SEP, + OP_CBR, + OP_COMMA, + OP_FUNC_ONEARG, // Special + OP_FUNC_MULTIARG // Special +} OperationType; + +typedef struct +{ + void* Func; + char prevvalTop; + OperationType type; +} Operation; + +typedef enum +{ + CH_LETTER = 0x01, + CH_DIGIT = 0x02, + CH_SEPARAT = 0x04, + CH_SYMBOL = 0x08, + CH_UNKNOWN = 0x7E, + CH_FINAL = 0x7F +} CharType; + +typedef enum +{ + TOK_ERROR, + TOK_NONE, + TOK_FINAL, + TOK_FLOAT, + TOK_SYMBOL, + TOK_NAME +} MathTokenType; + +typedef struct +{ + char* name; + FunctionProc proc; + unsigned char length; +} Function; + +typedef struct +{ + const char* string; + const char* name; + size_t nameLen; + double extValue; + int intValue; + MathTokenType PrevTokenType; + CharType CharType; +} Lexer; + +char eBrackets [] = "Unmatched brackets"; +char eSyntax [] = "Syntax error"; +char eInternal [] = "Internal error"; +char eExtraOp [] = "Extra operation"; +char eInfinity [] = "Infinity somewhere"; +char eInvArg [] = "Invalid argument"; +char eUnknFunc [] = "\"%s\" is unknown"; +char eLogicErr [] = "Logical expression error"; +char eCalcErr [] = "Calculation error"; +char eValSizErr[] = "Value too big for operation"; +char eInvPrmCnt[] = "Invalid function parameter count"; +char g_ErrorBuffer[128]; + +static char* CalcToObr(); +static char* Calc(); +static int GetFunction(const char* str, size_t len, void** data); +int FindSymbol(const char* str); + +static int Lexer_SetParseString(const char* str); +static MathTokenType Lexer_GetNextToken(); + +static double neg(double x); +static double frac(double x); +static double trunc(double x); +static double sgn(double x); +static char* round(int paramcnt, double* args, double* result); + +static Function g_Functions[] = +{ + { "atan", &atan, 4 }, + { "cos", &cos, 3 }, + { "sin", &sin, 3 }, + { "tan", &tan, 3 }, + { "abs", &fabs, 3 }, + { "exp", &exp, 3 }, + { "ln", &log, 2 }, + { "log", &log10, 3 }, + { "sqrt", &sqrt, 4 }, + { "frac", &frac, 4 }, + { "trunc", &trunc, 5 }, + { "floor", &floor, 5 }, + { "ceil", &ceil, 4 }, + { "round", (FunctionProc)&round, 5 }, + { "asin", &asin, 4 }, + { "acos", &acos, 4 }, + { "sgn", &sgn, 4 }, + { "neg", &neg, 4 }, + { "e", NULL, 1 }, + { "pi", NULL, 2} +}; + +static const int MAX_FUNC_LEN = 5; + +#define FUNC_ROUND 13 +#define FUNC_E 18 +#define FUNC_PI 19 + +static const Operation g_BrOp = { NULL, '0', OP_OBR }; +static const Operation g_NegOp = { (void*)&neg, '0', OP_FUNC_ONEARG }; + +static const char g_OpPriorities[OP_FUNC_MULTIARG + 1] = +{ + 5, // OP_SHL + 5, // OP_SHR + 5, // OP_POW + 2, // OP_LOGIC_NEQ + 2, // OP_LOGIC_GEQ + 2, // OP_LOGIC_LEQ + 2, // OP_LOGIC_AND + 2, // OP_LOGIC_OR + 0, // OP_OBR + 3, // OP_ADD + 3, // OP_SUB + 4, // OP_MUL + 4, // OP_DIV + 4, // OP_MOD + 4, // OP_UNK + 5, // OP_XOR + 5, // OP_NOT + 5, // OP_AND + 5, // OP_OR + 2, // OP_EQU + 2, // OP_GREATER + 2, // OP_SMALLER + 1, // OP_LOGIC + 2, // OP_LOGIC_SEP + 0, // OP_CBR + 2, // OP_COMMA + 6, // OP_FUNC_ONEARG + 6 // OP_FUNC_MULTIARG +}; + +static Operation g_OpStack[MAX_STACK_SIZE]; +static double g_ValStack[MAX_STACK_SIZE]; +static int g_OpTop = 0; +static int g_ValTop = -1; +static int g_ObrDist = 0; +static CharType g_CharTypes[256] = {(CharType)0}; +static Lexer g_Lexer = {0}; + +void MathParser::Initialize() +{ + g_CharTypes['\0'] = CH_FINAL; + + g_CharTypes[' '] = g_CharTypes['\t'] = g_CharTypes['\n'] = CH_SEPARAT; + + g_CharTypes['_'] = CH_LETTER; + for (int ch = 'A'; ch <= 'Z'; ++ch) g_CharTypes[ch] = CH_LETTER; + for (int ch = 'a'; ch <= 'z'; ++ch) g_CharTypes[ch] = CH_LETTER; + for (int ch = '0'; ch <= '9'; ++ch) g_CharTypes[ch] = CH_DIGIT; + + g_CharTypes['+'] = g_CharTypes['-'] = g_CharTypes['/'] = g_CharTypes['*'] = + g_CharTypes['~'] = g_CharTypes['('] = g_CharTypes[')'] = g_CharTypes['<'] = + g_CharTypes['>'] = g_CharTypes['%'] = g_CharTypes['$'] = g_CharTypes[','] = + g_CharTypes['?'] = g_CharTypes[':'] = g_CharTypes['='] = g_CharTypes['&'] = + g_CharTypes['|'] = CH_SYMBOL; +} + +char* MathParser::Check(const char* formula) +{ + int BrCnt = 0; + + // Brackets Matching + while (*formula) + { + if (*formula == '(') + { + ++BrCnt; + } + else if (*formula == ')' && (--BrCnt < 0)) + { + return eBrackets; + } + ++formula; + } + + if (BrCnt != 0) + { + return eBrackets; + } + + return NULL; +} + +char* MathParser::CheckParse(const char* formula, double* result) +{ + char* ret = Check(formula); + if (ret) return ret; + + ret = Parse(formula, NULL, result); + if (ret) return ret; + + return NULL; +} + +char* MathParser::Parse(const char* formula, ParameterSearchProc searchProc, double* result) +{ + if (!formula || !*formula) + { + *result = 0.0; + return NULL; + } + + Lexer_SetParseString(formula); + + g_OpTop = 0; + g_ValTop = -1; + g_OpStack[0].type = OP_OBR; + g_ObrDist = 2; + + char* error; + MathTokenType token = Lexer_GetNextToken(); + for (;;) + { + --g_ObrDist; + switch (token) + { + case TOK_ERROR: + return eSyntax; + + case TOK_FINAL: + if ((error = CalcToObr()) != NULL) + return error; + goto setResult; + + case TOK_FLOAT: + g_ValStack[++g_ValTop] = g_Lexer.extValue; + break; + + case TOK_SYMBOL: + switch (g_Lexer.intValue) + { + case OP_OBR: // ( + { + g_OpStack[++g_OpTop] = g_BrOp; + g_ObrDist = 2; + } + break; + + case OP_CBR: //) + { + if ((error = CalcToObr()) != NULL) return error; + } + break; + + case OP_COMMA: // , + { + Operation* pOp; + if ((error = CalcToObr()) != NULL) return error; + + if ((pOp = &g_OpStack[g_OpTop])->type == OP_FUNC_MULTIARG) + { + g_OpStack[++g_OpTop] = g_BrOp; + g_ObrDist = 2; + } + else + { + return eSyntax; + } + } + break; + + default: + { + Operation op; + op.type = (OperationType) g_Lexer.intValue; + switch (op.type) + { + case OP_ADD: + if (g_ObrDist >= 1) goto nextToken; + break; + + case OP_SUB: + if (g_ObrDist >= 1) + { + g_OpStack[++g_OpTop] = g_NegOp; + goto nextToken; + } + break; + + case OP_LOGIC: + case OP_LOGIC_SEP: + g_ObrDist = 2; + break; + } + + while (g_OpPriorities[op.type] <= g_OpPriorities[g_OpStack[g_OpTop].type]) + { + if ((error = Calc()) != NULL) return error; + } + g_OpStack[++g_OpTop] = op; + } + break; + } + break; + + case TOK_NAME: + { + Operation op; + double dblval; + void* *func = NULL; + int funcnum, namelen = g_Lexer.nameLen; + + if (g_Lexer.nameLen <= MAX_FUNC_LEN && + ((funcnum = GetFunction(g_Lexer.name, g_Lexer.nameLen, (void**)&op.Func)) >= 0)) + { + switch (funcnum) + { + case FUNC_E: + g_ValStack[++g_ValTop] = M_E; + break; + + case FUNC_PI: + g_ValStack[++g_ValTop] = M_PI; + break; + + case FUNC_ROUND: + op.type = OP_FUNC_MULTIARG; + op.prevvalTop = g_ValTop; + g_OpStack[++g_OpTop] = op; + break; + + default: // Internal function + op.type = OP_FUNC_ONEARG; + g_OpStack[++g_OpTop] = op; + break; + } + } + else + { + if (searchProc && (*searchProc)(g_Lexer.name, g_Lexer.nameLen, &dblval)) + { + g_ValStack[++g_ValTop] = dblval; + break; + } + + char buffer[128 - _countof(eUnknFunc)]; + strncpy_s(buffer, g_Lexer.name, g_Lexer.nameLen); + buffer[g_Lexer.nameLen] = '\0'; + _snprintf_s(g_ErrorBuffer, _TRUNCATE, eUnknFunc, buffer); + return g_ErrorBuffer; + } + break; + } + + default: + return eSyntax; + } + +nextToken: + token = Lexer_GetNextToken(); + } + +setResult: + if (g_OpTop != -1 || g_ValTop != 0) return eInternal; + + *result = g_ValStack[0]; + return NULL; +} + +static char* Calc() +{ + double res; + Operation op = g_OpStack[g_OpTop--]; + + // Multi-argument function + if (op.type == OP_FUNC_MULTIARG) + { + int paramcnt = g_ValTop - op.prevvalTop; + + g_ValTop = op.prevvalTop; + char* error = (*(MultiArgProc)op.Func)(paramcnt, &g_ValStack[g_ValTop + 1], &res); + if (error) return error; + + g_ValStack[++g_ValTop] = res; + return NULL; + } + else if (op.type == OP_LOGIC) + { + return NULL; + } + else if (g_ValTop < 0) + { + return eExtraOp; + } + + // Right arg + double right = g_ValStack[g_ValTop--]; + + // One arg operations + if (op.type == OP_NOT) + { + if (right >= INT_MIN && right <= INT_MAX) + { + res = ~((int)right); + } + else + { + return eValSizErr; + } + } + else if (op.type == OP_FUNC_ONEARG) + { + res = (*(OneArgProc)op.Func)(right); + } + else + { + if (g_ValTop < 0) + { + return eExtraOp; + } + + // Left arg + double left = g_ValStack[g_ValTop--]; + switch (op.type) + { + case OP_SHL: + if (left >= INT_MIN && left <= INT_MAX && right >= INT_MIN && right <= INT_MAX) + { + res = (int)left << (int)right; + } + else + { + return eValSizErr; + } + break; + + case OP_SHR: + if (left >= INT_MIN && left <= INT_MAX && right >= INT_MIN && right <= INT_MAX) + { + res = (int)left >> (int)right; + } + else + { + return eValSizErr; + } + break; + + case OP_POW: + res = pow(left, right); + break; + + case OP_LOGIC_NEQ: + res = left != right; + break; + + case OP_LOGIC_GEQ: + res = left >= right; + break; + + case OP_LOGIC_LEQ: + res = left <= right; + break; + + case OP_LOGIC_AND: + res = left && right; + break; + + case OP_LOGIC_OR: + res = left || right; + break; + + case OP_ADD: + res = left + right; + break; + + case OP_SUB: + res = left - right; + break; + + case OP_MUL: + res = left* right; + break; + + case OP_DIV: + if (right == 0.0) + { + return eInfinity; + } + else + { + res = left / right; + } + break; + + case OP_MOD: + res = fmod(left, right); + break; + + case OP_UNK: + if (left <= 0) + { + res = 0.0; + } + else if (right == 0.0) + { + return eInfinity; + } + else + { + res = ceil(left / right); + } + break; + + case OP_XOR: + if (left >= INT_MIN && left <= INT_MAX && right >= INT_MIN && right <= INT_MAX) + { + res = (int)left ^ (int)right; + } + else + { + return eValSizErr; + } + break; + + case OP_AND: + if (left >= INT_MIN && left <= INT_MAX && right >= INT_MIN && right <= INT_MAX) + { + res = (int)left & (int)right; + } + else + { + return eValSizErr; + } + break; + + case OP_OR: + if (left >= INT_MIN && left <= INT_MAX && right >= INT_MIN && right <= INT_MAX) + { + res = (int)left | (int)right; + } + else + { + return eValSizErr; + } + break; + + case OP_EQU: + res = left == right; + break; + + case OP_GREATER: + res = left > right; + break; + + case OP_SMALLER: + res = left < right; + break; + + case OP_LOGIC_SEP: + { + // needs three arguments + double ValLL; + if (g_OpTop < 0 || g_OpStack[g_OpTop--].type != OP_LOGIC) + { + return eLogicErr; + } + ValLL = g_ValStack[g_ValTop--]; + res = ValLL ? left : right; + } + break; + + default: + return eInternal; + } + } + + g_ValStack[++g_ValTop] = res; + return NULL; +} + +static char* CalcToObr() +{ + while (g_OpStack[g_OpTop].type != OP_OBR) + { + char* error = Calc(); + if (error) return error; + } + --g_OpTop; + return NULL; +} + +int GetFunction(const char* str, size_t len, void** data) +{ + const int funcCount = sizeof(g_Functions) / sizeof(Function); + for (int i = 0; i < funcCount; ++i) + { + if (g_Functions[i].length == len && + _strnicmp(str, g_Functions[i].name, len) == 0) + { + *data = g_Functions[i].proc; + return i; + } + } + + return -1; +} + +int FindSymbol(const char* str) +{ + switch (str[0]) + { + case '(': return (int)OP_OBR; + case '+': return OP_ADD; + case '-': return OP_SUB; + case '*': return (str[1] == '*') ? OP_POW : OP_MUL; + case '/': return OP_DIV; + case '%': return OP_MOD; + case '$': return OP_UNK; + case '^': return OP_XOR; + case '~': return OP_NOT; + case '&': return (str[1] == '&') ? OP_LOGIC_AND : OP_AND; + case '|': return (str[1] == '|') ? OP_LOGIC_OR : OP_OR; + case '=': return OP_EQU; + case '>': return (str[1] == '>') ? OP_SHR : (str[1] == '=') ? OP_LOGIC_GEQ : OP_GREATER; + case '<': return (str[1] == '>') ? OP_LOGIC_NEQ : (str[1] == '<') ? OP_SHL : (str[1] == '=') ? OP_LOGIC_LEQ : OP_SMALLER; + case '?': return OP_LOGIC; + case ':': return OP_LOGIC_SEP; + case ')': return OP_CBR; + case ',': return OP_COMMA; + } + + return -1; +} + +// ----------------------------------------------------------------------------------------------- +// Lexer +// ----------------------------------------------------------------------------------------------- + +inline CharType CHARTYPEPP() { return g_CharTypes[(unsigned char)*++(g_Lexer.string)]; } +inline CharType CHARTYPE() { return g_CharTypes[(unsigned char)*g_Lexer.string]; } + +int Lexer_SetParseString(const char* str) +{ + g_Lexer.PrevTokenType = TOK_NONE; + if (!str || !*str) return 0; + + g_Lexer.string = str; + g_Lexer.CharType = CHARTYPE(); + return 1; +} + +MathTokenType Lexer_GetNextToken() +{ + MathTokenType result = TOK_ERROR; + + while (g_Lexer.CharType == CH_SEPARAT) + { + g_Lexer.CharType = CHARTYPEPP(); + } + + switch (g_Lexer.CharType) + { + case CH_FINAL: + { + result = TOK_FINAL; + } + break; + + case CH_LETTER: + { + g_Lexer.name = g_Lexer.string; + do + { + g_Lexer.CharType = CHARTYPEPP(); + } + while (g_Lexer.CharType <= CH_DIGIT); + + g_Lexer.nameLen = g_Lexer.string - g_Lexer.name; + result = TOK_NAME; + } + break; + + case CH_DIGIT: + { + char* newString; + if (g_Lexer.string[0] == '0') + { + bool valid = true; + switch (g_Lexer.string[1]) + { + case 'x': // Hexadecimal + g_Lexer.intValue = strtol(g_Lexer.string, &newString, 16); + break; + + case 'o': // Octal + g_Lexer.intValue = strtol(g_Lexer.string + 2, &newString, 8); + break; + + case 'b': // Binary + g_Lexer.intValue = strtol(g_Lexer.string + 2, &newString, 2); + break; + + default: + valid = false; + break; + } + + if (valid) + { + if (g_Lexer.string != newString) + { + g_Lexer.string = newString; + g_Lexer.CharType = CHARTYPE(); + g_Lexer.extValue = g_Lexer.intValue; + result = TOK_FLOAT; + } + break; + } + } + + // Decimal + g_Lexer.extValue = strtod(g_Lexer.string, &newString); + if (g_Lexer.string != newString) + { + g_Lexer.string = newString; + g_Lexer.CharType = CHARTYPE(); + result = TOK_FLOAT; + } + } + break; + + case CH_SYMBOL: + { + int sym = FindSymbol(g_Lexer.string); + if (sym >= 0) + { + g_Lexer.string += (sym == OP_POW || + sym == OP_LOGIC_AND || sym == OP_LOGIC_OR || + sym == OP_SHR || sym == OP_LOGIC_GEQ || + sym == OP_LOGIC_NEQ || sym == OP_SHL || sym == OP_LOGIC_LEQ) ? 2 : 1; + + g_Lexer.CharType = CHARTYPE(); + g_Lexer.intValue = sym; + result = TOK_SYMBOL; + } + } + break; + + default: + break; + } + return g_Lexer.PrevTokenType = result; +} + +// ----------------------------------------------------------------------------------------------- +// Misc +// ----------------------------------------------------------------------------------------------- + +static double frac(double x) +{ + double y; + return modf(x, &y); +} + +static double trunc(double x) +{ + return (x >= 0.0) ? floor(x) : ceil(x); +} + +static double sgn(double x) +{ + return (x > 0) ? 1 : (x < 0) ? -1 : 0; +} + +static double neg(double x) +{ + return -x; +} + +// "Advanced" round function; second argument - sharpness +static char* round(int paramcnt, double* args, double* result) +{ + int sharpness; + if (paramcnt == 1) + { + sharpness = 0; + } + else if (paramcnt == 2) + { + sharpness = (int)args[1]; + } + else + { + return eInvPrmCnt; + } + + double x = args[0]; + double coef; + if (sharpness < 0) + { + coef = 0.1; + sharpness = -sharpness; + } + else + { + coef = 10; + } + + for (int i = 0; i < sharpness; i++) x *= coef; + + x = (x + ((x >= 0) ? 0.5 : -0.5)); + x = (x >= 0.0) ? floor(x) : ceil(x); + + for (int i = 0; i < sharpness; i++) x /= coef; + + *result = x; + return NULL; +} diff --git a/Library/MathParser.h b/Library/MathParser.h new file mode 100644 index 00000000..414532a5 --- /dev/null +++ b/Library/MathParser.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2011 Birunthan Mohanathas + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// Heavily based on ccalc 0.5.1 by Walery Studennikov + +#ifndef __MATHPARSER_H__ +#define __MATHPARSER_H__ + +namespace MathParser +{ + typedef int (*ParameterSearchProc)(const char* str, int len, double* value); + + void Initialize(); + + char* Check(const char* formula); + char* CheckParse(const char* formula, double* result); + char* Parse(const char* formula, ParameterSearchProc searchProc, double* result); +}; + +#endif \ No newline at end of file diff --git a/Library/MeasureCalc.cpp b/Library/MeasureCalc.cpp index 939070fa..288c5917 100644 --- a/Library/MeasureCalc.cpp +++ b/Library/MeasureCalc.cpp @@ -19,8 +19,9 @@ #include "StdAfx.h" #include "MeasureCalc.h" #include "Rainmeter.h" +#include "MathParser.h" -hqStrMap* CMeasureCalc::c_VarMap = NULL; +CMeterWindow* CMeasureCalc::c_MeterWindow = NULL; bool CMeasureCalc::c_RandSeeded = false; /* @@ -30,7 +31,6 @@ bool CMeasureCalc::c_RandSeeded = false; ** */ CMeasureCalc::CMeasureCalc(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name), - m_Parser(MathParser_Create(NULL)), m_LowBound(), m_HighBound(100), m_UpdateRandom(false) @@ -52,13 +52,6 @@ CMeasureCalc::CMeasureCalc(CMeterWindow* meterWindow, const WCHAR* name) : CMeas */ CMeasureCalc::~CMeasureCalc() { - MathParser_Destroy(m_Parser); - - if (c_VarMap) - { - StrMap_Destroy(c_VarMap); - c_VarMap = NULL; - } } /* @@ -71,13 +64,12 @@ bool CMeasureCalc::Update() { if (!CMeasure::PreUpdate()) return false; - m_Parser->Parameters = c_VarMap; if (m_UpdateRandom) { FormulaReplace(); } - char* errMsg = MathParser_Parse(m_Parser, ConvertToAscii(m_Formula.c_str()).c_str(), &m_Value); + char* errMsg = MathParser::Parse(ConvertToAscii(m_Formula.c_str()).c_str(), MatchMeasure, &m_Value); if (errMsg != NULL) { std::wstring error = L"Calc: "; @@ -91,32 +83,27 @@ bool CMeasureCalc::Update() return PostUpdate(); } -void CMeasureCalc::UpdateVariableMap(CMeterWindow& meterWindow) +int CMeasureCalc::MatchMeasure(const char* str, int len, double* value) { - // Delete the old map - if (c_VarMap) - { - StrMap_Destroy(c_VarMap); - c_VarMap = NULL; - } - - // Create the variable map - c_VarMap = Strmap_Create(sizeof(double), 0); - - const std::list& measures = meterWindow.GetMeasures(); + const std::list& measures = c_MeterWindow->GetMeasures(); std::list::const_iterator iter = measures.begin(); for ( ; iter != measures.end(); ++iter) { - const char* name = (*iter)->GetAsciiName(); - double val = (*iter)->GetValue(); - - StrMap_AddString(c_VarMap, name, &val); + if (_strnicmp(str, (*iter)->GetAsciiName(), len) == 0) + { + *value = (*iter)->GetValue(); + return 1; + } } - // Add the counter - double counter = meterWindow.GetUpdateCounter(); - StrMap_AddString(c_VarMap, "Counter", &counter); + if (_strnicmp(str, "counter", len) == 0) + { + *value = c_MeterWindow->GetUpdateCounter(); + return 1; + } + + return 0; } /* @@ -153,6 +140,17 @@ void CMeasureCalc::ReadConfig(CConfigParser& parser, const WCHAR* section) { FormulaReplace(); } + + char* errMsg = MathParser::Check(ConvertToAscii(m_Formula.c_str()).c_str()); + if (errMsg != NULL) + { + std::wstring error = L"Calc: "; + error += ConvertToWide(errMsg); + error += L" in ["; + error += m_Name; + error += L']'; + throw CError(error); + } } } @@ -164,8 +162,8 @@ void CMeasureCalc::ReadConfig(CConfigParser& parser, const WCHAR* section) */ void CMeasureCalc::FormulaReplace() { - //To implement random numbers the word "Random" in the string - //formula is being replaced by the random number value + // To implement random numbers the word "Random" in the string + // formula is being replaced by the random number value m_Formula = m_FormulaHolder; size_t start = 0, pos; diff --git a/Library/MeasureCalc.h b/Library/MeasureCalc.h index 9ab42fae..1512276f 100644 --- a/Library/MeasureCalc.h +++ b/Library/MeasureCalc.h @@ -20,7 +20,6 @@ #define __MEASURECALC_H__ #include "Measure.h" -#include "ccalc-0.5.1/mparser.h" class CMeasureCalc : public CMeasure { @@ -30,7 +29,7 @@ public: virtual bool Update(); - static void UpdateVariableMap(CMeterWindow& meterWindow); + static void SetCurrentMeterWindow(CMeterWindow* meterWindow) { c_MeterWindow = meterWindow; } protected: virtual void ReadConfig(CConfigParser& parser, const WCHAR* section); @@ -39,15 +38,16 @@ private: void FormulaReplace(); bool IsDelimiter(WCHAR ch); + static int MatchMeasure(const char* str, int len, double* value); + std::wstring m_Formula; std::wstring m_FormulaHolder; - hqMathParser* m_Parser; int m_LowBound; int m_HighBound; bool m_UpdateRandom; - static hqStrMap* c_VarMap; + static CMeterWindow* c_MeterWindow; static bool c_RandSeeded; }; diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index d3151cab..9622ea2f 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -1417,7 +1417,7 @@ void CMeterWindow::UpdateMeasure(const WCHAR* name, bool group) // Pre-updates if (!m_Measures.empty()) { - CMeasureCalc::UpdateVariableMap(*this); + CMeasureCalc::SetCurrentMeterWindow(this); } bool bNetStats = m_HasNetMeasures; @@ -2944,7 +2944,7 @@ void CMeterWindow::Update(bool nodraw) CMeasureNet::UpdateIFTable(); CMeasureNet::UpdateStats(); } - CMeasureCalc::UpdateVariableMap(*this); + CMeasureCalc::SetCurrentMeterWindow(this); // Update all measures std::list::const_iterator i = m_Measures.begin(); diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index 8e1d2d04..b3ecaa6f 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -23,6 +23,7 @@ #include "Error.h" #include "DialogAbout.h" #include "DialogManage.h" +#include "MathParser.h" #include "MeasureNet.h" #include "MeterString.h" #include "resource.h" @@ -1067,6 +1068,7 @@ int CRainmeter::Initialize(HWND hParent, HINSTANCE hInstance, LPCWSTR szPath) // Test that the Rainmeter.ini file is writable TestSettingsFile(bDefaultIniLocation); + MathParser::Initialize(); CSystem::Initialize(hInstance); CMeasureNet::InitializeNewApi(); diff --git a/Library/ccalc-0.5.1/lexer.c b/Library/ccalc-0.5.1/lexer.c deleted file mode 100644 index 535664ce..00000000 --- a/Library/ccalc-0.5.1/lexer.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - Universal lexical analiser implementation -*/ -#include -#include -#include -#include "lexer.h" - -//#define MY_DEBUG 1 - -#ifdef MY_DEBUG -#include -#endif -/* Uppercase translation table for the Win1251 charset */ -const char Win1251UpcaseTbl[] = - "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017" - "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" - " !\042#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\177" - "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" - "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" - "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" - "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" - "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" - "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" - "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" - "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"; - -char Win1251RusLetters[] = - "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" - "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" - "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" - "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"; - - -hqCharType Win1251NameTbl[256]; -int win1251nametbl_initialized = 0; - -int FindSymbol( SymbolRec **SymTable, const char *str, int *nchars ); - -// initializations - -void InitCharTypeTable( hqCharType *CharTypeTable, int CharTypes ) -{ - int ch; -#ifdef MY_DEBUG - printf( "CharTypeTable = 0x%X; CharTypes = %d\n", (unsigned)CharTypeTable, - CharTypes ); -#endif - memset( CharTypeTable, CH_UNKNOWN, 256 * sizeof(hqCharType) ); - - CharTypeTable[0] = CH_FINAL; - - if (CharTypes & CH_SEPARAT) { - CharTypeTable[' '] = CH_SEPARAT; - CharTypeTable[9] = CH_SEPARAT; - CharTypeTable[13] = CH_SEPARAT; - CharTypeTable[10] = CH_SEPARAT; - } - - if (CharTypes & CH_QUOTE) { - CharTypeTable['\''] = CH_QUOTE; - } - - if (CharTypes & CH_LETTER) { - for (ch='A'; ch<='Z'; ch++) - CharTypeTable[ch] = CH_LETTER; - for (ch='a'; ch<='z'; ch++) - CharTypeTable[ch] = CH_LETTER; - CharTypeTable['_'] = CH_LETTER; - } - - if (CharTypes & CH_DIGIT) { - for (ch='0'; ch<='9'; ch++) - CharTypeTable[ch] = CH_DIGIT; - } -} - -void TypeTableAddChars( hqCharType *CharTypeTable, char *Symbols, - hqCharType CharType ) -{ - while (*Symbols) - CharTypeTable[ (uchar) *Symbols++] = CharType; -} - -void UpcaseWin1251Str( char *Str ) -{ - while (( *Str = Win1251UpcaseTbl[ (uchar) *Str ] )) - ++Str; -} - - -// hqLexer implementation - -#define CHARTYPEPP lexer->CharTypeTable[ (uchar) *++(lexer->SS) ] -#define CHARTYPE lexer->CharTypeTable[ (uchar) *lexer->SS ] - -int Lexer_SetParseString( hqLexer *lexer, const char *str ) -{ - lexer->PrevTokenType = TOK_NONE; - if ( !str || !*str ) - return 0; - - lexer->SS = str; - lexer->CharType = CHARTYPE; - return 1; -} - -hqTokenType Lexer_GetNextToken( hqLexer *lexer ) -{ - hqTokenType result = TOK_ERROR; - -next_token: - - while ( lexer->CharType == CH_SEPARAT ) - lexer->CharType = CHARTYPEPP; - - switch ( lexer->CharType ) { - case CH_FINAL: - result = TOK_FINAL; - break; - case CH_LETTER: - lexer->Name = lexer->SS; - do { - lexer->CharType = CHARTYPEPP; - } while (lexer->CharType <= CH_DIGIT); - lexer->NameLen = lexer->SS - lexer->Name; - result = TOK_NAME; - break; - case CH_DIGIT: { - char *NewSS, ch = *lexer->SS, nch = *(lexer->SS+1); - int intreaded = 0; - // Readind hex number - if ( ch == '0' && nch == 'x' ) { - lexer->IntValue = strtol( lexer->SS, &NewSS, 16 ); - intreaded = 1; - } - // Readind oct number - if ( ch == '0' && nch == 'o') { // original version: if ( ch == '0' && nch >= '0' && nch <='9') - lexer->IntValue = strtol( lexer->SS+2, &NewSS, 8 ); - intreaded = 1; - } - - // Readind bin number - if ( ch == '0' && nch == 'b') { // original version: if ( ch == '0' && nch >= '0' && nch <='9') - lexer->IntValue = strtol( lexer->SS+2, &NewSS, 2 ); - intreaded = 1; - } - - if (intreaded == 1) { - if ( lexer->SS != NewSS ) { - lexer->SS = NewSS; - if (lexer->NoIntegers) { - lexer->ExtValue = lexer->IntValue; - result = TOK_FLOAT; - } else - result = TOK_INT; - lexer->CharType = CHARTYPE; - } - break; - } - - // Readind dec number - lexer->ExtValue = strtod( lexer->SS, &NewSS ); - if ( lexer->SS != NewSS ) {; - lexer->SS = NewSS; - if ( !lexer->NoIntegers - && lexer->ExtValue<=INT_MAX - && lexer->ExtValue>=INT_MAX - && (double)( lexer->IntValue = (uchar) lexer->ExtValue ) - == lexer->ExtValue ) { - result = TOK_INT; - } else - result = TOK_FLOAT; - lexer->CharType = CHARTYPE; - } - break; - } - case CH_SYMBOL: { - int nchars; - int i = FindSymbol( lexer->SymTable, lexer->SS, &nchars ); - if (i >= 0) { - lexer->SS += nchars; - if (i == lexer->cssn) { - char comend = *lexer->ComEnd; - char comendpp = *(lexer->ComEnd+1); - while ( *lexer->SS ) { - if ( *lexer->SS == comend - && - ( comendpp == '\0' || *(lexer->SS+1) == comendpp ) - ) { - ++lexer->SS; - if (comendpp != '\0') - ++lexer->SS; - lexer->CharType = CHARTYPE; - goto next_token; - } - ++lexer->SS; - } - break; - } - lexer->CharType = CHARTYPE; - lexer->IntValue = i; - result = TOK_SYMBOL; - } - break; - } - case CH_QUOTE: - lexer->Name = ++(lexer->SS); - while ( lexer->CharTypeTable[ (uchar)*lexer->SS ] != CH_QUOTE - && *(lexer->SS) != '\0' ) - ++lexer->SS; - if ( CHARTYPE == CH_QUOTE ) { - lexer->NameLen = lexer->SS - lexer->Name; - ++lexer->SS; - lexer->CharType = CHARTYPE; - result = TOK_STRING; - } - break; - default: - break; - } - return lexer->PrevTokenType = result; -} - -const char* Lexer_GetCurrentPos( hqLexer *lexer ) -{ - return lexer->SS; -} - -// misc functions - -void PrepareSymTable( SymbolRec **SymTable, char *symbols ) -{ - int i = 0, nchars = 1; - memset( SymTable, 0, 256 * sizeof(void*) ); - while (*symbols) { - if (*symbols=='\033') { - nchars = *++symbols; - ++symbols; - } else { - SymbolRec **RecList = SymTable + *symbols; - SymbolRec *Rec = *RecList; - int count = 0; - while ( Rec ) { - ++count; - if ( Rec->More ) - ++Rec; - else - break; - } - if ( Rec ) { - *RecList = (SymbolRec*) - realloc( *RecList, (count+1)*sizeof(SymbolRec) ); - Rec = *RecList + count; - (Rec-1)->More = 1; - } else { - *RecList = (SymbolRec*) malloc( sizeof(SymbolRec) ); - Rec = *RecList; - } - strncpy( Rec->Sym, symbols, 4 ); - Rec->Len = (char) nchars; - Rec->Index = (char) i; - Rec->More = 0; - symbols += nchars; - ++i; - } - } -} - -int FindSymbol( SymbolRec **SymTable, const char *str, int *nchars ) -{ - SymbolRec *Rec = SymTable[ (int)*str ]; - while ( Rec ) { - if ( (Rec->Len == 1 && Rec->Sym[0] == str[0]) - || - (Rec->Len == 2 && Rec->Sym[0] == str[0] && Rec->Sym[1] == str[1]) - || - (Rec->Len == 3 && Rec->Sym[0] == str[0] && Rec->Sym[1] == str[1] - && Rec->Sym[2] == str[2]) - ) { - *nchars = Rec->Len; - return Rec->Index; - } - Rec = ( Rec->More ) ? Rec + 1 : NULL; - } - return -1; -} - diff --git a/Library/ccalc-0.5.1/lexer.h b/Library/ccalc-0.5.1/lexer.h deleted file mode 100644 index a4ffee38..00000000 --- a/Library/ccalc-0.5.1/lexer.h +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -/* - Universal lexical analiser by hq_software -*/ - -#ifndef __LEXER_HPP__ -#define __LEXER_HPP__ - -#include "pack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned char uchar; - -typedef enum { - CH_LETTER = 0x01, CH_DIGIT = 0x02, CH_SEPARAT = 0x04, - CH_SYMBOL = 0x08, CH_QUOTE = 0x10, - CH_UNKNOWN= 0x7E, CH_FINAL = 0x7F -} hqCharType; - -typedef enum { - TOK_ERROR, TOK_NONE, TOK_FINAL, TOK_INT, TOK_FLOAT, TOK_SYMBOL, - TOK_NAME, TOK_STRING -} hqTokenType; - -#pragma pack(push,1) - -typedef struct { - char Sym[4]; - char Len; - char Index; - char More; -} SymbolRec; - -typedef struct { - // input params - const char *SS; - hqCharType *CharTypeTable; - SymbolRec **SymTable; - int NoIntegers; - int cssn; // Comment Start Symbol Number. -1 if none - char *ComEnd; // End of comment - // output params - const char *Name; - size_t NameLen; - double ExtValue; - int IntValue; - hqTokenType PrevTokenType; - hqCharType CharType; -} hqLexer; - -#pragma pack(pop) - -/* Main "API" */ - -int Lexer_SetParseString( hqLexer *lexer, const char *str ); -hqTokenType Lexer_GetNextToken( hqLexer *lexer ); -const char* Lexer_GetCurrentPos( hqLexer *lexer ); - -/* Misc */ - -void UpcaseWin1251Str( char *Str ); -void InitCharTypeTable( hqCharType *CharTypeTable, int CharTypes ); - -void TypeTableAddChars( hqCharType *CharTypeTable, char *Symbols, - hqCharType CharType ); - -void PrepareSymTable( SymbolRec **SymTable, char *symbols ); - -//int IsEngWin1251RusName( char *Str ); - -extern char const Win1251UpcaseTbl[]; - -#ifdef __cplusplus -} -#endif - -#endif /* __LEXER_HPP__ */ diff --git a/Library/ccalc-0.5.1/mparser.c b/Library/ccalc-0.5.1/mparser.c deleted file mode 100644 index e75dcbed..00000000 --- a/Library/ccalc-0.5.1/mparser.c +++ /dev/null @@ -1,657 +0,0 @@ -#include -#include -#include -#include -#include -#include "mparser.h" - -//#define MY_DEBUG 1 - -#ifndef M_E -# define M_E 2.7182818284590452354 -#endif -#ifndef M_PI -# define M_PI 3.14159265358979323846 -#endif - -const double DblErR = -1.68736462823243E308; -const double DblNiN = -1.68376462823243E308; - -char eBrackets [] = "#Brackets not match!"; -char eSyntax [] = "#Syntax error!"; -char eInternal [] = "#Internal error!"; -char eExtraOp [] = "#Extra operation!"; -char eInfinity [] = "#Infinity somewhere!"; -char eInvArg [] = "#Invalid argument!"; -char eUnknFunc [] = "# %s - Unknown function/variable!"; -char eExtrnFunc[] = "#External function error!"; -char eLogicErr [] = "#Logical expression error!"; -char eCalcErr [] = "#Calculation error!"; -char eUnexpEnd [] = "#Unexpected end of script!"; -char eExpVarRet[] = "#Variable name or return expected!"; -char eExpAssign[] = "#Assignment expected!"; -char eValSizErr[] = "#Value too big for operation!"; -char eInvPrmCnt[] = "#Invalid parameters count for function call!"; - -static double _neg_(double); -static double _frac_(double); -static double _trunc_(double); -static double _sgn_(double); -static double _neg_(double); -static double _floor_(double); -static double _ceil_(double); -static char* _round_( int paramcnt, double *args, hqStrMap *strparams, double *result ); - -const Operation BrOp = { OP_OBR }; -const Operation NegOp = { OP_FUNC_ONEARG, (void*)&_neg_, 0, NULL }; - -const char OpPriorities[OP_FUNC_MULTIARG+1] = { - 5, 5, 5, 2, 2, 2, 2, 2, -1, -1, 0, - 3, 3, 4, 4, 4, 4, - 5, 5, 5, 5, 2, 2, 2, 1, 2, 0, 2, - -1, 6, 6 }; - -char MathSymbols[] = - "\033\002" "<<" ">>" "**" "<>" ">=" "<=" "&&" "||" "/*" ":=" - "\033\001" "(+-*/%$^~&|=>%$,?:=&|;"; - -hqCharType MathCharTypeTable[256]; -int initializations_performed = 0; - -char func_names[] = - "ATAN\000COS\000SIN\000TAN\000ABS\000" - "EXP\000LN\000LOG\000SQRT\000FRAC\000" - "TRUNC\000FLOOR\000CEIL\000ROUND\000ASIN\000" - "ACOS\000SGN\000NEG\000E\000PI\000"; - -/* Indexes of some functions in func_names[] array */ -#define FUNC_ROUND 13 -#define FUNC_E 18 -#define FUNC_PI 19 - -static char* CalcToObr( hqMathParser *parser ); -static char* Calc( hqMathParser *parser ); -static char* MathParser_ParseScript( hqMathParser* parser, double *result ); -static char* MathParser_ParseFormula( hqMathParser* parser, double *result ); - -double (*func_addresses[]) () = { - &atan, &cos, &sin, &tan, &fabs, - &exp, &log, &log10, &sqrt, &_frac_, - &_trunc_, &_floor_, _ceil_, (double(*)(double)) &_round_, &asin, - &acos, &_sgn_, &_neg_, NULL, NULL }; - -hqStrMap *IntFunctions; - -SymbolRec *MathSymTable[256]; - -char errbuf[256]; - -// hqMathParser implementation - -hqMathParser* MathParser_Create( char *MoreLetters ) -{ - hqMathParser *parser = calloc( 1, sizeof(hqMathParser) ); - if (!initializations_performed) { - // init character tables - InitCharTypeTable( MathCharTypeTable, - CH_LETTER | CH_DIGIT | CH_SEPARAT | CH_QUOTE ); - TypeTableAddChars( MathCharTypeTable, StdSymbols, CH_SYMBOL ); - if (MoreLetters) - TypeTableAddChars( MathCharTypeTable, MoreLetters, CH_LETTER ); - // init function maps - PrepareSymTable( MathSymTable, MathSymbols ); - IntFunctions = Strmap_CreateFromChain( sizeof(void*), - (char*)func_names, - func_addresses ); - initializations_performed = 1; - } - parser->Lexer.NoIntegers = 1; - parser->Lexer.SymTable = MathSymTable; - parser->Lexer.CharTypeTable = MathCharTypeTable; - parser->Lexer.cssn = 8; - parser->Lexer.ComEnd = "*/"; - return parser; -} - -void MathParser_Destroy( hqMathParser* parser ) -{ - free( parser ); -} - -static char* PrepareFormula( hqMathParser* parser ) -{ - int BrCnt = 0; - const char *SS = parser->Lexer.SS; - - // Brackets Matching - while ( (!parser->script && *SS) || (parser->script && *SS != ';') ) { - if (*SS=='(') - ++BrCnt; - else if (*SS==')' && --BrCnt<0) - goto brkerr; - ++SS; - } - if (BrCnt != 0) -brkerr: return eBrackets; - - parser->OpTop = 0; - parser->ValTop = -1; - parser->OpStack[0].OperType = OP_OBR; - parser->ObrDist = 2; - return NULL; -} - -char* MathParser_Parse( hqMathParser* parser, const char *Formula, double *result ) -{ - if (!Formula || !*Formula) { - *result = 0.0; - return NULL; - } - - parser->script = *Formula == '#' && *(Formula+1) == '!' - && MathCharTypeTable[ (uchar)*(Formula+2) ] == CH_SEPARAT; - - if ( parser->script ) - Formula += 3; - - Lexer_SetParseString( &parser->Lexer, Formula ); - - return ( parser->script ) - ? - MathParser_ParseScript( parser, result ) - : - MathParser_ParseFormula( parser, result ); -} - -static char* MathParser_ParseFormula( hqMathParser* parser, double *result ) -{ - char *ErrorMsg; - hqTokenType ToTi; - - if ( (ErrorMsg = PrepareFormula( parser )) != NULL ) - return ErrorMsg; - - ToTi = Lexer_GetNextToken( &parser->Lexer ); - for (;;) { - --parser->ObrDist; - switch (ToTi) { - case TOK_ERROR: - return eSyntax; - case TOK_FINAL: -formulaend: if ( (ErrorMsg = CalcToObr( parser )) != NULL ) - return ErrorMsg; - goto getout; - case TOK_FLOAT: - parser->ValStack[++parser->ValTop] = parser->Lexer.ExtValue; - break; - case TOK_SYMBOL: - switch ( parser->Lexer.IntValue ) { - case OP_OBR: // ( - parser->OpStack[++parser->OpTop] = BrOp; - parser->ObrDist = 2; - break; - case OP_CBR: // ) - if ( (ErrorMsg = CalcToObr( parser )) != NULL ) - return ErrorMsg; - break; - case OP_COMMA: { // , - Operation *pOp; - if ( (ErrorMsg = CalcToObr( parser )) != NULL ) - return ErrorMsg; - if ( (pOp = &parser->OpStack[parser->OpTop])->OperType - == OP_FUNC_MULTIARG ) { - parser->OpStack[++parser->OpTop] = BrOp; - parser->ObrDist = 2; - } else - return eSyntax; - break; - } - default: { - Operation Op; - Op.OperType = (OperType_t) parser->Lexer.IntValue; - switch (Op.OperType) { - case OP_FORMULAEND: - if (parser->script) - goto formulaend; - else - return eSyntax; - case OP_ADD: - if (parser->ObrDist >= 1) - goto next_tok; - break; - case OP_SUB: - if (parser->ObrDist >= 1) { - parser->OpStack[++parser->OpTop] = NegOp; - goto next_tok; - } - break; - case OP_LOGIC: - case OP_LOGIC_SEP: - parser->ObrDist = 2; - default: - break; - } - while ( OpPriorities[ Op.OperType ] - <= - OpPriorities[ parser->OpStack[parser->OpTop].OperType ] ) { - if ( (ErrorMsg = Calc( parser )) != NULL ) - return ErrorMsg; - } - parser->OpStack[++parser->OpTop] = Op; - break; - } - } - break; - case TOK_NAME: { - Operation Op; - double *value, dblval; - void **func; - int funcnum, /*i,*/ namelen = parser->Lexer.NameLen; - -// const char *SS = parser->Lexer.Name; -// for (i = namelen; i>0; --i) -// *SS++ = Win1251UpcaseTbl[ (int) (uchar) *SS ]; - - funcnum = StrMap_LenIndexOf( IntFunctions, - parser->Lexer.Name, - parser->Lexer.NameLen, - (void**) &func ); - if ( funcnum >= 0 ) { - Op.Func = *func; - switch ( funcnum ) { - case FUNC_E: - parser->ValStack[++parser->ValTop] = M_E; - break; - case FUNC_PI: - parser->ValStack[++parser->ValTop] = M_PI; - break; - case FUNC_ROUND: - Op.OperType = OP_FUNC_MULTIARG; - Op.PrevValTop = parser->ValTop; - Op.StrParams = NULL; - parser->OpStack[++parser->OpTop] = Op; - break; - default:// Internal function - Op.OperType = OP_FUNC_ONEARG; - parser->OpStack[++parser->OpTop] = Op; - } - } else if (parser->Parameters - && - StrMap_LenIndexOf( parser->Parameters, - parser->Lexer.Name, - parser->Lexer.NameLen, - (void**) &value ) >= 0 - ) { - if (*value==DblErR) { - return eInternal; - } else - parser->ValStack[++parser->ValTop] = *value; - } else if (parser->ExtFunctions - && - StrMap_LenIndexOf( parser->ExtFunctions, - parser->Lexer.Name, - parser->Lexer.NameLen, - (void**) &func ) >= 0 - ) { - Op.Func = *func; - Op.OperType = OP_FUNC_MULTIARG; - Op.PrevValTop = parser->ValTop; - Op.StrParams = NULL; - parser->OpStack[++parser->OpTop] = Op; - } else if (parser->VarParams - && - StrMap_LenIndexOf( parser->VarParams, - parser->Lexer.Name, - parser->Lexer.NameLen, - (void**) &value ) >= 0 - ) { - if (*value==DblErR) { - return eInternal; - } else - parser->ValStack[++parser->ValTop] = *value; - } else if (parser->MoreParams - && - (*parser->MoreParams)( parser->Lexer.Name, - parser->Lexer.NameLen, - &dblval, - parser->ParamFuncParam ) - ) { - parser->ValStack[++parser->ValTop] = dblval; - } else { - char buf[256]; - strncpy( buf, parser->Lexer.Name, parser->Lexer.NameLen ); - buf[ parser->Lexer.NameLen ] = '\0'; - sprintf( errbuf, eUnknFunc, buf ); - return errbuf; - } - break; - } - case TOK_STRING: { - Operation *pOp; - if (parser->OpTop < 1) - return eSyntax; - if ( (pOp = &parser->OpStack[parser->OpTop-1])->OperType - == OP_FUNC_MULTIARG ) { - if (!pOp->StrParams) - pOp->StrParams = Strmap_Create( 0, 0 ); - StrMap_AddStrLen( pOp->StrParams, - parser->Lexer.Name, - parser->Lexer.NameLen, NULL ); - parser->ValStack[++parser->ValTop] = DblNiN; - } else - return eSyntax; - break; - } - default: - return eSyntax; - } -next_tok: - ToTi = Lexer_GetNextToken( &parser->Lexer ); - } // forever - -getout: - if (parser->OpTop != -1 || parser->ValTop != 0) - return eInternal; - - *result = parser->ValStack[0]; - return NULL; -} - -static char* MathParser_ParseScript( hqMathParser* parser, double *result ) -{ - char *ErrorMsg = NULL; - hqTokenType ToTi; - int expectvar = 1, was_return = 0; - const char *varname = NULL; - int varnamelen = 0; - - parser->VarParams = Strmap_Create( sizeof(double), 0 ); - - ToTi = Lexer_GetNextToken( &parser->Lexer ); - for (;;) { - switch (ToTi) { - case TOK_FINAL: - ErrorMsg = eUnexpEnd; - goto getout; - case TOK_NAME: { - if (!expectvar) { - ErrorMsg = eExpVarRet; - goto getout; - } else { -// int i; -// const char *SS = parser->Lexer.Name; - - varnamelen = parser->Lexer.NameLen; - -// for (i = varnamelen; i>0; --i) -// *SS++ = Win1251UpcaseTbl[ (int) (uchar) *SS ]; - } - varname = parser->Lexer.Name; - - was_return = strncmp( varname, "RETURN", varnamelen ) == 0; - if ( was_return ) { - ErrorMsg = MathParser_ParseFormula( parser, result ); - goto getout; - } - expectvar = 0; - break; - } - case TOK_SYMBOL: { - double *value; - - if ( parser->Lexer.IntValue != OP_ASSIGN || expectvar ) { - ErrorMsg = eExpAssign; - goto getout; - } - ErrorMsg = MathParser_ParseFormula( parser, result ); - if (ErrorMsg) - goto getout; - - if ( StrMap_LenIndexOf( parser->VarParams, - varname, varnamelen, - (void**) &value ) >= 0 ) - *value = *result; - else - StrMap_AddStrLen( parser->VarParams, varname, varnamelen, - result ); - expectvar = 1; - break; - } - default: - ErrorMsg = eSyntax; - goto getout; - } - ToTi = Lexer_GetNextToken( &parser->Lexer ); - } // forever - -getout: - StrMap_Destroy( parser->VarParams ); - parser->VarParams = NULL; - return ErrorMsg; -} - -static char* Calc( hqMathParser *parser ) -{ - double Res, ValR; - Operation Op = parser->OpStack[parser->OpTop--]; - - // multi-argument external or internal fucntion - if ( Op.OperType == OP_FUNC_MULTIARG ) { - int paramcnt = parser->ValTop - Op.PrevValTop; - char *ErrorMsg; -#ifdef MY_DEBUG - printf( "ValTop = %d, OpTop = %d, PrevValTop = %d\n", - parser->ValTop, parser->OpTop, Op.PrevValTop ); -#endif - parser->ValTop = Op.PrevValTop; - ErrorMsg = (*(MultiArgFunc)Op.Func)( paramcnt, - &parser->ValStack[parser->ValTop+1], - Op.StrParams, &Res ); - if (ErrorMsg) - return ErrorMsg; - if (Op.StrParams) - StrMap_Destroy( Op.StrParams ); - parser->ValStack[++parser->ValTop] = Res; -#ifdef MY_DEBUG - printf("ValTop = %d, OpTop = %d\n", parser->ValTop, parser->OpTop ); -#endif - return NULL; - } - - if (Op.OperType==OP_LOGIC) - return NULL; - - // get right arg - if (parser->ValTop<0) - return eExtraOp; - ValR = parser->ValStack[parser->ValTop--]; - - // one arg operations - if (Op.OperType==OP_NOT) { - if (ValR >= INT_MIN && ValR <= INT_MAX) - Res = ~((int) ValR); - else - return eValSizErr; - } else if (Op.OperType==OP_FUNC_ONEARG) { - Res = (*(OneArgFunc)Op.Func)( ValR ); - } else { - // get left arg - double ValL; - if (parser->ValTop<0) - return eExtraOp; - ValL = parser->ValStack[parser->ValTop--]; - switch (Op.OperType) { - // Binary - case OP_SHL: - if (ValL >= INT_MIN && ValL <= INT_MAX && ValR >= INT_MIN && ValR <= INT_MAX) - Res = (int) ValL << (int) ValR; - else - return eValSizErr; - break; - case OP_SHR: - if (ValL >= INT_MIN && ValL <= INT_MAX && ValR >= INT_MIN && ValR <= INT_MAX) - Res = (int) ValL >> (int) ValR; - else - return eValSizErr; - break; - case OP_POW: - Res = pow( ValL, ValR ); break; - // Logical - case OP_LOGIC_NEQ: - Res = ValL != ValR; break; - case OP_LOGIC_GEQ: - Res = ValL >= ValR; break; - case OP_LOGIC_LEQ: - Res = ValL <= ValR; break; - case OP_LOGIC_AND: - Res = ValL && ValR; break; - case OP_LOGIC_OR: - Res = ValL || ValR; break; - // Arithmetic - case OP_ADD: - Res = ValL + ValR; break; - case OP_SUB: - Res = ValL - ValR; break; - case OP_MUL: - Res = ValL * ValR; break; - case OP_DIV: - if (ValR == 0.0) - return eInfinity; - Res = ValL / ValR; - break; - case OP_MOD: - Res = fmod(ValL, ValR); break; - case OP_UNK: - if (ValL<=0) - Res = 0.0; - else if (ValR==0.0) - return eInfinity; - else - Res = ceil(ValL / ValR); - break; - // Bitwise - case OP_XOR: - if (ValL >= INT_MIN && ValL <= INT_MAX && ValR >= INT_MIN && ValR <= INT_MAX) - Res = (int) ValL ^ (int) ValR; - else - return eValSizErr; - break; - case OP_AND: - if (ValL >= INT_MIN && ValL <= INT_MAX && ValR >= INT_MIN && ValR <= INT_MAX) - Res = (int) ValL & (int) ValR; - else - return eValSizErr; - break; - case OP_OR: - if (ValL >= INT_MIN && ValL <= INT_MAX && ValR >= INT_MIN && ValR <= INT_MAX) - Res = (int) ValL | (int) ValR; - else - return eValSizErr; - break; - // Logical - case OP_EQU: - Res = ValL == ValR; break; - case OP_GREATER: - Res = ValL > ValR; break; - case OP_LESS: - Res = ValL < ValR; break; - case OP_LOGIC_SEP: { - // needs three arguments - double ValLL; - if (parser->OpTop < 0 - || parser->OpStack[parser->OpTop--].OperType != OP_LOGIC) - return eLogicErr; - ValLL = parser->ValStack[ parser->ValTop-- ]; - Res = ValLL ? ValL : ValR; - break; - } - default: - return eInternal; - } - } - parser->ValStack[++parser->ValTop] = Res; - return NULL; -} - -static char* CalcToObr( hqMathParser *parser ) -{ - while ( parser->OpStack[parser->OpTop].OperType != OP_OBR ) { - char *ErrorMsg; - if ( (ErrorMsg = Calc( parser )) != NULL ) - return ErrorMsg; - } - --parser->OpTop; - return NULL; -} - -/* misc functions */ - -static double _frac_( double x ) -{ - double y; - return modf(x, &y); -} - -static double _trunc_( double x ) -{ - return (x >= 0.0) ? floor(x) : ceil(x); -} - -static double _sgn_( double x ) -{ - return (x > 0) ? 1 : (x < 0) ? -1 : 0; -} - -static double _neg_( double x ) -{ - return -x; -} - -static double _floor_( double x ) -{ - return floor(x); -} - -static double _ceil_( double x ) -{ - return ceil(x); -} - -/* "Advanced" round function; second argument - sharpness */ -static char* _round_( int paramcnt, double *args, hqStrMap *strparams, double *result ) -{ - int i, sharpness; - double x, coef; - - if (paramcnt == 1) - sharpness = 0; - else if (paramcnt == 2) - sharpness = (int) args[1]; - else - return eInvPrmCnt; - - x = args[0]; - if (sharpness < 0) { - coef = 0.1; - sharpness = -sharpness; - } else - coef = 10; - - for (i = 0; i < sharpness; i++) - x *= coef; - - x = (x + ( (x >= 0) ? 0.5 : -0.5 ) ); - if (x >= 0.0) - x = floor(x); - else - x = ceil(x); - - for (i = 0; i < sharpness; i++) - x /= coef; - - *result = x; - - return NULL; -} diff --git a/Library/ccalc-0.5.1/mparser.h b/Library/ccalc-0.5.1/mparser.h deleted file mode 100644 index 360d8b31..00000000 --- a/Library/ccalc-0.5.1/mparser.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -/* - Math parser for CCalc library. -*/ -#include "strmap.h" -#include "lexer.h" -#include "pack.h" - -//#define RUSSIAN 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_STACK_SIZE 32 - -extern const double DblErR; -extern const double DblNiN; - -typedef enum { - // Binary - OP_SHL, OP_SHR, OP_POW, - OP_LOGIC_NEQ, OP_LOGIC_GEQ, OP_LOGIC_LEQ, - OP_LOGIC_AND, OP_LOGIC_OR, // Logical - OP_COMSTART, OP_ASSIGN, // For internal needs - OP_OBR, // Special - OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_UNK, // Arithmetic - OP_XOR, OP_NOT, OP_AND, OP_OR, // Bitwise - OP_EQU, OP_GREATER, OP_LESS, - OP_LOGIC, OP_LOGIC_SEP, OP_CBR, OP_COMMA, // Logical - OP_FORMULAEND, // For script - OP_FUNC_ONEARG, OP_FUNC_MULTIARG // Special -} OperType_t; - -typedef struct { - char *str; - double value; -} Parameter; - -typedef double (*OneArgFunc) ( double arg ); -typedef char* (*MultiArgFunc) ( int paramcnt, double *args, - hqStrMap *strparams, double *result ); -typedef int (*PrmSrchFunc) ( const char *str, int len, double *value, - void *param ); - -#pragma pack(push,1) - -typedef struct { - OperType_t OperType; - void *Func; - char PrevValTop; - hqStrMap *StrParams; -} Operation; - -typedef struct { - /* public */ - hqStrMap *Parameters; // List of numeric veriables - hqStrMap *ExtFunctions; // List of multi-argument external functions - PrmSrchFunc MoreParams; // Function for calculating unhandled parameters - void *ParamFuncParam; // Parameter given to this function - /* private */ - Operation OpStack[MAX_STACK_SIZE]; - double ValStack[MAX_STACK_SIZE]; - int OpTop, ValTop; - int ObrDist; - hqLexer Lexer; - int script; - hqStrMap *VarParams; -} hqMathParser; - -#pragma pack(pop) - -/* API */ - -hqMathParser* MathParser_Create( char *MoreLetters ); -void MathParser_Destroy( hqMathParser* parser ); -char* MathParser_Parse( hqMathParser* parser, const char *Formula, double *result ); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/Library/ccalc-0.5.1/pack.h b/Library/ccalc-0.5.1/pack.h deleted file mode 100644 index 2d9d5f5a..00000000 --- a/Library/ccalc-0.5.1/pack.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Definitions for packing structures */ -#ifndef __PACK_H__ -#define __PACK_H__ - -#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) -# define PACK_START #pragma option -a1 -#elif (defined(__GNUC__) && (__GNUC__ <= 2) && (__GNUC_MINOR__ < 95)) \ - || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) -# define PACK_START #pragma pack(1) -#else -# define PACK_START #pragma pack(push,1) -#endif - -#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) -# define PACK_STOP #pragma option -a. -#elif (defined(__GNUC__) && (__GNUC__ <= 2) && (__GNUC_MINOR__ < 95)) \ - || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) -# define PACK_STOP #pragma pack() -#else -# define PACK_STOP #pragma pack(pop) -#endif - -#endif /* __PACK_H__ */ diff --git a/Library/ccalc-0.5.1/strmap.c b/Library/ccalc-0.5.1/strmap.c deleted file mode 100644 index 018231f5..00000000 --- a/Library/ccalc-0.5.1/strmap.c +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include "strmap.h" - -hqStrMap* create_instance( int extrabytes, int dup ) -{ - hqStrMap* strmap = calloc( 1, sizeof(hqStrMap) ); - strmap->FDoDuplicate = dup; - strmap->FExtraLen = extrabytes; - strmap->FRecordLen = sizeof(char*) + sizeof(int) + extrabytes; - strmap->FList = NULL; - return strmap; -} - -hqStrMap* Strmap_Create( int extrabytes, int dup ) -{ - return create_instance( extrabytes, dup ); -} - -void Strmap_FillFromChain( hqStrMap* strmap, char *strchain, void *data ) -{ - while ( *strchain ) { - size_t len = strlen( strchain ); - StrMap_AddStrLen( strmap, strchain, len, data ); - strchain += len+1; - data = (char*)data + strmap->FExtraLen; - } -} - -hqStrMap* Strmap_CreateFromChain( int extrabytes, char *strchain, void *data ) -{ - hqStrMap* strmap = create_instance( extrabytes, 0 ); - Strmap_FillFromChain( strmap, strchain, data ); - StrMap_ShrinkMem( strmap ); - return strmap; -} - -void StrMap_Destroy( hqStrMap* strmap ) -{ - if ( strmap->FDoDuplicate ) - StrMap_TrimClear( strmap, 0 ); - if ( strmap->FList ) - free( strmap->FList ); - - free(strmap); -} - -void StrMap_AddString( hqStrMap* strmap, const char *str, void *data ) -{ - StrMap_AddStrLen( strmap, str, strlen(str), data ); -} - -void StrMap_AddStrLen( hqStrMap* strmap, const char *str, size_t len, void *data ) -{ - const char *Rec; - if ( strmap->FCount >= strmap->FCapacity ) { - int delta = (strmap->FCapacity > 64) ? strmap->FCapacity / 4 : 16; - StrMap_SetCapacity( strmap, strmap->FCapacity + delta ); - } - Rec = strmap->FList + strmap->FCount * strmap->FRecordLen; - *(const char**)Rec = str; - *(int*)(Rec + sizeof(char*)) = len; - if (data) { - void *recdata = (void*)(Rec + sizeof(char*) + sizeof(int)); - memcpy( recdata, data, strmap->FExtraLen ); - } - ++ strmap->FCount; -} - -void StrMap_ShrinkMem( hqStrMap* strmap ) -{ - StrMap_SetCapacity( strmap, strmap->FCount ); -} - -void StrMap_Trim( hqStrMap* strmap, int NewCount ) -{ - strmap->FCount = NewCount; -} - -void StrMap_TrimClear( hqStrMap* strmap, int NewCount ) -{ - int i; - char *Rec = strmap->FList + NewCount * strmap->FRecordLen; - for (i=NewCount; i < strmap->FCount; i++) { - free( *(char**)Rec ); - Rec += strmap->FRecordLen; - } - strmap->FCount = NewCount; -} - -void StrMap_SetCapacity( hqStrMap* strmap, int NewCapacity ) -{ - strmap->FCapacity = NewCapacity; - if ( strmap->FCount > strmap->FCapacity ) - strmap->FCount = strmap->FCapacity; - strmap->FList = (char*) realloc( strmap->FList, - strmap->FCapacity * strmap->FRecordLen ); -} - -int StrMap_IndexOf( hqStrMap* strmap, const char *str, void **data ) -{ - return StrMap_LenIndexOf( strmap, str, strlen(str), data ); -} - -int StrMap_LenIndexOf( hqStrMap* strmap, const char *str, size_t len, void **data ) -{ - int i; - char *Rec = strmap->FList; - for (i=0; iFCount; i++) { - int recLen = *(int*)(Rec + sizeof(char*)); - if (recLen==len && strnicmp( str, *(char**)Rec, recLen )==0 ) { - *data = (Rec + sizeof(char*) + sizeof(int)); - return i; - } - Rec += strmap->FRecordLen; - } - *data = NULL; - return -1; -} - -char* StrMap_GetString( hqStrMap* strmap, int index, int *len, void **data ) -{ - char *Rec = strmap->FList + index * strmap->FRecordLen; - *len = *(int*)(Rec + sizeof(char*)); - if (data!=NULL && strmap->FExtraLen>0) - *data = (Rec + sizeof(char*) + sizeof(int)); - return *(char**)Rec; -} - diff --git a/Library/ccalc-0.5.1/strmap.h b/Library/ccalc-0.5.1/strmap.h deleted file mode 100644 index 23ae4ca5..00000000 --- a/Library/ccalc-0.5.1/strmap.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "pack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#pragma pack(push,1) - -typedef struct { - int FCount, FCapacity; - int FExtraLen, FRecordLen; - int FDoDuplicate; - char *FList; -} hqStrMap; - -#pragma pack(pop) - -/* API */ - -hqStrMap* Strmap_Create( int extrabytes, int dup ); -hqStrMap* Strmap_CreateFromChain( int extrabytes, char *strchain, void *data ); -void StrMap_Destroy( hqStrMap* strmap ); - -void StrMap_AddString( hqStrMap* strmap, const char *str, void *data ); -void StrMap_AddStrLen( hqStrMap* strmap, const char *str, size_t len, void *data ); -void StrMap_ShrinkMem( hqStrMap* strmap ); -void StrMap_Trim( hqStrMap* strmap, int NewCount ); -void StrMap_TrimClear( hqStrMap* strmap, int NewCount ); -void StrMap_SetCapacity( hqStrMap* strmap, int NewCapacity ); -int StrMap_IndexOf( hqStrMap* strmap, const char *str, void **data ); -int StrMap_LenIndexOf( hqStrMap* strmap, const char *str, size_t len, void **data ); -char* StrMap_GetString( hqStrMap* strmap, int index, int *len, void **data ); -void Strmap_FillFromChain( hqStrMap* strmap, char *strchain, void *data ); - -#ifdef __cplusplus -} -#endif diff --git a/Library/ccalc-0.5.1/wininit.c b/Library/ccalc-0.5.1/wininit.c deleted file mode 100644 index 6c221c8d..00000000 --- a/Library/ccalc-0.5.1/wininit.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -extern int WINAPI dll_entry (HANDLE h, DWORD reason, void *ptr) -{ - return 1; -}