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