the script used to extract a release
[nvi.git] / common / util.c
blob213a2c727230589297fca088e788241ca6e78ac7
1 /*-
2 * Copyright (c) 1991, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1991, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "$Id: util.c,v 10.19 2000/07/21 17:35:02 skimo Exp $ (Berkeley) $Date: 2000/07/21 17:35:02 $";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
19 #include <bitstring.h>
20 #include <errno.h>
21 #include <limits.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
27 #include "common.h"
30 * binc --
31 * Increase the size of a buffer.
33 * PUBLIC: void *binc __P((SCR *, void *, size_t *, size_t));
35 void *
36 binc(sp, bp, bsizep, min)
37 SCR *sp; /* sp MAY BE NULL!!! */
38 void *bp;
39 size_t *bsizep, min;
41 size_t csize;
43 /* If already larger than the minimum, just return. */
44 if (min && *bsizep >= min)
45 return (bp);
47 csize = *bsizep + MAX(min, 256);
48 REALLOC(sp, bp, void *, csize);
50 if (bp == NULL) {
52 * Theoretically, realloc is supposed to leave any already
53 * held memory alone if it can't get more. Don't trust it.
55 *bsizep = 0;
56 return (NULL);
59 * Memory is guaranteed to be zero-filled, various parts of
60 * nvi depend on this.
62 memset((char *)bp + *bsizep, 0, csize - *bsizep);
63 *bsizep = csize;
64 return (bp);
68 * nonblank --
69 * Set the column number of the first non-blank character
70 * including or after the starting column. On error, set
71 * the column to 0, it's safest.
73 * PUBLIC: int nonblank __P((SCR *, db_recno_t, size_t *));
75 int
76 nonblank(sp, lno, cnop)
77 SCR *sp;
78 db_recno_t lno;
79 size_t *cnop;
81 CHAR_T *p;
82 size_t cnt, len, off;
83 int isempty;
85 /* Default. */
86 off = *cnop;
87 *cnop = 0;
89 /* Get the line, succeeding in an empty file. */
90 if (db_eget(sp, lno, &p, &len, &isempty))
91 return (!isempty);
93 /* Set the offset. */
94 if (len == 0 || off >= len)
95 return (0);
97 for (cnt = off, p = &p[off],
98 len -= off; len && isblank(*p); ++cnt, ++p, --len);
100 /* Set the return. */
101 *cnop = len ? cnt : cnt - 1;
102 return (0);
106 * tail --
107 * Return tail of a path.
109 * PUBLIC: char *tail __P((char *));
111 char *
112 tail(path)
113 char *path;
115 char *p;
117 if ((p = strrchr(path, '/')) == NULL)
118 return (path);
119 return (p + 1);
123 * v_strdup --
124 * Strdup for wide character strings with an associated length.
126 * PUBLIC: char *v_strdup __P((SCR *, const char *, size_t));
128 char *
129 v_strdup(sp, str, len)
130 SCR *sp;
131 const char *str;
132 size_t len;
134 char *copy;
136 MALLOC(sp, copy, char *, (len + 1));
137 if (copy == NULL)
138 return (NULL);
139 memcpy(copy, str, len);
140 copy[len] = '\0';
141 return (copy);
145 * v_strdup --
146 * Strdup for wide character strings with an associated length.
148 * PUBLIC: CHAR_T *v_wstrdup __P((SCR *, const CHAR_T *, size_t));
150 CHAR_T *
151 v_wstrdup(sp, str, len)
152 SCR *sp;
153 const CHAR_T *str;
154 size_t len;
156 CHAR_T *copy;
158 MALLOC(sp, copy, CHAR_T *, (len + 1) * sizeof(CHAR_T));
159 if (copy == NULL)
160 return (NULL);
161 MEMCPYW(copy, str, len);
162 copy[len] = '\0';
163 return (copy);
167 * PUBLIC: size_t v_strlen __P((const CHAR_T *str));
169 size_t
170 v_strlen(const CHAR_T *str)
172 size_t len = -1;
174 while(str[++len]);
175 return len;
179 * PUBLIC: int v_strcmp __P((const CHAR_T *s1, const CHAR_T *s2));
181 int
182 v_strcmp(const CHAR_T *s1, const CHAR_T *s2)
184 while (*s1 && *s2 && *s1 == *s2) s1++, s2++;
185 return *s1 - *s2;
189 * nget_uslong --
190 * Get an unsigned long, checking for overflow.
192 * PUBLIC: enum nresult nget_uslong __P((SCR *, u_long *, const CHAR_T *, CHAR_T **, int));
194 enum nresult
195 nget_uslong(sp, valp, p, endp, base)
196 SCR *sp;
197 u_long *valp;
198 const CHAR_T *p;
199 CHAR_T **endp;
200 int base;
202 CONST char *np;
203 char *endnp;
204 size_t nlen;
206 INT2CHAR(sp, p, v_strlen(p) + 1, np, nlen);
207 errno = 0;
208 *valp = strtoul(np, &endnp, base);
209 *endp = (CHAR_T*)p + (endnp - np);
210 if (errno == 0)
211 return (NUM_OK);
212 if (errno == ERANGE && *valp == ULONG_MAX)
213 return (NUM_OVER);
214 return (NUM_ERR);
218 * nget_slong --
219 * Convert a signed long, checking for overflow and underflow.
221 * PUBLIC: enum nresult nget_slong __P((SCR *, long *, const CHAR_T *, CHAR_T **, int));
223 enum nresult
224 nget_slong(sp, valp, p, endp, base)
225 SCR *sp;
226 long *valp;
227 const CHAR_T *p;
228 CHAR_T **endp;
229 int base;
231 CONST char *np;
232 char *endnp;
233 size_t nlen;
235 INT2CHAR(sp, p, v_strlen(p) + 1, np, nlen);
236 errno = 0;
237 *valp = strtol(np, &endnp, base);
238 *endp = (CHAR_T*)p + (endnp - np);
239 if (errno == 0)
240 return (NUM_OK);
241 if (errno == ERANGE) {
242 if (*valp == LONG_MAX)
243 return (NUM_OVER);
244 if (*valp == LONG_MIN)
245 return (NUM_UNDER);
247 return (NUM_ERR);