ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/misc.C
Revision: 1.59
Committed: Wed Nov 12 12:12:02 2014 UTC (9 years, 7 months ago) by sf-exg
Content type: text/plain
Branch: MAIN
CVS Tags: rxvt-unicode-rel-9_22, rxvt-unicode-rel-9_21
Changes since 1.58: +23 -0 lines
Log Message:
Make new/delete compatible with C++11 and change new to use rxvt_malloc.

File Contents

# Content
1 /*----------------------------------------------------------------------*
2 * File: misc.C
3 *----------------------------------------------------------------------*
4 *
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 <schmorp@schmorp.de>
10 *
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 3 of the License, or
14 * (at your option) any later version.
15 *
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.
20 *
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 *----------------------------------------------------------------------*/
25
26 #include "../config.h" /* NECESSARY */
27 #include "rxvt.h" /* NECESSARY */
28
29 #include <new>
30
31 // alas new/delete cannot be specified as inline in C++11 (see 17.6.4.6)
32 void *
33 operator new (size_t s)
34 #if !ECB_CPP11
35 throw (std::bad_alloc)
36 #endif
37 {
38 return rxvt_malloc (s);
39 }
40
41 void
42 operator delete (void *p)
43 #if ECB_CPP11
44 noexcept
45 #else
46 throw ()
47 #endif
48 {
49 free (p);
50 }
51
52 char *
53 rxvt_wcstombs (const wchar_t *str, int len)
54 {
55 if (len < 0) len = wcslen (str);
56
57 mbstate mbs;
58 char *r = (char *)rxvt_malloc (len * MB_CUR_MAX + 1);
59
60 char *dst = r;
61 while (len--)
62 {
63 ssize_t l = wcrtomb (dst, *str++, mbs);
64
65 if (l < 0)
66 {
67 *dst++ = '?';
68 wcrtomb (0, 0, mbs); // reset undefined state
69 }
70 else
71 dst += l;
72 }
73
74 *dst++ = 0;
75
76 return (char *)rxvt_realloc (r, dst - r);
77 }
78
79 wchar_t *
80 rxvt_mbstowcs (const char *str, int len)
81 {
82 if (len < 0) len = strlen (str);
83
84 wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t));
85
86 if ((ssize_t)mbstowcs (r, str, len + 1) < 0)
87 *r = 0;
88
89 return r;
90 }
91
92 char *
93 rxvt_wcstoutf8 (const wchar_t *str, int len)
94 {
95 if (len < 0) len = wcslen (str);
96
97 char *r = (char *)rxvt_malloc (len * 4 + 1);
98 char *p = r;
99
100 while (len--)
101 {
102 unicode_t w = *str++ & UNICODE_MASK;
103
104 if (w < 0x000080)
105 *p++ = w;
106 else if (w < 0x000800)
107 *p++ = 0xc0 | ( w >> 6),
108 *p++ = 0x80 | ( w & 0x3f);
109 else if (w < 0x010000)
110 *p++ = 0xe0 | ( w >> 12),
111 *p++ = 0x80 | ((w >> 6) & 0x3f),
112 *p++ = 0x80 | ( w & 0x3f);
113 else if (w < 0x110000)
114 *p++ = 0xf0 | ( w >> 18),
115 *p++ = 0x80 | ((w >> 12) & 0x3f),
116 *p++ = 0x80 | ((w >> 6) & 0x3f),
117 *p++ = 0x80 | ( w & 0x3f);
118 else
119 *p++ = '?';
120 }
121
122 *p++ = 0;
123
124 return (char *)rxvt_realloc (r, p - r);
125 }
126
127 wchar_t *
128 rxvt_utf8towcs (const char *str, int len)
129 {
130 if (len < 0) len = strlen (str);
131
132 wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)),
133 *p = r;
134
135 unsigned char *s = (unsigned char *)str,
136 *e = s + len;
137
138 for (;;)
139 {
140 len = e - s;
141
142 if (len == 0)
143 break;
144 else if (s[0] < 0x80)
145 *p++ = *s++;
146 else if (len >= 2
147 && s[0] >= 0xc2 && s[0] <= 0xdf
148 && (s[1] & 0xc0) == 0x80)
149 {
150 *p++ = ((s[0] & 0x1f) << 6)
151 | (s[1] & 0x3f);
152 s += 2;
153 }
154 else if (len >= 3
155 && ( (s[0] == 0xe0 && s[1] >= 0xa0 && s[1] <= 0xbf)
156 || (s[0] >= 0xe1 && s[0] <= 0xec && s[1] >= 0x80 && s[1] <= 0xbf)
157 || (s[0] == 0xed && s[1] >= 0x80 && s[1] <= 0x9f)
158 || (s[0] >= 0xee && s[0] <= 0xef && s[1] >= 0x80 && s[1] <= 0xbf)
159 )
160 && (s[2] & 0xc0) == 0x80)
161 {
162 *p++ = ((s[0] & 0x0f) << 12)
163 | ((s[1] & 0x3f) << 6)
164 | (s[2] & 0x3f);
165 s += 3;
166 }
167 else if (len >= 4
168 && ( (s[0] == 0xf0 && s[1] >= 0x90 && s[1] <= 0xbf)
169 || (s[0] >= 0xf1 && s[0] <= 0xf3 && s[1] >= 0x80 && s[1] <= 0xbf)
170 || (s[0] == 0xf4 && s[1] >= 0x80 && s[1] <= 0x8f)
171 )
172 && (s[2] & 0xc0) == 0x80
173 && (s[3] & 0xc0) == 0x80)
174 {
175 *p++ = ((s[0] & 0x07) << 18)
176 | ((s[1] & 0x3f) << 12)
177 | ((s[2] & 0x3f) << 6)
178 | (s[3] & 0x3f);
179 s += 4;
180 }
181 else
182 {
183 *p++ = 0xfffd;
184 s++;
185 }
186 }
187
188 *p = 0;
189
190 return r;
191 }
192
193 const char *
194 rxvt_basename (const char *str) NOTHROW
195 {
196 const char *base = strrchr (str, '/');
197
198 return base ? base + 1 : str;
199 }
200
201 /*
202 * Print an error message
203 */
204 void
205 rxvt_vlog (const char *fmt, va_list arg_ptr) NOTHROW
206 {
207 char msg[1024];
208
209 vsnprintf (msg, sizeof msg, fmt, arg_ptr);
210
211 if (GET_R && GET_R->log_hook)
212 (*GET_R->log_hook) (msg);
213 else
214 write (STDOUT_FILENO, msg, strlen (msg));
215 }
216
217 void
218 rxvt_log (const char *fmt,...) NOTHROW
219 {
220 va_list arg_ptr;
221
222 va_start (arg_ptr, fmt);
223 rxvt_vlog (fmt, arg_ptr);
224 va_end (arg_ptr);
225 }
226
227 /*
228 * Print an error message
229 */
230 void
231 rxvt_warn (const char *fmt,...) NOTHROW
232 {
233 va_list arg_ptr;
234
235 rxvt_log ("%s: ", RESNAME);
236
237 va_start (arg_ptr, fmt);
238 rxvt_vlog (fmt, arg_ptr);
239 va_end (arg_ptr);
240 }
241
242 void
243 rxvt_fatal (const char *fmt,...) THROW ((class rxvt_failure_exception))
244 {
245 va_list arg_ptr;
246
247 rxvt_log ("%s: ", RESNAME);
248
249 va_start (arg_ptr, fmt);
250 rxvt_vlog (fmt, arg_ptr);
251 va_end (arg_ptr);
252
253 rxvt_exit_failure ();
254 }
255
256 void
257 rxvt_exit_failure () THROW ((class rxvt_failure_exception))
258 {
259 static class rxvt_failure_exception rxvt_failure_exception;
260 throw (rxvt_failure_exception);
261 }
262
263 /*
264 * remove leading/trailing space in place.
265 */
266 char *
267 rxvt_strtrim (char *str) NOTHROW
268 {
269 char *r, *s;
270
271 if (!str || !*str) /* shortcut */
272 return str;
273
274 /* skip leading spaces */
275 for (s = str; *s && isspace (*s); s++) ;
276
277 /* goto end of string */
278 r = s + strlen (s) - 1;
279
280 /* dump return and other trailing whitespace */
281 while (r > s && isspace (*r))
282 r--;
283
284 memmove (str, s, r + 1 - s);
285 str[r + 1 - s] = 0;
286
287 return str;
288 }
289
290 /*
291 * Split a string into an array based on the given delimiter, stripping leading and
292 * trailing spaces from each entry. Empty strings are properly returned
293 */
294 char **
295 rxvt_strsplit (char delim, const char *str) NOTHROW
296 {
297 int l, n;
298 char *s, *t;
299 char **ret;
300
301 s = strdup (str ? str : "");
302
303 for (n = 1, t = s; *t; t++)
304 if (*t == delim)
305 n++;
306
307 ret = (char **)malloc ((n + 1) * sizeof (char *));
308 ret[n] = NULL;
309
310 for (l = 0, t = s; l < n; l++)
311 {
312 for (; *t && *t != delim; t++)
313 ;
314 *t = '\0';
315 ret[l] = s;
316 rxvt_strtrim (ret[l]);
317 s = ++t;
318 }
319
320 return ret;
321 }
322
323 void *
324 rxvt_malloc (size_t size)
325 {
326 void *p = malloc (size);
327
328 if (!p)
329 rxvt_fatal ("memory allocation failure. aborting.\n");
330
331 return p;
332 }
333
334 void *
335 rxvt_calloc (size_t number, size_t size)
336 {
337 void *p = calloc (number, size);
338
339 if (!p)
340 rxvt_fatal ("memory allocation failure. aborting.\n");
341
342 return p;
343 }
344
345 void *
346 rxvt_realloc (void *ptr, size_t size)
347 {
348 void *p = realloc (ptr, size);
349
350 if (!p)
351 rxvt_fatal ("memory allocation failure. aborting.\n");
352
353 return p;
354 }
355
356 KeySym
357 rxvt_XKeycodeToKeysym (Display *dpy, KeyCode code, int index)
358 {
359 int size;
360 KeySym *mapping = XGetKeyboardMapping (dpy, code, 1, &size);
361 KeySym keysym = IN_RANGE_EXC (index, 0, size) ? mapping[index] : NoSymbol;
362 XFree (mapping);
363 return keysym;
364 }