From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/5672 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: Tue, 29 Jul 2014 15:49:46 +0200 Message-ID: <20140729134946.GM10402@port70.net> References: <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> <20140728130017.GK10402@port70.net> <20140728140151.GL10402@port70.net> <20140728162731.GD1674@brightrain.aerifal.cx> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="UFHRwCdBEJvubb2X" X-Trace: ger.gmane.org 1406641814 6757 80.91.229.3 (29 Jul 2014 13:50:14 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 29 Jul 2014 13:50:14 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-5677-gllmg-musl=m.gmane.org@lists.openwall.com Tue Jul 29 15:50:06 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 1XC7my-0004Q2-IQ for gllmg-musl@plane.gmane.org; Tue, 29 Jul 2014 15:50:00 +0200 Original-Received: (qmail 11756 invoked by uid 550); 29 Jul 2014 13:49:59 -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 11748 invoked from network); 29 Jul 2014 13:49:58 -0000 Mail-Followup-To: musl@lists.openwall.com Content-Disposition: inline In-Reply-To: <20140728162731.GD1674@brightrain.aerifal.cx> User-Agent: Mutt/1.5.21 (2010-09-15) Xref: news.gmane.org gmane.linux.lib.musl.general:5672 Archived-At: --UFHRwCdBEJvubb2X Content-Type: text/plain; charset=us-ascii Content-Disposition: inline * Rich Felker [2014-07-28 12:27:32 -0400]: > My leaning is to go with the version that's smaller and more flexible; > I think the time spent in this function will usually be heavily > dominated by the binary search for the message text. But it's cool to > have both for possible future uses (independent of musl, even). i have a bit smaller pleval.c version: non-pic .o with -Os is 980 vs 826 bytes here, has about the same speed, binary op parsing is a bit magical otherwise clean --UFHRwCdBEJvubb2X Content-Type: text/x-csrc; charset=us-ascii Content-Disposition: attachment; filename="pleval.c" #include #include /* 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 '/' Term | Mul '%' Term 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 fail(struct st *st) { st->err = 1; return 0; } static unsigned long evalexpr(struct st *st, int d); static unsigned long evalterm(struct st *st, int d) { unsigned long a; char *e; if (--d < 0) return fail(st); st->s = skipspace(st->s); if (*st->s == '!') { st->s++; return !evalterm(st, d); } if (*st->s == '(') { st->s++; a = evalexpr(st, d); if (*st->s != ')') return fail(st); st->s = skipspace(st->s + 1); return a; } if (*st->s == 'n') { st->s = skipspace(st->s + 1); return st->n; } a = strtoul(st->s, &e, 10); if (!isdigit(*st->s) || e == st->s || a == -1) return fail(st); st->s = skipspace(e); return a; } static unsigned long binop(struct st *st, int op, unsigned long a, unsigned long b) { switch (op&0xff) { case 0: return a||b; case 1: return a&&b; case 2: return a==b; case 3: return a!=b; case 4: return a>=b; case 5: return a<=b; case 6: return a>b; case 7: return as == opch[i]) { p = prec[i]<<8; if (i<6 && st->s[1] == opch[i+12]) { st->s+=2; return i | p; } if (i>=4) { st->s++; return i+2 | p; } return 0; } return 0; } static unsigned long evalbinop2(struct st *st, int op, unsigned long a, int d) { unsigned long a2; int op2, highprec; d--; for (;;) { a2 = evalterm(st, d); op2 = parseop(st); highprec = op2>>8 > op>>8; if (highprec) a2 = evalbinop2(st, op2, a2, d); a = binop(st, op, a, a2); if (!op2 || highprec) return a; op = op2; } } static unsigned long evalbinop(struct st *st, int d) { unsigned long a; int op; a = evalterm(st, d); op = parseop(st); if (!op) return a; return evalbinop2(st, op, a, d); } static unsigned long evalexpr(struct st *st, int d) { unsigned long a1, a2, a3; if (--d < 0) return fail(st); a1 = evalbinop(st, d); if (*st->s != '?') return a1; st->s++; a2 = evalexpr(st, d); if (*st->s != ':') return fail(st); st->s++; a3 = evalexpr(st, d); return a1 ? a2 : a3; } unsigned long __pleval(const char *s, unsigned long n) { unsigned long a; struct st st; st.s = s; st.n = n; st.err = 0; a = evalexpr(&st, 100); if (st.err || *st.s != ';') return -1; return a; } --UFHRwCdBEJvubb2X--