rename O_DIRECTORY to O_TMP_DIRECTORY to avoid conflict with open option
[nvi.git] / common / util.c
blobaf6ff7172157ccafac0ed317cdc2633ada6393cc
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.22 2001/06/25 15:19:12 skimo Exp $ (Berkeley) $Date: 2001/06/25 15:19:12 $";
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(SCR *sp, void *bp, size_t *bsizep, size_t min)
37 /* sp MAY BE NULL!!! */
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(SCR *sp, db_recno_t lno, size_t *cnop)
78 CHAR_T *p;
79 size_t cnt, len, off;
80 int isempty;
82 /* Default. */
83 off = *cnop;
84 *cnop = 0;
86 /* Get the line, succeeding in an empty file. */
87 if (db_eget(sp, lno, &p, &len, &isempty))
88 return (!isempty);
90 /* Set the offset. */
91 if (len == 0 || off >= len)
92 return (0);
94 for (cnt = off, p = &p[off],
95 len -= off; len && isblank(*p); ++cnt, ++p, --len);
97 /* Set the return. */
98 *cnop = len ? cnt : cnt - 1;
99 return (0);
103 * tail --
104 * Return tail of a path.
106 * PUBLIC: char *tail __P((char *));
108 char *
109 tail(char *path)
111 char *p;
113 if ((p = strrchr(path, '/')) == NULL)
114 return (path);
115 return (p + 1);
119 * v_strdup --
120 * Strdup for wide character strings with an associated length.
122 * PUBLIC: char *v_strdup __P((SCR *, const char *, size_t));
124 char *
125 v_strdup(SCR *sp, const char *str, size_t len)
127 char *copy;
129 MALLOC(sp, copy, char *, (len + 1));
130 if (copy == NULL)
131 return (NULL);
132 memcpy(copy, str, len);
133 copy[len] = '\0';
134 return (copy);
138 * v_strdup --
139 * Strdup for wide character strings with an associated length.
141 * PUBLIC: CHAR_T *v_wstrdup __P((SCR *, const CHAR_T *, size_t));
143 CHAR_T *
144 v_wstrdup(SCR *sp, const CHAR_T *str, size_t len)
146 CHAR_T *copy;
148 MALLOC(sp, copy, CHAR_T *, (len + 1) * sizeof(CHAR_T));
149 if (copy == NULL)
150 return (NULL);
151 MEMCPYW(copy, str, len);
152 copy[len] = '\0';
153 return (copy);
157 * nget_uslong --
158 * Get an unsigned long, checking for overflow.
160 * PUBLIC: enum nresult nget_uslong __P((SCR *, u_long *, const CHAR_T *, CHAR_T **, int));
162 enum nresult
163 nget_uslong(SCR *sp, u_long *valp, const CHAR_T *p, CHAR_T **endp, int base)
165 errno = 0;
166 *valp = STRTOUL(p, endp, base);
167 if (errno == 0)
168 return (NUM_OK);
169 if (errno == ERANGE && *valp == ULONG_MAX)
170 return (NUM_OVER);
171 return (NUM_ERR);
175 * nget_slong --
176 * Convert a signed long, checking for overflow and underflow.
178 * PUBLIC: enum nresult nget_slong __P((SCR *, long *, const CHAR_T *, CHAR_T **, int));
180 enum nresult
181 nget_slong(SCR *sp, long int *valp, const CHAR_T *p, CHAR_T **endp, int base)
183 errno = 0;
184 *valp = STRTOL(p, endp, base);
185 if (errno == 0)
186 return (NUM_OK);
187 if (errno == ERANGE) {
188 if (*valp == LONG_MAX)
189 return (NUM_OVER);
190 if (*valp == LONG_MIN)
191 return (NUM_UNDER);
193 return (NUM_ERR);