1 /* 2 * Copyright (C) 2020-2021 Jo-Philipp Wich <jo@mein.io> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef UCODE_UTIL_H 18 #define UCODE_UTIL_H 19 20 #include <stdio.h> 21 #include <stddef.h> 22 #include <stdlib.h> 23 #include <stdbool.h> 24 #include <stdarg.h> /* va_start(), va_end(), va_list */ 25 #include <string.h> /* strdup() */ 26 #include <json-c/json.h> 27 28 29 #ifndef __hidden 30 #define __hidden __attribute__((visibility("hidden"))) 31 #endif 32 33 34 /* alignment & array size */ 35 36 #ifndef ALIGN 37 #define ALIGN(x) (((x) + sizeof(size_t) - 1) & -sizeof(size_t)) 38 #endif 39 40 #ifndef ARRAY_SIZE 41 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 42 #endif 43 44 45 /* vector macros */ 46 47 #define UC_VECTOR_CHUNK_SIZE 8 48 49 #define uc_declare_vector(name, type) \ 50 typedef struct { \ 51 size_t count; \ 52 type *entries; \ 53 } name 54 55 #define uc_vector_grow(vec) \ 56 do { \ 57 if (((vec)->count % UC_VECTOR_CHUNK_SIZE) == 0) { \ 58 (vec)->entries = xrealloc((vec)->entries, sizeof((vec)->entries[0]) * ((vec)->count + UC_VECTOR_CHUNK_SIZE)); \ 59 memset(&(vec)->entries[(vec)->count], 0, sizeof((vec)->entries[0]) * UC_VECTOR_CHUNK_SIZE); \ 60 } \ 61 } while(0) 62 63 #define uc_vector_clear(vec) \ 64 do { \ 65 free((vec)->entries); \ 66 (vec)->entries = NULL; \ 67 (vec)->count = 0; \ 68 } while(0) 69 70 #define uc_vector_first(vec) \ 71 (&((vec)->entries[0])) 72 73 #define uc_vector_last(vec) \ 74 (&((vec)->entries[(vec)->count - 1])) 75 76 #define uc_vector_push(vec, val) do { \ 77 uc_vector_grow(vec); \ 78 (vec)->entries[(vec)->count++] = (val); \ 79 } while(0) 80 81 82 /* linked lists */ 83 84 typedef struct uc_list { 85 struct uc_list *prev; 86 struct uc_list *next; 87 } uc_list_t; 88 89 static inline void uc_list_insert(uc_list_t *list, uc_list_t *item) 90 { 91 list->next->prev = item; 92 item->next = list->next; 93 item->prev = list; 94 list->next = item; 95 } 96 97 static inline void uc_list_remove(uc_list_t *item) 98 { 99 item->next->prev = item->prev; 100 item->prev->next = item->next; 101 item->prev = item->next = item; 102 } 103 104 #define uc_list_foreach(item, list) \ 105 for (uc_list_t *item = (list)->next; item != (list); item = item->next) 106 107 108 /* "failsafe" utility functions */ 109 110 static inline void *xcalloc(size_t size, size_t nmemb) { 111 void *ptr = calloc(size, nmemb); 112 113 if (!ptr) { 114 fprintf(stderr, "Out of memory\n"); 115 abort(); 116 } 117 118 return ptr; 119 } 120 121 static inline void *xalloc(size_t size) { 122 return xcalloc(1, size); 123 } 124 125 static inline void *xrealloc(void *ptr, size_t size) { 126 ptr = realloc(ptr, size); 127 128 if (!ptr) { 129 fprintf(stderr, "Out of memory\n"); 130 abort(); 131 } 132 133 return ptr; 134 } 135 136 static inline char *xstrdup(const char *s) { 137 char *ptr = strdup(s); 138 139 if (!ptr) { 140 fprintf(stderr, "Out of memory\n"); 141 abort(); 142 } 143 144 return ptr; 145 } 146 147 static inline struct json_tokener *xjs_new_tokener(void) { 148 struct json_tokener *tok = json_tokener_new(); 149 150 if (!tok) { 151 fprintf(stderr, "Out of memory\n"); 152 abort(); 153 } 154 155 return tok; 156 } 157 158 __attribute__((format(printf, 2, 0))) 159 static inline int xasprintf(char **strp, const char *fmt, ...) { 160 va_list ap; 161 int len; 162 163 va_start(ap, fmt); 164 len = vasprintf(strp, fmt, ap); 165 va_end(ap); 166 167 if (len == -1) { 168 fprintf(stderr, "Out of memory\n"); 169 abort(); 170 } 171 172 return len; 173 } 174 175 __attribute__((format(printf, 2, 0))) 176 static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { 177 int len = vasprintf(strp, fmt, ap); 178 179 if (len == -1) { 180 fprintf(stderr, "Out of memory\n"); 181 abort(); 182 } 183 184 return len; 185 } 186 187 static inline struct printbuf *xprintbuf_new(void) { 188 struct printbuf *pb = printbuf_new(); 189 190 if (!pb) { 191 fprintf(stderr, "Out of memory\n"); 192 abort(); 193 } 194 195 return pb; 196 } 197 198 #endif /* UCODE_UTIL_H */ 199
This page was automatically generated by LXR 0.3.1. • OpenWrt