(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 \_(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 2 CALLED_BY The CALLED_BY function is a relationship function. It finds occurrences that have a CALLED_BY relationship between them. For example, if routine B is called by routine A, then these two occurrences are in a CALLED_BY relationship. In its most common form, the function format is as follows: CALLED_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 those routines which are called by some specified routine. For example: FIND CALLED_BY( xyz, *, DEPTH=ALL ) This query finds the full call tree below XYZ, where XYZ is some routine in the SCA database. In other words, this query finds all routines which are either directly or indirectly called by XYZ. The CALLED_BY function provides the power to return the exact call tree you want. The full format is as follows: CALLED_BY( [ END= ], [ BEGIN= ], [ DEPTH={ | ALL} ], [ RESULT=RESULT_KEYWORD ], [ TRACE=query_expression ] ) In the previous format, and < caller> is any legal query expresion, 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 CALLED_BY relationship, see the on-line help file SCACOMMANDS. 2 CALLING The CALLING function is a relationship function. It finds occurrences with the CALLING relationship between them. For example, if routine A is calling routine B, then these two occurrences are in a CALLING relationship. In its most common form, the function format is as follows: CALLING( , , 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 those routines which are calling some specified routine call. For example, FIND CALLING( abc, *, DEPTH=ALL ) This query finds the full call tree above ABC, where ABC is some routine in the SCA database. In other words, find all the routines that are directly or indirectly calling ABC. The CALLING function provides the power to return the exact call tree of interest. The full format is: CALLING ( [ END= ], [ BEGIN= ], [ DEPTH={ | ALL} ], [ RESULT=RESULT_KEYWORD ], [ TRACE=query_expression ] ) In the previous format, and is any legal query expresion, is a positive integer, RESULT_KEYWORD can be STRUCTURE, ANY_PATH, BEGIN, or END, and QUERY_EXPRESSION is any legal query expression. For a full description of the CALLING relationship, see the on-line help file SCACOMMANDS. 2 CONTAINED_BY The CONTAINED_BY function is a relationship function. It finds occurrences that have a CONTAINED_BY relationship between them. In its most common form, the function format is as follows: CONTAINED_BY( , , DEPTH={ | ALL} ) In this format, and can be any legal query expression, and is a positive integer. Some examples will help you understand this function. The diagram that follows applies to these examples. A (module) +-------------------------+ | | | B (routine) | | +-------------------+ | | | | | | | C (routine) | | | | +-------------+ | | | | | | | | | | | D (variable)| | | | | | | | | | | | | | | | | +-------------+ | | | | | | | +-------------------+ | | | | E (variable) | | | +-------------------------+ Consider the following queries: 1. FIND CONTAINED_BY( A, *, DEPTH=1 ) 2. FIND CONTAINED_BY( C, *, DEPTH=1 ) 3. FIND CONTAINED_BY( A, *, DEPTH=2 ) The first query returns A (the container), B (a containee), and E (a containee). Similarly, the second query returns C and D. The third query returns A, B, and C and E. The D variable is NOT included because it is not reachable at a depth of two. Now consider the following two queries: 4. FIND CONTAINED_BY( A, D, DEPTH=ALL ) 5. FIND CONTAINED_BY( A, D, DEPTH=2 ) Query four returns A (the container), B (because it is on the path to D), C (becasue it is on the path) and D (which is the containee being searched for). The fifth query does not return anything because the D variable cannot be reached at a depth of two. Where a container begins and ends is determined by the language syntax. These boundaries are reported to SCA by the compiler and used by the CONTAINED_BY function to determine nesting. The CONTAINED_BY function provides the power to return the exact nesting structure you want. The full format is as follows: CONTAINED_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 CONTAINED_BY relationship, see the on-line help file SCACOMMANDS. See also the help topic for the IN function, which is similar to the CONTAINED_BY relationship. 2 CONTAINING The CONTAINING function is a relationship function. It finds occurrences that have a CONTAINING relationship between them. In its most common form, the function format is as follows: CONTAINING( , , DEPTH={ | ALL} ) In this format, and can be any legal query expression, and is a positive integer. Some examples will help you understand the CONTAINING function. The diagram that follows applies to these examples. A (module) +-------------------------+ | | | B (routine) | | +-------------------+ | | | | | | | C (routine) | | | | +-------------+ | | | | | | | | | | | D (variable)| | | | | | | | | | | | | | | | | +-------------+ | | | | | | | +-------------------+ | | | | E (variable) | | | +-------------------------+ Consider the following queries: 1. FIND CONTAINING( D, *, DEPTH=1 ) 2. FIND CONTAINING( C, *, DEPTH=1 ) 3. FIND CONTAINING( D, *, DEPTH=2 ) The first query returns D (the containee), and C (the container). Similarly, the second query returns C and B. The third query returns D, C and B. Now consider the following 2 queries: 4. FIND CONTAINING( D, A, DEPTH=ALL ) 5. FIND CONTAINING( D, A, DEPTH=2 ) Query four returns D (the containee), C (because it is on the path to A), B (because it is on the path) and A (which is the container being looked for). The fifth query does not return anything because A cannot be reached at a depth of two. Where a container begins and ends is determined by the language syntax. These boundaries are reported to SCA by the compiler and used by the CONTAINING function to determine nesting. The CONTAINING function provides the power to return the exact nesting structure you want. The full format is as follows: CONTAINING( [ 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 CONTAINING relationship, see the on-line help file SCACOMMANDS. 2 DOMAIN DOMAIN is an attribute of an occurrence that determines the scope of the symbol defined. It is the range of source code in which a symbol has the potential of being used. For example, A BLISS OWN declaration creates a symbol that has a module-specific symbol domain; it cannot be used outside that module. On the other hand, a BLISS GLOBAL declaration creates a symbol that has a multimodule symbol domain; it has the potential of being used in more than one module. The format for DOMAIN is as follows: DOMAIN=(keyword[,keyword...]) The keyword can be one of the following: o INHERITABLE - able to be inherited into other modules (for example, through BLISS library, PASCAL environment, or Ada compilation system mechanisms) o GLOBAL - known to multiple modules via linker global symbol definitions o PREDEFINED - defined by the language (examples: BLISS ap, FORTRAN sin, PASCAL writeln) o MULTI_MODULE - domain spans more than one module (domain=multi_ module is equivalent to domain=(inheritable,global,predefined) o MODULE_SPECIFIC - domain is limited to one module 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 DOMAIN attribute follows: FIND DOMAIN=GLOBAL AND SYMBOL=VARIABLE This query find all global variables. 2 EXPAND The EXPAND function determines the symbol to which an occurrence belongs and returns the full set of occurrences for the symbol. For example, the following code fragments, written in a pseudo language, declare and use the variable i in three files. file 1 file 2 file 3 ------ ------ ------ GLOBAL i (d) LOCAL i (d) EXTERNAL i (d) i := 0 (wr) i := 5 (wr) IF i EQUALS 0 (rr) (d) - declaration (wr) - write reference (rr) - read reference The pseudo language defines variables, such that the variable i in "file 1" and the variable i in "file 3" are the same variable. The variable i in "file 2", however, is a different variable. SCA treats these variables in the same manner by saying there are two unique symbols which happen to have the same name. The important point in the previous example is that what the programmer considers unique items SCA also considers unique items. In SCA terms, these items are symbols. Given the previous code fragments, consider the follwoing query: FIND SYMBOL_CLASS=VARIABLE AND OCCURRENCE=READ This query returns one occurrence, which is the read reference in "file 3." Now consider the next query: FIND EXPAND( symbol_class=variable and occurrence=read ) This query returns two occurrences of "i" in "file 1" and the two occurrences of "i" in "file 3." The EXPAND function uses the read reference to determine the corresponding symbol and then returns all the occurrences for that symbol. In this case the symbol was the global variable "i". Note that the two occurrences in "file 2" are not returned because they belong to a different symbol. The programmer does not view the i in "file 2" to be the same as the i in "file 1" and "file 3" and SCA reflects that view. When given more than one occurrence, the EXPAND function performs this operation iteratively and removes any duplicate occurrences from the result. In the following example, you use the EXPAND function to find the declarations of routines defined in the system, but which are not used. To do this, specify the following query: FIND (SYMBOL=ROUTINE AND OCCURRENCE=PRIMARY) AND NOT EXPAND(SYMBOL=ROUTINE AND OCCURRENCE=REFERENCE) 2 FILE_SPEC FILE_SPEC is an attribute selection that specifies the name of the file. You identify a source file by its OpenVMS file specification. You should enclose the file specification in quotation marks because it normally contains a period (.) The format for the FILE_SPEC attribute is as follows: FILE_SPEC="filename.filetype" An example using the FILE_SPEC attribute follows: FIND FILE_SPEC="MYPROG.FOR" This query finds all occurrences in the file MYPROG.FOR. 2 IN The IN function searches for occurrences inside a container. The IN function is a special case of the CONTAINED_BY function. In its most common form, the function format is as follows: IN( , ) In this format, and can be any legal query expression. The IN function returns all occurrences that match the expression as long as those occurrences are somewhere inside the container. Some examples will help you understand the IN function. The following picture applies to the examples that follow. A (module) +-------------------------+ | | | B (routine) | | +-------------------+ | | | | | | | C (routine) | | | | +-------------+ | | | | | | | | | | | D (variable)| | | | | | | | | | | | | | | | | +-------------+ | | | | | | | +-------------------+ | | | | E (variable) | | | +-------------------------+ Consider the following queries: 1. FIND IN( A, *) 2. FIND IN( B, D) 3. FIND IN( A, SYMBOL_CLASS=ROUTINE and OCCURRENCE=DECLARATION) The first query returns B (a containee), C (a containee), D (a containee) and E (a containee). A is not returned because it is the container. The second query returns only D (the containee). C is not returned because it does not match the expression. B is not returned because it is the container. The third query returns all routine declarations inside A. In this case, B and C are returned. The IN function is a convenient way to limit a query to a particular container. The full format of the In function is as follows: IN( [END=], [BEGIN=] ) In this format, and can be any legal query expression. 2 INDICATED The INDICATED function is available only from within LSE. The INDICATED function matches the occurrence on which the cursor is positioned. The INDICATED function has no parameters. The format is as follows: INDICATED() An example of using the INDICATED function is as follows: FIND EXPAND( INDICATED() ) This query finds all occurrences of the item on which the cursor is positioned in LSE. 2 NAME NAME is an attribute of an occurrence that is a string of ASCII characters which identifies symbols in your source code. A specific name can be associated with more than one symbol. The language you are using defines the legal characters for a name. Each name has zero or more characters. Any character may appear in a name. Special characters that appear in a name must be quoted using double quotes. You do not need to quote the following: $, _, *, %, &, -, alphanumeric characters. You can use wildcards (* and %) in the name expression. You can override the wildcard characters by using the escape character (&). For example, you can find the name consisting of a single asterisk using the name expression &*. If you want an ampersand in a string, you must use two successive ampersands. The format for NAME can be one of the following: name NAME=(name[,name...]) 2 OCCURRENCE The occurrence class is an attribute of an occurrence that identifies the type of occurrence. The occurrence class indicates if the occurrence is a declaration, a reference, or one of the other classes in the list that follows. If the occurrence class is a declaration or reference, the occurrence class indicates what type of declaration or reference it is. The format for the occurrence class attribute is as follows: OCCURRENCE=(keyword[,keyword...]) The occurrence class can be one of the following keywords: Declarations o PRIMARY - most significant declaration o ASSOCIATED - associated declaration o DECLARATION - primary or associated References o READ, FETCH - fetch of a symbol value o WRITE, STORE - assignment of a symbol value o ADDRESS, POINTER - reference to the location of a symbol o CALL - call to a routine or macro o COMMAND_LINE - command line file reference o INCLUDE - source file include referenece o PRECOMPILED - precompiled file include referenece o OTHER - any other kind of reference (such as a macro expansion or use of a constant) o REFERENCE - any of the preceding values o BASE - Any base class of a C++ class o FRIEND - Any friend of a C++ class o MEMBER - Any member of a C++ class o SPEPARATE - Any Ada package or sub-program unit defined as SEPARATE o WITH - Any WITH of an Ada package or sub-program unit Other Occurrence Classes o EXPLICIT - explicitly declared o IMPLICIT - implicitly declared o VISIBLE - occurrence appears in the source o HIDDEN - occurrence does not appear in the source o COMPILATION_UNIT - the declaration that contains all occurrences in a particular compilation unit o LIMITED - Any Ada limited private type o PRIVATE - Any private C++ objects, or Ada private type o PROTECTED - Any protected c++ object o PUBLIC - Any public C++ object o VIRTUAL - Any virtual C++ object 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 occurrence class attribute follows: FIND OCCURRENCE=PRIMARY This query finds all PRIMARY occurrences of declarations. 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 CLASS - Any C++ class object construct defined by the union, structure or class statements 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 on-line help file SCACOMMANDS. 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 on-line help file SCACOMMANDS.