aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/slang/slang_utility.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/slang/slang_utility.c')
-rw-r--r--src/mesa/slang/slang_utility.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/mesa/slang/slang_utility.c b/src/mesa/slang/slang_utility.c
new file mode 100644
index 00000000000..c1d57409a43
--- /dev/null
+++ b/src/mesa/slang/slang_utility.c
@@ -0,0 +1,228 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.3
+ *
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file slang_utility.c
+ * slang utilities
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "slang_utility.h"
+#include "slang_mem.h"
+
+char *
+slang_string_concat (char *dst, const char *src)
+{
+ return strcpy (dst + strlen (dst), src);
+}
+
+
+/* slang_string */
+
+GLvoid
+slang_string_init (slang_string *self)
+{
+ self->data = NULL;
+ self->capacity = 0;
+ self->length = 0;
+ self->fail = GL_FALSE;
+}
+
+GLvoid
+slang_string_free (slang_string *self)
+{
+ if (self->data != NULL)
+ free(self->data);
+}
+
+GLvoid
+slang_string_reset (slang_string *self)
+{
+ self->length = 0;
+ self->fail = GL_FALSE;
+}
+
+static GLboolean
+grow (slang_string *self, GLuint size)
+{
+ if (self->fail)
+ return GL_FALSE;
+ if (size > self->capacity) {
+ /* do not overflow 32-bit range */
+ assert (size < 0x80000000);
+
+ self->data = (char *) (_mesa_realloc (self->data, self->capacity, size * 2));
+ self->capacity = size * 2;
+ if (self->data == NULL) {
+ self->capacity = 0;
+ self->fail = GL_TRUE;
+ return GL_FALSE;
+ }
+ }
+ return GL_TRUE;
+}
+
+GLvoid
+slang_string_push (slang_string *self, const slang_string *str)
+{
+ if (str->fail) {
+ self->fail = GL_TRUE;
+ return;
+ }
+ if (grow (self, self->length + str->length)) {
+ memcpy (&self->data[self->length], str->data, str->length);
+ self->length += str->length;
+ }
+}
+
+GLvoid
+slang_string_pushc (slang_string *self, const char c)
+{
+ if (grow (self, self->length + 1)) {
+ self->data[self->length] = c;
+ self->length++;
+ }
+}
+
+GLvoid
+slang_string_pushs (slang_string *self, const char *cstr, GLuint len)
+{
+ if (grow (self, self->length + len)) {
+ memcpy (&self->data[self->length], cstr, len);
+ self->length += len;
+ }
+}
+
+GLvoid
+slang_string_pushi (slang_string *self, GLint i)
+{
+ char buffer[12];
+
+ _mesa_snprintf (buffer, sizeof(buffer), "%d", i);
+ slang_string_pushs (self, buffer, strlen (buffer));
+}
+
+const char *
+slang_string_cstr (slang_string *self)
+{
+ if (grow (self, self->length + 1))
+ self->data[self->length] = '\0';
+ return self->data;
+}
+
+/* slang_atom_pool */
+
+void
+slang_atom_pool_construct(slang_atom_pool * pool)
+{
+ GLuint i;
+
+ for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
+ pool->entries[i] = NULL;
+}
+
+void
+slang_atom_pool_destruct (slang_atom_pool * pool)
+{
+ GLuint i;
+
+ for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) {
+ slang_atom_entry * entry;
+
+ entry = pool->entries[i];
+ while (entry != NULL) {
+ slang_atom_entry *next = entry->next;
+ _slang_free(entry->id);
+ _slang_free(entry);
+ entry = next;
+ }
+ }
+}
+
+/*
+ * Search the atom pool for an atom with a given name.
+ * If atom is not found, create and add it to the pool.
+ * Returns ATOM_NULL if the atom was not found and the function failed
+ * to create a new atom.
+ */
+slang_atom
+slang_atom_pool_atom(slang_atom_pool * pool, const char * id)
+{
+ GLuint hash;
+ const char * p = id;
+ slang_atom_entry ** entry;
+
+ /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
+ hash = 0;
+ while (*p != '\0') {
+ GLuint g;
+
+ hash = (hash << 4) + (GLuint) (*p++);
+ g = hash & 0xf0000000;
+ if (g != 0)
+ hash ^= g >> 24;
+ hash &= ~g;
+ }
+ hash %= SLANG_ATOM_POOL_SIZE;
+
+ /* Now the hash points to a linked list of atoms with names that
+ * have the same hash value. Search the linked list for a given
+ * name.
+ */
+ entry = &pool->entries[hash];
+ while (*entry != NULL) {
+ /* If the same, return the associated atom. */
+ if (slang_string_compare((**entry).id, id) == 0)
+ return (slang_atom) (**entry).id;
+ /* Grab the next atom in the linked list. */
+ entry = &(**entry).next;
+ }
+
+ /* Okay, we have not found an atom. Create a new entry for it.
+ * Note that the <entry> points to the last entry's <next> field.
+ */
+ *entry = (slang_atom_entry *) _slang_alloc(sizeof(slang_atom_entry));
+ if (*entry == NULL)
+ return SLANG_ATOM_NULL;
+
+ /* Initialize a new entry. Because we'll need the actual name of
+ * the atom, we use the pointer to this string as an actual atom's
+ * value.
+ */
+ (**entry).next = NULL;
+ (**entry).id = _slang_strdup(id);
+ if ((**entry).id == NULL)
+ return SLANG_ATOM_NULL;
+ return (slang_atom) (**entry).id;
+}
+
+/**
+ * Return the name of a given atom.
+ */
+const char *
+slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom)
+{
+ return (const char *) (atom);
+}