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