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