Add description field to macros.
[cboard.git] / src / misc.c
blobeadabc5b62a69299d5cf227bbb71c4b91e3f42d4
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2002-2018 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <pwd.h>
30 #include <unistd.h>
31 #include <sys/types.h>
32 #include <err.h>
34 #ifdef HAVE_LIMITS_H
35 #include <limits.h>
36 #endif
38 #include "common.h"
39 #include "misc.h"
41 void *
42 Malloc (size_t size)
44 void *ptr;
46 if ((ptr = malloc (size)) == NULL)
47 err (EXIT_FAILURE, "malloc()");
49 return ptr;
52 void *
53 Realloc (void *ptr, size_t size)
55 void *ptr2;
57 if ((ptr2 = realloc (ptr, size)) == NULL)
58 err (EXIT_FAILURE, "realloc()");
60 return ptr2;
63 void *
64 Calloc (size_t n, size_t size)
66 void *p;
68 if ((p = calloc (n, size)) == NULL)
69 err (EXIT_FAILURE, "calloc()");
71 return p;
74 char *
75 rtrim (char *str)
77 int i;
79 if (!*str)
80 return str;
82 for (i = strlen (str) - 1; isspace (str[i]); i--)
83 str[i] = 0;
85 return str;
88 char *
89 trim (char *str)
91 if (!str)
92 return NULL;
94 while (isspace (*str))
95 str++;
97 return rtrim (str);
100 char *
101 itoa (long n, char *buf)
103 sprintf (buf, "%li", n);
104 return buf;
107 char *
108 trim_multi (char *value)
110 char *p;
111 int lastc;
112 char *str, *s;
114 if (!value || !*value)
115 return value;
117 str = Malloc (strlen (value) + 1);
119 for (p = value, lastc = 0, s = str; *p; p++)
121 if (isspace (lastc) && isspace (*p))
122 continue;
124 lastc = *s++ = *p;
127 *s = 0;
128 return str;
132 integer_len (long n)
134 char buf[32];
136 itoa (n, buf);
137 return strlen (buf);
141 isinteger (const char *str)
143 int i = 0;
144 int len = strlen (str);
146 if (*str == '-' && isdigit (*(str + 1)))
147 i = 1;
149 for (; i < len; i++)
151 if (!isdigit (str[i]))
152 return 0;
155 return 1;
158 char *
159 pathfix (const char *str)
161 static char buf[FILENAME_MAX] = { 0 };
162 struct passwd *pw;
164 if (*str == '~')
166 pw = getpwuid (getuid ());
167 strncpy (buf, pw->pw_dir, sizeof (buf) - 1);
168 strncat (buf, str + 1, sizeof (buf) - 1);
170 else
171 strncpy (buf, str, sizeof (buf) - 1);
173 return buf;
176 wchar_t *
177 str_etc (const char *str, int maxlen, int rev)
179 wchar_t *p;
180 wchar_t *buf = NULL;
182 if (!str)
183 return NULL;
185 p = str_to_wchar (str);
187 if (wcslen (p) > maxlen)
189 wchar_t *dot = str_to_wchar (_("..."));
191 if (rev)
193 buf = str_to_wchar_len (_("..."), maxlen);
194 buf[wcslen (dot)] = 0;
195 wcsncat (buf, p, maxlen - wcslen (dot));
197 else
199 buf = str_to_wchar_len (str, maxlen);
200 buf[wcslen (buf) - wcslen (dot)] = 0;
201 wcscat (buf, dot);
204 free (dot);
205 free (p);
207 else
208 buf = p;
210 return buf;
213 char **
214 split_str (char *str, const char *delim, int *n, int *width, int force_trim)
216 char *tmp;
217 int total = 0;
218 char **lines = NULL;
219 int w = 0;
221 if (!str || !delim)
222 return NULL;
224 while ((tmp = strsep (&str, delim)) != NULL)
226 char *p;
227 wchar_t *wc;
228 int len;
230 tmp = rtrim (tmp);
232 if (!*tmp)
233 continue;
235 lines = Realloc (lines, (total + 2) * sizeof (char *));
236 p = force_trim ? strdup (trim (tmp)) : strdup (tmp);
237 wc = str_to_wchar (p);
238 len = wcslen (wc);
239 if (w < len)
240 w = len;
242 free (wc);
243 lines[total++] = p;
246 if (total)
248 lines[total] = NULL;
249 *n += total;
251 if (*width < w + 2)
252 *width = w + 2;
255 return lines;
258 // 'max' will always allocate that amount when not 0.
259 wchar_t *
260 str_to_wchar_len (const char *str, int max)
262 wchar_t *wc;
263 mbstate_t ps;
264 const char *p = str;
265 size_t len = max;
267 memset (&ps, 0, sizeof (mbstate_t));
268 if (!len)
269 len = mbsrtowcs (NULL, &p, 0, &ps);
271 wc = Calloc (len + 1, sizeof (wchar_t));
272 p = str;
273 memset (&ps, 0, sizeof (mbstate_t));
274 len = mbsrtowcs (wc, &p, len, &ps);
275 return wc;
278 wchar_t *
279 str_to_wchar (const char *str)
281 return str_to_wchar_len (str, 0);
284 char *
285 wchar_to_str (const wchar_t * str)
287 size_t len = wcstombs (NULL, str, 0);
288 char *s = Malloc (len * sizeof (char) + 1);
289 len = wcstombs (s, str, len);
290 s[len] = 0;
291 return s;
294 size_t
295 wcharv_length (wchar_t **s)
297 size_t n = 0;
299 for (n = 0; s && s[n]; n++);
300 return n;
303 /* Replace the first occurence of 's' with 'r' in 'h'. */
304 char *
305 string_replace (const char *hay, const char *n, const char *r)
307 char *buf, *b;
308 const char *hp = hay;
310 if (!strstr (hay, n))
311 return strdup (hay);
313 buf = malloc (strlen (hay) + strlen (r) + 1);
314 b = buf;
315 for (hp = hay; hp && *hp; hp++)
317 if (!strncmp (hp, n, strlen (n)))
319 const char *rp;
321 for (rp = r; *rp; rp++)
322 *b++ = *rp;
324 hp += strlen (n);
325 while (*hp)
326 *b++ = *hp++;
327 break;
330 *b++ = *hp;
333 *b = 0;
334 return buf;