|
- OPTION VERSION BYWATER
- OPTION BUGS OFF
- REM PARSE SYNTAX DIAGRAMS AND GENERATE PARAMETER RANGE CHECK TESTS
- REM EXAMPLE " SYNTAX: N = ASC( A$ )"
- REM
- REM THIS PROGRAM ASSUMES A PROPERLY FORMATTED SYNTAX DIAGRAM;
- REM ONLY MINIMAL ERROR CHECKING IS PERFORMED.
- REM
- REM ------------------------------------------------------------
- REM VARIABLE USAGE
- REM F$ input file name, such as 'SYNTAX.INP'
- REM I$ inpuut line, such as 'SYNTAX: N = ASC( A$ )'
- REM L location of '('
- REM R location of ')'
- REM C location of ':' or '=' or or ','
- REM P$ current function/parameter
- REM N$() function/parameter name, P$(0) = 'ASC', P$(1) = 'A$'
- REM T() function/parameter type, T(0) = NUMBER, T(1) = STRING
- REM 0 == NUMBER, 1 == STRING
- REM N number of paameters, such as 1
- REM I generic loop variable
- REM C$ current character
- REM Z$ cleaned syntax diagram
- REM F$ cleaned function name, 'ASC'
- REM X$ user selevted function name, 'COS'
- REM U$ UniqueID, 'F_COS_X'
- REM VN TESTCASE ACTUAL RESULT, NUMBER
- REM VS$ TESTCASE ACTUAL RESULT, STRING
- REM Q$ CHR$(34)
- REM RN() RANDOM NUMBERS
- REM RS$() RANDOM STRINGS
- REM #1 INPUT FILE, 'SYNTAX.TXT'
- REM #2 MERGE FILE, 'SYNTAX.MRG'
- REM #3 OUTPUT FILE, 'F_COS_X.BAS'
- REM ------------------------------------------------------------
- REM DECLARE ARRAYS
- REM ------------------------------------------------------------
- REM RANDOMIZE ' this must be off for automated regression
- DIM N$(9)
- DIM T(9)
- DIM RN(100)
- DIM RS$(100)
- N = 0
- GOSUB 4500
- REM ------------------------------------------------------------
- REM GET THE INPUT FILE NAME
- REM ------------------------------------------------------------
- F$ = "SYNTAX.INP"
- X$ = "ASC"
- REM PRINT "F$=[";F$;"]"
- REM ------------------------------------------------------------
- REM PROCESS THE INPUT FILE
- REM ------------------------------------------------------------
- OPEN F$ FOR INPUT AS #1
- WHILE NOT EOF( 1 )
- LINE INPUT #1, I$
- REM PRINT "I$=[";I$;"]"
- REM Process Line in I$
- GOSUB 1000 ' ProcessLine
- REM IF I$ = X$ THEN
- GOSUB 4000 ' DetermineUniqueID
- GOSUB 5000 ' DumpResults
- REM END IF
- WEND
- CLOSE #1
- PRINT "OK"
- GOTO 9999 ' TheEnd
-
-
- 1000 REM ProcessLine
- REM ------------------------------------------------------------
- REM PROCESS THE SYNTAX DIAGRAM IN I$
- REM ------------------------------------------------------------
- N = 0
- REM PRINT "I$=[";I$;"]"
- I$ = TRIM$( I$ )
- IF LEN( I$ ) = 0 THEN RETURN
- REM PRINT "I$=[";I$;"]"
- REM CHECK MISSING COLON
- C = INSTR( I$, ":" )
- REM PRINT "C=[";C;"]"
- IF C = 0 THEN RETURN
- REM REMOVE "SYNTAX:"
- I$ = MID$( I$, C + 1 )
- I$ = TRIM$( I$ )
- REM PRINT "I$=[";I$;"]"
- IF LEN( I$ ) = 0 THEN RETURN
- REM SAVE CLEANED SYNTAX DIAGRAM
- Z$ = I$
- REM DETERMINE RETURN TYPE
- C = INSTR( I$, "=" )
- REM PRINT "C=[";C;"]"
- IF C = 0 THEN RETURN
- P$ = LEFT$( I$, C - 1 )
- P$ = TRIM$( P$ )
- REM PRINT "P$=[";P$;"]"
- IF LEN( P$ ) = 0 THEN RETURN
- I$ = MID$( I$, C + 1 )
- I$ = TRIM$( I$ )
- REM PRINT "I$=[";I$;"]"
- IF LEN( I$ ) = 0 THEN RETURN
- GOSUB 3000 ' DetermineTypeInP$
- REM I$ = "ASC( A$ )"
- REM PRINT "I$=[";I$;"]"
- L = INSTR( I$, "(" )
- R = INSTR( I$, ")" )
- REM PRINT "L=[";L;"]"
- REM PRINT "R=[";R;"]"
- IF R < L THEN RETURN ' ERROR ...)...(
- IF R = 0 AND L = 0 THEN
- REM "A$ = TIME$"
- REM N$(0) = I$
- REM PRINT "NO PARAMETERS"
- REM SAVE CLEANED FUNCTION NAME
- F$ = I$
- RETURN ' DONE
- END IF
- REM "...(...)"
- REM R > L AND L > 0
- REM SAVE CLEANED FUNCTION NAME
- F$ = LEFT$( I$, L-1 )
- F$ = TRIM$( F$ )
- REM PRINT "F$=[";F$;"]"
- I$ = MID$( I$, L+1, R-L-1 )
- REM PRINT "I$=[";I$;"]"
- I$ = TRIM$( I$ )
- REM PRINT "I$=[";I$;"]"
- IF LEN( I$ ) = 0 THEN RETURN ' N = POS()
- P$ = ""
- FOR I = 1 TO LEN( I$ )
- C$ = MID$( I$, I, 1 )
- REM PRINT "C$=[";C$;"]"
- IF C$ = "," THEN
- GOSUB 3000 ' DetermineTypeInP$
- P$ = ""
- ELSE
- P$ = P$ + C$
- END IF
- NEXT I
- GOSUB 3000 ' DetermineTypeInP$
- RETURN
-
-
- 3000 REM DetermineTypeInP$
- REM ------------------------------------------------------------
- REM DETERMINE THE TYPE IN P$
- REM ------------------------------------------------------------
- P$ = TRIM$( P$ )
- REM PRINT "P$=[";P$;"]"
- IF LEN( P$ ) = 0 THEN RETURN
- N$(N) = P$
- T(N) = SGN( INSTR( P$, "$" ) )
- N = N + 1
- RETURN
-
- 4000 REM DetermineUniqueID
- REM ------------------------------------------------------------
- REM DETERMINE THE UNIQUEID USING NS() AND T()
- REM ------------------------------------------------------------
- IF N <= 0 THEN RETURN
- U$ = "F_" + F$
- FOR I = 1 TO N - 1
- U$ = U$ + "_" + N$(I)
- NEXT I
- U$ = U$ + "_" + N$(0)
- REM PRINT "U$=[";U$;"]"
- REM REMOVE "$"
- J = LEN(U$)
- I$ = ""
- FOR I = 1 TO J
- C$ = MID$(U$,I,1)
- IF C$ = "$" THEN
- REM REMOVE
- ELSE
- I$ = I$ + C$
- END IF
- NEXT I
- U$ = I$
- REM PRINT "U$=[";U$;"]"
- RETURN
-
- 4500 REM LoadRandomValues
- REM ------------------------------------------------------------
- REM LOAD RANDOM VALUES
- REM ------------------------------------------------------------
- FOR I = 1 TO 100
- IF I < 25 THEN
- RN(I) = RND * 1.0 - 0.5
- ELSEIF I < 50 THEN
- RN(I) = RND * 255 - 128
- ELSEIF I < 75 THEN
- RN(I) = RND * 64535 - 32768
- ELSE
- RN(I) = RND * 10000000000 - 5000000000
- END IF
- K = 0
- WHILE K < 35 OR K > 126
- K = RND * 128
- WEND
- RS$(I) = SPACE$( RND * 5 ) + STRING$( RND * 5, K ) + SPACE$( RND * 5 )
- NEXT I
- REM CERTAIN VALUES THAT SHOULD ALWAYS BE CHECKED
- RN(1) = 0
- RN(2) = 1
- RN(3) = -1
- RN(4) = 0.4
- RN(5) = -0.4
- RN(6) = 0.6
- RN(7) = -0.6
- RN(8) = 254
- RN(9) = 255
- RN(10) = 256
- RN(11) = 32000
- RS$(1) = ""
- RS$(2) = " "
- RS$(3) = "3"
- RS$(4) = "z"
- RS$(5) = " "
- RS$(6) = " 3"
- RS$(7) = " z"
- RS$(8) = "3 "
- RS$(9) = "z "
- RS$(10) = " 3 "
- RS$(11) = " z "
- RETURN
-
- 5000 REM DumpResults
- REM ------------------------------------------------------------
- REM DUMP RESULTS
- REM ------------------------------------------------------------
- REM
- REM THE FOLLOWING FUNCTIONS SHOULD NOT BE AUTOMATED
- REM FOR VARIOUS REASONS
- REM
- IF N <= 0 THEN
- REM ERROR
- RETURN
- END IF
- IF INSTR( F$, " " ) THEN
- REM TESTCSE NOT POSSIBLE, INTERNAL FUNCTIONS
- REM such as "DEF FN"
- RETURN
- END IF
- IF N = 1 THEN
- REM MANUAL TESTCASE REQUIRED, NO PARAMETERS
- REM such as DATE$, TIME$, TIMER
- RETURN
- END IF
- IF INSTR(".CLOSE.EOF.GET.INPUT$.LOC.LOF.OPEN.PUT.RESET.", "." + F$ + ".") > 0 THEN
- REM MANUAL TESTCASE REQUIRED, FILE RELATIED
- RETURN
- END IF
- IF INSTR(".CHDIR.FILES.KILL.MKDIR.NAME.RMDIR.", "." + F$ + ".") > 0 THEN
- REM MANUAL TESTCASE REQUIRED, DIRECTORY RELATED
- RETURN
- END IF
- IF INSTR(".COMMAND$.ENVIRON.ENVIRON$.SHELL.", "." + F$ + ".") > 0 THEN
- REM MANUAL TESTCASE REQUIRED, SYSTEM RELATED
- RETURN
- END IF
- IF INSTR(".INP.OUT.PEEK.POKE.WAIT.", "." + F$ + ".") > 0 THEN
- REM MANUAL TESTCASE REQUIRED, HARDWARE RELAATED
- RETURN
- END IF
- IF INSTR(".COLOR.INKEY$.LOCATE.LPOS.LWIDTH.POS.WIDTH.", "." + F$ + ".") > 0 THEN
- REM MANUAL TESTCASE REQUIRED, SCREEN or PRINTER
- RETURN
- END IF
- IF INSTR(".MKC$.MKD$.MKI$.MKL$.MKS$.", "." + F$ + ".") > 0 THEN
- REM MANUAL TESTCASE REQUIRED, MK*
- RETURN
- END IF
- IF INSTR(".MOD.OPTION.", "." + F$ + ".") > 0 THEN
- REM MANUAL TESTCASE REQUIRED, MISCELLANEOUS
- RETURN
- END IF
- IF INSTR(".RANDOMIZE.RND.SPC.TAB.", "." + F$ + ".") > 0 THEN
- REM NO TESTCASE REQUIRED, TESTED BY P###.BAS
- RETURN
- END IF
- REM
- REM GENERATE TESTCASE
- REM
- LET X$ = U$ + ".BAS"
- PRINT X$
- OPEN X$ FOR OUTPUT AS #3
- PRINT #3, "REM ------------------------------------------------------------"
- PRINT #3, "REM PURPOSE: TEST THE PARAMETER RANGE CHECKS"
- PRINT #3, "REM AUTHOR: HOWARD WULF, AF5NE"
- PRINT #3, "REM GENERATED: ";DATE$;" ";TIME$
- PRINT #3, "REM FILENAME: ";X$
- PRINT #3, "REM SYNTAX: ";Z$
- PRINT #3, "REM UNIQUEID: ";U$
- PRINT #3, "REM FUNCTION: ";F$
- REM ------------------------------------------------------------
- REM HAS PARAMETERS
- REM N > 1
- PRINT #3, "REM "
- PRINT #3, "REM","VARIABLE","DESCRIPTION"
- PRINT #3, "REM","I" ,"CURRENT TESTCASE NUMBER"
- PRINT #3, "REM","E" ,"EXPECTED ERROR FLAG"
- PRINT #3, "REM","F" ,"ACTUAL ERROR FLAG"
- IF T(0) = 0 THEN
- PRINT #3, "REM","R" ,"EXPECTED FUNCTION RESULT"
- ELSE
- PRINT #3, "REM","R$" ,"EXPECTED FUNCTION RESULT"
- END IF
- FOR I = 0 TO N - 1
- IF I = 0 THEN
- PRINT #3, "REM",N$(I),"ACTUAL FUNCTION RESULT"
- ELSE
- PRINT #3, "REM",N$(I),"ACTUAL FUNCTION PARAMETER"
- END IF
- NEXT I
- PRINT #3, "REM "
-
- REM GENERATE TESTS
-
- Q$ = CHR$(34)
-
- PRINT #3, "RESTORE 2000"
- PRINT #3, "REM GET TESTCASE #"
- PRINT #3, "READ I"
- PRINT #3, "WHILE I > 0"
- PRINT #3, "REM GET TESTCASE DATA"
- PRINT #3, "READ E, ";
- IF T(0) = 0 THEN
- PRINT #3, "R";
- ELSE
- PRINT #3, "R$";
- END IF
- FOR J = 1 TO N - 1
- PRINT #3, ", ";
- PRINT #3, N$(J);
- NEXT J
- PRINT #3, ""
- PRINT #3, "REM DISPLAY TESTCASE DATA"
- PRINT #3, "PRINT ";Q$;"TESTCASE #";Q$;";I,";
- PRINT #3, Q$;"E=";Q$;";E,";
- IF T(0) = 0 THEN
- PRINT #3, Q$;"R=";Q$;";R";
- ELSE
- PRINT #3, Q$;"R$=[";Q$;";R$;";Q$;"]";Q$;
- END IF
- FOR J = 1 TO N - 1
- PRINT #3, ", ";
- IF T(J) = 0 THEN
- PRINT #3, Q$;N$(J);"=";Q$;";";N$(J);
- ELSE
- PRINT #3, Q$;N$(J);"=[";Q$;";";N$(J);";";Q$;"]";Q$;
- END IF
- NEXT J
- PRINT #3, ""
- PRINT #3, "REM EXECUTE TESTCASE"
- PRINT #3, "N = ";0
- PRINT #3, "S$ = ";Q$;Q$
- PRINT #3, "ON ERROR GOTO 9000"
- PRINT #3, "F = 0"
- PRINT #3, "999 ";Z$
- PRINT #3, "ERROR 0"
- PRINT #3, "REM DISPLAY TESTCASE RESULTS"
- PRINT #3, "PRINT ,";Q$;"F=";Q$;";F,";
- IF T(0) = 0 THEN
- PRINT #3, Q$;N$(0);"=";Q$;";";N$(0)
- ELSE
- PRINT #3, Q$;N$(0);"=[";Q$;";";N$(0);";";Q$;"]";Q$
- END IF
- PRINT #3, "REM VERIFY EXPECTED ERROR"
- PRINT #3, "IF E <> F THEN"
- PRINT #3, " PRINT ";Q$;"*** TEST FAILED, EXCEPTION MISMATCH ***";Q$
- PRINT #3, " STOP"
- PRINT #3, "END IF"
- PRINT #3, "REM VERIFY EXPECTED RESULT"
- IF T(0) = 0 THEN
- PRINT #3, "IF R > 0 THEN"
- PRINT #3, " LET RMIN = 0.99 * R"
- PRINT #3, " IF R > MAXNUM / 1.012 THEN"
- PRINT #3, " LET RMAX = MAXNUM"
- PRINT #3, " ELSE"
- PRINT #3, " LET RMAX = 1.01 * R"
- PRINT #3, " END IF"
- PRINT #3, "END IF"
- PRINT #3, "IF R < 0 THEN"
- PRINT #3, " IF R < - MAXNUM / 1.012 THEN"
- PRINT #3, " LET RMIN = -MAXNUM"
- PRINT #3, " ELSE"
- PRINT #3, " LET RMIN = 1.01 * R"
- PRINT #3, " END IF"
- PRINT #3, " LET RMAX = 0.99 * R"
- PRINT #3, "END IF"
- PRINT #3, "IF R = 0 THEN"
- PRINT #3, " LET RMIN = -.01"
- PRINT #3, " LET RMAX = +.01"
- PRINT #3, "END IF"
- PRINT #3, "IF ";N$(0);" < RMIN THEN"
- PRINT #3, " PRINT ";Q$;"*** TEST FAILED, RESULT MISMATCH ***";Q$
- PRINT #3, " STOP"
- PRINT #3, "END IF"
- PRINT #3, "IF ";N$(0);" > RMAX THEN"
- PRINT #3, " PRINT ";Q$;"*** TEST FAILED, RESULT MISMATCH ***";Q$
- PRINT #3, " STOP"
- PRINT #3, "END IF"
- ELSE
- PRINT #3, "IF R$ <> ";N$(0);" THEN"
- PRINT #3, " PRINT ";Q$;"*** TEST FAILED, RESULT MISMATCH ***";Q$
- PRINT #3, " STOP"
- PRINT #3, "END IF"
- END IF
- PRINT #3, "PRINT ";Q$;"*** TEST PASSED ***";Q$
- PRINT #3, "REM GET NEXT TESTCASE #"
- PRINT #3, "READ I"
- PRINT #3, "WEND"
- PRINT #3, "PRINT ";Q$;"*** ALL TESTS PASSED ***";Q$
- PRINT #3, "GOTO 9999"
- PRINT #3, "1999 REM TESTCASE, EXPECTED ERROR, EXPECTED RESULT, PARAMETERS..."
- FOR I = 1 TO 100
- REM ------------------------------------------------------------
- REM CREATE MERGE FILE
- REM ------------------------------------------------------------
- OPEN "SYNTAX.MRG" FOR OUTPUT AS #2
- PRINT #2, "6000 REM MERGE START";I
- REM PRINT #2, "6010 PRINT ";Q$;"BEFORE ERROR";Q$
- REM PRINT #2, "6020 ERROR 12"
- REM PRINT #2, "6030 PRINT ";Q$;"AFTER ERROR";Q$
- REM PRINT #2, "6040 RETURN"
- REM PRINT #2, "6050 PRINT ";Q$;"AFTER RETURN";Q$
- FOR J = 1 TO N - 1
- IF T(J) = 0 THEN
- K = RN(I)
- PRINT #2, "LET ";N$(J);" = ";K
- V(J) = K
- ELSE
- K$ = RS$(I)
- PRINT #2, "LET ";N$(J);" = ";Q$;K$;Q$
- V$(J) = K$
- END IF
- NEXT J
- PRINT #2, "6010 LET V";Z$
- REM PRINT #2, "6098 PRINT ";Q$;"BEFORE STOP";Q$
- PRINT #2, "6099 REM MERGE STOP";I
- CLOSE #2
- REM EXECUTE MERGED FILE
- DELETE 6000-6099
- MERGE "SYNTAX.MRG"
- REM LIST 5999-6999
- LET E = 0
- LET VN = 0
- LET VS$ = ""
- REM TRON
- ON ERROR RESUME NEXT
- GOSUB 6000
- REM TROFF
- REM DTERMINE ERROR FLAG
- LET E = ABS(SGN(ERR))
- REM CLEAR ERR, ERL, ERROR$
- ERROR 0
- ON ERROR GOTO 0
- REM REPORT RESULTS
- REM TESTCASE NUMBER, EXPECTED ERROR
- PRINT #3, "DATA ";I;", ";E;", ";
- REM EXPECTED RESULT
- IF T(0) = 0 THEN
- PRINT #3, VN;
- ELSE
- PRINT #3, Q$;VS$;Q$;
- END IF
- REM ACTUAL PARAMETERS
- FOR J = 1 TO N - 1
- PRINT #3, ", ";
- IF T(J) = 0 THEN
- PRINT #3, V(J);
- ELSE
- PRINT #3, Q$;V$(J);Q$;
- END IF
- NEXT J
- PRINT #3, ""
- NEXT I
- PRINT #3, "DATA 0"
- PRINT #3, "9000 REM ERROR HANDLER"
- PRINT #3, "IF ERL = 999 THEN"
- PRINT #3, " F = ABS(SGN(ERR))"
- PRINT #3, " RESUME NEXT"
- PRINT #3, "END IF"
- PRINT #3, "PRINT ";Q$;"*** UNEXPECTED ERROR ON LINE ";Q$;";ERL;";Q$;" ***";Q$
- PRINT #3, "9999 END"
- CLOSE #3
- RETURN
-
- 5999 REM BOUNDARY A
- 6000 REM MERGE START 0
- 6099 REM MERGE STOP 0
- 6100 RETURN
- 6999 REM BOUNDARY B
-
- REM ------------------------------------------------------------
- REM EOF
- REM ------------------------------------------------------------
- 9999 END
|