Source Scanner for IBM JCL

Source Scanner for IBM JCL


This document describes the entities and relations the JCL Scanner creates on encountering various JCL code constructs.

Current output

  • Structures
  • Jobs
  • Procedures (cataloged and in-stream)
  • JobSteps(EXEC)
  • Properties
  • File-levelmetrics
  • Procedure default arguments
  • Callmap
  • Step to procedure
  • Step to program
  • Data map (unifies with COBOL file maps)
  • Data definition to data source name (on program execution)
  • Step data definition overrides (when procedure unresolved)


Scanner knowledge not encoded

  • In-stream input values


Limitations

  • JES2 and JES3 commands are generally accepted by the parser, but JES2 and JES3 are not otherwise supported. That is, their semantic meaning is not understood or output by the scanner.
  • Files must have Control-M directives pre-processed
  • The PRINTDEV statement is not accepted. Although PRINTDEV is part of JCL, it is only used to start the Print Services Facility, and is not used in standard user jobs.
  • Symbol values that expose delimiters. (See examples below.)


Delimiter exposition

Parameter and symbol uses are not expanded at parse time. Thus, symbols that expose delimiters, such as quote and parentheses, can parse incorrectly.

For example, the following code contains an imbalanced quote on the EXEC statement:

// SET ENDSTRING='.END'''
//S1 EXEC PGM=EXAMPLE,PARM='BEGIN.&ENDSTRING

JCL will expand the ENDSTRING symbol to produce the following EXEC statement:

//S1 EXEC PGM=EXAMPLE,PARM='BEGIN.END'

which it then parses and recognizes a syntactically correct statement. Since our tool parses before symbolic substitution, it sees an unbalanced quote and will report an error.


Features improved over CA-provided scanner

  • Retargetable procedure and include library lookup


Detail on JCL-specific entities

  • Job and step libraries

Job library metrics are reported on the job's syntax: it includes in-stream procedures but not cataloged procedures or step libraries. Step library inclusion is not reported directly: the steps are processed into the stream of the job or procedure. The scanner issues a diagnostic error if a library is unavailable.

  • Job steps

The scanner reports both program and procedure execution job steps. The scanner issues a diagnostic error if a cataloged procedure is unavailable.

  • Procedures

In-stream procedures are reported within their surrounding job. Cataloged procedures have static information (e.g. default arguments and metrics) in a separate file, but dynamic information (e.g. program calls, DD to DSN maps) within the calling job.

  • Data definition cards (DDs) and dataset names (DSNs)

Procedure step DD overrides are propagated if the procedure is available. DD to DSN maps are given on a per-call basis.

  • Programs

Programs are external entities to JCL, encountered only as targets to exec steps. Scanner unification can interlace these entities with those of the target language (e.g. COBOL).


Metrics

The scanner computes a variety of standard code-line metrics, including:

  • total lines of code
  • comment line count
  • blank line count (note this is always zero, as JCL has no "blank card")

It also computes a variety of complexity and maintainability metrics based on standard industry practices, including:

  • McCabe_cyclomatic_complexity
  • decision_density
  • volume_sum
  • perCM_sum
  • number_of_unique_operators
  • number_of_unique_operands
  • number_of_operator_occurrences
  • number_of_operand_occurrences
  • halstead_program_length
  • halstead_program_vocabulary
  • halstead_program_volume
  • halstead_program_difficulty
  • halstead_program_effort
  • halstead_bug_prediction
  • SEI_maintainability_index

All metrics are reported in the same XML format in the same manner as for JCL and COBOL.


XML explication

XML entities, declared in format `name : attributes` with explanatory text below. Every entity and relation has a unique, numeric `id` attribute.

Entities

Job - JobName

Proc - JobName

  • uses JobName so they both fit in the JobSet bucket
  • JobName uniquely identifies stored procedures so their references can be unified with uses in other files

Program - Name

JobStep - JobStepName

File - Name

  • aka Data Definition

DataFil - Name

  • aka Data Set Name


Relationships

Step - StepId ParentId

  • parent is a job or proc

StepPrg - StepId PrgId

  • EXEC/Job step calls PGM; note the PGM is just a name to the JCL and must be connected by the repository

StepProc - StepId ProcId

  • EXEC/JobstepcallsPROC

StpPrcDS - StpPrcDSName StepProcId DataFilId

  • only output if the EXEC→PROC mapping is not found (as these overrides would then be seen on the actual EXEC→PGM call)

StepFile - StepFileName StepId FileId

  • EXECusesDD

FileDS - FileDSName StepFileId DataFilId

  • DDusemapstoDSN