File: util.h

package info (click to toggle)
pdp 1%3A0.14.1-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,904 kB
  • ctags: 4,405
  • sloc: ansic: 22,321; asm: 2,088; makefile: 551; perl: 145; sh: 93; cpp: 4
file content (185 lines) | stat: -rw-r--r-- 4,269 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
  util.h - (c) 2004 Tom Schouten.
  this software is in the public domain.

  This is supposed to be my low-level data structures toolbox.
  Defined as inline static to avoid version and symbol clashes.
*/


#ifndef ZL_UTIL_H
#define ZL_UTIL_H

#include <stdlib.h>

// linkage
#define INLINE inline static

// growable array object
typedef struct {
    int size;
    int elements;
    void **data;
} buf_t;


// fixed 2^n size queue object
typedef struct {
    void **data;
    unsigned int mask;
    unsigned int read;
    unsigned int write;
} queue_t;


typedef buf_t fifo_t; // same

/* small utils */

INLINE int imax(int x, int y){return (x > y) ? x : y;}
INLINE int imin(int x, int y){return (x < y) ? x : y;}

/* protos */

INLINE buf_t *buf_new(int size); ///< create a new growable array
INLINE void buf_add(buf_t *x, void *thing); ///< add an element
INLINE int buf_lookup(buf_t *x, void *thing); ///< lookup element and return index
INLINE int buf_add_to_set(buf_t *x, void *thing); ///< add if not already present
INLINE void buf_clear(buf_t *x);
INLINE void buf_free(buf_t *x);
INLINE void buf_remove(buf_t *x, void *thing);
INLINE int buf_allot(buf_t *x, int bytes); ///< allocate memory and return cell index

INLINE void stack_clear(fifo_t *x);
INLINE void stack_free(fifo_t *x);
INLINE int stack_elements(fifo_t *x);
INLINE void stack_push(fifo_t *x, void *data);
INLINE void *stack_pop(fifo_t *x);
INLINE void stack_clear(fifo_t *x);
INLINE void stack_free(fifo_t *x);
INLINE fifo_t *stack_new(int elements);





/* code */

INLINE buf_t *buf_new(int size){
    buf_t *x = malloc(sizeof(*x));
    x->size = size;
    x->elements = 0;
    x->data = malloc(sizeof(void *) * size);
    return x;
}

INLINE void buf_add(buf_t *x, void *thing){
    if (x->elements == x->size){
	x->size *= 2;
	x->data = realloc(x->data, x->size * sizeof(void *));
    }
    x->data[x->elements++] = thing;
}

INLINE int buf_lookup(buf_t *x, void *thing){
    int i;
    for (i=0; i<x->elements; i++){
	if (x->data[i] == thing) return i; // found
    }
    return -1; // not found
}

// add if not in there
INLINE int buf_add_to_set(buf_t *x, void *thing){
    int indx = buf_lookup(x, thing);
    if (indx < 0){ // add if not found
	indx = x->elements;
	buf_add(x, thing);
    }
    return indx;
}

INLINE void buf_remove(buf_t *x, void *thing){
    int indx = buf_lookup(x, thing);
    if (indx < 0) return; // not here
    x->elements--;
    x->data[indx] = x->data[x->elements];
}

INLINE void buf_clear(buf_t *x){x->elements = 0;}
INLINE void buf_free(buf_t *x){free (x->data); free(x);}

INLINE int buf_allot(buf_t *x, int bytes){
    int words = ((bytes-1) / sizeof(int)) - 1;
    int indx = x->elements;
    while(words--) buf_add(x, 0);
    return indx;
}


INLINE fifo_t *stack_new(int nb_elements){
    fifo_t *x = buf_new(nb_elements);
    return x;
}
INLINE int stack_elements(fifo_t *x){return x->elements;}
INLINE void stack_push(fifo_t *x, void *data){buf_add(x, data);}

INLINE void *stack_pop(fifo_t *x){
    if (!x->elements) return 0;
    return x->data[--x->elements];
}
    
INLINE void stack_clear(fifo_t *x){buf_clear(x);}
INLINE void stack_free(fifo_t *x){buf_free(x);}





#if 0  // FIXME: name conflicts with queue in leaf/queue.h
INLINE queue_t *queue_new(int logsize);
INLINE void queue_free(queue_t *queue);
INLINE void queue_write(queue_t *queue, void *thing);
INLINE void *queue_read(queue_t *queue);
INLINE unsigned int queue_elements(queue_t *queue);
INLINE int queue_full(queue_t *queue);

INLINE queue_t *queue_new(int logsize){
    queue_t *x = malloc(sizeof(*x));
    x->data = malloc(1<<logsize * sizeof(void *));
    x->mask = (1<<logsize) - 1;
    x->read = 0;
    x->write = 0;
    return x;
}
INLINE void queue_free(queue_t *x){
    free(x->data);
    free(x);
}

INLINE unsigned int queue_elements(queue_t *x){
    return (x->write - x->read) & x->mask;
}
INLINE int queue_full(queue_t *x){
    return (x->mask == queue_elements(x));
}

INLINE void queue_write(queue_t *x, void *thing){
    int i = x->write;
    x->data[i++] = thing;
    x->write = i & x->mask;
}

INLINE void *queue_read(queue_t *x){
    int i = x->read;
    void *thing = x->data[i++];
    x->write = i & x->mask;
    return thing;
}

#endif

#endif