GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
Loading...
Searching...
No Matches
token.c
Go to the documentation of this file.
1
/*!
2
\file lib/gis/token.c
3
4
\brief GIS Library - Tokenize strings
5
6
(C) 2001-2008, 2011-2013 by the GRASS Development Team
7
8
This program is free software under the GNU General Public License
9
(>=v2). Read the file COPYING that comes with GRASS for details.
10
11
\author USA CERL and others
12
*/
13
14
#include <stdlib.h>
15
#include <string.h>
16
#include <grass/gis.h>
17
#include <grass/glocale.h>
18
19
static
char
**tokenize(
const
char
*,
const
char
*,
const
char
*);
20
21
/*!
22
\brief Tokenize string
23
24
Given a string, <em>buf</em>, turn delimiter, <em>delim</em>, into
25
'\0' (NULL) and place pointers to tokens in tokens. <em>buf</em>
26
must not contain a new line (\n). <em>delim</em> may consist of more
27
than one character. G_free_tokens() must be called when finished
28
with tokens to release memory.
29
30
Example:
31
\code
32
char **tokens;
33
int ntok, i;
34
tokens = G_tokenize(buf, " |:,");
35
ntok = G_number_of_tokens(tokens);
36
for (i=0; i < ntok; i++) {
37
G_debug(1, "%d=[%s]", i, tokens[i]);
38
}
39
G_free_tokens(tokens);
40
\endcode
41
42
\param buf input string
43
\param delim string delimiter
44
45
\return pointer to string token
46
*/
47
char
**
G_tokenize
(
const
char
*buf,
const
char
*delim)
48
{
49
return
tokenize(buf, delim,
NULL
);
50
}
51
52
/*!
53
\brief Tokenize string
54
55
This function behaves similarly to G_tokenize().
56
57
It introduces <em>valchar</em> which defines borders of token. Within
58
token <em>delim</em> is ignored.
59
60
Example:
61
\code
62
char *str = "a,'b,c',d";
63
64
char **tokens1, **tokens2;
65
int ntok1, ntok2;
66
67
tokens1 = G_tokenize(str, ",");
68
ntok1 = G_number_of_tokens(tokens1);
69
70
tokens1 = G_tokenize2(str, ",", "'");
71
ntok2 = G_number_of_tokens(tokens2);
72
\endcode
73
74
In this example <em>ntok1</em> will be 4, <em>ntok2</em> only 3,
75
i.e. { "a", "'b, c'", "d"}
76
77
\param buf input string
78
\param delim string delimiter
79
\param valchar character defining border of token
80
81
\return pointer to string token
82
*/
83
char
**
G_tokenize2
(
const
char
*buf,
const
char
*delim,
const
char
*valchar)
84
{
85
return
tokenize(buf, delim, valchar);
86
}
87
88
char
**tokenize(
const
char
*buf,
const
char
*delim,
const
char
*inchar)
89
{
90
int
i;
91
char
**tokens;
92
const
char
*p;
93
char
*q;
94
enum
{
95
S_START,
96
S_IN_QUOTE,
97
S_AFTER_QUOTE,
98
};
99
enum
{ A_NO_OP, A_ADD_CHAR, A_NEW_FIELD, A_END_RECORD, A_ERROR };
100
int
state;
101
int
quo = inchar ? *inchar : -1;
102
103
/* do not modify buf, make a copy */
104
p = q =
G_store
(buf);
105
106
i = 0;
107
tokens = (
char
**)G_malloc(2 *
sizeof
(
char
*));
108
109
/* always one token */
110
tokens[i++] = q;
111
112
for
(state = S_START;; p++) {
113
int
c = *p;
114
int
action = A_NO_OP;
115
116
switch
(state) {
117
case
S_START:
118
if
(c == quo)
119
state = S_IN_QUOTE;
120
else
if
(c ==
'\0'
)
121
action = A_END_RECORD;
122
else
if
(strchr(delim, c))
123
action = A_NEW_FIELD;
124
else
125
action = A_ADD_CHAR;
126
break
;
127
case
S_IN_QUOTE:
128
if
(c == quo)
129
state = S_AFTER_QUOTE;
130
else
if
(c ==
'\0'
)
131
action = A_ERROR;
132
else
133
action = A_ADD_CHAR;
134
break
;
135
case
S_AFTER_QUOTE:
136
if
(c == quo)
137
state = S_IN_QUOTE, action = A_ADD_CHAR;
138
else
if
(c ==
'\0'
)
139
action = A_END_RECORD;
140
else
if
(strchr(delim, c))
141
state = S_START, action = A_NEW_FIELD;
142
else
143
action = A_ERROR;
144
break
;
145
}
146
147
switch
(action) {
148
case
A_NO_OP:
149
break
;
150
case
A_ADD_CHAR:
151
*q++ = *p;
152
break
;
153
case
A_NEW_FIELD:
154
*q++ =
'\0'
;
155
tokens[i++] = q;
156
tokens = G_realloc(tokens, (i + 2) *
sizeof
(
char
*));
157
break
;
158
case
A_END_RECORD:
159
*q++ =
'\0'
;
160
tokens[i++] =
NULL
;
161
return
tokens;
162
case
A_ERROR:
163
G_warning
(_(
"parse error"
));
164
*q++ =
'\0'
;
165
tokens[i++] =
NULL
;
166
return
tokens;
167
}
168
}
169
}
170
171
/*!
172
\brief Return number of tokens
173
174
\param tokens
175
176
\return number of tokens
177
*/
178
int
G_number_of_tokens
(
char
**tokens)
179
{
180
int
n;
181
182
n = 0;
183
for
(n = 0; tokens[n] !=
NULL
; n++)
184
;
185
186
return
n;
187
}
188
189
/*!
190
\brief Free memory allocated to tokens.
191
192
<b>Note:</b> <i>G_free_tokens()</i> must be called when finished with
193
tokens to release memory.
194
195
\param[out] tokens
196
*/
197
void
G_free_tokens
(
char
**tokens)
198
{
199
if
(tokens[0] !=
NULL
)
200
G_free
(tokens[0]);
201
G_free
(tokens);
202
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition
alloc.c:147
NULL
#define NULL
Definition
ccmath.h:32
G_warning
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition
gis/error.c:203
G_store
char * G_store(const char *s)
Copy string to allocated memory.
Definition
strings.c:87
G_tokenize2
char ** G_tokenize2(const char *buf, const char *delim, const char *valchar)
Tokenize string.
Definition
token.c:83
G_free_tokens
void G_free_tokens(char **tokens)
Free memory allocated to tokens.
Definition
token.c:197
G_tokenize
char ** G_tokenize(const char *buf, const char *delim)
Tokenize string.
Definition
token.c:47
G_number_of_tokens
int G_number_of_tokens(char **tokens)
Return number of tokens.
Definition
token.c:178
gis
token.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0