xref: /openbsd/usr.bin/vi/common/util.c (revision ac99a8fe)
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