;; Function To Be Tested: . (MASTERSCOPE) (Program Analysis) ;; ;; Source: Lyric Release Overview (Lyric Beta Release) ;; Section 19 (Masterscope), Page 22 ;; Section: Program Analysis ;; ;; Created By: John Park ;; ;; Creation Date: Feb 25, 1987 ;; ;; Last Update: March 26, 1987 ;; ;; Massively munged by Rene P. S. Bane June 24, 1988 ;; ;; Filed As: {ERIS}test>program-analysis>masterscope.u ;; ;; ;; Syntax: . &rest LINE ;; ;; Function Description: Make a MASTERSCOPE query. Masterscope is an interactive ;; program for analyzing and cross referencing user programs. It contains ;; facilities for analyzing user functions to determine what other functions are ;; called, how and where variables are bound, set, or referenced, as well as ;; which functions use particular record declarations. Masterscope is able to ;; analyze definitions directly from a file as well as in-core definitions. ;; This test is almost identical to the masterscope as an exec command, which is ;; located in {eris}test>exec>masterscope.u ;; ;; Argument(s): Masterscope commands (SEE IRM, Vol 3, Section 19) ;; ;; Returns: (SEE IRM, Vol 3, Section 19) ;; ;; Constraints/Limitations: Due to the nature of Programmer's Assistant commands, ;; testing them will be performed using do-test and the interlisp function bksysfuf. ;; Comments or messages are incorporated within ;; each command file, which will be run by using the function bksysbuf. ;; Each test setup is titled "MASTERSCOPE-TEST-SETUP", which executes the command ;; string. The do-test form within the command file will return T or "test ;; failed" This test file requires TEDIT and MASTERSCOPE package ;; The tree structure of the functions being analyzed are as follows: ;; ;; Top-Funtion ;; | ;; Fun-A------------------------Fun-B ;; | | ;; --------------------- -------------------- ;; | | | | | | ;; Fun-A1 Fun-A2 Fun-A3 Fun-B1 Fun-B2 Fun-B3 ;; | ;; -------------- ;; | | ;; Fun-C1 Fun-A1 ;; ;; Messages will be printed before each command in the command files is executed ;; for user monitoring. Test result is logged on ;; {eris}test>program-analysis>masterscope.report (DO-TEST "MASTERSCOPE-TEST-SETUP" ;; If the browser is already loaded, undo what the browser did so this testfile ;; will work properly, then redo it. This is relying on the browser to always ;; affect MSPATHS, because there is no official way of undoing the browser ;; (that I know of) (IL:IF (IL:GETD 'IL:OLDMSPATHS) IL:THEN (IL:MOVD 'IL:MSPATHS 'TMP-MSPATHS) (IL:MOVD 'IL:OLDMSPATHS 'IL:MSPATHS)) (SETQ TEST-SUCCEEDED T) (DEFUN PASS-FAIL (COMMAND-LANGUAGE TEST-ITEM) (IL:IF (NOT TEST-ITEM) IL:THEN (FORMAT *ERROR-OUTPUT* "Test ~s failed~%" COMMAND-LANGUAGE) (SETQ TEST-SUCCEEDED NIL) (BREAK "Argh!") IL:ELSE "Hey, no problem!")) ; Reinitialize and Define functions to be analyzed (IL:MASTERSCOPE '(ERASE)) (DEFUN TOP-FUNTION NIL (AND (FUN-A) (FUN-B))) (DEFUN FUN-A NIL (OR (FUN-A1) (FUN-A2) (FUN-A3))) (DEFUN FUN-B NIL (OR (FUN-B1) (FUN-B2) (FUN-B3))) (DEFUN FUN-A1 NIL T) (DEFUN FUN-A2 NIL NIL) (DEFUN FUN-A3 NIL T) (DEFUN FUN-B1 NIL (AND (FUN-C1)(FUN-A1))) (DEFUN FUN-B2 NIL NIL) (DEFUN FUN-B3 NIL T) (DEFUN FUN-C1 NIL NIL) ; Start analyzing functions in top-function (IL:MASTERSCOPE '(ANALYZE TOP-FUNTION)) (IL:MASTERSCOPE '(ANALYZE FUN-A)) (IL:MASTERSCOPE '(ANALYZE FUN-B)) (IL:MASTERSCOPE '(ANALYZE FUN-B1)) (PASS-FAIL "Who calls FUN-A1" (NOT (SET-EXCLUSIVE-OR (IL:MASTERSCOPE '(WHO CALLS FUN-A1)) '(FUN-A FUN-B1)))) (PASS-FAIL "Who calls TOP-FUNTION" (NOT (IL:MASTERSCOPE '(WHO CALLS TOP-FUNTION)))) (PASS-FAIL "Who calls FUN-A" (NOT (SET-EXCLUSIVE-OR (IL:MASTERSCOPE '(WHO CALLS FUN-A)) '(TOP-FUNTION)))) (PASS-FAIL "Who calls FUN-B2" (NOT (SET-EXCLUSIVE-OR (IL:MASTERSCOPE '(WHO CALLS FUN-B2)) '(FUN-B)))) (DRIBBLE '{CORE}WHO-CALLS) (IL:MASTERSCOPE '(WHO CALLS WHO)) (DRIBBLE) (DRIBBLE '{CORE}PATHS) (IL:MASTERSCOPE '(SHOW PATHS TO FUN-A1 FROM TOP-FUNTION)) (DRIBBLE) ; ERASE (erase all information about the functions in SET from the database) (IL:MASTERSCOPE '(ERASE)) (PASS-FAIL "All info erased" (NOT (OR (IL:MASTERSCOPE '(WHO CALLS FUN-A)) (IL:MASTERSCOPE '(WHO CALLS FUN-B1)) (IL:MASTERSCOPE '(WHO CALLS FUN-B2)) ))) ; REANALYZE (causes masterscope to reanalyze the functions in SET) (IL:MASTERSCOPE '(ANALYZE TOP-FUNTION)) (IL:MASTERSCOPE '(ANALYZE FUN-A)) (IL:MASTERSCOPE '(ANALYZE FUN-B)) (IL:MASTERSCOPE '(ANALYZE FUN-B1)) (IL:MASTERSCOPE '(ERASE FUN-A)) (IL:MASTERSCOPE '(REANALYZE FUN-A)) (PASS-FAIL "Reanalyzing" (NOT (SET-EXCLUSIVE-OR (IL:MASTERSCOPE '(WHO CALLS FUN-A1)) '(FUN-A FUN-B1)))) (IL:MASTERSCOPE '(ERASE)) (PASS-FAIL "Called-by (reanalyzing too)" (NOT (SET-EXCLUSIVE-OR (IL:MASTERSCOPE '(WHO IS CALLED BY TOP-FUNTION)) '(FUN-A FUN-B)))) ; DESCRIBE SET (prints out the bind, use freely and call information) (DEFUN FUN-DESCRIBE (X Y) (SETQ X1 (1+ X)) (SETQ Y1 (1- Y))) (IL:MASTERSCOPE '(ANALYZE FUN-DESCRIBE)) (DRIBBLE '{CORE}DESCRIBE) (IL:MASTERSCOPE '(DESCRIBE FUN-DESCRIBE)) (DRIBBLE) (IL:MASTERSCOPE '(ERASE)) ; analyzing the file that contains hopefully correct results (SETQ DESCRIBE-FLG NIL) (SETQ DESCRIBE-FILE (OPEN "{CORE}DESCRIBE")) ;; Yeeuck. Awful test, relies on Masterscope returning exactly the characters ;; expected. At least now it doesn't require the exact number of spaces....Rene ;; p.s. premature EOF will return a NIL, so that will count as failure as well. (LET (NEXT-LINE) (IL:WHILE (AND (NOT (EQ 'EOF (SETQ NEXT-LINE (READ-LINE DESCRIBE-FILE NIL 'EOF)))) (NOT (SEARCH "calls" NEXT-LINE :TEST #'STRING-EQUAL)))) (PASS-FAIL "Describe" (AND (STRING-EQUAL "calls:1+,1-" (DELETE #\Space NEXT-LINE)) (STRING-EQUAL "binds:X,Y" (DELETE #\Space (READ-LINE DESCRIBE-FILE NIL NIL))) (STRING-EQUAL "usesfree:Y1,X1" (DELETE #\Space (READ-LINE DESCRIBE-FILE NIL NIL))) )) ) ; close let (CLOSE DESCRIBE-FILE) (DELETE-FILE "{CORE}DESCRIBE") ; analyzing the file that contains the previous masterscope interactions ; (who calls?) (SETQ WHO-CALLS (OPEN "{CORE}WHO-CALLS")) ;; Another test which replaces the previous "throw away the first three lines ;; no matter what" and ignores spaces. See comment for the DESCRIBE test. There ;; MUST be a better way! And >>I<< didn't spell "funtion" that way....Rene ;; JRB - a feature of who calls who is that the order in which the calling information ;; comes out is dependent on the order things got analyzed in. Things get reanalyzed ;; by Masterscope itself all the time, in whatever order Masterscope feels like doing it. ;; What you really have to do here is suck in all the lines and do a SET-EXCLUSIVE-OR ;; between two lists of strings; yuck**2. (LET (ALL-LINES NEXT-LINE) ;; First suck in the lines (IL:WHILE (NOT (EQ 'EOF (SETQ NEXT-LINE (READ-LINE WHO-CALLS NIL 'EOF)))) IL:DO (PUSH (DELETE #\Space NEXT-LINE) ALL-LINES)) ;; Then compare them (PASS-FAIL "Who calls...? (analyzing)" (NOT (SET-EXCLUSIVE-OR ALL-LINES '("top-funtion--(fun-afun-b)" "FUN-B1--(FUN-C1FUN-A1)" "FUN-B--(FUN-B1FUN-B2FUN-B3)" "FUN-A--(FUN-A1FUN-A2FUN-A3)") :TEST #'STRING-EQUAL)))) (CLOSE WHO-CALLS) (DELETE-FILE "{CORE}WHO-CALLS") ; analyzing the file that contains the masterscope interaction (show paths) (SETQ PATHS (OPEN "{CORE}PATHS")) (LET (NEXT-LINE) (IL:WHILE (AND (NOT (EQ 'EOF (SETQ NEXT-LINE (READ-LINE PATHS NIL 'EOF)))) (NOT (SEARCH "top-funtion" NEXT-LINE :TEST #'STRING-EQUAL)))) (PASS-FAIL "Show paths (would-be graph)" (AND (STRING-EQUAL "1.FUN-A1FUN-ATOP-FUNTION" (DELETE #\Space NEXT-LINE)) (STRING-EQUAL "2.FUN-B1FUN-BTOP-FUNTION" (DELETE #\Space (READ-LINE PATHS NIL NIL))) )) ) ; close let (CLOSE PATHS) (DELETE-FILE "{CORE}PATHS") ;; if the browser was loaded, reset MSPATHS so it looks loaded again (IL:IF (IL:GETD 'OLDMSPATHS) IL:THEN (IL:MOVD 'TMP-MSPATHS 'IL:MSPATHS)) TEST-SUCCEEDED ) STOP