b62deb64d98735010d7a3b9f825072fbe37b0a54
[alexxy/gromacs.git] / src / external / muparser / muParserDLL.cpp
1 /*
2
3          _____  __ _____________ _______  ______ ___________
4         /     \|  |  \____ \__  \\_  __ \/  ___// __ \_  __ \
5    |  Y Y  \  |  /  |_> > __ \|  | \/\___ \\  ___/|  | \/
6    |__|_|  /____/|   __(____  /__|  /____  >\___  >__|
7                  \/      |__|       \/           \/     \/
8    Copyright (C) 2004 - 2020 Ingo Berg
9
10         Redistribution and use in source and binary forms, with or without modification, are permitted
11         provided that the following conditions are met:
12
13           * Redistributions of source code must retain the above copyright notice, this list of
14                 conditions and the following disclaimer.
15           * Redistributions in binary form must reproduce the above copyright notice, this list of
16                 conditions and the following disclaimer in the documentation and/or other materials provided
17                 with the distribution.
18
19         THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20         IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21         FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22         CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23         DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24         DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25         IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26         OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #if defined(MUPARSER_DLL) 
30
31 #if defined(_WIN32)
32         #define WIN32_LEAN_AND_MEAN
33         #define _CRT_SECURE_NO_WARNINGS
34         #define _CRT_SECURE_NO_DEPRECATE
35
36         #include <windows.h>
37 #endif
38
39 #include <cassert>
40
41 #include "muParserDLL.h"
42 #include "muParser.h"
43 #include "muParserInt.h"
44 #include "muParserError.h"
45
46 #if defined(_MSC_VER)
47         #pragma warning(push)
48         #pragma warning(disable : 26812) 
49 #endif
50
51 #define MU_TRY  \
52                 try             \
53         {
54
55 #define MU_CATCH                                                                               \
56         }                                                                                          \
57         catch (muError_t &e)                                           \
58         {                                                                                  \
59                 ParserTag *pTag = static_cast<ParserTag*>(a_hParser);  \
60                         pTag->exc = e;                                         \
61                         pTag->bError = true;                                   \
62                         if (pTag->errHandler)                                  \
63                                 (pTag->errHandler)(a_hParser);                     \
64         }                                                                              \
65         catch (...)                                                        \
66         {                                                                  \
67                 ParserTag *pTag = static_cast<ParserTag*>(a_hParser);  \
68                 pTag->exc = muError_t(mu::ecINTERNAL_ERROR);           \
69                 pTag->bError = true;                                   \
70                         if (pTag->errHandler)                                  \
71                                 (pTag->errHandler)(a_hParser);                     \
72         }
73
74 /** \file
75         \brief This file contains the implementation of the DLL interface of muParser.
76 */
77
78 typedef mu::ParserBase::exception_type muError_t;
79 typedef mu::ParserBase muParser_t;
80 int g_nBulkSize;
81
82
83 class ParserTag
84 {
85 public:
86         ParserTag(int nType)
87                 : pParser((nType == muBASETYPE_FLOAT)
88                         ? (mu::ParserBase*)new mu::Parser()
89                         : (nType == muBASETYPE_INT) ? (mu::ParserBase*)new mu::ParserInt() : nullptr)
90                 , exc()
91                 , errHandler(nullptr)
92                 , bError(false)
93                 , m_nParserType(nType)
94         {}
95
96         ~ParserTag()
97         {
98                 delete pParser;
99         }
100
101         mu::ParserBase* pParser;
102         mu::ParserBase::exception_type exc;
103         muErrorHandler_t errHandler;
104         bool bError;
105
106 private:
107         ParserTag(const ParserTag& ref);
108         ParserTag& operator=(const ParserTag& ref);
109
110         int m_nParserType;
111 };
112
113 static muChar_t s_tmpOutBuf[2048];
114
115 //---------------------------------------------------------------------------
116 //
117 //
118 //  unexported functions
119 //
120 //
121 //---------------------------------------------------------------------------
122
123
124 inline muParser_t* AsParser(muParserHandle_t a_hParser)
125 {
126         return static_cast<ParserTag*>(a_hParser)->pParser;
127 }
128
129
130 inline ParserTag* AsParserTag(muParserHandle_t a_hParser)
131 {
132         return static_cast<ParserTag*>(a_hParser);
133 }
134
135
136 #if defined(_WIN32)
137
138 BOOL APIENTRY DllMain(HANDLE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
139 {
140         switch (ul_reason_for_call)
141         {
142         case  DLL_PROCESS_ATTACH:
143                 break;
144
145         case  DLL_THREAD_ATTACH:
146         case  DLL_THREAD_DETACH:
147         case  DLL_PROCESS_DETACH:
148                 break;
149         }
150
151         return TRUE;
152 }
153
154 #endif
155
156 //---------------------------------------------------------------------------
157 //
158 //
159 //  exported functions
160 //
161 //
162 //---------------------------------------------------------------------------
163
164 API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void* pUserData)
165 {
166         MU_TRY
167                 muParser_t* p(AsParser(a_hParser));
168                 p->SetVarFactory(a_pFactory, pUserData);
169         MU_CATCH
170 }
171
172
173 /** \brief Create a new Parser instance and return its handle. */
174 API_EXPORT(muParserHandle_t) mupCreate(int nBaseType)
175 {
176         switch (nBaseType)
177         {
178         case  muBASETYPE_FLOAT:   return (void*)(new ParserTag(muBASETYPE_FLOAT));
179         case  muBASETYPE_INT:     return (void*)(new ParserTag(muBASETYPE_INT));
180         default:                  return nullptr;
181         }
182 }
183
184
185 /** \brief Release the parser instance related with a parser handle. */
186 API_EXPORT(void) mupRelease(muParserHandle_t a_hParser)
187 {
188         MU_TRY
189                 ParserTag* p = static_cast<ParserTag*>(a_hParser);
190                 delete p;
191         MU_CATCH
192 }
193
194
195 API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser)
196 {
197         MU_TRY
198                 muParser_t* const p(AsParser(a_hParser));
199
200 #ifndef _UNICODE
201                 sprintf(s_tmpOutBuf, "%s", p->GetVersion().c_str());
202 #else
203                 wsprintf(s_tmpOutBuf, _T("%s"), p->GetVersion().c_str());
204 #endif
205
206                 return s_tmpOutBuf;
207         MU_CATCH
208         return _T("");
209 }
210
211
212 /** \brief Evaluate the expression. */
213 API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser)
214 {
215         MU_TRY
216                 muParser_t* const p(AsParser(a_hParser));
217                 return p->Eval();
218         MU_CATCH
219         return 0;
220 }
221
222
223 API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int* nNum)
224 {
225         MU_TRY
226                 if (nNum == nullptr)
227                         throw std::runtime_error("Argument is null!"); 
228
229                 muParser_t* const p(AsParser(a_hParser));
230                 return p->Eval(*nNum);
231         MU_CATCH
232         return 0;
233 }
234
235
236 API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t* a_res, int nSize)
237 {
238         MU_TRY
239                 muParser_t* p(AsParser(a_hParser));
240                 p->Eval(a_res, nSize);
241         MU_CATCH
242 }
243
244
245 API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t* a_szExpr)
246 {
247         MU_TRY
248                 muParser_t* const p(AsParser(a_hParser));
249                 p->SetExpr(a_szExpr);
250         MU_CATCH
251 }
252
253
254 API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName)
255 {
256         MU_TRY
257                 muParser_t* const p(AsParser(a_hParser));
258                 p->RemoveVar(a_szName);
259         MU_CATCH
260 }
261
262
263 /** \brief Release all parser variables.
264         \param a_hParser Handle to the parser instance.
265 */
266 API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser)
267 {
268         MU_TRY
269                 muParser_t* const p(AsParser(a_hParser));
270                 p->ClearVar();
271         MU_CATCH
272 }
273
274
275 /** \brief Release all parser variables.
276         \param a_hParser Handle to the parser instance.
277 */
278 API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser)
279 {
280         MU_TRY
281                 muParser_t* const p(AsParser(a_hParser));
282                 p->ClearConst();
283         MU_CATCH
284 }
285
286
287 /** \brief Clear all user defined operators.
288         \param a_hParser Handle to the parser instance.
289 */
290 API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser)
291 {
292         MU_TRY
293                 muParser_t* const p(AsParser(a_hParser));
294                 p->ClearOprt();
295         MU_CATCH
296 }
297
298
299 API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser)
300 {
301         MU_TRY
302                 muParser_t* const p(AsParser(a_hParser));
303                 p->ClearFun();
304         MU_CATCH
305 }
306
307
308 API_EXPORT(void) mupDefineFun0(muParserHandle_t a_hParser,
309         const muChar_t* a_szName,
310         muFun0_t a_pFun,
311         muBool_t a_bAllowOpt)
312 {
313         MU_TRY
314                 muParser_t* const p(AsParser(a_hParser));
315                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
316         MU_CATCH
317 }
318
319
320 API_EXPORT(void) mupDefineFun1(muParserHandle_t a_hParser,      const muChar_t* a_szName, muFun1_t a_pFun, muBool_t a_bAllowOpt)
321 {
322         MU_TRY
323                 muParser_t* const p(AsParser(a_hParser));
324                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
325         MU_CATCH
326 }
327
328
329 API_EXPORT(void) mupDefineFun2(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun2_t a_pFun, muBool_t a_bAllowOpt)
330 {
331         MU_TRY
332                 muParser_t* const p(AsParser(a_hParser));
333                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
334         MU_CATCH
335 }
336
337
338 API_EXPORT(void) mupDefineFun3(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun3_t a_pFun, muBool_t a_bAllowOpt)
339 {
340         MU_TRY
341                 muParser_t* const p(AsParser(a_hParser));
342                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
343         MU_CATCH
344 }
345
346
347 API_EXPORT(void) mupDefineFun4(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun4_t a_pFun, muBool_t a_bAllowOpt)
348 {
349         MU_TRY
350                 muParser_t* const p(AsParser(a_hParser));
351                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
352         MU_CATCH
353 }
354
355
356 API_EXPORT(void) mupDefineFun5(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun5_t a_pFun, muBool_t a_bAllowOpt)
357 {
358         MU_TRY
359                 muParser_t* const p(AsParser(a_hParser));
360                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
361         MU_CATCH
362 }
363
364
365 API_EXPORT(void) mupDefineFun6(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun6_t a_pFun, muBool_t a_bAllowOpt)
366 {
367         MU_TRY
368                 muParser_t* const p(AsParser(a_hParser));
369                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
370         MU_CATCH
371 }
372
373
374 API_EXPORT(void) mupDefineFun7(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun7_t a_pFun, muBool_t a_bAllowOpt)
375 {
376         MU_TRY
377                 muParser_t* const p(AsParser(a_hParser));
378                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
379         MU_CATCH
380 }
381
382
383 API_EXPORT(void) mupDefineFun8(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun8_t a_pFun, muBool_t a_bAllowOpt)
384 {
385         MU_TRY
386                 muParser_t* const p(AsParser(a_hParser));
387                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
388         MU_CATCH
389 }
390
391
392 API_EXPORT(void) mupDefineFun9(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun9_t a_pFun, muBool_t a_bAllowOpt)
393 {
394         MU_TRY
395                 muParser_t* const p(AsParser(a_hParser));
396                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
397         MU_CATCH
398 }
399
400
401 API_EXPORT(void) mupDefineFun10(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun10_t a_pFun, muBool_t a_bAllowOpt)
402 {
403         MU_TRY
404                 muParser_t* const p(AsParser(a_hParser));
405                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
406         MU_CATCH
407 }
408
409
410 API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun0_t a_pFun)
411 {
412         MU_TRY
413                 muParser_t* const p(AsParser(a_hParser));
414                 p->DefineFun(a_szName, a_pFun, false);
415         MU_CATCH
416 }
417
418
419 API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun1_t a_pFun)
420 {
421         MU_TRY
422                 muParser_t* const p(AsParser(a_hParser));
423                 p->DefineFun(a_szName, a_pFun, false);
424         MU_CATCH
425 }
426
427
428 API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun2_t a_pFun)
429 {
430         MU_TRY
431                 muParser_t* const p(AsParser(a_hParser));
432                 p->DefineFun(a_szName, a_pFun, false);
433         MU_CATCH
434 }
435
436
437 API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun3_t a_pFun)
438 {
439         MU_TRY
440                 muParser_t* const p(AsParser(a_hParser));
441                 p->DefineFun(a_szName, a_pFun, false);
442         MU_CATCH
443 }
444
445
446 API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun4_t a_pFun)
447 {
448         MU_TRY
449                 muParser_t* const p(AsParser(a_hParser));
450                 p->DefineFun(a_szName, a_pFun, false);
451         MU_CATCH
452 }
453
454
455 API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun5_t a_pFun)
456 {
457         MU_TRY
458                 muParser_t* const p(AsParser(a_hParser));
459                 p->DefineFun(a_szName, a_pFun, false);
460         MU_CATCH
461 }
462
463
464 API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun6_t a_pFun)
465 {
466         MU_TRY
467                 muParser_t* const p(AsParser(a_hParser));
468                 p->DefineFun(a_szName, a_pFun, false);
469         MU_CATCH
470 }
471
472
473 API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun7_t a_pFun)
474 {
475         MU_TRY
476                 muParser_t* const p(AsParser(a_hParser));
477                 p->DefineFun(a_szName, a_pFun, false);
478         MU_CATCH
479 }
480
481
482 API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun8_t a_pFun)
483 {
484         MU_TRY
485                 muParser_t* const p(AsParser(a_hParser));
486                 p->DefineFun(a_szName, a_pFun, false);
487         MU_CATCH
488 }
489
490
491 API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun9_t a_pFun)
492 {
493         MU_TRY
494                 muParser_t* const p(AsParser(a_hParser));
495                 p->DefineFun(a_szName, a_pFun, false);
496         MU_CATCH
497 }
498
499
500 API_EXPORT(void) mupDefineBulkFun10(muParserHandle_t a_hParser, const muChar_t* a_szName, muBulkFun10_t a_pFun)
501 {
502         MU_TRY
503                 muParser_t* const p(AsParser(a_hParser));
504                 p->DefineFun(a_szName, a_pFun, false);
505         MU_CATCH
506 }
507
508
509 API_EXPORT(void) mupDefineStrFun1(muParserHandle_t a_hParser, const muChar_t* a_szName, muStrFun1_t a_pFun)
510 {
511         MU_TRY
512                 muParser_t* const p(AsParser(a_hParser));
513                 p->DefineFun(a_szName, a_pFun, false);
514         MU_CATCH
515 }
516
517
518 API_EXPORT(void) mupDefineStrFun2(muParserHandle_t a_hParser, const muChar_t* a_szName, muStrFun2_t a_pFun)
519 {
520         MU_TRY
521                 muParser_t* const p(AsParser(a_hParser));
522                 p->DefineFun(a_szName, a_pFun, false);
523         MU_CATCH
524 }
525
526
527 API_EXPORT(void) mupDefineStrFun3(muParserHandle_t a_hParser, const muChar_t* a_szName, muStrFun3_t a_pFun)
528 {
529         MU_TRY
530                 muParser_t* const p(AsParser(a_hParser));
531                 p->DefineFun(a_szName, a_pFun, false);
532         MU_CATCH
533 }
534
535
536 API_EXPORT(void) mupDefineMultFun(muParserHandle_t a_hParser, const muChar_t* a_szName, muMultFun_t a_pFun,     muBool_t a_bAllowOpt)
537 {
538         MU_TRY
539                 muParser_t* const p(AsParser(a_hParser));
540                 p->DefineFun(a_szName, a_pFun, a_bAllowOpt != 0);
541         MU_CATCH
542 }
543
544
545 API_EXPORT(void) mupDefineOprt(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun2_t a_pFun, muInt_t a_nPrec, muInt_t a_nOprtAsct, muBool_t a_bAllowOpt)
546 {
547         MU_TRY
548                 muParser_t* const p(AsParser(a_hParser));
549                 p->DefineOprt(a_szName, a_pFun, a_nPrec, (mu::EOprtAssociativity)a_nOprtAsct, a_bAllowOpt != 0);
550         MU_CATCH
551 }
552
553
554 API_EXPORT(void) mupDefineVar(muParserHandle_t a_hParser, const muChar_t* a_szName,     muFloat_t* a_pVar)
555 {
556         MU_TRY
557                 muParser_t* const p(AsParser(a_hParser));
558                 p->DefineVar(a_szName, a_pVar);
559         MU_CATCH
560 }
561
562
563 API_EXPORT(void) mupDefineBulkVar(muParserHandle_t a_hParser, const muChar_t* a_szName, muFloat_t* a_pVar)
564 {
565         MU_TRY
566                 muParser_t* const p(AsParser(a_hParser));
567                 p->DefineVar(a_szName, a_pVar);
568         MU_CATCH
569 }
570
571
572 API_EXPORT(void) mupDefineConst(muParserHandle_t a_hParser,     const muChar_t* a_szName, muFloat_t a_fVal)
573 {
574         MU_TRY
575                 muParser_t* const p(AsParser(a_hParser));
576                 p->DefineConst(a_szName, a_fVal);
577         MU_CATCH
578 }
579
580
581 API_EXPORT(void) mupDefineStrConst(muParserHandle_t a_hParser, const muChar_t* a_szName, const muChar_t* a_szVal)
582 {
583         MU_TRY
584                 muParser_t* const p(AsParser(a_hParser));
585                 p->DefineStrConst(a_szName, a_szVal);
586         MU_CATCH
587 }
588
589
590 API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser)
591 {
592         MU_TRY
593                 muParser_t* const p(AsParser(a_hParser));
594
595                 // C# explodes when pMsg is returned directly. For some reason it can't access
596                 // the memory where the message lies directly.
597 #ifndef _UNICODE
598                 sprintf(s_tmpOutBuf, "%s", p->GetExpr().c_str());
599 #else
600                 wsprintf(s_tmpOutBuf, _T("%s"), p->GetExpr().c_str());
601 #endif
602
603                 return s_tmpOutBuf;
604         MU_CATCH
605
606         return _T("");
607 }
608
609
610 API_EXPORT(void) mupDefinePostfixOprt(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun1_t a_pOprt, muBool_t a_bAllowOpt)
611 {
612         MU_TRY
613                 muParser_t* const p(AsParser(a_hParser));
614                 p->DefinePostfixOprt(a_szName, a_pOprt, a_bAllowOpt != 0);
615         MU_CATCH
616 }
617
618
619 API_EXPORT(void) mupDefineInfixOprt(muParserHandle_t a_hParser, const muChar_t* a_szName, muFun1_t a_pOprt,     muBool_t a_bAllowOpt)
620 {
621         MU_TRY
622                 muParser_t* const p(AsParser(a_hParser));
623                 p->DefineInfixOprt(a_szName, a_pOprt, a_bAllowOpt != 0);
624         MU_CATCH
625 }
626
627 // Define character sets for identifiers
628 API_EXPORT(void) mupDefineNameChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset)
629 {
630         muParser_t* const p(AsParser(a_hParser));
631         p->DefineNameChars(a_szCharset);
632 }
633
634
635 API_EXPORT(void) mupDefineOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset)
636 {
637         muParser_t* const p(AsParser(a_hParser));
638         p->DefineOprtChars(a_szCharset);
639 }
640
641
642 API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset)
643 {
644         muParser_t* const p(AsParser(a_hParser));
645         p->DefineInfixOprtChars(a_szCharset);
646 }
647
648
649 /** \brief Get the number of variables defined in the parser.
650         \param a_hParser [in] Must be a valid parser handle.
651         \return The number of used variables.
652         \sa mupGetExprVar
653 */
654 API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser)
655 {
656         MU_TRY
657                 muParser_t* const p(AsParser(a_hParser));
658                 const mu::varmap_type VarMap = p->GetVar();
659                 return (int)VarMap.size();
660         MU_CATCH
661
662         return 0; // never reached
663 }
664
665
666 /** \brief Return a variable that is used in an expression.
667         \param a_hParser [in] A valid parser handle.
668         \param a_iVar [in] The index of the variable to return.
669         \param a_szName [out] Pointer to the variable name.
670         \param a_pVar [out] Pointer to the variable.
671         \throw nothrow
672
673         Prior to calling this function call mupGetExprVarNum in order to get the
674         number of variables in the expression. If the parameter a_iVar is greater
675         than the number of variables both a_szName and a_pVar will be set to zero.
676         As a side effect this function will trigger an internal calculation of the
677         expression undefined variables will be set to zero during this calculation.
678         During the calculation user defined callback functions present in the expression
679         will be called, this is unavoidable.
680 */
681 API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_szName, muFloat_t** a_pVar)
682 {
683         // A static buffer is needed for the name since i can't return the
684         // pointer from the map.
685         static muChar_t  szName[1024];
686
687         MU_TRY
688                 muParser_t* const p(AsParser(a_hParser));
689                 const mu::varmap_type VarMap = p->GetVar();
690
691                 if (a_iVar >= VarMap.size())
692                 {
693                         *a_szName = 0;
694                         *a_pVar = 0;
695                         return;
696                 }
697                 mu::varmap_type::const_iterator item;
698
699                 item = VarMap.begin();
700                 for (unsigned i = 0; i < a_iVar; ++i)
701                         ++item;
702
703 #ifndef _UNICODE
704                 strncpy(szName, item->first.c_str(), sizeof(szName));
705 #else
706                 wcsncpy(szName, item->first.c_str(), sizeof(szName));
707 #endif
708
709                 szName[sizeof(szName) - 1] = 0;
710
711                 *a_szName = &szName[0];
712                 *a_pVar = item->second;
713                 return;
714         MU_CATCH
715
716         * a_szName = 0;
717         *a_pVar = 0;
718 }
719
720
721 /** \brief Get the number of variables used in the expression currently set in the parser.
722         \param a_hParser [in] Must be a valid parser handle.
723         \return The number of used variables.
724         \sa mupGetExprVar
725         */
726 API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser)
727 {
728         MU_TRY
729                 muParser_t* const p(AsParser(a_hParser));
730                 const mu::varmap_type VarMap = p->GetUsedVar();
731                 return (int)VarMap.size();
732         MU_CATCH
733
734         return 0; // never reached
735 }
736
737
738 /** \brief Return a variable that is used in an expression.
739
740         Prior to calling this function call mupGetExprVarNum in order to get the
741         number of variables in the expression. If the parameter a_iVar is greater
742         than the number of variables both a_szName and a_pVar will be set to zero.
743         As a side effect this function will trigger an internal calculation of the
744         expression undefined variables will be set to zero during this calculation.
745         During the calculation user defined callback functions present in the expression
746         will be called, this is unavoidable.
747
748         \param a_hParser [in] A valid parser handle.
749         \param a_iVar [in] The index of the variable to return.
750         \param a_szName [out] Pointer to the variable name.
751         \param a_pVar [out] Pointer to the variable.
752         \throw nothrow
753 */
754 API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_szName, muFloat_t** a_pVar)
755 {
756         // A static buffer is needed for the name since i can't return the
757         // pointer from the map.
758         static muChar_t  szName[1024];
759
760         MU_TRY
761                 muParser_t* const p(AsParser(a_hParser));
762                 const mu::varmap_type VarMap = p->GetUsedVar();
763
764                 if (a_iVar >= VarMap.size())
765                 {
766                         *a_szName = 0;
767                         *a_pVar = 0;
768                         return;
769                 }
770                 mu::varmap_type::const_iterator item;
771
772                 item = VarMap.begin();
773                 for (unsigned i = 0; i < a_iVar; ++i)
774                         ++item;
775
776 #ifndef _UNICODE
777                 strncpy(szName, item->first.c_str(), sizeof(szName));
778 #else
779                 wcsncpy(szName, item->first.c_str(), sizeof(szName));
780 #endif
781
782                 szName[sizeof(szName) - 1] = 0;
783
784                 *a_szName = &szName[0];
785                 *a_pVar = item->second;
786                 return;
787         MU_CATCH
788
789         * a_szName = 0;
790         *a_pVar = 0;
791 }
792
793
794 /** \brief Return the number of constants defined in a parser. */
795 API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser)
796 {
797         MU_TRY
798                 muParser_t* const p(AsParser(a_hParser));
799                 const mu::valmap_type ValMap = p->GetConst();
800                 return (int)ValMap.size();
801         MU_CATCH
802
803         return 0; // never reached
804 }
805
806
807 API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep)
808 {
809         MU_TRY
810                 muParser_t* const p(AsParser(a_hParser));
811                 p->SetArgSep(cArgSep);
812         MU_CATCH
813 }
814
815
816 API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser)
817 {
818         MU_TRY
819                 muParser_t* const p(AsParser(a_hParser));
820                 p->ResetLocale();
821         MU_CATCH
822 }
823
824
825 API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cDecSep)
826 {
827         MU_TRY
828                 muParser_t* const p(AsParser(a_hParser));
829         p->SetDecSep(cDecSep);
830         MU_CATCH
831 }
832
833
834 API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cThousandsSep)
835 {
836         MU_TRY
837                 muParser_t* const p(AsParser(a_hParser));
838                 p->SetThousandsSep(cThousandsSep);
839         MU_CATCH
840 }
841
842 //---------------------------------------------------------------------------
843 /** \brief Retrieve name and value of a single parser constant.
844         \param a_hParser [in] a valid parser handle
845         \param a_iVar [in] Index of the constant to query
846         \param a_pszName [out] pointer to a null terminated string with the constant name
847         \param [out] The constant value
848         */
849 API_EXPORT(void) mupGetConst(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t* a_fVal)
850 {
851         // A static buffer is needed for the name since i can't return the
852         // pointer from the map.
853         static muChar_t szName[1024];
854
855         MU_TRY
856                 muParser_t* const p(AsParser(a_hParser));
857                 const mu::valmap_type ValMap = p->GetConst();
858
859                 if (a_iVar >= ValMap.size())
860                 {
861                         *a_pszName = 0;
862                         *a_fVal = 0;
863                         return;
864                 }
865
866                 mu::valmap_type::const_iterator item;
867                 item = ValMap.begin();
868                 for (unsigned i = 0; i < a_iVar; ++i)
869                         ++item;
870
871 #ifndef _UNICODE
872                 strncpy(szName, item->first.c_str(), sizeof(szName));
873 #else
874                 wcsncpy(szName, item->first.c_str(), sizeof(szName));
875 #endif
876
877                 szName[sizeof(szName) - 1] = 0;
878
879                 *a_pszName = &szName[0];
880                 *a_fVal = item->second;
881                 return;
882
883         MU_CATCH
884
885         * a_pszName = 0;
886         *a_fVal = 0;
887 }
888
889
890 /** \brief Add a custom value recognition function. */
891 API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser,     muIdentFun_t a_pFun)
892 {
893         MU_TRY
894                 muParser_t* p(AsParser(a_hParser));
895                 p->AddValIdent(a_pFun);
896         MU_CATCH
897 }
898
899
900 /** \brief Query if an error occurred.
901
902         After querying the internal error bit will be reset. So a consecutive call
903         will return false.
904 */
905 API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser)
906 {
907         bool bError(AsParserTag(a_hParser)->bError);
908         AsParserTag(a_hParser)->bError = false;
909         return bError;
910 }
911
912
913 /** \brief Reset the internal error flag. */
914 API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser)
915 {
916         AsParserTag(a_hParser)->bError = false;
917 }
918
919
920 API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pHandler)
921 {
922         AsParserTag(a_hParser)->errHandler = a_pHandler;
923 }
924
925
926 /** \brief Return the message associated with the last error. */
927 API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser)
928 {
929         ParserTag* const p(AsParserTag(a_hParser));
930         const muChar_t* pMsg = p->exc.GetMsg().c_str();
931
932         // C# explodes when pMsg is returned directly. For some reason it can't access
933         // the memory where the message lies directly.
934 #ifndef _UNICODE
935         sprintf(s_tmpOutBuf, "%s", pMsg);
936 #else
937         wsprintf(s_tmpOutBuf, _T("%s"), pMsg);
938 #endif
939
940         return s_tmpOutBuf;
941 }
942
943
944 /** \brief Return the message associated with the last error. */
945 API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser)
946 {
947         ParserTag* const p(AsParserTag(a_hParser));
948         const muChar_t* pToken = p->exc.GetToken().c_str();
949
950         // C# explodes when pMsg is returned directly. For some reason it can't access
951         // the memory where the message lies directly.
952 #ifndef _UNICODE
953         sprintf(s_tmpOutBuf, "%s", pToken);
954 #else
955         wsprintf(s_tmpOutBuf, _T("%s"), pToken);
956 #endif
957
958         return s_tmpOutBuf;
959 }
960
961
962 /** \brief Return the code associated with the last error.
963 */
964 API_EXPORT(int) mupGetErrorCode(muParserHandle_t a_hParser)
965 {
966         return AsParserTag(a_hParser)->exc.GetCode();
967 }
968
969
970 /** \brief Return the position associated with the last error. */
971 API_EXPORT(int) mupGetErrorPos(muParserHandle_t a_hParser)
972 {
973         return (int)AsParserTag(a_hParser)->exc.GetPos();
974 }
975
976
977 API_EXPORT(muFloat_t*) mupCreateVar()
978 {
979         return new muFloat_t(0);
980 }
981
982
983 API_EXPORT(void) mupReleaseVar(muFloat_t* ptr)
984 {
985         delete ptr;
986 }
987
988 #if defined(_MSC_VER)
989         #pragma warning(pop)
990 #endif
991
992 #endif      // MUPARSER_DLL