diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/misc.C | 364 | ||||
-rw-r--r-- | src/rxvtutil.C | 67 |
2 files changed, 431 insertions, 0 deletions
diff --git a/src/misc.C b/src/misc.C new file mode 100644 index 0000000..ed92bc7 --- /dev/null +++ b/src/misc.C @@ -0,0 +1,364 @@ +/*----------------------------------------------------------------------* + * File: misc.C + *----------------------------------------------------------------------* + * + * All portions of code are copyright by their respective author/s. + * Copyright (c) 1996 mj olesen <olesen@me.QueensU.CA> Queen's Univ at Kingston + * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de> + * Copyright (c) 1998-2000 Geoff Wing <gcw@pobox.com> + * Copyright (c) 2003-2006 Marc Lehmann <schmorp@schmorp.de> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + *----------------------------------------------------------------------*/ + +#include "../config.h" /* NECESSARY */ +#include "rxvt.h" /* NECESSARY */ + +#include <new> + +// alas new/delete cannot be specified as inline in C++11 (see 17.6.4.6) +void * +operator new (size_t s) +#if !ECB_CPP11 + throw (std::bad_alloc) +#endif +{ + return rxvt_malloc (s); +} + +void +operator delete (void *p) +#if ECB_CPP11 + noexcept +#else + throw () +#endif +{ + free (p); +} + +char * +rxvt_wcstombs (const wchar_t *str, int len) +{ + if (len < 0) len = wcslen (str); + + mbstate mbs; + char *r = (char *)rxvt_malloc (len * MB_CUR_MAX + 1); + + char *dst = r; + while (len--) + { + ssize_t l = wcrtomb (dst, *str++, mbs); + + if (l < 0) + { + *dst++ = '?'; + wcrtomb (0, 0, mbs); // reset undefined state + } + else + dst += l; + } + + *dst++ = 0; + + return (char *)rxvt_realloc (r, dst - r); +} + +wchar_t * +rxvt_mbstowcs (const char *str, int len) +{ + if (len < 0) len = strlen (str); + + wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)); + + if ((ssize_t)mbstowcs (r, str, len + 1) < 0) + *r = 0; + + return r; +} + +char * +rxvt_wcstoutf8 (const wchar_t *str, int len) +{ + if (len < 0) len = wcslen (str); + + char *r = (char *)rxvt_malloc (len * 4 + 1); + char *p = r; + + while (len--) + { + unicode_t w = *str++ & UNICODE_MASK; + + if (w < 0x000080) + *p++ = w; + else if (w < 0x000800) + *p++ = 0xc0 | ( w >> 6), + *p++ = 0x80 | ( w & 0x3f); + else if (w < 0x010000) + *p++ = 0xe0 | ( w >> 12), + *p++ = 0x80 | ((w >> 6) & 0x3f), + *p++ = 0x80 | ( w & 0x3f); + else if (w < 0x110000) + *p++ = 0xf0 | ( w >> 18), + *p++ = 0x80 | ((w >> 12) & 0x3f), + *p++ = 0x80 | ((w >> 6) & 0x3f), + *p++ = 0x80 | ( w & 0x3f); + else + *p++ = '?'; + } + + *p++ = 0; + + return (char *)rxvt_realloc (r, p - r); +} + +wchar_t * +rxvt_utf8towcs (const char *str, int len) +{ + if (len < 0) len = strlen (str); + + wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)), + *p = r; + + unsigned char *s = (unsigned char *)str, + *e = s + len; + + for (;;) + { + len = e - s; + + if (len == 0) + break; + else if (s[0] < 0x80) + *p++ = *s++; + else if (len >= 2 + && s[0] >= 0xc2 && s[0] <= 0xdf + && (s[1] & 0xc0) == 0x80) + { + *p++ = ((s[0] & 0x1f) << 6) + | (s[1] & 0x3f); + s += 2; + } + else if (len >= 3 + && ( (s[0] == 0xe0 && s[1] >= 0xa0 && s[1] <= 0xbf) + || (s[0] >= 0xe1 && s[0] <= 0xec && s[1] >= 0x80 && s[1] <= 0xbf) + || (s[0] == 0xed && s[1] >= 0x80 && s[1] <= 0x9f) + || (s[0] >= 0xee && s[0] <= 0xef && s[1] >= 0x80 && s[1] <= 0xbf) + ) + && (s[2] & 0xc0) == 0x80) + { + *p++ = ((s[0] & 0x0f) << 12) + | ((s[1] & 0x3f) << 6) + | (s[2] & 0x3f); + s += 3; + } + else if (len >= 4 + && ( (s[0] == 0xf0 && s[1] >= 0x90 && s[1] <= 0xbf) + || (s[0] >= 0xf1 && s[0] <= 0xf3 && s[1] >= 0x80 && s[1] <= 0xbf) + || (s[0] == 0xf4 && s[1] >= 0x80 && s[1] <= 0x8f) + ) + && (s[2] & 0xc0) == 0x80 + && (s[3] & 0xc0) == 0x80) + { + *p++ = ((s[0] & 0x07) << 18) + | ((s[1] & 0x3f) << 12) + | ((s[2] & 0x3f) << 6) + | (s[3] & 0x3f); + s += 4; + } + else + { + *p++ = 0xfffd; + s++; + } + } + + *p = 0; + + return r; +} + +const char * +rxvt_basename (const char *str) NOTHROW +{ + const char *base = strrchr (str, '/'); + + return base ? base + 1 : str; +} + +/* + * Print an error message + */ +void +rxvt_vlog (const char *fmt, va_list arg_ptr) NOTHROW +{ + char msg[1024]; + + vsnprintf (msg, sizeof msg, fmt, arg_ptr); + + if (GET_R && GET_R->log_hook) + (*GET_R->log_hook) (msg); + else + write (STDOUT_FILENO, msg, strlen (msg)); +} + +void +rxvt_log (const char *fmt,...) NOTHROW +{ + va_list arg_ptr; + + va_start (arg_ptr, fmt); + rxvt_vlog (fmt, arg_ptr); + va_end (arg_ptr); +} + +/* + * Print an error message + */ +void +rxvt_warn (const char *fmt,...) NOTHROW +{ + va_list arg_ptr; + + rxvt_log ("%s: ", RESNAME); + + va_start (arg_ptr, fmt); + rxvt_vlog (fmt, arg_ptr); + va_end (arg_ptr); +} + +void +rxvt_fatal (const char *fmt,...) THROW ((class rxvt_failure_exception)) +{ + va_list arg_ptr; + + rxvt_log ("%s: ", RESNAME); + + va_start (arg_ptr, fmt); + rxvt_vlog (fmt, arg_ptr); + va_end (arg_ptr); + + rxvt_exit_failure (); +} + +void +rxvt_exit_failure () THROW ((class rxvt_failure_exception)) +{ + static class rxvt_failure_exception rxvt_failure_exception; + throw (rxvt_failure_exception); +} + +/* + * remove leading/trailing space in place. + */ +char * +rxvt_strtrim (char *str) NOTHROW +{ + char *r, *s; + + if (!str || !*str) /* shortcut */ + return str; + + /* skip leading spaces */ + for (s = str; *s && isspace (*s); s++) ; + + /* goto end of string */ + r = s + strlen (s) - 1; + + /* dump return and other trailing whitespace */ + while (r > s && isspace (*r)) + r--; + + memmove (str, s, r + 1 - s); + str[r + 1 - s] = 0; + + return str; +} + +/* + * Split a string into an array based on the given delimiter, stripping leading and + * trailing spaces from each entry. Empty strings are properly returned + */ +char ** +rxvt_strsplit (char delim, const char *str) NOTHROW +{ + int l, n; + char *s, *t; + char **ret; + + s = strdup (str ? str : ""); + + for (n = 1, t = s; *t; t++) + if (*t == delim) + n++; + + ret = (char **)malloc ((n + 1) * sizeof (char *)); + ret[n] = NULL; + + for (l = 0, t = s; l < n; l++) + { + for (; *t && *t != delim; t++) + ; + *t = '\0'; + ret[l] = s; + rxvt_strtrim (ret[l]); + s = ++t; + } + + return ret; +} + +void * +rxvt_malloc (size_t size) +{ + void *p = malloc (size); + + if (!p) + rxvt_fatal ("memory allocation failure. aborting.\n"); + + return p; +} + +void * +rxvt_calloc (size_t number, size_t size) +{ + void *p = calloc (number, size); + + if (!p) + rxvt_fatal ("memory allocation failure. aborting.\n"); + + return p; +} + +void * +rxvt_realloc (void *ptr, size_t size) +{ + void *p = realloc (ptr, size); + + if (!p) + rxvt_fatal ("memory allocation failure. aborting.\n"); + + return p; +} + +KeySym +rxvt_XKeycodeToKeysym (Display *dpy, KeyCode code, int index) +{ + int size; + KeySym *mapping = XGetKeyboardMapping (dpy, code, 1, &size); + KeySym keysym = IN_RANGE_EXC (index, 0, size) ? mapping[index] : NoSymbol; + XFree (mapping); + return keysym; +} diff --git a/src/rxvtutil.C b/src/rxvtutil.C new file mode 100644 index 0000000..663085f --- /dev/null +++ b/src/rxvtutil.C @@ -0,0 +1,67 @@ +/*----------------------------------------------------------------------* + * File: rxvtutil.C + *----------------------------------------------------------------------* + * + * All portions of code are copyright by their respective author/s. + * Copyright (c) 2004-2006 Marc Lehmann <schmorp@schmorp.de> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + *----------------------------------------------------------------------*/ + +// we include emman.c here to avoid relying on a C compiler, or +// on the c++ compiler not complaining about .c, which is unlikely, +// but... +// This must be the first include, because the _GNU_SOURCE and +// _XOPEN_SOURCE macros, used by emman.c, must be defined before +// inclusion of any header. +#include "emman.c" + +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> + +#include "rxvtutil.h" + +void * +zero_initialized::operator new (size_t s) +{ + void *p = malloc (s); + + memset (p, 0, s); + return p; +} + +void +zero_initialized::operator delete (void *p, size_t s) +{ + free (p); +} + +static void *temp_buf; +static uint32_t temp_len; + +void * +rxvt_temp_buf (int len) +{ + if (len > temp_len) + { + free (temp_buf); + temp_buf = malloc (len); + temp_len = len; + } + + return temp_buf; +} + |