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
27static char**		ids;
28
29static const char*	dflt[] = { "ast", "standard", 0 };
30
31/*
32 * initialize the conformance() id list
33 */
34
35static char**
36initconformance(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
105char*
106conformance(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