1*b9fc9a72Sderaadt /* $OpenBSD: util.c,v 1.10 2015/01/16 06:40:14 deraadt Exp $ */ 2d4e7c603Sniklas 3df930be7Sderaadt /*- 4df930be7Sderaadt * Copyright (c) 1991, 1993, 1994 5df930be7Sderaadt * The Regents of the University of California. All rights reserved. 645f2ab88Sderaadt * Copyright (c) 1991, 1993, 1994, 1995, 1996 745f2ab88Sderaadt * Keith Bostic. All rights reserved. 8df930be7Sderaadt * 945f2ab88Sderaadt * See the LICENSE file for redistribution information. 10df930be7Sderaadt */ 11df930be7Sderaadt 1245f2ab88Sderaadt #include "config.h" 1345f2ab88Sderaadt 14df930be7Sderaadt #include <sys/queue.h> 15df930be7Sderaadt 16df930be7Sderaadt #include <bitstring.h> 1745f2ab88Sderaadt #include <errno.h> 18df930be7Sderaadt #include <limits.h> 19df930be7Sderaadt #include <stdio.h> 20df930be7Sderaadt #include <stdlib.h> 21df930be7Sderaadt #include <string.h> 22df930be7Sderaadt #include <unistd.h> 23df930be7Sderaadt 2445f2ab88Sderaadt #include "common.h" 25df930be7Sderaadt 26*b9fc9a72Sderaadt #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) 27*b9fc9a72Sderaadt 28df930be7Sderaadt /* 29df930be7Sderaadt * binc -- 30df930be7Sderaadt * Increase the size of a buffer. 3145f2ab88Sderaadt * 32c72b5b24Smillert * PUBLIC: void *binc(SCR *, void *, size_t *, size_t); 33df930be7Sderaadt */ 34df930be7Sderaadt void * 35486aa1f0Sbentley binc(SCR *sp, void *bp, size_t *bsizep, size_t min) 36df930be7Sderaadt { 37df930be7Sderaadt size_t csize; 38df930be7Sderaadt 39df930be7Sderaadt /* If already larger than the minimum, just return. */ 40df930be7Sderaadt if (min && *bsizep >= min) 41df930be7Sderaadt return (bp); 42df930be7Sderaadt 43*b9fc9a72Sderaadt csize = *bsizep + MAXIMUM(min, 256); 44df930be7Sderaadt REALLOC(sp, bp, void *, csize); 45df930be7Sderaadt 46df930be7Sderaadt if (bp == NULL) { 47df930be7Sderaadt /* 48df930be7Sderaadt * Theoretically, realloc is supposed to leave any already 49df930be7Sderaadt * held memory alone if it can't get more. Don't trust it. 50df930be7Sderaadt */ 51df930be7Sderaadt *bsizep = 0; 52df930be7Sderaadt return (NULL); 53df930be7Sderaadt } 54df930be7Sderaadt /* 55df930be7Sderaadt * Memory is guaranteed to be zero-filled, various parts of 56df930be7Sderaadt * nvi depend on this. 57df930be7Sderaadt */ 58df930be7Sderaadt memset((char *)bp + *bsizep, 0, csize - *bsizep); 59df930be7Sderaadt *bsizep = csize; 60df930be7Sderaadt return (bp); 61df930be7Sderaadt } 62df930be7Sderaadt 63df930be7Sderaadt /* 64df930be7Sderaadt * nonblank -- 65df930be7Sderaadt * Set the column number of the first non-blank character 66df930be7Sderaadt * including or after the starting column. On error, set 67df930be7Sderaadt * the column to 0, it's safest. 6845f2ab88Sderaadt * 69c72b5b24Smillert * PUBLIC: int nonblank(SCR *, recno_t, size_t *); 70df930be7Sderaadt */ 71df930be7Sderaadt int 72486aa1f0Sbentley nonblank(SCR *sp, recno_t lno, size_t *cnop) 73df930be7Sderaadt { 74df930be7Sderaadt char *p; 75df930be7Sderaadt size_t cnt, len, off; 7645f2ab88Sderaadt int isempty; 77df930be7Sderaadt 78df930be7Sderaadt /* Default. */ 79df930be7Sderaadt off = *cnop; 80df930be7Sderaadt *cnop = 0; 81df930be7Sderaadt 8245f2ab88Sderaadt /* Get the line, succeeding in an empty file. */ 8345f2ab88Sderaadt if (db_eget(sp, lno, &p, &len, &isempty)) 8445f2ab88Sderaadt return (!isempty); 85df930be7Sderaadt 86df930be7Sderaadt /* Set the offset. */ 87df930be7Sderaadt if (len == 0 || off >= len) 88df930be7Sderaadt return (0); 89df930be7Sderaadt 90df930be7Sderaadt for (cnt = off, p = &p[off], 91df930be7Sderaadt len -= off; len && isblank(*p); ++cnt, ++p, --len); 92df930be7Sderaadt 93df930be7Sderaadt /* Set the return. */ 94df930be7Sderaadt *cnop = len ? cnt : cnt - 1; 95df930be7Sderaadt return (0); 96df930be7Sderaadt } 97df930be7Sderaadt 98df930be7Sderaadt /* 99df930be7Sderaadt * tail -- 100df930be7Sderaadt * Return tail of a path. 10145f2ab88Sderaadt * 102c72b5b24Smillert * PUBLIC: char *tail(char *); 103df930be7Sderaadt */ 104df930be7Sderaadt char * 105486aa1f0Sbentley tail(char *path) 106df930be7Sderaadt { 107df930be7Sderaadt char *p; 108df930be7Sderaadt 109df930be7Sderaadt if ((p = strrchr(path, '/')) == NULL) 110df930be7Sderaadt return (path); 111df930be7Sderaadt return (p + 1); 112df930be7Sderaadt } 113df930be7Sderaadt 114df930be7Sderaadt /* 115df930be7Sderaadt * v_strdup -- 116df930be7Sderaadt * Strdup for wide character strings with an associated length. 11745f2ab88Sderaadt * 118c72b5b24Smillert * PUBLIC: CHAR_T *v_strdup(SCR *, const CHAR_T *, size_t); 119df930be7Sderaadt */ 120df930be7Sderaadt CHAR_T * 121486aa1f0Sbentley v_strdup(SCR *sp, const CHAR_T *str, size_t len) 122df930be7Sderaadt { 123df930be7Sderaadt CHAR_T *copy; 124df930be7Sderaadt 125df930be7Sderaadt MALLOC(sp, copy, CHAR_T *, len + 1); 126df930be7Sderaadt if (copy == NULL) 127df930be7Sderaadt return (NULL); 1284fcb78e9Smichaels memcpy(copy, str, len * sizeof(CHAR_T)); 129df930be7Sderaadt copy[len] = '\0'; 130df930be7Sderaadt return (copy); 131df930be7Sderaadt } 132df930be7Sderaadt 133df930be7Sderaadt /* 13445f2ab88Sderaadt * nget_uslong -- 13545f2ab88Sderaadt * Get an unsigned long, checking for overflow. 13645f2ab88Sderaadt * 137c72b5b24Smillert * PUBLIC: enum nresult nget_uslong(u_long *, const char *, char **, int); 13845f2ab88Sderaadt */ 13945f2ab88Sderaadt enum nresult 140486aa1f0Sbentley nget_uslong(u_long *valp, const char *p, char **endp, int base) 14145f2ab88Sderaadt { 14245f2ab88Sderaadt errno = 0; 14345f2ab88Sderaadt *valp = strtoul(p, endp, base); 14445f2ab88Sderaadt if (errno == 0) 14545f2ab88Sderaadt return (NUM_OK); 14645f2ab88Sderaadt if (errno == ERANGE && *valp == ULONG_MAX) 14745f2ab88Sderaadt return (NUM_OVER); 14845f2ab88Sderaadt return (NUM_ERR); 14945f2ab88Sderaadt } 15045f2ab88Sderaadt 15145f2ab88Sderaadt /* 15245f2ab88Sderaadt * nget_slong -- 15345f2ab88Sderaadt * Convert a signed long, checking for overflow and underflow. 15445f2ab88Sderaadt * 155c72b5b24Smillert * PUBLIC: enum nresult nget_slong(long *, const char *, char **, int); 15645f2ab88Sderaadt */ 15745f2ab88Sderaadt enum nresult 158486aa1f0Sbentley nget_slong(long *valp, const char *p, char **endp, int base) 15945f2ab88Sderaadt { 16045f2ab88Sderaadt errno = 0; 16145f2ab88Sderaadt *valp = strtol(p, endp, base); 16245f2ab88Sderaadt if (errno == 0) 16345f2ab88Sderaadt return (NUM_OK); 16445f2ab88Sderaadt if (errno == ERANGE) { 16545f2ab88Sderaadt if (*valp == LONG_MAX) 16645f2ab88Sderaadt return (NUM_OVER); 16745f2ab88Sderaadt if (*valp == LONG_MIN) 16845f2ab88Sderaadt return (NUM_UNDER); 16945f2ab88Sderaadt } 17045f2ab88Sderaadt return (NUM_ERR); 17145f2ab88Sderaadt } 17245f2ab88Sderaadt 17345f2ab88Sderaadt #ifdef DEBUG 17445f2ab88Sderaadt #include <stdarg.h> 17545f2ab88Sderaadt 17645f2ab88Sderaadt /* 17745f2ab88Sderaadt * TRACE -- 17845f2ab88Sderaadt * debugging trace routine. 17945f2ab88Sderaadt * 180c72b5b24Smillert * PUBLIC: void TRACE(SCR *, const char *, ...); 181df930be7Sderaadt */ 182df930be7Sderaadt void 18345f2ab88Sderaadt TRACE(SCR *sp, const char *fmt, ...) 184df930be7Sderaadt { 18545f2ab88Sderaadt FILE *tfp; 18645f2ab88Sderaadt va_list ap; 18745f2ab88Sderaadt 18845f2ab88Sderaadt if ((tfp = sp->gp->tracefp) == NULL) 18945f2ab88Sderaadt return; 19045f2ab88Sderaadt va_start(ap, fmt); 19145f2ab88Sderaadt (void)vfprintf(tfp, fmt, ap); 19245f2ab88Sderaadt va_end(ap); 19345f2ab88Sderaadt 19445f2ab88Sderaadt (void)fflush(tfp); 195df930be7Sderaadt } 19645f2ab88Sderaadt #endif 197