public static Process SpawnProcess(string filename, string arguments, bool wait, StandardOutputCallback standardOut) { return(SpawnProcess( filename, arguments, wait, standardOut, standardOut)); }
public static Process SpawnProcess(string filename, string arguments, bool wait, StandardOutputCallback standardOut, StandardOutputCallback errorOut) { return(SpawnProcess( filename, new FileInfo(filename).Directory.FullName, arguments, wait, standardOut, errorOut)); }
public ICompilerOutput <Solution> Compile(Solution solution, StandardOutputCallback standardOutput) { /*This is only temporary code until we have an actual build config system*/ string finalOutput = solution.BuildDirectory + "\\disk.iso"; if (File.Exists(finalOutput)) { File.Delete(finalOutput); } string bootsect = ""; StandardCompileOutput <Solution> output = new StandardCompileOutput <Solution>(finalOutput, solution); foreach (Project p in solution.Projects) { ICompilerOutput <Project> projOut = CompileProject(p, standardOutput); foreach (ICompileOutputEntry e in projOut.Errors) { output.addError( e.File, e.Line, e.Column, e.Message); } foreach (ICompileOutputEntry w in projOut.Warnings) { output.addWarning( w.File, w.Line, w.Column, w.Message); } if (projOut.Errors.Length != 0) { continue; } bootsect = projOut.OutputFile; } if (File.Exists(bootsect)) { generateISO( "OS Test", bootsect, solution.BuildDirectory + "\\disk", finalOutput, standardOutput, new string[0]); } return(output); }
public static Process SpawnProcess(string filename, string currentDirectory, string arguments, bool wait, StandardOutputCallback standardOut, StandardOutputCallback errorOut) { //standardOut(filename + " " + arguments); //create the process with redirecting output enabled Process process = new Process() { StartInfo = new ProcessStartInfo() { FileName = filename, WorkingDirectory = currentDirectory, Arguments = arguments, RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true } }; process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (e.Data == null) { return; } standardOut(e.Data); }; process.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (e.Data == null) { return; } errorOut(e.Data); }; //start the process process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); //wait for the process to finish if (wait) { process.WaitForExit(); } return(process); }
public ICompilerOutput<Solution> Compile(Solution solution, StandardOutputCallback standardOutput) { /*This is only temporary code until we have an actual build config system*/ string finalOutput = solution.BuildDirectory + "\\disk.iso"; if (File.Exists(finalOutput)) { File.Delete(finalOutput); } string bootsect = ""; StandardCompileOutput<Solution> output = new StandardCompileOutput<Solution>(finalOutput, solution); foreach (Project p in solution.Projects) { ICompilerOutput<Project> projOut = CompileProject(p, standardOutput); foreach (ICompileOutputEntry e in projOut.Errors) { output.addError( e.File, e.Line, e.Column, e.Message); } foreach (ICompileOutputEntry w in projOut.Warnings) { output.addWarning( w.File, w.Line, w.Column, w.Message); } if (projOut.Errors.Length != 0) { continue; } bootsect = projOut.OutputFile; } if (File.Exists(bootsect)) { generateISO( "OS Test", bootsect, solution.BuildDirectory + "\\disk", finalOutput, standardOutput, new string[0]); } return output; }
private void link(ref outputEntry[] errors, ref outputEntry[] warnings, string[] files, string outputFile, StandardOutputCallback stdOut) { //define the filename for the linker string linker = new FileInfo("compilers/linker/ld.exe").FullName; //linker = "C:\\cygwin\\bin\\ld.exe"; //define the arguments to pass to the linker string args = "-m elf_i386 -o \"" + outputFile + "\" "; //-m elf_i386 for (int c = 0; c < files.Length; c++) { args += "\"" + files[c] + "\" "; } //invoke the linker outputEntry[] e = errors; outputEntry[] w = warnings; Helpers.SpawnProcess( linker, null, args, true, delegate(string line) { stdOut(line); gnuStdOutHandler(ref e, ref w, "/linker/ld", line); }); //clean up errors = e; warnings = w; }
private void link(string[] files, string outputFile, StandardCompileOutput<Project> output, StandardOutputCallback stdOut) { //perform the link outputEntry[] errors = new outputEntry[0]; outputEntry[] warnings = new outputEntry[0]; link(ref errors, ref warnings, files, outputFile, stdOut); //add the errors and warnings to the output object for (int c = 0; c < errors.Length; c++) { output.addError(null, 0, 0, errors[c].message); } for (int c = 0; c < warnings.Length; c++) { output.addWarning(null, 0, 0, warnings[c].message); } }
private void generateISO(string volumeTitle, string bootsector, string diskContents, string output, StandardOutputCallback stdOut, string[] hideFiles) { if (!Directory.Exists(diskContents)) { Directory.CreateDirectory(diskContents); } //define the path for the mkisofs (make iso filesystem) exe string mkisofs = new FileInfo("compilers/mkisofs/mkisofs.exe").FullName; //define the arguments to pass to the exe string[] args = new string[] { "-iso-level 3", "-v -allow-lowercase", "-volid \"" + volumeTitle + "\"", "-o \"" + output + "\"", }; if (bootsector != null) { if (!File.Exists(bootsector)) { return; } File.Copy(bootsector, diskContents + "\\bootsect.bin", true); int sectorCount = (int)Math.Ceiling(new FileInfo(bootsector).Length * 1.0f / 512); Helpers.AddObject(ref args, "-b bootsect.bin"); Helpers.AddObject(ref args, "-no-emul-boot -boot-load-size " + sectorCount); Helpers.AddObject(ref hideFiles, "bootsect.bin"); } //write the arguments for the hidden files string hideArgsBuffer = "-hide "; for (int c = 0; c < hideFiles.Length; c++) { hideArgsBuffer += "" + hideFiles[c] + " "; } Helpers.AddObject(ref args, hideArgsBuffer); //add disk contents folder Helpers.AddObject(ref args, "\"" + diskContents + "\""); //invoke the exe Helpers.SpawnProcess( mkisofs, new FileInfo(mkisofs).Directory.FullName, Helpers.Flatten(args, " "), true, stdOut); //clean up if (bootsector != null) { File.Delete(diskContents + "\\bootsect.bin"); } }
private void compileC(ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut) { //get the filename for the GCC compiler string gcc = new FileInfo("compilers/gcc/bin/gcc.exe").FullName; //invoke the GCC compiler outputEntry[] e = errors; outputEntry[] w = warnings; Helpers.SpawnProcess( gcc, null, "-c \"" + filename + "\" -o \"" + outputFile + "\" " + "-Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m32", true, delegate(string line) { stdOut(line); gnuStdOutHandler(ref e, ref w, filename, line); }); //clean up errors = e; warnings = w; }
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, ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut) { //define the filename for the NASM compiler string nasmCompiler = new FileInfo("compilers/nasm/nasm.exe").FullName; //call nasm to compile the ASM code. outputEntry[] e = errors; outputEntry[] w = warnings; Helpers.SpawnProcess( nasmCompiler, new FileInfo(filename).Directory.FullName, (linkable ? "-f elf32 " : "") + "\"" + filename + "\" " + "-o \"" + outputFile + "\"", true, delegate(string line) { stdOut(line); gnuStdOutHandler( ref e, ref w, filename, line); }); //clean up errors = e; warnings = w; }
private void link(ref outputEntry[] errors, ref outputEntry[] warnings, string[] files, string outputFile, StandardOutputCallback stdOut) { //define the filename for the linker string linker = new FileInfo("compilers/linker/ld.exe").FullName; //linker = "C:\\cygwin\\bin\\ld.exe"; //define the arguments to pass to the linker string args = "-m elf_i386 -o \"" + outputFile + "\" "; //-m elf_i386 for (int c = 0; c < files.Length; c++) { args += "\"" + files[c] + "\" "; } //invoke the linker outputEntry[] e = errors; outputEntry[] w = warnings; Helpers.SpawnProcess( linker, null, args, true, delegate(string line) { stdOut(line); gnuStdOutHandler(ref e, ref w, "/linker/ld", line); }); //clean up errors = e; warnings = w; }
public void Start(int memory, StandardOutputCallback standardOutput) { //already running? if (Running) { return; } #region Invoke Qemu string qemuArguments = "-qmp tcp:127.0.0.1:4444,server,nowait " + "-cdrom \"" + new FileInfo(p_DiskImage).FullName + "\" " + "-m " + memory; //create a processlink process so that if this process is killed //it automatically kills the emulator as well. standardOutput("Launching process linker..."); if (!File.Exists("processlink.exe")) { standardOutput(" Error! ProcessLink.exe is not found!"); return; } p_Process = new Process() { StartInfo = new ProcessStartInfo { FileName = "processLink.exe", Arguments = "-id " + Process.GetCurrentProcess().Id + " " + "-f \"" + new FileInfo("emulators/qemu/qemu.exe").FullName + "\" " + "-a " + qemuArguments, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true } }; //get the qemu process id from the spawn process int qemuPID = -1; p_Process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (e.Data == null || qemuPID != -1) { return; } qemuPID = Convert.ToInt32(e.Data); }; //launch the process standardOutput("Starting Qemu..."); p_Process.Start(); standardOutput(" Process linker PID=" + p_Process.Id); p_Process.BeginOutputReadLine(); //wait until the spawner has launched Qemu while (qemuPID == -1) { ; } p_QemuProcess = Process.GetProcessById(qemuPID); standardOutput(" Started, PID=" + qemuPID); #endregion //connect to the Qemu Monitor p_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); int connectStart = Environment.TickCount; standardOutput("Connecting to Qemu's QMP service..."); while (Environment.TickCount < connectStart + 1000) { try { p_Socket.Connect("localhost", 4444); p_Stream = new NetworkStream(p_Socket, true); break; } catch { } } //timed out? if (!p_Socket.Connected) { standardOutput("Error! Unable to connect to Qemu's QMP service"); Stop(); return; } //get the initial response from the server standardOutput("Performing handshake with QMP Server"); JSONObject handshake = JSONObject.Decode("", monitorRead())[0]; handshake = (JSONObject)handshake["QMP"]; //get the version of the qemu emulator JSONObject version = (JSONObject)handshake["version"]; version = (JSONObject)version["qemu"]; int versionMajor = Convert.ToInt32(version["major"]); int versionMinor = Convert.ToInt32(version["minor"]); //enter command mode monitorWrite("{ \"execute\": \"qmp_capabilities\" }"); JSONObject result = JSONObject.Decode(monitorRead())[0]; result = (JSONObject)result["return"]; if (result.ChildValues[0].ChildCount > 0) { standardOutput("Unable to enter into QMP Command mode!"); Stop(); return; } //create an event listener standardOutput("Starting event listener..."); Thread eventListener = new Thread(new ThreadStart(delegate { while (Running) { //send a blank signal to the server so we don't interfere //with current messages. Monitor.Enter(p_SyncLock); monitorExecute("", null); monitorReadObject(false); Monitor.Exit(p_SyncLock); Thread.Sleep(100); } })); eventListener.Start(); standardOutput(" Listening..."); //success standardOutput("Qemu Emulator version " + versionMajor + "." + versionMinor); standardOutput("Qemu Emulator ready..."); return; EmulationProcessor ps = GetProcessors()[0]; while (true) { int time = Environment.TickCount; GetRegisters(ps); Console.WriteLine((Environment.TickCount - time) + "ms"); } new DebugRegisters(this).Show(); }
private void generateISO(string volumeTitle, string bootsector, string diskContents, string output, StandardOutputCallback stdOut, string[] hideFiles) { if (!Directory.Exists(diskContents)) { Directory.CreateDirectory(diskContents); } //define the path for the mkisofs (make iso filesystem) exe string mkisofs = new FileInfo("compilers/mkisofs/mkisofs.exe").FullName; //define the arguments to pass to the exe string[] args = new string[] { "-iso-level 3", "-v -allow-lowercase", "-volid \"" + volumeTitle + "\"", "-o \"" + output + "\"", }; if (bootsector != null) { if (!File.Exists(bootsector)) { return; } File.Copy(bootsector, diskContents + "\\bootsect.bin", true); int sectorCount = (int)Math.Ceiling(new FileInfo(bootsector).Length * 1.0f / 512); Helpers.AddObject(ref args, "-b bootsect.bin"); Helpers.AddObject(ref args, "-no-emul-boot -boot-load-size " + sectorCount); Helpers.AddObject(ref hideFiles, "bootsect.bin"); } //write the arguments for the hidden files string hideArgsBuffer = "-hide "; for (int c = 0; c < hideFiles.Length; c++) { hideArgsBuffer += "" + hideFiles[c] + " "; } Helpers.AddObject(ref args, hideArgsBuffer); //add disk contents folder Helpers.AddObject(ref args, "\"" + diskContents + "\""); //invoke the exe Helpers.SpawnProcess( mkisofs, new FileInfo(mkisofs).Directory.FullName, Helpers.Flatten(args, " "), true, stdOut); //clean up if (bootsector != null) { File.Delete(diskContents + "\\bootsect.bin"); } }
private void compileC(ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut) { //get the filename for the GCC compiler string gcc = new FileInfo("compilers/gcc/bin/gcc.exe").FullName; //invoke the GCC compiler outputEntry[] e = errors; outputEntry[] w = warnings; Helpers.SpawnProcess( gcc, null, "-c \"" + filename + "\" -o \"" + outputFile + "\" " + "-Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m32", true, delegate(string line) { stdOut(line); gnuStdOutHandler(ref e, ref w, filename, line); }); //clean up errors = e; warnings = w; }
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, ref outputEntry[] errors, ref outputEntry[] warnings, string filename, string outputFile, StandardOutputCallback stdOut) { //define the filename for the NASM compiler string nasmCompiler = new FileInfo("compilers/nasm/nasm.exe").FullName; //call nasm to compile the ASM code. outputEntry[] e = errors; outputEntry[] w = warnings; Helpers.SpawnProcess( nasmCompiler, new FileInfo(filename).Directory.FullName, (linkable ? "-f elf32 " : "") + "\"" + filename + "\" " + "-o \"" + outputFile + "\"", true, delegate(string line) { stdOut(line); gnuStdOutHandler( ref e, ref w, filename, line); }); //clean up errors = e; warnings = w; }
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); }
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 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 void link(string[] files, string outputFile, StandardCompileOutput <Project> output, StandardOutputCallback stdOut) { //perform the link outputEntry[] errors = new outputEntry[0]; outputEntry[] warnings = new outputEntry[0]; link(ref errors, ref warnings, files, outputFile, stdOut); //add the errors and warnings to the output object for (int c = 0; c < errors.Length; c++) { output.addError(null, 0, 0, errors[c].message); } for (int c = 0; c < warnings.Length; c++) { output.addWarning(null, 0, 0, warnings[c].message); } }
public void Start(int memory, StandardOutputCallback standardOutput) { //already running? if (Running) { return; } #region Invoke Qemu string qemuArguments = "-qmp tcp:127.0.0.1:4444,server,nowait " + "-cdrom \"" + new FileInfo(p_DiskImage).FullName + "\" " + "-m " + memory; //create a processlink process so that if this process is killed //it automatically kills the emulator as well. standardOutput("Launching process linker..."); if (!File.Exists("processlink.exe")) { standardOutput(" Error! ProcessLink.exe is not found!"); return; } p_Process = new Process() { StartInfo = new ProcessStartInfo { FileName = "processLink.exe", Arguments = "-id " + Process.GetCurrentProcess().Id + " " + "-f \"" + new FileInfo("emulators/qemu/qemu.exe").FullName + "\" " + "-a " + qemuArguments, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true } }; //get the qemu process id from the spawn process int qemuPID = -1; p_Process.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { if (e.Data == null || qemuPID != -1) { return; } qemuPID = Convert.ToInt32(e.Data); }; //launch the process standardOutput("Starting Qemu..."); p_Process.Start(); standardOutput(" Process linker PID=" + p_Process.Id); p_Process.BeginOutputReadLine(); //wait until the spawner has launched Qemu while (qemuPID == -1) ; p_QemuProcess = Process.GetProcessById(qemuPID); standardOutput(" Started, PID=" + qemuPID); #endregion //connect to the Qemu Monitor p_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); int connectStart = Environment.TickCount; standardOutput("Connecting to Qemu's QMP service..."); while (Environment.TickCount < connectStart + 1000) { try { p_Socket.Connect("localhost", 4444); p_Stream = new NetworkStream(p_Socket, true); break; } catch { } } //timed out? if (!p_Socket.Connected) { standardOutput("Error! Unable to connect to Qemu's QMP service"); Stop(); return; } //get the initial response from the server standardOutput("Performing handshake with QMP Server"); JSONObject handshake = JSONObject.Decode("", monitorRead())[0]; handshake = (JSONObject)handshake["QMP"]; //get the version of the qemu emulator JSONObject version = (JSONObject)handshake["version"]; version = (JSONObject)version["qemu"]; int versionMajor = Convert.ToInt32(version["major"]); int versionMinor = Convert.ToInt32(version["minor"]); //enter command mode monitorWrite("{ \"execute\": \"qmp_capabilities\" }"); JSONObject result = JSONObject.Decode(monitorRead())[0]; result = (JSONObject)result["return"]; if (result.ChildValues[0].ChildCount > 0) { standardOutput("Unable to enter into QMP Command mode!"); Stop(); return; } //create an event listener standardOutput("Starting event listener..."); Thread eventListener = new Thread(new ThreadStart(delegate { while (Running) { //send a blank signal to the server so we don't interfere //with current messages. Monitor.Enter(p_SyncLock); monitorExecute("", null); monitorReadObject(false); Monitor.Exit(p_SyncLock); Thread.Sleep(100); } })); eventListener.Start(); standardOutput(" Listening..."); //success standardOutput("Qemu Emulator version " + versionMajor + "." + versionMinor); standardOutput("Qemu Emulator ready..."); return; EmulationProcessor ps = GetProcessors()[0]; while (true) { int time = Environment.TickCount; GetRegisters(ps); Console.WriteLine((Environment.TickCount - time) + "ms"); } new DebugRegisters(this).Show(); }
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); }