home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / emxtutor.zip / emxsrcd1.zip / emx / src / emxdoc / cond.c next >
C/C++ Source or Header  |  1995-10-19  |  5KB  |  257 lines

  1. /* cond.c -- Conditional expressions
  2.    Copyright (c) 1993-1995 Eberhard Mattes
  3.  
  4. This file is part of emxdoc.
  5.  
  6. emxdoc is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. emxdoc is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with emxdoc; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.  */
  20.  
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include "emxdoc.h"
  27. #include "cond.h"
  28.  
  29. enum ctok
  30. {
  31.   CTOK_END,
  32.   CTOK_LPAR,
  33.   CTOK_RPAR,
  34.   CTOK_OR,
  35.   CTOK_AND,
  36.   CTOK_NOT,
  37.   CTOK_CONST
  38. };
  39.  
  40. struct cond_var
  41. {
  42.   struct cond_var *next;
  43.   uchar *name;
  44.   int value;
  45. };
  46.  
  47. static const uchar *cond_ptr;
  48. static enum ctok ct_token;
  49. static int ct_value;
  50. static struct cond_var *cond_vars = NULL;
  51.  
  52.  
  53. static int cond_or (void);
  54. static void cond_fetch (void);
  55. static struct cond_var *cond_find (const uchar *name);
  56.  
  57.  
  58. int condition (const uchar *p)
  59. {
  60.   int result;
  61.  
  62.   cond_ptr = p;
  63.   cond_fetch ();
  64.   result = cond_or ();
  65.   if (ct_token != CTOK_END)
  66.     fatal ("%s:%d: End of line expected after condition expression",
  67.            input_fname, line_no);
  68.   return result;
  69. }
  70.  
  71.  
  72. void cond_set (const uchar *name, int value)
  73. {
  74.   struct cond_var *v;
  75.  
  76.   v = cond_find (name);
  77.   if (v == NULL)
  78.     {
  79.       v = xmalloc (sizeof (*v));
  80.       v->name = xstrdup (name);
  81.       v->next = cond_vars;
  82.       cond_vars = v;
  83.     }
  84.   v->value = value;
  85. }
  86.  
  87.  
  88. static struct cond_var *cond_find (const uchar *name)
  89. {
  90.   struct cond_var *v;
  91.  
  92.   for (v = cond_vars; v != NULL; v = v->next)
  93.     if (strcmp (v->name, name) == 0)
  94.       return v;
  95.   return NULL;
  96. }
  97.  
  98.  
  99. static void cond_fetch (void)
  100. {
  101.   static uchar name[512];
  102.   int len;
  103.   struct cond_var *v;
  104.  
  105.   while (isspace (*cond_ptr))
  106.     ++cond_ptr;
  107.   switch (*cond_ptr)
  108.     {
  109.     case 0:
  110.       ct_token = CTOK_END;
  111.       return;
  112.     case '!':
  113.       ct_token = CTOK_NOT; ++cond_ptr;
  114.       return;
  115.     case '&':
  116.       ct_token = CTOK_AND; ++cond_ptr;
  117.       return;
  118.     case '|':
  119.       ct_token = CTOK_OR; ++cond_ptr;
  120.       return;
  121.     case '(':
  122.       ct_token = CTOK_LPAR; ++cond_ptr;
  123.       return;
  124.     case ')':
  125.       ct_token = CTOK_RPAR; ++cond_ptr;
  126.       return;
  127.     case 'f':
  128.       if (strncmp (cond_ptr, "false", 5) == 0)
  129.         {
  130.           ct_token = CTOK_CONST; ct_value = FALSE;
  131.           cond_ptr += 5;
  132.           return;
  133.         }
  134.       break;
  135.     case 'i':
  136.       if (strncmp (cond_ptr, "ipf", 3) == 0)
  137.         {
  138.           ct_token = CTOK_CONST; ct_value = (mode == 'i');
  139.           cond_ptr += 3;
  140.           return;
  141.         }
  142.       break;
  143.     case 'l':
  144.       if (strncmp (cond_ptr, "latex", 5) == 0)
  145.         {
  146.           ct_token = CTOK_CONST; ct_value = (mode == 'l');
  147.           cond_ptr += 5;
  148.           return;
  149.         }
  150.       break;
  151.     case 't':
  152.       if (strncmp (cond_ptr, "text", 4) == 0)
  153.         {
  154.           ct_token = CTOK_CONST; ct_value = (mode == 't');
  155.           cond_ptr += 4;
  156.           return;
  157.         }
  158.       else if (strncmp (cond_ptr, "true", 4) == 0)
  159.         {
  160.           ct_token = CTOK_CONST; ct_value = TRUE;
  161.           cond_ptr += 4;
  162.           return;
  163.         }
  164.       break;
  165.     }
  166.   if (isalpha (*cond_ptr))
  167.     {
  168.       len = 0;
  169.       name[len] = cond_ptr[len]; ++len;
  170.       while (isalnum (cond_ptr[len]) || cond_ptr[len] == '_')
  171.         name[len] = cond_ptr[len], ++len;
  172.       name[len] = 0;
  173.       v = cond_find (name);
  174.       if (v != NULL)
  175.         {
  176.           ct_token = CTOK_CONST; ct_value = v->value;
  177.           cond_ptr += len;
  178.           return;
  179.         }
  180.     }
  181.   fatal ("%s:%d: Invalid token in condition expression",
  182.          input_fname, line_no);
  183. }
  184.  
  185.  
  186. static int cond_factor (void)
  187. {
  188.   int result;
  189.  
  190.   switch (ct_token)
  191.     {
  192.     case CTOK_LPAR:
  193.       cond_fetch ();
  194.       result = cond_or ();
  195.       if (ct_token != CTOK_RPAR)
  196.         fatal ("%s:%d: Missing right parenthesis in condition expression",
  197.                input_fname, line_no);
  198.       break;
  199.  
  200.     case CTOK_END:
  201.       fatal ("%s:%d: Operand expected in condition expression",
  202.              input_fname, line_no);
  203.  
  204.     case CTOK_CONST:
  205.       result = ct_value;
  206.       cond_fetch ();
  207.       break;
  208.  
  209.     default:
  210.       fatal ("%s:%d: Invalid operand in condition expression",
  211.              input_fname, line_no);
  212.     }
  213.   return result;
  214. }
  215.  
  216.  
  217. static int cond_not (void)
  218. {
  219.   if (ct_token == CTOK_NOT)
  220.     {
  221.       cond_fetch ();
  222.       return !cond_not ();
  223.     }
  224.   else
  225.     return cond_factor ();
  226. }
  227.  
  228.  
  229. static int cond_and (void)
  230. {
  231.   int result;
  232.  
  233.   result = cond_not ();
  234.   while (ct_token == CTOK_AND)
  235.     {
  236.       cond_fetch ();
  237.       if (!cond_not ())
  238.         result = FALSE;
  239.     }
  240.   return result;
  241. }
  242.  
  243.  
  244. static int cond_or (void)
  245. {
  246.   int result;
  247.  
  248.   result = cond_and ();
  249.   while (ct_token == CTOK_OR)
  250.     {
  251.       cond_fetch ();
  252.       if (cond_and ())
  253.         result = TRUE;
  254.     }
  255.   return result;
  256. }
  257.