Removed a syntax error.
[egate.git] / ccl / ccltoken.c
1 /* CCL - lexical analysis
2  * Europagate, 1995
3  *
4  * $Log: ccltoken.c,v $
5  * Revision 1.2  1995/02/14 19:55:13  adam
6  * Header files ccl.h/cclp.h are gone! They have been merged an
7  * moved to ../include/ccl.h.
8  * Node kind(s) in ccl_rpn_node have changed names.
9  *
10  * Revision 1.1  1995/02/13  12:35:21  adam
11  * First version of CCL. Qualifiers aren't handled yet.
12  *
13  */
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <assert.h>
19
20 #include <ccl.h>
21
22 static int strin (const char *s, const char *cset)
23 {
24     while (*cset)
25     {
26         if (*cset++ == *s)
27             return 1;
28     }
29     return 0;
30 }
31
32 char *ccl_token_and = "and";
33 char *ccl_token_or = "or";
34 char *ccl_token_not = "not";
35 char *ccl_token_set = "set";
36
37 struct ccl_token *ccl_tokenize (const char *command)
38 {
39     const char *cp = command;
40     struct ccl_token *first = NULL;
41     struct ccl_token *last = NULL;
42
43     while (1)
44     {
45         while (*cp && strin (cp, " \t\r\n"))
46         {
47             cp++;
48             continue;
49         }
50         if (!first)
51         {
52             first = last = malloc (sizeof (*first));
53             assert (first);
54             last->prev = NULL;
55         }
56         else
57         {
58             last->next = malloc (sizeof(*first));
59             assert (last->next);
60             last->next->prev = last;
61             last = last->next;
62         }
63         last->next = NULL;
64         last->name = cp;
65         last->len = 1;
66         switch (*cp++)
67         {
68         case '\0':
69             last->kind = CCL_TOK_EOL;
70             return first;
71         case '(':
72             last->kind = CCL_TOK_LP;
73             break;
74         case ')':
75             last->kind = CCL_TOK_RP;
76             break;
77         case ',':
78             last->kind = CCL_TOK_COMMA;
79             break;
80         case '%':
81         case '!':
82             last->kind = CCL_TOK_PROX;
83             while (*cp == '%' || *cp == '!')
84             {
85                 ++ last->len;
86                 cp++;
87             }
88             break;
89         case '>':
90         case '<':
91         case '=':
92             if (*cp == '=' || *cp == '<' || *cp == '>')
93             {
94                 cp++;
95                 last->kind = CCL_TOK_REL;
96                 ++ last->len;
97             }
98             else if (cp[-1] == '=')
99                 last->kind = CCL_TOK_EQ;
100             else
101                 last->kind = CCL_TOK_REL;
102             break;
103         case '-':
104             last->kind = CCL_TOK_MINUS;
105             break;
106         case '\"':
107             last->kind = CCL_TOK_TERM;
108             last->name = cp;
109             last->len = 0;
110             while (*cp && *cp != '\"')
111             {
112                 cp++;
113                 ++ last->len;
114             }
115             if (*cp == '\"')
116                 cp++;
117             break;
118         default:
119             while (*cp && !strin (cp, "(),%!><=- \t\n\r"))
120             {
121                 cp++;
122                 ++ last->len;
123             }
124             if (strlen (ccl_token_and)==last->len &&
125                 !memcmp (ccl_token_and, last->name, last->len))
126                 last->kind = CCL_TOK_AND;
127             else if (strlen (ccl_token_or)==last->len &&
128                 !memcmp (ccl_token_or, last->name, last->len))
129                 last->kind = CCL_TOK_OR;
130             else if (strlen (ccl_token_not)==last->len &&
131                 !memcmp (ccl_token_not, last->name, last->len))
132                 last->kind = CCL_TOK_NOT;
133             else if (strlen (ccl_token_set)==last->len &&
134                 !memcmp (ccl_token_set, last->name, last->len))
135                 last->kind = CCL_TOK_SET;
136             else
137                 last->kind = CCL_TOK_TERM;
138         }
139     }
140     return first;
141 }