2
* Copyright (C) 2003-2011 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"
22
#include "string_util.h"
32
return g_quark_from_static_string("tokenizer");
36
valid_word_first_char(char ch)
38
return g_ascii_isalpha(ch);
42
valid_word_char(char ch)
44
return g_ascii_isalnum(ch) || ch == '_';
48
tokenizer_next_word(char **input_p, GError **error_r)
52
assert(input_p != NULL);
53
assert(*input_p != NULL);
55
word = input = *input_p;
60
/* check the first character */
62
if (!valid_word_first_char(*input)) {
63
g_set_error(error_r, tokenizer_quark(), 0,
68
/* now iterate over the other characters until we find a
69
whitespace or end-of-string */
71
while (*++input != 0) {
72
if (g_ascii_isspace(*input)) {
73
/* a whitespace: the word ends here */
75
/* skip all following spaces, too */
76
input = strchug_fast(input + 1);
80
if (!valid_word_char(*input)) {
82
g_set_error(error_r, tokenizer_quark(), 0,
83
"Invalid word character");
88
/* end of string: the string is already null-terminated
96
valid_unquoted_char(char ch)
98
return (unsigned char)ch > 0x20 && ch != '"' && ch != '\'';
102
tokenizer_next_unquoted(char **input_p, GError **error_r)
106
assert(input_p != NULL);
107
assert(*input_p != NULL);
109
word = input = *input_p;
114
/* check the first character */
116
if (!valid_unquoted_char(*input)) {
117
g_set_error(error_r, tokenizer_quark(), 0,
118
"Invalid unquoted character");
122
/* now iterate over the other characters until we find a
123
whitespace or end-of-string */
125
while (*++input != 0) {
126
if (g_ascii_isspace(*input)) {
127
/* a whitespace: the word ends here */
129
/* skip all following spaces, too */
130
input = strchug_fast(input + 1);
134
if (!valid_unquoted_char(*input)) {
136
g_set_error(error_r, tokenizer_quark(), 0,
137
"Invalid unquoted character");
142
/* end of string: the string is already null-terminated
150
tokenizer_next_string(char **input_p, GError **error_r)
152
char *word, *dest, *input;
154
assert(input_p != NULL);
155
assert(*input_p != NULL);
157
word = dest = input = *input_p;
163
/* check for the opening " */
166
g_set_error(error_r, tokenizer_quark(), 0,
173
/* copy all characters */
175
while (*input != '"') {
177
/* the backslash escapes the following
182
/* return input-1 so the caller can see the
183
difference between "end of line" and
185
*input_p = input - 1;
186
g_set_error(error_r, tokenizer_quark(), 0,
187
"Missing closing '\"'");
191
/* copy one character */
195
/* the following character must be a whitespace (or end of
199
if (*input != 0 && !g_ascii_isspace(*input)) {
201
g_set_error(error_r, tokenizer_quark(), 0,
202
"Space expected after closing '\"'");
206
/* finish the string and return it */
209
*input_p = strchug_fast(input);
214
tokenizer_next_param(char **input_p, GError **error_r)
216
assert(input_p != NULL);
217
assert(*input_p != NULL);
219
if (**input_p == '"')
220
return tokenizer_next_string(input_p, error_r);
222
return tokenizer_next_unquoted(input_p, error_r);