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