2 * Copyright (C) 2003-2010 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.
21 #include "tokenizer.h"
31 return g_quark_from_static_string("tokenizer");
35 valid_word_first_char(char ch
)
37 return g_ascii_isalpha(ch
);
41 valid_word_char(char ch
)
43 return g_ascii_isalnum(ch
) || ch
== '_';
47 tokenizer_next_word(char **input_p
, GError
**error_r
)
51 assert(input_p
!= NULL
);
52 assert(*input_p
!= NULL
);
54 word
= input
= *input_p
;
59 /* check the first character */
61 if (!valid_word_first_char(*input
)) {
62 g_set_error(error_r
, tokenizer_quark(), 0,
67 /* now iterate over the other characters until we find a
68 whitespace or end-of-string */
70 while (*++input
!= 0) {
71 if (g_ascii_isspace(*input
)) {
72 /* a whitespace: the word ends here */
74 /* skip all following spaces, too */
75 input
= g_strchug(input
+ 1);
79 if (!valid_word_char(*input
)) {
81 g_set_error(error_r
, tokenizer_quark(), 0,
82 "Invalid word character");
87 /* end of string: the string is already null-terminated
95 valid_unquoted_char(char ch
)
97 return (unsigned char)ch
> 0x20 && ch
!= '"' && ch
!= '\'';
101 tokenizer_next_unquoted(char **input_p
, GError
**error_r
)
105 assert(input_p
!= NULL
);
106 assert(*input_p
!= NULL
);
108 word
= input
= *input_p
;
113 /* check the first character */
115 if (!valid_unquoted_char(*input
)) {
116 g_set_error(error_r
, tokenizer_quark(), 0,
117 "Invalid unquoted character");
121 /* now iterate over the other characters until we find a
122 whitespace or end-of-string */
124 while (*++input
!= 0) {
125 if (g_ascii_isspace(*input
)) {
126 /* a whitespace: the word ends here */
128 /* skip all following spaces, too */
129 input
= g_strchug(input
+ 1);
133 if (!valid_unquoted_char(*input
)) {
135 g_set_error(error_r
, tokenizer_quark(), 0,
136 "Invalid unquoted character");
141 /* end of string: the string is already null-terminated
149 tokenizer_next_string(char **input_p
, GError
**error_r
)
151 char *word
, *dest
, *input
;
153 assert(input_p
!= NULL
);
154 assert(*input_p
!= NULL
);
156 word
= dest
= input
= *input_p
;
162 /* check for the opening " */
165 g_set_error(error_r
, tokenizer_quark(), 0,
172 /* copy all characters */
174 while (*input
!= '"') {
176 /* the backslash escapes the following
181 /* return input-1 so the caller can see the
182 difference between "end of line" and
184 *input_p
= input
- 1;
185 g_set_error(error_r
, tokenizer_quark(), 0,
186 "Missing closing '\"'");
190 /* copy one character */
194 /* the following character must be a whitespace (or end of
198 if (*input
!= 0 && !g_ascii_isspace(*input
)) {
200 g_set_error(error_r
, tokenizer_quark(), 0,
201 "Space expected after closing '\"'");
205 /* finish the string and return it */
208 *input_p
= g_strchug(input
);
213 tokenizer_next_param(char **input_p
, GError
**error_r
)
215 assert(input_p
!= NULL
);
216 assert(*input_p
!= NULL
);
218 if (**input_p
== '"')
219 return tokenizer_next_string(input_p
, error_r
);
221 return tokenizer_next_unquoted(input_p
, error_r
);