Subroutine GetWords in NWTC_IO - not accepting spaces in file path [FAST 3.5.3]

Hi,
I have noticed that the latest FAST code has replaced all the ReadVar subroutine calls with ParseVar - which inturn calls GetWords.
This routine separates the first two words based on the delimiters, but if it encounters a “space” in the file path even if it is enclosed within " " - this considers it as a word. Previously the ReadVar subroutine seems more forgiving in this regard.
I think supporting space within file path would be a good idea considering backward compatibility…

Thank you,
Ashok

Ashok,

I agree that GetWords doesn’t properly handle quoted strings, it assumes that the text inside the quotes doesn’t contain spaces. ParseChVar, which calls GetWords also assumes that the words are less than 200 characters, which seems insufficient for file paths.

I’ll create an issue on GitHub and we’ll try to get it resolved in v3.5.5. Until then, please don’t use paths which contain spaces.

Thanks,
Derek

Thanks @Derek.Slaughter for looking at this!

Bug report here: ParseVar doesn't handle quoted strings properly · Issue #2552 · OpenFAST/openfast · GitHub

Dear @Ashok.Jammi,

Is there a specific module you are having trouble with?

We have been converting various modules over to use a newer file reading and parsing method. So some modules still use the older parsing method with ReadVar, while others have had the newer parsing for a long time (AeroDyn primary input file was changed over in May of 2021 with version 2.6.0).

I do agree that this is something we should address.

Regards,
Andy

Hi,
I was trying to use AeroDyn_Driver_Subs, that’s when I faced this issue.
Thanks for your response @Andy.Platt and @Derek.Slaughter

Regards,
Ashok

Hi @Andy.Platt and @Derek.Slaughter
The following modification to the GetWords routine resolved the issue for me.

SUBROUTINE GetWords ( Line, Words, NumWords, NumFound )

      ! Argument declarations.

   INTEGER, INTENT(IN)            :: NumWords                                     !< The maximum number of words to look for (and size of Words)

   CHARACTER(*), INTENT(IN)       :: Line                                         !< The string to search.
   CHARACTER(*), INTENT(OUT)      :: Words(NumWords)                              !< The array of found words.
   INTEGER, OPTIONAL, INTENT(OUT) :: NumFound                                     !< The number of words found

      ! Local declarations.

   INTEGER                        :: Ch                                           ! Character position within the string.
   INTEGER                        :: IW                                           ! Word index.
   INTEGER                        :: NextWhite                                    ! The location of the next whitespace in the string.
   CHARACTER(1)                   :: CurrentChar



      ! Let's prefill the array with blanks.

   DO IW=1,NumWords
      Words(IW) = ' '
   END DO ! IW

   IW = 0
   Ch = 0 
   
      ! Let's make sure we have text on this line.

   IF ( LEN_TRIM( Line ) > 0 )  THEN
       
       DO
           CurrentChar = Line(Ch+1:Ch+1)
           IF(CurrentChar == '"') THEN
               NextWhite = INDEX(Line(Ch+2:), '"') + 1
               IF(NextWhite > 1) THEN
                   IW = IW + 1
                   Words(IW) = Line(Ch+2:Ch+NextWhite-1)
                   Ch = Ch + NextWhite
               ELSE
                   EXIT
               END IF
           ELSE IF (Ch > 500) THEN
               EXIT
           ELSE
               NextWhite = SCAN( Line(Ch+1:) , ' ,;''"'//Tab )
               IF ( NextWhite > 1 )  THEN
                   IW   = IW + 1
                   Words(IW) = Line(Ch+1:Ch+NextWhite-1)
                   Ch = Ch + NextWhite
                   if (NextWhite > len(words(iw)) ) then 
                       call ProgWarn('Error reading field from file. There are too many characters in the input file to store in the field. Value may be truncated.') 
                       
                   end if               

               ELSE IF ( NextWhite == 1 )  THEN
                   Ch = Ch + 1
                   CYCLE
               ELSE
                   EXIT
               END IF
               
           END IF            
               
           IF ( IW == NumWords )  EXIT
       END DO
   END IF
   
               
           
      
   
   IF (PRESENT(NumFound)) NumFound = IW
         
   RETURN
   END SUBROUTINE GetWords

Please see if it helps.

Thank you,
Ashok

Ashok,

Unfortunately, there are a lot of input files that depend on the existing behavior of GetWords so the fix is a little more complicated. I’ve made modifications to address this in my branch of OpenFAST if you wouldn’t mind giving it a try: GitHub - deslaughter/openfast at b/GetWords_quotes. This branch is based on rc-3.5.5.

Thanks,
Derek