various utils
This commit is contained in:
1 parent
3851b60310
commit
45284910cc
8 files changed
+179
-2
No files matched your search
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct eventloop;
|
||||
|
||||
struct eventloop *eventloop_new(void);
|
||||
void eventloop_free(struct eventloop *el);
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "scoped.h"
|
||||
|
||||
static inline void _close_if_nonnegative(int fd) {
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
DEF_SCOPED_TYPE(fd, int, -1, _close_if_nonnegative)
|
||||
|
||||
#define FD_SCOPED(VAL) SCOPED(fd, int, VAL)
|
||||
#define FD_CLOSE(FD) _scoped_fd_cleanup(FD)
|
||||
#define FD_RELEASE(FD) _scoped_fd_release(FD)
|
||||
|
||||
static inline int setsockopt_int(int fd, int level, int option, int val) {
|
||||
return setsockopt(fd, level, option, &val, sizeof(val));
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "scoped.h"
|
||||
|
||||
DEF_SCOPED_TYPE(mem, void *, NULL, free)
|
||||
|
||||
#define MEM_SCOPED(TYPE, VAL) SCOPED(mem, TYPE *, VAL)
|
||||
#define MEM_FREE(TYPE, MEM) ({ CHECK_TYPE(TYPE **, MEM), (TYPE *)_scoped_mem_cleanup((void **)(MEM)); })
|
||||
#define MEM_RELEASE(TYPE, MEM) ({ CHECK_TYPE(TYPE **, MEM), (TYPE *)_scoped_mem_release((void **)(MEM)); })
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#define CHECK_TYPE(TYPE, VAL) ({ \
|
||||
typedef void (*_check_type_dummy_fn_t)(TYPE); \
|
||||
_check_type_dummy_fn_t _check_type_dummy_fn = (_check_type_dummy_fn_t)NULL; \
|
||||
if (0) \
|
||||
_check_type_dummy_fn(VAL); \
|
||||
1; \
|
||||
})
|
||||
|
||||
#define DEF_SCOPED_TYPE(NAME, TYPE, UNOCCUPIED, CLEANUP_FN) \
|
||||
static inline TYPE _scoped_##NAME##_unoccupied(void) { \
|
||||
return (UNOCCUPIED); \
|
||||
} \
|
||||
static inline void _scoped_##NAME##_cleanup(TYPE *_val) { \
|
||||
CLEANUP_FN(*_val); \
|
||||
*_val = (UNOCCUPIED); \
|
||||
} \
|
||||
static inline void _scoped_##NAME##_cleanup_raw(void *_val) { \
|
||||
_scoped_##NAME##_cleanup((TYPE *)_val); \
|
||||
} \
|
||||
static inline TYPE _scoped_##NAME##_release(TYPE *_val) { \
|
||||
TYPE _released = *_val; \
|
||||
*_val = (UNOCCUPIED); \
|
||||
return _released; \
|
||||
}
|
||||
|
||||
#define SCOPED(NAME, TYPE, VAL) \
|
||||
TYPE VAL __attribute__((cleanup(_scoped_##NAME##_cleanup_raw))) = _scoped_##NAME##_unoccupied()
|
||||
+64
-2
@@ -1,22 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SV_LIT(S) (S "LITERAL_CHECK", (str_view_t) { S, sizeof(S) - 1 })
|
||||
#define SV_LIT(S) ((void)(S "LITERAL_CHECK"), (str_view_t) { S, sizeof(S) - 1 })
|
||||
#define SV_NULL ((str_view_t) { NULL, 0 })
|
||||
#define SB_NULL ((str_buf_t) { NULL, 0 })
|
||||
#define SB_SCOPED(NAME) str_buf_t NAME __attribute__((cleanup(sb_free))) = SB_NULL
|
||||
|
||||
#define SV_PRI "%.*s"
|
||||
#define SV_PRI_ARGS(S) (int)((S).len), (S).ptr
|
||||
|
||||
// String which is:
|
||||
// - Not owned
|
||||
// - Not necessarily heap-allocated
|
||||
// - Not necessarily nul-terminated
|
||||
typedef struct {
|
||||
const char *ptr;
|
||||
size_t len;
|
||||
} str_view_t;
|
||||
|
||||
// String which is:
|
||||
// - Owned
|
||||
// - Heap-allocated
|
||||
// - Nul-terminated
|
||||
// The length does not include the nul terminator.
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
size_t len;
|
||||
} str_buf_t;
|
||||
|
||||
static inline bool sv_is_null(str_view_t s) {
|
||||
return !s.ptr;
|
||||
}
|
||||
|
||||
static inline bool sv_is_empty(str_view_t s) {
|
||||
return !s.len;
|
||||
}
|
||||
|
||||
static inline bool sb_is_null(str_buf_t buf) {
|
||||
return !buf.ptr;
|
||||
}
|
||||
|
||||
static inline bool sb_is_empty(str_buf_t buf) {
|
||||
return !buf.len;
|
||||
}
|
||||
|
||||
static inline str_view_t sv_from_parts(const char *ptr, size_t len) {
|
||||
return (str_view_t) { ptr, len };
|
||||
}
|
||||
|
||||
static inline str_view_t sv_from_cstr(const char *ptr, size_t maxlen) {
|
||||
size_t len = strnlen(ptr, maxlen);
|
||||
size_t len;
|
||||
|
||||
len = strnlen(ptr, maxlen);
|
||||
return sv_from_parts(ptr, len);
|
||||
}
|
||||
|
||||
@@ -24,3 +62,27 @@ static inline str_view_t sv_from_cstr_unbounded(const char *ptr) {
|
||||
size_t len = strlen(ptr);
|
||||
return sv_from_parts(ptr, len);
|
||||
}
|
||||
|
||||
static inline bool sv_eq(str_view_t s1, str_view_t s2) {
|
||||
return (s1.len == s2.len) && ((!s1.ptr || !s2.ptr)
|
||||
? (s1.ptr == s2.ptr)
|
||||
: !memcmp(s1.ptr, s2.ptr, s1.len));
|
||||
}
|
||||
|
||||
static inline str_view_t sv_substr(str_view_t s, size_t start, size_t end) {
|
||||
if ((start > end) || (start > s.len) || (end > s.len))
|
||||
return SV_NULL;
|
||||
return sv_from_parts(s.ptr + start, end - start);
|
||||
}
|
||||
|
||||
static inline str_view_t sb_view(str_buf_t buf) {
|
||||
return sv_from_parts(buf.ptr, buf.len);
|
||||
}
|
||||
|
||||
str_buf_t sb_from_sv(str_view_t s);
|
||||
|
||||
static inline void sb_free(str_buf_t *buf) {
|
||||
free(buf->ptr);
|
||||
buf->ptr = NULL;
|
||||
buf->len = 0;
|
||||
}
|
||||
@@ -8,6 +8,8 @@ sources = [
|
||||
'src/main.c',
|
||||
'src/server.c',
|
||||
'src/client.c',
|
||||
'src/str.c',
|
||||
'src/eventloop.c',
|
||||
]
|
||||
|
||||
includes = include_directories('include')
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "eventloop.h"
|
||||
#include "mem.h"
|
||||
|
||||
struct eventloop {
|
||||
int kqueue_fd;
|
||||
};
|
||||
|
||||
struct eventloop *eventloop_new(void) {
|
||||
MEM_SCOPED(struct eventloop, el);
|
||||
|
||||
if (!(el = malloc(sizeof(struct eventloop)))) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return MEM_RELEASE(struct eventloop, &el);
|
||||
}
|
||||
|
||||
void eventloop_free(struct eventloop *el) {
|
||||
if (!el)
|
||||
return;
|
||||
close(el->kqueue_fd);
|
||||
free(el);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "str.h"
|
||||
|
||||
str_buf_t sb_from_sv(str_view_t s) {
|
||||
char *buf;
|
||||
|
||||
if (sv_is_null(s) || sv_is_empty(s))
|
||||
return SB_NULL;
|
||||
|
||||
if (!(buf = malloc(s.len + 1)))
|
||||
return SB_NULL;
|
||||
|
||||
memcpy(buf, s.ptr, s.len);
|
||||
buf[s.len] = 0;
|
||||
return (str_buf_t) { buf, s.len };
|
||||
}
|
||||
Reference in new issue
Block a user