summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/misc.C364
-rw-r--r--src/rxvtutil.C67
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;
+}
+