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