Upload
vishnu400
View
224
Download
0
Embed Size (px)
Citation preview
8/3/2019 SEU User Defined Line Commands
1/9
SEU - User defined Line Commands code sample - long
Here's a sample - lurkers please feel free to critique!
h dftactgrp(*no) actgrp('QILE') indent(*none)
* dbgview(*list)
* Buck Calabro April 2000
* large portions lifted from the SEU User's Guide and Reference SC09-2605-
00
* If you have a really large source file, increase the size of SourceStmt
* Note that this is really a boiler-plate more than anything else.
* To activate, STRSEU, press F13, page down and fill in the name of this
program
* SEU puts data in QTEMP/QSUSPC
* this space has 3 data blocks:
* 1. Input from SEU
* 2. Output back to SEU
* 3. Actual source lines
* Supports the following line commands:
* ATTRxx - set line attribute (colour, highlight, etc.)
* Supports the following F keys:
* F7 - Split/join a line (Splits this line to next if cursor in the middle
of a line,
* joins next line to this if cursor at the end of
a line)
* F8 - NOP
* Uses messages in a user-created message file:
* Message ID Severity Message Text
* SEU0001 0 Cursor is not positioned within a source
statement.
* SEU0002 0 Line split complete.
* SEU0003 0 Line join complete.
* SEU0004 0 Cannot update in Browse mode
* SEU0005 0 ATTR command processed
* SEU0006 0 ATTR command not valid for this member type
* Input from SEU
D SEUInput DS BASED(SEUInputP)
D StmtLength 10i 0
D CurRec 10i 0
D CurCol 10i 0
D CCSID 10i 0
D InputRecords 10i 0D SrcMbr 10
D SrcFil 10
D SrcLib 10
D MbrType 10
D FnKey 1
D SEUMode 1
D SplitSession 1
D ReservedInp 1
* Output to SEU
D SEUOutput DS BASED(SEUOutputP)
8/3/2019 SEU User Defined Line Commands
2/9
D ReturnCode 1
D ReservedOut1 3
D OutputRecords 10i 0
D InsertedSeq 7
D ReservedOut2 21
* Source statements. SEU passes the line the cursor is on,
* and the next line
D SEUSource DS BASED(SEUSourceP)
D LineCmd 7
D LineRetCode 1
D SourceSeq 6
D SourceDate 6
D SourceStmt 256
* Work variables
D SEUInputPParm S *
D SEUOutputPParm S *
D SEUSourcePParm S *
D ThisLineP S *
D NextLineP S *
D WorkLineP S *
D i s 10i 0 inz
D CutColumns s like(SourceStmt)
D ThisLineCmd s like(LineCmd)
D ThisStmt s like(SourceStmt)
D NextStmt s like(SourceStmt)
D SourceLength s 10i 0
D CutLen s 10i 0
D BlankLineCmd s like(LineCmd)
D RtnCode s 7
DSndMsg pr
D MsgID 7 const
D RtnCodeOut Like(RtnCode)
DLoadWorkFromInp pr
D SrcDtaPtrInp * const
D LineCmdOut like(LineCmd) Options(*Omit)
D LineRetCodeOut like(LineRetCode) Options(*Omit)
D SourceSeqOut like(SourceSeq) Options(*Omit)
D SourceDateOut like(SourceDate) Options(*Omit)
D SourceStmtOut like(SourceStmt) Options(*Omit)
DLoadOutFromWork pr
D SrcDtaPtrInp * const
D LineCmdInp like(LineCmd) Options(*Omit)
D LineRetCodeInp like(LineRetCode) Options(*Omit)
D SourceSeqInp like(SourceSeq) Options(*Omit)D SourceDateInp like(SourceDate) Options(*Omit)
D SourceStmtInp like(SourceStmt) Options(*Omit)
DGetAttrFromCmd pr 1
D LineCmdInp like(LineCmd) const
*================================================================
C *Entry Plist
C Parm SEUInputPParm
C Parm SEUOutputPParm
C Parm SEUSourcePParm
8/3/2019 SEU User Defined Line Commands
3/9
* Get the data referred to by the input pointers
C Eval SEUInputP = SEUInputPParm
C Eval SourceLength = %len(SEUSource) -
C %len(SourceStmt) +
C StmtLength
C Eval SEUOutputP = SEUOutputPParm
C Eval ThisLineP = SEUSourcePParm
C Eval NextLineP = SEUSourcePParm + SourceLength
* Set default values
C Eval ReturnCode = '0'
C Eval OutputRecords = InputRecords - 1
C Eval InsertedSeq = '0000000'
* Allow updates only if in Update mode
C If SeuMode = 'U'
C Exsr LineCommands
C Exsr CmdKeys
C Else
C Eval ReturnCode = '1'
* Send back "Not in update mode" message
C CallP SndMsg('SEU0004': RtnCode)C EndIf
C Eval *InLR = *On
C Return
*================================================================
* Process all the line commands (commands typed in the seq number area)
* InputRecords includes the "next" line.
* For example, if a line command is placed on lines 1 and 5, InputRecords
will be 6
C LineCommands Begsr
C Eval WorkLineP = ThisLineP
C Eval i = 1
C DoW i
8/3/2019 SEU User Defined Line Commands
4/9
* based on the source member type
C If MbrType = 'RPG' or
C MbrType = 'RPGLE' or
C MbrType = 'SQLRPG' or
C MbrType = 'SQLRPGLE' or
C MbrType = 'PF' or
C MbrType = 'PRTF' or
C MbrType = 'DSPF'
C Eval %subst(ThisStmt: 1: 1) =
C GetAttrFromCmd(ThisLineCmd)
* Put the work fields back into the source space
C Callp LoadOutFromWork(ThisLineP:
C *Omit:
C *Omit:
C *Omit:
C *Omit:
C ThisStmt)
* Send back a message to show that we saw and processed the line cmd
C CallP SndMsg('SEU0005': RtnCode)
C Else
* Send back a message to show that we saw and ignored the line cmdC CallP SndMsg('SEU0006': RtnCode)
C EndIf
C EndSL
C Eval i = i + 1
C Eval WorkLineP = WorkLineP + SourceLength
C EndDO
C EndSR
*================================================================
* Process the command keys (F7/F8)
C CmdKeys Begsr
C Select
* Is the cursor outside of the source statement with an F key press?
C When (FnKey = '7' or
C FnKey = '8') and
C CurCol = 0
* Tell SEU that the cursor is outside the source area
C CallP SndMsg('SEU0001': RtnCode)
* F7 = split/joinC When FnKey = '7'
* Should we do a split or a join?
* Get the line the cursor is on
C Callp LoadWorkFromInp(ThisLineP:
C *Omit:
C *Omit:
C *Omit:
C *Omit:
C ThisStmt)
* Get the next line
8/3/2019 SEU User Defined Line Commands
5/9
C Callp LoadWorkFromInp(NextLineP:
C *Omit:
C *Omit:
C *Omit:
C *Omit:
C NextStmt)
* If there is data beyond the current column, split it
* If the rest of the line is blank, join the next line to this one
C if %subst(ThisStmt: CurCol:
C StmtLength - CurCol - 1)
C *Blanks
C Exsr SplitLine
C Else
C Exsr JoinLine
C EndIf
C EndSL
C EndSR
*================================================================
* Split line at blank
C SplitLine Begsr
* Cut the columns to the right including the column the cursor is in
C Eval CutColumns = %subst(ThisStmt:
C CurCol)
* Drop the rightmost columns into the next line
C Eval NextStmt = CutColumns
* Trim the cut columns off the right side of this line
C If CurCol > 1
C Eval ThisStmt = %subst(ThisStmt:
C 1:
C CurCol - 1)
C Else
C Eval ThisStmt = *Blanks
C EndIf
* Put the work fields back into the source space
C Callp LoadOutFromWork(ThisLineP:
C *Omit:
C *Omit:
C *Omit:
C *Omit:
C ThisStmt)
C Callp LoadOutFromWork(NextLineP:
C *Omit:
C *Omit:
C *Omit:
C *Omit:
C NextStmt)
* Tell SEU that we're returning 2 lines
C Eval OutputRecords = 2
* Tell SEU that the split is complete
8/3/2019 SEU User Defined Line Commands
6/9
C CallP SndMsg('SEU0002': RtnCode)
C EndSR
*================================================================
* Join line
C JoinLine Begsr
* Don't try to join if the next line is a blank
C If NextStmt *Blanks
* Grab the leftmost columns from the next line (as many columns
* as are blank at the end of this line)
C Eval CutColumns = %subst(NextStmt:
C 1:
C (StmtLength -
C CurCol +
C 1 ))
* Add the columns from the next line onto the end of this line
C ' ' Checkr CutColumns CutLen
C Eval ThisStmt = %subst(ThisStmt:
C 1:C CurCol - 1) +
C %subst(CutColumns:
C 1:
C CutLen)
* Blank out the cut columns
C Eval %subst(NextStmt: 1: CutLen) = *Blanks
* If we've cut the entire next line, delete it. Otherwise,
* simply cut the columns out - don't shift the remainder of the line
C If NextStmt = *Blanks
C Eval OutputRecords = 1
C Eval InsertedSeq = 'A000000'
C Else
C Eval OutputRecords = 2
C Eval InsertedSeq = 'A000000'
C EndIf
* Put the work fields back into the source space
C Callp LoadOutFromWork(ThisLineP:
C *Omit:
C *Omit:
C *Omit:
C *Omit:
C ThisStmt)
C Callp LoadOutFromWork(NextLineP:C *Omit:
C *Omit:
C *Omit:
C *Omit:
C NextStmt)
* Tell SEU that the join is complete
C CallP SndMsg('SEU0003': RtnCode)
C EndIf
C EndSR
8/3/2019 SEU User Defined Line Commands
7/9
*================================================================
* Send a "status" message back to SEU
* There's a trick in use here that you need to be aware of.
* the message stack count is determined by how deep in the call stack the
* subprocedure is! Here's why it was set to 3:
* STRSEU 1
* SEUEXIT 2
* SndMsg 3
PSndMsg b
DSndMsg pi
D MsgID 7 const
D RtnCodeOut Like(ErrSMsgID)
* Send message API parameters
D MsgIDWrk s like(MsgID)
D MsgFil s 20 inz('SEUEXIT *LIBL ')
D MsgData s 1 inz(' ')
D MsgDataLen s 10i 0 inz
D MsgType s 10 inz('*INFO')
D MsgStackEnt s 10 inz('*')
D MsgStackCnt s 10i 0 inz(3)D MsgKey s 4
D MsgErrStruc s like(ErrStruc)
* API error structure
D ErrStruc DS inz
D ErrSSize 10i 0 inz(%len(ErrStruc))
D ErrSUse 10i 0
D ErrSMsgID 7
D ErrSResrv 1
D ErrSData 80
C eval MsgIdWrk = MsgID
C eval MsgErrStruc = ErrStruc
C Call 'QMHSNDPM'
C Parm MsgIDWrk
C Parm MsgFil
C Parm MsgData
C Parm MsgDataLen
C Parm MsgType
C Parm MsgStackEnt
C Parm MsgStackCnt
C Parm MsgKey
C Parm MsgErrStruc
C Eval ErrStruc = MsgErrStruc
C Eval RtnCodeOut = ErrSMsgID
PSndMsg e
*================================================================
* Load the work fields from the data SEU sent us
PLoadWorkFromInp b
DLoadWorkFromInp pi
D SrcDtaPtrInp * const
D LineCmdOut like(LineCmd) Options(*Omit)
D LineRetCodeOut like(LineRetCode) Options(*Omit)
8/3/2019 SEU User Defined Line Commands
8/9
D SourceSeqOut like(SourceSeq) Options(*Omit)
D SourceDateOut like(SourceDate) Options(*Omit)
D SourceStmtOut like(SourceStmt) Options(*Omit)
* Point to the data within the SEU space
C Eval SEUSourceP = SrcDtaPtrInp
C If %addr(LineCmdOut) *Null
C Eval LineCmdOut = LineCmd
C Endif
C If %addr(LineRetCodeOut) *Null
C Eval LineRetCodeOut = LineRetCode
C Endif
C If %addr(SourceSeqOut) *Null
C Eval SourceSeqOut = SourceSeq
C Endif
C If %addr(SourceDateOut) *Null
C Eval SourceDateOut = SourceDate
C Endif
C If %addr(SourceStmtOut) *Null
C Eval SourceStmtOut = %subst(SourceStmt: 1:
C StmtLength)
C Endif
P e
*================================================================
* Load data back to SEU from the work fields
PLoadOutFromWork b
DLoadOutFromWork pi
D SrcDtaPtrInp * const
D LineCmdInp like(LineCmd) Options(*Omit)
D LineRetCodeInp like(LineRetCode) Options(*Omit)
D SourceSeqInp like(SourceSeq) Options(*Omit)
D SourceDateInp like(SourceDate) Options(*Omit)
D SourceStmtInp like(SourceStmt) Options(*Omit)
* Point to the data within the SEU space
C Eval SEUSourceP = SrcDtaPtrInp
C If %addr(LineCmdInp) *Null
C Eval LineCmd = LineCmdInp
C Endif
C If %addr(LineRetCodeInp) *Null
C Eval LineRetCode = LineRetCodeInp
C Endif
C If %addr(SourceSeqInp) *Null
C Eval SourceSeq = SourceSeqInp
C EndifC If %addr(SourceDateInp) *Null
C Eval SourceDate = SourceDateInp
C Endif
C If %addr(SourceStmtInp) *Null
C Eval SourceStmt = SourceStmtInp
C Endif
P e
*================================================================
* Extract an attribute byte from the input line command
8/3/2019 SEU User Defined Line Commands
9/9
* The line command is formatted "ATTRxx" where XX is a mnemnonic for
* the attribute byte to assign to the line. The mnemnonics are the same
* as used by DDS with the addition of colours.
PGetAttrFromCmd b
DGetAttrFromCmd pi 1
D LineCmdInp like(LineCmd) const
D AttributeByte s 1
D AttrTest s 2
D i s 10i 0
DAttrMnemDS ds
D 2 inz(' ')
D 2 inz('RI')
D 2 inz('HI')
D 2 inz('UL')
D 2 inz('BL')
D 2 inz('CS')
D 2 inz('CP')
D 2 inz('CL')
D AttrMnem 2 dim(8) overlay(AttrMnemDS)
DAttrDS ds
D 1 inz(x'20')
D 1 inz(x'21')
D 1 inz(x'22')
D 1 inz(x'24')
D 1 inz(x'28')
D 1 inz(x'30')
D 1 inz(x'38')
D 1 inz(x'3A')
D Attr 1 dim(8) overlay(AttrDS)
* Default to normal
C Eval AttributeByte = Attr(1)
* Extract the mnemnonic from the line command
C Eval AttrTest = %subst(ThisLineCmd: 5: 2)
* Convert the mnemnonic to an attribute byte
C Eval i = 1
C AttrTest Lookup AttrMnem(i) 20
C If *In20 = *On
C Eval AttributeByte = Attr(i)
C EndIf
C Return AttributeByte
P e