From 5da6b74567793e15cf651be50edbfe407f42a714 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 16 Aug 2016 12:33:11 +0100 Subject: [PATCH] Compile with odin.exe and no run.bat This is win32 only and requires CreateProcessA --- build.bat | 2 +- examples/main.ll | 254 +++++++++++++++++++++++++++++++++++-- examples/main.odin | 2 - run.bat | 14 -- src/codegen/print_llvm.cpp | 2 +- src/codegen/ssa.cpp | 10 +- src/common.cpp | 2 +- src/gb/gb.h | 3 - src/main.cpp | 88 +++++++++---- 9 files changed, 320 insertions(+), 57 deletions(-) diff --git a/build.bat b/build.bat index 9365254fa..87fe6c857 100644 --- a/build.bat +++ b/build.bat @@ -45,7 +45,7 @@ pushd %build_dir% cl %compiler_settings% "..\src\main.cpp" ^ /link %linker_settings% -OUT:%exe_name% ^ - && call ..\run.bat + && call odin run ..\examples/main.odin :do_not_compile_exe diff --git a/examples/main.ll b/examples/main.ll index 450f898d8..a1922d604 100644 --- a/examples/main.ll +++ b/examples/main.ll @@ -100,7 +100,242 @@ if.done.-.2: define void @main() { entry.-.0: call void @__$startup_runtime() + %0 = alloca %WNDCLASSEXA, align 8 ; wc + store %WNDCLASSEXA zeroinitializer, %WNDCLASSEXA* %0 + %1 = alloca %HINSTANCE, align 8 ; instance + store %HINSTANCE zeroinitializer, %HINSTANCE* %1 + %2 = call %HINSTANCE @GetModuleHandleA(i8* null) + store %HINSTANCE %2, %HINSTANCE* %1 + %3 = getelementptr inbounds i64, i64* @win32_perf_count_freq + %4 = call i32 @QueryPerformanceFrequency(i64* %3) + %5 = alloca i8*, align 8 ; class_name + store i8* zeroinitializer, i8** %5 + %6 = getelementptr inbounds [18 x i8], [18 x i8]* @.str2, i64 0, i64 0 + %7 = alloca %.string, align 8 + store %.string zeroinitializer, %.string* %7 + %8 = getelementptr inbounds %.string, %.string* %7, i64 0, i32 0 + %9 = getelementptr inbounds %.string, %.string* %7, i64 0, i32 1 + store i8* %6, i8** %8 + store i64 18, i64* %9 + %10 = load %.string, %.string* %7, align 8 + %11 = call i8* @main$to_c_string-0(%.string %10) + store i8* %11, i8** %5 + %12 = alloca i8*, align 8 ; title + store i8* zeroinitializer, i8** %12 + %13 = getelementptr inbounds [18 x i8], [18 x i8]* @.str3, i64 0, i64 0 + %14 = alloca %.string, align 8 + store %.string zeroinitializer, %.string* %14 + %15 = getelementptr inbounds %.string, %.string* %14, i64 0, i32 0 + %16 = getelementptr inbounds %.string, %.string* %14, i64 0, i32 1 + store i8* %13, i8** %15 + store i64 18, i64* %16 + %17 = load %.string, %.string* %14, align 8 + %18 = call i8* @main$to_c_string-0(%.string %17) + store i8* %18, i8** %12 + %19 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %0, i64 0, i32 0 + store i32 80, i32* %19 + %20 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %0, i64 0, i32 1 + store i32 3, i32* %20 + %21 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %0, i64 0, i32 5 + %22 = load %HINSTANCE, %HINSTANCE* %1, align 8 + store %HINSTANCE %22, %HINSTANCE* %21 + %23 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %0, i64 0, i32 10 + %24 = load i8*, i8** %5, align 8 + store i8* %24, i8** %23 + %25 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %0, i64 0, i32 8 + %26 = inttoptr i64 1 to %.rawptr + store %HBRUSH %26, %HBRUSH* %25 + %27 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %0, i64 0, i32 2 + store %WNDPROC @main$1, %WNDPROC* %27 + %28 = getelementptr inbounds %WNDCLASSEXA, %WNDCLASSEXA* %0 + %29 = call %ATOM @RegisterClassExA(%WNDCLASSEXA* %28) + %30 = icmp eq i16 %29, 0 + br i1 %30, label %if.then.-.1, label %if.done.-.2 + +if.then.-.1: ret void + +if.done.-.2: + %31 = alloca %HWND, align 8 ; hwnd + store %HWND zeroinitializer, %HWND* %31 + %32 = load i8*, i8** %5, align 8 + %33 = load i8*, i8** %12, align 8 + %34 = load %HINSTANCE, %HINSTANCE* %1, align 8 + %35 = call %HWND @CreateWindowExA(i32 0, i8* %32, i8* %33, i32 281673728, i32 0, i32 0, i32 854, i32 480, %HWND null, %HMENU null, %HINSTANCE %34, %.rawptr null) + store %HWND %35, %HWND* %31 + %36 = load %HWND, %HWND* %31, align 8 + %37 = icmp eq %.rawptr %36, null + br i1 %37, label %if.then.-.3, label %if.done.-.4 + +if.then.-.3: + call void @win32_print_last_error() + ret void + +if.done.-.4: + %38 = alloca double, align 8 ; start_time + store double zeroinitializer, double* %38 + %39 = call double @time_now() + store double %39, double* %38 + %40 = alloca i1, align 1 ; running + store i1 zeroinitializer, i1* %40 + store i1 true, i1* %40 + %41 = alloca i64, align 8 ; tick_count + store i64 zeroinitializer, i64* %41 + store i64 0, i64* %41 + br label %for.loop.-.6 + +for.body.-.5: + %42 = alloca double, align 8 ; curr_time + store double zeroinitializer, double* %42 + %43 = call double @time_now() + store double %43, double* %42 + %44 = alloca double, align 8 ; dt + store double zeroinitializer, double* %44 + %45 = load double, double* %38, align 8 + %46 = load double, double* %42, align 8 + %47 = fsub double %46, %45 + store double %47, double* %44 + %48 = load double, double* %44, align 8 + %49 = fcmp ogt double %48, 0x4000000000000000 + br i1 %49, label %if.then.-.7, label %if.done.-.8 + +for.loop.-.6: + %50 = load i1, i1* %40, align 1 + br i1 %50, label %for.body.-.5, label %for.done.-.16 + +if.then.-.7: + store i1 false, i1* %40 + br label %if.done.-.8 + +if.done.-.8: + %51 = alloca %MSG, align 8 ; msg + store %MSG zeroinitializer, %MSG* %51 + br label %for.body.-.9 + +for.body.-.9: + %52 = alloca i1, align 1 ; ok + store i1 zeroinitializer, i1* %52 + %53 = getelementptr inbounds %MSG, %MSG* %51 + %54 = call %BOOL @PeekMessageA(%MSG* %53, %HWND null, i32 0, i32 0, i32 1) + %55 = icmp ne i32 %54, 0 + store i1 %55, i1* %52 + %56 = load i1, i1* %52, align 1 + br i1 %56, label %if.done.-.11, label %if.then.-.10 + +if.then.-.10: + br label %for.done.-.15 + +if.done.-.11: + %57 = getelementptr inbounds %MSG, %MSG* %51, i64 0, i32 1 + %58 = load i32, i32* %57, align 4 + %59 = icmp eq i32 %58, 18 + br i1 %59, label %if.then.-.12, label %if.else.-.13 + +if.then.-.12: + ret void + +if.else.-.13: + %60 = getelementptr inbounds %MSG, %MSG* %51 + %61 = call %BOOL @TranslateMessage(%MSG* %60) + %62 = getelementptr inbounds %MSG, %MSG* %51 + %63 = call %LRESULT @DispatchMessageA(%MSG* %62) + br label %if.done.-.14 + +if.done.-.14: + br label %for.body.-.9 + +for.done.-.15: + %64 = getelementptr inbounds [6 x i8], [6 x i8]* @.str4, i64 0, i64 0 + %65 = alloca %.string, align 8 + store %.string zeroinitializer, %.string* %65 + %66 = getelementptr inbounds %.string, %.string* %65, i64 0, i32 0 + %67 = getelementptr inbounds %.string, %.string* %65, i64 0, i32 1 + store i8* %64, i8** %66 + store i64 6, i64* %67 + %68 = load %.string, %.string* %65, align 8 + call void @print_string(%.string %68) + %69 = load i64, i64* %41, align 8 + call void @print_int(i64 %69) + %70 = load i64, i64* %41, align 8 + %71 = add i64 %70, 1 + store i64 %71, i64* %41 + call void @print_rune(i32 10) + call void @sleep_ms(i32 16) + br label %for.loop.-.6 + +for.done.-.16: + ret void +} + +define i8* @main$to_c_string-0(%.string %s) { +entry.-.0: + %0 = alloca %.string, align 8 ; s + store %.string zeroinitializer, %.string* %0 + store %.string %s, %.string* %0 + %1 = alloca i8*, align 8 ; c_str + store i8* zeroinitializer, i8** %1 + %2 = getelementptr inbounds %.string, %.string* %0, i64 0, i32 1 + %3 = load i64, i64* %2, align 8 + %4 = add i64 %3, 1 + %5 = call %.rawptr @malloc(i64 %4) + %6 = bitcast %.rawptr %5 to i8* + store i8* %6, i8** %1 + %7 = load i8*, i8** %1, align 8 + %8 = getelementptr inbounds %.string, %.string* %0, i64 0, i32 0 + %9 = load i8*, i8** %8, align 8 + %10 = getelementptr i8, i8* %9, i64 0 + %11 = getelementptr inbounds i8, i8* %10 + %12 = getelementptr inbounds %.string, %.string* %0, i64 0, i32 1 + %13 = load i64, i64* %12, align 8 + %14 = call i32 @memcpy(%.rawptr %7, %.rawptr %11, i64 %13) + %15 = load i8*, i8** %1, align 8 + %16 = getelementptr inbounds %.string, %.string* %0, i64 0, i32 1 + %17 = load i64, i64* %16, align 8 + %18 = getelementptr i8, i8* %15, i64 %17 + store i8 0, i8* %18 + %19 = load i8*, i8** %1, align 8 + ret i8* %19 +} + +define %LRESULT @main$1(%HWND %hwnd, i32 %msg, %WPARAM %wparam, %LPARAM %lparam) noinline { +entry.-.0: + %0 = alloca %HWND, align 8 ; hwnd + store %HWND zeroinitializer, %HWND* %0 + store %HWND %hwnd, %HWND* %0 + %1 = alloca i32, align 4 ; msg + store i32 zeroinitializer, i32* %1 + store i32 %msg, i32* %1 + %2 = alloca %WPARAM, align 8 ; wparam + store %WPARAM zeroinitializer, %WPARAM* %2 + store %WPARAM %wparam, %WPARAM* %2 + %3 = alloca %LPARAM, align 8 ; lparam + store %LPARAM zeroinitializer, %LPARAM* %3 + store %LPARAM %lparam, %LPARAM* %3 + %4 = load i32, i32* %1, align 4 + %5 = icmp eq i32 %4, 2 + br i1 %5, label %if.then.-.1, label %cmp-or.-.3 + +if.then.-.1: + call void @ExitProcess(i32 0) + ret %LRESULT 0 + +cmp-or.-.2: + %6 = load i32, i32* %1, align 4 + %7 = icmp eq i32 %6, 18 + br i1 %7, label %if.then.-.1, label %if.done.-.4 + +cmp-or.-.3: + %8 = load i32, i32* %1, align 4 + %9 = icmp eq i32 %8, 16 + br i1 %9, label %if.then.-.1, label %cmp-or.-.2 + +if.done.-.4: + %10 = load %HWND, %HWND* %0, align 8 + %11 = load i32, i32* %1, align 4 + %12 = load %WPARAM, %WPARAM* %2, align 8 + %13 = load %LPARAM, %LPARAM* %3, align 8 + %14 = call %LRESULT @DefWindowProcA(%HWND %10, i32 %11, %WPARAM %12, %LPARAM %13) + ret i64 %14 } define void @print_string(%.string %s) { @@ -477,7 +712,7 @@ for.body.-.5: %16 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 %17 = load i64, i64* %3, align 8 %18 = getelementptr i8, i8* %16, i64 %17 - %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str2, i64 0, i64 0 + %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str5, i64 0, i64 0 %20 = load i64, i64* %1, align 8 %21 = load i64, i64* %0, align 8 %22 = srem i64 %21, %20 @@ -619,7 +854,7 @@ for.body.-.5: %16 = getelementptr inbounds [65 x i8], [65 x i8]* %2, i64 0, i64 0 %17 = load i64, i64* %3, align 8 %18 = getelementptr i8, i8* %16, i64 %17 - %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str3, i64 0, i64 0 + %19 = getelementptr inbounds [64 x i8], [64 x i8]* @.str6, i64 0, i64 0 %20 = load i64, i64* %1, align 8 %21 = load i64, i64* %0, align 8 %22 = urem i64 %21, %20 @@ -711,7 +946,7 @@ entry.-.0: br i1 %1, label %if.then.-.1, label %if.else.-.2 if.then.-.1: - %2 = getelementptr inbounds [4 x i8], [4 x i8]* @.str4, i64 0, i64 0 + %2 = getelementptr inbounds [4 x i8], [4 x i8]* @.str7, i64 0, i64 0 %3 = alloca %.string, align 8 store %.string zeroinitializer, %.string* %3 %4 = getelementptr inbounds %.string, %.string* %3, i64 0, i32 0 @@ -723,7 +958,7 @@ if.then.-.1: br label %if.done.-.3 if.else.-.2: - %7 = getelementptr inbounds [5 x i8], [5 x i8]* @.str5, i64 0, i64 0 + %7 = getelementptr inbounds [5 x i8], [5 x i8]* @.str8, i64 0, i64 0 %8 = alloca %.string, align 8 store %.string zeroinitializer, %.string* %8 %9 = getelementptr inbounds %.string, %.string* %8, i64 0, i32 0 @@ -1016,10 +1251,13 @@ entry.-.0: @.str0 = global [14 x i8] c"GetLastError\3A\20" @.str1 = global [1 x i8] c"\0A" -@.str2 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" -@.str3 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" -@.str4 = global [4 x i8] c"true" -@.str5 = global [5 x i8] c"false" +@.str2 = global [18 x i8] c"Odin-Language-Demo" +@.str3 = global [18 x i8] c"Odin\20Language\20Demo" +@.str4 = global [6 x i8] c"Tick\3A\20" +@.str5 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" +@.str6 = global [64 x i8] c"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\40$" +@.str7 = global [4 x i8] c"true" +@.str8 = global [5 x i8] c"false" define void @__$startup_runtime() { entry.-.0: %0 = call i64 @win32_get_perf_count_freq() diff --git a/examples/main.odin b/examples/main.odin index 3f9cdfa40..e9562d48c 100644 --- a/examples/main.odin +++ b/examples/main.odin @@ -33,7 +33,6 @@ win32_print_last_error :: proc() { } main :: proc() { -/* wc: WNDCLASSEXA; instance := GetModuleHandleA(null); @@ -114,5 +113,4 @@ main :: proc() { sleep_ms(16); } -*/ } diff --git a/run.bat b/run.bat index 62818dc8c..b3fb31397 100644 --- a/run.bat +++ b/run.bat @@ -2,17 +2,3 @@ rem call clang -c -emit-llvm -DGB_IMPLEMENTATION -DGB_DEF=GB_DLL_EXPORT ..\src\gb\gb.h - -pushd ..\examples -call ..\bin\odin.exe ..\examples/main.odin ^ - && opt -mem2reg main.ll -o main.bc ^ - && clang main.bc -o main.exe ^ - -Wno-override-module -lkernel32.lib -luser32.lib ^ - && main.exe -popd - - rem && llvm-dis ..\examples/main.bc -o - ^ -rem call ..\misc\llvm-bin\opt.exe -mem2reg ..\examples/output.ll > ..\examples/main.bc -rem call llc ..\examples/main.bc -rem call llvm-dis ..\examples/main.bc -o ..\examples/output.ll -rem call clang ..\examples/main.c -O0 -S -emit-llvm -o ..\examples/main-c.ll diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 0f145d408..80bc320cb 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -561,7 +561,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_fprintf(f, "\n"); } break; - case ssaInstr_CopyMemory: { + case ssaInstr_MemCopy: { ssa_fprintf(f, "call void @llvm.memmove.p0i8.p0i8."); ssa_print_type(f, m->sizes, t_int); ssa_fprintf(f, "(i8* "); diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 7a0c587c5..f9393dcff 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -70,7 +70,7 @@ struct ssaProcedure { SSA_INSTR_KIND(Unreachable), \ SSA_INSTR_KIND(BinaryOp), \ SSA_INSTR_KIND(Call), \ - SSA_INSTR_KIND(CopyMemory), \ + SSA_INSTR_KIND(MemCopy), \ SSA_INSTR_KIND(ExtractElement), \ SSA_INSTR_KIND(InsertElement), \ SSA_INSTR_KIND(ShuffleVector), \ @@ -330,8 +330,8 @@ Type *ssa_instr_type(ssaInstr *instr) { return pt; } return NULL; - } - case ssaInstr_CopyMemory: + } break; + case ssaInstr_MemCopy: return t_int; case ssaInstr_ExtractElement: { @@ -592,7 +592,7 @@ ssaValue *ssa_make_instr_call(ssaProcedure *p, ssaValue *value, ssaValue **args, } ssaValue *ssa_make_instr_copy_memory(ssaProcedure *p, ssaValue *dst, ssaValue *src, ssaValue *len, i32 align, b32 is_volatile) { - ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_CopyMemory); + ssaValue *v = ssa_alloc_instr(p->module->allocator, ssaInstr_MemCopy); v->instr.copy_memory.dst = dst; v->instr.copy_memory.src = src; v->instr.copy_memory.len = len; @@ -893,7 +893,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) { case ssaInstr_Br: case ssaInstr_Ret: case ssaInstr_Unreachable: - case ssaInstr_CopyMemory: + case ssaInstr_MemCopy: case ssaInstr_StartupRuntime: continue; case ssaInstr_Call: diff --git a/src/common.cpp b/src/common.cpp index 7d88e3d8b..8e23090e5 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1,4 +1,4 @@ -#define GB_NO_WINDOWS_H +// #define GB_NO_WINDOWS_H #define GB_IMPLEMENTATION #include "gb/gb.h" diff --git a/src/gb/gb.h b/src/gb/gb.h index b7c5a9b9c..7a4824fbc 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -2964,8 +2964,6 @@ extern "C" { DWORD dwFlags; } MONITORINFO; - - #define INFINITE 0xffffffffl #define INVALID_HANDLE_VALUE ((void *)(intptr)(-1)) @@ -2985,7 +2983,6 @@ extern "C" { GB_DLL_IMPORT void WINAPI RaiseException (DWORD, DWORD, DWORD, ULONG_PTR const *); - GB_DLL_IMPORT BOOL WINAPI GetLogicalProcessorInformation(SYSTEM_LOGICAL_PROCESSOR_INFORMATION *buffer, DWORD *return_length); GB_DLL_IMPORT DWORD_PTR WINAPI SetThreadAffinityMask(HANDLE thread, DWORD_PTR check_mask); GB_DLL_IMPORT HANDLE WINAPI GetCurrentThread(void); diff --git a/src/main.cpp b/src/main.cpp index 9b5b99aaa..f4240dec1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,46 +6,90 @@ #include "checker/checker.cpp" #include "codegen/codegen.cpp" +void win32_exec_command_line_app(char *fmt, ...) { + STARTUPINFOA start_info = {gb_size_of(STARTUPINFOA)}; + PROCESS_INFORMATION pi = {}; + start_info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + start_info.wShowWindow = SW_SHOW; + start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + start_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); + + char cmd_line[2048] = {}; + va_list va; + va_start(va, fmt); + gb_snprintf_va(cmd_line, gb_size_of(cmd_line), fmt, va); + va_end(va); + + if (CreateProcessA(NULL, cmd_line, + NULL, NULL, true, 0, NULL, NULL, + &start_info, &pi)) { + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } else { + // NOTE(bill): failed to create process + } + +} + int main(int argc, char **argv) { if (argc < 2) { gb_printf_err("Please specify a .odin file\n"); return 1; } - int success = 1; - init_universal_scope(); - for (int arg_index = 1; arg_index < argc; arg_index++) { - char *arg = argv[arg_index]; - char *init_filename = arg; - Parser parser = {0}; + char *init_filename = argv[1]; + b32 run_output = false; + if (gb_strncmp(argv[1], "run", 3) == 0) { + run_output = true; + init_filename = argv[2]; + } + Parser parser = {0}; - if (init_parser(&parser)) { - defer (destroy_parser(&parser)); - if (parse_files(&parser, init_filename) == ParseFile_None) { - // print_ast(parser.files[0].declarations, 0); + if (init_parser(&parser)) { + defer (destroy_parser(&parser)); - Checker checker = {}; + if (parse_files(&parser, init_filename) == ParseFile_None) { + // print_ast(parser.files[0].decls, 0); - init_checker(&checker, &parser); - defer (destroy_checker(&checker)); + Checker checker = {}; - check_parsed_files(&checker); - ssaGen ssa = {}; - if (ssa_gen_init(&ssa, &checker)) { - defer (ssa_gen_destroy(&ssa)); + init_checker(&checker, &parser); + defer (destroy_checker(&checker)); - ssa_gen_code(&ssa); + check_parsed_files(&checker); + ssaGen ssa = {}; + if (ssa_gen_init(&ssa, &checker)) { + defer (ssa_gen_destroy(&ssa)); - success = 0; - } else { - gb_printf("Failed to build: %s\n", init_filename); + ssa_gen_code(&ssa); + + char const *output_name = ssa.output_file.filename; + isize base_name_len = gb_path_extension(output_name)-1 - output_name; + + win32_exec_command_line_app( + "opt -mem2reg %s -o %.*s.bc", + output_name, cast(int)base_name_len, output_name); + win32_exec_command_line_app( + "clang %.*s.bc -o %.*s.exe -Wno-override-module " + "-lkernel32.lib -luser32.lib", + cast(int)base_name_len, output_name, + cast(int)base_name_len, output_name); + + + if (run_output) { + win32_exec_command_line_app("%.*s.exe", cast(int)base_name_len, output_name); } + + + return 0; } } } - return success; + return 1; }