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 }