1 // RUN: %check_clang_tidy %s cata-translator-comments %t -- -plugins=%cata_plugin --
2
3 // check_clang_tidy uses -nostdinc++, so we add dummy declaration of std::string here
4 namespace std
5 {
6 template<class CharT, class Traits = void, class Allocator = void>
7 class basic_string
8 {
9 public:
10 basic_string();
11 basic_string( const CharT * );
12 CharT *c_str();
13 const CharT *c_str() const;
14 };
15 using string = basic_string<char>;
16 } // namespace std
17
18 // check_clang_tidy uses -nostdinc++, so we add dummy translation interface here instead of including translations.h
19 #define translate_marker( s ) ( s )
20 #define translate_marker_context( c, s ) ( s )
21 // mimic how it's declared in translation.h
22 #define _( msg ) \
23 ( ( []( const auto & arg ) { \
24 return arg; \
25 } )( msg ) )
26
27 const char *gettext( const char * );
28 const char *pgettext( const char *, const char * );
29 const char *ngettext( const char *, const char *, int );
30 const char *npgettext( const char *, const char *, const char *, int );
31
32 class translation
33 {
34 public:
35 static translation to_translation( const std::string & );
36 static translation to_translation( const std::string &, const std::string & );
37 static translation pl_translation( const std::string &, const std::string & );
38 static translation pl_translation( const std::string &, const std::string &, const std::string & );
39 static translation no_translation( const std::string & );
40 };
41
42 translation to_translation( const std::string & );
43 translation to_translation( const std::string &, const std::string & );
44 translation pl_translation( const std::string &, const std::string & );
45 translation pl_translation( const std::string &, const std::string &, const std::string & );
46 translation no_translation( const std::string & );
47
foo()48 void foo()
49 {
50 // translation markers only accepts string literals as arguments
51 static_cast<void>( translate_marker( "bar" ) );
52 static_cast<void>( translate_marker( R"(foo)" "bar" ) );
53 static_cast<void>( translate_marker_context( "foo", "bar" ) );
54
55 static_cast<void>( translate_marker( ( "bar" ) ) );
56 // CHECK-MESSAGES: [[@LINE-1]]:42: warning: Translation marker macros only accepts string literal arguments
57 static_cast<void>( translate_marker_context( "foo", ( "bar" ) ) );
58 // CHECK-MESSAGES: [[@LINE-1]]:57: warning: Translation marker macros only accepts string literal arguments
59 #define pass_through( x ) x
60 static_cast<void>( translate_marker( pass_through( "bar" ) ) );
61 // CHECK-MESSAGES: [[@LINE-1]]:42: warning: Translation marker macros only accepts string literal arguments
62 static_cast<void>( translate_marker_context(, "bar" ) );
63 // CHECK-MESSAGES: [[@LINE-1]]:49: warning: Empty argument to a translation marker macro
64
65 // valid translator comments
66
67 // ~xgettext will treat this as a translator comment, but we ignore it
68 // to allow using the tilde (~) inside normal comments
69
70 //~ bar
71 _( "bar" );
72
73 ngettext( /*~ foo */ ( "bar" ), _( "baz" ), 0 );
74
75 //~ bar
76 gettext( "bar" );
77
78 //~bar
79 ngettext( "bar", "baz", 1 );
80
81 /*~ bar */ to_translation( "bar" );
82
83 /*~ bar */
84 pl_translation( "bar", "baz" );
85
86 _( /*~ bar */ "bar" );
87
88 /*~
89 bar*/
90 _( "bar" );
91
92 //~ bar
93 pgettext( "foo", "bar" );
94
95 //~ bark
96 static_cast<void>( translate_marker( "bar" ) );
97
98 static_cast<void>( translate_marker_context( "foo", /*~ bard */ "bar" ) );
99
100 // misplaced translator comments
101
102 //~ barbarian
103 const char *bar = "bar";
104 static_cast<void>( bar );
105 _( "bar" );
106 // CHECK-MESSAGES: [[@LINE-4]]:5: warning: Translator comment without a matching raw string
107
108 _( "bar" );
109 //~ barbara
110 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: Translator comment without a matching raw string
111
112 _( "bar" /*~ banana */ );
113 // CHECK-MESSAGES: [[@LINE-1]]:14: warning: Translator comment without a matching raw string
114
115 //~ barb
116 _( ( "bar" ) );
117 // CHECK-MESSAGES: [[@LINE-2]]:5: warning: Translator comment without a matching raw string
118
119 //~ barf
120 pgettext( ( "foo" ), "bar" );
121 // CHECK-MESSAGES: [[@LINE-2]]:5: warning: Translator comment without a matching raw string
122
123 /*~
124 barnacle */
125 npgettext( "foo",
126 "bar", "baz", 2 );
127 // CHECK-MESSAGES: [[@LINE-4]]:5: warning: Translator comment without a matching raw string
128
129 //~ barn
130 npgettext( "foo", "bar", ( "baz" ), 3 );
131 // CHECK-MESSAGES: [[@LINE-2]]:5: warning: Translator comment without a matching raw string
132
133 //~ baron
134 to_translation( "foo", { "bar" } );
135 // CHECK-MESSAGES: [[@LINE-2]]:5: warning: Translator comment without a matching raw string
136
137 //~ barricade
138 to_translation( "foo", ( "bar" ) );
139 // CHECK-MESSAGES: [[@LINE-2]]:5: warning: Translator comment without a matching raw string
140
141 //~ bartender
142 to_translation( "foo", std::string( "bar" ) );
143 // CHECK-MESSAGES: [[@LINE-2]]:5: warning: Translator comment without a matching raw string
144
145 //~ barbeque
146 to_translation( "foo",
147 "bar" );
148 // CHECK-MESSAGES: [[@LINE-3]]:5: warning: Translator comment without a matching raw string
149 }
150
151 //~ barometer
152 // CHECK-MESSAGES: [[@LINE-1]]:1: warning: Translator comment without a matching raw string
153