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