@@ -700,16 +700,12 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
700
700
ezxml_t nmlrecs_xml , nmlopt_xml ;
701
701
702
702
const char * const_core ;
703
- const char * nmlrecname , * nmlrecindef , * nmlrecinsub ;
704
- const char * nmloptname , * nmlopttype , * nmloptval , * nmloptunits , * nmloptdesc , * nmloptposvals , * nmloptindef ;
703
+ const char * original_nmlrecname , * nmlrecindef , * nmlrecinsub ;
704
+ const char * original_nmloptname , * nmlopttype , * nmloptval , * nmloptunits , * nmloptdesc , * nmloptposvals , * nmloptindef ;
705
705
706
- #ifdef MPAS_CAM_DYCORE
707
706
// Fortran variable names have a length limit of 63 characters. + 1 for the terminating null character.
708
- char new_nmlrecname [64 ];
709
- char new_nmloptname [64 ];
710
- const char * old_nmlrecname ;
711
- const char * old_nmloptname ;
712
- #endif
707
+ char nmlrecname [64 ];
708
+ char nmloptname [64 ];
713
709
714
710
char pool_name [1024 ];
715
711
char core_string [1024 ];
@@ -755,14 +751,9 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
755
751
756
752
// Parse Namelist Records
757
753
for (nmlrecs_xml = ezxml_child (registry , "nml_record" ); nmlrecs_xml ; nmlrecs_xml = nmlrecs_xml -> next ){
758
- #ifdef MPAS_CAM_DYCORE
759
- old_nmlrecname = ezxml_attr (nmlrecs_xml , "name" );
760
- transform_name (new_nmlrecname , sizeof (new_nmlrecname ), old_nmlrecname );
754
+ original_nmlrecname = ezxml_attr (nmlrecs_xml , "name" );
755
+ mangle_name (nmlrecname , sizeof (nmlrecname ), original_nmlrecname );
761
756
762
- nmlrecname = new_nmlrecname ;
763
- #else
764
- nmlrecname = ezxml_attr (nmlrecs_xml , "name" );
765
- #endif
766
757
nmlrecindef = ezxml_attr (nmlrecs_xml , "in_defaults" );
767
758
nmlrecinsub = ezxml_attr (nmlrecs_xml , "in_subpool" );
768
759
@@ -796,14 +787,9 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
796
787
797
788
// Define variable definitions prior to reading the namelist in.
798
789
for (nmlopt_xml = ezxml_child (nmlrecs_xml , "nml_option" ); nmlopt_xml ; nmlopt_xml = nmlopt_xml -> next ){
799
- #ifdef MPAS_CAM_DYCORE
800
- old_nmloptname = ezxml_attr (nmlopt_xml , "name" );
801
- transform_name (new_nmloptname , sizeof (new_nmloptname ), old_nmloptname );
790
+ original_nmloptname = ezxml_attr (nmlopt_xml , "name" );
791
+ mangle_name (nmloptname , sizeof (nmloptname ), original_nmloptname );
802
792
803
- nmloptname = new_nmloptname ;
804
- #else
805
- nmloptname = ezxml_attr (nmlopt_xml , "name" );
806
- #endif
807
793
nmlopttype = ezxml_attr (nmlopt_xml , "type" );
808
794
nmloptval = ezxml_attr (nmlopt_xml , "default_value" );
809
795
nmloptunits = ezxml_attr (nmlopt_xml , "units" );
@@ -835,14 +821,9 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
835
821
// Define the namelist block, to read the namelist record in.
836
822
fortprintf (fd , " namelist /%s/ &\n" , nmlrecname );
837
823
for (nmlopt_xml = ezxml_child (nmlrecs_xml , "nml_option" ); nmlopt_xml ; nmlopt_xml = nmlopt_xml -> next ){
838
- #ifdef MPAS_CAM_DYCORE
839
- old_nmloptname = ezxml_attr (nmlopt_xml , "name" );
840
- transform_name (new_nmloptname , sizeof (new_nmloptname ), old_nmloptname );
824
+ original_nmloptname = ezxml_attr (nmlopt_xml , "name" );
825
+ mangle_name (nmloptname , sizeof (nmloptname ), original_nmloptname );
841
826
842
- nmloptname = new_nmloptname ;
843
- #else
844
- nmloptname = ezxml_attr (nmlopt_xml , "name" );
845
- #endif
846
827
if (nmlopt_xml -> next ){
847
828
fortprintf (fd , " %s, &\n" , nmloptname );
848
829
} else {
@@ -873,14 +854,9 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
873
854
// Define broadcast calls for namelist values.
874
855
fortprintf (fd , " if (ierr <= 0) then\n" );
875
856
for (nmlopt_xml = ezxml_child (nmlrecs_xml , "nml_option" ); nmlopt_xml ; nmlopt_xml = nmlopt_xml -> next ){
876
- #ifdef MPAS_CAM_DYCORE
877
- old_nmloptname = ezxml_attr (nmlopt_xml , "name" );
878
- transform_name (new_nmloptname , sizeof (new_nmloptname ), old_nmloptname );
857
+ original_nmloptname = ezxml_attr (nmlopt_xml , "name" );
858
+ mangle_name (nmloptname , sizeof (nmloptname ), original_nmloptname );
879
859
880
- nmloptname = new_nmloptname ;
881
- #else
882
- nmloptname = ezxml_attr (nmlopt_xml , "name" );
883
- #endif
884
860
nmlopttype = ezxml_attr (nmlopt_xml , "type" );
885
861
886
862
if (strncmp (nmlopttype , "real" , 1024 ) == 0 ){
@@ -898,14 +874,9 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
898
874
fortprintf (fd , " call mpas_log_write(' The following values will be used for variables in this record:')\n" );
899
875
fortprintf (fd , " call mpas_log_write(' ')\n" );
900
876
for (nmlopt_xml = ezxml_child (nmlrecs_xml , "nml_option" ); nmlopt_xml ; nmlopt_xml = nmlopt_xml -> next ){
901
- #ifdef MPAS_CAM_DYCORE
902
- old_nmloptname = ezxml_attr (nmlopt_xml , "name" );
903
- transform_name (new_nmloptname , sizeof (new_nmloptname ), old_nmloptname );
877
+ original_nmloptname = ezxml_attr (nmlopt_xml , "name" );
878
+ mangle_name (nmloptname , sizeof (nmloptname ), original_nmloptname );
904
879
905
- nmloptname = new_nmloptname ;
906
- #else
907
- nmloptname = ezxml_attr (nmlopt_xml , "name" );
908
- #endif
909
880
nmlopttype = ezxml_attr (nmlopt_xml , "type" );
910
881
911
882
if (strncmp (nmlopttype , "character" , 1024 ) == 0 ) {
@@ -932,21 +903,12 @@ int parse_namelist_records_from_registry(ezxml_t registry)/*{{{*/
932
903
fortprintf (fd , "\n" );
933
904
934
905
for (nmlopt_xml = ezxml_child (nmlrecs_xml , "nml_option" ); nmlopt_xml ; nmlopt_xml = nmlopt_xml -> next ){
935
- #ifdef MPAS_CAM_DYCORE
936
- old_nmloptname = ezxml_attr (nmlopt_xml , "name" );
937
- transform_name (new_nmloptname , sizeof (new_nmloptname ), old_nmloptname );
906
+ original_nmloptname = ezxml_attr (nmlopt_xml , "name" );
907
+ mangle_name (nmloptname , sizeof (nmloptname ), original_nmloptname );
938
908
939
- nmloptname = new_nmloptname ;
940
-
941
- // Keep namelist options to their original names in MPAS pools for compatibility reasons.
942
- fortprintf (fd , " call mpas_pool_add_config(%s, '%s', %s)\n" , pool_name , old_nmloptname , nmloptname );
943
- fortprintf (fcg , " call mpas_pool_get_config(configPool, '%s', %s)\n" , old_nmloptname , nmloptname );
944
- #else
945
- nmloptname = ezxml_attr (nmlopt_xml , "name" );
946
-
947
- fortprintf (fd , " call mpas_pool_add_config(%s, '%s', %s)\n" , pool_name , nmloptname , nmloptname );
948
- fortprintf (fcg , " call mpas_pool_get_config(configPool, '%s', %s)\n" , nmloptname , nmloptname );
949
- #endif
909
+ // Always keep namelist options to their original names in MPAS pools for compatibility reasons.
910
+ fortprintf (fd , " call mpas_pool_add_config(%s, '%s', %s)\n" , pool_name , original_nmloptname , nmloptname );
911
+ fortprintf (fcg , " call mpas_pool_get_config(configPool, '%s', %s)\n" , original_nmloptname , nmloptname );
950
912
}
951
913
fortprintf (fd , "\n" );
952
914
fortprintf (fcg , "\n" );
@@ -2592,15 +2554,36 @@ int parse_structs_from_registry(ezxml_t registry)/*{{{*/
2592
2554
}/*}}}*/
2593
2555
2594
2556
2595
- #ifdef MPAS_CAM_DYCORE
2596
- // Perform transformations for namelist group and option names.
2597
- void transform_name (char * new_name , const size_t new_name_size , const char * old_name )
2557
+ /**
2558
+ * mangle_name
2559
+ *
2560
+ * Perform name mangling for MPAS namelist groups and options, as appropriate, depending on the containing
2561
+ * host model.
2562
+ *
2563
+ * When MPAS is used as a dynamical core in a host model (e.g., CAM/CAM-SIMA), it needs to share
2564
+ * the namelist file with other model components. As a result, MPAS namelist groups and options may not
2565
+ * be easily recognizable at first sight. With the `MPAS_CAM_DYCORE` macro being defined, this function
2566
+ * adds a unique identifier to each MPAS namelist group and option name by performing the following
2567
+ * transformations:
2568
+ *
2569
+ * 1. Leading "config_" is removed recursively from the name. Case-insensitive.
2570
+ * 2. Leading "mpas_" is removed recursively from the name. Case-insensitive.
2571
+ * 3. Prepend "mpas_" to the name.
2572
+ *
2573
+ * By doing so, it is now easier to distinguish MPAS namelist groups and options from host model ones.
2574
+ * The possibility of name collisions with host model ones is also resolved once and for all.
2575
+ *
2576
+ * For stand-alone MPAS, where the `MPAS_CAM_DYCORE` macro is not defined, this function just returns
2577
+ * the name as is.
2578
+ */
2579
+ void mangle_name (char * new_name , const size_t new_name_size , const char * old_name )
2598
2580
{
2581
+ if (!new_name || !old_name || new_name_size == 0 ) return ;
2582
+
2583
+ #ifdef MPAS_CAM_DYCORE
2599
2584
const char * const new_prefix = "mpas_" ;
2600
2585
const char * const old_prefix = "config_" ;
2601
2586
2602
- if (!new_name || !old_name || new_name_size == 0 ) return ;
2603
-
2604
2587
// Remove all leading whitespaces by moving pointer forward.
2605
2588
while (* old_name != '\0' && isspace ((unsigned char ) * old_name )) old_name ++ ;
2606
2589
@@ -2616,5 +2599,7 @@ void transform_name(char *new_name, const size_t new_name_size, const char *old_
2616
2599
// Remove all trailing whitespaces by zeroing (nulling) out.
2617
2600
new_name += strlen (new_name ) - 1 ;
2618
2601
while (* new_name != '\0' && isspace ((unsigned char ) * new_name )) * new_name -- = '\0' ;
2619
- }
2602
+ #else
2603
+ snprintf (new_name , new_name_size , "%s" , old_name );
2620
2604
#endif
2605
+ }
0 commit comments