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