kit

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

hosted.c (9767B)


      1 #include "os/hosted_internal.h"
      2 
      3 #include <stdarg.h>
      4 #include <string.h>
      5 
      6 void kit_os_hosted_errf(const KitOsHostedHost* host, void* host_user,
      7                         const char* tool, const char* fmt, ...) {
      8   va_list ap;
      9   if (!host || !host->vdiagf) return;
     10   va_start(ap, fmt);
     11   host->vdiagf(host_user, tool, fmt, ap);
     12   va_end(ap);
     13 }
     14 
     15 int kit_os_hosted_add_input(KitOsHostedInput* items, uint32_t* n, uint32_t cap,
     16                             uint8_t kind, char* path, size_t path_size) {
     17   KitOsHostedInput* it;
     18   if (*n >= cap) return 1;
     19   it = &items[*n];
     20   it->kind = kind;
     21   it->path = path;
     22   it->owned_path = path;
     23   it->owned_size = path_size;
     24   (*n)++;
     25   return 0;
     26 }
     27 
     28 static int hosted_store(const KitOsHostedHost* host, void* host_user,
     29                         char** arr, size_t* sizes, uint32_t* n, uint32_t cap,
     30                         const char* a, const char* b) {
     31   size_t bytes;
     32   char* out;
     33   if (!a || !a[0]) return 0;
     34   if (*n >= cap || !host || !host->path_join) return 1;
     35   out = host->path_join(host_user, a, b, &bytes);
     36   if (!out) return 1;
     37   arr[*n] = out;
     38   sizes[*n] = bytes;
     39   (*n)++;
     40   return 0;
     41 }
     42 
     43 int kit_os_hosted_dirs_add_inc(KitOsHostedDirs* dirs, const char* dir) {
     44   if (!dirs) return 1;
     45   return hosted_store(dirs->host, dirs->host_user, dirs->incdirs,
     46                       dirs->incdir_sizes, &dirs->nincdirs,
     47                       KIT_OS_HOSTED_MAX_INCDIRS, dir, NULL);
     48 }
     49 
     50 int kit_os_hosted_dirs_add_lib(KitOsHostedDirs* dirs, const char* dir) {
     51   if (!dirs) return 1;
     52   return hosted_store(dirs->host, dirs->host_user, dirs->libdirs,
     53                       dirs->libdir_sizes, &dirs->nlibdirs,
     54                       KIT_OS_HOSTED_MAX_LIBDIRS, dir, NULL);
     55 }
     56 
     57 int kit_os_hosted_dirs_add_inc_join(KitOsHostedDirs* dirs, const char* base,
     58                                     const char* sub) {
     59   if (!dirs) return 1;
     60   return hosted_store(dirs->host, dirs->host_user, dirs->incdirs,
     61                       dirs->incdir_sizes, &dirs->nincdirs,
     62                       KIT_OS_HOSTED_MAX_INCDIRS, base, sub);
     63 }
     64 
     65 int kit_os_hosted_dirs_add_lib_join(KitOsHostedDirs* dirs, const char* base,
     66                                     const char* sub) {
     67   if (!dirs) return 1;
     68   return hosted_store(dirs->host, dirs->host_user, dirs->libdirs,
     69                       dirs->libdir_sizes, &dirs->nlibdirs,
     70                       KIT_OS_HOSTED_MAX_LIBDIRS, base, sub);
     71 }
     72 
     73 void kit_os_hosted_dirs_fini(KitOsHostedDirs* dirs) {
     74   uint32_t i;
     75   if (!dirs || !dirs->host || !dirs->host->free) return;
     76   for (i = 0; i < dirs->nincdirs; ++i)
     77     dirs->host->free(dirs->host_user, dirs->incdirs[i], dirs->incdir_sizes[i]);
     78   for (i = 0; i < dirs->nlibdirs; ++i)
     79     dirs->host->free(dirs->host_user, dirs->libdirs[i], dirs->libdir_sizes[i]);
     80   dirs->nincdirs = 0;
     81   dirs->nlibdirs = 0;
     82 }
     83 
     84 char* kit_os_hosted_find_in_libdirs(const KitOsHostedHost* host,
     85                                     void* host_user,
     86                                     const KitOsHostedDirs* dirs,
     87                                     const char* file, size_t* out_size) {
     88   uint32_t i;
     89   if (!host || !host->path_join || !host->path_exists || !host->free || !dirs)
     90     return NULL;
     91   for (i = 0; i < dirs->nlibdirs; ++i) {
     92     size_t size = 0;
     93     char* path = host->path_join(host_user, dirs->libdirs[i], file, &size);
     94     if (!path) return NULL;
     95     if (host->path_exists(host_user, path)) {
     96       if (out_size) *out_size = size;
     97       return path;
     98     }
     99     host->free(host_user, path, size);
    100   }
    101   return NULL;
    102 }
    103 
    104 int kit_os_hosted_libdir_has(const KitOsHostedHost* host, void* host_user,
    105                              const KitOsHostedDirs* dirs, const char* file) {
    106   size_t size = 0;
    107   char* path = kit_os_hosted_find_in_libdirs(host, host_user, dirs, file, &size);
    108   if (!path) return 0;
    109   host->free(host_user, path, size);
    110   return 1;
    111 }
    112 
    113 int kit_os_hosted_add_required_search(KitOsHostedInput* items, uint32_t* n,
    114                                       uint32_t cap,
    115                                       const KitOsHostedRequest* req,
    116                                       const KitOsHostedDirs* dirs,
    117                                       const char* file, uint8_t kind) {
    118   size_t size = 0;
    119   char* path = kit_os_hosted_find_in_libdirs(req->host, req->host_user, dirs,
    120                                             file, &size);
    121   if (!path) {
    122     kit_os_hosted_errf(req->host, req->host_user, req->tool,
    123                        "hosted profile missing required file: %s (searched %u "
    124                        "library dir(s))",
    125                        file, (unsigned)dirs->nlibdirs);
    126     return 1;
    127   }
    128   if (kit_os_hosted_add_input(items, n, cap, kind, path, size) != 0) {
    129     kit_os_hosted_errf(req->host, req->host_user, req->tool,
    130                        "too many hosted inputs");
    131     req->host->free(req->host_user, path, size);
    132     return 1;
    133   }
    134   return 0;
    135 }
    136 
    137 static int hosted_add_existing_include(KitOsHostedPlan* plan,
    138                                        const KitOsHostedHost* host,
    139                                        void* host_user, const char* dir) {
    140   size_t len, bytes;
    141   char* path;
    142   if (plan->nsystem_includes >= KIT_OS_HOSTED_MAX_INCLUDES) return 1;
    143   if (!host || !host->path_exists || !host->alloc) return 1;
    144   if (!host->path_exists(host_user, dir)) return 0;
    145   len = strlen(dir);
    146   bytes = len + 1u;
    147   path = host->alloc(host_user, bytes);
    148   if (!path) return 1;
    149   memcpy(path, dir, len);
    150   path[len] = '\0';
    151   plan->system_includes[plan->nsystem_includes] = path;
    152   plan->owned_system_includes[plan->nsystem_includes] = path;
    153   plan->owned_system_include_sizes[plan->nsystem_includes] = bytes;
    154   plan->nsystem_includes++;
    155   return 0;
    156 }
    157 
    158 int kit_os_hosted_add_incdirs(KitOsHostedPlan* plan,
    159                               const KitOsHostedHost* host, void* host_user,
    160                               const KitOsHostedDirs* dirs) {
    161   uint32_t i;
    162   for (i = 0; i < dirs->nincdirs; ++i) {
    163     if (hosted_add_existing_include(plan, host, host_user, dirs->incdirs[i]) !=
    164         0)
    165       return 1;
    166   }
    167   return 0;
    168 }
    169 
    170 int kit_os_hosted_add_define(KitOsHostedPlan* plan, const char* name,
    171                              const char* body) {
    172   if (plan->ndefines >= KIT_OS_HOSTED_MAX_DEFINES) return 1;
    173   plan->defines[plan->ndefines].name = kit_slice_cstr(name);
    174   plan->defines[plan->ndefines].body = kit_slice_cstr(body);
    175   plan->ndefines++;
    176   return 0;
    177 }
    178 
    179 int kit_os_hosted_add_define_owned(KitOsHostedPlan* plan,
    180                                    const KitOsHostedHost* host,
    181                                    void* host_user, const char* name,
    182                                    const char* body) {
    183   size_t index, len, size;
    184   char* copy;
    185   if (!plan || !host || !host->alloc || !host->free || !name || !body)
    186     return 1;
    187   if (plan->ndefines >= KIT_OS_HOSTED_MAX_DEFINES) return 1;
    188   len = strlen(body);
    189   size = len + 1u;
    190   copy = (char*)host->alloc(host_user, size);
    191   if (!copy) return 1;
    192   memcpy(copy, body, size);
    193   index = plan->ndefines;
    194   if (kit_os_hosted_add_define(plan, name, copy) != 0) {
    195     host->free(host_user, copy, size);
    196     return 1;
    197   }
    198   plan->owned_define_bodies[index] = copy;
    199   plan->owned_define_body_sizes[index] = size;
    200   return 0;
    201 }
    202 
    203 int kit_os_hosted_add_clang_compat_defines(KitOsHostedPlan* plan) {
    204   if (kit_os_hosted_add_define(plan, "__clang__", "1") != 0 ||
    205       kit_os_hosted_add_define(plan, "__clang_major__", "17") != 0 ||
    206       kit_os_hosted_add_define(plan, "__clang_minor__", "0") != 0 ||
    207       kit_os_hosted_add_define(plan, "__clang_patchlevel__", "0") != 0 ||
    208       kit_os_hosted_add_define(plan, "__GNUC__", "4") != 0 ||
    209       kit_os_hosted_add_define(plan, "__GNUC_MINOR__", "2") != 0 ||
    210       kit_os_hosted_add_define(plan, "__GNUC_PATCHLEVEL__", "1") != 0 ||
    211       kit_os_hosted_add_define(plan, "__has_builtin(x)", "0") != 0 ||
    212       kit_os_hosted_add_define(plan, "__has_include(x)", "0") != 0 ||
    213       kit_os_hosted_add_define(plan, "__has_include_next(x)", "0") != 0 ||
    214       kit_os_hosted_add_define(plan, "__has_feature(x)", "0") != 0 ||
    215       kit_os_hosted_add_define(plan, "__has_extension(x)", "0") != 0 ||
    216       kit_os_hosted_add_define(plan, "__has_attribute(x)", "0") != 0 ||
    217       kit_os_hosted_add_define(plan, "_Nonnull", "/*empty*/") != 0 ||
    218       kit_os_hosted_add_define(plan, "_Nullable", "/*empty*/") != 0 ||
    219       kit_os_hosted_add_define(plan, "_Null_unspecified", "/*empty*/") != 0)
    220     return 1;
    221   return 0;
    222 }
    223 
    224 void kit_os_hosted_plan_fini(const KitOsHostedHost* host, void* host_user,
    225                              KitOsHostedPlan* plan) {
    226   uint32_t i;
    227   if (!host || !host->free || !plan) return;
    228   for (i = 0; i < plan->nbefore; ++i) {
    229     if (plan->before[i].owned_path)
    230       host->free(host_user, plan->before[i].owned_path,
    231                  plan->before[i].owned_size);
    232   }
    233   for (i = 0; i < plan->nafter; ++i) {
    234     if (plan->after[i].owned_path)
    235       host->free(host_user, plan->after[i].owned_path,
    236                  plan->after[i].owned_size);
    237   }
    238   for (i = 0; i < plan->nfinal; ++i) {
    239     if (plan->final[i].owned_path)
    240       host->free(host_user, plan->final[i].owned_path,
    241                  plan->final[i].owned_size);
    242   }
    243   for (i = 0; i < plan->nsystem_includes; ++i) {
    244     if (plan->owned_system_includes[i])
    245       host->free(host_user, plan->owned_system_includes[i],
    246                  plan->owned_system_include_sizes[i]);
    247   }
    248   for (i = 0; i < plan->ndefines; ++i) {
    249     if (plan->owned_define_bodies[i])
    250       host->free(host_user, plan->owned_define_bodies[i],
    251                  plan->owned_define_body_sizes[i]);
    252   }
    253   for (i = 0; i < plan->nlib_search_dirs; ++i) {
    254     if (plan->lib_search_dirs[i])
    255       host->free(host_user, plan->lib_search_dirs[i],
    256                  plan->lib_search_dir_sizes[i]);
    257   }
    258   memset(plan, 0, sizeof(*plan));
    259 }