mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-27 08:10:07 +08:00
malloc: simplify nasm_malloc code, add nasm_strcatn()
Simplify the nasm_malloc() code by moving the pointer check into a common subroutine. We can now issue a filename error even for failures like malloc(). Add support for the gcc sentinel attribute (verify that a list ends with NULL). Add a handful of safe_alloc attributes. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
parent
1ce81e10ef
commit
740ec3572b
7
aclocal.m4
vendored
7
aclocal.m4
vendored
@ -106,10 +106,11 @@ AC_DEFUN(PA_FUNC_ATTRIBUTE,
|
||||
AC_INCLUDES_DEFAULT
|
||||
extern ifelse([$3],[],[void *],[$3]) __attribute__(($1$2))
|
||||
bar(ifelse([$4],[],[int],[$4]));
|
||||
void *foo(void);
|
||||
void *foo(void)
|
||||
ifelse([$3],[],[void *],[$3]) foo(void);
|
||||
ifelse([$3],[],[void *],[$3]) foo(void)
|
||||
{
|
||||
return bar(ifelse([$5],[],[1],[$5]));
|
||||
ifelse([$3],[void],[],[return])
|
||||
bar(ifelse([$5],[],[1],[$5]));
|
||||
}
|
||||
])],
|
||||
[AC_MSG_RESULT([yes])
|
||||
|
@ -220,6 +220,7 @@ PA_FUNC_ATTRIBUTE(noreturn)
|
||||
PA_FUNC_ATTRIBUTE(returns_nonnull)
|
||||
PA_FUNC_ATTRIBUTE(malloc)
|
||||
PA_FUNC_ATTRIBUTE(alloc_size, (1))
|
||||
PA_FUNC_ATTRIBUTE(sentinel,,, [const char *, ...], ["a","b",NULL])
|
||||
PA_FUNC_ATTRIBUTE(format, [(printf,1,2)], int, [const char *, ...], ["%d",1])
|
||||
PA_FUNC_ATTRIBUTE(const)
|
||||
PA_FUNC_ATTRIBUTE(pure)
|
||||
|
@ -264,7 +264,7 @@ size_t strnlen(const char *s, size_t maxlen);
|
||||
#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
|
||||
# define safe_alloc never_null __attribute__((malloc))
|
||||
#else
|
||||
# define safe_alloc
|
||||
# define safe_alloc never_null
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE
|
||||
@ -277,6 +277,12 @@ size_t strnlen(const char *s, size_t maxlen);
|
||||
# define safe_realloc(s) never_null
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FUNC_ATTRIBUTE_SENTINEL
|
||||
# define end_with_null __attribute__((sentinel))
|
||||
#else
|
||||
# define end_with_null
|
||||
#endif
|
||||
|
||||
/*
|
||||
* How to tell the compiler that a function doesn't return
|
||||
*/
|
||||
|
@ -79,6 +79,8 @@ void * safe_realloc(2) nasm_realloc(void *, size_t);
|
||||
void nasm_free(void *);
|
||||
char * safe_alloc nasm_strdup(const char *);
|
||||
char * safe_alloc nasm_strndup(const char *, size_t);
|
||||
char * safe_alloc nasm_strcat(const char *one, const char *two);
|
||||
char * safe_alloc end_with_null nasm_strcatn(const char *one, ...);
|
||||
|
||||
/* Assert the argument is a pointer without evaluating it */
|
||||
#define nasm_assert_pointer(p) ((void)sizeof(*(p)))
|
||||
@ -282,8 +284,6 @@ void src_set(int32_t line, const char *filename);
|
||||
*/
|
||||
int32_t src_get(int32_t *xline, const char **xname);
|
||||
|
||||
char *nasm_strcat(const char *one, const char *two);
|
||||
|
||||
char *nasm_skip_spaces(const char *p);
|
||||
char *nasm_skip_word(const char *p);
|
||||
char *nasm_zap_spaces_fwd(char *p);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -42,33 +42,36 @@
|
||||
#include "nasmlib.h"
|
||||
#include "error.h"
|
||||
|
||||
static no_return nasm_alloc_failed(void)
|
||||
{
|
||||
nasm_fatal(0, "out of memory");
|
||||
}
|
||||
|
||||
static inline void *validate_ptr(void *p)
|
||||
{
|
||||
if (unlikely(!p))
|
||||
nasm_alloc_failed();
|
||||
return p;
|
||||
}
|
||||
|
||||
void *nasm_malloc(size_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
if (!p)
|
||||
nasm_fatal(ERR_NOFILE, "out of memory");
|
||||
return p;
|
||||
return validate_ptr(malloc(size));
|
||||
}
|
||||
|
||||
void *nasm_calloc(size_t size, size_t nelem)
|
||||
{
|
||||
void *p = calloc(size, nelem);
|
||||
if (!p)
|
||||
nasm_fatal(ERR_NOFILE, "out of memory");
|
||||
return p;
|
||||
return validate_ptr(calloc(size, nelem));
|
||||
}
|
||||
|
||||
void *nasm_zalloc(size_t size)
|
||||
{
|
||||
return nasm_calloc(size, 1);
|
||||
return validate_ptr(calloc(1, size));
|
||||
}
|
||||
|
||||
void *nasm_realloc(void *q, size_t size)
|
||||
{
|
||||
void *p = q ? realloc(q, size) : malloc(size);
|
||||
if (!p)
|
||||
nasm_fatal(ERR_NOFILE, "out of memory");
|
||||
return p;
|
||||
return validate_ptr(q ? realloc(q, size) : malloc(size));
|
||||
}
|
||||
|
||||
void nasm_free(void *q)
|
||||
@ -106,3 +109,55 @@ char *nasm_strcat(const char *one, const char *two)
|
||||
memcpy(rslt + l1, two, l2+1);
|
||||
return rslt;
|
||||
}
|
||||
|
||||
char *nasm_strcatn(const char *str1, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *rslt; /* Output buffer */
|
||||
size_t s; /* Total buffer size */
|
||||
size_t n; /* Number of arguments */
|
||||
size_t *ltbl; /* Table of lengths */
|
||||
size_t l, *lp; /* Length for current argument */
|
||||
const char *p; /* Currently examined argument */
|
||||
char *q; /* Output pointer */
|
||||
|
||||
n = 0; /* No strings encountered yet */
|
||||
p = str1;
|
||||
va_start(ap, str1);
|
||||
while (p) {
|
||||
n++;
|
||||
p = va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
ltbl = nasm_malloc(n * sizeof(size_t));
|
||||
|
||||
s = 1; /* Space for final NULL */
|
||||
p = str1;
|
||||
lp = ltbl;
|
||||
va_start(ap, str1);
|
||||
while (p) {
|
||||
*lp++ = l = strlen(p);
|
||||
s += l;
|
||||
p = va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
q = rslt = nasm_malloc(s);
|
||||
|
||||
p = str1;
|
||||
lp = ltbl;
|
||||
va_start(ap, str1);
|
||||
while (p) {
|
||||
l = *lp++;
|
||||
memcpy(q, p, l);
|
||||
q += l;
|
||||
p = va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
*q = '\0';
|
||||
|
||||
nasm_free(ltbl);
|
||||
|
||||
return rslt;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user