edd2974e37b6c330f6b1c3fd5644093bc0ec1073
[yaz-moved-to-github.git] / ccl / ccltoken.c
1 /* CCL - lexical analysis
2  * Europagate, 1995
3  *
4  * $Log: ccltoken.c,v $
5  * Revision 1.2  1995-09-27 15:02:44  quinn
6  * Modified function heads & prototypes.
7  *
8  * Revision 1.1  1995/04/10  10:28:22  quinn
9  * Added copy of CCL.
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 static int strin (const char *s, const char *cset)
36 {
37     while (*cset)
38     {
39         if (*cset++ == *s)
40             return 1;
41     }
42     return 0;
43 }
44
45 const char *ccl_token_and = "and";
46 const char *ccl_token_or = "or";
47 const char *ccl_token_not = "not";
48 const char *ccl_token_set = "set";
49
50 struct ccl_token MDF *ccl_tokenize (const char *command)
51 {
52     const char *cp = command;
53     struct ccl_token *first = NULL;
54     struct ccl_token *last = NULL;
55
56     while (1)
57     {
58         while (*cp && strin (cp, " \t\r\n"))
59         {
60             cp++;
61             continue;
62         }
63         if (!first)
64         {
65             first = last = malloc (sizeof (*first));
66             assert (first);
67             last->prev = NULL;
68         }
69         else
70         {
71             last->next = malloc (sizeof(*first));
72             assert (last->next);
73             last->next->prev = last;
74             last = last->next;
75         }
76         last->next = NULL;
77         last->name = cp;
78         last->len = 1;
79         switch (*cp++)
80         {
81         case '\0':
82             last->kind = CCL_TOK_EOL;
83             return first;
84         case '(':
85             last->kind = CCL_TOK_LP;
86             break;
87         case ')':
88             last->kind = CCL_TOK_RP;
89             break;
90         case ',':
91             last->kind = CCL_TOK_COMMA;
92             break;
93         case '%':
94         case '!':
95             last->kind = CCL_TOK_PROX;
96             while (*cp == '%' || *cp == '!')
97             {
98                 ++ last->len;
99                 cp++;
100             }
101             break;
102         case '>':
103         case '<':
104         case '=':
105             if (*cp == '=' || *cp == '<' || *cp == '>')
106             {
107                 cp++;
108                 last->kind = CCL_TOK_REL;
109                 ++ last->len;
110             }
111             else if (cp[-1] == '=')
112                 last->kind = CCL_TOK_EQ;
113             else
114                 last->kind = CCL_TOK_REL;
115             break;
116         case '-':
117             last->kind = CCL_TOK_MINUS;
118             break;
119         case '\"':
120             last->kind = CCL_TOK_TERM;
121             last->name = cp;
122             last->len = 0;
123             while (*cp && *cp != '\"')
124             {
125                 cp++;
126                 ++ last->len;
127             }
128             if (*cp == '\"')
129                 cp++;
130             break;
131         default:
132             while (*cp && !strin (cp, "(),%!><=- \t\n\r"))
133             {
134                 cp++;
135                 ++ last->len;
136             }
137             if (strlen (ccl_token_and)==last->len &&
138                 !memcmp (ccl_token_and, last->name, last->len))
139                 last->kind = CCL_TOK_AND;
140             else if (strlen (ccl_token_or)==last->len &&
141                 !memcmp (ccl_token_or, last->name, last->len))
142                 last->kind = CCL_TOK_OR;
143             else if (strlen (ccl_token_not)==last->len &&
144                 !memcmp (ccl_token_not, last->name, last->len))
145                 last->kind = CCL_TOK_NOT;
146             else if (strlen (ccl_token_set)==last->len &&
147                 !memcmp (ccl_token_set, last->name, last->len))
148                 last->kind = CCL_TOK_SET;
149             else
150                 last->kind = CCL_TOK_TERM;
151         }
152     }
153     return first;
154 }