/*! \file lib/gis/token.c \brief GIS Library - Tokenize strings (C) 2001-2008, 2011-2013 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS for details. \author USA CERL and others */ #include #include #include static char **tokenize(const char *, const char *, const char *); /*! \brief Tokenize string Given a string, buf, turn delimiter, delim, into '\0' (NULL) and place pointers to tokens in tokens. buf must not contain a new line (\n). delim may consist of more than one character. G_free_tokens() must be called when finished with tokens to release memory. Example: \code char **tokens; int ntok, i; tokens = G_tokenize(buf, " |:,"); ntok = G_number_of_tokens(tokens); for (i=0; i < ntok; i++) { G_debug(1, "%d=[%s]", i, tokens[i]); } G_free_tokens(tokens); \endcode \param buf input string \param delim string delimiter \return pointer to string token */ char **G_tokenize(const char *buf, const char *delim) { return tokenize(buf, delim, NULL); } /*! \brief Tokenize string This fuction behaves similarly to G_tokenize(). It introduces valchar which defines borders of token. Within token delim is ignored. Example: \code char *str = "a,'b,c',d"; char **tokens1, **tokens2; int ntok1, ntok2; tokens1 = G_tokenize(str, ","); ntok1 = G_number_of_tokens(tokens1); tokens1 = G_tokenize2(str, ",", "'"); ntok2 = G_number_of_tokens(tokens2); \endcode In this example ntok1 will be 4, ntok2 only 3, i.e. { "a", "'b, c'", "d"} \param buf input string \param delim string delimiter \param valchar character defining border of token \return pointer to string token */ char **G_tokenize2(const char *buf, const char *delim, const char *valchar) { return tokenize(buf, delim, valchar); } char **tokenize(const char *buf, const char *delim, const char *inchar) { int i; char **tokens; char *p; /* do not modify buf, make a copy */ p = G_store(buf); i = 0; tokens = (char **)G_malloc(2 * sizeof(char *)); /* always one token */ tokens[i++] = p; while (TRUE) { /* find next delimiter */ while (!strchr(delim, *p)) { /* opening border ? */ if (inchar && *p == *inchar) { p++; /* find closing border */ while (*p != *inchar && *p != 0) p++; if (*p == 0) break; } p++; } if (*p == 0) break; /* replace delim with '\0' */ *p++ = 0; /* set next token */ tokens[i++] = p; tokens = (char **)G_realloc((char *)tokens, (i + 1) * sizeof(char *)); } tokens[i] = NULL; return tokens; } /*! \brief Return number of tokens \param tokens \return number of tokens */ int G_number_of_tokens(char **tokens) { int n; n = 0; for (n = 0; tokens[n] != NULL; n++) ; return n; } /*! \brief Free memory allocated to tokens. Note: G_free_tokens() must be called when finished with tokens to release memory. \param[out] tokens */ void G_free_tokens(char **tokens) { if (tokens[0] != NULL) G_free(tokens[0]); G_free(tokens); }