A tiling window manager
at master 156 lines 3.2 kB view raw
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}