1*67b9b338Schristos /* $NetBSD: argv_split_at.c,v 1.2 2022/10/08 16:12:50 christos Exp $ */
24a672054Schristos
34a672054Schristos /*++
44a672054Schristos /* NAME
54a672054Schristos /* argv_split_at 3
64a672054Schristos /* SUMMARY
74a672054Schristos /* string array utilities
84a672054Schristos /* SYNOPSIS
94a672054Schristos /* #include <argv.h>
104a672054Schristos /*
114a672054Schristos /* ARGV *argv_split_at(string, sep)
124a672054Schristos /* const char *string;
134a672054Schristos /* int sep;
144a672054Schristos /*
154a672054Schristos /* ARGV *argv_split_at_count(string, sep, count)
164a672054Schristos /* const char *string;
174a672054Schristos /* int sep;
184a672054Schristos /* ssize_t count;
194a672054Schristos /*
204a672054Schristos /* ARGV *argv_split_at_append(argv, string, sep)
214a672054Schristos /* ARGV *argv;
224a672054Schristos /* const char *string;
234a672054Schristos /* int sep;
244a672054Schristos /* DESCRIPTION
254a672054Schristos /* argv_split_at() splits \fIstring\fR into fields using a
264a672054Schristos /* single separator specified in \fIsep\fR. The result is a
274a672054Schristos /* null-terminated string array.
284a672054Schristos /*
294a672054Schristos /* argv_split_at_count() is like argv_split_at() but stops
304a672054Schristos /* splitting input after at most \fIcount\fR -1 times and
314a672054Schristos /* leaves the remainder, if any, in the last array element.
324a672054Schristos /* It is an error to specify a count < 1.
334a672054Schristos /*
344a672054Schristos /* argv_split_at_append() performs the same operation as
354a672054Schristos /* argv_split_at(), but appends the result to an existing
364a672054Schristos /* string array.
374a672054Schristos /* SEE ALSO
384a672054Schristos /* split_at(), trivial string splitter.
394a672054Schristos /* DIAGNOSTICS
404a672054Schristos /* Fatal errors: memory allocation problem.
414a672054Schristos /* LICENSE
424a672054Schristos /* .ad
434a672054Schristos /* .fi
444a672054Schristos /* The Secure Mailer license must be distributed with this software.
454a672054Schristos /* AUTHOR(S)
464a672054Schristos /* Wietse Venema
474a672054Schristos /* IBM T.J. Watson Research
484a672054Schristos /* P.O. Box 704
494a672054Schristos /* Yorktown Heights, NY 10598, USA
504a672054Schristos /*
514a672054Schristos /* Wietse Venema
524a672054Schristos /* Google, Inc.
534a672054Schristos /* 111 8th Avenue
544a672054Schristos /* New York, NY 10011, USA
554a672054Schristos /*--*/
564a672054Schristos
574a672054Schristos /* System libraries. */
584a672054Schristos
594a672054Schristos #include <sys_defs.h>
604a672054Schristos #include <string.h>
614a672054Schristos
624a672054Schristos /* Application-specific. */
634a672054Schristos
644a672054Schristos #include <mymalloc.h>
654a672054Schristos #include <stringops.h>
664a672054Schristos #include <argv.h>
674a672054Schristos #include <msg.h>
684a672054Schristos #include <split_at.h>
694a672054Schristos
704a672054Schristos /* argv_split_at - split string into field array */
714a672054Schristos
argv_split_at(const char * string,int sep)724a672054Schristos ARGV *argv_split_at(const char *string, int sep)
734a672054Schristos {
744a672054Schristos ARGV *argvp = argv_alloc(1);
754a672054Schristos char *saved_string = mystrdup(string);
764a672054Schristos char *bp = saved_string;
774a672054Schristos char *arg;
784a672054Schristos
794a672054Schristos while ((arg = split_at(bp, sep)) != 0) {
804a672054Schristos argv_add(argvp, bp, (char *) 0);
814a672054Schristos bp = arg;
824a672054Schristos }
834a672054Schristos argv_add(argvp, bp, (char *) 0);
844a672054Schristos argv_terminate(argvp);
854a672054Schristos myfree(saved_string);
864a672054Schristos return (argvp);
874a672054Schristos }
884a672054Schristos
894a672054Schristos /* argv_split_at_count - split string into field array */
904a672054Schristos
argv_split_at_count(const char * string,int sep,ssize_t count)914a672054Schristos ARGV *argv_split_at_count(const char *string, int sep, ssize_t count)
924a672054Schristos {
934a672054Schristos ARGV *argvp = argv_alloc(1);
944a672054Schristos char *saved_string = mystrdup(string);
954a672054Schristos char *bp = saved_string;
964a672054Schristos char *arg;
974a672054Schristos
984a672054Schristos if (count < 1)
994a672054Schristos msg_panic("argv_split_at_count: bad count: %ld", (long) count);
1004a672054Schristos while (count-- > 1 && (arg = split_at(bp, sep)) != 0) {
1014a672054Schristos argv_add(argvp, bp, (char *) 0);
1024a672054Schristos bp = arg;
1034a672054Schristos }
1044a672054Schristos argv_add(argvp, bp, (char *) 0);
1054a672054Schristos argv_terminate(argvp);
1064a672054Schristos myfree(saved_string);
1074a672054Schristos return (argvp);
1084a672054Schristos }
1094a672054Schristos
1104a672054Schristos /* argv_split_at_append - split string into field array, append to array */
1114a672054Schristos
argv_split_at_append(ARGV * argvp,const char * string,int sep)1124a672054Schristos ARGV *argv_split_at_append(ARGV *argvp, const char *string, int sep)
1134a672054Schristos {
1144a672054Schristos char *saved_string = mystrdup(string);
1154a672054Schristos char *bp = saved_string;
1164a672054Schristos char *arg;
1174a672054Schristos
1184a672054Schristos while ((arg = split_at(bp, sep)) != 0) {
1194a672054Schristos argv_add(argvp, bp, (char *) 0);
1204a672054Schristos bp = arg;
1214a672054Schristos }
1224a672054Schristos argv_add(argvp, bp, (char *) 0);
1234a672054Schristos argv_terminate(argvp);
1244a672054Schristos myfree(saved_string);
1254a672054Schristos return (argvp);
1264a672054Schristos }
127