ralloc: Add new [v]asprintf_rewrite_tail functions.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 25 Oct 2011 02:33:16 +0000 (19:33 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 26 Oct 2011 00:51:43 +0000 (17:51 -0700)
This can be useful if you want to create a bunch of temporary strings
with a common prefix.  For example, when iterating over uniform
structure fields, one might want to create temporary strings like
"pallete.primary", "palette.outline", and "pallette.shadow".

This could be done by overwriting the '.' with a null-byte and calling
ralloc_asprintf_append, but that incurs the cost of strlen("pallete")
every time...when this is already known.

These new functions allow you rewrite the tail of the string, given a
starting index.  If the starting index is the length of the string, this
is equivalent to appending.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ralloc.c
src/glsl/ralloc.h

index fb48a91c56472376088a43b4b036e4245fb2cf95..2967598aecb6b28b8aab6224185d5cc6cf04908d 100644 (file)
@@ -439,7 +439,27 @@ ralloc_asprintf_append(char **str, const char *fmt, ...)
 bool
 ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
 {
-   size_t existing_length, new_length;
+   assert(str != NULL);
+   size_t existing_length = *str ? strlen(*str) : 0;
+   return ralloc_vasprintf_rewrite_tail(str, existing_length, fmt, args);
+}
+
+bool
+ralloc_asprintf_rewrite_tail(char **str, size_t start, const char *fmt, ...)
+{
+   bool success;
+   va_list args;
+   va_start(args, fmt);
+   success = ralloc_vasprintf_rewrite_tail(str, start, fmt, args);
+   va_end(args);
+   return success;
+}
+
+bool
+ralloc_vasprintf_rewrite_tail(char **str, size_t start, const char *fmt,
+                             va_list args)
+{
+   size_t new_length;
    char *ptr;
 
    assert(str != NULL);
@@ -450,14 +470,13 @@ ralloc_vasprintf_append(char **str, const char *fmt, va_list args)
       return true;
    }
 
-   existing_length = strlen(*str);
    new_length = printf_length(fmt, args);
 
-   ptr = resize(*str, existing_length + new_length + 1);
+   ptr = resize(*str, start + new_length + 1);
    if (unlikely(ptr == NULL))
       return false;
 
-   vsnprintf(ptr + existing_length, new_length + 1, fmt, args);
+   vsnprintf(ptr + start, new_length + 1, fmt, args);
    *str = ptr;
    return true;
 }
index d5338152f10f6a50cb504f974c5a5fde2ac05602..1324f3466bb2bb6d7e14b8e59f3bcf02e3d2077f 100644 (file)
@@ -313,10 +313,61 @@ char *ralloc_asprintf (const void *ctx, const char *fmt, ...);
  */
 char *ralloc_vasprintf(const void *ctx, const char *fmt, va_list args);
 
+/**
+ * Rewrite the tail of an existing string, starting at a given index.
+ *
+ * Overwrites the contents of *str starting at \p start with newly formatted
+ * text, including a new null-terminator.  Allocates more memory as necessary.
+ *
+ * This can be used to append formatted text when the length of the existing
+ * string is already known, saving a strlen() call.
+ *
+ * \sa ralloc_asprintf_append
+ *
+ * \param str   The string to be updated.
+ * \param start The index to start appending new data at.
+ * \param fmt   A printf-style formatting string
+ *
+ * \p str will be updated to the new pointer unless allocation fails.
+ *
+ * \return True unless allocation failed.
+ */
+bool ralloc_asprintf_rewrite_tail(char **str, size_t start,
+                                 const char *fmt, ...);
+
+/**
+ * Rewrite the tail of an existing string, starting at a given index.
+ *
+ * Overwrites the contents of *str starting at \p start with newly formatted
+ * text, including a new null-terminator.  Allocates more memory as necessary.
+ *
+ * This can be used to append formatted text when the length of the existing
+ * string is already known, saving a strlen() call.
+ *
+ * \sa ralloc_vasprintf_append
+ *
+ * \param str   The string to be updated.
+ * \param start The index to start appending new data at.
+ * \param fmt   A printf-style formatting string
+ * \param args  A va_list containing the data to be formatted
+ *
+ * \p str will be updated to the new pointer unless allocation fails.
+ *
+ * \return True unless allocation failed.
+ */
+bool ralloc_vasprintf_rewrite_tail(char **str, size_t start, const char *fmt,
+                                  va_list args);
+
 /**
  * Append formatted text to the supplied string.
  *
+ * This is equivalent to
+ * \code
+ * ralloc_asprintf_rewrite_tail(str, strlen(*str), fmt, ...)
+ * \endcode
+ *
  * \sa ralloc_asprintf
+ * \sa ralloc_asprintf_rewrite_tail
  * \sa ralloc_strcat
  *
  * \p str will be updated to the new pointer unless allocation fails.
@@ -328,7 +379,13 @@ bool ralloc_asprintf_append (char **str, const char *fmt, ...);
 /**
  * Append formatted text to the supplied string, given a va_list.
  *
+ * This is equivalent to
+ * \code
+ * ralloc_vasprintf_rewrite_tail(str, strlen(*str), fmt, args)
+ * \endcode
+ *
  * \sa ralloc_vasprintf
+ * \sa ralloc_vasprintf_rewrite_tail
  * \sa ralloc_strcat
  *
  * \p str will be updated to the new pointer unless allocation fails.