diff --git a/kittens/transfer/algorithm.c b/kittens/transfer/algorithm.c index 0f48e167d..7ee9bba6e 100644 --- a/kittens/transfer/algorithm.c +++ b/kittens/transfer/algorithm.c @@ -224,7 +224,7 @@ Patcher_dealloc(PyObject *self) { static PyObject* signature_header(Patcher *self, PyObject *a2) { - FREE_BUFFER_AFTER_FUNCTION Py_buffer dest = {0}; + RAII_PY_BUFFER(dest); if (PyObject_GetBuffer(a2, &dest, PyBUF_WRITE) == -1) return NULL; static const ssize_t header_size = 12; if (dest.len < header_size) { @@ -243,8 +243,7 @@ static PyObject* sign_block(Patcher *self, PyObject *args) { PyObject *a1, *a2; if (!PyArg_ParseTuple(args, "OO", &a1, &a2)) return NULL; - FREE_BUFFER_AFTER_FUNCTION Py_buffer src = {0}; - FREE_BUFFER_AFTER_FUNCTION Py_buffer dest = {0}; + RAII_PY_BUFFER(src); RAII_PY_BUFFER(dest); if (PyObject_GetBuffer(a1, &src, PyBUF_SIMPLE) == -1) return NULL; if (PyObject_GetBuffer(a2, &dest, PyBUF_WRITE) == -1) return NULL; if (dest.len < (ssize_t)signature_block_size) { @@ -307,16 +306,16 @@ unserialize_op(uint8_t *data, size_t len, Operation *op) { static bool write_block(Patcher *self, uint64_t block_index, PyObject *read, PyObject *write) { - DECREF_AFTER_FUNCTION PyObject *pos = PyLong_FromUnsignedLongLong((unsigned long long)(self->rsync.block_size * block_index)); + RAII_PyObject(pos, PyLong_FromUnsignedLongLong((unsigned long long)(self->rsync.block_size * block_index))); if (!pos) return false; - DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(read, pos, self->block_buf_view, NULL); + RAII_PyObject(ret, PyObject_CallFunctionObjArgs(read, pos, self->block_buf_view, NULL)); if (ret == NULL) return false; if (!PyLong_Check(ret)) { PyErr_SetString(PyExc_TypeError, "read callback function did not return an integer"); return false; } size_t n = PyLong_AsSize_t(ret); self->rsync.checksummer.update(self->rsync.checksummer.state, self->block_buf.data, n); - DECREF_AFTER_FUNCTION PyObject *view = PyMemoryView_FromMemory((char*)self->block_buf.data, n, PyBUF_READ); + RAII_PyObject(view, PyMemoryView_FromMemory((char*)self->block_buf.data, n, PyBUF_READ)); if (!view) return false; - DECREF_AFTER_FUNCTION PyObject *wret = PyObject_CallFunctionObjArgs(write, view, NULL); + RAII_PyObject(wret, PyObject_CallFunctionObjArgs(write, view, NULL)); if (wret == NULL) return false; return true; } @@ -345,9 +344,9 @@ apply_op(Patcher *self, Operation op, PyObject *read, PyObject *write) { case OpData: { self->total_data_in_delta += op.data.len; self->rsync.checksummer.update(self->rsync.checksummer.state, op.data.buf, op.data.len); - DECREF_AFTER_FUNCTION PyObject *view = PyMemoryView_FromMemory((char*)op.data.buf, op.data.len, PyBUF_READ); + RAII_PyObject(view, PyMemoryView_FromMemory((char*)op.data.buf, op.data.len, PyBUF_READ)); if (!view) return false; - DECREF_AFTER_FUNCTION PyObject *wret = PyObject_CallFunctionObjArgs(write, view, NULL); + RAII_PyObject(wret, PyObject_CallFunctionObjArgs(write, view, NULL)); if (!wret) return false; } return true; case OpHash: { @@ -357,9 +356,9 @@ apply_op(Patcher *self, Operation op, PyObject *read, PyObject *write) { if (memcmp(actual, op.data.buf, self->rsync.checksummer.hash_size) != 0) { char hexdigest[129]; bytes_as_hex(actual, self->rsync.checksummer.hash_size, hexdigest); - DECREF_AFTER_FUNCTION PyObject *h1 = PyUnicode_FromStringAndSize(hexdigest, 2*self->rsync.checksummer.hash_size); + RAII_PyObject(h1, PyUnicode_FromStringAndSize(hexdigest, 2*self->rsync.checksummer.hash_size)); bytes_as_hex(op.data.buf, op.data.len, hexdigest); - DECREF_AFTER_FUNCTION PyObject *h2 = PyUnicode_FromStringAndSize(hexdigest, 2*self->rsync.checksummer.hash_size); + RAII_PyObject(h2, PyUnicode_FromStringAndSize(hexdigest, 2*self->rsync.checksummer.hash_size)); PyErr_Format(RsyncError, "Failed to verify overall file checksum actual: %S != expected: %S, this usually happens because one of the involved files was altered while the operation was in progress.", h1, h2); return false; } @@ -373,7 +372,7 @@ apply_op(Patcher *self, Operation op, PyObject *read, PyObject *write) { static PyObject* apply_delta_data(Patcher *self, PyObject *args) { PyObject *read, *write; - FREE_BUFFER_AFTER_FUNCTION Py_buffer data = {0}; + RAII_PY_BUFFER(data); if (!PyArg_ParseTuple(args, "y*OO", &data, &read, &write)) return NULL; if (!write_to_buffer(&self->buf, data.buf, data.len)) return NULL; size_t pos = 0; @@ -543,7 +542,7 @@ parse_signature_block(Differ *self, uint8_t *data, size_t len) { static PyObject* add_signature_data(Differ *self, PyObject *args) { - FREE_BUFFER_AFTER_FUNCTION Py_buffer data = {0}; + RAII_PY_BUFFER(data); if (!PyArg_ParseTuple(args, "y*", &data)) return NULL; if (!write_to_buffer(&self->buf, data.buf, data.len)) return NULL; if (!self->signature_header_parsed) { @@ -597,12 +596,12 @@ send_op(Differ *self, Operation *op) { len = 5; break; } - DECREF_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)metadata, len, PyBUF_READ); - DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->write, mv, NULL); + RAII_PyObject(mv, PyMemoryView_FromMemory((char*)metadata, len, PyBUF_READ)); + RAII_PyObject(ret, PyObject_CallFunctionObjArgs(self->write, mv, NULL)); if (ret == NULL) return false; if (op->type == OpData) { - DECREF_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)op->data.buf, op->data.len, PyBUF_READ); - DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->write, mv, NULL); + RAII_PyObject(mv, PyMemoryView_FromMemory((char*)op->data.buf, op->data.len, PyBUF_READ)); + RAII_PyObject(ret, PyObject_CallFunctionObjArgs(self->write, mv, NULL)); if (ret == NULL) return false; } self->written = true; @@ -648,9 +647,9 @@ ensure_idx_valid(Differ *self, size_t idx) { self->data.pos = 0; return ensure_idx_valid(self, distance_from_window_pos); } - DECREF_AFTER_FUNCTION PyObject *mv = PyMemoryView_FromMemory((char*)self->buf.data + self->buf.len, self->buf.cap - self->buf.len, PyBUF_WRITE); + RAII_PyObject(mv, PyMemoryView_FromMemory((char*)self->buf.data + self->buf.len, self->buf.cap - self->buf.len, PyBUF_WRITE)); if (!mv) return false; - DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(self->read, mv, NULL); + RAII_PyObject(ret, PyObject_CallFunctionObjArgs(self->read, mv, NULL)); if (!ret) return false; if (!PyLong_Check(ret)) { PyErr_SetString(PyExc_TypeError, "read callback did not return an integer"); return false; } size_t n = PyLong_AsSize_t(ret); @@ -798,7 +797,7 @@ Hasher_init(PyObject *s, PyObject *args, PyObject *kwds) { Hasher *self = (Hasher*)s; static char *kwlist[] = {"which", "data", NULL}; const char *which = "xxh3-64"; - FREE_BUFFER_AFTER_FUNCTION Py_buffer data = {0}; + RAII_PY_BUFFER(data); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sy*", kwlist, &which, &data)) return -1; if (strcmp(which, "xxh3-64") == 0) { self->h = xxh64_hasher(); @@ -833,7 +832,7 @@ reset(Hasher *self, PyObject *args UNUSED) { static PyObject* update(Hasher *self, PyObject *o) { - FREE_BUFFER_AFTER_FUNCTION Py_buffer data = {0}; + RAII_PY_BUFFER(data); if (PyObject_GetBuffer(o, &data, PyBUF_SIMPLE) == -1) return NULL; if (data.buf && data.len > 0) { self->h.update(self->h.state, data.buf, data.len); @@ -904,7 +903,7 @@ PyTypeObject Hasher_Type = { static PyObject* decode_utf8_buffer(PyObject *self UNUSED, PyObject *args) { - FREE_BUFFER_AFTER_FUNCTION Py_buffer buf = {0}; + RAII_PY_BUFFER(buf); if (!PyArg_ParseTuple(args, "s*", &buf)) return NULL; return PyUnicode_FromStringAndSize(buf.buf, buf.len); } @@ -912,17 +911,17 @@ decode_utf8_buffer(PyObject *self UNUSED, PyObject *args) { static bool call_ftc_callback(PyObject *callback, char *src, Py_ssize_t key_start, Py_ssize_t key_length, Py_ssize_t val_start, Py_ssize_t val_length) { while(src[key_start] == ';' && key_length > 0 ) { key_start++; key_length--; } - DECREF_AFTER_FUNCTION PyObject *k = PyMemoryView_FromMemory(src + key_start, key_length, PyBUF_READ); + RAII_PyObject(k, PyMemoryView_FromMemory(src + key_start, key_length, PyBUF_READ)); if (!k) return false; - DECREF_AFTER_FUNCTION PyObject *v = PyMemoryView_FromMemory(src + val_start, val_length, PyBUF_READ); + RAII_PyObject(v, PyMemoryView_FromMemory(src + val_start, val_length, PyBUF_READ)); if (!v) return false; - DECREF_AFTER_FUNCTION PyObject *ret = PyObject_CallFunctionObjArgs(callback, k, v, NULL); + RAII_PyObject(ret, PyObject_CallFunctionObjArgs(callback, k, v, NULL)); return ret != NULL; } static PyObject* parse_ftc(PyObject *self UNUSED, PyObject *args) { - FREE_BUFFER_AFTER_FUNCTION Py_buffer buf = {0}; + RAII_PY_BUFFER(buf); PyObject *callback; size_t i = 0, key_start = 0, key_length = 0, val_start = 0, val_length = 0; if (!PyArg_ParseTuple(args, "s*O", &buf, &callback)) return NULL; diff --git a/kitty/child.c b/kitty/child.c index 9ddb4bc2a..aa328ee42 100644 --- a/kitty/child.c +++ b/kitty/child.c @@ -26,7 +26,7 @@ serialize_string_tuple(PyObject *src) { const char *pysrc = PyUnicode_AsUTF8(PyTuple_GET_ITEM(src, i)); if (!pysrc) { PyErr_Clear(); - DECREF_AFTER_FUNCTION PyObject *u8 = PyUnicode_AsEncodedString(PyTuple_GET_ITEM(src, i), "UTF-8", "ignore"); + RAII_PyObject(u8, PyUnicode_AsEncodedString(PyTuple_GET_ITEM(src, i), "UTF-8", "ignore")); if (!u8) { PyErr_Print(); fatal("couldn't parse command line"); } ans[i] = calloc(PyBytes_GET_SIZE(u8) + 1, sizeof(char)); if (ans[i] == NULL) fatal("Out of memory"); diff --git a/kitty/cocoa_window.m b/kitty/cocoa_window.m index be4d37b18..ae40efa84 100644 --- a/kitty/cocoa_window.m +++ b/kitty/cocoa_window.m @@ -683,7 +683,7 @@ cocoa_update_menu_bar_title(PyObject *pytitle) { if (OPT(macos_menubar_title_max_length) > 0 && PyUnicode_GetLength(pytitle) > OPT(macos_menubar_title_max_length)) { static char fmt[64]; snprintf(fmt, sizeof(fmt), "%%%ld.%ldU%%s", OPT(macos_menubar_title_max_length), OPT(macos_menubar_title_max_length)); - DECREF_AFTER_FUNCTION PyObject *st = PyUnicode_FromFormat(fmt, pytitle, "…"); + RAII_PyObject(st, PyUnicode_FromFormat(fmt, pytitle, "…")); if (st) title = @(PyUnicode_AsUTF8(st)); } else { title = @(PyUnicode_AsUTF8(pytitle)); diff --git a/kitty/colors.c b/kitty/colors.c index d507fdc1e..37e25df82 100644 --- a/kitty/colors.c +++ b/kitty/colors.c @@ -488,7 +488,7 @@ color_as_int(Color *self) { static PyObject* color_truediv(Color *self, PyObject *divisor) { - DECREF_AFTER_FUNCTION PyObject *o = PyNumber_Float(divisor); + RAII_PyObject(o, PyNumber_Float(divisor)); if (o == NULL) return NULL; double r = self->color.r, g = self->color.g, b = self->color.b, a = self->color.a; double d = PyFloat_AS_DOUBLE(o) * 255.; diff --git a/kitty/data-types.c b/kitty/data-types.c index f4b3d74a7..625cdf305 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -51,7 +51,7 @@ static PyObject* process_group_map(void) { int num_of_processes = proc_listallpids(NULL, 0); size_t bufsize = sizeof(pid_t) * (num_of_processes + 1024); - FREE_AFTER_FUNCTION pid_t *buf = malloc(bufsize); + RAII_ALLOC(pid_t, buf, malloc(bufsize)); if (!buf) return PyErr_NoMemory(); num_of_processes = proc_listallpids(buf, (int)bufsize); PyObject *ans = PyTuple_New(num_of_processes); @@ -79,7 +79,7 @@ redirect_std_streams(PyObject UNUSED *self, PyObject *args) { static PyObject* pybase64_encode(PyObject UNUSED *self, PyObject *args) { int add_padding = 0; - FREE_BUFFER_AFTER_FUNCTION Py_buffer view = {0}; + RAII_PY_BUFFER(view); if (!PyArg_ParseTuple(args, "s*|p", &view, &add_padding)) return NULL; size_t sz = required_buffer_size_for_base64_encode(view.len); PyObject *ans = PyBytes_FromStringAndSize(NULL, sz); @@ -91,7 +91,7 @@ pybase64_encode(PyObject UNUSED *self, PyObject *args) { static PyObject* pybase64_decode(PyObject UNUSED *self, PyObject *args) { - FREE_BUFFER_AFTER_FUNCTION Py_buffer view = {0}; + RAII_PY_BUFFER(view); if (!PyArg_ParseTuple(args, "s*", &view)) return NULL; size_t sz = required_buffer_size_for_base64_decode(view.len); PyObject *ans = PyBytes_FromStringAndSize(NULL, sz); diff --git a/kitty/data-types.h b/kitty/data-types.h index ad089a236..fafde2178 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -46,10 +46,10 @@ void log_error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); #define fatal(...) { log_error(__VA_ARGS__); exit(EXIT_FAILURE); } static inline void cleanup_free(void *p) { free(*(void**)p); } -#define FREE_AFTER_FUNCTION __attribute__((cleanup(cleanup_free))) +#define RAII_ALLOC(type, name, initializer) __attribute__((cleanup(cleanup_free))) type *name = initializer static inline void cleanup_decref(PyObject **p) { if(*p) { Py_DECREF(*p); *p = NULL;} } -#define DECREF_AFTER_FUNCTION __attribute__((cleanup(cleanup_decref))) -#define FREE_BUFFER_AFTER_FUNCTION __attribute__((cleanup(PyBuffer_Release))) +#define RAII_PyObject(name, initializer) __attribute__((cleanup(cleanup_decref))) PyObject *name = initializer +#define RAII_PY_BUFFER(name) __attribute__((cleanup(PyBuffer_Release))) Py_buffer name = {0} typedef unsigned long long id_type; typedef uint32_t char_type; diff --git a/kitty/disk-cache.c b/kitty/disk-cache.c index cdb00955d..f36750db3 100644 --- a/kitty/disk-cache.c +++ b/kitty/disk-cache.c @@ -80,7 +80,7 @@ open_cache_file_without_tmpfile(const char *cache_path) { int fd = -1; static const char template[] = "%s/disk-cache-XXXXXXXXXXXX"; const size_t sz = strlen(cache_path) + sizeof(template) + 4; - FREE_AFTER_FUNCTION char *buf = calloc(1, sz); + RAII_ALLOC(char, buf, calloc(1, sz)); if (!buf) { errno = ENOMEM; return -1; } snprintf(buf, sz - 1, template, cache_path); while (fd < 0) { @@ -132,8 +132,8 @@ typedef struct { static void defrag(DiskCache *self) { int new_cache_file = -1; - FREE_AFTER_FUNCTION DefragEntry *defrag_entries = NULL; - AutoFreeFastFileCopyBuffer fcb = {0}; + RAII_ALLOC(DefragEntry, defrag_entries, NULL); + RAII_FreeFastFileCopyBuffer(fcb); bool lock_released = false, ok = false; off_t size_on_disk = size_of_cache_file(self); @@ -441,7 +441,7 @@ add_to_disk_cache(PyObject *self_, const void *key, size_t key_sz, const void *d if (!ensure_state(self)) return false; if (key_sz > MAX_KEY_SIZE) { PyErr_SetString(PyExc_KeyError, "cache key is too long"); return false; } CacheEntry *s = NULL; - FREE_AFTER_FUNCTION uint8_t *copied_data = malloc(data_sz); + RAII_ALLOC(uint8_t, copied_data, malloc(data_sz)); if (!copied_data) { PyErr_NoMemory(); return false; } memcpy(copied_data, data, data_sz); diff --git a/kitty/fast-file-copy.h b/kitty/fast-file-copy.h index 39dda9b74..55e21d710 100644 --- a/kitty/fast-file-copy.h +++ b/kitty/fast-file-copy.h @@ -16,7 +16,6 @@ typedef struct FastFileCopyBuffer { static inline void free_fast_file_copy_buffer(FastFileCopyBuffer *fcb) { free(fcb->buf); fcb->buf = NULL; } -#define FREE_FCB_AFTER_FUNCTION __attribute__ ((__cleanup__(free_fast_file_copy_buffer))) -#define AutoFreeFastFileCopyBuffer FREE_FCB_AFTER_FUNCTION FastFileCopyBuffer +#define RAII_FreeFastFileCopyBuffer(name) __attribute__ ((__cleanup__(free_fast_file_copy_buffer))) FastFileCopyBuffer name = {0} bool copy_between_files(int infd, int outfd, off_t in_pos, size_t len, FastFileCopyBuffer *fcb); diff --git a/kitty/fonts.c b/kitty/fonts.c index 58e3dd10c..2295ecce7 100644 --- a/kitty/fonts.c +++ b/kitty/fonts.c @@ -1527,7 +1527,7 @@ sprite_map_set_layout(PyObject UNUSED *self, PyObject *args) { static PyObject* test_sprite_position_for(PyObject UNUSED *self, PyObject *args) { int error; - FREE_AFTER_FUNCTION glyph_index *glyphs = calloc(PyTuple_GET_SIZE(args), sizeof(glyph_index)); + RAII_ALLOC(glyph_index, glyphs, calloc(PyTuple_GET_SIZE(args), sizeof(glyph_index))); for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(args); i++) { if (!PyLong_Check(PyTuple_GET_ITEM(args, i))) { PyErr_SetString(PyExc_TypeError, "glyph indices must be integers"); diff --git a/kitty/freetype_render_ui_text.c b/kitty/freetype_render_ui_text.c index 49d0d15a6..bcbe46210 100644 --- a/kitty/freetype_render_ui_text.c +++ b/kitty/freetype_render_ui_text.c @@ -494,14 +494,14 @@ typedef struct TempFontData { FT_UInt orig_sz; } TempFontData; -static void cleanup_resize(void *p) { - TempFontData *f = p; +static void +cleanup_resize(TempFontData *f) { if (f->face && f->face->freetype) { f->face->pixel_size = f->orig_sz; FT_Set_Pixel_Sizes(f->face->freetype, f->orig_sz, f->orig_sz); } } -#define RESIZE_AFTER_FUNCTION __attribute__((cleanup(cleanup_resize))) +#define RAII_TempFontData(name) __attribute__((cleanup(cleanup_resize))) TempFontData name = {0} static void* report_freetype_error_for_char(int error, char ch, const char *operation) { @@ -515,7 +515,7 @@ uint8_t* render_single_ascii_char_as_mask(FreeTypeRenderCtx ctx_, const char ch, size_t *result_width, size_t *result_height) { RenderCtx *ctx = (RenderCtx*)ctx_; if (!ctx->created) { PyErr_SetString(PyExc_RuntimeError, "freetype render ctx not created"); return NULL; } - RESIZE_AFTER_FUNCTION TempFontData temp = {0}; + RAII_TempFontData(temp); Face *face = &main_face; int glyph_index = FT_Get_Char_Index(face->freetype, ch); if (!glyph_index) { PyErr_Format(PyExc_KeyError, "character %c not found in font", ch); return NULL; } diff --git a/kitty/glfw.c b/kitty/glfw.c index e0dea6b42..6e41861aa 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -92,7 +92,7 @@ update_menu_bar_title(PyObject *title UNUSED) { #ifdef __APPLE__ static char buf[2048]; strip_csi_(PyUnicode_AsUTF8(title), buf, arraysz(buf)); - DECREF_AFTER_FUNCTION PyObject *stitle = PyUnicode_FromString(buf); + RAII_PyObject(stitle, PyUnicode_FromString(buf)); cocoa_update_menu_bar_title(stitle); #endif } @@ -1836,7 +1836,7 @@ strip_csi(PyObject *self UNUSED, PyObject *src) { Py_ssize_t sz; const char *title = PyUnicode_AsUTF8AndSize(src, &sz); if (!title) return NULL; - FREE_AFTER_FUNCTION char *buf = malloc(sz + 1); + RAII_ALLOC(char, buf, malloc(sz + 1)); if (!buf) { return PyErr_NoMemory(); } strip_csi_(title, buf, sz + 1); return PyUnicode_FromString(buf); diff --git a/kitty/graphics.c b/kitty/graphics.c index 47fdd5f79..30f10ac99 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -24,7 +24,7 @@ PyTypeObject GraphicsManager_Type; #define DEFAULT_STORAGE_LIMIT 320u * (1024u * 1024u) #define REPORT_ERROR(...) { log_error(__VA_ARGS__); } -#define FREE_CFD_AFTER_FUNCTION __attribute__((cleanup(cfd_free))) +#define RAII_CoalescedFrameData(name, initializer) __attribute__((cleanup(cfd_free))) CoalescedFrameData name = initializer // caching {{{ #define CACHE_KEY_BUFFER_SIZE 32 @@ -424,7 +424,7 @@ load_image_data(GraphicsManager *self, Image *img, const GraphicsCommand *g, con else fd = safe_open(fname, O_CLOEXEC | O_RDONLY | O_NONBLOCK, 0); // O_NONBLOCK so that opening a FIFO pipe does not block if (fd == -1) ABRT("EBADF", "Failed to open file for graphics transmission with error: [%d] %s", errno, strerror(errno)); if (global_state.boss && transmission_type != 's') { - DECREF_AFTER_FUNCTION PyObject *cret_ = PyObject_CallMethod(global_state.boss, "is_ok_to_read_image_file", "si", fname, fd); + RAII_PyObject(cret_, PyObject_CallMethod(global_state.boss, "is_ok_to_read_image_file", "si", fname, fd)); if (cret_ == NULL) { PyErr_Print(); ABRT("EBADF", "Failed to check file for read permission"); @@ -1496,7 +1496,7 @@ scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t // {{{ composition a=c static void -cfd_free(void *p) { free(((CoalescedFrameData*)p)->buf); } +cfd_free(CoalescedFrameData *p) { free((p)->buf); p->buf = NULL; } static void handle_compose_command(GraphicsManager *self, bool *is_dirty, const GraphicsCommand *g, Image *img) { @@ -1530,12 +1530,12 @@ handle_compose_command(GraphicsManager *self, bool *is_dirty, const GraphicsComm } } - FREE_CFD_AFTER_FUNCTION CoalescedFrameData src_data = get_coalesced_frame_data(self, img, src_frame); + RAII_CoalescedFrameData(src_data, get_coalesced_frame_data(self, img, src_frame)); if (!src_data.buf) { set_command_failed_response("EINVAL", "Failed to get data for src frame: %u", g->frame_number - 1); return; } - FREE_CFD_AFTER_FUNCTION CoalescedFrameData dest_data = get_coalesced_frame_data(self, img, dest_frame); + RAII_CoalescedFrameData(dest_data, get_coalesced_frame_data(self, img, dest_frame)); if (!dest_data.buf) { set_command_failed_response("EINVAL", "Failed to get data for destination frame: %u", g->other_frame_number - 1); return; diff --git a/kitty/launcher/main.c b/kitty/launcher/main.c index d2308128e..10e4ca3d0 100644 --- a/kitty/launcher/main.c +++ b/kitty/launcher/main.c @@ -28,13 +28,13 @@ #endif static void cleanup_free(void *p) { free(*(void**) p); } -#define FREE_AFTER_FUNCTION __attribute__((cleanup(cleanup_free))) +#define RAII_ALLOC(type, name, initializer) __attribute__((cleanup(cleanup_free))) type *name = initializer #ifndef __FreeBSD__ static bool safe_realpath(const char* src, char *buf, size_t buf_sz) { - FREE_AFTER_FUNCTION char* ans = realpath(src, NULL); + RAII_ALLOC(char, ans, realpath(src, NULL)); if (ans == NULL) return false; snprintf(buf, buf_sz, "%s", ans); return true; @@ -83,8 +83,8 @@ canonicalize_path(const char *srcpath, char *dstpath, size_t sz) { // remove . and .. path segments bool ok = false; size_t plen = strlen(srcpath) + 1, chk; - FREE_AFTER_FUNCTION char *wtmp = malloc(plen); - FREE_AFTER_FUNCTION char **tokv = malloc(sizeof(char*) * plen); + RAII_ALLOC(char, wtmp, malloc(plen)); + RAII_ALLOC(char*, tokv, malloc(sizeof(char*) * plen)); if (!wtmp || !tokv) goto end; char *s, *tok, *sav; bool relpath = *srcpath != '/'; @@ -360,7 +360,7 @@ int main(int argc, char *argv[], char* envp[]) { if (!ensure_working_stdio()) return 1; char exe[PATH_MAX+1] = {0}; char exe_dir_buf[PATH_MAX+1] = {0}; - FREE_AFTER_FUNCTION const char *lc_ctype = NULL; + RAII_ALLOC(const char, lc_ctype, NULL); #ifdef __APPLE__ lc_ctype = getenv("LC_CTYPE"); if (lc_ctype) lc_ctype = strdup(lc_ctype); diff --git a/kitty/line-buf.c b/kitty/line-buf.c index 91bd24af9..7170b4fce 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -469,7 +469,7 @@ as_text(LineBuf *self, PyObject *args) { static PyObject* __str__(LineBuf *self) { - DECREF_AFTER_FUNCTION PyObject *lines = PyTuple_New(self->ynum); + RAII_PyObject(lines, PyTuple_New(self->ynum)); if (lines == NULL) return PyErr_NoMemory(); for (index_type i = 0; i < self->ynum; i++) { init_line(self, self->line, self->line_map[i]); @@ -477,7 +477,7 @@ __str__(LineBuf *self) { if (t == NULL) return NULL; PyTuple_SET_ITEM(lines, i, t); } - DECREF_AFTER_FUNCTION PyObject *sep = PyUnicode_FromString("\n"); + RAII_PyObject(sep, PyUnicode_FromString("\n")); return PyUnicode_Join(sep, lines); } diff --git a/kitty/line.c b/kitty/line.c index 80f333649..930b372f2 100644 --- a/kitty/line.c +++ b/kitty/line.c @@ -853,9 +853,9 @@ as_text_generic(PyObject *args, void *container, get_line_func get_line, index_t int as_ansi = 0, insert_wrap_markers = 0; if (!PyArg_ParseTuple(args, "O|pp", &callback, &as_ansi, &insert_wrap_markers)) return NULL; PyObject *t = NULL; - DECREF_AFTER_FUNCTION PyObject *nl = PyUnicode_FromString("\n"); - DECREF_AFTER_FUNCTION PyObject *cr = PyUnicode_FromString("\r"); - DECREF_AFTER_FUNCTION PyObject *sgr_reset = PyUnicode_FromString("\x1b[m"); + RAII_PyObject(nl, PyUnicode_FromString("\n")); + RAII_PyObject(cr, PyUnicode_FromString("\r")); + RAII_PyObject(sgr_reset, PyUnicode_FromString("\x1b[m")); if (nl == NULL || cr == NULL || sgr_reset == NULL) return NULL; const GPUCell *prev_cell = NULL; ansibuf->active_hyperlink_id = 0; diff --git a/kitty/options/to-c.h b/kitty/options/to-c.h index cc915bbb8..7634c9eb8 100644 --- a/kitty/options/to-c.h +++ b/kitty/options/to-c.h @@ -192,18 +192,18 @@ text_composition_strategy(PyObject *val, Options *opts) { else if (PyUnicode_CompareWithASCIIString(val, "legacy") == 0) { opts->text_old_gamma = true; } else { - DECREF_AFTER_FUNCTION PyObject *parts = PyUnicode_Split(val, NULL, 2); + RAII_PyObject(parts, PyUnicode_Split(val, NULL, 2)); int size = PyList_GET_SIZE(parts); if (size < 1 || 2 < size) { PyErr_SetString(PyExc_ValueError, "text_rendering_strategy must be of the form number:[number]"); return; } if (size > 0) { - DECREF_AFTER_FUNCTION PyObject *ga = PyFloat_FromString(PyList_GET_ITEM(parts, 0)); + RAII_PyObject(ga, PyFloat_FromString(PyList_GET_ITEM(parts, 0))); if (PyErr_Occurred()) return; opts->text_gamma_adjustment = MAX(0.01f, PyFloat_AsFloat(ga)); } if (size > 1) { - DECREF_AFTER_FUNCTION PyObject *contrast = PyFloat_FromString(PyList_GET_ITEM(parts, 1)); + RAII_PyObject(contrast, PyFloat_FromString(PyList_GET_ITEM(parts, 1))); if (PyErr_Occurred()) return; opts->text_contrast = MAX(0.0f, PyFloat_AsFloat(contrast)); opts->text_contrast = MIN(100.0f, opts->text_contrast); diff --git a/kitty/parser.c b/kitty/parser.c index eb82e5d75..6f69da014 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -1581,7 +1581,7 @@ do_parse_bytes(Screen *screen, const uint8_t *read_buf, const size_t read_buf_sz PyObject* FNAME(parse_bytes)(PyObject UNUSED *self, PyObject *args) { PyObject *dump_callback = NULL; - FREE_BUFFER_AFTER_FUNCTION Py_buffer pybuf = {0}; + RAII_PY_BUFFER(pybuf); Screen *screen; #ifdef DUMP_COMMANDS if (!PyArg_ParseTuple(args, "OO!y*", &dump_callback, &Screen_Type, &screen, &pybuf)) return NULL; diff --git a/kitty/screen.c b/kitty/screen.c index 04bf09b43..9daba9f7a 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -2049,9 +2049,9 @@ shell_prompt_marking(Screen *self, PyObject *data) { PromptKind pk = PROMPT_START; self->prompt_settings.redraws_prompts_at_all = 1; if (PyUnicode_FindChar(data, ';', 0, PyUnicode_GET_LENGTH(data), 1)) { - DECREF_AFTER_FUNCTION PyObject *sep = PyUnicode_FromString(";"); + RAII_PyObject(sep, PyUnicode_FromString(";")); if (sep) { - DECREF_AFTER_FUNCTION PyObject *parts = PyUnicode_Split(data, sep, -1); + RAII_PyObject(parts, PyUnicode_Split(data, sep, -1)); if (parts) parse_prompt_mark(self, parts, &pk); } } @@ -2707,8 +2707,8 @@ ansi_for_range(Screen *self, const Selection *sel, bool insert_newlines, bool st IterationData idata; iteration_data(self, sel, &idata, -self->historybuf->count, false); int limit = MIN((int)self->lines, idata.y_limit); - DECREF_AFTER_FUNCTION PyObject *ans = PyTuple_New(limit - idata.y + 1); - DECREF_AFTER_FUNCTION PyObject *nl = PyUnicode_FromString("\n"); + RAII_PyObject(ans, PyTuple_New(limit - idata.y + 1)); + RAII_PyObject(nl, PyUnicode_FromString("\n")); if (!ans || !nl) return NULL; ANSIBuf output = {0}; const GPUCell *prev_cell = NULL; @@ -2941,7 +2941,7 @@ screen_update_overlay_text(Screen *self, const char *utf8_text) { if (!text) return; Py_XDECREF(self->overlay_line.overlay_text); // Calculate the total number of cells for initial overlay cursor position - DECREF_AFTER_FUNCTION PyObject *text_len = wcswidth_std(NULL, text); + RAII_PyObject(text_len, wcswidth_std(NULL, text)); self->overlay_line.overlay_text = text; self->overlay_line.is_active = true; self->overlay_line.is_dirty = true; @@ -3230,8 +3230,8 @@ find_cmd_output(Screen *self, OutputOffset *oo, index_type start_screen_y, unsig static PyObject* cmd_output(Screen *self, PyObject *args) { unsigned int which = 0; - DECREF_AFTER_FUNCTION PyObject *which_args = PyTuple_GetSlice(args, 0, 1); - DECREF_AFTER_FUNCTION PyObject *as_text_args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); + RAII_PyObject(which_args, PyTuple_GetSlice(args, 0, 1)); + RAII_PyObject(as_text_args, PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args))); if (!which_args || !as_text_args) return NULL; if (!PyArg_ParseTuple(which_args, "I", &which)) return NULL; if (self->linebuf != self->main_linebuf) Py_RETURN_NONE; @@ -3280,7 +3280,7 @@ cmd_output(Screen *self, PyObject *args) { return NULL; } if (found) { - DECREF_AFTER_FUNCTION PyObject *ret = as_text_generic(as_text_args, &oo, get_line_from_offset, oo.num_lines, &self->as_ansi_buf, false); + RAII_PyObject(ret, as_text_generic(as_text_args, &oo, get_line_from_offset, oo.num_lines, &self->as_ansi_buf, false)); if (!ret) return NULL; } if (oo.reached_upper_limit && self->linebuf == self->main_linebuf && OPT(scrollback_pager_history_size) > 0) Py_RETURN_TRUE; @@ -4166,7 +4166,7 @@ paste_(Screen *self, PyObject *bytes, bool allow_bracketed_paste) { if (PyBytes_Check(bytes)) { data = PyBytes_AS_STRING(bytes); sz = PyBytes_GET_SIZE(bytes); } else if (PyMemoryView_Check(bytes)) { - DECREF_AFTER_FUNCTION PyObject *mv = PyMemoryView_GetContiguous(bytes, PyBUF_READ, PyBUF_C_CONTIGUOUS); + RAII_PyObject(mv, PyMemoryView_GetContiguous(bytes, PyBUF_READ, PyBUF_C_CONTIGUOUS)); if (mv == NULL) return NULL; Py_buffer *buf = PyMemoryView_GET_BUFFER(mv); data = buf->buf; diff --git a/kitty/shaders.c b/kitty/shaders.c index 57651e073..9ec261d37 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -1047,7 +1047,7 @@ draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_bu static bool attach_shaders(PyObject *sources, GLuint program_id, GLenum shader_type) { - FREE_AFTER_FUNCTION const GLchar * * c_sources = calloc(sizeof(char*), PyTuple_GET_SIZE(sources)); + RAII_ALLOC(const GLchar*, c_sources, calloc(sizeof(GLchar*), PyTuple_GET_SIZE(sources))); for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(sources); i++) { PyObject *temp = PyTuple_GET_ITEM(sources, i); if (!PyUnicode_Check(temp)) { PyErr_SetString(PyExc_TypeError, "shaders must be strings"); return false; }