Subversion Repositories Kolibri OS

Rev

Rev 7495 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2.  
  3. #include "func.h"
  4. #include "parser.h"
  5. //#include <math.h>
  6. //#include <stdlib.h>
  7. //#include <stdio.h>
  8.  
  9. // token types
  10. #define DELIMITER 1
  11. #define VARIABLE 2
  12. #define NUMBER 3
  13. #define FUNCTION 4
  14. #define FINISHED 10
  15.  
  16. //#define allocmem(x) malloc(x)
  17. //#define freemem(x) free(x)
  18.  
  19. double epsilon = 1e-6;
  20.  
  21. // structure for most parser functions
  22.  
  23.         char token[80];
  24.         int token_type;
  25.         char *prog;
  26.  
  27.         int code;    // error code
  28.  
  29.  
  30. variable_callback *find_var;
  31.  
  32. struct double_list  
  33. {
  34.         double val;
  35.         int code;                       // êîä îøèáêè
  36.         double_list *next;
  37. };
  38.  
  39. double tg(double d)
  40. {
  41.         double cosd = cos(d);
  42.         if (fabs(cosd) < epsilon)
  43.         {
  44.                 serror(ERR_OVERFLOW);
  45.                 return 0.0;
  46.         }
  47.         return sin(d) / cosd;
  48. }
  49.  
  50. double ctg(double d)
  51. {
  52.         double sind = sin(d);
  53.         if (fabs(sind) < epsilon)
  54.         {
  55.                 serror(ERR_OVERFLOW);
  56.                 return 0.0;
  57.         }
  58.         return cos(d) / sind;
  59. }
  60.  
  61. double exp(double x)
  62. {
  63.         __asm {
  64.                 fld     x
  65.                 FLDL2E
  66.                 FMUL
  67.  
  68.                 FLD st(0)
  69.  
  70.                 FLD1
  71.  
  72.                 FXCH
  73.                 FPREM
  74.                 F2XM1
  75.                 fadd
  76.                 FSCALE
  77.                 FSTP st(1)
  78.         }
  79.        
  80. }
  81.  
  82. double log(double x)
  83. {
  84.         //return 0.0;
  85.         if (x <= 0)
  86.         {
  87.                 serror(ERR_OVERFLOW);
  88.                 //return 0.0;
  89.                 __asm {
  90.                         fldz
  91.                 }
  92.         }
  93.         __asm {
  94.                 FLD1
  95.                 FLD     x
  96.                 FYL2X
  97.                 FLDLN2
  98.                 FMUL
  99.         }
  100. }
  101.  
  102. double sqrt(double x)
  103. {
  104.         if (x < 0)
  105.         {
  106.                 serror(ERR_BADPARAM);
  107.                 __asm {
  108.                         fldz
  109.                 }
  110.         }
  111.         __asm {
  112.                 fld x
  113.                 fsqrt
  114.         }
  115. }
  116.  
  117. double atan(double x)
  118. {
  119.         serror(ERR_GENERAL);
  120.         return 0.0; // â ëîì
  121. }
  122.  
  123. double pow(double x, double y)
  124. {
  125.         return exp(y * log(x)); //
  126. }
  127.  
  128. double func_pi()
  129. {
  130.         return 3.14159265358979;
  131. }
  132.  
  133. double func_eps()
  134. {
  135.         return epsilon;
  136. }
  137.  
  138. double func_if(double_list *p)
  139. {
  140.         double_list *a, *b, *c;
  141.         a = p;
  142.         b = a->next;
  143.         if (!b)
  144.         {
  145.                 serror(ERR_BADPARAM);
  146.                 return 0.0;
  147.         }
  148.         c = b->next;
  149.         if (!c || c->next)
  150.         {
  151.                 serror(ERR_BADPARAM);
  152.                 return 0.0;
  153.         }
  154.         if (a->val != 0.0)
  155.         {
  156.                 if (b->code)
  157.                         code = b->code;
  158.                 return b->val;
  159.         }
  160.         else
  161.         {
  162.                 if (c->code)
  163.                         code = c->code;
  164.                 return c->val;
  165.         }
  166. }
  167.  
  168. double sum(double_list *p)
  169. {
  170.         double res = 0.0;
  171.         while (p)
  172.         {
  173.                 res += p->val;
  174.                 if (p->code)
  175.                         code = p->code;
  176.                 p = p->next;
  177.         }
  178.         return res;
  179. }
  180.  
  181. double func_min(double_list *p)
  182. {
  183.         if (!p)
  184.                 serror(ERR_BADPARAM);
  185.         double res = p->val;
  186.         p = p->next;
  187.         while (p)
  188.         {
  189.                 if (p->code)
  190.                         code = p->code;
  191.                 if (p->val < res)
  192.                         res = p->val;
  193.                 p = p->next;
  194.         }
  195.         return res;
  196. }
  197.  
  198. double func_max(double_list *p)
  199. {
  200.         if (!p)
  201.                 serror(ERR_BADPARAM);
  202.         double res = p->val;
  203.         p = p->next;
  204.         while (p)
  205.         {
  206.                 if (p->code)
  207.                         code = p->code;
  208.                 if (p->val > res)
  209.                         res = p->val;
  210.                 p = p->next;
  211.         }
  212.         return res;
  213. }
  214.  
  215. double avg(double_list *p)
  216. {
  217.         double res = 0.0;
  218.         int count = 0;
  219.         while (p)
  220.         {
  221.                 if (p->code)
  222.                         code = p->code;
  223.                 res += p->val;
  224.                 count++;
  225.                 p = p->next;
  226.         }
  227.         return res / count;
  228. }
  229.  
  230. double func_isnull(char *str)
  231. {
  232.         if (code != 0)
  233.                 return 0.0;
  234.         double tmp = find_var(str);
  235.         int c = code;
  236.         code = 0;
  237.         if (c != 0)
  238.                 return 1.0;
  239.         return 0.0;
  240. }
  241.  
  242. const double HALF = 0.5;
  243. double func_ceil(double val)    // õîòåë round, à ïîëó÷èëñÿ ceil...
  244. {
  245.         int x;
  246.         __asm fld val
  247.         __asm fld HALF                          // äà, êðèâîðóêî ^_^
  248.         __asm fadd
  249.         __asm fistp x
  250.         __asm fild x
  251. }
  252.  
  253. double func_round(double val)
  254. {
  255.         int x;
  256.         __asm fld val
  257.         __asm fld epsilon
  258.         __asm fadd
  259.         __asm fistp x
  260.         __asm fild x
  261. }
  262.  
  263. //const double ALMOST_HALF = 0.5 - epsilon;
  264. double ALMOST_HALF;
  265. extern void ALMOST_HALF_init(void)
  266. { ALMOST_HALF = 0.5 - epsilon; }
  267. double func_floor(double val)
  268. {
  269.         int x;
  270.         __asm fld val
  271.         __asm fld ALMOST_HALF
  272.         __asm fsub
  273.         __asm fistp x
  274.         __asm fild x
  275. }
  276.  
  277. double logic_xor(double a, double b)
  278. {
  279.         if (a == 0.0)
  280.                 if (b == 0.0)
  281.                         return 0.0;
  282.                 else
  283.                         return 1.0;
  284.         else
  285.                 if (b == 0.0)
  286.                         return 1.0;
  287.                 else
  288.                         return 0.0;
  289. }
  290.  
  291. double logic_and(double a, double b)
  292. {
  293.         if (a == 0.0)
  294.                 return 0.0;
  295.         else
  296.                 if (b == 0.0)
  297.                         return 0.0;
  298.                 else
  299.                         return 1.0;
  300. }
  301.  
  302. double logic_or(double a, double b)
  303. {
  304.         if (a == 0.0)
  305.                 if (b == 0.0)
  306.                         return 0.0;
  307.                 else
  308.                         return 1.1;
  309.         else
  310.                 return 1.0;
  311. }
  312.  
  313. double rand_seed;
  314. double func_rand(double max)
  315. {
  316.         double q = (257.0 * rand_seed + 739.0); // ÷èñëà îò áàëäû. íàäî âñòàâèòü ïðàâèëüíûå.
  317.         rand_seed = q - 65536.0 * func_floor(q / 65536.0); // äëÿ õîðîøåãî ðàñïðåäåëåíèÿ
  318.         return q - max * func_floor(q / max);    // äëÿ ìîäóëÿ
  319. }
  320.  
  321. /*
  322. double func_case(double_list *p)
  323. {
  324.         if (!p || !p->next)
  325.         {
  326.                 serror(ERR_BADPARAM);
  327.                 return 0.0;
  328.         }
  329.         double x = p->val;
  330.         int count = (int)p->next->val;
  331.         int i, k;
  332.  
  333.         double_list *cur = p->next->next;
  334.         k = count;
  335.         for (i = 0; i < count; i++)
  336.         {
  337.                 if (!cur)
  338.                 {
  339.                         serror(ERR_BADPARAM);
  340.                         return 0.0;
  341.                 }
  342.                 if (fabs(x - cur->val) < epsilon)
  343.                 {
  344.                         if (k != count + 1)
  345.                         {
  346.                                 serror(ERR_GENERAL);
  347.                                 return 0.0;
  348.                         }
  349.                         k = i;
  350.                 }
  351.                 cur = cur->next;
  352.         }
  353.  
  354.         for (i = 0; i < k; i++)
  355.         {
  356.                 if (!cur)
  357.                 {
  358.                         serror(ERR_BADPARAM);
  359.                         return 0.0;
  360.                 }
  361.                 cur = cur->next;
  362.         }
  363.         if (!cur)                                       // ïðîâåðêè áèï. äîñòàëè áèï.
  364.         {
  365.                 serror(ERR_BADPARAM);
  366.                 return 0.0;
  367.         }
  368.         if (cur->code)
  369.                 code = cur->code;
  370.         return cur->val;
  371. }
  372. */
  373.  
  374. #define INF_ARGS -1
  375. #define STR_ARG -2
  376.  
  377. // represents general mathematical function
  378. typedef double(*matfunc0)();
  379. typedef double(*matfunc)(double);
  380. typedef double(*matfunc2)(double,double);
  381. typedef double(*matfunc3)(double,double,double);
  382. typedef double(*matfunc_inf)(double_list*);
  383. typedef double(*matfunc_str)(char*);
  384.  
  385. // used to link function name to the function
  386. typedef struct  
  387. {
  388.         char name[10];
  389.         int args;
  390.         void * f;
  391. } func;
  392.  
  393. // the list of functions
  394. const int max_func = 28;
  395. func functions[max_func] =
  396. {
  397.         "", 1, NULL,                                                            // íå ïîìíþ, ñ êàêîé öåëüþ
  398.         "sin", 1, &sin,
  399.         "cos", 1, &cos,
  400.         "exp", 1, &exp,
  401.         "sqrt", 1, &sqrt,
  402.         "log", 1, &log,
  403.         "tg", 1, &tg,
  404.         "ctg", 1, &ctg,
  405.         "arcsin", 1, &asin,
  406.         "arccos", 1, &acos,
  407.         "arctg", 1, &atan,                                                      // íå ðåàëèçîâàíî. âîçâðàùàåò îøèáêó ERR_GENERAL
  408.         "abs", 1, &fabs,
  409.         "pow", 2, &pow,
  410.         "if", INF_ARGS, &func_if,
  411.         "sum",INF_ARGS,&sum,
  412.         "isnull",STR_ARG,&func_isnull,                          // ñëåãêà ÷/æ
  413.         "min",INF_ARGS,&func_min,
  414.         "max",INF_ARGS,&func_max,
  415.         "avg",INF_ARGS,&avg,
  416.         "ceil",1,&func_ceil,
  417.         "round",1,&func_round,
  418.         "floor",1,&func_floor,
  419.         "and",2,&logic_and,
  420.         "or",2,&logic_or,
  421.         "xor",2,&logic_xor,
  422.         "rand",1,&func_rand,
  423.         //"case",INF_ARGS,&func_case,
  424.         "pi",0,&func_pi,
  425.         "eps",0,&func_eps
  426. };
  427.  
  428. // all delimiters
  429. #define MAXDELIM 17
  430. const char delim[MAXDELIM]="+-*^/%=;(),><#! ";          // not bad words
  431.  
  432.  
  433. int isdelim(char c)
  434. {
  435.         //return strchr(delim, c) != 0;
  436.         for (int i = 0; i < MAXDELIM; i++)
  437.                 if (c == delim[i])
  438.                         return 1;
  439.         return 0;
  440. }
  441.  
  442. int isdigit(char c)
  443. {
  444.         return (c >= '0' && c <= '9');
  445. }
  446.  
  447. int isalpha2(char c)
  448. {
  449.         return ((c >= 'a' && c <= 'z')
  450.                 || (c >= 'A' && c <= 'Z') || (c=='$'));
  451. }
  452.  
  453. int iswhite(char c)
  454. {
  455.         return (c==' ' || c=='\t');
  456. }
  457.  
  458.  
  459. void serror(int acode)
  460. {
  461.         if (acode != 0)
  462.                 code = acode;
  463. }
  464.  
  465. void set_exp(char *exp)
  466. {
  467.         prog = exp;
  468. }
  469.  
  470. int get_token()
  471. {
  472.         int tok;
  473.         char *temp;
  474.         (token_type) = 0;
  475.         tok = 0;
  476.         temp = (token);
  477.  
  478.         if (*(prog) == '\0')
  479.         {
  480.                 *(token) = 0;
  481.                 tok = FINISHED;
  482.                 return ((token_type) = DELIMITER);
  483.         }
  484.         while (iswhite(*(prog))) ++(prog);
  485.         if (isdelim(*(prog)))
  486.         {
  487.                 char t=*temp = *(prog);
  488.                 (prog)++;
  489.                 temp++;
  490.                 if ((t == '>' || t == '<' || t == '!') && (*prog) && (*prog == '='))
  491.                 {
  492.                         *temp = *(prog);
  493.                         (prog)++;
  494.                         temp++;
  495.                 }
  496.                 *temp = 0;
  497.                 return ((token_type) = DELIMITER);
  498.         }
  499.         if (isdigit(*(prog)))
  500.         {
  501.                 while (!isdelim(*(prog)))
  502.                         *temp++=*(prog)++;
  503.                 *temp = '\0';
  504.                 return ((token_type) = NUMBER);
  505.         }
  506.         if (isalpha2(*(prog)))
  507.         {
  508.                 while (!isdelim(*(prog)))
  509.                         *temp++=*(prog)++;
  510.                 (token_type) = VARIABLE;
  511.         }
  512.         *temp = '\0';
  513.         if ((token_type) == VARIABLE)
  514.         {
  515.                 tok = look_up((token));
  516.                 if (tok)
  517.                         (token_type) = FUNCTION;
  518.         }
  519.         return (token_type);
  520. }
  521.  
  522. double sign(double d)
  523. {
  524.   if (d > 0.0)
  525.     return 1.0;
  526.   if (d < 0.0)
  527.     return -1.0;
  528.   return 0.0;
  529. }
  530.  
  531. void putback()
  532. {
  533.         char *t;
  534.         t = (token);
  535.         for (;*t;t++)
  536.                 (prog)--;
  537. }
  538.  
  539. int get_exp(double *hold)
  540. {
  541.         code = 0;
  542.  
  543.         get_token();
  544.         if (!*(token))
  545.         {
  546.                 return 0;
  547.         }
  548.         level1( hold);
  549.         putback();
  550.   return code==0;
  551. }
  552.  
  553. void level1(double *hold)
  554. {
  555.         char op[2];
  556.         double h;
  557.  
  558.         level1_5( hold);
  559.         while (op[0] = *token, op[1] = (*(token+1)) ? *(token + 1) : 0,
  560.                 *op == '<' || *op == '>' || *op == '=' || *op == '#' || *op == '!')
  561.         {
  562.                 get_token();
  563.                 level1_5( &h);
  564.                 logic(op, hold, &h);
  565.         }
  566. }
  567.  
  568. void level1_5(double *hold)
  569. {
  570.         char op;
  571.  
  572.         op = 0;
  573.         if (((token_type) == DELIMITER) && *(token) == '!')
  574.         {
  575.                 op = *(token);
  576.                 get_token();
  577.         }
  578.         level2( hold);
  579.  
  580.         if (op)
  581.         {
  582.                 if (*hold == 0.0)
  583.                         *hold = 1.0;
  584.                 else
  585.                         *hold = 0.0;
  586.         }
  587. }
  588.  
  589. void level2(double *hold)
  590. {
  591.         char op;
  592.         double h;
  593.  
  594.         level3( hold);
  595.         while ((op=*(token)) == '+' || op == '-')
  596.         {
  597.                 get_token();
  598.                 level3( &h);
  599.                 arith(op, hold, &h);
  600.         }
  601. }
  602.  
  603. void level3(double *hold)
  604. {
  605.         char op;
  606.         double h;
  607.  
  608.         level4( hold);
  609.         while ((op=*(token)) == '*' || op == '/' || op == '%')
  610.         {
  611.                 get_token();
  612.                 level4( &h);
  613.                 arith( op, hold, &h);
  614.         }
  615. }
  616.  
  617. void level4(double *hold)
  618. {
  619.         double h;
  620.         level5( hold);
  621.  
  622.         if (*(token) == '^')
  623.         {
  624.                 get_token();
  625.                 level5( &h);
  626.                 arith( '^', hold, &h);
  627.         }
  628. }
  629.  
  630. void level5(double *hold)
  631. {
  632.         char op;
  633.  
  634.         op = 0;
  635.         if (((token_type) == DELIMITER) && *(token) == '+' || *(token) == '-')
  636.         {
  637.                 op = *(token);
  638.                 get_token();
  639.         }
  640.         level6( hold);
  641.  
  642.         if (op)
  643.                 unary(op, hold);
  644. }
  645.  
  646. void level6(double *hold)
  647. {
  648.         if ((*(token) == '(') && ((token_type) == DELIMITER))
  649.         {
  650.                 get_token();
  651.                 level1( hold);
  652.                 if (*(token) != ')')
  653.                           serror( ERR_NOBRACKET);
  654.                 get_token();
  655.         }
  656.         else
  657.                 primitive( hold);
  658. }
  659.  
  660. void calc_function(double *hold)
  661. {
  662.   double_list *args = NULL, *last = NULL, *t;          
  663.   double d;
  664.         int i,argc=0,save_code;
  665.  
  666.         save_code = code;
  667.         code = 0;
  668.         i = look_up(token);
  669.  
  670.         if (i == 0)
  671.                 serror(ERR_BADFUNCTION);        // error
  672.  
  673.         get_token();
  674.         if (*(token) != '(')
  675.                 serror(ERR_NOBRACKET);  // error
  676.         //get_token();
  677.         if (functions[i].args == STR_ARG)
  678.         {
  679.                 get_token();
  680.                 d = ((matfunc_str)(functions[i].f))(token);
  681.                 *hold = d;
  682.                 get_token();
  683.                 if (save_code)
  684.                         code = save_code;
  685.                 return;
  686.         }
  687.  
  688.         //last = args = (double_list*)malloc(sizeof(double_list));
  689.         //args->next = NULL;
  690.         //level1(&args->val);
  691.         //get_token();
  692.         argc=0;
  693.         do
  694.         {
  695.                 get_token();
  696.                 if (*token == ')')
  697.                         break;
  698.                 t = (double_list*)allocmem(sizeof(double_list));
  699.                 code = 0;
  700.                 level1(&t->val);
  701.                 t->code = code;
  702.                 t->next = NULL;
  703.                 if (last)
  704.                         last->next = t;
  705.                 else
  706.                         args = t;
  707.                 last = t;
  708.                 argc++;
  709.         } while (*token == ',');
  710.  
  711.         code = save_code;
  712.  
  713.         if (argc != functions[i].args && functions[i].args >= 0)
  714.         {
  715.                 serror(ERR_BADPARAM);
  716.         }
  717.         else
  718.         {
  719.                 switch (functions[i].args)
  720.                 {
  721.                         case 0:
  722.                                 d = ((matfunc0)(functions[i].f))();
  723.                                 break;
  724.                         case 1:
  725.                                 d = ((matfunc)(functions[i].f))(args->val);
  726.                                 break;                 
  727.                         case 2:
  728.                                 d = ((matfunc2)(functions[i].f))(args->val,args->next->val);
  729.                                 break;                 
  730.                         case 3:
  731.                                 d = ((matfunc3)(functions[i].f))(args->val,args->next->val,args->next->next->val);
  732.                                 break;         
  733.                         case INF_ARGS:
  734.                                 d = ((matfunc_inf)(functions[i].f))(args);
  735.                                 break;
  736.                 }
  737.         }
  738.  
  739.         t = args;
  740.         while (t)
  741.         {
  742.                 args = t->next;
  743.                 freemem(t);
  744.                 t = args;
  745.         }
  746.        
  747.   *hold = d;
  748. //  else
  749. //    serror( ERR_OVERFLOW);
  750.  
  751. }
  752.  
  753. void primitive(double *hold)
  754. {
  755.         switch (token_type)
  756.         {
  757.         case VARIABLE:
  758.                 *hold = find_var(token);
  759.                 get_token();
  760.                 return;
  761.         case NUMBER:
  762.     //
  763.                 *hold = atof((token));
  764.     //if (sscanf(token, "%lf", hold) != 1)
  765.         *hold = convert(token);
  766.         if (convert_error == ERROR)
  767.       serror( ERR_BADNUMER);
  768.                 get_token();
  769.                 return;
  770.         case FUNCTION:
  771.                 calc_function( hold);
  772.                 if (*token != ')')
  773.                         serror(ERR_NOBRACKET);
  774.                 get_token();
  775.                 return;
  776.         default:        // error
  777.                 return;
  778.         }
  779. }
  780.  
  781. void arith(char op, double *r, double *h)
  782. {
  783.         double t;
  784.         switch(op)
  785.         {
  786.         case '-':
  787.                 *r = *r - *h;
  788.                 break;
  789.         case '+':
  790.                 *r = *r + *h;
  791.                 break;
  792.         case '*':
  793.                 *r = *r * *h;
  794.                 break;
  795.         case '/':
  796.             if (fabs(*h) < epsilon)
  797.                         serror( ERR_OVERFLOW);
  798.                 else
  799.                   *r = (*r) / (*h);
  800.                 break;
  801.         case '%':
  802.             if (fabs(*h) < epsilon)
  803.                         serror( ERR_OVERFLOW);
  804.                 else
  805.                 {
  806.                         t = func_floor ((*r) / (*h));
  807.                         *r = *r - (t * (*h));
  808.                 }
  809.                 break;
  810.         case '^':
  811.                 *r = pow(*r, *h);
  812.                 break;
  813.         }
  814. }
  815.  
  816. void logic(char *op, double *r, double *h)
  817. {
  818.         double t;
  819.         switch (*op)
  820.         {
  821.         case '<':
  822.                 if (*(op+1) && *(op+1) == '=')
  823.                         t = *r <= *h + epsilon ? 1.0 : 0.0;
  824.                 else                           
  825.                         t = *r < *h - epsilon? 1.0 : 0.0;      
  826.                 break;
  827.         case '>':
  828.                 if (*(op+1) && *(op+1) == '=')
  829.                         t = *r >= *h - epsilon ? 1.0 : 0.0;
  830.                 else                           
  831.                         t = *r > *h + epsilon ? 1.0 : 0.0;
  832.                 break;
  833.         case '=':
  834.                 t = fabs(*r - *h) <= epsilon ? 1.0 : 0.0;
  835.                 break;
  836.         case '#':
  837.                 t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
  838.                 break;
  839.         case '!':
  840.                 if (*(op+1) && *(op+1) == '=')
  841.                         t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
  842.                 else
  843.                         serror(ERR_GENERAL);
  844.                 break;
  845.         }
  846.         *r = t;
  847. }
  848.  
  849.  
  850. void unary(char op, double *r)
  851. {
  852.         if (op == '-')
  853.                 *r = -(*r);
  854. }
  855.  
  856. bool strcmp(char *s1, char *s2)
  857. {
  858.         int i;
  859.  
  860.         if (s1 == NULL)
  861.                 if (s2 == NULL)
  862.                         return 0;
  863.                 else
  864.                         return 1;
  865.         else
  866.                 if (s2 == NULL)
  867.                         return 1;
  868.  
  869.         for (i = 0;;i++)
  870.         {
  871.                 if (s1[i] == '\0')
  872.                         if (s2[i] == '\0')
  873.                                 return 0;
  874.                         else
  875.                                 return 1;
  876.                 else
  877.                         if (s2[i] == '\0')
  878.                                 return 1;
  879.                         else
  880.                         {
  881.                                 if (s1[i] != s2[i])
  882.                                         return 1;
  883.                         }
  884.         }
  885.         return 0;
  886. }
  887.  
  888.  
  889. bool strncmp(char *s1, char *s2, int n)
  890. {
  891.         int i;
  892.  
  893.         if (s1 == NULL)
  894.                 if (s2 == NULL)
  895.                         return 0;
  896.                 else
  897.                         return 1;
  898.         else
  899.                 if (s2 == NULL)
  900.                         return 1;
  901.  
  902.         for (i = 0;i<n;i++)
  903.         {
  904.                 if (s1[i] == '\0')
  905.                         if (s2[i] == '\0')
  906.                                 return 0;
  907.                         else
  908.                                 return 1;
  909.                 else
  910.                         if (s2[i] == '\0')
  911.                                 return 1;
  912.                         else
  913.                         {
  914.                                 if (s1[i] != s2[i])
  915.                                         return 1;
  916.                         }
  917.         }
  918.         return 0;
  919. }
  920.  
  921. int look_up(char *s)
  922. {
  923.         int i;
  924.  
  925.         for (i = 0; i < max_func; i++)
  926.                 if (strcmp(s, functions[i].name) == 0)
  927.                         return i;
  928.         return 0;       // search command/function name
  929. }
  930.  
  931. unsigned int chrnum(char* text, char symbol)
  932. {
  933.         int num = 0;
  934.         int i = 0;
  935.         while(text[i])
  936.         {
  937.                 if (text[i] == symbol) num++;
  938.                 i++;
  939.         }
  940.         return num;
  941. }
  942.  
  943.