2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * \file slang_utility.c
32 #include "slang_utility.h"
33 #include "slang_mem.h"
36 slang_string_concat (char *dst
, const char *src
)
38 return _mesa_strcpy (dst
+ _mesa_strlen (dst
), src
);
45 slang_string_init (slang_string
*self
)
50 self
->fail
= GL_FALSE
;
54 slang_string_free (slang_string
*self
)
56 if (self
->data
!= NULL
)
57 _mesa_free (self
->data
);
61 slang_string_reset (slang_string
*self
)
64 self
->fail
= GL_FALSE
;
68 grow (slang_string
*self
, GLuint size
)
72 if (size
> self
->capacity
) {
73 /* do not overflow 32-bit range */
74 assert (size
< 0x80000000);
76 self
->data
= (char *) (_mesa_realloc (self
->data
, self
->capacity
, size
* 2));
77 self
->capacity
= size
* 2;
78 if (self
->data
== NULL
) {
88 slang_string_push (slang_string
*self
, const slang_string
*str
)
94 if (grow (self
, self
->length
+ str
->length
)) {
95 _mesa_memcpy (&self
->data
[self
->length
], str
->data
, str
->length
);
96 self
->length
+= str
->length
;
101 slang_string_pushc (slang_string
*self
, const char c
)
103 if (grow (self
, self
->length
+ 1)) {
104 self
->data
[self
->length
] = c
;
110 slang_string_pushs (slang_string
*self
, const char *cstr
, GLuint len
)
112 if (grow (self
, self
->length
+ len
)) {
113 _mesa_memcpy (&self
->data
[self
->length
], cstr
, len
);
119 slang_string_pushi (slang_string
*self
, GLint i
)
123 _mesa_sprintf (buffer
, "%d", i
);
124 slang_string_pushs (self
, buffer
, strlen (buffer
));
128 slang_string_cstr (slang_string
*self
)
130 if (grow (self
, self
->length
+ 1))
131 self
->data
[self
->length
] = '\0';
135 /* slang_atom_pool */
138 slang_atom_pool_construct(slang_atom_pool
* pool
)
142 for (i
= 0; i
< SLANG_ATOM_POOL_SIZE
; i
++)
143 pool
->entries
[i
] = NULL
;
147 slang_atom_pool_destruct (slang_atom_pool
* pool
)
151 for (i
= 0; i
< SLANG_ATOM_POOL_SIZE
; i
++) {
152 slang_atom_entry
* entry
;
154 entry
= pool
->entries
[i
];
155 while (entry
!= NULL
) {
156 slang_atom_entry
*next
;
160 _slang_free(entry
->id
);
163 slang_alloc_free(entry
->id
);
164 slang_alloc_free(entry
);
172 * Search the atom pool for an atom with a given name.
173 * If atom is not found, create and add it to the pool.
174 * Returns ATOM_NULL if the atom was not found and the function failed
175 * to create a new atom.
178 slang_atom_pool_atom(slang_atom_pool
* pool
, const char * id
)
182 slang_atom_entry
** entry
;
184 /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
189 hash
= (hash
<< 4) + (GLuint
) (*p
++);
190 g
= hash
& 0xf0000000;
195 hash
%= SLANG_ATOM_POOL_SIZE
;
197 /* Now the hash points to a linked list of atoms with names that
198 * have the same hash value. Search the linked list for a given
201 entry
= &pool
->entries
[hash
];
202 while (*entry
!= NULL
) {
203 /* If the same, return the associated atom. */
204 if (slang_string_compare((**entry
).id
, id
) == 0)
205 return (slang_atom
) (**entry
).id
;
206 /* Grab the next atom in the linked list. */
207 entry
= &(**entry
).next
;
210 /* Okay, we have not found an atom. Create a new entry for it.
211 * Note that the <entry> points to the last entry's <next> field.
214 *entry
= (slang_atom_entry
*) (_slang_alloc(sizeof(slang_atom_entry
)));
216 *entry
= (slang_atom_entry
*) (slang_alloc_malloc(sizeof(slang_atom_entry
)));
219 return SLANG_ATOM_NULL
;
221 /* Initialize a new entry. Because we'll need the actual name of
222 * the atom, we use the pointer to this string as an actual atom's
225 (**entry
).next
= NULL
;
227 (**entry
).id
= _slang_strdup(id
);
229 (**entry
).id
= slang_string_duplicate(id
);
231 if ((**entry
).id
== NULL
)
232 return SLANG_ATOM_NULL
;
233 return (slang_atom
) (**entry
).id
;
237 * Return the name of a given atom.
240 slang_atom_pool_id(slang_atom_pool
* pool
, slang_atom atom
)
242 return (const char *) (atom
);