build.c (3636B)
1 #include "build.h" 2 3 #include <stdio.h> 4 #include <string.h> 5 6 static int build_write(KitWriter* out, const void* data, size_t n) { 7 return out && kit_writer_write(out, data, n) == 0 ? BUILD_OK : BUILD_ERR; 8 } 9 10 static int build_write_cstr(KitWriter* out, const char* s) { 11 return build_write(out, s, strlen(s)); 12 } 13 14 static int build_text_field_valid(const char* s, size_t cap) { 15 size_t i; 16 if (!s || !s[0]) return 0; 17 for (i = 0; i < cap; ++i) { 18 unsigned char c = (unsigned char)s[i]; 19 if (c == '\0') return i < cap; 20 if (c == '\n' || c == '\r' || c == ' ' || c == '\t') return 0; 21 } 22 return 0; 23 } 24 25 static int build_slice_token_valid(KitSlice s, size_t cap) { 26 size_t i; 27 if (s.len == 0 || s.len >= cap || !s.s) return 0; 28 for (i = 0; i < s.len; ++i) { 29 unsigned char c = (unsigned char)s.s[i]; 30 if (c == '\0' || c == '\n' || c == '\r' || c == ' ' || c == '\t') 31 return 0; 32 } 33 return 1; 34 } 35 36 static int build_path_blob_cmp(const BuildPathBlob* a, const BuildPathBlob* b) { 37 return strcmp(a->path, b->path); 38 } 39 40 static int target_key_with_domain(KitSlice target_name, const char* domain, 41 size_t domain_len, 42 uint8_t out[BUILD_HASH_LEN]) { 43 uint8_t buf[sizeof(BUILD_TEST_TARGET_KEY_DOMAIN) - 1u + BUILD_TARGET_MAX - 1u]; 44 KitBlobInfo info; 45 46 if (!out || !domain) return BUILD_ERR; 47 if (!build_slice_token_valid(target_name, BUILD_TARGET_MAX)) return BUILD_ERR; 48 49 memcpy(buf, domain, domain_len); 50 memcpy(buf + domain_len, target_name.data, target_name.len); 51 kit_blob_info(&info, buf, domain_len + target_name.len); 52 memcpy(out, info.id, BUILD_HASH_LEN); 53 return BUILD_OK; 54 } 55 56 int build_target_key(KitSlice target_name, uint8_t out[BUILD_HASH_LEN]) { 57 return target_key_with_domain(target_name, BUILD_TARGET_KEY_DOMAIN, 58 sizeof(BUILD_TARGET_KEY_DOMAIN) - 1u, out); 59 } 60 61 int build_test_target_key(KitSlice target_name, uint8_t out[BUILD_HASH_LEN]) { 62 return target_key_with_domain(target_name, BUILD_TEST_TARGET_KEY_DOMAIN, 63 sizeof(BUILD_TEST_TARGET_KEY_DOMAIN) - 1u, 64 out); 65 } 66 67 int build_glob_result_hash(KitHeap* heap, const BuildPathBlob* entries, 68 size_t n, uint8_t out[BUILD_HASH_LEN]) { 69 KitWriter* w = NULL; 70 const uint8_t* bytes; 71 size_t len; 72 size_t i; 73 KitBlobInfo info; 74 75 if (!heap || !out) return BUILD_ERR; 76 if (n && !entries) return BUILD_ERR; 77 if (kit_writer_mem(heap, &w) != 0 || !w) return BUILD_ERR; 78 79 for (i = 0; i < n; ++i) { 80 char hex[BUILD_HEX_LEN]; 81 if (!build_text_field_valid(entries[i].path, BUILD_PATH_MAX)) goto err; 82 if (i > 0 && build_path_blob_cmp(&entries[i - 1u], &entries[i]) >= 0) 83 goto err; 84 kit_hex_encode(hex, entries[i].blob, BUILD_HASH_LEN); 85 if (build_write_cstr(w, entries[i].path) != BUILD_OK || 86 build_write_cstr(w, " ") != BUILD_OK || 87 build_write_cstr(w, hex) != BUILD_OK || 88 build_write_cstr(w, "\n") != BUILD_OK) 89 goto err; 90 } 91 92 if (kit_writer_status(w) != 0) goto err; 93 bytes = kit_writer_mem_bytes(w, &len); 94 kit_blob_info(&info, bytes, len); 95 memcpy(out, info.id, BUILD_HASH_LEN); 96 kit_writer_close(w); 97 return BUILD_OK; 98 99 err: 100 if (w) kit_writer_close(w); 101 return BUILD_ERR; 102 } 103 104 void build_diagf(const KitContext* ctx, const char* fmt, ...) { 105 KitSrcLoc loc; 106 va_list ap; 107 if (!ctx || !ctx->diag || !ctx->diag->emit || !fmt) return; 108 loc.file_id = 0; 109 loc.line = 0; 110 loc.col = 0; 111 va_start(ap, fmt); 112 ++ctx->diag->errors; 113 ctx->diag->emit(ctx->diag, KIT_DIAG_ERROR, loc, fmt, ap); 114 va_end(ap); 115 }