8 #if defined(ECERE_BOOTSTRAP) || defined(ECERE_STATIC)
13 #if !defined(ECERE_BOOTSTRAP)
19 // #define REDZONE 256
26 static define MAX_MEMORY_LOC = 40;
28 static class MemStack : BTNode
35 static BinaryTree memStacks { };
36 static uint memoryErrorsCount = 0;
41 #define property _property
60 public define null = ((void *)0);
62 dllexport Class eSystem_FindClass(Module module, char * name);
63 dllexport void * eSystem_Renew(void * memory, unsigned int size);
64 dllexport void * eSystem_Renew0(void * memory, unsigned int size);
65 dllexport void * eSystem_New(unsigned int size);
66 dllexport void * eSystem_New0(unsigned int size);
67 dllexport void eSystem_Delete(void * memory);
68 dllexport void * eInstance_New(Class _class);
71 extern int __ecereVMethodID_class_OnGetDataFromString;
73 // IMPLEMENTATION FOR THESE IN _instance.c:
74 bool Instance_LocateModule(char * name, char * fileName);
75 void Instance_COM_Initialize(int argc, char ** argv, char ** parsedCommand, int * argcPtr, char *** argvPtr);
76 void * Instance_Module_Load(char * name, void ** Load, void ** Unload);
77 void Instance_Module_Free(void * library);
81 public class unichar : uint32
84 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
86 UTF32toUTF8Len(&this, 1, tempString, 5);
90 bool OnGetDataFromString(char * string)
93 this = UTF8GetChar(string, &nb);
99 public class Property : struct
106 AccessMode memberAccess;
109 char * dataTypeString;
123 bool selfWatchable, isWatchable;
126 dllexport void eInstance_FireWatchers(Instance instance, Property _property);
128 public dllexport void MemoryGuard_PushLoc(char * loc)
133 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
136 stack = (MemStack)calloc(1, sizeof(class MemStack));
137 stack.key = GetCurrentThreadID();
138 memStacks.Add(stack);
141 stack.frames[stack.pos++] = loc;
148 public dllexport void MemoryGuard_PopLoc()
153 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
154 if(stack && stack.pos > 0)
166 #ifdef ECERE_COM_ONLY
168 #define COM_LOAD_FUNCTION __ecereDll_Load_ecereCOM
169 #define COM_UNLOAD_FUNCTION __ecereDll_Unload_ecereCOM
173 #define COM_LOAD_FUNCTION __ecereDll_Load_ecere
174 #define COM_UNLOAD_FUNCTION __ecereDll_Unload_ecere
180 #define COM_LOAD_FUNCTION __ecereDll_Load
181 #define COM_UNLOAD_FUNCTION __ecereDll_Unload
187 extern bool stdcall COM_LOAD_FUNCTION(Module module);
188 extern void stdcall COM_UNLOAD_FUNCTION(Module module);
192 public class BTNamedLink : struct
197 BTNamedLink parent, left, right;
202 class SelfWatcher : struct
205 SelfWatcher prev, next;
206 void (*callback)(Instance);
210 public enum AccessMode
219 public class SubModule : struct
222 SubModule prev, next;
224 AccessMode importMode;
227 public enum DataMemberType { normalMember, unionMember, structMember };
229 public enum ClassType
237 unionClass, // Temporary only in firstPass
241 public class Class : struct
248 int offset, structSize;
251 int (*Constructor)(Instance);
252 void (*Destructor)(Instance);
254 int offsetClass, sizeClass;
259 OldList membersAndProperties;
260 BinaryTree classProperties;
262 int memberID, startMemberID;
265 NameSpace * nameSpace;
266 char * dataTypeString;
269 int defaultAlignment;
270 void (*Initialize)();
272 OldList selfWatchers;
273 char * designerClass;
275 char * defaultProperty;
276 bool comRedefinition;
278 int count; // DEBUGGING
285 int destructionWatchOffset;
287 OldList delayedCPValues;
288 AccessMode inheritanceAccess;
293 OldList templateParams;
294 ClassTemplateArgument * templateArgs;
304 Class theClass = eSystem_FindClass(__thisModule, value);
307 theClass = eSystem_FindClass(__thisModule.application, value);
313 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
318 bool OnGetDataFromString(char * string)
321 theClass = eSystem_FindClass(__thisModule, string);
323 theClass = eSystem_FindClass(__thisModule.application, string);
324 this = (void *)theClass;
325 return theClass != null;
328 void OnSerialize(IOChannel channel)
330 channel.Serialize(fullName);
338 void OnUnserialize(IOChannel channel)
342 channel.Unserialize(string);
343 theClass = eSystem_FindClass(__thisModule, string);
345 theClass = eSystem_FindClass(__thisModule.application, string);
347 this = (void *)theClass;
352 public enum TemplateParameterType { type, identifier, expression };
353 public enum TemplateMemberType { dataMember, method, prop };
355 public struct ClassTemplateArgument
363 char * dataTypeString;
368 DataValue expression;
384 public class ClassTemplateParameter : struct
388 ClassTemplateParameter prev, next;
390 TemplateParameterType type;
393 // Class baseClass; // For type
394 char * dataTypeString; // For expression
395 TemplateMemberType memberType; // For identifier
397 ClassTemplateArgument defaultArg;
398 void * param; // To attach to Compiler TemplateParameter
402 public class Module : struct
409 // So we can clean them up
418 void (stdcall * Unload)(Module module);
419 ImportType importType;
421 NameSpace privateNameSpace;
422 NameSpace publicNameSpace;
425 public class Application : Module
434 char * parsedCommand;
435 NameSpace systemNameSpace;
438 public enum MethodType { normalMethod, virtualMethod };
440 public class Method : struct
445 Method parent, left, right;
448 int vid; // For METHOD_VIRTUAL: Index into the class virtual table
452 char * dataTypeString;
454 AccessMode memberAccess;
457 public enum ImportType
463 // For internal usage in the compiler:
468 public struct NameSpace
471 NameSpace * btParent, * left, * right;
475 BinaryTree nameSpaces;
478 BinaryTree functions;
481 public union DataValue
496 public class DataMember : struct
500 DataMember prev, next;
503 AccessMode memberAccess;
506 char * dataTypeString;
514 BinaryTree membersAlpha;
519 public class BitMember : struct
523 BitMember prev, next;
526 AccessMode memberAccess;
529 char * dataTypeString;
539 public class ClassProperty : struct
544 ClassProperty parent, left, right;
546 void (*Set)(Class, int);
548 char * dataTypeString;
553 public class DefinedExpression : struct
557 DefinedExpression prev, next;
560 NameSpace * nameSpace;
563 public class GlobalFunction : struct
567 GlobalFunction prev, next;
571 NameSpace * nameSpace;
572 char * dataTypeString;
577 public class EnumClassData : struct
585 class Watcher : struct
589 void (*callback)(Instance, Instance);
594 static class MemInfo : BTNode //struct
600 MemInfo parent, left, right;
609 char * allocLoc[MAX_MEMORY_LOC];
610 char * freeLoc[MAX_MEMORY_LOC];
613 void OutputStacks(bool showFree)
618 printf("Object of class %s\n", _class);
619 printf(" Allocation Stack:\n");
620 for(c = 0; c<MAX_MEMORY_LOC; c++)
621 if(allocLoc[c] && allocLoc[c] != (void *)0xabababab)
622 printf(" %s\n", allocLoc[c]);
626 printf(" Free Location Stack:\n");
627 for(c = 0; c<MAX_MEMORY_LOC; c++)
629 printf(" %s\n", freeLoc[c]);
635 static BinaryTree memBlocks;
637 bool recurse = false;
639 //Class allocateClass;
640 char * allocateClass;
641 bool allocateInternal;
645 static uint TOTAL_MEM = 0;
646 static uint OUTSIDE_MEM = 0;
648 #if !defined(ECERE_BOOTSTRAP)
649 static Mutex memMutex { };
652 private class MemBlock : struct
659 private class MemPart : struct
668 #define NEXT_SIZE(s) NextFibonacci(s)
669 #define SIZE_POSITION(s) PosFibonacci(s)
670 #define NTH_SIZE(p) NthFibonacci(p)
672 static uint initNumBlocks[NUM_POOLS] =
708 #define NEXT_SIZE(s) pow2i(s)
709 #define SIZE_POSITION(s) log2i(s)
710 #define NTH_SIZE(p) (1<<p)
713 4000, // 1024, // 2 bytes
714 2500, // 1024, // 4 bytes
715 18000, //1024, // 8 bytes
716 20000, //1024, // 16 bytes
717 29000, //1024, // 32 bytes
718 46000, //1024, // 64 bytes
719 20000, //1024, // 128 bytes
720 26000, //512, // 256 bytes
721 1400, //256, // 512 bytes
725 static uint initNumBlocks[NUM_POOLS] =
751 #define NEXT_SIZE(s) pow1_5i(s)
752 #define SIZE_POSITION(s) log1_5i(s)
753 #define NTH_SIZE(p) pow1_5(p)
755 static int power15[] =
828 private struct BlockPool
830 MemBlock first, last;
840 bool Expand(uint numBlocks)
842 byte * memory = malloc(numBlocks * blockSpace);
843 // byte * memory = calloc(1, numBlocks * blockSpace);
844 TOTAL_MEM += numBlocks * blockSpace;
846 /*if(blockSize == 28)
847 printf("Expanding pool %x (%d)\n", this, blockSize);*/
853 uint totalAvailable = 0, totalAllocated = 0, totalBlocks = 0, totalUsed = 0;
856 MemBlock block = (MemBlock)memory;
857 MemPart part = calloc(1, sizeof(class MemPart));
858 TOTAL_MEM += sizeof(class MemPart);
860 for(c = 0; c<numBlocks - 1; c++)
862 // block.pool = this;
865 printf("WARNING! part.size < 0\n");*/
867 block.next = (MemBlock)((byte *)block + blockSpace);
872 part.memory = memory;
873 part.size = numBlocks;
875 // block.pool = this;
878 printf("/! part.size < 0\n");
879 if(part.pool == (void*) -1)
880 printf("WARNING! pool is -1\n");*/
884 /*if(free && free.part && (free.part.size < 0 || free.part.pool == (void *)-1))
885 printf("WARNING! Bad next free block!\n");*/
887 //parts = realloc(parts, sizeof(MemPart) * (numParts + 1));
889 totalSize += numBlocks;
894 for(c = 0; c<NUM_POOLS; c++)
896 BlockPool * pool = &pools[c];
897 printf("[%d %s (%d)]: available: %d, allocated: %d, free: %d, used: %d k, wasted: %d k, free: %d k\n", c, (&pools[c] == this) ? "*" : " ",
898 pools[c].blockSize, pools[c].totalSize, pools[c].numBlocks,
899 pools[c].totalSize - pools[c].numBlocks, pools[c].usedSpace / 1024, ((pools[c].numBlocks * pools[c].blockSize) - pools[c].usedSpace) / 1024,
900 (pools[c].totalSize - pools[c].numBlocks) * pools[c].blockSize / 1024);
901 totalAvailable += pools[c].totalSize * pools[c].blockSize;
902 totalAllocated += pools[c].numBlocks * pools[c].blockSize;
903 totalUsed += pools[c].usedSpace;
904 totalBlocks += pools[c].totalSize;
905 totalParts += pools[c].numParts;
907 printf("Total Available %d k, Total Allocated: %d k, Total Free: %d k\n", totalAvailable / 1024, totalAllocated / 1024, (totalAvailable - totalAllocated) / 1024);
908 printf("Total Number of Blocks %d, overhead of %d k\n", totalBlocks, totalBlocks * sizeof(class MemBlock) / 1024);
909 printf("Total Used Space %d k, wasted from roundup: %d k\n", totalUsed / 1024, (totalAllocated - totalUsed) / 1024);
910 printf("Total Memory Parts: %d\n", totalParts);
911 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);
925 MemBlock block = null;
926 /*if(blockSize == 28)
927 printf("BlockPool::Add (%d)\n", blockSize);*/
929 Expand(Max(1, numBlocks / 2));
935 block.prev.next = block;
940 /*if(blockSize == 28)
941 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,
942 (free && free.part) ? free.part.size : 0, (free && free.part) ? free.part.pool : 0, this,
943 (free ? free.next : 0), (free && free.next) ? free.next.part : 0);
944 if(free && free.part && (free.part.size < 0 || free.part.pool == (void *)-1))
945 printf("WARNING! Bad next free block!\n");*/
949 block.part.blocksUsed++;
959 void Remove(MemBlock block)
961 /*if(blockSize == 28)
962 printf("BlockPool::Remove (%d)\n", blockSize);*/
964 block.prev.next = block.next;
966 block.next.prev = block.prev;
973 // block.prev = null;
977 /*if(blockSize == 28)
979 printf("Setting new free block: part = %x\n", block.part);
982 block.part.blocksUsed--;
984 block.part.pool->usedSpace -= block.size;
986 if(!block.part.blocksUsed && numBlocks && totalSize > numBlocks + numBlocks / 2)
988 MemBlock next = free, prev = null;
989 MemPart part = block.part;
991 totalSize -= part.size;
992 /*if(blockSize == 28)
993 printf("Freeing a part\n");*/
996 if(next.part != part)
1009 TOTAL_MEM -= part.size * blockSpace;
1010 TOTAL_MEM -= sizeof(class MemPart);
1013 ::free(part.memory);
1016 /*if(free && free.part && (free.part.size < 0 || free.part.pool == (void *)-1))
1017 printf("WARNING! Bad next free block!\n");*/
1021 static BlockPool * pools; //[NUM_POOLS];
1023 static uint PosFibonacci(uint number)
1026 uint last = 1, prev = 0;
1034 if(current >= number)
1040 static uint NthFibonacci(uint number)
1043 uint last = 1, prev = 0;
1046 for(pos=0; pos <= number; pos++)
1055 static uint NextFibonacci(uint number)
1058 uint last = 1, prev = 0;
1066 if(current >= number)
1071 static uint log1_5i(uint number)
1076 for(pos=0; pos < NUM_POOLS; pos++)
1078 if(current >= number)
1080 current = current * 3 / 2;
1081 if(current == 1) current = 2;
1086 static uint pow1_5(uint number)
1090 for(pos=0; pos < number; pos++)
1092 current = current * 3 / 2;
1093 if(current == 1) current = 2;
1095 return (uint)current;
1098 static uint pow1_5i(uint number)
1103 for(pos=0; pos < NUM_POOLS; pos++)
1105 if(current >= number)
1106 return (uint)current;
1107 current = current * 3 / 2;
1108 if(current == 1) current = 2;
1110 return (uint)current;
1113 // -- Math Helpers ---
1114 public uint log2i(uint number)
1118 for(power=0; power<32; power++)
1119 if((1L<<power) >= number)
1124 public uint pow2i(uint number)
1126 return 1<<log2i(number);
1129 static bool memoryInitialized = false;
1130 static void InitMemory()
1133 memoryInitialized = true;
1134 pools = calloc(1, sizeof(BlockPool) * NUM_POOLS);
1135 for(c = 0; c<NUM_POOLS; c++)
1139 pools[c].blockSize = NTH_SIZE(c);
1140 if(pools[c].blockSize % 4)
1141 pools[c].blockSize += 4 - (pools[c].blockSize % 4);
1142 pools[c].blockSpace = pools[c].blockSize;
1143 pools[c].blockSpace += sizeof(class MemBlock);
1144 // pools[c].Expand(initNumBlocks[c]);
1146 expansion = (pools[c].blockSize < 128) ? 1024 : (131072 / pools[c].blockSize);
1149 pools[c].Expand(Max(1, expansion));
1153 static void * _mymalloc(unsigned int size)
1155 MemBlock block = null;
1158 unsigned int p = SIZE_POSITION(size);
1159 if(!memoryInitialized) InitMemory();
1162 block = pools[p].Add();
1166 pools[p].usedSpace += size;
1171 block = malloc(sizeof(class MemBlock) + size);
1174 TOTAL_MEM += sizeof(class MemBlock) + size;
1175 OUTSIDE_MEM += sizeof(class MemBlock) + size;
1180 return block ? ((struct MemBlock *)block + 1) : null;
1183 static void * _mycalloc(int n, unsigned int size)
1185 void * pointer = _mymalloc(size);
1187 memset(pointer, 0, size);
1191 static void _myfree(void * pointer)
1195 MemBlock block = (MemBlock)((byte *)pointer - sizeof(class MemBlock));
1196 MemPart part = block.part;
1197 BlockPool * pool = part ? part.pool : null; //block.pool;
1198 /*if(pool == (void*) -1)
1199 printf("WARNING! pool is -1\n");
1202 pool->Remove(block);
1205 TOTAL_MEM -= sizeof(class MemBlock) + block.size;
1206 OUTSIDE_MEM -= sizeof(class MemBlock) + block.size;
1212 static void * _myrealloc(void * pointer, unsigned int size)
1214 MemBlock block = pointer ? ((MemBlock)((byte *)pointer - sizeof(class MemBlock))) : null;
1215 void * newPointer = null;
1216 MemPart part = block ? block.part : null;
1217 BlockPool * pool = part ? part.pool : null;
1220 /*if(pool == (void*) -1)
1221 printf("WARNING! pool is -1\n");
1225 // if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
1226 if(NEXT_SIZE(size) == pool->blockSize)
1228 newPointer = pointer;
1229 pool->usedSpace += size - block.size;
1235 MemBlock newBlock = realloc(block, sizeof(class MemBlock) + size);
1238 TOTAL_MEM += size - newBlock.size;
1239 OUTSIDE_MEM += size - newBlock.size;
1240 newPointer = ((struct MemBlock *)newBlock + 1);
1246 newPointer = _mymalloc(size);
1247 if(pointer && newPointer)
1249 memcpy(newPointer, pointer, Min(size, block.size));
1256 static void * _mycrealloc(void * pointer, unsigned int size)
1258 MemBlock block = pointer ? ((MemBlock)((byte *)pointer - sizeof(class MemBlock))) : null;
1259 void * newPointer = null;
1260 MemPart part = block ? block.part : null;
1261 BlockPool * pool = part ? part.pool : null;
1264 /*if(pool == (void*) -1)
1265 printf("WARNING! pool is -1\n");
1270 // if((1 << pool) >= size && (pool - SIZE_POSITION(size)) <= 1)
1271 if(NEXT_SIZE(size) == pool->blockSize)
1273 int extra = size - block.size;
1274 newPointer = pointer;
1275 pool->usedSpace += extra;
1277 memset((byte *)pointer + block.size, 0, extra);
1283 MemBlock newBlock = realloc(block, sizeof(class MemBlock) + size);
1286 int extra = size - newBlock.size;
1288 OUTSIDE_MEM += extra;
1289 newPointer = ((struct MemBlock *)newBlock + 1);
1291 memset((byte *)newPointer + newBlock.size, 0, extra);
1292 newBlock.size = size;
1298 newPointer = _mymalloc(size);
1303 memcpy(newPointer, pointer, Min(size, block.size));
1304 if(size > block.size)
1305 memset((byte *)newPointer + block.size, 0, size - block.size);
1309 memset((byte *)newPointer, 0, size);
1322 #define realloc _myrealloc
1323 #define crealloc _mycrealloc
1324 #define malloc _mymalloc
1325 #define free _myfree
1326 #define calloc _mycalloc
1329 static void * _malloc(unsigned int size)
1333 #if !defined(ECERE_BOOTSTRAP)
1337 pointer = malloc(size + 2 * REDZONE);
1341 MemStack stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1344 stack = (MemStack)calloc(1, sizeof(class MemStack));
1345 stack.key = GetCurrentThreadID();
1346 memStacks.Add(stack);
1352 printf("Memory allocation of %d bytes failed\n", size);
1353 printf("Current Stack:\n");
1354 for(c = 0; c<stack.pos; c++)
1356 printf(" %s\n", stack.frames[c]);
1358 memoryErrorsCount++;
1363 if(!recurse && !stack.recurse)
1365 stack.recurse = true;
1366 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
1367 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1368 memBlocks.Add(block);
1369 stack.recurse = false;
1374 #if !defined(ECERE_BOOTSTRAP)
1379 memset(pointer, 0xEC, REDZONE);
1380 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1381 // ((byte *)pointer)[0] = 0x00;
1383 return (byte*)pointer + REDZONE;
1386 static void * _calloc(int n, unsigned int size)
1389 #if !defined(ECERE_BOOTSTRAP)
1393 pointer = calloc(n, size + 2 * REDZONE);
1397 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1400 stack = (MemStack)calloc(1, sizeof(class MemStack));
1401 stack.key = GetCurrentThreadID();
1402 memStacks.Add(stack);
1407 printf("Memory allocation of %d bytes failed\n", size);
1408 printf("Current Stack:\n");
1409 for(c = 0; c<stack.pos; c++)
1411 printf(" %s\n", stack.frames[c]);
1412 memoryErrorsCount++;
1417 if(!recurse && !stack.recurse)
1421 stack.recurse = true;
1422 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), _class = allocateClass, internal = allocateInternal, id = blockID++ };
1423 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1424 memBlocks.Add(block);
1425 stack.recurse = false;
1430 #if !defined(ECERE_BOOTSTRAP)
1435 memset(pointer, 0xEC, REDZONE);
1436 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1438 return (byte*)pointer + REDZONE;
1441 static void * _realloc(void * pointer, unsigned int size)
1443 if(!size) { _free(pointer); return null; }
1444 #if !defined(ECERE_BOOTSTRAP)
1450 MemInfo block = null;
1452 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1455 stack = (MemStack)calloc(1, sizeof(class MemStack));
1456 stack.key = GetCurrentThreadID();
1457 memStacks.Add(stack);
1460 if(!recurse && !stack.recurse && pointer)
1462 block = (MemInfo)memBlocks.Find((uint)pointer);
1465 printf("Reallocating Bad Memory\n");
1466 memoryErrorsCount++;
1468 else if(block.freed)
1470 printf("Reallocating Freed Memory\n");
1471 memoryErrorsCount++;
1472 block.OutputStacks(true);
1476 pointer = malloc(size + REDZONE * 2);
1480 printf("Memory allocation of %d bytes failed\n", size);
1481 printf("Current Stack:\n");
1482 for(c = 0; c<stack.pos; c++)
1484 printf(" %s\n", stack.frames[c]);
1485 memoryErrorsCount++;
1489 memset(pointer, 0xEC, REDZONE);
1490 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1496 memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
1500 memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1501 memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
1502 block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
1503 memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
1504 memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
1509 if(!recurse && !stack.recurse)
1512 stack.recurse = true;
1513 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
1514 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1515 memBlocks.Add(block);
1516 stack.recurse = false;
1520 pointer = realloc(pointer, size);
1523 #if !defined(ECERE_BOOTSTRAP)
1526 return (byte *)pointer + REDZONE;
1529 static void * _crealloc(void * pointer, unsigned int size)
1531 if(!size) return null;
1532 #if !defined(ECERE_BOOTSTRAP)
1538 MemInfo block = null;
1540 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1543 stack = (MemStack)calloc(1, sizeof(class MemStack));
1544 stack.key = GetCurrentThreadID();
1545 memStacks.Add(stack);
1548 if(!recurse && !stack.recurse && pointer)
1550 block = (MemInfo)memBlocks.Find((uint)pointer);
1553 printf("Reallocating Bad Memory\n");
1554 memoryErrorsCount++;
1556 else if(block.freed)
1558 printf("Reallocating Freed Memory\n");
1559 memoryErrorsCount++;
1560 block.OutputStacks(true);
1564 pointer = calloc(1, size + REDZONE * 2);
1568 printf("Memory allocation of %d bytes failed\n", size);
1569 printf("Current Stack:\n");
1570 for(c = 0; c<stack.pos; c++)
1572 printf(" %s\n", stack.frames[c]);
1573 memoryErrorsCount++;
1577 memset(pointer, 0xEC, REDZONE);
1578 memset((byte *)pointer + REDZONE + size, 0xEC, REDZONE);
1584 memcpy((byte *)pointer + REDZONE, block.oldmem, Min(block.size, size));
1588 memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1589 memcpy((byte *)pointer + REDZONE, (byte *)block.key, Min(block.size, size));
1590 block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
1591 memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + 2 * REDZONE);
1592 memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
1597 if(!recurse && !stack.recurse)
1600 stack.recurse = true;
1601 block = MemInfo { size = size, key = (uint)((byte *)pointer + REDZONE), id = blockID++ };
1602 memcpy(block.allocLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1603 memBlocks.Add(block);
1604 stack.recurse = false;
1608 pointer = crealloc(pointer, size);
1611 #if !defined(ECERE_BOOTSTRAP)
1614 return (byte *)pointer + REDZONE;
1617 static void _free(void * pointer)
1621 #if !defined(ECERE_BOOTSTRAP)
1622 if(memMutex != pointer) memMutex.Wait();
1629 stack = (MemStack)memStacks.Find(GetCurrentThreadID());
1632 stack = (MemStack)calloc(1, sizeof(class MemStack));
1633 stack.key = GetCurrentThreadID();
1634 memStacks.Add(stack);
1637 if(!recurse && !stack.recurse)
1640 stack.recurse = true;
1641 block = (MemInfo)memBlocks.Find((uint)pointer);
1645 printf("Freeing Bad Memory\n");
1646 printf("Current Stack:\n");
1647 for(c = 0; c<stack.pos; c++)
1649 printf(" %s\n", stack.frames[c]);
1651 memoryErrorsCount++;
1653 else if(block.freed)
1656 printf("Freeing Already Freed Memory\n");
1657 printf("Current Stack:\n");
1658 for(c = 0; c<stack.pos; c++)
1660 printf(" %s\n", stack.frames[c]);
1662 memoryErrorsCount++;
1663 block.OutputStacks(true);
1668 byte * address = (byte *)block.key;
1669 for(c = 0; c<REDZONE; c++)
1671 if(address[-c-1] != 0xEC)
1673 printf("Buffer Underrun\n");
1674 memoryErrorsCount++;
1675 block.OutputStacks(block.freed);
1677 if(address[c + block.size] != 0xEC)
1679 printf("Buffer Overrun\n");
1680 memoryErrorsCount++;
1681 block.OutputStacks(block.freed);
1688 int size = block.size;
1689 address = (byte *)block.key;
1690 for(c = 0; c<REDZONE; c++)
1692 if(address[-c-1] != 0xEC)
1694 printf("Buffer Underrun\n");
1695 memoryErrorsCount++;
1696 block.OutputStacks(block.freed);
1698 if(address[c + size] != 0xEC)
1700 printf("Buffer Overrun\n");
1701 memoryErrorsCount++;
1702 block.OutputStacks(block.freed);
1708 block.oldmem = (byte *)malloc(block.size + REDZONE * 2) + REDZONE;
1709 memcpy(block.oldmem - REDZONE, (byte *)block.key - REDZONE, block.size + REDZONE * 2);
1710 memset((byte *)block.key - REDZONE, 0xEC, block.size + REDZONE * 2);
1712 memcpy(block.freeLoc, stack.frames + stack.pos - Min(stack.pos, MAX_MEMORY_LOC), Min(stack.pos, MAX_MEMORY_LOC) * sizeof(char *));
1714 stack.recurse = false;
1721 #if !defined(ECERE_BOOTSTRAP)
1722 if(memMutex != pointer) memMutex.Release();
1727 public void memswap(byte * a, byte * b, uint size)
1733 int s = sizeof(buffer);
1734 if(c + s > size) s = size - c;
1735 memcpy(buffer, a + c, s);
1736 memcpy(a + c, b + c, s);
1737 memcpy(b + c, buffer, s);
1742 public void CheckMemory()
1746 uint leaksCount = 0;
1747 uint leakedObjects = 0;
1750 // Verify Tree Integrity
1751 if(!memBlocks.Check())
1753 printf("Memory Blocks Tree Integrity Failed\n");
1754 memoryErrorsCount++;
1756 printf("Starting Memory Check\n");
1757 for(block = (MemInfo)memBlocks.root; block;)
1760 memswap((byte *)block.key - REDZONE, block.oldmem - REDZONE, block.size + REDZONE * 2);
1766 // if(!block.internal)
1768 // printf("Object of class %s\n", block._class);
1769 block.OutputStacks(false);
1774 printf("Memory Leak\n");
1775 block.OutputStacks(false);
1779 leaksSize += block.size;
1783 block = (MemInfo)block.left;
1784 else if(block.right)
1785 block = (MemInfo)block.right;
1790 MemInfo parent = (MemInfo)block.parent;
1791 if(parent && block == (MemInfo)parent.left && parent.right)
1793 block = (MemInfo)parent.right;
1801 while(block = (MemInfo)memBlocks.root)
1805 int size = block.size;
1808 address = block.oldmem;
1809 for(c = -REDZONE; c<size + REDZONE; c++)
1810 if(address[c] != 0xEC)
1814 if(c < size + REDZONE)
1816 printf("Freed Memory Write\n");
1817 memoryErrorsCount++;
1818 block.OutputStacks(true);
1822 address = (byte *)block.key;
1823 for(c = 0; c<REDZONE; c++)
1825 if(address[-c-1] != 0xEC)
1827 printf("Buffer Underrun\n");
1828 memoryErrorsCount++;
1829 block.OutputStacks(block.freed);
1831 if(address[c + size] != 0xEC)
1833 printf("Buffer Overrun\n");
1834 memoryErrorsCount++;
1835 block.OutputStacks(block.freed);
1839 memBlocks.Delete(block);
1843 printf("%d Memory Leaks Detected (%d objects, %d bytes).\n", leaksCount, leakedObjects, leaksSize);
1844 memoryErrorsCount++;
1846 printf("Memory Check Completed.\n");
1847 #if defined(__WIN32__) && !defined(ECERE_BOOTSTRAP)
1848 if(memoryErrorsCount)
1854 static void FixDerivativesBase(Class base, Class mod)
1857 OldLink templateLink;
1859 ComputeClassParameters(base, strchr(base.name, '<'), null);
1861 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
1863 Class _class = derivative.data;
1864 ClassType type = _class.type;
1865 int size = _class.structSize - _class.offset;
1866 int oldSizeClass = _class.sizeClass;
1867 int sizeClass = _class.sizeClass - _class.offsetClass;
1868 Class enumBase = null;
1869 char * dataTypeString = null;
1872 int offsetClass, totalSizeClass;
1874 for(baseClass = base; baseClass.base; baseClass = baseClass.base);
1876 if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass)) type = base.type;
1878 if(type == enumClass)
1880 if(base.type != enumClass)
1883 base = eSystem_FindClass(_class.module, "enum");
1887 dataTypeString = enumBase ? enumBase.dataTypeString : base.dataTypeString;
1889 /////////////////////
1891 offsetClass = base ? (base.templateClass ? base.templateClass.sizeClass : base.sizeClass) : (type == noHeadClass ? 0 : 0 /*sizeof(class Class)*/);
1892 totalSizeClass = offsetClass + sizeClass;
1894 // TESTING WITHOUT THIS... Seems to yield better results, as it otherwise prevents ComputeClassMembers from doing its job on derived classes
1896 // _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
1898 if(type == normalClass || type == noHeadClass)
1899 _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));
1901 if(type == structClass)
1903 _class.memberOffset = (base && (base.templateClass ? base.templateClass.structSize : base.structSize) && base.type != systemClass) ? (base.templateClass ? base.templateClass.structSize : base.structSize) : 0;
1905 _class.typeSize = _class.structSize = _class.memberOffset + size;
1907 else if(type == bitClass || type == enumClass || type == unitClass)
1909 Class dataTypeClass = eSystem_FindClass(_class.module, dataTypeString);
1911 _class.typeSize = dataTypeClass.typeSize;
1912 _class.structSize = 0;
1914 else if(type == normalClass || type == noHeadClass)
1916 _class.structSize = _class.offset + size;
1917 _class.typeSize = sizeof(void *);
1920 /////////////////////
1922 if(_class.type != systemClass)
1924 delete _class.dataTypeString;
1925 _class.dataTypeString = CopyString(dataTypeString);
1927 if(totalSizeClass != oldSizeClass)
1929 _class.data = renew _class.data byte[totalSizeClass];
1931 memmove((byte *)_class.data + offsetClass, (byte *)_class.data + _class.offsetClass, _class.sizeClass - _class.offsetClass);
1932 if(base.type != systemClass && base.type != enumClass)
1933 memcpy((byte *)_class.data + _class.offsetClass, (byte *)base.data + _class.offsetClass, totalSizeClass - _class.sizeClass);
1935 memset((byte *)_class.data + _class.offsetClass, 0, totalSizeClass - _class.sizeClass);
1937 memmove((byte *)_class.data + mod.offsetClass, (byte *)_class.data, totalSizeClass - mod.sizeClass);
1938 if(base.type != systemClass && base.type != enumClass)
1939 memcpy((byte *)_class.data, (byte *)base.data, totalSizeClass - _class.sizeClass);
1941 memset((byte *)_class.data, 0, totalSizeClass - _class.sizeClass);
1944 _class.offsetClass = offsetClass;
1945 _class.sizeClass = totalSizeClass;
1947 if(mod.base && mod.base.base && mod.base.vTblSize > baseClass.vTblSize &&
1948 (mod != (base.templateClass ? base.templateClass : base) || _class.vTblSize != mod.vTblSize))
1950 Method method, next;
1952 _class.vTblSize += mod.base.vTblSize - baseClass.vTblSize;
1953 _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
1954 // memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (mod.base.vTblSize - baseClass.vTblSize) * sizeof(void *));
1955 memmove(_class._vTbl + mod.base.vTblSize, _class._vTbl + baseClass.vTblSize, (_class.vTblSize - mod.vTblSize) * sizeof(void *));
1957 for(method = (Method)_class.methods.first; method; method = next)
1959 next = (Method)((BTNode)method).next;
1960 if(method.type == virtualMethod)
1961 method.vid += mod.base.vTblSize - baseClass.vTblSize;
1964 // TO CHECK: WHY WAS THIS baseClass? ANY PROBLEMS? CRASH WHEN DECLARING A BASE CLASS LATER (WSMS)
1965 for(b = mod.base; b && b != null; b = b.base)
1968 for(vMethod = (Method)b.methods.first; vMethod; vMethod = (Method)((BTNode)vMethod).next)
1970 if(vMethod.type == virtualMethod)
1972 method = (Method)_class.methods.FindString(vMethod.name);
1975 if(method.function) _class._vTbl[vMethod.vid] = method.function;
1977 delete method.dataTypeString;
1978 _class.methods.Delete((BTNode)method);
1981 _class._vTbl[vMethod.vid] = _class.base._vTbl[vMethod.vid];
1987 // _class.defaultAlignment = base ? base.defaultAlignment : 0;
1989 if(type == normalClass || type == noHeadClass || type == structClass)
1994 for(c = mod.base; c; c = c.base)
1997 for(_property = c.membersAndProperties.first; _property; _property = _property.next)
1999 if(_property.isProperty)
2001 BTNamedLink link = (BTNamedLink)_class.prop.FindString(_property.name);
2005 if(!prop.Set && !prop.Get && prop.memberAccess == baseSystemAccess)
2007 SelfWatcher watcher;
2008 for(watcher = _class.selfWatchers.first; watcher; watcher = watcher.next)
2010 if(watcher._property == prop)
2011 watcher._property = _property;
2013 _property.selfWatchable = true;
2014 _class.prop.Delete((BTNode)link);
2016 delete prop.dataTypeString;
2017 _class.membersAndProperties.Delete(prop); // Remove only was done before?
2023 if(mod.base.memberID)
2025 for(member = _class.membersAndProperties.first; member; member = member.next)
2026 member.id += mod.base.memberID;
2028 _class.memberID += mod.base.memberID;
2029 _class.startMemberID += mod.base.memberID;
2034 for(c = mod.base; c; c = c.base)
2036 ClassProperty _property;
2037 for(_property = (ClassProperty)c.classProperties.first; _property; _property = (ClassProperty)((BTNode)_property).next)
2039 SetDelayedCPValues(_class, _property);
2044 FixDerivativesBase(_class, mod);
2048 OldLink templateLink;
2049 for(templateLink = base.templatized.first; templateLink; templateLink = templateLink.next)
2051 Class template = templateLink.data;
2052 char * templateParams = strchr(template.name, '<');
2053 template.base = base.base;
2054 template._vTbl = base._vTbl;
2055 //ComputeClassParameters(template, templateParams, null);
2057 template.data = base.data;
2058 template.offset = base.offset;
2059 template.offsetClass = base.offsetClass;
2060 template.sizeClass = base.sizeClass;
2061 template.structSize = base.structSize;
2062 template.vTblSize = base.vTblSize;
2064 FixDerivativesBase(template, mod);
2069 public dllexport Class eSystem_RegisterClass(ClassType type, char * name, char * baseName, int size, int sizeClass,
2070 bool (* Constructor)(void *),void (* Destructor)(void *),
2071 Module module, AccessMode declMode, AccessMode inheritanceAccess)
2074 NameSpace * nameSpace = null;
2077 nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
2078 if(declMode == baseSystemAccess) nameSpace = &module.application.systemNameSpace;
2080 // if(declMode != staticAccess)
2082 for(c = 0; name[c]; c++)
2084 if(name[c] == '.' || (name[c] == ':' && name[c+1] == ':'))
2086 NameSpace * newSpace;
2088 char * spaceName = _malloc(c - start + 1);
2089 strncpy(spaceName, name + start, c - start);
2090 spaceName[c-start] = '\0';
2092 newSpace = (NameSpace *)nameSpace->nameSpaces.FindString(spaceName);
2095 newSpace = new0 NameSpace[1];
2096 newSpace->classes.CompareKey = (void *)BinaryTree::CompareString;
2097 newSpace->defines.CompareKey = (void *)BinaryTree::CompareString;
2098 newSpace->functions.CompareKey = (void *)BinaryTree::CompareString;
2099 newSpace->nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
2100 newSpace->name = spaceName;
2101 newSpace->parent = nameSpace;
2102 nameSpace->nameSpaces.Add((BTNode)newSpace);
2106 nameSpace = newSpace;
2107 if(name[c] == ':') c++;
2120 BTNamedLink classLink = null;
2121 Class _class = null;
2122 char * dataTypeString = null;
2123 Class enumBase = null;
2124 Class base = (baseName && baseName[0]) ? eSystem_FindClass(module, baseName) : null;
2125 bool refine = false;
2127 if(base && !base.internalDecl && (base.type == noHeadClass || base.type == structClass || base.type == normalClass))
2129 // Normal classes inheriting off simple classes should become no head classes
2130 if(base.type == structClass && type == normalClass)
2135 if(base && (type == normalClass || type == noHeadClass || type == structClass) &&
2136 (base.type == unitClass || base.type == bitClass || base.type == enumClass))
2140 if(!base || base.type == systemClass)
2142 if(type == enumClass)
2145 if(base || !baseName || !baseName[0] ||
2146 !strcmp(baseName, "unsigned int") ||
2147 !strcmp(baseName, "uint") ||
2148 !strcmp(baseName, "unsigned int64") ||
2149 !strcmp(baseName, "uint64") ||
2150 !strcmp(baseName, "int64") ||
2151 !strcmp(baseName, "unsigned short") ||
2152 !strcmp(baseName, "short") ||
2153 !strcmp(baseName, "unsigned char") ||
2154 !strcmp(baseName, "byte") ||
2155 !strcmp(baseName, "char") ||
2156 !strcmp(baseName, "uint32") ||
2157 !strcmp(baseName, "uint16"))
2159 base = eSystem_FindClass(module, "enum");
2160 dataTypeString = (baseName && baseName[0]) ? baseName : "int"; //"unsigned int";
2165 base = eSystem_RegisterClass(0, baseName, null, 0,0, null, null, module, declMode, publicAccess);
2166 base.internalDecl = true;
2169 base = eSystem_FindClass(module, "enum");
2170 //dataTypeString = (baseName && baseName[0]) ? baseName : "unsigned int";
2173 else if(type == structClass && (!baseName || !baseName[0]))
2175 base = eSystem_FindClass(module, "struct");
2176 dataTypeString = name + start;
2180 if(type == normalClass)
2181 // dataTypeString = "struct Instance";
2182 dataTypeString = "struct __ecereNameSpace__ecere__com__Instance";
2183 else if(type == noHeadClass)
2184 dataTypeString = "void *";
2185 else if(type == bitClass)
2186 dataTypeString = (baseName && baseName[0]) ? baseName : "unsigned int";
2187 else if(type == unitClass)
2188 dataTypeString = (baseName && baseName[0]) ? baseName : "int";
2189 else if(type == structClass)
2190 dataTypeString = name + start;
2192 // TODO: base bit, unit or enum classes not defined yet
2193 if(base || (!baseName || !baseName[0]) || type == bitClass || type == unitClass)
2195 // DANGEROUSLY TESTING THIS... PUT IT BACK
2197 if(base || !baseName || !baseName[0] ||
2198 !strcmp(baseName, "unsigned int") ||
2199 !strcmp(baseName, "uint") ||
2200 !strcmp(baseName, "unsigned int64") ||
2201 !strcmp(baseName, "uint64") ||
2202 !strcmp(baseName, "int64") ||
2203 !strcmp(baseName, "unsigned short") ||
2204 !strcmp(baseName, "short") ||
2205 !strcmp(baseName, "unsigned char") ||
2206 !strcmp(baseName, "byte") ||
2207 !strcmp(baseName, "char") ||
2208 !strcmp(baseName, "uint32") ||
2209 !strcmp(baseName, "uint16"))
2211 if(type == normalClass && strcmp(name, "ecere::com::Instance") && strcmp(name, "enum") && strcmp(name, "struct"))
2212 base = eSystem_FindClass(module, "ecere::com::Instance");
2214 base = eSystem_FindClass(module, "class");
2219 // Base class has not been defined yet!
2225 if(type == enumClass)
2227 if(base.type != enumClass)
2230 base = eSystem_FindClass(module, "enum");
2233 dataTypeString = enumBase ? enumBase.dataTypeString : base.dataTypeString;
2236 offsetClass = base ? base.sizeClass : (type == noHeadClass ? 0 : 0 /*sizeof(class Class)*/);
2237 totalSizeClass = offsetClass + sizeClass;
2239 if((_class = eSystem_FindClass(module, name)))
2241 FreeTemplatesDerivatives(_class);
2243 if(!_class.internalDecl)
2245 if(declMode != baseSystemAccess)
2246 printf("error: Redefinition of class %s\n", name);
2249 _class.comRedefinition = true;
2255 classLink = (BTNamedLink)_class.nameSpace->classes.FindString(name + start);
2256 _class.nameSpace->classes.Delete((BTNode)classLink);
2259 for(t = _class.templatized.first; t; t = t.next)
2261 Class template = t.data;
2262 classLink = (BTNamedLink)_class.nameSpace->classes.FindString(template.name);
2264 _class.nameSpace->classes.Delete((BTNode)classLink);
2268 NameSpace * ns = _class.nameSpace;
2270 !ns->classes.first &&
2271 !ns->functions.first &&
2272 !ns->defines.first &&
2273 !ns->nameSpaces.first)
2275 NameSpace * parent = ns->parent;
2277 parent->nameSpaces.Delete((BTNode)ns);
2285 classLink = SearchNameSpace(module.application.privateNameSpace, name, &((NameSpace *)0)->classes);
2287 classLink = SearchNameSpace(module.application.publicNameSpace, name, &((NameSpace *)0)->classes);
2290 classLink = SearchNameSpace(module.application.privateNameSpace, name + start, &((NameSpace *)0)->classes);
2292 classLink = SearchNameSpace(module.application.publicNameSpace, name + start, &((NameSpace *)0)->classes);
2295 _class = classLink.data;
2296 if(_class && _class.internalDecl)
2298 FreeTemplatesDerivatives(_class);
2300 _class.nameSpace->classes.Delete((BTNode)classLink);
2303 for(t = _class.templatized.first; t; t = t.next)
2305 Class template = t.data;
2306 classLink = (BTNamedLink)_class.nameSpace->classes.FindString(template.name);
2307 _class.nameSpace->classes.Delete((BTNode)classLink);
2313 delete _class.fullName;
2314 _class.fullName = CopyString(name);
2318 _class = _calloc(1, sizeof(class Class));
2319 _class.methods.CompareKey = (void *)BinaryTree::CompareString;
2320 _class.members.CompareKey = (void *)BinaryTree::CompareString;
2321 _class.prop.CompareKey = (void *)BinaryTree::CompareString;
2322 _class.classProperties.CompareKey = (void *)BinaryTree::CompareString;
2324 _class.name = CopyString(name + start);
2325 _class.fullName = CopyString(name);
2330 nameSpace->classes.Add((BTNode)BTNamedLink { name = _class.name, data = _class });
2333 for(t = _class.templatized.first; t; t = t.next)
2335 Class template = t.data;
2336 nameSpace->classes.Add((BTNode)BTNamedLink { name = template.name, data = template });
2344 if(!base && baseName && strcmp(baseName, name))
2347 if(strchr(baseName, '<'))
2349 char templateClassName[1024];
2351 strcpy(templateClassName, baseName);
2352 *strchr(templateClassName, '<') = '\0';
2353 templateBase = eSystem_FindClass(module, templateClassName);
2356 templateBase = eSystem_RegisterClass(0, templateClassName, null, 0,0, null, null, module, declMode, publicAccess);
2357 templateBase.internalDecl = true;
2359 base = eSystem_FindClass(module, baseName);
2363 base = eSystem_RegisterClass(0, baseName, null, 0,0, null, null, module, declMode, publicAccess);
2364 base.internalDecl = true;
2369 base.memberOffset = 0;
2373 _class.internalDecl = false;
2377 _class.data = renew _class.data byte[totalSizeClass];
2378 // memset(_class.data, 0, totalSizeClass);
2379 if(base && base.type != systemClass && base.type != enumClass)
2380 memcpy(_class.data, base.data, offsetClass);
2382 memset(_class.data, 0, offsetClass);
2383 memset((byte *)_class.data + offsetClass, 0, sizeClass);
2386 delete _class.dataTypeString;
2387 _class.dataTypeString = CopyString(dataTypeString);
2388 _class.defaultAlignment = base ? base.defaultAlignment : 0;
2390 // Dereference the class in previous module the classed belonged to
2393 _class.module.classes.Remove(_class);
2398 //Class base = _class.base.templateClass ? _class.base.templateClass : _class.base;
2399 Class base = _class.base;
2400 OldLink deriv = base.derivatives.FindLink(_class);
2401 base.derivatives.Delete(deriv);
2404 // Reference the class in the module
2407 module.classes.Add(_class);
2410 _class.nameSpace = nameSpace;
2413 for(t = _class.templatized.first; t; t = t.next)
2415 Class template = t.data;
2416 template.nameSpace = nameSpace;
2420 _class.module = module;
2426 for(sClass = base; sClass; sClass = sClass.base)
2428 if(sClass.templateClass) sClass = sClass.templateClass;
2429 numParams += sClass.templateParams.count;
2433 if(_class.templateArgs)
2435 FreeTemplateArgs(_class);
2437 delete _class.templateArgs;
2438 _class.templateArgs = new0 ClassTemplateArgument[numParams];
2439 _class.numParams = numParams;
2441 for(sClass = _class; sClass; sClass = sClass.base)
2444 ClassTemplateParameter param;
2446 if(sClass.templateClass) sClass = sClass.templateClass;
2447 for(prevClass = sClass.base; prevClass; prevClass = prevClass.base)
2449 if(prevClass.templateClass) prevClass = prevClass.templateClass;
2450 id += prevClass.templateParams.count;
2453 if(base.templateArgs) // Add numParams test here?
2455 for(param = sClass.templateParams.first; param; param = param.next)
2457 _class.templateArgs[id] = base.templateArgs[id];
2458 CopyTemplateArg(param, _class.templateArgs[id]);
2465 _class.memberID = _class.startMemberID = (base && (type == normalClass || type == noHeadClass || type == structClass)) ? base.memberID : 0;
2466 if(type == normalClass || type == noHeadClass)
2467 _class.offset = (base && base.structSize && base.type != systemClass) ? base.structSize : ((type == noHeadClass) ? 0 : sizeof(class Instance));
2468 if(type == structClass)
2470 _class.memberOffset = (base && base.structSize && base.type != systemClass) ? base.structSize : 0;
2472 _class.typeSize = _class.structSize = _class.memberOffset + size;
2474 else if(type == bitClass || type == enumClass || type == unitClass)
2476 Class dataTypeClass = eSystem_FindClass(_class.module, dataTypeString);
2478 _class.typeSize = dataTypeClass.typeSize;
2479 _class.structSize = 0;
2481 else if(type == normalClass || type == noHeadClass)
2483 _class.structSize = _class.offset + size;
2484 _class.typeSize = sizeof(void *);
2486 _class.offsetClass = offsetClass;
2487 _class.sizeClass = totalSizeClass;
2488 _class.Constructor = (void *)Constructor;
2489 _class.Destructor = Destructor;
2490 if(_class.type != systemClass)
2493 _class.computeSize = true;
2495 _class.computeSize = false;
2496 _class.inheritanceAccess = inheritanceAccess;
2498 /*if(type == bitClass)
2500 if(type == enumClass)
2503 _class.base = base = enumBase;
2506 EnumClassData data = (EnumClassData)_class.data;
2507 // TOCHECK: Trying this (if specifiers specified, no class found...)
2508 // What about bit classes, unit classes...
2509 if(base && base.type != enumClass)
2510 data.largest = -1;//_class.base = null;
2512 data.largest = ((EnumClassData)(base.data)).largest;
2515 if(base && base.vTblSize)
2517 _class.vTblSize = base.vTblSize;
2518 // OK to scrap existing virtual table?
2519 delete _class._vTbl;
2520 _class._vTbl = _malloc(sizeof(int(*)()) * _class.vTblSize);
2521 memcpy(_class._vTbl, base._vTbl, sizeof(int(*)()) * _class.vTblSize);
2526 OldLink link { data = _class };
2527 /*(_class.base.templateClass ? _class.base.templateClass : _class.base)*/_class.base.derivatives.Add(link);
2530 FixDerivativesBase(_class, _class);
2537 static void DataMember_Free(DataMember parentMember)
2540 BTNamedLink namedLink;
2541 delete parentMember.name;
2542 delete parentMember.dataTypeString;
2544 while((member = parentMember.members.first))
2546 DataMember_Free(member);
2547 parentMember.members.Delete(member);
2550 while((namedLink = (BTNamedLink)parentMember.membersAlpha.first))
2552 parentMember.membersAlpha.Delete((BTNode)namedLink);
2556 static void FreeEnumValue(NamedLink value)
2561 static void FreeTemplateArg(Class template, ClassTemplateParameter param, int id)
2566 delete template.templateArgs[id].dataTypeString;
2569 delete template.templateArgs[id].memberString;
2577 static void FreeTemplateArgs(Class template)
2579 if(template.templateArgs)
2582 for(_class = template; _class; _class = _class.base)
2585 ClassTemplateParameter param;
2587 if(_class.templateClass) _class = _class.templateClass;
2588 for(prevClass = _class.base; prevClass; prevClass = prevClass.base)
2590 if(prevClass.templateClass) prevClass = prevClass.templateClass;
2591 id += prevClass.templateParams.count;
2593 if(id < template.numParams)
2595 for(param = _class.templateParams.first; param; param = param.next)
2600 delete template.templateArgs[id].dataTypeString;
2603 delete template.templateArgs[id].memberString;
2606 // delete template.templateArgs[id].dataTypeString;
2616 static void FreeTemplate(Class template)
2620 if(template.nameSpace)
2622 BTNamedLink link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
2623 template.nameSpace->classes.Delete((BTNode)link);
2625 FreeTemplateArgs(template);
2627 delete template.fullName;
2628 delete template.name;
2629 delete template.templateArgs;
2631 while((deriv = template.derivatives.first))
2633 ((Class)deriv.data).base = null;
2634 template.derivatives.Delete(deriv);
2640 static void FreeTemplates(Class _class)
2642 OldLink deriv, template;
2644 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
2646 FreeTemplates(deriv.data);
2649 FreeTemplateArgs(_class);
2650 //if(_class.templateArgs)
2651 //printf("Deleting Template args for %s\n", _class.name);
2652 delete _class.templateArgs;
2654 while((template = _class.templatized.first))
2656 FreeTemplates(template.data);
2657 FreeTemplate(template.data);
2658 _class.templatized.Delete(template);
2662 public dllexport void eClass_Unregister(Class _class)
2664 BTNamedLink namedLink;
2667 OldLink deriv, template;
2668 ClassProperty classProp;
2669 ClassTemplateParameter param;
2671 delete _class._vTbl;
2673 FreeTemplates(_class);
2675 FreeTemplateArgs(_class);
2676 delete _class.templateArgs;
2678 while((template = _class.templatized.first))
2680 FreeTemplate(template.data);
2681 _class.templatized.Delete(template);
2684 while((member = _class.membersAndProperties.first))
2686 if(!member.isProperty && (member.type == unionMember || member.type == structMember))
2687 DataMember_Free(member);
2689 delete member.dataTypeString;
2690 _class.membersAndProperties.Delete(member);
2693 while((member = _class.conversions.first))
2696 delete member.dataTypeString;
2697 _class.conversions.Delete(member);
2700 while((namedLink = (BTNamedLink)_class.prop.first))
2702 _class.prop.Delete((BTNode)namedLink);
2705 while((namedLink = (BTNamedLink)_class.members.first))
2707 _class.members.Delete((BTNode)namedLink);
2710 while((classProp = (ClassProperty)_class.classProperties.first))
2712 delete classProp.name;
2713 delete classProp.dataTypeString;
2714 _class.classProperties.Delete((BTNode)classProp);
2717 while((method = (Method)_class.methods.first))
2720 delete method.dataTypeString;
2721 _class.methods.Delete((BTNode)method);
2724 if(_class.type == enumClass)
2726 EnumClassData data = (EnumClassData)_class.data;
2728 data.values.Free((void *)FreeEnumValue);
2730 _class.delayedCPValues.Free(null);
2732 _class.selfWatchers.Free(null);
2736 // Class base = _class.base.templateClass ? _class.base.templateClass : _class.base;
2737 Class base = _class.base;
2738 for(deriv = base.derivatives.first; deriv; deriv = deriv.next)
2740 if(deriv.data == _class)
2744 base.derivatives.Delete(deriv);
2746 while((deriv = _class.derivatives.first))
2748 ((Class)deriv.data).base = null;
2749 _class.derivatives.Delete(deriv);
2752 if(_class.nameSpace)
2754 BTNamedLink link = (BTNamedLink)_class.nameSpace->classes.FindString(_class.name);
2755 _class.nameSpace->classes.Delete((BTNode)link);
2759 delete _class.fullName;
2761 delete _class.dataTypeString;
2765 while((param = _class.templateParams.first))
2770 delete param.defaultArg.dataTypeString;
2773 delete param.defaultArg.memberString;
2779 if(param.type != identifier) delete param.dataTypeString;
2782 _class.templateParams.Delete(param);
2785 //_class.nameSpace->classes.Delete(_class);
2789 static BTNamedLink ScanNameSpace(NameSpace nameSpace, char * name, void * listOffset)
2791 BinaryTree * tree = (BinaryTree *)((byte *)nameSpace + (uint)listOffset);
2792 BTNamedLink link = (BTNamedLink)tree->Find((uint)name);
2796 for(child = (NameSpace *)nameSpace.nameSpaces.first; child; child = (NameSpace *)((BTNode)child).next)
2798 link = ScanNameSpace(child, name, listOffset);
2806 static BTNamedLink SearchNameSpace(NameSpace nameSpace, char * name, void * listOffset)
2811 for(c = 0; (ch = name[c]); c++)
2813 if(ch == '<') level++;
2814 if(ch == '>') level--;
2815 if(level == 0 && (ch == '.' || (ch == ':' && name[c+1] == ':')))
2817 NameSpace * newSpace;
2818 char * spaceName = _malloc(c - start + 1);
2819 memcpy(spaceName, name + start, c - start);
2820 spaceName[c-start] = '\0';
2821 newSpace = (NameSpace *)nameSpace.nameSpaces.FindString(spaceName);
2825 nameSpace = newSpace;
2826 if(level == 0 && ch == ':') c++;
2832 return ScanNameSpace(nameSpace, name + start, listOffset);
2837 static BTNamedLink SearchModule(Module module, char * name, void * listOffset, bool searchPrivate)
2839 SubModule subModule;
2844 link = SearchNameSpace(&module.privateNameSpace, name, listOffset);
2845 if(link) return link;
2847 link = SearchNameSpace(&module.publicNameSpace, name, listOffset);
2848 if(link) return link;
2850 for(subModule = module.modules.first; subModule; subModule = subModule.next)
2852 if(searchPrivate || subModule.importMode == publicAccess)
2854 // TOCHECK: Reverting to false to test what we were trying to fix by passing searchPrivate
2855 // Passing searchPrivate finds ALL classes private or not and thus classes clash
2856 // SearchModule here is called mainly from eSystem_FindClass, and also for Functions and Defines
2858 link = SearchModule(subModule.module, name, listOffset, false);
2859 //link = SearchModule(subModule.module, name, listOffset, searchPrivate /*false*/);
2860 if(link) return link;
2866 public int64 _strtoi64(char * string, char ** endString, int base)
2872 for(c = 0; (ch = string[c]) && isspace(ch); c++);
2874 else if(ch == '-') { sign = -1; c++; };
2877 if(ch == 0 && string[c+1] == 'x')
2890 for( ;(ch = string[c]); c++)
2894 else if(ch >= '1' && ch <= '9')
2896 else if(ch >= 'a' && ch <= 'z')
2898 else if(ch >= 'A' && ch <= 'Z')
2902 *endString = string + c;
2903 // Invalid character
2913 *endString = string + c;
2914 // Invalid character
2921 public uint64 _strtoui64(char * string, char ** endString, int base)
2927 for(c = 0; (ch = string[c]) && isspace(ch); c++);
2929 else if(ch == '-') { sign = -1; c++; };
2932 if(ch == 0 && string[c+1] == 'x')
2945 for( ;(ch = string[c]); c++)
2949 else if(ch >= '1' && ch <= '9')
2951 else if(ch >= 'a' && ch <= 'z')
2953 else if(ch >= 'A' && ch <= 'Z')
2957 *endString = string + c;
2958 // Invalid character
2968 *endString = string + c;
2969 // Invalid character
2976 public dllexport Class eSystem_FindClass(Module module, char * name)
2981 link = SearchNameSpace(&module.application.systemNameSpace, name, &((NameSpace *)0)->classes);
2982 if(link) return link.data;
2984 link = SearchModule(module, name, &((NameSpace *)0)->classes, true);
2985 if(link) return link.data;
2988 char noTemplateName[1024];
2989 char * templateParams = strchr(name, '<');
2993 strncpy(noTemplateName, name, templateParams - name);
2994 noTemplateName[templateParams - name] = '\0';
2997 strcpy(noTemplateName, name);
2999 link = SearchNameSpace(&module.application.systemNameSpace, noTemplateName, &((NameSpace *)0)->classes);
3001 link = SearchModule(module, noTemplateName, &((NameSpace *)0)->classes, true);
3004 Class _class = link.data;
3005 Class templatedClass = null;
3006 char className[1024];
3007 strcpy(className, _class.fullName);
3008 strcat(className, templateParams);
3010 link = SearchNameSpace(&module.application.systemNameSpace, className, &((NameSpace *)0)->classes);
3014 link = SearchModule(module, className, &((NameSpace *)0)->classes, true);
3018 if(_class && templateParams)
3020 // if(!numParams) return null;
3022 templatedClass = Class { };
3023 *templatedClass = *_class;
3024 templatedClass.templateClass = _class;
3025 //templatedClass.fullName = CopyString(name);
3026 templatedClass.fullName = CopyString(className);
3027 templatedClass.name = CopyString(templatedClass.fullName + strlen(_class.fullName) - strlen(_class.name));
3028 templatedClass.nameSpace->classes.Add((BTNode)BTNamedLink { name = templatedClass.name, data = templatedClass });
3029 templatedClass.templateArgs = null;
3030 templatedClass.numParams = 0;
3031 templatedClass.derivatives = { };
3032 templatedClass.templatized = { };
3034 ComputeClassParameters(templatedClass, templateParams, module);
3036 _class.templatized.Add(OldLink { data = templatedClass });
3038 return templatedClass;
3045 static void CopyTemplateArg(ClassTemplateParameter param, ClassTemplateArgument arg)
3050 arg.dataTypeString = CopyString(arg.dataTypeString);
3056 arg.memberString = CopyString(arg.memberString);
3061 static void ComputeClassParameters(Class templatedClass, char * templateParams, Module findModule)
3064 char * nextParamStart = templateParams ? (templateParams + 1) : null;
3065 ClassTemplateParameter curParam = null;
3066 Class lastClass = null, sClass;
3069 Class _class = templatedClass.templateClass ? templatedClass.templateClass : templatedClass;
3071 for(sClass = _class; sClass; sClass = sClass.base)
3073 if(sClass.templateClass) sClass = sClass.templateClass;
3074 numParams += sClass.templateParams.count;
3077 if(templatedClass.templateArgs)
3078 FreeTemplateArgs(templatedClass);
3079 delete templatedClass.templateArgs;
3080 templatedClass.templateArgs = new0 ClassTemplateArgument[numParams];
3081 templatedClass.numParams = numParams;
3083 if(_class != templatedClass)
3087 memcpy(templatedClass.templateArgs, _class.templateArgs, numParams * sizeof(ClassTemplateArgument));
3088 for(sClass = _class; sClass; sClass = sClass.base)
3090 ClassTemplateParameter param;
3093 if(sClass.templateClass) sClass = sClass.templateClass;
3094 for(prevClass = sClass.base; prevClass; prevClass = prevClass.base)
3096 if(prevClass.templateClass) prevClass = prevClass.templateClass;
3097 id += prevClass.templateParams.count;
3099 for(param = sClass.templateParams.first; param; param = param.next)
3100 CopyTemplateArg(param, templatedClass.templateArgs[id++]);
3104 if(templatedClass.base && templatedClass.base.templateArgs && _class == templatedClass)
3107 memcpy(templatedClass.templateArgs, templatedClass.base.templateArgs,
3108 sizeof(ClassTemplateArgument) * (numParams - templatedClass.templateParams.count));
3109 for(sClass = templatedClass.base; sClass; sClass = sClass.base)
3111 ClassTemplateParameter param;
3114 for(prevClass = sClass.base; prevClass; prevClass = prevClass.base)
3116 if(prevClass.templateClass) prevClass = prevClass.templateClass;
3117 id += prevClass.templateParams.count;
3120 if(sClass.templateClass) sClass = sClass.templateClass;
3121 for(param = sClass.templateParams.first; param; param = param.next)
3122 CopyTemplateArg(param, templatedClass.templateArgs[id++]);
3126 while(nextParamStart)
3128 char * paramStart = nextParamStart;
3131 while(*paramStart == ' ') paramStart++;
3132 paramEnd = paramStart;
3133 while((ch = *paramEnd, ch && (level > 0 || (ch != '>' && ch != ','))))
3135 if(ch == '<') level++;
3136 if(ch == '>') level--;
3140 nextParamStart = (ch == ',') ? (paramEnd + 1) : null;
3141 while(*paramEnd == ' ') paramEnd--;
3142 if(paramEnd > paramStart)
3144 char * ptr, * equal = null;
3145 for(ptr = paramStart; ptr <= paramEnd; ptr++)
3155 char * end = equal - 1;
3158 while(*end == ' ') end--;
3159 strncpy(ident, paramStart, end + 1 - paramStart);
3160 ident[end + 1 - paramStart] = 0;
3162 for(sClass = _class; sClass; sClass = sClass.base)
3164 if(sClass.templateClass) sClass = sClass.templateClass;
3165 for(curParam = sClass.templateParams.first; curParam; curParam = curParam.next)
3167 if(!strcmp(curParam.name, ident))
3173 ClassTemplateParameter prevParam;
3175 for(prevParam = curParam.prev; prevParam; prevParam = prevParam.prev) curParamID++;
3176 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3178 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3179 curParamID += nextClass.templateParams.count;
3190 curParam = curParam.next;
3196 for(sClass = lastClass ? lastClass.base : _class; sClass; sClass = sClass.base)
3198 ClassTemplateParameter param;
3200 if(sClass.templateClass) sClass = sClass.templateClass;
3201 for(param = sClass.templateParams.first; param; param = param.next, curParamID++)
3209 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3211 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3212 curParamID += nextClass.templateParams.count;
3219 for(sClass = _class; sClass; sClass = sClass.base)
3221 if(sClass.templateParams.first)
3224 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3225 if(nextClass.templateParams.first)
3227 if(nextClass != lastClass) continue;
3229 curParam = sClass.templateParams.first;
3232 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3233 if(nextClass.templateParams.first)
3235 curParamID += nextClass.templateParams.count;
3247 ClassTemplateArgument argument { };
3252 while(*equal == ' ') equal++;
3253 memcpy(value, equal, paramEnd - equal);
3254 value[paramEnd - equal] = 0;
3258 memcpy(value, paramStart, paramEnd - paramStart);
3259 value[paramEnd - paramStart] = 0;
3261 TrimRSpaces(value, value);
3263 switch(curParam.type)
3266 argument.dataTypeString = CopyString(value);
3267 argument.dataTypeClass = eSystem_FindClass(_class.module, value);
3268 if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(_class.module.application, value);
3269 if(!argument.dataTypeClass) argument.dataTypeClass = eSystem_FindClass(findModule, value);
3273 Class expClass = eSystem_FindClass(_class.module, curParam.dataTypeString);
3274 if(!expClass) expClass = eSystem_FindClass(_class.module.application, curParam.dataTypeString);
3277 //if(expClass.type ==
3278 expClass._vTbl[__ecereVMethodID_class_OnGetDataFromString](expClass, &argument.expression, value);
3280 // Expression should be pre simplified here
3281 else if(value[0] == '\"')
3283 char * endQuote = value + strlen(value) - 1;
3284 if(*endQuote != '\"') endQuote++;
3286 argument.expression.p = CopyString(value + 1);
3288 else if(value[0] == '\'')
3291 unichar ch = UTF8GetChar(value + 1, &nb);
3292 argument.expression.ui = ch;
3294 else if(!strcmp(curParam.dataTypeString, "uint"))
3296 argument.expression.ui = strtoul(value, null, 0);
3298 else if(!strcmp(curParam.dataTypeString, "char"))
3300 argument.expression.c = (char)strtol(value, null, 0);
3302 else if(!strcmp(curParam.dataTypeString, "byte"))
3304 argument.expression.uc = (unsigned char)strtoul(value, null, 0);
3306 else if(!strcmp(curParam.dataTypeString, "short"))
3308 argument.expression.s = (short)strtol(value, null, 0);
3310 else if(!strcmp(curParam.dataTypeString, "uint16"))
3312 argument.expression.us = (unsigned short)strtoul(value, null, 0);
3314 else if(!strcmp(curParam.dataTypeString, "int64"))
3316 argument.expression.i64 = _strtoi64(value, null, 0);
3318 else if(!strcmp(curParam.dataTypeString, "uint64"))
3320 argument.expression.ui64 = _strtoui64(value, null, 0);
3322 else if(!strcmp(curParam.dataTypeString, "float"))
3324 argument.expression.f = (float)strtod(value, null);
3326 else if(!strcmp(curParam.dataTypeString, "double"))
3328 argument.expression.d = strtod(value, null);
3330 else // if(!strcmp(curParam.dataTypeString, "int"))
3332 argument.expression.i = strtol(value, null, 0);
3337 argument.memberString = CopyString(value);
3340 FreeTemplateArg(templatedClass, curParam, curParamID);
3341 templatedClass.templateArgs[curParamID] = argument;
3346 // TESTING THIS BEFORE...
3347 if(templatedClass == _class)
3349 Class sClass = _class;
3352 ClassTemplateParameter param;
3353 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3355 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3356 curParamID += nextClass.templateParams.count;
3359 for(param = sClass.templateParams.first; param; param = param.next)
3361 if(!templatedClass.templateArgs[curParamID].dataTypeString)
3363 templatedClass.templateArgs[curParamID] = param.defaultArg;
3364 CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
3365 if(param.type == type && param.defaultArg.dataTypeString)
3367 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
3368 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3369 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
3370 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3371 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
3378 if(templatedClass.base && templatedClass.base.templateArgs && numParams - _class.templateParams.count)
3380 int c = numParams - _class.templateParams.count-1;
3382 for(sClass = _class.base; sClass; sClass = sClass.base)
3384 ClassTemplateParameter param;
3385 if(sClass.templateClass) sClass = sClass.templateClass;
3386 for(param = sClass.templateParams.last; param; param = param.prev)
3388 ClassTemplateArgument * arg = &templatedClass.templateArgs[c];
3389 ClassTemplateArgument * baseArg = &templatedClass.base.templateArgs[c];
3390 if(!arg->dataTypeString)
3392 *arg = templatedClass.base.templateArgs[c];
3393 CopyTemplateArg(param, arg);
3394 if(param.type == type)
3396 if(arg->dataTypeClass && strchr(arg->dataTypeString, '<') && arg->dataTypeClass.templateArgs)
3398 Class expClass = arg->dataTypeClass;
3399 Class cClass = null;
3403 char templateString[1024];
3404 sprintf(templateString, "%s<", expClass.templateClass.fullName);
3405 for(cClass = expClass; cClass; cClass = cClass.base)
3408 ClassTemplateParameter param;
3409 for(param = cClass.templateParams.first; param; param = param.next)
3413 ClassTemplateArgument arg;
3414 for(sClass = expClass.base; sClass; sClass = sClass.base) id += sClass.templateParams.count;
3415 arg = expClass.templateArgs[id];
3418 ClassTemplateParameter cParam;
3419 int p = numParams - _class.templateParams.count;
3420 for(cParam = _class.templateParams.first; cParam; cParam = cParam.next, p++)
3422 if(cParam.type == type && arg.dataTypeString && !strcmp(cParam.name, arg.dataTypeString))
3424 arg.dataTypeString = templatedClass.templateArgs[p].dataTypeString;
3425 arg.dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
3438 // THIS WHOLE THING IS A WILD GUESS... FIX IT UP
3440 char expString[1024];
3441 OldList * specs = MkList();
3442 Declarator decl = SpecDeclFromString(param.dataTypeString, specs, null);
3444 char * string = PrintHexUInt64(arg.expression.ui64);
3445 exp = MkExpCast(MkTypeName(specs, decl), MkExpConstant(string));
3447 ProcessExpressionType(exp);
3448 ComputeExpression(exp);
3449 expString[0] = '\0';
3450 PrintExpression(exp, expString);
3451 strcat(argument, expString);
3453 FreeExpression(exp);
3459 strcat(argument, arg.member.name);
3462 case TemplateParameterType::type:
3464 if(arg.dataTypeString)
3465 strcat(argument, arg.dataTypeString);
3471 if(paramCount) strcat(templateString, ", ");
3472 if(lastParam != p - 1)
3474 strcat(templateString, param.name);
3475 strcat(templateString, " = ");
3477 strcat(templateString, argument);
3486 int len = strlen(templateString);
3487 if(templateString[len-1] == '>') templateString[len++] = ' ';
3488 templateString[len++] = '>';
3489 templateString[len++] = '\0';
3492 FreeTemplateArg(templatedClass, param, c);
3494 arg->dataTypeString = CopyString(templateString);
3495 arg->dataTypeClass = eSystem_FindClass(templatedClass.module, templateString);
3496 if(!arg->dataTypeClass)
3497 arg->dataTypeClass = eSystem_FindClass(templatedClass.module.application, templateString);
3501 ClassTemplateParameter cParam;
3502 int p = numParams - _class.templateParams.count;
3503 for(cParam = _class.templateParams.first; cParam; cParam = cParam.next, p++)
3505 // if(cParam.type == type && !strcmp(cParam.name, param.name))
3506 if(cParam.type == type && baseArg->dataTypeString && !strcmp(cParam.name, baseArg->dataTypeString))
3508 FreeTemplateArg(templatedClass, param, c);
3510 arg->dataTypeString = templatedClass.templateArgs[p].dataTypeString;
3511 arg->dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
3512 CopyTemplateArg(cParam, arg);
3526 for(sClass = _class; sClass; sClass = sClass.base)
3530 ClassTemplateParameter param;
3531 if(sClass.templateClass) sClass = sClass.templateClass;
3533 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3535 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3536 curParamID += nextClass.templateParams.count;
3539 for(param = sClass.templateParams.first; param; param = param.next)
3541 if(!templatedClass.templateArgs[curParamID].dataTypeString)
3543 templatedClass.templateArgs[curParamID] = param.defaultArg;
3544 CopyTemplateArg(param, templatedClass.templateArgs[curParamID]);
3545 if(param.type == type && param.defaultArg.dataTypeString)
3547 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module, param.defaultArg.dataTypeString);
3548 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3549 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(templatedClass.module.application, param.defaultArg.dataTypeString);
3550 if(!templatedClass.templateArgs[curParamID].dataTypeClass)
3551 templatedClass.templateArgs[curParamID].dataTypeClass = eSystem_FindClass(findModule, param.defaultArg.dataTypeString);
3560 int c = numParams - 1;
3561 for(sClass = _class; sClass; sClass = sClass.base)
3563 ClassTemplateParameter param;
3564 if(sClass.templateClass) sClass = sClass.templateClass;
3565 for(param = sClass.templateParams.last; param; param = param.prev)
3567 if(param.type == type)
3569 ClassTemplateArgument * arg = &templatedClass.templateArgs[c];
3570 ClassTemplateParameter cParam;
3572 int p = numParams - 1;
3573 for(dClass = _class; dClass; dClass = dClass.base)
3575 if(dClass.templateClass) dClass = dClass.templateClass;
3576 for(cParam = dClass.templateParams.last; cParam; cParam = cParam.prev, p--)
3578 if(cParam.type == type && arg->dataTypeString && !strcmp(cParam.name, arg->dataTypeString))
3580 if(templatedClass.templateArgs[p].dataTypeString && c != p)
3582 FreeTemplateArg(templatedClass, param, c);
3584 arg->dataTypeString = templatedClass.templateArgs[p].dataTypeString;
3585 arg->dataTypeClass = templatedClass.templateArgs[p].dataTypeClass;
3586 CopyTemplateArg(cParam, arg);
3599 int c = numParams - 1;
3600 for(tClass = _class; tClass; tClass = tClass.base)
3602 ClassTemplateParameter param;
3603 if(tClass.templateClass) tClass = tClass.templateClass;
3604 for(param = tClass.templateParams.last; param; param = param.prev)
3606 ClassTemplateArgument * arg = &templatedClass.templateArgs[c];
3607 if(param.type == identifier && arg->memberString)
3609 Class memberClass = templatedClass;
3610 char * memberString = arg->memberString;
3611 char * colon = strstr(memberString, "::");
3612 char * memberName = memberString;
3613 if(colon) memberName = colon + 2;
3616 memberString = param.defaultArg.memberString;
3617 colon = memberString ? strstr(memberString, "::") : null;
3622 char className[1024];
3625 memcpy(className, memberString, colon - memberString);
3626 className[colon - memberString] = '\0';
3628 for(sClass = _class; sClass; sClass = sClass.base)
3630 ClassTemplateParameter cParam;
3634 if(sClass.templateClass) sClass = sClass.templateClass;
3635 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base)
3637 if(nextClass.templateClass) nextClass = nextClass.templateClass;
3638 id += nextClass.templateParams.count;
3640 for(cParam = sClass.templateParams.first; cParam; cParam = cParam.next)
3642 if(cParam.type == type && !strcmp(cParam.name, className) && templatedClass.templateArgs[id].dataTypeString)
3644 strcpy(className, templatedClass.templateArgs[id].dataTypeString);
3649 memberClass = eSystem_FindClass(templatedClass.module, className);
3650 // TESTING: Added this here...
3652 memberClass = eSystem_FindClass(findModule, className);
3654 memberClass = eSystem_FindClass(templatedClass.module.application, className);
3659 switch(param.memberType)
3662 arg->member = eClass_FindDataMember(memberClass, memberName, memberClass.module, null, null);
3665 arg->method = eClass_FindMethod(memberClass, memberName, memberClass.module);
3668 arg->prop = eClass_FindProperty(memberClass, memberName, memberClass.module);
3679 /*static */bool DefaultFunction()
3684 public dllexport bool eClass_IsDerived(Class _class, Class from)
3686 if(!_class && !from)
3689 if(_class && from && (_class.templateClass || from.templateClass))
3691 if(eClass_IsDerived(_class.templateClass ? _class.templateClass : _class, from.templateClass ? from.templateClass : from))
3693 if(!from.templateClass)
3695 else if(!_class.templateClass && _class == from.templateClass)
3700 for(sClass = from; sClass; sClass = sClass.base)
3702 if(sClass.templateParams.first)
3704 ClassTemplateParameter param;
3707 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base) p += nextClass.templateParams.count;
3708 for(param = sClass.templateParams.first; param; param = param.next, p++)
3710 ClassTemplateArgument * arg = &_class.templateArgs[p];
3711 ClassTemplateArgument * fArg = &from.templateArgs[p];
3712 if(param.type == type)
3714 if(arg->dataTypeString != fArg->dataTypeString && arg->dataTypeString && fArg->dataTypeString &&
3715 strcmp(arg->dataTypeString, fArg->dataTypeString))
3718 else if(param.type == identifier)
3720 if(arg->member != fArg->member)
3723 else if(param.type == expression)
3725 if(arg->expression.ui64 != fArg->expression.ui64)
3739 for(; _class && from; _class = _class.base)
3741 if(_class == from || _class.templateClass == from || (_class.type == systemClass && from.name && !strcmp(_class.name, from.name)))
3748 static void FixDerivativeVirtualMethod(Class base, char * name, int vid, void * origFunction)
3751 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
3753 Class _class = derivative.data;
3754 Method method, next;
3755 void * function = origFunction;
3758 _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
3759 memmove(_class._vTbl + vid + 1, _class._vTbl + vid, (_class.vTblSize - vid - 1) * sizeof(void *));
3761 method = (Method) _class.methods.FindString(name);
3764 if(method.function) function = method.function;
3767 delete method.dataTypeString;
3768 _class.methods.Delete((BTNode)method);
3770 for(method = (Method)_class.methods.first; method; method = next)
3772 next = (Method)((BTNode)method).next;
3773 if(method.type == virtualMethod)
3776 _class._vTbl[vid] = function;
3779 OldLink templateLink;
3780 for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
3782 Class template = templateLink.data;
3783 template._vTbl = _class._vTbl;
3786 if(_class.derivatives.first || _class.templatized.first)
3787 FixDerivativeVirtualMethod(_class, name, vid, function);
3790 OldLink templateLink;
3791 for(templateLink = base.templatized.first; templateLink; templateLink = templateLink.next)
3793 Class template = templateLink.data;
3794 template._vTbl = base._vTbl;
3795 FixDerivativeVirtualMethod(template, name, vid, origFunction);
3800 public dllexport Method eClass_AddMethod(Class _class, char * name, char * type, void * function, AccessMode declMode)
3805 for(base = _class; base; base = base.base)
3807 Method method = (Method)base.methods.FindString(name);
3810 // If this overides a virtual method
3811 if(method.type == virtualMethod)
3814 void * oldFunction = _class._vTbl[method.vid];
3815 if(method.vid > _class.vTblSize)
3818 _class._vTbl[method.vid] = function ? function : DefaultFunction;
3819 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
3821 Class derivClass = deriv.data;
3822 if(derivClass._vTbl[method.vid] == oldFunction)
3823 eClass_AddMethod(derivClass, name, type, function, declMode);
3826 OldLink templateLink;
3827 for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
3829 Class template = templateLink.data;
3830 for(deriv = template.derivatives.first; deriv; deriv = deriv.next)
3832 Class derivClass = deriv.data;
3833 if(derivClass._vTbl[method.vid] == oldFunction)
3834 eClass_AddMethod(derivClass, name, type, function, declMode);
3844 // printf("error: Redefinition of method %s in class %s\n", name, _class.name);
3858 name = CopyString(name),
3859 function = function ? function : DefaultFunction;
3861 dataTypeString = CopyString(type);
3862 memberAccess = declMode;
3864 _class.methods.Add((BTNode)method);
3871 public dllexport Method eClass_AddVirtualMethod(Class _class, char * name, char * type, void * function, AccessMode declMode)
3876 for(base = _class; base; base = base.base)
3878 Method method = (Method)base.methods.FindString(name);
3881 // If this overides a virtual method
3882 if(method.type == virtualMethod)
3883 _class._vTbl[method.vid] = function ? function : DefaultFunction;
3894 name = CopyString(name);
3895 function = function ? function : DefaultFunction;
3896 type = virtualMethod;
3898 vid = _class.vTblSize++;
3899 dataTypeString = CopyString(type);
3900 memberAccess = declMode;
3902 _class.methods.Add((BTNode)method);
3903 _class._vTbl = renew _class._vTbl void *[_class.vTblSize];
3904 _class._vTbl[method.vid] = function ? function : DefaultFunction;
3906 // TODO: Fix derived classes
3907 if(_class.derivatives.first || _class.templatized.first)
3908 FixDerivativeVirtualMethod(_class, name, method.vid, function ? function : (void *)DefaultFunction);
3915 static void FixDerivativeProperty(Class base, Property _property)
3918 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
3920 Class _class = derivative.data;
3923 link = (BTNamedLink)_class.prop.FindString(_property.name);
3927 if(!prop.Set && !prop.Get && prop.memberAccess == baseSystemAccess)
3929 SelfWatcher watcher;
3930 for(watcher = _class.selfWatchers.first; watcher; watcher = watcher.next)
3932 if(watcher._property == prop)
3933 watcher._property = _property;
3935 _property.selfWatchable = true;
3938 delete prop.dataTypeString;
3939 _class.membersAndProperties.Delete(prop);
3940 _class.prop.Delete((BTNode)link);
3944 for(prop = _class.membersAndProperties.first; prop; prop = prop.next)
3947 _class.startMemberID++;
3949 FixDerivativeProperty(_class, _property);
3953 public dllexport Property eClass_AddProperty(Class _class, char * name, char * dataType, void * setStmt, void * getStmt, AccessMode declMode)
3955 Property _property = null;
3958 if(!_class.prop.FindString((name ? name : dataType)))
3963 name = CopyString(name ? name : dataType);
3964 id = (name && (setStmt || getStmt || dataType)) ? _class.memberID++ : 0;
3967 dataTypeString = CopyString(dataType);
3970 conversion = name ? false : true;
3971 memberAccess = declMode;
3974 _class.membersAndProperties.Add(_property);
3976 _class.conversions.Add(_property);
3977 _class.prop.Add((BTNode)BTNamedLink { name = _property.name, data = _property });
3979 if(!_property.conversion)
3981 FixDerivativeProperty(_class, _property);
3988 static void SetDelayedCPValues(Class _class, ClassProperty _property)
3991 NamedLink value, next;
3993 for(value = _class.delayedCPValues.first; value; value = next)
3996 if(!strcmp(value.name, _property.name))
3998 // eClass_SetProperty(_class, _property.name, value.data);
3999 _property.Set(_class, (int)value.data);
4000 _class.delayedCPValues.Delete(value);
4004 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
4006 SetDelayedCPValues(deriv.data, _property);
4010 public dllexport ClassProperty eClass_AddClassProperty(Class _class, char * name, char * dataType, void * setStmt, void * getStmt)
4012 if(name && !_class.classProperties.FindString(name))
4014 ClassProperty _property
4016 name = CopyString(name);
4019 dataTypeString = CopyString(dataType);
4021 _class.classProperties.Add((BTNode)_property);
4022 SetDelayedCPValues(_class, _property);
4030 Time classFindTotalTime;
4032 public dllexport void ResetClassFindTime()
4034 classFindTotalTime = 0;
4037 public dllexport Time GetClassFindTime()
4039 return classFindTotalTime;
4042 public dllexport ClassProperty eClass_FindClassProperty(Class _class, char * name)
4044 //Time startTime = GetTime();
4045 ClassProperty _property = null;
4048 Class origClass = _class;
4049 for(; _class; _class = _class.base)
4051 _property = (ClassProperty)_class.classProperties.FindString(name);
4055 // For enum class deriving off something else than enum to find enumSize...
4056 if(!_property && origClass.type == enumClass)
4058 Class enumClass = eSystem_FindClass(origClass.module, "enum");
4059 _property = eClass_FindClassProperty(enumClass, name);
4063 eSystem_Logf("No such property (%s) for class %s\n", name, _class.name);*/
4064 //classFindTotalTime += GetTime() - startTime;
4068 public dllexport int eClass_GetProperty(Class _class, char * name)
4070 ClassProperty _property = eClass_FindClassProperty(_class, name);
4071 if(_property && _property.Get && _property.Get != (void *)1)
4073 int result = _property.Get(_class);
4079 public dllexport void eClass_SetProperty(Class _class, char * name, int value)
4081 ClassProperty _property = eClass_FindClassProperty(_class, name);
4085 _property.Set(_class, value);
4089 _class.delayedCPValues.Add(NamedLink { name = name, (void *)value });
4093 public dllexport Method eClass_FindMethod(Class _class, char * name, Module module)
4095 //Time startTime = GetTime();
4098 for(; _class; _class = _class.base)
4101 if(_class.templateClass) _class = _class.templateClass;
4102 method = (Method)_class.methods.FindString(name);
4103 if(method && (method.memberAccess == publicAccess || _class.module == module || !method.dataTypeString))
4105 if(!method.dataTypeString)
4107 if(_class.module != module)
4109 if(method.memberAccess == publicAccess)
4110 module = _class.module;
4113 //classFindTotalTime += GetTime() - startTime;
4120 //classFindTotalTime += GetTime() - startTime;
4124 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4127 //classFindTotalTime += GetTime() - startTime;
4131 // Construct an instance
4132 static bool ConstructInstance(void * instance, Class _class)
4134 if(_class.templateClass) _class = _class.templateClass;
4137 if(!ConstructInstance(instance, _class.base))
4140 if(_class.Initialize)
4142 void (* Initialize)(Module module) = (void *)_class.Initialize;
4143 _class.Initialize = null;
4144 Initialize(_class.module);
4146 if(_class.Constructor)
4148 if(!_class.Constructor(instance))
4150 for(; _class; _class = _class.base)
4152 if(_class.templateClass) _class = _class.templateClass;
4153 if(_class.Destructor)
4154 _class.Destructor(instance);
4159 (_class.templateClass ? _class.templateClass : _class).count++;
4163 public dllexport void * eInstance_New(Class _class)
4165 Instance instance = null;
4168 // instance = _malloc(_class.size);
4173 //allocateClass = _class;
4174 allocateClass = malloc(strlen(_class.name)+1);
4175 allocateInternal = _class.module == __thisModule;
4176 strcpy(allocateClass, _class.name);
4178 #define malloc _mymalloc
4182 instance = _calloc(1, _class.structSize);
4184 allocateClass = null;
4187 if(_class.type == normalClass)
4189 instance._class = _class;
4190 // Copy the virtual table initially
4191 instance._vTbl = _class._vTbl;
4193 if(!ConstructInstance(instance, _class))
4198 /*if(_class.type == normalClass && _class.count > 1000)
4199 printf("%s: %d instances\n", _class.name, _class.count);*/
4204 public dllexport void eInstance_Evolve(Instance * instancePtr, Class _class)
4206 if(_class && instancePtr && *instancePtr)
4208 Instance instance = (Instance)renew *instancePtr byte[_class.structSize];
4209 *instancePtr = instance;
4210 memset(((byte *)instance) + instance._class.structSize, 0, _class.structSize - instance._class.structSize);
4211 // Fix pointers to application
4212 if(!strcmp(instance._class.name, "Application"))
4215 Application app = (Application) instance;
4218 NameSpace * nameSpace;
4219 for(module = app.allModules.first; module; module = module.next)
4220 module.application = app;
4222 for(link = (BTNamedLink)app.privateNameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
4225 ((Class)link.data).nameSpace = &app.privateNameSpace;
4226 for(t = ((Class)link.data).templatized.first; t; t = t.next) { Class template = t.data; template.nameSpace = ((Class)link.data).nameSpace; }
4228 for(link = (BTNamedLink)app.publicNameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
4231 ((Class)link.data).nameSpace = &app.publicNameSpace;
4232 for(t = ((Class)link.data).templatized.first; t; t = t.next) { Class template = t.data; template.nameSpace = ((Class)link.data).nameSpace; }
4235 for(link = (BTNamedLink)app.privateNameSpace.defines.first; link; link = (BTNamedLink)((BTNode)link).next)
4236 ((DefinedExpression)link.data).nameSpace = &app.privateNameSpace;
4237 for(link = (BTNamedLink)app.publicNameSpace.defines.first; link; link = (BTNamedLink)((BTNode)link).next)
4238 ((DefinedExpression)link.data).nameSpace = &app.publicNameSpace;
4240 for(link = (BTNamedLink)app.privateNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4241 ((GlobalFunction)link.data).nameSpace = &app.privateNameSpace;
4242 for(link = (BTNamedLink)app.publicNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4243 ((GlobalFunction)link.data).nameSpace = &app.publicNameSpace;
4245 for(nameSpace = (NameSpace *)app.privateNameSpace.nameSpaces.first; nameSpace; nameSpace = (NameSpace *)((BTNode)nameSpace).next)
4246 nameSpace->parent = &app.privateNameSpace;
4247 for(nameSpace = (NameSpace *)app.publicNameSpace.nameSpaces.first; nameSpace; nameSpace = (NameSpace *)((BTNode)nameSpace).next)
4248 nameSpace->parent = &app.publicNameSpace;
4250 // --------------------------------------------------
4251 for(link = (BTNamedLink)app.systemNameSpace.classes.first; link; link = (BTNamedLink)((BTNode)link).next)
4254 ((Class)link.data).nameSpace = &app.systemNameSpace;
4255 for(t = ((Class)link.data).templatized.first; t; t = t.next) { Class template = t.data; template.nameSpace = ((Class)link.data).nameSpace; }
4257 for(link = (BTNamedLink)app.systemNameSpace.defines.first; link; link = (BTNamedLink)((BTNode)link).next)
4258 ((DefinedExpression)link.data).nameSpace = &app.systemNameSpace;
4259 for(link = (BTNamedLink)app.systemNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4260 ((GlobalFunction)link.data).nameSpace = &app.systemNameSpace;
4261 for(link = (BTNamedLink)app.systemNameSpace.functions.first; link; link = (BTNamedLink)((BTNode)link).next)
4262 ((GlobalFunction)link.data).nameSpace = &app.systemNameSpace;
4263 for(nameSpace = (NameSpace *)app.systemNameSpace.nameSpaces.first; nameSpace; nameSpace = (NameSpace *)((BTNode)nameSpace).next)
4264 nameSpace->parent = &app.systemNameSpace;
4265 // --------------------------------------------------
4267 for(_class = app.classes.first; _class; _class = _class.next)
4269 OldLink templateLink;
4270 _class.module = (Module) app;
4271 for(templateLink = _class.templatized.first; templateLink; templateLink = templateLink.next)
4273 Class template = templateLink.data;
4274 template.module = _class.module;
4277 app.application = app;
4282 for(base = instance._class; base && base.type == normalClass && base.count; base = base.base)
4283 (base.templateClass ? base.templateClass : base).count--;
4286 instance._class = _class;
4287 // Copy the virtual table initially
4288 instance._vTbl = _class._vTbl;
4290 if(!ConstructInstance(instance, _class))
4293 *instancePtr = null;
4298 public dllexport void eInstance_Delete(Instance instance)
4301 bool checkMemory = false;
4306 bool ownVtbl = instance._vTbl != instance._class._vTbl;
4308 for(_class = instance._class; _class; _class = base)
4310 if(_class.templateClass) _class = _class.templateClass;
4311 if(_class.destructionWatchOffset)
4313 OldList * watchers = (OldList *)((byte *)instance + _class.destructionWatchOffset);
4314 Watcher watcher, next;
4316 for(watcher = watchers->first; watcher; watcher = next)
4318 next = watcher.next;
4319 watchers->Remove(watcher);
4320 watcher.callback(watcher.object, instance);
4321 watchers->Delete(watcher);
4325 /*// Loop through properties to delete all watchers? Might slow down destruction...
4328 for(_property = _class.membersAndProperties.first; _property; _property = _property.next)
4330 if(_property.isProperty && _property.isWatchable)
4332 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
4333 Watcher watcher, next;
4334 for(watcher = watchers->first; watcher; watcher = next)
4336 next = watcher.next;
4337 watchers->Delete(watcher);
4345 if(base && base.type == systemClass) base = null;
4346 if(_class.Destructor)
4347 _class.Destructor(instance);
4349 if(_class == class(Application))
4354 for(_class = instance._class; _class; _class = base)
4356 if(_class.templateClass) _class = _class.templateClass;
4359 (_class.templateClass ? _class.templateClass : _class).count--;
4360 if(_class.type == normalClass && !_class.count && !_class.module)
4363 // printf("Now Destructing class %s\n", _class.name);
4365 eClass_Unregister(_class);
4371 delete instance._vTbl;
4373 //instance.prop.Free(null);
4376 if(checkMemory) CheckMemory();
4381 public dllexport Property eClass_FindProperty(Class _class, char * name, Module module)
4383 //Time startTime = GetTime();
4386 for(; _class; _class = _class.base)
4389 if(_class.templateClass) _class = _class.templateClass;
4390 link = (BTNamedLink)_class.prop.FindString(name);
4393 Property _property = (Property)link.data;
4394 if(_property.memberAccess == publicAccess || _class.module == module || !_property.dataTypeString)
4396 if(!_property.dataTypeString)
4398 if(_class.module != module)
4400 if(_property.memberAccess == publicAccess)
4401 module = _class.module;
4404 //classFindTotalTime += GetTime() - startTime;
4411 //classFindTotalTime += GetTime() - startTime;
4416 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4419 //classFindTotalTime += GetTime() - startTime;
4423 static DataMember FindDataMember(OldList list, BinaryTree alist, char * name, uint * offset, int * id, bool searchPrivate, DataMember * subMemberStack, int * subMemberStackPos)
4426 DataMember dataMember;
4428 link = (BTNamedLink)alist.FindString(name);
4431 dataMember = link.data;
4432 if(dataMember.type == normalMember && (dataMember.memberAccess == publicAccess || searchPrivate || !dataMember.dataTypeString))
4435 *offset += dataMember.offset;
4436 if(id) *id = dataMember.id;
4441 for(dataMember = list.first; dataMember; dataMember = dataMember.next)
4443 if(!dataMember.isProperty && (dataMember.memberAccess == publicAccess || searchPrivate) && !dataMember.name && (dataMember.type == unionMember || dataMember.type == structMember))
4445 DataMember childMember;
4446 if(subMemberStackPos) subMemberStack[(*subMemberStackPos)++] = dataMember;
4447 childMember = FindDataMember(dataMember.members, dataMember.membersAlpha, name, offset, id, searchPrivate, subMemberStack, subMemberStackPos);
4451 *offset += dataMember.offset;
4452 if(id) *id += dataMember.id;
4455 if(subMemberStackPos) (*subMemberStackPos)--;
4461 public dllexport DataMember eClass_FindDataMember(Class _class, char * name, Module module, DataMember * subMemberStack, int * subMemberStackPos)
4463 //Time startTime = GetTime();
4464 DataMember dataMember = null;
4465 if(subMemberStackPos) *subMemberStackPos = 0;
4468 for(; _class; _class = _class.base)
4470 if(_class.templateClass) _class = _class.templateClass;
4471 dataMember = FindDataMember(_class.membersAndProperties, _class.members, name, null, null, _class.module == module, subMemberStack, subMemberStackPos);
4474 if(!dataMember.dataTypeString)
4476 if(_class.module != module)
4478 if(dataMember.memberAccess == publicAccess)
4479 module = _class.module;
4482 //classFindTotalTime += GetTime() - startTime;
4490 // HACK: Is this good enough? avoiding setting it when adding...
4491 dataMember._class = _class.templateClass ? _class.templateClass : _class;
4492 //classFindTotalTime += GetTime() - startTime;
4496 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4499 //classFindTotalTime += GetTime() - startTime;
4503 public dllexport DataMember eClass_FindDataMemberAndOffset(Class _class, char * name, uint * offset, Module module, DataMember * subMemberStack, int * subMemberStackPos)
4505 //Time startTime = GetTime();
4506 DataMember dataMember = null;
4507 if(subMemberStackPos) *subMemberStackPos = 0;
4508 if(offset) *offset = 0;
4511 for(; _class; _class = _class.base)
4513 if(_class.templateClass) _class = _class.templateClass;
4514 dataMember = FindDataMember(_class.membersAndProperties, _class.members, name, offset, null, _class.module == module, subMemberStack, subMemberStackPos);
4517 if(!dataMember.dataTypeString)
4519 if(_class.module != module)
4521 if(dataMember.memberAccess == publicAccess)
4522 module = _class.module;
4525 //classFindTotalTime += GetTime() - startTime;
4533 // HACK: Is this good enouh? avoiding setting it when adding...
4534 dataMember._class = _class;
4535 //classFindTotalTime += GetTime() - startTime;
4539 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4542 //classFindTotalTime += GetTime() - startTime;
4546 public dllexport DataMember eClass_FindDataMemberAndId(Class _class, char * name, int * id, Module module, DataMember * subMemberStack, int * subMemberStackPos)
4548 //Time startTime = GetTime();
4549 DataMember dataMember = null;
4550 if(subMemberStackPos) *subMemberStackPos = 0;
4553 for(; _class; _class = _class.base)
4555 if(_class.templateClass) _class = _class.templateClass;
4556 dataMember = FindDataMember(_class.membersAndProperties, _class.members, name, null, id, _class.module == module, subMemberStack, subMemberStackPos); // TOCHECK: Why was this null? null, null);
4559 if(!dataMember.dataTypeString)
4561 if(_class.module != module)
4563 if(dataMember.memberAccess == publicAccess)
4564 module = _class.module;
4567 //classFindTotalTime += GetTime() - startTime;
4575 // HACK: Is this good enouh? avoiding setting it when adding...
4576 dataMember._class = _class;
4577 //classFindTotalTime += GetTime() - startTime;
4581 if(_class.inheritanceAccess == privateAccess && _class.module != module) break;
4584 //classFindTotalTime += GetTime() - startTime;
4588 public dllexport void eClass_FindNextMember(Class _class, Class * curClass, DataMember * curMember, DataMember * subMemberStack, int * subMemberStackPos)
4590 // THIS CODE WILL FIND NEXT MEMBER... (PUBLIC MEMBERS ONLY)
4593 *curMember = (*curMember).next;
4595 if(subMemberStackPos && *subMemberStackPos > 0 && subMemberStack[*subMemberStackPos-1].type == unionMember)
4597 *curMember = subMemberStack[--(*subMemberStackPos)];
4598 *curMember = (*curMember).next;
4601 if(subMemberStackPos && *subMemberStackPos > 0)
4603 while(*curMember && ((*curMember).memberAccess == privateAccess))
4604 *curMember = (*curMember).next;
4607 while(*curMember && (*curMember).name) // ADDED THIS HERE for eComPacket packet { Connect, 0, { ECOMMUNICATOR_PROTOCOL_VERSION } };
4609 DataMember dataMember = eClass_FindDataMember(_class, curMember->name, null, null, null);
4610 if(!dataMember) dataMember = (DataMember)eClass_FindProperty(_class, curMember->name, null);
4611 if(dataMember && dataMember.memberAccess != privateAccess)
4613 *curMember = dataMember;
4617 *curMember = (*curMember).next;
4620 if(subMemberStackPos)
4622 while((*curMember) && !(*curMember).isProperty && !(*curMember).name && ((*curMember).type == structMember || (*curMember).type == unionMember))
4624 subMemberStack[(*subMemberStackPos)++] = *curMember;
4626 *curMember = (*curMember).members.first;
4627 while(*curMember && ((*curMember).memberAccess == privateAccess))
4628 *curMember = (*curMember).next;
4636 if(subMemberStackPos && *subMemberStackPos)
4638 *curMember = subMemberStack[--(*subMemberStackPos)];
4639 *curMember = (*curMember).next;
4643 Class lastCurClass = *curClass;
4645 if(*curClass == _class) break; // REACHED THE END
4647 for(*curClass = _class; (*curClass).base != lastCurClass && (*curClass).base.type != systemClass && (*curClass).inheritanceAccess != privateAccess; *curClass = (*curClass).base);
4648 *curMember = (*curClass).membersAndProperties.first;
4651 if(subMemberStackPos && *subMemberStackPos > 0)
4653 while(*curMember && ((*curMember).memberAccess == privateAccess))
4654 *curMember = (*curMember).next;
4657 while(*curMember && (*curMember).name) // ADDED THIS HERE for eComPacket packet { Connect, 0, { ECOMMUNICATOR_PROTOCOL_VERSION } };
4659 DataMember dataMember = eClass_FindDataMember(_class, curMember->name, null, null, null);
4660 if(!dataMember) dataMember = (DataMember)eClass_FindProperty(_class, curMember->name, null);
4661 if(dataMember && dataMember.memberAccess != privateAccess)
4663 *curMember = dataMember;
4667 *curMember = (*curMember).next;
4670 if(subMemberStackPos)
4672 while((*curMember) && !(*curMember).isProperty && !(*curMember).name && ((*curMember).type == structMember || (*curMember).type == unionMember))
4674 subMemberStack[(*subMemberStackPos)++] = *curMember;
4676 *curMember = (*curMember).members.first;
4677 while(*curMember && (*curMember).memberAccess == privateAccess)
4678 *curMember = (*curMember).next;
4685 public dllexport void eInstance_SetMethod(Instance instance, char * name, void * function) // YET TO BE DECIDED: , Module module)
4687 if(instance && name)
4690 for(_class = instance._class; _class; _class = _class.base)
4692 Method method = (Method)_class.methods.FindString(name);
4693 if(method && method.type == virtualMethod)
4695 if(instance._vTbl == instance._class._vTbl)
4697 instance._vTbl = _malloc(sizeof(void *) * instance._class.vTblSize);
4698 memcpy(instance._vTbl, instance._class._vTbl,
4699 sizeof(int(*)()) * instance._class.vTblSize);
4701 instance._vTbl[method.vid] = function ? function : DefaultFunction;
4707 public dllexport bool eInstance_IsDerived(Instance instance, Class from)
4711 Class _class = instance._class;
4712 for(; _class; _class = _class.base)
4721 public dllexport void eInstance_IncRef(Instance instance)
4724 instance._refCount++;
4727 public dllexport void eInstance_DecRef(Instance instance)
4731 instance._refCount--;
4732 //if(!instance._refCount)
4733 if(instance._refCount <= 0)
4735 eInstance_Delete(instance);
4740 static void FixOffsets(Class _class)
4743 _class.structSize += _class.base.structSize - _class.offset;
4745 _class.offset = _class.base.structSize;
4747 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
4748 FixOffsets(deriv.data);
4751 public dllexport void eClass_Resize(Class _class, int newSize)
4754 _class.structSize = newSize;
4755 for(deriv = _class.derivatives.first; deriv; deriv = deriv.next)
4756 FixOffsets(deriv.data);
4759 public dllexport DataMember eClass_AddDataMember(Class _class, char * name, char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
4763 if(!_class.members.FindString(name))
4765 DataMember dataMember;
4769 _class.structAlignment = Max(_class.structAlignment, alignment);
4771 if(_class.memberOffset % alignment)
4772 _class.memberOffset += alignment - (_class.memberOffset % alignment);
4775 dataMember = DataMember {
4776 name = CopyString(name);
4777 dataTypeString = CopyString(type);
4778 id = _class.memberID++;
4780 offset = _class.memberOffset;
4781 memberOffset = size;
4782 memberAccess = declMode;
4783 membersAlpha.CompareKey = (void *)BinaryTree::CompareString;
4785 _class.membersAndProperties.Add(dataMember);
4786 _class.memberOffset += size;
4788 _class.members.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4795 public dllexport DataMember eMember_AddDataMember(DataMember member, char * name, char * type, unsigned int size, unsigned int alignment, AccessMode declMode)
4797 if(name && !member.membersAlpha.FindString(name))
4799 DataMember dataMember;
4803 member.structAlignment = Max(member.structAlignment, alignment);
4805 if(member.memberOffset % alignment)
4806 member.memberOffset += alignment - (member.memberOffset % alignment);
4808 dataMember = DataMember {
4809 name = CopyString(name);
4810 _class = member._class;
4811 dataTypeString = CopyString(type);
4812 id = member.memberID++;
4813 offset = (member.type == unionMember) ? 0 : member.memberOffset;
4814 memberAccess = declMode;
4815 membersAlpha.CompareKey = (void *)BinaryTree::CompareString;
4817 member.members.Add(dataMember);
4818 if(member.type == unionMember)
4820 if(size > member.memberOffset)
4821 member.memberOffset = size;
4824 member.memberOffset += size;
4825 member.membersAlpha.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4831 public dllexport DataMember eMember_New(DataMemberType type, AccessMode declMode)
4833 return DataMember { type = type, memberAccess = declMode, membersAlpha.CompareKey = (void *)BinaryTree::CompareString };
4836 static void SetMemberClass(DataMember member, Class _class)
4838 DataMember dataMember;
4839 member._class = _class;
4840 for(dataMember = member.members.first; dataMember; dataMember = dataMember.next)
4841 SetMemberClass(dataMember, _class);
4844 public dllexport bool eMember_AddMember(DataMember addTo, DataMember dataMember)
4846 if(dataMember.name && addTo.membersAlpha.FindString(dataMember.name)) return false;
4847 addTo.members.Add(dataMember);
4850 addTo.membersAlpha.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4852 dataMember._class = addTo._class;
4853 // ? SetMemberClass(dataMember, addTo._class);
4855 //dataMember.id = addTo.memberID++;
4856 dataMember.id = addTo.memberID;
4857 if(dataMember.type == unionMember)
4858 addTo.memberID += 1;
4860 addTo.memberID += dataMember.memberID;
4862 addTo.structAlignment = Max(addTo.structAlignment, dataMember.structAlignment);
4863 dataMember.offset = (addTo.type == unionMember) ? 0 : addTo.memberOffset;
4864 if(addTo.type == unionMember)
4866 if(dataMember.memberOffset > addTo.memberOffset)
4867 addTo.memberOffset = dataMember.memberOffset;
4870 addTo.memberOffset += dataMember.memberOffset;
4874 public dllexport bool eClass_AddMember(Class _class, DataMember dataMember)
4876 if(!_class || _class.comRedefinition || (dataMember.name && _class.members.FindString(dataMember.name)))
4878 _class.membersAndProperties.Add(dataMember);
4881 _class.members.Add((BTNode)BTNamedLink { name = dataMember.name, data = dataMember });
4883 //dataMember._class = _class;
4884 SetMemberClass(dataMember, _class);
4886 //dataMember.id = _class.memberID++;
4887 dataMember.id = _class.memberID;
4889 _class.structAlignment = Max(_class.structAlignment, dataMember.structAlignment);
4890 if(dataMember.type == unionMember)
4891 _class.memberID += 1;
4893 _class.memberID += dataMember.memberID;
4894 dataMember.offset = _class.memberOffset;
4895 _class.memberOffset += dataMember.memberOffset;
4899 public dllexport BitMember eClass_AddBitMember(Class _class, char * name, char * type, int bitSize, int bitPos, AccessMode declMode)
4901 if(_class && name && !_class.members.FindString(name))
4907 name = CopyString(name);
4909 dataTypeString = CopyString(type);
4910 id = _class.memberID++;
4911 memberAccess = declMode;
4913 _class.membersAndProperties.Add(bitMember);
4916 bitMember.pos = (bitPos == -1) ? _class.memberOffset : bitPos;
4917 bitMember.size = bitSize;
4918 _class.memberOffset = bitMember.pos + bitMember.size;
4919 for(c = 0; c<bitSize; c++)
4925 bitMember.mask = mask << bitMember.pos;
4928 _class.members.Add((BTNode)BTNamedLink { name = bitMember.name, data = bitMember });
4934 static Module Module_Load(Module fromModule, char * name, AccessMode importAccess, bool ensureCOM)
4936 bool (stdcall * Load)(Module module) = null;
4937 void (stdcall * Unload)(Module module) = null;
4940 for(module = fromModule.application.allModules.first; module; module = module.next)
4942 if(!strcmp(module.name, name))
4945 if(ensureCOM && (!strcmp(name, "ecereCOM") || !strcmp(name, "ecere")))
4947 for(module = fromModule.application.allModules.first; module; module = module.next)
4949 if(!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM"))
4955 void * library = null;
4957 if(ensureCOM && !strcmp(name, "ecereCOM"))
4959 Load = COM_LOAD_FUNCTION;
4960 Unload = COM_UNLOAD_FUNCTION;
4964 library = Instance_Module_Load(name, &Load, &Unload);
4968 module = (Module)eInstance_New(eSystem_FindClass(fromModule, "Module"));
4969 module.application = fromModule.application;
4970 module.library = library;
4971 module.name = CopyString(name);
4972 module.Unload = Unload;
4975 eInstance_Delete((Instance)module);
4979 fromModule.application.allModules.Add(module);
4981 if(ensureCOM && !strcmp(name, "ecere") && module)
4983 name = !strcmp(module.name, "ecereCOM") ? "ecere" : "ecereCOM";
4984 if((!Load && !strcmp(module.name, "ecereCOM")) ||
4985 (Load && (!__thisModule || !__thisModule.name || !strcmp(__thisModule.name, "ecereCOM")) && Load != COM_LOAD_FUNCTION))
4988 for(module = fromModule.application.allModules.first; module; module = module.next)
4990 if(!strcmp(module.name, name))
4995 Load = COM_LOAD_FUNCTION;
4996 Unload = COM_UNLOAD_FUNCTION;
4998 module = (Module)eInstance_New(eSystem_FindClass(fromModule, "Module"));
4999 module.application = fromModule.application;
5000 module.library = null;
5001 module.name = CopyString(name);
5002 module.Unload = Unload;
5005 eInstance_Delete((Instance)module);
5008 fromModule.application.allModules.Add(module);
5014 fromModule.modules.Add(SubModule { module = module, importMode = importAccess });
5024 fromModule.modules.Add(SubModule { module = module, importMode = importAccess });
5031 public dllexport Module eModule_Load(Module fromModule, char * name, AccessMode importAccess)
5033 return Module_Load(fromModule, name, importAccess, true);
5036 public dllexport Module eModule_LoadStrict(Module fromModule, char * name, AccessMode importAccess)
5038 return Module_Load(fromModule, name, importAccess, false);
5041 public dllexport Module eModule_LoadStatic(Module fromModule, char * name, AccessMode importAccess, bool (* Load)(Module module), bool (* Unload)(Module module))
5044 for(module = fromModule.application.allModules.first; module; module = module.next)
5046 if(!strcmp(module.name, name))
5053 module = (Module)eInstance_New(eSystem_FindClass(fromModule, "Module"));
5054 module.application = fromModule.application;
5055 module.name = CopyString(name);
5056 module.Unload = (void *)Unload;
5059 eInstance_Delete((Instance)module);
5063 fromModule.application.allModules.Add(module);
5069 fromModule.modules.Add(SubModule { module = module, importMode = importAccess });
5076 public dllexport void eModule_Unload(Module fromModule, Module module)
5079 for(m = fromModule.modules.first; m; m = m.next)
5081 if(m.data == module)
5086 fromModule.modules.Delete(m);
5091 public dllexport void eEnum_AddFixedValue(Class _class, char * string, int value)
5093 if(_class && _class.type == enumClass)
5095 EnumClassData data = (EnumClassData)_class.data;
5098 for(item = data.values.first; item; item = item.next)
5099 if(!strcmp(item.name, string))
5103 data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
5104 if(value > data.largest)
5105 data.largest = value;
5110 public dllexport int eEnum_AddValue(Class _class, char * string)
5112 if(_class && _class.type == enumClass)
5114 EnumClassData data = (EnumClassData)_class.data;
5115 int value = ((int) data.largest) + 1;
5117 for(item = data.values.first; item; item = item.next)
5118 if(!strcmp(item.name, string))
5122 data.values.Add(NamedLink { data = (void *)value, name = CopyString(string) });
5123 if(value > data.largest)
5124 data.largest = value;
5131 static void NameSpace_Free(NameSpace parentNameSpace)
5133 NameSpace * nameSpace;
5134 delete parentNameSpace.name;
5136 while((nameSpace = (NameSpace *)parentNameSpace.nameSpaces.first))
5138 NameSpace_Free(nameSpace);
5139 parentNameSpace.nameSpaces.Delete((BTNode)nameSpace);
5143 static void Application_Destructor(Application app)
5145 if(app.parsedCommand)
5148 delete app.parsedCommand;
5152 static bool Module_Constructor(Module module)
5154 module.privateNameSpace.classes.CompareKey = (void *)BinaryTree::CompareString;
5155 module.privateNameSpace.defines.CompareKey = (void *)BinaryTree::CompareString;
5156 module.privateNameSpace.functions.CompareKey = (void *)BinaryTree::CompareString;
5157 module.privateNameSpace.nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5159 module.publicNameSpace.classes.CompareKey = (void *)BinaryTree::CompareString;
5160 module.publicNameSpace.defines.CompareKey = (void *)BinaryTree::CompareString;
5161 module.publicNameSpace.functions.CompareKey = (void *)BinaryTree::CompareString;
5162 module.publicNameSpace.nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5166 static void Module_Destructor(Module module)
5169 DefinedExpression def;
5170 GlobalFunction function;
5174 // printf("Destructing module %s\n", module.name);
5176 // Take out references from all modules
5177 for(m = module.application.allModules.first; m; m = m.next)
5180 for(handle = m.modules.first; handle; handle = next)
5183 if(handle.module == module)
5184 m.modules.Delete(handle);
5190 if(module.importType == staticImport)
5192 bool (* Unload)(Module module) = (void *)module.Unload;
5197 bool (stdcall * Unload)(Module module) = (void *)module.Unload;
5202 // Unload dependencies
5204 Module ourWorld = class(Class).module;
5205 void * ourHandle = null;
5206 while((handle = module.modules.last)) // STARTING WITH LAST SO THAT ecereCOM IS UNLOADED LAST...
5208 Module depModule = handle.module;
5209 if(depModule == ourWorld)
5211 module.modules.Remove(handle);
5216 module.modules.Delete(handle);
5228 for(;(_class = module.classes.first);)
5230 if(_class.nameSpace)
5232 BTNamedLink classLink = (BTNamedLink)_class.nameSpace->classes.FindString(_class.name);
5234 for(t = _class.templatized.first; t; t = t.next)
5236 Class template = t.data;
5238 link = (BTNamedLink)template.nameSpace->classes.FindString(template.name);
5240 template.nameSpace->classes.Delete((BTNode)link);
5241 template.nameSpace = null;
5243 _class.nameSpace->classes.Delete((BTNode)classLink);
5244 _class.nameSpace = null;
5246 _class.module = null;
5247 module.classes.Remove(_class);
5248 if(!_class.count || _class.type != normalClass)
5249 eClass_Unregister(_class);
5253 // printf("Delayed destruction of class %s\n", _class.name);
5259 for(;(def = module.defines.first);)
5263 BTNamedLink defLink;
5264 for(defLink = (BTNamedLink)def.nameSpace->defines.first; defLink; defLink = (BTNamedLink)((BTNode)defLink).next)
5265 if(defLink.data == def)
5267 def.nameSpace->defines.Delete((BTNode)defLink);
5273 module.defines.Delete(def);
5277 for(;(function = module.functions.first);)
5279 if(function.nameSpace)
5281 BTNamedLink functionLink;
5282 for(functionLink = (BTNamedLink)function.nameSpace->functions.first; functionLink; functionLink = (BTNamedLink)((BTNode)functionLink).next)
5283 if(functionLink.data == function)
5285 function.nameSpace->functions.Delete((BTNode)functionLink);
5289 delete function.name;
5290 delete function.dataTypeString;
5291 module.functions.Delete(function);
5296 NameSpace_Free(module.privateNameSpace);
5297 NameSpace_Free(module.publicNameSpace);
5299 if(module != module.application)
5300 module.application.allModules.Remove(module);
5302 NameSpace_Free(module.application.systemNameSpace);
5305 Instance_Module_Free(module.library);
5309 static int GetEnumSize(Class _class)
5311 EnumClassData data = (EnumClassData)_class.data;
5312 return data.largest+1;
5315 #if defined(__GNUC__)
5316 #define strcmpi strcasecmp
5317 #define strnicmp strncasecmp
5320 #if defined(ECERE_BOOTSTRAP) || (defined(__GNUC__) && !defined(__DJGPP__) && !defined(__WIN32__))
5323 default dllexport char * strlwr(char *string)
5326 for(c=0; string[c]; c++)
5327 if(string[c]>='A' && string[c]<='Z')
5331 default dllexport char * strupr(char *string)
5334 for(c=0; string[c]; c++)
5335 if(string[c]>='a' && string[c]<='z')
5341 public dllexport DefinedExpression eSystem_RegisterDefine(char * name, char * value, Module module, AccessMode declMode)
5343 NameSpace * nameSpace = null;
5347 nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
5348 if(declMode == baseSystemAccess) nameSpace = &module.application.systemNameSpace;
5350 if(declMode != staticAccess)
5352 for(c = 0; name[c]; c++)
5354 if(name[c] == '.' || (name[c] == ':' && name[c+1] == ':'))
5356 NameSpace * newSpace;
5358 char * spaceName = _malloc(c - start + 1);
5359 strncpy(spaceName, name + start, c - start);
5360 spaceName[c-start] = '\0';
5362 newSpace = (NameSpace *)nameSpace->nameSpaces.FindString(spaceName);
5365 newSpace = new0 NameSpace[1];
5366 newSpace->classes.CompareKey = (void *)BinaryTree::CompareString;
5367 newSpace->defines.CompareKey = (void *)BinaryTree::CompareString;
5368 newSpace->functions.CompareKey = (void *)BinaryTree::CompareString;
5369 newSpace->nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5370 newSpace->name = spaceName;
5371 newSpace->parent = nameSpace;
5372 nameSpace->nameSpaces.Add((BTNode)newSpace);
5376 nameSpace = newSpace;
5377 if(name[c] == ':') c++;
5385 if(c - start && !nameSpace->defines.FindString(name + start))
5387 DefinedExpression def
5389 name = CopyString(name);
5390 nameSpace = nameSpace;
5391 value = CopyString(value);
5393 nameSpace->defines.Add((BTNode)BTNamedLink { name = def.name + start, data = def });
5394 // Reference the definition in the module
5395 module.defines.Add(def);
5401 public dllexport GlobalFunction eSystem_RegisterFunction(char * name, char * type, void * func, Module module, AccessMode declMode)
5403 NameSpace * nameSpace = null;
5406 nameSpace = (declMode == publicAccess) ? &module.publicNameSpace : &module.privateNameSpace;
5407 if(declMode == baseSystemAccess) nameSpace = &module.application.systemNameSpace;
5409 if(declMode != staticAccess)
5411 for(c = 0; name[c]; c++)
5413 if(name[c] == '.' || (name[c] == ':' && name[c+1] == ':'))
5415 NameSpace * newSpace;
5417 char * spaceName = _malloc(c - start + 1);
5418 strncpy(spaceName, name + start, c - start);
5419 spaceName[c-start] = '\0';
5421 newSpace = (NameSpace *)nameSpace->nameSpaces.FindString(spaceName);
5424 newSpace = new0 NameSpace[1];
5425 newSpace->classes.CompareKey = (void *)BinaryTree::CompareString;
5426 newSpace->defines.CompareKey = (void *)BinaryTree::CompareString;
5427 newSpace->functions.CompareKey = (void *)BinaryTree::CompareString;
5428 newSpace->nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5429 newSpace->name = spaceName;
5430 newSpace->parent = nameSpace;
5431 nameSpace->nameSpaces.Add((BTNode)newSpace);
5435 nameSpace = newSpace;
5436 if(name[c] == ':') c++;
5444 if(c - start && !nameSpace->functions.FindString(name + start))
5446 GlobalFunction function
5448 name = CopyString(name);
5449 nameSpace = nameSpace;
5450 dataTypeString = CopyString(type);
5454 nameSpace->functions.Add((BTNode)BTNamedLink { name = function.name + start, data = function });
5455 // Reference the definition in the module
5456 module.functions.Add(function);
5462 public dllexport DefinedExpression eSystem_FindDefine(Module module, char * name)
5467 link = SearchNameSpace(&module.application.systemNameSpace, name, &((NameSpace *)0)->defines);
5468 if(link) return link.data;
5470 link = SearchModule(module, name, &((NameSpace *)0)->defines, true);
5471 if(link) return link.data;
5476 public dllexport GlobalFunction eSystem_FindFunction(Module module, char * name)
5481 link = SearchNameSpace(&module.application.systemNameSpace, name, &((NameSpace *)0)->functions);
5482 if(link) return link.data;
5484 link = SearchModule(module, name, &((NameSpace *)0)->functions, true);
5485 if(link) return link.data;
5490 public dllexport void * eSystem_Renew(void * memory, unsigned int size)
5492 return _realloc(memory, size);
5495 public dllexport void * eSystem_Renew0(void * memory, unsigned int size)
5497 return _crealloc(memory, size);
5500 public dllexport void * eSystem_New(unsigned int size)
5503 void * pointer = _malloc(size);
5504 memset(pointer, 0xec, size);
5507 return _malloc(size);
5511 public dllexport void * eSystem_New0(unsigned int size)
5513 return _calloc(1,size);
5516 public dllexport void eSystem_Delete(void * memory)
5523 public dllexport void eInstance_FireSelfWatchers(Instance instance, Property _property)
5525 if(instance && _property && _property.selfWatchable)
5528 for(_class = instance._class; _class; _class = _class.base)
5530 SelfWatcher selfWatcher, next;
5531 for(selfWatcher = _class.selfWatchers.first; selfWatcher; selfWatcher = next)
5533 next = selfWatcher.next;
5534 if(selfWatcher._property == _property)
5535 selfWatcher.callback(instance);
5541 public dllexport void eInstance_FireWatchers(Instance instance, Property _property)
5543 if(instance && _property && _property.isWatchable)
5545 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5546 Watcher watcher, next;
5548 for(watcher = watchers->first; watcher; watcher = next)
5550 next = watcher.next;
5551 watcher.callback(watcher.object, instance);
5556 public dllexport void eProperty_Watchable(Property _property)
5558 if(!_property.isWatchable)
5560 Class _class = _property._class;
5561 if(!_class.computeSize)
5563 _property.watcherOffset = _class.structSize;
5564 _class.structSize += sizeof(OldList);
5566 // highly inefficient
5567 FixDerivativesBase(_class, _class);
5569 _property.isWatchable = true;
5573 public dllexport void eClass_DestructionWatchable(Class _class)
5575 if(!_class.destructionWatchOffset)
5577 _class.destructionWatchOffset = _class.structSize;
5578 _class.structSize += sizeof(OldList);
5579 // highly inefficient
5580 FixDerivativesBase(_class, _class);
5584 public dllexport void eProperty_SelfWatch(Class _class, char * name, void (*callback)(void *))
5588 Property _property = eClass_FindProperty(_class, name, _class.module);
5591 _property = eClass_AddProperty(_class, name, null, null, null, baseSystemAccess /*privateAccess*/);
5592 _class.selfWatchers.Add(SelfWatcher { _property = _property, callback = callback });
5593 _property.selfWatchable = true;
5597 public dllexport void eInstance_Watch(void * instance, Property _property, void * object, void (*callback)(void *, void *))
5599 if(_property.isWatchable)
5601 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5602 watchers->Add(Watcher { callback = callback, object = object });
5606 public dllexport void eInstance_WatchDestruction(Instance instance, Instance object, void (*callback)(Instance, Instance))
5608 OldList * watchers = (OldList *)((byte *)instance + instance._class.destructionWatchOffset);
5609 watchers->Add(Watcher { callback = callback, object = object });
5612 public dllexport void eInstance_StopWatching(Instance instance, Property _property, Instance object)
5614 if(instance && (!_property || _property.isWatchable))
5618 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5620 for(watcher = watchers->first; watcher; watcher = watcher.next)
5621 if(watcher.object == object)
5623 watchers->Delete(watcher);
5629 // Stop watching all properties as well as destruction
5631 for(_class = instance._class; _class; _class = base)
5633 if(_class.destructionWatchOffset)
5635 OldList * watchers = (OldList *)((byte *)instance + _class.destructionWatchOffset);
5638 for(watcher = watchers->first; watcher; watcher = watcher.next)
5640 watchers->Delete(watcher);
5644 for(_property = (Property)_class.membersAndProperties.first; _property; _property = _property.next)
5646 if(_property.isProperty && _property.isWatchable)
5648 OldList * watchers = (OldList *)((byte *)instance + _property.watcherOffset);
5650 for(watcher = watchers->first; watcher; watcher = watcher.next)
5651 if(watcher.object == object)
5653 watchers->Delete(watcher);
5659 if(base && base.type == systemClass) base = null;
5665 public dllexport subclass(ClassDesignerBase) eClass_GetDesigner(Class _class)
5667 for(;_class;_class = _class.base)
5669 if(_class.designerClass)
5670 return (subclass(ClassDesignerBase))eSystem_FindClass(_class.module, _class.designerClass);
5676 public dllexport subclass(ClassDesignerBase) eInstance_GetDesigner(Instance instance)
5679 return eClass_GetDesigner(instance._class);
5683 public bool LocateModule(char * name, char * fileName)
5685 return Instance_LocateModule(name, fileName);
5688 static void LoadCOM(Module module)
5690 Class applicationClass;
5691 Class enumClass, structClass, boolClass;
5694 // Create Base Class
5695 Class baseClass = eSystem_RegisterClass(normalClass, "class", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5696 baseClass.type = systemClass;
5697 baseClass.memberOffset = 0;
5698 baseClass.offset = 0;
5699 baseClass.structSize = 0;
5700 baseClass.typeSize = 0;
5703 Class instanceClass = eSystem_RegisterClass(normalClass, "ecere::com::Instance", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5704 // Instance should really be a Normal class, but inheritance checks for systemClass to see if something has a non system ancestor
5705 instanceClass.type = systemClass;
5706 instanceClass.fixed = true;
5707 instanceClass.memberOffset = 0;
5708 instanceClass.offset = 0;
5710 instanceClass.memberID = -3;
5711 instanceClass.startMemberID = -3;
5713 // eClass_AddDataMember(instanceClass, "_vTbl", "void **", sizeof(int (**)()), 4, publicAccess);
5714 eClass_AddDataMember(instanceClass, "_vTbl", "int (**)()", sizeof(int (**)()), 4, publicAccess);
5715 eClass_AddDataMember(instanceClass, "_class", "ecere::com::Class", sizeof(Class), 4, publicAccess);
5716 eClass_AddDataMember(instanceClass, "_refCount", "int", sizeof(int (**)()), 4, publicAccess);
5719 InitializeDataTypes1(module);
5721 // Create Enum class
5722 enumClass = eSystem_RegisterClass(normalClass, "enum", null, 0, sizeof(class EnumClassData), null, null, module, baseSystemAccess, publicAccess);
5723 eClass_AddClassProperty(enumClass, "enumSize", "int", null, GetEnumSize).constant = true;
5724 enumClass.type = systemClass;
5726 delete enumClass.dataTypeString;
5727 enumClass.dataTypeString = CopyString(/*"unsigned int"*/"int");
5729 // Create Struct (simple) class
5730 //structClass = eSystem_RegisterClass(structClass, "struct", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5731 structClass = eSystem_RegisterClass(normalClass, "struct", null, 0, 0, null, null, module, baseSystemAccess, publicAccess);
5732 structClass.type = systemClass;
5733 structClass.memberOffset = 0;
5734 structClass.offset = 0;
5735 structClass.structSize = 0;
5736 structClass.typeSize = 0;
5738 //eClass_AddMethod(enumClass, "AddValue", "int()", eEnum_AddValue);
5739 //eClass_AddMethod(enumClass, "AddFixedValue", "void()", eEnum_AddFixedValue);
5741 InitializeDataTypes(module);
5743 // Create bool class
5744 boolClass = eSystem_RegisterClass(ClassType::enumClass, "bool", "uint", 0, 0, null, null, module, baseSystemAccess, publicAccess);
5745 eEnum_AddFixedValue(boolClass, "true", bool::true);
5746 eEnum_AddFixedValue(boolClass, "false", bool::false);
5748 // Create Module class
5749 moduleClass = eSystem_RegisterClass(normalClass, "ecere::com::Module", null, sizeof(struct Module), 0, (void *)Module_Constructor, (void *)Module_Destructor, module, baseSystemAccess, publicAccess);
5750 eClass_AddVirtualMethod(moduleClass, "OnLoad", "bool()", null, publicAccess);
5751 eClass_AddVirtualMethod(moduleClass, "OnUnload", "void()", null, publicAccess);
5752 eClass_AddMethod(moduleClass, "Load", "Module(char * name, AccessMode importAccess)", eModule_Load, publicAccess);
5753 eClass_AddMethod(moduleClass, "Unload", "void(Module module)", eModule_Unload, publicAccess);
5754 eClass_AddDataMember(moduleClass, "application", "Application", sizeof(Application), 4, publicAccess);
5755 eClass_AddDataMember(moduleClass, "classes", "OldList", sizeof(OldList), 4, publicAccess);
5756 eClass_AddDataMember(moduleClass, "defines", "OldList", sizeof(OldList), 4, publicAccess);
5757 eClass_AddDataMember(moduleClass, "functions", "OldList", sizeof(OldList), 4, publicAccess);
5758 eClass_AddDataMember(moduleClass, "modules", "OldList", sizeof(OldList), 4, publicAccess);
5759 eClass_AddDataMember(moduleClass, "prev", "Module", sizeof(Module), 4, publicAccess);
5760 eClass_AddDataMember(moduleClass, "next", "Module", sizeof(Module), 4, publicAccess);
5761 eClass_AddDataMember(moduleClass, "name", "char *", sizeof(char *), 4, publicAccess);
5762 eClass_AddDataMember(moduleClass, "library", "void *", sizeof(void *), 4, publicAccess);
5763 eClass_AddDataMember(moduleClass, "Unload", "void *", sizeof(void *), 4, publicAccess);
5764 eClass_AddDataMember(moduleClass, "importType", "ImportType", sizeof(ImportType), 4, publicAccess);
5765 eClass_AddDataMember(moduleClass, "privateNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
5766 eClass_AddDataMember(moduleClass, "publicNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
5767 moduleClass.fixed = true;
5768 moduleClass.count++;
5770 // Create Application class
5771 applicationClass = eSystem_RegisterClass(normalClass, "ecere::com::Application", "Module", sizeof(struct Application), 0, null, (void *)Application_Destructor, module, baseSystemAccess, publicAccess);
5772 eClass_AddVirtualMethod(applicationClass, "Main", "void()", null, publicAccess);
5773 eClass_AddDataMember(applicationClass, "argc", "int", sizeof(int), 4, publicAccess);
5774 eClass_AddDataMember(applicationClass, "argv", "char **", sizeof(char **), 4, publicAccess);
5775 eClass_AddDataMember(applicationClass, "exitCode", "int", sizeof(int), 4, publicAccess);
5776 eClass_AddDataMember(applicationClass, "isGUIApp", "bool", sizeof(bool), 4, publicAccess);
5777 eClass_AddDataMember(applicationClass, "allModules", "OldList", sizeof(OldList), 4, publicAccess);
5778 eClass_AddDataMember(applicationClass, "parsedCommand", "char *", sizeof(char *), 4, publicAccess);
5779 eClass_AddDataMember(applicationClass, "systemNameSpace", "NameSpace", sizeof(NameSpace), 4, publicAccess);
5780 applicationClass.fixed = true;
5781 applicationClass.count++;
5783 //AttachConsole(-1);
5787 eSystem_RegisterFunction("sin", "double sin(Angle number)", sin, module, baseSystemAccess);
5788 eSystem_RegisterFunction("sinh", "double sinh(Angle number)", sinh, module, baseSystemAccess);
5789 eSystem_RegisterFunction("cosh", "double cosh(Angle number)", cosh, module, baseSystemAccess);
5790 eSystem_RegisterFunction("tanh", "double tanh(Angle number)", tanh, module, baseSystemAccess);
5791 eSystem_RegisterFunction("sqrt", "double sqrt(double number)", sqrt, module, baseSystemAccess);
5792 eSystem_RegisterFunction("cos", "double cos(Angle number)", cos, module, baseSystemAccess);
5793 eSystem_RegisterFunction("tan", "double tan(Angle number)", tan, module, baseSystemAccess);
5794 eSystem_RegisterFunction("atan2", "Angle atan2(double y, double x)", atan2, module, baseSystemAccess);
5795 eSystem_RegisterFunction("asin", "Angle asin(double number)", asin, module, baseSystemAccess);
5796 eSystem_RegisterFunction("acos", "Angle acos(double number)", acos, module, baseSystemAccess);
5797 eSystem_RegisterFunction("atan", "Angle atan(double number)", atan, module, baseSystemAccess);
5798 eSystem_RegisterFunction("pow", "double pow(double number, double number2)", pow, module, baseSystemAccess);
5799 eSystem_RegisterFunction("fmod", "double fmod(double x, double y)", fmod, module, baseSystemAccess);
5800 eSystem_RegisterFunction("fabs", "double fabs(double number)", fabs, module, baseSystemAccess);
5801 eSystem_RegisterFunction("log", "double log(double number)", log, module, baseSystemAccess);
5802 eSystem_RegisterFunction("log10", "double log10(double number)", log10, module, baseSystemAccess);
5803 eSystem_RegisterFunction("ceil", "double ceil(double number)", ceil, module, baseSystemAccess);
5804 eSystem_RegisterFunction("floor", "double floor(double number)", floor, module, baseSystemAccess);
5805 eSystem_RegisterFunction("exp", "double exp(double number)", exp, module, baseSystemAccess);
5808 eSystem_RegisterFunction("qsort", "void qsort(void *, uint, uint, int (*)(void *, void *))", qsort, module, baseSystemAccess);
5809 eSystem_RegisterFunction("strtod", "double strtod(char*, char**)", strtod, module, baseSystemAccess);
5810 eSystem_RegisterFunction("strtol", "int strtol(char*, char**, int base)", strtol, module, baseSystemAccess);
5811 eSystem_RegisterFunction("system", "int system(const char*)", system, module, baseSystemAccess);
5812 eSystem_RegisterFunction("atoi", "int atoi(const char*)", atoi, module, baseSystemAccess);
5813 eSystem_RegisterFunction("atof", "float atof(const char*)", atof, module, baseSystemAccess);
5814 eSystem_RegisterFunction("tolower", "int tolower(int)", tolower, module, baseSystemAccess);
5815 eSystem_RegisterFunction("toupper", "int toupper(int)", toupper, module, baseSystemAccess);
5816 eSystem_RegisterFunction("isdigit", "bool isdigit(int)", isdigit, module, baseSystemAccess);
5817 eSystem_RegisterFunction("memset", "void memset(void * area, byte value, uint count)", memset, module, baseSystemAccess);
5818 eSystem_RegisterFunction("getenv", "char * getenv(const char * name)", getenv, module, baseSystemAccess);
5819 eSystem_RegisterFunction("rename", "int rename(const char *oldpath, const char *newpath)", rename, module, baseSystemAccess);
5821 // --- String --- (These might move to the string class)
5822 eSystem_RegisterFunction("strlen", "int strlen(const char *)", strlen, module, baseSystemAccess);
5823 eSystem_RegisterFunction("strcat", "char * strcat(char *, const char *)", strcat, module, baseSystemAccess);
5824 eSystem_RegisterFunction("strncat", "char * strncat(char *, const char *, int n)", strncat, module, baseSystemAccess);
5825 eSystem_RegisterFunction("strchr", "char * strchr(char *, int)", strchr, module, baseSystemAccess);
5826 eSystem_RegisterFunction("strstr", "char * strstr(char *, const char *)", strstr, module, baseSystemAccess);
5828 eSystem_RegisterDefine("fstrcmp", "(GetRuntimePlatform() == win32) ? strcmpi : strcmp", module, baseSystemAccess);
5830 //#if defined(__GNUC__)
5831 eSystem_RegisterDefine("strcmpi", "strcasecmp", module, baseSystemAccess);
5832 eSystem_RegisterDefine("strnicmp", "strncasecmp", module, baseSystemAccess);
5833 eSystem_RegisterFunction("strcasecmp", "int strcasecmp(const char *, const char *)", strcmpi, module, baseSystemAccess);
5834 eSystem_RegisterFunction("strncasecmp", "int strncasecmp(const char *, const char *, int n)", strnicmp, module, baseSystemAccess);
5837 eSystem_RegisterDefine("strcasecmp", "strcmpi", module, baseSystemAccess);
5838 eSystem_RegisterDefine("strncasecmp", "strnicmp", module, baseSystemAccess);
5839 eSystem_RegisterFunction("strcmpi", "int strcmpi(const char *, const char *)", strcmpi, module, baseSystemAccess);
5840 eSystem_RegisterFunction("strnicmp", "int strnicmp(const char *, const char *, int n)", strnicmp, module, baseSystemAccess);
5844 eSystem_RegisterFunction("strcmp", "int strcmp(const char *, const char *)", strcmp, module, baseSystemAccess);
5845 eSystem_RegisterFunction("strncmp", "int strncmp(const char *, const char *, int n)", strncmp, module, baseSystemAccess);
5846 eSystem_RegisterFunction("strlwr", "char * strlwr(char *)", strlwr, module, baseSystemAccess);
5847 eSystem_RegisterFunction("strupr", "char * strupr(char *)", strupr, module, baseSystemAccess);
5848 eSystem_RegisterFunction("strcpy", "char * strcpy(char *, const char *)", strcpy, module, baseSystemAccess);
5849 eSystem_RegisterFunction("strncpy", "char * strncpy(char *, const char *, int n)", strncpy, module, baseSystemAccess);
5850 eSystem_RegisterFunction("memcpy", "void * memcpy(void *, const void *, uint size)", memcpy, module, baseSystemAccess);
5851 eSystem_RegisterFunction("memmove", "void * memmove(void *, const void *, uint size)", memmove, module, baseSystemAccess);
5854 eSystem_RegisterFunction("sprintf", "int sprintf(char *, char *, ...)", sprintf, module, baseSystemAccess);
5855 eSystem_RegisterFunction("printf", "int printf(char *, ...)", printf, module, baseSystemAccess);
5856 eSystem_RegisterFunction("vsprintf", "int vsprintf(char*, const char*, __builtin_va_list)", vsprintf, module, baseSystemAccess);
5857 eSystem_RegisterFunction("puts", "int puts(char *)", puts, module, baseSystemAccess);
5858 eSystem_RegisterFunction("fputs", "int fputs(char *, void * stream)", fputs, module, baseSystemAccess);
5861 eSystem_RegisterFunction("isalnum", "int isalnum(int c)", isalnum, module, baseSystemAccess);
5862 eSystem_RegisterFunction("isspace", "int isspace(int c)", isspace, module, baseSystemAccess);
5863 eSystem_RegisterFunction("isalpha", "int isalpha(int c)", isalpha, module, baseSystemAccess);
5864 eSystem_RegisterFunction("islower", "int islower(int c)", islower, module, baseSystemAccess);
5865 eSystem_RegisterFunction("isupper", "int isupper(int c)", isupper, module, baseSystemAccess);
5866 eSystem_RegisterFunction("isprint", "int isprint(int c)", isprint, module, baseSystemAccess);
5867 eSystem_RegisterFunction("strtoul", "unsigned long strtoul(const char * nptr, char ** endptr, int base)", strtoul, module, baseSystemAccess);
5871 public dllexport Application __ecere_COM_Initialize(bool guiApp, int argc, char * argv[])
5876 // printf("Using debug ecere runtime library\n");
5878 app = _calloc(1, sizeof(class Application));
5880 Module_Constructor(app);
5881 app.systemNameSpace.classes.CompareKey = (void *)BinaryTree::CompareString;
5882 app.systemNameSpace.defines.CompareKey = (void *)BinaryTree::CompareString;
5883 app.systemNameSpace.functions.CompareKey = (void *)BinaryTree::CompareString;
5884 app.systemNameSpace.nameSpaces.CompareKey = (void *)BinaryTree::CompareString;
5886 Instance_COM_Initialize(argc, argv, &app.parsedCommand, &app.argc, &app.argv);
5888 app.application = app;
5889 app.allModules.offset = sizeof(class Instance) + (uint)&((struct Module *)0)->prev;
5890 app.isGUIApp = guiApp;
5894 app._class = eSystem_FindClass(app, "Application");
5899 public dllexport ClassTemplateParameter eClass_AddTemplateParameter(Class _class, char * name, TemplateParameterType type, void * info, ClassTemplateArgument defaultArg)
5903 ClassTemplateParameter param;
5905 for(param = _class.templateParams.first; param; param = param.next)
5907 if(!strcmp(param.name, name))
5912 name = CopyString(name);
5914 (type == identifier) ? info : CopyString(info);
5916 if(defaultArg != null)
5918 param.defaultArg = defaultArg;
5919 CopyTemplateArg(param, param.defaultArg);
5921 _class.templateParams.Add(param);
5927 public dllexport void eClass_DoneAddingTemplateParameters(Class base)
5932 ClassTemplateParameter param;
5934 void * first = base.templateParams.first;
5935 int count = base.templateParams.count;
5936 base.templateParams.first = null;
5937 base.templateParams.count = 0;
5939 FreeTemplateArgs(base);
5940 delete base.templateArgs;
5941 FreeTemplatesDerivatives(base);
5943 base.templateParams.first = first;
5944 base.templateParams.count = count;
5947 for(param = base.templateParams.first; param; param = param.next)
5949 if(param.type == identifier && param.defaultArg.memberString)
5951 Class memberClass = base;
5952 char * colon = strstr(param.defaultArg.memberString, "::");
5956 char className[1024];
5959 memcpy(className, param.defaultArg.memberString, colon - param.defaultArg.memberString);
5960 className[colon - param.defaultArg.memberString] = '\0';
5961 memberName = colon + 2;
5963 for(sClass = base; sClass; sClass = sClass.base)
5965 ClassTemplateParameter cParam;
5968 for(nextClass = sClass.base; nextClass; nextClass = nextClass.base) id += nextClass.templateParams.count;
5969 // Safety! What could cause base.templateArgs to be null?
5970 if(sClass == base || base.templateArgs)
5972 for(cParam = sClass.templateParams.first; cParam; cParam = cParam.next)
5974 if(cParam.type == type && !strcmp(cParam.name, className))
5975 strcpy(className, (sClass == base) ? cParam.defaultArg.dataTypeString : base.templateArgs[id].dataTypeString);
5980 memberClass = eSystem_FindClass(base.module, className);
5982 memberClass = eSystem_FindClass(base.module.application, className);
5985 memberName = param.defaultArg.memberString;
5989 switch(param.memberType)
5992 param.defaultArg.member = eClass_FindDataMember(memberClass, memberName, memberClass.module, null, null);
5995 param.defaultArg.method = eClass_FindMethod(memberClass, memberName, memberClass.module);
5998 param.defaultArg.prop = eClass_FindProperty(memberClass, memberName, memberClass.module);
6005 //ComputeClassParameters(base, null, null);
6007 FixDerivativesBase(base, base);
6011 static void FreeTemplatesDerivatives(Class base)
6013 OldLink derivative, templateLink;
6014 for(derivative = base.derivatives.first; derivative; derivative = derivative.next)
6016 Class _class = derivative.data;
6017 if(_class.templateArgs)
6019 FreeTemplateArgs(_class);
6020 delete _class.templateArgs;
6022 FreeTemplatesDerivatives(_class);
6025 for(templateLink = base.templatized.first; templateLink; templateLink = templateLink.next)
6027 Class _class = templateLink.data;
6028 if(_class.templateArgs)
6030 FreeTemplateArgs(_class);
6031 delete _class.templateArgs;
6033 FreeTemplatesDerivatives(_class);
6037 static const char * platformNames[Platform] = { "", "win32", "linux", "apple" }; // how to have this be accessible outside of dll/lib
6038 static const Platform firstPlatform = win32;
6039 static const Platform lastPlatform = apple;
6041 public enum Platform
6043 unknown, win32, tux, apple;
6047 get { return OnGetString(null, null, null); }
6053 for(c = firstPlatform; c <= lastPlatform; c++)
6054 if(!strcmpi(value, platformNames[c]))
6061 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
6063 if(this >= firstPlatform && this <= lastPlatform)
6066 strcpy(tempString, platformNames[this]);
6067 return platformNames[this];
6069 if(tempString && tempString[0])
6070 tempString[0] = '\0';
6074 bool OnGetDataFromString(char * string)
6081 default extern Platform runtimePlatform;
6083 public Platform GetRuntimePlatform()
6085 return runtimePlatform;
6093 // CLASS DESIGNER SUPPORT
6095 public class ObjectInfo : struct
6098 ObjectInfo prev, next;
6101 Instantiation instCode;
6105 ClassDefinition classDefinition;
6109 public class DesignerBase : Window
6112 virtual bool FindObject(Instance * instance, char * string);
6113 virtual void RenameObject(ObjectInfo object, char * name);
6114 virtual void SelectObjectFromDesigner(ObjectInfo object);
6115 virtual void CodeAddObject(Instance instance, ObjectInfo * object);
6116 virtual void SheetAddObject(ObjectInfo object);
6117 virtual void AddToolBoxClass(Class _class);
6118 virtual void AddDefaultMethod(Instance instance, Instance classInstance);
6119 virtual void DeleteObject(ObjectInfo object);
6120 virtual bool ObjectContainsCode(ObjectInfo object);
6121 virtual void ModifyCode(void);
6122 virtual void UpdateProperties(void);
6124 ClassDesignerBase classDesigner;
6128 // FIX THIS WITH PUBLIC:
6129 property ClassDesignerBase classDesigner
6131 get { return classDesigner; }
6132 set { classDesigner = value; }
6134 property char * objectClass
6136 get { return objectClass; }
6137 set { objectClass = value; }
6139 property bool isDragging
6141 get { return isDragging; }
6142 set { isDragging = value; }
6146 public class ClassDesignerBase : Window
6149 virtual void Reset(void);
6150 virtual void AddObject(void);
6151 virtual void SelectObject(ObjectInfo object, Instance control);
6153 virtual void ListToolBoxClasses(DesignerBase designer);
6155 virtual void ::PrepareTestObject(DesignerBase designer, Instance test);
6156 virtual void ::CreateObject(DesignerBase designer, Instance instance, ObjectInfo object, bool isClass, Instance _class);
6157 virtual void ::PostCreateObject(Instance instance, ObjectInfo object, bool isClass, Instance _class);
6158 virtual void ::DroppedObject(Instance instance, ObjectInfo object, bool isClass, Instance _class);
6159 virtual void ::DestroyObject(Instance object);
6160 virtual void ::FixProperty(Property prop, Instance object);
6161 virtual void ::CreateNew(EditBox editBox, Size clientSize, char * name, char * inherit);
6164 DesignerBase activeDesigner;
6166 public void SetActiveDesigner(DesignerBase designer)
6168 activeDesigner = designer;
6171 public DesignerBase GetActiveDesigner()
6173 return activeDesigner;
6179 define LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
6180 define SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00;
6182 public bool UTF8Validate(char * source)
6187 for(c = 0; source[c];)
6189 byte ch = source[c];
6190 unichar codePoint = 0;
6216 for(i = 0; i<numBytes && (ch = source[c]); i++, c++)
6219 codePoint |= ch & mask;
6223 if(!(ch & 0x80) || (ch & 0x40))
6227 if(i < numBytes) return false;
6229 if(codePoint > 0x10FFFF || (codePoint >= 0xD800 && codePoint <= 0xDFFF) ||
6230 (codePoint < 0x80 && numBytes > 1) ||
6231 (codePoint < 0x800 && numBytes > 2) ||
6232 (codePoint < 0x10000 && numBytes > 3))
6239 public int ISO8859_1toUTF8(char * source, char * dest, int max)
6243 for(c = 0; source[c]; c++)
6245 unichar ch = ((byte *)source)[c];
6248 if(d + 1 >= max) break;
6249 dest[d++] = (char)ch;
6253 if(d + 2 >= max) break;
6254 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6255 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6257 else if(ch < 0x10000)
6259 if(d + 3 >= max) break;
6260 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6261 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6262 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6266 if(d + 4 >= max) break;
6267 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6268 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6269 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6270 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6277 public char * UTF16toUTF8(uint16 * source)
6284 bool invert = false;
6286 for(len = 0; source[len]; len++);
6287 dest = new char[len * 3 + 1];
6288 for(c = 0; (u16 = source[c]); c++)
6291 if(!c && (u16 == 0xFFFE || u16 == 0xFEFF))
6293 if(u16 == 0xFFFE) invert = true;
6296 if(invert) { u16 = ((u16 & 0xFF00) >> 8) | ((u16 & 0x00FF) << 8); }
6298 if(u16 < 0xD800 || u16 > 0xDBFF)
6301 ch = ((unichar)u16 << 10) + source[c++] + SURROGATE_OFFSET;
6305 dest[d++] = (char)ch;
6309 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6310 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6312 else if(ch < 0x10000)
6314 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6315 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6316 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6320 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6321 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6322 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6323 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6327 dest = renew dest char[d+1];
6331 public int UTF16toUTF8Buffer(uint16 * source, byte * dest, int max)
6336 for(c = 0; (u16 = source[c]); c++)
6339 if(u16 < 0xD800 || u16 > 0xDBFF)
6342 ch = ((unichar)u16 << 10) + source[c++] + SURROGATE_OFFSET;
6346 if(d + 1 >= max) break;
6347 dest[d++] = (char)ch;
6351 if(d + 2 >= max) break;
6352 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6353 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6355 else if(ch < 0x10000)
6357 if(d + 3 >= max) break;
6358 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6359 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6360 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6364 if(d + 4 >= max) break;
6365 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6366 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6367 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6368 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6375 public unichar UTF8GetChar(char * string, int * numBytes)
6378 byte b = ((byte *)string)[0];
6395 if(b & 0x08) { nb = 0; }
6404 for(i = 0; i<nb; i++)
6407 ch |= (b = ((byte *)string)[i]) & mask;
6409 if(i > 1 && (!(b & 0x80) || (b & 0x40)))
6417 ch > 0x10FFFF || (ch >= 0xD800 && ch <= 0xDFFF) ||
6418 (ch < 0x80 && nb > 1) ||
6419 (ch < 0x800 && nb > 2) ||
6420 (ch < 0x10000 && nb > 3))
6425 if(numBytes) *numBytes = nb;
6429 public int UTF8toUTF16Buffer(char * source, uint16 * dest, int max)
6435 for(c = 0; source[c];)
6437 byte ch = source[c];
6438 unichar codePoint = 0;
6442 if(ch & 0x80 && ch & 0x40)
6457 for(i = 0; i<numBytes; i++)
6460 codePoint |= source[c++] & mask;
6464 if(codePoint > 0xFFFF)
6466 uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
6467 uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
6468 if(d >= max - 1) break;
6475 dest[d++] = (uint16)codePoint;
6484 public int UTF32toUTF8Len(unichar * source, int count, byte * dest, int max)
6489 for(c = 0; c<count && (ch = source[c]); c++)
6493 if(d + 1 >= max) break;
6494 dest[d++] = (char)ch;
6498 if(d + 2 >= max) break;
6499 dest[d++] = 0xC0 | (byte)((ch & 0x7C0) >> 6);
6500 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6502 else if(ch < 0x10000)
6504 if(d + 3 >= max) break;
6505 dest[d++] = 0xE0 | (byte)((ch & 0xF000) >> 12);
6506 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6507 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6511 if(d + 4 >= max) break;
6512 dest[d++] = 0xF0 | (byte)((ch & 0x1C0000) >> 18);
6513 dest[d++] = 0x80 | (byte)((ch & 0x3F000) >> 12);
6514 dest[d++] = 0x80 | (byte)((ch & 0xFC0) >> 6);
6515 dest[d++] = 0x80 | (byte)(ch & 0x03F);
6522 public uint16 * UTF8toUTF16(char * source, int * wordCount)
6526 int len = strlen(source);
6527 uint16 * dest = new uint16[len + 1];
6530 for(c = 0; source[c];)
6532 byte ch = source[c];
6533 unichar codePoint = 0;
6537 if(ch & 0x80 && ch & 0x40)
6552 for(i = 0; i<numBytes; i++)
6555 codePoint |= source[c++] & mask;
6559 if(codePoint > 0xFFFF)
6561 uint16 lead = (uint16)(LEAD_OFFSET + (codePoint >> 10));
6562 uint16 trail = 0xDC00 + (uint16)(codePoint & 0x3FF);
6568 dest[d++] = (uint16)codePoint;
6572 if(wordCount) *wordCount = d;