silc_stack_free can now be called with NULL stack
[silc.git] / lib / silcutil / silcstack.c
index 30565e1fb4a759b87869d9d7afd1847379483508..6107cf047598a912e888fa55aadc59850b4f2be5 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2003 - 2005 Pekka Riikonen
+  Copyright (C) 2003 - 2008 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 
 /* #define SILC_STACK_DEBUG 1 */
 
-#include "silcincludes.h"
+#include "silc.h"
 
 /* Allocate the stack */
 
@@ -66,6 +66,9 @@ void silc_stack_free(SilcStack stack)
 {
   int i;
 
+  if (!stack)
+    return;
+
   silc_free(stack->frames);
   for (i = 0; i < SILC_STACK_BLOCK_NUM; i++)
     silc_free(stack->stack[i]);
@@ -145,7 +148,7 @@ SilcUInt32 silc_stack_pop(SilcStack stack)
    memory, otherwise memory is aligned.  Returns pointer to the memory
    or NULL on error. */
 
-void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, bool aligned)
+void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, SilcBool aligned)
 {
   void *ptr;
   SilcUInt32 bsize, bsize2;
@@ -155,13 +158,13 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, bool aligned)
   SILC_ST_DEBUG(("Allocating %d bytes (%s) from %p",
                 size, aligned ? "align" : "not align", stack));
 
-  if (!size) {
+  if (silc_unlikely(!size)) {
     SILC_LOG_ERROR(("Allocation by zero (0)"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
   }
 
-  if (size > SILC_STACK_MAX_ALLOC) {
+  if (silc_unlikely(size > SILC_STACK_MAX_ALLOC)) {
     SILC_LOG_ERROR(("Allocating too much"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
@@ -193,7 +196,7 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, bool aligned)
     bsize2 <<= 1;
     si++;
   }
-  if (si >= SILC_STACK_BLOCK_NUM) {
+  if (silc_unlikely(si >= SILC_STACK_BLOCK_NUM)) {
     SILC_LOG_ERROR(("Allocating too large block"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
@@ -205,7 +208,7 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, bool aligned)
     stack->stack[si] = silc_malloc(bsize2 +
                                   SILC_STACK_ALIGN(sizeof(**stack->stack),
                                                    SILC_STACK_DEFAULT_ALIGN));
-    if (!stack->stack[si]) {
+    if (silc_unlikely(!stack->stack[si])) {
       SILC_STACK_STAT(stack, num_errors, 1);
       return NULL;
     }
@@ -231,7 +234,7 @@ void *silc_stack_malloc(SilcStack stack, SilcUInt32 size, bool aligned)
    the old memory remains intact. */
 
 void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
-                        void *ptr, SilcUInt32 size, bool aligned)
+                        void *ptr, SilcUInt32 size, SilcBool aligned)
 {
   SilcUInt32 si = stack->frame->si;
   SilcUInt32 bsize;
@@ -244,13 +247,13 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
   SILC_ST_DEBUG(("Reallocating %d bytes (%d) (%s) from %p", size, old_size,
                 aligned ? "align" : "not align", stack));
 
-  if (!size || !old_size) {
+  if (silc_unlikely(!size || !old_size)) {
     SILC_LOG_ERROR(("Allocation by zero (0)"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
   }
 
-  if (size > SILC_STACK_MAX_ALLOC) {
+  if (silc_unlikely(size > SILC_STACK_MAX_ALLOC)) {
     SILC_LOG_ERROR(("Allocating too much"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
@@ -258,7 +261,8 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
 
   /* Align the old size if needed */
   old_size = (aligned ?
-             SILC_STACK_ALIGN(old_size, SILC_STACK_DEFAULT_ALIGN) : old_size);
+             SILC_STACK_ALIGN(old_size,
+                              SILC_STACK_DEFAULT_ALIGN) : old_size);
 
   /* Compute the size of current stack block */
   bsize = SILC_STACK_BLOCK_SIZE(stack, si);
@@ -266,7 +270,8 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
   /* Check that `ptr' is last allocation */
   sptr = (unsigned char *)stack->stack[si] +
     SILC_STACK_ALIGN(sizeof(**stack->stack), SILC_STACK_DEFAULT_ALIGN);
-  if (stack->stack[si]->bytes_left + old_size + (ptr - sptr) != bsize) {
+  if (stack->stack[si]->bytes_left + old_size +
+      ((unsigned char *)ptr - (unsigned char *)sptr) != bsize) {
     SILC_LOG_DEBUG(("Cannot reallocate"));
     SILC_STACK_STAT(stack, num_errors, 1);
     return NULL;
@@ -275,7 +280,8 @@ void *silc_stack_realloc(SilcStack stack, SilcUInt32 old_size,
   /* Now check that the new size fits to this block */
   if (stack->stack[si]->bytes_left >= size) {
     /* It fits, so simply return the old pointer */
-    size = (aligned ? SILC_STACK_ALIGN(size, SILC_STACK_DEFAULT_ALIGN) : size);
+    size = (aligned ? SILC_STACK_ALIGN(size,
+                                      SILC_STACK_DEFAULT_ALIGN) : size);
     stack->stack[si]->bytes_left -= (size - old_size);
     SILC_STACK_STAT(stack, bytes_malloc, (size - old_size));
     return ptr;