From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/7123 Path: news.gmane.org!not-for-mail From: Sergey Dmitrouk Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH] conforming strverscmp() implementation Date: Tue, 3 Mar 2015 12:45:07 +0200 Message-ID: <20150303104507.GA5094@zx-spectrum> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="uAKRQypu60I7Lcqm" X-Trace: ger.gmane.org 1425379511 1359 80.91.229.3 (3 Mar 2015 10:45:11 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 3 Mar 2015 10:45:11 +0000 (UTC) To: Original-X-From: musl-return-7136-gllmg-musl=m.gmane.org@lists.openwall.com Tue Mar 03 11:45:11 2015 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1YSkK7-0002js-B1 for gllmg-musl@m.gmane.org; Tue, 03 Mar 2015 11:45:11 +0100 Original-Received: (qmail 7877 invoked by uid 550); 3 Mar 2015 10:45:09 -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 7839 invoked from network); 3 Mar 2015 10:45:05 -0000 Content-Disposition: inline Xref: news.gmane.org gmane.linux.lib.musl.general:7123 Archived-At: --uAKRQypu60I7Lcqm Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline Hi, Attached is strverscmp() that should conform to what is described in manual pages. It's not actually a diff as it would be harder to read in this case. The idea is just as described in manuals (once you get what they mean): 1. Find point where strings differ as in current code, but keep track of locations of last seen numbers. 2. If numbers are both integers (that is they don't start with zero or it's a single zero) compare as in current implementation. 3. If only one of numbers is integer, the other one is smaller. 4. Otherwise, number with longer leading sequence of zeroes is smaller. 5. If leading zeroes match, compare characters following last zero in both strings. I didn't see much comments in musl, so there is none in this file, but can add some if requested. Implementation is admittedly more sophisticated than current version for the reason that all simpler approaches I tried fail for at least one of possible comparison cases. Regards, Sergey --uAKRQypu60I7Lcqm Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="strverscmp.c" #define _GNU_SOURCE #include #include int strverscmp(const char *l, const char *r) { const char *ln=(isdigit(*l) ? l : NULL), *rn=(isdigit(*r) ? r : NULL); while (*l==*r) { if (!*l) return 0; if (isdigit(*l)) { if (ln == NULL) { ln = l; rn = r; } } else { ln = NULL; rn = NULL; } l++; r++; } if ((*l != '\0' && !isdigit(*l)) || (*r != '\0' && !isdigit(*r))) { ln = NULL; rn = NULL; } if (ln != NULL) { int intl=(*ln != '0' || !isdigit(*(ln + 1))); int intr=(*rn != '0' || !isdigit(*(rn + 1))); if (intl ^ intr) { return intl ? 1 : -1; } else if (intl) { size_t lenl=0, lenr=0; while (isdigit(l[lenl])) lenl++; while (isdigit(r[lenr])) lenr++; if (lenl==lenr) { return (*l - *r); } else if (lenl>lenr) { return 1; } else { return -1; } } else { size_t zl=0, zr=0; while (ln[zl]=='0') zl++; while (rn[zr]=='0') zr++; if (zl>zr) { return -1; } else if (zl