1 /*
2 csound_type_system.c:
3
4 Copyright (C) 2012,2013 Steven Yi
5
6 This file is part of Csound.
7
8 The Csound Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 Csound is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with Csound; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301 USA
22 */
23
24 #include "csound_type_system.h"
25 #include <string.h>
26 #include <stdio.h>
27 #include "csoundCore.h"
28
csTypeExistsWithSameName(TYPE_POOL * pool,CS_TYPE * typeInstance)29 int csTypeExistsWithSameName(TYPE_POOL* pool, CS_TYPE* typeInstance) {
30 CS_TYPE_ITEM* current = pool->head;
31 while (current != NULL) {
32
33 /* printf("Search if type [%s] == [%s]",
34 current->varTypeName, typeInstance->varTypeName); */
35
36 if (strcmp(current->cstype->varTypeName,
37 typeInstance->varTypeName) == 0) {
38 return 1;
39 }
40 current = current->next;
41 }
42
43 return 0;
44 }
45
csoundGetTypeWithVarTypeName(TYPE_POOL * pool,char * typeName)46 CS_TYPE* csoundGetTypeWithVarTypeName(TYPE_POOL* pool, char* typeName) {
47 CS_TYPE_ITEM* current = pool->head;
48 while (current != NULL) {
49 if (strcmp(typeName, current->cstype->varTypeName) == 0) {
50 return current->cstype;
51 }
52 current = current->next;
53 }
54 return NULL;
55 }
56
csoundGetTypeForVarName(TYPE_POOL * pool,char * varName)57 CS_TYPE* csoundGetTypeForVarName(TYPE_POOL* pool, char* varName) {
58 CS_TYPE_ITEM* current = pool->head;
59 char temp[2];
60 temp[0] = varName[0];
61 temp[1] = 0;
62 while (current != NULL) {
63 if (strcmp(temp, current->cstype->varTypeName) == 0) {
64 return current->cstype;
65 }
66 current = current->next;
67 }
68 return NULL;
69 }
70
csoundAddVariableType(CSOUND * csound,TYPE_POOL * pool,CS_TYPE * typeInstance)71 int csoundAddVariableType(CSOUND* csound, TYPE_POOL* pool, CS_TYPE* typeInstance)
72 {
73 CS_TYPE_ITEM* item;
74 if (csTypeExistsWithSameName(pool, typeInstance)) {
75 return 0;
76 }
77
78 item = (CS_TYPE_ITEM*)csound->Calloc(csound, sizeof(CS_TYPE_ITEM));
79 item->cstype = typeInstance;
80
81 if (pool->head == NULL) {
82 pool->head = item;
83 } else {
84 CS_TYPE_ITEM* current = pool->head;
85 while (current->next) {
86 current = current->next;
87 }
88 current->next = item;
89 item->next = NULL;
90 }
91
92 /* printf("Adding type with type name: %s\n", typeInstance->varTypeName); */
93
94 return 1;
95 }
96
97 /* VAR POOL FUNCTIONS */
98
99
csoundCreateVarPool(CSOUND * csound)100 CS_VAR_POOL* csoundCreateVarPool(CSOUND* csound) {
101 CS_VAR_POOL* varPool = csound->Calloc(csound, sizeof(CS_VAR_POOL));
102 varPool->table = cs_hash_table_create(csound);
103 return varPool;
104 }
105
csoundFreeVarPool(CSOUND * csound,CS_VAR_POOL * pool)106 void csoundFreeVarPool(CSOUND* csound, CS_VAR_POOL* pool) {
107 if(pool->table) cs_hash_table_mfree_complete(csound, pool->table);
108 csound->Free(csound, pool);
109 }
110
getVarSimpleName(CSOUND * csound,const char * varName)111 char* getVarSimpleName(CSOUND* csound, const char* varName) {
112 char* retVal;
113
114 if (varName[0] != '[') {
115 retVal = (char*)csound->Calloc(csound, sizeof(char) * (strlen(varName) + 1));
116 strcpy(retVal, varName);
117 } else {
118 int start = 0;
119 int typeEnd = 0;
120 int len = strlen(varName);
121 int newFirstLen, newSecondLen, newTotalLen;
122 char* t = (char*) varName;
123 char* t2;
124
125 while(*t == '[') {
126 t++;
127 start++;
128 }
129 typeEnd = start;
130 t2 = t;
131 while(*t2 != ']' && *t2 != (char)0) {
132 t2++;
133 typeEnd++;
134 }
135 t2++;
136 typeEnd++;
137
138 newFirstLen = (typeEnd - start - 1);
139 newSecondLen = (len - typeEnd);
140 newTotalLen = newFirstLen + newSecondLen;
141
142 retVal = (char*)csound->Calloc(csound, sizeof(char) * (newTotalLen + 1));
143 strncpy(retVal, t, newFirstLen);
144 strncpy(retVal + newFirstLen, t2, newSecondLen);
145 }
146
147 return retVal;
148 }
149
csoundCreateVariable(void * csound,TYPE_POOL * pool,CS_TYPE * type,char * name,void * typeArg)150 CS_VARIABLE* csoundCreateVariable(void* csound, TYPE_POOL* pool,
151 CS_TYPE* type, char* name, void* typeArg)
152 {
153 CS_TYPE_ITEM* current = pool->head;
154 if (LIKELY(type != NULL))
155 while (current != NULL) {
156 if (strcmp(type->varTypeName, current->cstype->varTypeName) == 0) {
157 CS_VARIABLE* var = current->cstype->createVariable(csound, typeArg);
158 var->varType = type;
159 var->varName = cs_strdup(csound, name);
160 return var;
161 }
162 current = current->next;
163 }
164 else ((CSOUND *)csound)->ErrorMsg(csound,
165 Str("cannot create variable %s: NULL type"),
166 name);
167 return NULL;
168 }
169
csoundFindVariableWithName(CSOUND * csound,CS_VAR_POOL * pool,const char * name)170 CS_VARIABLE* csoundFindVariableWithName(CSOUND* csound, CS_VAR_POOL* pool,
171 const char* name)
172 {
173
174 CS_VARIABLE* returnValue = cs_hash_table_get(csound, pool->table, (char*)name);
175
176 if (returnValue == NULL && pool->parent != NULL) {
177 returnValue = csoundFindVariableWithName(csound, pool->parent, name);
178 }
179
180 return returnValue;
181 }
182
csoundGetVariable(CS_VAR_POOL * pool,int index)183 CS_VARIABLE* csoundGetVariable(CS_VAR_POOL* pool, int index) {
184
185 CS_VARIABLE* current = pool->head;
186 int i;
187
188 for(i = 0; i < index || current != NULL; i++) {
189 /* THIS WAS WRONG!! && or || meant foR , ?? */
190 current = current->next;
191 }
192
193 return current;
194 }
195
196 //int csoundGetVariableIndex(CS_VAR_POOL* pool, CS_VARIABLE* var) {
197 // CS_VARIABLE* current = pool->head;
198 // int index = 0;
199 //
200 // if (current == NULL) {
201 // return -1;
202 // }
203 //
204 // for (index = 0; current != NULL; index++) {
205 // if (current == var) {
206 // return index;
207 // }
208 // }
209 // return -1;
210 //}
211
csoundAddVariable(CSOUND * csound,CS_VAR_POOL * pool,CS_VARIABLE * var)212 int csoundAddVariable(CSOUND* csound, CS_VAR_POOL* pool, CS_VARIABLE* var) {
213 if(var != NULL) {
214 if(pool->head == NULL) {
215 pool->head = var;
216 pool->tail = var;
217 } else {
218 pool->tail->next = var;
219 pool->tail = var;
220 }
221 cs_hash_table_put(csound, pool->table, var->varName, var);
222 // may need to revise this; var pools are accessed as MYFLT*,
223 // so need to ensure all memory is aligned to sizeof(MYFLT)
224 var->memBlockIndex = (pool->poolSize / sizeof(MYFLT)) +
225 ((pool->varCount + 1) * (CS_FLOAT_ALIGN(CS_VAR_TYPE_OFFSET) / sizeof(MYFLT)));
226 pool->poolSize += var->memBlockSize;
227 pool->varCount += 1;
228 return 0;
229 } else return -1;
230 }
231
recalculateVarPoolMemory(void * csound,CS_VAR_POOL * pool)232 void recalculateVarPoolMemory(void* csound, CS_VAR_POOL* pool)
233 {
234 CS_VARIABLE* current = pool->head;
235 int varCount = 1;
236 pool->poolSize = 0;
237
238 while (current != NULL) {
239 /* VL 26-12-12: had to revert these lines to avoid memory crashes
240 with higher ksmps */
241 if(current->updateMemBlockSize != NULL) {
242 current->updateMemBlockSize(csound, current);
243 }
244
245 current->memBlockIndex = (pool->poolSize / sizeof(MYFLT)) +
246 (varCount * CS_FLOAT_ALIGN(CS_VAR_TYPE_OFFSET) / sizeof(MYFLT));
247 pool->poolSize += current->memBlockSize;
248
249 current = current->next;
250 varCount++;
251 }
252 }
253
reallocateVarPoolMemory(void * csound,CS_VAR_POOL * pool)254 void reallocateVarPoolMemory(void* csound, CS_VAR_POOL* pool) {
255 CS_VARIABLE* current = pool->head;
256 CS_VAR_MEM* varMem = NULL;
257 size_t memSize;
258 pool->poolSize = 0;
259
260 while (current != NULL) {
261 varMem = current->memBlock;
262 memSize = current->memBlockSize;
263
264 if(current->updateMemBlockSize != NULL) {
265 current->updateMemBlockSize(csound, current);
266 }
267 // VL 14-3-2015 only realloc if we need to
268 if(memSize < (size_t)current->memBlockSize) {
269 memSize = CS_VAR_TYPE_OFFSET + current->memBlockSize;
270 varMem =
271 (CS_VAR_MEM *)((CSOUND *)csound)->ReAlloc(csound,varMem,
272 memSize);
273 current->memBlock = varMem;
274 }
275 pool->poolSize += current->memBlockSize;
276 current = current->next;
277 }
278 }
279
deleteVarPoolMemory(void * csnd,CS_VAR_POOL * pool)280 void deleteVarPoolMemory(void* csnd, CS_VAR_POOL* pool) {
281 CS_VARIABLE* current = pool->head, *tmp;
282 CSOUND *csound = (CSOUND *)csnd;
283 CS_TYPE* type;
284 while (current != NULL) {
285 tmp = current;
286 type = current->subType;
287 if (type->freeVariableMemory != NULL) {
288 type->freeVariableMemory(csound, current->memBlock);
289 }
290 csound->Free(csound, current->memBlock);
291 current = current->next;
292 csound->Free(csound, tmp);
293 }
294 }
295
296
297
initializeVarPool(void * csound,MYFLT * memBlock,CS_VAR_POOL * pool)298 void initializeVarPool(void *csound, MYFLT* memBlock, CS_VAR_POOL* pool) {
299 CS_VARIABLE* current = pool->head;
300 int varNum = 1;
301
302 while (current != NULL) {
303 if (current->initializeVariableMemory != NULL) {
304 current->initializeVariableMemory(csound, current,
305 memBlock + current->memBlockIndex);
306 }
307 varNum++;
308 current = current->next;
309 }
310 }
311
debug_print_varpool(CSOUND * csound,CS_VAR_POOL * pool)312 void debug_print_varpool(CSOUND* csound, CS_VAR_POOL* pool) {
313 CS_VARIABLE* gVar = pool->head;
314 int count = 0;
315 while(gVar != NULL) {
316 csound->Message(csound, " %d) %s:%s\n", count++,
317 gVar->varName, gVar->varType->varTypeName);
318 gVar = gVar->next;
319 }
320 }
321