dist_parse.h (2606B)
1 #ifndef KIT_DIST_DIST_PARSE_H 2 #define KIT_DIST_DIST_PARSE_H 3 4 #include <kit/core.h> 5 #include <stddef.h> 6 #include <stdint.h> 7 #include <stdio.h> 8 #include <string.h> 9 10 #include "dist.h" 11 12 /* Shared `key = value` text-manifest parse/emit helpers used by the tree, 13 * package-manifest, and kpkg-descriptor codecs. These were once duplicated 14 * (with drift) across manifest.c/tree.c/kpkg.c; the single copy here 15 * reconciles them to the strictest/most-informative variant of each. Provided 16 * as `static inline` so no extra translation unit (and no Makefile 17 * registration) is required. */ 18 19 /* Max length of a single emitted "key = value\n" line. */ 20 #define DIST_KV_LINE_MAX 1024u 21 22 /* Skip leading spaces/tabs, returning a pointer into `s`. */ 23 static inline char* dist_trim_lead(char* s) { 24 while (*s == ' ' || *s == '\t') ++s; 25 return s; 26 } 27 28 /* Strip trailing spaces/tabs/CR/LF in place. */ 29 static inline void dist_trim_trail(char* s) { 30 size_t n = strlen(s); 31 while (n && (s[n - 1] == ' ' || s[n - 1] == '\t' || s[n - 1] == '\r' || 32 s[n - 1] == '\n')) 33 s[--n] = '\0'; 34 } 35 36 /* Record `msg` into the caller's error buffer (if any) and return DIST_ERR. */ 37 static inline int dist_set_err(char* err, size_t cap, const char* msg) { 38 if (err && cap) snprintf(err, cap, "%s", msg); 39 return DIST_ERR; 40 } 41 42 /* Copy NUL-terminated `src` into `dst` of capacity `cap`, failing (with an 43 * error message) if it would not fit. */ 44 static inline int dist_copy_field(char* dst, size_t cap, const char* src, 45 char* err, size_t errcap) { 46 if (strlen(src) >= cap) 47 return dist_set_err(err, errcap, "field value too long"); 48 snprintf(dst, cap, "%s", src); 49 return DIST_OK; 50 } 51 52 /* Strict base-10 parse of `s` into `*out`: rejects empty input, any non-digit, 53 * and values that would overflow uint64_t. */ 54 static inline int dist_parse_u64(const char* s, uint64_t* out) { 55 uint64_t v = 0; 56 if (!s || !*s || !out) return DIST_ERR; 57 for (; *s; ++s) { 58 unsigned d; 59 if (*s < '0' || *s > '9') return DIST_ERR; 60 d = (unsigned)(*s - '0'); 61 if (v > (UINT64_MAX - (uint64_t)d) / 10u) return DIST_ERR; 62 v = v * 10u + (uint64_t)d; 63 } 64 *out = v; 65 return DIST_OK; 66 } 67 68 /* Emit a single "key = value\n" line to `out`. */ 69 static inline int dist_emit_kv(KitWriter* out, const char* key, 70 const char* val) { 71 char line[DIST_KV_LINE_MAX]; 72 snprintf(line, sizeof line, "%s = %s\n", key, val); 73 return kit_writer_write(out, line, strlen(line)) == KIT_OK ? DIST_OK 74 : DIST_ERR; 75 } 76 77 #endif