private void resolveFile(outputEntry outputEntry, fileObj[] files, out ProjectFile file, out int line) { long lineTotal = 0; file = null; line = -1; for (int c = 0; c < files.Length; c++) { fileObj entry = files[c]; int relativeLine = (int)(outputEntry.line - lineTotal); if (relativeLine <= entry.LineLength) { line = relativeLine; file = entry.ProjectFile; return; } lineTotal += entry.LineLength; } }
private void compileC(string outputFile, StandardCompileOutput <Project> output, fileObj[] codeFiles, fileObj[] headerFiles, StandardOutputCallback stdOut) { if (File.Exists(outputFile)) { File.Delete(outputFile); } //collapse the code files and header files into one array but add the header files first. fileObj[] files = new fileObj[0]; Helpers.AddObject(ref files, headerFiles); Helpers.AddObject(ref files, codeFiles); //flatten the files down to a single file string collapsed = collapseFiles(files, ".c"); //perform the compile outputEntry[] errors = new outputEntry[0]; outputEntry[] warnings = new outputEntry[0]; compileC(ref errors, ref warnings, collapsed, outputFile, stdOut); processCompileResults(codeFiles, output, errors, warnings); //clean up File.Delete(collapsed); }
public ICompilerOutput<Project> CompileProject(Project project, StandardOutputCallback standardOutput) { #region split up every file in the project into a code file fileObj[] assemblyFiles = new fileObj[0]; fileObj[] cCodeFiles = new fileObj[0]; fileObj[] cHeaderFiles = new fileObj[0]; project.Root.Enumerate(true, delegate(ProjectEntity e) { if (!(e is ProjectFile)) { return true; } //add the filename into the appropriate code file list ProjectFile file = (ProjectFile)e; string ext = file.Extension.ToLower(); switch (ext) { case ".c": Helpers.AddObject(ref cCodeFiles, new fileObj(file)); break; case ".h": Helpers.AddObject(ref cHeaderFiles, new fileObj(file)); break; case ".asm": Helpers.AddObject(ref assemblyFiles, new fileObj(file)); break; } return true; }); #endregion //define the final output file string finalOutput = getOuputFilename(project, "build.bin"); StandardCompileOutput<Project> output = new StandardCompileOutput<Project>(finalOutput, project); string[] outputFiles = new string[0]; if (File.Exists(finalOutput)) { File.Delete(finalOutput); } //define whether or not the assembly code should //be linked (no point in linking if theres nothing //to link with) bool linkable = cCodeFiles.Length != 0 || cHeaderFiles.Length != 0; //compile the assembly if (assemblyFiles.Length != 0) { //make sure that the main entry point assembly file is at the top //of the list to be compiled first. int bootfileIndex = -1; for (int c = 0; c < assemblyFiles.Length; c++) { if (assemblyFiles[c].ProjectFile.Name.ToLower() == "boot.asm") { bootfileIndex = c; break; } } if (bootfileIndex != -1) { Helpers.SwapEntries(ref assemblyFiles, bootfileIndex, 0); } string asmOut = getOuputFilename(project, "asm.o"); compileAssembly(linkable, asmOut, output, assemblyFiles, standardOutput); Helpers.AddObject(ref outputFiles, asmOut); //if there are no C code/header files, then there is no point //compiling and linking them with the ASM code. if (!linkable) { if (File.Exists(asmOut)) { File.Move(asmOut, finalOutput); } return output; } } //compile all the C code string cOut = getOuputFilename(project, "c.o"); compileC(cOut, output, cCodeFiles, cHeaderFiles, standardOutput); Helpers.AddObject(ref outputFiles, cOut); //if there was no success, do not continue with linking. if (output.Errors.Length != 0) { return output; } //link the c and assembly code together. link( outputFiles, finalOutput, output, standardOutput); return output; }
private void processCompileResults(fileObj[] files, StandardCompileOutput<Project> output, outputEntry[] errors, outputEntry[] warnings) { for (int c = 0; c < errors.Length; c++) { ProjectFile file; int line; resolveFile(errors[c], files, out file, out line); output.addError( file, line, errors[c].column, errors[c].message); } for (int c = 0; c < warnings.Length; c++) { ProjectFile file; int line; resolveFile(warnings[c], files, out file, out line); output.addWarning( file, line, warnings[c].column, warnings[c].message); } }
private void compileC(string outputFile, StandardCompileOutput<Project> output, fileObj[] codeFiles, fileObj[] headerFiles, StandardOutputCallback stdOut) { if (File.Exists(outputFile)) { File.Delete(outputFile); } //collapse the code files and header files into one array but add the header files first. fileObj[] files = new fileObj[0]; Helpers.AddObject(ref files, headerFiles); Helpers.AddObject(ref files, codeFiles); //flatten the files down to a single file string collapsed = collapseFiles(files, ".c"); //perform the compile outputEntry[] errors = new outputEntry[0]; outputEntry[] warnings = new outputEntry[0]; compileC(ref errors, ref warnings, collapsed, outputFile, stdOut); processCompileResults(codeFiles, output, errors, warnings); //clean up File.Delete(collapsed); }
private void compileAssembly(bool linkable, string outputFile, StandardCompileOutput<Project> output, fileObj[] files, StandardOutputCallback stdOut) { if (File.Exists(outputFile)) { File.Delete(outputFile); } //collapse all the files into one file to compile string collapsed = collapseFiles(files, ".asm"); //compile outputEntry[] errors = new outputEntry[0]; outputEntry[] warnings = new outputEntry[0]; compileAssembly(linkable, ref errors, ref warnings, collapsed, outputFile, stdOut); processCompileResults(files, output, errors, warnings); //clean up File.Delete(collapsed); }
private string collapseFiles(fileObj[] files, string extension) { //create the file to collapse all the files into string filename; Stream stream = Helpers.CreateTempFile(extension, out filename); //read and then write every file in the file array //to the temporary file for (int c = 0; c < files.Length; c++) { //read the file data FileStream readStream = new FileStream(files[c].Filename, FileMode.Open); byte[] fileData = new byte[readStream.Length]; readStream.Read(fileData, 0, fileData.Length); //is there a newline character at the end of data? //if not, we need to write it. Otherwise we get //a mismatch when getting a file from an absolute line position //later on when we get the origination of errors/warnings. bool hasNewLineCharEnding = false; if (fileData.Length >= 2) { int len = fileData.Length; if (fileData[len - 2] == '\n' || fileData[len - 1] == '\n') { hasNewLineCharEnding = true; } } //write the data stream.Write(fileData, 0, fileData.Length); if (!hasNewLineCharEnding) { stream.Write(new byte[2] { (byte)'\r', (byte)'\n' }, 0, 2); } } //clean up stream.Close(); return filename; }
public ICompilerOutput <Project> CompileProject(Project project, StandardOutputCallback standardOutput) { #region split up every file in the project into a code file fileObj[] assemblyFiles = new fileObj[0]; fileObj[] cCodeFiles = new fileObj[0]; fileObj[] cHeaderFiles = new fileObj[0]; project.Root.Enumerate(true, delegate(ProjectEntity e) { if (!(e is ProjectFile)) { return(true); } //add the filename into the appropriate code file list ProjectFile file = (ProjectFile)e; string ext = file.Extension.ToLower(); switch (ext) { case ".c": Helpers.AddObject(ref cCodeFiles, new fileObj(file)); break; case ".h": Helpers.AddObject(ref cHeaderFiles, new fileObj(file)); break; case ".asm": Helpers.AddObject(ref assemblyFiles, new fileObj(file)); break; } return(true); }); #endregion //define the final output file string finalOutput = getOuputFilename(project, "build.bin"); StandardCompileOutput <Project> output = new StandardCompileOutput <Project>(finalOutput, project); string[] outputFiles = new string[0]; if (File.Exists(finalOutput)) { File.Delete(finalOutput); } //define whether or not the assembly code should //be linked (no point in linking if theres nothing //to link with) bool linkable = cCodeFiles.Length != 0 || cHeaderFiles.Length != 0; //compile the assembly if (assemblyFiles.Length != 0) { //make sure that the main entry point assembly file is at the top //of the list to be compiled first. int bootfileIndex = -1; for (int c = 0; c < assemblyFiles.Length; c++) { if (assemblyFiles[c].ProjectFile.Name.ToLower() == "boot.asm") { bootfileIndex = c; break; } } if (bootfileIndex != -1) { Helpers.SwapEntries(ref assemblyFiles, bootfileIndex, 0); } string asmOut = getOuputFilename(project, "asm.o"); compileAssembly(linkable, asmOut, output, assemblyFiles, standardOutput); Helpers.AddObject(ref outputFiles, asmOut); //if there are no C code/header files, then there is no point //compiling and linking them with the ASM code. if (!linkable) { if (File.Exists(asmOut)) { File.Move(asmOut, finalOutput); } return(output); } } //compile all the C code string cOut = getOuputFilename(project, "c.o"); compileC(cOut, output, cCodeFiles, cHeaderFiles, standardOutput); Helpers.AddObject(ref outputFiles, cOut); //if there was no success, do not continue with linking. if (output.Errors.Length != 0) { return(output); } //link the c and assembly code together. link( outputFiles, finalOutput, output, standardOutput); return(output); }