IBM RPG language for Prism

I’ve been putting together a Prism language file for IBM’s RPGLE (RPG IV) language.

A complicating factor is that the RPG language is composed of columnar, or fixed width, data, as well as free-form data. The legacy RPG language is almost totally fixed format, where groups of columns mean something different. For example, column 6 is the “specification”, such as C for calculation (program statements), D for (variable) definitions, or O for program output. Each of these different specifications use columns differently. The IBM ILE RPG Reference - PDF provides enormous detail in both language usage, format, and syntax.

The trick in Prism is for the fixed-format code, the regex need to be processed from right-to-left. For instance, a simple specification such as the H (header) control specifications would look first (after determining the specification type using the regex /^.{5}h.+/mi) at columns 81+, being comments; then columns 7-80, control specification keywords; then at column 6, the specification type.

For this language file, only the specifications I use most are defined:

  • C: calculation
  • D: definition
  • H: control
  • /free: free-form RPG

The complete specification list for ILE RPG is as follows:

  • C: calculation
  • D: definition
  • F: file description
  • H: control
  • I: input
  • O: output
  • P: procedure

Specification templates

The outlined portion of each line delineates each portion of the specification.


***********************************************************************************************
*** CONTROL SPECIFICATION
***********************************************************************************************

Control-secification layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
HKeywords++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (H)
 7-80: Keywords                                                            
                                                                           81-100: Comments    



***********************************************************************************************
*** FILE DESCRIPTION SPECIFICATION
***********************************************************************************************

File Description Specification Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
FFilename++IPEASFRlen+LKlen+AIDevice+.Keywords+++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (F)
 7-16: File Name
           17: File Type
            18: File Designation
             19: End of File
              20: File Addition
               21: Sequence
                22: File Format
                 23-27: Record Length
                      28: Limits Processing
                       29-33: Length of Key or Record Address
                            34: Record Address Type
                             35: File Organization
                              36-42: Device
                                      44-80: Keywords                      
                                                                           81-100: Comments    

File Description Keyword Continuation Line Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
F.....................................Keywords+++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (F)
                                      44-80: Keywords                      
                                                                           81-100: Comments    



***********************************************************************************************
*** DEFINITION SPECIFICATION
***********************************************************************************************

Definition Specification Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (D)
 7-21: Name     
                22: External Description
                 23: Type of Data Structure
                  24-25: Definition Type
                    26-32: From position
                           33-39: To Position/Length
                                  40: Internal Data Type
                                   41-42: Decimal Positions
                                      44-80: Keywords                      
                                                                           81-100: Comments    

Definition Specification Keyword Continuation Line Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
D.....................................Keywords+++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (D)
                                      44-80: Keywords                      
                                                                           81-100: Comments    

Definition Specification Continued Name Line Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
DContinuedName+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (D)
 7-80: Continued Name                                                      
                                                                           81-100: Comments    



***********************************************************************************************
*** INPUT SPECIFICATION
***********************************************************************************************

Program Described Record Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
IFilename++SqNORiPos1+NCCPos2+NCCPos3+NCC..................................Comments++++++++++++
6: Form Type (I)
 7-16: File Name
           17-18: Sequence
             19: Number
              20: Option
               21-22: Record Identifying Indicator
                 23-46: Record Identification Codes
                 23-30: Category
                 23-27: Position
                      28: Not
                       29: Code Part
                        30: Character
                         31-38: Category
                         31-35: Position
                              36: Not
                               37: Code Part
                                38: Character
                                 39-46: Category
                                 39-43: Position
                                      44: Not
                                       45: Code Part
                                        46: Character
                                                                           81-100: Comments    

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
I.........And..RiPos1+NCCPos2+NCCPos3+NCC..................................Comments++++++++++++
6: Form Type (I)
          16-18: Logical Relationship
               21-22: Record Identifying Indicator
                 23-46: Record Identification Codes
                 23-30: Category
                 23-27: Position
                      28: Not
                       29: Code Part
                        30: Character
                         31-38: Category
                         31-35: Position
                              36: Not
                               37: Code Part
                                38: Character
                                 39-46: Category
                                 39-43: Position
                                      44: Not
                                       45: Code Part
                                        46: Character
                                                                           81-100: Comments    

Program Described Field Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
I........................Fmt+SPFrom+To+++DcField+++++++++L1M1FrPlMnZr......Comments++++++++++++
6: Form Type (I)
                         31-34: Data Attributes
                             35: Date/Time Seperator
                              36: Data Format
                               37-46: Field Location
                                         47-48: Decimal Positions
                                           49-62: Field Name
                                                         63-64: Control Level
                                                           65-66: Matching Fields
                                                             67-68: Field Record Relation
                                                               69-74: Field Indicators
                                                                           81-100: Comments    

Externally Described Record Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
IRcdname+++....Ri..........................................................Comments++++++++++++
6: Form Type (I)
 7-16: Record Name
               21-22: Record Identifying Indicator
                                                                           81-100: Comments    

Externally Described Field Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
I..............Ext-field+..................Field+++++++++L1M1..PlMnZr......Comments++++++++++++
6: Form Type (I)
               21-30: External Field Name
                                           49-62: Field Name
                                                         63-64: Control Level
                                                           65-66: Matching Fields
                                                               69-74: Field Indicators
                                                                           81-100: Comments    



***********************************************************************************************
*** CALCULATION SPECIFICATION
***********************************************************************************************

Calculation Specification Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....Comments++++++++++++
6: Form Type (C)
 7-8: Control Level
   9-11: Indicators
      12-25: Factor 1
                    26-35: Operation and Extender
                              36-49: Factor 2
                                            50-63: Result 
                                                          64-68: Field Length
                                                               69-70: Decimal Positions
                                                                 71-76: Resulting Indicators
                                                                           81-100: Comments    


*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
CL0N01Factor1+++++++Opcode(E)+Extended-factor2+++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (C)
 7-8: Control Level
   9-11: Indicators
      12-25: Factor 1
                    26-35: Operation and Extender
                              36-80: Extended Factor 2                     
                                                                           81-100: Comments    

Calculation Specification Extended Factor-2 Continuation Line
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
C.............................Extended-factor2-continuation++++++++++++++++Comments++++++++++++
6: Form Type (C)
                              36-80: Extended Factor 2 Continuation        
                                                                           81-100: Comments    

Free-form Syntax
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
 /FREE
 7-11: Begin Free-form Group (/FREE)
  8-80: Free-form Operations                                               
 /END-FREE
 7-15: End Free-form Group (/END-FREE)


***********************************************************************************************
*** OUTPUT SPECIFICATION
***********************************************************************************************

Program Described Record Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
OFilename++DF..N01N02N03Excnam++++B++A++Sb+Sa+.............................Comment+++++++++++++
6: Form Type (O)
 7-16: File Name
           17: Type
            18: Fetch Overflow/Release
               21-29: Output Conditioning Indicators
                        30-39: EXCEPT Name
                                  40-51: Space and Skip
                                  40-42: Space Before
                                     43-45: Space After
                                        46-48: Skip Before
                                           49-51: Skip After
                                                                           81-100: Comments    

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
OFilename++DAddN01N02N03Excnam++++.........................................Comment+++++++++++++
6: Form Type (O)
 7-16: File Name
           17: Type
            18-20: Record Addition/Deletion
               21-29: Output Conditioning Indicators
                        30-39: EXCEPT Name
                                                                           81-100: Comments    

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
O.........And..N01N02N03Excnam++++.........................................Comment+++++++++++++
6: Form Type (O)
          16-18: Logical Relationship
               21-29: Output Conditioning Indicators
                        30-39: EXCEPT Name
                                                                           81-100: Comments    

Program Described Field Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
O..............N01N02N03Field+++++++++YB.End++PConstant/editword/DTformat++Comment+++++++++++++
6: Form Type (O)
               21-29: Output Indicators
                        30-43: Field Name
                                      44: Edit Codes
                                       45: Blank After
                                         47-51: End Position
                                              52: Data Format
                                               53-80: Constant, Edit Word, Data Attributes, Format Name
                                                                           81-100: Comments    

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
O..............................................Constant/editword-ContinutioComment+++++++++++++
6: Form Type (O)
                                               53-80: Constant, Edit Word, Data Attributes, Format Name
                                                                           81-100: Comments    

Externally Described Record Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
ORcdname+++D...N01N02N03Excnam++++.........................................Comment+++++++++++++
6: Form Type (O)
 7-16: Record Name
           17: Type
               21-29: Output Indicators
                        30-39: EXCEPT Name
                                                                           81-100: Comments    

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
ORcdname+++DAddN01N02N03Excnam++++.........................................Comment+++++++++++++
6: Form Type (O)
 7-16: Record Name
           17: Type
            18-20: Record Addition
               21-29: Output Indicators
                        30-39: EXCEPT Name
                                                                           81-100: Comments    

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
O.........And..N01N02N03Excnam++++.........................................Comment+++++++++++++
6: Form Type (O)
          16-18: Logical Relationship
               21-29: Output Indicators
                        30-39: EXCEPT Name
                                                                           81-100: Comments    

Externally Described Field Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
O..............N01N02N03Field+++++++++.B...................................Comment+++++++++++++
6: Form Type (O)
               21-29: Output Indicators
                        30-43: Field Name
                                       45: Blank After
                                                                           81-100: Comments    



***********************************************************************************************
*** PROCEDURE SPECIFICATION
***********************************************************************************************

Procedure Specification Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
PName+++++++++++..B...................Keywords+++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (P)
 7-21: Name     
                  24: Begin/End Procedure
                                      44-80: Keywords                      
                                                                           81-100: Comments    

Procedure Specification Keyword Continuation Line Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
P.....................................Keywords+++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (P)
                                      44-80: Keywords                      
                                                                           81-100: Comments    

Procedure Specification Continued Name Line Layout
*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10
PContinuedName+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Comments++++++++++++
6: Form Type (P)
 7-80: Continued Name                                                      
                                                                           81-100: Comments    

Prism language file

Prism.languages.rpgle = {

  // Fixed format items.  
  'comment': [
    /^.{6}\*.+/m,
    /^.{6}\/\/.+/m
  ],

  // Free-form syntax.
  'freeformsyntax': {
    'pattern': /(^|[^\\])(?:\/free[\w\W]*?\/end-free)/i,
    'inside': {
      'comment': { 
        'pattern': /(^|[^\\:])\/\/.*/,
        'lookbehind': true,
      },
      'string': {
        'pattern': /(['])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
        'greedy': true
      },
      'function': /\%\w+(?=\()/i,
      'symbol': /(\*(all[gux]?|altseq|blanks?|cancl|cdmy|cmdy|crtbndrpg|crtrpgmod|cymd|date|day|detc|detl|dmy|dtaara|end|entry|equate|eur|ext|extdft|file|ftrans|getin|hival|hms|ilerpg|in|init|in[0-9][0-9]|ino[a-g]|inov|inlr|inh[1-9]|inl[1-9]|inu[1-8]|inrt|inzsr|iso|jis|job|jobrun|jul|lda|like|longjul|lock|loval|m|mdy|month|noind|nokey|none|nopass|null|ofl|off|omit|on|pda|place|pssr|rightadj|routine|start|string|sys|term|totc|totl|trim|usa|user|var|v[0-9]r[0-9]m[0-9]|varsize|year|ymd|zeros?))/i,
      'keyword': [
        /(\/free|\/end-free)/i,
        /\b(acq|and|begsr|callp|chain|clear|close|commit|dealloc|delete|dou|dow|dsply|dump|else|elseif|enddo|endfor|endif|endmon|endsl|endsr|eval|evalr|eval-corr|except|exfmt|exsr|feod|for|force|if|in|iter|leave|leavesr|monitor|next|on-error|open|or|other|out|post|read|readc|reade|readp|readpe|rel|reset|return|rolbk|select|setgt|setll|sorta|test|unlock|update|when|write|xml-into|xml-sax)\b/i
      ],
      'number': /\b([\d]+)\b/i,
      'operator': /[<>+\-=/%*]/,
      'punctuation': /[()[\],.:;]/
    }
  },

  // Calculation (C) specification.
  'cspec': {
    'pattern': /^.{5}c.+/mi,
    'inside': {
      'comment': {
        'pattern': /(^.{80})(.+)/m,
        'lookbehind': true,
      },

      'cspecextendedfactor2': {
        'pattern': /(^.{25}(callp     |dou       |dow       |eval      |evalr      |for      |if        |on\-error  |return    |when      ))(.{1,45})/mi,
        'lookbehind': true,
        'inside': {
          'function': /\%\w+(?=\()/,
          'symbol': /\*\w+/,
          'number': /\b([\d]+)\b/i,
          'operator': /[<>+\-=/%*]/,
          'punctuation': /[():]/
        },
      },

      'cspecresult': {
        'pattern': /(^.{49})(\w{1,14})/mi,
        'lookbehind': true,
        'alias': 'variable',
      },

      // 'cspecfactor2': {
      //   'pattern': /(^.{35})(\w{1,14})/mi,
      //   'lookbehind': true,
      //   'alias': 'entity',
      // },

      'cspecfactor2': {
        'pattern': /(^.{35})(\w{1,14})/mi,
        'lookbehind': true,
        'inside': {
          'symbol': /\*\w+?/,
          'number': /\d+/,
          'statement': /\w+/,
          'punctuation': /[:]/,
        },
      },


      'cspecoperation': {
        'pattern': /(^.{25})(\w{1,10})/mi,
        'lookbehind': true,
        'alias': 'keyword',
      },

      'cspecfactor1': {
        'pattern': /(^.{11})(.{1,14})/,
        'lookbehind': true,
        'inside': {
          'symbol': /\*\w+/,
          'variable': /\w+/,
        },
      },

      'spec': {
        'pattern': /(^.{5})c/mi,
        'lookbehind': true,
        'alias': 'keyword'
      },


    },
  },

  // Control (H) specification.
  'hspec': {
    'pattern': /^.{5}h.+/mi,
    'inside': {
      'comment': {
        'pattern': /(^.{80})(.+)/m,
        'lookbehind': true,
      },

      'hspeckeywords': {
        'pattern': /(^.{6})(.{0,74})/m,
        'lookbehind': true,
        'inside': {
          'string': {
            'pattern': /(['])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
            'greedy': true
          },
          'symbol': /\*.+(?=[\):])/,
          'function': /(alloc|actgrp|altseq|alwnull|aut|bnddir|ccsid|copynest|copyright|cursym|cvtopt|datedit|datfmt|debug|decedit|decprec|dftactgrp|dftname|enbpfrcol|expropts|extbinint|fixnbr|fltdiv|formsalign|ftrans|genlvl|indent|intprec|langid|(no)?main|openopt|optimize|option|pgminfo|prfdta|srtseq|stgmdl|text|thread|timfmt|truncnbr|usrprf)/i,
          'number': /\b([\d]+)\b/i,
          'punctuation': /[():]/,
        },
      },

      'spec': {
        'pattern': /(^.{5})h/mi,
        'lookbehind': true,
        'alias': 'keyword'
      },

    },
  },


  // Procedure (P) specification.
  'pspec': {
    'pattern': /^.{5}p.+/mi,
    'inside': {
      'comment': {
        'pattern': /(^.{80})(.+)/m,
        'lookbehind': true,
      },

      'pspeckeywords': {
        'pattern': /(^.{43})(.{0,37})/m,
        'lookbehind': true,
        'inside': {
          'function': /(export|serialize)/i,
        },
      },

      'pspecdefinitiontype': {
        'pattern': /(^.{23})(b|e)/mi,
        'lookbehind': true,
        'alias': 'symbol',
      },

      'pspecname': {
        'pattern': /(^.{6})([ \w]+)/mi,
        'lookbehind': true,
        'alias': 'variable',
      },

      'pspeclongvariable': {
        'pattern': /(^.{6})(.+(?=\.{3}))/m,
        'lookbehind': true,
        'alias': 'variable',
      },

      'spec': {
        'pattern': /(^.{5})p/mi,
        'lookbehind': true,
        'alias': 'keyword'
      },

    },
  },

  // Definition (D) specification.
  'dspec': {
    'pattern': /^.{5}d.+/mi,
    'inside': {
      'comment': {
        'pattern': /(^.{80})(.+)/m,
        'lookbehind': true
      },

      'dspeckeywords': {
        'pattern': /(^.{43})(.{0,37})/m,
        'lookbehind': true,
        'inside': {
          'string': {
            'pattern': /(['])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
            'greedy': true
          },
          'function': [
            /\%\w+(?=\()/i,
            /\b(alias|align|alt(seq)?|ascend|based|ccsid|class|const|ctdata|datfmt|descend|dim|dtaara|export|extfld|extfmt|extname|extpgm|extproc|fromfile|import|inz|len|like|likeds|likefile|likerec|noopt|occurs|opdesc|options|overlay|packeven|perrcd|prefix|procptr|qualified|rtnparm|static|template|timfmt|tofile|value|varying)(?=\(?)(?!\w)/i
          ],
          'symbol': /\*(allx?|allthread|cl|cnowiden|cwiden|dft|input|java|key|next|none|nopass|nullind|omit|output|rightadj|string|trim|var(size)?)/i,
          'number': /\b([\d]+)\b/i,
          'punctuation': /[():]/,
        },
      },

      'dspecdecpos': {
        'pattern': /(^.{41})([\d ]\d?)/m,
        'lookbehind': true,
        'alias': 'number',
      },

      'dspecinternaldatatype': {
        'pattern': /(^.{39})(.)/m,
        'lookbehind': true,
        'alias': 'function',
      },

      'dspecfromtoposition': {
        'pattern': /(^.{25})(.{1,14})/m,
        'lookbehind': true,
        'inside': {
          'number': /\d/,
          'symbol': /\*(file|opcode|parm|proc|record|routine|status)/i,
        },
      },

      'dspecdefinitiontype': {
        'pattern': /(^.{23})(c |ds|pr|pi|s )/mi,
        'lookbehind': true,
        'alias': 'symbol',
      },

      'dspecname': {
        'pattern': /(^.{6})([ \w]+)/mi,
        'lookbehind': true,
        'alias': 'variable',
      },

      'dspeclongvariable': {
        'pattern': /(^.{6})(.+(?=\.{3}))/m,
        'lookbehind': true,
        'alias': 'variable',
      },

      'spec': {
        'pattern': /(^.{5})d/mi,
        'lookbehind': true,
        'alias': 'keyword'
      },

    },
  },


  // Compiler directives starting in position 7:
  // /title
  // /eject
  // /space
  // /copy
  // /include
  // /define
  // /undefine
  // /if
  // /else
  // /endif
  // /elseif
  // /eof

};

RPGLE highlight example


      *-- Parameters
     d inpath          s            100a
     d iomode          s             10  0
     d ioinode         s             10  0
     d ionlinks        s              5  0
     d iouserid        s             10  0
     d iogroupid       s             10  0
     d iosize          s             10  0
     d ioadate         s              7a
     d ioatime         s              6a
     d iomdate         s              7a
     d iomtime         s              6a
     d iocdate         s              7a
     d ioctime         s              6a
     d iodevice        s             10  0
     d iobsize         s             10  0
     d ioasize         s             10  0
     d ioobjtype       s             12a
     d iocodepage      s             10  0
     d ioerror         s              1a

      *-- API return structure

     d statds          ds
     d  st_mode                      10u 0                                      File mode
     d  st_ino                       10u 0                                      File inode
     d  st_nlink                      5u 0                                      # links
     d  st_pad                        2a                                        Padding
     d  st_uid                       10u 0                                      Owner's user id
     d  st_gid                       10u 0                                      Owner's group id
     d  st_size                      10i 0                                      Regular file size
     d  st_atime                     10i 0                                      Access date/time
     d  st_mtime                     10i 0                                      Mod date/time
     d  st_ctime                     10i 0                                      Change date/time
     d  st_dev                       10u 0                                      Device ID
     d  st_blksize                   10u 0                                      Block size
     d  st_alcsize                   10u 0                                      Allocated size
     d  st_objtype                   12a                                        AS/400 object type
     d  st_codepag                    5u 0                                      Data code page
     d  st_reserv1                   67a                                        Reserved

      *-- Constants

     d NULL            c                   x'00'
     d SUCCESS         c                   '0'
     d FAILURE         c                   '1'

      *-- Prototypes

     d stat            pr            10i 0 extproc('stat')
     d  path                           *   value
     d  buf                            *   value

      *-- Variables

     d path            s            640a   inz
     d epoch           s               z   inz(z'1970-01-01-00.00.00.00000')
     d status          s             10i 0 inz
     d workdt          s               z
     d workd           s               d
     d workt           s               t

      *-- Lists

     c     *entry        plist
     c                   parm                    inpath
     c                   parm                    iomode
     c                   parm                    ioinode
     c                   parm                    ionlinks
     c                   parm                    iouserid
     c                   parm                    iogroupid
     c                   parm                    iosize
     c                   parm                    ioadate
     c                   parm                    ioatime
     c                   parm                    iomdate
     c                   parm                    iomtime
     c                   parm                    iocdate
     c                   parm                    ioctime
     c                   parm                    iodevice
     c                   parm                    iobsize
     c                   parm                    ioasize
     c                   parm                    ioobjtype
     c                   parm                    iocodepage
     c                   parm                    ioerror

      *-------------------------------------------------------------------------

     c                   eval      path = %trim(inpath) + NULL

     c                   eval      status = stat(%addr(path) : %addr(statds))

     c                   if        status = 0
     c                   eval      ioerror = SUCCESS
     c                   else
     c                   eval      ioerror = FAILURE
     c                   endif

     c                   if        ioerror = SUCCESS

      *-- st_mode (file mode)

     c                   move      st_mode       iomode

      *-- st_ino (file inode)

     c                   move      st_ino        ioinode

      *-- st_nlink (# of links to file)

     c                   move      st_nlink      ionlinks

      *-- st_uid (owner's user id)

     c                   move      st_uid        iouserid

      *-- st_gid (owner's group id)

     c                   move      st_gid        iogroupid

      *-- st_size (regular file size)

     c                   move      st_size       iosize

      *-- st_atime (access date/time)

     c                   eval      workdt = epoch
     c                   adddur    st_atime:*s   workdt
     c                   move      workdt        workd
     c                   move      workdt        workt
     c     *cymd0        move      workd         ioadate
     c     *hms0         move      workt         ioatime

      *-- st_mtime (modification date/time)

     c                   eval      workdt = epoch
     c                   adddur    st_mtime:*s   workdt
     c                   move      workdt        workd
     c                   move      workdt        workt
     c     *cymd0        move      workd         iomdate
     c     *hms0         move      workt         iomtime

      *-- st_ctime (file status changed date/time)

     c                   eval      workdt = epoch
     c                   adddur    st_ctime:*s   workdt
     c                   move      workdt        workd
     c                   move      workdt        workt
     c     *cymd0        move      workd         iocdate
     c     *hms0         move      workt         ioctime

      *-- st_dev (file device)

     c                   move      st_dev        iodevice

      *-- st_blksize (block size)

     c                   move      st_blksize    iobsize

      *-- st_alcsize (allocated file size)

     c                   move      st_alcsize    ioasize

      *-- st_objtype (AS/400 object type)

     c                   move      st_objtype    ioobjtype

      *-- st_codepag (data code page)

     c                   move      st_codepag    iocodepage

     c                   endif

     c                   eval      *inlr = *on