bindings: Fixed support for C++ instantiating objects from eC
[sdk] / compiler / ecs / ecs.ec
index 9587994..225f0d6 100644 (file)
@@ -8,8 +8,11 @@ import "ec"
 
 static define localeDir = "locale";
 static bool i18n;
+static bool outputPot;
+static bool disabledPooling;
 
 static Platform targetPlatform;
+static int targetBits;
 
 static bool isConsole;
 static bool isDynamicLibrary;
@@ -19,7 +22,7 @@ static File dcomSymbols;
 
 static OldList _defines { };
 static OldList _imports { };
-static OldList _excludedSymbols { offset = (uint)&((Symbol)0).left };
+static OldList _excludedSymbols { offset = (uint)(uintptr)&((Symbol)0).left };
 static NameSpace globalData
 {
    classes.CompareKey = (void *)BinaryTree::CompareString;
@@ -33,7 +36,7 @@ static Module privateModule;
 
 static char mainModuleName[MAX_LOCATION];
 static char projectName[MAX_LOCATION];
-static void LoadImports(char * fileName)
+static void LoadImports(const char * fileName)
 {
    File f = FileOpen(fileName, read);
    if(f)
@@ -59,7 +62,7 @@ static void LoadImports(char * fileName)
                   {
                      ClassImport _class = null;
                      FunctionImport function = null;
-                     
+
                      if(!strcmp(line, "[This]"))
                      {
                         if((mainModule = GetMainModule()))
@@ -158,7 +161,7 @@ static void LoadImports(char * fileName)
                               if(!(_class = module.classes.FindName(line, false)))
                               {
                                  _class = ClassImport { name = CopyString(line) };
-                                 module.classes.AddName(_class); 
+                                 module.classes.AddName(_class);
                               }
                            }
                         }
@@ -231,7 +234,7 @@ class ModuleInfo : struct
 static bool SeardchModuleName(Module searchIn, char * name)
 {
    SubModule subModule;
-   
+
    if(searchIn.name && !strcmp(searchIn.name, name))
       return true;
 
@@ -243,16 +246,16 @@ static bool SeardchModuleName(Module searchIn, char * name)
    return false;
 }
 */
-static void WriteMain(char * fileName)
+static void WriteMain(const char * fileName)
 {
    File f = FileOpen(fileName, write);
    if(f)
    {
       ModuleImport module;
       ModuleInfo defModule;
-      bool nonInst = false, anyMethod = false, anyProp = false, anyFunction = false;
+      bool /*nonInst = false, */anyMethod = false, anyProp = false, anyFunction = false;
       ImportedModule importedModule;
-      
+
       GetLastDirectory(fileName, mainModuleName);
       StripExtension(mainModuleName);
       if(!projectName[0])
@@ -260,9 +263,7 @@ static void WriteMain(char * fileName)
          strcpy(projectName, mainModuleName);
          StripExtension(projectName);
       }
-      ChangeCh(mainModuleName, '.', '_');
-      ChangeCh(mainModuleName, '-', '_');
-      ChangeCh(mainModuleName, ' ', '_');
+      FixModuleName(mainModuleName);
 
       if(targetPlatform == win32 && !isConsole && !isStaticLibrary && !isDynamicLibrary)
       {
@@ -321,12 +322,11 @@ static void WriteMain(char * fileName)
             Class regClass = eSystem_FindClass(privateModule, _class.name);
 
             FullClassNameCat(className, _class.name, true);
-            MangleClassName(className);
 
             if(_class.itself)
                f.Printf("Class __ecereClass_%s;\n", className);
-            else
-               nonInst = true;
+            /*else
+               nonInst = true;*/
             //if(!_class.isRemote)
             {
                //if(strcmp(_class.name, "SerialBuffer"))
@@ -343,10 +343,10 @@ static void WriteMain(char * fileName)
 
                      if(method.isVirtual)
                         f.Printf("int __ecereVMethodID_%s_%s;\n", className, method.name);
-                     else if(module.name && module.importType != staticImport && (!meth || !meth.dataType.dllExport))
+                     else if((!strcmp(_class.name, "float") || !strcmp(_class.name, "double") || module.name) && module.importType != staticImport && (!meth || !meth.dataType.dllExport))
                      {
                         /*char name[4096];
-                        
+
                         Type type
                         {
                            kind = TypePointer,
@@ -372,10 +372,8 @@ static void WriteMain(char * fileName)
                   char propName[1024];
                   propName[0] = 0;
                   FullClassNameCat(propName, prop.name, true);
-                  // strcpy(propName, prop.name);
-                  MangleClassName(propName);
 
-                  if(module.name && module.importType != staticImport)
+                  if((!strcmp(_class.name, "float") || !strcmp(_class.name, "double") || module.name) && module.importType != staticImport)
                   {
                      if(prop.hasSet)
                         f.Printf("void * __ecereProp_%s_Set_%s;\n", className, propName);
@@ -408,10 +406,7 @@ static void WriteMain(char * fileName)
       {
          char moduleName[1024];
          strcpy(moduleName, defModule.name);
-         ChangeCh(moduleName, ' ', '_');
-         ChangeCh(moduleName, '-', '_');
-         ChangeCh(moduleName, '.', '_');
-
+         FixModuleName(moduleName);
          f.Printf("void __ecereRegisterModule_%s(Module module);\n", moduleName);
          f.Printf("void __ecereUnregisterModule_%s(Module module);\n", moduleName);
          if(defModule.globalInstance)
@@ -465,20 +460,27 @@ static void WriteMain(char * fileName)
       {
          f.Puts("   int exitCode;\n");
          f.Puts("   Module module;\n");
+         f.Puts("   bool setThingsUp = !__thisModule;\n");
       }
 
       //if(nonInst || thisAppClass)    // We use it all the time to get "Application" for the exit code now...
-         f.Puts("   Class _class;\n");
+         f.Puts("   __attribute__((unused)) Class _class;\n");
 
       if(anyMethod)
-         f.Puts("   Method method;\n");
+         f.Puts("   __attribute__((unused)) Method method;\n");
       if(anyProp)
-         f.Puts("   Property _property;\n");
+         f.Puts("   __attribute__((unused)) Property _property;\n");
       if(anyFunction)
-         f.Puts("   GlobalFunction function;\n");
-      
+         f.Puts("   __attribute__((unused)) GlobalFunction function;\n");
+
       f.Puts("\n");
 
+      if(disabledPooling)
+      {
+         f.Puts("   eSystem_SetPoolingDisabled(true);\n");
+         f.Puts("\n");
+      }
+
       if(isDynamicLibrary)
       {
          f.Puts("   if(!__currentModule)\n");
@@ -488,10 +490,15 @@ static void WriteMain(char * fileName)
             f.Puts("      __thisModule = module;\n");
          f.Puts("   }\n\n");
       }
-      else if(targetPlatform == win32 && !isConsole)
-         f.Puts("   __thisModule = __currentModule = module = __ecere_COM_Initialize(1, 0, null);\n\n");
       else
-         f.Puts("   __thisModule = __currentModule = module = __ecere_COM_Initialize(1, _argc, (void *)_argv);\n\n");
+      {
+         f.Puts("   if(setThingsUp)\n");
+         if(targetPlatform == win32 && !isConsole)
+            f.Puts("      __thisModule = __ecere_COM_Initialize(1, 0, null);\n\n");
+         else
+            f.Puts("      __thisModule = __ecere_COM_Initialize(1, _argc, (void *)_argv);\n\n");
+         f.Puts("   __currentModule = module = __thisModule;\n");
+      }
 
       // First load all modules
       if(_imports.count)
@@ -519,10 +526,7 @@ static void WriteMain(char * fileName)
          {
             char moduleName[1024];
             strcpy(moduleName, defModule.name);
-            ChangeCh(moduleName, ' ', '_');
-            ChangeCh(moduleName, '-', '_');
-            ChangeCh(moduleName, '.', '_');
-
+            FixModuleName(moduleName);
             f.Printf("   __ecereRegisterModule_%s(module);\n", moduleName);
          }
          f.Printf("\n");
@@ -558,13 +562,12 @@ static void WriteMain(char * fileName)
                   char classID[1024];
                   char className[1024] = "";
                   FullClassNameCat(className, _class.name, true);
-                  MangleClassName(className);
-            
+
                   if(_class.itself)
                      sprintf(classID, "__ecereClass_%s", className);
                   else
                      strcpy(classID, "_class");
-            
+
                   if(isDynamicLibrary && !isStaticLibrary)
                      f.Printf("   %s = eSystem_FindClass(__currentModule, \"%s\");\n", classID, _class.name);
                   else
@@ -575,9 +578,9 @@ static void WriteMain(char * fileName)
                      Method meth = eClass_FindMethod(regClass, method.name, privateModule);
                      if(!meth || !meth.dataType.dllExport)
                      {
-                        if(method.isVirtual || (module.name && module.importType != staticImport))
+                        if(method.isVirtual || ((!strcmp(_class.name, "float") || !strcmp(_class.name, "double") || module.name) && module.importType != staticImport))
                         {
-                           f.Printf("   method = eClass_FindMethod(%s, \"%s\", module);\n", 
+                           f.Printf("   method = eClass_FindMethod(%s, \"%s\", module);\n",
                               classID, method.name);
                            if(method.isVirtual)
                               f.Printf("   if(method) __ecereVMethodID_%s_%s = method.vid;\n", className, method.name);
@@ -592,13 +595,11 @@ static void WriteMain(char * fileName)
                      char propName[1024];
                      propName[0] = 0;
                      FullClassNameCat(propName, prop.name, true);
-                     // strcpy(propName, prop.name);
-                     MangleClassName(propName);
 
-                     f.Printf("   __ecereProp_%s_%s = _property = eClass_FindProperty(%s, \"%s\", module);\n", 
+                     f.Printf("   __ecereProp_%s_%s = _property = eClass_FindProperty(%s, \"%s\", module);\n",
                         className, propName, classID, prop.name);
 
-                     if(module.name && module.importType != staticImport)
+                     if((!strcmp(_class.name, "float") || !strcmp(_class.name, "double") || module.name) && module.importType != staticImport)
                      {
                         if(prop.hasSet)
                            f.Printf("   __ecereProp_%s_Set_%s = _property.Set;\n", className, propName);
@@ -641,7 +642,12 @@ static void WriteMain(char * fileName)
                f.Printf("   __ecereCreateModuleInstances_i18n();\n");
          }
       if(i18n)
-         f.Printf("      LoadTranslatedStrings(module, \"%s\");\n", projectName);
+      {
+         if(isDynamicLibrary)
+            f.Printf("      LoadTranslatedStrings(\"%s\", \"%s\");\n", projectName, projectName);
+         else
+            f.Printf("      LoadTranslatedStrings(null, \"%s\");\n", projectName);
+      }
       if(isDynamicLibrary)
       {
          //f.Printf("   module._vTbl[10](module);\n");
@@ -651,7 +657,7 @@ static void WriteMain(char * fileName)
       if(!isDynamicLibrary && thisAppClass)
       {
          f.Printf("   _class = eSystem_FindClass(__currentModule, \"%s\");\n", thisAppClass.name);
-         f.Printf("   eInstance_Evolve((Instance *)&__currentModule, _class);\n");
+         f.Printf("   if(setThingsUp) eInstance_Evolve((Instance *)&__currentModule, _class);\n");
          f.Printf("   __thisModule = __currentModule;\n");
       }
 
@@ -670,10 +676,7 @@ static void WriteMain(char * fileName)
                char moduleName[1024];
                if(!strcmp(defModule.name, "i18n")) continue;
                strcpy(moduleName, defModule.name);
-               ChangeCh(moduleName, ' ', '_');
-               ChangeCh(moduleName, '-', '_');
-               ChangeCh(moduleName, '.', '_');
-
+               FixModuleName(moduleName);
                f.Printf("   __ecereCreateModuleInstances_%s();\n", moduleName);
             }
 
@@ -686,7 +689,7 @@ static void WriteMain(char * fileName)
       }
       if(!isDynamicLibrary && thisAppClass)
       {
-         f.Printf("   __currentModule._vTbl[12](__currentModule);\n");
+         f.Printf("   ((void(*)(void *))(void *)__currentModule._vTbl[12])(__currentModule);\n");
       }
 
       if(isDynamicLibrary)
@@ -719,22 +722,21 @@ static void WriteMain(char * fileName)
          bool destroyI18n = false;
          if(::modules.count)
          {
-            for(defModule = ::modules.first; defModule; defModule = defModule.next)
+            for(defModule = ::modules.last; defModule; defModule = defModule.prev)
                if(defModule.globalInstance)
                {
                   char moduleName[1024];
                   if(!strcmp(defModule.name, "i18n")) { destroyI18n = true; continue; }
                   strcpy(moduleName, defModule.name);
-                  ChangeCh(moduleName, ' ', '_');
-                  ChangeCh(moduleName, '-', '_');
-                  ChangeCh(moduleName, '.', '_');
+                  FixModuleName(moduleName);
                   f.Printf("   __ecereDestroyModuleInstances_%s();\n", moduleName);
                }
 
             f.Printf("\n");
          }
          if(i18n)
-            f.Printf("   UnloadTranslatedStrings(__currentModule);\n");
+            //f.Printf("   UnloadTranslatedStrings(__currentModule);\n");
+            f.Printf("   UnloadTranslatedStrings(\"%s\");\n", projectName);
          if(destroyI18n)
             f.Printf("   __ecereDestroyModuleInstances_i18n();\n");
       }
@@ -753,9 +755,7 @@ static void WriteMain(char * fileName)
             {
                char moduleName[1024];
                strcpy(moduleName, defModule.name);
-               ChangeCh(moduleName, ' ', '_');
-               ChangeCh(moduleName, '-', '_');
-               ChangeCh(moduleName, '.', '_');
+               FixModuleName(moduleName);
                f.Printf("   __ecereUnregisterModule_%s(module);\n", moduleName);
             }
             f.Printf("\n");
@@ -853,7 +853,7 @@ static void BindDCOMClient()
          int vid;
          bool doVirtual;
 
-         DeclareClass(FindClass("ecere::net::DCOMClientObject"), "__ecereClass___ecereNameSpace__ecere__net__DCOMClientObject");
+         DeclareClass(null, FindClass("ecere::net::DCOMClientObject"), "__ecereClass___ecereNameSpace__ecere__net__DCOMClientObject");
          f.Printf("class %s : ecere::net::DCOMClientObject\n", _class.fullName);
          f.Printf("{\n");
 
@@ -896,14 +896,13 @@ static void BindDCOMClient()
                               classSym = method.dataType.returnType._class; // VERIFY THIS FindClass(method.dataType.returnType._class.string);
                            else
                            {
-                              PrintType(method.dataType.returnType, type, false, true);
+                              PrintTypeNoConst(method.dataType.returnType, type, false, true);
                               classSym = FindClass(type);
                               type[0] = 0;
                            }
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, classSym.string, true);
-                           MangleClassName(className);
-                           DeclareClass(classSym, className);
+                           DeclareClass(null, classSym, className);
 
                            PrintType(method.dataType.returnType, type, true, true);
 
@@ -911,7 +910,7 @@ static void BindDCOMClient()
                            resultType = MkTypeName(specs, decl);
 
                            f.Printf("            ");
-                           OutputTypeName(resultType, f);
+                           OutputTypeName(resultType, f, false);
                            f.Printf(";\n");
                         }
 
@@ -921,8 +920,8 @@ static void BindDCOMClient()
                            {
                               // Hardcode 1024 chars max string for now
                               f.Printf("            char %s[1024];\n", param.name);
-                              DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
-                              DeclareClass(FindClass("String"), "__ecereClass_String");
+                              DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
+                              DeclareClass(null, FindClass("String"), "__ecereClass_String");
                            }
                            else
                            {
@@ -937,15 +936,14 @@ static void BindDCOMClient()
                                  classSym = param._class; // VERIFY THIS FindClass(param._class.string);
                               else
                               {
-                                 PrintType(param, type, false, true);
+                                 PrintTypeNoConst(param, type, false, true);
                                  classSym = FindClass(type);
                                  type[0] = 0;
                               }
 
                               strcpy(className, "__ecereClass_");
                               FullClassNameCat(className, classSym.string, true);
-                              MangleClassName(className);
-                              DeclareClass(classSym, className);
+                              DeclareClass(null, classSym, className);
 
                               PrintType(param, type, true, true);
 
@@ -953,7 +951,7 @@ static void BindDCOMClient()
                               paramTypeName = MkTypeName(specs, decl);
 
                               f.Printf("            ");
-                              OutputTypeName(paramTypeName, f);
+                              OutputTypeName(paramTypeName, f, false);
 
                               f.Printf(";\n");
                            }
@@ -965,7 +963,7 @@ static void BindDCOMClient()
                            f.Printf("            __ecereBuffer.Unserialize(");
                            if(param.kind == classType && !strcmp(param._class.string, "String"))
                            {
-                              DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
+                              DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
                               f.Printf("(StaticString)");
                            }
                            f.Puts(param.name);
@@ -978,7 +976,7 @@ static void BindDCOMClient()
 
                         // f.Printf("this.instance.%s(", method.name);
                         f.Printf("%s(", method.name);
-                        
+
                         for(param = method.dataType.params.first; param; param = param.next)
                         {
                            if(param.prev)
@@ -994,7 +992,7 @@ static void BindDCOMClient()
                            {
                               if(!strcmp(param._class.string, "String"))
                               {
-                                 DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
+                                 DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
                                  f.Printf("            __ecereBuffer.Serialize((StaticString)%s);\n", param.name);
                               }
                               else
@@ -1008,13 +1006,13 @@ static void BindDCOMClient()
 
                         for(param = method.dataType.params.first; param; param = param.next)
                         {
-                           if(param.kind == classType && strcmp(param._class.string, "String") && param._class.registered && 
+                           if(param.kind == classType && strcmp(param._class.string, "String") && param._class.registered &&
                               (param._class.registered.type == normalClass || param._class.registered.type == noHeadClass))
                            {
                               f.Printf("            delete %s;\n", param.name);
                            }
                         }
-                        if(method.dataType.returnType.kind == classType && strcmp(method.dataType.returnType._class.string, "String") && method.dataType.returnType._class.registered && 
+                        if(method.dataType.returnType.kind == classType && strcmp(method.dataType.returnType._class.string, "String") && method.dataType.returnType._class.registered &&
                               (method.dataType.returnType._class.registered.type == normalClass || method.dataType.returnType._class.registered.type == noHeadClass))
                         {
                            f.Printf("            delete __ecereResult;\n");
@@ -1029,7 +1027,7 @@ static void BindDCOMClient()
             f.Printf("      }\n");
             f.Printf("   }\n");
             f.Printf("\n");
-         } 
+         }
 
          doVirtual = true;
          id = 0;
@@ -1067,7 +1065,7 @@ static void BindDCOMClient()
                   FullClassNameCat(name, method._class.fullName, true);
                   strcat(name, "_");
                   strcat(name, method.name);
-                  DeclareMethod(method, name);
+                  DeclareMethod(null, method, name);
 
                   f.Printf("virtual ");
                }
@@ -1089,15 +1087,14 @@ static void BindDCOMClient()
                         classSym = method.dataType.returnType._class; // VERIFY THIS FindClass(method.dataType.returnType._class.string);
                      else
                      {
-                        PrintType(method.dataType.returnType, type, false, true);
+                        PrintTypeNoConst(method.dataType.returnType, type, false, true);
                         classSym = FindClass(type);
                         type[0] = 0;
                      }
 
                      strcpy(className, "__ecereClass_");
                      FullClassNameCat(className, classSym.string, true);
-                     MangleClassName(className);
-                     DeclareClass(classSym, className);
+                     DeclareClass(null, classSym, className);
 
                      PrintType(method.dataType.returnType, type, true, true);
 
@@ -1105,7 +1102,7 @@ static void BindDCOMClient()
                      resultType = MkTypeName(specs, decl);
 
                      f.Printf("      ");
-                     OutputTypeName(resultType, f);
+                     OutputTypeName(resultType, f, false);
                      if(method.dataType.returnType.kind == structType)
                         f.Printf(" = { 0 }");
                      else if(method.dataType.returnType.kind == classType && method.dataType.returnType._class.registered && method.dataType.returnType._class.registered.type == structClass)
@@ -1114,7 +1111,8 @@ static void BindDCOMClient()
                         f.Printf(" = 0");
                      f.Printf(";\n\n");
                   }
-                  //f.Printf("      incref this;\n");
+                  // f.Printf("      incref this;\n");
+                  f.Printf("      safeIncRef();\n");
                   for(param = method.dataType.params.first; param; param = param.next)
                   {
                      char type[1024] = "";
@@ -1125,27 +1123,26 @@ static void BindDCOMClient()
                         classSym = param._class; // VERIFY THIS FindClass(param._class.string);
                      else
                      {
-                        PrintType(param, type, false, true);
+                        PrintTypeNoConst(param, type, false, true);
                         classSym = FindClass(type);
                         type[0] = 0;
                      }
                      strcpy(className, "__ecereClass_");
                      FullClassNameCat(className, classSym.string, true);
 
-                     MangleClassName(className);
-                     DeclareClass(classSym, className);
+                     DeclareClass(null, classSym, className);
 
                      if(param.kind == classType && !strcmp(param._class.string, "String"))
                      {
-                        DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
+                        DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
                         f.Printf("      __ecereBuffer.Serialize((StaticString)%s);\n", param.name);
                      }
                      else
                         f.Printf("      __ecereBuffer.Serialize(%s);\n", param.name);
                   }
-                  DeclareMethod(
+                  DeclareMethod(null,
                      eClass_FindMethod(
-                        eSystem_FindClass(privateModule, "ecere::net::DCOMClientObject"), "CallMethod", privateModule), 
+                        eSystem_FindClass(privateModule, "ecere::net::DCOMClientObject"), "CallMethod", privateModule),
                      "__ecereMethod___ecereNameSpace__ecere__net__DCOMClientObject_CallMethod");
 
                   f.Printf("      if(DCOMClientObject::CallMethod(%d))\n", id++);
@@ -1156,7 +1153,7 @@ static void BindDCOMClient()
                      {
                         if(!strcmp(param._class.string, "String"))
                         {
-                           DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
+                           DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
                            f.Printf("         __ecereBuffer.Unserialize((StaticString)%s);\n", param.name);
                         }
                         else
@@ -1167,7 +1164,7 @@ static void BindDCOMClient()
                   {
                      if(method.dataType.returnType.kind == classType && !strcmp(method.dataType.returnType._class.string, "String"))
                      {
-                        DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
+                        DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
                         f.Printf("         __ecereBuffer.Unserialize((StaticString)__ecereResult);\n");
                      }
                      else
@@ -1176,6 +1173,7 @@ static void BindDCOMClient()
                   f.Printf("      }\n");
                   f.Printf("      __ecereBuffer.Free();\n");
                   //f.Printf("      delete this;\n");
+                  f.Printf("      safeDecRef();\n");
                   if(method.dataType.returnType.kind != voidType)
                   {
                      f.Printf("      return __ecereResult;\n");
@@ -1185,10 +1183,10 @@ static void BindDCOMClient()
                f.Printf("   }\n");
             }
             next = (Method)((BTNode)method).next;
-            while(next && ((next.type == virtualMethod) != doVirtual || (doVirtual && next.vid != vid)))
+            while((!next && doVirtual) || (next && ((next.type == virtualMethod) != doVirtual || (doVirtual && next.vid != vid))))
             {
                id++;
-               next = (Method)((BTNode)next).next;
+               next = next ? (Method)((BTNode)next).next : null;
                if(!next && doVirtual)
                {
                   if(vid == _class.vTblSize)
@@ -1199,13 +1197,13 @@ static void BindDCOMClient()
                   next = (Method)_class.methods.first;
                }
             }
-            
-            if(next) 
+
+            if(next)
                f.Printf("\n");
          }
 
          f.Printf("}\n");
-         if(deriv.next) 
+         if(deriv.next)
             f.Printf("\n");
       }
    }
@@ -1213,6 +1211,7 @@ static void BindDCOMClient()
 
 static void BindDCOMServer()
 {
+   bool mutexDeclared = false;
    Class _class;
    for(_class = privateModule.classes.first; _class; _class = _class.next)
    {
@@ -1226,7 +1225,7 @@ static void BindDCOMServer()
       if(!dcomSymbols) dcomSymbols = TempFile { };
       f = dcomSymbols;
 
-      DeclareClass(FindClass("ecere::net::DCOMServerObject"), "__ecereClass___ecereNameSpace__ecere__net__DCOMServerObject");
+      DeclareClass(null, FindClass("ecere::net::DCOMServerObject"), "__ecereClass___ecereNameSpace__ecere__net__DCOMServerObject");
 
       // SERVER BINDINGS
       for(_class = privateModule.classes.first; _class; _class = _class.next)
@@ -1255,6 +1254,8 @@ static void BindDCOMServer()
             // f.Printf("\n");
             f.Printf("   virtual void CallMethod(uint __ecereMethodID, SerialBuffer __ecereBuffer)\n");
             f.Printf("   {\n");
+            f.Printf("      %s inst = (%s)instance;\n", _class.fullName, _class.fullName);
+            f.Printf("      incref inst;\n");
             f.Printf("      switch(__ecereMethodID)\n");
             f.Printf("      {\n");
 
@@ -1281,14 +1282,13 @@ static void BindDCOMServer()
                            classSym = method.dataType.returnType._class; // VERIFY THIS FindClass(method.dataType.returnType._class.string);
                         else
                         {
-                           PrintType(method.dataType.returnType, type, false, true);
+                           PrintTypeNoConst(method.dataType.returnType, type, false, true);
                            classSym = FindClass(type);
                            type[0] = 0;
                         }
                         strcpy(className, "__ecereClass_");
                         FullClassNameCat(className, classSym.string, true);
-                        MangleClassName(className);
-                        DeclareClass(classSym, className);
+                        DeclareClass(null, classSym, className);
 
                         PrintType(method.dataType.returnType, type, true, true);
 
@@ -1296,7 +1296,7 @@ static void BindDCOMServer()
                         resultType = MkTypeName(specs, decl);
 
                         f.Printf("            ");
-                        OutputTypeName(resultType, f);
+                        OutputTypeName(resultType, f, false);
                         f.Printf(";\n");
                      }
 
@@ -1306,8 +1306,8 @@ static void BindDCOMServer()
                         {
                            // Hardcode 1024 chars max string for now
                            f.Printf("            char %s[1024];\n", param.name);
-                           DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
-                           DeclareClass(FindClass("String"), "__ecereClass_String");
+                           DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
+                           DeclareClass(null, FindClass("String"), "__ecereClass_String");
                         }
                         else
                         {
@@ -1322,15 +1322,14 @@ static void BindDCOMServer()
                               classSym = param._class; // VERIFY THIS FindClass(param._class.string);
                            else
                            {
-                              PrintType(param, type, false, true);
+                              PrintTypeNoConst(param, type, false, true);
                               classSym = FindClass(type);
                               type[0] = 0;
                            }
 
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, classSym.string, true);
-                           MangleClassName(className);
-                           DeclareClass(classSym, className);
+                           DeclareClass(null, classSym, className);
 
                            PrintType(param, type, true, true);
 
@@ -1338,7 +1337,7 @@ static void BindDCOMServer()
                            paramTypeName = MkTypeName(specs, decl);
 
                            f.Printf("            ");
-                           OutputTypeName(paramTypeName, f);
+                           OutputTypeName(paramTypeName, f, false);
 
                            f.Printf(";\n");
                         }
@@ -1350,7 +1349,7 @@ static void BindDCOMServer()
                         f.Printf("            __ecereBuffer.Unserialize(");
                         if(param.kind == classType && !strcmp(param._class.string, "String"))
                         {
-                           DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
+                           DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
                            f.Printf("(StaticString)");
                         }
                         f.Puts(param.name);
@@ -1363,7 +1362,7 @@ static void BindDCOMServer()
 
                      // f.Printf("this.instance.%s(", method.name);
                      f.Printf("((%s)instance).%s(", _class.fullName, method.name);
-                     
+
                      for(param = method.dataType.params.first; param; param = param.next)
                      {
                         if(param.prev)
@@ -1379,7 +1378,7 @@ static void BindDCOMServer()
                         {
                            if(!strcmp(param._class.string, "String"))
                            {
-                              DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
+                              DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
                               f.Printf("            __ecereBuffer.Serialize((StaticString)%s);\n", param.name);
                            }
                            else
@@ -1393,13 +1392,13 @@ static void BindDCOMServer()
 
                      for(param = method.dataType.params.first; param; param = param.next)
                      {
-                        if(param.kind == classType && strcmp(param._class.string, "String") && param._class.registered && 
+                        if(param.kind == classType && strcmp(param._class.string, "String") && param._class.registered &&
                            (param._class.registered.type == normalClass || param._class.registered.type == noHeadClass))
                         {
                            f.Printf("            delete %s;\n", param.name);
                         }
                      }
-                     if(method.dataType.returnType.kind == classType && strcmp(method.dataType.returnType._class.string, "String") && method.dataType.returnType._class.registered && 
+                     if(method.dataType.returnType.kind == classType && strcmp(method.dataType.returnType._class.string, "String") && method.dataType.returnType._class.registered &&
                            (method.dataType.returnType._class.registered.type == normalClass || method.dataType.returnType._class.registered.type == noHeadClass))
                      {
                         f.Printf("            delete __ecereResult;\n");
@@ -1411,6 +1410,7 @@ static void BindDCOMServer()
                }
             }
             f.Printf("      }\n");
+            f.Printf("      delete inst;\n");
             f.Printf("   }\n");
 
             // *** VIRTUAL FUNCTIONS BINDINGS ***
@@ -1424,6 +1424,20 @@ static void BindDCOMServer()
                      break;
                if(method)
                {
+                  if(!mutexDeclared)
+                  {
+                     DeclareClass(null, FindClass("ecere::sys::Mutex"), "__ecereClass___ecereNameSpace__ecere__sys__Mutex");
+                     DeclareMethod(null,
+                        eClass_FindMethod(
+                           eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Wait", privateModule),
+                              "__ecereMethod___ecereNameSpace__ecere__sys__Mutex_Wait");
+                     DeclareMethod(null,
+                        eClass_FindMethod(
+                           eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Release", privateModule),
+                              "__ecereMethod___ecereNameSpace__ecere__sys__Mutex_Release");
+                     mutexDeclared = true;
+                  }
+
                   f.Printf("\n");
                   if(!method.dataType)
                      method.dataType = ProcessTypeString(method.dataTypeString, false);
@@ -1449,15 +1463,14 @@ static void BindDCOMServer()
                               classSym = method.dataType.returnType._class; // VERIFY THIS FindClass(method.dataType.returnType._class.string);
                            else
                            {
-                              PrintType(method.dataType.returnType, type, false, true);
+                              PrintTypeNoConst(method.dataType.returnType, type, false, true);
                               classSym = FindClass(type);
                               type[0] = 0;
                            }
 
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, classSym.string, true);
-                           MangleClassName(className);
-                           DeclareClass(classSym, className);
+                           DeclareClass(null, classSym, className);
 
                            PrintType(method.dataType.returnType, type, true, true);
 
@@ -1465,7 +1478,7 @@ static void BindDCOMServer()
                            resultType = MkTypeName(specs, decl);
 
                            f.Printf("      ");
-                           OutputTypeName(resultType, f);
+                           OutputTypeName(resultType, f, false);
                            if(method.dataType.returnType.kind == structType)
                               f.Printf(" = { 0 }");
                            else if(method.dataType.returnType.kind == classType && method.dataType.returnType._class.registered && method.dataType.returnType._class.registered.type == structClass)
@@ -1474,6 +1487,10 @@ static void BindDCOMServer()
                               f.Printf(" = 0");
                            f.Printf(";\n\n");
                         }
+
+                        f.Printf("      incref __ecereObject;\n");
+                        f.Printf("      __ecereMethod___ecereNameSpace__ecere__sys__Mutex_Wait(__ecereObject.mutex);\n");
+
                         //f.Printf("      incref this;\n");
                         for(param = method.dataType.params.first; param; param = param.next)
                         {
@@ -1485,30 +1502,45 @@ static void BindDCOMServer()
                               classSym = param._class; // VERIFY THIS FindClass(param._class.string);
                            else
                            {
-                              PrintType(param, type, false, true);
+                              PrintTypeNoConst(param, type, false, true);
                               classSym = FindClass(type);
                               type[0] = 0;
                            }
                            strcpy(className, "__ecereClass_");
                            FullClassNameCat(className, classSym.string, true);
-                           MangleClassName(className);
-                           DeclareClass(classSym, className);
+                           DeclareClass(null, classSym, className);
 
                            if(param.kind == classType && !strcmp(param._class.string, "String"))
                            {
-                              DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
-                              f.Printf("      __ecereObject.virtualsBuffer.Serialize((StaticString)%s);\n", param.name);
+                              DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
+                              f.Printf("      __ecereObject.argsBuffer.Serialize((StaticString)%s);\n", param.name);
                            }
                            else
-                              f.Printf("      __ecereObject.virtualsBuffer.Serialize(%s);\n", param.name);
+                              f.Printf("      __ecereObject.argsBuffer.Serialize(%s);\n", param.name);
                         }
 
-                        DeclareMethod(
+                        DeclareMethod(null,
                            eClass_FindMethod(
-                              eSystem_FindClass(privateModule, "ecere::net::DCOMServerObject"), "CallVirtualMethod", privateModule), 
-                           "__ecereMethod___ecereNameSpace__ecere__net__DCOMServerObject_CallVirutalMethod");
+                              eSystem_FindClass(privateModule, "ecere::net::DCOMServerObject"), "CallVirtualMethod", privateModule),
+                           "__ecereMethod___ecereNameSpace__ecere__net__DCOMServerObject_CallVirtualMethod");
 
-                        f.Printf("      if(__ecereObject.CallVirtualMethod(%d))\n", vid - _class.base.vTblSize);
+                        // Check if this method needs to return anything (hasReturnValue)
+                        {
+                           bool hasReturnValue = method.dataType.returnType.kind != voidType;
+                           if(!hasReturnValue)
+                           {
+                              for(param = method.dataType.params.first; param; param = param.next)
+                              {
+                                 if(param.kind == classType && ((param._class && param._class.registered && param._class.registered.type == structClass) || !strcmp(param._class.string, "String")) && !param.constant)
+                                 {
+                                    hasReturnValue = true;
+                                    break;
+                                 }
+                              }
+                           }
+                           f.Printf("      if(__ecereObject.CallVirtualMethod(%d, %s))\n", vid - _class.base.vTblSize,
+                              hasReturnValue ? "true" : "false");
+                        }
                         f.Printf("      {\n");
                         for(param = method.dataType.params.first; param; param = param.next)
                         {
@@ -1516,22 +1548,22 @@ static void BindDCOMServer()
                            {
                               if(!strcmp(param._class.string, "String"))
                               {
-                                 DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
-                                 f.Printf("         __ecereObject.virtualsBuffer.Unserialize((StaticString)%s);\n", param.name);
+                                 DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
+                                 f.Printf("         __ecereObject.returnBuffer.Unserialize((StaticString)%s);\n", param.name);
                               }
                               else
-                                 f.Printf("         __ecereObject.virtualsBuffer.Unserialize(%s);\n", param.name);
+                                 f.Printf("         __ecereObject.returnBuffer.Unserialize(%s);\n", param.name);
                            }
                         }
                         if(method.dataType.returnType.kind != voidType)
                         {
                            if(method.dataType.returnType.kind == classType && !strcmp(method.dataType.returnType._class.string, "String"))
                            {
-                              DeclareClass(FindClass("StaticString"), "__ecereClass_StaticString");
-                              f.Printf("         __ecereObject.virtualsBuffer.Unserialize((StaticString)__ecereResult);\n");
+                              DeclareClass(null, FindClass("StaticString"), "__ecereClass_StaticString");
+                              f.Printf("         __ecereObject.returnBuffer.Unserialize((StaticString)__ecereResult);\n");
                            }
                            else
-                              f.Printf("         __ecereObject.virtualsBuffer.Unserialize(__ecereResult);\n");
+                              f.Printf("         __ecereObject.returnBuffer.Unserialize(__ecereResult);\n");
                         }
                         f.Printf("      }\n");
                         f.Printf("      else\n");
@@ -1543,8 +1575,10 @@ static void BindDCOMServer()
                         }
                         f.Printf(");\n");
 
-                        f.Printf("      __ecereObject.virtualsBuffer.Free();\n");
+                        f.Printf("      __ecereObject.returnBuffer.Free();\n");
+                        f.Printf("      __ecereMethod___ecereNameSpace__ecere__sys__Mutex_Release(__ecereObject.mutex);\n");
                         //f.Printf("      delete this;\n");
+                        f.Printf("      delete __ecereObject;\n");
                         if(method.dataType.returnType.kind != voidType)
                         {
                            f.Printf("      return __ecereResult;\n");
@@ -1552,7 +1586,7 @@ static void BindDCOMServer()
                      }
 
                      f.Printf("   }\n");
-                     /*if(vid < _class.vTblSize) 
+                     /*if(vid < _class.vTblSize)
                         f.Printf("\n");*/
                   }
                }
@@ -1573,9 +1607,12 @@ class SymbolgenApp : Application
       */
       int c;
       bool valid = true;
-      char * output = null;
+      const char * output = null;
 
-      targetPlatform = GetRuntimePlatform();
+      outputPot = false;
+      disabledPooling = false;
+      targetPlatform = __runtimePlatform;
+      targetBits = GetHostBits();
 
       /*
       for(c = 0; c<this.argc; c++)
@@ -1604,12 +1641,31 @@ class SymbolgenApp : Application
       }
       */
 
+#if 0 //def _DEBUG
+      printf("\nArguments given:\n");
+      for(c=1; c<argc; c++)
+         printf(" %s", argv[c]);
+      printf("\n\n");
+      for(c=1; c<argc; c++)
+         PrintLn("Arg", c, ": ", argv[c]);
+      printf("\n");
+      //getch();
+#endif
+
       for(c = 1; c<argc; c++)
       {
-         char * arg = argv[c];
+         const char * arg = argv[c];
          if(arg[0] == '-')
          {
-            if(!strcmp(arg+1, "o"))
+            if(!strcmp(arg + 1, "m32") || !strcmp(arg + 1, "m64"))
+            {
+               targetBits = !strcmp(arg + 1, "m32") ? 32 : 64;
+            }
+            else if(!strcmp(arg + 1, "t32") || !strcmp(arg + 1, "t64"))
+            {
+               targetBits = !strcmp(arg + 1, "t32") ? 32 : 64;
+            }
+            else if(!strcmp(arg+1, "o"))
             {
                if(!output && c + 1 < argc)
                {
@@ -1636,6 +1692,10 @@ class SymbolgenApp : Application
                else
                   valid = false;
             }
+            else if(!strcmp(arg, "-outputpot"))
+               outputPot = true;
+            else if(!strcmp(arg, "-disabled-pooling"))
+               disabledPooling = true;
             else if(!strcmp(arg, "-console"))
                isConsole = true;
             else if(!strcmp(arg, "-dynamiclib"))
@@ -1659,9 +1719,11 @@ class SymbolgenApp : Application
       }
       if(!output)
          valid = false;
-     
+
       if(!valid)
-         printf("Syntax:\n   ecs [-t <target platform>] <input>[, <input>]* -o <output>\n");
+      {
+         printf("%s", $"Syntax:\n   ecs [-t <target platform>] <input>[, <input>]* -o <output>\n");
+      }
       else
       {
          int c;
@@ -1669,7 +1731,7 @@ class SymbolgenApp : Application
          char symbolModule[MAX_FILENAME];
          GetExtension(output, ext);
          GetLastDirectory(output, symbolModule);
-         
+
          SetDefines(&::_defines);
          SetImports(&_imports);
          SetGlobalData(&globalData);
@@ -1678,8 +1740,10 @@ class SymbolgenApp : Application
          SetTopContext(theGlobalContext);
          SetCurrentContext(theGlobalContext);
          SetTargetPlatform(targetPlatform);
+         SetTargetBits(targetBits);
+         SetInSymbolGen(true);
 
-         privateModule = __ecere_COM_Initialize(true, 1, null);
+         privateModule = (Module)__ecere_COM_Initialize((bool)(true | (targetBits == sizeof(uintptr)*8 ? 0 : targetBits == 64 ? 2 : targetBits==32 ? 4 : 0) | 8), 1, null);
          SetPrivateModule(privateModule);
          mainModule = ModuleImport { };
          SetMainModule(mainModule);
@@ -1687,31 +1751,57 @@ class SymbolgenApp : Application
 
          //if(!strcmp(ext, "c"))
          {
-            File potFile = null;
-            Map<String, String> intlStrings { };
-            MapIterator<String, String> it { map = intlStrings };
+            //const String symbolsDir = GetSymbolsDir();
+            // Only generating .pot files when building from release.* directory for now
+            //bool outputPot = symbolsDir && SearchString(symbolsDir, 0, "release.", false, false);
+            Map<ContextStringPair, List<String> > intlStrings { };
+            MapIterator<ContextStringPair, List<String>> it { map = intlStrings };
 
             for(c = 1; c<argc; c++)
             {
-               char * file = argv[c];
+               const char * file = argv[c];
+               File f = null;
+               char line[16384];
+               int count = 0;
+               char * tokens[512];
                if(file[0] == '-')
                {
                   if(!strcmp(file, "-c"))
                      c++;
                }
+               else if(file[0] == '@')
+                  f = FileOpen(&file[1], read);
                else
                {
-                  char ext[MAX_EXTENSION];
-                  GetExtension(file,ext);
-                  if(!strcmp(ext, "imp"))
-                     LoadImports(file);
+                  count = 1;
+                  tokens[0] = (char *)file;
+               }
+               while(count || f)
+               {
+                  int c;
+                  if(f)
+                  {
+                     while(!count && f.GetLine(line, sizeof(line)))
+                        count = Tokenize(line, sizeof(tokens)/sizeof(tokens[0]), tokens, forArgsPassing);
+                     if(!count)
+                        delete f;
+                  }
+                  for(c = 0; c < count; c++)
+                  {
+                     char ext[MAX_EXTENSION];
+                     file = tokens[c];
+                     GetExtension(file, ext);
+                     if(!strcmp(ext, "imp"))
+                        LoadImports(file);
+                  }
+                  count = 0;
                }
             }
 
             // What is this supposed to do?
             for(c = 1; c<argc; c++)
             {
-               char * file = argv[c];
+               const char * file = argv[c];
                if(file[0] == '-')
                {
                   if(!strcmp(file, "-c"))
@@ -1721,108 +1811,156 @@ class SymbolgenApp : Application
 
             for(c = 1; c<argc; c++)
             {
-               char * file = argv[c];
+               const char * file = argv[c];
+               File f = null;
+               char line[16384];
+               int count = 0;
+               char * tokens[512];
                if(file[0] == '-')
                {
                   // Don't even know what it does here?
                   if(!strcmp(file, "-c"))
                      c++;
                }
+               else if(file[0] == '@')
+                  f = FileOpen(&file[1], read);
                else
                {
-                  char ext[MAX_EXTENSION];
-                  char moduleName[MAX_LOCATION];
-
-                  GetExtension(file,ext);
-
-                  GetLastDirectory(file, moduleName);
-                  StripExtension(moduleName);
-                  strcat(moduleName, ".ec");
+                  count = 1;
+                  tokens[0] = (char *)file;
+               }
 
-                  if(fstrcmp(moduleName, symbolModule) && (!strcmp(ext, "sym") || !strcmp(ext, "ec")))
+               while(count || f)
+               {
+                  int c;
+                  if(f)
+                  {
+                     while(!count && f.GetLine(line, sizeof(line)))
+                        count = Tokenize(line, sizeof(tokens)/sizeof(tokens[0]), tokens, forArgsPassing);
+                     if(!count)
+                        delete f;
+                  }
+                  for(c = 0; c < count; c++)
                   {
-                     ImportedModule importedModule;
-                     ModuleInfo module { };
-                     char fileName[MAX_FILENAME];
-                     ::modules.Add(module);
+                     char ext[MAX_EXTENSION];
+                     char moduleName[MAX_LOCATION];
 
-                     GetLastDirectory(file, fileName);
+                     file = tokens[c];
 
-                     module.name = CopyString(fileName);
-                     
-                     StripExtension(module.name);                     
+                     GetExtension(file, ext);
 
-                     for(importedModule = ::_defines.first; importedModule; importedModule = importedModule.next)
-                     {
-                        if(importedModule.type == moduleDefinition && !strcmpi(importedModule.name, module.name) && !(importedModule.importType == remoteImport))
-                           break;
-                     }
+                     GetLastDirectory(file, moduleName);
+                     StripExtension(moduleName);
+                     strcat(moduleName, ".ec");
 
-                     if(importedModule)
-                        module.globalInstance = importedModule.globalInstance;
-                     else
+                     if(fstrcmp(moduleName, symbolModule) && (!strcmp(ext, "sym") || !strcmp(ext, "ec")))
                      {
-                        importedModule = ImportedModule
-                        {
-                           name = CopyString(module.name),
-                           type = moduleDefinition,
-                           importType = normalImport
-                        };
-                        ::_defines.AddName(importedModule);
+                        ImportedModule importedModule;
+                        ModuleInfo module { };
+                        char fileName[MAX_FILENAME];
+                        ::modules.Add(module);
 
-                        module.globalInstance = LoadSymbols(file, normalImport, false);
-                        CheckDataRedefinitions();
-                     }
+                        GetLastDirectory(file, fileName);
 
-                     // I18n code
-                     {
-                        File f;
-                        ChangeExtension(file, "bowl", fileName);
-                        f = FileOpen(fileName, read);
-                        if(f)
+                        module.name = CopyString(fileName);
+
+                        StripExtension(module.name);
+
+                        for(importedModule = ::_defines.first; importedModule; importedModule = importedModule.next)
                         {
-                           if(!potFile)
+                           if(importedModule.type == moduleDefinition && !strcmpi(importedModule.name, module.name) && !(importedModule.importType == remoteImport))
+                              break;
+                        }
+
+                        if(importedModule)
+                           module.globalInstance = importedModule.globalInstance;
+                        else
+                        {
+                           importedModule = ImportedModule
                            {
-                              char potFileName[MAX_LOCATION];
-                              strcpy(potFileName, output);
-                              StripExtension(potFileName);
-                              ChangeExtension(potFileName, "pot", potFileName);
-                              potFile = FileOpen(potFileName, write);
-                           }
-                           potFile.Printf("# %s\n", moduleName);
-                           while(!f.Eof())
+                              name = CopyString(module.name),
+                              type = moduleDefinition,
+                              importType = normalImport
+                           };
+                           ::_defines.AddName(importedModule);
+
+                           module.globalInstance = LoadSymbols(file, normalImport, false);
+                           CheckDataRedefinitions();
+                        }
+
+                        // I18n code
+                        {
+                           File f;
+                           ChangeExtension(file, "bowl", fileName);
+                           f = FileOpen(fileName, read);
+                           if(f)
                            {
-                              String comment = null, msgid = null, msgstr = null;
-                              int c;
-                              for(c = 0; c < 4; c++)
+                              static char line[65536];
+                              List<String> comments { };
+                              String msgid = null, msgstr = null, msgctxt = null;
+                              while(!f.Eof())
                               {
-                                 static char line[65536];
                                  if(f.GetLine(line, sizeof(line)))
                                  {
-                                    if(c == 0) comment = CopyString(line);
-                                    else if(c == 1) msgid = CopyString(line);
-                                    else if(c == 2) msgstr = CopyString(line);
+                                    int len;
+                                    TrimLSpaces(line, line);
+                                    if(line[0] == '#')
+                                    {
+                                       comments.Add(CopyString(line));
+                                    }
+                                    else if(strstr(line, "msgid \"") == line)
+                                    {
+                                       delete msgid;
+                                       msgid = CopyString(line + 7);
+                                       len = strlen(msgid);
+                                       if(len) msgid[len-1] = 0;
+                                    }
+                                    else if(strstr(line, "msgctxt \"") == line)
+                                    {
+                                       delete msgctxt;
+                                       msgctxt = CopyString(line + 9);
+                                       len = strlen(msgctxt);
+                                       if(len) msgctxt[len-1] = 0;
+                                    }
+                                    else if(strstr(line, "msgstr \"") == line)
+                                    {
+                                       delete msgstr;
+                                       msgstr = CopyString(line + 8);
+                                       len = strlen(msgstr);
+                                       if(len) msgstr[len-1] = 0;
+                                    }
+
+                                    if(msgid && msgstr)
+                                    {
+                                       ContextStringPair pair { msgid, msgctxt };
+                                       i18n = true;
+                                       if(!it.Index(pair, false))
+                                       {
+                                          msgid = null; msgctxt = null;
+                                          intlStrings[pair] = comments;
+                                          comments = { };
+                                       }
+                                       else
+                                       {
+                                          for(s : comments)
+                                             it.data.Add(s);
+                                          comments.RemoveAll();
+                                       }
+
+                                       delete msgid;
+                                       delete msgctxt;
+                                       delete msgstr;
+                                    }
                                  }
                               }
-                              if(msgid && !it.Index(msgid, false))
-                              {
-                                 i18n = true;
-                                 intlStrings[msgid] = comment;
-                                 if(comment)
-                                    potFile.Puts(comment); potFile.Puts("\n");
-                                 potFile.Puts(msgid); potFile.Puts("\n");
-                                 if(msgstr)
-                                    potFile.Puts(msgstr); potFile.Puts("\n");
-                                 potFile.Puts("\n");
-                                 delete msgstr;
-                                 // delete comment;
-                              }
+                              comments.Free();
+                              delete comments;
+                              delete f;
                            }
-                           delete f;
-                           potFile.Puts("\n");
                         }
                      }
                   }
+                  count = 0;
                }
             }
 
@@ -1841,13 +1979,60 @@ class SymbolgenApp : Application
                   thisAppClass = FindAppClass(&privateModule.application.privateNameSpace, false);
                */
                thisAppClass = SearchAppClass_Module(privateModule);
+               if(!thisAppClass)
+                  thisAppClass = eSystem_FindClass(privateModule, "Application");
             }
             WriteMain(output);
 
-            intlStrings.Free();
-            delete intlStrings;
-            if(potFile)
-               delete potFile;
+            if(outputPot && intlStrings.count)
+            {
+               File potFile;
+               char potFileName[MAX_LOCATION];
+               //strcpy(potFileName, output);
+               //StripExtension(potFileName);
+               strcpy(potFileName, "locale");
+               PathCat(potFileName, projectName);
+               ChangeExtension(potFileName, "pot", potFileName);
+               potFile = FileOpen(potFileName, write);
+               if(potFile)
+               {
+                  // Write header:
+                  potFile.Puts("msgid \"\"\n");
+                  potFile.Puts("msgstr \"\"\n");
+                  potFile.Puts("\"Project-Id-Version: \\n\"\n");
+                  potFile.Puts("\"POT-Creation-Date: \\n\"\n");
+                  potFile.Puts("\"PO-Revision-Date: \\n\"\n");
+                  potFile.Puts("\"Last-Translator: \\n\"\n");
+                  potFile.Puts("\"Language-Team: \\n\"\n");
+                  potFile.Puts("\"MIME-Version: 1.0\\n\"\n");
+                  potFile.Puts("\"Content-Type: text/plain; charset=iso-8859-1\\n\"\n");
+                  potFile.Puts("\"Content-Transfer-Encoding: 8bit\\n\"\n");
+                  potFile.Puts("\"X-Poedit-Basepath: ../\\n\"\n");
+                  potFile.Puts("\n");
+
+                  for(i : intlStrings)
+                  {
+                     ContextStringPair pair = &i;
+                     List<String> comments = i;
+                     for(s : comments)
+                     {
+                        potFile.Printf(s);
+                        potFile.Puts("\n");
+                     }
+
+                     if(pair.context)
+                     {
+                        potFile.Puts("msgctxt \""); potFile.Puts(pair.context); potFile.Puts("\"\n");
+                     }
+                     potFile.Puts("msgid \""); potFile.Puts(pair.string); potFile.Puts("\"\n");
+                     potFile.Puts("msgstr \""); potFile.Puts(pair.string); potFile.Puts("\"\n");
+                     potFile.Puts("\n");
+                  }
+                  intlStrings.Free();
+                  delete intlStrings;
+                  delete potFile;
+               }
+            }
          }
 
          FreeContext(theGlobalContext);
@@ -1856,7 +2041,7 @@ class SymbolgenApp : Application
          ::_defines.Free(FreeModuleDefine);
          _imports.Free(FreeModuleImport);
 
-         //precompDefines.Free(FreeDefinition);   
+         //precompDefines.Free(FreeDefinition);
 
          FreeTypeData(privateModule);
          FreeIncludeFiles();
@@ -1873,7 +2058,7 @@ class SymbolgenApp : Application
       delete argv;
       */
 
-#ifdef _DEBUG
+#if 0 //defined(_DEBUG) && defined(__WIN32__)
       getch();
 #endif
    }