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