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