i18n: (#858) Fixed directory layout to really match what Launchpad expects
[sdk] / compiler / ecs / ecs.ec
index fd06ebd..6b1fbbf 100644 (file)
@@ -8,6 +8,8 @@ import "ec"
 
 static define localeDir = "locale";
 static bool i18n;
+static bool outputPot;
+static bool disabledPooling;
 
 static Platform targetPlatform;
 static int targetBits;
@@ -60,7 +62,7 @@ static void LoadImports(char * fileName)
                   {
                      ClassImport _class = null;
                      FunctionImport function = null;
-                     
+
                      if(!strcmp(line, "[This]"))
                      {
                         if((mainModule = GetMainModule()))
@@ -159,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);
                               }
                            }
                         }
@@ -232,7 +234,7 @@ class ModuleInfo : struct
 static bool SeardchModuleName(Module searchIn, char * name)
 {
    SubModule subModule;
-   
+
    if(searchIn.name && !strcmp(searchIn.name, name))
       return true;
 
@@ -253,7 +255,7 @@ static void WriteMain(char * fileName)
       ModuleInfo defModule;
       bool nonInst = false, anyMethod = false, anyProp = false, anyFunction = false;
       ImportedModule importedModule;
-      
+
       GetLastDirectory(fileName, mainModuleName);
       StripExtension(mainModuleName);
       if(!projectName[0])
@@ -261,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)
       {
@@ -347,7 +347,7 @@ static void WriteMain(char * fileName)
                      else if(module.name && module.importType != staticImport && (!meth || !meth.dataType.dllExport))
                      {
                         /*char name[4096];
-                        
+
                         Type type
                         {
                            kind = TypePointer,
@@ -409,10 +409,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)
@@ -477,9 +474,15 @@ static void WriteMain(char * fileName)
          f.Puts("   Property _property;\n");
       if(anyFunction)
          f.Puts("   GlobalFunction function;\n");
-      
+
       f.Puts("\n");
 
+      if(disabledPooling)
+      {
+         f.Puts("   eSystem_SetPoolingDisabled(true);\n");
+         f.Puts("\n");
+      }
+
       if(isDynamicLibrary)
       {
          f.Puts("   if(!__currentModule)\n");
@@ -520,10 +523,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");
@@ -560,12 +560,12 @@ static void WriteMain(char * fileName)
                   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
@@ -578,7 +578,7 @@ static void WriteMain(char * fileName)
                      {
                         if(method.isVirtual || (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);
@@ -596,7 +596,7 @@ static void WriteMain(char * fileName)
                      // 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)
@@ -671,10 +671,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);
             }
 
@@ -726,9 +723,7 @@ static void WriteMain(char * fileName)
                   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);
                }
 
@@ -754,9 +749,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");
@@ -897,7 +890,7 @@ 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;
                            }
@@ -938,7 +931,7 @@ 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;
                               }
@@ -979,7 +972,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)
@@ -1009,13 +1002,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");
@@ -1030,7 +1023,7 @@ static void BindDCOMClient()
             f.Printf("      }\n");
             f.Printf("   }\n");
             f.Printf("\n");
-         } 
+         }
 
          doVirtual = true;
          id = 0;
@@ -1090,7 +1083,7 @@ 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;
                      }
@@ -1126,7 +1119,7 @@ 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;
                      }
@@ -1146,7 +1139,7 @@ static void BindDCOMClient()
                   }
                   DeclareMethod(
                      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++);
@@ -1200,13 +1193,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");
       }
    }
@@ -1285,7 +1278,7 @@ 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;
                         }
@@ -1326,7 +1319,7 @@ 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;
                            }
@@ -1367,7 +1360,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)
@@ -1397,13 +1390,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");
@@ -1434,11 +1427,11 @@ static void BindDCOMServer()
                      DeclareClass(FindClass("ecere::sys::Mutex"), "__ecereClass___ecereNameSpace__ecere__sys__Mutex");
                      DeclareMethod(
                         eClass_FindMethod(
-                           eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Wait", privateModule), 
+                           eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Wait", privateModule),
                               "__ecereMethod___ecereNameSpace__ecere__sys__Mutex_Wait");
                      DeclareMethod(
                         eClass_FindMethod(
-                           eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Release", privateModule), 
+                           eSystem_FindClass(privateModule, "ecere::sys::Mutex"), "Release", privateModule),
                               "__ecereMethod___ecereNameSpace__ecere__sys__Mutex_Release");
                      mutexDeclared = true;
                   }
@@ -1468,7 +1461,7 @@ 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;
                            }
@@ -1493,7 +1486,7 @@ 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");
 
@@ -1508,7 +1501,7 @@ 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;
                            }
@@ -1528,7 +1521,7 @@ static void BindDCOMServer()
 
                         DeclareMethod(
                            eClass_FindMethod(
-                              eSystem_FindClass(privateModule, "ecere::net::DCOMServerObject"), "CallVirtualMethod", privateModule), 
+                              eSystem_FindClass(privateModule, "ecere::net::DCOMServerObject"), "CallVirtualMethod", privateModule),
                            "__ecereMethod___ecereNameSpace__ecere__net__DCOMServerObject_CallVirtualMethod");
 
                         // Check if this method needs to return anything (hasReturnValue)
@@ -1593,7 +1586,7 @@ static void BindDCOMServer()
                      }
 
                      f.Printf("   }\n");
-                     /*if(vid < _class.vTblSize) 
+                     /*if(vid < _class.vTblSize)
                         f.Printf("\n");*/
                   }
                }
@@ -1616,6 +1609,8 @@ class SymbolgenApp : Application
       bool valid = true;
       char * output = null;
 
+      outputPot = false;
+      disabledPooling = false;
       targetPlatform = GetRuntimePlatform();
       targetBits = GetHostBits();
 
@@ -1646,6 +1641,17 @@ class SymbolgenApp : Application
       }
       */
 
+#ifdef _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];
@@ -1655,6 +1661,10 @@ class SymbolgenApp : Application
             {
                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)
@@ -1682,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"))
@@ -1705,9 +1719,11 @@ class SymbolgenApp : Application
       }
       if(!output)
          valid = false;
-     
+
       if(!valid)
+      {
          printf($"Syntax:\n   ecs [-t <target platform>] <input>[, <input>]* -o <output>\n");
+      }
       else
       {
          int c;
@@ -1715,7 +1731,7 @@ class SymbolgenApp : Application
          char symbolModule[MAX_FILENAME];
          GetExtension(output, ext);
          GetLastDirectory(output, symbolModule);
-         
+
          SetDefines(&::_defines);
          SetImports(&_imports);
          SetGlobalData(&globalData);
@@ -1737,24 +1753,48 @@ class SymbolgenApp : Application
          {
             String symbolsDir = GetSymbolsDir();
             // Only generating .pot files when building from release.* directory for now
-            bool outputPot = symbolsDir && SearchString(symbolsDir, 0, "release.", false, false);
+            //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];
+               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] = 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;
                }
             }
 
@@ -1772,129 +1812,155 @@ class SymbolgenApp : Application
             for(c = 1; c<argc; c++)
             {
                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] = 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
+                        ImportedModule importedModule;
+                        ModuleInfo module { };
+                        char fileName[MAX_FILENAME];
+                        ::modules.Add(module);
+
+                        GetLastDirectory(file, fileName);
+
+                        module.name = CopyString(fileName);
+
+                        StripExtension(module.name);
+
+                        for(importedModule = ::_defines.first; importedModule; importedModule = importedModule.next)
                         {
-                           name = CopyString(module.name),
-                           type = moduleDefinition,
-                           importType = normalImport
-                        };
-                        ::_defines.AddName(importedModule);
+                           if(importedModule.type == moduleDefinition && !strcmpi(importedModule.name, module.name) && !(importedModule.importType == remoteImport))
+                              break;
+                        }
 
-                        module.globalInstance = LoadSymbols(file, normalImport, false);
-                        CheckDataRedefinitions();
-                     }
+                        if(importedModule)
+                           module.globalInstance = importedModule.globalInstance;
+                        else
+                        {
+                           importedModule = ImportedModule
+                           {
+                              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)
+                        // I18n code
                         {
-                           static char line[65536];
-                           List<String> comments { };
-                           String msgid = null, msgstr = null, msgctxt = null;
-                           while(!f.Eof())
+                           File f;
+                           ChangeExtension(file, "bowl", fileName);
+                           f = FileOpen(fileName, read);
+                           if(f)
                            {
-                              if(f.GetLine(line, sizeof(line)))
+                              static char line[65536];
+                              List<String> comments { };
+                              String msgid = null, msgstr = null, msgctxt = null;
+                              while(!f.Eof())
                               {
-                                 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)
+                                 if(f.GetLine(line, sizeof(line)))
                                  {
-                                    ContextStringPair pair { msgid, msgctxt };
-                                    i18n = true;
-                                    if(!it.Index(pair, false))
+                                    int len;
+                                    TrimLSpaces(line, line);
+                                    if(line[0] == '#')
                                     {
-                                       msgid = null; msgctxt = null;
-                                       intlStrings[pair] = comments;
-                                       comments = { };
+                                       comments.Add(CopyString(line));
                                     }
-                                    else
+                                    else if(strstr(line, "msgid \"") == line)
                                     {
-                                       for(s : comments)
-                                          it.data.Add(s);
-                                       comments.RemoveAll();
+                                       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;
                                     }
 
-                                    delete msgid;
-                                    delete msgctxt;
-                                    delete msgstr;
+                                    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;
+                                    }
                                  }
                               }
+                              comments.Free();
+                              delete comments;
+                              delete f;
                            }
-                           comments.Free();
-                           delete comments;
-                           delete f;
                         }
                      }
                   }
+                  count = 0;
                }
             }
 
@@ -1923,6 +1989,7 @@ class SymbolgenApp : Application
                //strcpy(potFileName, output);
                //StripExtension(potFileName);
                strcpy(potFileName, "locale");
+               PathCat(potFileName, projectName);
                MakeDir(potFileName);
                PathCat(potFileName, projectName);
                ChangeExtension(potFileName, "pot", potFileName);
@@ -1974,7 +2041,7 @@ class SymbolgenApp : Application
          ::_defines.Free(FreeModuleDefine);
          _imports.Free(FreeModuleImport);
 
-         //precompDefines.Free(FreeDefinition);   
+         //precompDefines.Free(FreeDefinition);
 
          FreeTypeData(privateModule);
          FreeIncludeFiles();