1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #pragma prototyped
23 
24 #include <ast.h>
25 #include <ctype.h>
26 
27 static char**		ids;
28 
29 static const char*	dflt[] = { "ast", "standard", 0 };
30 
31 /*
32  * initialize the conformance() id list
33  */
34 
35 static char**
initconformance(void)36 initconformance(void)
37 {
38 	char*			m;
39 	char**			p;
40 	char*			t;
41 	int			h;
42 	int			i;
43 	int			j;
44 	int			c;
45 	Sfio_t*			sp;
46 
47 	static const char*	conf[] = { "CONFORMANCE", "HOSTTYPE", "UNIVERSE" };
48 
49 	p = 0;
50 	if (sp = sfstropen())
51 	{
52 		for (i = h = 0, j = 1; i < elementsof(conf); i++)
53 			if (*(m = astconf(conf[i], NiL, NiL)) && (h |= (1<<i)) || !i && (m = "ast"))
54 			{
55 				t = m;
56 				while ((c = *m++) && c != '.')
57 				{
58 					if (isupper(c))
59 						c = tolower(c);
60 					sfputc(sp, c);
61 				}
62 				sfputc(sp, 0);
63 				j++;
64 				if ((c = (m - t)) == 6 && strneq(t, "linux", 5))
65 				{
66 					sfputr(sp, "gnu", 0);
67 					j++;
68 				}
69 				else if (c > 3 && strneq(t, "bsd", 3) || c == 7 && strneq(t, "debian", 7))
70 				{
71 					sfputr(sp, "bsd", 0);
72 					j++;
73 				}
74 				if (h & 1)
75 					break;
76 			}
77 		i = sfstrtell(sp);
78 		sfstrseek(sp, 0, SEEK_SET);
79 		if (p = newof(0, char*, j, i))
80 		{
81 			m = (char*)(p + j--);
82 			memcpy(m, sfstrbase(sp), i);
83 			i = 0;
84 			p[i++] = m;
85 			while (i < j)
86 			{
87 				while (*m++);
88 				p[i++] = m;
89 			}
90 			p[i] = 0;
91 		}
92 		sfstrclose(sp);
93 	}
94 	if (!p)
95 		p = (char**)dflt;
96 	return ids = p;
97 }
98 
99 /*
100  * return conformance id if s size n is in conformance
101  * prefix match of s on the conformance id table
102  * s==0 => "standard"
103  */
104 
105 char*
conformance(const char * s,size_t n)106 conformance(const char* s, size_t n)
107 {
108 	char**		p;
109 	char**		q;
110 	char*		m;
111 	const char*	e;
112 	const char*	t;
113 
114 	static uint32_t	serial = ~(uint32_t)0;
115 
116 	if (!(p = ids) || serial != ast.env_serial)
117 	{
118 		serial = ast.env_serial;
119 		if (ids)
120 		{
121 			if (ids != (char**)dflt)
122 				free(ids);
123 			ids = 0;
124 		}
125 		p = initconformance();
126 	}
127 	if (!s)
128 		s = dflt[1];
129 	if (!n)
130 		n = strlen(s);
131 	e = s + n;
132 	if (*s == '(')
133 		s++;
134 	do
135 	{
136 		while (s < e && (isspace(*s) || *s == ',' || *s == '|'))
137 			s++;
138 		if (*s == ')')
139 			break;
140 		for (t = s; s < e && !isspace(*s) && *s != ',' && *s != '|' && *s != ')'; s++);
141 		if (s == t)
142 			break;
143 		q = p;
144 		while (m = *q++)
145 			if (strneq(t, m, s - t))
146 				return m;
147 		if (s < e)
148 			s++;
149 	} while (s < e);
150 	return 0;
151 }
152