about summary refs log tree commit diff
path: root/boot/catboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/catboot.c')
-rw-r--r--boot/catboot.c89
1 files changed, 41 insertions, 48 deletions
diff --git a/boot/catboot.c b/boot/catboot.c
index 40756ac..db100dd 100644
--- a/boot/catboot.c
+++ b/boot/catboot.c
@@ -20,12 +20,6 @@
 
 #define _POSIX_C_SOURCE 200809L
 
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
 #include "catboot.h"
 
 #define VERSION "0.0.0"
@@ -206,11 +200,33 @@ test_transpile_command(struct Command_Arguments* arguments)
     return COMMAND_OK;
 }
 
+struct String
+output_name_from_input_name(struct String input)
+{
+    uint end = string_length(input);
+    for (uint start = string_length(input) - 1; start > 0; --start) {
+        switch (string_at(input, start)) {
+        // we captured the file extension, we need to keep going until we find a slash,
+        // but we move the end index to the current index first to exclude the extension.
+        case '.':
+            end = start;
+            break;
+        // we found a slash, so we captured the first part of the filename,
+        // we can stop here.
+        case '/':
+            return string_slice(input, start + 1, end); // exclude the slash itself
+        // otherwise, keep going.
+        default:
+            break;
+        }
+    }
+
+    return string_slice(input, 0, end);
+}
+
 enum Command_Result
 default_command(struct Command_Arguments* arguments)
 {
-    enum Command_Result result = COMMAND_OK;
-
     struct String source = read_file(arguments->input);
     struct Source_File source_file = {
         .source = source,
@@ -226,61 +242,38 @@ default_command(struct Command_Arguments* arguments)
     struct Tree tree;
     if (parser_do_your_thing(&parser, &tree) != 0) {
         log_error("parser finished with errors\n");
-
-        result = COMMAND_FAIL;
-        goto end;
+        return COMMAND_FAIL;
     }
 
-    ascii build_directory_template[] = "/tmp/catboot-build-XXXXXX"; // TODO: /tmp/catboot/build-XXXXXX
-
-    ascii* build_directory_path = mkdtemp(build_directory_template);
-    struct String build_path = string_from_c_string(build_directory_path);
-    struct String source_path = string_append_c_str(build_path, "/input.c");
-
-    FILE* output_file = fopen(string_c_str(source_path), "w");
-    if (!output_file) {
-        log_error("could not open temporary output file: %s\n", string_c_str(source_path));
-
-        result = COMMAND_FAIL;
-        goto end;
-    }
-
-    struct Transpile_Output output = transpile_output_from_file(output_file);
-
     struct Transpiler transpiler;
-    transpiler_new(&transpiler, output);
+    transpiler_new(&transpiler, transpile_output_from_string());
 
     if (transpiler_catskill_to_c(&transpiler, &tree) != 0) {
         log_error("transpiler finished with errors\n");
-        fclose(output_file);
+        return COMMAND_FAIL;
+    }
+    struct String transpiled_source = transpile_output_string(&transpiler.output);
 
-        result = COMMAND_FAIL;
-        goto end;
+    struct String output_file;
+    if (arguments->output) {
+        output_file = string_from_c_string(arguments->output);
+    } else {
+        output_file = output_name_from_input_name(source_file.path);
     }
-    fclose(output_file);
 
-    struct Build_Result build_result = build_executable(build_path);
+    struct Build_Result build_result = build_executable(transpiled_source, output_file);
     if (!build_result.success) {
         log_error("backend failure with exit code %ld\n", build_result.compiler_exit_code);
-        log_error("compiler output:\n%.*s\n", (int)build_result.compiler_log.length, build_result.compiler_log.data);
+        log_error(
+            "compiler output:\n%.*s\n", (int)build_result.compiler_log.length,
+            build_result.compiler_log.data);
 
-        result = COMMAND_FAIL;
-        goto end;
+        return COMMAND_FAIL;
     }
 
-    // copy the output executable to the desired location
-    const ascii* output_filename = arguments->output ? arguments->output : "a.out";
+    log_debug("success! executable written to '%s'.\n", string_c_str(build_result.output_path));
 
-    // simple copy command for now
-    ascii copy_command[2048];
-    snprintf(copy_command, sizeof(copy_command), "cp %s %s", string_c_str(build_result.output_path), output_filename);
-    if (system(copy_command) != 0) {
-        log_error("failed to copy executable to %s\n", output_filename);
-        result = COMMAND_FAIL;
-    }
-
-end:
-    return result;
+    return COMMAND_OK;
 }
 
 typedef enum Command_Result (*Command_Function)(struct Command_Arguments*);