Fix broken clang and Android builds

Recent addition of the GCC __attribute__(alloc_size) to some functions
in mem.h broke the build when using Clang 3.5.  This commit introduces
configure-time checks for all GCC attributes used in the Serval source
code, and adapts accordingly.
This commit is contained in:
Andrew Bettison 2015-11-23 13:18:30 +10:30
parent 1d3a6abe61
commit e8e87b8a34
18 changed files with 524 additions and 73 deletions

View File

@ -21,6 +21,11 @@ SERVALD_LOCAL_CFLAGS = \
-DINSTANCE_PATH="\"/data/data/org.servalproject/var/serval-node\"" \
-DSHELL -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" \
-DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" \
-DHAVE_FUNC_ATTRIBUTE_ERROR=1 \
-DHAVE_FUNC_ATTRIBUTE_ALIGNED=1 -DHAVE_VAR_ATTRIBUTE_SECTION=1 -DHAVE_FUNC_ATTRIBUTE_USED=1 \
-DHAVE_FUNC_ATTRIBUTE_ALLOC_SIZE=1 -DHAVE_FUNC_ATTRIBUTE_MALLOC=1 \
-DHAVE_FUNC_ATTRIBUTE_FORMAT=1 \
-DHAVE_FUNC_ATTRIBUTE_USED=1 -DHAVE_FUNC_ATTRIBUTE_UNUSED=1 \
-DHAVE_LIBC=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 \
-DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 \
-DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDIO_H=1 \

372
aclocal.m4 vendored
View File

@ -743,3 +743,375 @@ else
$3
fi[]dnl
])# PKG_CHECK_MODULES
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
#
# DESCRIPTION
#
# This macro checks if the compiler supports one of GCC's function
# attributes; many other compilers also provide function attributes with
# the same syntax. Compiler warnings are used to detect supported
# attributes as unsupported ones are ignored by default so quieting
# warnings when using this macro will yield false positives.
#
# The ATTRIBUTE parameter holds the name of the attribute to be checked.
#
# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
#
# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
# variable.
#
# The macro currently supports the following function attributes:
#
# alias
# aligned
# alloc_size
# always_inline
# artificial
# cold
# const
# constructor
# constructor_priority for constructor attribute with priority
# deprecated
# destructor
# dllexport
# dllimport
# error
# externally_visible
# flatten
# format
# format_arg
# gnu_inline
# hot
# ifunc
# leaf
# malloc
# noclone
# noinline
# nonnull
# noreturn
# nothrow
# optimize
# pure
# returns_nonnull (added 23 Nov 2015, Serval Project)
# unused
# used
# visibility
# warning
# warn_unused_result
# weak
# weakref
#
# Unsuppored function attributes will be tested with a prototype returning
# an int and not accepting any arguments and the result of the check might
# be wrong or meaningless so use with care.
#
# LICENSE
#
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 3
AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([
m4_case([$1],
[alias], [
int foo( void ) { return 0; }
int bar( void ) __attribute__(($1("foo")));
],
[aligned], [
int foo( void ) __attribute__(($1(32)));
],
[alloc_size], [
void *foo(int a) __attribute__(($1(1)));
],
[always_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[artificial], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[cold], [
int foo( void ) __attribute__(($1));
],
[const], [
int foo( void ) __attribute__(($1));
],
[constructor_priority], [
int foo( void ) __attribute__((__constructor__(65535/2)));
],
[constructor], [
int foo( void ) __attribute__(($1));
],
[deprecated], [
int foo( void ) __attribute__(($1("")));
],
[destructor], [
int foo( void ) __attribute__(($1));
],
[dllexport], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[dllimport], [
int foo( void ) __attribute__(($1));
],
[error], [
int foo( void ) __attribute__(($1("")));
],
[externally_visible], [
int foo( void ) __attribute__(($1));
],
[flatten], [
int foo( void ) __attribute__(($1));
],
[format], [
int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
],
[format_arg], [
char *foo(const char *p) __attribute__(($1(1)));
],
[gnu_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[hot], [
int foo( void ) __attribute__(($1));
],
[ifunc], [
int my_foo( void ) { return 0; }
static int (*resolve_foo(void))(void) { return my_foo; }
int foo( void ) __attribute__(($1("resolve_foo")));
],
[leaf], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[malloc], [
void *foo( void ) __attribute__(($1));
],
[noclone], [
int foo( void ) __attribute__(($1));
],
[noinline], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[nonnull], [
int foo(char *p) __attribute__(($1(1)));
],
[noreturn], [
void foo( void ) __attribute__(($1));
],
[nothrow], [
int foo( void ) __attribute__(($1));
],
[optimize], [
__attribute__(($1(3))) int foo( void ) { return 0; }
],
[pure], [
int foo( void ) __attribute__(($1));
],
[returns_nonnull], [
char * foo( void ) __attribute__(($1));
],
[unused], [
int foo( void ) __attribute__(($1));
],
[used], [
int foo( void ) __attribute__(($1));
],
[visibility], [
int foo_def( void ) __attribute__(($1("default")));
int foo_hid( void ) __attribute__(($1("hidden")));
int foo_int( void ) __attribute__(($1("internal")));
int foo_pro( void ) __attribute__(($1("protected")));
],
[warning], [
int foo( void ) __attribute__(($1("")));
],
[warn_unused_result], [
int foo( void ) __attribute__(($1));
],
[weak], [
int foo( void ) __attribute__(($1));
],
[weakref], [
static int foo( void ) { return 0; }
static int bar( void ) __attribute__(($1("foo")));
],
[
m4_warn([syntax], [Unsupported attribute $1, the test may fail])
int foo( void ) __attribute__(($1));
]
)], [])
],
dnl GCC doesn't exit with an error if an unknown attribute is
dnl provided but only outputs a warning, so accept the attribute
dnl only if no warning were issued.
[AS_IF([test -s conftest.err],
[AS_VAR_SET([ac_var], [no])],
[AS_VAR_SET([ac_var], [yes])])],
[AS_VAR_SET([ac_var], [no])])
])
AS_IF([test yes = AS_VAR_GET([ac_var])],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
[Define to 1 if the system has the `$1' function attribute])], [])
AS_VAR_POPDEF([ac_var])
])
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_gcc_var_attribute.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_VAR_ATTRIBUTE(ATTRIBUTE)
#
# DESCRIPTION
#
# This macro checks if the compiler supports one of GCC's variable
# attributes; many other compilers also provide variable attributes with
# the same syntax. Compiler warnings are used to detect supported
# attributes as unsupported ones are ignored by default so quieting
# warnings when using this macro will yield false positives.
#
# The ATTRIBUTE parameter holds the name of the attribute to be checked.
#
# If ATTRIBUTE is supported define HAVE_VAR_ATTRIBUTE_<ATTRIBUTE>.
#
# The macro caches its result in the ax_cv_have_var_attribute_<attribute>
# variable.
#
# The macro currently supports the following variable attributes:
#
# aligned
# cleanup
# common
# nocommon
# deprecated
# mode
# packed
# section (added 23 Nov 2015, Serval Project)
# tls_model
# unused
# used
# vector_size
# weak
# dllimport
# dllexport
# init_priority
#
# Unsuppored variable attributes will be tested against a global integer
# variable and without any arguments given to the attribute itself; the
# result of this check might be wrong or meaningless so use with care.
#
# LICENSE
#
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 3
AC_DEFUN([AX_GCC_VAR_ATTRIBUTE], [
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_var_attribute_$1])
AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([
m4_case([$1],
[aligned], [
int foo __attribute__(($1(32)));
],
[cleanup], [
int bar(int *t) { return *t; };
],
[common], [
int foo __attribute__(($1));
],
[nocommon], [
int foo __attribute__(($1));
],
[deprecated], [
int foo __attribute__(($1)) = 0;
],
[mode], [
long foo __attribute__(($1(word)));
],
[packed], [
struct bar {
int baz __attribute__(($1));
};
],
[section], [
int foo __attribute__(($1("a"))) = 0;
],
[tls_model], [
__thread int bar1 __attribute__(($1("global-dynamic")));
__thread int bar2 __attribute__(($1("local-dynamic")));
__thread int bar3 __attribute__(($1("initial-exec")));
__thread int bar4 __attribute__(($1("local-exec")));
],
[unused], [
int foo __attribute__(($1));
],
[used], [
int foo __attribute__(($1));
],
[vector_size], [
int foo __attribute__(($1(16)));
],
[weak], [
int foo __attribute__(($1));
],
[dllimport], [
int foo __attribute__(($1));
],
[dllexport], [
int foo __attribute__(($1));
],
[init_priority], [
struct bar { bar() {} ~bar() {} };
bar b __attribute__(($1(65535/2)));
],
[
m4_warn([syntax], [Unsupported attribute $1, the test may fail])
int foo __attribute__(($1));
]
)], [
m4_case([$1],
[cleanup], [
int foo __attribute__(($1(bar))) = 0;
foo = foo + 1;
],
[]
)])
],
dnl GCC doesn't exit with an error if an unknown attribute is
dnl provided but only outputs a warning, so accept the attribute
dnl only if no warning were issued.
[AS_IF([test -s conftest.err],
[AS_VAR_SET([ac_var], [no])],
[AS_VAR_SET([ac_var], [yes])])],
[AS_VAR_SET([ac_var], [no])])
])
AS_IF([test yes = AS_VAR_GET([ac_var])],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_VAR_ATTRIBUTE_$1), 1,
[Define to 1 if the system has the `$1' variable attribute])], [])
AS_VAR_POPDEF([ac_var])
])

View File

@ -19,6 +19,7 @@
#ifndef __SERVAL_DNA__COMMANDLINE_H
#define __SERVAL_DNA__COMMANDLINE_H
#include "features.h"
#include "section.h"
#define KEYRING_PIN_OPTION ,"[--keyring-pin=<pin>]"
@ -48,7 +49,7 @@ DECLARE_SECTION(struct cli_schema, commands);
void cli_flush(struct cli_context *context);
int cli_delim(struct cli_context *context, const char *opt);
int cli_puts(struct cli_context *context, const char *str);
void cli_printf(struct cli_context *context, const char *fmt, ...) __attribute__ (( format(printf,2,3) ));
void cli_printf(struct cli_context *context, const char *fmt, ...) __attribute__ (( __ATTRIBUTE_format(printf,2,3) ));
void cli_columns(struct cli_context *context, int columns, const char *names[]);
void cli_row_count(struct cli_context *context, int rows);
void cli_field_name(struct cli_context *context, const char *name, const char *delim);

View File

@ -46,7 +46,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
return CFOK; \
}
#define STRUCT_ASSIGN(__substructname, __structname) \
__attribute__((unused)) static void __cf_unused_1_##__substructname(struct config_##__substructname *s) {
__attribute__((__ATTRIBUTE_unused)) static void __cf_unused_1_##__substructname(struct config_##__substructname *s) {
#define END_STRUCT_ASSIGN \
}
#define STRUCT_DEFAULT(__name, __dfllabel) \
@ -106,7 +106,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// Generate config assign function definitions, cf_cpy_config_NAME().
#define VALIDATOR(__validator)
#define STRUCT(__name, __options...) \
__attribute__((unused)) static void __cf_unused_2_##__name(struct config_##__name *dst, const struct config_##__name *src) {
__attribute__((__ATTRIBUTE_unused)) static void __cf_unused_2_##__name(struct config_##__name *dst, const struct config_##__name *src) {
#define END_STRUCT \
}
#define STRUCT_ASSIGN(__substructname, __structname) \
@ -240,7 +240,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
return result; \
}
#define STRUCT_ASSIGN(__substructname, __structname) \
__attribute__((unused)) static int __cf_unused_3_##__substructname(struct config_##__substructname *strct, const struct cf_om_node *node) { \
__attribute__((__ATTRIBUTE_unused)) static int __cf_unused_3_##__substructname(struct config_##__substructname *strct, const struct cf_om_node *node) { \
int result = 0; \
char used[0];
#define END_STRUCT_ASSIGN \
@ -462,7 +462,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
return 0; \
}
#define STRUCT_ASSIGN(__substructname, __structname) \
__attribute__((unused)) static int __cf_unused_4_##__substructname(struct cf_om_node **rootp) { \
__attribute__((__ATTRIBUTE_unused)) static int __cf_unused_4_##__substructname(struct cf_om_node **rootp) { \
int i; \
struct cf_om_node **childp;
#define END_STRUCT_ASSIGN \
@ -625,7 +625,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
return result; \
}
#define STRUCT_ASSIGN(__substructname, __structname) \
__attribute__((unused)) static int __cf_unused_5_##__substructname(struct cf_om_node **parentp, const struct config_##__substructname *strct, const struct config_##__substructname *dflt) { \
__attribute__((__ATTRIBUTE_unused)) static int __cf_unused_5_##__substructname(struct cf_om_node **parentp, const struct config_##__substructname *strct, const struct config_##__substructname *dflt) { \
int result = 0; \
int ret;
#define END_STRUCT_ASSIGN \
@ -764,7 +764,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
return 0; \
}
#define STRUCT_ASSIGN(__substructname, __structname) \
__attribute__((unused)) static int __cf__unused_6_##__substructname(const struct config_##__substructname *a, const struct config_##__substructname *b) { \
__attribute__((__ATTRIBUTE_unused)) static int __cf__unused_6_##__substructname(const struct config_##__substructname *a, const struct config_##__substructname *b) { \
int c;
#define END_STRUCT_ASSIGN \
return 0; \

View File

@ -7,6 +7,16 @@ CPPFLAGS=-D_GNU_SOURCE
dnl Set $host_os, which is needed by javac detection.
AC_CANONICAL_SYSTEM
dnl Various GCC function and variable attributes
AX_GCC_FUNC_ATTRIBUTE(aligned)
AX_GCC_FUNC_ATTRIBUTE(alloc_size)
AX_GCC_FUNC_ATTRIBUTE(error)
AX_GCC_FUNC_ATTRIBUTE(format)
AX_GCC_FUNC_ATTRIBUTE(malloc)
AX_GCC_FUNC_ATTRIBUTE(unused)
AX_GCC_FUNC_ATTRIBUTE(used)
AX_GCC_VAR_ATTRIBUTE(section)
dnl Init pkg-config
PKG_PROG_PKG_CONFIG()

View File

@ -18,11 +18,11 @@
#include <stdio.h>
#include "fdqueue.h"
#include "str.h"
#include "cli.h"
#include "net.h"
#include "mem.h"
#include "net.h"
#include "str.h"
#include "fdqueue.h"
#include "console.h"
struct command_state{

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2012 Serval Project Inc.
Copyright (C) 2012-2015 Serval Project Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -19,22 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef __SERVAL_DNA__CONSTANTS_H
#define __SERVAL_DNA__CONSTANTS_H
/* Useful macros not specific to Serval DNA
*/
// Number of elements in an array (Warning: does not work if A is a pointer!).
#define NELS(A) (sizeof (A) / sizeof *(A))
// To suppress the "unused parameter" warning from -Wunused-parameter.
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if (defined(__GNUC__)) || __has_attribute(unused)
#define UNUSED(x) x __attribute__((__unused__))
#else
#define UNUSED(x) x
#endif
// UDP Port numbers for various Serval services.
#define PORT_DNA 4110

63
features.h Normal file
View File

@ -0,0 +1,63 @@
/*
Copyright (C) 2015 Serval Project Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __SERVAL_DNA__FEATURES_H
#define __SERVAL_DNA__FEATURES_H
/* Useful macros not specific to Serval DNA
*/
// Number of elements in an array (Warning: does not work if A is a pointer!).
#define NELS(A) (sizeof (A) / sizeof *(A))
// Support for various GCC attributes.
#ifdef HAVE_FUNC_ATTRIBUTE_ERROR
# define __ATTRIBUTE_error(m) __error__(m)
#else
# define __ATTRIBUTE_error(m)
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT
# define __ATTRIBUTE_format(a,b,c) __format__(a,b,c)
#else
# define __ATTRIBUTE_format(a,b,c)
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
# define __ATTRIBUTE_malloc __malloc__
#else
# define __ATTRIBUTE_malloc
#endif
#ifdef HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE
# define __ATTRIBUTE_alloc_size(n) __alloc_size__(n)
#else
# define __ATTRIBUTE_alloc_size(n)
#endif
// To suppress the "unused parameter" warning from -Wunused-parameter.
#ifdef HAVE_FUNC_ATTRIBUTE_UNUSED
# define __ATTRIBUTE_unused __unused__
# define UNUSED(x) x __attribute__((__unused__))
#else
# define __ATTRIBUTE_unused
# define UNUSED(x) x
#endif
#endif // __SERVAL_DNA__FEATURES_H

View File

@ -38,6 +38,7 @@ HDRS= fifo.h \
fdqueue.h \
http_server.h \
xprintf.h \
features.h \
constants.h \
monitor-client.h \
mdp_client.h \

View File

@ -20,19 +20,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef __SERVAL_DNA__INSTANCE_H
#define __SERVAL_DNA__INSTANCE_H
#include "features.h"
#include "whence.h"
#include "strbuf.h"
const char *instance_path(); // returns NULL if not using an instance path
int create_serval_instance_dir();
int _formf_serval_etc_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
int _formf_serval_run_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
int _formf_serval_etc_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((__ATTRIBUTE_format(printf,4,5)));
int _formf_serval_run_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((__ATTRIBUTE_format(printf,4,5)));
int _vformf_serval_run_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, va_list);
int _formf_serval_cache_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
int _formf_serval_tmp_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
int _formf_servald_proc_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
int _formf_rhizome_store_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((format(printf,4,5)));
int _formf_serval_cache_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((__ATTRIBUTE_format(printf,4,5)));
int _formf_serval_tmp_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((__ATTRIBUTE_format(printf,4,5)));
int _formf_servald_proc_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((__ATTRIBUTE_format(printf,4,5)));
int _formf_rhizome_store_path(struct __sourceloc, char *buf, size_t bufsiz, const char *fmt, ...) __attribute__((__ATTRIBUTE_format(printf,4,5)));
#define formf_serval_etc_path(buf,bufsz,fmt,...) _formf_serval_etc_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)
#define formf_serval_run_path(buf,bufsz,fmt,...) _formf_serval_run_path(__WHENCE__, buf, bufsz, fmt, ##__VA_ARGS__)

15
mem.h
View File

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define __SERVAL_DNA__MEM_H
#include <sys/types.h>
#include "features.h"
#include "log.h"
// #define MALLOC_PARANOIA
@ -29,8 +30,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define malloc(X) _serval_debug_malloc(X,__WHENCE__)
#define calloc(X,Y) _serval_debug_calloc(X,Y,__WHENCE__)
#define free(X) _serval_debug_free(X,__WHENCE__)
void *_serval_debug_malloc(unsigned int bytes, struct __sourceloc whence) __attribute__ ((malloc, alloc_size(1)));
void *_serval_debug_calloc(unsigned int bytes, unsigned int count, struct __sourceloc whence) __attribute__ ((malloc, alloc_size(1)));
void *_serval_debug_malloc(unsigned int bytes, struct __sourceloc whence) __attribute__ ((__ATTRIBUTE_malloc, __ATTRIBUTE_alloc_size(1)));
void *_serval_debug_calloc(unsigned int bytes, unsigned int count, struct __sourceloc whence) __attribute__ ((__ATTRIBUTE_malloc, __ATTRIBUTE_alloc_size(1)));
void _serval_debug_free(void *p, struct __sourceloc whence);
#endif
@ -38,20 +39,20 @@ void _serval_debug_free(void *p, struct __sourceloc whence);
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
void *_emalloc(struct __sourceloc, size_t bytes) __attribute__ ((malloc, alloc_size(2)));
void *_emalloc(struct __sourceloc, size_t bytes) __attribute__ ((__ATTRIBUTE_malloc, __ATTRIBUTE_alloc_size(2)));
/* Equivalent to realloc(3), but logs an error before returning NULL.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
void *_erealloc(struct __sourceloc __whence, void *ptr, size_t bytes) __attribute__ ((alloc_size(3)));
void *_erealloc(struct __sourceloc __whence, void *ptr, size_t bytes) __attribute__ ((__ATTRIBUTE_alloc_size(3)));
/* Equivalent to malloc(3) followed by memset(3) to zerofill, but logs an error
* before returning NULL.
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
void *_emalloc_zero(struct __sourceloc, size_t bytes) __attribute__ ((malloc, alloc_size(2)));
void *_emalloc_zero(struct __sourceloc, size_t bytes) __attribute__ ((__ATTRIBUTE_malloc, __ATTRIBUTE_alloc_size(2)));
/* Equivalent to strdup(3)/strndup(3), but logs an error before returning NULL.
*
@ -60,8 +61,8 @@ void *_emalloc_zero(struct __sourceloc, size_t bytes) __attribute__ ((malloc, al
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
char *_str_edup(struct __sourceloc, const char *str) __attribute__ ((malloc));
char *_strn_edup(struct __sourceloc, const char *str, size_t len) __attribute__ ((malloc));
char *_str_edup(struct __sourceloc, const char *str) __attribute__ ((__ATTRIBUTE_malloc));
char *_strn_edup(struct __sourceloc, const char *str, size_t len) __attribute__ ((__ATTRIBUTE_malloc));
#define emalloc(bytes) _emalloc(__HERE__, (bytes))
#define erealloc(ptr, bytes) _erealloc(__HERE__, (ptr), (bytes))

View File

@ -25,21 +25,29 @@
#define SECTION_START(X) __start_##X
#define SECTION_END(X) __stop_##X
#ifdef __APPLE__
#define _SECTION_ATTRIBUTE(X) section("__DATA,__"#X)
#define DECLARE_SECTION(TYPE, X) \
extern TYPE SECTION_START(X)[] __asm("section$start$__DATA$__" #X);\
extern TYPE SECTION_END(X)[] __asm("section$end$__DATA$__" #X)
#else
#define _SECTION_ATTRIBUTE(X) section(#X)
#define DECLARE_SECTION(TYPE, X) \
extern TYPE SECTION_START(X)[];\
extern TYPE SECTION_END(X)[]
#ifndef HAVE_VAR_ATTRIBUTE_SECTION
#error "Compiler does not support __attribute__(section())"
#endif
#ifndef HAVE_FUNC_ATTRIBUTE_ALIGNED
#error "Compiler does not support __attribute__(aligned())"
#endif
#ifndef HAVE_FUNC_ATTRIBUTE_USED
#error "Compiler does not support __attribute__(used)"
#endif
#ifdef __APPLE__
# define _SECTION_ATTRIBUTE(X) __section__("__DATA,__"#X)
# define DECLARE_SECTION(TYPE, X) \
extern TYPE SECTION_START(X)[] __asm("section$start$__DATA$__" #X);\
extern TYPE SECTION_END(X)[] __asm("section$end$__DATA$__" #X)
#else // !__APPLE__
# define _SECTION_ATTRIBUTE(X) __section__(#X)
# define DECLARE_SECTION(TYPE, X) \
extern TYPE SECTION_START(X)[];\
extern TYPE SECTION_END(X)[]
#endif // !__APPLE__
#define IN_SECTION(name) __attribute__((used,aligned(sizeof(void *)),_SECTION_ATTRIBUTE(name)))
#define IN_SECTION(name) __attribute__((__used__, __aligned__(sizeof(void *)), _SECTION_ATTRIBUTE(name)))
#endif // __SERVAL_DNA__SECTION_H

View File

@ -117,12 +117,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <fcntl.h>
#include <sys/stat.h>
#include "constants.h"
#include "cli.h"
#include "serval_types.h"
#include "sighandlers.h"
#include "instance.h"
#include "fdqueue.h"
#include "constants.h"
#include "mem.h"
#include "xprintf.h"
#include "log.h"

View File

@ -18,6 +18,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "features.h"
#include "constants.h"
#include "sighandlers.h"

View File

@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# endif
#endif
#include "features.h"
#include "whence.h"
struct socket_address{
@ -48,7 +49,7 @@ struct socket_address{
/* Basic socket operations.
*/
int _make_local_sockaddr(struct __sourceloc, struct socket_address *addr, const char *fmt, ...)
__attribute__((format(printf, 3, 4)));
__attribute__((__ATTRIBUTE_format(printf, 3, 4)));
int _esocket(struct __sourceloc, int domain, int type, int protocol);
int _socket_bind(struct __sourceloc, int sock, const struct socket_address *addr);
int _socket_connect(struct __sourceloc, int sock, const struct socket_address *addr);

View File

@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef __STRBUF_H__
#define __STRBUF_H__
#include "features.h"
/**
A strbuf provides a convenient set of primitives for assembling a
nul-terminated string in a fixed-size, caller-provided backing buffer,
@ -277,25 +279,25 @@ typedef const struct strbuf *const_strbuf;
* buffer pointed to by p were less than 8 in size, then appending to strbuf b
* would cause memory corruption and a likely SIGSEGV.
*
* If compiled with the GNU C compiler, then the above example would result in
* an error at compile time.
* If compiled with the GNU C compiler (or equivalent, like Clang), then the
* above example would produce a build error (see below). However, if the
* compiler does not support __attribute__((alloc_size(n)) (such as Clang 3.5),
* then the check is not performed, because it would also cause errors for
* perfectly legitimate uses, eg, strbuf_local_buf(a->buf).
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
#ifdef __GNUC__
#define strbuf_local_buf(buf) strbuf_local((char*)(buf), (sizeof(buf) == __builtin_object_size(buf, 1)) ? sizeof(buf) : __buffer_arg_is_not_array())
#if defined(__GNUC__) && defined(HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE)
# define strbuf_local_buf(buf) strbuf_local((char*)(buf), (sizeof(buf) == __builtin_object_size(buf, 1)) ? sizeof(buf) : __buffer_arg_is_not_array())
// If the following error occurs at compile time or this function is not
// resolved at link time, it means that the argument to strbuf_local_buf()
// was not an array whose size is known at compile time. The most common
// cause of this is passing a pointer as the argument. The solution is to
// use strbuf_local(b, len) instead of strbuf_local_buf(b), and supply the
// length of the buffer explicitly.
size_t __buffer_arg_is_not_array() __attribute__ ((__ATTRIBUTE_error("argument to strbuf_local_buf() must be an array not a pointer")));
#else
#define strbuf_local_buf(buf) strbuf_local((char*)(buf), sizeof(buf))
#endif
#ifdef __GNUC__
// If the following error occurs at compile time or this function is not found
// at link time, it means that the argument passed to strbuf_local_buf() was
// not an array whose size is known at compile time. The most common cause of
// this is passing a pointer as the argument. The solution is to use
// strbuf_local(b, len) instead of strbuf_local_buf(b), and supply the length
// of the buffer explicitly.
size_t __buffer_arg_is_not_array() __attribute__ ((error("argument to strbuf_local_buf() must be an array not a pointer")));
# define strbuf_local_buf(buf) strbuf_local((char*)(buf), sizeof(buf))
#endif
/** Initialise a strbuf with a caller-supplied backing buffer. The current
@ -452,7 +454,7 @@ strbuf strbuf_putc(strbuf sb, char ch);
*
* @author Andrew Bettison <andrew@servalproject.com>
*/
strbuf strbuf_sprintf(strbuf sb, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
strbuf strbuf_sprintf(strbuf sb, const char *fmt, ...) __attribute__((__ATTRIBUTE_format(printf, 2, 3)));
strbuf strbuf_vsprintf(strbuf sb, const char *fmt, va_list ap);
/** Return a pointer to the current nul-terminated string in the strbuf.

View File

@ -25,10 +25,10 @@
#include <poll.h>
#include <sys/stat.h>
#include "cli.h"
#include "serval_types.h"
#include "dataformats.h"
#include "os.h"
#include "cli.h"
#include "conf.h"
#include "commandline.h"
#include "mem.h"

View File

@ -64,6 +64,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <stdarg.h>
#include <unistd.h>
#include "features.h"
typedef void CONTEXT_VPRINTF(void *context, const char *fmt, va_list);
typedef struct _xprintf {
@ -73,8 +75,7 @@ typedef struct _xprintf {
#define _XPRINTF(F,C) ((XPRINTF){(F),(C)})
void xprintf(XPRINTF xpf, const char *fmt, ...)
__attribute__ (( format(printf,2,3) ));
void xprintf(XPRINTF xpf, const char *fmt, ...) __attribute__ ((__ATTRIBUTE_format(printf,2,3)));
;
void vxprintf(XPRINTF xpf, const char *fmt, va_list);
void xputs(const char *str, XPRINTF xpf);