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