@@ -44,8 +44,7 @@ bool IODEF(OutputNamelist)(Cookie cookie, const NamelistGroup &group) {
44
44
if ((connection.NeedAdvance (prefixLen) &&
45
45
!(io.AdvanceRecord () && EmitAscii (io, " " , 1 ))) ||
46
46
!EmitAscii (io, prefix, prefixLen) ||
47
- (connection.NeedAdvance (
48
- Fortran::runtime::strlen (str) + (suffix != ' ' )) &&
47
+ (connection.NeedAdvance (runtime::strlen (str) + (suffix != ' ' )) &&
49
48
!(io.AdvanceRecord () && EmitAscii (io, " " , 1 )))) {
50
49
return false ;
51
50
}
@@ -102,8 +101,8 @@ static constexpr RT_API_ATTRS char NormalizeIdChar(char32_t ch) {
102
101
return static_cast <char >(ch >= ' A' && ch <= ' Z' ? ch - ' A' + ' a' : ch);
103
102
}
104
103
105
- static RT_API_ATTRS bool GetLowerCaseName (
106
- IoStatementState &io, char buffer[], std::size_t maxLength) {
104
+ static RT_API_ATTRS bool GetLowerCaseName (IoStatementState &io, char buffer[],
105
+ std::size_t maxLength, bool crashIfTooLong = true ) {
107
106
std::size_t byteLength{0 };
108
107
if (auto ch{io.GetNextNonBlank (byteLength)}) {
109
108
if (IsLegalIdStart (*ch)) {
@@ -117,8 +116,10 @@ static RT_API_ATTRS bool GetLowerCaseName(
117
116
if (j <= maxLength) {
118
117
return true ;
119
118
}
120
- io.GetIoErrorHandler ().SignalError (
121
- " Identifier '%s...' in NAMELIST input group is too long" , buffer);
119
+ if (crashIfTooLong) {
120
+ io.GetIoErrorHandler ().SignalError (
121
+ " Identifier '%s...' in NAMELIST input group is too long" , buffer);
122
+ }
122
123
}
123
124
}
124
125
return false ;
@@ -356,9 +357,8 @@ static RT_API_ATTRS bool HandleComponent(IoStatementState &io, Descriptor &desc,
356
357
const DescriptorAddendum *addendum{source.Addendum ()};
357
358
if (const typeInfo::DerivedType *
358
359
type{addendum ? addendum->derivedType () : nullptr }) {
359
- if (const typeInfo::Component *
360
- comp{type->FindDataComponent (
361
- compName, Fortran::runtime::strlen (compName))}) {
360
+ if (const typeInfo::Component *comp{
361
+ type->FindDataComponent (compName, runtime::strlen (compName))}) {
362
362
bool createdDesc{false };
363
363
if (comp->rank () > 0 && source.rank () > 0 ) {
364
364
// If base and component are both arrays, the component name
@@ -484,7 +484,7 @@ bool IODEF(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
484
484
handler.SignalError (" NAMELIST input group has no name" );
485
485
return false ;
486
486
}
487
- if (Fortran:: runtime::strcmp (group.groupName , name) == 0 ) {
487
+ if (runtime::strcmp (group.groupName , name) == 0 ) {
488
488
break ; // found it
489
489
}
490
490
SkipNamelistGroup (io);
@@ -503,7 +503,7 @@ bool IODEF(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
503
503
}
504
504
std::size_t itemIndex{0 };
505
505
for (; itemIndex < group.items ; ++itemIndex) {
506
- if (Fortran:: runtime::strcmp (name, group.item [itemIndex].name ) == 0 ) {
506
+ if (runtime::strcmp (name, group.item [itemIndex].name ) == 0 ) {
507
507
break ;
508
508
}
509
509
}
@@ -577,13 +577,14 @@ bool IODEF(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
577
577
if (const auto *addendum{useDescriptor->Addendum ()};
578
578
addendum && addendum->derivedType ()) {
579
579
const NonTbpDefinedIoTable *table{group.nonTbpDefinedIo };
580
- listInput->ResetForNextNamelistItem (/* inNamelistSequence= */ true );
580
+ listInput->ResetForNextNamelistItem (&group );
581
581
if (!IONAME (InputDerivedType)(cookie, *useDescriptor, table) &&
582
582
handler.InError ()) {
583
583
return false ;
584
584
}
585
585
} else {
586
- listInput->ResetForNextNamelistItem (useDescriptor->rank () > 0 );
586
+ listInput->ResetForNextNamelistItem (
587
+ useDescriptor->rank () > 0 ? &group : nullptr );
587
588
if (!descr::DescriptorIO<Direction::Input>(io, *useDescriptor) &&
588
589
handler.InError ()) {
589
590
return false ;
@@ -607,27 +608,51 @@ bool IODEF(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
607
608
}
608
609
609
610
RT_API_ATTRS bool IsNamelistNameOrSlash (IoStatementState &io) {
610
- if (auto *listInput{
611
- io.get_if <ListDirectedStatementState<Direction::Input>>()}) {
612
- if (listInput->inNamelistSequence ()) {
613
- SavedPosition savedPosition{io};
614
- std::size_t byteCount{0 };
615
- if (auto ch{io.GetNextNonBlank (byteCount)}) {
616
- if (IsLegalIdStart (*ch)) {
617
- do {
618
- io.HandleRelativePosition (byteCount);
619
- ch = io.GetCurrentChar (byteCount);
620
- } while (ch && IsLegalIdChar (*ch));
621
- ch = io.GetNextNonBlank (byteCount);
622
- // TODO: how to deal with NaN(...) ambiguity?
623
- return ch && (*ch == ' =' || *ch == ' (' || *ch == ' %' );
624
- } else {
625
- return *ch == ' /' || *ch == ' &' || *ch == ' $' ;
626
- }
627
- }
611
+ auto *listInput{io.get_if <ListDirectedStatementState<Direction::Input>>()};
612
+ if (!listInput || !listInput->namelistGroup ()) {
613
+ return false ; // not namelist
614
+ }
615
+ SavedPosition savedPosition{io};
616
+ std::size_t byteCount{0 };
617
+ auto ch{io.GetNextNonBlank (byteCount)};
618
+ if (!ch) {
619
+ return false ;
620
+ } else if (!IsLegalIdStart (*ch)) {
621
+ return *ch == ' /' || *ch == ' &' || *ch == ' $' ;
622
+ }
623
+ char id[nameBufferSize];
624
+ if (!GetLowerCaseName (io, id, sizeof id, /* crashIfTooLong=*/ false )) {
625
+ return true ; // long name
626
+ }
627
+ // It looks like a name, but might be "inf" or "nan". Check what
628
+ // follows.
629
+ ch = io.GetNextNonBlank (byteCount);
630
+ if (!ch) {
631
+ return false ;
632
+ } else if (*ch == ' =' || *ch == ' %' ) {
633
+ return true ;
634
+ } else if (*ch != ' (' ) {
635
+ return false ;
636
+ } else if (runtime::strcmp (id, " nan" ) != 0 ) {
637
+ return true ;
638
+ }
639
+ // "nan(" ambiguity
640
+ int depth{1 };
641
+ while (true ) {
642
+ io.HandleRelativePosition (byteCount);
643
+ ch = io.GetNextNonBlank (byteCount);
644
+ if (depth == 0 ) {
645
+ // nan(...) followed by '=', '%', or '('?
646
+ break ;
647
+ } else if (!ch) {
648
+ return true ; // not a valid NaN(...)
649
+ } else if (*ch == ' (' ) {
650
+ ++depth;
651
+ } else if (*ch == ' )' ) {
652
+ --depth;
628
653
}
629
654
}
630
- return false ;
655
+ return ch && (*ch == ' = ' || *ch == ' % ' || *ch == ' ( ' ) ;
631
656
}
632
657
633
658
RT_OFFLOAD_API_GROUP_END
0 commit comments