1*ac99a8feSmartijn /* $OpenBSD: util.c,v 1.16 2017/11/10 18:31:36 martijn 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> 176735d3fdSbcallah #include <ctype.h> 1845f2ab88Sderaadt #include <errno.h> 19df930be7Sderaadt #include <limits.h> 20df930be7Sderaadt #include <stdio.h> 21df930be7Sderaadt #include <stdlib.h> 22df930be7Sderaadt #include <string.h> 23df930be7Sderaadt #include <unistd.h> 24df930be7Sderaadt 2545f2ab88Sderaadt #include "common.h" 26df930be7Sderaadt 27b9fc9a72Sderaadt #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) 28b9fc9a72Sderaadt 29df930be7Sderaadt /* 30df930be7Sderaadt * binc -- 31df930be7Sderaadt * Increase the size of a buffer. 3245f2ab88Sderaadt * 33c72b5b24Smillert * PUBLIC: void *binc(SCR *, void *, size_t *, size_t); 34df930be7Sderaadt */ 35df930be7Sderaadt void * 36486aa1f0Sbentley binc(SCR *sp, void *bp, size_t *bsizep, size_t min) 37df930be7Sderaadt { 38df930be7Sderaadt size_t csize; 39df930be7Sderaadt 40df930be7Sderaadt /* If already larger than the minimum, just return. */ 41df930be7Sderaadt if (min && *bsizep >= min) 42df930be7Sderaadt return (bp); 43df930be7Sderaadt 44b9fc9a72Sderaadt csize = *bsizep + MAXIMUM(min, 256); 4554d5890cSmmcc REALLOC(sp, bp, csize); 46df930be7Sderaadt 47df930be7Sderaadt if (bp == NULL) { 48df930be7Sderaadt /* 49df930be7Sderaadt * Theoretically, realloc is supposed to leave any already 50df930be7Sderaadt * held memory alone if it can't get more. Don't trust it. 51df930be7Sderaadt */ 52df930be7Sderaadt *bsizep = 0; 53df930be7Sderaadt return (NULL); 54df930be7Sderaadt } 55df930be7Sderaadt /* 56df930be7Sderaadt * Memory is guaranteed to be zero-filled, various parts of 57df930be7Sderaadt * nvi depend on this. 58df930be7Sderaadt */ 59df930be7Sderaadt memset((char *)bp + *bsizep, 0, csize - *bsizep); 60df930be7Sderaadt *bsizep = csize; 61df930be7Sderaadt return (bp); 62df930be7Sderaadt } 63df930be7Sderaadt 64df930be7Sderaadt /* 65df930be7Sderaadt * nonblank -- 66df930be7Sderaadt * Set the column number of the first non-blank character 67df930be7Sderaadt * including or after the starting column. On error, set 68df930be7Sderaadt * the column to 0, it's safest. 6945f2ab88Sderaadt * 70c72b5b24Smillert * PUBLIC: int nonblank(SCR *, recno_t, size_t *); 71df930be7Sderaadt */ 72df930be7Sderaadt int 73486aa1f0Sbentley nonblank(SCR *sp, recno_t lno, size_t *cnop) 74df930be7Sderaadt { 75df930be7Sderaadt char *p; 76df930be7Sderaadt size_t cnt, len, off; 7745f2ab88Sderaadt int isempty; 78df930be7Sderaadt 79df930be7Sderaadt /* Default. */ 80df930be7Sderaadt off = *cnop; 81df930be7Sderaadt *cnop = 0; 82df930be7Sderaadt 8345f2ab88Sderaadt /* Get the line, succeeding in an empty file. */ 8445f2ab88Sderaadt if (db_eget(sp, lno, &p, &len, &isempty)) 8545f2ab88Sderaadt return (!isempty); 86df930be7Sderaadt 87df930be7Sderaadt /* Set the offset. */ 88df930be7Sderaadt if (len == 0 || off >= len) 89df930be7Sderaadt return (0); 90df930be7Sderaadt 91df930be7Sderaadt for (cnt = off, p = &p[off], 92df930be7Sderaadt len -= off; len && isblank(*p); ++cnt, ++p, --len); 93df930be7Sderaadt 94df930be7Sderaadt /* Set the return. */ 95df930be7Sderaadt *cnop = len ? cnt : cnt - 1; 96df930be7Sderaadt return (0); 97df930be7Sderaadt } 98df930be7Sderaadt 99df930be7Sderaadt /* 100df930be7Sderaadt * v_strdup -- 101df930be7Sderaadt * Strdup for wide character strings with an associated length. 10245f2ab88Sderaadt * 103721c3ea3Smartijn * PUBLIC: CHAR_T *v_strdup(SCR *, const CHAR_T *, size_t); 104df930be7Sderaadt */ 105721c3ea3Smartijn CHAR_T * 106721c3ea3Smartijn v_strdup(SCR *sp, const CHAR_T *str, size_t len) 107df930be7Sderaadt { 108721c3ea3Smartijn CHAR_T *copy; 109df930be7Sderaadt 11054d5890cSmmcc MALLOC(sp, copy, len + 1); 111df930be7Sderaadt if (copy == NULL) 112df930be7Sderaadt return (NULL); 113721c3ea3Smartijn memcpy(copy, str, len * sizeof(CHAR_T)); 114df930be7Sderaadt copy[len] = '\0'; 115df930be7Sderaadt return (copy); 116df930be7Sderaadt } 117df930be7Sderaadt 118df930be7Sderaadt /* 11945f2ab88Sderaadt * nget_uslong -- 12045f2ab88Sderaadt * Get an unsigned long, checking for overflow. 12145f2ab88Sderaadt * 122c72b5b24Smillert * PUBLIC: enum nresult nget_uslong(u_long *, const char *, char **, int); 12345f2ab88Sderaadt */ 12445f2ab88Sderaadt enum nresult 125486aa1f0Sbentley nget_uslong(u_long *valp, const char *p, char **endp, int base) 12645f2ab88Sderaadt { 12745f2ab88Sderaadt errno = 0; 12845f2ab88Sderaadt *valp = strtoul(p, endp, base); 12945f2ab88Sderaadt if (errno == 0) 13045f2ab88Sderaadt return (NUM_OK); 13145f2ab88Sderaadt if (errno == ERANGE && *valp == ULONG_MAX) 13245f2ab88Sderaadt return (NUM_OVER); 13345f2ab88Sderaadt return (NUM_ERR); 13445f2ab88Sderaadt } 13545f2ab88Sderaadt 13645f2ab88Sderaadt /* 13745f2ab88Sderaadt * nget_slong -- 13845f2ab88Sderaadt * Convert a signed long, checking for overflow and underflow. 13945f2ab88Sderaadt * 140c72b5b24Smillert * PUBLIC: enum nresult nget_slong(long *, const char *, char **, int); 14145f2ab88Sderaadt */ 14245f2ab88Sderaadt enum nresult 143486aa1f0Sbentley nget_slong(long *valp, const char *p, char **endp, int base) 14445f2ab88Sderaadt { 14545f2ab88Sderaadt errno = 0; 14645f2ab88Sderaadt *valp = strtol(p, endp, base); 14745f2ab88Sderaadt if (errno == 0) 14845f2ab88Sderaadt return (NUM_OK); 14945f2ab88Sderaadt if (errno == ERANGE) { 15045f2ab88Sderaadt if (*valp == LONG_MAX) 15145f2ab88Sderaadt return (NUM_OVER); 15245f2ab88Sderaadt if (*valp == LONG_MIN) 15345f2ab88Sderaadt return (NUM_UNDER); 15445f2ab88Sderaadt } 15545f2ab88Sderaadt return (NUM_ERR); 15645f2ab88Sderaadt } 15745f2ab88Sderaadt 15845f2ab88Sderaadt #ifdef DEBUG 15945f2ab88Sderaadt #include <stdarg.h> 16045f2ab88Sderaadt 16145f2ab88Sderaadt /* 16245f2ab88Sderaadt * TRACE -- 16345f2ab88Sderaadt * debugging trace routine. 16445f2ab88Sderaadt * 165c72b5b24Smillert * PUBLIC: void TRACE(SCR *, const char *, ...); 166df930be7Sderaadt */ 167df930be7Sderaadt void 16845f2ab88Sderaadt TRACE(SCR *sp, const char *fmt, ...) 169df930be7Sderaadt { 17045f2ab88Sderaadt FILE *tfp; 17145f2ab88Sderaadt va_list ap; 17245f2ab88Sderaadt 17345f2ab88Sderaadt if ((tfp = sp->gp->tracefp) == NULL) 17445f2ab88Sderaadt return; 17545f2ab88Sderaadt va_start(ap, fmt); 17645f2ab88Sderaadt (void)vfprintf(tfp, fmt, ap); 177*ac99a8feSmartijn fflush(tfp); 17845f2ab88Sderaadt va_end(ap); 17945f2ab88Sderaadt 18045f2ab88Sderaadt (void)fflush(tfp); 181df930be7Sderaadt } 18245f2ab88Sderaadt #endif 183