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