kit

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

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 }