1/* ----------------------------------------------------------------------- *
2 *
3 * Copyright 1996-2018 The NASM Authors - All Rights Reserved
4 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following
9 * conditions are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * ----------------------------------------------------------------------- */
33
34/*
35 * nasmlib.c library routines for the Netwide Assembler
36 */
37
38#include "compiler.h"
39
40#include <stdlib.h>
41
42#include "nasmlib.h"
43#include "error.h"
44
45static no_return nasm_alloc_failed(void)
46{
47 /* If nasm_fatal() gets us back here, then croak hard */
48 static bool already_here = false;
49 FILE *errfile;
50
51 if (likely(!already_here)) {
52 already_here = true;
53 nasm_fatal(0, "out of memory!");
54 }
55
56 errfile = error_file;
57 if (!errfile)
58 error_file = stderr;
59
60 fprintf(error_file, "nasm: out of memory!\n");
61 fflush(error_file);
62 fflush(NULL);
63 abort();
64}
65
66static inline void *validate_ptr(void *p)
67{
68 if (unlikely(!p))
69 nasm_alloc_failed();
70 return p;
71}
72
73void *nasm_malloc(size_t size)
74{
75 return validate_ptr(malloc(size));
76}
77
78void *nasm_calloc(size_t size, size_t nelem)
79{
80 return validate_ptr(calloc(size, nelem));
81}
82
83void *nasm_zalloc(size_t size)
84{
85 return validate_ptr(calloc(1, size));
86}
87
88void *nasm_realloc(void *q, size_t size)
89{
90 return validate_ptr(q ? realloc(q, size) : malloc(size));
91}
92
93void nasm_free(void *q)
94{
95 if (q)
96 free(q);
97}
98
99char *nasm_strdup(const char *s)
100{
101 char *p;
102 size_t size = strlen(s) + 1;
103
104 p = nasm_malloc(size);
105 return memcpy(p, s, size);
106}
107
108char *nasm_strndup(const char *s, size_t len)
109{
110 char *p;
111
112 len = strnlen(s, len);
113 p = nasm_malloc(len+1);
114 p[len] = '\0';
115 return memcpy(p, s, len);
116}
117
118char *nasm_strcat(const char *one, const char *two)
119{
120 char *rslt;
121 size_t l1 = strlen(one);
122 size_t l2 = strlen(two);
123 rslt = nasm_malloc(l1 + l2 + 1);
124 memcpy(rslt, one, l1);
125 memcpy(rslt + l1, two, l2+1);
126 return rslt;
127}
128
129char *nasm_strcatn(const char *str1, ...)
130{
131 va_list ap;
132 char *rslt; /* Output buffer */
133 size_t s; /* Total buffer size */
134 size_t n; /* Number of arguments */
135 size_t *ltbl; /* Table of lengths */
136 size_t l, *lp; /* Length for current argument */
137 const char *p; /* Currently examined argument */
138 char *q; /* Output pointer */
139
140 n = 0; /* No strings encountered yet */
141 p = str1;
142 va_start(ap, str1);
143 while (p) {
144 n++;
145 p = va_arg(ap, const char *);
146 }
147 va_end(ap);
148
149 ltbl = nasm_malloc(n * sizeof(size_t));
150
151 s = 1; /* Space for final NULL */
152 p = str1;
153 lp = ltbl;
154 va_start(ap, str1);
155 while (p) {
156 *lp++ = l = strlen(p);
157 s += l;
158 p = va_arg(ap, const char *);
159 }
160 va_end(ap);
161
162 q = rslt = nasm_malloc(s);
163
164 p = str1;
165 lp = ltbl;
166 va_start(ap, str1);
167 while (p) {
168 l = *lp++;
169 memcpy(q, p, l);
170 q += l;
171 p = va_arg(ap, const char *);
172 }
173 va_end(ap);
174 *q = '\0';
175
176 nasm_free(ltbl);
177
178 return rslt;
179}
180