Link with C++ linker
[oweals/cde.git] / cde / programs / dtpdmd / util.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /******************************************************************************
24  ******************************************************************************
25  **
26  ** File:         util.c
27  ** RCS:          $XConsortium: util.c /main/3 1996/10/30 11:16:26 drk $
28  **
29  ** Description:  Utility code for the dtpdmd
30  **
31  ** (c) Copyright 1995, 1996, Hewlett-Packard Company, all rights reserved.
32  **
33  ******************************************************************************
34  *****************************************************************************/
35
36 #define UTIL_DOT_C
37
38 #include "dtpdmdP.h"
39 #include <setjmp.h>
40 #include <unistd.h>
41
42 jmp_buf  xio_quickie_jmp_buf;
43
44 /******************************************************************************
45  *
46  * Misc utility routines.
47  */
48
49 int xio_quickie_handler( Display *dpy )
50 {
51     longjmp( xio_quickie_jmp_buf, 1 );
52 }
53
54 /***************************************
55  *
56  * str_dup using Xmalloc
57  */
58 char *xpstrdup(char * str)
59 {
60     int len;
61     char *newstr;
62
63     len = strlen(str) + 1;
64     newstr = (char *) Xmalloc( len );
65     memcpy( newstr, str, len );
66     return( newstr );
67 }
68
69 /***************************************
70  *
71  * Multi-byte capable version of strspn(s1, s2).
72  *    Returns the span of characters in s1 contained in s2.
73  *    Only s1 can be multibyte.
74  */
75 int
76 xpstrspn(
77         char *s1,
78         char *s2 )
79 {
80 #ifdef NLS16
81    wchar_t s1char, s2char;
82    int s1len, s2len;
83    int i;
84    int count;
85    char * ptr;
86    Boolean match;
87
88
89    /* A Null string has no spans */
90    if (s1 == NULL)
91       return(0);
92
93    count = 0;
94    while (*s1)
95    {
96       /* Extract the next character from s1; may be multibyte */
97       if ((s1len = mbtowc(&s1char, s1, MB_CUR_MAX)) < 0)
98          return(0);
99       s1 += s1len;
100
101       /*
102        * Compare this character against all the chars in s2.  Keep
103        * working through s1, until a character is found in s1 which
104        * is not contained in s2.
105        */
106       ptr = s2;
107       match = False;
108       while (*ptr)
109       {
110          /* Extract the next character from s2; cannot be multibyte */
111          s2char = *ptr++;
112
113          /* If a match is found, keep processing s1 */
114          if (s1char == s2char)
115          {
116             match = True;
117             count += s1len;
118             break;
119          }
120       }
121
122       /*
123        * If we made it here because all of s2 was searched, and a match
124        * was not found against s1, then we are done.
125        */
126       if (!match)
127          return(count);
128    }
129
130    return(count);
131 #else
132    return(strspn(s1, s2));
133 #endif /* NLS16 */
134 }
135
136 /***************************************
137  *
138  * Multi-byte capable version of strcspn(s1, s2).
139  *    Returns the span of characters in s1 not contained in s2.
140  *    Only s1 can be multibyte.
141  */
142 int
143 xpstrcspn(
144         char *s1,
145         char *s2 )
146 {
147 #ifdef NLS16
148    wchar_t s1char, s2char;
149    int s1len, s2len;
150    int i;
151    int count;
152    char * ptr;
153
154
155    /* An empty string has no spans */
156    if (s1 == NULL)
157       return(0);
158
159    count = 0;
160    while (*s1)
161    {
162       /* Extract the next character from s1; may be multibyte */
163       if ((s1len = mbtowc(&s1char, s1, MB_CUR_MAX)) < 0)
164          return(0);
165       s1 += s1len;
166
167       /*
168        * Compare this character against all the chars in s2.  Keep
169        * working through s1, until a character is found in s1 which
170        * is contained in s2.
171        */
172       ptr = s2;
173       while (*ptr)
174       {
175          /* Extract the next character from s2; cannot be multibyte */
176          s2char = *ptr++;
177
178          /* If a match occurs, then we are done */
179          if (s1char == s2char)
180             return(count);
181       }
182
183       /*
184        * If we've made it here, then we searched all of s2, and none of
185        * its components matched s1; continue with the next character
186        * in s1.
187        */
188       count += s1len;
189    }
190
191    return(count);
192 #else
193    return(strcspn(s1, s2));
194 #endif /* NLS16 */
195 }
196
197 /***************************************
198  * 
199  * Multi-byte capable version of strtok(s1, s2).
200  *    Returns a pointer to the span of characters in s1 terminated by
201  *    one of the characters in s2.  Only s1 can be multibyte.
202  */
203 char *
204 xpstrtok(
205         char *s1,
206         char *s2 )
207 {
208 #ifdef NLS16
209    static char * ptr = NULL;
210    char * return_ptr;
211    int len;
212    int offset;
213
214
215    /*
216     * If this is the first call, save the string pointer, and bypass
217     * any leading separators.
218     */
219    if (s1)
220       ptr = s1 + xpstrspn(s1, s2);
221
222    /* A Null string pointer has no tokens */
223    if (ptr == NULL)
224       return(NULL);
225
226    /* Find out where the first terminator is */
227    if ((len = xpstrcspn(ptr, s2)) <= 0)
228    {
229       /* No tokens left */
230       return(NULL);
231    }
232
233    /* Keep track of where the token started */
234    return_ptr = ptr;
235
236    /* Null out the terminator; we need to know how many bytes are
237     * occupied by the terminator, so that we can skip over it to
238     * the next character.
239     */
240    offset = mblen(ptr + len, MB_CUR_MAX);
241    *(ptr + len) = '\0';
242    ptr += (len + offset);
243
244   /*
245    * In preparation for the next pass, skip any other occurrances of
246    * the terminator characters which were joined with the terminator
247    * we first encountered.
248    */
249    len = xpstrspn(ptr, s2);
250    ptr += len;
251
252    return(return_ptr);
253 #else
254    return(strtok(s1, s2));
255 #endif /* NLS16 */
256 }
257
258 void xp_add_argv( char ***argv, char *str )
259 {
260     int i;
261
262     if ( *argv ) {
263         for ( i = 0; (*argv)[i]; i++ );
264         *argv = (char **) Xrealloc( (char *) *argv, sizeof(char *) * (i + 2) );
265     }
266     else {
267         i = 0;
268         *argv = (char **) Xmalloc( sizeof(char *) * 2 );
269     }
270
271     (*argv)[i] = str;
272     (*argv)[i+1] = (char *) NULL;
273 }
274