xref: /minix3/external/bsd/nvi/dist/common/util.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: util.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
284d9c625SLionel Sambuc /*-
384d9c625SLionel Sambuc  * Copyright (c) 1991, 1993, 1994
484d9c625SLionel Sambuc  *	The Regents of the University of California.  All rights reserved.
584d9c625SLionel Sambuc  * Copyright (c) 1991, 1993, 1994, 1995, 1996
684d9c625SLionel Sambuc  *	Keith Bostic.  All rights reserved.
784d9c625SLionel Sambuc  *
884d9c625SLionel Sambuc  * See the LICENSE file for redistribution information.
984d9c625SLionel Sambuc  */
1084d9c625SLionel Sambuc 
1184d9c625SLionel Sambuc #include "config.h"
1284d9c625SLionel Sambuc 
13*0a6a1f1dSLionel Sambuc #include <sys/cdefs.h>
14*0a6a1f1dSLionel Sambuc #if 0
1584d9c625SLionel Sambuc #ifndef lint
1684d9c625SLionel Sambuc 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 ";
1784d9c625SLionel Sambuc #endif /* not lint */
18*0a6a1f1dSLionel Sambuc #else
19*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: util.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
20*0a6a1f1dSLionel Sambuc #endif
2184d9c625SLionel Sambuc 
2284d9c625SLionel Sambuc #include <sys/types.h>
2384d9c625SLionel Sambuc #include <sys/queue.h>
2484d9c625SLionel Sambuc 
2584d9c625SLionel Sambuc #include <bitstring.h>
2684d9c625SLionel Sambuc #include <errno.h>
2784d9c625SLionel Sambuc #include <limits.h>
2884d9c625SLionel Sambuc #include <stdio.h>
2984d9c625SLionel Sambuc #include <stdlib.h>
3084d9c625SLionel Sambuc #include <string.h>
3184d9c625SLionel Sambuc #include <unistd.h>
3284d9c625SLionel Sambuc 
3384d9c625SLionel Sambuc #include "common.h"
3484d9c625SLionel Sambuc 
3584d9c625SLionel Sambuc /*
3684d9c625SLionel Sambuc  * binc --
3784d9c625SLionel Sambuc  *	Increase the size of a buffer.
3884d9c625SLionel Sambuc  *
3984d9c625SLionel Sambuc  * PUBLIC: void *binc __P((SCR *, void *, size_t *, size_t));
4084d9c625SLionel Sambuc  */
4184d9c625SLionel Sambuc void *
binc(SCR * sp,void * bp,size_t * bsizep,size_t min)4284d9c625SLionel Sambuc binc(SCR *sp, void *bp, size_t *bsizep, size_t min)
4384d9c625SLionel Sambuc 	        			/* sp MAY BE NULL!!! */
4484d9c625SLionel Sambuc 
4584d9c625SLionel Sambuc 
4684d9c625SLionel Sambuc {
4784d9c625SLionel Sambuc 	size_t csize;
4884d9c625SLionel Sambuc 
4984d9c625SLionel Sambuc 	/* If already larger than the minimum, just return. */
5084d9c625SLionel Sambuc 	if (min && *bsizep >= min)
5184d9c625SLionel Sambuc 		return (bp);
5284d9c625SLionel Sambuc 
5384d9c625SLionel Sambuc 	csize = *bsizep + MAX(min, 256);
5484d9c625SLionel Sambuc 	REALLOC(sp, bp, void *, csize);
5584d9c625SLionel Sambuc 
5684d9c625SLionel Sambuc 	if (bp == NULL) {
5784d9c625SLionel Sambuc 		/*
5884d9c625SLionel Sambuc 		 * Theoretically, realloc is supposed to leave any already
5984d9c625SLionel Sambuc 		 * held memory alone if it can't get more.  Don't trust it.
6084d9c625SLionel Sambuc 		 */
6184d9c625SLionel Sambuc 		*bsizep = 0;
6284d9c625SLionel Sambuc 		return (NULL);
6384d9c625SLionel Sambuc 	}
6484d9c625SLionel Sambuc 	/*
6584d9c625SLionel Sambuc 	 * Memory is guaranteed to be zero-filled, various parts of
6684d9c625SLionel Sambuc 	 * nvi depend on this.
6784d9c625SLionel Sambuc 	 */
6884d9c625SLionel Sambuc 	memset((char *)bp + *bsizep, 0, csize - *bsizep);
6984d9c625SLionel Sambuc 	*bsizep = csize;
7084d9c625SLionel Sambuc 	return (bp);
7184d9c625SLionel Sambuc }
7284d9c625SLionel Sambuc 
7384d9c625SLionel Sambuc /*
7484d9c625SLionel Sambuc  * nonblank --
7584d9c625SLionel Sambuc  *	Set the column number of the first non-blank character
7684d9c625SLionel Sambuc  *	including or after the starting column.  On error, set
7784d9c625SLionel Sambuc  *	the column to 0, it's safest.
7884d9c625SLionel Sambuc  *
7984d9c625SLionel Sambuc  * PUBLIC: int nonblank __P((SCR *, db_recno_t, size_t *));
8084d9c625SLionel Sambuc  */
8184d9c625SLionel Sambuc int
nonblank(SCR * sp,db_recno_t lno,size_t * cnop)8284d9c625SLionel Sambuc nonblank(SCR *sp, db_recno_t lno, size_t *cnop)
8384d9c625SLionel Sambuc {
8484d9c625SLionel Sambuc 	CHAR_T *p;
8584d9c625SLionel Sambuc 	size_t cnt, len, off;
8684d9c625SLionel Sambuc 	int isempty;
8784d9c625SLionel Sambuc 
8884d9c625SLionel Sambuc 	/* Default. */
8984d9c625SLionel Sambuc 	off = *cnop;
9084d9c625SLionel Sambuc 	*cnop = 0;
9184d9c625SLionel Sambuc 
9284d9c625SLionel Sambuc 	/* Get the line, succeeding in an empty file. */
9384d9c625SLionel Sambuc 	if (db_eget(sp, lno, &p, &len, &isempty))
9484d9c625SLionel Sambuc 		return (!isempty);
9584d9c625SLionel Sambuc 
9684d9c625SLionel Sambuc 	/* Set the offset. */
9784d9c625SLionel Sambuc 	if (len == 0 || off >= len)
9884d9c625SLionel Sambuc 		return (0);
9984d9c625SLionel Sambuc 
10084d9c625SLionel Sambuc 	for (cnt = off, p = &p[off],
10184d9c625SLionel Sambuc 	    len -= off; len && ISBLANK((UCHAR_T)*p); ++cnt, ++p, --len);
10284d9c625SLionel Sambuc 
10384d9c625SLionel Sambuc 	/* Set the return. */
10484d9c625SLionel Sambuc 	*cnop = len ? cnt : cnt - 1;
10584d9c625SLionel Sambuc 	return (0);
10684d9c625SLionel Sambuc }
10784d9c625SLionel Sambuc 
10884d9c625SLionel Sambuc /*
10984d9c625SLionel Sambuc  * tail --
11084d9c625SLionel Sambuc  *	Return tail of a path.
11184d9c625SLionel Sambuc  *
11284d9c625SLionel Sambuc  * PUBLIC: const char *tail __P((const char *));
11384d9c625SLionel Sambuc  */
11484d9c625SLionel Sambuc const char *
tail(const char * path)11584d9c625SLionel Sambuc tail(const char *path)
11684d9c625SLionel Sambuc {
11784d9c625SLionel Sambuc 	const char *p;
11884d9c625SLionel Sambuc 
11984d9c625SLionel Sambuc 	if ((p = strrchr(path, '/')) == NULL)
12084d9c625SLionel Sambuc 		return (path);
12184d9c625SLionel Sambuc 	return (p + 1);
12284d9c625SLionel Sambuc }
12384d9c625SLionel Sambuc 
12484d9c625SLionel Sambuc /*
12584d9c625SLionel Sambuc  * v_strdup --
12684d9c625SLionel Sambuc  *	Strdup for wide character strings with an associated length.
12784d9c625SLionel Sambuc  *
12884d9c625SLionel Sambuc  * PUBLIC: char *v_strdup __P((SCR *, const char *, size_t));
12984d9c625SLionel Sambuc  */
13084d9c625SLionel Sambuc char *
v_strdup(SCR * sp,const char * str,size_t len)13184d9c625SLionel Sambuc v_strdup(SCR *sp, const char *str, size_t len)
13284d9c625SLionel Sambuc {
13384d9c625SLionel Sambuc 	char *copy;
13484d9c625SLionel Sambuc 
13584d9c625SLionel Sambuc 	MALLOC(sp, copy, char *, (len + 1));
13684d9c625SLionel Sambuc 	if (copy == NULL)
13784d9c625SLionel Sambuc 		return (NULL);
13884d9c625SLionel Sambuc 	memcpy(copy, str, len);
13984d9c625SLionel Sambuc 	copy[len] = '\0';
14084d9c625SLionel Sambuc 	return (copy);
14184d9c625SLionel Sambuc }
14284d9c625SLionel Sambuc 
14384d9c625SLionel Sambuc /*
14484d9c625SLionel Sambuc  * v_strdup --
14584d9c625SLionel Sambuc  *	Strdup for wide character strings with an associated length.
14684d9c625SLionel Sambuc  *
14784d9c625SLionel Sambuc  * PUBLIC: CHAR_T *v_wstrdup __P((SCR *, const CHAR_T *, size_t));
14884d9c625SLionel Sambuc  */
14984d9c625SLionel Sambuc CHAR_T *
v_wstrdup(SCR * sp,const CHAR_T * str,size_t len)15084d9c625SLionel Sambuc v_wstrdup(SCR *sp, const CHAR_T *str, size_t len)
15184d9c625SLionel Sambuc {
15284d9c625SLionel Sambuc 	CHAR_T *copy;
15384d9c625SLionel Sambuc 
15484d9c625SLionel Sambuc 	MALLOC(sp, copy, CHAR_T *, (len + 1) * sizeof(CHAR_T));
15584d9c625SLionel Sambuc 	if (copy == NULL)
15684d9c625SLionel Sambuc 		return (NULL);
15784d9c625SLionel Sambuc 	MEMCPYW(copy, str, len);
15884d9c625SLionel Sambuc 	copy[len] = '\0';
15984d9c625SLionel Sambuc 	return (copy);
16084d9c625SLionel Sambuc }
16184d9c625SLionel Sambuc 
16284d9c625SLionel Sambuc /*
16384d9c625SLionel Sambuc  * nget_uslong --
16484d9c625SLionel Sambuc  *      Get an unsigned long, checking for overflow.
16584d9c625SLionel Sambuc  *
16684d9c625SLionel Sambuc  * PUBLIC: enum nresult nget_uslong __P((SCR *, u_long *, const CHAR_T *, CHAR_T **, int));
16784d9c625SLionel Sambuc  */
16884d9c625SLionel Sambuc enum nresult
nget_uslong(SCR * sp,u_long * valp,const CHAR_T * p,CHAR_T ** endp,int base)16984d9c625SLionel Sambuc nget_uslong(SCR *sp, u_long *valp, const CHAR_T *p, CHAR_T **endp, int base)
17084d9c625SLionel Sambuc {
17184d9c625SLionel Sambuc 	errno = 0;
17284d9c625SLionel Sambuc 	*valp = STRTOUL(p, (RCHAR_T **)endp, base);
17384d9c625SLionel Sambuc 	if (errno == 0)
17484d9c625SLionel Sambuc 		return (NUM_OK);
17584d9c625SLionel Sambuc 	if (errno == ERANGE && *valp == ULONG_MAX)
17684d9c625SLionel Sambuc 		return (NUM_OVER);
17784d9c625SLionel Sambuc 	return (NUM_ERR);
17884d9c625SLionel Sambuc }
17984d9c625SLionel Sambuc 
18084d9c625SLionel Sambuc /*
18184d9c625SLionel Sambuc  * nget_slong --
18284d9c625SLionel Sambuc  *      Convert a signed long, checking for overflow and underflow.
18384d9c625SLionel Sambuc  *
18484d9c625SLionel Sambuc  * PUBLIC: enum nresult nget_slong __P((SCR *, long *, const CHAR_T *, CHAR_T **, int));
18584d9c625SLionel Sambuc  */
18684d9c625SLionel Sambuc enum nresult
nget_slong(SCR * sp,long int * valp,const CHAR_T * p,CHAR_T ** endp,int base)18784d9c625SLionel Sambuc nget_slong(SCR *sp, long int *valp, const CHAR_T *p, CHAR_T **endp, int base)
18884d9c625SLionel Sambuc {
18984d9c625SLionel Sambuc 	errno = 0;
19084d9c625SLionel Sambuc 	*valp = STRTOL(p, (RCHAR_T **)endp, base);
19184d9c625SLionel Sambuc 	if (errno == 0)
19284d9c625SLionel Sambuc 		return (NUM_OK);
19384d9c625SLionel Sambuc 	if (errno == ERANGE) {
19484d9c625SLionel Sambuc 		if (*valp == LONG_MAX)
19584d9c625SLionel Sambuc 			return (NUM_OVER);
19684d9c625SLionel Sambuc 		if (*valp == LONG_MIN)
19784d9c625SLionel Sambuc 			return (NUM_UNDER);
19884d9c625SLionel Sambuc 	}
19984d9c625SLionel Sambuc 	return (NUM_ERR);
20084d9c625SLionel Sambuc }
201