QW Scripting: ListLines
ListLines 1.07 April 14, 2000
Listlines is a script that searches for a string, a regular expression or a pattern
in the current file and, optionally, all
associated Include files. Include files can be nested up to 10 levels deep.
The script takes care of opening and closing all files it encounters.
The search string can be a simple
string, a regular expression or a pattern. The appropriate string format is selected
using the corresponding entry point implemented using On Command
blocks.
The script is designed to be loaded. You can load it manually using the
Manage scripts command of the Script menu. If you wish to have it loaded
automatically, you can copy it to the customer script library directory
e.g. c:\robelle\qedit\user\autoload\
.
The driver subroutine is called ProcessListRequest.
Information on Listlines is organized as follows:
The main subroutine is called ProcessListRequest and accepts 2 parameters.
- SearchType: This parameter is required.
It is an integer indicating which search option to use:
- is a String
- is a Regular Expression
- is a Pattern
- IncludeFile: This parameter is required.
It is a boolean indicating whether or not to search $Include files.
The script is designed to be loaded. It can be invoked from the Script menu
or from any other script.
Running From the Script Menu
The script can be loaded manually. Its commands are added
to the Robelle command group of the
Script menu. The subcommand name is simply List.
The subcommand offers 7 different options:
- String: Search the active document using a simple string
- Regexp: Search the active document using a regular expression
- Pattern: Search the active document using a pattern
- String in $Include: Search the active document and all $include files
using a simple string
- Regexp in $Include: Search the active document and all $include files
using a regular expression
- Pattern in $Include: Search the active document and all $include files
using a pattern
- About...: Displays a brief explanation of the script's purposes
Running From Another Script
The following sample script provides an example that searches all $include files referred to
in the file k.data
on the connection Production MPE.
The search uses a simple string.
This sample script takes advantage of the
fact that the QSLUtilList script is distributed with Qedit
for Windows as a loadable script (in this case, already loaded):
file = open(connection: "Production MPE", filename: "k.data");
searchType = 1; -- Search for a string
scanInclude = true;
QSLUtilList.ProcessListRequest(searchType, scanInclude);
file.close();
Execution Logic Overview
The script uses the same approach whether you use the menu command or invoke it from
another script.
- The script assumes the currently active document is the main source.
- If there is no active selection, the script prompts for a search string.
If a string is entered, it is used in subsequent steps. If no string is entered,
the script simply
lists all the $include filenames it finds.
- If the user chooses to search for a regular expression or a pattern,
the script always prompts for one. If there is an active selection,
the selection is used as the default search string.
- If there is an active selection and the user chooses to search for a simple
string, the script uses the selection as the search string.
- If the user did not request to scan $Include files, the script finds all occurrences
of the search string in the active document only.
The steps below are executed only if the user requested to scan $Include files.
- The script scans the main source file and searches for the next $Include statement.
- It opens the $include file (if any) and searches for nested $Include statements.
It does so until it reaches the include file at the lowest level i.e. one which does
not contain any $Include statement.
- Then, it searches for the string entered in steps 2, 3 or 4.
- If the string is found, the
line is displayed along with the corresponding
record number in the log window of the
Script Control dialog box.
- It repeats steps 8 and 9 until all matching lines have been displayed.
- When it is done with a file, the script goes back up one
level (if there are nested include files) and repeats steps 7 through 10.
- The script repeats steps 6 through 11 until it has scanned all include files.
- Finally, it searches the main source file for the entered string.
The ProcessListRequest subroutine displays informative messages in the log window
of the Script Control dialog box. These messages include the version number,
error messages (if any) and termination message.
The actual list is displayed in a new local file. The script creates a new file
for each execution. It is up to the user to dispose of these files.
Here is a sample ouput after searching for a string:
Searching MPE Dev:Q.SRC.DEVACCT for STRING 'next'
Found in: EQUATES.INCLUDE.DEVACCT
68: << The next equates define the sub-portions of an MPE filname.
Found in: DATABASE.INCLUDE.DEVACCT
46: double array db'next'rec(*) = db'status'area(8);
Found in: Q.SRC.DEVACCT
2: fix next line: $control nolist/$control list,map >>
Here is a sample output when no search string has been entered:
Listing all Include filenames
Include file: OPTIONS.INCLUDE.DEVACCT
Include file: EQUATES.INCLUDE.DEVACCT
Include file: ERRORS.INCLUDE.DEVACCT
Include file: GLOBALS.INCLUDE.DEVACCT
Include file: DATABASE.INCLUDE.DEVACCT
Include file: MPEINTR.INCLUDE.DEVACCT
Include file: ERRORS.EXTSUB.DEVACCT
Include file: SPLSUB.EXTSUB.DEVACCT
Include file: DATETIME.EXTSUB.DEVACCT
Include file: Q.SRC.DEVACCT
$Include Statements
Assuming that whitespace is a space or a tab character, a valid $Include statement is:
- a line that starts with any number of whitespace (possibly none)
- followed by a dollar sign $, a pound sign # or a dot .
- followed by any number of whitespace (possibly none)
- followed by the string inc
- optionally followed by l, u, d and e
- followed by any number of whitespace (possibly none)
- followed by the include filename
- followed by any number of whitespace (possibly none)
Caseless Search Option
Whether searching for $include statements or for the user-specified search string,
the script uses the IgnoreCase option i.e. does a caseless search.
File Scanning Order
Because the script scans files at the lowest level first, lines found are listed in that
order. For example, let's say the files are nested like this:
Main.src
=> Level1.include
=>Level2.include
=>Level2a.include
=> Level3.include
The output results from a string search will be:
Searching MPE Dev:Q.SRC.DEVACCT for STRING 'String found'
Found in: LEVEL2.INCLUDE.DEVACCT
68: String found here...
Found in: LEVEL3.INCLUDE.DEVACCT
222: String found here...
Found in: LEVEL2A.INCLUDE.DEVACCT
46: String found here...
Found in: LEVEL1.INCLUDE.DEVACCT
100: String found here...
Found in: MAIN.SRC.DEVACCT
2: String found here...
The output for an Include list will be:
Listing all Include filenames
Include file: LEVEL2.INCLUDE.DEVACCT
Include file: LEVEL3.INCLUDE.DEVACCT
Include file: LEVEL2A.INCLUDE.DEVACCT
Include file: LEVEL1.INCLUDE.DEVACCT
Include file: MAIN.SRC.DEVACCT
File Locations
For host files, the script takes whatever follows the $Include keyword and
assumes it is the filename. Certain problems can arise if the include files are
not qualified.
Let's say the connection's logon group is the SRC
, the main
file is in MAINSRC
and the include files are in SRCINC
.
It's feasible to write a job stream to compile this successfully:
!job jobname,user.acct,SRCINC
!cob85xl prog1.MAINSRC
$include copy1
!eoj
What is the script supposed to do? There are different options:
- Force the user to login to the group where the compile usually occurs.
This would simulate the compile job environment.
- Change the script in order to recover from open errors. The sequence would be:
- Try the filename as found on the $Include statement
- If it fails and the filename does not appear to be qualified,
append the group and account of the main source file
- If that fails too, report an error
The script handles local files using a different approach. The script tries to open the
file using just the filename as it appears on the $include statement. If it is unable to
open it, the scripts extracts the pathname for the file at the previous level
(where the $include statement is) and prepends it to the name on the $include statement.
This technique is based on the assumption that the include files are either in the
current working directory (CWD) or in the same directory as the file where it is included.
Maximum Nested Limits
Because the server does not allow more than 10 files opened concurrently on the same
connection, the Include files can not be nested more than 10 levels deep.
Handling Searched Files
The script opens $include files already minimized to icons to reduce the
flickering effect as windows are opened, searched and closed.
$Include files are not added to the Recent Files list of the File
menu.