@@ -36,7 +36,7 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
36
36
string_like sl, string_like_camel slc, prefer_underscore_version puv,
37
37
prefer_underscore_version_flip puvf) {
38
38
s.find (" a" ) == 0 ;
39
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of find() == 0
39
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of find [modernize-use-starts-ends-with]
40
40
// CHECK-FIXES: s.starts_with("a");
41
41
42
42
(((((s)).find (" a" )))) == ((0 ));
@@ -68,7 +68,7 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
68
68
// CHECK-FIXES: !s.starts_with("a");
69
69
70
70
s.rfind (" a" , 0 ) == 0 ;
71
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of rfind() == 0
71
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of rfind [modernize-use-starts-ends-with]
72
72
// CHECK-FIXES: s.starts_with("a");
73
73
74
74
s.rfind (s, 0 ) == 0 ;
@@ -91,16 +91,6 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
91
91
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
92
92
// CHECK-FIXES: !s.starts_with("a");
93
93
94
- #define STR (x ) std::string(x)
95
- 0 == STR (s).find (" a" );
96
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
97
- // CHECK-FIXES: STR(s).starts_with("a");
98
-
99
- #define STRING s
100
- if (0 == STRING.find (" ala" )) { /* do something */ }
101
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
102
- // CHECK-FIXES: if (STRING.starts_with("ala"))
103
-
104
94
#define FIND find
105
95
s.FIND (" a" ) == 0 ;
106
96
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
@@ -149,11 +139,11 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
149
139
// CHECK-FIXES: puvf.starts_with("a");
150
140
151
141
s.compare (0 , 1 , " a" ) == 0 ;
152
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare() == 0
142
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare [modernize-use-starts-ends-with]
153
143
// CHECK-FIXES: s.starts_with("a");
154
144
155
145
s.compare (0 , 1 , " a" ) != 0 ;
156
- // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare() != 0
146
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare [modernize-use-starts-ends-with]
157
147
// CHECK-FIXES: !s.starts_with("a");
158
148
159
149
s.compare (0 , strlen (" a" ), " a" ) == 0 ;
@@ -265,4 +255,68 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
265
255
266
256
s.compare (0 , 1 , " ab" ) == 0 ;
267
257
s.rfind (suffix, 1 ) == s.size () - suffix.size ();
258
+
259
+ #define STR (x ) std::string(x)
260
+ 0 == STR (s).find (" a" );
261
+
262
+ #define STRING s
263
+ if (0 == STRING.find (" ala" )) { /* do something */ }
264
+ }
265
+
266
+ void test_substr () {
267
+ std::string str (" hello world" );
268
+ std::string prefix = " hello" ;
269
+
270
+ // Basic pattern
271
+ str.substr (0 , 5 ) == " hello" ;
272
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
273
+ // CHECK-FIXES: str.starts_with("hello");
274
+
275
+ // With string literal on left side
276
+ " hello" == str.substr (0 , 5 );
277
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
278
+ // CHECK-FIXES: str.starts_with("hello");
279
+
280
+ // Inequality comparison
281
+ str.substr (0 , 5 ) != " world" ;
282
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
283
+ // CHECK-FIXES: !str.starts_with("world");
284
+
285
+ // Ensure non-zero start position is not transformed
286
+ str.substr (1 , 5 ) == " hello" ;
287
+ str.substr (0 , 4 ) == " hello" ; // Length mismatch
288
+
289
+ size_t len = 5 ;
290
+ str.substr (0 , len) == " hello" ; // Non-constant length
291
+
292
+ // String literal with size calculation
293
+ str.substr (0 , strlen (" hello" )) == " hello" ;
294
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
295
+ // CHECK-FIXES: str.starts_with("hello");
296
+
297
+ str.substr (0 , prefix.size ()) == prefix;
298
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
299
+ // CHECK-FIXES: str.starts_with(prefix);
300
+
301
+ str.substr (0 , prefix.length ()) == prefix;
302
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
303
+ // CHECK-FIXES: str.starts_with(prefix);
304
+
305
+ // Tests to verify macro behavior
306
+ #define MSG " hello"
307
+ str.substr (0 , strlen (MSG)) == MSG;
308
+ // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of substr [modernize-use-starts-ends-with]
309
+ // CHECK-FIXES: str.starts_with(MSG);
310
+
311
+ #define STARTS_WITH (X, Y ) (X).substr(0 , (Y).size()) == (Y)
312
+ STARTS_WITH (str, prefix);
313
+
314
+ #define SUBSTR (X, A, B ) (X).substr((A), (B))
315
+ SUBSTR (str, 0 , 6 ) == " prefix" ;
316
+
317
+ #define STR () str
318
+ SUBSTR (STR (), 0 , 6 ) == " prefix" ;
319
+ " prefix" == SUBSTR (STR (), 0 , 6 );
320
+
321
+ str.substr (0 , strlen (" hello123" )) == " hello" ;
268
322
}
0 commit comments