defs.h (9864B)
1 /* This program is licensed under the terms of GNU GPL v3 or (at your option) 2 * any later version. Copyright (C) 2020-2026 Страхиња Радић. 3 * See the file LICENSE for exact copyright and license details. */ 4 5 #define COPYRIGHT_YEAR "2020-2026" 6 #define MADEBY_URL "https://strahinja.srht.site/slweb/" 7 8 #define BUFSIZE 1024 9 #define KEYSIZE 256 10 #define LINE_DEFAULT 85 11 #define SMALL_ARGSIZE 256 12 #define DATEBUFSIZE 12 13 14 #define SLWEB_ERR_CODE(num) (200 + (num)) 15 16 enum { 17 ERR_NONE = 0, 18 ERR_ARG_NOTNUM = SLWEB_ERR_CODE(1), 19 ERR_ARG_NOTSTR = SLWEB_ERR_CODE(2), 20 ERR_BAD_CL_ARG = SLWEB_ERR_CODE(3), 21 ERR_BAD_CND_MARK = SLWEB_ERR_CODE(4), 22 ERR_BAD_EMPTY_CND = SLWEB_ERR_CODE(5), 23 ERR_BAD_HR_MARK = SLWEB_ERR_CODE(6), 24 ERR_BAD_REG_MARK = SLWEB_ERR_CODE(7), 25 ERR_FORMAT_DATE_FAIL = SLWEB_ERR_CODE(8), 26 ERR_MACRO_UNDEF = SLWEB_ERR_CODE(9), 27 ERR_NEST_CSV = SLWEB_ERR_CODE(10), 28 ERR_NEST_MACRO = SLWEB_ERR_CODE(11), 29 ERR_NEST_MATH = SLWEB_ERR_CODE(12), 30 ERR_NO_ARG = SLWEB_ERR_CODE(13), 31 ERR_POPEN_FAIL = SLWEB_ERR_CODE(14), 32 ERR_SCANDIR_FAIL = SLWEB_ERR_CODE(15), 33 }; 34 35 typedef enum { 36 CMD_NONE, 37 CMD_BODY_ONLY, 38 CMD_BASEDIR, 39 CMD_HELP, 40 CMD_LINK_PREFIX, 41 CMD_VERSION, 42 CMD_FULL_VERSION 43 } Command; 44 45 typedef struct { 46 u8* key; 47 u8* value; 48 size_t value_size; 49 } KeyValue; 50 51 typedef void (*csv_callback_t)(FILE* output, u8** csv_header, u8** csv_register); 52 typedef void (*tsv_callback_t)(FILE* output, u8** tsv_header, u8** tsv_register); 53 54 static const char article_timestamp_format[] = "d.m.y"; 55 static const char list_timestamp_format[] = "y-m-d"; 56 static const char timestamp_output_ext[] = ".html"; 57 58 static const char CMD_GIT_LOG[] = "xargs"; 59 static const char* CMD_GIT_LOG_ARGS[] = {"xargs", "-I{}", "git", "log", "-1", 60 "--pretty=format:{} %h %ci (%cn) %d", NULL}; 61 62 static const char CMD_KATEX[] = "katex"; 63 static const char* CMD_KATEX_INLINE_ARGS[] = {"katex", NULL}; 64 static const char* CMD_KATEX_DISPLAY_ARGS[] = {"katex", "-d", NULL}; 65 66 static const char* CMD_IDENTIFY 67 = "identify %s | sed -e's/.* \\([0-9]\\{1,\\}\\)x\\([0-9]\\{1,\\}\\)" 68 ".*/width=\"\\1\" height=\"\\2\"/g'"; 69 70 /* clang-format off */ 71 /* True iff all given "members" are present in the set */ 72 /* Usage: ALL(state, STATE1 | STATE2 | ...) */ 73 #define ALL(var, mask) (((var) & (mask)) == (mask)) 74 /* True if any of the given "members" are present in the set */ 75 /* Usage: ANY(state, STATE1 | STATE2 | ...) */ 76 #define ANY(var, mask) (((var) & (mask)) != 0) 77 /* Removes the given "members" from the set */ 78 /* Usage: CLEAR(state, STATE1 | STATE2 | ...) */ 79 #define CLEAR(v, c) do { (v) &= ~(c); } while(0) 80 #define IN(var, mask) ALL(var, mask) 81 /* Adds the given "members" to the set */ 82 /* Usage: SET(state, STATE1 | STATE2 | ...) */ 83 #define SET(v, c) do { (v) |= (c); } while(0) 84 /* Adds/removes the given "members" to/from the set */ 85 /* Usage: TOGGLE(state, STATE1 | STATE2 | ...) */ 86 #define TOGGLE(v, c) do { (v) ^= (c); } while(0) 87 /* clang-format on */ 88 89 #define MIN(a, b) ((a < b) ? (a) : (b)) 90 #define UNUSED(x) ((void)(x)) 91 92 #define COPYRIGHT \ 93 (" This program is licensed under the terms of GNU GPL v3" \ 94 " or (at your option)\n" \ 95 " any later version. Copyright (C) 2020-2026 Strahinya Radich.\n" \ 96 " See the file LICENSE for exact copyright and license " \ 97 "details.") 98 99 #define CALLOC(ptr, ptrtype, nmemb) \ 100 do \ 101 { \ 102 errno = 0; \ 103 ptr = calloc(nmemb, sizeof(ptrtype)); \ 104 if (!ptr) \ 105 { \ 106 perror(PROGRAMNAME ": calloc"); \ 107 exit(error(ENOMEM, __FILE__, __func__, __LINE__, \ 108 "Allocation error")); \ 109 } \ 110 } while (0) 111 112 #define REALLOC(ptr, ptrtype, newsize) \ 113 do \ 114 { \ 115 ptrtype* newptr = NULL; \ 116 errno = 0; \ 117 newptr = realloc(ptr, newsize); \ 118 if (!newptr) \ 119 { \ 120 perror(PROGRAMNAME ": realloc"); \ 121 exit(error(ENOMEM, __FILE__, __func__, __LINE__, \ 122 "Allocation error")); \ 123 } \ 124 ptr = newptr; \ 125 } while (0) 126 127 #define REALLOCARRAY(ptr, membtype, newcount) \ 128 REALLOC(ptr, membtype, sizeof(membtype) * newcount); 129 130 #define MEMCCPY(to, from, tolen, temp) \ 131 do \ 132 { \ 133 temp = memccpy(to, from, 0, tolen); \ 134 if (!temp) \ 135 to[tolen > 0 ? tolen - 1 : 0] = 0; \ 136 } while (0) 137 #define MEMCCPY_EXT(to, fallbackto, from, tolen, temp) \ 138 do \ 139 { \ 140 temp = memccpy(to, from, 0, tolen); \ 141 if (!temp) \ 142 fallbackto[tolen > 0 ? tolen - 1 : 0] = 0; \ 143 } while (0) 144 145 /* Copy *pline to *ptoken and increase ptoken */ 146 #define CHECKCOPY(token, ptoken, token_size, pline) \ 147 do \ 148 { \ 149 if (ptoken + 2 > token + token_size) \ 150 { \ 151 size_t old_size = token_size; \ 152 token_size += BUFSIZE; \ 153 REALLOC(token, u8, token_size); \ 154 ptoken = token + old_size - 1; \ 155 } \ 156 *ptoken++ = *pline++; \ 157 } while (0) 158 159 #define RESET_TOKEN(token, ptoken, token_size) \ 160 do \ 161 { \ 162 token_size = BUFSIZE; \ 163 REALLOC(token, u8, token_size); \ 164 *token = 0; \ 165 ptoken = token; \ 166 } while (0) 167 168 #define ENSURE_SIZE(to, temp, tosize, testsize, fromsize, label, type) \ 169 do \ 170 { \ 171 if (!(to) || (tosize) < (testsize)) \ 172 { \ 173 (tosize) = fromsize; \ 174 errno = 0; \ 175 temp = realloc(to, (tosize) * sizeof(type)); \ 176 if (!temp) \ 177 { \ 178 perror(PROGRAMNAME ": realloc"); \ 179 goto label; \ 180 } \ 181 (to) = temp; \ 182 } \ 183 } while (0) 184 185 #define MAX_HEADING_LEVEL 4 186 #define MAX_CSV_REGISTERS 9 187 #define MAX_TSV_REGISTERS 9 188 189 #define ST_NONE 0 190 #define ST_YAML 1 191 #define ST_YAML_VAL ((unsigned long long)1 << 1) 192 #define ST_PARA_OPEN ((unsigned long long)1 << 2) 193 #define ST_TAG ((unsigned long long)1 << 3) 194 #define ST_HEADING ((unsigned long long)1 << 4) 195 #define ST_HEADING_TEXT ((unsigned long long)1 << 5) 196 #define ST_BOLD ((unsigned long long)1 << 6) 197 #define ST_ITALIC ((unsigned long long)1 << 7) 198 #define ST_PRE ((unsigned long long)1 << 8) 199 #define ST_CODE ((unsigned long long)1 << 9) 200 #define ST_BLOCKQUOTE ((unsigned long long)1 << 10) 201 #define ST_LINK ((unsigned long long)1 << 11) 202 #define ST_LINK_SECOND_ARG ((unsigned long long)1 << 12) 203 #define ST_LINK_SECOND_ARG_END ((unsigned long long)1 << 13) 204 #define ST_LINK_SPAN ((unsigned long long)1 << 14) 205 #define ST_LINK_MACRO ((unsigned long long)1 << 15) 206 #define ST_IMAGE ((unsigned long long)1 << 16) 207 #define ST_IMAGE_SECOND_ARG ((unsigned long long)1 << 17) 208 #define ST_MACRO_BODY ((unsigned long long)1 << 18) 209 #define ST_CSV_BODY ((unsigned long long)1 << 19) 210 #define ST_TSV_BODY ((unsigned long long)1 << 20) 211 #define ST_HTML_TAG ((unsigned long long)1 << 21) 212 #define ST_KBD ((unsigned long long)1 << 22) 213 #define ST_LIST ((unsigned long long)1 << 23) 214 #define ST_NUMLIST ((unsigned long long)1 << 24) 215 #define ST_FOOTNOTE ((unsigned long long)1 << 25) 216 #define ST_FOOTNOTE_TEXT ((unsigned long long)1 << 26) 217 #define ST_INLINE_FOOTNOTE ((unsigned long long)1 << 27) 218 #define ST_FORMULA ((unsigned long long)1 << 28) 219 #define ST_DISPLAY_FORMULA ((unsigned long long)1 << 29) 220 #define ST_TABLE_HEADER ((unsigned long long)1 << 30) 221 #define ST_TABLE_LINE ((unsigned long long)1 << 31) 222 #define ST_TABLE ((unsigned long long)1 << 32) 223 #define ST_STRIKE ((unsigned long long)1 << 33) 224 #define ST_SUMMARY ((unsigned long long)1 << 34) 225 #define ST_INCDIR ((unsigned long long)1 << 35) 226 227 #define ST_CS_NONE 0 228 #define ST_CS_HEADER 1 229 #define ST_CS_REGISTER (1 << 2) 230 #define ST_CS_QUOTE (1 << 3) 231 #define ST_CS_COND (1 << 4) 232 #define ST_CS_COND_NONEMPTY (1 << 5) 233 #define ST_CS_COND_EMPTY (1 << 6) 234 #define ST_CS_ESCAPE (1 << 7)