From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/5669 Path: news.gmane.org!not-for-mail From: Szabolcs Nagy Newsgroups: gmane.linux.lib.musl.general Subject: Re: Non-stub gettext API functions committed, ready for testing Date: Mon, 28 Jul 2014 15:00:17 +0200 Message-ID: <20140728130017.GK10402@port70.net> References: <20140727084633.GA22355@brightrain.aerifal.cx> <53D4CF09.1050209@gmx.de> <20140727141417.GG10402@port70.net> <20140727164921.GY4038@brightrain.aerifal.cx> <20140727172308.GH10402@port70.net> <20140727173605.GZ4038@brightrain.aerifal.cx> <20140727175125.GI10402@port70.net> <20140727180041.GA4038@brightrain.aerifal.cx> <20140728101829.GJ10402@port70.net> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="cmJC7u66zC7hs+87" X-Trace: ger.gmane.org 1406552437 23202 80.91.229.3 (28 Jul 2014 13:00:37 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 28 Jul 2014 13:00:37 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-5674-gllmg-musl=m.gmane.org@lists.openwall.com Mon Jul 28 15:00:31 2014 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1XBkXW-0007sT-4b for gllmg-musl@plane.gmane.org; Mon, 28 Jul 2014 15:00:30 +0200 Original-Received: (qmail 12059 invoked by uid 550); 28 Jul 2014 13:00:29 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 12051 invoked from network); 28 Jul 2014 13:00:28 -0000 Mail-Followup-To: musl@lists.openwall.com Content-Disposition: inline In-Reply-To: <20140728101829.GJ10402@port70.net> User-Agent: Mutt/1.5.21 (2010-09-15) Xref: news.gmane.org gmane.linux.lib.musl.general:5669 Archived-At: --cmJC7u66zC7hs+87 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline * Szabolcs Nagy [2014-07-28 12:18:30 +0200]: > the parser and eval code is about 2k now, i can try to do it > without a separate parsing step (my approach requires a 100-200 > byte buffer to store the parsed expr now) > attached a simpler solution without separate parsing (code is about 1.4k now, and it is more compatible with gnu gettext) --cmJC7u66zC7hs+87 Content-Type: text/x-csrc; charset=us-ascii Content-Disposition: attachment; filename="pl.c" #include #include #include "pl.h" /* grammar: Start = Expr ';' Expr = Or | Or '?' Expr ':' Expr Or = And | Or '||' And And = Eq | And '&&' Eq Eq = Rel | Eq '==' Rel | Eq '!=' Rel Rel = Add | Rel '<=' Add | Rel '>=' Add | Rel '<' Add | Rel '>' Add Add = Mul | Add '+' Mul | Add '-' Mul Mul = Term | Mul '*' Term | Mul '/' decimal | Mul '%' decimal Term = '(' Expr ')' | '!' Term | decimal | 'n' internals: recursive descent expression evaluator with stack depth limit. eval* functions return the value of the subexpression and set the current string pointer to the next non-space char. */ struct st { const char *s; unsigned long n; int err; }; static const char *skipspace(const char *s) { while (isspace(*s)) s++; return s; } static unsigned long evalconst(struct st *st) { char *e; unsigned long n; n = strtoul(st->s, &e, 10); if (!isdigit(*st->s) || e == st->s || n == -1) st->err = 1; st->s = skipspace(e); return n; } static unsigned long evalexpr(struct st *st, int d); static unsigned long evalterm(struct st *st, int d) { unsigned long a; if (d <= 0) { st->err = 1; return 0; } st->s = skipspace(st->s); if (*st->s == '!') { st->s++; return !evalterm(st, d-1); } if (*st->s == '(') { st->s++; a = evalexpr(st, d-1); if (*st->s != ')') { st->err = 1; return 0; } st->s = skipspace(st->s + 1); return a; } if (*st->s == 'n') { st->s = skipspace(st->s + 1); return st->n; } return evalconst(st); } static unsigned long evalmul(struct st *st, int d) { unsigned long b, a = evalterm(st, d-1); int op; for (;;) { op = *st->s; if (op != '*' && op != '/' && op != '%') return a; st->s++; b = evalterm(st, d-1); if (op == '*') { a *= b; } else if (!b) { st->err = 1; return 0; } else if (op == '%') { a %= b; } else { a /= b; } } } static unsigned long evaladd(struct st *st, int d) { unsigned long a = 0; int add = 1; for (;;) { a += (add?1:-1) * evalmul(st, d-1); if (*st->s != '+' && *st->s != '-') return a; add = *st->s == '+'; st->s++; } } static unsigned long evalrel(struct st *st, int d) { unsigned long b, a = evaladd(st, d-1); int less, eq; for (;;) { if (*st->s != '<' && *st->s != '>') return a; less = st->s[0] == '<'; eq = st->s[1] == '='; st->s += 1 + eq; b = evaladd(st, d-1); a = (less ? a < b : a > b) || (eq && a == b); } } static unsigned long evaleq(struct st *st, int d) { unsigned long a = evalrel(st, d-1); int neg; for (;;) { if ((st->s[0] != '=' && st->s[0] != '!') || st->s[1] != '=') return a; neg = st->s[0] == '!'; st->s += 2; a = evalrel(st, d-1) == a; a ^= neg; } } static unsigned long evaland(struct st *st, int d) { unsigned long a = evaleq(st, d-1); for (;;) { if (st->s[0] != '&' || st->s[1] != '&') return a; st->s += 2; a = evaleq(st, d-1) && a; } } static unsigned long evalor(struct st *st, int d) { unsigned long a = evaland(st, d-1); for (;;) { if (st->s[0] != '|' || st->s[1] != '|') return a; st->s += 2; a = evaland(st, d-1) || a; } } static unsigned long evalexpr(struct st *st, int d) { unsigned long a1, a2, a3; if (d <= 0) { st->err = 1; return 0; } a1 = evalor(st, d-1); if (*st->s != '?') return a1; st->s++; a2 = evalexpr(st, d-1); if (*st->s != ':') { st->err = 1; return 0; } st->s++; a3 = evalexpr(st, d-1); return a1 ? a2 : a3; } unsigned long eval(const char *s, size_t len, unsigned long n) { unsigned long a; const char *e = s+len-1; struct st st; if (*e != ';') return -1; st.s = s; st.n = n; st.err = 0; a = evalexpr(&st, 100); if (st.err || st.s != e) return -1; return a; } --cmJC7u66zC7hs+87--