kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

cflags.c (5526B)


      1 #include "cflags.h"
      2 
      3 #include <stddef.h>
      4 #include <stdint.h>
      5 
      6 int driver_cflags_init(DriverCflags* cf, DriverEnv* env, int argc_bound) {
      7   size_t bound = argc_bound > 0 ? (size_t)argc_bound + 4u : 4u;
      8   cf->_cap = bound;
      9   cf->include_dirs =
     10       driver_alloc_zeroed(env, bound * sizeof(*cf->include_dirs));
     11   cf->system_include_dirs =
     12       driver_alloc_zeroed(env, bound * sizeof(*cf->system_include_dirs));
     13   cf->defines = driver_alloc_zeroed(env, bound * sizeof(*cf->defines));
     14   cf->_owned_define_names =
     15       driver_alloc_zeroed(env, bound * sizeof(*cf->_owned_define_names));
     16   cf->_owned_define_name_sizes =
     17       driver_alloc_zeroed(env, bound * sizeof(*cf->_owned_define_name_sizes));
     18   cf->undefines = driver_alloc_zeroed(env, bound * sizeof(*cf->undefines));
     19   if (!cf->include_dirs || !cf->system_include_dirs || !cf->defines ||
     20       !cf->_owned_define_names || !cf->_owned_define_name_sizes ||
     21       !cf->undefines) {
     22     return 1;
     23   }
     24   return 0;
     25 }
     26 
     27 void driver_cflags_fini(DriverCflags* cf, DriverEnv* env) {
     28   size_t cap = cf->_cap;
     29   uint32_t i;
     30   if (cf->_owned_define_names) {
     31     for (i = 0; i < cf->ndefines; ++i) {
     32       if (cf->_owned_define_names[i]) {
     33         driver_free(env, cf->_owned_define_names[i],
     34                     cf->_owned_define_name_sizes[i]);
     35       }
     36     }
     37   }
     38   driver_free(env, cf->include_dirs, cap * sizeof(*cf->include_dirs));
     39   driver_free(env, cf->system_include_dirs,
     40               cap * sizeof(*cf->system_include_dirs));
     41   driver_free(env, cf->defines, cap * sizeof(*cf->defines));
     42   driver_free(env, cf->_owned_define_names,
     43               cap * sizeof(*cf->_owned_define_names));
     44   driver_free(env, cf->_owned_define_name_sizes,
     45               cap * sizeof(*cf->_owned_define_name_sizes));
     46   driver_free(env, cf->undefines, cap * sizeof(*cf->undefines));
     47   cf->_cap = 0;
     48 }
     49 
     50 /* Split `name[=body]` into a heap-owned NUL-terminated name and a body that
     51  * aliases the original argv tail. Returns 0 on success, 1 on alloc failure. */
     52 static int cflags_record_define(DriverCflags* cf, DriverEnv* env,
     53                                 const char* arg) {
     54   const char* eq = driver_strchr(arg, '=');
     55   KitDefine* d = &cf->defines[cf->ndefines];
     56   if (eq) {
     57     size_t n = (size_t)(eq - arg);
     58     size_t bytes = n + 1;
     59     char* name = driver_alloc(env, bytes);
     60     if (!name) return 1;
     61     driver_memcpy(name, arg, n);
     62     name[n] = '\0';
     63     cf->_owned_define_names[cf->ndefines] = name;
     64     cf->_owned_define_name_sizes[cf->ndefines] = bytes;
     65     d->name = (KitSlice){.s = name, .len = n};
     66     d->body = kit_slice_cstr(eq + 1);
     67   } else {
     68     d->name = kit_slice_cstr(arg);
     69     d->body = KIT_SLICE_NULL;
     70   }
     71   cf->ndefines++;
     72   return 0;
     73 }
     74 
     75 /* Pull the value for a flag that accepts either `-Xvalue` or `-X value`.
     76  * `prefix_len` is the byte length of `-X` itself (e.g. 2 for `-I`/`-D`/`-U`,
     77  * larger for `-isystem`). On the attached form (`-Xvalue`) returns argv[*i]
     78  * + prefix_len without advancing. On the separate form, advances *i to the
     79  * value slot and returns argv[*i]; if no value follows, reports a diagnostic
     80  * and returns NULL. */
     81 static const char* cflags_pull_value(const char* tool, int argc, char** argv,
     82                                      int* i, size_t prefix_len,
     83                                      const char* flag_label) {
     84   const char* a = argv[*i];
     85   if (a[prefix_len]) return a + prefix_len;
     86   if (++(*i) >= argc) {
     87     driver_errf(tool, "%.*s requires an argument",
     88                 KIT_SLICE_ARG(kit_slice_cstr(flag_label)));
     89     return NULL;
     90   }
     91   return argv[*i];
     92 }
     93 
     94 int driver_cflags_try_consume(DriverCflags* cf, DriverEnv* env,
     95                               const char* tool, int argc, char** argv, int* i) {
     96   const char* a = argv[*i];
     97 
     98   if (driver_strneq(a, "-I", 2)) {
     99     const char* dir = cflags_pull_value(tool, argc, argv, i, 2, "-I");
    100     if (!dir) return -1;
    101     cf->include_dirs[cf->ninclude_dirs++] = dir;
    102     return 1;
    103   }
    104 
    105   if (driver_streq(a, "-isystem")) {
    106     if (++(*i) >= argc) {
    107       driver_errf(tool, "-isystem requires an argument");
    108       return -1;
    109     }
    110     cf->system_include_dirs[cf->nsystem_include_dirs++] = argv[*i];
    111     return 1;
    112   }
    113 
    114   if (driver_strneq(a, "-iquote", 7)) {
    115     const char* dir = cflags_pull_value(tool, argc, argv, i, 7, "-iquote");
    116     if (!dir) return -1;
    117     cf->include_dirs[cf->ninclude_dirs++] = dir;
    118     return 1;
    119   }
    120 
    121   if (driver_strneq(a, "-idirafter", 10)) {
    122     const char* dir = cflags_pull_value(tool, argc, argv, i, 10, "-idirafter");
    123     if (!dir) return -1;
    124     cf->system_include_dirs[cf->nsystem_include_dirs++] = dir;
    125     return 1;
    126   }
    127 
    128   if (driver_strneq(a, "-D", 2)) {
    129     const char* arg = cflags_pull_value(tool, argc, argv, i, 2, "-D");
    130     if (!arg) return -1;
    131     if (cflags_record_define(cf, env, arg) != 0) {
    132       driver_errf(tool, "out of memory");
    133       return -1;
    134     }
    135     return 1;
    136   }
    137 
    138   if (driver_strneq(a, "-U", 2)) {
    139     const char* arg = cflags_pull_value(tool, argc, argv, i, 2, "-U");
    140     if (!arg) return -1;
    141     cf->undefines[cf->nundefines++] = kit_slice_cstr(arg);
    142     return 1;
    143   }
    144 
    145   return 0;
    146 }
    147 
    148 void driver_cflags_fill_pp(const DriverCflags* cf, KitPreprocessOptions* pp) {
    149   KitPreprocessOptions z = {0};
    150   *pp = z;
    151   pp->include_dirs = cf->include_dirs;
    152   pp->ninclude_dirs = cf->ninclude_dirs;
    153   pp->system_include_dirs = cf->system_include_dirs;
    154   pp->nsystem_include_dirs = cf->nsystem_include_dirs;
    155   pp->defines = cf->defines;
    156   pp->ndefines = cf->ndefines;
    157   pp->undefines = cf->undefines;
    158   pp->nundefines = cf->nundefines;
    159 }