xref: /minix3/external/bsd/bind/dist/unit/atf-src/atf-c/detail/text.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: text.c,v 1.3 2014/12/10 04:38:03 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Automated Testing Framework (atf)
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Copyright (c) 2008 The NetBSD Foundation, Inc.
7*00b67f09SDavid van Moolenbroek  * All rights reserved.
8*00b67f09SDavid van Moolenbroek  *
9*00b67f09SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
10*00b67f09SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
11*00b67f09SDavid van Moolenbroek  * are met:
12*00b67f09SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
13*00b67f09SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
14*00b67f09SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
15*00b67f09SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
16*00b67f09SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
17*00b67f09SDavid van Moolenbroek  *
18*00b67f09SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19*00b67f09SDavid van Moolenbroek  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*00b67f09SDavid van Moolenbroek  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21*00b67f09SDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*00b67f09SDavid van Moolenbroek  * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23*00b67f09SDavid van Moolenbroek  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*00b67f09SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25*00b67f09SDavid van Moolenbroek  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*00b67f09SDavid van Moolenbroek  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27*00b67f09SDavid van Moolenbroek  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28*00b67f09SDavid van Moolenbroek  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29*00b67f09SDavid van Moolenbroek  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*00b67f09SDavid van Moolenbroek  */
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include <errno.h>
33*00b67f09SDavid van Moolenbroek #include <limits.h>
34*00b67f09SDavid van Moolenbroek #include <string.h>
35*00b67f09SDavid van Moolenbroek #include <stdlib.h>
36*00b67f09SDavid van Moolenbroek 
37*00b67f09SDavid van Moolenbroek #include "atf-c/error.h"
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek #include "dynstr.h"
40*00b67f09SDavid van Moolenbroek #include "sanity.h"
41*00b67f09SDavid van Moolenbroek #include "text.h"
42*00b67f09SDavid van Moolenbroek 
43*00b67f09SDavid van Moolenbroek atf_error_t
atf_text_for_each_word(const char * instr,const char * sep,atf_error_t (* func)(const char *,void *),void * data)44*00b67f09SDavid van Moolenbroek atf_text_for_each_word(const char *instr, const char *sep,
45*00b67f09SDavid van Moolenbroek                        atf_error_t (*func)(const char *, void *),
46*00b67f09SDavid van Moolenbroek                        void *data)
47*00b67f09SDavid van Moolenbroek {
48*00b67f09SDavid van Moolenbroek     atf_error_t err;
49*00b67f09SDavid van Moolenbroek     char *str, *str2, *last;
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek     str = strdup(instr);
52*00b67f09SDavid van Moolenbroek     if (str == NULL) {
53*00b67f09SDavid van Moolenbroek         err = atf_no_memory_error();
54*00b67f09SDavid van Moolenbroek         goto out;
55*00b67f09SDavid van Moolenbroek     }
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek     err = atf_no_error();
58*00b67f09SDavid van Moolenbroek     str2 = strtok_r(str, sep, &last);
59*00b67f09SDavid van Moolenbroek     while (str2 != NULL && !atf_is_error(err)) {
60*00b67f09SDavid van Moolenbroek         err = func(str2, data);
61*00b67f09SDavid van Moolenbroek         str2 = strtok_r(NULL, sep, &last);
62*00b67f09SDavid van Moolenbroek     }
63*00b67f09SDavid van Moolenbroek 
64*00b67f09SDavid van Moolenbroek     free(str);
65*00b67f09SDavid van Moolenbroek out:
66*00b67f09SDavid van Moolenbroek     return err;
67*00b67f09SDavid van Moolenbroek }
68*00b67f09SDavid van Moolenbroek 
69*00b67f09SDavid van Moolenbroek atf_error_t
atf_text_format(char ** dest,const char * fmt,...)70*00b67f09SDavid van Moolenbroek atf_text_format(char **dest, const char *fmt, ...)
71*00b67f09SDavid van Moolenbroek {
72*00b67f09SDavid van Moolenbroek     atf_error_t err;
73*00b67f09SDavid van Moolenbroek     va_list ap;
74*00b67f09SDavid van Moolenbroek 
75*00b67f09SDavid van Moolenbroek     va_start(ap, fmt);
76*00b67f09SDavid van Moolenbroek     err = atf_text_format_ap(dest, fmt, ap);
77*00b67f09SDavid van Moolenbroek     va_end(ap);
78*00b67f09SDavid van Moolenbroek 
79*00b67f09SDavid van Moolenbroek     return err;
80*00b67f09SDavid van Moolenbroek }
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek atf_error_t
atf_text_format_ap(char ** dest,const char * fmt,va_list ap)83*00b67f09SDavid van Moolenbroek atf_text_format_ap(char **dest, const char *fmt, va_list ap)
84*00b67f09SDavid van Moolenbroek {
85*00b67f09SDavid van Moolenbroek     atf_error_t err;
86*00b67f09SDavid van Moolenbroek     atf_dynstr_t tmp;
87*00b67f09SDavid van Moolenbroek     va_list ap2;
88*00b67f09SDavid van Moolenbroek 
89*00b67f09SDavid van Moolenbroek     va_copy(ap2, ap);
90*00b67f09SDavid van Moolenbroek     err = atf_dynstr_init_ap(&tmp, fmt, ap2);
91*00b67f09SDavid van Moolenbroek     va_end(ap2);
92*00b67f09SDavid van Moolenbroek     if (!atf_is_error(err))
93*00b67f09SDavid van Moolenbroek         *dest = atf_dynstr_fini_disown(&tmp);
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek     return err;
96*00b67f09SDavid van Moolenbroek }
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek atf_error_t
atf_text_split(const char * str,const char * delim,atf_list_t * words)99*00b67f09SDavid van Moolenbroek atf_text_split(const char *str, const char *delim, atf_list_t *words)
100*00b67f09SDavid van Moolenbroek {
101*00b67f09SDavid van Moolenbroek     atf_error_t err;
102*00b67f09SDavid van Moolenbroek     const char *end;
103*00b67f09SDavid van Moolenbroek     const char *iter;
104*00b67f09SDavid van Moolenbroek 
105*00b67f09SDavid van Moolenbroek     err = atf_list_init(words);
106*00b67f09SDavid van Moolenbroek     if (atf_is_error(err))
107*00b67f09SDavid van Moolenbroek         goto err;
108*00b67f09SDavid van Moolenbroek 
109*00b67f09SDavid van Moolenbroek     end = str + strlen(str);
110*00b67f09SDavid van Moolenbroek     INV(*end == '\0');
111*00b67f09SDavid van Moolenbroek     iter = str;
112*00b67f09SDavid van Moolenbroek     while (iter < end) {
113*00b67f09SDavid van Moolenbroek         const char *ptr;
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek         INV(iter != NULL);
116*00b67f09SDavid van Moolenbroek         ptr = strstr(iter, delim);
117*00b67f09SDavid van Moolenbroek         if (ptr == NULL)
118*00b67f09SDavid van Moolenbroek             ptr = end;
119*00b67f09SDavid van Moolenbroek 
120*00b67f09SDavid van Moolenbroek         INV(ptr >= iter);
121*00b67f09SDavid van Moolenbroek         if (ptr > iter) {
122*00b67f09SDavid van Moolenbroek             atf_dynstr_t word;
123*00b67f09SDavid van Moolenbroek 
124*00b67f09SDavid van Moolenbroek             err = atf_dynstr_init_raw(&word, iter, ptr - iter);
125*00b67f09SDavid van Moolenbroek             if (atf_is_error(err))
126*00b67f09SDavid van Moolenbroek                 goto err_list;
127*00b67f09SDavid van Moolenbroek 
128*00b67f09SDavid van Moolenbroek             err = atf_list_append(words, atf_dynstr_fini_disown(&word), true);
129*00b67f09SDavid van Moolenbroek             if (atf_is_error(err))
130*00b67f09SDavid van Moolenbroek                 goto err_list;
131*00b67f09SDavid van Moolenbroek         }
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek         iter = ptr + strlen(delim);
134*00b67f09SDavid van Moolenbroek     }
135*00b67f09SDavid van Moolenbroek 
136*00b67f09SDavid van Moolenbroek     INV(!atf_is_error(err));
137*00b67f09SDavid van Moolenbroek     return err;
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek err_list:
140*00b67f09SDavid van Moolenbroek     atf_list_fini(words);
141*00b67f09SDavid van Moolenbroek err:
142*00b67f09SDavid van Moolenbroek     return err;
143*00b67f09SDavid van Moolenbroek }
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek atf_error_t
atf_text_to_bool(const char * str,bool * b)146*00b67f09SDavid van Moolenbroek atf_text_to_bool(const char *str, bool *b)
147*00b67f09SDavid van Moolenbroek {
148*00b67f09SDavid van Moolenbroek     atf_error_t err;
149*00b67f09SDavid van Moolenbroek 
150*00b67f09SDavid van Moolenbroek     if (strcasecmp(str, "yes") == 0 ||
151*00b67f09SDavid van Moolenbroek         strcasecmp(str, "true") == 0) {
152*00b67f09SDavid van Moolenbroek         *b = true;
153*00b67f09SDavid van Moolenbroek         err = atf_no_error();
154*00b67f09SDavid van Moolenbroek     } else if (strcasecmp(str, "no") == 0 ||
155*00b67f09SDavid van Moolenbroek                strcasecmp(str, "false") == 0) {
156*00b67f09SDavid van Moolenbroek         *b = false;
157*00b67f09SDavid van Moolenbroek         err = atf_no_error();
158*00b67f09SDavid van Moolenbroek     } else {
159*00b67f09SDavid van Moolenbroek         /* XXX Not really a libc error. */
160*00b67f09SDavid van Moolenbroek         err = atf_libc_error(EINVAL, "Cannot convert string '%s' "
161*00b67f09SDavid van Moolenbroek                              "to boolean", str);
162*00b67f09SDavid van Moolenbroek     }
163*00b67f09SDavid van Moolenbroek 
164*00b67f09SDavid van Moolenbroek     return err;
165*00b67f09SDavid van Moolenbroek }
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek atf_error_t
atf_text_to_long(const char * str,long * l)168*00b67f09SDavid van Moolenbroek atf_text_to_long(const char *str, long *l)
169*00b67f09SDavid van Moolenbroek {
170*00b67f09SDavid van Moolenbroek     atf_error_t err;
171*00b67f09SDavid van Moolenbroek     char *endptr;
172*00b67f09SDavid van Moolenbroek     long tmp;
173*00b67f09SDavid van Moolenbroek 
174*00b67f09SDavid van Moolenbroek     errno = 0;
175*00b67f09SDavid van Moolenbroek     tmp = strtol(str, &endptr, 10);
176*00b67f09SDavid van Moolenbroek     if (str[0] == '\0' || *endptr != '\0')
177*00b67f09SDavid van Moolenbroek         err = atf_libc_error(EINVAL, "'%s' is not a number", str);
178*00b67f09SDavid van Moolenbroek     else if (errno == ERANGE || (tmp == LONG_MAX || tmp == LONG_MIN))
179*00b67f09SDavid van Moolenbroek         err = atf_libc_error(ERANGE, "'%s' is out of range", str);
180*00b67f09SDavid van Moolenbroek     else {
181*00b67f09SDavid van Moolenbroek         *l = tmp;
182*00b67f09SDavid van Moolenbroek         err = atf_no_error();
183*00b67f09SDavid van Moolenbroek     }
184*00b67f09SDavid van Moolenbroek 
185*00b67f09SDavid van Moolenbroek     return err;
186*00b67f09SDavid van Moolenbroek }
187