1 /*
2  * Copyright (c) 2003-2012 Tim Kientzle
3  * Copyright (c) 2012 Andres Mejia
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "test_utils.h"
28 
29 #include <stdlib.h>
30 #include <string.h>
31 
32 /* Filter tests against a glob pattern. Returns non-zero if test matches
33  * pattern, zero otherwise. A '^' at the beginning of the pattern negates
34  * the return values (i.e. returns zero for a match, non-zero otherwise.
35  */
36 static int
37 test_filter(const char *pattern, const char *test)
38 {
39 	int retval = 0;
40 	int negate = 0;
41 	const char *p = pattern;
42 	const char *t = test;
43 
44 	if (p[0] == '^')
45 	{
46 		negate = 1;
47 		p++;
48 	}
49 
50 	while (1)
51 	{
52 		if (p[0] == '\\')
53 			p++;
54 		else if (p[0] == '*')
55 		{
56 			while (p[0] == '*')
57 				p++;
58 			if (p[0] == '\\')
59 				p++;
60 			if ((t = strchr(t, p[0])) == 0)
61 				break;
62 		}
63 		if (p[0] != t[0])
64 			break;
65 		if (p[0] == '\0') {
66 			retval = 1;
67 			break;
68 		}
69 		p++;
70 		t++;
71 	}
72 
73 	return (negate) ? !retval : retval;
74 }
75 
76 int get_test_set(int *test_set, int limit, const char *test,
77 	struct test_list_t *tests)
78 {
79 	int start, end;
80 	int idx = 0;
81 
82 	if (test == NULL) {
83 		/* Default: Run all tests. */
84 		for (;idx < limit; idx++)
85 			test_set[idx] = idx;
86 		return (limit);
87 	}
88 	if (*test >= '0' && *test <= '9') {
89 		const char *vp = test;
90 		start = 0;
91 		while (*vp >= '0' && *vp <= '9') {
92 			start *= 10;
93 			start += *vp - '0';
94 			++vp;
95 		}
96 		if (*vp == '\0') {
97 			end = start;
98 		} else if (*vp == '-') {
99 			++vp;
100 			if (*vp == '\0') {
101 				end = limit - 1;
102 			} else {
103 				end = 0;
104 				while (*vp >= '0' && *vp <= '9') {
105 					end *= 10;
106 					end += *vp - '0';
107 					++vp;
108 				}
109 			}
110 		} else
111 			return (-1);
112 		if (start < 0 || end >= limit || start > end)
113 			return (-1);
114 		while (start <= end)
115 			test_set[idx++] = start++;
116 	} else {
117 		for (start = 0; start < limit; ++start) {
118 			const char *name = tests[start].name;
119 			if (test_filter(test, name))
120 				test_set[idx++] = start;
121 		}
122 	}
123 	return ((idx == 0)?-1:idx);
124 }
125