1 /* 2 * routines.h -- general use routines 3 * Copyright (c) 1995-1999 Akim Demaille, Miguel Santana 4 */ 5 6 /* 7 * This file is part of a2ps. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2, or (at your option) 12 * any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; see the file COPYING. If not, write to 21 * the Free Software Foundation, 59 Temple Place - Suite 330, 22 * Boston, MA 02111-1307, USA. 23 */ 24 25 #ifndef _ROUTINES_H_ 26 # define _ROUTINES_H_ 27 28 /* 29 * From xgetcwd.c 30 */ 31 char *xgetcwd PARAMS ((void)); 32 33 /* 34 * from xgethostname.c 35 */ 36 char *xgethostname PARAMS ((void)); 37 38 char *stpcpy PARAMS ((char * dest, const char * src)); 39 char *stpncpy PARAMS ((char * dest, const char * src, size_t n)); 40 41 /* 42 * unsigned char variation of usual functions on strings 43 */ 44 #define ustrcat(x,y) \ 45 (strcat((char *)(x), (const char *)(y))) 46 47 #define ustrncat(x,y,n) \ 48 (strncat(((char *)x), (const char *) y, n)) 49 50 #define ustrcpy(x,y) \ 51 (strcpy((char *)(x), (const char *)(y))) 52 #define ustrncpy(x,y,z) \ 53 (strncpy((char *)(x), (const char *)(y), (z))) 54 55 #define ustpcpy(x,y) \ 56 (stpcpy((char *)(x), (const char *)(y))) 57 #define ustpncpy(x,y,z) \ 58 (stpncpy((char *)(x), (const char *)(y), (z))) 59 60 #define ustrcmp(x,y) \ 61 (strcmp((const char *)(x), (const char *)(y))) 62 #define ustrncmp(x,y,z) \ 63 (strncmp((const char *)(x), (const char *)(y), (z))) 64 65 #define ustrlen(x) \ 66 (strlen((const char *)(x))) 67 68 #define ustrchr(x,y) \ 69 ((uchar *) strchr((char *)(x), (int)(y))) 70 #define ustrrchr(x,y) \ 71 ((uchar *) strrchr((char *)(x), (int)(y))) 72 73 #define xustrdup(x) \ 74 ((uchar *) xstrdup((const char *)(x))) 75 76 #define ustrtok(x,y) \ 77 ((uchar *) strtok ((char *)(x), (const char *)(y))) 78 79 /* 80 * Put in X a copy of chars in Y from Z to T 81 */ 82 #define ustrsub(x,y,z,t) \ 83 ((uchar *) strsub ((char *)(x), (const char *)(y), (z), (t))); 84 85 /* 86 * A string prefixes another 87 */ 88 #define strprefix(s1, s2) \ 89 (!strncmp(s1, s2, strlen(s1))) 90 #define ustrprefix(s1, s2) \ 91 (!ustrncmp(s1, s2, ustrlen(s1))) 92 93 /* 94 * A string is the end of another 95 * 96 * Note that there are too many strlens. But I know 97 * no other way... 98 */ 99 #define strsuffix(s1, s2) \ 100 ((strlen (s1) < strlen (s2)) \ 101 ? 0 \ 102 : !strcmp (s1 + strlen (s1) - strlen (s2), s2)) 103 104 #define ustrsuffix(s1, s2) \ 105 ((ustrlen (s1) < ustrlen (s2)) \ 106 ? 0 \ 107 : !ustrcmp (s1 + ustrlen (s1) - ustrlen (s2), s2)) 108 109 /* 110 * Replace a malloc'd string with another 111 */ 112 #define xstrcpy(s1, s2) \ 113 do { \ 114 const char *my_s2 = (s2); \ 115 XFREE (s1); \ 116 s1 = !IS_EMPTY (my_s2) ? xstrdup (my_s2) : NULL; \ 117 } while (0) 118 119 /* We cannot just define this one like 120 xstrcpy ((char *) s1, (const char *) s2); 121 because it will expand into a line like 122 (char *) s1 = ... 123 and AIX 3.2's cc choke on this!!! It says 124 (S) Operand must be a modifiable lvalue. */ 125 126 #define xustrcpy(s1, s2) \ 127 do { \ 128 const uchar *my_s2 = (uchar *) (s2); \ 129 XFREE (s1); \ 130 s1 = !IS_EMPTY (my_s2) ? xustrdup (my_s2) : UNULL; \ 131 } while (0) 132 133 /* 134 * Cut the _STRING_ a the first occurence of the _CHAR_ if there is 135 */ 136 #define strcut(_string_, _char_) \ 137 do { \ 138 char * __strcut_cp; \ 139 __strcut_cp = strchr (_string_, _char_); \ 140 if (__strcut_cp) \ 141 *__strcut_cp = '\0'; \ 142 } while (0) 143 144 #define ustrcut(_ustring_, _uchar_) \ 145 strcut ((char *) (_ustring_), (char) _uchar_) 146 147 /* 148 * Cut the _STRING_ a the last occurence of the _CHAR_ if there is 149 */ 150 #define strrcut(_string_, _char_) \ 151 do { \ 152 char * __strrcut_cp; \ 153 __strrcut_cp = strrchr (_string_, _char_); \ 154 if (__strrcut_cp) \ 155 *__strrcut_cp = '\0'; \ 156 } while (0) 157 158 #define ustrrcut(_ustring_, _uchar_) \ 159 strrcut ((char *) (_ustring_), (char) _uchar_) 160 161 /* 162 * alloca version of some str routines 163 */ 164 /* 165 Here is a very interesting part of the GNU libc doc, 166 which explains a problem I had... 167 168 Do not use `alloca' inside the arguments of a function call--you 169 will get unpredictable results, because the stack space for the 170 `alloca' would appear on the stack in the middle of the space for the 171 function arguments. An example of what to avoid is `foo (x, alloca 172 (4), y)'. 173 */ 174 #define astrcpy(_d_,_s_) \ 175 do { \ 176 const char * _tmp_ = (const char *) (_s_); \ 177 _d_ = ALLOCA (char, strlen (_tmp_) + 1); \ 178 strcpy (_d_, _tmp_); \ 179 } while (0) 180 181 #define austrcpy(_d_,_s_) \ 182 do { \ 183 const uchar * _tmp_ = (const uchar *) (_s_); \ 184 _d_ = ALLOCA (uchar, ustrlen (_tmp_) + 1); \ 185 ustrcpy (_d_, _tmp_); \ 186 } while (0) 187 188 #define strcat2(_d_,_s1_,_s2_) \ 189 do { \ 190 stpcpy (stpcpy (_d_, _s1_), _s2_); \ 191 } while (0) 192 193 #define astrcat2(_d_,_s1_,_s2_) \ 194 do { \ 195 const char * _tmp1_ = (const char *) (_s1_); \ 196 const char * _tmp2_ = (const char *) (_s2_); \ 197 _d_ = ALLOCA (char, (strlen (_tmp1_) \ 198 + strlen (_tmp2_) + 1));\ 199 strcat2(_d_,_s1_,_s2_); \ 200 } while (0) 201 202 /* 203 * Concatenation of a char. No malloc is done. 204 */ 205 #define USTRCCAT(s, c) \ 206 do { int __len = strlen((const char *)s); \ 207 *(s+__len) = c; \ 208 *(s+__len+1) = '\0'; \ 209 } while (false) 210 211 212 #define IS_BETWEEN(x, min, max) (((min) <= (x)) && ((x) <= (max))) 213 214 #define IS_EMPTY(s1) \ 215 (((const char *) (s1) == NULL) || (*(s1) == '\0')) 216 #define UNNULL(s1) \ 217 ((((void const *) s1) == NULL) ? (const char *) "" : (const char *) (s1)) 218 #define ustrequ(s1, s2) (!ustrcmp(s1, s2)) 219 #define strcaseequ(s1, s2) (!strcasecmp(s1, s2)) 220 221 /* Functions on strings */ 222 void string_to_array PARAMS ((uchar arr[256], const uchar * string)); 223 int is_strlower PARAMS((const uchar * string)); 224 uchar *strnlower PARAMS ((uchar * string, size_t len)); 225 uchar *strlower PARAMS ((uchar * string)); 226 uchar *strcpylc PARAMS ((uchar *dst, const uchar *src)); 227 228 void ustrccat PARAMS((uchar * string, uchar c)); 229 int strcnt PARAMS((uchar * s, uchar c)); 230 char * strsub PARAMS ((char * dest, 231 const char * string, int start, int length)); 232 233 /* Copy the content of IN into OUT */ 234 void streams_copy PARAMS ((FILE * in, FILE * out)); 235 236 /* Dump the content of a file onto STREAM */ 237 void stream_dump PARAMS ((FILE * stream, const char * filename)); 238 /* unlink FILENAME */ 239 void unlink2 PARAMS ((void* dummy, const char * filename)); 240 241 /* Fopen but exits on failure */ 242 FILE * xfopen PARAMS ((const char * filename, const char * rights, 243 const char * format)); 244 /* opened "r", and "w" */ 245 FILE * xrfopen PARAMS ((const char * filename)); 246 FILE * xwfopen PARAMS ((const char * filename)); 247 248 /* Popen but exits on failure */ 249 FILE * xpopen PARAMS ((const char * command, const char * rights, 250 const char * format)); 251 /* opened "r", and "w" */ 252 FILE * xrpopen PARAMS ((const char * command)); 253 FILE * xwpopen PARAMS ((const char * command)); 254 255 /* If _STR_ is not defined, give it a tempname in _TMPDIR_ */ 256 #define tempname_ensure(Str) \ 257 do { \ 258 (Str) = (Str) ? (Str) : tempnam (NULL, "a2_"); \ 259 } while (0) 260 261 #endif 262