Open-code isprint(c) and isspace(c)

We don't call setlocale, thus we always use C locale.
But libc supports various other locales, and therefore
its ctype interface is general and at times inefficient.
For example, in glibc these macros result in function call,
whereas for e.g. isprint(c) just c >= ' ' && c <= 0x7e
suffices.

By open-coding ctype checks (we have only 4 of them)
we avoid function calls, we get smaller code:

   text	   data	    bss	    dec	    hex	filename
 245127	    680	   5708	 251515	  3d67b	strace_old
 245019	    676	   5708	 251403	  3d60b	strace

and we don't link in ctype tables (beneficial for static builds).

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2013-03-06 23:44:23 +01:00
parent 76f61bec5e
commit 5198ed4bb3
3 changed files with 16 additions and 4 deletions

5
defs.h
View File

@ -52,7 +52,10 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
/* Open-coding isprint(ch) et al proved more efficient than calling
* generalized libc interface. We don't *want* to do non-ASCII anyway.
*/
/* #include <ctype.h> */
#include <string.h>
#include <errno.h>
#include <signal.h>

2
file.c
View File

@ -2456,7 +2456,7 @@ print_xattr_val(struct tcb *tcp, int failed,
unsigned char *in = &buf[3 * size];
size_t i;
for (i = 0; i < size; ++i) {
if (isprint(in[i]))
if (in[i] >= ' ' && in[i] <= 0x7e)
*out++ = in[i];
else {
#define tohex(n) "0123456789abcdef"[n]

13
util.c
View File

@ -400,7 +400,16 @@ string_quote(const char *instr, char *outstr, long len, int size)
/* Check for NUL-terminated string. */
if (c == eol)
break;
if (!isprint(c) && !isspace(c)) {
/* Force hex unless c is printable or whitespace */
if (c > 0x7e) {
usehex = 1;
break;
}
/* In ASCII isspace is only these chars: "\t\n\v\f\r".
* They happen to have ASCII codes 9,10,11,12,13.
*/
if (c < ' ' && (unsigned)(c - 9) >= 5) {
usehex = 1;
break;
}
@ -453,7 +462,7 @@ string_quote(const char *instr, char *outstr, long len, int size)
*s++ = 'v';
break;
default:
if (isprint(c))
if (c >= ' ' && c <= 0x7e)
*s++ = c;
else {
/* Print \octal */