]> git.cameronkatri.com Git - mandoc.git/blob - xstd.c
Memory-corruption fix.
[mandoc.git] / xstd.c
1 /* $Id: xstd.c,v 1.8 2009/03/08 11:41:22 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19 #include <assert.h>
20 #include <err.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "private.h"
25
26 /*
27 * Contains wrappers for common functions to simplify their general
28 * usage throughout this codebase.
29 */
30
31 #ifdef __linux__
32 extern size_t strlcat(char *, const char *, size_t);
33 extern size_t strlcpy(char *, const char *, size_t);
34 #endif
35
36
37 int
38 xstrncmp(const char *p1, const char *p2, size_t sz)
39 {
40
41 return(0 == strncmp(p1, p2, sz));
42 }
43
44 int
45 xstrcmp(const char *p1, const char *p2)
46 {
47
48 return(0 == strcmp(p1, p2));
49 }
50
51 int
52 xstrlcat(char *dst, const char *src, size_t sz)
53 {
54
55 return(strlcat(dst, src, sz) < sz);
56 }
57
58 int
59 xstrlcpy(char *dst, const char *src, size_t sz)
60 {
61
62 return(strlcpy(dst, src, sz) < sz);
63 }
64
65 void *
66 xrealloc(void *ptr, size_t sz)
67 {
68 void *p;
69
70 if (NULL == (p = realloc(ptr, sz)))
71 err(EXIT_FAILURE, "realloc");
72 return(p);
73 }
74
75 void *
76 xcalloc(size_t num, size_t sz)
77 {
78 void *p;
79
80 if (NULL == (p = calloc(num, sz)))
81 err(EXIT_FAILURE, "calloc");
82 return(p);
83 }
84
85 char *
86 xstrdup(const char *p)
87 {
88 char *pp;
89
90 if (NULL == (pp = strdup(p)))
91 err(EXIT_FAILURE, "strdup");
92 return(pp);
93 }
94
95 int
96 xstrlcpys(char *buf, const struct mdoc_node *n, size_t sz)
97 {
98 char *p;
99
100 assert(sz > 0);
101 assert(buf);
102 *buf = 0;
103
104 for ( ; n; n = n->next) {
105 assert(MDOC_TEXT == n->type);
106 p = n->string;
107 if ( ! xstrlcat(buf, p, sz))
108 return(0);
109 if (n->next && ! xstrlcat(buf, " ", sz))
110 return(0);
111 }
112
113 return(1);
114 }
115
116 #ifdef __linux__
117 /* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
118
119 /*
120 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
121 *
122 * Permission to use, copy, modify, and distribute this software for any
123 * purpose with or without fee is hereby granted, provided that the above
124 * copyright notice and this permission notice appear in all copies.
125 *
126 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
127 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
128 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
129 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
130 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
131 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
132 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
133 */
134
135 #include <sys/types.h>
136 #include <string.h>
137
138
139 size_t
140 strlcat(char *dst, const char *src, size_t siz)
141 {
142 char *d = dst;
143 const char *s = src;
144 size_t n = siz;
145 size_t dlen;
146
147 /* Find the end of dst and adjust bytes left but don't go past end */
148 while (n-- != 0 && *d != '\0')
149 d++;
150 dlen = d - dst;
151 n = siz - dlen;
152
153 if (n == 0)
154 return(dlen + strlen(s));
155 while (*s != '\0') {
156 if (n != 1) {
157 *d++ = *s;
158 n--;
159 }
160 s++;
161 }
162 *d = '\0';
163
164 return(dlen + (s - src)); /* count does not include NUL */
165 }
166
167 size_t
168 strlcpy(char *dst, const char *src, size_t siz)
169 {
170 char *d = dst;
171 const char *s = src;
172 size_t n = siz;
173
174 /* Copy as many bytes as will fit */
175 if (n != 0) {
176 while (--n != 0) {
177 if ((*d++ = *s++) == '\0')
178 break;
179 }
180 }
181
182 /* Not enough room in dst, add NUL and traverse rest of src */
183 if (n == 0) {
184 if (siz != 0)
185 *d = '\0'; /* NUL-terminate dst */
186 while (*s++)
187 ;
188 }
189
190 return(s - src - 1); /* count does not include NUL */
191 }
192 #endif