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