int _Locterm(const char **ps, unsigned long *ans) { /* evaluate a term on a locale file line */ const char *s = *ps; const char *s1; int mi; unsigned long *pvars = _TLS_ARR(vars); for (mi = 0; *s == '+' || *s == '-'; s = _Skip(s)) mi = *s == '-' ? !mi : mi; if (isdigit((unsigned char)s[0])) *ans = strtoul(s, (char **)&s, 0); else if (s[0] == '\'' && s[1] != '\0' && s[2] == '\'') *ans = ((unsigned char *)s)[1], s += 3; else if (s[0] && (s1 = strchr(uppers, s[0])) != 0) *ans = pvars[s1 - uppers], ++s; else if (s[0] == '$' && s[1] && (s1 = strchr(dollars, s[1])) != 0) *ans = dolvals[s1 - dollars], s += 2; else return (0); if (mi) *ans = 0 - *ans; *ps = _Skip(s - 1); return (1); }
_Locitem *_Readloc(FILE *lf, char *buf, const char **ps) { /* get a line from locale file */ for (; ; ) { /* loop until EOF or full line */ size_t n; for (buf[0] = ' ', n = 1; ; n -= 2) if (fgets(buf + n, MAXLIN - n, lf) == NULL || buf[(n += strlen(buf + n)) - 1] != '\n') return (NULL); /* EOF or line too long */ else if (n <= 1 || buf[n - 2] != '\\') break; /* continue only if ends in \ */ buf[n - 1] = '\0'; /* overwrite newline */ { /* look for keyword on line */ const char *s = _Skip(buf); _Locitem *q; if (0 < (n = strspn(s, kc))) for (q = _Loctab; q->_Name; ++q) if (strncmp(q->_Name, s, n) == 0 && strlen(q->_Name) == n) { /* found a match */ *ps = _Skip(s + n - 1); return (q); } return (NULL); /* unknown or missing keyword */ } } }
_STD_BEGIN int _Makestab(_Linfo *p, const _Locitem *q, const char *s) { /* process tab[#,lo:hi] $x expr */ int inc = 0; unsigned long hi, lo, stno, val; unsigned short *usp, **uspp; if (*s != '[' || (s = _Locsum(_Skip(s), &stno)) == 0) return (0); if (*s != ',') lo = stno, stno = 0; else if (q->_Code != L_STATE || _NSTATE <= stno || (s = _Locsum(_Skip(s), &lo)) == 0) return (0); lo = (unsigned char)lo; if (*s != ':') hi = lo; else if ((s = _Locsum(_Skip(s), &hi)) == 0) return (0); else hi = (unsigned char)hi; if (*s != ']') return (0); for (s = _Skip(s); s[0] == '$'; s = _Skip(s + 1)) if (s[1] == '@' && (inc & 1) == 0) inc |= 1; else if (s[1] == '$' && (inc & 2) == 0) inc |= 2; else break; if ((s = _Locsum(s, &val)) == 0 && inc == 0 || s != 0 && *s != '\0') return (0); uspp = &ADDR(p, q, unsigned short *) + (int)(stno & 0xf); if (q->_Code == L_TABLE) usp = NEWADDR(p, q, short *) ? *uspp : 0; else