chiark / gitweb /
Imported Upstream version 1.0.0
[e16] / src / memory.c
1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2005-2008 Kim Woelders
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies of the Software, its documentation and marketing & publicity
14  * materials, and acknowledgment shall be given in the documentation, materials
15  * and software packages that this Software was used.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include "E.h"
25 #include <ctype.h>
26
27 char               *
28 Estrtrim(char *s)
29 {
30    int                 l;
31
32    while (*s == ' ')
33       s++;
34    if (!*s)
35       return s;
36
37    l = strlen(s);
38    while (isspace(s[l - 1]))
39       l--;
40    s[l] = '\0';
41
42    return s;
43 }
44
45 char               *
46 Estrdup(const char *s)
47 {
48 #if USE_LIBC_STRDUP
49    if (s)
50       return strdup(s);
51    return NULL;
52 #else
53    int                 sz;
54
55    if (!s)
56       return NULL;
57    sz = strlen(s);
58    ss = EMALLOC(char, sz + 1);
59    strncpy(ss, s, sz + 1);
60    return ss;
61 #endif
62 }
63
64 char               *
65 Estrndup(const char *s, size_t n)
66 {
67 #if USE_LIBC_STRNDUP
68    if (s)
69       return strndup(s, n);
70    return NULL;
71 #else
72    char               *ss;
73
74    if (!s)
75       return NULL;
76    ss = EMALLOC(char, n + 1);
77    strncpy(ss, s, n);
78    ss[n] = '\0';
79    return ss;
80 #endif
81 }
82
83 char               *
84 Estrdupcat2(char *ss, const char *s1, const char *s2)
85 {
86    char               *s;
87    int                 len, l1, l2;
88
89    if (!ss)
90       return Estrdup(s2);
91
92    len = (ss) ? strlen(ss) : 0;
93    l1 = (s1) ? strlen(s1) : 0;
94    l2 = (s2) ? strlen(s2) : 0;
95
96    s = EREALLOC(char, ss, len + l1 + l2 + 1);
97    if (!s)
98       return NULL;
99    if (s1 && l1)
100       memcpy(s + len, s1, l1);
101    if (s2 && l2)
102       memcpy(s + len + l1, s2, l2);
103    s[len + l1 + l2] = '\0';
104
105    return s;
106 }
107
108 #if 0                           /* Unused */
109 char              **
110 StrlistDup(char **lst, int num)
111 {
112    char              **ss;
113    int                 i;
114
115    if (!lst || num <= 0)
116       return NULL;
117
118    ss = EMALLOC(char *, num + 1);
119    for (i = 0; i < num; i++)
120       ss[i] = Estrdup(lst[i]);
121    ss[i] = NULL;
122
123    return ss;
124 }
125 #endif
126
127 void
128 StrlistFree(char **lst, int num)
129 {
130    if (!lst)
131       return;
132    while (num--)
133       Efree(lst[num]);
134    Efree(lst);
135 }
136
137 #if 0                           /* FIXME - Remove? */
138 char               *
139 StrlistJoin(char **lst, int num)
140 {
141    int                 i, size;
142    char               *s;
143
144    if (!lst || num <= 0)
145       return NULL;
146
147    s = NULL;
148
149    size = strlen(lst[0]) + 1;
150    s = EMALLOC(char, size);
151    strcpy(s, lst[0]);
152    for (i = 1; i < num; i++)
153      {
154         size += strlen(lst[i]) + 1;
155         s = EREALLOC(char, s, size);
156
157         strcat(s, " ");
158         strcat(s, lst[i]);
159      }
160
161    return s;
162 }
163 #endif
164
165 char               *
166 StrlistEncodeEscaped(char *buf, int len, char **lst, int num)
167 {
168    int                 i, j, ch;
169    char               *s, *p;
170
171    if (!lst || num <= 0)
172       return NULL;
173
174    j = 0;
175    s = buf;
176    p = lst[0];
177    for (i = 0; i < len - 2; i++)
178      {
179         if (!p)                 /* A string list should not contain NULL items */
180            break;
181
182         ch = *p++;
183         switch (ch)
184           {
185           default:
186              *s++ = ch;
187              break;
188           case '\0':
189              if (++j >= num)
190                 goto done;
191              p = lst[j];
192              if (!p || !p[0])
193                 goto done;
194              *s++ = ' ';
195              break;
196           case ' ':
197              *s++ = '\\';
198              *s++ = ' ';
199              i++;
200              break;
201           }
202      }
203
204  done:
205    *s = '\0';
206    return buf;
207 }
208
209 char              **
210 StrlistDecodeEscaped(const char *str, int *pnum)
211 {
212    int                 num, len;
213    const char         *s, *p;
214    char              **lst;
215
216    if (!str)
217       return NULL;
218
219    lst = NULL;
220    num = 0;
221    s = str;
222    for (;;)
223      {
224         while (*s == ' ')
225            s++;
226         if (*s == '\0')
227            break;
228
229         lst = EREALLOC(char *, lst, num + 1);
230
231         lst[num] = NULL;
232         len = 0;
233
234         for (;;)
235           {
236              p = strchr(s, ' ');
237              if (!p)
238                 p = s + strlen(s);
239
240              lst[num] = EREALLOC(char, lst[num], len + p - s + 1);
241
242              memcpy(lst[num] + len, s, p - s);
243              len += p - s;
244              lst[num][len] = '\0';
245
246              s = p;
247              if (p[-1] == '\\')
248                {
249                   if (*p)
250                      lst[num][len - 1] = ' ';
251                   else
252                      break;
253                }
254              else
255                {
256                   break;
257                }
258              while (*s == ' ')
259                 s++;
260              if (*s == '\0')
261                 break;
262           }
263         num++;
264      }
265
266    /* Append NULL item */
267    lst = EREALLOC(char *, lst, num + 1);
268
269    lst[num] = NULL;
270
271    *pnum = num;
272    return lst;
273 }
274
275 char              **
276 StrlistFromString(const char *str, int delim, int *num)
277 {
278    const char         *s, *p;
279    char              **lst;
280    int                 n, len;
281
282    lst = NULL;
283    n = 0;
284    for (s = str; s; s = p)
285      {
286         p = strchr(s, delim);
287         if (p)
288           {
289              len = p - s;
290              p++;
291           }
292         else
293           {
294              len = strlen(s);
295           }
296         if (len <= 0)
297            continue;
298
299         lst = EREALLOC(char *, lst, n + 2);
300
301         lst[n++] = Estrndup(s, len);
302      }
303
304    if (lst)
305       lst[n] = NULL;
306    *num = n;
307    return lst;
308 }
309
310 void
311 Esetenv(const char *name, const char *value)
312 {
313    if (value)
314      {
315 #if HAVE_SETENV
316         setenv(name, value, 1);
317 #else
318         char                buf[FILEPATH_LEN_MAX];
319
320         Esnprintf(buf, FILEPATH_LEN_MAX, "%s=%s", name, value);
321         putenv(Estrdup(buf));
322 #endif
323      }
324    else
325      {
326 #if HAVE_UNSETENV
327         unsetenv(name);
328 #else
329         if (getenv(name))
330            putenv((char *)name);
331 #endif
332      }
333 }