Robelle | Products | Library | Support | Partners | Contact Us | Qedit for Windows

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:


ProcessListRequest Parameters

The main subroutine is called ProcessListRequest and accepts 2 parameters.


Invoking Listlines

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:

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.
  1. The script assumes the currently active document is the main source.
  2. 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.
  3. 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.
  4. 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.
  5. 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.

  6. The script scans the main source file and searches for the next $Include statement.
  7. 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.
  8. Then, it searches for the string entered in steps 2, 3 or 4.
  9. 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.
  10. It repeats steps 8 and 9 until all matching lines have been displayed.
  11. 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.
  12. The script repeats steps 6 through 11 until it has scanned all include files.
  13. Finally, it searches the main source file for the entered string.


Listlines Results

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.

String Search Results

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 >>

List Include Filenames Only

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


Notes

$Include Statements

Assuming that whitespace is a space or a tab character, a valid $Include statement is:

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:
  1. Force the user to login to the group where the compile usually occurs. This would simulate the compile job environment.
  2. Change the script in order to recover from open errors. The sequence would be:
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.