xref: /openbsd/usr.bin/vi/common/util.c (revision 8b325477)
1*8b325477Smartijn /*	$OpenBSD: util.c,v 1.17 2018/07/11 06:39:23 martijn 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>
176735d3fdSbcallah #include <ctype.h>
1845f2ab88Sderaadt #include <errno.h>
19df930be7Sderaadt #include <limits.h>
20df930be7Sderaadt #include <stdio.h>
21df930be7Sderaadt #include <stdlib.h>
22df930be7Sderaadt #include <string.h>
23df930be7Sderaadt #include <unistd.h>
24df930be7Sderaadt 
2545f2ab88Sderaadt #include "common.h"
26df930be7Sderaadt 
27b9fc9a72Sderaadt #define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
28b9fc9a72Sderaadt 
29df930be7Sderaadt /*
30df930be7Sderaadt  * binc --
31df930be7Sderaadt  *	Increase the size of a buffer.
3245f2ab88Sderaadt  *
33c72b5b24Smillert  * PUBLIC: void *binc(SCR *, void *, size_t *, size_t);
34df930be7Sderaadt  */
35df930be7Sderaadt void *
binc(SCR * sp,void * bp,size_t * bsizep,size_t min)36486aa1f0Sbentley binc(SCR *sp, void *bp, size_t *bsizep, size_t min)
37df930be7Sderaadt {
38df930be7Sderaadt 	size_t csize;
39df930be7Sderaadt 
40df930be7Sderaadt 	/* If already larger than the minimum, just return. */
41df930be7Sderaadt 	if (min && *bsizep >= min)
42df930be7Sderaadt 		return (bp);
43df930be7Sderaadt 
44b9fc9a72Sderaadt 	csize = *bsizep + MAXIMUM(min, 256);
4554d5890cSmmcc 	REALLOC(sp, bp, csize);
46df930be7Sderaadt 
47df930be7Sderaadt 	if (bp == NULL) {
48df930be7Sderaadt 		*bsizep = 0;
49df930be7Sderaadt 		return (NULL);
50df930be7Sderaadt 	}
51df930be7Sderaadt 	/*
52df930be7Sderaadt 	 * Memory is guaranteed to be zero-filled, various parts of
53df930be7Sderaadt 	 * nvi depend on this.
54df930be7Sderaadt 	 */
55df930be7Sderaadt 	memset((char *)bp + *bsizep, 0, csize - *bsizep);
56df930be7Sderaadt 	*bsizep = csize;
57df930be7Sderaadt 	return (bp);
58df930be7Sderaadt }
59df930be7Sderaadt 
60df930be7Sderaadt /*
61df930be7Sderaadt  * nonblank --
62df930be7Sderaadt  *	Set the column number of the first non-blank character
63df930be7Sderaadt  *	including or after the starting column.  On error, set
64df930be7Sderaadt  *	the column to 0, it's safest.
6545f2ab88Sderaadt  *
66c72b5b24Smillert  * PUBLIC: int nonblank(SCR *, recno_t, size_t *);
67df930be7Sderaadt  */
68df930be7Sderaadt int
nonblank(SCR * sp,recno_t lno,size_t * cnop)69486aa1f0Sbentley nonblank(SCR *sp, recno_t lno, size_t *cnop)
70df930be7Sderaadt {
71df930be7Sderaadt 	char *p;
72df930be7Sderaadt 	size_t cnt, len, off;
7345f2ab88Sderaadt 	int isempty;
74df930be7Sderaadt 
75df930be7Sderaadt 	/* Default. */
76df930be7Sderaadt 	off = *cnop;
77df930be7Sderaadt 	*cnop = 0;
78df930be7Sderaadt 
7945f2ab88Sderaadt 	/* Get the line, succeeding in an empty file. */
8045f2ab88Sderaadt 	if (db_eget(sp, lno, &p, &len, &isempty))
8145f2ab88Sderaadt 		return (!isempty);
82df930be7Sderaadt 
83df930be7Sderaadt 	/* Set the offset. */
84df930be7Sderaadt 	if (len == 0 || off >= len)
85df930be7Sderaadt 		return (0);
86df930be7Sderaadt 
87df930be7Sderaadt 	for (cnt = off, p = &p[off],
88df930be7Sderaadt 	    len -= off; len && isblank(*p); ++cnt, ++p, --len);
89df930be7Sderaadt 
90df930be7Sderaadt 	/* Set the return. */
91df930be7Sderaadt 	*cnop = len ? cnt : cnt - 1;
92df930be7Sderaadt 	return (0);
93df930be7Sderaadt }
94df930be7Sderaadt 
95df930be7Sderaadt /*
96df930be7Sderaadt  * v_strdup --
97df930be7Sderaadt  *	Strdup for wide character strings with an associated length.
9845f2ab88Sderaadt  *
99721c3ea3Smartijn  * PUBLIC: CHAR_T *v_strdup(SCR *, const CHAR_T *, size_t);
100df930be7Sderaadt  */
101721c3ea3Smartijn CHAR_T *
v_strdup(SCR * sp,const CHAR_T * str,size_t len)102721c3ea3Smartijn v_strdup(SCR *sp, const CHAR_T *str, size_t len)
103df930be7Sderaadt {
104721c3ea3Smartijn 	CHAR_T *copy;
105df930be7Sderaadt 
10654d5890cSmmcc 	MALLOC(sp, copy, len + 1);
107df930be7Sderaadt 	if (copy == NULL)
108df930be7Sderaadt 		return (NULL);
109721c3ea3Smartijn 	memcpy(copy, str, len * sizeof(CHAR_T));
110df930be7Sderaadt 	copy[len] = '\0';
111df930be7Sderaadt 	return (copy);
112df930be7Sderaadt }
113df930be7Sderaadt 
114df930be7Sderaadt /*
11545f2ab88Sderaadt  * nget_uslong --
11645f2ab88Sderaadt  *      Get an unsigned long, checking for overflow.
11745f2ab88Sderaadt  *
118c72b5b24Smillert  * PUBLIC: enum nresult nget_uslong(u_long *, const char *, char **, int);
11945f2ab88Sderaadt  */
12045f2ab88Sderaadt enum nresult
nget_uslong(u_long * valp,const char * p,char ** endp,int base)121486aa1f0Sbentley nget_uslong(u_long *valp, const char *p, char **endp, int base)
12245f2ab88Sderaadt {
12345f2ab88Sderaadt 	errno = 0;
12445f2ab88Sderaadt 	*valp = strtoul(p, endp, base);
12545f2ab88Sderaadt 	if (errno == 0)
12645f2ab88Sderaadt 		return (NUM_OK);
12745f2ab88Sderaadt 	if (errno == ERANGE && *valp == ULONG_MAX)
12845f2ab88Sderaadt 		return (NUM_OVER);
12945f2ab88Sderaadt 	return (NUM_ERR);
13045f2ab88Sderaadt }
13145f2ab88Sderaadt 
13245f2ab88Sderaadt /*
13345f2ab88Sderaadt  * nget_slong --
13445f2ab88Sderaadt  *      Convert a signed long, checking for overflow and underflow.
13545f2ab88Sderaadt  *
136c72b5b24Smillert  * PUBLIC: enum nresult nget_slong(long *, const char *, char **, int);
13745f2ab88Sderaadt  */
13845f2ab88Sderaadt enum nresult
nget_slong(long * valp,const char * p,char ** endp,int base)139486aa1f0Sbentley nget_slong(long *valp, const char *p, char **endp, int base)
14045f2ab88Sderaadt {
14145f2ab88Sderaadt 	errno = 0;
14245f2ab88Sderaadt 	*valp = strtol(p, endp, base);
14345f2ab88Sderaadt 	if (errno == 0)
14445f2ab88Sderaadt 		return (NUM_OK);
14545f2ab88Sderaadt 	if (errno == ERANGE) {
14645f2ab88Sderaadt 		if (*valp == LONG_MAX)
14745f2ab88Sderaadt 			return (NUM_OVER);
14845f2ab88Sderaadt 		if (*valp == LONG_MIN)
14945f2ab88Sderaadt 			return (NUM_UNDER);
15045f2ab88Sderaadt 	}
15145f2ab88Sderaadt 	return (NUM_ERR);
15245f2ab88Sderaadt }
15345f2ab88Sderaadt 
15445f2ab88Sderaadt #ifdef DEBUG
15545f2ab88Sderaadt #include <stdarg.h>
15645f2ab88Sderaadt 
15745f2ab88Sderaadt /*
15845f2ab88Sderaadt  * TRACE --
15945f2ab88Sderaadt  *	debugging trace routine.
16045f2ab88Sderaadt  *
161c72b5b24Smillert  * PUBLIC: void TRACE(SCR *, const char *, ...);
162df930be7Sderaadt  */
163df930be7Sderaadt void
TRACE(SCR * sp,const char * fmt,...)16445f2ab88Sderaadt TRACE(SCR *sp, const char *fmt, ...)
165df930be7Sderaadt {
16645f2ab88Sderaadt 	FILE *tfp;
16745f2ab88Sderaadt 	va_list ap;
16845f2ab88Sderaadt 
16945f2ab88Sderaadt 	if ((tfp = sp->gp->tracefp) == NULL)
17045f2ab88Sderaadt 		return;
17145f2ab88Sderaadt 	va_start(ap, fmt);
17245f2ab88Sderaadt 	(void)vfprintf(tfp, fmt, ap);
173ac99a8feSmartijn 	fflush(tfp);
17445f2ab88Sderaadt 	va_end(ap);
17545f2ab88Sderaadt 
17645f2ab88Sderaadt 	(void)fflush(tfp);
177df930be7Sderaadt }
17845f2ab88Sderaadt #endif
179