A tiling window manager
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004 Shawn Betts <sabetts@vcn.bc.ca>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place, Suite 330, Boston, MA 02111-1307 USA.
17 */
18
19#include "sdorfehs.h"
20
21#include <ctype.h>
22#include <err.h>
23
24__dead void
25fatal(const char *msg)
26{
27 fprintf(stderr, PROGNAME ": %s", msg);
28 abort();
29}
30
31void *
32xmalloc(size_t size)
33{
34 void *value;
35
36 value = malloc(size);
37 if (value == NULL)
38 fatal("Virtual memory exhausted");
39 return value;
40}
41
42void *
43xrealloc(void *ptr, size_t size)
44{
45 void *value;
46
47 value = realloc(ptr, size);
48 if (value == NULL)
49 fatal("Virtual memory exhausted");
50 return value;
51}
52
53char *
54xstrdup(const char *s)
55{
56 char *value;
57 value = strdup(s);
58 if (value == NULL)
59 fatal("Virtual memory exhausted");
60 return value;
61}
62
63/* Return a new string based on fmt. */
64char *
65xvsprintf(char *fmt, va_list ap)
66{
67 int size, nchars;
68 char *buffer;
69 va_list ap_copy;
70
71 /* A reasonable starting value. */
72 size = strlen(fmt) + 1;
73 buffer = xmalloc(size);
74
75 while (1) {
76#if defined(va_copy)
77 va_copy(ap_copy, ap);
78#elif defined(__va_copy)
79 __va_copy(ap_copy, ap);
80#else
81 /*
82 * If there is no copy macro then this MAY work. On some
83 * systems this could fail because va_list is a pointer so
84 * assigning one to the other as below wouldn't make a copy of
85 * the data, but just the pointer to the data.
86 */
87 ap_copy = ap;
88#endif
89 nchars = vsnprintf(buffer, size, fmt, ap_copy);
90#if defined(va_copy) || defined(__va_copy)
91 va_end(ap_copy);
92#endif
93
94 if (nchars > -1 && nchars < size)
95 return buffer;
96 else if (nchars > -1)
97 size = nchars + 1;
98 else {
99 free(buffer);
100 break;
101 }
102
103 /* Resize the buffer and try again. */
104 buffer = xrealloc(buffer, size);
105 }
106
107 return xstrdup("<FAILURE>");
108}
109
110/* Return a new string based on fmt. */
111char *
112xsprintf(char *fmt,...)
113{
114 char *buffer;
115 va_list ap;
116
117 va_start(ap, fmt);
118 buffer = xvsprintf(fmt, ap);
119 va_end(ap);
120
121 return buffer;
122}
123
124/* strtok but do it for whitespace and be locale compliant. */
125char *
126strtok_ws(char *s)
127{
128 char *nonws;
129 static char *last = NULL;
130
131 if (s != NULL)
132 last = s;
133 else if (last == NULL) {
134 warnx("strtok_ws() called but not initalized, this is a *BUG*");
135 abort();
136 }
137 /* skip to first non-whitespace char. */
138 while (*last && isspace((unsigned char) *last))
139 last++;
140
141 /*
142 * If we reached the end of the string here then there is no more data.
143 */
144 if (*last == '\0')
145 return NULL;
146
147 /* Now skip to the end of the data. */
148 nonws = last;
149 while (*last && !isspace((unsigned char) *last))
150 last++;
151 if (*last) {
152 *last = '\0';
153 last++;
154 }
155 return nonws;
156}