Subversion Repositories Kolibri OS

Rev

Rev 990 | Rev 7495 | Go to most recent revision | 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. double func_case(double_list *p)
  322. {
  323.         if (!p || !p->next)
  324.         {
  325.                 serror(ERR_BADPARAM);
  326.                 return 0.0;
  327.         }
  328.         double x = p->val;
  329.         int count = (int)p->next->val;
  330.         int i, k;
  331.  
  332.         double_list *cur = p->next->next;
  333.         k = count;
  334.         for (i = 0; i < count; i++)
  335.         {
  336.                 if (!cur)
  337.                 {
  338.                         serror(ERR_BADPARAM);
  339.                         return 0.0;
  340.                 }
  341.                 if (fabs(x - cur->val) < epsilon)
  342.                 {
  343.                         if (k != count + 1)
  344.                         {
  345.                                 serror(ERR_GENERAL);
  346.                                 return 0.0;
  347.                         }
  348.                         k = i;
  349.                 }
  350.                 cur = cur->next;
  351.         }
  352.  
  353.         for (i = 0; i < k; i++)
  354.         {
  355.                 if (!cur)
  356.                 {
  357.                         serror(ERR_BADPARAM);
  358.                         return 0.0;
  359.                 }
  360.                 cur = cur->next;
  361.         }
  362.         if (!cur)                                       // ïðîâåðêè áèï. äîñòàëè áèï.
  363.         {
  364.                 serror(ERR_BADPARAM);
  365.                 return 0.0;
  366.         }
  367.         if (cur->code)
  368.                 code = cur->code;
  369.         return cur->val;
  370. }
  371.  
  372. #define INF_ARGS -1
  373. #define STR_ARG -2
  374.  
  375. // represents general mathematical function
  376. typedef double(*matfunc0)();
  377. typedef double(*matfunc)(double);
  378. typedef double(*matfunc2)(double,double);
  379. typedef double(*matfunc3)(double,double,double);
  380. typedef double(*matfunc_inf)(double_list*);
  381. typedef double(*matfunc_str)(char*);
  382.  
  383. // used to link function name to the function
  384. typedef struct  
  385. {
  386.         char name[10];
  387.         int args;
  388.         void * f;
  389. } func;
  390.  
  391. // the list of functions
  392. const int max_func = 29;
  393. func functions[max_func] =
  394. {
  395.         "", 1, NULL,                                                            // íå ïîìíþ, ñ êàêîé öåëüþ
  396.         "sin", 1, &sin,
  397.         "cos", 1, &cos,
  398.         "exp", 1, &exp,
  399.         "sqrt", 1, &sqrt,
  400.         "log", 1, &log,
  401.         "tg", 1, &tg,
  402.         "ctg", 1, &ctg,
  403.         "arcsin", 1, &asin,
  404.         "arccos", 1, &acos,
  405.         "arctg", 1, &atan,                                                      // íå ðåàëèçîâàíî. âîçâðàùàåò îøèáêó ERR_GENERAL
  406.         "abs", 1, &fabs,
  407.         "pow", 2, &pow,
  408.         "if", INF_ARGS, &func_if,
  409.         "sum",INF_ARGS,&sum,
  410.         "isnull",STR_ARG,&func_isnull,                          // ñëåãêà ÷/æ
  411.         "min",INF_ARGS,&func_min,
  412.         "max",INF_ARGS,&func_max,
  413.         "avg",INF_ARGS,&avg,
  414.         "ceil",1,&func_ceil,
  415.         "round",1,&func_round,
  416.         "floor",1,&func_floor,
  417.         "and",2,&logic_and,
  418.         "or",2,&logic_or,
  419.         "xor",2,&logic_xor,
  420.         "rand",1,&func_rand,
  421.         "case",INF_ARGS,&func_case,
  422.         "pi",0,&func_pi,
  423.         "eps",0,&func_eps
  424. };
  425.  
  426. // all delimiters
  427. #define MAXDELIM 17
  428. const char delim[MAXDELIM]="+-*^/%=;(),><#! ";          // not bad words
  429.  
  430.  
  431. int isdelim(char c)
  432. {
  433.         //return strchr(delim, c) != 0;
  434.         for (int i = 0; i < MAXDELIM; i++)
  435.                 if (c == delim[i])
  436.                         return 1;
  437.         return 0;
  438. }
  439.  
  440. int isdigit(char c)
  441. {
  442.         return (c >= '0' && c <= '9');
  443. }
  444.  
  445. int isalpha2(char c)
  446. {
  447.         return ((c >= 'a' && c <= 'z')
  448.                 || (c >= 'A' && c <= 'Z') || (c=='$'));
  449. }
  450.  
  451. int iswhite(char c)
  452. {
  453.         return (c==' ' || c=='\t');
  454. }
  455.  
  456.  
  457. void serror(int acode)
  458. {
  459.         if (acode != 0)
  460.                 code = acode;
  461. }
  462.  
  463. void set_exp(char *exp)
  464. {
  465.         prog = exp;
  466. }
  467.  
  468. int get_token()
  469. {
  470.         int tok;
  471.         char *temp;
  472.         (token_type) = 0;
  473.         tok = 0;
  474.         temp = (token);
  475.  
  476.         if (*(prog) == '\0')
  477.         {
  478.                 *(token) = 0;
  479.                 tok = FINISHED;
  480.                 return ((token_type) = DELIMITER);
  481.         }
  482.         while (iswhite(*(prog))) ++(prog);
  483.         if (isdelim(*(prog)))
  484.         {
  485.                 char t=*temp = *(prog);
  486.                 (prog)++;
  487.                 temp++;
  488.                 if ((t == '>' || t == '<' || t == '!') && (*prog) && (*prog == '='))
  489.                 {
  490.                         *temp = *(prog);
  491.                         (prog)++;
  492.                         temp++;
  493.                 }
  494.                 *temp = 0;
  495.                 return ((token_type) = DELIMITER);
  496.         }
  497.         if (isdigit(*(prog)))
  498.         {
  499.                 while (!isdelim(*(prog)))
  500.                         *temp++=*(prog)++;
  501.                 *temp = '\0';
  502.                 return ((token_type) = NUMBER);
  503.         }
  504.         if (isalpha2(*(prog)))
  505.         {
  506.                 while (!isdelim(*(prog)))
  507.                         *temp++=*(prog)++;
  508.                 (token_type) = VARIABLE;
  509.         }
  510.         *temp = '\0';
  511.         if ((token_type) == VARIABLE)
  512.         {
  513.                 tok = look_up((token));
  514.                 if (tok)
  515.                         (token_type) = FUNCTION;
  516.         }
  517.         return (token_type);
  518. }
  519.  
  520. double sign(double d)
  521. {
  522.   if (d > 0.0)
  523.     return 1.0;
  524.   if (d < 0.0)
  525.     return -1.0;
  526.   return 0.0;
  527. }
  528.  
  529. void putback()
  530. {
  531.         char *t;
  532.         t = (token);
  533.         for (;*t;t++)
  534.                 (prog)--;
  535. }
  536.  
  537. int get_exp(double *hold)
  538. {
  539.         code = 0;
  540.  
  541.         get_token();
  542.         if (!*(token))
  543.         {
  544.                 return 0;
  545.         }
  546.         level1( hold);
  547.         putback();
  548.   return code==0;
  549. }
  550.  
  551. void level1(double *hold)
  552. {
  553.         char op[2];
  554.         double h;
  555.  
  556.         level1_5( hold);
  557.         while (op[0] = *token, op[1] = (*(token+1)) ? *(token + 1) : 0,
  558.                 *op == '<' || *op == '>' || *op == '=' || *op == '#' || *op == '!')
  559.         {
  560.                 get_token();
  561.                 level1_5( &h);
  562.                 logic(op, hold, &h);
  563.         }
  564. }
  565.  
  566. void level1_5(double *hold)
  567. {
  568.         char op;
  569.  
  570.         op = 0;
  571.         if (((token_type) == DELIMITER) && *(token) == '!')
  572.         {
  573.                 op = *(token);
  574.                 get_token();
  575.         }
  576.         level2( hold);
  577.  
  578.         if (op)
  579.         {
  580.                 if (*hold == 0.0)
  581.                         *hold = 1.0;
  582.                 else
  583.                         *hold = 0.0;
  584.         }
  585. }
  586.  
  587. void level2(double *hold)
  588. {
  589.         char op;
  590.         double h;
  591.  
  592.         level3( hold);
  593.         while ((op=*(token)) == '+' || op == '-')
  594.         {
  595.                 get_token();
  596.                 level3( &h);
  597.                 arith(op, hold, &h);
  598.         }
  599. }
  600.  
  601. void level3(double *hold)
  602. {
  603.         char op;
  604.         double h;
  605.  
  606.         level4( hold);
  607.         while ((op=*(token)) == '*' || op == '/' || op == '%')
  608.         {
  609.                 get_token();
  610.                 level4( &h);
  611.                 arith( op, hold, &h);
  612.         }
  613. }
  614.  
  615. void level4(double *hold)
  616. {
  617.         double h;
  618.         level5( hold);
  619.  
  620.         if (*(token) == '^')
  621.         {
  622.                 get_token();
  623.                 level5( &h);
  624.                 arith( '^', hold, &h);
  625.         }
  626. }
  627.  
  628. void level5(double *hold)
  629. {
  630.         char op;
  631.  
  632.         op = 0;
  633.         if (((token_type) == DELIMITER) && *(token) == '+' || *(token) == '-')
  634.         {
  635.                 op = *(token);
  636.                 get_token();
  637.         }
  638.         level6( hold);
  639.  
  640.         if (op)
  641.                 unary(op, hold);
  642. }
  643.  
  644. void level6(double *hold)
  645. {
  646.         if ((*(token) == '(') && ((token_type) == DELIMITER))
  647.         {
  648.                 get_token();
  649.                 level1( hold);
  650.                 if (*(token) != ')')
  651.                           serror( ERR_NOBRACKET);
  652.                 get_token();
  653.         }
  654.         else
  655.                 primitive( hold);
  656. }
  657.  
  658. void calc_function(double *hold)
  659. {
  660.   double_list *args = NULL, *last = NULL, *t;          
  661.   double d;
  662.         int i,argc=0,save_code;
  663.  
  664.         save_code = code;
  665.         code = 0;
  666.         i = look_up(token);
  667.  
  668.         if (i == 0)
  669.                 serror(ERR_BADFUNCTION);        // error
  670.  
  671.         get_token();
  672.         if (*(token) != '(')
  673.                 serror(ERR_NOBRACKET);  // error
  674.         //get_token();
  675.         if (functions[i].args == STR_ARG)
  676.         {
  677.                 get_token();
  678.                 d = ((matfunc_str)(functions[i].f))(token);
  679.                 *hold = d;
  680.                 get_token();
  681.                 if (save_code)
  682.                         code = save_code;
  683.                 return;
  684.         }
  685.  
  686.         //last = args = (double_list*)malloc(sizeof(double_list));
  687.         //args->next = NULL;
  688.         //level1(&args->val);
  689.         //get_token();
  690.         argc=0;
  691.         do
  692.         {
  693.                 get_token();
  694.                 if (*token == ')')
  695.                         break;
  696.                 t = (double_list*)allocmem(sizeof(double_list));
  697.                 code = 0;
  698.                 level1(&t->val);
  699.                 t->code = code;
  700.                 t->next = NULL;
  701.                 if (last)
  702.                         last->next = t;
  703.                 else
  704.                         args = t;
  705.                 last = t;
  706.                 argc++;
  707.         } while (*token == ',');
  708.  
  709.         code = save_code;
  710.  
  711.         if (argc != functions[i].args && functions[i].args >= 0)
  712.         {
  713.                 serror(ERR_BADPARAM);
  714.         }
  715.         else
  716.         {
  717.                 switch (functions[i].args)
  718.                 {
  719.                         case 0:
  720.                                 d = ((matfunc0)(functions[i].f))();
  721.                                 break;
  722.                         case 1:
  723.                                 d = ((matfunc)(functions[i].f))(args->val);
  724.                                 break;                 
  725.                         case 2:
  726.                                 d = ((matfunc2)(functions[i].f))(args->val,args->next->val);
  727.                                 break;                 
  728.                         case 3:
  729.                                 d = ((matfunc3)(functions[i].f))(args->val,args->next->val,args->next->next->val);
  730.                                 break;         
  731.                         case INF_ARGS:
  732.                                 d = ((matfunc_inf)(functions[i].f))(args);
  733.                                 break;
  734.                 }
  735.         }
  736.  
  737.         t = args;
  738.         while (t)
  739.         {
  740.                 args = t->next;
  741.                 freemem(t);
  742.                 t = args;
  743.         }
  744.        
  745.   *hold = d;
  746. //  else
  747. //    serror( ERR_OVERFLOW);
  748.  
  749. }
  750.  
  751. void primitive(double *hold)
  752. {
  753.         switch (token_type)
  754.         {
  755.         case VARIABLE:
  756.                 *hold = find_var(token);
  757.                 get_token();
  758.                 return;
  759.         case NUMBER:
  760.     //
  761.                 *hold = atof((token));
  762.     //if (sscanf(token, "%lf", hold) != 1)
  763.         *hold = convert(token);
  764.         if (convert_error == ERROR)
  765.       serror( ERR_BADNUMER);
  766.                 get_token();
  767.                 return;
  768.         case FUNCTION:
  769.                 calc_function( hold);
  770.                 if (*token != ')')
  771.                         serror(ERR_NOBRACKET);
  772.                 get_token();
  773.                 return;
  774.         default:        // error
  775.                 return;
  776.         }
  777. }
  778.  
  779. void arith(char op, double *r, double *h)
  780. {
  781.         double t;
  782.         switch(op)
  783.         {
  784.         case '-':
  785.                 *r = *r - *h;
  786.                 break;
  787.         case '+':
  788.                 *r = *r + *h;
  789.                 break;
  790.         case '*':
  791.                 *r = *r * *h;
  792.                 break;
  793.         case '/':
  794.             if (fabs(*h) < epsilon)
  795.                         serror( ERR_OVERFLOW);
  796.                 else
  797.                   *r = (*r) / (*h);
  798.                 break;
  799.         case '%':
  800.             if (fabs(*h) < epsilon)
  801.                         serror( ERR_OVERFLOW);
  802.                 else
  803.                 {
  804.                         t = func_floor ((*r) / (*h));
  805.                         *r = *r - (t * (*h));
  806.                 }
  807.                 break;
  808.         case '^':
  809.                 *r = pow(*r, *h);
  810.                 break;
  811.         }
  812. }
  813.  
  814. void logic(char *op, double *r, double *h)
  815. {
  816.         double t;
  817.         switch (*op)
  818.         {
  819.         case '<':
  820.                 if (*(op+1) && *(op+1) == '=')
  821.                         t = *r <= *h + epsilon ? 1.0 : 0.0;
  822.                 else                           
  823.                         t = *r < *h - epsilon? 1.0 : 0.0;      
  824.                 break;
  825.         case '>':
  826.                 if (*(op+1) && *(op+1) == '=')
  827.                         t = *r >= *h - epsilon ? 1.0 : 0.0;
  828.                 else                           
  829.                         t = *r > *h + epsilon ? 1.0 : 0.0;
  830.                 break;
  831.         case '=':
  832.                 t = fabs(*r - *h) <= epsilon ? 1.0 : 0.0;
  833.                 break;
  834.         case '#':
  835.                 t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
  836.                 break;
  837.         case '!':
  838.                 if (*(op+1) && *(op+1) == '=')
  839.                         t = fabs(*r - *h) > epsilon ? 1.0 : 0.0;
  840.                 else
  841.                         serror(ERR_GENERAL);
  842.                 break;
  843.         }
  844.         *r = t;
  845. }
  846.  
  847.  
  848. void unary(char op, double *r)
  849. {
  850.         if (op == '-')
  851.                 *r = -(*r);
  852. }
  853.  
  854. bool strcmp(char *s1, char *s2)
  855. {
  856.         int i;
  857.  
  858.         if (s1 == NULL)
  859.                 if (s2 == NULL)
  860.                         return 0;
  861.                 else
  862.                         return 1;
  863.         else
  864.                 if (s2 == NULL)
  865.                         return 1;
  866.  
  867.         for (i = 0;;i++)
  868.         {
  869.                 if (s1[i] == '\0')
  870.                         if (s2[i] == '\0')
  871.                                 return 0;
  872.                         else
  873.                                 return 1;
  874.                 else
  875.                         if (s2[i] == '\0')
  876.                                 return 1;
  877.                         else
  878.                         {
  879.                                 if (s1[i] != s2[i])
  880.                                         return 1;
  881.                         }
  882.         }
  883.         return 0;
  884. }
  885.  
  886.  
  887. bool strncmp(char *s1, char *s2, int n)
  888. {
  889.         int i;
  890.  
  891.         if (s1 == NULL)
  892.                 if (s2 == NULL)
  893.                         return 0;
  894.                 else
  895.                         return 1;
  896.         else
  897.                 if (s2 == NULL)
  898.                         return 1;
  899.  
  900.         for (i = 0;i<n;i++)
  901.         {
  902.                 if (s1[i] == '\0')
  903.                         if (s2[i] == '\0')
  904.                                 return 0;
  905.                         else
  906.                                 return 1;
  907.                 else
  908.                         if (s2[i] == '\0')
  909.                                 return 1;
  910.                         else
  911.                         {
  912.                                 if (s1[i] != s2[i])
  913.                                         return 1;
  914.                         }
  915.         }
  916.         return 0;
  917. }
  918.  
  919. int look_up(char *s)
  920. {
  921.         int i;
  922.  
  923.         for (i = 0; i < max_func; i++)
  924.                 if (strcmp(s, functions[i].name) == 0)
  925.                         return i;
  926.         return 0;       // search command/function name
  927. }
  928.  
  929.