xref: /netbsd-src/external/bsd/nvi/dist/common/util.c (revision b6e834eb55886377b58050127cf7b4ad99c12856)
1*b6e834ebSrin /*	$NetBSD: util.c,v 1.4 2017/11/12 15:26:33 rin Exp $ */
2dbd550edSchristos /*-
3dbd550edSchristos  * Copyright (c) 1991, 1993, 1994
4dbd550edSchristos  *	The Regents of the University of California.  All rights reserved.
5dbd550edSchristos  * Copyright (c) 1991, 1993, 1994, 1995, 1996
6dbd550edSchristos  *	Keith Bostic.  All rights reserved.
7dbd550edSchristos  *
8dbd550edSchristos  * See the LICENSE file for redistribution information.
9dbd550edSchristos  */
10dbd550edSchristos 
11dbd550edSchristos #include "config.h"
12dbd550edSchristos 
132f698edbSchristos #include <sys/cdefs.h>
142f698edbSchristos #if 0
15dbd550edSchristos #ifndef lint
16dbd550edSchristos static const char sccsid[] = "Id: util.c,v 10.22 2001/06/25 15:19:12 skimo Exp  (Berkeley) Date: 2001/06/25 15:19:12 ";
17dbd550edSchristos #endif /* not lint */
182f698edbSchristos #else
19*b6e834ebSrin __RCSID("$NetBSD: util.c,v 1.4 2017/11/12 15:26:33 rin Exp $");
202f698edbSchristos #endif
21dbd550edSchristos 
22dbd550edSchristos #include <sys/types.h>
23dbd550edSchristos #include <sys/queue.h>
24dbd550edSchristos 
25dbd550edSchristos #include <bitstring.h>
26dbd550edSchristos #include <errno.h>
27dbd550edSchristos #include <limits.h>
28dbd550edSchristos #include <stdio.h>
29dbd550edSchristos #include <stdlib.h>
30dbd550edSchristos #include <string.h>
31dbd550edSchristos #include <unistd.h>
32dbd550edSchristos 
33dbd550edSchristos #include "common.h"
34dbd550edSchristos 
35dbd550edSchristos /*
36dbd550edSchristos  * binc --
37dbd550edSchristos  *	Increase the size of a buffer.
38dbd550edSchristos  *
39dbd550edSchristos  * PUBLIC: void *binc __P((SCR *, void *, size_t *, size_t));
40dbd550edSchristos  */
41dbd550edSchristos void *
binc(SCR * sp,void * bp,size_t * bsizep,size_t min)42dbd550edSchristos binc(SCR *sp, void *bp, size_t *bsizep, size_t min)
43dbd550edSchristos 	        			/* sp MAY BE NULL!!! */
44dbd550edSchristos 
45dbd550edSchristos 
46dbd550edSchristos {
47dbd550edSchristos 	size_t csize;
48dbd550edSchristos 
49dbd550edSchristos 	/* If already larger than the minimum, just return. */
50dbd550edSchristos 	if (min && *bsizep >= min)
51dbd550edSchristos 		return (bp);
52dbd550edSchristos 
53dbd550edSchristos 	csize = *bsizep + MAX(min, 256);
54dbd550edSchristos 	REALLOC(sp, bp, void *, csize);
55dbd550edSchristos 
56dbd550edSchristos 	if (bp == NULL) {
57dbd550edSchristos 		/*
58dbd550edSchristos 		 * Theoretically, realloc is supposed to leave any already
59dbd550edSchristos 		 * held memory alone if it can't get more.  Don't trust it.
60dbd550edSchristos 		 */
61dbd550edSchristos 		*bsizep = 0;
62dbd550edSchristos 		return (NULL);
63dbd550edSchristos 	}
64dbd550edSchristos 	/*
65dbd550edSchristos 	 * Memory is guaranteed to be zero-filled, various parts of
66dbd550edSchristos 	 * nvi depend on this.
67dbd550edSchristos 	 */
68dbd550edSchristos 	memset((char *)bp + *bsizep, 0, csize - *bsizep);
69dbd550edSchristos 	*bsizep = csize;
70dbd550edSchristos 	return (bp);
71dbd550edSchristos }
72dbd550edSchristos 
73dbd550edSchristos /*
74dbd550edSchristos  * nonblank --
75dbd550edSchristos  *	Set the column number of the first non-blank character
76dbd550edSchristos  *	including or after the starting column.  On error, set
77dbd550edSchristos  *	the column to 0, it's safest.
78dbd550edSchristos  *
79dbd550edSchristos  * PUBLIC: int nonblank __P((SCR *, db_recno_t, size_t *));
80dbd550edSchristos  */
81dbd550edSchristos int
nonblank(SCR * sp,db_recno_t lno,size_t * cnop)82dbd550edSchristos nonblank(SCR *sp, db_recno_t lno, size_t *cnop)
83dbd550edSchristos {
84dbd550edSchristos 	CHAR_T *p;
85dbd550edSchristos 	size_t cnt, len, off;
86dbd550edSchristos 	int isempty;
87dbd550edSchristos 
88dbd550edSchristos 	/* Default. */
89dbd550edSchristos 	off = *cnop;
90dbd550edSchristos 	*cnop = 0;
91dbd550edSchristos 
92dbd550edSchristos 	/* Get the line, succeeding in an empty file. */
93dbd550edSchristos 	if (db_eget(sp, lno, &p, &len, &isempty))
94dbd550edSchristos 		return (!isempty);
95dbd550edSchristos 
96dbd550edSchristos 	/* Set the offset. */
97dbd550edSchristos 	if (len == 0 || off >= len)
98dbd550edSchristos 		return (0);
99dbd550edSchristos 
100dbd550edSchristos 	for (cnt = off, p = &p[off],
1018d01a27eSchristos 	    len -= off; len && ISBLANK((UCHAR_T)*p); ++cnt, ++p, --len);
102dbd550edSchristos 
103dbd550edSchristos 	/* Set the return. */
104dbd550edSchristos 	*cnop = len ? cnt : cnt - 1;
105dbd550edSchristos 	return (0);
106dbd550edSchristos }
107dbd550edSchristos 
108dbd550edSchristos /*
109dbd550edSchristos  * tail --
110dbd550edSchristos  *	Return tail of a path.
111dbd550edSchristos  *
1128d01a27eSchristos  * PUBLIC: const char *tail __P((const char *));
113dbd550edSchristos  */
1148d01a27eSchristos const char *
tail(const char * path)1158d01a27eSchristos tail(const char *path)
116dbd550edSchristos {
1178d01a27eSchristos 	const char *p;
118dbd550edSchristos 
119dbd550edSchristos 	if ((p = strrchr(path, '/')) == NULL)
120dbd550edSchristos 		return (path);
121dbd550edSchristos 	return (p + 1);
122dbd550edSchristos }
123dbd550edSchristos 
124dbd550edSchristos /*
125dbd550edSchristos  * v_strdup --
126dbd550edSchristos  *	Strdup for wide character strings with an associated length.
127dbd550edSchristos  *
128dbd550edSchristos  * PUBLIC: char *v_strdup __P((SCR *, const char *, size_t));
129dbd550edSchristos  */
130dbd550edSchristos char *
v_strdup(SCR * sp,const char * str,size_t len)131dbd550edSchristos v_strdup(SCR *sp, const char *str, size_t len)
132dbd550edSchristos {
133dbd550edSchristos 	char *copy;
134dbd550edSchristos 
135dbd550edSchristos 	MALLOC(sp, copy, char *, (len + 1));
136dbd550edSchristos 	if (copy == NULL)
137dbd550edSchristos 		return (NULL);
138dbd550edSchristos 	memcpy(copy, str, len);
139dbd550edSchristos 	copy[len] = '\0';
140dbd550edSchristos 	return (copy);
141dbd550edSchristos }
142dbd550edSchristos 
143dbd550edSchristos /*
144dbd550edSchristos  * v_strdup --
145dbd550edSchristos  *	Strdup for wide character strings with an associated length.
146dbd550edSchristos  *
147dbd550edSchristos  * PUBLIC: CHAR_T *v_wstrdup __P((SCR *, const CHAR_T *, size_t));
148dbd550edSchristos  */
149dbd550edSchristos CHAR_T *
v_wstrdup(SCR * sp,const CHAR_T * str,size_t len)150dbd550edSchristos v_wstrdup(SCR *sp, const CHAR_T *str, size_t len)
151dbd550edSchristos {
152dbd550edSchristos 	CHAR_T *copy;
153dbd550edSchristos 
154dbd550edSchristos 	MALLOC(sp, copy, CHAR_T *, (len + 1) * sizeof(CHAR_T));
155dbd550edSchristos 	if (copy == NULL)
156dbd550edSchristos 		return (NULL);
157dbd550edSchristos 	MEMCPYW(copy, str, len);
158dbd550edSchristos 	copy[len] = '\0';
159dbd550edSchristos 	return (copy);
160dbd550edSchristos }
161dbd550edSchristos 
162dbd550edSchristos /*
163dbd550edSchristos  * nget_uslong --
164dbd550edSchristos  *      Get an unsigned long, checking for overflow.
165dbd550edSchristos  *
166dbd550edSchristos  * PUBLIC: enum nresult nget_uslong __P((SCR *, u_long *, const CHAR_T *, CHAR_T **, int));
167dbd550edSchristos  */
168dbd550edSchristos enum nresult
nget_uslong(SCR * sp,u_long * valp,const CHAR_T * p,CHAR_T ** endp,int base)169dbd550edSchristos nget_uslong(SCR *sp, u_long *valp, const CHAR_T *p, CHAR_T **endp, int base)
170dbd550edSchristos {
171dbd550edSchristos 	errno = 0;
172*b6e834ebSrin 	*valp = STRTOUL(p, endp, base);
173dbd550edSchristos 	if (errno == 0)
174dbd550edSchristos 		return (NUM_OK);
175dbd550edSchristos 	if (errno == ERANGE && *valp == ULONG_MAX)
176dbd550edSchristos 		return (NUM_OVER);
177dbd550edSchristos 	return (NUM_ERR);
178dbd550edSchristos }
179dbd550edSchristos 
180dbd550edSchristos /*
181dbd550edSchristos  * nget_slong --
182dbd550edSchristos  *      Convert a signed long, checking for overflow and underflow.
183dbd550edSchristos  *
184dbd550edSchristos  * PUBLIC: enum nresult nget_slong __P((SCR *, long *, const CHAR_T *, CHAR_T **, int));
185dbd550edSchristos  */
186dbd550edSchristos enum nresult
nget_slong(SCR * sp,long int * valp,const CHAR_T * p,CHAR_T ** endp,int base)187dbd550edSchristos nget_slong(SCR *sp, long int *valp, const CHAR_T *p, CHAR_T **endp, int base)
188dbd550edSchristos {
189dbd550edSchristos 	errno = 0;
190*b6e834ebSrin 	*valp = STRTOL(p, endp, base);
191dbd550edSchristos 	if (errno == 0)
192dbd550edSchristos 		return (NUM_OK);
193dbd550edSchristos 	if (errno == ERANGE) {
194dbd550edSchristos 		if (*valp == LONG_MAX)
195dbd550edSchristos 			return (NUM_OVER);
196dbd550edSchristos 		if (*valp == LONG_MIN)
197dbd550edSchristos 			return (NUM_UNDER);
198dbd550edSchristos 	}
199dbd550edSchristos 	return (NUM_ERR);
200dbd550edSchristos }
201