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, 6 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

# User Rev Content
1 root 1.40 /*----------------------------------------------------------------------*
2 pcg 1.13 * File: misc.C
3 pcg 1.1 *----------------------------------------------------------------------*
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 root 1.56 * Copyright (c) 2003-2006 Marc Lehmann <schmorp@schmorp.de>
10 pcg 1.1 *
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 root 1.57 * the Free Software Foundation; either version 3 of the License, or
14 pcg 1.1 * (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 sf-exg 1.59 #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 pcg 1.3 char *
53 pcg 1.10 rxvt_wcstombs (const wchar_t *str, int len)
54     {
55 root 1.19 if (len < 0) len = wcslen (str);
56    
57 pcg 1.10 mbstate mbs;
58     char *r = (char *)rxvt_malloc (len * MB_CUR_MAX + 1);
59    
60     char *dst = r;
61     while (len--)
62     {
63 root 1.24 ssize_t l = wcrtomb (dst, *str++, mbs);
64 root 1.31
65 pcg 1.10 if (l < 0)
66 root 1.52 {
67     *dst++ = '?';
68     wcrtomb (0, 0, mbs); // reset undefined state
69     }
70 pcg 1.10 else
71     dst += l;
72     }
73    
74     *dst++ = 0;
75    
76 root 1.24 return (char *)rxvt_realloc (r, dst - r);
77 pcg 1.10 }
78    
79 root 1.19 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 root 1.24 if ((ssize_t)mbstowcs (r, str, len + 1) < 0)
87 root 1.19 *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 root 1.22 unicode_t w = *str++ & UNICODE_MASK;
103 root 1.19
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 ayin 1.48 *p++ = 0xe0 | ( w >> 12),
111 root 1.19 *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 root 1.24 *p++ = 0;
123 root 1.19
124 root 1.24 return (char *)rxvt_realloc (r, p - r);
125 root 1.19 }
126    
127     wchar_t *
128     rxvt_utf8towcs (const char *str, int len)
129     {
130     if (len < 0) len = strlen (str);
131    
132 root 1.21 wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)),
133     *p = r;
134 root 1.19
135 root 1.21 unsigned char *s = (unsigned char *)str,
136     *e = s + len;
137 root 1.19
138 root 1.21 for (;;)
139 root 1.19 {
140 root 1.21 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 ayin 1.49 && s[0] >= 0xc2 && s[0] <= 0xdf
148 root 1.19 && (s[1] & 0xc0) == 0x80)
149     {
150     *p++ = ((s[0] & 0x1f) << 6)
151     | (s[1] & 0x3f);
152 root 1.21 s += 2;
153 root 1.19 }
154 root 1.21 else if (len >= 3
155 root 1.19 && ( (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 root 1.21 s += 3;
166 root 1.19 }
167 root 1.21 else if (len >= 4
168 root 1.19 && ( (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 ayin 1.49 *p++ = ((s[0] & 0x07) << 18)
176     | ((s[1] & 0x3f) << 12)
177     | ((s[2] & 0x3f) << 6)
178 root 1.19 | (s[3] & 0x3f);
179 root 1.21 s += 4;
180 root 1.19 }
181     else
182     {
183     *p++ = 0xfffd;
184 root 1.21 s++;
185 root 1.19 }
186     }
187    
188     *p = 0;
189    
190     return r;
191     }
192    
193 root 1.53 const char *
194 ayin 1.46 rxvt_basename (const char *str) NOTHROW
195 pcg 1.1 {
196 root 1.54 const char *base = strrchr (str, '/');
197 pcg 1.1
198 root 1.54 return base ? base + 1 : str;
199 pcg 1.1 }
200    
201     /*
202     * Print an error message
203     */
204     void
205 root 1.36 rxvt_vlog (const char *fmt, va_list arg_ptr) NOTHROW
206 pcg 1.12 {
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 root 1.36 rxvt_log (const char *fmt,...) NOTHROW
219 pcg 1.1 {
220 pcg 1.8 va_list arg_ptr;
221 pcg 1.1
222 pcg 1.7 va_start (arg_ptr, fmt);
223 pcg 1.12 rxvt_vlog (fmt, arg_ptr);
224 pcg 1.7 va_end (arg_ptr);
225 pcg 1.1 }
226    
227     /*
228 pcg 1.12 * Print an error message
229     */
230     void
231 root 1.36 rxvt_warn (const char *fmt,...) NOTHROW
232 pcg 1.12 {
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 root 1.36 rxvt_fatal (const char *fmt,...) THROW ((class rxvt_failure_exception))
244 pcg 1.12 {
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 root 1.36 rxvt_exit_failure () THROW ((class rxvt_failure_exception))
258 pcg 1.12 {
259 root 1.36 static class rxvt_failure_exception rxvt_failure_exception;
260 pcg 1.12 throw (rxvt_failure_exception);
261     }
262    
263     /*
264 ayin 1.44 * remove leading/trailing space in place.
265 pcg 1.1 */
266 ayin 1.47 char *
267 ayin 1.46 rxvt_strtrim (char *str) NOTHROW
268 pcg 1.1 {
269 pcg 1.8 char *r, *s;
270 pcg 1.1
271 pcg 1.5 if (!str || !*str) /* shortcut */
272     return str;
273 pcg 1.1
274 pcg 1.5 /* skip leading spaces */
275 pcg 1.7 for (s = str; *s && isspace (*s); s++) ;
276 root 1.25
277 pcg 1.5 /* goto end of string */
278 root 1.25 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 pcg 1.1
287 pcg 1.5 return str;
288 pcg 1.1 }
289    
290     /*
291 sf-exg 1.55 * Split a string into an array based on the given delimiter, stripping leading and
292 root 1.25 * trailing spaces from each entry. Empty strings are properly returned
293 pcg 1.1 */
294 ayin 1.47 char **
295 sf-exg 1.55 rxvt_strsplit (char delim, const char *str) NOTHROW
296 pcg 1.1 {
297 sf-exg 1.55 int l, n;
298     char *s, *t;
299     char **ret;
300 pcg 1.5
301 sf-exg 1.55 s = strdup (str ? str : "");
302 pcg 1.5
303     for (n = 1, t = s; *t; t++)
304 sf-exg 1.55 if (*t == delim)
305 pcg 1.5 n++;
306 root 1.25
307 pcg 1.7 ret = (char **)malloc ((n + 1) * sizeof (char *));
308 pcg 1.5 ret[n] = NULL;
309    
310     for (l = 0, t = s; l < n; l++)
311     {
312 sf-exg 1.55 for (; *t && *t != delim; t++)
313     ;
314     *t = '\0';
315     ret[l] = s;
316 ayin 1.46 rxvt_strtrim (ret[l]);
317 pcg 1.5 s = ++t;
318 pcg 1.1 }
319 root 1.25
320 pcg 1.5 return ret;
321 pcg 1.1 }
322    
323 ayin 1.50 void *
324     rxvt_malloc (size_t size)
325     {
326     void *p = malloc (size);
327 pcg 1.1
328 ayin 1.50 if (!p)
329     rxvt_fatal ("memory allocation failure. aborting.\n");
330 root 1.28
331 ayin 1.50 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 sf-exg 1.58
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     }