filters
- filters
- kspread
- qpro
- libqpro
- src
1#include <qpro/common.h>
8#include <qpro/formula.h>
9#include <qpro/stream.h>
14QpFormulaStack::QpFormulaStack()
18 cStack = new char*[cMax];
21QpFormulaStack::~QpFormulaStack()
26QpFormulaStack::bracket( const char* pBefore, const char* pAfter)
30 int lLen = strlen(cStack[cIdx]) + 1;
32 if( pBefore ) lLen += strlen(pBefore);
34 if( pAfter ) lLen += strlen(pAfter);
36 char* lNew = new char[ lLen ];
40 if( pBefore ) strcpy( lNew, pBefore );
42 strcat( lNew, cStack[cIdx] );
44 if( pAfter ) strcat( lNew, pAfter );
46 delete [] cStack[cIdx];
52QpFormulaStack::join( int pCnt, const char* pSeparator)
54 int lFirstIdx = 1 - pCnt;
56 if( pCnt > 0 && (cIdx-lFirstIdx) >=0 )
58 int lSepLen = strlen(pSeparator);
59 int lLen = lSepLen * (pCnt-1) +1;
61 for( int lIdx=lFirstIdx; lIdx <= 0; ++lIdx)
63 lLen += strlen( cStack[cIdx + lIdx] );
66 char* lNew = new char[lLen];
70 for( int lIdx=lFirstIdx; lIdx <= 0; ++lIdx)
72 strcat( lNew, cStack[cIdx + lIdx] );
75 strcat( lNew, pSeparator );
88QpFormulaStack::pop( int pCnt)
90 while( cIdx >= 0 && pCnt-- )
92 delete [] cStack[cIdx--];
97QpFormulaStack::push( const char* pString)
105 char** cTemp = new char*[cMax];
107 for( int lIdx=0; lIdx<cIdx; ++lIdx)
109 cTemp[lIdx] = cStack[lIdx];
116 cStack[cIdx] = strcpy( new char[strlen(pString)+1], pString);
122 return (cIdx >=0 ? cStack[cIdx] : 0);
126QpFormulaStack::operator [] ( int pIdx)
130 if( pIdx <= 0 && (cIdx + pIdx) >= 0 )
132 lResult = cStack[cIdx + pIdx];
140static const QpFormulaConv gConv[] =
142 {0, QpFormula::floatFunc, 0},
143 {1, QpFormula::ref, 0},
144 {2, QpFormula::ref, 0},
145 {4, QpFormula::func1, "("},
146 {5, QpFormula::intFunc, 0},
147 {6, QpFormula::stringFunc, 0},
149 {8, QpFormula::unaryOperand, "-"},
150 {9, QpFormula::binaryOperand, "+"},
151 {10, QpFormula::binaryOperand, "-"},
152 {11, QpFormula::binaryOperand, "*"},
153 {12, QpFormula::binaryOperand, "/"},
154 {13, QpFormula::binaryOperand, "^"},
155 {14, QpFormula::binaryOperand, "="},
156 {15, QpFormula::binaryOperand, "<>"},
157 {16, QpFormula::binaryOperand, "<="},
158 {17, QpFormula::binaryOperand, ">="},
159 {18, QpFormula::binaryOperand, "<"},
160 {19, QpFormula::binaryOperand, ">"},
161 {20, QpFormula::binaryOperand, "#AND#"},
162 {21, QpFormula::binaryOperand, "#OR#"},
163 {22, QpFormula::unaryOperand, "#NOT#"},
164 {23, QpFormula::unaryOperand, "+"},
165 {24, QpFormula::binaryOperand, "&"},
173 {32, QpFormula::func0, "@err"},
174 {33, QpFormula::func1, "@abs("},
175 {34, QpFormula::func1, "@int("},
176 {35, QpFormula::func1, "@sqrt("},
177 {36, QpFormula::func1, "@log("},
178 {37, QpFormula::func1, "@ln("},
179 {38, QpFormula::func0, "@pi"},
180 {39, QpFormula::func1, "@sin("},
181 {40, QpFormula::func1, "@cos("},
182 {41, QpFormula::func1, "@tan("},
183 {42, QpFormula::func2, "@atan2("},
184 {43, QpFormula::func1, "@atan("},
185 {44, QpFormula::func1, "@asin("},
186 {45, QpFormula::func1, "@acos("},
187 {46, QpFormula::func1, "@exp("},
188 {47, QpFormula::func2, "@mod("},
189 {48, QpFormula::funcV, "@choose("},
190 {49, QpFormula::func1, "@isna("},
191 {50, QpFormula::func1, "@iserr("},
192 {51, QpFormula::func0, "@false"},
193 {52, QpFormula::func0, "@true"},
194 {53, QpFormula::func0, "@rand"},
195 {54, QpFormula::func3, "@date("},
196 {55, QpFormula::func0, "@now"},
197 {56, QpFormula::func3, "@pmt("},
198 {57, QpFormula::func3, "@pv("},
199 {58, QpFormula::func3, "@fv("},
200 {59, QpFormula::func3, "@if("},
201 {60, QpFormula::func1, "@day("},
202 {61, QpFormula::func1, "@month("},
203 {62, QpFormula::func1, "@year("},
204 {63, QpFormula::func2, "@round("},
205 {64, QpFormula::func3, "@time("},
206 {65, QpFormula::func1, "@hour("},
207 {66, QpFormula::func1, "@minute("},
208 {67, QpFormula::func1, "@second("},
209 {68, QpFormula::func1, "@isnumber("},
210 {69, QpFormula::func1, "@isstring("},
211 {70, QpFormula::func1, "@length("},
212 {71, QpFormula::func1, "@value("},
213 {72, QpFormula::func2, "@string("},
214 {73, QpFormula::func3, "@mid("},
215 {74, QpFormula::func1, "@char("},
216 {75, QpFormula::func1, "@code("},
217 {76, QpFormula::func3, "@find("},
218 {77, QpFormula::func1, "@dateVal("},
219 {78, QpFormula::func1, "@timeVal("},
220 {79, QpFormula::func1, "@cellPtr("},
221 {80, QpFormula::funcV, "@sum("},
222 {81, QpFormula::funcV, "@avg("},
223 {82, QpFormula::funcV, "@count("},
224 {83, QpFormula::funcV, "@min("},
225 {84, QpFormula::funcV, "@max("},
226 {85, QpFormula::func3, "@vlookup("},
227 {86, QpFormula::func2, "@npv("},
228 {87, QpFormula::funcV, "@var("},
229 {88, QpFormula::funcV, "@std("},
230 {89, QpFormula::func2, "@irr("},
231 {90, QpFormula::func3, "@hlookup("},
232 {91, QpFormula::func3, "@dsum("},
233 {92, QpFormula::func3, "@davg("},
234 {93, QpFormula::func3, "@dcount("},
235 {94, QpFormula::func3, "@dmin("},
236 {95, QpFormula::func3, "@dmax("},
237 {96, QpFormula::func3, "@dvar("},
238 {97, QpFormula::func3, "@dstd("},
239 {98, QpFormula::func3, "@index("},
240 {99, QpFormula::func1, "@cols("},
241 {100, QpFormula::func1, "@rows("},
242 {101, QpFormula::func2, "@repeat("},
243 {102, QpFormula::func1, "@upper("},
244 {103, QpFormula::func1, "@lower("},
245 {104, QpFormula::func2, "@left("},
246 {105, QpFormula::func2, "@right("},
247 {106, QpFormula::func4, "@replace("},
248 {107, QpFormula::func1, "@proper("},
249 {108, QpFormula::func2, "@cell("},
250 {109, QpFormula::func1, "@trim("},
251 {110, QpFormula::func1, "@clean("},
252 {111, QpFormula::func1, "@s("},
253 {112, QpFormula::func1, "@n("},
254 {113, QpFormula::func1, "@exact("},
256 {115, QpFormula::func1, "@@("},
257 {116, QpFormula::func3, "@rate("},
258 {117, QpFormula::func3, "@term("},
259 {118, QpFormula::func3, "@cterm("},
260 {119, QpFormula::func3, "@sln("},
261 {120, QpFormula::func4, "@syd("},
262 {121, QpFormula::func4, "@ddb("},
263 {122, QpFormula::funcV, "@stds("},
264 {123, QpFormula::funcV, "@vars("},
265 {124, QpFormula::func1, "@dstds("},
266 {125, QpFormula::func1, "@dvars("},
267 {126, QpFormula::func1, "@pval("},
268 {127, QpFormula::func1, "@paymt("},
269 {128, QpFormula::func1, "@fval("},
270 {129, QpFormula::func1, "@nper("},
271 {130, QpFormula::func1, "@irate("},
272 {131, QpFormula::func1, "@ipaymt("},
273 {132, QpFormula::func1, "@ppaymt("},
274 {133, QpFormula::func1, "@sumproduct("},
275 {134, QpFormula::func1, "@memavail("},
276 {135, QpFormula::func1, "@mememsavail("},
277 {136, QpFormula::func1, "@fileexists("},
278 {137, QpFormula::func1, "@curval("},
279 {138, QpFormula::func1, "@degrees("},
280 {139, QpFormula::func1, "@radians("},
281 {140, QpFormula::func1, "@hextonum("},
282 {141, QpFormula::func1, "@numtohex("},
283 {142, QpFormula::func1, "@today("},
284 {143, QpFormula::func3, "@npv("},
285 {144, QpFormula::func1, "@cellindex2d("},
286 {145, QpFormula::func1, "@version("},
287 {154, QpFormula::func1, "@sheets("},
288 {157, QpFormula::func1, "@index3d("},
289 {158, QpFormula::func1, "@cellindex3d("},
290 {159, QpFormula::func1, "@property("},
291 {160, QpFormula::func1, "@ddelink("},
292 {161, QpFormula::func1, "@command("},
296QpFormula::QpFormula(QpRecFormulaCell& pCell, QpTableNames& pTable)
297 : cArgSeparator(strcpy(new char[2], ","))
299 , cFormula( (unsigned char*)pCell.formula(), (unsigned int)pCell.formulaLen() )
300 , cFormulaRefs( (unsigned char*)&pCell.formula()[pCell.formulaReferences()]
301 , (unsigned)(pCell.formulaLen()-pCell.formulaReferences())
304 , cFormulaStart(strcpy(new char[2], "+"))
311QpFormula::~QpFormula()
313 delete [] cArgSeparator;
316 delete [] cFormulaStart;
323QpFormula::argSeparator( const char* pArg)
325 delete [] cArgSeparator;
326 cArgSeparator = strcpy( new char[strlen(pArg)+1], pArg);
334 cStack.push(cFormulaStart);
336 while( cFormula >> lOperand, cFormula && lOperand != 3 )
341 if(cReplaceFunc != 0)
345 ; !lFound && cReplaceFunc[lIdx].cFunc != 0
349 if( cReplaceFunc[lIdx].cOperand == lOperand )
352 TQP_DEBUG( "Processing " << ( int)lOperand << endl);
353 (*cReplaceFunc[lIdx].cFunc)(* this, cReplaceFunc[lIdx].cArg);
360 ; !lFound && gConv[lIdx].cFunc != 0
364 if( gConv[lIdx].cOperand == lOperand )
367 TQP_DEBUG( "Processing " << ( int)lOperand << endl);
368 (*gConv[lIdx].cFunc)(* this, gConv[lIdx].cArg);
372 TQP_DEBUG( "Top = " << cStack.top() << endl);
377 TQP_DEBUG( "Formula = " << cStack.top() << endl);
378 return strcpy( new char[strlen(cStack.top())+1], cStack.top());
382QpFormula::formulaStart( const char* pFirstChar)
384 delete [] cFormulaStart;
385 cFormulaStart = strcpy( new char[strlen(pFirstChar)+1], pFirstChar);
389QpFormula::binaryOperandReal( const char* pOper)
391 cStack.join( 2, pOper );
395QpFormula::absKludgeReal( const char*)
402 char* lArg = strcpy( new char[strlen(cStack.top())+1], cStack.top());
404 cStack.bracket( "", "<0");
407 cStack.bracket( "-", "");
411 cStack.join(3, cArgSeparator);
413 cStack.bracket( "if(");
419QpFormula::func0Real( const char* pFunc)
421 const char* lFunc = (cDropLeadingAt && pFunc[0] == '@' ? &pFunc[1] : pFunc);
423 cStack.push( lFunc );
427QpFormula::func1Real( const char* pFunc)
429 const char* lFunc = (cDropLeadingAt && pFunc[0] == '@' ? &pFunc[1] : pFunc);
431 cStack.bracket( lFunc );
435QpFormula::func2Real( const char* pFunc)
437 const char* lFunc = (cDropLeadingAt && pFunc[0] == '@' ? &pFunc[1] : pFunc);
439 cStack.join( 2, cArgSeparator );
440 cStack.bracket( lFunc );
444QpFormula::func3Real( const char* pFunc)
446 const char* lFunc = (cDropLeadingAt && pFunc[0] == '@' ? &pFunc[1] : pFunc);
448 cStack.join( 3, cArgSeparator );
449 cStack.bracket( lFunc );
453QpFormula::func4Real( const char* pFunc)
455 const char* lFunc = (cDropLeadingAt && pFunc[0] == '@' ? &pFunc[1] : pFunc);
457 cStack.join( 4, cArgSeparator );
458 cStack.bracket( lFunc );
462QpFormula::funcVReal( const char* pFunc)
465 const char* lFunc = (cDropLeadingAt && pFunc[0] == '@' ? &pFunc[1] : pFunc);
469 cStack.join( lCnt, cArgSeparator );
470 cStack.bracket( lFunc );
474QpFormula::floatFuncReal( const char*)
477 std::ostringstream lNum;
481 lNum << lFloat << ends;
483 cStack.push( lNum.str().c_str() );
487QpFormula::intFuncReal( const char*)
490 std::ostringstream lNum;
494 lNum << lInt << ends;
496 cStack.push( lNum.str().c_str() );
500QpFormula::dropLeadingAt( int pBool)
502 cDropLeadingAt = pBool;
506QpFormula::refReal( const char*)
510 cCell.cellRef( lRef, cTable, cFormulaRefs );
516QpFormula::replaceFunc(QpFormulaConv* pFuncEntry)
518 cReplaceFunc = pFuncEntry;
522QpFormula::stringFuncReal( const char*)
528 char* lQuoteString = new char[strlen(lString)+3];
530 lQuoteString[0] = '"';
531 strcpy(&lQuoteString[1], lString);
532 strcat(lQuoteString, "\"");
534 cStack.push( lQuoteString );
537 delete [] lQuoteString;
541QpFormula::unaryOperandReal( const char* pOper)
543 cStack.bracket( pOper, "" );
|