xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/argv_split_at.c (revision 67b9b338a7386232ac596b5fd0cd5a9cc8a03c71)
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