util.c revision 19305
1/*-
2 * Copyright (c) 1991, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1991, 1993, 1994, 1995, 1996
5 *	Keith Bostic.  All rights reserved.
6 *
7 * See the LICENSE file for redistribution information.
8 */
9
10#include "config.h"
11
12#ifndef lint
13static const char sccsid[] = "@(#)util.c	10.11 (Berkeley) 9/15/96";
14#endif /* not lint */
15
16#include <sys/types.h>
17#include <sys/queue.h>
18
19#include <bitstring.h>
20#include <errno.h>
21#include <limits.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26
27#include "common.h"
28
29/*
30 * binc --
31 *	Increase the size of a buffer.
32 *
33 * PUBLIC: void *binc __P((SCR *, void *, size_t *, size_t));
34 */
35void *
36binc(sp, bp, bsizep, min)
37	SCR *sp;			/* sp MAY BE NULL!!! */
38	void *bp;
39	size_t *bsizep, min;
40{
41	size_t csize;
42
43	/* If already larger than the minimum, just return. */
44	if (min && *bsizep >= min)
45		return (bp);
46
47	csize = *bsizep + MAX(min, 256);
48	REALLOC(sp, bp, void *, csize);
49
50	if (bp == NULL) {
51		/*
52		 * Theoretically, realloc is supposed to leave any already
53		 * held memory alone if it can't get more.  Don't trust it.
54		 */
55		*bsizep = 0;
56		return (NULL);
57	}
58	/*
59	 * Memory is guaranteed to be zero-filled, various parts of
60	 * nvi depend on this.
61	 */
62	memset((char *)bp + *bsizep, 0, csize - *bsizep);
63	*bsizep = csize;
64	return (bp);
65}
66
67/*
68 * nonblank --
69 *	Set the column number of the first non-blank character
70 *	including or after the starting column.  On error, set
71 *	the column to 0, it's safest.
72 *
73 * PUBLIC: int nonblank __P((SCR *, recno_t, size_t *));
74 */
75int
76nonblank(sp, lno, cnop)
77	SCR *sp;
78	recno_t lno;
79	size_t *cnop;
80{
81	char *p;
82	size_t cnt, len, off;
83	int isempty;
84
85	/* Default. */
86	off = *cnop;
87	*cnop = 0;
88
89	/* Get the line, succeeding in an empty file. */
90	if (db_eget(sp, lno, &p, &len, &isempty))
91		return (!isempty);
92
93	/* Set the offset. */
94	if (len == 0 || off >= len)
95		return (0);
96
97	for (cnt = off, p = &p[off],
98	    len -= off; len && isblank(*p); ++cnt, ++p, --len);
99
100	/* Set the return. */
101	*cnop = len ? cnt : cnt - 1;
102	return (0);
103}
104
105/*
106 * tail --
107 *	Return tail of a path.
108 *
109 * PUBLIC: char *tail __P((char *));
110 */
111char *
112tail(path)
113	char *path;
114{
115	char *p;
116
117	if ((p = strrchr(path, '/')) == NULL)
118		return (path);
119	return (p + 1);
120}
121
122/*
123 * v_strdup --
124 *	Strdup for wide character strings with an associated length.
125 *
126 * PUBLIC: CHAR_T *v_strdup __P((SCR *, const CHAR_T *, size_t));
127 */
128CHAR_T *
129v_strdup(sp, str, len)
130	SCR *sp;
131	const CHAR_T *str;
132	size_t len;
133{
134	CHAR_T *copy;
135
136	MALLOC(sp, copy, CHAR_T *, len + 1);
137	if (copy == NULL)
138		return (NULL);
139	memcpy(copy, str, len * sizeof(CHAR_T));
140	copy[len] = '\0';
141	return (copy);
142}
143
144/*
145 * nget_uslong --
146 *      Get an unsigned long, checking for overflow.
147 *
148 * PUBLIC: enum nresult nget_uslong __P((u_long *, const char *, char **, int));
149 */
150enum nresult
151nget_uslong(valp, p, endp, base)
152	u_long *valp;
153	const char *p;
154	char **endp;
155	int base;
156{
157	errno = 0;
158	*valp = strtoul(p, endp, base);
159	if (errno == 0)
160		return (NUM_OK);
161	if (errno == ERANGE && *valp == ULONG_MAX)
162		return (NUM_OVER);
163	return (NUM_ERR);
164}
165
166/*
167 * nget_slong --
168 *      Convert a signed long, checking for overflow and underflow.
169 *
170 * PUBLIC: enum nresult nget_slong __P((long *, const char *, char **, int));
171 */
172enum nresult
173nget_slong(valp, p, endp, base)
174	long *valp;
175	const char *p;
176	char **endp;
177	int base;
178{
179	errno = 0;
180	*valp = strtol(p, endp, base);
181	if (errno == 0)
182		return (NUM_OK);
183	if (errno == ERANGE) {
184		if (*valp == LONG_MAX)
185			return (NUM_OVER);
186		if (*valp == LONG_MIN)
187			return (NUM_UNDER);
188	}
189	return (NUM_ERR);
190}
191
192#ifdef DEBUG
193#ifdef __STDC__
194#include <stdarg.h>
195#else
196#include <varargs.h>
197#endif
198
199/*
200 * TRACE --
201 *	debugging trace routine.
202 *
203 * PUBLIC: void TRACE __P((SCR *, const char *, ...));
204 */
205void
206#ifdef __STDC__
207TRACE(SCR *sp, const char *fmt, ...)
208#else
209TRACE(sp, fmt, va_alist)
210	SCR *sp;
211	char *fmt;
212	va_dcl
213#endif
214{
215	FILE *tfp;
216	va_list ap;
217
218	if ((tfp = sp->gp->tracefp) == NULL)
219		return;
220#ifdef __STDC__
221	va_start(ap, fmt);
222#else
223	va_start(ap);
224#endif
225	(void)vfprintf(tfp, fmt, ap);
226	va_end(ap);
227
228	(void)fflush(tfp);
229}
230#endif
231