ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/misc.C
Revision: 1.60
Committed: Thu May 13 19:40:19 2021 UTC (3 years ago) by sf-exg
Content type: text/plain
Branch: MAIN
CVS Tags: rxvt-unicode-rel-9_29, rxvt-unicode-rel-9_26, rxvt-unicode-rel-9_25, rxvt-unicode-rel-9_30, HEAD
Changes since 1.59: +9 -17 lines
Log Message:
Require C++11

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