ltk

Socket-based GUI for X11 (WIP)
git clone git://lumidify.org/ltk.git (fast, but not encrypted)
git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

memory.c (4742B)


      1 /*
      2  * Copyright (c) 2021, 2022 lumidify <nobody@lumidify.org>
      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 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <stdarg.h>
     20 #include <string.h>
     21 #include <stdint.h>
     22 #include "util.h"
     23 #include "memory.h"
     24 
     25 char *
     26 ltk_strdup_impl(const char *s) {
     27 	char *str = strdup(s);
     28 	if (!str)
     29 		ltk_fatal("Out of memory.\n");
     30 	return str;
     31 }
     32 
     33 char *
     34 ltk_strdup_debug(const char *s, const char *caller, const char *file, int line) {
     35 	char *str = strdup(s);
     36 	fprintf(stderr, "DEBUG: strdup %p to %p in %s (%s:%d)\n",
     37 		(void *)s, (void *)str, caller, file, line);
     38 	if (!str)
     39 		ltk_fatal("Out of memory.\n");
     40 	return str;
     41 }
     42 
     43 char *
     44 ltk_strndup_impl(const char *s, size_t n) {
     45 	char *str = strndup(s, n);
     46 	if (!str)
     47 		ltk_fatal("Out of memory.\n");
     48 	return str;
     49 }
     50 
     51 char *
     52 ltk_strndup_debug(const char *s, size_t n, const char *caller, const char *file, int line) {
     53 	char *str = strndup(s, n);
     54 	fprintf(stderr, "DEBUG: strndup %p to %p in %s (%s:%d)\n",
     55 		(void *)s, (void *)str, caller, file, line);
     56 	if (!str)
     57 		ltk_fatal("Out of memory.\n");
     58 	return str;
     59 }
     60 
     61 void *
     62 ltk_malloc_impl(size_t size) {
     63 	void *ptr = malloc(size);
     64 	if (!ptr)
     65 		ltk_fatal("Out of memory.\n");
     66 	return ptr;
     67 }
     68 
     69 void *
     70 ltk_malloc_debug(size_t size, const char *caller, const char *file, int line) {
     71 	void *ptr = malloc(size);
     72 	fprintf(stderr, "DEBUG: malloc %p, %zu bytes in %s (%s:%d)\n",
     73 		ptr, size, caller, file, line);
     74 	if (!ptr)
     75 		ltk_fatal("Out of memory.\n");
     76 	return ptr;
     77 }
     78 
     79 void *
     80 ltk_calloc_impl(size_t nmemb, size_t size) {
     81 	void *ptr = calloc(nmemb, size);
     82 	if (!ptr)
     83 		ltk_fatal("Out of memory.\n");
     84 	return ptr;
     85 }
     86 
     87 void *
     88 ltk_calloc_debug(size_t nmemb, size_t size, const char *caller, const char *file, int line) {
     89 	void *ptr = calloc(nmemb, size);
     90 	fprintf(stderr, "DEBUG: calloc %p, %zu bytes in %s (%s:%d)\n",
     91 		ptr, size, caller, file, line);
     92 	if (!ptr)
     93 		ltk_fatal("Out of memory.\n");
     94 	return ptr;
     95 }
     96 
     97 void *
     98 ltk_realloc_impl(void *ptr, size_t size) {
     99 	void *new_ptr = realloc(ptr, size);
    100 	if (!new_ptr)
    101 		ltk_fatal("Out of memory.\n");
    102 	return new_ptr;
    103 }
    104 
    105 void *
    106 ltk_realloc_debug(void *ptr, size_t size, const char *caller, const char *file, int line) {
    107 	void *new_ptr = realloc(ptr, size);
    108 	fprintf(stderr, "DEBUG: realloc %p to %p, %zu bytes in %s (%s:%d)\n",
    109 		ptr, new_ptr, size, caller, file, line);
    110 	if (!new_ptr)
    111 		ltk_fatal("Out of memory.\n");
    112 	return new_ptr;
    113 }
    114 
    115 void
    116 ltk_free_debug(void *ptr, const char *caller, const char *file, int line) {
    117 	fprintf(stderr, "DEBUG: free %p in %s (%s:%d)\n", ptr, caller, file, line);
    118 	free(ptr);
    119 }
    120 
    121 /*
    122  * This (reallocarray) is from OpenBSD (adapted to exit on error):
    123  * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
    124  */
    125 
    126 /*
    127  * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
    128  * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
    129  */
    130 #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
    131 
    132 void *
    133 ltk_reallocarray(void *optr, size_t nmemb, size_t size)
    134 {
    135 	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
    136 	    nmemb > 0 && SIZE_MAX / nmemb < size) {
    137 		ltk_fatal("Integer overflow in allocation.\n");
    138 	}
    139 	return ltk_realloc(optr, size * nmemb);
    140 }
    141 
    142 /* FIXME: maybe don't double when already very large? */
    143 /* FIXME: better start size when old == 0? */
    144 size_t
    145 ideal_array_size(size_t old, size_t needed) {
    146 	size_t ret = old;
    147 	/* FIXME: the shrinking here only makes sense if not
    148 	   many elements are removed at once - what would be
    149 	   more sensible here? */
    150 	/* FIXME: overflow */
    151 	if (old < needed)
    152 		ret = old * 2 > needed ? old * 2 : needed;
    153 	else if (needed * 4 < old)
    154 		ret = old / 2;
    155 	if (ret == 0)
    156 		ret = 1; /* not sure if this is necessary */
    157 	return ret;
    158 }
    159 
    160 char *
    161 ltk_print_fmt(char *fmt, ...) {
    162 	va_list args;
    163 	va_start(args, fmt);
    164 	int len = vsnprintf(NULL, 0, fmt, args);
    165 	/* FIXME: what should be done on error? */
    166 	if (len < 0)
    167 		ltk_fatal("Error in vsnprintf called from print_fmt");
    168 	/* FIXME: overflow */
    169 	char *str = ltk_malloc(len + 1);
    170 	va_end(args);
    171 	va_start(args, fmt);
    172 	vsnprintf(str, len + 1, fmt, args);
    173 	va_end(args);
    174 	return str;
    175 }