1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <sngcm/ast/InitDone.hpp>
  7 #include <soulng/util/InitDone.hpp>
  8 #include <cmajor/build/Build.hpp>
  9 #include <cmajor/cmmid/InitDone.hpp>
 10 #include <cmajor/symbols/Exception.hpp>
 11 #include <cmajor/symbols/InitDone.hpp>
 12 #include <cmajor/symbols/GlobalFlags.hpp>
 13 #include <cmajor/symbols/ModuleCache.hpp>
 14 #include <cmajor/symbols/Trace.hpp>
 15 #include <cmajor/symbols/Warning.hpp>
 16 #ifdef _WIN32
 17 #include <cmajor/cmres/InitDone.hpp>
 18 #endif
 19 #include <soulng/lexer/ParsingException.hpp>
 20 #include <sngxml/dom/Document.hpp>
 21 #include <sngxml/dom/Element.hpp>
 22 #include <sngxml/dom/CharacterData.hpp>
 23 #include <sngxml/xpath/InitDone.hpp>
 24 #include <soulng/util/Util.hpp>
 25 #include <soulng/util/Path.hpp>
 26 #include <soulng/util/Json.hpp>
 27 #include <soulng/util/Unicode.hpp>
 28 #include <boost/filesystem.hpp>
 29 #include <boost/lexical_cast.hpp>
 30 #include <iostream>
 31 #include <string>
 32 #include <stdexcept>
 33 #include <chrono>
 34 
 35 struct InitDone 
 36 {
 37     InitDone()
 38     {
 39         soulng::util::Init();
 40         sngcm::ast::Init();
 41         cmajor::symbols::Init();
 42         sngxml::xpath::Init();
 43 #ifdef _WIN32
 44 
 45 #endif
 46     }
 47     ~InitDone()
 48     {
 49 #ifdef _WIN32
 50 
 51 #endif
 52         sngxml::xpath::Done();
 53         cmajor::symbols::Done();
 54         sngcm::ast::Done();
 55         soulng::util::Done();
 56     }
 57 };
 58 
 59 struct BackendSelector 
 60 {
 61     BackendSelector(cmajor::symbols::BackEnd backend)
 62     {
 63         switch (backend)
 64         {
 65             case cmajor::symbols::BackEnd::llvm:
 66             {
 67                 CmmInit(cmajor::mid::BackEndKind::llvmBackEnd);
 68                 break;
 69             }
 70             case cmajor::symbols::BackEnd::cmsx:
 71             {
 72                 CmmInit(cmajor::mid::BackEndKind::cmsxBackEnd);
 73                 break;
 74             }
 75             case cmajor::symbols::BackEnd::cmcpp:
 76             {
 77                 CmmInit(cmajor::mid::BackEndKind::cmcppBackEnd);
 78                 break;
 79             }
 80         }
 81     }
 82     ~BackendSelector()
 83     {
 84         CmmDone();
 85     }
 86 };
 87 
 88 const char* version = "3.10.0";
 89 
 90 void PrintHelp()
 91 {
 92 #ifdef _WIN32
 93 
 94 #else
 95     std::cout << "Cmajor with LLVM backend compiler version " << version << std::endl;
 96 #endif
 97     std::cout << "Usage: cmc [options] { project.cmp | solution.cms }" << std::endl;
 98     std::cout << "Compiles given Cmajor solutions and projects." << std::endl;
 99     std::cout << "Options:\n" << 
100         "--help (-h)\n" << 
101         "   print this help message\n" << 
102         "--config=CONFIG (-c=CONFIG)\n" << 
103         "   set configuration to CONFIG (debug | release)\n" << 
104         "   default is debug\n" << 
105         "--backend=BACKEND (-be=BACKEND)\n" << 
106         "   set compiler back-end to BACKEND : (llvm | cmsx)\n" << 
107         "   default is llvm\n" << 
108         "--optimization-level=LEVEL (-O=LEVEL)\n" << 
109         "   set optimization level to LEVEL=0-3\n" << 
110         "   defaults: debug=0, release=2\n" << 
111         "--verbose (-v)\n" << 
112         "   print verbose messages\n" << 
113         "--quiet (-q)\n" << 
114         "   print no messages\n" << 
115         "--strict-nothrow (-s)\n" << 
116         "   treat nothrow violation as an error\n" << 
117         "--time (-t)\n" << 
118         "   print duration of compilation\n" << 
119         "--outdir=OUTDIR (-o=OUTDIR)\n" << 
120         "   set output directory root to OUTDIR\n" << 
121         "--rebuild (-u)\n" << 
122         "   build although sources not changed\n" << 
123         "--emit-llvm (-l)\n" << 
124         "   emit intermediate LLVM code to file.ll files\n" << 
125         "--emit-opt-llvm (-o)\n" << 
126         "   emit optimized intermediate LLVM code to file.opt.ll files\n" << 
127         "--clean (-e)\n" << 
128         "   clean given solutions and projects\n" << 
129         "--debug-parse (-p)\n" << 
130         "   debug parsing to stdout\n" << 
131         "--ast2xml (-x)\n" << 
132         "   output AST of each source file as xml\n" << 
133         "--sym2xml (-y)\n" << 
134         "   output symbol table as xml\n" << 
135         "--bdt2xml (-bd)\n" << 
136         "   output bound tree as xml\n" << 
137         "--link-with-debug-runtime (-d)\n" << 
138         "   link with the debug version of the runtime library cmrt3100(d).dll\n" << 
139         "--link-using-ms-link (-m)\n" << 
140         "   use Microsoft's link.exe as the linker\n" << 
141         "--define SYMBOL (-D SYMBOL)\n" << 
142         "   define a conditional compilation symbol SYMBOL.\n" << 
143         "--gen-debug-info (-g)\n" << 
144         "   generate debug info (on by default in debug configuration)\n" << 
145         "--no-debug-info (-n)\n" << 
146         "   don't generate debug info even for debug build\n" << 
147         "--ide (-i)\n" << 
148         "   set IDE mode: this mode is for Cmajor Development Environment.\n" << 
149         "--msbuild (-b)\n" << 
150         "   set MSBuild mode: this mode is for Visual Studio and MSBuild.\n" << 
151         "--build-threads=N (-bt=N)\n" << 
152         "   set number of build threads to N, default=1\n" << 
153         "--disable-module-cache (-dm)\n" << 
154         "   do not cache recently built modules\n" << 
155         "--single-threaded-compile (-st)\n" << 
156         "   compile source files in a project using a single thread\n" << 
157         "--debug-compile (-dc)\n" << 
158         "   show debug messages from multithreaded compilation\n" << 
159         "--all (-a)\n" << 
160         "   build all dependencies\n" << 
161         std::endl;
162 }
163 
164 using namespace soulng::util;
165 using namespace soulng::unicode;
166 using namespace cmajor::symbols;
167 using namespace cmajor::build;
168 
169 #if(0)
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 #endif 
214 
215 int main(int argcconst char** argv)
216 {
217     InitDone initDone;
218     std::unique_ptr<Module> rootModule;
219     std::vector<std::std::unique_ptr<Module>>rootModules;
220     std::set<std::string> builtProjects;
221     try
222     {
223         std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
224         bool all = false;
225         std::string projectName;
226         std::string projectDirectory;
227         std::string target = "program";
228         std::vector<std::string> files;
229         std::vector<std::string> sourceFiles;
230         std::vector<std::string> resourceFiles;
231         std::vector<std::string> referenceFiles;
232         if (argc < 2)
233         {
234             PrintHelp();
235         }
236         else
237         {
238             SetCompilerVersion(version);
239             bool prevWasDefine = false;
240             bool noDebugInfo = false;
241             bool useModuleCache = true;
242             for (int i = 1; i < argc; ++i)
243             {
244                 std::string arg = argv[i];
245                 if (!arg.empty() && arg[0] == '-')
246                 {
247                     if (arg == "--help" || arg == "-h")
248                     {
249                         PrintHelp();
250                         return 0;
251                     }
252                     else if (arg == "--verbose" || arg == "-v")
253                     {
254                         SetGlobalFlag(GlobalFlags::verbose);
255                     }
256                     else if (arg == "--quiet" || arg == "-q")
257                     {
258                         SetGlobalFlag(GlobalFlags::quiet);
259                     }
260                     else if (arg == "--clean" || arg == "-e")
261                     {
262                         SetGlobalFlag(GlobalFlags::clean);
263                     }
264                     else if (arg == "--ide" || arg == "-i")
265                     {
266                         SetGlobalFlag(GlobalFlags::ide);
267                     }
268                     else if (arg == "--msbuild" || arg == "-b")
269                     {
270                         SetGlobalFlag(GlobalFlags::msbuild);
271                     }
272                     else if (arg == "--debug-parse" || arg == "-p")
273                     {
274                         SetGlobalFlag(GlobalFlags::debugParsing);
275                     }
276                     else if (arg == "--ast2xml" || arg == "-x")
277                     {
278                         SetGlobalFlag(GlobalFlags::ast2xml);
279                         SetGlobalFlag(GlobalFlags::singleThreadedCompile);
280                     }
281                     else if (arg == "--sym2xml" || arg == "-y")
282                     {
283                         SetGlobalFlag(GlobalFlags::sym2xml);
284                         SetGlobalFlag(GlobalFlags::singleThreadedCompile);
285                     }
286                     else if (arg == "--bdt2xml" || arg == "-bd")
287                     {
288                         SetGlobalFlag(GlobalFlags::bdt2xml);
289                         SetGlobalFlag(GlobalFlags::singleThreadedCompile);
290                     }
291                     else if (arg == "--strict-nothrow" || arg == "-s")
292                     {
293                         SetGlobalFlag(GlobalFlags::strictNothrow);
294                     }
295                     else if (arg == "--emit-llvm" || arg == "-l")
296                     {
297                         SetGlobalFlag(GlobalFlags::emitLlvm);
298                     }
299                     else if (arg == "--emit-opt-llvm" || arg == "-o")
300                     {
301                         SetGlobalFlag(GlobalFlags::emitLlvm);
302                         SetGlobalFlag(GlobalFlags::emitOptLlvm);
303                     }
304                     else if (arg == "--link-with-debug-runtime" || arg == "-d")
305                     {
306                         SetGlobalFlag(GlobalFlags::linkWithDebugRuntime);
307                     }
308                     else if (arg == "--link-using-ms-link" || arg == "-m")
309                     {
310                         SetGlobalFlag(GlobalFlags::linkUsingMsLink);
311                     }
312                     else if (arg == "--time" || arg == "-t")
313                     {
314                         SetGlobalFlag(GlobalFlags::time);
315                     }
316                     else if (arg == "--rebuild" || arg == "-u")
317                     {
318                         SetGlobalFlag(GlobalFlags::rebuild);
319                     }
320                     else if (arg == "--all" || arg == "-a")
321                     {
322                         SetGlobalFlag(GlobalFlags::buildAll);
323                     }
324                     else if (arg == "--define" || arg == "-D")
325                     {
326                         prevWasDefine = true;
327                     }
328                     else if (arg == "--gen-debug-info" || arg == "-g")
329                     {
330                         SetGlobalFlag(GlobalFlags::generateDebugInfo);
331                     }
332                     else if (arg == "--no-debug-info" || arg == "-n")
333                     {
334                         noDebugInfo = true;
335                     }
336                     else if (arg == "--disable-module-cache" || arg == "-dm")
337                     {
338                         useModuleCache = false;
339                     }
340                     else if (arg == "--single-threaded-compile" || arg == "-st")
341                     {
342                         SetGlobalFlag(GlobalFlags::singleThreadedCompile);
343                     }
344                     else if (arg == "--debug-compile" || arg == "-dc")
345                     {
346                         SetGlobalFlag(GlobalFlags::debugCompile);
347                     }
348                     else if (arg.find('=') != std::string::npos)
349                     {
350                         std::vector<std::string> components = Split(arg'=');
351                         if (components.size() == 2)
352                         {
353                             if (components[0] == "--config" || components[0] == "-c")
354                             {
355                                 if (components[1] == "release")
356                                 {
357                                     SetGlobalFlag(GlobalFlags::release);
358                                 }
359                                 else if (components[1] == "trace")
360                                 {
361                                     SetGlobalFlag(GlobalFlags::trace);
362                                 }
363                                 else if (components[1] != "debug")
364                                 {
365                                     throw std::runtime_error("unknown configuration '" + components[1] + "'");
366                                 }
367                             }
368                             else if (components[0] == "--backend" || components[0] == "-be")
369                             {
370                                 if (components[1] == "llvm")
371                                 {
372                                     SetBackEnd(cmajor::symbols::BackEnd::llvm);
373                                 }
374                                 else if (components[1] == "cmsx")
375                                 {
376                                     SetBackEnd(cmajor::symbols::BackEnd::cmsx);
377                                 }
378                                 else if (components[1] == "cmcpp")
379                                 {
380                                     SetBackEnd(cmajor::symbols::BackEnd::cmcpp);
381                                 }
382                                 else
383                                 {
384                                     throw std::runtime_error("unknown compile target '" + components[1] + "'");
385                                 }
386                             }
387                             else if (components[0] == "--optimization-level" || components[0] == "-O")
388                             {
389                                 int optimizationLevel = boost::lexical_cast<int>(components[1]);
390                                 if (optimizationLevel >= 0 && optimizationLevel <= 3)
391                                 {
392                                     SetOptimizationLevel(optimizationLevel);
393                                 }
394                                 else
395                                 {
396                                     throw std::runtime_error("unknown optimization level '" + components[1] + "'");
397                                 }
398                             }
399                             else if (components[0] == "--reference" || components[0] == "-r")
400                             {
401                                 std::string file = components[1];
402                                 boost::filesystem::path fp(file);
403                                 if (!boost::filesystem::exists(fp))
404                                 {
405                                     throw std::runtime_error("referenced project file '" + fp.generic_string() + "' not found");
406                                 }
407                                 referenceFiles.push_back(file);
408                             }
409                             else if (components[0] == "--resource")
410                             {
411                                 std::string file = components[1];
412                                 boost::filesystem::path fp(file);
413                                 if (!boost::filesystem::exists(fp))
414                                 {
415                                     throw std::runtime_error("resource XML file '" + fp.generic_string() + "' not found");
416                                 }
417                                 resourceFiles.push_back(file);
418                             }
419                             else if (components[0] == "--target")
420                             {
421                                 target = components[1];
422                                 if (target != "program" && target != "winguiapp" && target != "winapp" && target != "library" && target != "winlib" && target != "unitTest")
423                                 {
424                                     throw std::runtime_error("unknown target '" + target + "': not 'program', 'winguiapp', 'winapp', 'library', 'winlib' or 'unitTest'");
425                                 }
426                             }
427                             else if (components[0] == "--name" || components[0] == "-N")
428                             {
429                                 projectName = components[1];
430                             }
431                             else if (components[0] == "--dir" || components[0] == "-pd")
432                             {
433                                 projectDirectory = components[1];
434                             }
435                             else if (components[0] == "--build-threads" || components[0] == "-bt")
436                             {
437                                 int numBuildThreads = boost::lexical_cast<int>(components[1]);
438                                 SetNumBuildThreads(numBuildThreads);
439                             }
440                             else if (components[0] == "--outdir" || components[0] == "-o")
441                             {
442                                 std::string outdir = components[1];
443                                 SetOutDir(outdir);
444                             }
445                             else
446                             {
447                                 throw std::runtime_error("unknown option '" + arg + "'");
448                             }
449                         }
450                         else
451                         {
452                             throw std::runtime_error("invalid argument '" + arg + "'");
453                         }
454                     }
455                     else
456                     {
457                         throw std::runtime_error("unknown option '" + arg + "'");
458                     }
459                 }
460                 else if (prevWasDefine)
461                 {
462                     prevWasDefine = false;
463                     DefineCommandLineConditionalSymbol(ToUtf32(arg));
464                 }
465                 else
466                 {
467                     files.push_back(arg);
468                 }
469             }
470             if (files.empty())
471             {
472                 PrintHelp();
473                 return 0;
474             }
475             if (GetGlobalFlag(GlobalFlags::verbose))
476             {
477 #ifdef _WIN32
478 
479 #else
480                 std::cout << "Cmajor with LLVM backend compiler version " << version << std::endl;
481 #endif
482             }
483 #ifndef _WIN32
484             noDebugInfo = true;
485 #endif
486             if (GetGlobalFlag(GlobalFlags::trace))
487             {
488                 ReadTraceTable();
489             }
490             SetUseModuleCache(useModuleCache);
491             BackendSelector backend(GetBackEnd());
492             if (!GetGlobalFlag(GlobalFlags::release) && !noDebugInfo)
493             {
494                 SetGlobalFlag(GlobalFlags::generateDebugInfo);
495             }
496 #ifndef _WIN32
497             SetNumBuildThreads(1);
498             SetGlobalFlag(GlobalFlags::singleThreadedCompile);
499 #endif
500             for (const std::string& file : files)
501             {
502                 boost::filesystem::path fp(file);
503                 if (fp.extension() == ".cms")
504                 {
505                     if (GetGlobalFlag(GlobalFlags::msbuild))
506                     {
507                         throw std::runtime_error("solution file '" + fp.generic_string() + "'  cannot be given in --msbuild mode");
508                     }
509                     else if (!boost::filesystem::exists(fp))
510                     {
511                         throw std::runtime_error("solution file '" + fp.generic_string() + "' not found");
512                     }
513                     else
514                     {
515                         BuildSolution(GetFullPath(fp.generic_string())rootModules);
516                     }
517                 }
518                 else if (fp.extension() == ".cmp")
519                 {
520                     if (GetGlobalFlag(GlobalFlags::msbuild))
521                     {
522                         throw std::runtime_error("project file '" + fp.generic_string() + "'  cannot be given in --msbuild mode");
523                     }
524                     else if (!boost::filesystem::exists(fp))
525                     {
526                         throw std::runtime_error("project file '" + fp.generic_string() + "' not found");
527                     }
528                     else
529                     {
530                         BuildProject(GetFullPath(fp.generic_string())rootModulebuiltProjects);
531                     }
532                 }
533                 else if (fp.extension() == ".cm")
534                 {
535                     if (GetGlobalFlag(GlobalFlags::msbuild))
536                     {
537                         boost::filesystem::path f(projectDirectory);
538                         f /= fp;
539                         if (!boost::filesystem::exists(f))
540                         {
541                             throw std::runtime_error("source file '" + f.generic_string() + "' not found");
542                         }
543                         else
544                         {
545                             sourceFiles.push_back(GetFullPath(f.generic_string()));
546                         }
547                     }
548                     else
549                     {
550                         throw std::runtime_error("single .cm source file '" + fp.generic_string() + "' cannot be given if not in --msbuild mode");
551                     }
552                 }
553                 else
554                 {
555                     if (GetGlobalFlag(GlobalFlags::msbuild))
556                     {
557                         throw std::runtime_error("Argument '" + fp.generic_string() + "' has invalid extension. Not Cmajor source (.cm) file.");
558                     }
559                     else
560                     {
561                         throw std::runtime_error("Argument '" + fp.generic_string() + "' has invalid extension. Not Cmajor solution (.cms) or project (.cmp) file.");
562                     }
563                 }
564             }
565             if (GetGlobalFlag(GlobalFlags::msbuild))
566             {
567                 SetGlobalFlag(GlobalFlags::rebuild);
568                 BuildMsBuildProject(projectNameprojectDirectorytargetsourceFilesresourceFilesreferenceFilesrootModule);
569             }
570             if (rootModule && !rootModule->WarningCollection().Warnings().empty())
571             {
572                 if (!GetGlobalFlag(GlobalFlags::quiet) && !GetGlobalFlag(GlobalFlags::ide) && !GetGlobalFlag(GlobalFlags::msbuild))
573                 {
574 #if(0)
575 
576 
577 
578 
579 
580 #endif
581                 }
582                 if (GetGlobalFlag(GlobalFlags::ide))
583                 {
584 #if(0)
585 
586 
587 
588 
589 
590 #endif
591                     std::unique_ptr<JsonObject> compileResult(new JsonObject());
592                     compileResult->AddField(U"success"std::unique_ptr<JsonValue>(new JsonBool(true)));
593 #if(0)
594 
595 
596 
597 
598 
599 
600 
601 
602 
603 #endif
604                     std::cerr << compileResult->ToString() << std::endl;
605                 }
606                 else if (GetGlobalFlag(GlobalFlags::msbuild))
607                 {
608                     sngxml::dom::Document compileResultDoc;
609                     std::unique_ptr<sngxml::dom::Element> compileResultElement(new sngxml::dom::Element(U"compileResult"));
610                     std::unique_ptr<sngxml::dom::Element> successElement(new sngxml::dom::Element(U"success"));
611                     std::unique_ptr<sngxml::dom::Text> trueValue(new sngxml::dom::Text(U"true"));
612                     successElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(trueValue.release()));
613                     compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(successElement.release()));
614                     compileResultDoc.AppendChild(std::unique_ptr<sngxml::dom::Node>(compileResultElement.release()));
615                     CodeFormatter formatter(std::cerr);
616                     formatter.SetIndentSize(1);
617                     compileResultDoc.Write(formatter);
618                 }
619             }
620             else if (GetGlobalFlag(GlobalFlags::ide))
621             {
622                 std::unique_ptr<JsonObject> compileResult(new JsonObject());
623                 compileResult->AddField(U"success"std::unique_ptr<JsonValue>(new JsonBool(true)));
624                 std::cerr << compileResult->ToString() << std::endl;
625             }
626             else if (GetGlobalFlag(GlobalFlags::msbuild))
627             {
628                 sngxml::dom::Document compileResultDoc;
629                 std::unique_ptr<sngxml::dom::Element> compileResultElement(new sngxml::dom::Element(U"compileResult"));
630                 std::unique_ptr<sngxml::dom::Element> successElement(new sngxml::dom::Element(U"success"));
631                 std::unique_ptr<sngxml::dom::Text> trueValue(new sngxml::dom::Text(U"true"));
632                 successElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(trueValue.release()));
633                 compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(successElement.release()));
634                 compileResultDoc.AppendChild(std::unique_ptr<sngxml::dom::Node>(compileResultElement.release()));
635                 CodeFormatter formatter(std::cerr);
636                 formatter.SetIndentSize(1);
637                 compileResultDoc.Write(formatter);
638             }
639             if (GetGlobalFlag(GlobalFlags::trace))
640             {
641                 WriteTraceTable();
642             }
643             if (GetGlobalFlag(GlobalFlags::time))
644             {
645                 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
646                 auto dur = end - start;
647                 long long totalSecs = std::chrono::duration_cast<std::chrono::seconds>(dur).count() + 1;
648                 int hours = static_cast<int>(totalSecs / 3600);
649                 int mins = static_cast<int>((totalSecs / 60) % 60);
650                 int secs = static_cast<int>(totalSecs % 60);
651                 std::cout << 
652                     (hours > 0 ? std::to_string(hours) + " hour" + ((hours != 1) ? "s " : " ") : "") << 
653                     (mins > 0 ? std::to_string(mins) + " minute" + ((mins != 1) ? "s " : " ") : "") << 
654                     secs << " second" << ((secs != 1) ? "s" : "") << std::endl;
655             }
656         }
657     }
658     catch (const soulng::lexer::ParsingException& ex;)
659     {
660         if (!GetGlobalFlag(GlobalFlags::quiet) && !GetGlobalFlag(GlobalFlags::ide) && !GetGlobalFlag(GlobalFlags::msbuild))
661         {
662             std::cerr << ex.what() << std::endl;
663             if (rootModule)
664             {
665 #if(0)
666 
667 
668 
669 
670 
671 #endif
672             }
673         }
674         if (GetGlobalFlag(GlobalFlags::ide))
675         {
676             std::cout << ex.what() << std::endl;
677             if (rootModule)
678             {
679 #if(0)
680 
681 
682 
683 
684 
685 #endif
686             }
687             std::unique_ptr<JsonObject> compileResult(new JsonObject());
688             compileResult->AddField(U"success"std::unique_ptr<JsonValue>(new JsonBool(false)));
689             std::unique_ptr<JsonObject> json(new JsonObject());
690             json->AddField(U"tool"std::unique_ptr<JsonValue>(new JsonString(U"cmc")));
691             json->AddField(U"kind"std::unique_ptr<JsonValue>(new JsonString(U"error")));
692             json->AddField(U"project"std::unique_ptr<JsonValue>(new JsonString(ToUtf32(ex.Project()))));
693             json->AddField(U"message"std::unique_ptr<JsonValue>(new JsonString(ToUtf32(ex.Message()))));
694             std::unique_ptr<JsonArray> refs(new JsonArray());
695             std::unique_ptr<JsonObject> ref = SpanToJson(rootModule.get()ex.GetSpan());
696             if (ref)
697             {
698                 refs->AddItem(std::move(ref));
699             }
700             json->AddField(U"references"std::move(refs));
701             compileResult->AddField(U"diagnostics"std::move(json));
702 #if(0)
703 
704 
705 
706 
707 
708 
709 
710 
711 
712 #endif
713             std::cerr << compileResult->ToString() << std::endl;
714         }
715         else if (GetGlobalFlag(GlobalFlags::msbuild))
716         {
717             std::cout << ex.what() << std::endl;
718             if (rootModule)
719             {
720 #if(0)
721 
722 
723 
724 
725 
726 #endif
727             }
728             sngxml::dom::Document compileResultDoc;
729             std::unique_ptr<sngxml::dom::Element> compileResultElement(new sngxml::dom::Element(U"compileResult"));
730             std::unique_ptr<sngxml::dom::Element> successElement(new sngxml::dom::Element(U"success"));
731             std::unique_ptr<sngxml::dom::Text> falseValue(new sngxml::dom::Text(U"false"));
732             successElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(falseValue.release()));
733             compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(successElement.release()));
734             std::unique_ptr<sngxml::dom::Element> diagnosticsElement(new sngxml::dom::Element(U"diagnostics"));
735             std::unique_ptr<sngxml::dom::Element> diagnosticElement(new sngxml::dom::Element(U"diagnostic"));
736             std::unique_ptr<sngxml::dom::Element> categoryElement(new sngxml::dom::Element(U"category"));
737             std::unique_ptr<sngxml::dom::Text> categoryText(new sngxml::dom::Text(U"error"));
738             categoryElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(categoryText.release()));
739             std::unique_ptr<sngxml::dom::Element> subcategoryElement(new sngxml::dom::Element(U"subcategory"));
740             std::unique_ptr<sngxml::dom::Text> subcategoryText(new sngxml::dom::Text(U"error"));
741             subcategoryElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(subcategoryText.release()));
742             std::unique_ptr<sngxml::dom::Element> messageElement(new sngxml::dom::Element(U"message"));
743             std::unique_ptr<sngxml::dom::Text> messageText(new sngxml::dom::Text(ToUtf32(ex.Message())));
744             messageElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(messageText.release()));
745             diagnosticElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(categoryElement.release()));
746             diagnosticElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(subcategoryElement.release()));
747             diagnosticElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(messageElement.release()));
748             std::unique_ptr<sngxml::dom::Element> spanElement = SpanToDomElement(rootModule.get()ex.GetSpan());
749             if (spanElement)
750             {
751                 diagnosticElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(spanElement.release()));
752             }
753             diagnosticsElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(diagnosticElement.release()));
754 #if(0)
755 
756 #endif
757             compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(diagnosticsElement.release()));
758             compileResultDoc.AppendChild(std::unique_ptr<sngxml::dom::Node>(compileResultElement.release()));
759             CodeFormatter formatter(std::cerr);
760             formatter.SetIndentSize(1);
761             compileResultDoc.Write(formatter);
762         }
763         return 1;
764     }
765     catch (const Exception& ex;)
766     {
767         if (!GetGlobalFlag(GlobalFlags::quiet) && !GetGlobalFlag(GlobalFlags::ide) && !GetGlobalFlag(GlobalFlags::msbuild))
768         {
769             std::cerr << ex.What() << std::endl;
770 #if(0)
771 
772 
773 
774 
775 
776 #endif
777         }
778         if (GetGlobalFlag(GlobalFlags::ide))
779         {
780             std::cout << ex.What() << std::endl;
781 #if(0)
782 
783 
784 
785 
786 
787 #endif
788             std::unique_ptr<JsonObject> compileResult(new JsonObject());
789             compileResult->AddField(U"success"std::unique_ptr<JsonValue>(new JsonBool(false)));
790             compileResult->AddField(U"diagnostics"std::move(ex.ToJson()));
791 #if(0)
792 
793 
794 
795 
796 
797 
798 
799 
800 
801 #endif
802             std::cerr << compileResult->ToString() << std::endl;
803         }
804         else if (GetGlobalFlag(GlobalFlags::msbuild))
805         {
806             std::cout << ex.What() << std::endl;
807 #if(0)
808 
809 
810 
811 
812 
813 #endif
814             sngxml::dom::Document compileResultDoc;
815             std::unique_ptr<sngxml::dom::Element> compileResultElement(new sngxml::dom::Element(U"compileResult"));
816             std::unique_ptr<sngxml::dom::Element> successElement(new sngxml::dom::Element(U"success"));
817             std::unique_ptr<sngxml::dom::Text> falseValue(new sngxml::dom::Text(U"false"));
818             successElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(falseValue.release()));
819             compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(successElement.release()));
820             std::unique_ptr<sngxml::dom::Element> diagnosticsElement(new sngxml::dom::Element(U"diagnostics"));
821             ex.AddToDiagnosticsElement(diagnosticsElement.get());
822 #if(0)
823 
824 #endif
825             compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(diagnosticsElement.release()));
826             compileResultDoc.AppendChild(std::unique_ptr<sngxml::dom::Node>(compileResultElement.release()));
827             CodeFormatter formatter(std::cerr);
828             formatter.SetIndentSize(1);
829             compileResultDoc.Write(formatter);
830         }
831         return 1;
832     }
833     catch (const std::exception& ex;)
834     {
835         if (!GetGlobalFlag(GlobalFlags::quiet) && !GetGlobalFlag(GlobalFlags::ide) && !GetGlobalFlag(GlobalFlags::msbuild))
836         {
837             std::cerr << ex.what() << std::endl;
838             if (rootModule)
839             {
840 #if(0)
841 
842 
843 
844 
845 
846 #endif
847             }
848         }
849         if (GetGlobalFlag(GlobalFlags::ide))
850         {
851             std::cout << ex.what() << std::endl;
852             if (rootModule)
853             {
854 #if(0)
855 
856 
857 
858 
859 
860 #endif
861             }
862             std::unique_ptr<JsonObject> compileResult(new JsonObject());
863             compileResult->AddField(U"success"std::unique_ptr<JsonValue>(new JsonBool(false)));
864             std::unique_ptr<JsonObject> diagnostics(new JsonObject());
865             diagnostics->AddField(U"tool"std::unique_ptr<JsonValue>(new JsonString(U"cmc")));
866             diagnostics->AddField(U"kind"std::unique_ptr<JsonValue>(new JsonString(U"error")));
867             diagnostics->AddField(U"project"std::unique_ptr<JsonValue>(new JsonString(U"")));
868             diagnostics->AddField(U"message"std::unique_ptr<JsonValue>(new JsonString(ToUtf32(ex.what()))));
869             compileResult->AddField(U"diagnostics"std::move(diagnostics));
870 #if(0)
871 
872 
873 
874 
875 
876 
877 
878 
879 
880 #endif
881             std::cerr << compileResult->ToString() << std::endl;
882         }
883         else if (GetGlobalFlag(GlobalFlags::msbuild))
884         {
885             std::cout << ex.what() << std::endl;
886             if (rootModule)
887             {
888 #if(0)
889 
890 
891 
892 
893 
894 #endif
895             }
896             sngxml::dom::Document compileResultDoc;
897             std::unique_ptr<sngxml::dom::Element> compileResultElement(new sngxml::dom::Element(U"compileResult"));
898             std::unique_ptr<sngxml::dom::Element> successElement(new sngxml::dom::Element(U"success"));
899             std::unique_ptr<sngxml::dom::Text> falseValue(new sngxml::dom::Text(U"false"));
900             successElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(falseValue.release()));
901             compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(successElement.release()));
902             std::unique_ptr<sngxml::dom::Element> diagnosticsElement(new sngxml::dom::Element(U"diagnostics"));
903             std::unique_ptr<sngxml::dom::Element> diagnosticElement(new sngxml::dom::Element(U"diagnostic"));
904             std::unique_ptr<sngxml::dom::Element> categoryElement(new sngxml::dom::Element(U"category"));
905             std::unique_ptr<sngxml::dom::Text> categoryText(new sngxml::dom::Text(U"error"));
906             std::unique_ptr<sngxml::dom::Element> subcategoryElement(new sngxml::dom::Element(U"subcategory"));
907             std::unique_ptr<sngxml::dom::Text> subcategoryText(new sngxml::dom::Text(U"general"));
908             subcategoryElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(subcategoryText.release()));
909             categoryElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(categoryText.release()));
910             std::unique_ptr<sngxml::dom::Element> messageElement(new sngxml::dom::Element(U"message"));
911             std::unique_ptr<sngxml::dom::Text> messageText(new sngxml::dom::Text(ToUtf32(ex.what())));
912             messageElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(messageText.release()));
913             diagnosticElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(categoryElement.release()));
914             diagnosticElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(subcategoryElement.release()));
915             diagnosticElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(messageElement.release()));
916             diagnosticsElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(diagnosticElement.release()));
917 #if(0)
918 
919 #endif
920             compileResultElement->AppendChild(std::unique_ptr<sngxml::dom::Node>(diagnosticsElement.release()));
921             compileResultDoc.AppendChild(std::unique_ptr<sngxml::dom::Node>(compileResultElement.release()));
922             CodeFormatter formatter(std::cerr);
923             formatter.SetIndentSize(1);
924             compileResultDoc.Write(formatter);
925         }
926         return 1;
927     }
928     return 0;
929 }