diff --git a/include/criterion/assert.h b/include/criterion/assert.h index 9a42e55..62c578c 100644 --- a/include/criterion/assert.h +++ b/include/criterion/assert.h @@ -53,6 +53,22 @@ struct criterion_assert_args { #endif }; +enum criterion_assert_messages { + CRITERION_ASSERT_MSG_FAIL, + CRITERION_ASSERT_MSG_EXPR_FALSE, + CRITERION_ASSERT_MSG_EXPR_AS_STRINGS_FALSE, + CRITERION_ASSERT_MSG_IS_NULL, + CRITERION_ASSERT_MSG_IS_NOT_NULL, + CRITERION_ASSERT_MSG_IS_EMPTY, + CRITERION_ASSERT_MSG_IS_NOT_EMPTY, +}; + +CR_BEGIN_C_API + +CR_API char *translate_assert_msg(int msg_index, ...); + +CR_END_C_API + # define CR_GET_CONDITION(Condition, ...) Condition # define CR_GET_CONDITION_STR(Condition, ...) #Condition # define CR_VA_SKIP(_, ...) __VA_ARGS__ @@ -63,16 +79,26 @@ struct criterion_assert_args { # define CR_STDN # endif +# define CR_TRANSLATE_DEF_MSG__(Arg) \ + CR_EXPAND Arg + +# define CR_TRANSLATE_DEF_MSG_(...) \ + CR_EXPAND(translate_assert_msg( \ + CR_VA_HEAD(__VA_ARGS__), \ + "" CR_TRANSLATE_DEF_MSG__(CR_VA_HEAD(CR_VA_TAIL(__VA_ARGS__))) \ + )) + # define CR_INIT_STATS_(BufSize, MsgVar, ...) CR_EXPAND( \ do { \ - const char *default_msg = "" CR_VA_HEAD(__VA_ARGS__); \ + char *def_msg = CR_EXPAND(CR_TRANSLATE_DEF_MSG_(__VA_ARGS__)); \ char *formatted_msg = NULL; \ - int msglen = cr_asprintf(&formatted_msg, "" CR_VA_TAIL(__VA_ARGS__)); \ + int msglen = cr_asprintf(&formatted_msg, \ + "" CR_VA_TAIL(CR_VA_TAIL(__VA_ARGS__))); \ MsgVar = formatted_msg && *formatted_msg ? \ - formatted_msg : default_msg; \ + formatted_msg : def_msg; \ \ if (!formatted_msg || !*formatted_msg) \ - msglen = strlen(default_msg); \ + msglen = strlen(def_msg); \ \ BufSize = sizeof(struct criterion_assert_stats) \ + sizeof (size_t) + msglen + 1; \ @@ -84,7 +110,7 @@ struct criterion_assert_args { *((size_t*) buf) = msglen + 1; \ buf += sizeof (size_t); \ CR_STDN strcpy(buf, MsgVar); \ - CR_STDN free(formatted_msg); \ + CR_STDN free(MsgVar); \ } while (0)) # define CR_FAIL_ABORT_ criterion_abort_test @@ -100,7 +126,7 @@ struct criterion_assert_args { do { \ bool passed = !!(Condition); \ \ - const char *msg = NULL; \ + char *msg = NULL; \ size_t bufsize; \ \ struct criterion_assert_stats *stat; \ @@ -123,7 +149,8 @@ struct criterion_assert_args { Fail, \ 0, \ dummy, \ - "The conditions for this assertion were not met.", \ + CRITERION_ASSERT_MSG_FAIL, \ + (), \ __VA_ARGS__ \ )) @@ -135,7 +162,8 @@ struct criterion_assert_args { CR_FAIL_ABORT_, \ CR_VA_HEAD(__VA_ARGS__), \ dummy, \ - "The expression " CR_STR(CR_VA_HEAD(__VA_ARGS__)) " is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR(CR_VA_HEAD(__VA_ARGS__))), \ CR_VA_TAIL(__VA_ARGS__) \ )) @@ -144,7 +172,8 @@ struct criterion_assert_args { CR_FAIL_CONTINUES_, \ CR_VA_HEAD(__VA_ARGS__), \ dummy, \ - "The expression " CR_STR(CR_VA_HEAD(__VA_ARGS__)) " is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR(CR_VA_HEAD(__VA_ARGS__))), \ CR_VA_TAIL(__VA_ARGS__) \ )) @@ -153,7 +182,8 @@ struct criterion_assert_args { CR_FAIL_ABORT_, \ !(CR_VA_HEAD(__VA_ARGS__)), \ dummy, \ - "The expression " CR_STR(!(CR_VA_HEAD(__VA_ARGS__))) " is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR(!(CR_VA_HEAD(__VA_ARGS__)))), \ CR_VA_TAIL(__VA_ARGS__) \ )) @@ -162,7 +192,8 @@ struct criterion_assert_args { CR_FAIL_CONTINUES_, \ !(CR_VA_HEAD(__VA_ARGS__)), \ dummy, \ - "The expression " CR_STR(!(CR_VA_HEAD(__VA_ARGS__))) " is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR(!(CR_VA_HEAD(__VA_ARGS__)))), \ CR_VA_TAIL(__VA_ARGS__) \ )) @@ -173,7 +204,8 @@ struct criterion_assert_args { Fail, \ (Actual) Op (Expected), \ dummy, \ - "The expression " CR_STR((Actual) Op (Expected)) " is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR((Actual) Op (Expected))), \ __VA_ARGS__ \ )) @@ -206,29 +238,30 @@ struct criterion_assert_args { // Common unary assertions -# define cr_assert_null_op_(Fail, Op, Not, Value, ...) \ +# define cr_assert_null_op_(Fail, Op, Msg, Value, ...) \ CR_EXPAND(cr_assert_impl( \ Fail, \ (Value) Op NULL, \ dummy, \ - CR_STR(Value) " is" Not " null.", \ + Msg, \ + (CR_STR(Value)), \ __VA_ARGS__ \ )) -# define cr_assert_null_op_va_(Fail, Op, Not, ...) \ +# define cr_assert_null_op_va_(Fail, Op, Msg, ...) \ CR_EXPAND(cr_assert_null_op_( \ Fail, \ Op, \ - Not, \ + Msg, \ CR_VA_HEAD(__VA_ARGS__), \ CR_VA_TAIL(__VA_ARGS__) \ )) -# define cr_assert_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_ABORT_, ==, " not", __VA_ARGS__)) -# define cr_expect_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_CONTINUES_, ==, " not", __VA_ARGS__)) +# define cr_assert_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_ABORT_, ==, CRITERION_ASSERT_MSG_IS_NOT_NULL, __VA_ARGS__)) +# define cr_expect_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_CONTINUES_, ==, CRITERION_ASSERT_MSG_IS_NOT_NULL, __VA_ARGS__)) -# define cr_assert_not_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_ABORT_, !=, "", __VA_ARGS__)) -# define cr_expect_not_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_CONTINUES_, !=, "", __VA_ARGS__)) +# define cr_assert_not_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_ABORT_, !=, CRITERION_ASSERT_MSG_IS_NULL, __VA_ARGS__)) +# define cr_expect_not_null(...) CR_EXPAND(cr_assert_null_op_va_(CR_FAIL_CONTINUES_, !=, CRITERION_ASSERT_MSG_IS_NULL, __VA_ARGS__)) // Floating-point assertions @@ -243,7 +276,8 @@ struct criterion_assert_args { Fail, \ Op(Actual, Expected, Epsilon), \ dummy, \ - "The expression " CR_STR(Op(Actual, Expected, Epsilon)) " is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR(Op(Actual, Expected, Epsilon))), \ __VA_ARGS__ \ )) @@ -265,37 +299,38 @@ struct criterion_assert_args { // String assertions -# define cr_assert_str_op_empty_(Fail, Op, Not, Value, ...) \ +# define cr_assert_str_op_empty_(Fail, Op, Msg, Value, ...) \ CR_EXPAND(cr_assert_impl( \ Fail, \ (Value)[0] Op '\0', \ dummy, \ - CR_STR(Value) " is" Not " empty.", \ + Msg, \ + (CR_STR(Value)), \ __VA_ARGS__ \ )) -# define cr_assert_str_op_empty_va_(Fail, Op, Not, ...) \ +# define cr_assert_str_op_empty_va_(Fail, Op, Msg, ...) \ CR_EXPAND(cr_assert_str_op_empty_( \ Fail, \ Op, \ - Not, \ + Msg, \ CR_VA_HEAD(__VA_ARGS__), \ CR_VA_TAIL(__VA_ARGS__) \ )) -# define cr_assert_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, ==, " not", __VA_ARGS__)) -# define cr_expect_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, ==, " not", __VA_ARGS__)) +# define cr_assert_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, ==, CRITERION_ASSERT_MSG_IS_NOT_EMPTY, __VA_ARGS__)) +# define cr_expect_str_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, ==, CRITERION_ASSERT_MSG_IS_NOT_EMPTY, __VA_ARGS__)) -# define cr_assert_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, !=, "", __VA_ARGS__)) -# define cr_expect_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, !=, "", __VA_ARGS__)) +# define cr_assert_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_ABORT_, !=, CRITERION_ASSERT_MSG_IS_EMPTY, __VA_ARGS__)) +# define cr_expect_str_not_empty(...) CR_EXPAND(cr_assert_str_op_empty_va_(CR_FAIL_CONTINUES_, !=, CRITERION_ASSERT_MSG_IS_EMPTY, __VA_ARGS__)) # define cr_assert_str_op_(Fail, Op, Actual, Expected, ...) \ CR_EXPAND(cr_assert_impl( \ Fail, \ CR_STDN strcmp((Actual), (Expected)) Op 0, \ dummy, \ - "The expression (as strings) " \ - CR_STR((Actual) Op (Expected)) " is false", \ + CRITERION_ASSERT_MSG_EXPR_AS_STRINGS_FALSE, \ + (CR_STR((Actual) Op (Expected))), \ __VA_ARGS__ \ )) @@ -333,9 +368,8 @@ struct criterion_assert_args { Fail, \ CR_STDN memcmp((Actual), (Expected), (Size)) Op 0, \ dummy, \ - "The expression " \ - CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size]) \ - "is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size])), \ __VA_ARGS__ \ )) @@ -379,9 +413,8 @@ struct criterion_assert_args { Fail, \ order Op 0, \ dummy, \ - "The expression " \ - CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size]) \ - " is false.", \ + CRITERION_ASSERT_MSG_EXPR_FALSE, \ + (CR_STR((Actual)[0 .. Size] Op (Expected)[0 .. Size])), \ __VA_ARGS__ \ )); \ } while (0) diff --git a/po/POTFILES.in b/po/POTFILES.in index d9d2b16..e93e6cd 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,2 +1,3 @@ # List of source files which contain translatable strings. src/log/normal.c +src/i18n.c diff --git a/po/fr.po b/po/fr.po index 3845331..8e0b48e 100644 --- a/po/fr.po +++ b/po/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: criterion 1.0.0\n" "Report-Msgid-Bugs-To: franklinmathieu+criterion@gmail.com\n" -"POT-Creation-Date: 2015-09-09 02:59+0200\n" +"POT-Creation-Date: 2015-09-10 03:35+0200\n" "PO-Revision-Date: 2015-04-03 17:58+0200\n" "Last-Translator: \n" "Language-Team: French\n" @@ -18,60 +18,60 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: src/log/normal.c:54 +#: src/log/normal.c:50 #, c-format msgid "Criterion v%s\n" msgstr "Criterion v%s\n" -#: src/log/normal.c:55 +#: src/log/normal.c:51 #, c-format msgid " %s\n" msgstr " %s\n" -#: src/log/normal.c:58 src/log/normal.c:60 +#: src/log/normal.c:54 src/log/normal.c:56 #, c-format msgid "%1$s::%2$s\n" msgstr "%1$s::%2$s\n" -#: src/log/normal.c:59 +#: src/log/normal.c:55 #, fuzzy, c-format msgid "%1$s::%2$s: (%3$3.2fs)\n" msgstr "%1$s::%2$s: (%3$3.2fs)\n" -#: src/log/normal.c:61 +#: src/log/normal.c:57 #, c-format msgid "%1$s::%2$s: Test is disabled\n" msgstr "%1$s::%2$s: Le test est désactivé\n" -#: src/log/normal.c:62 +#: src/log/normal.c:58 #, c-format msgid "%1$s::%2$s: Suite is disabled\n" msgstr "%1$s::%2$s: La suite est désactivée\n" -#: src/log/normal.c:63 +#: src/log/normal.c:59 #, c-format msgid "%1$s%2$s%3$s:%4$s%5$d%6$s: Assertion failed: %7$s\n" msgstr "%1$s%2$s%3$s:%4$s%5$d%6$s: Échec d'assertion: %7$s\n" -#: src/log/normal.c:64 +#: src/log/normal.c:60 #, fuzzy, c-format msgid " Theory %1$s::%2$s failed with the following parameters: (%3$s)\n" msgstr "" " La théorie %1$s::%2$s a échoué avec les paramètres suivants: (%3$s)\n" -#: src/log/normal.c:65 +#: src/log/normal.c:61 #, c-format msgid "%1$s%2$s%3$s:%4$s%5$u%6$s: Unexpected signal caught below this line!\n" msgstr "" "%1$s%2$s%3$s:%4$s%5$u%6$s: Un signal inattendu a été reçu après cette " "ligne!\n" -#: src/log/normal.c:66 +#: src/log/normal.c:62 #, c-format msgid "%1$s::%2$s: CRASH!\n" msgstr "%1$s::%2$s: PLANTAGE!\n" -#: src/log/normal.c:67 +#: src/log/normal.c:63 #, fuzzy, c-format msgid "" "%1$sWarning! The test `%2$s::%3$s` crashed during its setup or teardown." @@ -80,7 +80,7 @@ msgstr "" "%1$sAttention! Le test `%2$s::%3$s` a planté pendant son initialisation ou " "sa finalisation.%4$s\n" -#: src/log/normal.c:68 +#: src/log/normal.c:64 #, fuzzy, c-format msgid "" "%1$sWarning! The test `%2$s::%3$s` exited during its setup or teardown.%4$s\n" @@ -88,14 +88,14 @@ msgstr "" "%1$sAttention! Le test `%2$s::%3$s` a quitté pendant son initialisation ou " "sa finalisation.%4$s\n" -#: src/log/normal.c:69 +#: src/log/normal.c:65 #, c-format msgid "Running %1$s%2$lu%3$s test from %4$s%5$s%6$s:\n" msgid_plural "Running %1$s%2$lu%3$s tests from %4$s%5$s%6$s:\n" msgstr[0] "Lancement de %1$s%2$lu%3$s test dans %4$s%5$s%6$s:\n" msgstr[1] "Lancement de %1$s%2$lu%3$s tests dans %4$s%5$s%6$s:\n" -#: src/log/normal.c:71 +#: src/log/normal.c:67 #, c-format msgid "" "%1$sSynthesis: Tested: %2$s%3$lu%4$s | Passing: %5$s%6$lu%7$s | Failing: %8$s" @@ -103,3 +103,37 @@ msgid "" msgstr "" "%1$sSynthèse: Testés: %2$s%3$lu%4$s | Validés: %5$s%6$lu%7$s | Échoués: %8$s" "%9$lu%10$s | Plantages: %11$s%12$lu%13$s %14$s\n" + +#: src/i18n.c:13 +msgid "The conditions for this assertion were not met." +msgstr "Les conditions de cette assertions n'ont pas été remplies." + +#: src/i18n.c:14 +#, c-format +msgid "The expression %s is false." +msgstr "L'expression %s est fausse." + +#: src/i18n.c:15 +#, c-format +msgid "The expression (as strings) %s is false." +msgstr "L'expression (en tant que chaînes de caractères) %s est fausse." + +#: src/i18n.c:16 +#, c-format +msgid "%s is null." +msgstr "%s est nul." + +#: src/i18n.c:17 +#, c-format +msgid "%s is not null." +msgstr "%s n'est pas nul." + +#: src/i18n.c:18 +#, c-format +msgid "%s is empty." +msgstr "%s est vide." + +#: src/i18n.c:19 +#, c-format +msgid "%s is not empty." +msgstr "%s n'est pas vide." diff --git a/src/i18n.c b/src/i18n.c index 7a7c51b..b600399 100644 --- a/src/i18n.c +++ b/src/i18n.c @@ -1,7 +1,29 @@ #include "i18n.h" +#include "criterion/assert.h" +#include "criterion/asprintf-compat.h" void init_i18n(void) { #if ENABLE_NLS bindtextdomain (PACKAGE, LOCALEDIR); #endif } + +char *translate_assert_msg(int msg_index, ...) { + static char *messages[] = { + [CRITERION_ASSERT_MSG_FAIL] = N_("The conditions for this assertion were not met."), + [CRITERION_ASSERT_MSG_EXPR_FALSE] = N_("The expression %s is false."), + [CRITERION_ASSERT_MSG_EXPR_AS_STRINGS_FALSE] = N_("The expression (as strings) %s is false."), + [CRITERION_ASSERT_MSG_IS_NULL] = N_("%s is null."), + [CRITERION_ASSERT_MSG_IS_NOT_NULL] = N_("%s is not null."), + [CRITERION_ASSERT_MSG_IS_EMPTY] = N_("%s is empty."), + [CRITERION_ASSERT_MSG_IS_NOT_EMPTY] = N_("%s is not empty."), + }; + + va_list vl; + va_start(vl, msg_index); + char *out; + cr_vasprintf(&out, _(messages[msg_index]), vl); + va_end(vl); + + return out; +} diff --git a/src/i18n.h b/src/i18n.h index 2657c1e..827dc0a 100644 --- a/src/i18n.h +++ b/src/i18n.h @@ -13,6 +13,10 @@ dngettext(PACKAGE, String, Plural, (Quantity)) # endif +// Used to mark string for gettext +# define N_(Str) Str +# define N_s(Str, Pl) {Str, Pl} + void init_i18n(void); #endif /* !I18N_H_ */ diff --git a/src/log/normal.c b/src/log/normal.c index dedcd5e..fc5c7f0 100644 --- a/src/log/normal.c +++ b/src/log/normal.c @@ -47,10 +47,6 @@ typedef const char *const msg_t; -// Used to mark string for gettext -# define N_(Str) Str -# define N_s(Str, Pl) {Str, Pl} - static msg_t msg_pre_all = N_("Criterion v%s\n"); static msg_t msg_desc = N_(" %s\n");