8 #if defined(ECERE_BOOTSTRAP) || defined(ECERE_STATIC)
10 #if !defined(ECERE_BOOTSTRAP)
15 #if !defined(ECERE_BOOTSTRAP)
21 // #define REDZONE 256
28 static define MAX_MEMORY_LOC = 40;
30 static class MemStack : BTNode
37 static BinaryTree memStacks { };
38 static uint memoryErrorsCount = 0;
43 #define property _property
62 public define null = ((void *)0);
64 dllexport Class eSystem_FindClass(Module module, char * name);
65 dllexport void * eSystem_Renew(void * memory, unsigned int size);
66 dllexport void * eSystem_Renew0(void * memory, unsigned int size);
67 dllexport void * eSystem_New(unsigned int size);
68 dllexport void * eSystem_New0(unsigned int size);
69 dllexport void eSystem_Delete(void * memory);
70 dllexport void * eInstance_New(Class _class);
73 extern int __ecereVMethodID_class_OnGetDataFromString;
75 // IMPLEMENTATION FOR THESE IN _instance.c:
76 bool Instance_LocateModule(char * name, char * fileName);
77 void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, char *** argvPtr);
78 void * Instance_Module_Load(char * name, void ** Load, void ** Unload);
79 void Instance_Module_Free(void * library);
83 public class unichar : uint32
86 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
88 UTF32toUTF8Len(&this, 1, tempString, 5);
92 bool OnGetDataFromString(char * string)
95 this = UTF8GetChar(string, &nb);
101 public class Property : struct
108 AccessMode memberAccess;
111 char * dataTypeString;
125 bool selfWatchable, isWatchable;
128 dllexport void eInstance_FireWatchers(Instance instance, Property _property);
130 public dllexport void MemoryGuard_PushLoc(char * loc)
135 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
138 stack = (MemStack)calloc(1, sizeof(class MemStack));
139 stack.key = GetCurrentThreadID();
140 memStacks.Add(stack);
143 stack.frames[stack.pos++] = loc;
150 public dllexport void MemoryGuard_PopLoc()
155 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
156 if(stack && stack.pos > 0)
168 #ifdef ECERE_COM_ONLY
170 #define COM_LOAD_FUNCTION __ecereDll_Load_ecereCOM
171 #define COM_UNLOAD_FUNCTION __ecereDll_Unload_ecereCOM
175 #define COM_LOAD_FUNCTION __ecereDll_Load_ecere
176 #define COM_UNLOAD_FUNCTION __ecereDll_Unload_ecere
182 #define COM_LOAD_FUNCTION __ecereDll_Load
183 #define COM_UNLOAD_FUNCTION __ecereDll_Unload
189 extern bool stdcall COM_LOAD_FUNCTION(Module module);
190 extern void stdcall COM_UNLOAD_FUNCTION(Module module);
194 public class BTNamedLink : struct
199 BTNamedLink parent, left, right;
204 class SelfWatcher : struct
207 SelfWatcher prev, next;
208 void (*callback)(Instance);
212 public enum AccessMode
221 public class SubModule : struct
224 SubModule prev, next;
226 AccessMode importMode;
229 public enum DataMemberType { normalMember, unionMember, structMember };
231 public enum ClassType
239 unionClass, // Temporary only in firstPass
243 public class Class : struct
250 int offset, structSize;
253 int (*Constructor)(Instance);
254 void (*Destructor)(Instance);
256 int offsetClass, sizeClass;
261 OldList membersAndProperties;
262 BinaryTree classProperties;
264 int memberID, startMemberID;
267 NameSpace * nameSpace;
268 char * dataTypeString;
271 int defaultAlignment;
272 void (*Initialize)();
274 OldList selfWatchers;
275 char * designerClass;
277 char * defaultProperty;
278 bool comRedefinition;
280 int count; // DEBUGGING
287 int destructionWatchOffset;
289 OldList delayedCPValues;
290 AccessMode inheritanceAccess;
295 OldList templateParams;
296 ClassTemplateArgument * templateArgs;
306 Class theClass = eSystem_FindClass(__thisModule, value);
309 theClass = eSystem_FindClass(__thisModule.application, value);
315 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
320 bool OnGetDataFromString(char * string)
323 theClass = eSystem_FindClass(__thisModule, string);
325 theClass = eSystem_FindClass(__thisModule.application, string);
326 this = (void *)theClass;
327 return theClass != null;
330 void OnSerialize(IOChannel channel)
332 channel.Serialize(fullName);
340 void OnUnserialize(IOChannel channel)
344 channel.Unserialize(string);
345 theClass = eSystem_FindClass(__thisModule, string);
347 theClass = eSystem_FindClass(__thisModule.application, string);
349 this = (void *)theClass;
354 public enum TemplateParameterType { type, identifier, expression };
355 public enum TemplateMemberType { dataMember, method, prop };
357 public struct ClassTemplateArgument
365 char * dataTypeString;
370 DataValue expression;
386 public class ClassTemplateParameter : struct
390 ClassTemplateParameter prev, next;
392 TemplateParameterType type;
395 // Class baseClass; // For type
396 char * dataTypeString; // For expression
397 TemplateMemberType memberType; // For identifier
399 ClassTemplateArgument defaultArg;
400 void * param; // To attach to Compiler TemplateParameter
404 public class Module : struct
411 // So we can clean them up
420 void (stdcall * Unload)(Module module);
421 ImportType importType;
423 NameSpace privateNameSpace;
424 NameSpace publicNameSpace;
427 public class Application : Module
436 char * parsedCommand;
437 NameSpace systemNameSpace;
440 public enum MethodType { normalMethod, virtualMethod };
442 public class Method : struct
447 Method parent, left, right;
450 int vid; // For METHOD_VIRTUAL: Index into the class virtual table
454 char * dataTypeString;
456 AccessMode memberAccess;
459 public enum ImportType
465 // For internal usage in the compiler:
470 public struct NameSpace
473 NameSpace * btParent, * left, * right;
477 BinaryTree nameSpaces;
480 BinaryTree functions;
483 public union DataValue
498 public class DataMember : struct
502 DataMember prev, next;
505 AccessMode memberAccess;
508 char * dataTypeString;
516 BinaryTree membersAlpha;
521 public class BitMember : struct
525 BitMember prev, next;
528 AccessMode memberAccess;
531 char * dataTypeString;
541 public class ClassProperty : struct
546 ClassProperty parent, left, right;
548 void (*Set)(Class, int);
550 char * dataTypeString;
555 public class DefinedExpression : struct
559 DefinedExpression prev, next;
562 NameSpace * nameSpace;
565 public class GlobalFunction : struct
569 GlobalFunction prev, next;
573 NameSpace * nameSpace;
574 char * dataTypeString;
579 public class EnumClassData : struct
587 class Watcher : struct
591 void (*callback)(Instance, Instance);
596 static class MemInfo : BTNode //struct
602 MemInfo parent, left, right;
611 char * allocLoc[MAX_MEMORY_LOC];
612 char * freeLoc[MAX_MEMORY_LOC];
615 void OutputStacks(bool showFree)
620 printf("Object of class %s\n", _class);
621 printf(" Allocation Stack:\n");
622 for(c = 0; c<MAX_MEMORY_LOC; c++)
623 if(allocLoc[c] && allocLoc[c] != (void *)0xabababab)
624 printf(" %s\n", allocLoc[c]);
628 printf(" Free Location Stack:\n");
629 for(c = 0; c<MAX_MEMORY_LOC; c++)
631 printf(" %s\n", freeLoc[c]);
637 static BinaryTree memBlocks;
639 bool recurse = false;
641 //Class allocateClass;
642 char * allocateClass;
643 bool allocateInternal;
647 static uint TOTAL_MEM = 0;
648 static uint OUTSIDE_MEM = 0;
650 #if !defined(ECERE_BOOTSTRAP)
651 static Mutex memMutex { };
654 private class MemBlock : struct
661 private class MemPart : struct
670 #define NEXT_SIZE(s) NextFibonacci(s)
671 #define SIZE_POSITION(s) PosFibonacci(s)
672 #define NTH_SIZE(p) NthFibonacci(p)
674 static uint initNumBlocks[NUM_POOLS] =
710 #define NEXT_SIZE(s) pow2i(s)
711 #define SIZE_POSITION(s) log2i(s)
712 #define NTH_SIZE(p) (1<<p)
715 4000, // 1024, // 2 bytes
716 2500, // 1024, // 4 bytes
717 18000, //1024, // 8 bytes
718 20000, //1024, // 16 bytes
719 29000, //1024, // 32 bytes
720 46000, //1024, // 64 bytes
721 20000, //1024, // 128 bytes
722 26000, //512, // 256 bytes
723 1400, //256, // 512 bytes
727 static uint initNumBlocks[NUM_POOLS] =
753 #define NEXT_SIZE(s) pow1_5i(s)
754 #define SIZE_POSITION(s) log1_5i(s)
755 #define NTH_SIZE(p) pow1_5(p)
757 static int power15[] =
830 private struct BlockPool
832 MemBlock first, last;
842 bool Expand(uint numBlocks)
844 byte * memory = malloc(numBlocks * blockSpace);
845 // byte * memory = calloc(1, numBlocks * blockSpace);
846 TOTAL_MEM += numBlocks * blockSpace;
848 /*if(blockSize == 28)
849 printf("Expanding pool %x (%d)\n", this, blockSize);*/
855 uint totalAvailable = 0, totalAllocated = 0, totalBlocks = 0, totalUsed = 0;
858 MemBlock block = (MemBlock)memory;
859 MemPart part = calloc(1, sizeof(class MemPart));
860 TOTAL_MEM += sizeof(class MemPart);
862 for(c = 0; c<numBlocks - 1; c++)
864 // block.pool = this;
867 printf("WARNING! part.size < 0\n");*/
869 block.next = (MemBlock)((byte *)block + blockSpace);
874 part.memory = memory;
875 part.size = numBlocks;
877 // block.pool = this;
880 printf("/! part.size < 0\n");
881 if(part.pool == (void*) -1)
882 printf("WARNING! pool is -1\n");*/
886 /*if(free && free.part && (free.part.size < 0 || free.part.pool == (void *)-1))
887 printf("WARNING! Bad next free block!\n");*/
889 //parts = realloc(parts, sizeof(MemPart) * (numParts + 1));
891 totalSize += numBlocks;
896 for(c = 0; c<NUM_POOLS; c++)
898 BlockPool * pool = &pools[c];
899 printf("[%d %s (%d)]: available: %d, allocated: %d, free: %d, used: %d k, wasted: %d k, free: %d k\n", c, (&pools[c] == this) ? "*" : " ",
900 pools[c].blockSize, pools[c].totalSize, pools[c].numBlocks,
901 pools[c].totalSize - pools[c].numBlocks, pools[c].usedSpace / 1024, ((pools[c].numBlocks * pools[c].blockSize) - pools[c].usedSpace) / 1024,
902 (pools[c].totalSize - pools[c].numBlocks) * pools[c].blockSize / 1024);
903 totalAvailable += pools[c].totalSize * pools[c].blockSize;
904 totalAllocated += pools[c].numBlocks * pools[c].blockSize;
905 totalUsed += pools[c].usedSpace;
906 totalBlocks += pools[c].totalSize;
907 totalParts += pools[c].numParts;
909 printf("Total Available %d k, Total Allocated: %d k, Total Free: %d k\n", totalAvailable / 1024, totalAllocated / 1024, (totalAvailable - totalAllocated) / 1024);
910 printf("Total Number of Blocks %d, overhead of %d k\n", totalBlocks, totalBlocks * sizeof(class MemBlock) / 1024);
911 printf("Total Used Space %d k, wasted from roundup: %d k\n", totalUsed / 1024, (totalAllocated - totalUsed) / 1024);
912 printf("Total Memory Parts: %d\n", totalParts);
913 printf("TOTAL_MEM: %d k, OUTSIDE_MEM: %d k, BLOCKS: %d k\n", TOTAL_MEM / 1024, OUTSIDE_MEM / 1024, (totalAvailable + totalBlocks * sizeof(class MemBlock)) / 1024);
927 MemBlock block = null;
928 /*if(blockSize == 28)
929 printf("BlockPool::Add (%d)\n", blockSize);*/
931 Expand(Max(1, numBlocks / 2));
937 block.prev.next = block;
942 /*if(blockSize == 28)
943 printf("Free: %x, free.part: %x, free.part.size: %d, free.part.pool: %x (this = %x), next = %x (part = %x)\n", free, free ? free.part : null,
944 (free && free.part) ? free.part.size : 0, (free && free.part) ? free.part.pool : 0, this,
945 (free ? free.next : 0), (free && free.next) ? free.next.part : 0);
946 if(free && free.part && (free.part.size < 0 || free.part.pool == (void *)-1))
947 printf("WARNING! Bad next free block!\n");*/
951 block.part.blocksUsed++;
961 void Remove(MemBlock block)
963 /*if(blockSize == 28)
964 printf("BlockPool::Remove (%d)\n", blockSize);*/
966 block.prev.next = block.next;
968 block.next.prev = block.prev;
975 // block.prev = null;
979 /*if(blockSize == 28)
981 printf("Setting new free block: part = %x\n", block.part);
984 block.part.blocksUsed--;
986 block.part.pool->usedSpace -= block.size;
988 if(!block.part.blocksUsed && numBlocks && totalSize > numBlocks + numBlocks / 2)
990 MemBlock next = free, prev = null;
991 MemPart part = block.part;
993 totalSize -= part.size;
994 /*if(blockSize == 28)
995 printf("Freeing a part\n");*/
998 if(next.part != part)
1011 TOTAL_MEM -= part.size * blockSpace;
1012 TOTAL_MEM -= sizeof(class MemPart);
1015 ::free(part.memory);
1018 /*if(free && free.part && (free.part.size < 0 || free.part.pool == (void *)-1))
1019 printf("WARNING! Bad next free block!\n");*/
1023 static BlockPool * pools; //[NUM_POOLS];
1025 static uint PosFibonacci(uint number)
1028 uint last = 1, prev = 0;
1036 if(current >= number)
1042 static uint NthFibonacci(uint number)
1045 uint last = 1, prev = 0;
1048 for(pos=0; pos <= number; pos++)
1057 static uint NextFibonacci(uint number)
1060 uint last = 1, prev = 0;
1068 if(current >= number)
1073 static uint log1_5i(uint number)
1078 for(pos=0; pos < NUM_POOLS; pos++)
1080 if(current >= number)
1082 current = current * 3 / 2;
1083 if(current == 1) current = 2;
1088 static uint pow1_5(uint number)
1092 for(pos=0; pos < number; pos++)
1094 current = current * 3 / 2;
1095 if(current == 1) current = 2;
1097 return (uint)current;
1100 static uint pow1_5i(uint number)
1105 for(pos=0; pos < NUM_POOLS; pos++)
1107 if(current >= number)
1108 return (uint)current;
1109 current = current * 3 / 2;
1110 if(current == 1) current = 2;
1112 return (uint)current;
1115 // -- Math Helpers ---
1116 public uint log2i(uint number)
1120 for(power=0; power<32; power++)
1121 if((1L<<power) >= number)
1126 public uint pow2i(uint number)
1128 return 1<<log2i(number);
1131 static bool memoryInitialized = false;
1132 static void InitMemory()
1135 memoryInitialized = true;
1136 pools = calloc(1, sizeof(BlockPool) * NUM_POOLS);
1137 for(c = 0; c<NUM_POOLS; c++)
1141 pools[c].blockSize = NTH_SIZE(c);
1142 if(pools[c].blockSize % 4)
1143 pools[c].blockSize += 4 - (pools[c].blockSize % 4);
1144 pools[c].blockSpace = pools[c].blockSize;
1145 pools[c].blockSpace += sizeof(class MemBlock);
1146 // pools[c].Expand(initNumBlocks[c]);
1148 expansion = (pools[c].blockSize < 128) ? 1024 : (131072 / pools[c].blockSize);
1151 pools[c].Expand(Max(1, expansion));
1155 static void * _mymalloc(unsigned int size)
1157 MemBlock block = null;
1160 unsigned int p = SIZE_POSITION(size);
1161 if(!memoryInitialized) InitMemory();
1164 block = pools[p].Add();
1168 pools[p].usedSpace += size;
1173 block = malloc(sizeof(class MemBlock) + size);
1176 TOTAL_MEM += sizeof(class MemBlock) + size;
1177 OUTSIDE_MEM += sizeof(class MemBlock) + size;
1182 return block ? ((struct MemBlock *)block + 1) : null;
1185 static void * _mycalloc(int n, unsigned int size)
1187 void * pointer = _mymalloc(size);
1189 memset(pointer, 0, size);
1193 static void _myfree(void * pointer)
1197 MemBlock block = (MemBlock)((byte *)pointer - sizeof(class MemBlock));
1198 MemPart part = block.part;
1199 BlockPool * pool = part ? part.pool : null; //block.pool;
1200 /*if(pool == (void*) -1)
1201 printf("WARNING! pool is -1\n");
1204 pool->Remove(block);
1207 TOTAL_MEM -= sizeof(class MemBlock) + block.size;
1208 OUTSIDE_MEM -= sizeof(class MemBlock) + block.size;
1214 static void * _myrealloc(void * pointer, unsigned int size)
1216 MemBlock block = pointer ? ((MemBlock)((byte *)pointer - sizeof(class MemBlock))) : null;
1217 void * newPointer = null;
1218 MemPart part = block ? block.part : null;
1219 BlockPool * pool = part ? part.pool : null;
1222 /*if(pool == (void*) -1)
1223 printf("WARNING! pool is -1\n");
1227 // if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
1228 if(NEXT_SIZE(size) == pool->blockSize)
1230 newPointer = pointer;
1231 pool->usedSpace += size - block.size;
1237 MemBlock newBlock = realloc(block, sizeof(class MemBlock) + size);
1240 TOTAL_MEM += size - newBlock.size;
1241 OUTSIDE_MEM += size - newBlock.size;
1242 newPointer = ((struct MemBlock *)newBlock + 1);
1248 newPointer = _mymalloc(size);
1249 if(pointer && newPointer)
1251 memcpy(newPointer, pointer, Min(size, block.size));
1258 static void * _mycrealloc(void * pointer, unsigned int size)
1260 MemBlock block = pointer ? ((MemBlock)((byte *)pointer - sizeof(class MemBlock))) : null;
1261 void * newPointer = null;
1262 MemPart part = block ? block.part : null;
1263 BlockPool * pool = part ? part.pool : null;
1266 /*if(pool == (void*) -1)
1267 printf("WARNING! pool is -1\n");
1272 // if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
1273 if(NEXT_SIZE(size) == pool->blockSize)
1275 int extra = size - block.size;
1276 newPointer = pointer;
1277 pool->usedSpace += extra;
1279 memset((byte *)pointer + block.size, 0, extra);
1285 MemBlock newBlock = realloc(block, sizeof(class MemBlock) + size);
1288 int extra = size - newBlock.size;
1290 OUTSIDE_MEM += extra;
1291 newPointer = ((struct MemBlock *)newBlock + 1);
1293 memset((byte *)newPointer + newBlock.size, 0, extra);
1294 newBlock.size = size;
1300 newPointer = _mymalloc(size);
1305 memcpy(newPointer, pointer, Min(size, block.size));
1306 if(size > block.size)
1307 memset((byte *)newPointer + block.size, 0, size - block.size);
1311 memset((byte *)newPointer, 0, size);
1324 #define realloc _myrealloc
1325 #define crealloc _mycrealloc
1326 #define malloc _mymalloc
1327 #define free _myfree
1328 #define calloc _mycalloc
1331 static void * _malloc(unsigned int size)
1335 #if !defined(ECERE_BOOTSTRAP)
1339 pointer = malloc(size + 2 * REDZONE);
1343 MemStack stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1346 stack = (MemStack)calloc(1, sizeof(class MemStack));
1347 stack.key = GetCurrentThreadID();
1348 memStacks.Add(stack);
1354 printf("Memory allocation of %d bytes failed\n", size);
1355 printf("Current Stack:\n");
1356 for(c = 0; c<stack.pos; c++)
1358 printf(" %s\n", stack.frames[c]);
1360 memoryErrorsCount++;
1365 if(!recurse && !stack.recurse)
1367 stack.recurse = true;
1368 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
1369 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1370 memBlocks.Add(block);
1371 stack.recurse = false;
1376 #if !defined(ECERE_BOOTSTRAP)
1381 memset(pointer, 0xEC, REDZONE);
1382 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1383 // ((byte *)pointer)[0] = 0x00;
1385 return (byte*)pointer + REDZONE;
1388 static void * _calloc(int n, unsigned int size)
1391 #if !defined(ECERE_BOOTSTRAP)
1395 pointer = calloc(n, size + 2 * REDZONE);
1399 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1402 stack = (MemStack)calloc(1, sizeof(class MemStack));
1403 stack.key = GetCurrentThreadID();
1404 memStacks.Add(stack);
1409 printf("Memory allocation of %d bytes failed\n", size);
1410 printf("Current Stack:\n");
1411 for(c = 0; c<stack.pos; c++)
1413 printf(" %s\n", stack.frames[c]);
1414 memoryErrorsCount++;
1419 if(!recurse && !stack.recurse)
1423 stack.recurse = true;
1424 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), _class = allocateClass, internal = allocateInternal, id = blockID++ };
1425 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1426 memBlocks.Add(block);
1427 stack.recurse = false;
1432 #if !defined(ECERE_BOOTSTRAP)
1437 memset(pointer, 0xEC, REDZONE);
1438 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1440 return (byte*)pointer + REDZONE;
1443 static void * _realloc(void * pointer, unsigned int size)
1445 if(!size) { _free(pointer); return null; }
1446 #if !defined(ECERE_BOOTSTRAP)
1452 MemInfo block = null;
1454 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1457 stack = (MemStack)calloc(1, sizeof(class MemStack));
1458 stack.key = GetCurrentThreadID();
1459 memStacks.Add(stack);
1462 if(!recurse && !stack.recurse && pointer)
1464 block = (MemInfo)memBlocks.Find((uint)pointer);
1467 printf("Reallocating Bad Memory\n");
1468 memoryErrorsCount++;
1470 else if(block.freed)
1472 printf("Reallocating Freed Memory\n");
1473 memoryErrorsCount++;
1474 block.OutputStacks(true);
1478 pointer = malloc(size + REDZONE * 2);
1482 printf("Memory allocation of %d bytes failed\n", size);
1483 printf("Current Stack:\n");
1484 for(c = 0; c<stack.pos; c++)
1486 printf(" %s\n", stack.frames[c]);
1487 memoryErrorsCount++;
1491 memset(pointer, 0xEC, REDZONE);
1492 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1498 memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
1502 memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1503 memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
1504 block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
1505 memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
1506 memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
1511 if(!recurse && !stack.recurse)
1514 stack.recurse = true;
1515 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
1516 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1517 memBlocks.Add(block);
1518 stack.recurse = false;
1522 pointer = realloc(pointer, size);
1525 #if !defined(ECERE_BOOTSTRAP)
1528 return (byte *)pointer + REDZONE;
1531 static void * _crealloc(void * pointer, unsigned int size)
1533 if(!size) return null;
1534 #if !defined(ECERE_BOOTSTRAP)
1540 MemInfo block = null;
1542 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1545 stack = (MemStack)calloc(1, sizeof(class MemStack));
1546 stack.key = GetCurrentThreadID();
1547 memStacks.Add(stack);
1550 if(!recurse && !stack.recurse && pointer)
1552 block = (MemInfo)memBlocks.Find((uint)pointer);
1555 printf("Reallocating Bad Memory\n");
1556 memoryErrorsCount++;
1558 else if(block.freed)
1560 printf("Reallocating Freed Memory\n");
1561 memoryErrorsCount++;
1562 block.OutputStacks(true);
1566 pointer = calloc(1, size + REDZONE * 2);
1570 printf("Memory allocation of %d bytes failed\n", size);
1571 printf("Current Stack:\n");
1572 for(c = 0; c<stack.pos; c++)
1574 printf(" %s\n", stack.frames[c]);
1575 memoryErrorsCount++;
1579 memset(pointer, 0xEC, REDZONE);
1580 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1586 memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
1590 memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1591 memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
1592 block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
1593 memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
1594 memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
1599 if(!recurse && !stack.recurse)
1602 stack.recurse = true;
1603 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
1604 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1605 memBlocks.Add(block);
1606 stack.recurse = false;
1610 pointer = crealloc(pointer, size);
1613 #if !defined(ECERE_BOOTSTRAP)
1616 return (byte *)pointer + REDZONE;
1619 static void _free(void * pointer)
1623 #if !defined(ECERE_BOOTSTRAP)
1624 if(memMutex != pointer) memMutex.Wait();
1631 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1634 stack = (MemStack)calloc(1, sizeof(class MemStack));
1635 stack.key = GetCurrentThreadID();
1636 memStacks.Add(stack);
1639 if(!recurse && !stack.recurse)
1642 stack.recurse = true;
1643 block = (MemInfo)memBlocks.Find((uint)pointer);
1647 printf("Freeing Bad Memory\n");
1648 printf("Current Stack:\n");
1649 for(c = 0; c<stack.pos; c++)
1651 printf(" %s\n", stack.frames[c]);
1653 memoryErrorsCount++;
1655 else if(block.freed)
1658 printf("Freeing Already Freed Memory\n");
1659 printf("Current Stack:\n");
1660 for(c = 0; c<stack.pos; c++)
1662 printf(" %s\n", stack.frames[c]);
1664 memoryErrorsCount++;
1665 block.OutputStacks(true);
1670 byte * address = (byte *)block.key;
1671 for(c = 0; c<REDZONE; c++)
1673 if(address[-c-1] != 0xEC)
1675 printf("Buffer Underrun\n");
1676 memoryErrorsCount++;
1677 block.OutputStacks(block.freed);
1679 if(address[c + block.size] != 0xEC)
1681 printf("Buffer Overrun\n");
1682 memoryErrorsCount++;
1683 block.OutputStacks(block.freed);
1690 int size = block.size;
1691 address = (byte *)block.key;
1692 for(c = 0; c<REDZONE; c++)
1694 if(address[-c-1] != 0xEC)
1696 printf("Buffer Underrun\n");
1697 memoryErrorsCount++;
1698 block.OutputStacks(block.freed);
1700 if(address[c + size] != 0xEC)
1702 printf("Buffer Overrun\n");
1703 memoryErrorsCount++;
1704 block.OutputStacks(block.freed);
1710 block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
1711 memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + REDZONE * 2);
1712 memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
1714 memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1716 stack.recurse = false;
1723 #if !defined(ECERE_BOOTSTRAP)
1724 if(memMutex != pointer) memMutex.Release();
1729 public void memswap(byte * a, byte * b, uint size)
1735 int s = sizeof(buffer);
1736 if(c + s > size) s = size - c;
1737 memcpy(buffer, a + c, s);
1738 memcpy(a + c, b + c, s);
1739 memcpy(b + c, buffer, s);
1744 public void CheckMemory()
1748 uint leaksCount = 0;
1749 uint leakedObjects = 0;
1752 // Verify Tree Integrity
1753 if(!memBlocks.Check())
1755 printf("Memory Blocks Tree Integrity Failed\n");
1756 memoryErrorsCount++;
1758 printf("Starting Memory Check\n");
1759 for(block = (MemInfo)memBlocks.root; block;)
1762 memswap((byte *)block.key - REDZONE, block.oldmem - REDZONE, block.size + REDZONE * 2);
1768 // if(!block.internal)
1770 // printf("Object of class %s\n", block._class);
1771 block.OutputStacks(false);
1776 printf("Memory Leak\n");
1777 block.OutputStacks(false);
1781 leaksSize += block.size;
1785 block = (MemInfo)block.left;
1786 else if(block.right)
1787 block = (MemInfo)block.right;
1792 MemInfo parent = (MemInfo)block.parent;
1793 if(parent && block == (MemInfo)parent.left && parent.right)
1795 block = (MemInfo)parent.right;
1803 while(block = (MemInfo)memBlocks.root)
1807 int size = block.size;
1810 address = block.oldmem;
1811 for(c = -REDZONE; c<size + REDZONE; c++)
1812 if(address[c] != 0xEC)
1816 if(c < size + REDZONE)
1818 printf("Freed Memory Write\n");
1819 memoryErrorsCount++;
1820 block.OutputStacks(true);
1824 address = (byte *)block.key;
1825 for(c = 0; c<REDZONE; c++)
1827 if(address[-c-1] != 0xEC)
1829 printf("Buffer Underrun\n");
1830 memoryErrorsCount++;
1831 block.OutputStacks(block.freed);
1833 if(address[c + size] != 0xEC)
1835 printf("Buffer Overrun\n");
1836 memoryErrorsCount++;
1837 block.OutputStacks(block.freed);
1841 memBlocks.Delete(block);
1845 printf("%d Memory Leaks Detected (%d objects, %d bytes).\n", leaksCount, leakedObjects, leaksSize);
1846 memoryErrorsCount++;
1848 printf("Memory Check Completed.\n");
1849 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
1850 if(memoryErrorsCount)
1856 static void FixDerivativesBase(Class base, Class mod)
1859 OldLink templateLink;
1861 ComputeClassParameters(base, strchr(base.name, '<'), null);
1863 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
1865 Class _class = derivative.data;
1866 ClassType type = _class.type;
1867 int size = _class.structSize - _class.offset;
1868 int oldSizeClass = _class.sizeClass;
1869 int sizeClass = _class.sizeClass - _class.offsetClass;
1870 Class enumBase = null;
1871 char * dataTypeString = null;
1873 uint offsetBefore = _class.offset;
1875 int offsetClass, totalSizeClass;
1877 for(baseClass = base; baseClass.base; baseClass = baseClass.base);
1879 if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass)) type = base.type;
1881 if(type == enumClass)
1883 if(base.type != enumClass)
1886 base = eSystem_FindClass(_class.module, "enum");
1890 dataTypeString = enumBase ? enumBase.dataTypeString : base.dataTypeString;
1892 /////////////////////
1894 offsetClass = base ? (base.templateClass ? base.templateClass.sizeClass : base.sizeClass) : (type == noHeadClass ? 0 : 0 /*sizeof(class Class)*/);
1895 totalSizeClass = offsetClass + sizeClass;
1897 // TESTING WITHOUT THIS... Seems to yield better results, as it otherwise prevents ComputeClassMembers from doing its job on derived classes
1899 // _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
1901 if(type == normalClass || type == noHeadClass)
1902 _class.offset = (base && (base.templateClass ? base.templateClass.structSize : base.structSize) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : ((type == noHeadClass) ? 0 : sizeof(class Instance));
1904 if(type == structClass)
1906 _class.memberOffset = (base && (base.templateClass ? base.templateClass.structSize : base.structSize) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : 0;
1908 _class.typeSize = _class.structSize = _class.memberOffset + size;
1910 else if(type == bitClass || type == enumClass || type == unitClass)
1912 Class dataTypeClass = eSystem_FindClass(_class.module, dataTypeString);
1914 _class.typeSize = dataTypeClass.typeSize;
1915 _class.structSize = 0;
1917 else if(type == normalClass || type == noHeadClass)
1919 _class.structSize = _class.offset + size;
1920 _class.typeSize = sizeof(void *);
1923 /////////////////////
1925 if(_class.type != systemClass)
1927 delete _class.dataTypeString;
1928 _class.dataTypeString = CopyString(dataTypeString);
1930 if(totalSizeClass != oldSizeClass)
1932 _class.data = renew _class.data byte[totalSizeClass];
1934 memmove((byte *)_class.data + offsetClass, (byte *)_class.data + _class.offsetClass, _class.sizeClass - _class.offsetClass);
1935 if(base.type != systemClass && base.type != enumClass)
1936 memcpy((byte *)_class.data + _class.offsetClass, (byte *)base.data + _class.offsetClass, totalSizeClass - _class.sizeClass);
1938 memset((byte *)_class.data + _class.offsetClass, 0, totalSizeClass - _class.sizeClass);
1940 memmove((byte *)_class.data + mod.offsetClass, (byte *)_class.data, totalSizeClass - mod.sizeClass);
1941 if(base.type != systemClass && base.type != enumClass)
1942 memcpy((byte *)_class.data, (byte *)base.data, totalSizeClass - _class.sizeClass);
1944 memset((byte *)_class.data, 0, totalSizeClass - _class.sizeClass);
1947 _class.offsetClass = offsetClass;
1948 _class.sizeClass = totalSizeClass;
1950 if(mod.base && mod.base.base && mod.base.vTblSize > baseClass.vTblSize &&
1951 (mod != (base.templateClass ? base.templateClass : base) || _class.vTblSize != mod.vTblSize))
1953 Method method, next;
1955 _class.vTblSize += mod.base.vTblSize - baseClass.vTblSize;
1956 _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
1957 // memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (mod.base.vTblSize - baseClass.vTblSize) * sizeof(void *));
1958 memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (_class.vTblSize - mod.vTblSize) * sizeof(void *));
1960 for(method = (Method)_class.methods.first; method; method = next)
1962 next = (Method)((BTNode)method).next;
1963 if(method.type == virtualMethod)
1964 method.vid += mod.base.vTblSize - baseClass.vTblSize;
1967 // TO CHECK: WHY WAS THIS baseClass? ANY PROBLEMS? CRASH WHEN DECLARING A BASE CLASS LATER (WSMS)
1968 for(b = mod.base; b && b != null; b = b.base)
1971 for(vMethod = (Method)b.methods.first; vMethod; vMethod = (Method)((BTNode)vMethod).next)
1973 if(vMethod.type == virtualMethod)
1975 method = (Method)_class.methods.FindString(vMethod.name);
1978 if(method.function) _class._vTbl[vMethod.vid] = method.function;
1982 delete method.dataTypeString;
1983 _class.methods.Delete((BTNode)method);
1987 delete method.dataTypeString;
1988 method.type = vMethod.type;
1989 method.dataTypeString = CopyString(vMethod.dataTypeString);
1990 method._class = vMethod._class;
1994 _class._vTbl[vMethod.vid] = _class.base._vTbl[vMethod.vid];
2000 // _class.defaultAlignment = base ? base.defaultAlignment : 0;
2002 if(type == normalClass || type == noHeadClass || type == structClass)
2007 for(c = mod.base; c; c = c.base)
2010 for(_property = c.membersAndProperties.first; _property; _property = _property.next)
2012 if(_property.isProperty)
2014 BTNamedLink link = (BTNamedLink)_class.prop.FindString(_property.name);
2018 if(!prop.Set && !prop.Get && prop.memberAccess == baseSystemAccess)
2020 SelfWatcher watcher;
2021 for(watcher = _class.selfWatchers.first; watcher; watcher = watcher.next)
2023 if(watcher._property == prop)
2024 watcher._property = _property;
2026 _property.selfWatchable = true;
2027 _class.prop.Delete((BTNode)link);
2029 delete prop.dataTypeString;
2030 _class.membersAndProperties.Delete(prop); // Remove only was done before?
2036 // if(mod.base.memberID)
2038 for(member = _class.membersAndProperties.first; member; member = member.next)
2040 int offsetDiff = _class.offset - offsetBefore;
2041 if(!member.isProperty && offsetDiff > 0)
2043 member.offset += offsetDiff;
2044 member.memberOffset += offsetDiff;
2046 member.id += mod.base.memberID;
2049 _class.memberID += mod.base.memberID;
2050 _class.startMemberID += mod.base.memberID;
2053 // Moved this before to ensure CPValues have their data ready
2054 FixDerivativesBase(_class, mod);
2057 for(c = mod.base; c; c = c.base)
2059 ClassProperty _property;
2060 for(_property = (ClassProperty)c.classProperties.first; _property; _property = (ClassProperty)((BTNode)_property).next)
2062 SetDelayedCPValues(_class, _property);
2069 OldLink templateLink;
2070 for(templateLink = base.templatized.first; templateLink; templateLink = templateLink.next)
2072 Class template = templateLink.data;
2073 char * templateParams = strchr(template.name, '<');
2074 template.base = base.base;
2075 template._vTbl = base._vTbl;
2076 //ComputeClassParameters(template, templateParams, null);
2078 template.data = base.data;
2079 template.offset = base.offset;
2080 template.offsetClass = base.offsetClass;
2081 template.sizeClass = base.sizeClass;
2082 template.structSize = base.structSize;
2083 template.vTblSize = base.vTblSize;
2085 FixDerivativesBase(template, mod);
2090 public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char * baseName, int size, int sizeClass,
2091 bool (* Constructor)(void *),void (* Destructor)(void *),
2092 Module module, AccessMode declMode, AccessMode inheritanceAccess)
2095 NameSpace * nameSpace = null;
2098 nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
2099 if(declMode == baseSystemAccess) nameSpace = &module.application.systemNameSpace;
2101 // if(declMode != staticAccess)
2103 for(c = 0; name[c]; c++)
2105 if(name[c] == '.' || (name[c] == ':' && name[c+1] == ':'))
2107 NameSpace * newSpace;
2109 char * spaceName = _malloc(c - start + 1);
2110 strncpy(spaceName, name + start, c - start);
2111 spaceName[c-start] = '\0';
2113 newSpace = (NameSpace *)nameSpace->nameSpaces.FindString(spaceName);
2116 newSpace = new0 NameSpace[1];
2117 newSpace->classes.CompareKey = (void *)BinaryTree::CompareString;
2118 newSpace->defines.CompareKey = (void *)BinaryTree::CompareString;
2119 newSpace->functions.CompareKey = (void *)BinaryTree::CompareString;
2120 newSpace->nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
2121 newSpace->name = spaceName;
2122 newSpace->parent = nameSpace;
2123 nameSpace->nameSpaces.Add((BTNode)newSpace);
2127 nameSpace = newSpace;
2128 if(name[c] == ':') c++;
2141 BTNamedLink classLink = null;
2142 Class _class = null;
2143 char * dataTypeString = null;
2144 Class enumBase = null;
2145 Class base = (baseName && baseName[0]) ? eSystem_FindClass(module, baseName) : null;
2146 bool refine = false;
2148 if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass))
2150 // Normal classes inheriting off simple classes should become no head classes
2151 if(base.type == structClass && type == normalClass)
2156 if(base && (type == normalClass || type == noHeadClass || type == structClass) &&
2157 (base.type == unitClass || base.type == bitClass || base.type == enumClass))
2161 if(!base || base.type == systemClass)
2163 if(type == enumClass)
2166 if(base || !baseName || !baseName[0] ||
2167 !strcmp(baseName, "unsigned int") ||
2168 !strcmp(baseName, "uint") ||
2169 !strcmp(baseName, "unsigned int64") ||
2170 !strcmp(baseName, "uint64") ||
2171 !strcmp(baseName, "int64") ||
2172 !strcmp(baseName, "unsigned short") ||
2173 !strcmp(baseName, "short") ||
2174 !strcmp(baseName, "unsigned char") ||
2175 !strcmp(baseName, "byte") ||
2176 !strcmp(baseName, "char") ||
2177 !strcmp(baseName, "uint32") ||
2178 !strcmp(baseName, "uint16"))
2180 base = eSystem_FindClass(module, "enum");
2181 dataTypeString = (baseName && baseName[0]) ? baseName : "int"; //"unsigned int";
2186 base = eSystem_RegisterClass(0, baseName, null, 0,0, null, null, module, declMode, publicAccess);
2187 base.internalDecl = true;
2190 base = eSystem_FindClass(module, "enum");
2191 //dataTypeString = (baseName && baseName[0]) ? baseName : "unsigned int";
2194 else if(type == structClass && (!baseName || !baseName[0]))
2196 base = eSystem_FindClass(module, "struct");
2197 dataTypeString = name + start;
2201 if(type == normalClass)
2202 // dataTypeString = "struct Instance";
2203 dataTypeString = "struct __ecereNameSpace__ecere__com__Instance";
2204 else if(type == noHeadClass)
2205 dataTypeString = "void *";
2206 else if(type == bitClass)
2207 dataTypeString = (baseName && baseName[0]) ? baseName : "unsigned int";
2208 else if(type == unitClass)
2209 dataTypeString = (baseName && baseName[0]) ? baseName : "int";
2210 else if(type == structClass)
2211 dataTypeString = name + start;
2213 // TODO: base bit, unit or enum classes not defined yet
2214 if(base || (!baseName || !baseName[0]) || type == bitClass || type == unitClass)
2216 // DANGEROUSLY TESTING THIS... PUT IT BACK
2218 if(base || !baseName || !baseName[0] ||
2219 !strcmp(baseName, "unsigned int") ||
2220 !strcmp(baseName, "uint") ||
2221 !strcmp(baseName, "unsigned int64") ||
2222 !strcmp(baseName, "uint64") ||
2223 !strcmp(baseName, "int64") ||
2224 !strcmp(baseName, "unsigned short") ||
2225 !strcmp(baseName, "short") ||
2226 !strcmp(baseName, "unsigned char") ||
2227 !strcmp(baseName, "byte") ||
2228 !strcmp(baseName, "char") ||
2229 !strcmp(baseName, "uint32") ||
2230 !strcmp(baseName, "uint16"))
2232 if(type == normalClass && strcmp(name, "ecere::com::Instance") && strcmp(name, "enum") && strcmp(name, "struct"))
2233 base = eSystem_FindClass(module, "ecere::com::Instance");
2235 base = eSystem_FindClass(module, "class");
2240 // Base class has not been defined yet!
2246 if(type == enumClass)
2248 if(base.type != enumClass)
2251 base = eSystem_FindClass(module, "enum");
2254 dataTypeString = enumBase ? enumBase.dataTypeString : base.dataTypeString;
2257 offsetClass = base ? base.sizeClass : (type == noHeadClass ? 0 : 0 /*sizeof(class Class)*/);
2258 totalSizeClass = offsetClass + sizeClass;
2260 if((_class = eSystem_FindClass(module, name)))
2262 FreeTemplatesDerivatives(_class);
2264 if(!_class.internalDecl)
2266 if(declMode != baseSystemAccess)
2267 printf("error: Redefinition of class %s\n", name);
2270 _class.comRedefinition = true;
2276 classLink = (BTNamedLink)_class.nameSpace->classes.FindString(name + start);
2277 _class.nameSpace->classes.Delete((BTNode)classLink);
2280 for(t = _class.templatized.first; t; t = t.next)
2282 Class template = t.data;
2283 classLink = (BTNamedLink)_class.nameSpace->classes.FindString(template.name);
2285 _class.nameSpace->classes.Delete((BTNode)classLink);
2289 NameSpace * ns = _class.nameSpace;
2291 !ns->classes.first &&
2292 !ns->functions.first &&
2293 !ns->defines.first &&
2294 !ns->nameSpaces.first)
2296 NameSpace * parent = ns->parent;
2298 parent->nameSpaces.Delete((BTNode)ns);
2306 classLink = SearchNameSpace(module.application.privateNameSpace, name, &((NameSpace *)0)->classes);
2308 classLink = SearchNameSpace(module.application.publicNameSpace, name, &((NameSpace *)0)->classes);
2311 classLink = SearchNameSpace(module.application.privateNameSpace, name + start, &((NameSpace *)0)->classes);
2313 classLink = SearchNameSpace(module.application.publicNameSpace, name + start, &((NameSpace *)0)->classes);
2316 _class = classLink.data;
2317 if(_class && _class.internalDecl)
2319 FreeTemplatesDerivatives(_class);
2321 _class.nameSpace->classes.Delete((BTNode)classLink);
2324 for(t = _class.templatized.first; t; t = t.next)
2326 Class template = t.data;
2327 classLink = (BTNamedLink)_class.nameSpace->classes.FindString(template.name);
2328 _class.nameSpace->classes.Delete((BTNode)classLink);
2334 delete _class.fullName;
2335 _class.fullName = CopyString(name);
2339 _class = _calloc(1, sizeof(class Class));
2340 _class.methods.CompareKey = (void *)BinaryTree::CompareString;
2341 _class.members.CompareKey = (void *)BinaryTree::CompareString;
2342 _class.prop.CompareKey = (void *)BinaryTree::CompareString;
2343 _class.classProperties.CompareKey = (void *)BinaryTree::CompareString;
2345 _class.name = CopyString(name + start);
2346 _class.fullName = CopyString(name);
2351 nameSpace->classes.Add((BTNode)BTNamedLink { name = _class.name, data = _class });
2354 for(t = _class.templatized.first; t; t = t.next)
2356 Class template = t.data;
2357 nameSpace->classes.Add((BTNode)BTNamedLink { name = template.name, data = template });
2365 if(!base && baseName && strcmp(baseName, name))
2368 if(strchr(baseName, '<'))
2370 char templateClassName[1024];
2372 strcpy(templateClassName, baseName);
2373 *strchr(templateClassName, '<') = '\0';
2374 templateBase = eSystem_FindClass(module, templateClassName);
2377 templateBase = eSystem_RegisterClass(0, templateClassName, null, 0,0, null, null, module, declMode, publicAccess);
2378 templateBase.internalDecl = true;
2380 base = eSystem_FindClass(module, baseName);
2384 base = eSystem_RegisterClass(0, baseName, null, 0,0, null, null, module, declMode, publicAccess);
2385 base.internalDecl = true;
2390 base.memberOffset = 0;
2394 _class.internalDecl = false;
2398 _class.data = renew _class.data byte[totalSizeClass];
2399 // memset(_class.data, 0, totalSizeClass);
2400 if(base && base.type != systemClass && base.type != enumClass)
2401 memcpy(_class.data, base.data, offsetClass);
2403 memset(_class.data, 0, offsetClass);
2404 memset((byte *)_class.data + offsetClass, 0, sizeClass);
2407 delete _class.dataTypeString;
2408 _class.dataTypeString = CopyString(dataTypeString);
2409 _class.defaultAlignment = base ? base.defaultAlignment : 0;
2411 // Dereference the class in previous module the classed belonged to
2414 _class.module.classes.Remove(_class);
2419 //Class base = _class.base.templateClass ? _class.base.templateClass : _class.base;
2420 Class base = _class.base;
2421 OldLink deriv = base.derivatives.FindLink(_class);
2422 base.derivatives.Delete(deriv);
2425 // Reference the class in the module
2428 module.classes.Add(_class);
2431 _class.nameSpace = nameSpace;
2434 for(t = _class.templatized.first; t; t = t.next)
2436 Class template = t.data;
2437 template.nameSpace = nameSpace;
2441 _class.module = module;
2447 for(sClass = base; sClass; sClass = sClass.base)
2449 if(sClass.templateClass) sClass = sClass.templateClass;
2450 numParams += sClass.templateParams.count;
2454 if(_class.templateArgs)
2456 FreeTemplateArgs(_class);
2458 delete _class.templateArgs;
2459 _class.templateArgs = new0 ClassTemplateArgument[numParams];
2460 _class.numParams = numParams;
2462 for(sClass = _class; sClass; sClass = sClass.base)
2465 ClassTemplateParameter param;
2467 if(sClass.templateClass) sClass = sClass.templateClass;
2468 for(prevClass = sClass.base; prevClass; prevClass = prevClass.base)
2470 if(prevClass.templateClass) prevClass = prevClass.templateClass;
2471 id += prevClass.templateParams.count;
2474 if(base.templateArgs) // Add numParams test here?
2476 for(param = sClass.templateParams.first; param; param = param.next)
2478 _class.templateArgs[id] = base.templateArgs[id];
2479 CopyTemplateArg(param, _class.templateArgs[id]);
2486 _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
2487 if(type == normalClass || type == noHeadClass)
2488 _class.offset = (base && base.structSize && base.type != systemClass) ? base.structSize : ((type == noHeadClass) ? 0 : sizeof(class Instance));
2489 if(type == structClass)
2491 _class.memberOffset = (base && base.structSize && base.type != systemClass) ? base.structSize : 0;
2493 _class.typeSize = _class.structSize = _class.memberOffset + size;
2495 else if(type == bitClass || type == enumClass || type == unitClass)
2497 Class dataTypeClass = eSystem_FindClass(_class.module, dataTypeString);
2499 _class.typeSize = dataTypeClass.typeSize;
2500 _class.structSize = 0;
2502 else if(type == normalClass || type == noHeadClass)
2504 _class.structSize = _class.offset + size;
2505 _class.typeSize = sizeof(void *);
2507 _class.offsetClass = offsetClass;
2508 _class.sizeClass = totalSizeClass;
2509 _class.Constructor = (void *)Constructor;
2510 _class.Destructor = Destructor;
2511 if(_class.type != systemClass)
2514 _class.computeSize = true;
2516 _class.computeSize = false;
2517 _class.inheritanceAccess = inheritanceAccess;
2519 /*if(type == bitClass)
2521 if(type == enumClass)
2524 _class.base = base = enumBase;
2527 EnumClassData data = (EnumClassData)_class.data;
2528 // TOCHECK: Trying this (if specifiers specified, no class found...)
2529 // What about bit classes, unit classes...
2530 if(base && base.type != enumClass)
2531 data.largest = -1;//_class.base = null;
2533 data.largest = ((EnumClassData)(base.data)).largest;
2536 if(base && base.vTblSize)
2538 _class.vTblSize = base.vTblSize;
2539 // OK to scrap existing virtual table?
2540 delete _class._vTbl;
2541 _class._vTbl = _malloc(sizeof(int(*)()) * _class.vTblSize);
2542 memcpy(_class._vTbl, base._vTbl, sizeof(int(*)()) * _class.vTblSize);
2547 OldLink link { data = _class };
2548 /*(_class.base.templateClass ? _class.base.templateClass : _class.base)*/_class.base.derivatives.Add(link);
2551 FixDerivativesBase(_class, _class);
2558 static void DataMember_Free(DataMember parentMember)
2561 BTNamedLink namedLink;
2562 delete parentMember.name;
2563 delete parentMember.dataTypeString;
2565 while((member = parentMember.members.first))
2567 DataMember_Free(member);
2568 parentMember.members.Delete(member);
2571 while((namedLink = (BTNamedLink)parentMember.membersAlpha.first))
2573 parentMember.membersAlpha.Delete((BTNode)namedLink);
2577 static void FreeEnumValue(NamedLink value)
2582 static void FreeTemplateArg(Class template, ClassTemplateParameter param, int id)
2587 delete template.templateArgs[id].dataTypeString;
2590 delete template.templateArgs[id].memberString;
2598 static void FreeTemplateArgs(Class template)
2600 if(template.templateArgs)
2603 for(_class = template; _class; _class = _class.base)
2606 ClassTemplateParameter param;
2608 if(_class.templateClass) _class = _class.templateClass;
2609 for(prevClass = _class.base; prevClass; prevClass = prevClass.base)
2611 if(prevClass.templateClass) prevClass = prevClass.templateClass;
2612 id += prevClass.templateParams.count;
2614 if(id < template.numParams)
2616 for(param = _class.templateParams.first; param; param = param.next)
2621 delete template.templateArgs[id].dataTypeString;
2624 delete template.templateArgs[id].memberString;
2627 // delete template.templateArgs[id].dataTypeString;
2637 static void FreeTemplate(Class template)
2641 if(template.nameSpace)
2643 BTNamedLink link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
2644 template.nameSpace->classes.Delete((BTNode)link);
2646 FreeTemplateArgs(template);
2648 delete template.fullName;
2649 delete template.name;
2650 delete template.templateArgs;
2652 while((deriv = template.derivatives.first))
2654 ((Class)deriv.data).base = null;
2655 template.derivatives.Delete(deriv);
2661 static void FreeTemplates(Class _class)
2663 OldLink deriv, template;
2665 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
2667 FreeTemplates(deriv.data);
2670 FreeTemplateArgs(_class);
2671 //if(_class.templateArgs)
2672 //printf("Deleting Template args for %s\n", _class.name);
2673 delete _class.templateArgs;
2675 while((template = _class.templatized.first))
2677 FreeTemplates(template.data);
2678 FreeTemplate(template.data);
2679 _class.templatized.Delete(template);
2683 public dllexport void eClass_Unregister(Class _class)
2685 BTNamedLink namedLink;
2688 OldLink deriv, template;
2689 ClassProperty classProp;
2690 ClassTemplateParameter param;
2692 delete _class._vTbl;
2694 FreeTemplates(_class);
2696 FreeTemplateArgs(_class);
2697 delete _class.templateArgs;
2699 while((template = _class.templatized.first))
2701 FreeTemplate(template.data);
2702 _class.templatized.Delete(template);
2705 while((member = _class.membersAndProperties.first))
2707 if(!member.isProperty && (member.type == unionMember || member.type == structMember))
2708 DataMember_Free(member);
2710 delete member.dataTypeString;
2711 _class.membersAndProperties.Delete(member);
2714 while((member = _class.conversions.first))
2717 delete member.dataTypeString;
2718 _class.conversions.Delete(member);
2721 while((namedLink = (BTNamedLink)_class.prop.first))
2723 _class.prop.Delete((BTNode)namedLink);
2726 while((namedLink = (BTNamedLink)_class.members.first))
2728 _class.members.Delete((BTNode)namedLink);
2731 while((classProp = (ClassProperty)_class.classProperties.first))
2733 delete classProp.name;
2734 delete classProp.dataTypeString;
2735 _class.classProperties.Delete((BTNode)classProp);
2738 while((method = (Method)_class.methods.first))
2741 delete method.dataTypeString;
2742 _class.methods.Delete((BTNode)method);
2745 if(_class.type == enumClass)
2747 EnumClassData data = (EnumClassData)_class.data;
2749 data.values.Free((void *)FreeEnumValue);
2751 _class.delayedCPValues.Free(null);
2753 _class.selfWatchers.Free(null);
2757 // Class base = _class.base.templateClass ? _class.base.templateClass : _class.base;
2758 Class base = _class.base;
2759 for(deriv = base.derivatives.first; deriv; deriv = deriv.next)
2761 if(deriv.data == _class)
2765 base.derivatives.Delete(deriv);
2767 while((deriv = _class.derivatives.first))
2769 ((Class)deriv.data).base = null;
2770 _class.derivatives.Delete(deriv);
2773 if(_class.nameSpace)
2775 BTNamedLink link = (BTNamedLink)_class.nameSpace->classes.FindString(_class.name);
2776 _class.nameSpace->classes.Delete((BTNode)link);
2780 delete _class.fullName;
2782 delete _class.dataTypeString;
2786 while((param = _class.templateParams.first))
2791 delete param.defaultArg.dataTypeString;
2794 delete param.defaultArg.memberString;
2800 if(param.type != identifier) delete param.dataTypeString;
2803 _class.templateParams.Delete(param);
2806 //_class.nameSpace->classes.Delete(_class);
2810 static BTNamedLink ScanNameSpace(NameSpace nameSpace, char * name, void * listOffset)
2812 BinaryTree * tree = (BinaryTree *)((byte *)nameSpace + (uint)listOffset);
2813 BTNamedLink link = (BTNamedLink)tree->Find((uint)name);
2817 for(child = (NameSpace *)nameSpace.nameSpaces.first; child; child = (NameSpace *)((BTNode)child).next)
2819 link = ScanNameSpace(child, name, listOffset);
2827 static BTNamedLink SearchNameSpace(NameSpace nameSpace, char * name, void * listOffset)
2832 for(c = 0; (ch = name[c]); c++)
2834 if(ch == '<') level++;
2835 if(ch == '>') level--;
2836 if(level == 0 && (ch == '.' || (ch == ':' && name[c+1] == ':')))
2838 NameSpace * newSpace;
2839 char * spaceName = _malloc(c - start + 1);
2840 memcpy(spaceName, name + start, c - start);
2841 spaceName[c-start] = '\0';
2842 newSpace = (NameSpace *)nameSpace.nameSpaces.FindString(spaceName);
2846 nameSpace = newSpace;
2847 if(level == 0 && ch == ':') c++;
2853 return ScanNameSpace(nameSpace, name + start, listOffset);
2858 static BTNamedLink SearchModule(Module module, char * name, void * listOffset, bool searchPrivate)
2860 SubModule subModule;
2865 link = SearchNameSpace(&module.privateNameSpace, name, listOffset);
2866 if(link) return link;
2868 link = SearchNameSpace(&module.publicNameSpace, name, listOffset);
2869 if(link) return link;
2871 for(subModule = module.modules.first; subModule; subModule = subModule.next)
2873 if(searchPrivate || subModule.importMode == publicAccess)
2875 // TOCHECK: Reverting to false to test what we were trying to fix by passing searchPrivate
2876 // Passing searchPrivate finds ALL classes private or not and thus classes clash
2877 // SearchModule here is called mainly from eSystem_FindClass, and also for Functions and Defines
2879 link = SearchModule(subModule.module, name, listOffset, false);
2880 //link = SearchModule(subModule.module, name, listOffset, searchPrivate /*false*/);
2881 if(link) return link;
2887 public int64 _strtoi64(char * string, char ** endString, int base)
2893 for(c = 0; (ch = string[c]) && isspace(ch); c++);
2895 else if(ch == '-') { sign = -1; c++; };
2898 if(ch == 0 && string[c+1] == 'x')
2911 for( ;(ch = string[c]); c++)
2915 else if(ch >= '1' && ch <= '9')
2917 else if(ch >= 'a' && ch <= 'z')
2919 else if(ch >= 'A' && ch <= 'Z')
2923 *endString = string + c;
2924 // Invalid character
2934 *endString = string + c;
2935 // Invalid character
2942 public uint64 _strtoui64(char * string, char ** endString, int base)
2948 for(c = 0; (ch = string[c]) && isspace(ch); c++);
2950 else if(ch == '-') { sign = -1; c++; };
2953 if(ch == 0 && string[c+1] == 'x')
2966 for( ;(ch = string[c]); c++)
2970 else if(ch >= '1' && ch <= '9')
2972 else if(ch >= 'a' && ch <= 'z')
2974 else if(ch >= 'A' && ch <= 'Z')
2978 *endString = string + c;
2979 // Invalid character
2989 *endString = string + c;
2990 // Invalid character
2997 public dllexport Class eSystem_FindClass(Module module, char * name)
3002 link = SearchNameSpace(&module.application.systemNameSpace, name, &((NameSpace *)0)->classes);
3003 if(link) return link.data;
3005 link = SearchModule(module, name, &((NameSpace *)0)->classes, true);
3006 if(link) return link.data;
3009 char noTemplateName[1024];
3010 char * templateParams = strchr(name, '<');
3014 strncpy(noTemplateName, name, templateParams - name);
3015 noTemplateName[templateParams - name] = '\0';
3018 strcpy(noTemplateName, name);
3020 link = SearchNameSpace(&module.application.systemNameSpace, noTemplateName, &((NameSpace *)0)->classes);
3022 link = SearchModule(module, noTemplateName, &((NameSpace *)0)->classes, true);
3025 Class _class = link.data;
3026 Class templatedClass = null;
3027 char className[1024];
3028 strcpy(className, _class.fullName);
3029 strcat(className, templateParams);
3031 link = SearchNameSpace(&module.application.systemNameSpace, className, &((NameSpace *)0)->classes);
3035 link = SearchModule(module, className, &((NameSpace *)0)->classes, true);
3039 if(_class && templateParams)
3041 // if(!numParams) return null;
3043 templatedClass = Class { };
3044 *templatedClass = *_class;
3045 templatedClass.templateClass = _class;
3046 //templatedClass.fullName = CopyString(name);
3047 templatedClass.fullName = CopyString(className);
3048 templatedClass.name = CopyString(templatedClass.fullName + strlen(_class.fullName) - strlen(_class.name));
3049 templatedClass.nameSpace->classes.Add((BTNode)BTNamedLink { name = templatedClass.name, data = templatedClass });
3050 templatedClass.templateArgs = null;
3051 templatedClass.numParams = 0;
3052 templatedClass.derivatives = { };
3053 templatedClass.templatized = { };
3055 ComputeClassParameters(templatedClass, templateParams, module);
3057 _class.templatized.Add(OldLink { data = templatedClass });
3059 return templatedClass;
3066 static void CopyTemplateArg(ClassTemplateParameter param, ClassTemplateArgument arg)
3071 arg.dataTypeString = CopyString(arg.dataTypeString);
3077 arg.memberString = CopyString(arg.memberString);
3082 static void ComputeClassParameters(Class templatedClass, char * templateParams, Module findModule)
3085 char * nextParamStart = templateParams ? (templateParams + 1) : null;
3086 ClassTemplateParameter curParam = null;
3087 Class lastClass = null, sClass;
3090 Class _class = templatedClass.templateClass ? templatedClass.templateClass : templatedClass;
3092 for(sClass = _class; sClass; sClass = sClass.base)
3094 if(sClass.templateClass) sClass = sClass.templateClass;
3095 numParams += sClass.templateParams.count;
3098 if(templatedClass.templateArgs)
3099 FreeTemplateArgs(templatedClass);
3100 delete templatedClass.templateArgs;
3101 templatedClass.templateArgs = new0 ClassTemplateArgument[numParams];
3102 templatedClass.numParams = numParams;
3104 if(_class != templatedClass)
3108 memcpy(templatedClass.templateArgs, _class.templateArgs, numParams * sizeof(ClassTemplateArgument));
3109 for(sClass = _class; sClass; sClass = sClass.base)
3111 ClassTemplateParameter param;
3114 if(sClass.templateClass) sClass = sClass.templateClass;
3115 for(prevClass = sClass.base; prevClass; prevClass = prevClass.base)
3117 if(prevClass.templateClass) prevClass = prevClass.templateClass;
3118 id += prevClass.templateParams.count;
3120 for(param = sClass.templateParams.first; param; param = param.next)
3121 CopyTemplateArg(param, templatedClass.templateArgs[id++]);
3125 if(templatedClass.base && templatedClass.base.templateArgs && _class == templatedClass)
3128 memcpy(templatedClass.templateArgs, templatedClass.base.templateArgs,
3129 sizeof(ClassTemplateArgument) * (numParams - templatedClass.templateParams.count));
3130 for(sClass = templatedClass.base; sClass; sClass = sClass.base)
3132 ClassTemplateParameter param;
3135 for(prevClass = sClass.base; prevClass; prevClass = prevClass.base)
3137 if(prevClass.templateClass) prevClass = prevClass.templateClass;
3138 id += prevClass.templateParams.count;
3141 if(sClass.templateClass) sClass = sClass.templateClass;
3142 for(param = sClass.templateParams.first; param; param = param.next)
3143 CopyTemplateArg(param, templatedClass.templateArgs[id++]);
3147 while(nextParamStart)
3149 char * paramStart = nextParamStart;
3152 while(*paramStart == ' ') paramStart++;
3153 paramEnd = paramStart;
3154 while((ch = *paramEnd, ch && (level > 0 || (ch != '>' && ch != ','))))
3156 if(ch == '<') level++;
3157 if(ch == '>') level--;
3161 nextParamStart = (ch == ',') ? (paramEnd + 1) : null;
3162 while(*paramEnd == ' ') paramEnd--;
3163 if(paramEnd > paramStart)
3165 char * ptr, * equal = null;
3166 for(ptr = paramStart; ptr <= paramEnd; ptr++)
3176 char * end = equal - 1;
3179 while(*end == ' ') end--;
3180 strncpy(ident, paramStart, end + 1 - paramStart);
3181 ident[end + 1 - paramStart] = 0;
3183 for(sClass = _class; sClass; sClass = sClass.base)
3185 if(sClass.templateClass) sClass = sClass.templateClass;
3186 for(curParam = sClass.templateParams.first; curParam; curParam = curParam.next)
3188 if(!strcmp(curParam.name, ident))
3194 ClassTemplateParameter prevParam;
3196 for(prevParam = curParam.prev; prevParam; prevParam = prevParam.prev) curParamID++;
3197 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3199 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3200 curParamID += nextClass.templateParams.count;
3211 curParam = curParam.next;
3217 for(sClass = lastClass ? lastClass.base : _class; sClass; sClass = sClass.base)
3219 ClassTemplateParameter param;
3221 if(sClass.templateClass) sClass = sClass.templateClass;
3222 for(param = sClass.templateParams.first; param; param = param.next, curParamID++)
3230 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3232 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3233 curParamID += nextClass.templateParams.count;
3240 for(sClass = _class; sClass; sClass = sClass.base)
3242 if(sClass.templateParams.first)
3245 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3246 if(nextClass.templateParams.first)
3248 if(nextClass != lastClass) continue;
3250 curParam = sClass.templateParams.first;
3253 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3254 if(nextClass.templateParams.first)
3256 curParamID += nextClass.templateParams.count;
3268 ClassTemplateArgument argument { };
3273 while(*equal == ' ') equal++;
3274 memcpy(value, equal, paramEnd - equal);
3275 value[paramEnd - equal] = 0;
3279 memcpy(value, paramStart, paramEnd - paramStart);
3280 value[paramEnd - paramStart] = 0;
3282 TrimRSpaces(value, value);
3284 switch(curParam.type)
3287 argument.dataTypeString = CopyString(value);
3288 argument.dataTypeClass = eSystem_FindClass(_class.module, value);
3289 if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(_class.module.application, value);
3290 if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(findModule, value);
3294 Class expClass = eSystem_FindClass(_class.module, curParam.dataTypeString);
3295 if(!expClass) expClass = eSystem_FindClass(_class.module.application, curParam.dataTypeString);
3298 //if(expClass.type ==
3299 expClass._vTbl[__ecereVMethodID_class_OnGetDataFromString](expClass, &argument.expression, value);
3301 // Expression should be pre simplified here
3302 else if(value[0] == '\"')
3304 char * endQuote = value + strlen(value) - 1;
3305 if(*endQuote != '\"') endQuote++;
3307 argument.expression.p = CopyString(value + 1);
3309 else if(value[0] == '\'')
3312 unichar ch = UTF8GetChar(value + 1, &nb);
3313 argument.expression.ui = ch;
3315 else if(!strcmp(curParam.dataTypeString, "uint"))
3317 argument.expression.ui = strtoul(value, null, 0);
3319 else if(!strcmp(curParam.dataTypeString, "char"))
3321 argument.expression.c = (char)strtol(value, null, 0);
3323 else if(!strcmp(curParam.dataTypeString, "byte"))
3325 argument.expression.uc = (unsigned char)strtoul(value, null, 0);
3327 else if(!strcmp(curParam.dataTypeString, "short"))
3329 argument.expression.s = (short)strtol(value, null, 0);
3331 else if(!strcmp(curParam.dataTypeString, "uint16"))
3333 argument.expression.us = (unsigned short)strtoul(value, null, 0);
3335 else if(!strcmp(curParam.dataTypeString, "int64"))
3337 argument.expression.i64 = _strtoi64(value, null, 0);
3339 else if(!strcmp(curParam.dataTypeString, "uint64"))
3341 argument.expression.ui64 = _strtoui64(value, null, 0);
3343 else if(!strcmp(curParam.dataTypeString, "float"))
3345 argument.expression.f = (float)strtod(value, null);
3347 else if(!strcmp(curParam.dataTypeString, "double"))
3349 argument.expression.d = strtod(value, null);
3351 else // if(!strcmp(curParam.dataTypeString, "int"))
3353 argument.expression.i = strtol(value, null, 0);
3358 argument.memberString = CopyString(value);
3361 FreeTemplateArg(templatedClass, curParam, curParamID);
3362 templatedClass.templateArgs[curParamID] = argument;
3367 // TESTING THIS BEFORE...
3368 if(templatedClass == _class)
3370 Class sClass = _class;
3373 ClassTemplateParameter param;
3374 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3376 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3377 curParamID += nextClass.templateParams.count;
3380 for(param = sClass.templateParams.first; param; param = param.next)
3382 if(!templatedClass.templateArgs[curParamID].dataTypeString)
3384 templatedClass.templateArgs[curParamID] = param.defaultArg;
3385 CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
3386 if(param.type == type && param.defaultArg.dataTypeString)
3388 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
3389 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3390 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
3391 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3392 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
3399 if(templatedClass.base && templatedClass.base.templateArgs && numParams - _class.templateParams.count)
3401 int c = numParams - _class.templateParams.count-1;
3403 for(sClass = _class.base; sClass; sClass = sClass.base)
3405 ClassTemplateParameter param;
3406 if(sClass.templateClass) sClass = sClass.templateClass;
3407 for(param = sClass.templateParams.last; param; param = param.prev)
3409 ClassTemplateArgument * arg = &templatedClass.templateArgs[c];
3410 ClassTemplateArgument * baseArg = &templatedClass.base.templateArgs[c];
3411 if(!arg->dataTypeString)
3413 *arg = templatedClass.base.templateArgs[c];
3414 CopyTemplateArg(param, arg);
3415 if(param.type == type)
3417 if(arg->dataTypeClass && strchr(arg->dataTypeString, '<') && arg->dataTypeClass.templateArgs)
3419 Class expClass = arg->dataTypeClass;
3420 Class cClass = null;
3424 char templateString[1024];
3425 sprintf(templateString, "%s<", expClass.templateClass.fullName);
3426 for(cClass = expClass; cClass; cClass = cClass.base)
3429 ClassTemplateParameter param;
3430 for(param = cClass.templateParams.first; param; param = param.next)
3434 ClassTemplateArgument arg;
3435 for(sClass = expClass.base; sClass; sClass = sClass.base) id += sClass.templateParams.count;
3436 arg = expClass.templateArgs[id];
3439 ClassTemplateParameter cParam;
3440 int p = numParams - _class.templateParams.count;
3441 for(cParam = _class.templateParams.first; cParam; cParam = cParam.next, p++)
3443 if(cParam.type == type && arg.dataTypeString && !strcmp(cParam.name, arg.dataTypeString))
3445 arg.dataTypeString = templatedClass.templateArgs[p].dataTypeString;
3446 arg.dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
3459 // THIS WHOLE THING IS A WILD GUESS... FIX IT UP
3461 char expString[1024];
3462 OldList * specs = MkList();
3463 Declarator decl = SpecDeclFromString(param.dataTypeString, specs, null);
3465 char * string = PrintHexUInt64(arg.expression.ui64);
3466 exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
3468 ProcessExpressionType(exp);
3469 ComputeExpression(exp);
3470 expString[0] = '\0';
3471 PrintExpression(exp, expString);
3472 strcat(argument, expString);
3474 FreeExpression(exp);
3480 strcat(argument, arg.member.name);
3483 case TemplateParameterType::type:
3485 if(arg.dataTypeString)
3486 strcat(argument, arg.dataTypeString);
3492 if(paramCount) strcat(templateString, ", ");
3493 if(lastParam != p - 1)
3495 strcat(templateString, param.name);
3496 strcat(templateString, " = ");
3498 strcat(templateString, argument);
3507 int len = strlen(templateString);
3508 if(templateString[len-1] == '>') templateString[len++] = ' ';
3509 templateString[len++] = '>';
3510 templateString[len++] = '\0';
3513 FreeTemplateArg(templatedClass, param, c);
3515 arg->dataTypeString = CopyString(templateString);
3516 arg->dataTypeClass = eSystem_FindClass(templatedClass.module, templateString);
3517 if(!arg->dataTypeClass)
3518 arg->dataTypeClass = eSystem_FindClass(templatedClass.module.application, templateString);
3522 ClassTemplateParameter cParam;
3523 int p = numParams - _class.templateParams.count;
3524 for(cParam = _class.templateParams.first; cParam; cParam = cParam.next, p++)
3526 // if(cParam.type == type && !strcmp(cParam.name, param.name))
3527 if(cParam.type == type && baseArg->dataTypeString && !strcmp(cParam.name, baseArg->dataTypeString))
3529 FreeTemplateArg(templatedClass, param, c);
3531 arg->dataTypeString = templatedClass.templateArgs[p].dataTypeString;
3532 arg->dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
3533 CopyTemplateArg(cParam, arg);
3547 for(sClass = _class; sClass; sClass = sClass.base)
3551 ClassTemplateParameter param;
3552 if(sClass.templateClass) sClass = sClass.templateClass;
3554 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3556 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3557 curParamID += nextClass.templateParams.count;
3560 for(param = sClass.templateParams.first; param; param = param.next)
3562 if(!templatedClass.templateArgs[curParamID].dataTypeString)
3564 templatedClass.templateArgs[curParamID] = param.defaultArg;
3565 CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
3566 if(param.type == type && param.defaultArg.dataTypeString)
3568 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
3569 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3570 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
3571 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3572 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
3581 int c = numParams - 1;
3582 for(sClass = _class; sClass; sClass = sClass.base)
3584 ClassTemplateParameter param;
3585 if(sClass.templateClass) sClass = sClass.templateClass;
3586 for(param = sClass.templateParams.last; param; param = param.prev)
3588 if(param.type == type)
3590 ClassTemplateArgument * arg = &templatedClass.templateArgs[c];
3591 ClassTemplateParameter cParam;
3593 int p = numParams - 1;
3594 for(dClass = _class; dClass; dClass = dClass.base)
3596 if(dClass.templateClass) dClass = dClass.templateClass;
3597 for(cParam = dClass.templateParams.last; cParam; cParam = cParam.prev, p--)
3599 if(cParam.type == type && arg->dataTypeString && !strcmp(cParam.name, arg->dataTypeString))
3601 if(templatedClass.templateArgs[p].dataTypeString && c != p)
3603 FreeTemplateArg(templatedClass, param, c);
3605 arg->dataTypeString = templatedClass.templateArgs[p].dataTypeString;
3606 arg->dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
3607 CopyTemplateArg(cParam, arg);
3620 int c = numParams - 1;
3621 for(tClass = _class; tClass; tClass = tClass.base)
3623 ClassTemplateParameter param;
3624 if(tClass.templateClass) tClass = tClass.templateClass;
3625 for(param = tClass.templateParams.last; param; param = param.prev)
3627 ClassTemplateArgument * arg = &templatedClass.templateArgs[c];
3628 if(param.type == identifier && arg->memberString)
3630 Class memberClass = templatedClass;
3631 char * memberString = arg->memberString;
3632 char * colon = strstr(memberString, "::");
3633 char * memberName = memberString;
3634 if(colon) memberName = colon + 2;
3637 memberString = param.defaultArg.memberString;
3638 colon = memberString ? strstr(memberString, "::") : null;
3643 char className[1024];
3646 memcpy(className, memberString, colon - memberString);
3647 className[colon - memberString] = '\0';
3649 for(sClass = _class; sClass; sClass = sClass.base)
3651 ClassTemplateParameter cParam;
3655 if(sClass.templateClass) sClass = sClass.templateClass;
3656 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3658 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3659 id += nextClass.templateParams.count;
3661 for(cParam = sClass.templateParams.first; cParam; cParam = cParam.next)
3663 if(cParam.type == type && !strcmp(cParam.name, className) && templatedClass.templateArgs[id].dataTypeString)
3665 strcpy(className, templatedClass.templateArgs[id].dataTypeString);
3670 memberClass = eSystem_FindClass(templatedClass.module, className);
3671 // TESTING: Added this here...
3673 memberClass = eSystem_FindClass(findModule, className);
3675 memberClass = eSystem_FindClass(templatedClass.module.application, className);
3680 switch(param.memberType)
3683 arg->member = eClass_FindDataMember(memberClass, memberName, memberClass.module, null, null);
3686 arg->method = eClass_FindMethod(memberClass, memberName, memberClass.module);
3689 arg->prop = eClass_FindProperty(memberClass, memberName, memberClass.module);
3700 /*static */bool DefaultFunction()
3705 public dllexport bool eClass_IsDerived(Class _class, Class from)
3707 if(!_class && !from)
3710 if(_class && from && (_class.templateClass || from.templateClass))
3712 if(eClass_IsDerived(_class.templateClass ? _class.templateClass : _class, from.templateClass ? from.templateClass : from))
3714 if(!from.templateClass)
3716 else if(!_class.templateClass && _class == from.templateClass)
3721 for(sClass = from; sClass; sClass = sClass.base)
3723 if(sClass.templateParams.first)
3725 ClassTemplateParameter param;
3728 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base) p += nextClass.templateParams.count;
3729 for(param = sClass.templateParams.first; param; param = param.next, p++)
3731 ClassTemplateArgument * arg = &_class.templateArgs[p];
3732 ClassTemplateArgument * fArg = &from.templateArgs[p];
3733 if(param.type == type)
3735 if(arg->dataTypeString != fArg->dataTypeString && arg->dataTypeString && fArg->dataTypeString &&
3736 strcmp(arg->dataTypeString, fArg->dataTypeString))
3739 else if(param.type == identifier)
3741 if(arg->member != fArg->member)
3744 else if(param.type == expression)
3746 if(arg->expression.ui64 != fArg->expression.ui64)
3760 for(; _class && from; _class = _class.base)
3762 if(_class == from || _class.templateClass == from || (_class.type == systemClass && from.name && !strcmp(_class.name, from.name)))
3769 static void FixDerivativeVirtualMethod(Class base, char * name, int vid, void * origFunction, char * type)
3772 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
3774 Class _class = derivative.data;
3775 Method method, next;
3776 void * function = origFunction;
3779 _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
3780 memmove(_class._vTbl + vid + 1, _class._vTbl + vid, (_class.vTblSize - vid - 1) * sizeof(void *));
3782 method = (Method) _class.methods.FindString(name);
3785 if(method.function) function = method.function;
3790 delete method.dataTypeString;
3791 _class.methods.Delete((BTNode)method);
3795 delete method.dataTypeString;
3796 method.type = virtualMethod;
3797 method.dataTypeString = CopyString(type);
3798 method._class = base;
3801 for(method = (Method)_class.methods.first; method; method = next)
3803 next = (Method)((BTNode)method).next;
3804 if(method.type == virtualMethod)
3807 _class._vTbl[vid] = function;
3810 OldLink templateLink;
3811 for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
3813 Class template = templateLink.data;
3814 template._vTbl = _class._vTbl;
3817 if(_class.derivatives.first || _class.templatized.first)
3818 FixDerivativeVirtualMethod(_class, name, vid, function, type);
3821 OldLink templateLink;
3822 for(templateLink = base.templatized.first; templateLink; templateLink = templateLink.next)
3824 Class template = templateLink.data;
3825 template._vTbl = base._vTbl;
3826 FixDerivativeVirtualMethod(template, name, vid, origFunction, type);
3831 public dllexport Method eClass_AddMethod(Class _class, char * name, char * type, void * function, AccessMode declMode)
3836 for(base = _class; base; base = base.base)
3838 Method method = (Method)base.methods.FindString(name);
3841 // If this overides a virtual method
3842 if(method.type == virtualMethod)
3845 void * oldFunction = _class._vTbl[method.vid];
3846 if(method.vid > _class.vTblSize)
3849 _class._vTbl[method.vid] = function ? function : DefaultFunction;
3850 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
3852 Class derivClass = deriv.data;
3853 if(derivClass._vTbl[method.vid] == oldFunction)
3854 eClass_AddMethod(derivClass, name, type, function, declMode);
3857 OldLink templateLink;
3858 for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
3860 Class template = templateLink.data;
3861 for(deriv = template.derivatives.first; deriv; deriv = deriv.next)
3863 Class derivClass = deriv.data;
3864 if(derivClass._vTbl[method.vid] == oldFunction)
3865 eClass_AddMethod(derivClass, name, type, function, declMode);
3875 // printf("error: Redefinition of method %s in class %s\n", name, _class.name);
3889 name = CopyString(name),
3890 function = function ? function : DefaultFunction;
3892 dataTypeString = CopyString(type);
3893 memberAccess = declMode;
3895 _class.methods.Add((BTNode)method);
3902 public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char * type, void * function, AccessMode declMode)
3907 for(base = _class; base; base = base.base)
3909 Method method = (Method)base.methods.FindString(name);
3912 // If this overides a virtual method
3913 if(method.type == virtualMethod)
3914 _class._vTbl[method.vid] = function ? function : DefaultFunction;
3925 name = CopyString(name);
3926 function = function ? function : DefaultFunction;
3927 type = virtualMethod;
3929 vid = _class.vTblSize++;
3930 dataTypeString = CopyString(type);
3931 memberAccess = declMode;
3933 _class.methods.Add((BTNode)method);
3934 _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
3935 _class._vTbl[method.vid] = function ? function : DefaultFunction;
3937 // TODO: Fix derived classes
3938 if(_class.derivatives.first || _class.templatized.first)
3939 FixDerivativeVirtualMethod(_class, name, method.vid, function ? function : (void *)DefaultFunction, type);
3946 static void FixDerivativeProperty(Class base, Property _property)
3949 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
3951 Class _class = derivative.data;
3954 link = (BTNamedLink)_class.prop.FindString(_property.name);
3958 if(!prop.Set && !prop.Get && prop.memberAccess == baseSystemAccess)
3960 SelfWatcher watcher;
3961 for(watcher = _class.selfWatchers.first; watcher; watcher = watcher.next)
3963 if(watcher._property == prop)
3964 watcher._property = _property;
3966 _property.selfWatchable = true;
3969 delete prop.dataTypeString;
3970 _class.membersAndProperties.Delete(prop);
3971 _class.prop.Delete((BTNode)link);
3975 for(prop = _class.membersAndProperties.first; prop; prop = prop.next)
3978 _class.startMemberID++;
3980 FixDerivativeProperty(_class, _property);
3984 public dllexport Property eClass_AddProperty(Class _class, char * name, char * dataType, void * setStmt, void * getStmt, AccessMode declMode)
3986 Property _property = null;
3989 if(!_class.prop.FindString((name ? name : dataType)))
3994 name = CopyString(name ? name : dataType);
3995 id = (name && (setStmt || getStmt || dataType)) ? _class.memberID++ : 0;
3998 dataTypeString = CopyString(dataType);
4001 conversion = name ? false : true;
4002 memberAccess = declMode;
4005 _class.membersAndProperties.Add(_property);
4007 _class.conversions.Add(_property);
4008 _class.prop.Add((BTNode)BTNamedLink { name = _property.name, data = _property });
4010 if(!_property.conversion)
4012 FixDerivativeProperty(_class, _property);
4019 static void SetDelayedCPValues(Class _class, ClassProperty _property)
4022 NamedLink value, next;
4024 for(value = _class.delayedCPValues.first; value; value = next)
4027 if(!strcmp(value.name, _property.name))
4029 // eClass_SetProperty(_class, _property.name, value.data);
4030 _property.Set(_class, (int)value.data);
4031 _class.delayedCPValues.Delete(value);
4035 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
4037 SetDelayedCPValues(deriv.data, _property);
4041 public dllexport ClassProperty eClass_AddClassProperty(Class _class, char * name, char * dataType, void * setStmt, void * getStmt)
4043 if(name && !_class.classProperties.FindString(name))
4045 ClassProperty _property
4047 name = CopyString(name);
4050 dataTypeString = CopyString(dataType);
4052 _class.classProperties.Add((BTNode)_property);
4053 SetDelayedCPValues(_class, _property);
4061 Time classFindTotalTime;
4063 public dllexport void ResetClassFindTime()
4065 classFindTotalTime = 0;
4068 public dllexport Time GetClassFindTime()
4070 return classFindTotalTime;
4073 public dllexport ClassProperty eClass_FindClassProperty(Class _class, char * name)
4075 //Time startTime = GetTime();
4076 ClassProperty _property = null;
4079 Class origClass = _class;
4080 for(; _class; _class = _class.base)
4082 _property = (ClassProperty)_class.classProperties.FindString(name);
4086 // For enum class deriving off something else than enum to find enumSize...
4087 if(!_property && origClass.type == enumClass)
4089 Class enumClass = eSystem_FindClass(origClass.module, "enum");
4090 _property = eClass_FindClassProperty(enumClass, name);
4094 eSystem_Logf("No such property (%s) for class %s\n", name, _class.name);*/
4095 //classFindTotalTime += GetTime() - startTime;
4099 public dllexport int eClass_GetProperty(Class _class, char * name)
4101 ClassProperty _property = eClass_FindClassProperty(_class, name);
4102 if(_property && _property.Get && _property.Get != (void *)1)
4104 int result = _property.Get(_class);
4110 public dllexport void eClass_SetProperty(Class _class, char * name, int value)
4112 ClassProperty _property = eClass_FindClassProperty(_class, name);
4116 _property.Set(_class, value);
4120 _class.delayedCPValues.Add(NamedLink { name = name, (void *)value });
4124 public dllexport Method eClass_FindMethod(Class _class, char * name, Module module)
4126 //Time startTime = GetTime();
4129 for(; _class; _class = _class.base)
4132 if(_class.templateClass) _class = _class.templateClass;
4133 method = (Method)_class.methods.FindString(name);
4134 if(method && (method.memberAccess == publicAccess || _class.module == module || !method.dataTypeString))
4136 if(!method.dataTypeString)
4138 if(_class.module != module)
4140 if(method.memberAccess == publicAccess)
4141 module = _class.module;
4144 //classFindTotalTime += GetTime() - startTime;
4151 //classFindTotalTime += GetTime() - startTime;
4155 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4158 //classFindTotalTime += GetTime() - startTime;
4162 // Construct an instance
4163 static bool ConstructInstance(void * instance, Class _class)
4165 if(_class.templateClass) _class = _class.templateClass;
4168 if(!ConstructInstance(instance, _class.base))
4171 if(_class.Initialize)
4173 void (* Initialize)(Module module) = (void *)_class.Initialize;
4174 _class.Initialize = null;
4175 Initialize(_class.module);
4177 if(_class.Constructor)
4179 if(!_class.Constructor(instance))
4181 for(; _class; _class = _class.base)
4183 if(_class.templateClass) _class = _class.templateClass;
4184 if(_class.Destructor)
4185 _class.Destructor(instance);
4190 (_class.templateClass ? _class.templateClass : _class).count++;
4194 public dllexport void * eInstance_New(Class _class)
4196 Instance instance = null;
4199 // instance = _malloc(_class.size);
4204 //allocateClass = _class;
4205 allocateClass = malloc(strlen(_class.name)+1);
4206 allocateInternal = _class.module == __thisModule;
4207 strcpy(allocateClass, _class.name);
4209 #define malloc _mymalloc
4213 instance = _calloc(1, _class.structSize);
4215 allocateClass = null;
4218 if(_class.type == normalClass)
4220 instance._class = _class;
4221 // Copy the virtual table initially
4222 instance._vTbl = _class._vTbl;
4224 if(!ConstructInstance(instance, _class))
4229 /*if(_class.type == normalClass && _class.count > 1000)
4230 printf("%s: %d instances\n", _class.name, _class.count);*/
4235 public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
4237 if(_class && instancePtr && *instancePtr)
4239 Instance instance = (Instance)renew *instancePtr byte[_class.structSize];
4240 *instancePtr = instance;
4241 memset(((byte *)instance) + instance._class.structSize, 0, _class.structSize - instance._class.structSize);
4242 // Fix pointers to application
4243 if(!strcmp(instance._class.name, "Application"))
4246 Application app = (Application) instance;
4249 NameSpace * nameSpace;
4250 for(module = app.allModules.first; module; module = module.next)
4251 module.application = app;
4253 for(link = (BTNamedLink)app.privateNameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
4256 ((Class)link.data).nameSpace = &app.privateNameSpace;
4257 for(t = ((Class)link.data).templatized.first; t; t = t.next) { Class template = t.data; template.nameSpace = ((Class)link.data).nameSpace; }
4259 for(link = (BTNamedLink)app.publicNameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
4262 ((Class)link.data).nameSpace = &app.publicNameSpace;
4263 for(t = ((Class)link.data).templatized.first; t; t = t.next) { Class template = t.data; template.nameSpace = ((Class)link.data).nameSpace; }
4266 for(link = (BTNamedLink)app.privateNameSpace.defines.first; link; link = (BTNamedLink)((BTNode)link).next)
4267 ((DefinedExpression)link.data).nameSpace = &app.privateNameSpace;
4268 for(link = (BTNamedLink)app.publicNameSpace.defines.first; link; link = (BTNamedLink)((BTNode)link).next)
4269 ((DefinedExpression)link.data).nameSpace = &app.publicNameSpace;
4271 for(link = (BTNamedLink)app.privateNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4272 ((GlobalFunction)link.data).nameSpace = &app.privateNameSpace;
4273 for(link = (BTNamedLink)app.publicNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4274 ((GlobalFunction)link.data).nameSpace = &app.publicNameSpace;
4276 for(nameSpace = (NameSpace *)app.privateNameSpace.nameSpaces.first; nameSpace; nameSpace = (NameSpace *)((BTNode)nameSpace).next)
4277 nameSpace->parent = &app.privateNameSpace;
4278 for(nameSpace = (NameSpace *)app.publicNameSpace.nameSpaces.first; nameSpace; nameSpace = (NameSpace *)((BTNode)nameSpace).next)
4279 nameSpace->parent = &app.publicNameSpace;
4281 // --------------------------------------------------
4282 for(link = (BTNamedLink)app.systemNameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
4285 ((Class)link.data).nameSpace = &app.systemNameSpace;
4286 for(t = ((Class)link.data).templatized.first; t; t = t.next) { Class template = t.data; template.nameSpace = ((Class)link.data).nameSpace; }
4288 for(link = (BTNamedLink)app.systemNameSpace.defines.first; link; link = (BTNamedLink)((BTNode)link).next)
4289 ((DefinedExpression)link.data).nameSpace = &app.systemNameSpace;
4290 for(link = (BTNamedLink)app.systemNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4291 ((GlobalFunction)link.data).nameSpace = &app.systemNameSpace;
4292 for(link = (BTNamedLink)app.systemNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4293 ((GlobalFunction)link.data).nameSpace = &app.systemNameSpace;
4294 for(nameSpace = (NameSpace *)app.systemNameSpace.nameSpaces.first; nameSpace; nameSpace = (NameSpace *)((BTNode)nameSpace).next)
4295 nameSpace->parent = &app.systemNameSpace;
4296 // --------------------------------------------------
4298 for(_class = app.classes.first; _class; _class = _class.next)
4300 OldLink templateLink;
4301 _class.module = (Module) app;
4302 for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
4304 Class template = templateLink.data;
4305 template.module = _class.module;
4308 app.application = app;
4313 for(base = instance._class; base && base.type == normalClass && base.count; base = base.base)
4314 (base.templateClass ? base.templateClass : base).count--;
4317 instance._class = _class;
4318 // Copy the virtual table initially
4319 instance._vTbl = _class._vTbl;
4321 if(!ConstructInstance(instance, _class))
4324 *instancePtr = null;
4329 public dllexport void eInstance_Delete(Instance instance)
4332 bool checkMemory = false;
4340 if(instance._class == (void *)0xecececec)
4344 ownVtbl = instance._vTbl != instance._class._vTbl;
4346 for(_class = instance._class; _class; _class = base)
4348 if(_class.templateClass) _class = _class.templateClass;
4349 if(_class.destructionWatchOffset)
4351 OldList * watchers = (OldList *)((byte *)instance + _class.destructionWatchOffset);
4352 Watcher watcher, next;
4354 for(watcher = watchers->first; watcher; watcher = next)
4356 next = watcher.next;
4357 watchers->Remove(watcher);
4358 watcher.callback(watcher.object, instance);
4359 watchers->Delete(watcher);
4363 /*// Loop through properties to delete all watchers? Might slow down destruction...
4366 for(_property = _class.membersAndProperties.first; _property; _property = _property.next)
4368 if(_property.isProperty && _property.isWatchable)
4370 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
4371 Watcher watcher, next;
4372 for(watcher = watchers->first; watcher; watcher = next)
4374 next = watcher.next;
4375 watchers->Delete(watcher);
4383 if(base && base.type == systemClass) base = null;
4384 if(_class.Destructor)
4385 _class.Destructor(instance);
4387 if(_class == class(Application))
4392 for(_class = instance._class; _class; _class = base)
4394 if(_class.templateClass) _class = _class.templateClass;
4397 (_class.templateClass ? _class.templateClass : _class).count--;
4398 if(_class.type == normalClass && !_class.count && !_class.module)
4401 // printf("Now Destructing class %s\n", _class.name);
4403 eClass_Unregister(_class);
4409 delete instance._vTbl;
4411 //instance.prop.Free(null);
4414 if(checkMemory) CheckMemory();
4419 public dllexport Property eClass_FindProperty(Class _class, char * name, Module module)
4421 //Time startTime = GetTime();
4424 for(; _class; _class = _class.base)
4427 if(_class.templateClass) _class = _class.templateClass;
4428 link = (BTNamedLink)_class.prop.FindString(name);
4431 Property _property = (Property)link.data;
4432 if(_property.memberAccess == publicAccess || _class.module == module || !_property.dataTypeString)
4434 if(!_property.dataTypeString)
4436 if(_class.module != module)
4438 if(_property.memberAccess == publicAccess)
4439 module = _class.module;
4442 //classFindTotalTime += GetTime() - startTime;
4449 //classFindTotalTime += GetTime() - startTime;
4454 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4457 //classFindTotalTime += GetTime() - startTime;
4461 static DataMember FindDataMember(OldList list, BinaryTree alist, char * name, uint * offset, int * id, bool searchPrivate, DataMember * subMemberStack, int * subMemberStackPos)
4464 DataMember dataMember;
4466 link = (BTNamedLink)alist.FindString(name);
4469 dataMember = link.data;
4470 if(dataMember.type == normalMember && (dataMember.memberAccess == publicAccess || searchPrivate || !dataMember.dataTypeString))
4473 *offset += dataMember.offset;
4474 if(id) *id = dataMember.id;
4479 for(dataMember = list.first; dataMember; dataMember = dataMember.next)
4481 if(!dataMember.isProperty && (dataMember.memberAccess == publicAccess || searchPrivate) && !dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
4483 DataMember childMember;
4484 if(subMemberStackPos) subMemberStack[(*subMemberStackPos)++] = dataMember;
4485 childMember = FindDataMember(dataMember.members, dataMember.membersAlpha, name, offset, id, searchPrivate, subMemberStack, subMemberStackPos);
4489 *offset += dataMember.offset;
4490 if(id) *id += dataMember.id;
4493 if(subMemberStackPos) (*subMemberStackPos)--;
4499 public dllexport DataMember eClass_FindDataMember(Class _class, char * name, Module module, DataMember * subMemberStack, int * subMemberStackPos)
4501 //Time startTime = GetTime();
4502 DataMember dataMember = null;
4503 if(subMemberStackPos) *subMemberStackPos = 0;
4506 for(; _class; _class = _class.base)
4508 if(_class.templateClass) _class = _class.templateClass;
4509 dataMember = FindDataMember(_class.membersAndProperties, _class.members, name, null, null, _class.module == module, subMemberStack, subMemberStackPos);
4512 if(!dataMember.dataTypeString)
4514 if(_class.module != module)
4516 if(dataMember.memberAccess == publicAccess)
4517 module = _class.module;
4520 //classFindTotalTime += GetTime() - startTime;
4528 // HACK: Is this good enough? avoiding setting it when adding...
4529 dataMember._class = _class.templateClass ? _class.templateClass : _class;
4530 //classFindTotalTime += GetTime() - startTime;
4534 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4537 //classFindTotalTime += GetTime() - startTime;
4541 public dllexport DataMember eClass_FindDataMemberAndOffset(Class _class, char * name, uint * offset, Module module, DataMember * subMemberStack, int * subMemberStackPos)
4543 //Time startTime = GetTime();
4544 DataMember dataMember = null;
4545 if(subMemberStackPos) *subMemberStackPos = 0;
4546 if(offset) *offset = 0;
4549 for(; _class; _class = _class.base)
4551 if(_class.templateClass) _class = _class.templateClass;
4552 dataMember = FindDataMember(_class.membersAndProperties, _class.members, name, offset, null, _class.module == module, subMemberStack, subMemberStackPos);
4555 if(!dataMember.dataTypeString)
4557 if(_class.module != module)
4559 if(dataMember.memberAccess == publicAccess)
4560 module = _class.module;
4563 //classFindTotalTime += GetTime() - startTime;
4571 // HACK: Is this good enouh? avoiding setting it when adding...
4572 dataMember._class = _class;
4573 //classFindTotalTime += GetTime() - startTime;
4577 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4580 //classFindTotalTime += GetTime() - startTime;
4584 public dllexport DataMember eClass_FindDataMemberAndId(Class _class, char * name, int * id, Module module, DataMember * subMemberStack, int * subMemberStackPos)
4586 //Time startTime = GetTime();
4587 DataMember dataMember = null;
4588 if(subMemberStackPos) *subMemberStackPos = 0;
4591 for(; _class; _class = _class.base)
4593 if(_class.templateClass) _class = _class.templateClass;
4594 dataMember = FindDataMember(_class.membersAndProperties, _class.members, name, null, id, _class.module == module, subMemberStack, subMemberStackPos); // TOCHECK: Why was this null? null, null);
4597 if(!dataMember.dataTypeString)
4599 if(_class.module != module)
4601 if(dataMember.memberAccess == publicAccess)
4602 module = _class.module;
4605 //classFindTotalTime += GetTime() - startTime;
4613 // HACK: Is this good enouh? avoiding setting it when adding...
4614 dataMember._class = _class;
4615 //classFindTotalTime += GetTime() - startTime;
4619 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4622 //classFindTotalTime += GetTime() - startTime;
4626 public dllexport void eClass_FindNextMember(Class _class, Class * curClass, DataMember * curMember, DataMember * subMemberStack, int * subMemberStackPos)
4628 // THIS CODE WILL FIND NEXT MEMBER... (PUBLIC MEMBERS ONLY)
4631 *curMember = (*curMember).next;
4633 if(subMemberStackPos && *subMemberStackPos > 0 && subMemberStack[*subMemberStackPos-1].type == unionMember)
4635 *curMember = subMemberStack[--(*subMemberStackPos)];
4636 *curMember = (*curMember).next;
4639 if(subMemberStackPos && *subMemberStackPos > 0)
4641 while(*curMember && ((*curMember).memberAccess == privateAccess))
4642 *curMember = (*curMember).next;
4645 while(*curMember && (*curMember).name) // ADDED THIS HERE for eComPacket packet { Connect, 0, { ECOMMUNICATOR_PROTOCOL_VERSION } };
4647 DataMember dataMember = eClass_FindDataMember(_class, curMember->name, null, null, null);
4648 if(!dataMember) dataMember = (DataMember)eClass_FindProperty(_class, curMember->name, null);
4649 if(dataMember && dataMember.memberAccess != privateAccess)
4651 *curMember = dataMember;
4655 *curMember = (*curMember).next;
4658 if(subMemberStackPos)
4660 while((*curMember) && !(*curMember).isProperty && !(*curMember).name && ((*curMember).type == structMember || (*curMember).type == unionMember))
4662 subMemberStack[(*subMemberStackPos)++] = *curMember;
4664 *curMember = (*curMember).members.first;
4665 while(*curMember && ((*curMember).memberAccess == privateAccess))
4666 *curMember = (*curMember).next;
4674 if(subMemberStackPos && *subMemberStackPos)
4676 *curMember = subMemberStack[--(*subMemberStackPos)];
4677 *curMember = (*curMember).next;
4681 Class lastCurClass = *curClass;
4683 if(*curClass == _class) break; // REACHED THE END
4685 for(*curClass = _class; (*curClass).base != lastCurClass && (*curClass).base.type != systemClass && (*curClass).inheritanceAccess != privateAccess; *curClass = (*curClass).base);
4686 *curMember = (*curClass).membersAndProperties.first;
4689 if(subMemberStackPos && *subMemberStackPos > 0)
4691 while(*curMember && ((*curMember).memberAccess == privateAccess))
4692 *curMember = (*curMember).next;
4695 while(*curMember && (*curMember).name) // ADDED THIS HERE for eComPacket packet { Connect, 0, { ECOMMUNICATOR_PROTOCOL_VERSION } };
4697 DataMember dataMember = eClass_FindDataMember(_class, curMember->name, null, null, null);
4698 if(!dataMember) dataMember = (DataMember)eClass_FindProperty(_class, curMember->name, null);
4699 if(dataMember && dataMember.memberAccess != privateAccess)
4701 *curMember = dataMember;
4705 *curMember = (*curMember).next;
4708 if(subMemberStackPos)
4710 while((*curMember) && !(*curMember).isProperty && !(*curMember).name && ((*curMember).type == structMember || (*curMember).type == unionMember))
4712 subMemberStack[(*subMemberStackPos)++] = *curMember;
4714 *curMember = (*curMember).members.first;
4715 while(*curMember && (*curMember).memberAccess == privateAccess)
4716 *curMember = (*curMember).next;
4723 public dllexport void eInstance_SetMethod(Instance instance, char * name, void * function) // YET TO BE DECIDED: , Module module)
4725 if(instance && name)
4728 for(_class = instance._class; _class; _class = _class.base)
4730 Method method = (Method)_class.methods.FindString(name);
4731 if(method && method.type == virtualMethod)
4733 if(instance._vTbl == instance._class._vTbl)
4735 instance._vTbl = _malloc(sizeof(void *) * instance._class.vTblSize);
4736 memcpy(instance._vTbl, instance._class._vTbl,
4737 sizeof(int(*)()) * instance._class.vTblSize);
4739 instance._vTbl[method.vid] = function ? function : DefaultFunction;
4745 public dllexport bool eInstance_IsDerived(Instance instance, Class from)
4749 Class _class = instance._class;
4750 for(; _class; _class = _class.base)
4759 public dllexport void eInstance_IncRef(Instance instance)
4762 instance._refCount++;
4765 public dllexport void eInstance_DecRef(Instance instance)
4769 instance._refCount--;
4770 //if(!instance._refCount)
4771 if(instance._refCount <= 0)
4773 eInstance_Delete(instance);
4778 static void FixOffsets(Class _class)
4781 _class.structSize += _class.base.structSize - _class.offset;
4783 _class.offset = _class.base.structSize;
4785 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
4786 FixOffsets(deriv.data);
4789 public dllexport void eClass_Resize(Class _class, int newSize)
4792 _class.structSize = newSize;
4793 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
4794 FixOffsets(deriv.data);
4797 public dllexport DataMember eClass_AddDataMember(Class _class, char * name, char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
4801 if(!_class.members.FindString(name))
4803 DataMember dataMember;
4807 _class.structAlignment = Max(_class.structAlignment, alignment);
4809 if(_class.memberOffset % alignment)
4810 _class.memberOffset += alignment - (_class.memberOffset % alignment);
4813 dataMember = DataMember {
4814 name = CopyString(name);
4815 dataTypeString = CopyString(type);
4816 id = _class.memberID++;
4818 offset = _class.memberOffset;
4819 memberOffset = size;
4820 memberAccess = declMode;
4821 membersAlpha.CompareKey = (void *)BinaryTree::CompareString;
4823 _class.membersAndProperties.Add(dataMember);
4824 _class.memberOffset += size;
4826 _class.members.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4833 public dllexport DataMember eMember_AddDataMember(DataMember member, char * name, char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
4835 if(name && !member.membersAlpha.FindString(name))
4837 DataMember dataMember;
4841 member.structAlignment = Max(member.structAlignment, alignment);
4843 if(member.memberOffset % alignment)
4844 member.memberOffset += alignment - (member.memberOffset % alignment);
4846 dataMember = DataMember {
4847 name = CopyString(name);
4848 _class = member._class;
4849 dataTypeString = CopyString(type);
4850 id = member.memberID++;
4851 offset = (member.type == unionMember) ? 0 : member.memberOffset;
4852 memberAccess = declMode;
4853 membersAlpha.CompareKey = (void *)BinaryTree::CompareString;
4855 member.members.Add(dataMember);
4856 if(member.type == unionMember)
4858 if(size > member.memberOffset)
4859 member.memberOffset = size;
4862 member.memberOffset += size;
4863 member.membersAlpha.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4869 public dllexport DataMember eMember_New(DataMemberType type, AccessMode declMode)
4871 return DataMember { type = type, memberAccess = declMode, membersAlpha.CompareKey = (void *)BinaryTree::CompareString };
4874 static void SetMemberClass(DataMember member, Class _class)
4876 DataMember dataMember;
4877 member._class = _class;
4878 for(dataMember = member.members.first; dataMember; dataMember = dataMember.next)
4879 SetMemberClass(dataMember, _class);
4882 public dllexport bool eMember_AddMember(DataMember addTo, DataMember dataMember)
4884 if(dataMember.name && addTo.membersAlpha.FindString(dataMember.name)) return false;
4885 addTo.members.Add(dataMember);
4888 addTo.membersAlpha.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4890 dataMember._class = addTo._class;
4891 // ? SetMemberClass(dataMember, addTo._class);
4893 //dataMember.id = addTo.memberID++;
4894 dataMember.id = addTo.memberID;
4895 if(dataMember.type == unionMember)
4896 addTo.memberID += 1;
4898 addTo.memberID += dataMember.memberID;
4900 addTo.structAlignment = Max(addTo.structAlignment, dataMember.structAlignment);
4901 dataMember.offset = (addTo.type == unionMember) ? 0 : addTo.memberOffset;
4902 if(addTo.type == unionMember)
4904 if(dataMember.memberOffset > addTo.memberOffset)
4905 addTo.memberOffset = dataMember.memberOffset;
4908 addTo.memberOffset += dataMember.memberOffset;
4912 public dllexport bool eClass_AddMember(Class _class, DataMember dataMember)
4914 if(!_class || _class.comRedefinition || (dataMember.name && _class.members.FindString(dataMember.name)))
4916 _class.membersAndProperties.Add(dataMember);
4919 _class.members.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4921 //dataMember._class = _class;
4922 SetMemberClass(dataMember, _class);
4924 //dataMember.id = _class.memberID++;
4925 dataMember.id = _class.memberID;
4927 _class.structAlignment = Max(_class.structAlignment, dataMember.structAlignment);
4928 if(dataMember.type == unionMember)
4929 _class.memberID += 1;
4931 _class.memberID += dataMember.memberID;
4932 dataMember.offset = _class.memberOffset;
4933 _class.memberOffset += dataMember.memberOffset;
4937 public dllexport BitMember eClass_AddBitMember(Class _class, char * name, char * type, int bitSize, int bitPos, AccessMode declMode)
4939 if(_class && name && !_class.members.FindString(name))
4945 name = CopyString(name);
4947 dataTypeString = CopyString(type);
4948 id = _class.memberID++;
4949 memberAccess = declMode;
4951 _class.membersAndProperties.Add(bitMember);
4954 bitMember.pos = (bitPos == -1) ? _class.memberOffset : bitPos;
4955 bitMember.size = bitSize;
4956 _class.memberOffset = bitMember.pos + bitMember.size;
4957 for(c = 0; c<bitSize; c++)
4963 bitMember.mask = mask << bitMember.pos;
4966 _class.members.Add((BTNode)BTNamedLink { name = bitMember.name, data = bitMember });
4972 static Module Module_Load(Module fromModule, char * name, AccessMode importAccess, bool ensureCOM)
4974 bool (stdcall * Load)(Module module) = null;
4975 void (stdcall * Unload)(Module module) = null;
4978 for(module = fromModule.application.allModules.first; module; module = module.next)
4980 if(!strcmp(module.name, name))
4983 if(ensureCOM && (!strcmp(name, "ecereCOM") || !strcmp(name, "ecere")))
4985 for(module = fromModule.application.allModules.first; module; module = module.next)
4987 if(!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM"))
4993 void * library = null;
4995 if(ensureCOM && !strcmp(name, "ecereCOM"))
4997 Load = COM_LOAD_FUNCTION;
4998 Unload = COM_UNLOAD_FUNCTION;
5002 library = Instance_Module_Load(name, &Load, &Unload);
5006 module = (Module)eInstance_New(eSystem_FindClass(fromModule, "Module"));
5007 module.application = fromModule.application;
5008 module.library = library;
5009 module.name = CopyString(name);
5010 module.Unload = Unload;
5013 eInstance_Delete((Instance)module);
5017 fromModule.application.allModules.Add(module);
5019 if(ensureCOM && !strcmp(name, "ecere") && module)
5021 name = !strcmp(module.name, "ecereCOM") ? "ecere" : "ecereCOM";
5022 if((!Load && !strcmp(module.name, "ecereCOM")) ||
5023 (Load && (!__thisModule || !__thisModule.name || !strcmp(__thisModule.name, "ecereCOM")) && Load != COM_LOAD_FUNCTION))
5026 for(module = fromModule.application.allModules.first; module; module = module.next)
5028 if(!strcmp(module.name, name))
5033 Load = COM_LOAD_FUNCTION;
5034 Unload = COM_UNLOAD_FUNCTION;
5036 module = (Module)eInstance_New(eSystem_FindClass(fromModule, "Module"));
5037 module.application = fromModule.application;
5038 module.library = null;
5039 module.name = CopyString(name);
5040 module.Unload = Unload;
5043 eInstance_Delete((Instance)module);
5046 fromModule.application.allModules.Add(module);
5052 fromModule.modules.Add(SubModule { module = module, importMode = importAccess });
5062 fromModule.modules.Add(SubModule { module = module, importMode = importAccess });
5069 public dllexport Module eModule_Load(Module fromModule, char * name, AccessMode importAccess)
5071 return Module_Load(fromModule, name, importAccess, true);
5074 public dllexport Module eModule_LoadStrict(Module fromModule, char * name, AccessMode importAccess)
5076 return Module_Load(fromModule, name, importAccess, false);
5079 public dllexport Module eModule_LoadStatic(Module fromModule, char * name, AccessMode importAccess, bool (* Load)(Module module), bool (* Unload)(Module module))
5082 for(module = fromModule.application.allModules.first; module; module = module.next)
5084 if(!strcmp(module.name, name))
5091 module = (Module)eInstance_New(eSystem_FindClass(fromModule, "Module"));
5092 module.application = fromModule.application;
5093 module.name = CopyString(name);
5094 module.Unload = (void *)Unload;
5097 eInstance_Delete((Instance)module);
5101 fromModule.application.allModules.Add(module);
5107 fromModule.modules.Add(SubModule { module = module, importMode = importAccess });
5114 public dllexport void eModule_Unload(Module fromModule, Module module)
5117 for(m = fromModule.modules.first; m; m = m.next)
5119 if(m.data == module)
5124 fromModule.modules.Delete(m);
5129 public dllexport void eEnum_AddFixedValue(Class _class, char * string, int value)
5131 if(_class && _class.type == enumClass)
5133 EnumClassData data = (EnumClassData)_class.data;
5136 for(item = data.values.first; item; item = item.next)
5137 if(!strcmp(item.name, string))
5141 data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
5142 if(value > data.largest)
5143 data.largest = value;
5148 public dllexport int eEnum_AddValue(Class _class, char * string)
5150 if(_class && _class.type == enumClass)
5152 EnumClassData data = (EnumClassData)_class.data;
5153 int value = ((int) data.largest) + 1;
5155 for(item = data.values.first; item; item = item.next)
5156 if(!strcmp(item.name, string))
5160 data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
5161 if(value > data.largest)
5162 data.largest = value;
5169 static void NameSpace_Free(NameSpace parentNameSpace)
5171 NameSpace * nameSpace;
5172 delete parentNameSpace.name;
5174 while((nameSpace = (NameSpace *)parentNameSpace.nameSpaces.first))
5176 NameSpace_Free(nameSpace);
5177 parentNameSpace.nameSpaces.Delete((BTNode)nameSpace);
5181 static void Application_Destructor(Application app)
5183 if(app.parsedCommand)
5186 delete app.parsedCommand;
5190 static bool Module_Constructor(Module module)
5192 module.privateNameSpace.classes.CompareKey = (void *)BinaryTree::CompareString;
5193 module.privateNameSpace.defines.CompareKey = (void *)BinaryTree::CompareString;
5194 module.privateNameSpace.functions.CompareKey = (void *)BinaryTree::CompareString;
5195 module.privateNameSpace.nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5197 module.publicNameSpace.classes.CompareKey = (void *)BinaryTree::CompareString;
5198 module.publicNameSpace.defines.CompareKey = (void *)BinaryTree::CompareString;
5199 module.publicNameSpace.functions.CompareKey = (void *)BinaryTree::CompareString;
5200 module.publicNameSpace.nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5204 static void Module_Destructor(Module module)
5207 DefinedExpression def;
5208 GlobalFunction function;
5212 // printf("Destructing module %s\n", module.name);
5214 // Take out references from all modules
5215 for(m = module.application.allModules.first; m; m = m.next)
5218 for(handle = m.modules.first; handle; handle = next)
5221 if(handle.module == module)
5222 m.modules.Delete(handle);
5228 if(module.importType == staticImport)
5230 bool (* Unload)(Module module) = (void *)module.Unload;
5235 bool (stdcall * Unload)(Module module) = (void *)module.Unload;
5240 // Unload dependencies
5242 Module ourWorld = class(Class).module;
5243 void * ourHandle = null;
5244 while((handle = module.modules.last)) // STARTING WITH LAST SO THAT ecereCOM IS UNLOADED LAST...
5246 Module depModule = handle.module;
5247 if(depModule == ourWorld)
5249 module.modules.Remove(handle);
5254 module.modules.Delete(handle);
5266 for(;(_class = module.classes.first);)
5268 if(_class.nameSpace)
5270 BTNamedLink classLink = (BTNamedLink)_class.nameSpace->classes.FindString(_class.name);
5272 for(t = _class.templatized.first; t; t = t.next)
5274 Class template = t.data;
5276 link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
5278 template.nameSpace->classes.Delete((BTNode)link);
5279 template.nameSpace = null;
5281 _class.nameSpace->classes.Delete((BTNode)classLink);
5282 _class.nameSpace = null;
5284 _class.module = null;
5285 module.classes.Remove(_class);
5286 if(!_class.count || _class.type != normalClass)
5287 eClass_Unregister(_class);
5291 // printf("Delayed destruction of class %s\n", _class.name);
5297 for(;(def = module.defines.first);)
5301 BTNamedLink defLink;
5302 for(defLink = (BTNamedLink)def.nameSpace->defines.first; defLink; defLink = (BTNamedLink)((BTNode)defLink).next)
5303 if(defLink.data == def)
5305 def.nameSpace->defines.Delete((BTNode)defLink);
5311 module.defines.Delete(def);
5315 for(;(function = module.functions.first);)
5317 if(function.nameSpace)
5319 BTNamedLink functionLink;
5320 for(functionLink = (BTNamedLink)function.nameSpace->functions.first; functionLink; functionLink = (BTNamedLink)((BTNode)functionLink).next)
5321 if(functionLink.data == function)
5323 function.nameSpace->functions.Delete((BTNode)functionLink);
5327 delete function.name;
5328 delete function.dataTypeString;
5329 module.functions.Delete(function);
5334 NameSpace_Free(module.privateNameSpace);
5335 NameSpace_Free(module.publicNameSpace);
5337 if(module != module.application)
5338 module.application.allModules.Remove(module);
5340 NameSpace_Free(module.application.systemNameSpace);
5343 Instance_Module_Free(module.library);
5347 static int GetEnumSize(Class _class)
5349 EnumClassData data = (EnumClassData)_class.data;
5350 return data.largest+1;
5353 #if defined(__GNUC__)
5354 #define strcmpi strcasecmp
5355 #define strnicmp strncasecmp
5358 #if defined(ECERE_BOOTSTRAP) || (defined(__GNUC__) && !defined(__DJGPP__) && !defined(__WIN32__))
5361 default dllexport char * strlwr(char *string)
5364 for(c=0; string[c]; c++)
5365 if(string[c]>='A' && string[c]<='Z')
5369 default dllexport char * strupr(char *string)
5372 for(c=0; string[c]; c++)
5373 if(string[c]>='a' && string[c]<='z')
5379 public dllexport DefinedExpression eSystem_RegisterDefine(char * name, char * value, Module module, AccessMode declMode)
5381 NameSpace * nameSpace = null;
5385 nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
5386 if(declMode == baseSystemAccess) nameSpace = &module.application.systemNameSpace;
5388 if(declMode != staticAccess)
5390 for(c = 0; name[c]; c++)
5392 if(name[c] == '.' || (name[c] == ':' && name[c+1] == ':'))
5394 NameSpace * newSpace;
5396 char * spaceName = _malloc(c - start + 1);
5397 strncpy(spaceName, name + start, c - start);
5398 spaceName[c-start] = '\0';
5400 newSpace = (NameSpace *)nameSpace->nameSpaces.FindString(spaceName);
5403 newSpace = new0 NameSpace[1];
5404 newSpace->classes.CompareKey = (void *)BinaryTree::CompareString;
5405 newSpace->defines.CompareKey = (void *)BinaryTree::CompareString;
5406 newSpace->functions.CompareKey = (void *)BinaryTree::CompareString;
5407 newSpace->nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5408 newSpace->name = spaceName;
5409 newSpace->parent = nameSpace;
5410 nameSpace->nameSpaces.Add((BTNode)newSpace);
5414 nameSpace = newSpace;
5415 if(name[c] == ':') c++;
5423 if(c - start && !nameSpace->defines.FindString(name + start))
5425 DefinedExpression def
5427 name = CopyString(name);
5428 nameSpace = nameSpace;
5429 value = CopyString(value);
5431 nameSpace->defines.Add((BTNode)BTNamedLink { name = def.name + start, data = def });
5432 // Reference the definition in the module
5433 module.defines.Add(def);
5439 public dllexport GlobalFunction eSystem_RegisterFunction(char * name, char * type, void * func, Module module, AccessMode declMode)
5441 NameSpace * nameSpace = null;
5444 nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
5445 if(declMode == baseSystemAccess) nameSpace = &module.application.systemNameSpace;
5447 if(declMode != staticAccess)
5449 for(c = 0; name[c]; c++)
5451 if(name[c] == '.' || (name[c] == ':' && name[c+1] == ':'))
5453 NameSpace * newSpace;
5455 char * spaceName = _malloc(c - start + 1);
5456 strncpy(spaceName, name + start, c - start);
5457 spaceName[c-start] = '\0';
5459 newSpace = (NameSpace *)nameSpace->nameSpaces.FindString(spaceName);
5462 newSpace = new0 NameSpace[1];
5463 newSpace->classes.CompareKey = (void *)BinaryTree::CompareString;
5464 newSpace->defines.CompareKey = (void *)BinaryTree::CompareString;
5465 newSpace->functions.CompareKey = (void *)BinaryTree::CompareString;
5466 newSpace->nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5467 newSpace->name = spaceName;
5468 newSpace->parent = nameSpace;
5469 nameSpace->nameSpaces.Add((BTNode)newSpace);
5473 nameSpace = newSpace;
5474 if(name[c] == ':') c++;
5482 if(c - start && !nameSpace->functions.FindString(name + start))
5484 GlobalFunction function
5486 name = CopyString(name);
5487 nameSpace = nameSpace;
5488 dataTypeString = CopyString(type);
5492 nameSpace->functions.Add((BTNode)BTNamedLink { name = function.name + start, data = function });
5493 // Reference the definition in the module
5494 module.functions.Add(function);
5500 public dllexport DefinedExpression eSystem_FindDefine(Module module, char * name)
5505 link = SearchNameSpace(&module.application.systemNameSpace, name, &((NameSpace *)0)->defines);
5506 if(link) return link.data;
5508 link = SearchModule(module, name, &((NameSpace *)0)->defines, true);
5509 if(link) return link.data;
5514 public dllexport GlobalFunction eSystem_FindFunction(Module module, char * name)
5519 link = SearchNameSpace(&module.application.systemNameSpace, name, &((NameSpace *)0)->functions);
5520 if(link) return link.data;
5522 link = SearchModule(module, name, &((NameSpace *)0)->functions, true);
5523 if(link) return link.data;
5528 public dllexport void * eSystem_Renew(void * memory, unsigned int size)
5530 return _realloc(memory, size);
5533 public dllexport void * eSystem_Renew0(void * memory, unsigned int size)
5535 return _crealloc(memory, size);
5538 public dllexport void * eSystem_New(unsigned int size)
5541 void * pointer = _malloc(size);
5542 memset(pointer, 0xec, size);
5545 return _malloc(size);
5549 public dllexport void * eSystem_New0(unsigned int size)
5551 return _calloc(1,size);
5554 public dllexport void eSystem_Delete(void * memory)
5561 public dllexport void eInstance_FireSelfWatchers(Instance instance, Property _property)
5563 if(instance && _property && _property.selfWatchable)
5566 for(_class = instance._class; _class; _class = _class.base)
5568 SelfWatcher selfWatcher, next;
5569 for(selfWatcher = _class.selfWatchers.first; selfWatcher; selfWatcher = next)
5571 next = selfWatcher.next;
5572 if(selfWatcher._property == _property)
5573 selfWatcher.callback(instance);
5579 public dllexport void eInstance_FireWatchers(Instance instance, Property _property)
5581 if(instance && _property && _property.isWatchable)
5583 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5584 Watcher watcher, next;
5586 for(watcher = watchers->first; watcher; watcher = next)
5588 next = watcher.next;
5589 watcher.callback(watcher.object, instance);
5594 public dllexport void eProperty_Watchable(Property _property)
5596 if(!_property.isWatchable)
5598 Class _class = _property._class;
5599 if(!_class.computeSize)
5601 _property.watcherOffset = _class.structSize;
5602 _class.structSize += sizeof(OldList);
5604 // highly inefficient
5605 FixDerivativesBase(_class, _class);
5607 _property.isWatchable = true;
5611 public dllexport void eClass_DestructionWatchable(Class _class)
5613 if(!_class.destructionWatchOffset)
5615 _class.destructionWatchOffset = _class.structSize;
5616 _class.structSize += sizeof(OldList);
5617 // highly inefficient
5618 FixDerivativesBase(_class, _class);
5622 public dllexport void eProperty_SelfWatch(Class _class, char * name, void (*callback)(void *))
5626 Property _property = eClass_FindProperty(_class, name, _class.module);
5629 _property = eClass_AddProperty(_class, name, null, null, null, baseSystemAccess /*privateAccess*/);
5630 _class.selfWatchers.Add(SelfWatcher { _property = _property, callback = callback });
5631 _property.selfWatchable = true;
5635 public dllexport void eInstance_Watch(void * instance, Property _property, void * object, void (*callback)(void *, void *))
5637 if(_property.isWatchable)
5639 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5640 watchers->Add(Watcher { callback = callback, object = object });
5644 public dllexport void eInstance_WatchDestruction(Instance instance, Instance object, void (*callback)(Instance, Instance))
5646 OldList * watchers = (OldList *)((byte *)instance + instance._class.destructionWatchOffset);
5647 watchers->Add(Watcher { callback = callback, object = object });
5650 public dllexport void eInstance_StopWatching(Instance instance, Property _property, Instance object)
5652 if(instance && (!_property || _property.isWatchable))
5656 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5658 for(watcher = watchers->first; watcher; watcher = watcher.next)
5659 if(watcher.object == object)
5661 watchers->Delete(watcher);
5667 // Stop watching all properties as well as destruction
5669 for(_class = instance._class; _class; _class = base)
5671 if(_class.destructionWatchOffset)
5673 OldList * watchers = (OldList *)((byte *)instance + _class.destructionWatchOffset);
5676 for(watcher = watchers->first; watcher; watcher = watcher.next)
5678 watchers->Delete(watcher);
5682 for(_property = (Property)_class.membersAndProperties.first; _property; _property = _property.next)
5684 if(_property.isProperty && _property.isWatchable)
5686 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5688 for(watcher = watchers->first; watcher; watcher = watcher.next)
5689 if(watcher.object == object)
5691 watchers->Delete(watcher);
5697 if(base && base.type == systemClass) base = null;
5703 public dllexport subclass(ClassDesignerBase) eClass_GetDesigner(Class _class)
5705 for(;_class;_class = _class.base)
5707 if(_class.designerClass)
5708 return (subclass(ClassDesignerBase))eSystem_FindClass(_class.module, _class.designerClass);
5714 public dllexport subclass(ClassDesignerBase) eInstance_GetDesigner(Instance instance)
5717 return eClass_GetDesigner(instance._class);
5721 public bool LocateModule(char * name, char * fileName)
5723 return Instance_LocateModule(name, fileName);
5726 static void LoadCOM(Module module)
5728 Class applicationClass;
5729 Class enumClass, structClass, boolClass;
5732 // Create Base Class
5733 Class baseClass = eSystem_RegisterClass(normalClass, "class", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5734 baseClass.type = systemClass;
5735 baseClass.memberOffset = 0;
5736 baseClass.offset = 0;
5737 baseClass.structSize = 0;
5738 baseClass.typeSize = 0;
5741 Class instanceClass = eSystem_RegisterClass(normalClass, "ecere::com::Instance", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5742 // Instance should really be a Normal class, but inheritance checks for systemClass to see if something has a non system ancestor
5743 instanceClass.type = systemClass;
5744 instanceClass.fixed = true;
5745 instanceClass.memberOffset = 0;
5746 instanceClass.offset = 0;
5748 instanceClass.memberID = -3;
5749 instanceClass.startMemberID = -3;
5751 // eClass_AddDataMember(instanceClass, "_vTbl", "void **", sizeof(int (**)()), 4, publicAccess);
5752 eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", sizeof(int (**)()), 4, publicAccess);
5753 eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", sizeof(Class), 4, publicAccess);
5754 eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int (**)()), 4, publicAccess);
5757 InitializeDataTypes1(module);
5759 // Create Enum class
5760 enumClass = eSystem_RegisterClass(normalClass, "enum", null, 0, sizeof(class EnumClassData), null, null, module, baseSystemAccess, publicAccess);
5761 eClass_AddClassProperty(enumClass, "enumSize", "int", null, GetEnumSize).constant = true;
5762 enumClass.type = systemClass;
5764 delete enumClass.dataTypeString;
5765 enumClass.dataTypeString = CopyString(/*"unsigned int"*/"int");
5767 // Create Struct (simple) class
5768 //structClass = eSystem_RegisterClass(structClass, "struct", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5769 structClass = eSystem_RegisterClass(normalClass, "struct", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5770 structClass.type = systemClass;
5771 structClass.memberOffset = 0;
5772 structClass.offset = 0;
5773 structClass.structSize = 0;
5774 structClass.typeSize = 0;
5776 //eClass_AddMethod(enumClass, "AddValue", "int()", eEnum_AddValue);
5777 //eClass_AddMethod(enumClass, "AddFixedValue", "void()", eEnum_AddFixedValue);
5779 InitializeDataTypes(module);
5781 // Create bool class
5782 boolClass = eSystem_RegisterClass(ClassType::enumClass, "bool", "uint", 0, 0, null, null, module, baseSystemAccess, publicAccess);
5783 eEnum_AddFixedValue(boolClass, "true", bool::true);
5784 eEnum_AddFixedValue(boolClass, "false", bool::false);
5786 // Create Module class
5787 moduleClass = eSystem_RegisterClass(normalClass, "ecere::com::Module", null, sizeof(struct Module), 0, (void *)Module_Constructor, (void *)Module_Destructor, module, baseSystemAccess, publicAccess);
5788 eClass_AddVirtualMethod(moduleClass, "OnLoad", "bool()", null, publicAccess);
5789 eClass_AddVirtualMethod(moduleClass, "OnUnload", "void()", null, publicAccess);
5790 eClass_AddMethod(moduleClass, "Load", "Module(char * name, AccessMode importAccess)", eModule_Load, publicAccess);
5791 eClass_AddMethod(moduleClass, "Unload", "void(Module module)", eModule_Unload, publicAccess);
5792 eClass_AddDataMember(moduleClass, "application", "Application", sizeof(Application), 4, publicAccess);
5793 eClass_AddDataMember(moduleClass, "classes", "OldList", sizeof(OldList), 4, publicAccess);
5794 eClass_AddDataMember(moduleClass, "defines", "OldList", sizeof(OldList), 4, publicAccess);
5795 eClass_AddDataMember(moduleClass, "functions", "OldList", sizeof(OldList), 4, publicAccess);
5796 eClass_AddDataMember(moduleClass, "modules", "OldList", sizeof(OldList), 4, publicAccess);
5797 eClass_AddDataMember(moduleClass, "prev", "Module", sizeof(Module), 4, publicAccess);
5798 eClass_AddDataMember(moduleClass, "next", "Module", sizeof(Module), 4, publicAccess);
5799 eClass_AddDataMember(moduleClass, "name", "char *", sizeof(char *), 4, publicAccess);
5800 eClass_AddDataMember(moduleClass, "library", "void *", sizeof(void *), 4, publicAccess);
5801 eClass_AddDataMember(moduleClass, "Unload", "void *", sizeof(void *), 4, publicAccess);
5802 eClass_AddDataMember(moduleClass, "importType", "ImportType", sizeof(ImportType), 4, publicAccess);
5803 eClass_AddDataMember(moduleClass, "privateNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
5804 eClass_AddDataMember(moduleClass, "publicNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
5805 moduleClass.fixed = true;
5806 moduleClass.count++;
5808 // Create Application class
5809 applicationClass = eSystem_RegisterClass(normalClass, "ecere::com::Application", "Module", sizeof(struct Application), 0, null, (void *)Application_Destructor, module, baseSystemAccess, publicAccess);
5810 eClass_AddVirtualMethod(applicationClass, "Main", "void()", null, publicAccess);
5811 eClass_AddDataMember(applicationClass, "argc", "int", sizeof(int), 4, publicAccess);
5812 eClass_AddDataMember(applicationClass, "argv", "char **", sizeof(char **), 4, publicAccess);
5813 eClass_AddDataMember(applicationClass, "exitCode", "int", sizeof(int), 4, publicAccess);
5814 eClass_AddDataMember(applicationClass, "isGUIApp", "bool", sizeof(bool), 4, publicAccess);
5815 eClass_AddDataMember(applicationClass, "allModules", "OldList", sizeof(OldList), 4, publicAccess);
5816 eClass_AddDataMember(applicationClass, "parsedCommand", "char *", sizeof(char *), 4, publicAccess);
5817 eClass_AddDataMember(applicationClass, "systemNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
5818 applicationClass.fixed = true;
5819 applicationClass.count++;
5821 //AttachConsole(-1);
5825 eSystem_RegisterFunction("sin", "double sin(Angle number)", sin, module, baseSystemAccess);
5826 eSystem_RegisterFunction("sinh", "double sinh(Angle number)", sinh, module, baseSystemAccess);
5827 eSystem_RegisterFunction("cosh", "double cosh(Angle number)", cosh, module, baseSystemAccess);
5828 eSystem_RegisterFunction("tanh", "double tanh(Angle number)", tanh, module, baseSystemAccess);
5829 eSystem_RegisterFunction("sqrt", "double sqrt(double number)", sqrt, module, baseSystemAccess);
5830 eSystem_RegisterFunction("cos", "double cos(Angle number)", cos, module, baseSystemAccess);
5831 eSystem_RegisterFunction("tan", "double tan(Angle number)", tan, module, baseSystemAccess);
5832 eSystem_RegisterFunction("atan2", "Angle atan2(double y, double x)", atan2, module, baseSystemAccess);
5833 eSystem_RegisterFunction("asin", "Angle asin(double number)", asin, module, baseSystemAccess);
5834 eSystem_RegisterFunction("acos", "Angle acos(double number)", acos, module, baseSystemAccess);
5835 eSystem_RegisterFunction("atan", "Angle atan(double number)", atan, module, baseSystemAccess);
5836 eSystem_RegisterFunction("pow", "double pow(double number, double number2)", pow, module, baseSystemAccess);
5837 eSystem_RegisterFunction("fmod", "double fmod(double x, double y)", fmod, module, baseSystemAccess);
5838 eSystem_RegisterFunction("fabs", "double fabs(double number)", fabs, module, baseSystemAccess);
5839 eSystem_RegisterFunction("log", "double log(double number)", log, module, baseSystemAccess);
5840 eSystem_RegisterFunction("log10", "double log10(double number)", log10, module, baseSystemAccess);
5841 eSystem_RegisterFunction("ceil", "double ceil(double number)", ceil, module, baseSystemAccess);
5842 eSystem_RegisterFunction("floor", "double floor(double number)", floor, module, baseSystemAccess);
5843 eSystem_RegisterFunction("exp", "double exp(double number)", exp, module, baseSystemAccess);
5846 eSystem_RegisterFunction("qsort", "void qsort(void *, uint, uint, int (*)(void *, void *))", qsort, module, baseSystemAccess);
5847 eSystem_RegisterFunction("strtod", "double strtod(char*, char**)", strtod, module, baseSystemAccess);
5848 eSystem_RegisterFunction("strtol", "int strtol(char*, char**, int base)", strtol, module, baseSystemAccess);
5849 eSystem_RegisterFunction("system", "int system(const char*)", system, module, baseSystemAccess);
5850 eSystem_RegisterFunction("atoi", "int atoi(const char*)", atoi, module, baseSystemAccess);
5851 eSystem_RegisterFunction("atof", "float atof(const char*)", atof, module, baseSystemAccess);
5852 eSystem_RegisterFunction("tolower", "int tolower(int)", tolower, module, baseSystemAccess);
5853 eSystem_RegisterFunction("toupper", "int toupper(int)", toupper, module, baseSystemAccess);
5854 eSystem_RegisterFunction("isdigit", "bool isdigit(int)", isdigit, module, baseSystemAccess);
5855 eSystem_RegisterFunction("memset", "void memset(void * area, byte value, uint count)", memset, module, baseSystemAccess);
5856 eSystem_RegisterFunction("getenv", "char * getenv(const char * name)", getenv, module, baseSystemAccess);
5857 eSystem_RegisterFunction("rename", "int rename(const char *oldpath, const char *newpath)", rename, module, baseSystemAccess);
5859 // --- String --- (These might move to the string class)
5860 eSystem_RegisterFunction("strlen", "int strlen(const char *)", strlen, module, baseSystemAccess);
5861 eSystem_RegisterFunction("strcat", "char * strcat(char *, const char *)", strcat, module, baseSystemAccess);
5862 eSystem_RegisterFunction("strncat", "char * strncat(char *, const char *, int n)", strncat, module, baseSystemAccess);
5863 eSystem_RegisterFunction("strchr", "char * strchr(char *, int)", strchr, module, baseSystemAccess);
5864 eSystem_RegisterFunction("strstr", "char * strstr(char *, const char *)", strstr, module, baseSystemAccess);
5866 eSystem_RegisterDefine("fstrcmp", "(GetRuntimePlatform() == win32) ? strcmpi : strcmp", module, baseSystemAccess);
5868 //#if defined(__GNUC__)
5869 eSystem_RegisterDefine("strcmpi", "strcasecmp", module, baseSystemAccess);
5870 eSystem_RegisterDefine("strnicmp", "strncasecmp", module, baseSystemAccess);
5871 eSystem_RegisterFunction("strcasecmp", "int strcasecmp(const char *, const char *)", strcmpi, module, baseSystemAccess);
5872 eSystem_RegisterFunction("strncasecmp", "int strncasecmp(const char *, const char *, int n)", strnicmp, module, baseSystemAccess);
5875 eSystem_RegisterDefine("strcasecmp", "strcmpi", module, baseSystemAccess);
5876 eSystem_RegisterDefine("strncasecmp", "strnicmp", module, baseSystemAccess);
5877 eSystem_RegisterFunction("strcmpi", "int strcmpi(const char *, const char *)", strcmpi, module, baseSystemAccess);
5878 eSystem_RegisterFunction("strnicmp", "int strnicmp(const char *, const char *, int n)", strnicmp, module, baseSystemAccess);
5882 eSystem_RegisterFunction("strcmp", "int strcmp(const char *, const char *)", strcmp, module, baseSystemAccess);
5883 eSystem_RegisterFunction("strncmp", "int strncmp(const char *, const char *, int n)", strncmp, module, baseSystemAccess);
5884 eSystem_RegisterFunction("strlwr", "char * strlwr(char *)", strlwr, module, baseSystemAccess);
5885 eSystem_RegisterFunction("strupr", "char * strupr(char *)", strupr, module, baseSystemAccess);
5886 eSystem_RegisterFunction("strcpy", "char * strcpy(char *, const char *)", strcpy, module, baseSystemAccess);
5887 eSystem_RegisterFunction("strncpy", "char * strncpy(char *, const char *, int n)", strncpy, module, baseSystemAccess);
5888 eSystem_RegisterFunction("memcpy", "void * memcpy(void *, const void *, uint size)", memcpy, module, baseSystemAccess);
5889 eSystem_RegisterFunction("memmove", "void * memmove(void *, const void *, uint size)", memmove, module, baseSystemAccess);
5892 eSystem_RegisterFunction("sprintf", "int sprintf(char *, char *, ...)", sprintf, module, baseSystemAccess);
5893 eSystem_RegisterFunction("printf", "int printf(char *, ...)", printf, module, baseSystemAccess);
5894 eSystem_RegisterFunction("vsprintf", "int vsprintf(char*, const char*, __builtin_va_list)", vsprintf, module, baseSystemAccess);
5895 eSystem_RegisterFunction("puts", "int puts(char *)", puts, module, baseSystemAccess);
5896 eSystem_RegisterFunction("fputs", "int fputs(char *, void * stream)", fputs, module, baseSystemAccess);
5899 eSystem_RegisterFunction("isalnum", "int isalnum(int c)", isalnum, module, baseSystemAccess);
5900 eSystem_RegisterFunction("isspace", "int isspace(int c)", isspace, module, baseSystemAccess);
5901 eSystem_RegisterFunction("isalpha", "int isalpha(int c)", isalpha, module, baseSystemAccess);
5902 eSystem_RegisterFunction("islower", "int islower(int c)", islower, module, baseSystemAccess);
5903 eSystem_RegisterFunction("isupper", "int isupper(int c)", isupper, module, baseSystemAccess);
5904 eSystem_RegisterFunction("isprint", "int isprint(int c)", isprint, module, baseSystemAccess);
5905 eSystem_RegisterFunction("strtoul", "unsigned long strtoul(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
5909 public dllexport Application __ecere_COM_Initialize(bool guiApp, int argc, char * argv[])
5914 // printf("Using debug ecere runtime library\n");
5916 app = _calloc(1, sizeof(class Application));
5918 Module_Constructor(app);
5919 app.systemNameSpace.classes.CompareKey = (void *)BinaryTree::CompareString;
5920 app.systemNameSpace.defines.CompareKey = (void *)BinaryTree::CompareString;
5921 app.systemNameSpace.functions.CompareKey = (void *)BinaryTree::CompareString;
5922 app.systemNameSpace.nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5924 Instance_COM_Initialize(argc, argv, &app.parsedCommand, &app.argc, &app.argv);
5926 app.application = app;
5927 app.allModules.offset = sizeof(class Instance) + (uint)&((struct Module *)0)->prev;
5928 app.isGUIApp = guiApp;
5932 app._class = eSystem_FindClass(app, "Application");
5937 public dllexport ClassTemplateParameter eClass_AddTemplateParameter(Class _class, char * name, TemplateParameterType type, void * info, ClassTemplateArgument defaultArg)
5941 ClassTemplateParameter param;
5943 for(param = _class.templateParams.first; param; param = param.next)
5945 if(!strcmp(param.name, name))
5950 name = CopyString(name);
5952 (type == identifier) ? info : CopyString(info);
5954 if(defaultArg != null)
5956 param.defaultArg = defaultArg;
5957 CopyTemplateArg(param, param.defaultArg);
5959 _class.templateParams.Add(param);
5965 public dllexport void eClass_DoneAddingTemplateParameters(Class base)
5970 ClassTemplateParameter param;
5972 void * first = base.templateParams.first;
5973 int count = base.templateParams.count;
5974 base.templateParams.first = null;
5975 base.templateParams.count = 0;
5977 FreeTemplateArgs(base);
5978 delete base.templateArgs;
5979 FreeTemplatesDerivatives(base);
5981 base.templateParams.first = first;
5982 base.templateParams.count = count;
5985 for(param = base.templateParams.first; param; param = param.next)
5987 if(param.type == identifier && param.defaultArg.memberString)
5989 Class memberClass = base;
5990 char * colon = strstr(param.defaultArg.memberString, "::");
5994 char className[1024];
5997 memcpy(className, param.defaultArg.memberString, colon - param.defaultArg.memberString);
5998 className[colon - param.defaultArg.memberString] = '\0';
5999 memberName = colon + 2;
6001 for(sClass = base; sClass; sClass = sClass.base)
6003 ClassTemplateParameter cParam;
6006 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base) id += nextClass.templateParams.count;
6007 // Safety! What could cause base.templateArgs to be null?
6008 if(sClass == base || base.templateArgs)
6010 for(cParam = sClass.templateParams.first; cParam; cParam = cParam.next)
6012 if(cParam.type == type && !strcmp(cParam.name, className))
6013 strcpy(className, (sClass == base) ? cParam.defaultArg.dataTypeString : base.templateArgs[id].dataTypeString);
6018 memberClass = eSystem_FindClass(base.module, className);
6020 memberClass = eSystem_FindClass(base.module.application, className);
6023 memberName = param.defaultArg.memberString;
6027 switch(param.memberType)
6030 param.defaultArg.member = eClass_FindDataMember(memberClass, memberName, memberClass.module, null, null);
6033 param.defaultArg.method = eClass_FindMethod(memberClass, memberName, memberClass.module);
6036 param.defaultArg.prop = eClass_FindProperty(memberClass, memberName, memberClass.module);
6043 //ComputeClassParameters(base, null, null);
6045 FixDerivativesBase(base, base);
6049 static void FreeTemplatesDerivatives(Class base)
6051 OldLink derivative, templateLink;
6052 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
6054 Class _class = derivative.data;
6055 if(_class.templateArgs)
6057 FreeTemplateArgs(_class);
6058 delete _class.templateArgs;
6060 FreeTemplatesDerivatives(_class);
6063 for(templateLink = base.templatized.first; templateLink; templateLink = templateLink.next)
6065 Class _class = templateLink.data;
6066 if(_class.templateArgs)
6068 FreeTemplateArgs(_class);
6069 delete _class.templateArgs;
6071 FreeTemplatesDerivatives(_class);
6075 static const char * platformNames[Platform] = { "", "win32", "linux", "apple" }; // how to have this be accessible outside of dll/lib
6076 static const Platform firstPlatform = win32;
6077 static const Platform lastPlatform = apple;
6079 public enum Platform
6081 unknown, win32, tux, apple;
6085 get { return OnGetString(null, null, null); }
6091 for(c = firstPlatform; c <= lastPlatform; c++)
6092 if(!strcmpi(value, platformNames[c]))
6099 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
6101 if(this >= firstPlatform && this <= lastPlatform)
6104 strcpy(tempString, platformNames[this]);
6105 return platformNames[this];
6107 if(tempString && tempString[0])
6108 tempString[0] = '\0';
6112 bool OnGetDataFromString(char * string)
6119 default extern Platform runtimePlatform;
6121 public Platform GetRuntimePlatform()
6123 return runtimePlatform;
6131 // CLASS DESIGNER SUPPORT
6133 public class ObjectInfo : struct
6136 ObjectInfo prev, next;
6139 Instantiation instCode;
6143 ClassDefinition classDefinition;
6147 public class DesignerBase : Window
6150 virtual bool FindObject(Instance * instance, char * string);
6151 virtual void RenameObject(ObjectInfo object, char * name);
6152 virtual void SelectObjectFromDesigner(ObjectInfo object);
6153 virtual void CodeAddObject(Instance instance, ObjectInfo * object);
6154 virtual void SheetAddObject(ObjectInfo object);
6155 virtual void AddToolBoxClass(Class _class);
6156 virtual void AddDefaultMethod(Instance instance, Instance classInstance);
6157 virtual void DeleteObject(ObjectInfo object);
6158 virtual bool ObjectContainsCode(ObjectInfo object);
6159 virtual void ModifyCode(void);
6160 virtual void UpdateProperties(void);
6162 ClassDesignerBase classDesigner;
6166 // FIX THIS WITH PUBLIC:
6167 property ClassDesignerBase classDesigner
6169 get { return classDesigner; }
6170 set { classDesigner = value; }
6172 property char * objectClass
6174 get { return objectClass; }
6175 set { objectClass = value; }
6177 property bool isDragging
6179 get { return isDragging; }
6180 set { isDragging = value; }
6184 public class ClassDesignerBase : Window
6187 virtual void Reset(void);
6188 virtual void AddObject(void);
6189 virtual void SelectObject(ObjectInfo object, Instance control);
6191 virtual void ListToolBoxClasses(DesignerBase designer);
6193 virtual void ::PrepareTestObject(DesignerBase designer, Instance test);
6194 virtual void ::CreateObject(DesignerBase designer, Instance instance, ObjectInfo object, bool isClass, Instance _class);
6195 virtual void ::PostCreateObject(Instance instance, ObjectInfo object, bool isClass, Instance _class);
6196 virtual void ::DroppedObject(Instance instance, ObjectInfo object, bool isClass, Instance _class);
6197 virtual void ::DestroyObject(Instance object);
6198 virtual void ::FixProperty(Property prop, Instance object);
6199 virtual void ::CreateNew(EditBox editBox, Size clientSize, char * name, char * inherit);
6202 DesignerBase activeDesigner;
6204 public void SetActiveDesigner(DesignerBase designer)
6206 activeDesigner = designer;
6209 public DesignerBase GetActiveDesigner()
6211 return activeDesigner;
6217 define LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
6218 define SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00;
6220 public bool UTF8Validate(char * source)
6225 for(c = 0; source[c];)
6227 byte ch = source[c];
6228 unichar codePoint = 0;
6254 for(i = 0; i<numBytes && (ch = source[c]); i++, c++)
6257 codePoint |= ch & mask;
6261 if(!(ch & 0x80) || (ch & 0x40))
6265 if(i < numBytes) return false;
6267 if(codePoint > 0x10FFFF || (codePoint >= 0xD800 && codePoint <= 0xDFFF) ||
6268 (codePoint < 0x80 && numBytes > 1) ||
6269 (codePoint < 0x800 && numBytes > 2) ||
6270 (codePoint < 0x10000 && numBytes > 3))
6277 public int ISO8859_1toUTF8(char * source, char * dest, int max)
6281 for(c = 0; source[c]; c++)
6283 unichar ch = ((byte *)source)[c];
6286 if(d + 1 >= max) break;
6287 dest[d++] = (char)ch;
6291 if(d + 2 >= max) break;
6292 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6293 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6295 else if(ch < 0x10000)
6297 if(d + 3 >= max) break;
6298 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6299 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6300 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6304 if(d + 4 >= max) break;
6305 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6306 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6307 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6308 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6315 public char * UTF16toUTF8(uint16 * source)
6322 bool invert = false;
6324 for(len = 0; source[len]; len++);
6325 dest = new char[len * 3 + 1];
6326 for(c = 0; (u16 = source[c]); c++)
6329 if(!c && (u16 == 0xFFFE || u16 == 0xFEFF))
6331 if(u16 == 0xFFFE) invert = true;
6334 if(invert) { u16 = ((u16 & 0xFF00) >> 8) | ((u16 & 0x00FF) << 8); }
6336 if(u16 < 0xD800 || u16 > 0xDBFF)
6339 ch = ((unichar)u16 << 10) + source[c++] + SURROGATE_OFFSET;
6343 dest[d++] = (char)ch;
6347 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6348 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6350 else if(ch < 0x10000)
6352 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6353 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6354 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6358 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6359 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6360 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6361 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6365 dest = renew dest char[d+1];
6369 public int UTF16toUTF8Buffer(uint16 * source, byte * dest, int max)
6374 for(c = 0; (u16 = source[c]); c++)
6377 if(u16 < 0xD800 || u16 > 0xDBFF)
6380 ch = ((unichar)u16 << 10) + source[c++] + SURROGATE_OFFSET;
6384 if(d + 1 >= max) break;
6385 dest[d++] = (char)ch;
6389 if(d + 2 >= max) break;
6390 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6391 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6393 else if(ch < 0x10000)
6395 if(d + 3 >= max) break;
6396 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6397 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6398 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6402 if(d + 4 >= max) break;
6403 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6404 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6405 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6406 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6413 public unichar UTF8GetChar(char * string, int * numBytes)
6416 byte b = ((byte *)string)[0];
6433 if(b & 0x08) { nb = 0; }
6442 for(i = 0; i<nb; i++)
6445 ch |= (b = ((byte *)string)[i]) & mask;
6447 if(i > 1 && (!(b & 0x80) || (b & 0x40)))
6455 ch > 0x10FFFF || (ch >= 0xD800 && ch <= 0xDFFF) ||
6456 (ch < 0x80 && nb > 1) ||
6457 (ch < 0x800 && nb > 2) ||
6458 (ch < 0x10000 && nb > 3))
6463 if(numBytes) *numBytes = nb;
6467 public int UTF8toUTF16Buffer(char * source, uint16 * dest, int max)
6473 for(c = 0; source[c];)
6475 byte ch = source[c];
6476 unichar codePoint = 0;
6480 if(ch & 0x80 && ch & 0x40)
6495 for(i = 0; i<numBytes; i++)
6498 codePoint |= source[c++] & mask;
6502 if(codePoint > 0xFFFF)
6504 uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
6505 uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
6506 if(d >= max - 1) break;
6513 dest[d++] = (uint16)codePoint;
6522 public int UTF32toUTF8Len(unichar * source, int count, byte * dest, int max)
6527 for(c = 0; c<count && (ch = source[c]); c++)
6531 if(d + 1 >= max) break;
6532 dest[d++] = (char)ch;
6536 if(d + 2 >= max) break;
6537 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6538 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6540 else if(ch < 0x10000)
6542 if(d + 3 >= max) break;
6543 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6544 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6545 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6549 if(d + 4 >= max) break;
6550 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6551 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6552 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6553 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6560 public uint16 * UTF8toUTF16(char * source, int * wordCount)
6564 int len = strlen(source);
6565 uint16 * dest = new uint16[len + 1];
6568 for(c = 0; source[c];)
6570 byte ch = source[c];
6571 unichar codePoint = 0;
6575 if(ch & 0x80 && ch & 0x40)
6590 for(i = 0; i<numBytes; i++)
6593 codePoint |= source[c++] & mask;
6597 if(codePoint > 0xFFFF)
6599 uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
6600 uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
6606 dest[d++] = (uint16)codePoint;
6610 if(wordCount) *wordCount = d;