1 /*----------------------------------------------------------------------*
3 *----------------------------------------------------------------------*
5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 1996 mj olesen <olesen@me.QueensU.CA> Queen's Univ at Kingston
7 * Copyright (c) 1997,1998 Oezguer Kesim <kesim@math.fu-berlin.de>
8 * Copyright (c) 1998-2000 Geoff Wing <gcw@pobox.com>
9 * Copyright (c) 2003-2006 Marc Lehmann <pcg@goof.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *----------------------------------------------------------------------*/
26 #include "../config.h" /* NECESSARY */
27 #include "rxvt.h" /* NECESSARY */
30 rxvt_wcstombs (const wchar_t *str, int len)
32 if (len < 0) len = wcslen (str);
35 char *r = (char *)rxvt_malloc (len * MB_CUR_MAX + 1);
40 ssize_t l = wcrtomb (dst, *str++, mbs);
45 wcrtomb (0, 0, mbs); // reset undefined state
53 return (char *)rxvt_realloc (r, dst - r);
57 rxvt_mbstowcs (const char *str, int len)
59 if (len < 0) len = strlen (str);
61 wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t));
63 if ((ssize_t)mbstowcs (r, str, len + 1) < 0)
70 rxvt_wcstoutf8 (const wchar_t *str, int len)
72 if (len < 0) len = wcslen (str);
74 char *r = (char *)rxvt_malloc (len * 4 + 1);
79 unicode_t w = *str++ & UNICODE_MASK;
83 else if (w < 0x000800)
84 *p++ = 0xc0 | ( w >> 6),
85 *p++ = 0x80 | ( w & 0x3f);
86 else if (w < 0x010000)
87 *p++ = 0xe0 | ( w >> 12),
88 *p++ = 0x80 | ((w >> 6) & 0x3f),
89 *p++ = 0x80 | ( w & 0x3f);
90 else if (w < 0x110000)
91 *p++ = 0xf0 | ( w >> 18),
92 *p++ = 0x80 | ((w >> 12) & 0x3f),
93 *p++ = 0x80 | ((w >> 6) & 0x3f),
94 *p++ = 0x80 | ( w & 0x3f);
101 return (char *)rxvt_realloc (r, p - r);
105 rxvt_utf8towcs (const char *str, int len)
107 if (len < 0) len = strlen (str);
109 wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)),
112 unsigned char *s = (unsigned char *)str,
121 else if (s[0] < 0x80)
124 && s[0] >= 0xc2 && s[0] <= 0xdf
125 && (s[1] & 0xc0) == 0x80)
127 *p++ = ((s[0] & 0x1f) << 6)
132 && ( (s[0] == 0xe0 && s[1] >= 0xa0 && s[1] <= 0xbf)
133 || (s[0] >= 0xe1 && s[0] <= 0xec && s[1] >= 0x80 && s[1] <= 0xbf)
134 || (s[0] == 0xed && s[1] >= 0x80 && s[1] <= 0x9f)
135 || (s[0] >= 0xee && s[0] <= 0xef && s[1] >= 0x80 && s[1] <= 0xbf)
137 && (s[2] & 0xc0) == 0x80)
139 *p++ = ((s[0] & 0x0f) << 12)
140 | ((s[1] & 0x3f) << 6)
145 && ( (s[0] == 0xf0 && s[1] >= 0x90 && s[1] <= 0xbf)
146 || (s[0] >= 0xf1 && s[0] <= 0xf3 && s[1] >= 0x80 && s[1] <= 0xbf)
147 || (s[0] == 0xf4 && s[1] >= 0x80 && s[1] <= 0x8f)
149 && (s[2] & 0xc0) == 0x80
150 && (s[3] & 0xc0) == 0x80)
152 *p++ = ((s[0] & 0x07) << 18)
153 | ((s[1] & 0x3f) << 12)
154 | ((s[2] & 0x3f) << 6)
171 rxvt_basename (const char *str) NOTHROW
173 const char *base = strrchr (str, '/');
175 return base ? base + 1 : str;
179 * Print an error message
182 rxvt_vlog (const char *fmt, va_list arg_ptr) NOTHROW
186 vsnprintf (msg, sizeof msg, fmt, arg_ptr);
188 if (GET_R && GET_R->log_hook)
189 (*GET_R->log_hook) (msg);
191 write (STDOUT_FILENO, msg, strlen (msg));
195 rxvt_log (const char *fmt,...) NOTHROW
199 va_start (arg_ptr, fmt);
200 rxvt_vlog (fmt, arg_ptr);
205 * Print an error message
208 rxvt_warn (const char *fmt,...) NOTHROW
212 rxvt_log ("%s: ", RESNAME);
214 va_start (arg_ptr, fmt);
215 rxvt_vlog (fmt, arg_ptr);
220 rxvt_fatal (const char *fmt,...) THROW ((class rxvt_failure_exception))
224 rxvt_log ("%s: ", RESNAME);
226 va_start (arg_ptr, fmt);
227 rxvt_vlog (fmt, arg_ptr);
230 rxvt_exit_failure ();
234 rxvt_exit_failure () THROW ((class rxvt_failure_exception))
236 static class rxvt_failure_exception rxvt_failure_exception;
237 throw (rxvt_failure_exception);
241 * remove leading/trailing space in place.
244 rxvt_strtrim (char *str) NOTHROW
248 if (!str || !*str) /* shortcut */
251 /* skip leading spaces */
252 for (s = str; *s && isspace (*s); s++) ;
254 /* goto end of string */
255 r = s + strlen (s) - 1;
257 /* dump return and other trailing whitespace */
258 while (r > s && isspace (*r))
261 memmove (str, s, r + 1 - s);
268 * Split a comma-separated string into an array, stripping leading and
269 * trailing spaces from each entry. Empty strings are properly returned
272 rxvt_splitcommastring (const char *cs) NOTHROW
278 if ((s = cs) == NULL)
281 for (n = 1, t = s; *t; t++)
285 ret = (char **)malloc ((n + 1) * sizeof (char *));
288 for (l = 0, t = s; l < n; l++)
290 for ( ; *t && *t != ','; t++) ;
292 ret[l] = (char *)malloc (p + 1);
293 memcpy (ret[l], s, p);
295 rxvt_strtrim (ret[l]);
303 rxvt_freecommastring (char **cs) NOTHROW
305 for (int i = 0; cs[i]; ++i)
312 rxvt_malloc (size_t size)
314 void *p = malloc (size);
317 rxvt_fatal ("memory allocation failure. aborting.\n");
323 rxvt_calloc (size_t number, size_t size)
325 void *p = calloc (number, size);
328 rxvt_fatal ("memory allocation failure. aborting.\n");
334 rxvt_realloc (void *ptr, size_t size)
336 void *p = realloc (ptr, size);
339 rxvt_fatal ("memory allocation failure. aborting.\n");