diff --git a/Android.mk b/Android.mk index 6555affb..f3c46b2a 100644 --- a/Android.mk +++ b/Android.mk @@ -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 \ diff --git a/aclocal.m4 b/aclocal.m4 index acb94821..fbc7f086 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -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_. +# +# The macro caches its result in the ax_cv_have_func_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 +# +# 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_. +# +# The macro caches its result in the ax_cv_have_var_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 +# +# 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]) +]) diff --git a/commandline.h b/commandline.h index e6979987..dd0b6532 100644 --- a/commandline.h +++ b/commandline.h @@ -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=]" @@ -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); diff --git a/conf_parse.c b/conf_parse.c index e7c1d7d1..4bbfd904 100644 --- a/conf_parse.c +++ b/conf_parse.c @@ -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; \ diff --git a/configure.in b/configure.in index 6f2209ae..4ecf7b98 100644 --- a/configure.in +++ b/configure.in @@ -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() diff --git a/console.c b/console.c index 872d842d..41c0540e 100644 --- a/console.c +++ b/console.c @@ -18,11 +18,11 @@ #include -#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{ diff --git a/constants.h b/constants.h index 408e8b89..1b44e39f 100644 --- a/constants.h +++ b/constants.h @@ -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 diff --git a/features.h b/features.h new file mode 100644 index 00000000..3d8fe44c --- /dev/null +++ b/features.h @@ -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 diff --git a/headerfiles.mk b/headerfiles.mk index 595f628d..c9610598 100644 --- a/headerfiles.mk +++ b/headerfiles.mk @@ -38,6 +38,7 @@ HDRS= fifo.h \ fdqueue.h \ http_server.h \ xprintf.h \ + features.h \ constants.h \ monitor-client.h \ mdp_client.h \ diff --git a/instance.h b/instance.h index 6b057fcc..06cc867b 100644 --- a/instance.h +++ b/instance.h @@ -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__) diff --git a/mem.h b/mem.h index c8439bc9..a06fb5f6 100644 --- a/mem.h +++ b/mem.h @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define __SERVAL_DNA__MEM_H #include +#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 */ -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 */ -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 */ -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 */ -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)) diff --git a/section.h b/section.h index eede5447..a0cdc3bd 100644 --- a/section.h +++ b/section.h @@ -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 diff --git a/serval.h b/serval.h index a67df4ff..b2018010 100644 --- a/serval.h +++ b/serval.h @@ -117,12 +117,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include +#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" diff --git a/sighandlers.c b/sighandlers.c index cc5d3665..c9098dbd 100644 --- a/sighandlers.c +++ b/sighandlers.c @@ -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" diff --git a/socket.h b/socket.h index 6b9d293b..51191361 100644 --- a/socket.h +++ b/socket.h @@ -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); diff --git a/strbuf.h b/strbuf.h index abdda550..1af4b985 100644 --- a/strbuf.h +++ b/strbuf.h @@ -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 */ -#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 */ -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. diff --git a/test_cli.c b/test_cli.c index 1aeaf933..09c4441f 100644 --- a/test_cli.c +++ b/test_cli.c @@ -25,10 +25,10 @@ #include #include +#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" diff --git a/xprintf.h b/xprintf.h index 5b046ce3..2e784a28 100644 --- a/xprintf.h +++ b/xprintf.h @@ -64,6 +64,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include +#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);