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