2 * Copyright (C) 2003-2009 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "tokenizer.h"
30 return g_quark_from_static_string("tokenizer");
34 valid_word_first_char(char ch
)
36 return g_ascii_isalpha(ch
);
40 valid_word_char(char ch
)
42 return g_ascii_isalnum(ch
) || ch
== '_';
46 tokenizer_next_word(char **input_p
, GError
**error_r
)
50 assert(input_p
!= NULL
);
51 assert(*input_p
!= NULL
);
53 word
= input
= *input_p
;
58 /* check the first character */
60 if (!valid_word_first_char(*input
)) {
61 g_set_error(error_r
, tokenizer_quark(), 0,
66 /* now iterate over the other characters until we find a
67 whitespace or end-of-string */
69 while (*++input
!= 0) {
70 if (g_ascii_isspace(*input
)) {
71 /* a whitespace: the word ends here */
73 /* skip all following spaces, too */
74 input
= g_strchug(input
+ 1);
78 if (!valid_word_char(*input
)) {
80 g_set_error(error_r
, tokenizer_quark(), 0,
81 "Invalid word character");
86 /* end of string: the string is already null-terminated
94 tokenizer_next_string(char **input_p
, GError
**error_r
)
96 char *word
, *dest
, *input
;
98 assert(input_p
!= NULL
);
99 assert(*input_p
!= NULL
);
101 word
= dest
= input
= *input_p
;
107 /* check for the opening " */
110 g_set_error(error_r
, tokenizer_quark(), 0,
117 /* copy all characters */
119 while (*input
!= '"') {
121 /* the backslash escapes the following
126 /* return input-1 so the caller can see the
127 difference between "end of line" and
129 *input_p
= input
- 1;
130 g_set_error(error_r
, tokenizer_quark(), 0,
131 "Missing closing '\"'");
135 /* copy one character */
139 /* the following character must be a whitespace (or end of
143 if (*input
!= 0 && !g_ascii_isspace(*input
)) {
145 g_set_error(error_r
, tokenizer_quark(), 0,
146 "Space expected after closing '\"'");
150 /* finish the string and return it */
153 *input_p
= g_strchug(input
);
158 tokenizer_next_word_or_string(char **input_p
, GError
**error_r
)
160 assert(input_p
!= NULL
);
161 assert(*input_p
!= NULL
);
163 if (**input_p
== '"')
164 return tokenizer_next_string(input_p
, error_r
);
166 return tokenizer_next_word(input_p
, error_r
);