summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Camera <skonfig@dtnr.ch>2022-08-25 22:15:36 +0200
committerDennis Camera <skonfig@dtnr.ch>2022-08-25 22:15:36 +0200
commita62828595b9865a13cdc9b4adba3e3aaa9bc8e73 (patch)
tree837e8fd58dea93d0a84414e9807ecd5b4b33ac91
parentd73af9d8e436f36b612869422291caeb3239c758 (diff)
downloadskonfig-c-a62828595b9865a13cdc9b4adba3e3aaa9bc8e73.tar.gz
skonfig-c-a62828595b9865a13cdc9b4adba3e3aaa9bc8e73.zip
Enable more __attribute__s
-rw-r--r--configure.ac40
-rw-r--r--src/config.h26
-rw-r--r--src/log.h8
-rw-r--r--src/rexec.c1
-rw-r--r--src/skonfig.c3
-rw-r--r--src/util/envp.c10
-rw-r--r--src/util/envp.h23
-rw-r--r--src/util/string.h15
8 files changed, 97 insertions, 29 deletions
diff --git a/configure.ac b/configure.ac
index 650fc91..ed42e9f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,9 +91,49 @@ then
then
_sk_printf='SK_ATTRIBUTE(format (printf, i, j))'
fi
+
+ AX_GCC_FUNC_ATTRIBUTE([malloc])
+ if test x"${ax_cv_have_func_attribute_malloc}" = x'yes'
+ then
+ _sk_malloc='SK_ATTRIBUTE(malloc)'
+ _sk_malloc_free='SK_ATTRIBUTE(malloc, malloc (f, i))'
+ fi
+
+ AX_GCC_FUNC_ATTRIBUTE([nonnull])
+ if test x"${ax_cv_have_func_attribute_nonnull}" = x'yes'
+ then
+ _sk_nonnull='SK_ATTRIBUTE(nonnull (__VA_ARGS__))'
+ _sk_cc_nonnull_check=1
+ fi
+
+ AX_GCC_FUNC_ATTRIBUTE([returns_nonnull])
+ if test x"${ax_cv_have_func_attribute_returns_nonnull}" = x'yes'
+ then
+ _sk_returns_nonnull='SK_ATTRIBUTE(returns_nonnull)'
+ fi
+
+ AX_GCC_FUNC_ATTRIBUTE([sentinel])
+ if test x"${ax_cv_have_func_attribute_sentinel}" = x'yes'
+ then
+ _sk_sentinel='SK_ATTRIBUTE(sentinel(i))'
+ fi
+
+ AX_GCC_FUNC_ATTRIBUTE([warn_unused_result])
+ if test x"${ax_cv_have_func_attribute_warn_unused_result}" = x'yes'
+ then
+ _sk_warn_unused_result='SK_ATTRIBUTE(warn_unused_result)'
+ fi
fi
AC_DEFINE_UNQUOTED([SK_ATTRIBUTE(...)], [${_sk_attribute:-/* attribute(x) */}], [Define to the compiler name of its __attribute__])
AC_DEFINE_UNQUOTED([SK_PRINTF(i, j)], [${_sk_printf:-/* format(printf, i, j) */}], [Define to a code snippet your compiler uses for __attribute__ (format)])
+AC_DEFINE_UNQUOTED([SK_MALLOC], [${_sk_malloc:-/* malloc */}], [...])
+AC_DEFINE_UNQUOTED([SK_MALLOC_FREE(f, i)], [${_sk_malloc_free:-/* malloc (f, i) */}], [...])
+AC_DEFINE_UNQUOTED([SK_NONNULL(...)], [${_sk_nonnull:-/* nonnull(__VA_ARGS__) */}], [...])
+AC_DEFINE_UNQUOTED([SK_RETURNS_NONNULL], [${_sk_returns_nonnull:-/* returns_nonnull */}], [...])
+AC_DEFINE_UNQUOTED([SK_SENTINEL(i)], [${_sk_sentinel:-/* sentinel */}], [...])
+AC_DEFINE_UNQUOTED([SK_WARN_UNUSED_RESULT], [${_sk_warn_unused_result:-/* warn_unused_result */}], [...])
+
+AC_DEFINE_UNQUOTED([HAVE_CC_NONNULL_CHECK], $((_sk_cc_nonnull_check)), [Define to 1 if the CC supports __attribute__(nonnull)])
# Checks for libraries.
diff --git a/src/config.h b/src/config.h
index f6dbcf5..3e941a5 100644
--- a/src/config.h
+++ b/src/config.h
@@ -53,6 +53,12 @@ struct sk_config {
struct sk_config_global global;
};
+
+#if HAVE_FUNC_ATTRIBUTE_MALLOC
+/* pre-declare free function for SK_MALLOC_FREE(sk_config_free) */
+extern void sk_config_free(struct sk_config *);
+#endif
+
/* type conversion functions */
/**
@@ -74,7 +80,7 @@ const char *sk_archiving_mode_to_string(enum sk_archiving_mode a);
* @param s: the string representation of an sk_archiving_mode.
* @return an sk_archiving_mode.
*/
-enum sk_archiving_mode sk_archiving_mode_of_string(const char *s);
+enum sk_archiving_mode sk_archiving_mode_of_string(const char *s) SK_NONNULL(1);
/**
* sk_colour_output_to_string:
@@ -83,7 +89,7 @@ enum sk_archiving_mode sk_archiving_mode_of_string(const char *s);
* @param c: the sk_colour_output.
* @return the string representation of c.
*/
-const char *sk_colour_output_to_string(enum sk_colour_output c);
+const char *sk_colour_output_to_string(enum sk_colour_output c) SK_RETURNS_NONNULL;
/**
* sk_colour_output_of_string:
@@ -96,7 +102,7 @@ const char *sk_colour_output_to_string(enum sk_colour_output c);
* @param s: the string representation of an sk_colour_output.
* @return sk_colour_output
*/
-enum sk_colour_output sk_colour_output_of_string(const char *s);
+enum sk_colour_output sk_colour_output_of_string(const char *s) SK_NONNULL(1);
/* functions */
@@ -108,7 +114,7 @@ enum sk_colour_output sk_colour_output_of_string(const char *s);
* @return pointer to a new sk_config struct
* (or NULL if it ran out of memory.)
*/
-struct sk_config *sk_config_alloc();
+struct sk_config *sk_config_alloc() SK_MALLOC_FREE(sk_config_free, 1) SK_WARN_UNUSED_RESULT;
/**
* sk_config_print:
@@ -117,7 +123,7 @@ struct sk_config *sk_config_alloc();
* @param config: the sk_config struct to print
* @param outstream: the stream to print to
*/
-void sk_config_print(struct sk_config *config, FILE *outstream);
+void sk_config_print(struct sk_config *config, FILE *outstream) SK_NONNULL(1, 2);
/**
* sk_config_find:
@@ -128,7 +134,7 @@ void sk_config_print(struct sk_config *config, FILE *outstream);
* @return path to the .skonfig/config file to use,
* or NULL if none was found or an error occurred.
*/
-const char *sk_config_find();
+const char *sk_config_find() SK_WARN_UNUSED_RESULT;
/**
* sk_config_cpy:
@@ -139,9 +145,9 @@ const char *sk_config_find();
* @param dest: pointer to a newly allocated config struct
* @param src: pointer to the struct to copy to dest
*/
-void sk_config_cpy(struct sk_config *restrict dest, const struct sk_config *restrict src);
+void sk_config_cpy(struct sk_config *restrict dest, const struct sk_config *restrict src) SK_NONNULL(1, 2);
-int sk_config_parse_file(struct sk_config *config, FILE *fh);
+int sk_config_parse_file(struct sk_config *config, FILE *fh) SK_NONNULL(1, 2);
/**
* sk_config_parse_env:
@@ -149,7 +155,7 @@ int sk_config_parse_file(struct sk_config *config, FILE *fh);
*
* @param config: the struct to update
*/
-void sk_config_parse_env(struct sk_config *config);
+void sk_config_parse_env(struct sk_config *config) SK_NONNULL(1);
/**
* sk_config_free:
@@ -159,6 +165,6 @@ void sk_config_parse_env(struct sk_config *config);
*
* @param config: the struct to free
*/
-void sk_config_free(struct sk_config *);
+void sk_config_free(struct sk_config *) SK_NONNULL(1);
#endif
diff --git a/src/log.h b/src/log.h
index 0e898f1..cc3bf89 100644
--- a/src/log.h
+++ b/src/log.h
@@ -37,7 +37,7 @@ extern sk_font_map _SK_LOG_MONOCHROME;
* @param level: the log level
* @return the string representation of level.
*/
-const char *sk_log_level_to_string(sk_log_level level);
+const char *sk_log_level_to_string(sk_log_level level) SK_RETURNS_NONNULL;
/**
* sk_log_level_of_string:
@@ -50,7 +50,7 @@ const char *sk_log_level_to_string(sk_log_level level);
* @param s: the string representation of the log level
* @return sk_log_level
*/
-sk_log_level sk_log_level_of_string(const char *s);
+sk_log_level sk_log_level_of_string(const char *s) SK_NONNULL(1);
/* getters/setters for global state variables */
@@ -77,7 +77,7 @@ void sk_log_level_set(sk_log_level new);
*
* @return the current logging font map
*/
-sk_font_map *sk_log_font_get();
+sk_font_map *sk_log_font_get() SK_RETURNS_NONNULL;
/**
* sk_log_font_set:
@@ -85,7 +85,7 @@ sk_font_map *sk_log_font_get();
*
* @param font: the new logging font map.
*/
-void sk_log_font_set(sk_font_map *restrict font);
+void sk_log_font_set(sk_font_map *restrict font) SK_NONNULL(1);
/* logging functions */
diff --git a/src/rexec.c b/src/rexec.c
index 56b0b4e..d55b8c3 100644
--- a/src/rexec.c
+++ b/src/rexec.c
@@ -9,6 +9,7 @@
#include <string.h>
#include <sys/wait.h>
+SK_NONNULL(1, 2)
int sk_rexec_command(
const char *restrict target_host, char *restrict cmd,
int stdin, int stdout, int stderr, envp_t *const extra_envp) {
diff --git a/src/skonfig.c b/src/skonfig.c
index 0d2341b..a23f2d8 100644
--- a/src/skonfig.c
+++ b/src/skonfig.c
@@ -162,10 +162,11 @@ static int sk_get_global_opts(
/* config */
+SK_NONNULL(1)
void sk_init_config(struct sk_config *config, const char *config_file) {
FILE *fh;
- if (config_file) {
+ if (NULL != config_file) {
/* Parse config file (as given by option) */
#if DEBUG
printf("processing config file (opt): %s\n", config_file);
diff --git a/src/util/envp.c b/src/util/envp.c
index 808d9b8..ca3c848 100644
--- a/src/util/envp.c
+++ b/src/util/envp.c
@@ -82,7 +82,9 @@ static char *_envp_get_elem(envp_t envp, const char *restrict name) {
}
char *envp_get(envp_t *envp, const char *name) {
+#if !HAVE_CC_NONNULL_CHECK
if (NULL == envp) return NULL;
+#endif
char *elem = _envp_get_elem(*envp, name);
@@ -96,6 +98,10 @@ char *envp_get(envp_t *envp, const char *name) {
int envp_put(envp_t *envp, char *string) {
+#if !HAVE_CC_NONNULL_CHECK
+ if (NULL == envp || NULL == string) return -1;
+#endif
+
char envname[strchr(string, '=')-string+1];
strncpy(envname, string, sizeof(envname));
@@ -160,7 +166,9 @@ int envp_unset(envp_t *envp, const char *restrict name) {
}
void envp_merge(envp_t *dest, envp_t *const src) {
- if (NULL == src) return;
+#if !HAVE_CC_NONNULL_CHECK
+ if (NULL == src || NULL == dest) return;
+#endif
for (size_t i = 0; NULL != (*src)[i]; ++i) {
envp_put(dest, strdup((*src)[i]));
diff --git a/src/util/envp.h b/src/util/envp.h
index 37871f9..a696330 100644
--- a/src/util/envp.h
+++ b/src/util/envp.h
@@ -9,6 +9,11 @@
typedef char ** envp_t;
+#if HAVE_FUNC_ATTRIBUTE_MALLOC
+/* pre-declare free function for SK_MALLOC_FREE(envp_free) */
+extern void envp_free(envp_t *);
+#endif
+
/**
* envp_alloc:
* allocates a new, empty envp_t.
@@ -17,7 +22,7 @@ typedef char ** envp_t;
*
* @return new, empty envp_t.
*/
-envp_t *envp_alloc(void);
+envp_t *envp_alloc(void) SK_MALLOC_FREE(envp_free, 1) SK_WARN_UNUSED_RESULT;
/**
* envp_dup:
@@ -27,7 +32,7 @@ envp_t *envp_alloc(void);
*
* @return new envp_t.
*/
-envp_t *envp_dup(void);
+envp_t *envp_dup(void) SK_MALLOC_FREE(envp_free, 1) SK_WARN_UNUSED_RESULT;
/**
* envp_get:
@@ -37,7 +42,7 @@ envp_t *envp_dup(void);
* @param name: the name of the environment variable to return.
* @return the value of the environment variable if found, NULL otherwise.
*/
-char *envp_get(envp_t *envp, const char *name);
+char *envp_get(envp_t *envp, const char *name) SK_NONNULL(1, 2);
/**
* envp_put:
@@ -54,7 +59,7 @@ char *envp_get(envp_t *envp, const char *name);
* @param string: a string of the form "name=value".
* @return 0 on success, -1 otherwise and sets errno.
*/
-int envp_put(envp_t *envp, char *string);
+int envp_put(envp_t *envp, char *string) SK_NONNULL(1, 2);
/**
* envp_set:
@@ -70,7 +75,7 @@ int envp_put(envp_t *envp, char *string);
*/
int envp_set(
envp_t *envp, const char *restrict envname, const char *restrict envval,
- bool overwrite);
+ bool overwrite) SK_NONNULL(1, 2, 3);
/**
* envp_unset:
@@ -80,7 +85,7 @@ int envp_set(
* @param name: the name of the environment variable to remove.
* @return 0
*/
-int envp_unset(envp_t *envp, const char *restrict name);
+int envp_unset(envp_t *envp, const char *restrict name) SK_NONNULL(1, 2);
/**
* envp_merge:
@@ -89,7 +94,7 @@ int envp_unset(envp_t *envp, const char *restrict name);
* @param dest: the envp to modify.
* @param src: the source envp.
*/
-void envp_merge(envp_t *dest, envp_t *const src);
+void envp_merge(envp_t *dest, envp_t *const src) SK_NONNULL(1, 2);
/**
* envp_print:
@@ -98,7 +103,7 @@ void envp_merge(envp_t *dest, envp_t *const src);
* @param envp: the envp to print.
* @param stream: the stream to output to.
*/
-void envp_print(envp_t *envp, FILE *restrict stream);
+void envp_print(envp_t *envp, FILE *restrict stream) SK_NONNULL(1, 2);
/**
* envp_free:
@@ -106,6 +111,6 @@ void envp_print(envp_t *envp, FILE *restrict stream);
*
* @param envp: the structure to free.
*/
-void envp_free(envp_t *envp);
+void envp_free(envp_t *envp) SK_NONNULL(1);
#endif
diff --git a/src/util/string.h b/src/util/string.h
index 5e31e21..2359b8f 100644
--- a/src/util/string.h
+++ b/src/util/string.h
@@ -10,6 +10,11 @@
#include <stddef.h>
#include <string.h>
+#if HAVE_FUNC_ATTRIBUTE_MALLOC
+#include <stdlib.h> /* for SK_MALLOC_FREE(free) */
+#endif
+
+
/**
* stringize:
* Convert value of preprocessor macro to C string literal.
@@ -59,11 +64,13 @@
*/
#define string_starts_with(s, p) (strncmp(s, p, strlen(p)))
+#ifndef HAVE_STRDUP
/**
* strdup:
* like strdup(3p).
*/
-char *strdup(const char *s);
+char *strdup(const char *s) SK_MALLOC_FREE(free, 1) SK_NONNULL(1);
+#endif
/**
* strajoin:
@@ -107,7 +114,7 @@ char *strdup(const char *s);
* @param nmemb: the number of elements of @a
* @return a newly-allocated C string containing all of the elements joined
*/
-char *stranjoin(char sep, const char *a[], size_t nmemb);
+char *stranjoin(char sep, const char *a[], size_t nmemb) SK_WARN_UNUSED_RESULT SK_MALLOC_FREE(free, 1);
/**
* stranjoin_r:
@@ -132,9 +139,9 @@ size_t stranjoin_r(
char *_strjoin( /* internal */
- char sep, void *_, /* const char * */...);
+ char sep, void *_, /* const char * */...) SK_SENTINEL(0) SK_WARN_UNUSED_RESULT SK_MALLOC_FREE(free, 1);
size_t _strjoin_r( /* internal */
- char sep, char *restrict buf, size_t buflen, /* const char * */...);
+ char sep, char *restrict buf, size_t buflen, /* const char * */...) SK_SENTINEL(0);
/**
* strjoin: