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