LCOV - code coverage report
Current view: top level - src - main.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 345 838 41.2 %
Date: 1970-01-01 00:00:01 Functions: 3 9 33.3 %
Branches: 208 600 34.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2015 Andrew Kelley
       3                 :            :  *
       4                 :            :  * This file is part of zig, which is MIT licensed.
       5                 :            :  * See http://opensource.org/licenses/MIT
       6                 :            :  */
       7                 :            : 
       8                 :            : #include "ast_render.hpp"
       9                 :            : #include "buffer.hpp"
      10                 :            : #include "codegen.hpp"
      11                 :            : #include "compiler.hpp"
      12                 :            : #include "config.h"
      13                 :            : #include "error.hpp"
      14                 :            : #include "os.hpp"
      15                 :            : #include "target.hpp"
      16                 :            : #include "libc_installation.hpp"
      17                 :            : #include "userland.h"
      18                 :            : #include "glibc.hpp"
      19                 :            : 
      20                 :            : #include <stdio.h>
      21                 :            : 
      22                 :          0 : static int print_error_usage(const char *arg0) {
      23                 :          0 :     fprintf(stderr, "See `%s --help` for detailed usage information\n", arg0);
      24                 :          0 :     return EXIT_FAILURE;
      25                 :            : }
      26                 :            : 
      27                 :          0 : static int print_full_usage(const char *arg0, FILE *file, int return_code) {
      28                 :          0 :     fprintf(file,
      29                 :            :         "Usage: %s [command] [options]\n"
      30                 :            :         "\n"
      31                 :            :         "Commands:\n"
      32                 :            :         "  build                        build project from build.zig\n"
      33                 :            :         "  build-exe [source]           create executable from source or object files\n"
      34                 :            :         "  build-lib [source]           create library from source or object files\n"
      35                 :            :         "  build-obj [source]           create object from source or assembly\n"
      36                 :            :         "  builtin                      show the source code of that @import(\"builtin\")\n"
      37                 :            :         "  cc                           C compiler\n"
      38                 :            :         "  fmt                          parse files and render in canonical zig format\n"
      39                 :            :         "  id                           print the base64-encoded compiler id\n"
      40                 :            :         "  init-exe                     initialize a `zig build` application in the cwd\n"
      41                 :            :         "  init-lib                     initialize a `zig build` library in the cwd\n"
      42                 :            :         "  libc [paths_file]            Display native libc paths file or validate one\n"
      43                 :            :         "  run [source] [-- [args]]     create executable and run immediately\n"
      44                 :            :         "  translate-c [source]         convert c code to zig code\n"
      45                 :            :         "  translate-c-2 [source]       experimental self-hosted translate-c\n"
      46                 :            :         "  targets                      list available compilation targets\n"
      47                 :            :         "  test [source]                create and run a test build\n"
      48                 :            :         "  version                      print version number and exit\n"
      49                 :            :         "  zen                          print zen of zig and exit\n"
      50                 :            :         "\n"
      51                 :            :         "Compile Options:\n"
      52                 :            :         "  --c-source [options] [file]  compile C source code\n"
      53                 :            :         "  --cache-dir [path]           override the local cache directory\n"
      54                 :            :         "  --cache [auto|off|on]        build in cache, print output path to stdout\n"
      55                 :            :         "  --color [auto|off|on]        enable or disable colored error messages\n"
      56                 :            :         "  --disable-gen-h              do not generate a C header file (.h)\n"
      57                 :            :         "  --disable-valgrind           omit valgrind client requests in debug builds\n"
      58                 :            :         "  --enable-valgrind            include valgrind client requests release builds\n"
      59                 :            :         "  -fstack-check                enable stack probing in unsafe builds\n"
      60                 :            :         "  -fno-stack-check             disable stack probing in safe builds\n"
      61                 :            :         "  --emit [asm|bin|llvm-ir]     emit a specific file format as compilation output\n"
      62                 :            :         "  -fPIC                        enable Position Independent Code\n"
      63                 :            :         "  -fno-PIC                     disable Position Independent Code\n"
      64                 :            :         "  -ftime-report                print timing diagnostics\n"
      65                 :            :         "  --libc [file]                Provide a file which specifies libc paths\n"
      66                 :            :         "  --name [name]                override output name\n"
      67                 :            :         "  --output-dir [dir]           override output directory (defaults to cwd)\n"
      68                 :            :         "  --pkg-begin [name] [path]    make pkg available to import and push current pkg\n"
      69                 :            :         "  --pkg-end                    pop current pkg\n"
      70                 :            :         "  --main-pkg-path              set the directory of the root package\n"
      71                 :            :         "  --release-fast               build with optimizations on and safety off\n"
      72                 :            :         "  --release-safe               build with optimizations on and safety on\n"
      73                 :            :         "  --release-small              build with size optimizations on and safety off\n"
      74                 :            :         "  --single-threaded            source may assume it is only used single-threaded\n"
      75                 :            :         "  -dynamic                     create a shared library (.so; .dll; .dylib)\n"
      76                 :            :         "  --strip                      exclude debug symbols\n"
      77                 :            :         "  -target [name]               <arch><sub>-<os>-<abi> see the targets command\n"
      78                 :            :         "  -target-glibc [version]      target a specific glibc version (default: 2.17)\n"
      79                 :            :         "  --verbose-tokenize           enable compiler debug output for tokenization\n"
      80                 :            :         "  --verbose-ast                enable compiler debug output for AST parsing\n"
      81                 :            :         "  --verbose-link               enable compiler debug output for linking\n"
      82                 :            :         "  --verbose-ir                 enable compiler debug output for Zig IR\n"
      83                 :            :         "  --verbose-llvm-ir            enable compiler debug output for LLVM IR\n"
      84                 :            :         "  --verbose-cimport            enable compiler debug output for C imports\n"
      85                 :            :         "  --verbose-cc                 enable compiler debug output for C compilation\n"
      86                 :            :         "  -dirafter [dir]              same as -isystem but do it last\n"
      87                 :            :         "  -isystem [dir]               add additional search path for other .h files\n"
      88                 :            :         "  -mllvm [arg]                 (unsupported) forward an arg to LLVM's option processing\n"
      89                 :            :         "  --override-std-dir [arg]     override path to Zig standard library\n"
      90                 :            :         "  --override-lib-dir [arg]     override path to Zig lib library\n"
      91                 :            :         "  -ffunction-sections          places each function in a seperate section\n"
      92                 :            :         "\n"
      93                 :            :         "Link Options:\n"
      94                 :            :         "  --bundle-compiler-rt         for static libraries, include compiler-rt symbols\n"
      95                 :            :         "  --dynamic-linker [path]      set the path to ld.so\n"
      96                 :            :         "  --each-lib-rpath             add rpath for each used dynamic library\n"
      97                 :            :         "  --library [lib]              link against lib\n"
      98                 :            :         "  --forbid-library [lib]       make it an error to link against lib\n"
      99                 :            :         "  --library-path [dir]         add a directory to the library search path\n"
     100                 :            :         "  --linker-script [path]       use a custom linker script\n"
     101                 :            :         "  --version-script [path]      provide a version .map file\n"
     102                 :            :         "  --object [obj]               add object file to build\n"
     103                 :            :         "  -L[dir]                      alias for --library-path\n"
     104                 :            :         "  -l[lib]                      alias for --library\n"
     105                 :            :         "  -rdynamic                    add all symbols to the dynamic symbol table\n"
     106                 :            :         "  -rpath [path]                add directory to the runtime library search path\n"
     107                 :            :         "  --subsystem [subsystem]      (windows) /SUBSYSTEM:<subsystem> to the linker\n"
     108                 :            :         "  -F[dir]                      (darwin) add search path for frameworks\n"
     109                 :            :         "  -framework [name]            (darwin) link against framework\n"
     110                 :            :         "  -mios-version-min [ver]      (darwin) set iOS deployment target\n"
     111                 :            :         "  -mmacosx-version-min [ver]   (darwin) set Mac OS X deployment target\n"
     112                 :            :         "  --ver-major [ver]            dynamic library semver major version\n"
     113                 :            :         "  --ver-minor [ver]            dynamic library semver minor version\n"
     114                 :            :         "  --ver-patch [ver]            dynamic library semver patch version\n"
     115                 :            :         "\n"
     116                 :            :         "Test Options:\n"
     117                 :            :         "  --test-filter [text]         skip tests that do not match filter\n"
     118                 :            :         "  --test-name-prefix [text]    add prefix to all tests\n"
     119                 :            :         "  --test-cmd [arg]             specify test execution command one arg at a time\n"
     120                 :            :         "  --test-cmd-bin               appends test binary path to test cmd args\n"
     121                 :            :     , arg0);
     122                 :          0 :     return return_code;
     123                 :            : }
     124                 :            : 
     125                 :          0 : static int print_libc_usage(const char *arg0, FILE *file, int return_code) {
     126                 :          0 :     fprintf(file,
     127                 :            :         "Usage: %s libc\n"
     128                 :            :         "\n"
     129                 :            :         "Detect the native libc installation and print the resulting paths to stdout.\n"
     130                 :            :         "You can save this into a file and then edit the paths to create a cross\n"
     131                 :            :         "compilation libc kit. Then you can pass `--libc [file]` for Zig to use it.\n"
     132                 :            :         "\n"
     133                 :            :         "When compiling natively and no `--libc` argument provided, Zig automatically\n"
     134                 :            :         "creates zig-cache/native_libc.txt so that it does not have to detect libc\n"
     135                 :            :         "on every invocation. You can remove this file to have Zig re-detect the\n"
     136                 :            :         "native libc.\n"
     137                 :            :         "\n\n"
     138                 :            :         "Usage: %s libc [file]\n"
     139                 :            :         "\n"
     140                 :            :         "Parse a libc installation text file and validate it.\n"
     141                 :            :     , arg0, arg0);
     142                 :          0 :     return return_code;
     143                 :            : }
     144                 :            : 
     145                 :          0 : static bool arch_available_in_llvm(ZigLLVM_ArchType arch) {
     146                 :            :     LLVMTargetRef target_ref;
     147                 :          0 :     char *err_msg = nullptr;
     148                 :            :     char triple_string[128];
     149                 :          0 :     sprintf(triple_string, "%s-unknown-unknown-unknown", ZigLLVMGetArchTypeName(arch));
     150                 :          0 :     return !LLVMGetTargetFromTriple(triple_string, &target_ref, &err_msg);
     151                 :            : }
     152                 :            : 
     153                 :          0 : static int print_target_list(FILE *f) {
     154                 :            :     ZigTarget native;
     155                 :          0 :     get_native_target(&native);
     156                 :            : 
     157                 :          0 :     fprintf(f, "Architectures:\n");
     158                 :          0 :     size_t arch_count = target_arch_count();
     159         [ #  # ]:          0 :     for (size_t arch_i = 0; arch_i < arch_count; arch_i += 1) {
     160                 :          0 :         ZigLLVM_ArchType arch = target_arch_enum(arch_i);
     161         [ #  # ]:          0 :         if (!arch_available_in_llvm(arch))
     162                 :          0 :             continue;
     163                 :          0 :         const char *arch_name = target_arch_name(arch);
     164                 :          0 :         SubArchList sub_arch_list = target_subarch_list(arch);
     165                 :          0 :         size_t sub_count = target_subarch_count(sub_arch_list);
     166         [ #  # ]:          0 :         const char *arch_native_str = (native.arch == arch) ? " (native)" : "";
     167                 :          0 :         fprintf(f, "  %s%s\n", arch_name, arch_native_str);
     168         [ #  # ]:          0 :         for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
     169                 :          0 :             ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
     170                 :          0 :             const char *sub_name = target_subarch_name(sub);
     171 [ #  # ][ #  # ]:          0 :             const char *sub_native_str = (native.arch == arch && native.sub_arch == sub) ? " (native)" : "";
     172                 :          0 :             fprintf(f, "    %s%s\n", sub_name, sub_native_str);
     173                 :            :         }
     174                 :            :     }
     175                 :            : 
     176                 :          0 :     fprintf(f, "\nOperating Systems:\n");
     177                 :          0 :     size_t os_count = target_os_count();
     178         [ #  # ]:          0 :     for (size_t i = 0; i < os_count; i += 1) {
     179                 :          0 :         Os os_type = target_os_enum(i);
     180         [ #  # ]:          0 :         const char *native_str = (native.os == os_type) ? " (native)" : "";
     181                 :          0 :         fprintf(f, "  %s%s\n", target_os_name(os_type), native_str);
     182                 :            :     }
     183                 :            : 
     184                 :          0 :     fprintf(f, "\nC ABIs:\n");
     185                 :          0 :     size_t abi_count = target_abi_count();
     186         [ #  # ]:          0 :     for (size_t i = 0; i < abi_count; i += 1) {
     187                 :          0 :         ZigLLVM_EnvironmentType abi = target_abi_enum(i);
     188         [ #  # ]:          0 :         const char *native_str = (native.abi == abi) ? " (native)" : "";
     189                 :          0 :         fprintf(f, "  %s%s\n", target_abi_name(abi), native_str);
     190                 :            :     }
     191                 :            : 
     192                 :          0 :     fprintf(f, "\nAvailable libcs:\n");
     193                 :          0 :     size_t libc_count = target_libc_count();
     194         [ #  # ]:          0 :     for (size_t i = 0; i < libc_count; i += 1) {
     195                 :            :         ZigTarget libc_target;
     196                 :          0 :         target_libc_enum(i, &libc_target);
     197         [ #  # ]:          0 :         bool is_native = native.arch == libc_target.arch &&
     198 [ #  # ][ #  # ]:          0 :             native.os == libc_target.os &&
     199                 :          0 :             native.abi == libc_target.abi;
     200         [ #  # ]:          0 :         const char *native_str = is_native ? " (native)" : "";
     201                 :          0 :         fprintf(f, "  %s-%s-%s%s\n", target_arch_name(libc_target.arch),
     202                 :            :                 target_os_name(libc_target.os), target_abi_name(libc_target.abi), native_str);
     203                 :            :     }
     204                 :            : 
     205                 :          0 :     fprintf(f, "\nAvailable glibc versions:\n");
     206                 :            :     ZigGLibCAbi *glibc_abi;
     207                 :            :     Error err;
     208         [ #  # ]:          0 :     if ((err = glibc_load_metadata(&glibc_abi, get_zig_lib_dir(), true))) {
     209                 :          0 :         return EXIT_FAILURE;
     210                 :            :     }
     211         [ #  # ]:          0 :     for (size_t i = 0; i < glibc_abi->all_versions.length; i += 1) {
     212                 :          0 :         ZigGLibCVersion *this_ver = &glibc_abi->all_versions.at(i);
     213         [ #  # ]:          0 :         bool is_native = native.glibc_version != nullptr &&
     214         [ #  # ]:          0 :             native.glibc_version->major == this_ver->major &&
     215 [ #  # ][ #  # ]:          0 :             native.glibc_version->minor == this_ver->minor &&
     216                 :          0 :             native.glibc_version->patch == this_ver->patch;
     217         [ #  # ]:          0 :         const char *native_str = is_native ? " (native)" : "";
     218         [ #  # ]:          0 :         if (this_ver->patch == 0) {
     219                 :          0 :             fprintf(f, "  %d.%d%s\n", this_ver->major, this_ver->minor, native_str);
     220                 :            :         } else {
     221                 :          0 :             fprintf(f, "  %d.%d.%d%s\n", this_ver->major, this_ver->minor, this_ver->patch, native_str);
     222                 :            :         }
     223                 :            :     }
     224                 :          0 :     return EXIT_SUCCESS;
     225                 :            : }
     226                 :            : 
     227                 :            : enum Cmd {
     228                 :            :     CmdNone,
     229                 :            :     CmdBuild,
     230                 :            :     CmdBuiltin,
     231                 :            :     CmdRun,
     232                 :            :     CmdTargets,
     233                 :            :     CmdTest,
     234                 :            :     CmdTranslateC,
     235                 :            :     CmdTranslateCUserland,
     236                 :            :     CmdVersion,
     237                 :            :     CmdZen,
     238                 :            :     CmdLibC,
     239                 :            : };
     240                 :            : 
     241                 :            : static const char *default_zig_cache_name = "zig-cache";
     242                 :            : 
     243                 :            : struct CliPkg {
     244                 :            :     const char *name;
     245                 :            :     const char *path;
     246                 :            :     ZigList<CliPkg *> children;
     247                 :            :     CliPkg *parent;
     248                 :            : };
     249                 :            : 
     250                 :         16 : static void add_package(CodeGen *g, CliPkg *cli_pkg, ZigPackage *pkg) {
     251         [ -  + ]:         16 :     for (size_t i = 0; i < cli_pkg->children.length; i += 1) {
     252                 :          0 :         CliPkg *child_cli_pkg = cli_pkg->children.at(i);
     253                 :            : 
     254                 :          0 :         Buf *dirname = buf_alloc();
     255                 :          0 :         Buf *basename = buf_alloc();
     256                 :          0 :         os_path_split(buf_create_from_str(child_cli_pkg->path), dirname, basename);
     257                 :            : 
     258                 :          0 :         ZigPackage *child_pkg = codegen_create_package(g, buf_ptr(dirname), buf_ptr(basename),
     259                 :          0 :                 buf_ptr(buf_sprintf("%s.%s", buf_ptr(&pkg->pkg_path), child_cli_pkg->name)));
     260                 :          0 :         auto entry = pkg->package_table.put_unique(buf_create_from_str(child_cli_pkg->name), child_pkg);
     261         [ #  # ]:          0 :         if (entry) {
     262                 :          0 :             ZigPackage *existing_pkg = entry->value;
     263                 :          0 :             Buf *full_path = buf_alloc();
     264                 :          0 :             os_path_join(&existing_pkg->root_src_dir, &existing_pkg->root_src_path, full_path);
     265                 :          0 :             fprintf(stderr, "Unable to add package '%s'->'%s': already exists as '%s'\n",
     266                 :            :                     child_cli_pkg->name, child_cli_pkg->path, buf_ptr(full_path));
     267                 :          0 :             exit(EXIT_FAILURE);
     268                 :            :         }
     269                 :            : 
     270                 :          0 :         add_package(g, child_cli_pkg, child_pkg);
     271                 :            :     }
     272                 :         16 : }
     273                 :            : 
     274                 :            : enum CacheOpt {
     275                 :            :     CacheOptAuto,
     276                 :            :     CacheOptOn,
     277                 :            :     CacheOptOff,
     278                 :            : };
     279                 :            : 
     280                 :         18 : static bool get_cache_opt(CacheOpt opt, bool default_value) {
     281   [ +  -  -  - ]:         18 :     switch (opt) {
     282                 :         18 :         case CacheOptAuto:
     283                 :         18 :             return default_value;
     284                 :          0 :         case CacheOptOn:
     285                 :          0 :             return true;
     286                 :          0 :         case CacheOptOff:
     287                 :          0 :             return false;
     288                 :            :     }
     289                 :          0 :     zig_unreachable();
     290                 :            : }
     291                 :            : 
     292                 :          0 : static int zig_error_no_build_file(void) {
     293                 :          0 :     fprintf(stderr,
     294                 :            :         "No 'build.zig' file found, in the current directory or any parent directories.\n"
     295                 :            :         "Initialize a 'build.zig' template file with `zig init-lib` or `zig init-exe`,\n"
     296                 :            :         "or see `zig --help` for more options.\n"
     297                 :            :     );
     298                 :          0 :     return EXIT_FAILURE;
     299                 :            : }
     300                 :            : 
     301                 :            : extern "C" int ZigClang_main(int argc, char **argv);
     302                 :            : 
     303                 :         98 : int main(int argc, char **argv) {
     304                 :         98 :     stage2_attach_segfault_handler();
     305                 :            : 
     306                 :         98 :     char *arg0 = argv[0];
     307                 :            :     Error err;
     308                 :            : 
     309 [ +  - ][ +  + ]:         98 :     if (argc == 2 && strcmp(argv[1], "BUILD_INFO") == 0) {
     310                 :          2 :         printf("%s\n%s\n%s\n%s\n%s\n%s\n",
     311                 :            :                 ZIG_CMAKE_BINARY_DIR,
     312                 :            :                 ZIG_CXX_COMPILER,
     313                 :            :                 ZIG_LLVM_CONFIG_EXE,
     314                 :            :                 ZIG_LLD_INCLUDE_PATH,
     315                 :            :                 ZIG_LLD_LIBRARIES,
     316                 :            :                 ZIG_DIA_GUIDS_LIB);
     317                 :         98 :         return 0;
     318                 :            :     }
     319                 :            : 
     320 [ +  - ][ +  + ]:         96 :     if (argc >= 2 && (strcmp(argv[1], "cc") == 0 ||
                 [ +  + ]
     321         [ +  + ]:         26 :             strcmp(argv[1], "-cc1") == 0 || strcmp(argv[1], "-cc1as") == 0))
     322                 :            :     {
     323                 :         78 :         return ZigClang_main(argc, argv);
     324                 :            :     }
     325                 :            : 
     326                 :            :     // Must be before all os.hpp function calls.
     327                 :         18 :     os_init();
     328                 :            : 
     329 [ #  # ][ -  + ]:         18 :     if (argc == 2 && strcmp(argv[1], "id") == 0) {
     330                 :            :         Buf *compiler_id;
     331         [ #  # ]:          0 :         if ((err = get_compiler_id(&compiler_id))) {
     332                 :          0 :             fprintf(stderr, "Unable to determine compiler id: %s\n", err_str(err));
     333                 :          0 :             return EXIT_FAILURE;
     334                 :            :         }
     335                 :          0 :         printf("%s\n", buf_ptr(compiler_id));
     336                 :          0 :         return EXIT_SUCCESS;
     337                 :            :     }
     338                 :            : 
     339                 :            :     enum InitKind {
     340                 :            :         InitKindNone,
     341                 :            :         InitKindExe,
     342                 :            :         InitKindLib,
     343                 :            :     };
     344                 :         18 :     InitKind init_kind = InitKindNone;
     345         [ +  - ]:         18 :     if (argc >= 2) {
     346                 :         18 :         const char *init_cmd = argv[1];
     347         [ -  + ]:         18 :         if (strcmp(init_cmd, "init-exe") == 0) {
     348                 :          0 :             init_kind = InitKindExe;
     349         [ -  + ]:         18 :         } else if (strcmp(init_cmd, "init-lib") == 0) {
     350                 :          0 :             init_kind = InitKindLib;
     351                 :            :         }
     352         [ -  + ]:         18 :         if (init_kind != InitKindNone) {
     353         [ #  # ]:          0 :             if (argc >= 3) {
     354                 :          0 :                 fprintf(stderr, "Unexpected extra argument: %s\n", argv[2]);
     355                 :          0 :                 return print_error_usage(arg0);
     356                 :            :             }
     357                 :          0 :             Buf *cmd_template_path = buf_alloc();
     358                 :          0 :             os_path_join(get_zig_special_dir(get_zig_lib_dir()), buf_create_from_str(init_cmd), cmd_template_path);
     359                 :          0 :             Buf *build_zig_path = buf_alloc();
     360                 :          0 :             os_path_join(cmd_template_path, buf_create_from_str("build.zig"), build_zig_path);
     361                 :          0 :             Buf *src_dir_path = buf_alloc();
     362                 :          0 :             os_path_join(cmd_template_path, buf_create_from_str("src"), src_dir_path);
     363                 :          0 :             Buf *main_zig_path = buf_alloc();
     364                 :          0 :             os_path_join(src_dir_path, buf_create_from_str("main.zig"), main_zig_path);
     365                 :            : 
     366                 :          0 :             Buf *cwd = buf_alloc();
     367         [ #  # ]:          0 :             if ((err = os_get_cwd(cwd))) {
     368                 :          0 :                 fprintf(stderr, "Unable to get cwd: %s\n", err_str(err));
     369                 :          0 :                 return EXIT_FAILURE;
     370                 :            :             }
     371                 :          0 :             Buf *cwd_basename = buf_alloc();
     372                 :          0 :             os_path_split(cwd, nullptr, cwd_basename);
     373                 :            : 
     374                 :          0 :             Buf *build_zig_contents = buf_alloc();
     375         [ #  # ]:          0 :             if ((err = os_fetch_file_path(build_zig_path, build_zig_contents))) {
     376                 :          0 :                 fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(build_zig_path), err_str(err));
     377                 :          0 :                 return EXIT_FAILURE;
     378                 :            :             }
     379                 :          0 :             Buf *modified_build_zig_contents = buf_alloc();
     380         [ #  # ]:          0 :             for (size_t i = 0; i < buf_len(build_zig_contents); i += 1) {
     381                 :          0 :                 char c = buf_ptr(build_zig_contents)[i];
     382         [ #  # ]:          0 :                 if (c == '$') {
     383                 :          0 :                     buf_append_buf(modified_build_zig_contents, cwd_basename);
     384                 :            :                 } else {
     385                 :          0 :                     buf_append_char(modified_build_zig_contents, c);
     386                 :            :                 }
     387                 :            :             }
     388                 :            : 
     389                 :          0 :             Buf *main_zig_contents = buf_alloc();
     390         [ #  # ]:          0 :             if ((err = os_fetch_file_path(main_zig_path, main_zig_contents))) {
     391                 :          0 :                 fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(main_zig_path), err_str(err));
     392                 :          0 :                 return EXIT_FAILURE;
     393                 :            :             }
     394                 :            : 
     395                 :          0 :             Buf *out_build_zig_path = buf_create_from_str("build.zig");
     396                 :          0 :             Buf *out_src_dir_path = buf_create_from_str("src");
     397                 :          0 :             Buf *out_main_zig_path = buf_alloc();
     398                 :          0 :             os_path_join(out_src_dir_path, buf_create_from_str("main.zig"), out_main_zig_path);
     399                 :            : 
     400                 :            :             bool already_exists;
     401         [ #  # ]:          0 :             if ((err = os_file_exists(out_build_zig_path, &already_exists))) {
     402                 :          0 :                 fprintf(stderr, "Unable test existence of %s: %s\n", buf_ptr(out_build_zig_path), err_str(err));
     403                 :          0 :                 return EXIT_FAILURE;
     404                 :            :             }
     405         [ #  # ]:          0 :             if (already_exists) {
     406                 :          0 :                 fprintf(stderr, "This file would be overwritten: %s\n", buf_ptr(out_build_zig_path));
     407                 :          0 :                 return EXIT_FAILURE;
     408                 :            :             }
     409                 :            : 
     410         [ #  # ]:          0 :             if ((err = os_make_dir(out_src_dir_path))) {
     411                 :          0 :                 fprintf(stderr, "Unable to make directory: %s: %s\n", buf_ptr(out_src_dir_path), err_str(err));
     412                 :          0 :                 return EXIT_FAILURE;
     413                 :            :             }
     414         [ #  # ]:          0 :             if ((err = os_write_file(out_build_zig_path, modified_build_zig_contents))) {
     415                 :          0 :                 fprintf(stderr, "Unable to write file: %s: %s\n", buf_ptr(out_build_zig_path), err_str(err));
     416                 :          0 :                 return EXIT_FAILURE;
     417                 :            :             }
     418         [ #  # ]:          0 :             if ((err = os_write_file(out_main_zig_path, main_zig_contents))) {
     419                 :          0 :                 fprintf(stderr, "Unable to write file: %s: %s\n", buf_ptr(out_main_zig_path), err_str(err));
     420                 :          0 :                 return EXIT_FAILURE;
     421                 :            :             }
     422                 :          0 :             fprintf(stderr, "Created %s\n", buf_ptr(out_build_zig_path));
     423                 :          0 :             fprintf(stderr, "Created %s\n", buf_ptr(out_main_zig_path));
     424         [ #  # ]:          0 :             if (init_kind == InitKindExe) {
     425                 :          0 :                 fprintf(stderr, "\nNext, try `zig build --help` or `zig build run`\n");
     426         [ #  # ]:          0 :             } else if (init_kind == InitKindLib) {
     427                 :          0 :                 fprintf(stderr, "\nNext, try `zig build --help` or `zig build test`\n");
     428                 :            :             } else {
     429                 :          0 :                 zig_unreachable();
     430                 :            :             }
     431                 :            : 
     432                 :         18 :             return EXIT_SUCCESS;
     433                 :            :         }
     434                 :            :     }
     435                 :            : 
     436                 :         18 :     Cmd cmd = CmdNone;
     437                 :         18 :     EmitFileType emit_file_type = EmitFileTypeBinary;
     438                 :         18 :     const char *in_file = nullptr;
     439                 :         18 :     Buf *output_dir = nullptr;
     440                 :         18 :     bool strip = false;
     441                 :         18 :     bool is_dynamic = false;
     442                 :         18 :     OutType out_type = OutTypeUnknown;
     443                 :         18 :     const char *out_name = nullptr;
     444                 :         18 :     bool verbose_tokenize = false;
     445                 :         18 :     bool verbose_ast = false;
     446                 :         18 :     bool verbose_link = false;
     447                 :         18 :     bool verbose_ir = false;
     448                 :         18 :     bool verbose_llvm_ir = false;
     449                 :         18 :     bool verbose_cimport = false;
     450                 :         18 :     bool verbose_cc = false;
     451                 :         18 :     ErrColor color = ErrColorAuto;
     452                 :         18 :     CacheOpt enable_cache = CacheOptAuto;
     453                 :         18 :     Buf *dynamic_linker = nullptr;
     454                 :         18 :     const char *libc_txt = nullptr;
     455                 :         18 :     ZigList<const char *> clang_argv = {0};
     456                 :         18 :     ZigList<const char *> lib_dirs = {0};
     457                 :         18 :     ZigList<const char *> link_libs = {0};
     458                 :         18 :     ZigList<const char *> forbidden_link_libs = {0};
     459                 :         18 :     ZigList<const char *> framework_dirs = {0};
     460                 :         18 :     ZigList<const char *> frameworks = {0};
     461                 :         18 :     bool have_libc = false;
     462                 :         18 :     const char *target_string = nullptr;
     463                 :         18 :     bool rdynamic = false;
     464                 :         18 :     const char *mmacosx_version_min = nullptr;
     465                 :         18 :     const char *mios_version_min = nullptr;
     466                 :         18 :     const char *linker_script = nullptr;
     467                 :         18 :     Buf *version_script = nullptr;
     468                 :         18 :     const char *target_glibc = nullptr;
     469                 :         18 :     ZigList<const char *> rpath_list = {0};
     470                 :         18 :     bool each_lib_rpath = false;
     471                 :         18 :     ZigList<const char *> objects = {0};
     472                 :         18 :     ZigList<CFile *> c_source_files = {0};
     473                 :         18 :     const char *test_filter = nullptr;
     474                 :         18 :     const char *test_name_prefix = nullptr;
     475                 :         18 :     size_t ver_major = 0;
     476                 :         18 :     size_t ver_minor = 0;
     477                 :         18 :     size_t ver_patch = 0;
     478                 :         18 :     bool timing_info = false;
     479                 :         18 :     const char *cache_dir = nullptr;
     480                 :         18 :     CliPkg *cur_pkg = allocate<CliPkg>(1);
     481                 :         18 :     BuildMode build_mode = BuildModeDebug;
     482                 :         18 :     ZigList<const char *> test_exec_args = {0};
     483                 :         18 :     int runtime_args_start = -1;
     484                 :         18 :     bool system_linker_hack = false;
     485                 :         18 :     TargetSubsystem subsystem = TargetSubsystemAuto;
     486                 :         18 :     bool want_single_threaded = false;
     487                 :         18 :     bool disable_gen_h = false;
     488                 :         18 :     bool bundle_compiler_rt = false;
     489                 :         18 :     Buf *override_std_dir = nullptr;
     490                 :         18 :     Buf *override_lib_dir = nullptr;
     491                 :         18 :     Buf *main_pkg_path = nullptr;
     492                 :         18 :     ValgrindSupport valgrind_support = ValgrindSupportAuto;
     493                 :         18 :     WantPIC want_pic = WantPICAuto;
     494                 :         18 :     WantStackCheck want_stack_check = WantStackCheckAuto;
     495                 :         18 :     bool function_sections = false;
     496                 :            : 
     497                 :         18 :     ZigList<const char *> llvm_argv = {0};
     498                 :         18 :     llvm_argv.append("zig (LLVM option parsing)");
     499                 :            : 
     500 [ +  + ][ +  - ]:         18 :     if (argc >= 2 && strcmp(argv[1], "build") == 0) {
     501                 :          2 :         Buf zig_exe_path_buf = BUF_INIT;
     502         [ -  + ]:          2 :         if ((err = os_self_exe_path(&zig_exe_path_buf))) {
     503                 :          0 :             fprintf(stderr, "Unable to determine path to zig's own executable\n");
     504                 :          0 :             return EXIT_FAILURE;
     505                 :            :         }
     506                 :          2 :         const char *zig_exe_path = buf_ptr(&zig_exe_path_buf);
     507                 :          2 :         const char *build_file = nullptr;
     508                 :            : 
     509                 :          2 :         init_all_targets();
     510                 :            : 
     511                 :          2 :         ZigList<const char *> args = {0};
     512                 :          2 :         args.append(NULL); // placeholder
     513                 :          2 :         args.append(zig_exe_path);
     514                 :          2 :         args.append(NULL); // placeholder
     515                 :          2 :         args.append(NULL); // placeholder
     516         [ +  + ]:          6 :         for (int i = 2; i < argc; i += 1) {
     517         [ -  + ]:          4 :             if (strcmp(argv[i], "--help") == 0) {
     518                 :          0 :                 args.append(argv[i]);
     519 [ +  + ][ -  + ]:          4 :             } else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) {
     520                 :          0 :                 build_file = argv[i + 1];
     521                 :          0 :                 i += 1;
     522 [ +  + ][ -  + ]:          4 :             } else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) {
     523                 :          0 :                 cache_dir = argv[i + 1];
     524                 :          0 :                 i += 1;
     525 [ +  + ][ -  + ]:          4 :             } else if (i + 1 < argc && strcmp(argv[i], "--override-std-dir") == 0) {
     526                 :          0 :                 override_std_dir = buf_create_from_str(argv[i + 1]);
     527                 :          0 :                 i += 1;
     528                 :            : 
     529                 :          0 :                 args.append("--override-std-dir");
     530                 :          0 :                 args.append(buf_ptr(override_std_dir));
     531 [ +  + ][ -  + ]:          4 :             } else if (i + 1 < argc && strcmp(argv[i], "--override-lib-dir") == 0) {
     532                 :          0 :                 override_lib_dir = buf_create_from_str(argv[i + 1]);
     533                 :          0 :                 i += 1;
     534                 :            : 
     535                 :          0 :                 args.append("--override-lib-dir");
     536                 :          0 :                 args.append(buf_ptr(override_lib_dir));
     537                 :            :             } else {
     538                 :          4 :                 args.append(argv[i]);
     539                 :            :             }
     540                 :            :         }
     541                 :            : 
     542         [ +  - ]:          2 :         Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir;
     543                 :            : 
     544                 :          2 :         Buf *build_runner_path = buf_alloc();
     545                 :          2 :         os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path);
     546                 :            : 
     547                 :            :         ZigTarget target;
     548                 :          2 :         get_native_target(&target);
     549                 :            : 
     550         [ -  + ]:          2 :         Buf *build_file_buf = buf_create_from_str((build_file != nullptr) ? build_file : "build.zig");
     551                 :          2 :         Buf build_file_abs = os_path_resolve(&build_file_buf, 1);
     552                 :          2 :         Buf build_file_basename = BUF_INIT;
     553                 :          2 :         Buf build_file_dirname = BUF_INIT;
     554                 :          2 :         os_path_split(&build_file_abs, &build_file_dirname, &build_file_basename);
     555                 :            : 
     556                 :            :         for (;;) {
     557                 :            :             bool build_file_exists;
     558         [ -  + ]:          4 :             if ((err = os_file_exists(&build_file_abs, &build_file_exists))) {
     559                 :          0 :                 fprintf(stderr, "unable to check existence of '%s': %s\n", buf_ptr(&build_file_abs), err_str(err));
     560                 :          0 :                 return 1;
     561                 :            :             }
     562         [ +  + ]:          4 :             if (build_file_exists)
     563                 :          2 :                 break;
     564                 :            : 
     565         [ -  + ]:          2 :             if (build_file != nullptr) {
     566                 :            :                 // they asked for a specific build file path. only look for that one
     567                 :          0 :                 return zig_error_no_build_file();
     568                 :            :             }
     569                 :            : 
     570                 :          2 :             Buf *next_dir = buf_alloc();
     571                 :          2 :             os_path_dirname(&build_file_dirname, next_dir);
     572         [ -  + ]:          2 :             if (buf_eql_buf(&build_file_dirname, next_dir)) {
     573                 :            :                 // no more parent directories to search, give up
     574                 :          0 :                 return zig_error_no_build_file();
     575                 :            :             }
     576                 :          2 :             os_path_join(next_dir, &build_file_basename, &build_file_abs);
     577                 :          2 :             buf_init_from_buf(&build_file_dirname, next_dir);
     578                 :          2 :         }
     579                 :            : 
     580                 :          2 :         Buf full_cache_dir = BUF_INIT;
     581         [ +  - ]:          2 :         if (cache_dir == nullptr) {
     582                 :          2 :             os_path_join(&build_file_dirname, buf_create_from_str(default_zig_cache_name), &full_cache_dir);
     583                 :            :         } else {
     584                 :          0 :             Buf *cache_dir_buf = buf_create_from_str(cache_dir);
     585                 :          0 :             full_cache_dir = os_path_resolve(&cache_dir_buf, 1);
     586                 :            :         }
     587                 :            : 
     588                 :            :         CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe,
     589                 :          2 :                 BuildModeDebug, override_lib_dir, override_std_dir, nullptr, &full_cache_dir, false);
     590                 :          2 :         g->valgrind_support = valgrind_support;
     591                 :          2 :         g->enable_time_report = timing_info;
     592                 :          2 :         codegen_set_out_name(g, buf_create_from_str("build"));
     593                 :            : 
     594                 :          2 :         args.items[2] = buf_ptr(&build_file_dirname);
     595                 :          2 :         args.items[3] = buf_ptr(&full_cache_dir);
     596                 :            : 
     597                 :          2 :         ZigPackage *build_pkg = codegen_create_package(g, buf_ptr(&build_file_dirname),
     598                 :          2 :                 buf_ptr(&build_file_basename), "std.special");
     599                 :          2 :         g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg);
     600                 :          2 :         g->enable_cache = get_cache_opt(enable_cache, true);
     601                 :          2 :         codegen_build_and_link(g);
     602                 :            : 
     603                 :            :         Termination term;
     604                 :          2 :         args.items[0] = buf_ptr(&g->output_file_path);
     605                 :          2 :         os_spawn_process(args, &term);
     606 [ -  + ][ +  - ]:          2 :         if (term.how != TerminationIdClean || term.code != 0) {
     607                 :          0 :             fprintf(stderr, "\nBuild failed. The following command failed:\n");
     608                 :          0 :             const char *prefix = "";
     609         [ #  # ]:          0 :             for (size_t i = 0; i < args.length; i += 1) {
     610                 :          0 :                 fprintf(stderr, "%s%s", prefix, args.at(i));
     611                 :          0 :                 prefix = " ";
     612                 :            :             }
     613                 :          0 :             fprintf(stderr, "\n");
     614                 :            :         }
     615         [ +  - ]:          2 :         return (term.how == TerminationIdClean) ? term.code : -1;
     616 [ +  - ][ -  + ]:         16 :     } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {
     617                 :          0 :         return stage2_fmt(argc, argv);
     618                 :            :     }
     619                 :            : 
     620         [ +  + ]:        116 :     for (int i = 1; i < argc; i += 1) {
     621                 :        100 :         char *arg = argv[i];
     622                 :            : 
     623         [ +  + ]:        100 :         if (arg[0] == '-') {
     624         [ -  + ]:         68 :             if (strcmp(arg, "--") == 0) {
     625         [ #  # ]:          0 :                 if (cmd == CmdRun) {
     626                 :          0 :                     runtime_args_start = i + 1;
     627                 :          0 :                     break; // rest of the args are for the program
     628                 :            :                 } else {
     629                 :          0 :                     fprintf(stderr, "Unexpected end-of-parameter mark: %s\n", arg);
     630                 :            :                 }
     631         [ -  + ]:         68 :             } else if (strcmp(arg, "--release-fast") == 0) {
     632                 :          0 :                 build_mode = BuildModeFastRelease;
     633         [ -  + ]:         68 :             } else if (strcmp(arg, "--release-safe") == 0) {
     634                 :          0 :                 build_mode = BuildModeSafeRelease;
     635         [ -  + ]:         68 :             } else if (strcmp(arg, "--release-small") == 0) {
     636                 :          0 :                 build_mode = BuildModeSmallRelease;
     637         [ -  + ]:         68 :             } else if (strcmp(arg, "--help") == 0) {
     638         [ #  # ]:          0 :                 if (cmd == CmdLibC) {
     639                 :          0 :                     return print_libc_usage(arg0, stdout, EXIT_SUCCESS);
     640                 :            :                 } else {
     641                 :          0 :                     return print_full_usage(arg0, stdout, EXIT_SUCCESS);
     642                 :            :                 }
     643         [ -  + ]:         68 :             } else if (strcmp(arg, "--strip") == 0) {
     644                 :          0 :                 strip = true;
     645         [ -  + ]:         68 :             } else if (strcmp(arg, "-dynamic") == 0) {
     646                 :          0 :                 is_dynamic = true;
     647         [ -  + ]:         68 :             } else if (strcmp(arg, "--verbose-tokenize") == 0) {
     648                 :          0 :                 verbose_tokenize = true;
     649         [ -  + ]:         68 :             } else if (strcmp(arg, "--verbose-ast") == 0) {
     650                 :          0 :                 verbose_ast = true;
     651         [ -  + ]:         68 :             } else if (strcmp(arg, "--verbose-link") == 0) {
     652                 :          0 :                 verbose_link = true;
     653         [ -  + ]:         68 :             } else if (strcmp(arg, "--verbose-ir") == 0) {
     654                 :          0 :                 verbose_ir = true;
     655         [ -  + ]:         68 :             } else if (strcmp(arg, "--verbose-llvm-ir") == 0) {
     656                 :          0 :                 verbose_llvm_ir = true;
     657         [ -  + ]:         68 :             } else if (strcmp(arg, "--verbose-cimport") == 0) {
     658                 :          0 :                 verbose_cimport = true;
     659         [ -  + ]:         68 :             } else if (strcmp(arg, "--verbose-cc") == 0) {
     660                 :          0 :                 verbose_cc = true;
     661         [ -  + ]:         68 :             } else if (strcmp(arg, "-rdynamic") == 0) {
     662                 :          0 :                 rdynamic = true;
     663         [ -  + ]:         68 :             } else if (strcmp(arg, "--each-lib-rpath") == 0) {
     664                 :          0 :                 each_lib_rpath = true;
     665         [ -  + ]:         68 :             } else if (strcmp(arg, "-ftime-report") == 0) {
     666                 :          0 :                 timing_info = true;
     667         [ -  + ]:         68 :             } else if (strcmp(arg, "--enable-valgrind") == 0) {
     668                 :          0 :                 valgrind_support = ValgrindSupportEnabled;
     669         [ -  + ]:         68 :             } else if (strcmp(arg, "--disable-valgrind") == 0) {
     670                 :          0 :                 valgrind_support = ValgrindSupportDisabled;
     671         [ -  + ]:         68 :             } else if (strcmp(arg, "-fPIC") == 0) {
     672                 :          0 :                 want_pic = WantPICEnabled;
     673         [ -  + ]:         68 :             } else if (strcmp(arg, "-fno-PIC") == 0) {
     674                 :          0 :                 want_pic = WantPICDisabled;
     675         [ -  + ]:         68 :             } else if (strcmp(arg, "-fstack-check") == 0) {
     676                 :          0 :                 want_stack_check = WantStackCheckEnabled;
     677         [ -  + ]:         68 :             } else if (strcmp(arg, "-fno-stack-check") == 0) {
     678                 :          0 :                 want_stack_check = WantStackCheckDisabled;
     679         [ -  + ]:         68 :             } else if (strcmp(arg, "--system-linker-hack") == 0) {
     680                 :          0 :                 system_linker_hack = true;
     681         [ +  + ]:         68 :             } else if (strcmp(arg, "--single-threaded") == 0) {
     682                 :          8 :                 want_single_threaded = true;
     683         [ -  + ]:         60 :             } else if (strcmp(arg, "--disable-gen-h") == 0) {
     684                 :          0 :                 disable_gen_h = true;
     685         [ -  + ]:         60 :             } else if (strcmp(arg, "--bundle-compiler-rt") == 0) {
     686                 :          0 :                 bundle_compiler_rt = true;
     687         [ -  + ]:         60 :             } else if (strcmp(arg, "--test-cmd-bin") == 0) {
     688                 :          0 :                 test_exec_args.append(nullptr);
     689 [ -  + ][ #  # ]:         60 :             } else if (arg[1] == 'L' && arg[2] != 0) {
     690                 :            :                 // alias for --library-path
     691                 :          0 :                 lib_dirs.append(&arg[2]);
     692 [ -  + ][ #  # ]:         60 :             } else if (arg[1] == 'l' && arg[2] != 0) {
     693                 :            :                 // alias for --library
     694                 :          0 :                 const char *l = &arg[2];
     695         [ #  # ]:          0 :                 if (strcmp(l, "c") == 0)
     696                 :          0 :                     have_libc = true;
     697                 :          0 :                 link_libs.append(l);
     698 [ -  + ][ #  # ]:         60 :             } else if (arg[1] == 'F' && arg[2] != 0) {
     699                 :          0 :                 framework_dirs.append(&arg[2]);
     700         [ -  + ]:         60 :             } else if (strcmp(arg, "--pkg-begin") == 0) {
     701         [ #  # ]:          0 :                 if (i + 2 >= argc) {
     702                 :          0 :                     fprintf(stderr, "Expected 2 arguments after --pkg-begin\n");
     703                 :          0 :                     return print_error_usage(arg0);
     704                 :            :                 }
     705                 :          0 :                 CliPkg *new_cur_pkg = allocate<CliPkg>(1);
     706                 :          0 :                 i += 1;
     707                 :          0 :                 new_cur_pkg->name = argv[i];
     708                 :          0 :                 i += 1;
     709                 :          0 :                 new_cur_pkg->path = argv[i];
     710                 :          0 :                 new_cur_pkg->parent = cur_pkg;
     711                 :          0 :                 cur_pkg->children.append(new_cur_pkg);
     712                 :          0 :                 cur_pkg = new_cur_pkg;
     713         [ -  + ]:         60 :             } else if (strcmp(arg, "--pkg-end") == 0) {
     714         [ #  # ]:          0 :                 if (cur_pkg->parent == nullptr) {
     715                 :          0 :                     fprintf(stderr, "Encountered --pkg-end with no matching --pkg-begin\n");
     716                 :          0 :                     return EXIT_FAILURE;
     717                 :            :                 }
     718                 :          0 :                 cur_pkg = cur_pkg->parent;
     719         [ -  + ]:         60 :             } else if (strcmp(arg, "-ffunction-sections") == 0) {
     720                 :          0 :                 function_sections = true;
     721         [ -  + ]:         60 :             } else if (i + 1 >= argc) {
     722                 :          0 :                 fprintf(stderr, "Expected another argument after %s\n", arg);
     723                 :          0 :                 return print_error_usage(arg0);
     724                 :            :             } else {
     725                 :         60 :                 i += 1;
     726         [ -  + ]:         60 :                 if (strcmp(arg, "--output-dir") == 0) {
     727                 :          0 :                     output_dir = buf_create_from_str(argv[i]);
     728         [ -  + ]:         60 :                 } else if (strcmp(arg, "--color") == 0) {
     729         [ #  # ]:          0 :                     if (strcmp(argv[i], "auto") == 0) {
     730                 :          0 :                         color = ErrColorAuto;
     731         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "on") == 0) {
     732                 :          0 :                         color = ErrColorOn;
     733         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "off") == 0) {
     734                 :          0 :                         color = ErrColorOff;
     735                 :            :                     } else {
     736                 :          0 :                         fprintf(stderr, "--color options are 'auto', 'on', or 'off'\n");
     737                 :          0 :                         return print_error_usage(arg0);
     738                 :            :                     }
     739         [ -  + ]:         60 :                 } else if (strcmp(arg, "--cache") == 0) {
     740         [ #  # ]:          0 :                     if (strcmp(argv[i], "auto") == 0) {
     741                 :          0 :                         enable_cache = CacheOptAuto;
     742         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "on") == 0) {
     743                 :          0 :                         enable_cache = CacheOptOn;
     744         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "off") == 0) {
     745                 :          0 :                         enable_cache = CacheOptOff;
     746                 :            :                     } else {
     747                 :          0 :                         fprintf(stderr, "--cache options are 'auto', 'on', or 'off'\n");
     748                 :          0 :                         return print_error_usage(arg0);
     749                 :            :                     }
     750         [ -  + ]:         60 :                 } else if (strcmp(arg, "--emit") == 0) {
     751         [ #  # ]:          0 :                     if (strcmp(argv[i], "asm") == 0) {
     752                 :          0 :                         emit_file_type = EmitFileTypeAssembly;
     753         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "bin") == 0) {
     754                 :          0 :                         emit_file_type = EmitFileTypeBinary;
     755         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "llvm-ir") == 0) {
     756                 :          0 :                         emit_file_type = EmitFileTypeLLVMIr;
     757                 :            :                     } else {
     758                 :          0 :                         fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");
     759                 :          0 :                         return print_error_usage(arg0);
     760                 :            :                     }
     761         [ +  + ]:         60 :                 } else if (strcmp(arg, "--name") == 0) {
     762                 :         16 :                     out_name = argv[i];
     763         [ -  + ]:         44 :                 } else if (strcmp(arg, "--dynamic-linker") == 0) {
     764                 :          0 :                     dynamic_linker = buf_create_from_str(argv[i]);
     765         [ -  + ]:         44 :                 } else if (strcmp(arg, "--libc") == 0) {
     766                 :          0 :                     libc_txt = argv[i];
     767         [ -  + ]:         44 :                 } else if (strcmp(arg, "-isystem") == 0) {
     768                 :          0 :                     clang_argv.append("-isystem");
     769                 :          0 :                     clang_argv.append(argv[i]);
     770         [ -  + ]:         44 :                 } else if (strcmp(arg, "-dirafter") == 0) {
     771                 :          0 :                     clang_argv.append("-dirafter");
     772                 :          0 :                     clang_argv.append(argv[i]);
     773         [ -  + ]:         44 :                 } else if (strcmp(arg, "-mllvm") == 0) {
     774                 :          0 :                     clang_argv.append("-mllvm");
     775                 :          0 :                     clang_argv.append(argv[i]);
     776                 :            : 
     777                 :          0 :                     llvm_argv.append(argv[i]);
     778         [ -  + ]:         44 :                 } else if (strcmp(arg, "--override-std-dir") == 0) {
     779                 :          0 :                     override_std_dir = buf_create_from_str(argv[i]);
     780         [ -  + ]:         44 :                 } else if (strcmp(arg, "--override-lib-dir") == 0) {
     781                 :          0 :                     override_lib_dir = buf_create_from_str(argv[i]);
     782         [ -  + ]:         44 :                 } else if (strcmp(arg, "--main-pkg-path") == 0) {
     783                 :          0 :                     main_pkg_path = buf_create_from_str(argv[i]);
     784 [ +  - ][ -  + ]:         44 :                 } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
     785                 :          0 :                     lib_dirs.append(argv[i]);
     786         [ -  + ]:         44 :                 } else if (strcmp(arg, "-F") == 0) {
     787                 :          0 :                     framework_dirs.append(argv[i]);
     788 [ +  + ][ -  + ]:         44 :                 } else if (strcmp(arg, "--library") == 0 || strcmp(arg, "-l") == 0) {
     789         [ +  - ]:          4 :                     if (strcmp(argv[i], "c") == 0)
     790                 :          4 :                         have_libc = true;
     791                 :          4 :                     link_libs.append(argv[i]);
     792         [ -  + ]:         40 :                 } else if (strcmp(arg, "--forbid-library") == 0) {
     793                 :          0 :                     forbidden_link_libs.append(argv[i]);
     794         [ -  + ]:         40 :                 } else if (strcmp(arg, "--object") == 0) {
     795                 :          0 :                     objects.append(argv[i]);
     796         [ -  + ]:         40 :                 } else if (strcmp(arg, "--c-source") == 0) {
     797                 :          0 :                     CFile *c_file = allocate<CFile>(1);
     798                 :            :                     for (;;) {
     799         [ #  # ]:          0 :                         if (argv[i][0] == '-') {
     800                 :          0 :                             c_file->args.append(argv[i]);
     801                 :          0 :                             i += 1;
     802         [ #  # ]:          0 :                             if (i < argc) {
     803                 :          0 :                                 continue;
     804                 :            :                             }
     805                 :            : 
     806                 :          0 :                             break;
     807                 :            :                         } else {
     808                 :          0 :                             c_file->source_path = argv[i];
     809                 :          0 :                             c_source_files.append(c_file);
     810                 :          0 :                             break;
     811                 :            :                         }
     812                 :            :                     }
     813         [ +  + ]:         40 :                 } else if (strcmp(arg, "--cache-dir") == 0) {
     814                 :         16 :                     cache_dir = argv[i];
     815         [ +  + ]:         24 :                 } else if (strcmp(arg, "-target") == 0) {
     816                 :          8 :                     target_string = argv[i];
     817         [ -  + ]:         16 :                 } else if (strcmp(arg, "-mmacosx-version-min") == 0) {
     818                 :          0 :                     mmacosx_version_min = argv[i];
     819         [ -  + ]:         16 :                 } else if (strcmp(arg, "-mios-version-min") == 0) {
     820                 :          0 :                     mios_version_min = argv[i];
     821         [ -  + ]:         16 :                 } else if (strcmp(arg, "-framework") == 0) {
     822                 :          0 :                     frameworks.append(argv[i]);
     823         [ -  + ]:         16 :                 } else if (strcmp(arg, "--linker-script") == 0) {
     824                 :          0 :                     linker_script = argv[i];
     825         [ -  + ]:         16 :                 } else if (strcmp(arg, "--version-script") == 0) {
     826                 :          0 :                     version_script = buf_create_from_str(argv[i]); 
     827         [ -  + ]:         16 :                 } else if (strcmp(arg, "-target-glibc") == 0) {
     828                 :          0 :                     target_glibc = argv[i];
     829         [ -  + ]:         16 :                 } else if (strcmp(arg, "-rpath") == 0) {
     830                 :          0 :                     rpath_list.append(argv[i]);
     831         [ -  + ]:         16 :                 } else if (strcmp(arg, "--test-filter") == 0) {
     832                 :          0 :                     test_filter = argv[i];
     833         [ +  - ]:         16 :                 } else if (strcmp(arg, "--test-name-prefix") == 0) {
     834                 :         16 :                     test_name_prefix = argv[i];
     835         [ #  # ]:          0 :                 } else if (strcmp(arg, "--ver-major") == 0) {
     836                 :          0 :                     ver_major = atoi(argv[i]);
     837         [ #  # ]:          0 :                 } else if (strcmp(arg, "--ver-minor") == 0) {
     838                 :          0 :                     ver_minor = atoi(argv[i]);
     839         [ #  # ]:          0 :                 } else if (strcmp(arg, "--ver-patch") == 0) {
     840                 :          0 :                     ver_patch = atoi(argv[i]);
     841         [ #  # ]:          0 :                 } else if (strcmp(arg, "--test-cmd") == 0) {
     842                 :          0 :                     test_exec_args.append(argv[i]);
     843         [ #  # ]:          0 :                 } else if (strcmp(arg, "--subsystem") == 0) {
     844         [ #  # ]:          0 :                     if (strcmp(argv[i], "console") == 0) {
     845                 :          0 :                         subsystem = TargetSubsystemConsole;
     846         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "windows") == 0) {
     847                 :          0 :                         subsystem = TargetSubsystemWindows;
     848         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "posix") == 0) {
     849                 :          0 :                         subsystem = TargetSubsystemPosix;
     850         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "native") == 0) {
     851                 :          0 :                         subsystem = TargetSubsystemNative;
     852         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "efi_application") == 0) {
     853                 :          0 :                         subsystem = TargetSubsystemEfiApplication;
     854         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "efi_boot_service_driver") == 0) {
     855                 :          0 :                         subsystem = TargetSubsystemEfiBootServiceDriver;
     856         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "efi_rom") == 0) {
     857                 :          0 :                         subsystem = TargetSubsystemEfiRom;
     858         [ #  # ]:          0 :                     } else if (strcmp(argv[i], "efi_runtime_driver") == 0) {
     859                 :          0 :                         subsystem = TargetSubsystemEfiRuntimeDriver;
     860                 :            :                     } else {
     861                 :          0 :                         fprintf(stderr, "invalid: --subsystem %s\n"
     862                 :            :                                 "Options are:\n"
     863                 :            :                                 "  console\n"
     864                 :            :                                 "  windows\n"
     865                 :            :                                 "  posix\n"
     866                 :            :                                 "  native\n"
     867                 :            :                                 "  efi_application\n"
     868                 :            :                                 "  efi_boot_service_driver\n"
     869                 :            :                                 "  efi_rom\n"
     870                 :            :                                 "  efi_runtime_driver\n"
     871                 :          0 :                             , argv[i]);
     872                 :          0 :                         return EXIT_FAILURE;
     873                 :            :                     }
     874                 :            :                 } else {
     875                 :          0 :                     fprintf(stderr, "Invalid argument: %s\n", arg);
     876                 :         68 :                     return print_error_usage(arg0);
     877                 :            :                 }
     878                 :            :             }
     879         [ +  + ]:         32 :         } else if (cmd == CmdNone) {
     880         [ -  + ]:         16 :             if (strcmp(arg, "build-exe") == 0) {
     881                 :          0 :                 cmd = CmdBuild;
     882                 :          0 :                 out_type = OutTypeExe;
     883         [ -  + ]:         16 :             } else if (strcmp(arg, "build-obj") == 0) {
     884                 :          0 :                 cmd = CmdBuild;
     885                 :          0 :                 out_type = OutTypeObj;
     886         [ -  + ]:         16 :             } else if (strcmp(arg, "build-lib") == 0) {
     887                 :          0 :                 cmd = CmdBuild;
     888                 :          0 :                 out_type = OutTypeLib;
     889         [ -  + ]:         16 :             } else if (strcmp(arg, "run") == 0) {
     890                 :          0 :                 cmd = CmdRun;
     891                 :          0 :                 out_type = OutTypeExe;
     892         [ -  + ]:         16 :             } else if (strcmp(arg, "version") == 0) {
     893                 :          0 :                 cmd = CmdVersion;
     894         [ -  + ]:         16 :             } else if (strcmp(arg, "zen") == 0) {
     895                 :          0 :                 cmd = CmdZen;
     896         [ -  + ]:         16 :             } else if (strcmp(arg, "libc") == 0) {
     897                 :          0 :                 cmd = CmdLibC;
     898         [ -  + ]:         16 :             } else if (strcmp(arg, "translate-c") == 0) {
     899                 :          0 :                 cmd = CmdTranslateC;
     900         [ -  + ]:         16 :             } else if (strcmp(arg, "translate-c-2") == 0) {
     901                 :          0 :                 cmd = CmdTranslateCUserland;
     902         [ +  - ]:         16 :             } else if (strcmp(arg, "test") == 0) {
     903                 :         16 :                 cmd = CmdTest;
     904                 :         16 :                 out_type = OutTypeExe;
     905         [ #  # ]:          0 :             } else if (strcmp(arg, "targets") == 0) {
     906                 :          0 :                 cmd = CmdTargets;
     907         [ #  # ]:          0 :             } else if (strcmp(arg, "builtin") == 0) {
     908                 :          0 :                 cmd = CmdBuiltin;
     909                 :            :             } else {
     910                 :          0 :                 fprintf(stderr, "Unrecognized command: %s\n", arg);
     911                 :          0 :                 return print_error_usage(arg0);
     912                 :            :             }
     913                 :            :         } else {
     914   [ +  -  -  - ]:         16 :             switch (cmd) {
     915                 :         16 :                 case CmdBuild:
     916                 :            :                 case CmdRun:
     917                 :            :                 case CmdTranslateC:
     918                 :            :                 case CmdTranslateCUserland:
     919                 :            :                 case CmdTest:
     920                 :            :                 case CmdLibC:
     921         [ +  - ]:         16 :                     if (!in_file) {
     922                 :         16 :                         in_file = arg;
     923                 :            :                     } else {
     924                 :          0 :                         fprintf(stderr, "Unexpected extra parameter: %s\n", arg);
     925                 :          0 :                         return print_error_usage(arg0);
     926                 :            :                     }
     927                 :         16 :                     break;
     928                 :          0 :                 case CmdBuiltin:
     929                 :            :                 case CmdVersion:
     930                 :            :                 case CmdZen:
     931                 :            :                 case CmdTargets:
     932                 :          0 :                     fprintf(stderr, "Unexpected extra parameter: %s\n", arg);
     933                 :          0 :                     return print_error_usage(arg0);
     934                 :          0 :                 case CmdNone:
     935                 :          0 :                     zig_unreachable();
     936                 :            :             }
     937                 :            :         }
     938                 :            :     }
     939                 :            : 
     940         [ -  + ]:         16 :     if (cur_pkg->parent != nullptr) {
     941                 :          0 :         fprintf(stderr, "Unmatched --pkg-begin\n");
     942                 :          0 :         return EXIT_FAILURE;
     943                 :            :     }
     944                 :            : 
     945                 :         16 :     init_all_targets();
     946                 :            : 
     947                 :            :     ZigTarget target;
     948         [ +  + ]:         16 :     if (target_string == nullptr) {
     949                 :          8 :         get_native_target(&target);
     950         [ -  + ]:          8 :         if (target_glibc != nullptr) {
     951                 :          0 :             fprintf(stderr, "-target-glibc provided but no -target parameter\n");
     952                 :          0 :             return print_error_usage(arg0);
     953                 :            :         }
     954                 :            :     } else {
     955         [ -  + ]:          8 :         if ((err = target_parse_triple(&target, target_string))) {
     956 [ #  # ][ #  # ]:          0 :             if (err == ErrorUnknownArchitecture && target.arch != ZigLLVM_UnknownArch) {
     957                 :          0 :                 fprintf(stderr, "'%s' requires a sub-architecture. Try one of these:\n",
     958                 :            :                         target_arch_name(target.arch));
     959                 :          0 :                 SubArchList sub_arch_list = target_subarch_list(target.arch);
     960                 :          0 :                 size_t subarch_count = target_subarch_count(sub_arch_list);
     961         [ #  # ]:          0 :                 for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) {
     962                 :          0 :                     ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
     963                 :          0 :                     fprintf(stderr, "  %s%s\n", target_arch_name(target.arch), target_subarch_name(sub));
     964                 :            :                 }
     965                 :          0 :                 return print_error_usage(arg0);
     966                 :            :             } else {
     967                 :          0 :                 fprintf(stderr, "invalid target: %s\n", err_str(err));
     968                 :          0 :                 return print_error_usage(arg0);
     969                 :            :             }
     970                 :            :         }
     971         [ -  + ]:          8 :         if (target_is_glibc(&target)) {
     972                 :          0 :             target.glibc_version = allocate<ZigGLibCVersion>(1);
     973                 :            : 
     974         [ #  # ]:          0 :             if (target_glibc != nullptr) {
     975         [ #  # ]:          0 :                 if ((err = target_parse_glibc_version(target.glibc_version, target_glibc))) {
     976                 :          0 :                     fprintf(stderr, "invalid glibc version '%s': %s\n", target_glibc, err_str(err));
     977                 :          0 :                     return print_error_usage(arg0);
     978                 :            :                 }
     979                 :            :             } else {
     980                 :            :                 // Default cross-compiling glibc version
     981                 :          0 :                 *target.glibc_version = {2, 17, 0};
     982                 :            :             }
     983         [ -  + ]:          8 :         } else if (target_glibc != nullptr) {
     984                 :          0 :             fprintf(stderr, "'%s' is not a glibc-compatible target", target_string);
     985                 :          0 :             return print_error_usage(arg0);
     986                 :            :         }
     987                 :            :     }
     988                 :            : 
     989 [ -  + ][ #  # ]:         16 :     if (output_dir != nullptr && enable_cache == CacheOptOn) {
     990                 :          0 :         fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n");
     991                 :          0 :         return print_error_usage(arg0);
     992                 :            :     }
     993                 :            : 
     994 [ +  + ][ -  + ]:         16 :     if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) {
                 [ -  + ]
     995                 :          0 :         Buf triple_buf = BUF_INIT;
     996                 :          0 :         target_triple_zig(&triple_buf, &target);
     997                 :          0 :         fprintf(stderr, "`--disable-pic` is incompatible with target '%s'\n", buf_ptr(&triple_buf));
     998                 :          0 :         return print_error_usage(arg0);
     999                 :            :     }
    1000                 :            : 
    1001 [ -  + ][ #  # ]:         16 :     if (emit_file_type != EmitFileTypeBinary && in_file == nullptr) {
    1002                 :          0 :         fprintf(stderr, "A root source file is required when using `--emit asm` or `--emit llvm-ir`\n");
    1003                 :          0 :         return print_error_usage(arg0);
    1004                 :            :     }
    1005                 :            : 
    1006         [ -  + ]:         16 :     if (llvm_argv.length > 1) {
    1007                 :          0 :         llvm_argv.append(nullptr);
    1008                 :          0 :         ZigLLVMParseCommandLineOptions(llvm_argv.length - 1, llvm_argv.items);
    1009                 :            :     }
    1010                 :            : 
    1011   [ -  -  +  -  :         16 :     switch (cmd) {
             -  -  -  - ]
    1012                 :          0 :     case CmdLibC: {
    1013         [ #  # ]:          0 :         if (in_file) {
    1014                 :            :             ZigLibCInstallation libc;
    1015         [ #  # ]:          0 :             if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true)))
    1016                 :          0 :                 return EXIT_FAILURE;
    1017                 :          0 :             return EXIT_SUCCESS;
    1018                 :            :         }
    1019                 :            :         ZigLibCInstallation libc;
    1020         [ #  # ]:          0 :         if ((err = zig_libc_find_native(&libc, true)))
    1021                 :          0 :             return EXIT_FAILURE;
    1022                 :          0 :         zig_libc_render(&libc, stdout);
    1023                 :          0 :         return EXIT_SUCCESS;
    1024                 :            :     }
    1025                 :          0 :     case CmdBuiltin: {
    1026                 :            :         CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
    1027                 :          0 :                 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr, false);
    1028                 :          0 :         codegen_set_strip(g, strip);
    1029         [ #  # ]:          0 :         for (size_t i = 0; i < link_libs.length; i += 1) {
    1030                 :          0 :             LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i)));
    1031                 :          0 :             link_lib->provided_explicitly = true;
    1032                 :            :         }
    1033                 :          0 :         g->subsystem = subsystem;
    1034                 :          0 :         g->valgrind_support = valgrind_support;
    1035                 :          0 :         g->want_pic = want_pic;
    1036                 :          0 :         g->want_stack_check = want_stack_check;
    1037                 :          0 :         g->want_single_threaded = want_single_threaded;
    1038                 :          0 :         Buf *builtin_source = codegen_generate_builtin_source(g);
    1039         [ #  # ]:          0 :         if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
    1040                 :          0 :             fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout)));
    1041                 :          0 :             return EXIT_FAILURE;
    1042                 :            :         }
    1043                 :          0 :         return EXIT_SUCCESS;
    1044                 :            :     }
    1045                 :         16 :     case CmdRun:
    1046                 :            :     case CmdBuild:
    1047                 :            :     case CmdTranslateC:
    1048                 :            :     case CmdTranslateCUserland:
    1049                 :            :     case CmdTest:
    1050                 :            :         {
    1051 [ -  + ][ #  # ]:         16 :             if (cmd == CmdBuild && !in_file && objects.length == 0 &&
         [ #  # ][ #  # ]
    1052                 :          0 :                     c_source_files.length == 0)
    1053                 :            :             {
    1054                 :          0 :                 fprintf(stderr,
    1055                 :            :                     "Expected at least one of these things:\n"
    1056                 :            :                     " * Zig root source file argument\n"
    1057                 :            :                     " * --object argument\n"
    1058                 :            :                     " * --c-source argument\n");
    1059                 :          0 :                 return print_error_usage(arg0);
    1060 [ +  - ][ +  - ]:         16 :             } else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland ||
                 [ -  + ]
    1061 [ #  # ][ -  + ]:         16 :                         cmd == CmdTest || cmd == CmdRun) && !in_file)
    1062                 :            :             {
    1063                 :          0 :                 fprintf(stderr, "Expected source file argument.\n");
    1064                 :          0 :                 return print_error_usage(arg0);
    1065 [ -  + ][ #  # ]:         16 :             } else if (cmd == CmdRun && emit_file_type != EmitFileTypeBinary) {
    1066                 :          0 :                 fprintf(stderr, "Cannot run non-executable file.\n");
    1067                 :          0 :                 return print_error_usage(arg0);
    1068                 :            :             }
    1069                 :            : 
    1070 [ -  + ][ #  # ]:         16 :             assert(cmd != CmdBuild || out_type != OutTypeUnknown);
    1071                 :            : 
    1072 [ +  - ][ -  + ]:         16 :             bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland);
                 [ +  - ]
    1073                 :            : 
    1074         [ -  + ]:         16 :             if (cmd == CmdRun) {
    1075                 :          0 :                 out_name = "run";
    1076                 :            :             }
    1077                 :            : 
    1078                 :         16 :             Buf *in_file_buf = nullptr;
    1079                 :            : 
    1080         [ +  - ]:         16 :             Buf *buf_out_name = (cmd == CmdTest) ? buf_create_from_str("test") :
    1081         [ #  # ]:          0 :                 (out_name == nullptr) ? nullptr : buf_create_from_str(out_name);
    1082                 :            : 
    1083         [ +  - ]:         16 :             if (in_file) {
    1084                 :         16 :                 in_file_buf = buf_create_from_str(in_file);
    1085                 :            : 
    1086 [ #  # ][ -  + ]:         16 :                 if (need_name && buf_out_name == nullptr) {
    1087                 :          0 :                     Buf basename = BUF_INIT;
    1088                 :          0 :                     os_path_split(in_file_buf, nullptr, &basename);
    1089                 :          0 :                     buf_out_name = buf_alloc();
    1090                 :         16 :                     os_path_extname(&basename, buf_out_name, nullptr);
    1091                 :            :                 }
    1092                 :            :             }
    1093                 :            : 
    1094 [ -  + ][ #  # ]:         16 :             if (need_name && buf_out_name == nullptr && c_source_files.length == 1) {
                 [ #  # ]
    1095                 :          0 :                 Buf basename = BUF_INIT;
    1096                 :          0 :                 os_path_split(buf_create_from_str(c_source_files.at(0)->source_path), nullptr, &basename);
    1097                 :          0 :                 buf_out_name = buf_alloc();
    1098                 :          0 :                 os_path_extname(&basename, buf_out_name, nullptr);
    1099                 :            :             }
    1100                 :            : 
    1101 [ -  + ][ #  # ]:         16 :             if (need_name && buf_out_name == nullptr) {
    1102                 :          0 :                 fprintf(stderr, "--name [name] not provided and unable to infer\n\n");
    1103                 :          0 :                 return print_error_usage(arg0);
    1104                 :            :             }
    1105                 :            : 
    1106 [ +  - ][ +  - ]:         16 :             Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ?
    1107                 :            :                 nullptr : in_file_buf;
    1108                 :            : 
    1109 [ -  + ][ #  # ]:         16 :             if (cmd == CmdRun && buf_out_name == nullptr) {
    1110                 :          0 :                 buf_out_name = buf_create_from_str("run");
    1111                 :            :             }
    1112                 :         16 :             ZigLibCInstallation *libc = nullptr;
    1113         [ -  + ]:         16 :             if (libc_txt != nullptr) {
    1114                 :          0 :                 libc = allocate<ZigLibCInstallation>(1);
    1115         [ #  # ]:          0 :                 if ((err = zig_libc_parse(libc, buf_create_from_str(libc_txt), &target, true))) {
    1116                 :          0 :                     fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err));
    1117                 :          0 :                     return EXIT_FAILURE;
    1118                 :            :                 }
    1119                 :            :             }
    1120                 :            :             Buf *cache_dir_buf;
    1121         [ -  + ]:         16 :             if (cache_dir == nullptr) {
    1122         [ #  # ]:          0 :                 if (cmd == CmdRun) {
    1123                 :          0 :                     cache_dir_buf = get_stage1_cache_path();
    1124                 :            :                 } else {
    1125                 :          0 :                     cache_dir_buf = buf_create_from_str(default_zig_cache_name);
    1126                 :            :                 }
    1127                 :            :             } else {
    1128                 :         16 :                 cache_dir_buf = buf_create_from_str(cache_dir);
    1129                 :            :             }
    1130                 :         16 :             CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,
    1131                 :         16 :                     override_lib_dir, override_std_dir, libc, cache_dir_buf, cmd == CmdTest);
    1132         [ -  + ]:         16 :             if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
    1133                 :         16 :             g->valgrind_support = valgrind_support;
    1134                 :         16 :             g->want_pic = want_pic;
    1135                 :         16 :             g->want_stack_check = want_stack_check;
    1136                 :         16 :             g->subsystem = subsystem;
    1137                 :            : 
    1138                 :         16 :             g->enable_time_report = timing_info;
    1139                 :         16 :             codegen_set_out_name(g, buf_out_name);
    1140                 :         16 :             codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
    1141                 :         16 :             g->want_single_threaded = want_single_threaded;
    1142                 :         16 :             codegen_set_linker_script(g, linker_script);
    1143                 :         16 :             g->version_script_path = version_script; 
    1144         [ -  + ]:         16 :             if (each_lib_rpath)
    1145                 :          0 :                 codegen_set_each_lib_rpath(g, each_lib_rpath);
    1146                 :            : 
    1147                 :         16 :             codegen_set_clang_argv(g, clang_argv.items, clang_argv.length);
    1148                 :            : 
    1149                 :         16 :             codegen_set_strip(g, strip);
    1150                 :         16 :             g->is_dynamic = is_dynamic;
    1151                 :         16 :             g->dynamic_linker_path = dynamic_linker;
    1152                 :         16 :             g->verbose_tokenize = verbose_tokenize;
    1153                 :         16 :             g->verbose_ast = verbose_ast;
    1154                 :         16 :             g->verbose_link = verbose_link;
    1155                 :         16 :             g->verbose_ir = verbose_ir;
    1156                 :         16 :             g->verbose_llvm_ir = verbose_llvm_ir;
    1157                 :         16 :             g->verbose_cimport = verbose_cimport;
    1158                 :         16 :             g->verbose_cc = verbose_cc;
    1159                 :         16 :             g->output_dir = output_dir;
    1160                 :         16 :             g->disable_gen_h = disable_gen_h;
    1161                 :         16 :             g->bundle_compiler_rt = bundle_compiler_rt;
    1162                 :         16 :             codegen_set_errmsg_color(g, color);
    1163                 :         16 :             g->system_linker_hack = system_linker_hack;
    1164                 :         16 :             g->function_sections = function_sections;
    1165                 :            : 
    1166         [ -  + ]:         16 :             for (size_t i = 0; i < lib_dirs.length; i += 1) {
    1167                 :          0 :                 codegen_add_lib_dir(g, lib_dirs.at(i));
    1168                 :            :             }
    1169         [ -  + ]:         16 :             for (size_t i = 0; i < framework_dirs.length; i += 1) {
    1170                 :          0 :                 g->framework_dirs.append(framework_dirs.at(i));
    1171                 :            :             }
    1172         [ +  + ]:         20 :             for (size_t i = 0; i < link_libs.length; i += 1) {
    1173                 :          4 :                 LinkLib *link_lib = codegen_add_link_lib(g, buf_create_from_str(link_libs.at(i)));
    1174                 :          4 :                 link_lib->provided_explicitly = true;
    1175                 :            :             }
    1176         [ -  + ]:         16 :             for (size_t i = 0; i < forbidden_link_libs.length; i += 1) {
    1177                 :          0 :                 Buf *forbidden_link_lib = buf_create_from_str(forbidden_link_libs.at(i));
    1178                 :          0 :                 codegen_add_forbidden_lib(g, forbidden_link_lib);
    1179                 :            :             }
    1180         [ -  + ]:         16 :             for (size_t i = 0; i < frameworks.length; i += 1) {
    1181                 :          0 :                 codegen_add_framework(g, frameworks.at(i));
    1182                 :            :             }
    1183         [ -  + ]:         16 :             for (size_t i = 0; i < rpath_list.length; i += 1) {
    1184                 :          0 :                 codegen_add_rpath(g, rpath_list.at(i));
    1185                 :            :             }
    1186                 :            : 
    1187                 :         16 :             codegen_set_rdynamic(g, rdynamic);
    1188 [ #  # ][ -  + ]:         16 :             if (mmacosx_version_min && mios_version_min) {
    1189                 :          0 :                 fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n");
    1190                 :          0 :                 return EXIT_FAILURE;
    1191                 :            :             }
    1192                 :            : 
    1193         [ -  + ]:         16 :             if (mmacosx_version_min) {
    1194                 :          0 :                 codegen_set_mmacosx_version_min(g, buf_create_from_str(mmacosx_version_min));
    1195                 :            :             }
    1196                 :            : 
    1197         [ -  + ]:         16 :             if (mios_version_min) {
    1198                 :          0 :                 codegen_set_mios_version_min(g, buf_create_from_str(mios_version_min));
    1199                 :            :             }
    1200                 :            : 
    1201         [ -  + ]:         16 :             if (test_filter) {
    1202                 :          0 :                 codegen_set_test_filter(g, buf_create_from_str(test_filter));
    1203                 :            :             }
    1204                 :            : 
    1205         [ +  - ]:         16 :             if (test_name_prefix) {
    1206                 :         16 :                 codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix));
    1207                 :            :             }
    1208                 :            : 
    1209                 :         16 :             add_package(g, cur_pkg, g->root_package);
    1210                 :            : 
    1211 [ +  - ][ +  - ]:         16 :             if (cmd == CmdBuild || cmd == CmdRun || cmd == CmdTest) {
                 [ +  - ]
    1212                 :         16 :                 g->c_source_files = c_source_files;
    1213         [ -  + ]:         16 :                 for (size_t i = 0; i < objects.length; i += 1) {
    1214                 :          0 :                     codegen_add_object(g, buf_create_from_str(objects.at(i)));
    1215                 :            :                 }
    1216                 :            :             }
    1217                 :            : 
    1218                 :            : 
    1219 [ +  - ][ -  + ]:         16 :             if (cmd == CmdBuild || cmd == CmdRun) {
    1220                 :          0 :                 codegen_set_emit_file_type(g, emit_file_type);
    1221                 :            : 
    1222                 :          0 :                 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);
    1223                 :          0 :                 codegen_build_and_link(g);
    1224         [ #  # ]:          0 :                 if (timing_info)
    1225                 :          0 :                     codegen_print_timing_report(g, stdout);
    1226                 :            : 
    1227         [ #  # ]:          0 :                 if (cmd == CmdRun) {
    1228                 :          0 :                     const char *exec_path = buf_ptr(&g->output_file_path);
    1229                 :          0 :                     ZigList<const char*> args = {0};
    1230                 :            : 
    1231                 :          0 :                     args.append(exec_path);
    1232         [ #  # ]:          0 :                     if (runtime_args_start != -1) {
    1233         [ #  # ]:          0 :                         for (int i = runtime_args_start; i < argc; ++i) {
    1234                 :          0 :                             args.append(argv[i]);
    1235                 :            :                         }
    1236                 :            :                     }
    1237                 :          0 :                     args.append(nullptr);
    1238                 :            : 
    1239                 :          0 :                     os_execv(exec_path, args.items);
    1240                 :            : 
    1241                 :          0 :                     args.pop();
    1242                 :            :                     Termination term;
    1243                 :          0 :                     os_spawn_process(args, &term);
    1244                 :          0 :                     return term.code;
    1245         [ #  # ]:          0 :                 } else if (cmd == CmdBuild) {
    1246         [ #  # ]:          0 :                     if (g->enable_cache) {
    1247                 :            : #if defined(ZIG_OS_WINDOWS)
    1248                 :            :                         buf_replace(&g->output_file_path, '/', '\\');
    1249                 :            : #endif
    1250         [ #  # ]:          0 :                         if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0)
    1251                 :          0 :                             return EXIT_FAILURE;
    1252                 :            :                     }
    1253                 :          0 :                     return EXIT_SUCCESS;
    1254                 :            :                 } else {
    1255                 :          0 :                     zig_unreachable();
    1256                 :            :                 }
    1257 [ +  - ][ -  + ]:         16 :             } else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) {
    1258                 :          0 :                 codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland);
    1259         [ #  # ]:          0 :                 if (timing_info)
    1260                 :          0 :                     codegen_print_timing_report(g, stderr);
    1261                 :          0 :                 return EXIT_SUCCESS;
    1262         [ +  - ]:         16 :             } else if (cmd == CmdTest) {
    1263                 :         16 :                 codegen_set_emit_file_type(g, emit_file_type);
    1264                 :            : 
    1265                 :            :                 ZigTarget native;
    1266                 :         16 :                 get_native_target(&native);
    1267                 :            : 
    1268                 :         16 :                 g->enable_cache = get_cache_opt(enable_cache, output_dir == nullptr);
    1269                 :         16 :                 codegen_build_and_link(g);
    1270                 :            : 
    1271         [ -  + ]:         16 :                 if (timing_info) {
    1272                 :          0 :                     codegen_print_timing_report(g, stdout);
    1273                 :            :                 }
    1274                 :            : 
    1275                 :         16 :                 Buf *test_exe_path_unresolved = &g->output_file_path;
    1276                 :         16 :                 Buf *test_exe_path = buf_alloc();
    1277                 :         16 :                 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);
    1278                 :            : 
    1279         [ -  + ]:         16 :                 if (emit_file_type != EmitFileTypeBinary) {
    1280                 :          0 :                     fprintf(stderr, "Created %s but skipping execution because it is non executable.\n",
    1281                 :            :                             buf_ptr(test_exe_path));
    1282                 :          0 :                     return 0;
    1283                 :            :                 }
    1284                 :            : 
    1285         [ -  + ]:         16 :                 for (size_t i = 0; i < test_exec_args.length; i += 1) {
    1286         [ #  # ]:          0 :                     if (test_exec_args.items[i] == nullptr) {
    1287                 :          0 :                         test_exec_args.items[i] = buf_ptr(test_exe_path);
    1288                 :            :                     }
    1289                 :            :                 }
    1290                 :            : 
    1291         [ +  + ]:         16 :                 if (!target_can_exec(&native, &target)) {
    1292                 :          8 :                     fprintf(stderr, "Created %s but skipping execution because it is non-native.\n",
    1293                 :            :                             buf_ptr(test_exe_path));
    1294                 :          8 :                     return 0;
    1295                 :            :                 }
    1296                 :            : 
    1297                 :            :                 Termination term;
    1298         [ +  - ]:          8 :                 if (test_exec_args.length == 0) {
    1299                 :          8 :                     test_exec_args.append(buf_ptr(test_exe_path));
    1300                 :            :                 }
    1301                 :          8 :                 os_spawn_process(test_exec_args, &term);
    1302 [ -  + ][ +  - ]:          8 :                 if (term.how != TerminationIdClean || term.code != 0) {
    1303                 :          0 :                     fprintf(stderr, "\nTests failed. Use the following command to reproduce the failure:\n");
    1304                 :          0 :                     fprintf(stderr, "%s\n", buf_ptr(test_exe_path));
    1305                 :            :                 }
    1306         [ +  - ]:         16 :                 return (term.how == TerminationIdClean) ? term.code : -1;
    1307                 :            :             } else {
    1308                 :          0 :                 zig_unreachable();
    1309                 :            :             }
    1310                 :            :         }
    1311                 :          0 :     case CmdVersion:
    1312                 :          0 :         printf("%s\n", ZIG_VERSION_STRING);
    1313                 :          0 :         return EXIT_SUCCESS;
    1314                 :          0 :     case CmdZen: {
    1315                 :            :         const char *ptr;
    1316                 :            :         size_t len;
    1317                 :          0 :         stage2_zen(&ptr, &len);
    1318                 :          0 :         fwrite(ptr, len, 1, stdout);
    1319                 :          0 :         return EXIT_SUCCESS;
    1320                 :            :     }
    1321                 :          0 :     case CmdTargets:
    1322                 :          0 :         return print_target_list(stdout);
    1323                 :          0 :     case CmdNone:
    1324                 :          0 :         return print_full_usage(arg0, stderr, EXIT_FAILURE);
    1325                 :            :     }
    1326                 :          0 : }

Generated by: LCOV version 1.14