summaryrefslogtreecommitdiffstats
path: root/audio-plugins/rt-plugins/0002-make-the-code-compile-with-higher-warning-levels.patch
diff options
context:
space:
mode:
Diffstat (limited to 'audio-plugins/rt-plugins/0002-make-the-code-compile-with-higher-warning-levels.patch')
-rw-r--r--audio-plugins/rt-plugins/0002-make-the-code-compile-with-higher-warning-levels.patch516
1 files changed, 516 insertions, 0 deletions
diff --git a/audio-plugins/rt-plugins/0002-make-the-code-compile-with-higher-warning-levels.patch b/audio-plugins/rt-plugins/0002-make-the-code-compile-with-higher-warning-levels.patch
new file mode 100644
index 0000000000..86963a879f
--- /dev/null
+++ b/audio-plugins/rt-plugins/0002-make-the-code-compile-with-higher-warning-levels.patch
@@ -0,0 +1,516 @@
+From 00e9bb011628328ecbf0b2229d5a68e5c1ec9f3e Mon Sep 17 00:00:00 2001
+From: Florian Franzmann <siflfran@hawo.stw.uni-erlangen.de>
+Date: Thu, 20 Mar 2014 12:14:37 +0000
+Subject: [PATCH 2/2] make the code compile with higher warning levels
+
+- also separate CFLAGS and CPPFLAGS
+- remove -ffast-math from CFLAGS since -Ofast already implies it
+- use CFLAGS and LDFLAGS passed in from the outside
+---
+ Makefile | 15 +++++++++++++--
+ RTallpass1.c | 12 +++++++-----
+ RTallpass2.c | 10 ++++++----
+ RThighpass.c | 10 ++++++----
+ RThighshelf.c | 10 ++++++----
+ RTlowpass.c | 10 ++++++----
+ RTlowshelf.c | 10 ++++++----
+ RTlr4hipass.c | 10 ++++++----
+ RTlr4lowpass.c | 10 ++++++----
+ RTparaeq.c | 10 ++++++----
+ util/biquad.h | 5 +++--
+ util/ladspa-util.h | 25 +++++++++++--------------
+ 12 files changed, 82 insertions(+), 55 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 78a76ea..ed93dd1 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,8 +1,19 @@
+ INSTALL_PLUGINS_DIR ?= /usr/local/lib/ladspa/
+
+ # rt 31.5.2013: got rid of sse2 stuff so we can build for ARM
+-CFLAGS = -I. -Ofast -Wall -fomit-frame-pointer -ffast-math -fstrength-reduce -funroll-loops -c -fPIC -DPIC
+-LDFLAGS = -shared
++CPPFLAGS += -D_BSD_SOURCE -DPIC -D_XOPEN_SOURCE=600 -I.
++
++CFLAGS += -Ofast -fomit-frame-pointer -fstrength-reduce -funroll-loops -fPIC -std=c11
++
++CFLAGS += -Wall -Wextra -Werror -pedantic
++CFLAGS += -Wcast-align -Wfloat-equal -Wformat-nonliteral -Wformat-security
++CFLAGS += -Winit-self -Wmissing-include-dirs
++CFLAGS += -Wno-suggest-attribute=noreturn -Wno-write-strings -Wpointer-arith -Wundef -Wpacked
++CFLAGS += -Wredundant-decls
++CFLAGS += -Wunreachable-code -Wno-unused-parameter -Wconversion -Wshadow
++CFLAGS += -Wstrict-prototypes -Wbad-function-cast -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wnested-externs
++
++LDFLAGS += -shared
+
+ PLUGINS = RTallpass1.so \
+ RTallpass2.so \
+diff --git a/RTallpass1.c b/RTallpass1.c
+index 71c62ac..4ea528b 100644
+--- a/RTallpass1.c
++++ b/RTallpass1.c
+@@ -140,12 +140,13 @@ static void runAllPass(LADSPA_Handle instance, unsigned long sample_count) {
+ for (pos = 0; pos < sample_count; pos++) {
+ // RT 2.9.2013: replace biquad_run with ap1_run to cut floating-
+ // point multiplications from 3 to 1:
+- buffer_write(output[pos], ap1_run(filter, input[pos]));
++ buffer_write(output[pos], (LADSPA_Data) ap1_run(filter, input[pos]));
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -189,8 +190,8 @@ void _init() {
+ D_("Frequency (Hz)");
+ port_range_hints[ALLPASS1_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+- port_range_hints[ALLPASS1_FC].LowerBound = 0;
+- port_range_hints[ALLPASS1_FC].UpperBound = 0.4;
++ port_range_hints[ALLPASS1_FC].LowerBound = 0.0;
++ port_range_hints[ALLPASS1_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Input */
+ port_descriptors[ALLPASS1_INPUT] =
+@@ -222,7 +223,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (allPassDescriptor) {
+ free((LADSPA_PortDescriptor *)allPassDescriptor->PortDescriptors);
+ free((char **)allPassDescriptor->PortNames);
+diff --git a/RTallpass2.c b/RTallpass2.c
+index d36dad6..a0bac58 100644
+--- a/RTallpass2.c
++++ b/RTallpass2.c
+@@ -149,12 +149,13 @@ static void runAllPass(LADSPA_Handle instance, unsigned long sample_count) {
+ for (pos = 0; pos < sample_count; pos++) {
+ // RT 2.9.2013: replace biquad_run with ap2_run to cut floating-
+ // point multiplications from 5 to 2:
+- buffer_write(output[pos], ap2_run(filter, input[pos]));
++ buffer_write(output[pos], (LADSPA_Data) ap2_run(filter, input[pos]));
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -199,7 +200,7 @@ void _init() {
+ port_range_hints[ALLPASS_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[ALLPASS_FC].LowerBound = 0;
+- port_range_hints[ALLPASS_FC].UpperBound = 0.4;
++ port_range_hints[ALLPASS_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Bandwidth (octaves) */
+ port_descriptors[ALLPASS_Q] =
+@@ -241,7 +242,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (allPassDescriptor) {
+ free((LADSPA_PortDescriptor *)allPassDescriptor->PortDescriptors);
+ free((char **)allPassDescriptor->PortNames);
+diff --git a/RThighpass.c b/RThighpass.c
+index c7d6a65..3376ad9 100644
+--- a/RThighpass.c
++++ b/RThighpass.c
+@@ -145,12 +145,13 @@ static void runHighPass(LADSPA_Handle instance, unsigned long sample_count) {
+ hp_set_params(filter, fc, Q, fs);
+
+ for (pos = 0; pos < sample_count; pos++) {
+- buffer_write(output[pos], biquad_run(filter, input[pos]));
++ buffer_write(output[pos], (LADSPA_Data) biquad_run(filter, input[pos]));
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -195,7 +196,7 @@ void _init() {
+ port_range_hints[HIGHPASS_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[HIGHPASS_FC].LowerBound = 0;
+- port_range_hints[HIGHPASS_FC].UpperBound = 0.4;
++ port_range_hints[HIGHPASS_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Q */
+ port_descriptors[HIGHPASS_Q] =
+@@ -237,7 +238,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (highPassDescriptor) {
+ free((LADSPA_PortDescriptor *)highPassDescriptor->PortDescriptors);
+ free((char **)highPassDescriptor->PortNames);
+diff --git a/RThighshelf.c b/RThighshelf.c
+index 39f0abf..9d02d45 100644
+--- a/RThighshelf.c
++++ b/RThighshelf.c
+@@ -153,12 +153,13 @@ static void runHighShelf(LADSPA_Handle instance, unsigned long sample_count) {
+ hs_set_params(filter, fc, gain, Q, fs);
+
+ for (pos = 0; pos < sample_count; pos++) {
+- buffer_write(output[pos], biquad_run(filter, input[pos]));
++ buffer_write(output[pos], (LADSPA_Data) biquad_run(filter, input[pos]));
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -213,7 +214,7 @@ void _init() {
+ port_range_hints[HIGHSHELF_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[HIGHSHELF_FC].LowerBound = 0;
+- port_range_hints[HIGHSHELF_FC].UpperBound = 0.4;
++ port_range_hints[HIGHSHELF_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Quality Factor */
+ port_descriptors[HIGHSHELF_Q] =
+@@ -255,7 +256,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (highShelfDescriptor) {
+ free((LADSPA_PortDescriptor *)highShelfDescriptor->PortDescriptors);
+ free((char **)highShelfDescriptor->PortNames);
+diff --git a/RTlowpass.c b/RTlowpass.c
+index 869969d..9ea377f 100644
+--- a/RTlowpass.c
++++ b/RTlowpass.c
+@@ -145,12 +145,13 @@ static void runLowPass(LADSPA_Handle instance, unsigned long sample_count) {
+ lp_set_params(filter, fc, Q, fs);
+
+ for (pos = 0; pos < sample_count; pos++) {
+- buffer_write(output[pos], biquad_run(filter, input[pos]));
++ buffer_write(output[pos], (LADSPA_Data) biquad_run(filter, input[pos]));
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -195,7 +196,7 @@ void _init() {
+ port_range_hints[LOWPASS_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[LOWPASS_FC].LowerBound = 0;
+- port_range_hints[LOWPASS_FC].UpperBound = 0.4;
++ port_range_hints[LOWPASS_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Q */
+ port_descriptors[LOWPASS_Q] =
+@@ -237,7 +238,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (lowPassDescriptor) {
+ free((LADSPA_PortDescriptor *)lowPassDescriptor->PortDescriptors);
+ free((char **)lowPassDescriptor->PortNames);
+diff --git a/RTlowshelf.c b/RTlowshelf.c
+index 2c3f945..12a2c7c 100644
+--- a/RTlowshelf.c
++++ b/RTlowshelf.c
+@@ -153,12 +153,13 @@ static void runLowShelf(LADSPA_Handle instance, unsigned long sample_count) {
+ ls_set_params(filter, fc, gain, Q, fs);
+
+ for (pos = 0; pos < sample_count; pos++) {
+- buffer_write(output[pos], biquad_run(filter, input[pos]));
++ buffer_write(output[pos], (LADSPA_Data) biquad_run(filter, input[pos]));
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -213,7 +214,7 @@ void _init() {
+ port_range_hints[LOWSHELF_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[LOWSHELF_FC].LowerBound = 0;
+- port_range_hints[LOWSHELF_FC].UpperBound = 0.4;
++ port_range_hints[LOWSHELF_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Quality Factor */
+ port_descriptors[LOWSHELF_Q] =
+@@ -255,7 +256,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (lowShelfDescriptor) {
+ free((LADSPA_PortDescriptor *)lowShelfDescriptor->PortDescriptors);
+ free((char **)lowShelfDescriptor->PortNames);
+diff --git a/RTlr4hipass.c b/RTlr4hipass.c
+index 6462b5e..15d6c49 100644
+--- a/RTlr4hipass.c
++++ b/RTlr4hipass.c
+@@ -143,12 +143,13 @@ static void runLR4HighPass(LADSPA_Handle instance, unsigned long sample_count) {
+ for (pos = 0; pos < sample_count; pos++) {
+ in = biquad_run(&filters[0], input[pos]);
+ in = biquad_run(&filters[1], in);
+- buffer_write(output[pos], in);
++ buffer_write(output[pos], (LADSPA_Data) in);
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -193,7 +194,7 @@ void _init() {
+ port_range_hints[LR4HIGHPASS_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[LR4HIGHPASS_FC].LowerBound = 0;
+- port_range_hints[LR4HIGHPASS_FC].UpperBound = 0.4;
++ port_range_hints[LR4HIGHPASS_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Input */
+ port_descriptors[LR4HIGHPASS_INPUT] =
+@@ -225,7 +226,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (lr4highPassDescriptor) {
+ free((LADSPA_PortDescriptor *)lr4highPassDescriptor->PortDescriptors);
+ free((char **)lr4highPassDescriptor->PortNames);
+diff --git a/RTlr4lowpass.c b/RTlr4lowpass.c
+index 2d864cc..16ad5c9 100644
+--- a/RTlr4lowpass.c
++++ b/RTlr4lowpass.c
+@@ -143,12 +143,13 @@ static void runLR4LowPass(LADSPA_Handle instance, unsigned long sample_count) {
+ for (pos = 0; pos < sample_count; pos++) {
+ in = biquad_run(&filters[0], input[pos]);
+ in = biquad_run(&filters[1], in);
+- buffer_write(output[pos], in);
++ buffer_write(output[pos], (LADSPA_Data) in);
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -193,7 +194,7 @@ void _init() {
+ port_range_hints[LR4LOWPASS_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[LR4LOWPASS_FC].LowerBound = 0;
+- port_range_hints[LR4LOWPASS_FC].UpperBound = 0.4;
++ port_range_hints[LR4LOWPASS_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Input */
+ port_descriptors[LR4LOWPASS_INPUT] =
+@@ -225,7 +226,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (lr4lowPassDescriptor) {
+ free((LADSPA_PortDescriptor *)lr4lowPassDescriptor->PortDescriptors);
+ free((char **)lr4lowPassDescriptor->PortNames);
+diff --git a/RTparaeq.c b/RTparaeq.c
+index f55e3c5..3e77a83 100644
+--- a/RTparaeq.c
++++ b/RTparaeq.c
+@@ -153,12 +153,13 @@ static void runSinglePara(LADSPA_Handle instance, unsigned long sample_count) {
+ eq_set_params(filter, fc, gain, Q, fs);
+
+ for (pos = 0; pos < sample_count; pos++) {
+- buffer_write(output[pos], biquad_run(filter, input[pos]));
++ buffer_write(output[pos], (LADSPA_Data) biquad_run(filter, input[pos]));
+ }
+
+ }
+
+-void _init() {
++void _init(void);
++void _init(void) {
+ char **port_names;
+ LADSPA_PortDescriptor *port_descriptors;
+ LADSPA_PortRangeHint *port_range_hints;
+@@ -213,7 +214,7 @@ void _init() {
+ port_range_hints[SINGLEPARA_FC].HintDescriptor =
+ LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_SAMPLE_RATE | LADSPA_HINT_DEFAULT_440;
+ port_range_hints[SINGLEPARA_FC].LowerBound = 0;
+- port_range_hints[SINGLEPARA_FC].UpperBound = 0.4;
++ port_range_hints[SINGLEPARA_FC].UpperBound = (LADSPA_Data) 0.4;
+
+ /* Parameters for Quality Factor */
+ port_descriptors[SINGLEPARA_Q] =
+@@ -255,7 +256,8 @@ void _init() {
+ }
+ }
+
+-void _fini() {
++void _fini(void);
++void _fini(void) {
+ if (singleParaDescriptor) {
+ free((LADSPA_PortDescriptor *)singleParaDescriptor->PortDescriptors);
+ free((char **)singleParaDescriptor->PortNames);
+diff --git a/util/biquad.h b/util/biquad.h
+index 8994e4b..49451d8 100644
+--- a/util/biquad.h
++++ b/util/biquad.h
+@@ -4,6 +4,7 @@
+ #define LN_2_2 0.34657359f // ln(2)/2
+
+ #include "ladspa-util.h"
++#include <math.h>
+
+ #ifndef LIMIT
+ #define LIMIT(v,l,u) (v<l?l:(v>u?u:v))
+@@ -96,7 +97,7 @@ static inline void ls_set_params(biquad *f, bq_t fc, bq_t gain, bq_t Q,
+ bq_t w = 2.0f * M_PI * LIMIT(fc, 1.0, fs/2.0) / fs;
+ bq_t cw = cos(w);
+ bq_t sw = sin(w);
+- bq_t A = powf(10.0f, gain * 0.025f);
++ bq_t A = powf(10.0f, (float) (gain * (bq_t) 0.025));
+
+ // rt 8.1.2013: increased slope limit from 1.0f to 5.0f:
+ // bq_t b = sqrt(((1.0f + A * A) / LIMIT(slope, 0.0001f, 5.0f)) - ((A -
+@@ -135,7 +136,7 @@ static inline void hs_set_params(biquad *f, bq_t fc, bq_t gain, bq_t Q, bq_t fs)
+ bq_t w = 2.0f * M_PI * LIMIT(fc, 1.0, fs/2.0) / fs;
+ bq_t cw = cos(w);
+ bq_t sw = sin(w);
+- bq_t A = powf(10.0f, gain * 0.025f);
++ bq_t A = powf(10.0f, (float) (gain * (bq_t) 0.025));
+ // rt 8.1.2013: increased slope limit from 1.0f to 5.0f:
+ // bq_t b = sqrt(((1.0f + A * A) / LIMIT(slope, 0.0001f, 5.0f)) - ((A -
+ // 1.0f) * (A - 1.0f)));
+diff --git a/util/ladspa-util.h b/util/ladspa-util.h
+index ef6e31b..5d3dcc9 100644
+--- a/util/ladspa-util.h
++++ b/util/ladspa-util.h
+@@ -46,9 +46,6 @@ typedef union {
+ int32_t i;
+ } ls_pcast32;
+
+-// Sometimes it doesn't get defined, even though it eists and C99 is declared
+-long int lrintf (float x);
+-
+ // 1.0 / ln(2)
+ #define LN2R 1.442695041f
+
+@@ -72,8 +69,8 @@ static inline float flush_to_zero(float f)
+
+ static inline void round_to_zero(volatile float *f)
+ {
+- *f += 1e-18;
+- *f -= 1e-18;
++ *f += 1e-18f;
++ *f -= 1e-18f;
+ }
+
+ /* A set of branchless clipping operations from Laurent de Soras */
+@@ -81,8 +78,8 @@ static inline void round_to_zero(volatile float *f)
+ static inline float f_max(float x, float a)
+ {
+ x -= a;
+- x += fabs(x);
+- x *= 0.5;
++ x += fabsf(x);
++ x *= 0.5f;
+ x += a;
+
+ return x;
+@@ -91,8 +88,8 @@ static inline float f_max(float x, float a)
+ static inline float f_min(float x, float b)
+ {
+ x = b - x;
+- x += fabs(x);
+- x *= 0.5;
++ x += fabsf(x);
++ x *= 0.5f;
+ x = b - x;
+
+ return x;
+@@ -100,12 +97,12 @@ static inline float f_min(float x, float b)
+
+ static inline float f_clamp(float x, float a, float b)
+ {
+- const float x1 = fabs(x - a);
+- const float x2 = fabs(x - b);
++ const float x1 = fabsf(x - a);
++ const float x2 = fabsf(x - b);
+
+ x = x1 + a + b;
+ x -= x2;
+- x *= 0.5;
++ x *= 0.5f;
+
+ return x;
+ }
+@@ -166,7 +163,7 @@ static inline float f_sin_sq(float angle)
+ #else
+
+ // Round float to int using IEEE int* hack
+-static inline int f_round(float f)
++static inline long int f_round(float f)
+ {
+ ls_pcast32 p;
+
+@@ -179,7 +176,7 @@ static inline int f_round(float f)
+ #endif
+
+ // Truncate float to int
+-static inline int f_trunc(float f)
++static inline long int f_trunc(float f)
+ {
+ return f_round(floorf(f));
+ }
+--
+1.9.0
+