compiler_experiment

Unnamed repository; edit this file 'description' to name the repository.
git clone https://git.deepztream.com/compiler_experiment
Log | Files | Refs

dlib.h (8368B)


      1 #ifndef DLIB_H
      2 #define DLIB_H 1
      3 
      4 #include <assert.h>
      5 #include <ctype.h>
      6 #include <fcntl.h>
      7 #include <limits.h>
      8 #include <stdarg.h>
      9 #include <stdio.h>
     10 #include <stdbool.h>
     11 #include <stdint.h>
     12 #include <stdlib.h>
     13 #include <errno.h>
     14 #include <string.h>
     15 #include <unistd.h>
     16 
     17 #define unimplemented() \
     18   do { \
     19     fprintf(stderr, "%s:%i:1: Error: not implemented %s\n", __FILE__, __LINE__, __func__); \
     20     abort(); \
     21   } while (0)
     22 
     23 #define pop_arg(argc, argv) ((argc)--, *(argv)++)
     24 
     25 #define da_append(da, new)\
     26   do {\
     27     if ((da)->capacity <= (da)->count) {\
     28       (da)->capacity = (da)->capacity ? (da)->capacity * 2 : 16;\
     29       (da)->items = realloc((da)->items, sizeof(*(da)->items) * (da)->capacity);\
     30     }\
     31     (da)->items[(da)->count++] = (new);\
     32   } while(0)
     33 
     34 #define da_prepend(da, new)\
     35   do {\
     36     if ((da)->capacity <= (da)->count) {\
     37       (da)->capacity = (da)->capacity ? (da)->capacity * 2 : 16;\
     38       (da)->items = realloc((da)->items, sizeof(*(da)->items) * (da)->capacity);\
     39     }\
     40     memmove((da)->items + 1, (da)->items, sizeof(*(da)->items) * ((da)->count++));\
     41     (da)->items[0] = (new);\
     42   } while(0)
     43 
     44 #define da_reserve(da, len)\
     45   do {\
     46     if ((da)->capacity >= (len)) break;\
     47     (da)->capacity = (len);\
     48     (da)->items = realloc((da)->items, sizeof(*(da)->items) * (len));\
     49   } while(0)
     50 
     51 #define da_expand(da, size)\
     52   do {\
     53     if ((da)->count >= (size)) break;\
     54     da_reserve(da, size);\
     55     (da)->count = (size);\
     56   } while(0)
     57 
     58 #define da_delete(da, index)\
     59   do {\
     60     assert(index >= 0 && index < (da)->count);\
     61     (da)->items[index] = (da)->items[--(da)->count];\
     62   } while (0)
     63 
     64 typedef struct {
     65   union {
     66     char *items;
     67     const char *data;
     68   };
     69   union {
     70     ssize_t count;
     71     ssize_t length;
     72   };
     73   ssize_t capacity;
     74 } Sb;
     75 #define String_builder Sb
     76 
     77 typedef struct {
     78   union {
     79     const char *items;
     80     const char *data;
     81   };
     82   union {
     83     ssize_t count;
     84     ssize_t length;
     85   };
     86 } Sv;
     87 #define String_view Sv
     88 
     89 typedef struct {
     90   void *base;
     91   void *head;
     92   void *end;
     93 } Temp_allocator;
     94 
     95 #define TA_DEFAULT_SIZE (1024*1024)
     96 
     97 void ta_init(Temp_allocator *ta, size_t size);
     98 void *ta_alloc(Temp_allocator *ta, size_t size);
     99 
    100 #define sb_append_char da_append
    101 void sb_printf(Sb *sb, const char *fmt, ...);
    102 void sb_append_cstr(Sb *sb, const char *cstr);
    103 void sb_append_sv(Sb *sb, Sv sv);
    104 
    105 bool sb_read(Sb *sb, int fd);
    106 bool sb_read_file(Sb *sb, const char *file_name);
    107 void sb_write(int fd, Sb sb);
    108 
    109 void sb_release(Sb *sb);
    110 
    111 #define sv_literal(str) ((Sv){.items = (str), .count = (sizeof (str) - 1)})
    112 
    113 Sv sv_from_sb(Sb sb);
    114 Sv sv_from_cstr(const char *cstr);
    115 ssize_t sv_find_char(Sv sv, char c);
    116 
    117 Sv sv_chop(Sv sv, ssize_t count, Sv *rest);
    118 Sv sv_chop_delim(Sv sv, char c, Sv *rest);
    119 
    120 Sv sv_getline(Sv *sv);
    121 
    122 Sv sv_trim_left(Sv sv);
    123 Sv sv_trim_right(Sv sv);
    124 Sv sv_trim(Sv sv);
    125 
    126 Sv sv_substring(Sv sv, ssize_t start, ssize_t req_count);
    127 
    128 int sv_compare(Sv sv1, Sv sv2);
    129 bool sv_equal(Sv sv1, Sv sv2);
    130 bool sv_starts_with_cstr(Sv sv, const char *cstr);
    131 
    132 void sv_write(int fd, Sv sv);
    133 
    134 #ifdef DLIB_IMPLEMENTATION
    135 
    136 void
    137 ta_init(Temp_allocator *ta, size_t size)
    138 {
    139   ta->base = malloc(size);
    140   ta->head = ta->base;
    141   ta->end = ta->base + size;
    142 }
    143 
    144 void *
    145 ta_alloc(Temp_allocator *ta, size_t size)
    146 {
    147   if (!ta->base) {
    148     ta->base = malloc(TA_DEFAULT_SIZE);
    149     ta->head = ta->base;
    150     ta->end = ta->base + TA_DEFAULT_SIZE;
    151   }
    152   void *result = ta->head;
    153   ta->head += (size + 0xF) & ~0xFul;
    154   if (ta->head >= ta->end) {
    155     fprintf(stderr, "Error: Temp allocator out of memory\n");
    156     exit(1);
    157   }
    158   return result;
    159 }
    160 
    161 void
    162 sb_printf(Sb *sb, const char *fmt, ...) {
    163   va_list args, args_copy;
    164   va_start(args, fmt);
    165   va_copy(args_copy, args);
    166   int len = vsnprintf(NULL, 0, fmt, args_copy) + 1;
    167   ssize_t new_size = sb->count + len;
    168   da_reserve(sb, new_size);
    169   va_end(args_copy);
    170   vsnprintf(sb->items + sb->count, len, fmt, args);
    171   va_end(args);
    172   sb->count = new_size - 1;
    173 }
    174 
    175 void
    176 sb_append_cstr(Sb *sb, const char *cstr)
    177 {
    178   ssize_t len = strlen(cstr);
    179   da_reserve(sb, sb->count + len);
    180   strcpy(sb->items + sb->count, cstr);
    181   sb->count += len;
    182 }
    183 
    184 void
    185 sb_append_sv(Sb *sb, Sv sv)
    186 {
    187   da_reserve(sb, sb->count + sv.count);
    188   memcpy(sb->items + sb->count, sv.items, sv.count);
    189   sb->count += sv.count;
    190 }
    191 
    192 bool
    193 sb_read(Sb *sb, int fd)
    194 {
    195   ssize_t read_count;
    196   ssize_t buf_size = 4096;
    197   char *buf = malloc(buf_size);
    198   do {
    199     read_count = read(fd, buf, buf_size);
    200     if (read_count < 0) {
    201       if (errno == EINTR) {
    202         continue;
    203       }
    204       perror("sb_read()");
    205       return false;
    206     }
    207     if (read_count == 0) {
    208       break;
    209     }
    210     sb_append_sv(sb, ((Sv) {.items = buf, .length = read_count}));
    211     if (read_count < buf_size) {
    212       break;
    213     }
    214   } while (1);
    215   free(buf);
    216   return true;
    217 }
    218 
    219 bool
    220 sb_read_file(Sb *sb, const char *file_name)
    221 {
    222   int fd = open(file_name, O_RDONLY);
    223   if (fd < 0) {
    224     perror("sb_read()");
    225     return false;
    226   }
    227   ssize_t read_count;
    228   ssize_t buf_size = 4096;
    229   char *buf = malloc(buf_size);
    230   do {
    231     read_count = read(fd, buf, buf_size);
    232     if (read_count < 0) {
    233       if (errno == EINTR) {
    234         continue;
    235       }
    236       perror("sb_read_file()");
    237       return false;
    238     }
    239     if (read_count == 0) {
    240       break;
    241     }
    242     sb_append_sv(sb, ((Sv) {.items = buf, .length = read_count}));
    243   } while (1);
    244   free(buf);
    245   return true;
    246 }
    247 
    248 void
    249 sb_write(int fd, Sb sb)
    250 {
    251   write(fd, sb.items, sb.length);
    252 }
    253 
    254 void
    255 sb_release(Sb *sb)
    256 {
    257   if (sb->capacity) {
    258     free(sb->items);
    259     sb->items = NULL;
    260     sb->count = 0;
    261     sb->capacity = 0;
    262   }
    263 }
    264 
    265 /* String view functions */
    266 
    267 void
    268 sv_write(int fd, Sv sv)
    269 {
    270   write(fd, sv.items, sv.count);
    271 }
    272 
    273 Sv
    274 sv_from_sb(Sb sb)
    275 {
    276   return (Sv) {.items = sb.items, .count = sb.count};
    277 }
    278 
    279 Sv
    280 sv_from_cstr(const char *cstr)
    281 {
    282   return (Sv) {.items = cstr, .count = strlen(cstr)};
    283 }
    284 
    285 ssize_t
    286 sv_find_char(Sv sv, char c)
    287 {
    288   ssize_t pos = 0;
    289   while (sv.count > pos && sv.items[pos] != c)
    290     pos++;
    291   for (pos = 0; pos < sv.count && sv.items[pos] != c; pos++);
    292   return pos < sv.count ? pos : -1;
    293 }
    294 
    295 Sv
    296 sv_chop_delim(Sv sv, char c, Sv *rest)
    297 {
    298   ssize_t pos = sv_find_char(sv, c);
    299   Sv res = sv;
    300   if (pos > 0) {
    301     res.count = pos;
    302 
    303     rest->count -= pos + 1;
    304     rest->items += pos + 1;
    305   }
    306   return res;
    307 }
    308 
    309 Sv
    310 sv_chop(Sv sv, ssize_t count, Sv *rest)
    311 {
    312   Sv left = {0};
    313   ssize_t lcount, rcount;
    314   if (count > sv.count) {
    315     lcount = sv.count;
    316     rcount = 0;
    317   } else if (-count > sv.count) {
    318     lcount = 0;
    319     rcount = sv.count;
    320   } else if (count < 0) {
    321     lcount = sv.count + count;
    322     rcount = -count;
    323   } else {
    324     lcount = count;
    325     rcount = sv.count - count;
    326   }
    327   left.items = sv.items;
    328   left.count = lcount;
    329   if (rest) {
    330     rest->items = sv.items + lcount;
    331     rest->count = rcount;
    332   }
    333   return left;
    334 }
    335 
    336 Sv
    337 sv_trim_left(Sv sv)
    338 {
    339   while (sv.count && isspace(sv.items[0])) {
    340     sv.count--;
    341     sv.items++;
    342   }
    343   return sv;
    344 }
    345 
    346 Sv
    347 sv_trim_right(Sv sv)
    348 {
    349   while (sv.count && isspace(sv.items[sv.count - 1])) {
    350     sv.count--;
    351   }
    352   return sv;
    353 }
    354 
    355 Sv
    356 sv_trim(Sv sv)
    357 {
    358   return sv_trim_right(sv_trim_left(sv));
    359 }
    360 
    361 Sv
    362 sv_substring(Sv sv, ssize_t start, ssize_t req_count)
    363 {
    364   Sv ss = {0};
    365   if (start >= sv.count) return ss;
    366   ss.count = (req_count < sv.count - start) ? req_count : sv.count - start;
    367   ss.items = sv.items + start;
    368   return ss;
    369 }
    370 
    371 int
    372 sv_compare(Sv sv1, Sv sv2)
    373 {
    374   if (sv1.items == sv2.items && sv1.count == sv2.count) return 0;
    375   signed char diff;
    376   ssize_t pos;
    377   for (pos = 0; pos < sv1.count; pos++) {
    378     if (pos == sv2.count) return 1;
    379     if ((diff = sv1.items[pos] - sv2.items[pos])) return diff;
    380   }
    381   return pos < sv2.count ? -1 : 0;
    382 }
    383 
    384 bool
    385 sv_equal(Sv sv1, Sv sv2)
    386 {
    387   if (sv1.count != sv2.count) return false;
    388   if (sv1.items == sv2.items) return true;
    389   ssize_t pos;
    390   for (pos = 0; pos < sv1.count && sv1.items[pos] == sv2.items[pos]; pos++);
    391   return pos == sv1.count;
    392 }
    393 
    394 bool
    395 sv_starts_with_cstr(Sv sv, const char *cstr)
    396 {
    397   size_t cstr_len = strlen(cstr);
    398   assert(cstr_len <= SSIZE_MAX);
    399   if (sv.count < (ssize_t) cstr_len) return false;
    400   ssize_t pos;
    401   for (pos = 0; pos < (ssize_t) cstr_len && sv.items[pos] == cstr[pos]; pos++);
    402   return pos == (ssize_t) cstr_len;
    403 }
    404 
    405 Sv
    406 sv_getline(Sv *sv)
    407 {
    408   Sv line = sv_chop_delim(*sv, '\n', sv);
    409   if (line.count && line.items[line.count - 1] == '\r') {
    410     line.count--;
    411   }
    412   return line;
    413 }
    414 
    415 #endif // DLIB_IMPLEMENTATION
    416 
    417 #endif // DLIB_H