1 /*
2 This file is part of SLRN.
3
4 Copyright (c) 1994, 1999, 2007-2016 John E. Davis <jed@jedsoft.org>
5 Copyright (c) 2002-2006 Thomas Schultz <tststs@gmx.de>
6 Copyright (c) 2007 John E. Davis <jed@jedsoft.org>
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2 of the License, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23 #include "config.h"
24 #include "slrnfeat.h"
25 #include <stdio.h>
26 #include <string.h>
27 #include <errno.h>
28 #ifdef HAVE_STDLIB_H
29 # include <stdlib.h>
30 #endif
31
32 #ifdef HAVE_UNISTD_H
33 # include <unistd.h>
34 #endif
35 #include <slang.h>
36 #include "jdmacros.h"
37 #include "strutil.h"
38 #include "common.h"
39
40 /* This function allows NULL as a parameter. This fact _is_ exploited */
slrn_skip_whitespace(char * b)41 char *slrn_skip_whitespace (char *b) /*{{{*/
42 {
43 if (b == NULL) return NULL;
44
45 while (isspace (*b))
46 b++;
47
48 return b;
49 }
50
51 /*}}}*/
52
slrn_bskip_whitespace(char * smin)53 char *slrn_bskip_whitespace (char *smin)
54 {
55 char *s;
56
57 if (smin == NULL) return NULL;
58 s = smin + strlen (smin);
59
60 while (s > smin)
61 {
62 s--;
63 if (0 == isspace(*s))
64 return s + 1;
65 }
66 return s;
67 }
68
69 /* returns a pointer to the end of the string */
slrn_trim_string(char * s)70 char *slrn_trim_string (char *s) /*{{{*/
71 {
72 s = slrn_bskip_whitespace (s);
73 if (s != NULL)
74 *s = 0;
75
76 return s;
77 }
78 /*}}}*/
79
slrn_strbyte(char * s,char ch)80 char *slrn_strbyte (char *s, char ch) /*{{{*/
81 {
82 register char ch1;
83
84 while (((ch1 = *s) != 0) && (ch != ch1)) s++;
85 if (ch1 == 0) return NULL;
86 return s;
87 }
88
89 /*}}}*/
90
91 /* Search for characters from list in string str. If found, return a pointer
92 * to the first occurrence. If not found, return NULL. */
slrn_strbrk(char * str,char * list)93 char *slrn_strbrk (char *str, char *list) /*{{{*/
94 {
95 char ch, ch1, *p;
96
97 while ((ch = *str) != 0)
98 {
99 p = list;
100 while ((ch1 = *p) != 0)
101 {
102 if (ch == ch1) return str;
103 p++;
104 }
105 str++;
106 }
107 return NULL;
108 }
109
110 /*}}}*/
111
slrn_simple_strtok(char * s,char * chp)112 char *slrn_simple_strtok (char *s, char *chp) /*{{{*/
113 {
114 static char *s1;
115 char ch = *chp;
116
117 if (s == NULL)
118 {
119 if (s1 == NULL) return NULL;
120 s = s1;
121 }
122 else s1 = s;
123
124 while (*s1 && (*s1 != ch)) s1++;
125
126 if (*s1 == 0)
127 {
128 s1 = NULL;
129 }
130 else *s1++ = 0;
131 return s;
132 }
133
134 /*}}}*/
135
slrn_case_strncmp(char * a,char * b,unsigned int n)136 int slrn_case_strncmp (char *a, char *b, unsigned int n) /*{{{*/
137 {
138 char *bmax;
139
140 if (a == NULL)
141 {
142 if (b == NULL)
143 return 0;
144 else
145 return -1;
146 }
147 if (b == NULL)
148 return 1;
149
150 if (Slrn_UTF8_Mode)
151 return SLutf8_compare((SLuchar_Type *)a, (SLuchar_Type *)a+strlen(a),
152 (SLuchar_Type *)b, (SLuchar_Type *)b+strlen(b),
153 n, 0);
154 bmax = b + n;
155 while (b < bmax)
156 {
157 unsigned char cha = UPPER_CASE(*a);
158 unsigned char chb = UPPER_CASE(*b);
159 if (cha != chb)
160 {
161 return (int) cha - (int) chb;
162 }
163 else if (chb == 0) return 0;
164 b++;
165 a++;
166 }
167 return 0;
168 }
169
170 /*}}}*/
171
slrn_case_strcmp(char * a,char * b)172 int slrn_case_strcmp (char *a, char *b) /*{{{*/
173 {
174 register unsigned char cha, chb;
175 int len_a,len_b;
176
177 if (a == NULL)
178 {
179 if (b == NULL)
180 return 0;
181 else
182 return -1;
183 }
184
185 if (b == NULL)
186 return 1;
187
188 if (Slrn_UTF8_Mode)
189 {
190 len_a=strlen(a);
191 len_b=strlen(b);
192
193 return SLutf8_compare((SLuchar_Type *)a, (SLuchar_Type *)a+len_a,
194 (SLuchar_Type *)b, (SLuchar_Type *)b+len_b,
195 ((len_a > len_b) ? len_a : len_b), 0);
196 }
197
198 while (1)
199 {
200 cha = UPPER_CASE(*a);
201 chb = UPPER_CASE(*b);
202 if (cha != chb)
203 {
204 return (int) cha - (int) chb;
205 }
206 else if (chb == 0) break;
207 b++;
208 a++;
209 }
210 return 0;
211 }
212
213 /*}}}*/
214
slrn_strncpy(char * dest,const char * src,size_t n)215 char *slrn_strncpy (char *dest, const char *src, size_t n) /*{{{*/
216 {
217 strncpy (dest, src, n);
218 dest[n-1] = '\0';
219 return dest;
220 }
221 /*}}}*/
222
223 /*{{{ Memory Allocation Routines */
224
do_malloc_error(int do_error)225 static char *do_malloc_error (int do_error)
226 {
227 if (do_error) slrn_error (_("Memory allocation failure."));
228 return NULL;
229 }
230
slrn_safe_strmalloc(char * s)231 char *slrn_safe_strmalloc (char *s) /*{{{*/
232 {
233 s = SLmake_string (s);
234 if (s == NULL) slrn_exit_error (_("Out of memory."));
235 return s;
236 }
237
238 /*}}}*/
239
slrn_safe_strnmalloc(char * s,unsigned int len)240 char *slrn_safe_strnmalloc (char *s, unsigned int len)
241 {
242 s = SLmake_nstring (s, len);
243 if (s == NULL) slrn_exit_error (_("Out of memory."));
244 return s;
245 }
246
slrn_strnmalloc(char * s,unsigned int len,int do_error)247 char *slrn_strnmalloc (char *s, unsigned int len, int do_error)
248 {
249 s = SLmake_nstring (s, len);
250
251 if (s == NULL)
252 return do_malloc_error (do_error);
253
254 return s;
255 }
256
slrn_strmalloc(char * s,int do_error)257 char *slrn_strmalloc (char *s, int do_error)
258 {
259 if (s == NULL) return NULL;
260 return slrn_strnmalloc (s, strlen (s), do_error);
261 }
262
slrn_malloc(unsigned int len,int do_memset,int do_error)263 char *slrn_malloc (unsigned int len, int do_memset, int do_error)
264 {
265 char *s;
266
267 s = (char *) SLmalloc (len);
268 if (s == NULL)
269 return do_malloc_error (do_error);
270
271 if (do_memset)
272 memset (s, 0, len);
273
274 return s;
275 }
276
slrn_realloc(char * s,unsigned int len,int do_error)277 char *slrn_realloc (char *s, unsigned int len, int do_error)
278 {
279 if (s == NULL)
280 return slrn_malloc (len, 0, do_error);
281
282 s = SLrealloc (s, len);
283 if (s == NULL)
284 return do_malloc_error (do_error);
285
286 return s;
287 }
288
slrn_safe_malloc(unsigned int len)289 char *slrn_safe_malloc (unsigned int len)
290 {
291 char *s;
292
293 s = slrn_malloc (len, 1, 0);
294
295 if (s == NULL)
296 slrn_exit_error (_("Out of memory"));
297
298 return s;
299 }
300
slrn_free(char * s)301 void slrn_free (char *s)
302 {
303 if (s != NULL) SLfree (s);
304 }
305
306 /* return a:amax + s + b:bmax */
slrn_substrjoin(char * a,char * amax,char * b,char * bmax,char * s)307 char *slrn_substrjoin (char *a, char *amax, char *b, char *bmax, char *s)
308 {
309 unsigned int len_a, len_b, len_s, len;
310 char *c;
311
312 if (a == NULL) a = amax = "";
313 if (b == NULL) b = bmax = "";
314 if (s == NULL) s = "";
315
316 len_a = (amax == NULL) ? strlen (a) : (unsigned int)(amax - a);
317 len_b = (bmax == NULL) ? strlen (b) : (unsigned int)(bmax - b);
318
319 if ((len_a == 0) || (len_b == 0))
320 len_s = 0;
321 else
322 len_s = strlen (s);
323
324 len = len_a + len_s + len_b;
325 c = slrn_malloc (len+1, 0, 1);
326 if (c == NULL)
327 return NULL;
328
329 strncpy (c, a, len_a);
330 if (len_s != 0)
331 strcpy (c+len_a, s);
332 strncpy (c+len_a+len_s, b, len_b);
333
334 c[len] = 0;
335 return c;
336 }
337
338 /* return a + s + b */
slrn_strjoin(char * a,char * b,char * s)339 char *slrn_strjoin (char *a, char *b, char *s)
340 {
341 return slrn_substrjoin (a, NULL, b, NULL, s);
342 }
343
344