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; +} + | 
