xref: /freebsd/contrib/nvi/common/util.c (revision b8ba871bd943582ed54f83888569d65b356469bd)
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