jdict

command line tool for looking up terms in yomidict dictionaries
git clone anongit@rnpnr.xyz:jdict.git
Log | Files | Refs | Feed | README | LICENSE

util.c (1952B)


      1 /* See LICENSE for license details. */
      2 #include <ctype.h>
      3 #include <stdarg.h>
      4 #include <stddef.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 #include <stdint.h>
     10 #include <stddef.h>
     11 typedef uint8_t   u8;
     12 typedef int64_t   i64;
     13 typedef uint64_t  u64;
     14 typedef int32_t   i32;
     15 typedef uint32_t  u32;
     16 typedef ptrdiff_t size;
     17 
     18 #define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a))
     19 
     20 typedef struct {
     21 	size len;
     22 	u8   *s;
     23 } s8;
     24 #define s8(cstr) (s8){.len = ARRAY_COUNT(cstr) - 1, .s = (u8 *)cstr}
     25 
     26 static void __attribute__((noreturn))
     27 die(const char *fmt, ...)
     28 {
     29 	va_list ap;
     30 
     31 	va_start(ap, fmt);
     32 	vfprintf(stderr, fmt, ap);
     33 	va_end(ap);
     34 
     35 	exit(1);
     36 }
     37 
     38 static int
     39 s8cmp(s8 a, s8 b)
     40 {
     41 	if (a.len == 0 || a.len != b.len)
     42 		return a.len - b.len;
     43 	return memcmp(a.s, b.s, a.len);
     44 }
     45 
     46 /*
     47  * trim whitespace from start and end of str
     48  * returns a new s8 (same memory)
     49  */
     50 static s8
     51 s8trim(s8 str)
     52 {
     53 	u8 *p = str.s + str.len - 1;
     54 
     55 	for (; str.len && isspace(*p); str.len--, p--);
     56 	for (; str.len && isspace(*str.s); str.len--, str.s++);
     57 
     58 	return str;
     59 }
     60 
     61 /* replace escaped control chars with their actual char */
     62 static s8
     63 unescape(s8 str)
     64 {
     65 	u8 *t    = str.s;
     66 	size rem = str.len;
     67 	int off;
     68 
     69 	while ((t = memchr(t, '\\', rem)) != NULL) {
     70 		off = 1;
     71 		switch (t[1]) {
     72 		case 'n': t[0] = '\n'; t++; break;
     73 		case 't': t[0] = '\t'; t++; break;
     74 		case 'u': t++; continue;
     75 		default: off++;
     76 		}
     77 		rem = str.len-- - (t - str.s) - off;
     78 		memmove(t, t + off, rem);
     79 	}
     80 
     81 	return str;
     82 }
     83 
     84 static void *
     85 xreallocarray(void *o, size_t n, size_t s)
     86 {
     87 	void *new;
     88 
     89 	if (!(new = reallocarray(o, n, s)))
     90 		die("reallocarray()\n");
     91 
     92 	return new;
     93 }
     94 
     95 static s8
     96 s8dup(void *src, size len)
     97 {
     98 	s8 str = {.len = len};
     99 	if (len < 0)
    100 		die("s8dup(): negative len\n");
    101 	str.s = xreallocarray(NULL, 1, len);
    102 	memcpy(str.s, src, len);
    103 	return str;
    104 }
    105 
    106 static s8
    107 cstr_to_s8(char *cstr)
    108 {
    109 	s8 result = {.s = (u8 *)cstr};
    110 	if (cstr) while (*cstr) { result.len++; cstr++; }
    111 	return result;
    112 }