glsl: In loop analysis, handle unconditional second assignment.
[mesa.git] / src / glsl / ralloc.c
index 3ba5d86cd9c353fc70b7f19c8758bb9d7b9091e3..36bc61fd07585c6db585a5d60797af3fb12a3beb 100644 (file)
 #include <string.h>
 #include <stdint.h>
 
-#include "ralloc.h"
+/* Android defines SIZE_MAX in limits.h, instead of the standard stdint.h */
+#ifdef ANDROID
+#include <limits.h>
+#endif
 
-#ifdef __GNUC__
-#define likely(x)       __builtin_expect(!!(x),1)
-#define unlikely(x)     __builtin_expect(!!(x),0)
-#else
-#define likely(x)       !!(x)
-#define unlikely(x)     !!(x)
+/* Some versions of MinGW are missing _vscprintf's declaration, although they
+ * still provide the symbol in the import library. */
+#ifdef __MINGW32__
+_CRTIMP int _vscprintf(const char *format, va_list argptr);
 #endif
 
+#include "ralloc.h"
+
 #ifndef va_copy
 #ifdef __va_copy
 #define va_copy(dest, src) __va_copy((dest), (src))
 
 struct ralloc_header
 {
+#ifdef DEBUG
    /* A canary value used to determine whether a pointer is ralloc'd. */
    unsigned canary;
+#endif
 
    struct ralloc_header *parent;
 
@@ -75,7 +80,9 @@ get_header(const void *ptr)
 {
    ralloc_header *info = (ralloc_header *) (((char *) ptr) -
                                            sizeof(ralloc_header));
+#ifdef DEBUG
    assert(info->canary == CANARY);
+#endif
    return info;
 }
 
@@ -104,13 +111,19 @@ void *
 ralloc_size(const void *ctx, size_t size)
 {
    void *block = calloc(1, size + sizeof(ralloc_header));
+   ralloc_header *info;
+   ralloc_header *parent;
 
-   ralloc_header *info = (ralloc_header *) block;
-   ralloc_header *parent = ctx != NULL ? get_header(ctx) : NULL;
+   if (unlikely(block == NULL))
+      return NULL;
+   info = (ralloc_header *) block;
+   parent = ctx != NULL ? get_header(ctx) : NULL;
 
    add_child(parent, info);
 
+#ifdef DEBUG
    info->canary = CANARY;
+#endif
 
    return PTR_FROM_HEADER(info);
 }
@@ -267,7 +280,7 @@ ralloc_parent(const void *ptr)
       return NULL;
 
    info = get_header(ptr);
-   return PTR_FROM_HEADER(info->parent);
+   return info->parent ? PTR_FROM_HEADER(info->parent) : NULL;
 }
 
 static void *autofree_context = NULL;
@@ -392,7 +405,7 @@ printf_length(const char *fmt, va_list untouched_args)
    va_list args;
    va_copy(args, untouched_args);
 
-#ifdef _MSC_VER
+#ifdef _WIN32
    /* We need to use _vcsprintf to calculate the size as vsnprintf returns -1
     * if the number of characters to write is greater than count.
     */
@@ -403,6 +416,8 @@ printf_length(const char *fmt, va_list untouched_args)
 #endif
    assert(size >= 0);
 
+   va_end(args);
+
    return size;
 }
 
@@ -432,7 +447,28 @@ 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;
+   size_t existing_length;
+   assert(str != NULL);
+   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);
@@ -443,14 +479,14 @@ 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;
+   *start += new_length;
    return true;
 }