bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Patch] Buitin printf command is too slow and allocate memory too much


From: Yuya Katayama
Subject: [Patch] Buitin printf command is too slow and allocate memory too much
Date: Tue, 11 Mar 2008 22:27:18 +0900

Configuration Information :
Machine: i486
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='i486' -DCONF_OSTYPE='lin$
uname output: Linux yuya.local 2.6.18-5-686 #1 SMP Wed Sep 26 17:54:59 UTC 2$
Machine Type: i486-pc-linux-gnu

Bash Version: 3.1
Patch Level: 17
Release Status: release

Description:
        Buitin printf command is too slow and allocate memory too much.

Repeat-By:
        ex.
           printf %1000000000d 1

Fix:
        I made patch for builtins/printf.def. Please test.

--- printf.def.bak      2005-10-30 03:51:29.000000000 +0900
+++ printf.def  2008-03-11 21:37:26.000000000 +0900
@@ -64,6 +64,12 @@
 #include "bashgetopt.h"
 #include "common.h"

+#if defined (PREFER_STDARG)
+#  include <stdarg.h>
+#else
+#  include <varargs.h>
+#endif
+
 #if !defined (PRIdMAX)
 #  if HAVE_LONG_LONG
 #    define PRIdMAX    "lld"
@@ -89,25 +95,28 @@

 #define PF(f, func) \
   do { \
-    char *b = 0; \
     int nw; \
     if (have_fieldwidth && have_precision) \
-      nw = asprintf(&b, f, fieldwidth, precision, func); \
+      if (vflag) \
+        nw = vbaddprintf(f, fieldwidth, precision, func); \
+      else \
+        nw = printf(f, fieldwidth, precision, func); \
     else if (have_fieldwidth) \
-      nw = asprintf(&b, f, fieldwidth, func); \
+      if (vflag) \
+        nw = vbaddprintf(f, fieldwidth, func); \
+      else \
+        nw = printf(f, fieldwidth, func); \
     else if (have_precision) \
-      nw = asprintf(&b, f, precision, func); \
+      if (vflag) \
+        nw = vbaddprintf(f, precision, func); \
+      else \
+        nw = printf(f, precision, func); \
     else \
-      nw = asprintf(&b, f, func); \
+      if (vflag) \
+        nw = vbaddprintf(f, func); \
+      else \
+        nw = printf(f, func); \
     tw += nw; \
-    if (b) \
-      { \
-       if (vflag) \
-         (void)vbadd (b, nw); \
-       else \
-         (void)fputs (b, stdout); \
-       free (b); \
-      } \
   } while (0)

 /* We free the buffer used by mklong() if it's `too big'. */
@@ -144,6 +153,7 @@
 static int tescape __P((char *, char *, int *));
 static char *bexpand __P((char *, int, int *, int *));
 static char *vbadd __P((char *, int));
+static int vbaddprintf __P((const char *, ...))
__attribute__((__format__ (printf, 1, 2)));
 static char *mklong __P((char *, char *, size_t));
 static int getchr __P((void));
 static char *getstr __P((void));
@@ -822,6 +832,36 @@
   return vbuf;
 }

+static int
+#if defined (PREFER_STDARG)
+vbaddprintf (const char *format, ...)
+#else
+vbaddprintf (format, va_alist)
+     const char *format;
+     va_dcl
+#endif
+{
+  va_list args;
+  size_t nlen;
+  int blen;
+
+  SH_VA_START (args, format);
+  blen = vsnprintf(vbuf + vblen, vbsize - vblen, format, args);
+
+  nlen = vblen + blen + 1;
+  if (nlen >= vbsize)
+    {
+      vbsize = ((nlen + 63) >> 6) << 6;
+      vbuf = (char *)xrealloc (vbuf, vbsize);
+      blen = vsnprintf(vbuf + vblen, vbsize - vblen, format, args);
+    }
+
+  va_end (args);
+  vblen += blen;
+
+  return blen;
+}
+
 static char *
 mklong (str, modifiers, mlen)
      char *str;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]