@@ -2125,56 +2125,6 @@ def generate_version_header_implementation(
2125
2125
{tests}\
2126
2126
"""
2127
2127
2128
- #
2129
- # The templates used for a single FTM block in the tests.
2130
- #
2131
-
2132
- ftm_unavailable_in_dialect = """
2133
- # ifdef {ftm}
2134
- # error "{ftm} should not be defined before {dialect}"
2135
- # endif
2136
- """
2137
-
2138
- libcxx_ftm_not_implemented = """
2139
- # if !defined(_LIBCPP_VERSION)
2140
- # ifndef {ftm}
2141
- # error "{ftm} should be defined in {dialect}"
2142
- # endif
2143
- # if {ftm} != {value}
2144
- # error "{ftm} should have the value {value} in {dialect}"
2145
- # endif
2146
- # else
2147
- # ifdef {ftm}
2148
- # error "{ftm} should not be defined because it is unimplemented in libc++!"
2149
- # endif
2150
- # endif
2151
- """
2152
-
2153
- libcxx_ftm_conditionally_implemented = """
2154
- # if {condition}
2155
- # ifndef {ftm}
2156
- # error "{ftm} should be defined in {dialect}"
2157
- # endif
2158
- # if {ftm} != {value}
2159
- # error "{ftm} should have the value {value} in {dialect}"
2160
- # endif
2161
- # else
2162
- # ifdef {ftm}
2163
- # error "{ftm} should not be defined when the requirement '{condition}' is not met!"
2164
- # endif
2165
- # endif
2166
- """
2167
-
2168
- libcxx_ftm_implemented = """
2169
- # ifndef {ftm}
2170
- # error "{ftm} should be defined in {dialect}"
2171
- # endif
2172
- # if {ftm} != {value}
2173
- # error "{ftm} should have the value {value} in {dialect}"
2174
- # endif
2175
- """
2176
-
2177
-
2178
2128
class FeatureTestMacros :
2179
2129
"""Provides all feature-test macro (FTM) output components.
2180
2130
@@ -2424,7 +2374,7 @@ def version_header(self) -> str:
2424
2374
)
2425
2375
)
2426
2376
2427
- def header_ftm (self , header : str ) -> Dict [Std , List [Dict [Ftm , FtmHeaderTest ]]]:
2377
+ def header_ftm_data (self , header : str ) -> Dict [Std , List [Dict [Ftm , FtmHeaderTest ]]]:
2428
2378
"""Generates the FTM information for a `header`."""
2429
2379
2430
2380
result = dict ()
@@ -2440,19 +2390,17 @@ def header_ftm(self, header: str) -> Dict[Std, List[Dict[Ftm, FtmHeaderTest]]]:
2440
2390
2441
2391
for std in self .std_dialects :
2442
2392
if not std in values .keys ():
2443
- result [get_std_number (std )].append (dict ( {ftm : None }) )
2393
+ result [get_std_number (std )].append ({ftm : None })
2444
2394
continue
2445
2395
2446
2396
result [get_std_number (std )].append (
2447
- dict (
2448
2397
{
2449
2398
ftm : FtmHeaderTest (
2450
2399
values [std ],
2451
2400
self .is_implemented (ftm , std ),
2452
2401
self .ftm_metadata [ftm ].test_suite_guard ,
2453
2402
)
2454
2403
}
2455
- )
2456
2404
)
2457
2405
2458
2406
return result
@@ -2466,25 +2414,70 @@ def generate_header_test_ftm(self, std: Std, ftm: Ftm, value: FtmHeaderTest) ->
2466
2414
this is 14, since FTM have been introduced in C++14.)
2467
2415
"""
2468
2416
2417
+ ftm_unavailable_in_dialect = """
2418
+ # ifdef {ftm}
2419
+ # error "{ftm} should not be defined before {dialect}"
2420
+ # endif
2421
+ """
2422
+
2423
+ ftm_not_implemented = """
2424
+ # if !defined(_LIBCPP_VERSION)
2425
+ # ifndef {ftm}
2426
+ # error "{ftm} should be defined in {dialect}"
2427
+ # endif
2428
+ # if {ftm} != {value}
2429
+ # error "{ftm} should have the value {value} in {dialect}"
2430
+ # endif
2431
+ # else
2432
+ # ifdef {ftm}
2433
+ # error "{ftm} should not be defined because it is unimplemented in libc++!"
2434
+ # endif
2435
+ # endif
2436
+ """
2437
+
2438
+ ftm_conditionally_implemented = """
2439
+ # if {condition}
2440
+ # ifndef {ftm}
2441
+ # error "{ftm} should be defined in {dialect}"
2442
+ # endif
2443
+ # if {ftm} != {value}
2444
+ # error "{ftm} should have the value {value} in {dialect}"
2445
+ # endif
2446
+ # else
2447
+ # ifdef {ftm}
2448
+ # error "{ftm} should not be defined when the requirement '{condition}' is not met!"
2449
+ # endif
2450
+ # endif
2451
+ """
2452
+
2453
+ ftm_implemented = """
2454
+ # ifndef {ftm}
2455
+ # error "{ftm} should be defined in {dialect}"
2456
+ # endif
2457
+ # if {ftm} != {value}
2458
+ # error "{ftm} should have the value {value} in {dialect}"
2459
+ # endif
2460
+ """
2461
+
2469
2462
if std == None or value == None :
2470
2463
return ftm_unavailable_in_dialect .format (
2471
2464
ftm = ftm , dialect = self .ftm_metadata [ftm ].available_since
2472
2465
)
2473
2466
2474
2467
if not value .implemented :
2475
- return libcxx_ftm_not_implemented .format (
2468
+ return ftm_not_implemented .format (
2476
2469
ftm = ftm , value = value .value , dialect = std
2477
2470
)
2478
2471
2479
2472
if self .ftm_metadata [ftm ].test_suite_guard :
2480
- return libcxx_ftm_conditionally_implemented .format (
2473
+ return ftm_conditionally_implemented .format (
2481
2474
ftm = ftm ,
2482
2475
value = value .value ,
2483
2476
dialect = std ,
2484
2477
condition = self .ftm_metadata [ftm ].test_suite_guard ,
2485
2478
)
2486
2479
2487
- return libcxx_ftm_implemented .format (ftm = ftm , value = value .value , dialect = std )
2480
+ return ftm_implemented .format (ftm = ftm , value = value .value , dialect = std )
2488
2481
2489
2482
def generate_header_test_dialect (
2490
2483
self , std : Std , data : List [Dict [Ftm , FtmHeaderTest ]]
@@ -2502,47 +2495,49 @@ def generate_lit_markup(self, header:str) -> str:
2502
2495
2503
2496
return "\n " .join (f"// { markup } " for markup in lit_markup [header ]) + "\n \n "
2504
2497
2505
- def generate_header_test (self , header : str ) -> str :
2498
+ def generate_header_test_file (self , header : str ) -> str :
2506
2499
"""Returns the body for the FTM test of a `header`."""
2507
2500
2508
- return ftm_header_test_file_contents .format (
2509
- script_name = script_name ,
2510
- lit_markup = self .generate_lit_markup (header ),
2511
- header = header ,
2512
- include = (
2513
- ftm_header_test_file_include_conditional .format (header = header )
2514
- if header in self .__unavailable_headers
2515
- else ftm_header_test_file_include_unconditional .format (header = header )
2516
- ),
2517
- data =
2518
- # FTM block before the first Standard that introduced them.
2519
- # This test the macros are not available before this version.
2520
- ftm_header_test_file_dialect_block .format (
2501
+ # FTM block before the first Standard that introduced them.
2502
+ # This test the macros are not available before this version.
2503
+ data = ftm_header_test_file_dialect_block .format (
2521
2504
pp_if = "if" ,
2522
2505
operator = "<" ,
2523
- dialect = self .std_dialects [0 ][ 3 :] ,
2506
+ dialect = get_std_number ( self .std_dialects [0 ]) ,
2524
2507
tests = self .generate_header_test_dialect (
2525
- None , next (iter (self .header_ftm (header ).values ()))
2508
+ None , next (iter (self .header_ftm_data (header ).values ()))
2526
2509
),
2527
2510
)
2528
- +
2529
- # FTM for all Standards that have FTM defined.
2530
- # Note in libc++ the TEST_STD_VER contains 99 for the Standard
2531
- # in development, therefore the last entry uses a different #elif.
2532
- "" .join (
2511
+
2512
+ # FTM for all Standards that have FTM defined.
2513
+ # Note in libc++ the TEST_STD_VER contains 99 for the Standard
2514
+ # in development, therefore the last entry uses a different #elif.
2515
+ data += "" .join (
2533
2516
ftm_header_test_file_dialect_block .format (
2534
2517
pp_if = "elif" ,
2535
- operator = "==" if std != self .std_dialects [- 1 ][ 3 :] else ">" ,
2518
+ operator = "==" if std != get_std_number ( self .std_dialects [- 1 ]) else ">" ,
2536
2519
dialect = std
2537
- if std != self .std_dialects [- 1 ][ 3 :]
2538
- else self .std_dialects [- 2 ][ 3 :] ,
2520
+ if std != get_std_number ( self .std_dialects [- 1 ])
2521
+ else get_std_number ( self .std_dialects [- 2 ]) ,
2539
2522
tests = self .generate_header_test_dialect (f"c++{ std } " , values ),
2540
2523
)
2541
- for std , values in self .header_ftm (header ).items ()
2524
+ for std , values in self .header_ftm_data (header ).items ()
2542
2525
)
2543
- +
2544
- # The final #endif for the last #elif block.
2545
- f"\n #endif // TEST_STD_VER > { self .std_dialects [- 2 ][3 :]} " ,
2526
+
2527
+ # The final #endif for the last #elif block.
2528
+ data += f"\n #endif // TEST_STD_VER > { get_std_number (self .std_dialects [- 2 ])} "
2529
+
2530
+ # Generate the test for the requested header.
2531
+ return ftm_header_test_file_contents .format (
2532
+ script_name = script_name ,
2533
+ lit_markup = self .generate_lit_markup (header ),
2534
+ header = header ,
2535
+ include = (
2536
+ ftm_header_test_file_include_conditional .format (header = header )
2537
+ if header in self .__unavailable_headers
2538
+ else ftm_header_test_file_include_unconditional .format (header = header )
2539
+ ),
2540
+ data = data
2546
2541
)
2547
2542
2548
2543
def generate_header_test_directory (self , path : os .path ) -> None :
@@ -2557,7 +2552,7 @@ def generate_header_test_directory(self, path: os.path) -> None:
2557
2552
"w" ,
2558
2553
newline = "\n " ,
2559
2554
) as f :
2560
- f .write (self .generate_header_test (header ))
2555
+ f .write (self .generate_header_test_file (header ))
2561
2556
2562
2557
2563
2558
def main ():
0 commit comments