1/* $NetBSD: argv_splitq.c,v 1.2 2017/02/14 01:16:48 christos Exp $ */ 2 3/*++ 4/* NAME 5/* argv_splitq 3 6/* SUMMARY 7/* string array utilities 8/* SYNOPSIS 9/* #include <argv.h> 10/* 11/* ARGV *argv_splitq(string, delim, parens) 12/* const char *string; 13/* const char *delim; 14/* const char *parens; 15/* 16/* ARGV *argv_splitq_count(string, delim, parens, count) 17/* const char *string; 18/* const char *delim; 19/* const char *parens; 20/* ssize_t count; 21/* 22/* ARGV *argv_splitq_append(argv, string, delim, parens) 23/* ARGV *argv; 24/* const char *string; 25/* const char *delim; 26/* const char *parens; 27/* DESCRIPTION 28/* argv_splitq() breaks up \fIstring\fR into tokens according 29/* to the delimiters specified in \fIdelim\fR, while avoiding 30/* splitting text between matching parentheses. The result is 31/* a null-terminated string array. 32/* 33/* argv_splitq_count() is like argv_splitq() but stops splitting 34/* input after at most \fIcount\fR -1 times and leaves the 35/* remainder, if any, in the last array element. It is an error 36/* to specify a count < 1. 37/* 38/* argv_splitq_append() performs the same operation as argv_splitq(), 39/* but appends the result to an existing string array. 40/* SEE ALSO 41/* mystrtokq(), safe string splitter. 42/* DIAGNOSTICS 43/* Fatal errors: memory allocation problem. 44/* LICENSE 45/* .ad 46/* .fi 47/* The Secure Mailer license must be distributed with this software. 48/* AUTHOR(S) 49/* Wietse Venema 50/* IBM T.J. Watson Research 51/* P.O. Box 704 52/* Yorktown Heights, NY 10598, USA 53/*--*/ 54 55/* System libraries. */ 56 57#include <sys_defs.h> 58#include <string.h> 59 60/* Application-specific. */ 61 62#include "mymalloc.h" 63#include "stringops.h" 64#include "argv.h" 65#include "msg.h" 66 67/* argv_splitq - split string into token array */ 68 69ARGV *argv_splitq(const char *string, const char *delim, const char *parens) 70{ 71 ARGV *argvp = argv_alloc(1); 72 char *saved_string = mystrdup(string); 73 char *bp = saved_string; 74 char *arg; 75 76 while ((arg = mystrtokq(&bp, delim, parens)) != 0) 77 argv_add(argvp, arg, (char *) 0); 78 argv_terminate(argvp); 79 myfree(saved_string); 80 return (argvp); 81} 82 83/* argv_splitq_count - split string into token array */ 84 85ARGV *argv_splitq_count(const char *string, const char *delim, 86 const char *parens, ssize_t count) 87{ 88 ARGV *argvp = argv_alloc(1); 89 char *saved_string = mystrdup(string); 90 char *bp = saved_string; 91 char *arg; 92 93 if (count < 1) 94 msg_panic("argv_splitq_count: bad count: %ld", (long) count); 95 while (count-- > 1 && (arg = mystrtokq(&bp, delim, parens)) != 0) 96 argv_add(argvp, arg, (char *) 0); 97 if (*bp) 98 bp += strspn(bp, delim); 99 if (*bp) 100 argv_add(argvp, bp, (char *) 0); 101 argv_terminate(argvp); 102 myfree(saved_string); 103 return (argvp); 104} 105 106/* argv_splitq_append - split string into token array, append to array */ 107 108ARGV *argv_splitq_append(ARGV *argvp, const char *string, const char *delim, 109 const char *parens) 110{ 111 char *saved_string = mystrdup(string); 112 char *bp = saved_string; 113 char *arg; 114 115 while ((arg = mystrtokq(&bp, delim, parens)) != 0) 116 argv_add(argvp, arg, (char *) 0); 117 argv_terminate(argvp); 118 myfree(saved_string); 119 return (argvp); 120} 121