*&* PARSER.PRG *&* >L< * Lisa Slater Nicholls *&* January 1997 revision *&* Rename this file to a *.PRG for runnable code *&* Purpose: Get runnable lines of code from a memofield or *&* other text string, put into an array passed by reference *&* so that the calling program can execute code if it *&* qualifies under additionalconditions you specify *&* Refer to additional notes at the bottom of this file *&* for a sample calling program, comments, etc. PARAMETERS tcString, taLines *&* note: array passed by reference, see example call *&* in notes at the bottom of this file #DEFINE INLINECOMMENT CHR(38)+CHR(38) LOCAL lnIndex, lcThisLine, lcThisCmd, lnLines _MLINE = 0 lcThisLine = "" lcThisCmd = "" lnLines = 0 FOR lnIndex = 1 TO MEMLINES(tcString) lcThisLine = MLINE(tcString,1,_MLINE) IF EMPTY(lcThisLine) LOOP ENDIF lcThisCmd = lcThisCmd + " "+ lcThisLine lcThisCmd = ALLTRIM(lcThisCmd) IF RIGHT(lcThisCmd,1) = ";" lcThisCmd = SUBSTR(lcThisCmd,1,LEN(lcThisCmd)-1) LOOP ENDIF IF NOT (LEFT(lcThisCmd,1) = "*" ; OR LEFT(lcThisCmd,2) = INLINECOMMENT ; OR LEFT(UPPER(lcThisCmd),5) = "NOTE " ) IF INLINECOMMENT $ lcThisCmd lcThisCmd = LEFT(lcThisCmd,AT(INLINECOMMENT,lcThisCmd)-1) ENDIF lnLines = lnLines + 1 DIME taLines[lnLines] taLines[lnLines] = lcThisCmd ENDIF lcThisCmd = "" ENDFOR RETURN lnLines *&* note the use of _MLINE system variable for speed, *&* as well as attention to all comment types. *&* example call: *&* PRIVATE paLines *&* DIME paLines[1] *&* IF Parser(lcComment,@paLines) > 0 *&* FOR lnIndex = 1 TO ALEN(paLines) *&* IF .T. && whatever condition you want -- for example && I have used IF UPPER(paLines[lnIndex]) = "THIS." && to grab stuff out of the Comments field && of the DBC and execute if it && followed my "THIS." convention for && additional properties I'd like to set, && leaving other people's additions to this DBC field... *&* &paLines[lnIndex] *&* ENDIF *&* ENDFOR *&* ENDIF *&* It is quite possible to evaluate each line *&* for loop and logic constructs, such as *&* FOR EACH... IN... ENDFOR/NEXT *&* FOR TO ... ENDFOR/NEXT *&* DO WHILE... ENDDO *&* SCAN... ENDSCAN *&* DO CASE... ENDCASE *&* IF... ELSE... ENDIF *&* (I've probably forgotten some) *&* But the additional evaluation *&* would be done by the calling program as *&* PARSER is currently *&* written, and is left as an exercise *&* for the graduate student . *&* If you are interested in continuing this work, *&* you could cause PARSER to test the logic, and execute *&* the lines multiple times for conditions that were met, etc, *&* rather than doing this in the outer program. You'd need to *&* pass a third string argument, representing the outer program's *&* extra evaluatory requirement if you wanted to use one as I've *&* suggested above.