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