OSDN Git Service

r600g: add POW instruction
[android-x86/external-mesa.git] / src / mesa / slang / slang_utility.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.5.3
4  *
5  * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
6  *
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:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
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.
23  */
24
25 /**
26  * \file slang_utility.c
27  * slang utilities
28  * \author Michal Krol
29  */
30
31 #include "main/imports.h"
32 #include "slang_utility.h"
33 #include "slang_mem.h"
34
35 char *
36 slang_string_concat (char *dst, const char *src)
37 {
38    return strcpy (dst + strlen (dst), src);
39 }
40
41
42 /* slang_string */
43
44 GLvoid
45 slang_string_init (slang_string *self)
46 {
47    self->data = NULL;
48    self->capacity = 0;
49    self->length = 0;
50    self->fail = GL_FALSE;
51 }
52
53 GLvoid
54 slang_string_free (slang_string *self)
55 {
56    if (self->data != NULL)
57       free(self->data);
58 }
59
60 GLvoid
61 slang_string_reset (slang_string *self)
62 {
63    self->length = 0;
64    self->fail = GL_FALSE;
65 }
66
67 static GLboolean
68 grow (slang_string *self, GLuint size)
69 {
70    if (self->fail)
71       return GL_FALSE;
72    if (size > self->capacity) {
73       /* do not overflow 32-bit range */
74       assert (size < 0x80000000);
75
76       self->data = (char *) (_mesa_realloc (self->data, self->capacity, size * 2));
77       self->capacity = size * 2;
78       if (self->data == NULL) {
79          self->capacity = 0;
80          self->fail = GL_TRUE;
81          return GL_FALSE;
82       }
83    }
84    return GL_TRUE;
85 }
86
87 GLvoid
88 slang_string_push (slang_string *self, const slang_string *str)
89 {
90    if (str->fail) {
91       self->fail = GL_TRUE;
92       return;
93    }
94    if (grow (self, self->length + str->length)) {
95       memcpy (&self->data[self->length], str->data, str->length);
96       self->length += str->length;
97    }
98 }
99
100 GLvoid
101 slang_string_pushc (slang_string *self, const char c)
102 {
103    if (grow (self, self->length + 1)) {
104       self->data[self->length] = c;
105       self->length++;
106    }
107 }
108
109 GLvoid
110 slang_string_pushs (slang_string *self, const char *cstr, GLuint len)
111 {
112    if (grow (self, self->length + len)) {
113       memcpy (&self->data[self->length], cstr, len);
114       self->length += len;
115    }
116 }
117
118 GLvoid
119 slang_string_pushi (slang_string *self, GLint i)
120 {
121    char buffer[12];
122
123    _mesa_snprintf (buffer, sizeof(buffer), "%d", i);
124    slang_string_pushs (self, buffer, strlen (buffer));
125 }
126
127 const char *
128 slang_string_cstr (slang_string *self)
129 {
130    if (grow (self, self->length + 1))
131       self->data[self->length] = '\0';
132    return self->data;
133 }
134
135 /* slang_atom_pool */
136
137 void
138 slang_atom_pool_construct(slang_atom_pool * pool)
139 {
140    GLuint i;
141
142    for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
143       pool->entries[i] = NULL;
144 }
145
146 void
147 slang_atom_pool_destruct (slang_atom_pool * pool)
148 {
149    GLuint i;
150
151    for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) {
152       slang_atom_entry * entry;
153                 
154       entry = pool->entries[i];
155       while (entry != NULL) {
156          slang_atom_entry *next = entry->next;
157          _slang_free(entry->id);
158          _slang_free(entry);
159          entry = next;
160       }
161    }
162 }
163
164 /*
165  * Search the atom pool for an atom with a given name.
166  * If atom is not found, create and add it to the pool.
167  * Returns ATOM_NULL if the atom was not found and the function failed
168  * to create a new atom.
169  */
170 slang_atom
171 slang_atom_pool_atom(slang_atom_pool * pool, const char * id)
172 {
173    GLuint hash;
174    const char * p = id;
175    slang_atom_entry ** entry;
176
177    /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
178    hash = 0;
179    while (*p != '\0') {
180       GLuint g;
181
182       hash = (hash << 4) + (GLuint) (*p++);
183       g = hash & 0xf0000000;
184       if (g != 0)
185          hash ^= g >> 24;
186       hash &= ~g;
187    }
188    hash %= SLANG_ATOM_POOL_SIZE;
189
190    /* Now the hash points to a linked list of atoms with names that
191     * have the same hash value.  Search the linked list for a given
192     * name.
193     */
194    entry = &pool->entries[hash];
195    while (*entry != NULL) {
196       /* If the same, return the associated atom. */
197       if (slang_string_compare((**entry).id, id) == 0)
198          return (slang_atom) (**entry).id;
199       /* Grab the next atom in the linked list. */
200       entry = &(**entry).next;
201    }
202
203    /* Okay, we have not found an atom. Create a new entry for it.
204     * Note that the <entry> points to the last entry's <next> field.
205     */
206    *entry = (slang_atom_entry *) _slang_alloc(sizeof(slang_atom_entry));
207    if (*entry == NULL)
208       return SLANG_ATOM_NULL;
209
210    /* Initialize a new entry. Because we'll need the actual name of
211     * the atom, we use the pointer to this string as an actual atom's
212     * value.
213     */
214    (**entry).next = NULL;
215    (**entry).id = _slang_strdup(id);
216    if ((**entry).id == NULL)
217       return SLANG_ATOM_NULL;
218    return (slang_atom) (**entry).id;
219 }
220
221 /**
222  * Return the name of a given atom.
223  */
224 const char *
225 slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom)
226 {
227    return (const char *) (atom);
228 }