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 
argv_splitq(const char * string,const char * delim,const char * parens)69 ARGV   *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 
argv_splitq_count(const char * string,const char * delim,const char * parens,ssize_t count)85 ARGV   *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 
argv_splitq_append(ARGV * argvp,const char * string,const char * delim,const char * parens)108 ARGV   *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