2
* Copyright (C) 2003-2013 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.hxx"
22
#include "CharUtil.hxx"
23
#include "StringUtil.hxx"
32
static constexpr Domain tokenizer_domain("tokenizer");
35
valid_word_first_char(char ch)
37
return IsAlphaASCII(ch);
41
valid_word_char(char ch)
43
return IsAlphaNumericASCII(ch) || ch == '_';
47
Tokenizer::NextWord(Error &error)
49
char *const word = input;
54
/* check the first character */
56
if (!valid_word_first_char(*input)) {
57
error.Set(tokenizer_domain, "Letter expected");
61
/* now iterate over the other characters until we find a
62
whitespace or end-of-string */
64
while (*++input != 0) {
65
if (IsWhitespaceOrNull(*input)) {
66
/* a whitespace: the word ends here */
68
/* skip all following spaces, too */
69
input = strchug_fast(input + 1);
73
if (!valid_word_char(*input)) {
74
error.Set(tokenizer_domain, "Invalid word character");
79
/* end of string: the string is already null-terminated
86
valid_unquoted_char(char ch)
88
return (unsigned char)ch > 0x20 && ch != '"' && ch != '\'';
92
Tokenizer::NextUnquoted(Error &error)
94
char *const word = input;
99
/* check the first character */
101
if (!valid_unquoted_char(*input)) {
102
error.Set(tokenizer_domain, "Invalid unquoted character");
106
/* now iterate over the other characters until we find a
107
whitespace or end-of-string */
109
while (*++input != 0) {
110
if (IsWhitespaceOrNull(*input)) {
111
/* a whitespace: the word ends here */
113
/* skip all following spaces, too */
114
input = strchug_fast(input + 1);
118
if (!valid_unquoted_char(*input)) {
119
error.Set(tokenizer_domain,
120
"Invalid unquoted character");
125
/* end of string: the string is already null-terminated
132
Tokenizer::NextString(Error &error)
134
char *const word = input, *dest = input;
140
/* check for the opening " */
143
error.Set(tokenizer_domain, "'\"' expected");
149
/* copy all characters */
151
while (*input != '"') {
153
/* the backslash escapes the following
158
/* return input-1 so the caller can see the
159
difference between "end of line" and
162
error.Set(tokenizer_domain, "Missing closing '\"'");
166
/* copy one character */
170
/* the following character must be a whitespace (or end of
174
if (!IsWhitespaceOrNull(*input)) {
175
error.Set(tokenizer_domain,
176
"Space expected after closing '\"'");
180
/* finish the string and return it */
183
input = strchug_fast(input);
188
Tokenizer::NextParam(Error &error)
191
return NextString(error);
193
return NextUnquoted(error);