1 /*- 2 * Copyright (c) 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1991, 1993, 1994, 1995, 1996 5 * Keith Bostic. All rights reserved. 6 * 7 * See the LICENSE file for redistribution information. 8 */ 9 10 #include "config.h" 11 12 #ifndef lint 13 static const char sccsid[] = "@(#)util.c 10.11 (Berkeley) 9/15/96"; 14 #endif /* not lint */ 15 16 #include <sys/types.h> 17 #include <sys/queue.h> 18 19 #include <bitstring.h> 20 #include <errno.h> 21 #include <limits.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <unistd.h> 26 27 #include "common.h" 28 29 /* 30 * binc -- 31 * Increase the size of a buffer. 32 * 33 * PUBLIC: void *binc __P((SCR *, void *, size_t *, size_t)); 34 */ 35 void * 36 binc(sp, bp, bsizep, min) 37 SCR *sp; /* sp MAY BE NULL!!! */ 38 void *bp; 39 size_t *bsizep, min; 40 { 41 size_t csize; 42 43 /* If already larger than the minimum, just return. */ 44 if (min && *bsizep >= min) 45 return (bp); 46 47 csize = *bsizep + MAX(min, 256); 48 REALLOC(sp, bp, void *, csize); 49 50 if (bp == NULL) { 51 /* 52 * Theoretically, realloc is supposed to leave any already 53 * held memory alone if it can't get more. Don't trust it. 54 */ 55 *bsizep = 0; 56 return (NULL); 57 } 58 /* 59 * Memory is guaranteed to be zero-filled, various parts of 60 * nvi depend on this. 61 */ 62 memset((char *)bp + *bsizep, 0, csize - *bsizep); 63 *bsizep = csize; 64 return (bp); 65 } 66 67 /* 68 * nonblank -- 69 * Set the column number of the first non-blank character 70 * including or after the starting column. On error, set 71 * the column to 0, it's safest. 72 * 73 * PUBLIC: int nonblank __P((SCR *, recno_t, size_t *)); 74 */ 75 int 76 nonblank(sp, lno, cnop) 77 SCR *sp; 78 recno_t lno; 79 size_t *cnop; 80 { 81 char *p; 82 size_t cnt, len, off; 83 int isempty; 84 85 /* Default. */ 86 off = *cnop; 87 *cnop = 0; 88 89 /* Get the line, succeeding in an empty file. */ 90 if (db_eget(sp, lno, &p, &len, &isempty)) 91 return (!isempty); 92 93 /* Set the offset. */ 94 if (len == 0 || off >= len) 95 return (0); 96 97 for (cnt = off, p = &p[off], 98 len -= off; len && isblank(*p); ++cnt, ++p, --len); 99 100 /* Set the return. */ 101 *cnop = len ? cnt : cnt - 1; 102 return (0); 103 } 104 105 /* 106 * tail -- 107 * Return tail of a path. 108 * 109 * PUBLIC: char *tail __P((char *)); 110 */ 111 char * 112 tail(path) 113 char *path; 114 { 115 char *p; 116 117 if ((p = strrchr(path, '/')) == NULL) 118 return (path); 119 return (p + 1); 120 } 121 122 /* 123 * v_strdup -- 124 * Strdup for wide character strings with an associated length. 125 * 126 * PUBLIC: CHAR_T *v_strdup __P((SCR *, const CHAR_T *, size_t)); 127 */ 128 CHAR_T * 129 v_strdup(sp, str, len) 130 SCR *sp; 131 const CHAR_T *str; 132 size_t len; 133 { 134 CHAR_T *copy; 135 136 MALLOC(sp, copy, CHAR_T *, len + 1); 137 if (copy == NULL) 138 return (NULL); 139 memcpy(copy, str, len * sizeof(CHAR_T)); 140 copy[len] = '\0'; 141 return (copy); 142 } 143 144 /* 145 * nget_uslong -- 146 * Get an unsigned long, checking for overflow. 147 * 148 * PUBLIC: enum nresult nget_uslong __P((u_long *, const char *, char **, int)); 149 */ 150 enum nresult 151 nget_uslong(valp, p, endp, base) 152 u_long *valp; 153 const char *p; 154 char **endp; 155 int base; 156 { 157 errno = 0; 158 *valp = strtoul(p, endp, base); 159 if (errno == 0) 160 return (NUM_OK); 161 if (errno == ERANGE && *valp == ULONG_MAX) 162 return (NUM_OVER); 163 return (NUM_ERR); 164 } 165 166 /* 167 * nget_slong -- 168 * Convert a signed long, checking for overflow and underflow. 169 * 170 * PUBLIC: enum nresult nget_slong __P((long *, const char *, char **, int)); 171 */ 172 enum nresult 173 nget_slong(valp, p, endp, base) 174 long *valp; 175 const char *p; 176 char **endp; 177 int base; 178 { 179 errno = 0; 180 *valp = strtol(p, endp, base); 181 if (errno == 0) 182 return (NUM_OK); 183 if (errno == ERANGE) { 184 if (*valp == LONG_MAX) 185 return (NUM_OVER); 186 if (*valp == LONG_MIN) 187 return (NUM_UNDER); 188 } 189 return (NUM_ERR); 190 } 191 192 #ifdef DEBUG 193 #ifdef __STDC__ 194 #include <stdarg.h> 195 #else 196 #include <varargs.h> 197 #endif 198 199 /* 200 * TRACE -- 201 * debugging trace routine. 202 * 203 * PUBLIC: void TRACE __P((SCR *, const char *, ...)); 204 */ 205 void 206 #ifdef __STDC__ 207 TRACE(SCR *sp, const char *fmt, ...) 208 #else 209 TRACE(sp, fmt, va_alist) 210 SCR *sp; 211 char *fmt; 212 va_dcl 213 #endif 214 { 215 FILE *tfp; 216 va_list ap; 217 218 if ((tfp = sp->gp->tracefp) == NULL) 219 return; 220 #ifdef __STDC__ 221 va_start(ap, fmt); 222 #else 223 va_start(ap); 224 #endif 225 (void)vfprintf(tfp, fmt, ap); 226 va_end(ap); 227 228 (void)fflush(tfp); 229 } 230 #endif 231