i18n: ear, epj2make, (self)extract
[sdk] / epj2make / epj2make.ec
1 #ifdef ECERE_STATIC
2 public import static "ecere"
3 #else
4 public import "ecere"
5 #endif
6
7 import "Project"
8
9 #if defined(__WIN32__)
10 define pathListSep = ";";
11 #else
12 define pathListSep = ":";
13 #endif
14
15 void ParseDirList(char * string, Container<String> list)
16 {
17    int c;
18    byte * tokens[256];
19    int numTokens = TokenizeWith(string, sizeof(tokens) / sizeof(byte *), tokens, ";", false);
20    list.Free();
21    for(c = 0; c < numTokens; c++)
22       list.Add(CopyString(tokens[c]));
23 }
24
25 // NOTE: FileMonitors are not to be used by an Application class. globalSystem is not set up properly otherwise.
26 // Mantis ticket #545 was filed regarding this.
27 class epj2makeApp : GuiApplication
28 {
29    void Main()
30    {
31       int c;
32       bool valid = true;
33       char * configName = null;
34       char * epjPath = null;
35       char * makePath = null;
36       /*
37       char ** argv = null;
38       int argc = 0;
39       */
40
41       Platform targetPlatform = GetRuntimePlatform();
42
43       Project project = null;
44
45       CompilerConfig optionsCompiler { };
46
47       bool noGlobalSettings = false;
48       bool noResources = false;
49       bool noWarnings = false;
50       char * overrideObjDir = null;
51       char * includemkPath = null;
52
53       /*
54       for(c = 0; c < this.argc; c++)
55       {
56          char * arg = this.argv[c];
57          int argLen = strlen(arg);
58
59          argv = renew argv char *[argc + 1];
60          argv[argc] = new char[argLen + 1];
61          strcpy(argv[argc], arg);
62
63          while(argv[argc][argLen - 1] == '\\' && c < this.argc-1)
64          {
65             int len;
66
67             c++;
68             arg = this.argv[c];
69             len = strlen(arg);
70             argv[argc] = renew argv[argc] char[argLen + len + 1];
71
72             argv[argc][argLen - 1] = ' ';
73             strcpy(argv[argc] + argLen, arg);
74             argLen += len;
75          }
76          argc++;
77       }
78       */
79
80       for(c = 1; c < argc; c++)
81       {
82          char * arg = argv[c];
83          if(arg[0] == '-')
84          {
85             if(!strcmpi(arg+1, "make"))
86             {
87                if(++c < argc)
88                   optionsCompiler.makeCommand = argv[c];
89                else
90                   valid = false;
91             }
92             else if(!strcmpi(arg+1, "cpp"))
93             {
94                if(++c < argc)
95                   optionsCompiler.cppCommand = argv[c];
96                else
97                   valid = false;
98             }
99             else if(!strcmpi(arg+1, "cc"))
100             {
101                if(++c < argc)
102                   optionsCompiler.ccCommand = argv[c];
103                else
104                   valid = false;
105             }
106             else if(!strcmpi(arg+1, "ecp"))
107             {
108                if(++c < argc)
109                   optionsCompiler.ecpCommand = argv[c];
110                else
111                   valid = false;
112             }
113             else if(!strcmpi(arg+1, "ecc"))
114             {
115                if(++c < argc)
116                   optionsCompiler.eccCommand = argv[c];
117                else
118                   valid = false;
119             }
120             else if(!strcmpi(arg+1, "ecs"))
121             {
122                if(++c < argc)
123                   optionsCompiler.ecsCommand = argv[c];
124                else
125                   valid = false;
126             }
127             else if(!strcmpi(arg+1, "ear"))
128             {
129                if(++c < argc)
130                   optionsCompiler.earCommand = argv[c];
131                else
132                   valid = false;
133             }
134             else if(!strcmpi(arg+1, "noglobalsettings"))
135             {
136                noGlobalSettings = true;
137             }
138             else if(!strcmpi(arg+1, "noresources"))
139             {
140                noResources = true;
141             }
142             else if(!strcmpi(arg+1, "includemk"))
143             {
144                if(++c < argc)
145                   includemkPath = argv[c];
146                else
147                   valid = false;
148             }
149             else if(arg[1] == 'w' && !arg[2])
150             {
151                noWarnings = true;
152             }
153             else if(arg[1] == 'c' && !arg[2])
154             {
155                if(++c < argc)
156                {
157                   int argLen = strlen(argv[c]);
158                   configName = new char[argLen + 1];
159                   strcpy(configName, argv[c]);
160                }
161                else
162                   valid = false;
163             }
164             else if(arg[1] == 't' && !arg[2])
165             {
166                if(++c < argc)
167                   targetPlatform = argv[c];
168                else
169                   valid = false;
170             }
171             else if(arg[1] == 'o')
172             {
173                if(++c < argc)
174                {
175                   int argLen = strlen(argv[c]);
176                   makePath = new char[argLen + 1];
177                   strcpy(makePath, argv[c]);
178                }
179                else
180                   valid = false;
181             }
182             else if(arg[1] == 'i')
183             {
184                if(++c < argc)
185                   ParseDirList(argv[c], optionsCompiler.includeDirs);
186                else
187                   valid = false;
188             }
189             else if(arg[1] == 'l')
190             {
191                if(++c < argc)
192                   ParseDirList(argv[c], optionsCompiler.libraryDirs);
193                else
194                   valid = false;
195             }
196             else if(arg[1] == 'd' && !arg[2])
197             {
198                if(++c < argc)
199                   overrideObjDir = argv[c];
200                else
201                   valid = false;
202             }
203             else
204             {
205                valid = false;
206                printf($"invalid option: %s\n", arg);
207             }
208          }
209          else
210          {
211             if(!epjPath)
212             {
213                int argLen = strlen(arg);
214                epjPath = new char[argLen + 1];
215                strcpy(epjPath, arg);
216                c++;
217             }
218             else
219                valid = false;
220          }
221       }
222       if(!epjPath)
223          valid = false;
224       
225       if(!valid)
226       {
227          printf($"Syntax:\n");
228          printf($"   epj2make [-t <target platform>] [-c <configuration>] [toolchain] [directories] [options] [-o <output>] <input>\n");
229          printf($"      toolchain:\n");
230          printf($"         [-make <make tool>]\n");
231          printf($"         [-cpp <c preprocessor>]\n");
232          printf($"         [-cc <c compiler>]\n");
233          printf($"         [-ecp <eC preprocessor>]\n");
234          printf($"         [-ecc <eC compiler>]\n");
235          printf($"         [-ecs <eC symbol generator>]\n");
236          printf($"         [-ear <Ecere Archiver>]\n");
237          printf($"      directories:\n");
238          printf($"         [-i <include dir[;inc dir[...]]>]\n");
239          printf($"         [-l <library dir[;lib dir[...]]>]\n");
240          printf($"      options:\n");
241          printf($"         [-noglobalsettings]\n");
242          printf($"         [-noresources]\n");
243          printf($"         [-d <intermediate objects directory>]\n");
244          printf($"         [-includemk <include.mk path>]\n");
245       }
246       else
247       {
248          if(FileExists(epjPath).isFile)
249          {
250             char extension[MAX_EXTENSION] = "";
251             GetExtension(epjPath, extension);
252             strlwr(extension);
253             if(!strcmp(extension, ProjectExtension))
254             {
255                if(noGlobalSettings)
256                {
257                   defaultCompiler = MakeDefaultCompiler("Default", true);
258                   delete ideSettings;
259                }
260                else
261                {
262                   settingsContainer.Load();
263                   //incref ideSettings;
264                   delete settingsContainer;
265
266       // TODO: Command line option to choose between the two
267       // or a command line option to not use global settings 
268       //defaultCompiler = MakeDefaultCompiler();
269                   defaultCompiler = ideSettings.GetCompilerConfig("Default");
270       // possible TODO: use the workspace to select the active compiler
271       // TODO: option to specify compiler name when using global settings
272                }
273
274                if(optionsCompiler.makeCommand)
275                   defaultCompiler.makeCommand = optionsCompiler.makeCommand;
276                if(optionsCompiler.cppCommand)
277                   defaultCompiler.cppCommand = optionsCompiler.cppCommand;
278                if(optionsCompiler.ccCommand)
279                   defaultCompiler.ccCommand = optionsCompiler.ccCommand;
280                if(optionsCompiler.ecpCommand)
281                   defaultCompiler.ecpCommand = optionsCompiler.ecpCommand;
282                if(optionsCompiler.eccCommand)
283                   defaultCompiler.eccCommand = optionsCompiler.eccCommand;
284                if(optionsCompiler.ecsCommand)
285                   defaultCompiler.ecsCommand = optionsCompiler.ecsCommand;
286                if(optionsCompiler.earCommand)
287                   defaultCompiler.earCommand = optionsCompiler.earCommand;
288                // TODO: Pass/combine/override the include and library dirs
289                for(dir : optionsCompiler.includeDirs)
290                   defaultCompiler.includeDirs.Add(dir);
291                for(dir : optionsCompiler.libraryDirs)
292                   defaultCompiler.libraryDirs.Add(dir);
293                delete optionsCompiler;
294
295                project = LoadProject(epjPath);
296                if(project)
297                {
298                   ProjectConfig defaultConfig = null;
299                   if(configName)
300                   {
301                      valid = false;
302                      for(config : project.configurations)
303                      {
304                         if(!strcmpi(configName, config.name))
305                         {
306                            project.config = config;
307                            valid = true;
308                            break;
309                         }
310                      }
311                      if(!valid)
312                         printf($"Error: Project configuration (%s) was not found.\n", configName);
313                   }
314                   else
315                   {
316                      ProjectConfig releaseConfig = null;
317                      for(config : project.configurations)
318                      {
319                         if(!strcmpi(config.name, "Release"))
320                         {
321                            releaseConfig = config;
322                            break;
323                         }
324                      }
325                      if(!releaseConfig && project.configurations.count)
326                      {
327                         releaseConfig = project.configurations[0];
328                         printf($"Notice: Project configuration (%s) will be used.\n", releaseConfig.name);
329                      }
330
331                      if(releaseConfig)
332                      {
333                         project.config = releaseConfig;
334                         if(overrideObjDir)
335                         {
336                            delete releaseConfig.options.targetDirectory;
337                            releaseConfig.options.targetDirectory = CopyString(overrideObjDir);
338                            delete releaseConfig.options.objectsDirectory;
339                            releaseConfig.options.objectsDirectory = CopyString(overrideObjDir);
340                         }
341                         if(noWarnings)
342                            releaseConfig.options.warnings = none;
343                      }
344                      else if(overrideObjDir)
345                      {
346                         delete project.options.targetDirectory;
347                         project.options.targetDirectory = CopyString(overrideObjDir);
348                         delete project.options.objectsDirectory;
349                         project.options.objectsDirectory = CopyString(overrideObjDir);
350                      }
351                      if(noWarnings)
352                         project.options.warnings = none;
353                   }
354                   if(valid)
355                   {
356                      if(project.GenerateMakefile(makePath, noResources, includemkPath, defaultCompiler, project.config))
357                      {
358                         if(makePath)
359                            printf("%s\n", makePath);
360                      }
361                   }
362
363                   if(noGlobalSettings)
364                      delete defaultCompiler;
365
366                   delete defaultConfig;
367                   delete project;
368                }
369                else
370                   printf($"Error: Unable to open project file (%s) due to unknown error.\n", epjPath);
371             }
372          }
373          else
374             printf($"Error: Input file (%s) does not exist.\n", epjPath);
375       }
376
377       //if(optionsCompiler) // how to fix those leaks?
378       delete optionsCompiler;
379
380       delete configName;
381       delete epjPath;
382       delete makePath;
383
384       // Why do we need to free this here?
385       delete defaultCompiler;
386
387       /*
388       for(c = 0; c<argc; c++)
389          delete argv[c];
390       delete argv;
391       */
392
393       // CheckMemory();
394       delete ideSettings;
395 #ifdef _DEBUG      
396       getch();
397 #endif
398    }
399 }