diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
commit | 3950ffe2a485479f6561c27364d3d7df5a21d124 (patch) | |
tree | 468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/misc/conformance.c | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/misc/conformance.c')
-rw-r--r-- | src/lib/libast/misc/conformance.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/lib/libast/misc/conformance.c b/src/lib/libast/misc/conformance.c new file mode 100644 index 0000000..12ee2ca --- /dev/null +++ b/src/lib/libast/misc/conformance.c @@ -0,0 +1,151 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped + +#include <ast.h> +#include <ctype.h> + +static char** ids; + +static const char* dflt[] = { "ast", "standard", 0 }; + +/* + * initialize the conformance() id list + */ + +static char** +initconformance(void) +{ + char* m; + char** p; + char* t; + int h; + int i; + int j; + int c; + Sfio_t* sp; + + static const char* conf[] = { "CONFORMANCE", "HOSTTYPE", "UNIVERSE" }; + + p = 0; + if (sp = sfstropen()) + { + for (i = h = 0, j = 1; i < elementsof(conf); i++) + if (*(m = astconf(conf[i], NiL, NiL)) && (h |= (1<<i)) || !i && (m = "ast")) + { + t = m; + while ((c = *m++) && c != '.') + { + if (isupper(c)) + c = tolower(c); + sfputc(sp, c); + } + sfputc(sp, 0); + j++; + if ((c = (m - t)) == 6 && strneq(t, "linux", 5)) + { + sfputr(sp, "gnu", 0); + j++; + } + else if (c > 3 && strneq(t, "bsd", 3) || c == 7 && strneq(t, "debian", 7)) + { + sfputr(sp, "bsd", 0); + j++; + } + if (h & 1) + break; + } + i = sfstrtell(sp); + sfstrseek(sp, 0, SEEK_SET); + if (p = newof(0, char*, j, i)) + { + m = (char*)(p + j--); + memcpy(m, sfstrbase(sp), i); + i = 0; + p[i++] = m; + while (i < j) + { + while (*m++); + p[i++] = m; + } + p[i] = 0; + } + sfstrclose(sp); + } + if (!p) + p = (char**)dflt; + return ids = p; +} + +/* + * return conformance id if s size n is in conformance + * prefix match of s on the conformance id table + * s==0 => "standard" + */ + +char* +conformance(const char* s, size_t n) +{ + char** p; + char** q; + char* m; + const char* e; + const char* t; + + static uint32_t serial = ~(uint32_t)0; + + if (!(p = ids) || serial != ast.env_serial) + { + serial = ast.env_serial; + if (ids) + { + if (ids != (char**)dflt) + free(ids); + ids = 0; + } + p = initconformance(); + } + if (!s) + s = dflt[1]; + if (!n) + n = strlen(s); + e = s + n; + if (*s == '(') + s++; + do + { + while (s < e && (isspace(*s) || *s == ',' || *s == '|')) + s++; + if (*s == ')') + break; + for (t = s; s < e && !isspace(*s) && *s != ',' && *s != '|' && *s != ')'; s++); + if (s == t) + break; + q = p; + while (m = *q++) + if (strneq(t, m, s - t)) + return m; + if (s < e) + s++; + } while (s < e); + return 0; +} |