Code updates which makes things compile as C++. Mostly type casts were
[yaz-moved-to-github.git] / src / tokenizer.c
1 /*
2  * Copyright (C) 1995-2007, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: tokenizer.c,v 1.3 2007-05-06 20:12:20 adam Exp $
6  */
7
8 /**
9  * \file tokenizer.c
10  * \brief Implements attribute match of CCL RPN nodes
11  */
12
13 #include <assert.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <yaz/log.h>
18 #include <yaz/wrbuf.h>
19 #include <yaz/tokenizer.h>
20
21 struct yaz_tok_parse {
22     int unget_byte;
23     WRBUF wr_string;
24     int look;
25     
26     yaz_tok_cfg_t cfg;
27     yaz_tok_get_byte_t get_byte_func;
28     void *get_byte_data;
29 };
30
31 struct yaz_tok_cfg {
32     int ref_count;
33     char *white_space;
34     char *single_tokens;
35     char *quote_tokens_begin;
36     char *quote_tokens_end;
37 };
38
39 void yaz_tok_cfg_single_tokens(yaz_tok_cfg_t t, const char *simple)
40 {
41     xfree(t->single_tokens);
42     t->single_tokens = xstrdup(simple);
43 }
44
45 yaz_tok_cfg_t yaz_tok_cfg_create(void)
46 {
47     yaz_tok_cfg_t t = (yaz_tok_cfg_t) xmalloc(sizeof(*t));
48     t->white_space = xstrdup(" \t\r\n");
49     t->single_tokens = xstrdup("");
50     t->quote_tokens_begin = xstrdup("\"");
51     t->quote_tokens_end = xstrdup("\"");
52     t->ref_count = 1;
53     return t;
54 }
55
56 void yaz_tok_cfg_destroy(yaz_tok_cfg_t t)
57 {
58     t->ref_count--;
59     if (t->ref_count == 0)
60     {
61         xfree(t->white_space);
62         xfree(t->single_tokens);
63         xfree(t->quote_tokens_begin);
64         xfree(t->quote_tokens_end);
65         xfree(t);
66     }
67 }
68
69 static int read_buf(void **vp)
70 {
71     const char *cp = *(const char **) vp;
72     int ch = *cp;
73     if (ch)
74     {
75         cp++;
76         *(const char **)vp = cp;
77     }
78     return ch;
79 }
80
81 yaz_tok_parse_t yaz_tok_parse_buf(yaz_tok_cfg_t t, const char *buf)
82 {
83     return yaz_tok_parse_create(t, read_buf, (void *) buf);
84 }
85
86 static int get_byte(yaz_tok_parse_t tp)
87 {
88     int ch = tp->unget_byte;
89     assert(tp->get_byte_func);
90     if (ch)
91         tp->unget_byte = 0;
92     else
93         ch = tp->get_byte_func(&tp->get_byte_data);
94     return ch;
95 }
96
97 static void unget_byte(yaz_tok_parse_t tp, int ch)
98 {
99     tp->unget_byte = ch;
100 }
101
102 yaz_tok_parse_t yaz_tok_parse_create(yaz_tok_cfg_t t,
103                                      yaz_tok_get_byte_t h,
104                                      void *vp)
105 {
106     yaz_tok_parse_t tp = (yaz_tok_parse_t) xmalloc(sizeof(*tp));
107
108     tp->cfg = t;
109     tp->cfg->ref_count++;
110     tp->get_byte_func = h;
111     tp->get_byte_data = vp;
112
113     tp->look = YAZ_TOK_ERROR;
114     tp->unget_byte = 0;
115
116     tp->wr_string = wrbuf_alloc();
117     return tp;
118 }
119                                            
120
121 void yaz_tok_parse_destroy(yaz_tok_parse_t tp)
122 {
123     yaz_tok_cfg_destroy(tp->cfg);
124     wrbuf_destroy(tp->wr_string);
125     xfree(tp);
126 }
127
128 int yaz_tok_move(yaz_tok_parse_t tp)
129 {
130     yaz_tok_cfg_t t = tp->cfg;
131     const char *cp;
132     int ch = get_byte(tp);
133
134     /* skip white space */
135     while (ch && strchr(t->white_space, ch))
136         ch = get_byte(tp);
137     if (!ch) 
138     {
139         ch = YAZ_TOK_EOF;
140     }
141     else if ((cp = strchr(t->single_tokens, ch)))
142         ch = *cp;  /* single token match */
143     else if ((cp = strchr(t->quote_tokens_begin, ch)))
144     {   /* quoted string */
145         int end_ch = t->quote_tokens_end[cp - t->quote_tokens_begin];
146         ch = get_byte(tp);
147         wrbuf_rewind(tp->wr_string);
148         while (ch && ch != end_ch)
149             wrbuf_putc(tp->wr_string, ch);
150         if (!ch)
151             ch = YAZ_TOK_ERROR;
152         else
153             ch = YAZ_TOK_QSTRING;
154     }
155     else
156     {  /* unquoted string */
157         wrbuf_rewind(tp->wr_string);
158         while (ch && !strchr(t->white_space, ch)
159                && !strchr(t->single_tokens, ch))
160         {
161             wrbuf_putc(tp->wr_string, ch);
162             ch = get_byte(tp);
163         }
164         unget_byte(tp, ch);
165         ch = YAZ_TOK_STRING;
166     }
167     tp->look = ch;
168     return ch;
169 }
170
171 const char *yaz_tok_parse_string(yaz_tok_parse_t tp)
172 {
173     return wrbuf_cstr(tp->wr_string);
174 }
175
176 /*
177  * Local variables:
178  * c-basic-offset: 4
179  * indent-tabs-mode: nil
180  * End:
181  * vim: shiftwidth=4 tabstop=8 expandtab
182  */
183