From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753070AbbEBAxc (ORCPT ); Fri, 1 May 2015 20:53:32 -0400 Received: from mail-wg0-f52.google.com ([74.125.82.52]:33135 "EHLO mail-wg0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750961AbbEBAx2 (ORCPT ); Fri, 1 May 2015 20:53:28 -0400 Date: Sat, 2 May 2015 03:53:24 +0300 From: Alexey Dobriyan To: akpm@linux-foundation.org Cc: linux-kernel@vger.kernel.org Subject: [PATCH 05/10] parse_integer: convert lib/ Message-ID: <20150502005324.GE21655@p183.telecom.by> References: <20150502004714.GA21655@p183.telecom.by> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150502004714.GA21655@p183.telecom.by> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Convert away lib/ from deprecated simple_strto*() interfaces. "&(int []){0}[0]" expression is anonymous variable, don't be scared. Filesystem option parser code does parsing 1.5 times: first to know boundaries of a value (args[0].from, args[0].to) and then actual parsing with match_number(). Noody knows why it does that. match_number() needlessly allocates/duplicates memory, parsing can be done straight from original string. Signed-off-by: Alexey Dobriyan --- lib/cmdline.c | 36 ++++++++++++++++++------------------ lib/parser.c | 29 ++++++++++++----------------- lib/swiotlb.c | 2 +- 3 files changed, 31 insertions(+), 36 deletions(-) --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -27,7 +27,7 @@ static int get_range(char **str, int *pint) int x, inc_counter, upper_range; (*str)++; - upper_range = simple_strtol((*str), NULL, 0); + parse_integer(*str, 0, &upper_range); inc_counter = upper_range - *pint; for (x = *pint; x < upper_range; x++) *pint++ = x; @@ -51,13 +51,14 @@ static int get_range(char **str, int *pint) int get_option(char **str, int *pint) { - char *cur = *str; + int len; - if (!cur || !(*cur)) + if (!str || !*str) return 0; - *pint = simple_strtol(cur, str, 0); - if (cur == *str) + len = parse_integer(*str, 0, pint); + if (len < 0) return 0; + *str += len; if (**str == ',') { (*str)++; return 2; @@ -126,38 +127,37 @@ EXPORT_SYMBOL(get_options); unsigned long long memparse(const char *ptr, char **retptr) { - char *endptr; /* local pointer to end of parsed string */ + unsigned long long val; - unsigned long long ret = simple_strtoull(ptr, &endptr, 0); - - switch (*endptr) { + ptr += parse_integer(ptr, 0, &val); + switch (*ptr) { case 'E': case 'e': - ret <<= 10; + val <<= 10; case 'P': case 'p': - ret <<= 10; + val <<= 10; case 'T': case 't': - ret <<= 10; + val <<= 10; case 'G': case 'g': - ret <<= 10; + val <<= 10; case 'M': case 'm': - ret <<= 10; + val <<= 10; case 'K': case 'k': - ret <<= 10; - endptr++; + val <<= 10; + ptr++; default: break; } if (retptr) - *retptr = endptr; + *retptr = (char *)ptr; - return ret; + return val; } EXPORT_SYMBOL(memparse); --- a/lib/parser.c +++ b/lib/parser.c @@ -44,7 +44,7 @@ static int match_one(char *s, const char *p, substring_t args[]) p = meta + 1; if (isdigit(*p)) - len = simple_strtoul(p, (char **) &p, 10); + p += parse_integer(p, 10, (unsigned int *)&len); else if (*p == '%') { if (*s++ != '%') return 0; @@ -68,19 +68,21 @@ static int match_one(char *s, const char *p, substring_t args[]) break; } case 'd': - simple_strtol(s, &args[argc].to, 0); + /* anonymous variable */ + len = parse_integer(s, 0, &(int []){0}[0]); goto num; case 'u': - simple_strtoul(s, &args[argc].to, 0); + len = parse_integer(s, 0, &(unsigned int []){0}[0]); goto num; case 'o': - simple_strtoul(s, &args[argc].to, 8); + len = parse_integer(s, 8, &(unsigned int []){0}[0]); goto num; case 'x': - simple_strtoul(s, &args[argc].to, 16); + len = parse_integer(s, 16, &(unsigned int []){0}[0]); num: - if (args[argc].to == args[argc].from) + if (len < 0) return 0; + args[argc].to = args[argc].from + len; break; default: return 0; @@ -127,10 +129,8 @@ EXPORT_SYMBOL(match_token); */ static int match_number(substring_t *s, int *result, int base) { - char *endp; char *buf; int ret; - long val; size_t len = s->to - s->from; buf = kmalloc(len + 1, GFP_KERNEL); @@ -139,16 +139,11 @@ static int match_number(substring_t *s, int *result, int base) memcpy(buf, s->from, len); buf[len] = '\0'; - ret = 0; - val = simple_strtol(buf, &endp, base); - if (endp == buf) - ret = -EINVAL; - else if (val < (long)INT_MIN || val > (long)INT_MAX) - ret = -ERANGE; - else - *result = (int) val; + ret = parse_integer(buf, base, result); kfree(buf); - return ret; + if (ret < 0) + return ret; + return 0; } /** --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -100,7 +100,7 @@ static int __init setup_io_tlb_npages(char *str) { if (isdigit(*str)) { - io_tlb_nslabs = simple_strtoul(str, &str, 0); + str += parse_integer(str, 0, &io_tlb_nslabs); /* avoid tail segment of size < IO_TLB_SEGSIZE */ io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE); }