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