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