Libparserutils
stack.c
Go to the documentation of this file.
1 /*
2  * This file is part of LibParserUtils.
3  * Licensed under the MIT License,
4  * http://www.opensource.org/licenses/mit-license.php
5  * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org>
6  */
7 
8 #include <inttypes.h>
9 #include <string.h>
10 
12 
17 {
18  size_t item_size;
19  size_t chunk_size;
20  size_t items_allocated;
21  int32_t current_item;
22  void *items;
23 };
24 
35 parserutils_error parserutils_stack_create(size_t item_size, size_t chunk_size,
36  parserutils_stack **stack)
37 {
39 
40  if (item_size == 0 || chunk_size == 0 || stack == NULL)
41  return PARSERUTILS_BADPARM;
42 
43  s = malloc(sizeof(parserutils_stack));
44  if (s == NULL)
45  return PARSERUTILS_NOMEM;
46 
47  s->items = malloc(item_size * chunk_size);
48  if (s->items == NULL) {
49  free(s);
50  return PARSERUTILS_NOMEM;
51  }
52 
53  s->item_size = item_size;
54  s->chunk_size = chunk_size;
55  s->items_allocated = chunk_size;
56  s->current_item = -1;
57 
58  *stack = s;
59 
60  return PARSERUTILS_OK;
61 }
62 
70 {
71  if (stack == NULL)
72  return PARSERUTILS_BADPARM;
73 
74  free(stack->items);
75  free(stack);
76 
77  return PARSERUTILS_OK;
78 }
79 
88  const void *item)
89 {
90  int32_t slot;
91 
92  if (stack == NULL || item == NULL)
93  return PARSERUTILS_BADPARM;
94 
95  /* Ensure we'll get a valid slot */
96  if (stack->current_item < -1 || stack->current_item == INT32_MAX)
97  return PARSERUTILS_INVALID;
98 
99  slot = stack->current_item + 1;
100 
101  if ((size_t) slot >= stack->items_allocated) {
102  void *temp = realloc(stack->items,
103  (stack->items_allocated + stack->chunk_size) *
104  stack->item_size);
105  if (temp == NULL)
106  return PARSERUTILS_NOMEM;
107 
108  stack->items = temp;
109  stack->items_allocated += stack->chunk_size;
110  }
111 
112  memcpy((uint8_t *) stack->items + (slot * stack->item_size),
113  item, stack->item_size);
114  stack->current_item = slot;
115 
116  return PARSERUTILS_OK;
117 }
118 
127 {
128  if (stack == NULL)
129  return PARSERUTILS_BADPARM;
130 
131  if (stack->current_item < 0)
132  return PARSERUTILS_INVALID;
133 
134  if (item != NULL) {
135  memcpy(item, (uint8_t *) stack->items +
136  (stack->current_item * stack->item_size),
137  stack->item_size);
138  }
139 
140  stack->current_item -= 1;
141 
142  return PARSERUTILS_OK;
143 }
144 
152 {
153  if (stack == NULL || stack->current_item < 0)
154  return NULL;
155 
156  return (uint8_t *) stack->items +
157  (stack->current_item * stack->item_size);
158 }
159 
160 #ifndef NDEBUG
161 #include <stdio.h>
162 
163 extern void parserutils_stack_dump(parserutils_stack *stack, const char *prefix,
164  void (*printer)(void *item));
165 
166 void parserutils_stack_dump(parserutils_stack *stack, const char *prefix,
167  void (*printer)(void *item))
168 {
169  int32_t i;
170 
171  if (stack == NULL || printer == NULL)
172  return;
173 
174  for (i = 0; i <= stack->current_item; i++) {
175  printf("%s %d: ", prefix != NULL ? prefix : "", i);
176  printer((uint8_t *) stack->items + (i * stack->item_size));
177  printf("\n");
178  }
179 }
180 
181 #endif
182 
PARSERUTILS_BADPARM
@ PARSERUTILS_BADPARM
Definition: errors.h:22
parserutils_stack::items_allocated
size_t items_allocated
Number of slots allocated.
Definition: stack.c:20
parserutils_stack::chunk_size
size_t chunk_size
Size of a stack chunk.
Definition: stack.c:19
parserutils_stack::current_item
int32_t current_item
Index of current item.
Definition: stack.c:21
PARSERUTILS_OK
@ PARSERUTILS_OK
Definition: errors.h:19
parserutils_stack_destroy
parserutils_error parserutils_stack_destroy(parserutils_stack *stack)
Destroy a stack instance.
Definition: stack.c:69
parserutils_stack::items
void * items
Items in stack.
Definition: stack.c:22
parserutils_stack_dump
void parserutils_stack_dump(parserutils_stack *stack, const char *prefix, void(*printer)(void *item))
Definition: stack.c:166
parserutils_stack_push
parserutils_error parserutils_stack_push(parserutils_stack *stack, const void *item)
Push an item onto the stack.
Definition: stack.c:87
parserutils_stack_get_current
void * parserutils_stack_get_current(parserutils_stack *stack)
Retrieve a pointer to the current item on the stack.
Definition: stack.c:151
PARSERUTILS_INVALID
@ PARSERUTILS_INVALID
Definition: errors.h:23
parserutils_error
parserutils_error
Definition: errors.h:18
parserutils_stack_create
parserutils_error parserutils_stack_create(size_t item_size, size_t chunk_size, parserutils_stack **stack)
Create a stack.
Definition: stack.c:35
parserutils_stack::item_size
size_t item_size
Size of an item in the stack.
Definition: stack.c:18
PARSERUTILS_NOMEM
@ PARSERUTILS_NOMEM
Definition: errors.h:21
parserutils_stack_pop
parserutils_error parserutils_stack_pop(parserutils_stack *stack, void *item)
Pop an item off a stack.
Definition: stack.c:126
parserutils_stack
Stack object.
Definition: stack.c:16
stack.h