introduce skip_spaces(), reducing code size plus some clean-ups
Subsystems (22)
v4 cover introduce skip_spaces(), reducing code size plus some clean-ups
This patch reduces lib.a code size by 173 bytes on my Core 2 with gcc 4.4.1 even considering that it exports a newly defined function skip_spaces() to drivers:
text data bss dec hex filename 64867 840 592 66299 102fb (TOTALS-lib.a-before) 64954 584 588 66126 1024e (TOTALS-lib.a-after)
and implements some code tidy up.
Besides reducing lib.a size, it converts many in-tree drivers to use the newly defined function, which makes another small reduction on kernel size overall when those drivers are used.
p.s.: Ingo, I hope to have finally fixed my environment by using send-email now. Please let me know if you have any problem with these and thank you for the good advice. get_maintainer.pl gave lots of people as output, I hope that's ok.
Changelog:
v4: convert drivers over newly defined skip_spaces() function
v3: improved comments on patch 5/7 and factorize a switch statement on 6/7
as per suggestions from Ingo and Frederic (thanks!)
v2: addressed feedback from Frederic Weisbecker review (thanks!!)
and split into separate patches
v1: original submission
André Goddard Rosa (12):
vsprintf: factorize "(null)" string
vsprintf: pre-calculate final string length for later use
vsprintf: give it some care to please checkpatch.pl
vsprintf: use TOLOWER whenever possible
vsprintf: reduce code size by avoiding extra check
vsprintf: move local vars to block local vars and remove unneeded
ones
vsprintf: factor out skip_space code in a separate function
vsprintf: reuse almost identical simple_strtoulX() functions
ctype: constify read-only _ctype string
string: factorize skip_spaces and export it to be generally available
string: on strstrip(), first remove leading spaces before running
over str
tree-wide: convert open calls to remove spaces to skip_spaces() lib
function
arch/s390/kernel/debug.c | 3 +- arch/um/drivers/mconsole_kern.c | 16 +- arch/x86/kernel/cpu/mtrr/if.c | 11 +- drivers/md/dm-table.c | 6 +- drivers/md/md.c | 4 +- drivers/parisc/pdc_stable.c | 9 +- drivers/platform/x86/thinkpad_acpi.c | 7 +- drivers/pnp/interface.c | 36 +--- drivers/s390/block/dasd_proc.c | 5 +- drivers/video/backlight/lcd.c | 4 +- drivers/video/display/display-sysfs.c | 2 +- fs/cachefiles/daemon.c | 8 +- fs/ext4/super.c | 7 +- include/linux/ctype.h | 2 +- include/linux/string.h | 1 + kernel/params.c | 8 +- lib/argv_split.c | 13 +- lib/ctype.c | 50 +++--- lib/dynamic_debug.c | 4 +- lib/string.c | 19 ++- lib/vsprintf.c | 342 ++++++++++++++++----------------- net/irda/irnet/irnet.h | 1 + net/irda/irnet/irnet_ppp.c | 8 +- net/netfilter/xt_recent.c | 3 +- sound/pci/hda/hda_hwdep.c | 7 +- 25 files changed, 264 insertions(+), 312 deletions(-)
PATCH v4 1/12 vsprintf: factorize "(null)" string
Change "<NULL>" to "(null)" and make it a static const char[] hoping that the compiler will make null_str a label to a read-only area containing it.
See:
http://people.redhat.com/drepper/dsohowto.pdf part 2.4.2
http://udrepper.livejournal.com/13851.html
http://udrepper.livejournal.com/15119.html
--- lib/vsprintf.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
lib/vsprintf.c +6 -4
@@ -34,6 +34,8 @@/* Works only for digits and letters, but small and fast */ #define TOLOWER (x) ((x) | 0x20) +static const char null_str[] ="(null)" ; +static unsigned int simple_guess_base (const char *cp) {if (cp[0 ] =='0' ) {
@@ -546,12 +548,12 @@ static char *number(char *buf, char *end, unsigned long long num,return buf; } -static char *string (char *buf,char *end,char *s,struct printf_spec spec) +static char *string (char *buf,char *end,const char *s,struct printf_spec spec) {int len, i;if ((unsigned long )s <PAGE_SIZE ) - s ="<NULL>" ; + s = null_str; len =strnlen (s, spec.precision);
@@ -822,7 +824,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, struct printf_spec spec) {if (!ptr) -return string (buf, end,"(null)" , spec); +return string (buf, end, null_str, spec);switch (*fmt) {case 'F' :
@@ -1445,7 +1447,7 @@ do { \size_t len;if ((unsigned long )save_str > (unsigned long )-PAGE_SIZE || (unsigned long )save_str <PAGE_SIZE ) - save_str ="<NULL>" ; + save_str = null_str; len =strlen (save_str);if (str + len +1 < end)memcpy (str, save_str, len +1 );
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 2/12 vsprintf: pre-calculate final string length for later use
In reply to André Goddard Rosa--- lib/vsprintf.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
lib/vsprintf.c +6 -4
@@ -1445,13 +1445,15 @@ do { \case FORMAT_TYPE_STR : { const char *save_str = va_arg(args, char *);size_t len; +if ((unsigned long )save_str > (unsigned long )-PAGE_SIZE || (unsigned long )save_str <PAGE_SIZE ) save_str = null_str; - len =strlen (save_str); -if (str + len +1 < end) -memcpy (str, save_str, len +1 ); - str += len +1 ; + len =strlen (save_str) +1 ; +if (str + len < end) +memcpy (str, save_str, len); + str += len; +break ; }
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 3/12 vsprintf: give it some care to please checkpatch.pl
In reply to André Goddard RosaMost relevant complaints were addressed.
--- lib/vsprintf.c | 186 ++++++++++++++++++++++++++++++-------------------------- 1 files changed, 99 insertions(+), 87 deletions(-)
lib/vsprintf.c +99 -87
@@ -9,7 +9,7 @@* Wirzenius wrote this portably, Torvalds fucked it up :-) */ -/* +/* * Fri Jul 13 2001 Crutcher Dunnavant <[email protected]> * - changed to provide snprintf and vsnprintf functions * So Feb 1 16:51:32 CET 2004 Juergen Quade <[email protected]>
@@ -73,9 +73,9 @@ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) result = result * base + value; cp++; } -if (endp) *endp = (char *)cp; +return result; }EXPORT_SYMBOL (simple_strtoul);
@@ -88,8 +88,9 @@ EXPORT_SYMBOL(simple_strtoul);*/ long simple_strtol (const char *cp,char **endp,unsigned int base) { -if (*cp =='-' ) +if (*cp =='-' )return -simple_strtoul (cp +1 , endp, base); +return simple_strtoul (cp, endp, base); }EXPORT_SYMBOL (simple_strtol);
@@ -119,9 +120,9 @@ unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int bas result = result * base + value; cp++; } -if (endp) *endp = (char *)cp; +return result; }EXPORT_SYMBOL (simple_strtoull);
@@ -134,8 +135,9 @@ EXPORT_SYMBOL(simple_strtoull);*/ long long simple_strtoll (const char *cp,char **endp,unsigned int base) { -if (*cp=='-' ) +if (*cp =='-' )return -simple_strtoull (cp +1 , endp, base); +return simple_strtoull (cp, endp, base); }
@@ -175,6 +177,7 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) val =simple_strtoul (cp, &tail, base);if (tail == cp)return -EINVAL ; +if ((*tail =='\0' ) || ((len == (size_t )(tail - cp) +1 ) && (*tail =='\n' ))) { *res = val;
@@ -287,10 +290,11 @@ EXPORT_SYMBOL(strict_strtoll);static int skip_atoi (const char **s) { -int i=0 ; +int i =0 ;while (isdigit (**s)) i = i*10 + *((*s)++) -'0' ; +return i; }
@@ -304,7 +308,7 @@ static int skip_atoi(const char **s)/* Formats correctly any integer in [0,99999]. * Outputs from one to five digits depending on input. * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */ -static char *put_dec_trunc (char *buf,unsigned q) +static char *put_dec_trunc (char *buf,unsigned q) {unsigned d3, d2, d1, d0; d1 = (q>>4 ) &0xf ;
@@ -333,14 +337,15 @@ static char* put_dec_trunc(char *buf, unsigned q) d3 = d3 -10 *q; *buf++ = d3 +'0' ;/* next digit */ if (q !=0 ) - *buf++ = q +'0' ;/* most sign. digit */ + *buf++ = q +'0' ;/* most sign. digit */ } } } +return buf; }/* Same with if's removed. Always emits five digits */ -static char *put_dec_full (char *buf,unsigned q) +static char *put_dec_full (char *buf,unsigned q) {/* BTW, if q is in [0,9999], 8-bit ints will be enough, */ /* but anyway, gcc produces better code with full-sized ints */
@@ -349,14 +354,15 @@ static char* put_dec_full(char *buf, unsigned q) d2 = (q>>8 ) &0xf ; d3 = (q>>12 ); -/* Possible ways to approx. divide by 10 */ -/* gcc -O2 replaces multiply with shifts and adds */ -// (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) -// (x * 0x67) >> 10: 1100111 -// (x * 0x34) >> 9: 110100 - same -// (x * 0x1a) >> 8: 11010 - same -// (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) - +/* +* Possible ways to approx. divide by 10 +* gcc -O2 replaces multiply with shifts and adds +* (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) +* (x * 0x67) >> 10: 1100111 +* (x * 0x34) >> 9: 110100 - same +* (x * 0x1a) >> 8: 11010 - same +* (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) +*/ d0 =6 *(d3 + d2 + d1) + (q &0xf ); q = (d0 *0xcd ) >>11 ; d0 = d0 -10 *q;
@@ -377,10 +383,11 @@ static char* put_dec_full(char *buf, unsigned q) d3 = d3 -10 *q; *buf++ = d3 +'0' ; *buf++ = q +'0' ; +return buf; }/* No inlining helps gcc to use registers better */ -static noinline char* put_dec(char *buf, unsigned long long num) +static noinline char *put_dec(char *buf, unsigned long long num) {while (1 ) {unsigned rem;
@@ -450,9 +457,9 @@ static char *number(char *buf, char *end, unsigned long long num, spec.flags &= ~ZEROPAD ; sign =0 ;if (spec.flags &SIGN ) { -if ((signed long long ) num <0 ) { +if ((signed long long )num <0 ) { sign ='-' ; - num = - (signed long long ) num; + num = -(signed long long )num; spec.field_width--; }else if (spec.flags &PLUS ) { sign ='+' ;
@@ -480,7 +487,9 @@ static char *number(char *buf, char *end, unsigned long long num,else if (spec.base !=10 ) {/* 8 or 16 */ int mask = spec.base -1 ;int shift =3 ; -if (spec.base ==16 ) shift =4 ; + +if (spec.base ==16 ) + shift =4 ; do { tmp[i++] = (digits[((unsigned char)num) & mask] | locase); num >>= shift;
@@ -495,7 +504,7 @@ static char *number(char *buf, char *end, unsigned long long num,/* leading space padding */ spec.field_width -= spec.precision;if (!(spec.flags & (ZEROPAD +LEFT ))) { -while (--spec.field_width >=0 ) { +while (--spec.field_width >=0 ) {if (buf < end) *buf =' ' ; ++buf;
@@ -545,6 +554,7 @@ static char *number(char *buf, char *end, unsigned long long num, *buf =' ' ; ++buf; } +return buf; }
@@ -574,6 +584,7 @@ static char *string(char *buf, char *end, const char *s, struct printf_spec spec *buf =' ' ; ++buf; } +return buf; }
@@ -587,11 +598,13 @@ static char *symbol_string(char *buf, char *end, void *ptr,sprint_symbol (sym, value); elsekallsyms_lookup (value ,NULL ,NULL ,NULL ,sym ); +return string (buf, end, sym, spec);#else - spec.field_width =2 *sizeof (void *); + spec.field_width =2 *sizeof (void *); spec.flags |=SPECIAL |SMALL |ZEROPAD ; spec.base =16 ; +return number (buf, end, value, spec);#endif }
@@ -611,7 +624,7 @@ static char *resource_string(char *buf, char *end, struct resource *res, .precision = -1, .flags = SPECIAL | SMALL | ZEROPAD, }; -/* room for the actual numbers, the two "0x", -, [, ] and the final zero */ +/* room for actual numbers: the two "0x", -, [, ] and the final zero */ char sym[4 *sizeof (resource_size_t) +8 ];char *p = sym, *pend = sym +sizeof (sym);int size =-1 ;
@@ -668,22 +681,19 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)if (i <3 ) *p++ ='.' ; } - *p ='\0' ; +return p; }static char *ip6_compressed_string (char *p,const char *addr) { -int i; -int j; -int range; +int i, j, range;unsigned char zerolength[8 ];int longest =1 ;int colonpos =-1 ;u16 word; -u8 hi; -u8 lo; +u8 hi, lo;bool needcolon = false;bool useIPv4;struct in6_addr in6;
@@ -750,22 +760,23 @@ static char *ip6_compressed_string(char *p, const char *addr) *p++ =':' ; p =ip4_string (p, &in6.s6_addr[12 ], false); } - *p ='\0' ; +return p; }static char *ip6_string (char *p,const char *addr,const char *fmt) {int i; +for (i =0 ; i <8 ; i++) { p =pack_hex_byte (p, *addr++); p =pack_hex_byte (p, *addr++);if (fmt[0 ] =='I' && i !=7 ) *p++ =':' ; } - *p ='\0' ; +return p; }
@@ -1271,7 +1282,8 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) {int i; - i=vsnprintf (buf,size,fmt,args); + i =vsnprintf (buf, size, fmt, args); +return (i >= size) ? (size -1 ) : i; }EXPORT_SYMBOL (vscnprintf);
@@ -1290,14 +1302,15 @@ EXPORT_SYMBOL(vscnprintf);* * See the vsnprintf() documentation for format string extensions over C99. */ -int snprintf (char * buf,size_t size,const char *fmt, ...) +int snprintf (char *buf,size_t size,const char *fmt, ...) {va_list args;int i;va_start (args, fmt); - i=vsnprintf (buf,size,fmt,args); + i =vsnprintf (buf, size, fmt, args);va_end (args); +return i; }EXPORT_SYMBOL (snprintf);
@@ -1313,7 +1326,7 @@ EXPORT_SYMBOL(snprintf);* the trailing '\0'. If @size is <= 0 the function returns 0. */ -int scnprintf (char * buf,size_t size,const char *fmt, ...) +int scnprintf (char *buf,size_t size,const char *fmt, ...) {va_list args;int i;
@@ -1321,6 +1334,7 @@ int scnprintf(char * buf, size_t size, const char *fmt, ...)va_start (args, fmt); i =vsnprintf (buf, size, fmt, args);va_end (args); +return (i >= size) ? (size -1 ) : i; }EXPORT_SYMBOL (scnprintf);
@@ -1358,14 +1372,15 @@ EXPORT_SYMBOL(vsprintf);* * See the vsnprintf() documentation for format string extensions over C99. */ -int sprintf (char * buf,const char *fmt, ...) +int sprintf (char *buf,const char *fmt, ...) {va_list args;int i;va_start (args, fmt); - i=vsnprintf (buf,INT_MAX , fmt, args); + i =vsnprintf (buf,INT_MAX , fmt, args);va_end (args); +return i; }EXPORT_SYMBOL (sprintf);
@@ -1423,7 +1438,6 @@ do { \ str +=sizeof (type); \ }while (0 ) -while (*fmt) { read =format_decode (fmt, &spec);
@@ -1512,8 +1526,8 @@ do { \ } } } -return (u32 *)(PTR_ALIGN (str,sizeof (u32))) - bin_buf; +return (u32 *)(PTR_ALIGN (str,sizeof (u32))) - bin_buf;#undef save_arg }EXPORT_SYMBOL_GPL (vbin_printf);
@@ -1545,7 +1559,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)unsigned long long num;char *str, *end, c;const char *args = (const char *)bin_buf; -struct printf_spec spec = {0 };if (WARN_ON_ONCE ((int ) size <0 ))
@@ -1725,6 +1738,7 @@ int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)va_start (args, fmt); ret =vbin_printf (bin_buf, size, fmt, args);va_end (args); +return ret; }EXPORT_SYMBOL_GPL (bprintf);
@@ -1737,18 +1751,16 @@ EXPORT_SYMBOL_GPL(bprintf);* @fmt: format of buffer * @args: arguments */ -int vsscanf (const char * buf,const char * fmt,va_list args) +int vsscanf (const char *buf,const char *fmt,va_list args) {const char *str = buf;char *next;char digit;int num =0 ; -int qualifier; -int base; -int field_width; +int qualifier, base, field_width;int is_sign =0 ; -while (*fmt && *str) { +while (*fmt && *str) {/* skip any white space in format */ /* white space in format matchs any amount of * white space, including none, in the input.
@@ -1770,7 +1782,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)if (!*fmt)break ; ++fmt; - +/* skip this conversion. * advance both strings to next white space */
@@ -1808,10 +1820,10 @@ int vsscanf(const char * buf, const char * fmt, va_list args)if (!*fmt || !*str)break ; -switch (*fmt++) { +switch (*fmt++) {case 'c' : { - char *s = (char *) va_arg(args,char*); + char *s = (char *)va_arg(args, char*);if (field_width ==-1 ) field_width =1 ; do {
@@ -1822,17 +1834,16 @@ int vsscanf(const char * buf, const char * fmt, va_list args)continue ;case 's' : { - char *s = (char *) va_arg(args, char *); -if (field_width ==-1 ) + char *s = (char *)va_arg(args, char *); +if (field_width ==-1 ) field_width =INT_MAX ;/* first, skip leading white space in buffer */ while (isspace (*str)) str++;/* now copy until next white space */ -while (*str && !isspace (*str) && field_width--) { +while (*str && !isspace (*str) && field_width--) *s++ = *str++; - } *s ='\0' ; num++; }
@@ -1840,7 +1851,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)case 'n' :/* return number of characters read so far */ { - int *i = (int *)va_arg(args,int*); + int *i = (int *)va_arg(args, int*); *i = str - buf; }continue ;
@@ -1852,14 +1863,14 @@ int vsscanf(const char * buf, const char * fmt, va_list args) base =16 ;break ;case 'i' : - base =0 ; + base =0 ;case 'd' : is_sign =1 ;case 'u' :break ;case '%' :/* looking for '%' in str */ -if (*str++ !='%' ) +if (*str++ !='%' )return num;continue ;default :
@@ -1878,63 +1889,63 @@ int vsscanf(const char * buf, const char * fmt, va_list args) digit = *(str +1 );if (!digit - || (base ==16 && !isxdigit (digit)) - || (base ==10 && !isdigit (digit)) - || (base ==8 && (!isdigit (digit) || digit >'7' )) - || (base ==0 && !isdigit (digit))) -break ; + || (base ==16 && !isxdigit (digit)) + || (base ==10 && !isdigit (digit)) + || (base ==8 && (!isdigit (digit) || digit >'7' )) + || (base ==0 && !isdigit (digit))) +break ; -switch (qualifier) { +switch (qualifier) {case 'H' :/* that's 'hh' in format */ if (is_sign) { - signed char *s = (signed char *) va_arg(args,signed char *); - *s = (signed char )simple_strtol (str,&next,base); + signed char *s = (signed char *)va_arg(args, signed char *); + *s = (signed char )simple_strtol (str, &next, base); }else { - unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); - *s = (unsigned char )simple_strtoul (str, &next, base); + unsigned char *s = (unsigned char *)va_arg(args, unsigned char *); + *s = (unsigned char )simple_strtoul (str, &next, base); }break ;case 'h' :if (is_sign) { - short *s = (short *) va_arg(args,short *); - *s = (short )simple_strtol (str,&next,base); + short *s = (short *)va_arg(args, short *); + *s = (short )simple_strtol (str, &next, base); }else { - unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); - *s = (unsigned short )simple_strtoul (str, &next, base); + unsigned short *s = (unsigned short *)va_arg(args, unsigned short *); + *s = (unsigned short )simple_strtoul (str, &next, base); }break ;case 'l' :if (is_sign) { - long *l = (long *) va_arg(args,long *); - *l =simple_strtol (str,&next,base); + long *l = (long *)va_arg(args, long *); + *l =simple_strtol (str, &next, base); }else { - unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); - *l =simple_strtoul (str,&next,base); + unsigned long *l = (unsigned long *)va_arg(args, unsigned long *); + *l =simple_strtoul (str, &next, base); }break ;case 'L' :if (is_sign) { - long long *l = (long long*) va_arg(args,long long *); - *l =simple_strtoll (str,&next,base); + long long *l = (long long *)va_arg(args, long long *); + *l =simple_strtoll (str, &next, base); }else { - unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); - *l =simple_strtoull (str,&next,base); + unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *); + *l =simple_strtoull (str, &next, base); }break ;case 'Z' :case 'z' : { - size_t *s = (size_t*) va_arg(args,size_t*); - *s = (size_t )simple_strtoul (str,&next,base); + size_t *s = (size_t *)va_arg(args, size_t *); + *s = (size_t )simple_strtoul (str, &next, base); }break ;default :if (is_sign) { - int *i = (int *) va_arg(args, int*); - *i = (int )simple_strtol (str,&next,base); + int *i = (int *)va_arg(args, int *); + *i = (int )simple_strtol (str, &next, base); }else { - unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); - *i = (unsigned int )simple_strtoul (str,&next,base); + unsigned int *i = (unsigned int *)va_arg(args, unsigned int*); + *i = (unsigned int )simple_strtoul (str, &next, base); }break ; }
@@ -1965,14 +1976,15 @@ EXPORT_SYMBOL(vsscanf);* @fmt: formatting of buffer * @...: resulting arguments */ -int sscanf (const char * buf,const char * fmt, ...) +int sscanf (const char *buf,const char *fmt, ...) {va_list args;int i; -va_start (args,fmt); - i =vsscanf (buf,fmt,args); +va_start (args, fmt); + i =vsscanf (buf, fmt, args);va_end (args); +return i; }EXPORT_SYMBOL (sscanf);
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 4/12 vsprintf: use TOLOWER whenever possible
In reply to André Goddard RosaIt decreases code size as well:
text data bss dec hex filename
15767 0 8 15775 3d9f lib/vsprintf.o-before 15735 0 8 15743 3d7f lib/vsprintf.o-TOLOWER
--- lib/vsprintf.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-)
lib/vsprintf.c +7 -8
@@ -983,8 +983,8 @@ precision: qualifier:/* get the conversion qualifier */ spec->qualifier =-1 ; -if (*fmt =='h' || *fmt =='l' || *fmt =='L' || - *fmt =='Z' || *fmt =='z' || *fmt =='t' ) { +if (*fmt =='h' ||TOLOWER (*fmt) =='l' || +TOLOWER (*fmt) =='z' || *fmt =='t' ) { spec->qualifier = *fmt++;if (unlikely (spec->qualifier == *fmt)) {if (spec->qualifier =='l' ) {
@@ -1051,7 +1051,7 @@ qualifier: spec->type =FORMAT_TYPE_LONG ; else spec->type = FORMAT_TYPE_ULONG; - }else if (spec->qualifier =='Z' || spec->qualifier =='z' ) { + }else if (TOLOWER (spec->qualifier) =='z' ) { spec->type =FORMAT_TYPE_SIZE_T ; }else if (spec->qualifier =='t' ) { spec->type =FORMAT_TYPE_PTRDIFF ;
@@ -1198,8 +1198,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)if (qualifier =='l' ) { long *ip = va_arg(args, long *); *ip = (str - buf); - }else if (qualifier =='Z' || - qualifier =='z' ) { + }else if (TOLOWER (qualifier) =='z' ) { size_t *ip = va_arg(args, size_t *); *ip = (str - buf); }else {
@@ -1490,7 +1489,7 @@ do { \void *skip_arg;if (qualifier =='l' ) skip_arg = va_arg(args, long *); -else if (qualifier =='Z' || qualifier =='z' ) +else if (TOLOWER (qualifier) =='z' ) skip_arg = va_arg(args, size_t *);else skip_arg = va_arg(args, int *);
@@ -1801,8 +1800,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)/* get conversion qualifier */ qualifier =-1 ; -if (*fmt =='h' || *fmt =='l' || *fmt =='L' || - *fmt =='Z' || *fmt =='z' ) { +if (*fmt =='h' ||TOLOWER (*fmt) =='l' || +TOLOWER (*fmt) =='z' ) { qualifier = *fmt++;if (unlikely (qualifier == *fmt)) {if (qualifier =='h' ) {
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 5/12 vsprintf: reduce code size by avoiding extra check
In reply to André Goddard RosaNo functional change, just refactor the code so that it avoid checking "if (hi)" two times in a sequence, taking advantage of previous check made.
It also reduces code size:
text data bss dec hex filename
15735 0 8 15743 3d7f lib/vsprintf.o-before 15719 0 8 15727 3d6f lib/vsprintf.o-minus-double-check
--- lib/vsprintf.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
lib/vsprintf.c +2 -1
@@ -747,8 +747,9 @@ static char *ip6_compressed_string(char *p, const char *addr) p =pack_hex_byte (p, hi); else *p++ = hex_asc_lo(hi); + p =pack_hex_byte (p, lo); } -if (hi || lo >0x0f ) +else if (lo >0x0f ) p =pack_hex_byte (p, lo);else *p++ =hex_asc_lo (lo);
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 6/12 vsprintf: move local vars to block local vars and remove unneeded ones
In reply to André Goddard RosaCleanup by moving variables closer to the scope where they're used in fact. Also, remove unneeded ones.
--- lib/vsprintf.c | 64 ++++++++++++++++++++++++------------------------------- 1 files changed, 28 insertions(+), 36 deletions(-)
lib/vsprintf.c +28 -36
@@ -842,8 +842,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,case 'F' :case 'f' : ptr =dereference_function_descriptor (ptr); -case 's' :/* Fallthrough */ +case 's' :case 'S' :return symbol_string (buf, end, ptr, spec, *fmt);case 'R' :
@@ -1105,8 +1105,7 @@ qualifier:int vsnprintf (char *buf,size_t size,const char *fmt,va_list args) {unsigned long long num; -char *str, *end, c; -int read; +char *str, *end;struct printf_spec spec = {0 };/* Reject out-of-range values early. Large positive sizes are
@@ -1125,8 +1124,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)while (*fmt) {const char *old_fmt = fmt; - - read =format_decode (fmt, &spec); +int read =format_decode (fmt, &spec); fmt += read;
@@ -1150,7 +1148,9 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) spec.precision =va_arg (args, int);break ; -case FORMAT_TYPE_CHAR : +case FORMAT_TYPE_CHAR : { +char c; +if (!(spec.flags &LEFT )) {while (--spec.field_width >0 ) {if (str < end)
@@ -1169,6 +1169,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++str; }break ; + }case FORMAT_TYPE_STR : str = string(str, end, va_arg(args, char *), spec);
@@ -1413,7 +1414,6 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) {struct printf_spec spec = {0 };char *str, *end; -int read; str = (char *)bin_buf; end = (char *)(bin_buf + size);
@@ -1439,12 +1439,14 @@ do { \ }while (0 )while (*fmt) { - read =format_decode (fmt, &spec); +int read =format_decode (fmt, &spec); fmt += read;switch (spec.type) {case FORMAT_TYPE_NONE : +case FORMAT_TYPE_INVALID : +case FORMAT_TYPE_PERCENT_CHAR :break ;case FORMAT_TYPE_WIDTH :
@@ -1478,12 +1480,6 @@ do { \ fmt++;break ; -case FORMAT_TYPE_PERCENT_CHAR : -break ; - -case FORMAT_TYPE_INVALID : -break ; -case FORMAT_TYPE_NRCHARS : {/* skip %n 's argument */ int qualifier = spec.qualifier;
@@ -1556,10 +1552,9 @@ EXPORT_SYMBOL_GPL(vbin_printf);*/ int bstr_printf (char *buf,size_t size,const char *fmt,const u32 *bin_buf) { -unsigned long long num; -char *str, *end, c; -const char *args = (const char *)bin_buf;struct printf_spec spec = {0 }; +char *str, *end; +const char *args = (const char *)bin_buf;if (WARN_ON_ONCE ((int ) size <0 ))return 0 ;
@@ -1589,10 +1584,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) }while (*fmt) { -int read;const char *old_fmt = fmt; - - read =format_decode (fmt, &spec); +int read =format_decode (fmt, &spec); fmt += read;
@@ -1616,7 +1609,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) spec.precision =get_arg (int);break ; -case FORMAT_TYPE_CHAR : +case FORMAT_TYPE_CHAR : { +char c; +if (!(spec.flags &LEFT )) {while (--spec.field_width >0 ) {if (str < end)
@@ -1634,11 +1629,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) ++str; }break ; + }case FORMAT_TYPE_STR : {const char *str_arg = args; -size_t len =strlen (str_arg); - args += len +1 ; + args +=strlen (str_arg) +1 ; str =string (str, end, (char *)str_arg, spec);break ; }
@@ -1650,11 +1645,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)break ;case FORMAT_TYPE_PERCENT_CHAR : -if (str < end) - *str ='%' ; - ++str; -break ; -case FORMAT_TYPE_INVALID :if (str < end) *str ='%' ;
@@ -1665,15 +1655,15 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)/* skip */ break ; -default : +default : { +unsigned long long num; +switch (spec.type) {case FORMAT_TYPE_LONG_LONG : num = get_arg(long long);break ;case FORMAT_TYPE_ULONG : - num = get_arg(unsigned long); -break ;case FORMAT_TYPE_LONG : num = get_arg(unsigned long);break ;
@@ -1703,8 +1693,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) } str =number (str, end, num, spec); - } - } + }/* default: */ + }/* switch(spec.type) */ + }/* while(*fmt) */ if (size >0 ) {if (str < end)
@@ -1758,7 +1749,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)char digit;int num =0 ;int qualifier, base, field_width; -int is_sign =0 ; +bool is_sign;while (*fmt && *str) {/* skip any white space in format */
@@ -1814,12 +1805,13 @@ int vsscanf(const char *buf, const char *fmt, va_list args) } } } - base =10 ; - is_sign =0 ;if (!*fmt || !*str)break ; + base =10 ; + is_sign =0 ; +switch (*fmt++) {case 'c' : {
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 7/12 vsprintf: factor out skip_space code in a separate function
In reply to André Goddard RosaIt decreases code size:
text data bss dec hex filename
15719 0 8 15727 3d6f lib/vsprintf.o-before 15543 0 8 15551 3cbf lib/vsprintf.o-after
--- lib/vsprintf.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-)
lib/vsprintf.c +11 -8
@@ -1736,6 +1736,13 @@ EXPORT_SYMBOL_GPL(bprintf);#endif /* CONFIG_BINARY_PRINTF */ +static noinline const char *skip_space(const char *str) +{ +while (isspace (*str)) + ++str; +return str; +} +/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer
@@ -1757,10 +1764,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)* white space, including none, in the input. */ if (isspace (*fmt)) { -while (isspace (*fmt)) - ++fmt; -while (isspace (*str)) - ++str; + fmt =skip_space (fmt); + str =skip_space (str); }/* anything that is not a conversion must match exactly */
@@ -1830,8 +1835,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)if (field_width ==-1 ) field_width =INT_MAX ;/* first, skip leading white space in buffer */ -while (isspace (*str)) - str++; + str =skip_space (str);/* now copy until next white space */ while (*str && !isspace (*str) && field_width--)
@@ -1873,8 +1877,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)/* have some sort of integer conversion. * first, skip white space in buffer. */ -while (isspace (*str)) - str++; + str =skip_space (str); digit = *str;if (is_sign && digit =='-' )
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 8/12 vsprintf: reuse almost identical simple_strtoulX() functions
In reply to André Goddard RosaThe difference between simple_strtoul() and simple_strtoull() is just the size of the variable used to keep track of the sum of characters converted to numbers:
unsigned long simple_strtoul() {...}
unsigned long long simple_strtoull(){...}
Both are same size (8 bytes) on my Core 2/gcc 4.4.1.
Overflow condition is not checked on both functions, so an extremely large string can break these functions so that they don't even notice it.
As we do not care for overflowing on these functions, always keep the sum using the larger variable around (unsigned long long) on simple_strtoull() and cast it to (unsigned long) on simple_strtoul(), which then becomes just a wrapper around simple_strtoull().
Code size decreases by 304 bytes:
text data bss dec hex filename
15543 0 8 15551 3cbf lib/vsprintf.o-before 15239 0 8 15247 3b8f lib/vsprintf.o-after
--- lib/vsprintf.c | 48 ++++++++++++++---------------------------------- 1 files changed, 14 insertions(+), 34 deletions(-)
lib/vsprintf.c +14 -34
@@ -49,14 +49,14 @@ static unsigned int simple_guess_base(const char *cp) }/** -* simple_strtoul - convert a string to an unsigned long +* simple_strtoull - convert a string to an unsigned long long * @cp: The start of the string * @endp: A pointer to the end of the parsed string will be placed here * @base: The number base to use */ -unsigned long simple_strtoul (const char *cp,char **endp,unsigned int base) +unsigned long long simple_strtoull (const char *cp,char **endp,unsigned int base) { -unsigned long result =0 ; +unsigned long long result =0 ;if (!base) base =simple_guess_base (cp);
@@ -78,54 +78,34 @@ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)return result; } -EXPORT_SYMBOL (simple_strtoul); +EXPORT_SYMBOL (simple_strtoull);/** -* simple_strtol - convert a string to a signed long +* simple_strtoul - convert a string to an unsigned long * @cp: The start of the string * @endp: A pointer to the end of the parsed string will be placed here * @base: The number base to use */ -long simple_strtol (const char *cp,char **endp,unsigned int base) +unsigned long simple_strtoul (const char *cp,char **endp,unsigned int base) { -if (*cp =='-' ) -return -simple_strtoul (cp +1 , endp, base); - -return simple_strtoul (cp, endp, base); +return (unsigned long )simple_strtoull (cp, endp, base); } -EXPORT_SYMBOL (simple_strtol); +EXPORT_SYMBOL (simple_strtoul);/** -* simple_strtoull - convert a string to an unsigned long long +* simple_strtol - convert a string to a signed long * @cp: The start of the string * @endp: A pointer to the end of the parsed string will be placed here * @base: The number base to use */ -unsigned long long simple_strtoull (const char *cp,char **endp,unsigned int base) +long simple_strtol (const char *cp,char **endp,unsigned int base) { -unsigned long long result =0 ; - -if (!base) - base =simple_guess_base (cp); - -if (base ==16 && cp[0 ] =='0' &&TOLOWER (cp[1 ]) =='x' ) - cp +=2 ; - -while (isxdigit (*cp)) { -unsigned int value; - - value =isdigit (*cp) ? *cp -'0' :TOLOWER (*cp) -'a' +10 ; -if (value >= base) -break ; - result = result * base + value; - cp++; - } -if (endp) - *endp = (char *)cp; +if (*cp =='-' ) +return -simple_strtoul (cp +1 , endp, base); -return result; +return simple_strtoul (cp, endp, base); } -EXPORT_SYMBOL (simple_strtoull); +EXPORT_SYMBOL (simple_strtol);/** * simple_strtoll - convert a string to a signed long long
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 9/12 ctype: constify read-only _ctype string
In reply to André Goddard RosaWhile at it, use tabs to indent the comments.
--- include/linux/ctype.h | 2 +- lib/ctype.c | 50 ++++++++++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 26 deletions(-)
include/linux/ctype.h +1 -1
@@ -15,7 +15,7 @@#define _X 0x40/* hex digit */ #define _SP 0x80/* hard space (0x20) */ -extern unsigned char _ctype[]; +extern const unsigned char _ctype[];#define __ismask (x) (_ctype[(int)(unsigned char)(x)])
lib/ctype.c +25 -25
55 lines not on this page · raw message
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 10/12 string: factorize skip_spaces and export it to be generally available
In reply to André Goddard RosaOn the following sentence:
while (*s && isspace(*s))
s++;If *s == 0, isspace() evaluates to ((_ctype[*s] & 0x20) != 0), which evaluates to ((0x08 & 0x20) != 0) which equals to 0 as well. If *s == 1, we depend on isspace() result anyway.
In other words, "a char equals zero is never a space". So remove this check. Also, *s != 0 is by far the most common case (non-empty string).
--- include/linux/string.h | 1 + lib/string.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-)
include/linux/string.h +1 -0
@@ -62,6 +62,7 @@ extern char * strnchr(const char *, size_t, int);#ifndef __HAVE_ARCH_STRRCHRextern char *strrchr (const char *,int );#endif +extern const char *__must_check skip_spaces (const char *);extern char *__must_check strstrip (char *);#ifndef __HAVE_ARCH_STRSTRextern char *strstr (const char *,const char *);
lib/string.c +15 -4
@@ -330,6 +330,20 @@ EXPORT_SYMBOL(strnchr);#endif /** +* skip_spaces - Removes leading whitespace from @s. +* @s: The string to be stripped. +* +* Returns a pointer to the first non-whitespace character in @s. +*/ +const char *skip_spaces (const char *str) +{ +while (isspace (*str)) + ++str; +return str; +} +EXPORT_SYMBOL (skip_spaces); + +/** * strstrip - Removes leading and trailing whitespace from @s. * @s: The string to be stripped. *
@@ -352,10 +366,7 @@ char *strstrip(char *s) end--; *(end +1 ) ='\0' ; -while (*s &&isspace (*s)) - s++; - -return s; +return (char *)skip_spaces (s); }EXPORT_SYMBOL (strstrip);
Signature · 1 line
1.6.5.2.153.g6e31f.dirty
PATCH v4 11/12 string: on strstrip(), first remove leading spaces before running over str
In reply to André Goddard Rosa... so that strlen() iterates over a smaller string comprising of the remaining characters only.
--- lib/string.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
lib/string.c +2 -2
@@ -356,8 +356,8 @@ char *strstrip(char *s)size_t size;char *end; + s = (char *)skip_spaces (s); size =strlen (s); -if (!size)return s;
@@ -366,7 +366,7 @@ char *strstrip(char *s) end--; *(end +1 ) ='\0' ; -return (char *)skip_spaces (s); +return s; }EXPORT_SYMBOL (strstrip);
Signature · 12 lines
1.6.5.2.153.g6e31f.dirty ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ User-mode-linux-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
PATCH v4 12/12 tree-wide: convert open calls to remove spaces to skip_spaces() lib function
In reply to André Goddard RosaMakes use of skip_spaces() defined in lib/string.c for removing leading spaces from strings all over the tree.
Also, while at it, if we see (*str && isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".
--- arch/s390/kernel/debug.c | 3 +- arch/um/drivers/mconsole_kern.c | 16 ++++++-------- arch/x86/kernel/cpu/mtrr/if.c | 11 +++------ drivers/md/dm-table.c | 6 +--- drivers/md/md.c | 4 +- drivers/parisc/pdc_stable.c | 9 ++----- drivers/platform/x86/thinkpad_acpi.c | 7 +---- drivers/pnp/interface.c | 36 +++++++++----------------------- drivers/s390/block/dasd_proc.c | 5 ++- drivers/video/backlight/lcd.c | 4 +- drivers/video/display/display-sysfs.c | 2 +- fs/cachefiles/daemon.c | 8 ++---- fs/ext4/super.c | 7 +---- kernel/params.c | 8 ++---- lib/argv_split.c | 13 ++--------- lib/dynamic_debug.c | 4 +- lib/vsprintf.c | 15 +++---------- net/irda/irnet/irnet.h | 1 + net/irda/irnet/irnet_ppp.c | 8 ++---- net/netfilter/xt_recent.c | 3 +- sound/pci/hda/hda_hwdep.c | 7 ++--- 21 files changed, 63 insertions(+), 114 deletions(-)
arch/s390/kernel/debug.c +2 -1
@@ -18,6 +18,7 @@#include <linux/errno.h> #include <linux/slab.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/sysctl.h> #include <asm/uaccess.h> #include <linux/module.h>
@@ -1183,7 +1184,7 @@ debug_get_uint(char *buf) {int rc; -for (;isspace (*buf); buf++); + buf =skip_spaces (buf); rc =simple_strtoul (buf, &buf,10 );if (*buf){ rc = -EINVAL ;
arch/um/drivers/mconsole_kern.c +7 -9
@@ -6,6 +6,7 @@#include <linux/console.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/mm.h>
@@ -131,7 +132,7 @@ void mconsole_proc(struct mc_request *req)char *ptr = req->request.data, *buf; ptr +=strlen ("proc" ); -while (isspace (*ptr)) ptr++; + ptr =skip_spaces (ptr); proc =get_fs_type ("proc" );if (proc ==NULL ) {
@@ -212,8 +213,7 @@ void mconsole_proc(struct mc_request *req)char *ptr = req->request.data; ptr +=strlen ("proc" ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);snprintf (path,sizeof (path),"/proc/%s" , ptr); fd =sys_open (path,0 ,0 );
@@ -560,8 +560,7 @@ void mconsole_config(struct mc_request *req)int err; ptr +=strlen ("config" ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr); dev =mconsole_find_dev (ptr);if (dev ==NULL ) {mconsole_reply (req,"Bad configuration option" ,1 ,0 );
@@ -588,7 +587,7 @@ void mconsole_remove(struct mc_request *req)int err, start, end, n; ptr +=strlen ("remove" ); -while (isspace (*ptr)) ptr++; + ptr =skip_spaces (ptr); dev =mconsole_find_dev (ptr);if (dev ==NULL ) {mconsole_reply (req,"Bad remove option" ,1 ,0 );
@@ -712,7 +711,7 @@ void mconsole_sysrq(struct mc_request *req)char *ptr = req->request.data; ptr +=strlen ("sysrq" ); -while (isspace (*ptr)) ptr++; + ptr =skip_spaces (ptr);/* * With 'b', the system will shut down without a chance to reply,
@@ -757,8 +756,7 @@ void mconsole_stack(struct mc_request *req)*/ ptr +=strlen ("stack" ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);/* * Should really check for multiple pids or reject bad args here
arch/x86/kernel/cpu/mtrr/if.c +4 -7
@@ -4,6 +4,7 @@#include <linux/proc_fs.h> #include <linux/module.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/init.h> #define LINE_SIZE 80
@@ -133,8 +134,7 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)return -EINVAL ; base =simple_strtoull (line +5 , &ptr,0 ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);if (strncmp (ptr,"size=" ,5 ))return -EINVAL ;
@@ -142,14 +142,11 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos) size =simple_strtoull (ptr +5 , &ptr,0 );if ((base &0xfff ) || (size &0xfff ))return -EINVAL ; -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);if (strncmp (ptr,"type=" ,5 ))return -EINVAL ; - ptr +=5 ; -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr +5 );for (i =0 ; i <MTRR_NUM_TYPES ; ++i) {if (strcmp (ptr, mtrr_strings[i]))
drivers/md/dm-table.c +2 -4
@@ -12,6 +12,7 @@#include <linux/blkdev.h> #include <linux/namei.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/mutex.h>
@@ -600,11 +601,8 @@ int dm_split_args(int *argc, char ***argvp, char *input)return -ENOMEM ;while (1 ) { - start = end; -/* Skip whitespace */ -while (*start &&isspace (*start)) - start++; + start =skip_spaces (end);if (!*start)break ;/* success, we hit the end */
drivers/md/md.c +2 -2
@@ -39,6 +39,7 @@#include <linux/buffer_head.h> /* for invalidate_bdev */ #include <linux/poll.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/hdreg.h> #include <linux/proc_fs.h> #include <linux/random.h>
@@ -3225,8 +3226,7 @@ bitmap_store(mddev_t *mddev, const char *buf, size_t len) }if (*end && !isspace (*end))break ;bitmap_dirty_bits (mddev->bitmap, chunk, end_chunk); - buf = end; -while (isspace (*buf)) buf++; + buf =skip_spaces (end); }bitmap_unplug (mddev->bitmap);/* flush the bits to disk */ out:
drivers/parisc/pdc_stable.c +3 -6
@@ -779,12 +779,9 @@ static ssize_t pdcs_auto_write(struct kobject *kobj,read_unlock (&pathentry->rw_lock);DPRINTK ("%s: flags before: 0x%X\n" , __func__, flags); - - temp = in; - -while (*temp &&isspace (*temp)) - temp++; - + + temp =skip_spaces (in); + c = *temp++ -'0' ;if ((c !=0 ) && (c !=1 )) goto parse_error;
drivers/platform/x86/thinkpad_acpi.c +2 -5
@@ -1006,11 +1006,8 @@ static int parse_strtoul(const char *buf, {char *endp; -while (*buf &&isspace (*buf)) - buf++; - *value =simple_strtoul (buf, &endp,0 ); -while (*endp &&isspace (*endp)) - endp++; + *value =simple_strtoul (skip_spaces (buf), &endp,0 ); + endp =skip_spaces (endp);if (*endp || *value > max)return -EINVAL ;
drivers/pnp/interface.c +10 -26
@@ -310,8 +310,7 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, goto done; } -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (!strnicmp (buf,"disable" ,7 )) { retval =pnp_disable_dev (dev); goto done;
@@ -353,19 +352,13 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,pnp_init_resources (dev);mutex_lock (&pnp_res_mutex);while (1 ) { -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (!strnicmp (buf,"io" ,2 )) { - buf +=2 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +2 ); start =simple_strtoul (buf, &buf,0 ); -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (*buf =='-' ) { - buf +=1 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +1 ); end =simple_strtoul (buf, &buf,0 ); }else end = start;
@@ -373,16 +366,11 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,continue ; }if (!strnicmp (buf,"mem" ,3 )) { - buf +=3 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +3 ); start =simple_strtoul (buf, &buf,0 ); -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (*buf =='-' ) { - buf +=1 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +1 ); end =simple_strtoul (buf, &buf,0 ); }else end = start;
@@ -390,17 +378,13 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,continue ; }if (!strnicmp (buf,"irq" ,3 )) { - buf +=3 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +3 ); start =simple_strtoul (buf, &buf,0 );pnp_add_irq_resource (dev, start,0 );continue ; }if (!strnicmp (buf,"dma" ,3 )) { - buf +=3 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +3 ); start =simple_strtoul (buf, &buf,0 );pnp_add_dma_resource (dev, start,0 );continue ;
drivers/s390/block/dasd_proc.c +3 -2
@@ -14,6 +14,7 @@#define KMSG_COMPONENT "dasd"#include <linux/ctype.h> +#include <linux/string.h> #include <linux/seq_file.h> #include <linux/vmalloc.h> #include <linux/proc_fs.h>
@@ -272,10 +273,10 @@ dasd_statistics_write(struct file *file, const char __user *user_buf,DBF_EVENT (DBF_DEBUG ,"/proc/dasd/statictics: '%s'\n" , buffer);/* check for valid verbs */ -for (str = buffer;isspace (*str); str++); + str =skip_spaces (buffer);if (strncmp (str,"set" ,3 ) ==0 &&isspace (str[3 ])) {/* 'set xxx' was given */ -for (str = str +4 ;isspace (*str); str++); + str =skip_spaces (str +4 );if (strcmp (str,"on" ) ==0 ) {/* switch on statistics profiling */ dasd_profile_level =DASD_PROFILE_ON ;
drivers/video/backlight/lcd.c +2 -2
@@ -101,7 +101,7 @@ static ssize_t lcd_store_power(struct device *dev,int power =simple_strtoul (buf, &endp,0 );size_t size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)return -EINVAL ;
@@ -140,7 +140,7 @@ static ssize_t lcd_store_contrast(struct device *dev,int contrast =simple_strtoul (buf, &endp,0 );size_t size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)return -EINVAL ;
drivers/video/display/display-sysfs.c +1 -1
@@ -67,7 +67,7 @@ static ssize_t display_store_contrast(struct device *dev, contrast =simple_strtoul (buf, &endp,0 ); size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)
fs/cachefiles/daemon.c +3 -5
@@ -21,6 +21,7 @@#include <linux/mount.h> #include <linux/statfs.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/fs_struct.h> #include "internal.h"
@@ -250,15 +251,12 @@ static ssize_t cachefiles_daemon_write(struct file *file,/* parse the command */ ret = -EOPNOTSUPP ; -for (args = data; *args; args++) -if (isspace (*args)) -break ; + args =skip_spaces (data);if (*args) {if (args == data) goto error; *args ='\0' ; -for (args++;isspace (*args); args++) -continue ; + args =skip_spaces (++args); }/* run the appropriate command handler */
fs/ext4/super.c +2 -5
@@ -2097,11 +2097,8 @@ static int parse_strtoul(const char *buf, {char *endp; -while (*buf &&isspace (*buf)) - buf++; - *value =simple_strtoul (buf, &endp,0 ); -while (*endp &&isspace (*endp)) - endp++; + *value =simple_strtoul (skip_spaces (buf), &endp,0 ); + endp =skip_spaces (endp);if (*endp || *value > max)return -EINVAL ;
kernel/params.c +3 -5
@@ -24,6 +24,7 @@#include <linux/err.h> #include <linux/slab.h> #include <linux/ctype.h> +#include <linux/string.h> #if 0 #define DEBUGP printk
@@ -122,9 +123,7 @@ static char *next_arg(char *args, char **param, char **val) next = args + i;/* Chew up trailing spaces. */ -while (isspace (*next)) - next++; -return next; +return skip_spaces (next); }/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
@@ -139,8 +138,7 @@ int parse_args(const char *name,DEBUGP ("Parsing ARGS: %s\n" , args);/* Chew leading spaces */ -while (isspace (*args)) - args++; + args =skip_spaces (args);while (*args) {int ret;
lib/argv_split.c +3 -10
@@ -4,17 +4,10 @@#include <linux/kernel.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/slab.h> #include <linux/module.h> -static const char *skip_sep (const char *cp) -{ -while (*cp &&isspace (*cp)) - cp++; - -return cp; -} -static const char *skip_arg (const char *cp) {while (*cp && !isspace (*cp))
@@ -28,7 +21,7 @@ static int count_argc(const char *str)int count =0 ;while (*str) { - str =skip_sep (str); + str =skip_spaces (str);if (*str) { count++; str =skip_arg (str);
@@ -82,7 +75,7 @@ char **argv_split(gfp_t gfp, const char *str, int *argcp) argvp = argv;while (*str) { - str =skip_sep (str); + str =skip_spaces (str);if (*str) {const char *p = str;
lib/dynamic_debug.c +2 -2
@@ -21,6 +21,7 @@#include <linux/list.h> #include <linux/sysctl.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/uaccess.h> #include <linux/dynamic_debug.h> #include <linux/debugfs.h>
@@ -209,8 +210,7 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)char *end;/* Skip leading whitespace */ -while (*buf &&isspace (*buf)) - buf++; + buf =skip_spaces (buf);if (!*buf)break ;/* oh, it was trailing whitespace */
lib/vsprintf.c +4 -11
@@ -1716,13 +1716,6 @@ EXPORT_SYMBOL_GPL(bprintf);#endif /* CONFIG_BINARY_PRINTF */ -static noinline const char *skip_space(const char *str) -{ -while (isspace (*str)) - ++str; -return str; -} -/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer
@@ -1744,8 +1737,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)* white space, including none, in the input. */ if (isspace (*fmt)) { - fmt =skip_space (fmt); - str =skip_space (str); + fmt =skip_spaces (++fmt); + str =skip_spaces (str); }/* anything that is not a conversion must match exactly */
@@ -1815,7 +1808,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)if (field_width ==-1 ) field_width =INT_MAX ;/* first, skip leading white space in buffer */ - str =skip_space (str); + str =skip_spaces (str);/* now copy until next white space */ while (*str && !isspace (*str) && field_width--)
@@ -1857,7 +1850,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)/* have some sort of integer conversion. * first, skip white space in buffer. */ - str =skip_space (str); + str =skip_spaces (str); digit = *str;if (is_sign && digit =='-' )
net/irda/irnet/irnet.h +1 -0
@@ -249,6 +249,7 @@#include <linux/poll.h> #include <linux/capability.h> #include <linux/ctype.h> /* isspace() */ +#include <linux/string.h> /* skip_spaces() */ #include <asm/uaccess.h> #include <linux/init.h>
net/irda/irnet/irnet_ppp.c +3 -5
@@ -76,9 +76,8 @@ irnet_ctrl_write(irnet_socket * ap,/* Look at the next command */ start = next; -/* Scrap whitespaces before the command */ -while (isspace (*start)) - start++; +/* Scrap whitespaces before the command */ + start =skip_spaces (start);/* ',' is our command separator */ next =strchr (start,',' );
@@ -133,8 +132,7 @@ irnet_ctrl_write(irnet_socket * ap,char * endp;/* Scrap whitespaces before the command */ -while (isspace (*begp)) - begp++; + begp =skip_spaces (begp);/* Convert argument to a number (last arg is the base) */ addr =simple_strtoul (begp, &endp,16 );
net/netfilter/xt_recent.c +1 -2
@@ -482,8 +482,7 @@ static ssize_t recent_old_proc_write(struct file *file,if (copy_from_user (buf, input, size))return -EFAULT ; -while (isspace (*c)) - c++; + c =skip_spaces (c);if (size - (c - buf) <5 )return c - buf;
sound/pci/hda/hda_hwdep.c +3 -4
@@ -24,6 +24,7 @@#include <linux/compat.h> #include <linux/mutex.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/firmware.h> #include <sound/core.h> #include "hda_codec.h"
@@ -390,8 +391,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf)char *key, *val;struct hda_hint *hint; -while (isspace (*buf)) - buf++; + buf =skip_spaces (buf);if (!*buf || *buf =='#' || *buf =='\n' )return 0 ;if (*buf =='=' )
@@ -406,8 +406,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf)return -EINVAL ; } *val++ =0 ; -while (isspace (*val)) - val++; + val =skip_spaces (val);remove_trail_spaces (key);remove_trail_spaces (val); hint =get_hint (codec, key);
Signature · 1 line
1.6.5.2.153.g6e31f.dirty
PATCH v4 1/12 vsprintf: factorize "(null)" string
In reply to André Goddard RosaChange "<NULL>" to "(null)" and make it a static const char[] hoping that the compiler will make null_str a label to a read-only area containing it.
See:
http://people.redhat.com/drepper/dsohowto.pdf part 2.4.2
http://udrepper.livejournal.com/13851.html
http://udrepper.livejournal.com/15119.html
--- lib/vsprintf.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
lib/vsprintf.c +6 -4
@@ -34,6 +34,8 @@/* Works only for digits and letters, but small and fast */ #define TOLOWER (x) ((x) | 0x20) +static const char null_str[] ="(null)" ; +static unsigned int simple_guess_base (const char *cp) {if (cp[0 ] =='0' ) {
@@ -546,12 +548,12 @@ static char *number(char *buf, char *end, unsigned long long num,return buf; } -static char *string (char *buf,char *end,char *s,struct printf_spec spec) +static char *string (char *buf,char *end,const char *s,struct printf_spec spec) {int len, i;if ((unsigned long )s <PAGE_SIZE ) - s ="<NULL>" ; + s = null_str; len =strnlen (s, spec.precision);
@@ -822,7 +824,7 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, struct printf_spec spec) {if (!ptr) -return string (buf, end,"(null)" , spec); +return string (buf, end, null_str, spec);switch (*fmt) {case 'F' :
@@ -1445,7 +1447,7 @@ do { \size_t len;if ((unsigned long )save_str > (unsigned long )-PAGE_SIZE || (unsigned long )save_str <PAGE_SIZE ) - save_str ="<NULL>" ; + save_str = null_str; len =strlen (save_str);if (str + len +1 < end)memcpy (str, save_str, len +1 );
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 2/12 vsprintf: pre-calculate final string length for later use
In reply to André Goddard Rosa--- lib/vsprintf.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
lib/vsprintf.c +6 -4
@@ -1445,13 +1445,15 @@ do { \case FORMAT_TYPE_STR : { const char *save_str = va_arg(args, char *);size_t len; +if ((unsigned long )save_str > (unsigned long )-PAGE_SIZE || (unsigned long )save_str <PAGE_SIZE ) save_str = null_str; - len =strlen (save_str); -if (str + len +1 < end) -memcpy (str, save_str, len +1 ); - str += len +1 ; + len =strlen (save_str) +1 ; +if (str + len < end) +memcpy (str, save_str, len); + str += len; +break ; }
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 3/12 vsprintf: give it some care to please checkpatch.pl
In reply to André Goddard RosaMost relevant complaints were addressed.
--- lib/vsprintf.c | 186 ++++++++++++++++++++++++++++++-------------------------- 1 files changed, 99 insertions(+), 87 deletions(-)
lib/vsprintf.c +99 -87
@@ -9,7 +9,7 @@* Wirzenius wrote this portably, Torvalds fucked it up :-) */ -/* +/* * Fri Jul 13 2001 Crutcher Dunnavant <[email protected]> * - changed to provide snprintf and vsnprintf functions * So Feb 1 16:51:32 CET 2004 Juergen Quade <[email protected]>
@@ -73,9 +73,9 @@ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) result = result * base + value; cp++; } -if (endp) *endp = (char *)cp; +return result; }EXPORT_SYMBOL (simple_strtoul);
@@ -88,8 +88,9 @@ EXPORT_SYMBOL(simple_strtoul);*/ long simple_strtol (const char *cp,char **endp,unsigned int base) { -if (*cp =='-' ) +if (*cp =='-' )return -simple_strtoul (cp +1 , endp, base); +return simple_strtoul (cp, endp, base); }EXPORT_SYMBOL (simple_strtol);
@@ -119,9 +120,9 @@ unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int bas result = result * base + value; cp++; } -if (endp) *endp = (char *)cp; +return result; }EXPORT_SYMBOL (simple_strtoull);
@@ -134,8 +135,9 @@ EXPORT_SYMBOL(simple_strtoull);*/ long long simple_strtoll (const char *cp,char **endp,unsigned int base) { -if (*cp=='-' ) +if (*cp =='-' )return -simple_strtoull (cp +1 , endp, base); +return simple_strtoull (cp, endp, base); }
@@ -175,6 +177,7 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) val =simple_strtoul (cp, &tail, base);if (tail == cp)return -EINVAL ; +if ((*tail =='\0' ) || ((len == (size_t )(tail - cp) +1 ) && (*tail =='\n' ))) { *res = val;
@@ -287,10 +290,11 @@ EXPORT_SYMBOL(strict_strtoll);static int skip_atoi (const char **s) { -int i=0 ; +int i =0 ;while (isdigit (**s)) i = i*10 + *((*s)++) -'0' ; +return i; }
@@ -304,7 +308,7 @@ static int skip_atoi(const char **s)/* Formats correctly any integer in [0,99999]. * Outputs from one to five digits depending on input. * On i386 gcc 4.1.2 -O2: ~250 bytes of code. */ -static char *put_dec_trunc (char *buf,unsigned q) +static char *put_dec_trunc (char *buf,unsigned q) {unsigned d3, d2, d1, d0; d1 = (q>>4 ) &0xf ;
@@ -333,14 +337,15 @@ static char* put_dec_trunc(char *buf, unsigned q) d3 = d3 -10 *q; *buf++ = d3 +'0' ;/* next digit */ if (q !=0 ) - *buf++ = q +'0' ;/* most sign. digit */ + *buf++ = q +'0' ;/* most sign. digit */ } } } +return buf; }/* Same with if's removed. Always emits five digits */ -static char *put_dec_full (char *buf,unsigned q) +static char *put_dec_full (char *buf,unsigned q) {/* BTW, if q is in [0,9999], 8-bit ints will be enough, */ /* but anyway, gcc produces better code with full-sized ints */
@@ -349,14 +354,15 @@ static char* put_dec_full(char *buf, unsigned q) d2 = (q>>8 ) &0xf ; d3 = (q>>12 ); -/* Possible ways to approx. divide by 10 */ -/* gcc -O2 replaces multiply with shifts and adds */ -// (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) -// (x * 0x67) >> 10: 1100111 -// (x * 0x34) >> 9: 110100 - same -// (x * 0x1a) >> 8: 11010 - same -// (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) - +/* +* Possible ways to approx. divide by 10 +* gcc -O2 replaces multiply with shifts and adds +* (x * 0xcd) >> 11: 11001101 - shorter code than * 0x67 (on i386) +* (x * 0x67) >> 10: 1100111 +* (x * 0x34) >> 9: 110100 - same +* (x * 0x1a) >> 8: 11010 - same +* (x * 0x0d) >> 7: 1101 - same, shortest code (on i386) +*/ d0 =6 *(d3 + d2 + d1) + (q &0xf ); q = (d0 *0xcd ) >>11 ; d0 = d0 -10 *q;
@@ -377,10 +383,11 @@ static char* put_dec_full(char *buf, unsigned q) d3 = d3 -10 *q; *buf++ = d3 +'0' ; *buf++ = q +'0' ; +return buf; }/* No inlining helps gcc to use registers better */ -static noinline char* put_dec(char *buf, unsigned long long num) +static noinline char *put_dec(char *buf, unsigned long long num) {while (1 ) {unsigned rem;
@@ -450,9 +457,9 @@ static char *number(char *buf, char *end, unsigned long long num, spec.flags &= ~ZEROPAD ; sign =0 ;if (spec.flags &SIGN ) { -if ((signed long long ) num <0 ) { +if ((signed long long )num <0 ) { sign ='-' ; - num = - (signed long long ) num; + num = -(signed long long )num; spec.field_width--; }else if (spec.flags &PLUS ) { sign ='+' ;
@@ -480,7 +487,9 @@ static char *number(char *buf, char *end, unsigned long long num,else if (spec.base !=10 ) {/* 8 or 16 */ int mask = spec.base -1 ;int shift =3 ; -if (spec.base ==16 ) shift =4 ; + +if (spec.base ==16 ) + shift =4 ; do { tmp[i++] = (digits[((unsigned char)num) & mask] | locase); num >>= shift;
@@ -495,7 +504,7 @@ static char *number(char *buf, char *end, unsigned long long num,/* leading space padding */ spec.field_width -= spec.precision;if (!(spec.flags & (ZEROPAD +LEFT ))) { -while (--spec.field_width >=0 ) { +while (--spec.field_width >=0 ) {if (buf < end) *buf =' ' ; ++buf;
@@ -545,6 +554,7 @@ static char *number(char *buf, char *end, unsigned long long num, *buf =' ' ; ++buf; } +return buf; }
@@ -574,6 +584,7 @@ static char *string(char *buf, char *end, const char *s, struct printf_spec spec *buf =' ' ; ++buf; } +return buf; }
@@ -587,11 +598,13 @@ static char *symbol_string(char *buf, char *end, void *ptr,sprint_symbol (sym, value); elsekallsyms_lookup (value ,NULL ,NULL ,NULL ,sym ); +return string (buf, end, sym, spec);#else - spec.field_width =2 *sizeof (void *); + spec.field_width =2 *sizeof (void *); spec.flags |=SPECIAL |SMALL |ZEROPAD ; spec.base =16 ; +return number (buf, end, value, spec);#endif }
@@ -611,7 +624,7 @@ static char *resource_string(char *buf, char *end, struct resource *res, .precision = -1, .flags = SPECIAL | SMALL | ZEROPAD, }; -/* room for the actual numbers, the two "0x", -, [, ] and the final zero */ +/* room for actual numbers: the two "0x", -, [, ] and the final zero */ char sym[4 *sizeof (resource_size_t) +8 ];char *p = sym, *pend = sym +sizeof (sym);int size =-1 ;
@@ -668,22 +681,19 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)if (i <3 ) *p++ ='.' ; } - *p ='\0' ; +return p; }static char *ip6_compressed_string (char *p,const char *addr) { -int i; -int j; -int range; +int i, j, range;unsigned char zerolength[8 ];int longest =1 ;int colonpos =-1 ;u16 word; -u8 hi; -u8 lo; +u8 hi, lo;bool needcolon = false;bool useIPv4;struct in6_addr in6;
@@ -750,22 +760,23 @@ static char *ip6_compressed_string(char *p, const char *addr) *p++ =':' ; p =ip4_string (p, &in6.s6_addr[12 ], false); } - *p ='\0' ; +return p; }static char *ip6_string (char *p,const char *addr,const char *fmt) {int i; +for (i =0 ; i <8 ; i++) { p =pack_hex_byte (p, *addr++); p =pack_hex_byte (p, *addr++);if (fmt[0 ] =='I' && i !=7 ) *p++ =':' ; } - *p ='\0' ; +return p; }
@@ -1271,7 +1282,8 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) {int i; - i=vsnprintf (buf,size,fmt,args); + i =vsnprintf (buf, size, fmt, args); +return (i >= size) ? (size -1 ) : i; }EXPORT_SYMBOL (vscnprintf);
@@ -1290,14 +1302,15 @@ EXPORT_SYMBOL(vscnprintf);* * See the vsnprintf() documentation for format string extensions over C99. */ -int snprintf (char * buf,size_t size,const char *fmt, ...) +int snprintf (char *buf,size_t size,const char *fmt, ...) {va_list args;int i;va_start (args, fmt); - i=vsnprintf (buf,size,fmt,args); + i =vsnprintf (buf, size, fmt, args);va_end (args); +return i; }EXPORT_SYMBOL (snprintf);
@@ -1313,7 +1326,7 @@ EXPORT_SYMBOL(snprintf);* the trailing '\0'. If @size is <= 0 the function returns 0. */ -int scnprintf (char * buf,size_t size,const char *fmt, ...) +int scnprintf (char *buf,size_t size,const char *fmt, ...) {va_list args;int i;
@@ -1321,6 +1334,7 @@ int scnprintf(char * buf, size_t size, const char *fmt, ...)va_start (args, fmt); i =vsnprintf (buf, size, fmt, args);va_end (args); +return (i >= size) ? (size -1 ) : i; }EXPORT_SYMBOL (scnprintf);
@@ -1358,14 +1372,15 @@ EXPORT_SYMBOL(vsprintf);* * See the vsnprintf() documentation for format string extensions over C99. */ -int sprintf (char * buf,const char *fmt, ...) +int sprintf (char *buf,const char *fmt, ...) {va_list args;int i;va_start (args, fmt); - i=vsnprintf (buf,INT_MAX , fmt, args); + i =vsnprintf (buf,INT_MAX , fmt, args);va_end (args); +return i; }EXPORT_SYMBOL (sprintf);
@@ -1423,7 +1438,6 @@ do { \ str +=sizeof (type); \ }while (0 ) -while (*fmt) { read =format_decode (fmt, &spec);
@@ -1512,8 +1526,8 @@ do { \ } } } -return (u32 *)(PTR_ALIGN (str,sizeof (u32))) - bin_buf; +return (u32 *)(PTR_ALIGN (str,sizeof (u32))) - bin_buf;#undef save_arg }EXPORT_SYMBOL_GPL (vbin_printf);
@@ -1545,7 +1559,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)unsigned long long num;char *str, *end, c;const char *args = (const char *)bin_buf; -struct printf_spec spec = {0 };if (WARN_ON_ONCE ((int ) size <0 ))
@@ -1725,6 +1738,7 @@ int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)va_start (args, fmt); ret =vbin_printf (bin_buf, size, fmt, args);va_end (args); +return ret; }EXPORT_SYMBOL_GPL (bprintf);
@@ -1737,18 +1751,16 @@ EXPORT_SYMBOL_GPL(bprintf);* @fmt: format of buffer * @args: arguments */ -int vsscanf (const char * buf,const char * fmt,va_list args) +int vsscanf (const char *buf,const char *fmt,va_list args) {const char *str = buf;char *next;char digit;int num =0 ; -int qualifier; -int base; -int field_width; +int qualifier, base, field_width;int is_sign =0 ; -while (*fmt && *str) { +while (*fmt && *str) {/* skip any white space in format */ /* white space in format matchs any amount of * white space, including none, in the input.
@@ -1770,7 +1782,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)if (!*fmt)break ; ++fmt; - +/* skip this conversion. * advance both strings to next white space */
@@ -1808,10 +1820,10 @@ int vsscanf(const char * buf, const char * fmt, va_list args)if (!*fmt || !*str)break ; -switch (*fmt++) { +switch (*fmt++) {case 'c' : { - char *s = (char *) va_arg(args,char*); + char *s = (char *)va_arg(args, char*);if (field_width ==-1 ) field_width =1 ; do {
@@ -1822,17 +1834,16 @@ int vsscanf(const char * buf, const char * fmt, va_list args)continue ;case 's' : { - char *s = (char *) va_arg(args, char *); -if (field_width ==-1 ) + char *s = (char *)va_arg(args, char *); +if (field_width ==-1 ) field_width =INT_MAX ;/* first, skip leading white space in buffer */ while (isspace (*str)) str++;/* now copy until next white space */ -while (*str && !isspace (*str) && field_width--) { +while (*str && !isspace (*str) && field_width--) *s++ = *str++; - } *s ='\0' ; num++; }
@@ -1840,7 +1851,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)case 'n' :/* return number of characters read so far */ { - int *i = (int *)va_arg(args,int*); + int *i = (int *)va_arg(args, int*); *i = str - buf; }continue ;
@@ -1852,14 +1863,14 @@ int vsscanf(const char * buf, const char * fmt, va_list args) base =16 ;break ;case 'i' : - base =0 ; + base =0 ;case 'd' : is_sign =1 ;case 'u' :break ;case '%' :/* looking for '%' in str */ -if (*str++ !='%' ) +if (*str++ !='%' )return num;continue ;default :
@@ -1878,63 +1889,63 @@ int vsscanf(const char * buf, const char * fmt, va_list args) digit = *(str +1 );if (!digit - || (base ==16 && !isxdigit (digit)) - || (base ==10 && !isdigit (digit)) - || (base ==8 && (!isdigit (digit) || digit >'7' )) - || (base ==0 && !isdigit (digit))) -break ; + || (base ==16 && !isxdigit (digit)) + || (base ==10 && !isdigit (digit)) + || (base ==8 && (!isdigit (digit) || digit >'7' )) + || (base ==0 && !isdigit (digit))) +break ; -switch (qualifier) { +switch (qualifier) {case 'H' :/* that's 'hh' in format */ if (is_sign) { - signed char *s = (signed char *) va_arg(args,signed char *); - *s = (signed char )simple_strtol (str,&next,base); + signed char *s = (signed char *)va_arg(args, signed char *); + *s = (signed char )simple_strtol (str, &next, base); }else { - unsigned char *s = (unsigned char *) va_arg(args, unsigned char *); - *s = (unsigned char )simple_strtoul (str, &next, base); + unsigned char *s = (unsigned char *)va_arg(args, unsigned char *); + *s = (unsigned char )simple_strtoul (str, &next, base); }break ;case 'h' :if (is_sign) { - short *s = (short *) va_arg(args,short *); - *s = (short )simple_strtol (str,&next,base); + short *s = (short *)va_arg(args, short *); + *s = (short )simple_strtol (str, &next, base); }else { - unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); - *s = (unsigned short )simple_strtoul (str, &next, base); + unsigned short *s = (unsigned short *)va_arg(args, unsigned short *); + *s = (unsigned short )simple_strtoul (str, &next, base); }break ;case 'l' :if (is_sign) { - long *l = (long *) va_arg(args,long *); - *l =simple_strtol (str,&next,base); + long *l = (long *)va_arg(args, long *); + *l =simple_strtol (str, &next, base); }else { - unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); - *l =simple_strtoul (str,&next,base); + unsigned long *l = (unsigned long *)va_arg(args, unsigned long *); + *l =simple_strtoul (str, &next, base); }break ;case 'L' :if (is_sign) { - long long *l = (long long*) va_arg(args,long long *); - *l =simple_strtoll (str,&next,base); + long long *l = (long long *)va_arg(args, long long *); + *l =simple_strtoll (str, &next, base); }else { - unsigned long long *l = (unsigned long long*) va_arg(args,unsigned long long*); - *l =simple_strtoull (str,&next,base); + unsigned long long *l = (unsigned long long *)va_arg(args, unsigned long long *); + *l =simple_strtoull (str, &next, base); }break ;case 'Z' :case 'z' : { - size_t *s = (size_t*) va_arg(args,size_t*); - *s = (size_t )simple_strtoul (str,&next,base); + size_t *s = (size_t *)va_arg(args, size_t *); + *s = (size_t )simple_strtoul (str, &next, base); }break ;default :if (is_sign) { - int *i = (int *) va_arg(args, int*); - *i = (int )simple_strtol (str,&next,base); + int *i = (int *)va_arg(args, int *); + *i = (int )simple_strtol (str, &next, base); }else { - unsigned int *i = (unsigned int*) va_arg(args, unsigned int*); - *i = (unsigned int )simple_strtoul (str,&next,base); + unsigned int *i = (unsigned int *)va_arg(args, unsigned int*); + *i = (unsigned int )simple_strtoul (str, &next, base); }break ; }
@@ -1965,14 +1976,15 @@ EXPORT_SYMBOL(vsscanf);* @fmt: formatting of buffer * @...: resulting arguments */ -int sscanf (const char * buf,const char * fmt, ...) +int sscanf (const char *buf,const char *fmt, ...) {va_list args;int i; -va_start (args,fmt); - i =vsscanf (buf,fmt,args); +va_start (args, fmt); + i =vsscanf (buf, fmt, args);va_end (args); +return i; }EXPORT_SYMBOL (sscanf);
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 4/12 vsprintf: use TOLOWER whenever possible
In reply to André Goddard RosaIt decreases code size as well:
text data bss dec hex filename
15767 0 8 15775 3d9f lib/vsprintf.o-before 15735 0 8 15743 3d7f lib/vsprintf.o-TOLOWER
--- lib/vsprintf.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-)
lib/vsprintf.c +7 -8
@@ -983,8 +983,8 @@ precision: qualifier:/* get the conversion qualifier */ spec->qualifier =-1 ; -if (*fmt =='h' || *fmt =='l' || *fmt =='L' || - *fmt =='Z' || *fmt =='z' || *fmt =='t' ) { +if (*fmt =='h' ||TOLOWER (*fmt) =='l' || +TOLOWER (*fmt) =='z' || *fmt =='t' ) { spec->qualifier = *fmt++;if (unlikely (spec->qualifier == *fmt)) {if (spec->qualifier =='l' ) {
@@ -1051,7 +1051,7 @@ qualifier: spec->type =FORMAT_TYPE_LONG ; else spec->type = FORMAT_TYPE_ULONG; - }else if (spec->qualifier =='Z' || spec->qualifier =='z' ) { + }else if (TOLOWER (spec->qualifier) =='z' ) { spec->type =FORMAT_TYPE_SIZE_T ; }else if (spec->qualifier =='t' ) { spec->type =FORMAT_TYPE_PTRDIFF ;
@@ -1198,8 +1198,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)if (qualifier =='l' ) { long *ip = va_arg(args, long *); *ip = (str - buf); - }else if (qualifier =='Z' || - qualifier =='z' ) { + }else if (TOLOWER (qualifier) =='z' ) { size_t *ip = va_arg(args, size_t *); *ip = (str - buf); }else {
@@ -1490,7 +1489,7 @@ do { \void *skip_arg;if (qualifier =='l' ) skip_arg = va_arg(args, long *); -else if (qualifier =='Z' || qualifier =='z' ) +else if (TOLOWER (qualifier) =='z' ) skip_arg = va_arg(args, size_t *);else skip_arg = va_arg(args, int *);
@@ -1801,8 +1800,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)/* get conversion qualifier */ qualifier =-1 ; -if (*fmt =='h' || *fmt =='l' || *fmt =='L' || - *fmt =='Z' || *fmt =='z' ) { +if (*fmt =='h' ||TOLOWER (*fmt) =='l' || +TOLOWER (*fmt) =='z' ) { qualifier = *fmt++;if (unlikely (qualifier == *fmt)) {if (qualifier =='h' ) {
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 5/12 vsprintf: reduce code size by avoiding extra check
In reply to André Goddard RosaNo functional change, just refactor the code so that it avoid checking "if (hi)" two times in a sequence, taking advantage of previous check made.
It also reduces code size:
text data bss dec hex filename
15735 0 8 15743 3d7f lib/vsprintf.o-before 15719 0 8 15727 3d6f lib/vsprintf.o-minus-double-check
--- lib/vsprintf.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
lib/vsprintf.c +2 -1
@@ -747,8 +747,9 @@ static char *ip6_compressed_string(char *p, const char *addr) p =pack_hex_byte (p, hi); else *p++ = hex_asc_lo(hi); + p =pack_hex_byte (p, lo); } -if (hi || lo >0x0f ) +else if (lo >0x0f ) p =pack_hex_byte (p, lo);else *p++ =hex_asc_lo (lo);
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 6/12 vsprintf: move local vars to block local vars and remove unneeded ones
In reply to André Goddard RosaCleanup by moving variables closer to the scope where they're used in fact. Also, remove unneeded ones.
--- lib/vsprintf.c | 64 ++++++++++++++++++++++++------------------------------- 1 files changed, 28 insertions(+), 36 deletions(-)
lib/vsprintf.c +28 -36
@@ -842,8 +842,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,case 'F' :case 'f' : ptr =dereference_function_descriptor (ptr); -case 's' :/* Fallthrough */ +case 's' :case 'S' :return symbol_string (buf, end, ptr, spec, *fmt);case 'R' :
@@ -1105,8 +1105,7 @@ qualifier:int vsnprintf (char *buf,size_t size,const char *fmt,va_list args) {unsigned long long num; -char *str, *end, c; -int read; +char *str, *end;struct printf_spec spec = {0 };/* Reject out-of-range values early. Large positive sizes are
@@ -1125,8 +1124,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)while (*fmt) {const char *old_fmt = fmt; - - read =format_decode (fmt, &spec); +int read =format_decode (fmt, &spec); fmt += read;
@@ -1150,7 +1148,9 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) spec.precision =va_arg (args, int);break ; -case FORMAT_TYPE_CHAR : +case FORMAT_TYPE_CHAR : { +char c; +if (!(spec.flags &LEFT )) {while (--spec.field_width >0 ) {if (str < end)
@@ -1169,6 +1169,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++str; }break ; + }case FORMAT_TYPE_STR : str = string(str, end, va_arg(args, char *), spec);
@@ -1413,7 +1414,6 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) {struct printf_spec spec = {0 };char *str, *end; -int read; str = (char *)bin_buf; end = (char *)(bin_buf + size);
@@ -1439,12 +1439,14 @@ do { \ }while (0 )while (*fmt) { - read =format_decode (fmt, &spec); +int read =format_decode (fmt, &spec); fmt += read;switch (spec.type) {case FORMAT_TYPE_NONE : +case FORMAT_TYPE_INVALID : +case FORMAT_TYPE_PERCENT_CHAR :break ;case FORMAT_TYPE_WIDTH :
@@ -1478,12 +1480,6 @@ do { \ fmt++;break ; -case FORMAT_TYPE_PERCENT_CHAR : -break ; - -case FORMAT_TYPE_INVALID : -break ; -case FORMAT_TYPE_NRCHARS : {/* skip %n 's argument */ int qualifier = spec.qualifier;
@@ -1556,10 +1552,9 @@ EXPORT_SYMBOL_GPL(vbin_printf);*/ int bstr_printf (char *buf,size_t size,const char *fmt,const u32 *bin_buf) { -unsigned long long num; -char *str, *end, c; -const char *args = (const char *)bin_buf;struct printf_spec spec = {0 }; +char *str, *end; +const char *args = (const char *)bin_buf;if (WARN_ON_ONCE ((int ) size <0 ))return 0 ;
@@ -1589,10 +1584,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) }while (*fmt) { -int read;const char *old_fmt = fmt; - - read =format_decode (fmt, &spec); +int read =format_decode (fmt, &spec); fmt += read;
@@ -1616,7 +1609,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) spec.precision =get_arg (int);break ; -case FORMAT_TYPE_CHAR : +case FORMAT_TYPE_CHAR : { +char c; +if (!(spec.flags &LEFT )) {while (--spec.field_width >0 ) {if (str < end)
@@ -1634,11 +1629,11 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) ++str; }break ; + }case FORMAT_TYPE_STR : {const char *str_arg = args; -size_t len =strlen (str_arg); - args += len +1 ; + args +=strlen (str_arg) +1 ; str =string (str, end, (char *)str_arg, spec);break ; }
@@ -1650,11 +1645,6 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)break ;case FORMAT_TYPE_PERCENT_CHAR : -if (str < end) - *str ='%' ; - ++str; -break ; -case FORMAT_TYPE_INVALID :if (str < end) *str ='%' ;
@@ -1665,15 +1655,15 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)/* skip */ break ; -default : +default : { +unsigned long long num; +switch (spec.type) {case FORMAT_TYPE_LONG_LONG : num = get_arg(long long);break ;case FORMAT_TYPE_ULONG : - num = get_arg(unsigned long); -break ;case FORMAT_TYPE_LONG : num = get_arg(unsigned long);break ;
@@ -1703,8 +1693,9 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) } str =number (str, end, num, spec); - } - } + }/* default: */ + }/* switch(spec.type) */ + }/* while(*fmt) */ if (size >0 ) {if (str < end)
@@ -1758,7 +1749,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)char digit;int num =0 ;int qualifier, base, field_width; -int is_sign =0 ; +bool is_sign;while (*fmt && *str) {/* skip any white space in format */
@@ -1814,12 +1805,13 @@ int vsscanf(const char *buf, const char *fmt, va_list args) } } } - base =10 ; - is_sign =0 ;if (!*fmt || !*str)break ; + base =10 ; + is_sign =0 ; +switch (*fmt++) {case 'c' : {
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 7/12 vsprintf: factor out skip_space code in a separate function
In reply to André Goddard RosaIt decreases code size:
text data bss dec hex filename
15719 0 8 15727 3d6f lib/vsprintf.o-before 15543 0 8 15551 3cbf lib/vsprintf.o-after
--- lib/vsprintf.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-)
lib/vsprintf.c +11 -8
@@ -1736,6 +1736,13 @@ EXPORT_SYMBOL_GPL(bprintf);#endif /* CONFIG_BINARY_PRINTF */ +static noinline const char *skip_space(const char *str) +{ +while (isspace (*str)) + ++str; +return str; +} +/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer
@@ -1757,10 +1764,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)* white space, including none, in the input. */ if (isspace (*fmt)) { -while (isspace (*fmt)) - ++fmt; -while (isspace (*str)) - ++str; + fmt =skip_space (fmt); + str =skip_space (str); }/* anything that is not a conversion must match exactly */
@@ -1830,8 +1835,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)if (field_width ==-1 ) field_width =INT_MAX ;/* first, skip leading white space in buffer */ -while (isspace (*str)) - str++; + str =skip_space (str);/* now copy until next white space */ while (*str && !isspace (*str) && field_width--)
@@ -1873,8 +1877,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)/* have some sort of integer conversion. * first, skip white space in buffer. */ -while (isspace (*str)) - str++; + str =skip_space (str); digit = *str;if (is_sign && digit =='-' )
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 8/12 vsprintf: reuse almost identical simple_strtoulX() functions
In reply to André Goddard RosaThe difference between simple_strtoul() and simple_strtoull() is just the size of the variable used to keep track of the sum of characters converted to numbers:
unsigned long simple_strtoul() {...}
unsigned long long simple_strtoull(){...}
Both are same size (8 bytes) on my Core 2/gcc 4.4.1.
Overflow condition is not checked on both functions, so an extremely large string can break these functions so that they don't even notice it.
As we do not care for overflowing on these functions, always keep the sum using the larger variable around (unsigned long long) on simple_strtoull() and cast it to (unsigned long) on simple_strtoul(), which then becomes just a wrapper around simple_strtoull().
Code size decreases by 304 bytes:
text data bss dec hex filename
15543 0 8 15551 3cbf lib/vsprintf.o-before 15239 0 8 15247 3b8f lib/vsprintf.o-after
--- lib/vsprintf.c | 48 ++++++++++++++---------------------------------- 1 files changed, 14 insertions(+), 34 deletions(-)
lib/vsprintf.c +14 -34
@@ -49,14 +49,14 @@ static unsigned int simple_guess_base(const char *cp) }/** -* simple_strtoul - convert a string to an unsigned long +* simple_strtoull - convert a string to an unsigned long long * @cp: The start of the string * @endp: A pointer to the end of the parsed string will be placed here * @base: The number base to use */ -unsigned long simple_strtoul (const char *cp,char **endp,unsigned int base) +unsigned long long simple_strtoull (const char *cp,char **endp,unsigned int base) { -unsigned long result =0 ; +unsigned long long result =0 ;if (!base) base =simple_guess_base (cp);
@@ -78,54 +78,34 @@ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)return result; } -EXPORT_SYMBOL (simple_strtoul); +EXPORT_SYMBOL (simple_strtoull);/** -* simple_strtol - convert a string to a signed long +* simple_strtoul - convert a string to an unsigned long * @cp: The start of the string * @endp: A pointer to the end of the parsed string will be placed here * @base: The number base to use */ -long simple_strtol (const char *cp,char **endp,unsigned int base) +unsigned long simple_strtoul (const char *cp,char **endp,unsigned int base) { -if (*cp =='-' ) -return -simple_strtoul (cp +1 , endp, base); - -return simple_strtoul (cp, endp, base); +return (unsigned long )simple_strtoull (cp, endp, base); } -EXPORT_SYMBOL (simple_strtol); +EXPORT_SYMBOL (simple_strtoul);/** -* simple_strtoull - convert a string to an unsigned long long +* simple_strtol - convert a string to a signed long * @cp: The start of the string * @endp: A pointer to the end of the parsed string will be placed here * @base: The number base to use */ -unsigned long long simple_strtoull (const char *cp,char **endp,unsigned int base) +long simple_strtol (const char *cp,char **endp,unsigned int base) { -unsigned long long result =0 ; - -if (!base) - base =simple_guess_base (cp); - -if (base ==16 && cp[0 ] =='0' &&TOLOWER (cp[1 ]) =='x' ) - cp +=2 ; - -while (isxdigit (*cp)) { -unsigned int value; - - value =isdigit (*cp) ? *cp -'0' :TOLOWER (*cp) -'a' +10 ; -if (value >= base) -break ; - result = result * base + value; - cp++; - } -if (endp) - *endp = (char *)cp; +if (*cp =='-' ) +return -simple_strtoul (cp +1 , endp, base); -return result; +return simple_strtoul (cp, endp, base); } -EXPORT_SYMBOL (simple_strtoull); +EXPORT_SYMBOL (simple_strtol);/** * simple_strtoll - convert a string to a signed long long
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 9/12 ctype: constify read-only _ctype string
In reply to André Goddard RosaWhile at it, use tabs to indent the comments.
--- include/linux/ctype.h | 2 +- lib/ctype.c | 50 ++++++++++++++++++++++++------------------------ 2 files changed, 26 insertions(+), 26 deletions(-)
include/linux/ctype.h +1 -1
@@ -15,7 +15,7 @@#define _X 0x40/* hex digit */ #define _SP 0x80/* hard space (0x20) */ -extern unsigned char _ctype[]; +extern const unsigned char _ctype[];#define __ismask (x) (_ctype[(int)(unsigned char)(x)])
lib/ctype.c +25 -25
55 lines not on this page · raw message
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 10/12 string: factorize skip_spaces and export it to be generally available
In reply to André Goddard RosaOn the following sentence:
while (*s && isspace(*s))
s++;If *s == 0, isspace() evaluates to ((_ctype[*s] & 0x20) != 0), which evaluates to ((0x08 & 0x20) != 0) which equals to 0 as well. If *s == 1, we depend on isspace() result anyway.
In other words, "a char equals zero is never a space". So remove this check. Also, *s != 0 is by far the most common case (non-empty string).
--- include/linux/string.h | 1 + lib/string.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-)
include/linux/string.h +1 -0
@@ -62,6 +62,7 @@ extern char * strnchr(const char *, size_t, int);#ifndef __HAVE_ARCH_STRRCHRextern char *strrchr (const char *,int );#endif +extern const char *__must_check skip_spaces (const char *);extern char *__must_check strstrip (char *);#ifndef __HAVE_ARCH_STRSTRextern char *strstr (const char *,const char *);
lib/string.c +15 -4
@@ -330,6 +330,20 @@ EXPORT_SYMBOL(strnchr);#endif /** +* skip_spaces - Removes leading whitespace from @s. +* @s: The string to be stripped. +* +* Returns a pointer to the first non-whitespace character in @s. +*/ +const char *skip_spaces (const char *str) +{ +while (isspace (*str)) + ++str; +return str; +} +EXPORT_SYMBOL (skip_spaces); + +/** * strstrip - Removes leading and trailing whitespace from @s. * @s: The string to be stripped. *
@@ -352,10 +366,7 @@ char *strstrip(char *s) end--; *(end +1 ) ='\0' ; -while (*s &&isspace (*s)) - s++; - -return s; +return (char *)skip_spaces (s); }EXPORT_SYMBOL (strstrip);
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 11/12 string: on strstrip(), first remove leading spaces before running over str
In reply to André Goddard Rosa... so that strlen() iterates over a smaller string comprising of the remaining characters only.
--- lib/string.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
lib/string.c +2 -2
@@ -356,8 +356,8 @@ char *strstrip(char *s)size_t size;char *end; + s = (char *)skip_spaces (s); size =strlen (s); -if (!size)return s;
@@ -366,7 +366,7 @@ char *strstrip(char *s) end--; *(end +1 ) ='\0' ; -return (char *)skip_spaces (s); +return s; }EXPORT_SYMBOL (strstrip);
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
PATCH v4 12/12 tree-wide: convert open calls to remove spaces to skip_spaces() lib function
In reply to André Goddard RosaMakes use of skip_spaces() defined in lib/string.c for removing leading spaces from strings all over the tree.
Also, while at it, if we see (*str && isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".
--- arch/s390/kernel/debug.c | 3 +- arch/um/drivers/mconsole_kern.c | 16 ++++++-------- arch/x86/kernel/cpu/mtrr/if.c | 11 +++------ drivers/md/dm-table.c | 6 +--- drivers/md/md.c | 4 +- drivers/parisc/pdc_stable.c | 9 ++----- drivers/platform/x86/thinkpad_acpi.c | 7 +---- drivers/pnp/interface.c | 36 +++++++++----------------------- drivers/s390/block/dasd_proc.c | 5 ++- drivers/video/backlight/lcd.c | 4 +- drivers/video/display/display-sysfs.c | 2 +- fs/cachefiles/daemon.c | 8 ++---- fs/ext4/super.c | 7 +---- kernel/params.c | 8 ++---- lib/argv_split.c | 13 ++--------- lib/dynamic_debug.c | 4 +- lib/vsprintf.c | 15 +++---------- net/irda/irnet/irnet.h | 1 + net/irda/irnet/irnet_ppp.c | 8 ++---- net/netfilter/xt_recent.c | 3 +- sound/pci/hda/hda_hwdep.c | 7 ++--- 21 files changed, 63 insertions(+), 114 deletions(-)
arch/s390/kernel/debug.c +2 -1
@@ -18,6 +18,7 @@#include <linux/errno.h> #include <linux/slab.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/sysctl.h> #include <asm/uaccess.h> #include <linux/module.h>
@@ -1183,7 +1184,7 @@ debug_get_uint(char *buf) {int rc; -for (;isspace (*buf); buf++); + buf =skip_spaces (buf); rc =simple_strtoul (buf, &buf,10 );if (*buf){ rc = -EINVAL ;
arch/um/drivers/mconsole_kern.c +7 -9
@@ -6,6 +6,7 @@#include <linux/console.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/interrupt.h> #include <linux/list.h> #include <linux/mm.h>
@@ -131,7 +132,7 @@ void mconsole_proc(struct mc_request *req)char *ptr = req->request.data, *buf; ptr +=strlen ("proc" ); -while (isspace (*ptr)) ptr++; + ptr =skip_spaces (ptr); proc =get_fs_type ("proc" );if (proc ==NULL ) {
@@ -212,8 +213,7 @@ void mconsole_proc(struct mc_request *req)char *ptr = req->request.data; ptr +=strlen ("proc" ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);snprintf (path,sizeof (path),"/proc/%s" , ptr); fd =sys_open (path,0 ,0 );
@@ -560,8 +560,7 @@ void mconsole_config(struct mc_request *req)int err; ptr +=strlen ("config" ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr); dev =mconsole_find_dev (ptr);if (dev ==NULL ) {mconsole_reply (req,"Bad configuration option" ,1 ,0 );
@@ -588,7 +587,7 @@ void mconsole_remove(struct mc_request *req)int err, start, end, n; ptr +=strlen ("remove" ); -while (isspace (*ptr)) ptr++; + ptr =skip_spaces (ptr); dev =mconsole_find_dev (ptr);if (dev ==NULL ) {mconsole_reply (req,"Bad remove option" ,1 ,0 );
@@ -712,7 +711,7 @@ void mconsole_sysrq(struct mc_request *req)char *ptr = req->request.data; ptr +=strlen ("sysrq" ); -while (isspace (*ptr)) ptr++; + ptr =skip_spaces (ptr);/* * With 'b', the system will shut down without a chance to reply,
@@ -757,8 +756,7 @@ void mconsole_stack(struct mc_request *req)*/ ptr +=strlen ("stack" ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);/* * Should really check for multiple pids or reject bad args here
arch/x86/kernel/cpu/mtrr/if.c +4 -7
@@ -4,6 +4,7 @@#include <linux/proc_fs.h> #include <linux/module.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/init.h> #define LINE_SIZE 80
@@ -133,8 +134,7 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)return -EINVAL ; base =simple_strtoull (line +5 , &ptr,0 ); -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);if (strncmp (ptr,"size=" ,5 ))return -EINVAL ;
@@ -142,14 +142,11 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos) size =simple_strtoull (ptr +5 , &ptr,0 );if ((base &0xfff ) || (size &0xfff ))return -EINVAL ; -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr);if (strncmp (ptr,"type=" ,5 ))return -EINVAL ; - ptr +=5 ; -while (isspace (*ptr)) - ptr++; + ptr =skip_spaces (ptr +5 );for (i =0 ; i <MTRR_NUM_TYPES ; ++i) {if (strcmp (ptr, mtrr_strings[i]))
drivers/md/dm-table.c +2 -4
@@ -12,6 +12,7 @@#include <linux/blkdev.h> #include <linux/namei.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/mutex.h>
@@ -600,11 +601,8 @@ int dm_split_args(int *argc, char ***argvp, char *input)return -ENOMEM ;while (1 ) { - start = end; -/* Skip whitespace */ -while (*start &&isspace (*start)) - start++; + start =skip_spaces (end);if (!*start)break ;/* success, we hit the end */
drivers/md/md.c +2 -2
@@ -39,6 +39,7 @@#include <linux/buffer_head.h> /* for invalidate_bdev */ #include <linux/poll.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/hdreg.h> #include <linux/proc_fs.h> #include <linux/random.h>
@@ -3225,8 +3226,7 @@ bitmap_store(mddev_t *mddev, const char *buf, size_t len) }if (*end && !isspace (*end))break ;bitmap_dirty_bits (mddev->bitmap, chunk, end_chunk); - buf = end; -while (isspace (*buf)) buf++; + buf =skip_spaces (end); }bitmap_unplug (mddev->bitmap);/* flush the bits to disk */ out:
drivers/parisc/pdc_stable.c +3 -6
@@ -779,12 +779,9 @@ static ssize_t pdcs_auto_write(struct kobject *kobj,read_unlock (&pathentry->rw_lock);DPRINTK ("%s: flags before: 0x%X\n" , __func__, flags); - - temp = in; - -while (*temp &&isspace (*temp)) - temp++; - + + temp =skip_spaces (in); + c = *temp++ -'0' ;if ((c !=0 ) && (c !=1 )) goto parse_error;
drivers/platform/x86/thinkpad_acpi.c +2 -5
@@ -1006,11 +1006,8 @@ static int parse_strtoul(const char *buf, {char *endp; -while (*buf &&isspace (*buf)) - buf++; - *value =simple_strtoul (buf, &endp,0 ); -while (*endp &&isspace (*endp)) - endp++; + *value =simple_strtoul (skip_spaces (buf), &endp,0 ); + endp =skip_spaces (endp);if (*endp || *value > max)return -EINVAL ;
drivers/pnp/interface.c +10 -26
@@ -310,8 +310,7 @@ static ssize_t pnp_set_current_resources(struct device *dmdev, goto done; } -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (!strnicmp (buf,"disable" ,7 )) { retval =pnp_disable_dev (dev); goto done;
@@ -353,19 +352,13 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,pnp_init_resources (dev);mutex_lock (&pnp_res_mutex);while (1 ) { -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (!strnicmp (buf,"io" ,2 )) { - buf +=2 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +2 ); start =simple_strtoul (buf, &buf,0 ); -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (*buf =='-' ) { - buf +=1 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +1 ); end =simple_strtoul (buf, &buf,0 ); }else end = start;
@@ -373,16 +366,11 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,continue ; }if (!strnicmp (buf,"mem" ,3 )) { - buf +=3 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +3 ); start =simple_strtoul (buf, &buf,0 ); -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf);if (*buf =='-' ) { - buf +=1 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +1 ); end =simple_strtoul (buf, &buf,0 ); }else end = start;
@@ -390,17 +378,13 @@ static ssize_t pnp_set_current_resources(struct device *dmdev,continue ; }if (!strnicmp (buf,"irq" ,3 )) { - buf +=3 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +3 ); start =simple_strtoul (buf, &buf,0 );pnp_add_irq_resource (dev, start,0 );continue ; }if (!strnicmp (buf,"dma" ,3 )) { - buf +=3 ; -while (isspace (*buf)) - ++buf; + buf =skip_spaces (buf +3 ); start =simple_strtoul (buf, &buf,0 );pnp_add_dma_resource (dev, start,0 );continue ;
drivers/s390/block/dasd_proc.c +3 -2
@@ -14,6 +14,7 @@#define KMSG_COMPONENT "dasd"#include <linux/ctype.h> +#include <linux/string.h> #include <linux/seq_file.h> #include <linux/vmalloc.h> #include <linux/proc_fs.h>
@@ -272,10 +273,10 @@ dasd_statistics_write(struct file *file, const char __user *user_buf,DBF_EVENT (DBF_DEBUG ,"/proc/dasd/statictics: '%s'\n" , buffer);/* check for valid verbs */ -for (str = buffer;isspace (*str); str++); + str =skip_spaces (buffer);if (strncmp (str,"set" ,3 ) ==0 &&isspace (str[3 ])) {/* 'set xxx' was given */ -for (str = str +4 ;isspace (*str); str++); + str =skip_spaces (str +4 );if (strcmp (str,"on" ) ==0 ) {/* switch on statistics profiling */ dasd_profile_level =DASD_PROFILE_ON ;
drivers/video/backlight/lcd.c +2 -2
@@ -101,7 +101,7 @@ static ssize_t lcd_store_power(struct device *dev,int power =simple_strtoul (buf, &endp,0 );size_t size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)return -EINVAL ;
@@ -140,7 +140,7 @@ static ssize_t lcd_store_contrast(struct device *dev,int contrast =simple_strtoul (buf, &endp,0 );size_t size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)return -EINVAL ;
drivers/video/display/display-sysfs.c +1 -1
@@ -67,7 +67,7 @@ static ssize_t display_store_contrast(struct device *dev, contrast =simple_strtoul (buf, &endp,0 ); size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)
fs/cachefiles/daemon.c +3 -5
@@ -21,6 +21,7 @@#include <linux/mount.h> #include <linux/statfs.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/fs_struct.h> #include "internal.h"
@@ -250,15 +251,12 @@ static ssize_t cachefiles_daemon_write(struct file *file,/* parse the command */ ret = -EOPNOTSUPP ; -for (args = data; *args; args++) -if (isspace (*args)) -break ; + args =skip_spaces (data);if (*args) {if (args == data) goto error; *args ='\0' ; -for (args++;isspace (*args); args++) -continue ; + args =skip_spaces (++args); }/* run the appropriate command handler */
fs/ext4/super.c +2 -5
@@ -2097,11 +2097,8 @@ static int parse_strtoul(const char *buf, {char *endp; -while (*buf &&isspace (*buf)) - buf++; - *value =simple_strtoul (buf, &endp,0 ); -while (*endp &&isspace (*endp)) - endp++; + *value =simple_strtoul (skip_spaces (buf), &endp,0 ); + endp =skip_spaces (endp);if (*endp || *value > max)return -EINVAL ;
kernel/params.c +3 -5
@@ -24,6 +24,7 @@#include <linux/err.h> #include <linux/slab.h> #include <linux/ctype.h> +#include <linux/string.h> #if 0 #define DEBUGP printk
@@ -122,9 +123,7 @@ static char *next_arg(char *args, char **param, char **val) next = args + i;/* Chew up trailing spaces. */ -while (isspace (*next)) - next++; -return next; +return skip_spaces (next); }/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
@@ -139,8 +138,7 @@ int parse_args(const char *name,DEBUGP ("Parsing ARGS: %s\n" , args);/* Chew leading spaces */ -while (isspace (*args)) - args++; + args =skip_spaces (args);while (*args) {int ret;
lib/argv_split.c +3 -10
@@ -4,17 +4,10 @@#include <linux/kernel.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/slab.h> #include <linux/module.h> -static const char *skip_sep (const char *cp) -{ -while (*cp &&isspace (*cp)) - cp++; - -return cp; -} -static const char *skip_arg (const char *cp) {while (*cp && !isspace (*cp))
@@ -28,7 +21,7 @@ static int count_argc(const char *str)int count =0 ;while (*str) { - str =skip_sep (str); + str =skip_spaces (str);if (*str) { count++; str =skip_arg (str);
@@ -82,7 +75,7 @@ char **argv_split(gfp_t gfp, const char *str, int *argcp) argvp = argv;while (*str) { - str =skip_sep (str); + str =skip_spaces (str);if (*str) {const char *p = str;
lib/dynamic_debug.c +2 -2
@@ -21,6 +21,7 @@#include <linux/list.h> #include <linux/sysctl.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/uaccess.h> #include <linux/dynamic_debug.h> #include <linux/debugfs.h>
@@ -209,8 +210,7 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)char *end;/* Skip leading whitespace */ -while (*buf &&isspace (*buf)) - buf++; + buf =skip_spaces (buf);if (!*buf)break ;/* oh, it was trailing whitespace */
lib/vsprintf.c +4 -11
@@ -1716,13 +1716,6 @@ EXPORT_SYMBOL_GPL(bprintf);#endif /* CONFIG_BINARY_PRINTF */ -static noinline const char *skip_space(const char *str) -{ -while (isspace (*str)) - ++str; -return str; -} -/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer
@@ -1744,8 +1737,8 @@ int vsscanf(const char *buf, const char *fmt, va_list args)* white space, including none, in the input. */ if (isspace (*fmt)) { - fmt =skip_space (fmt); - str =skip_space (str); + fmt =skip_spaces (++fmt); + str =skip_spaces (str); }/* anything that is not a conversion must match exactly */
@@ -1815,7 +1808,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)if (field_width ==-1 ) field_width =INT_MAX ;/* first, skip leading white space in buffer */ - str =skip_space (str); + str =skip_spaces (str);/* now copy until next white space */ while (*str && !isspace (*str) && field_width--)
@@ -1857,7 +1850,7 @@ int vsscanf(const char *buf, const char *fmt, va_list args)/* have some sort of integer conversion. * first, skip white space in buffer. */ - str =skip_space (str); + str =skip_spaces (str); digit = *str;if (is_sign && digit =='-' )
net/irda/irnet/irnet.h +1 -0
@@ -249,6 +249,7 @@#include <linux/poll.h> #include <linux/capability.h> #include <linux/ctype.h> /* isspace() */ +#include <linux/string.h> /* skip_spaces() */ #include <asm/uaccess.h> #include <linux/init.h>
net/irda/irnet/irnet_ppp.c +3 -5
@@ -76,9 +76,8 @@ irnet_ctrl_write(irnet_socket * ap,/* Look at the next command */ start = next; -/* Scrap whitespaces before the command */ -while (isspace (*start)) - start++; +/* Scrap whitespaces before the command */ + start =skip_spaces (start);/* ',' is our command separator */ next =strchr (start,',' );
@@ -133,8 +132,7 @@ irnet_ctrl_write(irnet_socket * ap,char * endp;/* Scrap whitespaces before the command */ -while (isspace (*begp)) - begp++; + begp =skip_spaces (begp);/* Convert argument to a number (last arg is the base) */ addr =simple_strtoul (begp, &endp,16 );
net/netfilter/xt_recent.c +1 -2
@@ -482,8 +482,7 @@ static ssize_t recent_old_proc_write(struct file *file,if (copy_from_user (buf, input, size))return -EFAULT ; -while (isspace (*c)) - c++; + c =skip_spaces (c);if (size - (c - buf) <5 )return c - buf;
sound/pci/hda/hda_hwdep.c +3 -4
@@ -24,6 +24,7 @@#include <linux/compat.h> #include <linux/mutex.h> #include <linux/ctype.h> +#include <linux/string.h> #include <linux/firmware.h> #include <sound/core.h> #include "hda_codec.h"
@@ -390,8 +391,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf)char *key, *val;struct hda_hint *hint; -while (isspace (*buf)) - buf++; + buf =skip_spaces (buf);if (!*buf || *buf =='#' || *buf =='\n' )return 0 ;if (*buf =='=' )
@@ -406,8 +406,7 @@ static int parse_hints(struct hda_codec *codec, const char *buf)return -EINVAL ; } *val++ =0 ; -while (isspace (*val)) - val++; + val =skip_spaces (val);remove_trail_spaces (key);remove_trail_spaces (val); hint =get_hint (codec, key);
Signature · 6 lines
1.6.5.2.153.g6e31f.dirty _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Re: [PATCH v4 01/12] vsprintf: factorize "(null)" string
In reply to André Goddard RosaStripping the humongous Cc list for sanity.
Quoted 2 lines · André Goddard Rosa
Change "<NULL>" to "(null)" and make it a static const char[] hoping that the compiler will make
null_stra label to a read-only area containing it.
Hoping? Nah, thanks.
Quoted 2 lines
Ulrich's example already _has_ a variable that is then changed from const char * to const char[]. Of course doing that will save you the extra pointer.
But vsprintf.c on the other hand did not have that extra variable to begin with! But it is ok nevertheless, and the unification of <NULL> vs (null) is worthwhile.
Re: [PATCH v4 07/12] vsprintf: factor out skip_space code in a separate function
In reply to André Goddard RosaQuoted 1 line · André Goddard Rosa
It decreases code size:
And may increase runtime. If GCC determined that skip_space itself (without the noinline you added) is going to be inlined, let it go ahead.
Quoted 3 lines
text data bss dec hex filename
15719 0 8 15727 3d6f lib/vsprintf.o-before 15543 0 8 15551 3cbf lib/vsprintf.o-after
Re: [PATCH v4 01/12] vsprintf: factorize "(null)" string
In reply to Jan EngelhardtQuoted 10 lines · Jan Engelhardt
Stripping the humongous Cc list for sanity.
Quoted 2 lines · André Goddard Rosa
Change "<NULL>" to "(null)" and make it a static const char[] hoping that the compiler will make
null_stra label to a read-only area containing it.Hoping? Nah, thanks.
:) That's just because I don't always trust gcc blindly. :)
Quoted 8 lines
Quoted 2 lines
Ulrich's example already _has_ a variable that is then changed from const char * to const char[]. Of course doing that will save you the extra pointer.
Butvsprintf.con the other hand did not have that extra variable to begin with!
Correct, of course! Most relevant reference is the first one:
http://people.redhat.com/drepper/dsohowto.pdf part 2.4.2
The others are just related/akin to the topic; interesting nevertheless.
Quoted 2 lines
But it is ok nevertheless, and the unification of <NULL> vs (null) is worthwhile.
Thanks,
André
Re: [PATCH v4 07/12] vsprintf: factor out skip_space code in a separate function
In reply to Jan EngelhardtQuoted 8 lines · Jan Engelhardt
Quoted 1 line · André Goddard Rosa
It decreases code size:
And may increase runtime. If GCC determined that
skip_spaceitself (without the noinline you added) is going to be inlined, let it go ahead.
Later in the series, when stepping over the whole tree for using that function, I changed it to let gcc decide instead as you correctly pointed out.
Thanks for reviewing,
André
Re: [PATCH v4 10/12] string: factorize skip_spaces and export it to be generally available
In reply to André Goddard RosaQuoted 6 lines · André Goddard Rosa
/**
+ *skip_spaces- Removes leading whitespace from @s.
+ * @s: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @s.
+ */
lib/string.c EXPORT_SYMBOL(strnchr); · line 345
Quoted 8 lines
lib/string.c +8
-0+const char *skip_spaces (const char *str) +{ +while (isspace (*str)) + ++str; +return str; +} +EXPORT_SYMBOL (skip_spaces); +
I would make this
char *skip_spaces(const char *)
just like most of the stdc functions, so that you do not need ugly casts like this (v) in callers of skip_spaces.
Quoted 7 lines
lib/string.c +1
-4-while (*s &&isspace (*s)) - s++; - -return s; +return (char *)skip_spaces (s);}
EXPORT_SYMBOL(strstrip);
James Bottomley
maintainerQuoted 11 lines · André Goddard Rosa
This patch reduces lib.a code size by 173 bytes on my Core 2 with gcc 4.4.1 even considering that it exports a newly defined function
skip_spaces()to drivers:text data bss dec hex filename 64867 840 592 66299 102fb (TOTALS-lib.a-before) 64954 584 588 66126 1024e (TOTALS-lib.a-after)and implements some code tidy up.
Besides reducing lib.a size, it converts many in-tree drivers to use the newly defined function, which makes another small reduction on kernel size overall when those drivers are used.
Before we embark on something as massive as this, could we take a step back. I agree that if I were coming up with the strstip() interface today I probably wouldn't have given it two overloaded uses.
However, I think the function, in spite of this minor issue, is very usable. I still don't understand why people thought adding a __must_check, which is what damaged one of the overloaded uses, is a good idea.
Assuming there's a good answer to the above:
Quoted 6 lines
+ *
skip_spaces- Removes leading whitespace from @s.
+ * @s: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @s.
+ */
+const char *skip_spaces(const char *str)
I don't think const return is a good idea because most functions will be manipulating the string and using pointers that won't be const, so this will generate a ton of 'initialization discards qualifiers from pointer target type' ... so that leads to the question of whether this patch series was actually compiled ...
James
James Bottomley
maintainerRe: [PATCH v4 10/12] string: factorize skip_spaces and export it to be generally available
In reply to André Goddard RosaQuoted 6 lines · André Goddard Rosa
+ *
skip_spaces- Removes leading whitespace from @s.
+ * @s: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @s.
+ */
+char *skip_spaces(const char *str)
OK, so this now becomes a bad interface because it silently promotes const to non const ... and I'm sure the compiler would warn about this too in string.c ... did this get compiled?
James
Re: [PATCH v4 10/12] string: factorize skip_spaces and export it to be generally available
In reply to André Goddard RosaQuoted 3 lines · On Sat, 7 Nov 2009 13:16:18 -0200 André Goddard Rosa…
On the following sentence:
while (*s && isspace(*s)) s++;
Looks fine but for one thing: it's actually shorter inline than moved into /lib so at the very least it should be a header inline not a function call.
Second minor comment. Although it never made it into the final ANSI C, the proposed name (and the one used in a lot of other non Linux code for this) is stpblk().
Alan
Hi, James!
Quoted 13 lines · James Bottomley
Quoted 11 lines · André Goddard Rosa
This patch reduces lib.a code size by 173 bytes on my Core 2 with gcc 4.4.1 even considering that it exports a newly defined function
skip_spaces()to drivers:
text data bss dec hex filename
64867 840 592 66299 102fb (TOTALS-lib.a-before) 64954 584 588 66126 1024e (TOTALS-lib.a-after) and implements some code tidy up.Besides reducing lib.a size, it converts many in-tree drivers to use the newly defined function, which makes another small reduction on kernel size overall when those drivers are used.
Quoted 8 lines
Before we embark on something as massive as this, could we take a step back. I agree that if I were coming up with the
strstip()interface today I probably wouldn't have given it two overloaded uses.However, I think the function, in spite of this minor issue, is very usable. I still don't understand why people thought adding a
__must_check, which is what damaged one of the overloaded uses, is a good idea.
Differently of "static void strip(char *str)"@scripts/kconfig/conf.c , this function
does not moves the characters to the beginning of the string, so that if that string is going to be reused it should refer to the newly returned string start.
I've changed it to remove the const and return a "char *".
Do you think __must_check is not needed as well?
Thanks,
André
Re: [PATCH v4 10/12] string: factorize skip_spaces and export it to be generally available
In reply to James BottomleyQuoted 10 lines · James Bottomley
Quoted 6 lines · André Goddard Rosa
+ *
skip_spaces- Removes leading whitespace from @s.
+ * @s: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @s.
+ */
+char *skip_spaces(const char *str)OK, so this now becomes a bad interface because it silently promotes const to non const ...
strchr, etc. all do the same. Do you think they are bad too?
Quoted 13 lines · André Goddard Rosa
Hi, James!
Quoted 8 lines · James Bottomley
Before we embark on something as massive as this, could we take a step back. I agree that if I were coming up with the
strstip()interface today I probably wouldn't have given it two overloaded uses.However, I think the function, in spite of this minor issue, is very usable. I still don't understand why people thought adding a
__must_check, which is what damaged one of the overloaded uses, is a good idea.
Quoted 8 lines
Differently of "static void
strip(char *str)"@scripts/kconfig/conf.c, this function
does not moves the characters to the beginning of the string, so that if that string is going to be reused it should refer to the newly returned string start.I've changed it to remove the const and return a "char *".
Do you think
__must_checkis not needed as well?
If you called strstrip, and not use its result, what good would that do besides being effectively a strrtrim? __must_check is a good thing IMO.
Re: [PATCH v4 10/12] string: factorize skip_spaces and export it to be generally available
In reply to André Goddard Rosalib/string.c char *strstrip(char *s) · line 370
Quoted 12 lines · André Goddard Rosa
lib/string.c +2
-4+char *skip_spaces (const char *str)@@ -352,10 +366,7 @@ char *strstrip(char *s) end--; *(end +1 ) ='\0' ; -while (*s &&isspace (*s)) - s++; - -return s; +return (char *)skip_spaces (s); }
sparse would probably say "how much more casting to the same type do you want?" It is already char*.
Re: [PATCH v4 10/12] string: factorize skip_spaces and export it to be generally available
In reply to Jan EngelhardtQuoted 11 lines · Jan Engelhardt
Quoted 8 lines · James Bottomley
Quoted 6 lines · André Goddard Rosa
+ *
skip_spaces- Removes leading whitespace from @s.
+ * @s: The string to be stripped.
+ *
+ * Returns a pointer to the first non-whitespace character in @s.
+ */
+char *skip_spaces(const char *str)
Quoted 4 lines
Quoted 2 lines
OK, so this now becomes a bad interface because it silently promotes const to non const ...
strchr, etc. all do the same. Do you think they are bad too?
Yeap, I just based on those.
James, what would you suggest instead?
Thanks,
André
Quoted 1 line · André Goddard Rosa
skip_spaces()
This is pointless wrapper and if you don't understand and immediately see what such code does you shouldn't be allowed near kernel.
"const _ctype" patch should be fine.
It's pretty sad to see so much activity around all sorts of simple and simultaneously
irrelevant stuff like formatting, printk, pr_debug, printk_once, loglevels etc
I suggest to kernel newbies to find and fix a bug. You'll learn much more from this exercise.
Theodore Tso
maintainerRe: [PATCH v4 12/12] tree-wide: convert open calls to remove spaces to skip_spaces() lib function
In reply to André Goddard RosaQuoted 7 lines · André Goddard Rosa
Makes use of
skip_spaces()defined inlib/string.cfor removing leading spaces from strings all over the tree.Also, while at it, if we see (*str &&
isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".
There are a number of places that have the pattern of skipping whitespace, calling simpler_strtoul(), and then skipping whitespace afterwards. And thinkpad_acpi.c and fs/ext4/super.c both have an indentical function, parse_strotul(), which basically does this plus doing actual error checking (a number of callers of simple_strtoul aren't checking to see if the user passed in a valid number or not, boo.)
I would suggest that we should lift parse_strtoul() into lib/, both to save a bit of code, as well as encouraging people to do proper input validation, while we are doing this tree-wide cleanup.
- Ted
Re: [PATCH v4 12/12] tree-wide: convert open calls to remove spaces to skip_spaces() lib function
Quoted 4 lines
Quoted 4 lines
Also, while at it, if we see (*str &&
isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".
I tried the following semantic patch (http://coccinelle.lip6.fr), and got the results below.
@@
expression str;
@@
( // ignore skip_spaces cases
while (*str && isspace(*str)) { \(str++;\|++str;\) }
|
- *str &&
isspace(*str)
)
I haven't checked the results in any way, however.
julia
drivers/leds/led-class.c +1 -1
@@ -50,7 +50,7 @@ static ssize_t led_brightness_store(struunsigned long state =simple_strtoul (buf, &after,10 );size_t count = after - buf; -if (*after &&isspace (*after)) +if (isspace (*after)) count++;if (count == size) {
drivers/leds/ledtrig-timer.c +2 -2
@@ -83,7 +83,7 @@ static ssize_t led_delay_on_store(structunsigned long state =simple_strtoul (buf, &after,10 );size_t count = after - buf; -if (*after &&isspace (*after)) +if (isspace (*after)) count++;if (count == size) {
@@ -127,7 +127,7 @@ static ssize_t led_delay_off_store(strucunsigned long state =simple_strtoul (buf, &after,10 );size_t count = after - buf; -if (*after &&isspace (*after)) +if (isspace (*after)) count++;if (count == size) {
drivers/video/backlight/lcd.c +2 -2
@@ -101,7 +101,7 @@ static ssize_t lcd_store_power(struct deint power =simple_strtoul (buf, &endp,0 );size_t size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)return -EINVAL ;
@@ -140,7 +140,7 @@ static ssize_t lcd_store_contrast(structint contrast =simple_strtoul (buf, &endp,0 );size_t size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)return -EINVAL ;
drivers/video/display/display-sysfs.c +1 -1
@@ -67,7 +67,7 @@ static ssize_t display_store_contrast(st contrast =simple_strtoul (buf, &endp,0 ); size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)
drivers/video/output.c +1 -1
@@ -50,7 +50,7 @@ static ssize_t video_output_store_state(int request_state =simple_strtoul (buf,&endp,0 );size_t size = endp - buf; -if (*endp &&isspace (*endp)) +if (isspace (*endp)) size++;if (size != count)return -EINVAL ;
Re: [PATCH v4 01/12] vsprintf: factorize "(null)" string
In reply to André Goddard RosaQuoted 2 lines · you
Change "<NULL>" to "(null)" and make it a static const char[] hoping that the compiler will make
null_stra label to a read-only area containing it.
(Trimmed the 79 recipients of the original).
Hi Andre,
Consistently using <NULL> or (null) makes sense. But I'm really missing your argument: is there some reason why normal string merging won't work?
Confused,
Rusty.
Re: [PATCH v4 10/12] string: factorize skip_spaces and export it to be generally available
In reply to Alan CoxQuoted 10 lines · Alan Cox
Quoted 3 lines · On Sat, 7 Nov 2009 13:16:18 -0200 André Goddard Rosa…
On the following sentence:
while (*s &&isspace(*s))
s++;Looks fine but for one thing: it's actually shorter inline than moved into /lib so at the very least it should be a header inline not a function call.
I have tried header "static inline" approach per your suggestion and code size increases by 197 bytes from:
64954 584 588 66126 1024e (TOTALS-lib.a-before)
to:
65151 584 588 66323 10313 (TOTALS-lib.a-after)
Quoted 3 lines
Second minor comment. Although it never made it into the final ANSI C, the proposed name (and the one used in a lot of other non Linux code for this) is
stpblk().
Thank you,
André
Re:
In reply to a message not in the archiveQuoted 6 lines · David Howells
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printableAndr=E9 Goddard Rosa <[email protected]> wrote:
Quoted 7 lines
Quoted 4 lines
It decreases code size:
text data bss dec hex filename 15719 0 8 15727 3d6flib/vsprintf.o-before15543 0 8 15551 3cbflib/vsprintf.o-afterWhilst this may be true, there will be a countervailing decrease in performance. Have you assessed that?
(trimmed long cc: list to keep it sane, I'll not use get_maintainer.pl output this way anymore)
I'm not sure it decreases performance. From the last iteration of the patch, I removed
the hint to force "not inlining", so that gcc can inline it if it thinks it's better.
Are those so performance sensitive that it makes sense to perform this assessment?
If you think so, what would you suggest? A micro-benchmark or some real use case?
Best regards,
André
Re: [PATCH v4 01/12] vsprintf: factorize "(null)" string
In reply to Rusty RussellQuoted 5 lines · Rusty Russell
Hi Andre,
Consistently using <NULL> or (null) makes sense. But I'm really missing your argument: is there some reason why normal string merging won't work?
Hi, Rusty!
I agree that it works fine as well; the factorization only makes
explicit the fact that's a constant string, that's all.
Thank you,
André
Re: [ibm-acpi-devel] [PATCH v4 12/12] tree-wide: convert open calls to remove spaces to skip_spaces() lib function
In reply to André Goddard RosaQuoted 4 lines · André Goddard Rosa
Also, while at it, if we see (*str &&
isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".
You didn't document in isspace() that it must return false for NUL. Please do that before you remove any such checks.
Signature · 4 lines
"One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh
Re: [ibm-acpi-devel] [PATCH v4 12/12] tree-wide: convert open calls to remove spaces to skip_spaces() lib function
Quoted 9 lines · Henrique de Moraes Holschuh
Quoted 4 lines · André Goddard Rosa
Also, while at it, if we see (*str &&
isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".You didn't document in
isspace()that it must return false for NUL. Please do that before you remove any such checks.
Good idea Henrique, I will do it!
Thank you,
André
Re: [PATCH v4 12/12] tree-wide: convert open calls to remove spaces to skip_spaces() lib function
In reply to Julia Lawall[stripped very long cc: line]
Quoted 19 lines · Julia Lawall
Quoted 4 lines
Quoted 4 lines
Also, while at it, if we see (*str &&
isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".I tried the following semantic patch (http://coccinelle.lip6.fr), and got the results below.
@@
expression str;
@@( // ignore
skip_spacescases
while (*str && isspace(*str)) { \(str++;\|++str;\) } |
- *str &&
isspace(*str)
)
Quoted 4 lines
I haven't checked the results in any way, however.
julia
Hi, Julia!
Your patch looks good, but it conflicted at the following files
when I tried to apply it:
Quoted 2 lines
diff -u -p
a/drivers/video/backlight/lcd.cb/drivers/video/backlight/lcd.cdiff -u -pa/drivers/video/display/display-sysfs.cb/drivers/video/display/display-sysfs.c
That's because I had changed them as well. The other ones you spotted I haven't seen originally:
Quoted 3 lines
diff -u -p
a/drivers/leds/led-class.cb/drivers/leds/led-class.cdiff -u -pa/drivers/leds/ledtrig-timer.cb/drivers/leds/ledtrig-timer.cdiff -u -pa/drivers/video/output.cb/drivers/video/output.c
Do you mind sending another patch or do you want me folding these in?
Thank you,
André
Re: [PATCH v4 12/12] tree-wide: convert open calls to remove spaces to skip_spaces() lib function
In reply to Theodore Tso[trimmed very long cc: line]
Quoted 17 lines · Theodore Tso
Quoted 7 lines · André Goddard Rosa
Makes use of
skip_spaces()defined inlib/string.cfor removing leading spaces from strings all over the tree.Also, while at it, if we see (*str &&
isspace(*str)), we can be sure to remove the first condition (*str) as the second one (isspace(*str)) also evaluates to 0 whenever *str == 0, making it redundant. In other words, "a char equals zero is never a space".There are a number of places that have the pattern of skipping whitespace, calling
simpler_strtoul(), and then skipping whitespace afterwards. Andthinkpad_acpi.candfs/ext4/super.cboth have an indentical function,parse_strotul(), which basically does this plus doing actual error checking (a number of callers ofsimple_strtoularen't checking to see if the user passed in a valid number or not, boo.)
Quoted 4 lines
I would suggest that we should lift
parse_strtoul()intolib/, both to save a bit of code, as well as encouraging people to do proper input validation, while we are doing this tree-wide cleanup.
Hi, Ted!
I took a look at it but couldn't find use for it much besides the
ones you've
pointed out, so I'm not sure it really deserves a lib function. Most calls to simple_strtoul() does not skips spaces.
Thanks,
André