diff options
Diffstat (limited to 'sntp/libopts/tokenize.c')
-rw-r--r-- | sntp/libopts/tokenize.c | 252 |
1 files changed, 133 insertions, 119 deletions
diff --git a/sntp/libopts/tokenize.c b/sntp/libopts/tokenize.c index 0e576ce..4ca1245 100644 --- a/sntp/libopts/tokenize.c +++ b/sntp/libopts/tokenize.c @@ -1,26 +1,28 @@ /* * This file defines the string_tokenize interface - * Time-stamp: "2006-06-24 15:27:49 bkorb" + * Time-stamp: "2010-07-17 10:40:26 bkorb" * - * string_tokenize copyright 2005 Bruce Korb + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved * - * string_tokenize is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. * - * string_tokenize is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" * - * You should have received a copy of the GNU Lesser General Public - * License along with string_tokenize; if not, write to: - * The Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following md5sums: + * + * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3 + * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3 + * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd */ -#include <ctype.h> + #include <errno.h> #include <stdlib.h> @@ -28,16 +30,18 @@ #define ch_t unsigned char /* = = = START-STATIC-FORWARD = = = */ -/* static forward declarations maintained by :mkfwd */ static void -copy_cooked( ch_t** ppDest, char const ** ppSrc ); +copy_cooked(ch_t** ppDest, char const ** ppSrc); static void -copy_raw( ch_t** ppDest, char const ** ppSrc ); +copy_raw(ch_t** ppDest, char const ** ppSrc); + +static token_list_t * +alloc_token_list(char const * str); /* = = = END-STATIC-FORWARD = = = */ static void -copy_cooked( ch_t** ppDest, char const ** ppSrc ) +copy_cooked(ch_t** ppDest, char const ** ppSrc) { ch_t* pDest = (ch_t*)*ppDest; const ch_t* pSrc = (const ch_t*)(*ppSrc + 1); @@ -48,7 +52,7 @@ copy_cooked( ch_t** ppDest, char const ** ppSrc ) case NUL: *ppSrc = NULL; return; case '"': goto done; case '\\': - pSrc += ao_string_cook_escape_char( (char*)pSrc, (char*)&ch, 0x7F ); + pSrc += ao_string_cook_escape_char((char*)pSrc, (char*)&ch, 0x7F); if (ch == 0x7F) break; /* FALLTHROUGH */ @@ -65,7 +69,7 @@ copy_cooked( ch_t** ppDest, char const ** ppSrc ) static void -copy_raw( ch_t** ppDest, char const ** ppSrc ) +copy_raw(ch_t** ppDest, char const ** ppSrc) { ch_t* pDest = *ppDest; cc_t* pSrc = (cc_t*) (*ppSrc + 1); @@ -111,6 +115,53 @@ copy_raw( ch_t** ppDest, char const ** ppSrc ) *ppSrc = (char const *) pSrc; /* char following closing quote */ } +static token_list_t * +alloc_token_list(char const * str) +{ + token_list_t * res; + + int max_token_ct = 2; /* allow for trailing NULL pointer & NUL on string */ + + if (str == NULL) goto enoent_res; + + /* + * Trim leading white space. Use "ENOENT" and a NULL return to indicate + * an empty string was passed. + */ + while (IS_WHITESPACE_CHAR(*str)) str++; + if (*str == NUL) goto enoent_res; + + /* + * Take an approximate count of tokens. If no quoted strings are used, + * it will be accurate. If quoted strings are used, it will be a little + * high and we'll squander the space for a few extra pointers. + */ + { + cc_t* pz = (cc_t*)str; + + do { + max_token_ct++; + while (! IS_WHITESPACE_CHAR(*++pz)) + if (*pz == NUL) goto found_nul; + while (IS_WHITESPACE_CHAR(*pz)) pz++; + } while (*pz != NUL); + + found_nul: + res = malloc(sizeof(*res) + (pz - (cc_t*)str) + + (max_token_ct * sizeof(ch_t*))); + } + + if (res == NULL) + errno = ENOMEM; + else res->tkn_list[0] = (ch_t*)(res->tkn_list + (max_token_ct - 1)); + + return res; + + enoent_res: + + errno = ENOENT; + return NULL; +} /*=export_func ao_string_tokenize * @@ -159,10 +210,10 @@ copy_raw( ch_t** ppDest, char const ** ppSrc ) * @example * #include <stdlib.h> * int ix; - * token_list_t* ptl = ao_string_tokenize( some_string ) + * token_list_t* ptl = ao_string_tokenize(some_string) * for (ix = 0; ix < ptl->tkn_ct; ix++) - * do_something_with_tkn( ptl->tkn_list[ix] ); - * free( ptl ); + * do_something_with_tkn(ptl->tkn_list[ix]); + * free(ptl); * @end example * Note that everything is freed with the one call to @code{free(3C)}. * @@ -178,106 +229,69 @@ copy_raw( ch_t** ppDest, char const ** ppSrc ) * @end itemize =*/ token_list_t* -ao_string_tokenize( char const* str ) +ao_string_tokenize(char const* str) { - int max_token_ct = 1; /* allow for trailing NUL on string */ - token_list_t* res; - - if (str == NULL) goto bogus_str; - - /* - * Trim leading white space. Use "ENOENT" and a NULL return to indicate - * an empty string was passed. - */ - while (isspace( (ch_t)*str )) str++; - if (*str == NUL) { - bogus_str: - errno = ENOENT; - return NULL; - } + token_list_t* res = alloc_token_list(str); + ch_t* pzDest; /* - * Take an approximate count of tokens. If no quoted strings are used, - * it will be accurate. If quoted strings are used, it will be a little - * high and we'll squander the space for a few extra pointers. + * Now copy each token into the output buffer. */ - { - cc_t* pz = (cc_t*)str; - - do { - max_token_ct++; - while (! isspace( *++pz )) - if (*pz == NUL) goto found_nul; - while (isspace( *pz )) pz++; - } while (*pz != NUL); + if (res == NULL) + return res; - found_nul: - ; - } + pzDest = (ch_t*)(res->tkn_list[0]); + res->tkn_ct = 0; - res = malloc( sizeof(*res) + strlen(str) + (max_token_ct * sizeof(ch_t*)) ); - if (res == NULL) { - errno = ENOMEM; - return res; - } + do { + res->tkn_list[ res->tkn_ct++ ] = pzDest; + for (;;) { + int ch = (ch_t)*str; + if (IS_WHITESPACE_CHAR(ch)) { + found_white_space: + while (IS_WHITESPACE_CHAR(*++str)) ; + break; + } - /* - * Now copy each token into the output buffer. - */ - { - ch_t* pzDest = (ch_t*)(res->tkn_list + (max_token_ct + 1)); - res->tkn_ct = 0; - - do { - res->tkn_list[ res->tkn_ct++ ] = pzDest; - for (;;) { - int ch = (ch_t)*str; - if (isspace( ch )) { - found_white_space: - while (isspace( (ch_t)*++str )) ; - break; + switch (ch) { + case '"': + copy_cooked(&pzDest, &str); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; } + if (IS_WHITESPACE_CHAR(*str)) + goto found_white_space; + break; - switch (ch) { - case '"': - copy_cooked( &pzDest, &str ); - if (str == NULL) { - free(res); - errno = EINVAL; - return NULL; - } - if (isspace( (ch_t)*str )) - goto found_white_space; - break; - - case '\'': - copy_raw( &pzDest, &str ); - if (str == NULL) { - free(res); - errno = EINVAL; - return NULL; - } - if (isspace( (ch_t)*str )) - goto found_white_space; - break; - - case NUL: - goto copy_done; - - default: - str++; - *(pzDest++) = ch; + case '\'': + copy_raw(&pzDest, &str); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; } - } copy_done:; + if (IS_WHITESPACE_CHAR(*str)) + goto found_white_space; + break; - /* - * NUL terminate the last token and see if we have any more tokens. - */ - *(pzDest++) = NUL; - } while (*str != NUL); + case NUL: + goto copy_done; - res->tkn_list[ res->tkn_ct ] = NULL; - } + default: + str++; + *(pzDest++) = ch; + } + } copy_done:; + + /* + * NUL terminate the last token and see if we have any more tokens. + */ + *(pzDest++) = NUL; + } while (*str != NUL); + + res->tkn_list[ res->tkn_ct ] = NULL; return res; } @@ -287,7 +301,7 @@ ao_string_tokenize( char const* str ) #include <string.h> int -main( int argc, char** argv ) +main(int argc, char** argv) { if (argc == 1) { printf("USAGE: %s arg [ ... ]\n", *argv); @@ -295,15 +309,15 @@ main( int argc, char** argv ) } while (--argc > 0) { char* arg = *(++argv); - token_list_t* p = ao_string_tokenize( arg ); + token_list_t* p = ao_string_tokenize(arg); if (p == NULL) { - printf( "Parsing string ``%s'' failed:\n\terrno %d (%s)\n", - arg, errno, strerror( errno )); + printf("Parsing string ``%s'' failed:\n\terrno %d (%s)\n", + arg, errno, strerror(errno)); } else { int ix = 0; - printf( "Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct ); + printf("Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct); do { - printf( " %3d: ``%s''\n", ix+1, p->tkn_list[ix] ); + printf(" %3d: ``%s''\n", ix+1, p->tkn_list[ix]); } while (++ix < p->tkn_ct); free(p); } |