OpcUaCanOpen
CANopen OPC-UA server
example2.c
Go to the documentation of this file.
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <wchar.h>
5 
6 #include "muParserDLL.h"
7 
8 #define PARSER_CONST_PI 3.141592653589793238462643
9 #define PARSER_CONST_E 2.718281828459045235360287
10 #define PARSER_MAXVARS 10
11 
12 #ifndef _UNICODE
13  #define _T(x) x
14  #define myprintf printf
15  #define mystrlen strlen
16  #define myfgets fgets
17  #define mystrcmp strcmp
18 #else
19  #define _T(x) L ##x
20  #define myprintf wprintf
21  #define mystrlen wcslen
22  #define myfgets fgetws
23  #define mystrcmp wcscmp
24 #endif
25 
26 extern void CalcBulk();
27 
28 //---------------------------------------------------------------------------
29 // Callbacks for postfix operators
31 {
32  return a_fVal * 1.0e6;
33 }
34 
36 {
37  return a_fVal / 1.0e3;
38 }
39 
41 {
42  myprintf(_T("i'm a function without arguments.\n"));
43  return 123;
44 }
45 
46 muFloat_t BulkTest(int nBulkIdx, int nThreadIdx, muFloat_t v1)
47 {
48  myprintf(_T("%d,%2.2f\n"), nBulkIdx, v1);
49  return v1 / (nBulkIdx + 1);
50 }
51 
52 //---------------------------------------------------------------------------
53 // Callbacks for infix operators
54 muFloat_t Not(muFloat_t v) { return v == 0; }
55 
56 //---------------------------------------------------------------------------
57 // Function callbacks
58 muFloat_t Rnd(muFloat_t v) { return v * rand() / (muFloat_t)(RAND_MAX + 1.0); }
59 
61 {
62  if (szMsg)
63  {
64  myprintf(_T("%s\n"), szMsg);
65  }
66 
67  return 999;
68 }
69 
70 muFloat_t Sum(const muFloat_t *a_afArg, int a_iArgc)
71 {
72  muFloat_t fRes = 0;
73  int i = 0;
74 
75  for (i = 0; i < a_iArgc; ++i)
76  fRes += a_afArg[i];
77 
78  return fRes;
79 }
80 
81 //---------------------------------------------------------------------------
82 // Binarty operator callbacks
84 {
85  return v1 + v2;
86 }
87 
89 {
90  return v1*v2;
91 }
92 
93 //---------------------------------------------------------------------------
94 // Factory function for creating new parser variables
95 // This could as well be a function performing database queries.
97 {
98  static muFloat_t afValBuf[PARSER_MAXVARS]; // I don't want dynamic allocation here
99  static int iVal = 0; // so i used this buffer
100 
101  myprintf(_T("Generating new variable \"%s\" (slots left: %d; context pointer: 0x%x)\n"), a_szName, PARSER_MAXVARS - iVal, (int)pUserData);
102 
103  afValBuf[iVal] = 0;
104  if (iVal >= PARSER_MAXVARS - 1)
105  {
106  myprintf(_T("Variable buffer overflow."));
107  return NULL;
108  }
109 
110  return &afValBuf[iVal++];
111 }
112 
113 //---------------------------------------------------------------------------
114 void Intro(muParserHandle_t hParser)
115 {
116  myprintf(_T(" __________ \n"));
117  myprintf(_T(" _____ __ __\\______ \\_____ _______ ______ ____ _______\n"));
118  myprintf(_T(" / \\ | | \\| ___/\\__ \\ \\_ __ \\/ ___/_/ __ \\\\_ __ \\ \n"));
119  myprintf(_T(" | Y Y \\| | /| | / __ \\_| | \\/\\___ \\ \\ ___/ | | \\/ \n"));
120  myprintf(_T(" |__|_| /|____/ |____| (____ /|__| /____ > \\___ >|__| \n"));
121  myprintf(_T(" \\/ \\/ \\/ \\/ \n"));
122  myprintf(_T(" Version %s (DLL)\n"), mupGetVersion(hParser));
123 #ifdef _UNICODE
124  myprintf(_T(" Sample build with UNICODE support\n"));
125 #else
126  myprintf(_T(" Sample build with ASCII support\n"));
127 #endif
128  myprintf(_T(" (C) 2015 Ingo Berg\n"));
129  myprintf(_T("---------------------------------------\n"));
130  myprintf(_T("Commands:\n"));
131  myprintf(_T(" list var - list parser variables\n"));
132  myprintf(_T(" list exprvar - list expression variables\n"));
133  myprintf(_T(" list const - list all numeric parser constants\n"));
134  myprintf(_T(" locale de - switch to german locale\n"));
135  myprintf(_T(" locale en - switch to english locale\n"));
136  myprintf(_T(" locale reset - reset locale\n"));
137  myprintf(_T(" test bulk - test bulk mode\n"));
138  myprintf(_T(" quit - exits the parser\n\n"));
139  myprintf(_T("---------------------------------------\n"));
140  myprintf(_T("Constants:\n"));
141  myprintf(_T(" \"_e\" 2.718281828459045235360287\n"));
142  myprintf(_T(" \"_pi\" 3.141592653589793238462643\n"));
143  myprintf(_T("---------------------------------------\n"));
144  myprintf(_T("Please enter an expression:\n"));
145 }
146 
147 //---------------------------------------------------------------------------
148 // Callback function for parser errors
150 {
151  myprintf(_T("\nError:\n"));
152  myprintf(_T("------\n"));
153  myprintf(_T("Message: \"%s\"\n"), mupGetErrorMsg(hParser));
154  myprintf(_T("Token: \"%s\"\n"), mupGetErrorToken(hParser));
155  myprintf(_T("Position: %d\n"), mupGetErrorPos(hParser));
156  myprintf(_T("Errc: %d\n"), mupGetErrorCode(hParser));
157 }
158 
159 //---------------------------------------------------------------------------
160 void ListVar(muParserHandle_t a_hParser)
161 {
162  int iNumVar = mupGetVarNum(a_hParser);
163  int i = 0;
164 
165  if (iNumVar == 0)
166  {
167  myprintf(_T("No variables defined\n"));
168  return;
169  }
170 
171  myprintf(_T("\nExpression variables:\n"));
172  myprintf(_T("---------------------\n"));
173  myprintf(_T("Number: %d\n"), iNumVar);
174 
175  for (i = 0; i < iNumVar; ++i)
176  {
177  const muChar_t* szName = 0;
178  muFloat_t* pVar = 0;
179 
180  mupGetVar(a_hParser, i, &szName, &pVar);
181  myprintf(_T("Name: %s Address: [0x%x]\n"), szName, (int)pVar);
182  }
183 }
184 
185 //---------------------------------------------------------------------------
187 {
188  muInt_t iNumVar = mupGetExprVarNum(a_hParser),
189  i = 0;
190 
191  if (iNumVar == 0)
192  {
193  myprintf(_T("Expression dos not contain variables\n"));
194  return;
195  }
196 
197  myprintf(_T("\nExpression variables:\n"));
198  myprintf(_T("---------------------\n"));
199  myprintf(_T("Expression: %s\n"), mupGetExpr(a_hParser));
200  myprintf(_T("Number: %d\n"), iNumVar);
201 
202  for (i = 0; i < iNumVar; ++i)
203  {
204  const muChar_t* szName = 0;
205  muFloat_t* pVar = 0;
206 
207  mupGetExprVar(a_hParser, i, &szName, &pVar);
208  myprintf(_T("Name: %s Address: [0x%x]\n"), szName, (int)pVar);
209  }
210 }
211 
212 //---------------------------------------------------------------------------
214 {
215  muInt_t iNumVar = mupGetConstNum(a_hParser),
216  i = 0;
217 
218  if (iNumVar == 0)
219  {
220  myprintf(_T("No constants defined\n"));
221  return;
222  }
223 
224  myprintf(_T("\nParser constants:\n"));
225  myprintf(_T("---------------------\n"));
226  myprintf(_T("Number: %d"), iNumVar);
227 
228  for (i = 0; i < iNumVar; ++i)
229  {
230  const muChar_t* szName = 0;
231  muFloat_t fVal = 0;
232 
233  mupGetConst(a_hParser, i, &szName, &fVal);
234  myprintf(_T(" %s = %f\n"), szName, fVal);
235  }
236 }
237 
238 //---------------------------------------------------------------------------
241 int CheckKeywords(const muChar_t *a_szLine, muParserHandle_t a_hParser)
242 {
243  if (!mystrcmp(a_szLine, _T("quit")))
244  {
245  return -1;
246  }
247  else if (!mystrcmp(a_szLine, _T("list var")))
248  {
249  ListVar(a_hParser);
250  return 1;
251  }
252  else if (!mystrcmp(a_szLine, _T("list exprvar")))
253  {
254  ListExprVar(a_hParser);
255  return 1;
256  }
257  else if (!mystrcmp(a_szLine, _T("list const")))
258  {
259  ListConst(a_hParser);
260  return 1;
261  }
262  else if (!mystrcmp(a_szLine, _T("locale de")))
263  {
264  myprintf(_T("Setting german locale: ArgSep=';' DecSep=',' ThousandsSep='.'\n"));
265  mupSetArgSep(a_hParser, ';');
266  mupSetDecSep(a_hParser, ',');
267  mupSetThousandsSep(a_hParser, '.');
268  return 1;
269  }
270  else if (!mystrcmp(a_szLine, _T("locale en")))
271  {
272  myprintf(_T("Setting english locale: ArgSep=',' DecSep='.' ThousandsSep=''\n"));
273  mupSetArgSep(a_hParser, ',');
274  mupSetDecSep(a_hParser, '.');
275  mupSetThousandsSep(a_hParser, 0);
276  return 1;
277  }
278  else if (!mystrcmp(a_szLine, _T("locale reset")))
279  {
280  myprintf(_T("Resetting locale\n"));
281  mupResetLocale(a_hParser);
282  return 1;
283  }
284  else if (!mystrcmp(a_szLine, _T("test bulk")))
285  {
286  myprintf(_T("Testing bulk mode\n"));
287  CalcBulk();
288  return 1;
289  }
290 
291  return 0;
292 }
293 
294 //---------------------------------------------------------------------------
295 void CalcBulk()
296 {
297  int nBulkSize = 200, i;
298  muFloat_t *x = (muFloat_t*)malloc(nBulkSize * sizeof(muFloat_t));
299  muFloat_t *y = (muFloat_t*)malloc(nBulkSize * sizeof(muFloat_t));
300  muFloat_t *r = (muFloat_t*)malloc(nBulkSize * sizeof(muFloat_t));
301 
302  muParserHandle_t hParser = mupCreate(muBASETYPE_FLOAT); // initialize the parser
303 
304  for (i = 0; i < nBulkSize; ++i)
305  {
306  x[i] = i;
307  y[i] = i;
308  r[i] = 0;
309  }
310 
311  mupDefineVar(hParser, _T("x"), x);
312  mupDefineVar(hParser, _T("y"), y);
313  mupDefineBulkFun1(hParser, _T("bulktest"), BulkTest);
314  mupSetExpr(hParser, _T("bulktest(x+y)"));
315  mupEvalBulk(hParser, r, nBulkSize);
316  if (mupError(hParser))
317  {
318  myprintf(_T("\nError:\n"));
319  myprintf(_T("------\n"));
320  myprintf(_T("Message: %s\n"), mupGetErrorMsg(hParser));
321  myprintf(_T("Token: %s\n"), mupGetErrorToken(hParser));
322  myprintf(_T("Position: %d\n"), mupGetErrorPos(hParser));
323  myprintf(_T("Errc: %d\n"), mupGetErrorCode(hParser));
324  return;
325  }
326 
327  for (i = 0; i < nBulkSize; ++i)
328  {
329  myprintf(_T("%d: bulkfun(%2.2f + %2.2f) = %2.2f\n"), i, x[i], y[i], r[i]);
330  x[i] = i;
331  y[i] = (muFloat_t)i / 10;
332  }
333 
334  free(x);
335  free(y);
336  free(r);
337 }
338 
339 //---------------------------------------------------------------------------
340 void Calc()
341 {
342  muChar_t szLine[100];
343  muFloat_t fVal = 0,
344  afVarVal[] = { 1, 2 }; // Values of the parser variables
345  muParserHandle_t hParser;
346 
347  hParser = mupCreate(muBASETYPE_FLOAT); // initialize the parser
348  Intro(hParser);
349 
350  // Set an error handler [optional]
351  // the only function that does not take a parser instance handle
352  mupSetErrorHandler(hParser, OnError);
353 
354  //#define GERMAN_LOCALS
355 #ifdef GERMAN_LOCALS
356  mupSetArgSep(hParser, ';');
357  mupSetDecSep(hParser, ',');
358  mupSetThousandsSep(hParser, '.');
359 #else
360  mupSetArgSep(hParser, ',');
361  mupSetDecSep(hParser, '.');
362 #endif
363 
364  // Set a variable factory
365  mupSetVarFactory(hParser, AddVariable, NULL);
366 
367  // Define parser variables and bind them to C++ variables [optional]
368  mupDefineConst(hParser, _T("const1"), 1);
369  mupDefineConst(hParser, _T("const2"), 2);
370  mupDefineStrConst(hParser, _T("strBuf"), _T("Hallo welt"));
371 
372  // Define parser variables and bind them to C++ variables [optional]
373  mupDefineVar(hParser, _T("a"), &afVarVal[0]);
374  mupDefineVar(hParser, _T("b"), &afVarVal[1]);
375 
376  // Define postfix operators [optional]
377  mupDefinePostfixOprt(hParser, _T("M"), Mega, 0);
378  mupDefinePostfixOprt(hParser, _T("m"), Milli, 0);
379 
380  // Define infix operator [optional]
381  mupDefineInfixOprt(hParser, _T("!"), Not, 0);
382 
383  // Define functions [optional]
384  // mupDefineStrFun(hParser, "query", SampleQuery, 0); // Add an unoptimizeable function
385  mupDefineFun0(hParser, _T("zero"), ZeroArg, 0);
386  mupDefineFun1(hParser, _T("rnd"), Rnd, 0); // Add an unoptimizeable function
387  mupDefineFun1(hParser, _T("rnd2"), Rnd, 1);
388  mupDefineMultFun(hParser, _T("_sum"), Sum, 0); // "sum" is already a default function
389 
390  // Define binary operators [optional]
391  mupDefineOprt(hParser, _T("add"), Add, 0, muOPRT_ASCT_LEFT, 0);
392  mupDefineOprt(hParser, _T("mul"), Mul, 1, muOPRT_ASCT_LEFT, 0);
393 
394  while (myfgets(szLine, 99, stdin))
395  {
396  szLine[mystrlen(szLine) - 1] = 0; // overwrite the newline
397 
398  switch (CheckKeywords(szLine, hParser))
399  {
400  case 0: break; // no keyword found; parse the line
401  case 1: continue; // A Keyword was found do not parse the line
402  case -1: return; // abort the application
403  }
404 
405  mupSetExpr(hParser, szLine);
406 
407  fVal = mupEval(hParser);
408 
409 
410  // Without an Error handler function
411  // you must use this for error treatment:
412  //if (mupError(hParser))
413  //{
414  // printf("\nError:\n");
415  // printf("------\n");
416  // printf("Message: %s\n", mupGetErrorMsg(hParser) );
417  // printf("Token: %s\n", mupGetErrorToken(hParser) );
418  // printf("Position: %s\n", mupGetErrorPos(hParser) );
419  // printf("Errc: %d\n", mupGetErrorCode(hParser) );
420  // continue;
421  //}
422 
423  if (!mupError(hParser))
424  myprintf(_T("%f\n"), fVal);
425 
426  } // while
427 
428  // finally free the parser resources
429  mupRelease(hParser);
430 }
431 
432 //---------------------------------------------------------------------------
433 int main(int argc, char *argv[])
434 {
435  // The next line is just for shutting up the compiler warning
436  // about unused variables without getting another warning about not
437  // being able to use type lists in function declarations.
438  myprintf(_T("Executing \"%s\" (argc=%d)\n"), argv[0], argc);
439  Calc();
440  printf(_T("done..."));
441 }