o FIND TYPED_BY integer - tells you what things are of type integer o FIND TYPING (table, depth=all) - tells you what components make up the aggregate structure table. SCA also understands the CONTAINED_BY and CONTAINING relationships. These functions tell you what symbols are contained within something else. For example, the following query tells you all the procedures that are within the signal_duplicate procedure: LSE Command> FIND CONTAINED_BY (SIGNAL_DUPLICATE, SYMBOL=PROCEDURE) For more information about the relationship functions, see the help topic for each relationship. Because you are debugging READ_COMMAND_LINE, you might be interested in occurrences of all the symbols contained directly or indirectly in READ_COMMAND_LINE. You can get this information by using the CONTAINED_BY function. However, you can use the IN function instead, which is less general but easier to use. The IN function lets you specify the container and the containee, and traces the relationship through all depths (including nested subroutines, for example). Type the following query to see all the occurrences of symbols used within the READ_COMMAND_LINE procedure: LSE command> FIND IN (READ_COMMAND_LINE) The results show that 178 occurrences of symbols were used within the READ_COMMAND_LINE procedure. Using Previous Queries As you continue to use SCA, you may be interested in looking at results from previous queries that you have issued. SCA keeps track of all your queries, and allows you to move back and forth between them. To see all your queries, type the following command: LSE command> SHOW QUERY You will see the following list: Name Query expression Description 1 WRITELN (none) 2 BUILD* (none) 3 NAME=BUILD* AND SYMBOL_CLASS=PROCEDURE (none) 4 BUILD_TABLE AND SYMBOL_CLASS=PROCEDURE AND OCCURRENCE=CALL (none) 5 CALLED_BY (READ_COMMAND_LINE) (none) 6 CALLED_BY (READ_COMMAND_LINE, LIB$*) (none) 7 CALLED_BY (READ_COMMAND_LINE, LIB$*,DEPTH=ALL) (none) 8 CALLING (READ_COMMAND_LINE, DEPTH=ALL) (none) (*) 9 IN (READ_COMMAND_LINE) (none) You can see that there is an asterisk (*), next to query 9, which was the last query you entered. This is called the current query. Because query 9 is the current query, you can navigate its display, and enter GOTO SOURCE commands for that query. SCA also lets you set the current query with the PREVIOUS QUERY, NEXT QUERY, and GOTO QUERY commands. Suppose you want to look at the results of the FIND NAME=BUILD* AND SYMBOL_CLASS=PROCEDURE query again. The name of the query is 3. To see the results of query 3 in a query buffer, type the following: LSE Command> GOTO QUERY 3 It is now the current query, and you will be able to navigate it, and see the source code corresponding to the found occurrences. You can navigate previously entered queries and use their results in new queries. Remember that after you entered query 3, NAME=BUILD* AND SYMBOL_CLASS=PROCEDURE, you wanted to refine that query to see only call occurrences. You then entered a new query as follows: LSE Command> FIND BUILD_TABLE AND SYMBOL_CLASS=PROCEDURE - _LSE Command> AND OCCURRENCE=CALL You could have entered the new query by typing the following: LSE Command> FIND @3 AND OCCURRENCE=CALL The previous command is the same as the following query: LSE Command> FIND NAME=BUILD* AND SYMBOL_CLASS=PROCEDURE - _LSE Command> AND OCCURRENCE=CALL Creating Your Own Library Now that you have seen how to use SCA, you can create an SCA library with information about your own source code. The following example contains the commands for creating a library at the DCL level. Remember that any SCA commands can also be entered from within LSE. In order to create your own SCA library, you must first create a library directory for it. Using your personal directory, type the following command to create a subdirectory for a local SCA library: $ CREATE/DIRECTORY [.LIB1] Once you have a directory in which to create a library, enter the following command to SCA to create a library: $ SCA CREATE LIBRARY [.LIB1] You now have an empty SCA library. To add a module to the SCA library, you must first compile your source code. If you have a Pascal compiler available, you can compile and load one of the SCA example files into your new library. First, copy the example file into your working directory by typing the following command: $ COPY SCA$EXAMPLE:TYPES.PAS [] Then, compile it with the /ANALYSIS_DATA qualifier. This creates the file TYPES.ANA, which can be loaded into your SCA library. To compile this file, use the following command: $ PASCAL/ANALYSIS_DATA TYPES.PAS If you do not have a Pascal compiler, try adding the /ANALYSIS_ DATA qualifier when you use any other supported compiler. For example: $ CC/ANALYSIS_DATA myfile.c Once you have a .ANA file, you can load it into your SCA library either from LSE or standalone SCA. To load the .ANA file and show the new module, type the following commands: SCA> LOAD myfile.ANA SCA> SHOW MODULE You will see that the new module has been loaded into the library, and you will now be able to query that library. 2 SYMBOL_CLASS SYMBOL_CLASS is an attribute selection that identifies the type of symbol. A symbol can be a variable, constant, or some other class. The format for SYMBOL_CLASS is as follows: SYMBOL_CLASS=(keyword[,keyword...]) The SYMBOL_CLASS can be one of the following keywords: o ARGUMENT - formal argument (such as a routine argument or macro argument) o COMPONENT,FIELD - component of a record o CONSTANT,LITERAL - named compile-time constant value o EXCEPTION - exception o FILE - file o FUNCTION,PROCEDURE, PROGRAM,ROUTINE, SUBROUTINE - callable program function o GENERIC - generic unit o KEYWORD - keyword o LABEL - user-specified label o MACRO - macro o MODULE, PACKAGE - collection of logically related elements o PLACEHOLDER - marker where program text is needed o PSECT - program section o TAG - comment heading o TASK - task o TYPE - user-defined type o UNBOUND - unbound name o VARIABLE - program variable o OTHER - any other class of symbol The previous keywords are SCA terms. For information on corresponding language-specific terms, request help for the appropriate language table (for example, FORTRAN_ATTRIBUTES_TABLE) under the Getting_Started help topic. An example using the SYMBOL_CLASS attribute follows: FIND X AND SYMBOL_CLASS=ROUTINE This query finds all routines named X. 2 TYPING The TYPING function is a relationship function. It finds the type of some occurrence. Occurrences related in this manner have a TYPING relationship between them. For example, if INTEGER is typing variable X, then these two occurrences are in a TYPING relationship. In its most common form, the function format is as follows: TYPING( , , DEPTH={ | ALL} ) In this format, and can be any legal query expression, and is a positive integer. A typical use of the function is to find the type of a variable. For example: FIND TYPING( X, *, DEPTH=1) This query finds the type of X, where X is some variable in the SCA database. The TYPING function also works on user-defined types. The defined type can have many levels, in which case the user can specify a depth as follows: FIND TYPING( user_defined_type, *, DEPTH=ALL) This query gives the full type tree for USER_DEFINED_TYPE. The TYPING function provides the power to return the exact type tree you want. The full format is as follows: TYPING( [ END= ], [ BEGIN= ], [ DEPTH={ | ALL} ], [ RESULT=RESULT_KEYWORD ], [ TRACE=query_expression ] ) In the previous format, and is any legal query expression, is a positive integer, RESULT_KEYWORD can be STRUCTURE, NOSTRUCTURE, ANY_PATH, BEGIN, or END, and QUERY_ EXPRESSION is any legal query expression. For a full description of the TYPING relationship, see the LSE/SCA User Manual. 2 TYPED_BY The TYPED_BY function is a relationship function. It finds occurrences that have a TYPED_BY relationship between them. For example, if variable X is typed by INTEGER, then these two occurrences are in a TYPED_BY relationship. In its most common form, the function format is as follows: TYPED_BY( , , DEPTH={ | ALL} ) In this format, and can be any legal query expression, and is a positive integer. A typical use of the function is to find what is being typed by INTEGER. For example: FIND TYPED_BY( INTEGER, *, DEPTH=1) This query finds everything that is of type INTEGER. The TYPED_BY function can also tell you the items that are in some way affected by a given type. The type can be predefined by language elements such as INTEGER, or can be user defined. For example: FIND TYPED_BY( user_defined_type, *, DEPTH=ALL) This query finds all the items that are directly or indirectly affected by USER_DEFINED_TYPE. The TYPED_BY function provides the power to return the exact type tree you want. The full format is as follows: TYPED_BY( [ END= ], [ BEGIN= ], [ DEPTH={ | ALL} ], [ RESULT=RESULT_KEYWORD ], [ TRACE=query_expression ] ) In the previous format, and is any legal query expression, is a positive integer, RESULT_KEYWORD can be STRUCTURE, NOSTRUCTURE, ANY_PATH, BEGIN, or END, and QUERY_ EXPRESSION is any legal query expression. For a full description of the TYPED_BY relationship, see the LSE/SCA User Manual. 2 \_(Pathname) The path name expression allows you to identify specific symbols based on the path of the expression. This is similar to the debugger pathname notation. The format of this expression is as follows: query_expression\query_expression[\query_expression...] Typically, you use this expression to identify a particular variable in a routine when you may have declared a variable of the same name in more than one routine. For example, RETURN_STATUS may be a common variable in multiple routines. Some typical queries are as follows: 1. FIND MYROUTINE\RETURN_STATUS 2. FIND MYMODULE\MYROUTINE\RETURN_STATUS 3. FIND MYMODULE\SYMBOL_CLASS=ROUTINE The first query returns all occurrences of the RETURN_STATUS variable that are declared inside MYROUTINE. The second example returns all occurrences of the RETURN_STATUS variable which are declared inside MYROUTINE, where MYROUTINE is declared inside MYMODULE. The third example returns all occurrences of routines which are declared inside MYMODULE. You may also use the pathname when the exact path is not known. For example, assume that you know the module name and that XYZ is declared somewhere inside the MYMODULE, but you do not know the exact pathname. You can then use the following query: FIND MYMODULE\\XYZ This query locates the XYZ variable that is declared somewhere inside MYMODULE and returns all occurrences of XYZ. 2 @_(Query_Usage) A query usage function incorporates the results of previous queries into query expressions. The function has the following form: @( query_name ) The value of this expression is that of the expression that is specified as query_name. The default query name is the current query, SCA$CURRENT_QUERY. You can see an example of its use in the following sequence of queries: FIND X FIND @(SCA$CURRENT_QUERY) AND SYMBOL=ROUTINE The advantage of using this notation is that the results of the previous query are not reevaluated. Thus the second query will be faster than the query: FIND X AND SYMBOL=ROUTINE