From f619da74ea3b38bb9f8b1f6a022c32b38eac85b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Fri, 5 Nov 2004 16:23:32 +0100
Subject: [PATCH] Added string_builder_{v,}sprintf().

Rev: src/stralloc.c:1.169
Rev: src/stralloc.h:1.83
---
 src/stralloc.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/stralloc.h |  13 ++++-
 2 files changed, 158 insertions(+), 4 deletions(-)

diff --git a/src/stralloc.c b/src/stralloc.c
index eff17d2697..a5ce3ce7db 100644
--- a/src/stralloc.c
+++ b/src/stralloc.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: stralloc.c,v 1.168 2004/09/27 21:37:23 mast Exp $
+|| $Id: stralloc.c,v 1.169 2004/11/05 15:23:15 grubba Exp $
 */
 
 #include "global.h"
@@ -2052,7 +2052,8 @@ PMOD_EXPORT void string_builder_putchar(struct string_builder *s, int ch)
 }
 
 
-PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s, char *str, ptrdiff_t len)
+PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s,
+					      const char *str, ptrdiff_t len)
 {
   string_build_mkspace(s,len,0);
   switch(s->s->size_shift)
@@ -2173,6 +2174,150 @@ PMOD_EXPORT void string_builder_shared_strcat(struct string_builder *s, struct p
   s->s->str[s->s->len << s->s->size_shift] = 0;
 }
 
+PMOD_EXPORT void string_builder_vsprintf(struct string_builder *s,
+					 const char *fmt,
+					 va_list args)
+{
+  while (*fmt) {
+    if (*fmt == '%') {
+      fmt++;
+      switch (*fmt) {
+      case '%':
+	string_builder_putchar(s, '%');
+	break;
+      case 'O':
+	{
+	  dynamic_buffer old_buf;
+	  init_buf(&old_buf);
+	  describe_svalue(va_arg(args, struct svalue *), 0, NULL);
+	  string_builder_binary_strcat(s, pike_global_buffer.s.str,
+				       pike_global_buffer.s.len);
+	  toss_buffer(&pike_global_buffer);
+	  restore_buffer(&old_buf);
+	}
+	break;
+      case 'S':
+	string_builder_shared_strcat(s, va_arg(args, struct pike_string *));
+	break;
+      case 's':
+	{
+	  const char *str = va_arg(args, char *);
+	  string_builder_binary_strcat(s, str, strlen(str));
+	}
+	break;
+      case 'c':
+	string_builder_putchar(s, va_arg(args, INT32));
+	break;
+      case 'b':
+      case 'o':
+      case 'x':
+      case 'X':
+	{
+	  int delta;
+	  unsigned int val = va_arg(args, unsigned int);
+	  char *numbers = "0123456789abcdef";
+	  int shift;
+	  unsigned int mask;
+
+	  switch (*fmt) {
+	  case 'b':
+	    delta = 1;
+	    break;
+	  case 'o':
+	    delta = 3;
+	    break;
+	  case 'X':
+	    numbers = "0123456789ABCDEF";
+	    /* FALL_THROUGH */
+	  case 'x':
+	    delta = 4;
+	    break;
+	  default:
+	    fatal("Unsupported binary integer formatting directive '%c'\n",
+		  *fmt);
+	    break;
+	  }
+	  mask = (1<<delta)-1;
+
+	  for (shift = 0; val >> shift; shift += delta)
+	    ;
+	  while(shift >= 0) {
+	    string_builder_putchar(s, numbers[(val>>shift) & mask]);
+	    shift -= delta;
+	  }
+	}
+	break;
+      case 'd':
+      case 'u':
+	{
+	  unsigned int val = va_arg(args, unsigned int);
+	  unsigned int tmp;
+	  int len;
+	  if ((*fmt == 'd') && ((int)val < 0)) {
+	    string_builder_putchar(s, '-');
+	    val = -val;
+	  }
+	  tmp = val;
+	  len = 0;
+	  do {
+	    len++;
+	    tmp /= 10;
+	  } while (tmp);
+
+	  switch(s->s->size_shift) {
+	  case 0:
+	    {
+	      p_wchar0 *p = string_builder_allocate(s, len, 0);
+	      do {
+		*(p++) = '0' + val%10;
+		val /= 10;
+	      } while (val);
+	    }
+	    break;
+	  case 1:
+	    {
+	      p_wchar1 *p = string_builder_allocate(s, len, 0);
+	      do {
+		*(p++) = '0' + val%10;
+		val /= 10;
+	      } while (val);
+	    }
+	    break;
+	  case 2:
+	    {
+	      p_wchar2 *p = string_builder_allocate(s, len, 0);
+	      do {
+		*(p++) = '0' + val%10;
+		val /= 10;
+	      } while (val);
+	    }
+	    break;
+	  }
+	}
+	break;
+	
+      default:
+	Pike_fatal("string_builder_vsprintf(): Invalid formatting method: "
+		   "'%c' 0x%x.\n", *fmt, *fmt);
+      }
+    } else {
+      const char *start = fmt;
+      while (*fmt && (*fmt != '%'))
+	fmt++;
+      string_builder_binary_strcat(s, start, fmt-start);
+    }
+  }
+}
+
+PMOD_EXPORT void string_builder_sprintf(struct string_builder *s,
+					const char *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  string_builder_vsprintf(s, fmt, args);
+  va_end(args);
+}
+
 
 PMOD_EXPORT void reset_string_builder(struct string_builder *s)
 {
diff --git a/src/stralloc.h b/src/stralloc.h
index 19a6d9bbe8..4009aefc2d 100644
--- a/src/stralloc.h
+++ b/src/stralloc.h
@@ -2,12 +2,15 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: stralloc.h,v 1.82 2004/09/27 21:37:23 mast Exp $
+|| $Id: stralloc.h,v 1.83 2004/11/05 15:23:32 grubba Exp $
 */
 
 #ifndef STRALLOC_H
 #define STRALLOC_H
 #include "global.h"
+
+#include <stdarg.h>
+
 #include "pike_macros.h"
 #include "block_alloc_h.h"
 
@@ -264,7 +267,8 @@ PMOD_EXPORT void string_build_mkspace(struct string_builder *s,
 				      ptrdiff_t chars, int mag);
 PMOD_EXPORT void *string_builder_allocate(struct string_builder *s, ptrdiff_t chars, int mag);
 PMOD_EXPORT void string_builder_putchar(struct string_builder *s, int ch);
-PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s, char *str, ptrdiff_t len);
+PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s,
+					      const char *str, ptrdiff_t len);
 PMOD_EXPORT void string_builder_append(struct string_builder *s,
 				       PCHARP from,
 				       ptrdiff_t len);
@@ -275,6 +279,11 @@ PMOD_EXPORT void string_builder_fill(struct string_builder *s,
 				     ptrdiff_t offset);
 PMOD_EXPORT void string_builder_strcat(struct string_builder *s, char *str);
 PMOD_EXPORT void string_builder_shared_strcat(struct string_builder *s, struct pike_string *str);
+PMOD_EXPORT void string_builder_vsprintf(struct string_builder *s,
+					 const char *fmt,
+					 va_list args);
+PMOD_EXPORT void string_builder_sprintf(struct string_builder *s,
+					const char *fmt, ...);
 PMOD_EXPORT void reset_string_builder(struct string_builder *s);
 PMOD_EXPORT void free_string_builder(struct string_builder *s);
 PMOD_EXPORT struct pike_string *finish_string_builder(struct string_builder *s);
-- 
GitLab