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