/* util.c -- Various error checking wrappers and utilities. * * Copyright (C) 2016 Tomasz Kramkowski * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Some contents of this file (indicated below) are based on work covered by * the following copyright and permission notice: * * Copyright (c) 2008 Otto Moerbeek * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include "log.h" #include "util.h" /* szadd: checked size_t addition */ size_t szadd(size_t a, size_t b) { if (SIZE_MAX - a < b) error(0, EMSG_SZOP); return a + b; } /* szmul: checked size_t multiplication * License information can be found at the top of this file */ size_t szmul(size_t a, size_t b) { #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof (size_t) * 4)) if ((a >= MUL_NO_OVERFLOW || b >= MUL_NO_OVERFLOW) && a > 0 && SIZE_MAX / a < b) error(0, EMSG_SZOP); #undef MUL_NO_OVERFLOW return a * b; } /* xstrmalloc: allocate for a string (+1) or exit with error */ void *xstrmalloc(size_t size) { size_t nsize; nsize = size + 1; if (nsize < size) error(0, EMSG_ALLOC); return xmalloc(nsize); } /* xstrdup: duplicae string or exit with error */ char *xstrdup(const char *s) { char *ret; assert(s); ret = xstrmalloc(strlen(s)); strcpy(ret, s); return ret; } /* xrealloc: reallocate or exit with error */ void *xrealloc(void *p, size_t size) { p = realloc(p, size); if (!p) error(errno, EMSG_ALLOC); return p; } /* xmalloc: allocate or exit with error */ void *xmalloc(size_t size) { return xrealloc(NULL, size); } /* xstrcut: cut out a bit of a string into a new string */ char *xstrcut(const char *s, size_t offt, size_t len) { char *ret; ret = xstrmalloc(len); strncpy(ret, s + offt, len + 1); return ret; } /* xstrcasecmp: case insensitive strcmp */ int xstrcasecmp(const char *s1, const char *s2) { while (toupper(*s1++) == toupper(*s2++)) if (*s1 == '\0' || *s2 == '\0') break; if (*s1 == *s2) return 0; if (*s1 < *s2) return -1; return 1; }