VMS Help  —  SCA  SCA Topics, SCA Tutorial
    This tutorial is for character cell LSE and SCA on
    the OpenVMS platform.  For a tutorial on the
    DECwindows interface, please see the DECset Guide to
    Source Code Analyzer.

    If you do not have DECwindows, you may want to have a hardcopy
    of this tutorial to follow it along interactively.  The directions
    for producing a hardcopy are as follows:

    1. Place the contents of SCA_Tutorial in a printable file
       by typing the following command on the DCL command line:

         $ HELP/OUTPUT=SCA_TUTORIAL.TXT SCA SCA_Topics SCA_Tutorial

    2. Print SCA_TUTORIAL.TXT from the DCL command line as follows:

         $ PRINT SCA_TUTORIAL.TXT

    SCA allows you to browse through a complex software system. In a
    large multimodule software system, you may not be familiar with
    all of the source code. It may have been written by different
    authors in a number of different programming languages. SCA can
    help you browse through the source code and give you important
    information about the program structure. If you are familiar with
    the source code, SCA will help you navigate directly to the source
    code you want, and give you valuable cross-reference information.

    This tutorial guides you through a sample SCA session to show how
    SCA can improve your software development productivity as you work
    on an unfamiliar software system.

    If you encounter terms that are unfamiliar, see the SCA online
    glossary for definitions. SCA's terminology for program structures
    is language independent. If you want to see how this terminology
    maps onto the programming language that you use most frequently,
    see the language tables under the Getting_Started help topic.

    This tutorial assumes that you use SCA while in LSE. You can
    still follow the tutorial if you are using SCA from the command
    line, but you will not be able to use the GOTO DECLARATION, GOTO
    SOURCE, EXPAND, or NEXT STEP commands. The way in which results
    are displayed also differ slightly between standalone SCA and SCA
    used from within LSE.

    Invoking SCA

    To invoke SCA through LSE, type the following from the DCL command
    line:

      $ LSEDIT

    Typing Commands

    Your cursor is now in an LSE buffer.

    Press the DO key or COMMAND key (PF1-KP7). This places you in LSE
    command mode.

    You will see the "LSE command>" prompt at the bottom of your LSE
    window. This means that you can now enter an SCA command. During
    this tutorial, when you see SCA commands following an LSE command>
    prompt, press the DO key before you try to type the command.

    Selecting a Library

    SCA gets its information from an SCA library, a database of
    information about your source code. You will be using the sample
    SCA library provided in this tutorial.

    To use the sample SCA library, type the following in LSE command
    mode:

      LSE command> SET LIBRARY SCA$EXAMPLE:

    Later in this tutorial, you will learn how to create your own SCA
    library using your own source code.

    Looking at Modules

    Because the components of the system are unfamiliar to you, the
    first thing you may want to do is determine which modules comprise
    the system loaded into the SCA library. The SHOW MODULE command
    gives you a synopsis of the contents of the library.

    To get information about the contents of an SCA library, type the
    following command at the LSE Command> prompt:

      LSE command> SHOW MODULE

    For each module, you will see the module name, the language in
    which the source code is written, and some other information. A
    module is a logical unit of source code, as determined by your
    compiler. In FORTRAN, a module may be a PROGRAM or SUBROUTINE. In
    C, it may consist of the source code within one file. If you are
    interested in how "module" and other SCA concepts map to different
    language specific constructs, see the language tables under the
    Getting_Started help topic.

    Press the Return key when you are finished looking at the list of
    modules.

    Creating a Query

    Suppose you are assigned the task of changing the output format
    for this software system. Because you are unfamiliar with the
    source code, you do not know where the system produces output.
    Using SCA, you can find out by looking for places where the
    program uses WRITELN. WRITELN is a built-in Pascal output
    function, similar to PUT_LINE in Ada, or PRINTF in C.

    To ask SCA to find all the occurrences of the symbol in the system
    with the name WRITELN, type the following command:

      LSE command> FIND WRITELN

    LSE/SCA creates the following display in your buffer:

      WRITELN procedure
          COPY_FILE\75         call reference
          COPY_FILE\84         call reference

    The first line tells you about the existence of a symbol whose
    name is WRITELN and whose symbol class is procedure. (A procedure
    in Pascal is like a subroutine in FORTRAN, or a function in C. See
    the language tables under the Getting_Started help topic.

    The subsequent indented lines give you information about where
    occurrences of the WRITELN symbol were found. For example, the
    first occurrence or use of the WRITELN symbol is in the module
    COPY_FILE on line 75, and the occurrence class (the way the symbol
    was used) is a call reference.

    Navigating the Query Display

    Once you have a list of occurrences of the symbol, you will want
    to look at the source code corresponding to those occurrences.

    You will see that the first two lines of the display are
    highlighted. This highlighting tells you which symbol and
    occurrence are selected. When an occurrence is selected, you can
    use the GOTO SOURCE command to see the corresponding source code.
    Press CTRL/G or type the GOTO SOURCE command at the LSE command>
    prompt. The file COPYFILE.PAS is read into a buffer by LSE, and
    your cursor will be positioned on the first occurrence of WRITELN.

    You may now be interested in looking at the source code for the
    next occurrence.

    Press CTRL/F or type the NEXT STEP command at the LSE command>
    prompt. (Note that there is a corresponding CTRL/B command for
    PREVIOUS STEP.)

    You will see that the second occurrence of WRITELN, on line 84, is
    highlighted.

    Press CTRL/G again to invoke the GOTO SOURCE command.

    Going to a Declaration

    Your cursor is again positioned on an occurrence of WRITELN.
    Looking at the source code, you see the following line:

      WRITELN (out_file, SUBSTR (out_line, 1, out_index));

    You might be interested in finding out where the first argument,
    the variable OUT_FILE, is declared.

    Press the arrow keys to position your cursor on the word OUT_FILE
    in the source code. If you are using LSE with DECwindows, you can
    also point to the word OUT_FILE by pointing and clicking with the
    mouse.

    Press CTRL/D or type the GOTO DECLARATION/PRIMARY/INDICATED
    command at the LSE Command> prompt.

    Your cursor will now be placed on the declaration of OUT_FILE.

    Using SCA, you can navigate directly to the declaration of any
    symbol declared in your system by placing your cursor on the
    symbol, and pressing CTRL/D. If you are not positioned on a
    symbol, you can also go to the declaration of a symbol by typing
    the following command:

      LSE COMMAND> GOTO DECLARATION symbol-name

    Using Wildcards to Find Occurrences

    Because SCA allows wildcard expressions, it can help you navigate
    through the source code, even if you are not quite sure of the
    name of the symbols of interest.

    Suppose you know of a procedure in the system that you might use
    in some new code that you are writing. In order to see how this
    procedure has been used elsewhere, you want to look at the source
    code for calls to the procedure, but you do not remember its name.
    You may only remember that it begins with the letters BUILD. Type
    the following command:

      LSE command> FIND build*

    You will now see the following display:

      BUILDTABLE.PAS file
          BUILD_TABLE\1        PASCAL command reference
      BUILD_TABLE procedure
      BUILD_TABLE module

    SCA also gives you a message in the message buffer as follows:

    5 occurrences found (3 symbols, 2 names)

    You can see that two names were found: BUILDTABLE.PAS and BUILD_
    TABLE. The BUILDTABLE.PAS symbol has the symbol class "file."
    Two different BUILD_TABLE symbols were found. One of these is a
    procedure; the other is a module.

    You may notice that there are no occurrences displayed for either
    the BUILD_TABLE procedure or the BUILD_TABLE module. To prevent
    the display from being too cluttered, SCA/LSE displays only the
    occurrences of the first symbol.

    Because you are interested in seeing the occurrences of the BUILD_
    TABLE procedure, you must expand the display as follows;

    1. Press CTRL/F, or type the NEXT STEP command at the LSE Command>
       prompt, to select the BUILD_TABLE procedure symbol.

    2. Press CTRL/E, or type the EXPAND command at the LSE command>
       prompt, to expand the display.

    In the following display, you will see that three occurrences of
    the BUILD_TABLE procedure are now visible:

      BUILDTABLE.PAS file
          BUILD_TABLE\1        PASCAL command reference
      BUILD_TABLE procedure
          BUILD_TABLE\41       PROCEDURE declaration
          TRANSLIT\61          FORWARD or EXTERNAL PROCEDURE declaration
          TRANSLIT\171         call reference
      BUILD_TABLE module

    You could now look at the corresponding source code if you
    desired. Note that there is a corresponding CTRL/\ key, or
    COLLAPSE command, that you can use to hide expanded occurrences.

    Attribute Selection

    To avoid finding more occurrences than you want, SCA lets you
    select occurrences based on attributes other than just the name
    of a symbol. In the previous example, you were looking for a
    procedure named BUILD_TABLE. However, the results included a file
    and a module, as well as the procedure you wanted.

    To get results that include only the BUILD_TABLE procedure with
    its corresponding occurrences, type the following query:

      LSE command> FIND NAME=BUILD* AND SYMBOL_CLASS=PROCEDURE

    Up to this point, you have selected only occurrences based on
    the name of the symbol. The name of a symbol is only one of its
    attributes. In fact, FIND BUILD_TABLE is an abbreviation for
    FIND NAME=BUILD_TABLE, where "NAME=" specifies which particular
    attribute we are using to select the occurrences found. FIND
    BUILD_TABLE without "NAME=" works for the following reason. If
    you don't specify the attribute, SCA assumes you are selecting
    occurrences based on a name because this is the most commonly used
    attribute.

    In this new query, you have specified that you want to see only
    symbols whose name is BUILD_TABLE, and whose symbol class is
    PROCEDURE. (Note that the symbol class PROCEDURE is synonymous
    with the classes FUNCTION, SUBROUTINE, ROUTINE, and PROGRAM.)

    Symbol classes indicate the type of symbols. Examples of other
    symbol classes that SCA understands are FIELD, CONSTANT, MACRO,
    TASK, TYPE, and VARIABLE. For more information and a complete list
    of these symbol classes, see the information under the SYMBOL_
    CLASS help topic.

    In the previous example, you used two selection clauses to
    restrict the items found, NAME=BUILD* and SYMBOL_CLASS=PROCEDURE.
    Each of these clauses resulted in a set of occurrences. You
    combined the results of the two clauses by using the AND operator,
    which resulted in only those occurrences that were found in both
    sets of results.

    The set operators available in SCA are AND, OR, NOT, and XOR. You
    can use any number of set operators to combine attribute selection
    clauses (such as SYMBOL_CLASS=PROCEDURE) to specify your query.

    In the following display, which resulted from the previous query,
    there are two declarations of the BUILD_TABLE procedure and one
    call reference:

      BUILD_TABLE procedure
          BUILD_TABLE\41       PROCEDURE declaration
          TRANSLIT\61          FORWARD or EXTERNAL PROCEDURE declaration
          TRANSLIT\171         call reference

    In the previous example, remember that you are interested in
    seeing only call references to this procedure. You can further
    restrict your query by using the OCCURRENCE= attribute, which
    describes how a particular occurrence of a symbol is used. To do
    this, type the query as follows:

      LSE Command> FIND BUILD_TABLE AND SYMBOL_CLASS=PROCEDURE -
      _LSE Command> AND OCCURRENCE=CALL

    This command asks SCA to find the same results as the previous
    query, but to limit the results to those occurrences that are
    call references. In the resulting occurrence set, the declaration
    occurrences no longer appear.

    Because this is a very small example, it seems unnecessary to
    continue refining these queries because you could look at the
    source code for only the occurrences you want. However, if the
    system were larger, and thousands of occurrences were found for
    each query, it would be more important to give as detailed a query
    as possible to avoid extraneous information.

    The occurrence class attribute describes how an occurrence is
    used. Examples of other occurrence classes that are understood
    by SCA are READ, WRITE, POINTER, CALL, DECLARATION , EXPLICIT,
    HIDDEN, and REFERENCE. For a complete list and description of
    these occurrence classes, see the OCCURRENCE_CLASS help topic.

    There are two more attributes that you can use to restrict your
    queries. The first attribute, DOMAIN=, allows you to restrict the
    occurrences based on the range of source code in which the symbols
    might be used. Possible values for DOMAIN= are INHERITABLE,
    GLOBAL, PREDEFINED, MULTI-MODULE, and MODULE_SPECIFIC.

    The second attribute, FILE=, allows you to limit occurrences to
    those found within a particular file, such as COPYFILE.PAS.

    You could find all the global symbols (those symbols visible
    throughout the program) occurring in the file COPYFILE.PAS by
    entering the following query:

      LSE Command> FIND DOMAIN=GLOBAL AND FILE="COPYFILE.PAS"

    If you do not specify a name, as in the previous example, the
    default is NAME=*.

    In summary, there are five attributes that you can use to select
    occurrences: NAME=, SYMBOL_CLASS=, OCCURRENCE=, FILE=, and
    DOMAIN=. You can combine these selection clauses using the AND,
    OR, XOR, and NOT operators. For more information, request help for
    each attribute.

    Relationship Functions

    Up to this point, you have been navigating through source code
    by asking SCA to find occurrences of interesting symbols. SCA
    can also help you see the structure of your code. If you are
    debugging a routine, such as READ_COMMAND_LINE, you may want to
    know which system library routines might be invoked if you called
    READ_COMMAND_LINE. To get this information, type the following:

      LSE command> FIND CALLED_BY (READ_COMMAND_LINE)

    In this example, you are invoking the CALLED_BY function and
    sending it one argument, the name READ_COMMAND_LINE. The resulting
    display is as follows:

      READ_COMMAND_LINE procedure calls
         BUILD_TABLE procedure
         CLI$DCL_PARSE function
         CLI$GET_VALUE function
         CLI$PRESENT function
         EXPAND_STRING function
         IADDRESS function
         LENGTH function
         LIB$GET_FOREIGN function
         LIB$SIGNAL procedure
         ODD function
         OPEN_IN procedure
         OPEN_OUT procedure
         SUBSTR function

    The query that you just entered resulted in all the routines
    called by READ_COMMAND_LINE.

    However, assume you are interested in finding out only which
    system library routines are called by READ_COMMAND_LINE. You
    can also specify that only some of the routines called by READ_
    COMMAND_LINE should be a part of the result. That is, SCA lets
    you specify both the caller and the callee in the "called_by"
    relationship, as in the following example:

      LSE command> FIND CALLED_BY (READ_COMMAND_LINE, LIB$*)

    You will then see the following results:

      READ_COMMAND_LINE procedure calls
         LIB$GET_FOREIGN function
         LIB$SIGNAL procedure

    The first argument to the CALLED_BY function specified the
    caller, and the second argument specified the callee. Both
    of these arguments can be general query expressions, such as
    SYMBOL=ROUTINE.

    You may notice that there is only one level of depth to the call
    trees we have seen. That is, LIB$SIGNAL and LIB$GET_FOREIGN are
    called directly by READ_COMMAND_LINE. You may be interested in
    looking at a complete call tree from READ_COMMAND_LINE to LIB$
    routines, including calls through intervening routines.

    To specify the number of levels of the call tree you want to see,
    type the following command:

      LSE command> FIND CALLED_BY (READ_COMMAND_LINE, LIB$*, DEPTH=ALL)

    The result is as follows:

      READ_COMMAND_LINE procedure calls
         BUILD_TABLE procedure calls
         .  LIB$SIGNAL procedure
         .  SIGNAL_DUPLICATE procedure calls
         .     LIB$SIGNAL procedure  (See above)
         LIB$GET_FOREIGN function
         LIB$SIGNAL procedure  (See above)

    In the previous example, the DEPTH= argument of the CALLED_BY
    relationship allowed you to specify the number of levels of the
    call tree. For the DEPTH= argument, you can either specify an
    integer value (the default is 1), or you can specify the keyword
    ALL.

    The CALLED_BY relationship is not the only function available in
    SCA. As with other relationship functions, the CALLED_BY function
    has an inverse, the CALLING function. To find those routines that
    call READ_COMMAND_LINE, type the following query:

      LSE command> FIND CALLING (READ_COMMAND_LINE, DEPTH=ALL)

    The result is as follows:

      TRANSLIT procedure calls
         READ_COMMAND_LINE procedure calls

    If you do not specify the second argument to a relationship
    function, it defaults to * (which means anything). This query
    translates to "find anything calling READ_COMMAND_LINE, at any
    depth." You will see that there is only one call to READ_COMMAND_
    LINE from the TRANSLIT procedure.

    These relationship displays are like previous query displays in
    that you can expand, collapse, and navigate through them.

    SCA also has information about two other types of relationships.
    The TYPED_BY and TYPING relationship functions are useful for
    finding information about how things are typed. For example, you
    can learn the following:

    o  FIND TYPING in_file - tells you the type of the variable in_file

    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.
Close Help