| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
-
- #include "generator.h"
- using namespace dsr;
- static ScriptLanguage identifyLanguage(const ReadableString &filename) {
- String scriptExtension = string_upperCase(file_getExtension(filename));
- if (string_match(scriptExtension, U"BAT")) {
- return ScriptLanguage::Batch;
- } else if (string_match(scriptExtension, U"SH")) {
- return ScriptLanguage::Bash;
- } else {
- throwError(U"Could not identify the scripting language of ", filename, U". Use *.bat or *.sh.\n");
- return ScriptLanguage::Unknown;
- }
- }
- static void script_printMessage(String &output, ScriptLanguage language, const ReadableString message) {
- if (language == ScriptLanguage::Batch) {
- string_append(output, U"echo ", message, U"\n");
- } else if (language == ScriptLanguage::Bash) {
- string_append(output, U"echo ", message, U"\n");
- }
- }
- static void setCompilationFolder(String &generatedCode, ScriptLanguage language, String ¤tPath, const ReadableString &newPath) {
- if (!string_match(currentPath, newPath)) {
- if (string_length(currentPath) > 0) {
- if (language == ScriptLanguage::Batch) {
- string_append(generatedCode, "popd\n");
- } else if (language == ScriptLanguage::Bash) {
- string_append(generatedCode, U")\n");
- }
- }
- if (string_length(newPath) > 0) {
- if (language == ScriptLanguage::Batch) {
- string_append(generatedCode, "pushd ", newPath, "\n");
- } else if (language == ScriptLanguage::Bash) {
- string_append(generatedCode, U"(cd ", newPath, ";\n");
- }
- }
- }
- }
- void generateCompilationScript(SessionContext &input, const ReadableString &scriptPath) {
- printText(U"Generating build script\n");
- String generatedCode;
- ScriptLanguage language = identifyLanguage(scriptPath);
- if (language == ScriptLanguage::Batch) {
- string_append(generatedCode, U"@echo off\n\n");
- } else if (language == ScriptLanguage::Bash) {
- string_append(generatedCode, U"#!/bin/bash\n\n");
- }
- // Keep track of the current path, so that it only changes when needed.
- String currentPath;
- // Generate code for compiling source code into objects.
- printText(U"Generating code for compiling ", input.sourceObjects.length(), U" objects.\n");
- for (int64_t o = 0; o < input.sourceObjects.length(); o++) {
- SourceObject *sourceObject = &(input.sourceObjects[o]);
- printText(U"\t* ", sourceObject->sourcePath, U"\n");
- setCompilationFolder(generatedCode, language, currentPath, sourceObject->compileFrom);
- if (language == ScriptLanguage::Batch) {
- string_append(generatedCode, U"if exist ", sourceObject->objectPath, U" (\n");
- } else if (language == ScriptLanguage::Bash) {
- string_append(generatedCode, U"if [ -e \"", sourceObject->objectPath, U"\" ]; then\n");
- }
- script_printMessage(generatedCode, language, string_combine(U"Reusing ", sourceObject->sourcePath, U" ID:", sourceObject->identityChecksum, U"."));
- if (language == ScriptLanguage::Batch) {
- string_append(generatedCode, U") else (\n");
- } else if (language == ScriptLanguage::Bash) {
- string_append(generatedCode, U"else\n");
- }
- String compilerFlags = sourceObject->generatedCompilerFlags;
- script_printMessage(generatedCode, language, string_combine(U"Compiling ", sourceObject->sourcePath, U" ID:", sourceObject->identityChecksum, U" with ", compilerFlags, U"."));
- string_append(generatedCode, sourceObject->compilerName, compilerFlags, U" -c ", sourceObject->sourcePath, U" -o ", sourceObject->objectPath, U"\n");
- if (language == ScriptLanguage::Batch) {
- string_append(generatedCode, ")\n");
- } else if (language == ScriptLanguage::Bash) {
- string_append(generatedCode, U"fi\n");
- }
- }
- // Generate code for linking objects into executables.
- printText(U"Generating code for linking ", input.linkerSteps.length(), U" executables:\n");
- for (int64_t l = 0; l < input.linkerSteps.length(); l++) {
- LinkingStep *linkingStep = &(input.linkerSteps[l]);
- String programPath = linkingStep->binaryName;
- printText(U"\tGenerating code for linking ", programPath, U" of :\n");
- setCompilationFolder(generatedCode, language, currentPath, linkingStep->compileFrom);
- String linkerFlags;
- for (int64_t lib = 0; lib < linkingStep->linkerFlags.length(); lib++) {
- String library = linkingStep->linkerFlags[lib];
- string_append(linkerFlags, " -l", library);
- printText(U"\t\t* ", library, U" library\n");
- }
- // Generate a list of object paths from indices.
- String allObjects;
- for (int64_t i = 0; i < linkingStep->sourceObjectIndices.length(); i++) {
- int64_t objectIndex = linkingStep->sourceObjectIndices[i];
- SourceObject *sourceObject = &(input.sourceObjects[objectIndex]);
- if (objectIndex >= 0 || objectIndex < input.sourceObjects.length()) {
- printText(U"\t\t* ", sourceObject->sourcePath, U"\n");
- string_append(allObjects, U" ", sourceObject->objectPath);
- } else {
- throwError(U"Object index ", objectIndex, U" is out of bound ", 0, U"..", (input.sourceObjects.length() - 1), U"\n");
- }
- }
- // Generate the code for building.
- if (string_length(linkerFlags) > 0) {
- script_printMessage(generatedCode, language, string_combine(U"Linking ", programPath, U" with", linkerFlags, U"."));
- } else {
- script_printMessage(generatedCode, language, string_combine(U"Linking ", programPath, U"."));
- }
- string_append(generatedCode, linkingStep->compilerName, allObjects, linkerFlags, U" -o ", programPath, U"\n");
- if (linkingStep->executeResult) {
- script_printMessage(generatedCode, language, string_combine(U"Starting ", programPath));
- string_append(generatedCode, programPath, U"\n");
- script_printMessage(generatedCode, language, U"The program terminated.");
- }
- }
- setCompilationFolder(generatedCode, language, currentPath, U"");
- script_printMessage(generatedCode, language, U"Done building.");
- // Save the script.
- printText(U"Saving script to ", scriptPath, "\n");
- if (language == ScriptLanguage::Batch) {
- string_save(scriptPath, generatedCode);
- } else if (language == ScriptLanguage::Bash) {
- string_save(scriptPath, generatedCode, CharacterEncoding::BOM_UTF8, LineEncoding::Lf);
- }
- }
|