C----------------------------------------------------------------------- PROGRAM PEFFMT C----------------------------------------------------------------------- C C A simple PEF file parser and reader. C C May be used as a starting point for a PEF converter. C C Language: FORTRAN 77 C C Created: 20.4.1996 Martin Hepperle C C----------------------------------------------------------------------- INTEGER IUNIT, IRET, ILEN, ILPT INTEGER ISETS, IS, IPOLAR, IP, IPOINT, IPT REAL REYNO CHARACTER*128 CNAME CHARACTER*128 CPOINT CHARACTER*32 CSET CHARACTER*32 CVAL C block header for set 1001 FORMAT ( 'Set', I1 ) 1002 FORMAT ( 'Set', I2 ) C block header for polar 1011 FORMAT ( 'Set', I1, '-Polar', I1 ) 1021 FORMAT ( 'Set', I2, '-Polar', I1 ) 1012 FORMAT ( 'Set', I1, '-Polar', I2 ) 1022 FORMAT ( 'Set', I2, '-Polar', I2 ) C key for data point 1010 FORMAT ( 'Value', I2.2 ) C open the PEF file IUNIT = 10 OPEN ( IUNIT, FILE='MH32.PEF', STATUS='OLD' ) C locate at start of [Airfoil] block to lookup a key-value pair IRET = ILBLOK ( IUNIT, 'Airfoil', 7 ) IF ( IRET .NE. 1 ) THEN write (6,*) ' *** Cannot locate Airfoil block.' write (6,*) ' Probably no PEF file..' GO TO 600 END IF C we have to use a variable for ILEN, because IGTKEY adjusts C the value to the actual length of the key's value. ILEN = 128 IRET = IGTKEY ( IUNIT, 'Description1', 12, CNAME, ILEN ) C locate at start of block again to lookup next key-value pair IRET = ILBLOK ( IUNIT, 'Airfoil', 7 ) IRET = IGTINT ( IUNIT, 'NumberSets', 10, ISETS ) write (6,*) 'Airfoil: ', CNAME(1:ILEN) write (6,*) 'Number of Sets:', ISETS C --- Loop over all sets in this file: -- DO 400 IS=1,ISETS,1 IF ( IS .LT. 10 ) THEN WRITE ( CSET, 1001 ) IS ILEN = 4 ELSE WRITE ( CSET, 1002 ) IS ILEN = 5 END IF C locate at start of block to lookup next key-value pair IRET = ILBLOK ( IUNIT, CSET, ILEN ) IRET = IGTINT ( IUNIT, 'NumberPolars', 12, IPOLAR ) IF ( IRET .NE. 1 ) THEN write (6,*) ' *** Cannot read number of polars.' GO TO 600 END IF write (6,*) 'Set:', IS write (6,*) ' Number of Polars:', IPOLAR C --- Loop over all polars in this set: --- DO 300 IP=1,IPOLAR IF ( IS .LT. 10 ) THEN IF ( IP .LT. 10 ) THEN WRITE ( CSET, 1011 ) IS, IP ILEN = 9+2 ELSE WRITE ( CSET, 1012 ) IS, IP ILEN = 9+3 END IF ELSE IF ( IP .LT. 10 ) THEN WRITE ( CSET, 1021 ) IS, IP ILEN = 9+3 ELSE WRITE ( CSET, 1022 ) IS, IP ILEN = 9+4 END IF END IF IRET = ILBLOK ( IUNIT, CSET, ILEN ) IF ( IRET .NE. 1 ) THEN write (6,*) ' *** Cannot locate polar in set.' GO TO 600 END IF IRET = IGTINT ( IUNIT, 'NumberPoints', 12, IPOINT ) C we have to locate the start of the block again, C to make sure that we are independant of sequence: IRET = ILBLOK ( IUNIT, CSET, ILEN ) IRET = IGTFLT ( IUNIT, 'ReynoldsNumber', 14, REYNO ) write (6,*) ' Polar:', IP write (6,*) ' Number of Points:', IPOINT write (6,*) ' Reynolds Number: ', REYNO C --- Loop over all points in this polar: --- DO 200 IPT=1,IPOINT,1 IRET = ILBLOK ( IUNIT, CSET, ILEN ) WRITE ( CVAL, 1010 ) IPT ILPT = 128 IRET = IGTKEY ( IUNIT, CVAL, 7, CPOINT, ILPT ) IF ( IRET .NE. 1 ) THEN write (6,*) ' *** Cannot locate point in polar.' GO TO 600 END IF write(6,*) CPOINT(1:ILPT) C here the data points should be parsed into an array, C - this is left to the reader as an execise in C FORTRAN programming... C -> next data point in polar 200 CONTINUE C -> next polar in set 300 CONTINUE C -> next set 400 CONTINUE 600 CONTINUE CLOSE ( IUNIT ) END C----------------------------------------------------------------------- INTEGER FUNCTION ILBLOK ( IUNIT, CBLTIT, IBLLEN ) C----------------------------------------------------------------------- C C locates a specified block in a file C C IUNIT ... file C CBLTIT ... block name C IBLLEN ... length of block name (no. of characters) C C----------------------------------------------------------------------- C Parameters INTEGER IUNIT, IBLLEN CHARACTER *(*) CBLTIT C Multipurpose buffer CHARACTER*255 CBUF COMMON /BUFFER/ CBUF C----------------------------------------------------------------------- REWIND ( IUNIT ) 100 CONTINUE READ ( IUNIT, '(A255)', ERR=300, END=400 ) CBUF IF ( CBUF(1:1) .EQ. '[' ) THEN IF ( CBUF(2:1+IBLLEN) .EQ. CBLTIT .AND. & CBUF(2+IBLLEN:2+IBLLEN) .EQ. ']' ) THEN C Block header found. GO TO 200 END IF ENDIF C GO ON GO TO 100 C Successful! 200 CONTINUE ILBLOK = 1 RETURN 300 CONTINUE ILBLOK = -1 RETURN 400 CONTINUE ILBLOK = -2 RETURN END C----------------------------------------------------------------------- C----------------------------------------------------------------------- INTEGER FUNCTION IGTKEY ( IUNIT, CKEY, IKEYLN, CVALUE, IVALLN ) C----------------------------------------------------------------------- C C Gets the value of the specified key from a file. C The value is returned in the string buffer CVALUE. C IVALLN is adjusted to the length of the string. C The equal sign can be separated by spaces from key name C i.e. "KEY=" or "KEY =". Following spaces are assumed to be C part of the key's value. C C Returns: C - 1 on success C -3 if a read error occured C -2 if end of file was reached C -3 if block was not found C - the value of the key via argument CVALUE C - the length of the value of the key via argument IVALLN C C (I ... input) C (O ... output) C IUNIT ... (I) file C CKEY ... (I) key name C IKEYLN ... (I) length of key name (no. of characters) C CVALUE ... (O) value corresponding to CKEY C IVALLN ... (I/O) length of key value (no. of characters) C C----------------------------------------------------------------------- C Parameters INTEGER IUNIT, IKEYLN, IVALLN CHARACTER *(*) CKEY, CVALUE C Multipurpose buffer CHARACTER*255 CBUF COMMON /BUFFER/ CBUF C----------------------------------------------------------------------- 100 CONTINUE READ ( IUNIT, '(A255)', ERR=300, END=400 ) CBUF IF ( CBUF(1:IKEYLN) .EQ. CKEY ) THEN IF ( CBUF(1+IKEYLN:1+IKEYLN) .EQ. ' ' ) THEN C space found, skip all following spaces DO 110 IEQUAL=1+IKEYLN, 255-1, 1 IF ( CBUF(IEQUAL:IEQUAL) .NE. ' ' ) THEN C break that loop GO TO 115 END IF 110 CONTINUE C non space character or end of buffer found 115 CONTINUE ELSE IEQUAL = 1+IKEYLN END IF IF ( CBUF(IEQUAL:IEQUAL) .EQ. '=' ) THEN C Key found. ILEN = MIN(IVALLN,255) CVALUE = CBUF(2+IKEYLN:ILEN) IVALLN = IRTRIM ( CVALUE, ILEN ) GO TO 200 END IF ELSE IF ( CBUF(1:1) .EQ. ']' ) THEN C next block begins here GO TO 500 END IF C GO ON GO TO 100 C Successful! 200 CONTINUE IGTKEY = 1 RETURN 300 CONTINUE IGTKEY = -1 RETURN 400 CONTINUE IGTKEY = -2 RETURN 500 CONTINUE C key not found IGTKEY = -3 RETURN END C----------------------------------------------------------------------- C----------------------------------------------------------------------- INTEGER FUNCTION IRTRIM ( CBUFF, ILEN ) C C Right Trim function for strings. C Replaces trailing blanks with ASCII(0) characters. C C Returns: C - the length of the trimmed string C - the trimmed string via argument CBUFF C C (I ... input) C (O ... output) C CBUFF ... (I/O) string, may have trailing blanks C ILEN ... (I) length of string (no. of characters) C----------------------------------------------------------------------- C Parameters: CHARACTER *(*) CBUFF INTEGER ILEN C----------------------------------------------------------------------- DO 100 I=ILEN,1,-1 IF ( CBUFF(I:I) .EQ. ' ' ) THEN CBUFF(I:I) = CHAR(0) ELSE GO TO 200 END IF 100 CONTINUE 200 CONTINUE IRTRIM = I RETURN END C----------------------------------------------------------------------- C----------------------------------------------------------------------- INTEGER FUNCTION IGTINT ( IUNIT, CKEY, IKEYLN, IVALUE ) C C Reads a integer (INTEGER) value IVALUE corresponding to C the given key CKEY from the file adressed by IUNIT. C C Returns: C - 1 on success, -ERR otherwise (see IGTKEY()) C - the read value via argument IVALUE C C (I ... input) C (O ... output) C IUNIT ... (I) file C CKEY ... (I) key name C IKEYLN ... (I) length of key name (no. of characters) C IVALUE ... (O) integer value corresponding to CKEY C C----------------------------------------------------------------------- C Parameters INTEGER IUNIT, IKEYLN, IVALUE CHARACTER *(*) CKEY C local variables: CHARACTER*32 BUFFER, FORM 1001 FORMAT ( '(I', I1, ')' ) 1002 FORMAT ( '(I', I2, ')' ) ILEN = 32 IRET = IGTKEY ( IUNIT, CKEY, IKEYLN, BUFFER, ILEN ) IF ( IRET .EQ. 1 ) THEN IF ( ILEN .LT. 10 ) THEN WRITE ( FORM, 1001 ) ILEN ELSE WRITE ( FORM, 1002 ) ILEN END IF READ(BUFFER(1:ILEN),FORM) IVALUE END IF IGTINT = IRET RETURN END C----------------------------------------------------------------------- C----------------------------------------------------------------------- INTEGER FUNCTION IGTFLT ( IUNIT, CKEY, IKEYLN, FVALUE ) C C Reads a floating point (REAL) value FVALUE corresponding to C the given key CKEY from the file adressed by IUNIT. C C Returns: C - 1 on success, -ERR otherwise (see IGTKEY()) C - the read value via argument FVALUE C C (I ... input) C (O ... output) C IUNIT ... (I) file C CKEY ... (I) key name C IKEYLN ... (I) length of key name (no. of characters) C FVALUE ... (O) REAL value corresponding to CKEY C C----------------------------------------------------------------------- C Parameters INTEGER IUNIT, IKEYLN REAL FVALUE CHARACTER *(*) CKEY C local variables: CHARACTER*32 BUFFER, FORM 1001 FORMAT ( '(F', I1, '.0)' ) 1002 FORMAT ( '(F', I2, '.0)' ) ILEN = 32 IRET = IGTKEY ( IUNIT, CKEY, IKEYLN, BUFFER, ILEN ) IF ( IRET .EQ. 1 ) THEN IF ( ILEN .LT. 10 ) THEN WRITE ( FORM, 1001 ) ILEN ELSE WRITE ( FORM, 1002 ) ILEN END IF READ(BUFFER(1:ILEN),FORM) FVALUE END IF IGTFLT = IRET RETURN END C----------------------------------------------------------------------- C----------------------------------------------------------------------- C----------------------------- END OF FILE ----------------------------- C----------------------------------------------------------------------- IF READ(BUFFER(1:ILEN),FORM) FVALUE END IF IGTFLT = IRET RETURN END C----------------------------------------------------------------------- C----------------------------------------------------------------------- C----------------------------- END OF FILE ----------------------------- C-----------------------------------------------------------------------