C$Procedure GETTKN ( MPFPEF, extract tokens from data string ) SUBROUTINE GETTKN ( LINE, HLINE, SPACE, N, TOKENS, SUFFIX ) C$ Abstract C C This subroutine parses input string and extracts all comma C delimited tokens from it. C C$ Copyright C C Copyright (1999), California Institute of Technology. C U.S. Government sponsorship acknowledged. C C$ Required_Reading C C None. C C$ Keywords C C None. C C$ Declarations CHARACTER*(*) LINE CHARACTER*(*) HLINE INTEGER SPACE INTEGER N CHARACTER*(*) TOKENS (*) CHARACTER*(*) SUFFIX C$ Brief_I/O C C Variable I/O Description C -------- --- -------------------------------------------------- C LINE I Input character string. C HLINE I Work space string. C SPACE I Maximum number of token that can be saved. C N O Number of tokens extracted from the string. C TOKENS O Array containing tokens. C SUFFIX O Suffix string. C C$ Detailed_Input C C Not provided yet. C C$ Detailed_Output C C Not provided yet. C C$ Parameters C C None. C C$ Exceptions C C 1) If semicolon is missing at the end of the string then C an error SPICE(MISSINGEOLMARKER) is reported. C C 2) If not enough space in output array to store all extracted C tokens then an error SPICE(OUTOFSPACE) is reported. C C$ Files C C None. C C$ Particulars C C Input string may contain a number of the following types of C tokens C C "simple token" C "type 1 list token" C "type 2 list token" C C delimited by commas (",") in any order. String must end C with ";". There could be an additonal text after ";". If it's C present, it's considered to be suffix on which no parsing C should be done. C C "Simple token" is a character string that doesn't contain C commas (","), brackets ("(" and ")") and square brackets. C For example: C Rover_MAE803$1NTE or CAMERA_DEPLOY=UNDEPLOYED C C "Type 1 list token" is a character string that contains C a list of comma delimited value enclosed in brackets. C For example: C (1,0,80,31,0,20,....,33) C C "Type 1 list token" is a character string that contains C a list of comma delimited value enclosed in square brackets. C For example: C act_seq=[SURFCE26,SURFCE28,SURFCE17,NULL,NULL] C C$ Examples C C Some valid examples of input string and corresponding output C tokens: C C 1) INPUT: SSC,HGA_D/L_3-3392$13CMD,300,60,2,14; <>; C TOKENS: SSC C HGA_D/L_3-3392$13CMD C 300 C 60 C 2 C 14 C SUFFIX: <>; C C 2) INPUT: SSC,HGA_D/L_3-3392$14CMD,9,42,(1,0,80,31,...6,33); C TOKENS: SSC C HGA_D/L_3-3392$14CMD C 9 C 42 C (1,0,80,31,...6,33) C NO SUFFIX C C 3) INPUT: act_seq=[SURFCE26,NULL,NULL],act_count=6; <<...>>; C TOKENS: act_seq=[SURFCE26,NULL,NULL] C act_count=6 C SUFFIX: <<...>>; C C$ Restrictions C C Not described yet. C C$ Literature_References C C None. C C$ Author_and_Institution C C B.V. Semenov (JPL) C C$ Version C C- Beta Version 2.0.0, 12-MAY-1999 (NVS) C C Added suffix to argument list. Made processing more C efficient. C C- Beta Version 1.0.0, 07-OCT-1996 (NVS) C C-& C C SPICELIB functions C LOGICAL RETURN INTEGER POS INTEGER RTRIM INTEGER LTRIM C C Local variables C INTEGER HINT INTEGER CMMPOS INTEGER LBRPOS INTEGER LSBPOS INTEGER LFTPOS INTEGER RHTPOS INTEGER START C C Standard SPICE error handling. C IF ( RETURN () ) THEN RETURN ELSE CALL CHKIN ( 'GETTKN' ) END IF C C Look for end-of-line marker and modify line depending C on the marker position. C START = LTRIM ( LINE ) HINT = POS ( LINE( START : ), ';', 1 ) IF ( HINT .GT. 1 ) THEN C C Check whether we have suffix. C IF ( RTRIM( LINE( START : ) ) .NE. HINT ) THEN SUFFIX = LINE( START+HINT : ) ELSE SUFFIX = ' ' END IF C C Replace end-of-pef-line marker, ";", with "," and C clear LINE after it. C LINE( START+HINT : ) = ' ' LINE( START-1+HINT : START-1+HINT ) = ',' ELSE IF ( HINT .EQ. 1 ) THEN LINE( START-1+HINT : START-1+HINT ) = ',' ELSE C C No end-of-line marker was found. Report an error in this case. C CALL DLTEEK CALL SETMSG ( 'The end of line marker '';'' was not found ' // . 'on the line ''#'' ...' ) CALL ERRCH ( '#', LINE(:132) ) CALL SIGERR ( 'SPICE(MISSINGEOLMARKER)' ) END IF C C Process LINE. Pull out tokens separated by commas. Do it until C comma cannot be found anymore. Save each token in the next C element of the array. C N = 0 CMMPOS = POS ( LINE( START : ), ',', 1 ) DO WHILE( CMMPOS .NE. 0 ) C C First we look whether next token is the list. Lists of values C separated by commas are enclosed into brackets, round of C square. So if right bracket goes before comma, then here it C is. C LBRPOS = POS ( LINE( START : ), '(', 1 ) LSBPOS = POS ( LINE( START : ), '[', 1 ) IF ( LBRPOS .EQ. 0 ) THEN IF ( LSBPOS .EQ. 0 ) THEN LFTPOS = 0 ELSE LFTPOS = LSBPOS END IF ELSE IF ( LSBPOS .EQ. 0 ) THEN LFTPOS = LBRPOS ELSE LFTPOS = MIN ( LSBPOS, LBRPOS ) END IF END IF C C Now we know nearest left bracket position. We compare it to C nearest comma position C IF ( LFTPOS .NE. 0 .AND. LFTPOS .LT. CMMPOS ) THEN C C Current token is a list. Find right bracket and grab C everything between them. After that left-justify the C rest of the line. C IF ( LFTPOS .EQ. LSBPOS ) THEN RHTPOS = POS ( LINE( START : ), ']', 1 ) ELSE RHTPOS = POS ( LINE( START : ), ')', 1 ) END IF C C We also need to know the position of the comma that follows C right bracket. And we will save everything before this C comma. C CMMPOS = POS ( LINE( START : ), ',', RHTPOS ) HLINE = LINE ( START : START-1+CMMPOS-1 ) LINE( START : START+CMMPOS-1 ) = ' ' START = LTRIM ( LINE ) ELSE C C Current token is not a list. Pull it out and C left-justify the rest of the line. C IF ( CMMPOS .GT. 1 ) THEN C C Current token is not blank. So we get and save it. C HLINE = LINE( START : START-1+CMMPOS-1 ) LINE( START : START+CMMPOS-1 ) = ' ' START = LTRIM( LINE ) ELSE C C Current token is blank, something like that C '..,prev_token,,next_token,.'. C HLINE = ' ' LINE( START : START ) = ' ' START = LTRIM( LINE ) END IF END IF C C Save current token. C IF ( N + 1 .LE. SPACE ) THEN N = N + 1 TOKENS( N ) = HLINE ELSE C C Cannot store current token. Signal an error. C CALL DLTEEK CALL SETMSG ( 'Not enough space in the input array to ' // . 'store all tokens in the line # ...' ) CALL ERRCH ( '#', LINE(:132) ) CALL SIGERR ( 'SPICE(OUTOFSPACE)' ) END IF C C Look for the next comma. C CMMPOS = POS( LINE( START : ), ',', 1 ) END DO CALL CHKOUT ( 'GETTKN' ) RETURN END