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