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