sled

Једноставни уређивач текста
git clone https://git.sr.ht/~strahinja/sled
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

util.h (5843B)


      1 /* This program is licensed under the terms of GNU GPL v3 or (at your option)
      2  * any later version. Copyright (C) 2022-2026  Страхиња Радић.
      3  * See the file LICENSE for exact copyright and license details. */
      4 
      5 #include <stdint.h>
      6 #include <sys/types.h>
      7 #include <unistd.h>
      8 
      9 /* clang-format off */
     10 #define CLEAR(v, c)	do { (v) &= ~(c); } while(0)
     11 #define IN(v, c)	(((v) & (c)) == (c))
     12 #define LEN(x)		(sizeof(x) / sizeof(x[0]))
     13 #define MAX(a, b)	((a > b) ? (a) : (b))
     14 #define MIN(a, b)	((a < b) ? (a) : (b))
     15 #define SET(v, c)	do { (v) |= (c); } while(0)
     16 #define TOGGLE(v, c)	do { (v) ^= (c); } while(0)
     17 #define UNUSED(x)	((void)(x))
     18 /* clang-format on */
     19 
     20 #define U32_REPL_CHAR ((uint32_t)0xFFFD)
     21 
     22 #define MEMCCPY(to, from, tolen, temp)                     \
     23 	do                                                 \
     24 	{                                                  \
     25 		temp = memccpy(to, from, 0, tolen);        \
     26 		if (!temp)                                 \
     27 			to[tolen > 0 ? tolen - 1 : 0] = 0; \
     28 	} while (0)
     29 #define MEMCCPY_EXT(to, fallbackto, from, tolen, temp)             \
     30 	do                                                         \
     31 	{                                                          \
     32 		temp = memccpy(to, from, 0, tolen);                \
     33 		if (!temp)                                         \
     34 			fallbackto[tolen > 0 ? tolen - 1 : 0] = 0; \
     35 	} while (0)
     36 #define U32_MEMCCPY(to, from, tolen, temp)                 \
     37 	do                                                 \
     38 	{                                                  \
     39 		temp = u32_memccpy(to, from, 0L, tolen);   \
     40 		if (!temp)                                 \
     41 			to[tolen > 0 ? tolen - 1 : 0] = 0; \
     42 	} while (0)
     43 #define U32_U8_MEMCCPY(to, from, tolen, temp)               \
     44 	do                                                  \
     45 	{                                                   \
     46 		temp = u32_u8_memccpy(to, from, 0L, tolen); \
     47 		if (!temp)                                  \
     48 			to[tolen > 0 ? tolen - 1 : 0] = 0;  \
     49 	} while (0)
     50 #define U32_MEMCCPY_EXT(to, fallbackto, from, tolen, fbtolen, temp)    \
     51 	do                                                             \
     52 	{                                                              \
     53 		temp = u32_memccpy(to, from, 0L, tolen);               \
     54 		if (!temp)                                             \
     55 			fallbackto[fbtolen > 0 ? fbtolen - 1 : 0] = 0; \
     56 	} while (0)
     57 
     58 #define ENSURE_SIZE(to, temp, tosize, testsize, fromsize, label, type) \
     59 	do                                                             \
     60 	{                                                              \
     61 		if (!(to) || (tosize) < (testsize))                    \
     62 		{                                                      \
     63 			temp = realloc(to, (fromsize) * sizeof(type)); \
     64 			if (!temp)                                     \
     65 			{                                              \
     66 				state->running = 0;                    \
     67 				goto label;                            \
     68 			}                                              \
     69 			tosize = fromsize;                             \
     70 			to     = temp;                                 \
     71 		}                                                      \
     72 	} while (0)
     73 /*
     74  * - Make sure the size of the destination string is large enough to copy, and
     75  *   copy
     76  * - Sizes are in bytes
     77  * - We explicitly use fromsize in MEMCCPY, because we ensured that tosize is
     78  *   at least as big, and to allow a subset of from to be copied
     79  */
     80 #define U8_SAFE_COPY(to, temp, tosize, from, fromsize, label)                   \
     81 	do                                                                      \
     82 	{                                                                       \
     83 		ENSURE_SIZE(to, temp, tosize, fromsize, fromsize, label, char); \
     84 		MEMCCPY(to, from, fromsize, temp);                              \
     85 	} while (0)
     86 /*
     87  * - Make sure the size of the destination string is large enough to copy, and
     88  *   copy
     89  * - Sizes are in uint32_t units
     90  * - We explicitly use fromsize in U32_MEMCCPY, because we ensured that tosize
     91  *   is at least as big, and to allow a subset of from to be copied
     92  */
     93 #define U32_SAFE_COPY(to, temp, tosize, from, fromsize, label)           \
     94 	do                                                               \
     95 	{                                                                \
     96 		ENSURE_SIZE(to, temp, tosize, fromsize, fromsize, label, \
     97 			uint32_t);                                       \
     98 		U32_MEMCCPY(to, from, fromsize, temp);                   \
     99 	} while (0)
    100 
    101 #define CUSTOM_ERROR_START 200
    102 
    103 enum {
    104 	ERR_NONE,
    105 	ERR_NO_CL_ARG,
    106 	ERR_BINARY,
    107 	ERR_NOTREG_FILE,
    108 	ERR_TB_ERROR,
    109 	ERR_UNKNOWN_KEY,
    110 	ERR_EXIT_KEY,
    111 	ERR_DLG_OPEN,
    112 	ERR_DLG_OPEN_QUIT,
    113 	ERR_INPUT_NONNUM,
    114 	ERR_INVALID_NUM,
    115 	ERR_NOT_IMP,
    116 	ERR_ERRNO_SET
    117 };
    118 
    119 enum { ACT_IDLE, ACT_WRITING, ACT_READING, ACT_WRAPPING };
    120 
    121 size_t u8_string_to_unicode(uint32_t* us, const char* s, const ssize_t max);
    122 size_t unicode_string_to_u8(char* s, const uint32_t* us, const ssize_t max);
    123 int u32_has_nonblanks(const uint32_t* s);
    124 uint32_t* u32_memccpy(uint32_t* dst, const uint32_t* src, uint32_t c,
    125 	size_t len);
    126 uint32_t* u32_u8_memccpy(uint32_t* dst, const char* src, uint32_t c, size_t len);
    127 size_t u8_strlen(const char* s);
    128 size_t u32_strlen(const uint32_t* s);
    129 const uint32_t* u32_strstr(const uint32_t* haystack, const uint32_t* needle);
    130 const uint32_t* u32_strrstr(const uint32_t* haystack, const uint32_t* needle,
    131 	const uint32_t* haystack_tail);
    132 const uint32_t* u32_strchr(const uint32_t* haystack, const uint32_t needle);
    133 int is_word_boundary(const char ch, const int strictly_whitespace);
    134 int u32_is_word_boundary(const uint32_t ch, const int strictly_whitespace);
    135 int starts_with(const char* s, const char* with);
    136 int u32_starts_with(const uint32_t* s, const uint32_t* with);
    137 const char* u8_basename(const char* path);