diff --git a/Makefile.am b/Makefile.am index e768b53..c480e09 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,8 +7,9 @@ dist_doc_DATA = COPYING NEWS README EXTRA_DIST = \ autogen.sh \ - m4/ccflags.m4 m4/libshout.m4 m4/libvorbis.m4 m4/libxml2.m4 \ - m4/progname.m4 m4/taglib.m4 m4/tree.m4 m4/vacopy.m4 m4/vars.m4 + m4/attribute.m4 m4/ccflags.m4 m4/libshout.m4 m4/libvorbis.m4 \ + m4/libxml2.m4 m4/progname.m4 m4/taglib.m4 m4/tree.m4 m4/vacopy.m4 \ + m4/vars.m4 CLEANFILES = core *.core *~ .*~ diff --git a/configure.ac b/configure.ac index d7157a3..31e671b 100644 --- a/configure.ac +++ b/configure.ac @@ -81,6 +81,30 @@ else esac fi +have_attributes=no +CFG_ATTRIBUTE_UNUSED=0 +AX_FUNC_ATTRIBUTE_UNUSED([ + CFG_ATTRIBUTE_UNUSED=1 + have_attributes=yes +], []) +AC_SUBST([CFG_ATTRIBUTE_UNUSED]) + +CFG_HAVE_ATTRIBUTES=0 +CFG_ATTRIBUTE_FORMAT=0 +CFG_ATTRIBUTE_NONNULL=0 +if test x"${have_attributes}" = "xyes"; then + CFG_HAVE_ATTRIBUTES=1 + AX_FUNC_ATTRIBUTE([const char *a, ...], + [format], [(printf, 1, 2)], + [CFG_ATTRIBUTE_FORMAT=1], []) + AX_FUNC_ATTRIBUTE([const char *a], + [nonnull], [(1)], + [CFG_ATTRIBUTE_NONNULL=1], []) +fi +AC_SUBST([CFG_HAVE_ATTRIBUTES]) +AC_SUBST([CFG_ATTRIBUTE_FORMAT]) +AC_SUBST([CFG_ATTRIBUTE_NONNULL]) + AC_C_CONST AC_C_VOLATILE @@ -268,6 +292,7 @@ AC_CONFIG_FILES([ examples/Makefile m4/Makefile src/Makefile + src/attr_config.h src/ezstream-file.sh ]) diff --git a/m4/attribute.m4 b/m4/attribute.m4 new file mode 100644 index 0000000..eb4d7ff --- /dev/null +++ b/m4/attribute.m4 @@ -0,0 +1,113 @@ +dnl # $Id$ + +dnl # Check if the compiler understands a certain __attribute__. + + +dnl # Copyright (c) 2008 Moritz Grimm <mgrimm@mrsserver.net> +dnl # +dnl # Permission to use, copy, modify, and distribute this software for any +dnl # purpose with or without fee is hereby granted, provided that the above +dnl # copyright notice and this permission notice appear in all copies. +dnl # +dnl # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +dnl # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +dnl # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +dnl # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +dnl # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +dnl # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +dnl # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +dnl # AX_FUNC_ATTRIBUTE([FUNC-SIGNATURE], [ATTRIBUTE], [ARGS], +dnl # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) + +dnl # AX_FUNC_ATTRIBUTE_UNUSED([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) + + +AC_DEFUN([AX_FUNC_ATTRIBUTE], +[ +AC_REQUIRE([AX_CHECK_ERROR_FLAG]) +if test x"${local_cv_prog_cc_error_flag}" != "xno"; then + _errflag="${local_cv_prog_cc_error_flag}" +else + _errflag="" +fi +AC_MSG_CHECKING([if __attribute__((__$2__$3)) is supported]) +_cv_sufx_=$(echo "$3" | sed 'y|-+,=() |_p_____|') +AC_CACHE_VAL([local_cv_prog_cc_attr_$2_${_cv_sufx}], +[ + AC_LANG_PUSH([C]) + save_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} ${_errflag}" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #ifdef HAVE_SYS_TYPES_H + # include <sys/types.h> + #endif + #include <stdlib.h> + void * attrtest($1) + __attribute__((__$2__$3)); + void * + attrtest($1) { return(NULL); } + ]], + [[]])], + [eval "local_cv_prog_cc_attr_$2_${_cv_sufx_}=yes"], + [eval "local_cv_prog_cc_attr_$2_${_cv_sufx_}=no"]) + CFLAGS="${save_CFLAGS}" + AC_LANG_POP([C]) +]) +eval "_cache_val_=\${local_cv_prog_cc_attr_$2_${_cv_sufx_}}" +if test x"${_cache_val_}" = "xyes"; then + AC_MSG_RESULT([yes]) + : + $4 +else + AC_MSG_RESULT([no]) + : + $5 +fi +]) + + +AC_DEFUN([AX_FUNC_ATTRIBUTE_UNUSED], +[ +AC_REQUIRE([AX_CHECK_ERROR_FLAG]) +if test x"${local_cv_prog_cc_error_flag}" != "xno"; then + _errflag="${local_cv_prog_cc_error_flag}" +else + _errflag="" +fi +AC_MSG_CHECKING([if __attribute__((unused)) is supported]) +AC_CACHE_VAL([local_cv_proc_cc_attr_unused], +[ + AC_LANG_PUSH([C]) + save_CFLAGS="${CFLAGS}" + CFLAGS="${CFLAGS} ${_errflag}" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + void attrtest(void) + __attribute__((unused)); + void + attrtest(void) {} + ]], + [[ + int attrtest_var + __attribute__((unused)); + ]])], + [local_cv_proc_cc_attr_unused=yes], + [local_cv_proc_cc_attr_unused=no]) + CFLAGS="${save_CFLAGS}" + AC_LANG_POP([C]) +]) +if test x"${local_cv_proc_cc_attr_unused}" = "xyes"; then + AC_MSG_RESULT([yes]) + : + $1 +else + AC_MSG_RESULT([no]) + : + $2 +fi +]) diff --git a/src/Makefile.am b/src/Makefile.am index d2ffbfa..cb7ca6d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,6 +4,7 @@ bin_PROGRAMS = ezstream bin_SCRIPTS = ezstream-file.sh noinst_HEADERS = \ + attributes.h \ cfg.h \ configfile.h \ ezstream.h \ diff --git a/src/attr_config.h.in b/src/attr_config.h.in new file mode 100644 index 0000000..576191d --- /dev/null +++ b/src/attr_config.h.in @@ -0,0 +1,20 @@ +#ifndef __ATTR_CONFIG_H__ +#define __ATTR_CONFIG_H__ + +#ifndef CFG_HAVE_ATTRIBUTES +# define CFG_HAVE_ATTRIBUTES @CFG_HAVE_ATTRIBUTES@ +#endif /* !CFG_HAVE_ATTRIBUTES */ + +#ifndef CFG_ATTRIBUTE_UNUSED +# define CFG_ATTRIBUTE_UNUSED @CFG_ATTRIBUTE_UNUSED@ +#endif /* !CFG_ATTRIBUTE_UNUSED */ + +#ifndef CFG_ATTRIBUTE_FORMAT +# define CFG_ATTRIBUTE_FORMAT @CFG_ATTRIBUTE_FORMAT@ +#endif /* !CFG_ATTRIBUTE_FORMAT */ + +#ifndef CFG_ATTRIBUTE_NONNULL +# define CFG_ATTRIBUTE_NONNULL @CFG_ATTRIBUTE_NONNULL@ +#endif /* !CFG_ATTRIBUTE_NONNULL */ + +#endif /* __ATTR_CONFIG_H__ */ diff --git a/src/attributes.h b/src/attributes.h new file mode 100644 index 0000000..98ceef5 --- /dev/null +++ b/src/attributes.h @@ -0,0 +1,45 @@ +#ifndef __ATTRIBUTES_H__ +#define __ATTRIBUTES_H__ + +#include "attr_config.h" + +#if defined(CFG_HAVE_ATTRIBUTES) && 1 == CFG_HAVE_ATTRIBUTES + /* nothing */ +#else +# define __attribute__(x) \ + /* nothing, e.g. for sys/tree.h */ +#endif /* CFG_HAVE_ATTRIBUTES */ + +#if defined(CFG_ATTRIBUTE_UNUSED) && 1 == CFG_ATTRIBUTE_UNUSED +# define ATTRIBUTE_UNUSED() \ + __attribute__((unused)) +#else +# define ATTRIBUTE_UNUSED() \ + /* nothing */ +#endif /* CFG_ATTRIBUTE_UNUSED */ + +#if defined(CFG_ATTRIBUTE_FORMAT) && 1 == CFG_ATTRIBUTE_FORMAT +# define ATTRIBUTE_FORMAT(t, n, m) \ + __attribute__((__format__(t, (n), (m)))) +#else +# define ATTRIBUTE_FORMAT(t, n, m) \ + /* nothing */ +#endif /* CFG_ATTRIBUTE_FORMAT */ + +#if defined(CFG_ATTRIBUTE_NONNULL) && 1 == CFG_ATTRIBUTE_NONNULL +# define ATTRIBUTE_NONNULL(n) \ + __attribute__((__nonnull__(n))) +# define ATTRIBUTE_NONNULL_2(n, m) \ + __attribute__((__nonnull__(n, m))) +# define ATTRIBUTE_NONNULL_3(n, m, o) \ + __attribute__((__nonnull__(n, m, o))) +#else +# define ATTRIBUTE_NONNULL(n) \ + /* nothing */ +# define ATTRIBUTE_NONNULL_2(n, m) \ + /* nothing */ +# define ATTRIBUTE_NONNULL_3(n, m, o) \ + /* nothing */ +#endif /* CFG_ATTRIBUTE_NONNULL */ + +#endif /* __ATTRIBUTES_H__ */