xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/argv_splitq.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
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