home *** CD-ROM | disk | FTP | other *** search
/ Power GUI Programming with VisualAge C++ / powergui.iso / trialva / ibmcppw / macros / ispfcmd.lx < prev    next >
Encoding:
Text File  |  1996-02-22  |  27.3 KB  |  630 lines

  1. /******************************************************************************
  2.  * ISPF Prefix commands                                                       *
  3.  *                                                                            *
  4.  * Arguments:  cmd  - prefix command to be executed.  This may be any of the  *
  5.  *                    following:  add                                         *
  6.  *                                delete                                      *
  7.  *                                target                                      *
  8.  *                                show                                        *
  9.  *                                exclude                                     *
  10.  *                                shift                                       *
  11.  *                                duplicate                                   *
  12.  *                                current                                     *
  13.  *                                case                                        *
  14.  *                                                                            *
  15.  *             parm - command specific parameters                             *
  16.  *                                                                            *
  17.  *****************************************************************************/
  18. arg cmd parm
  19.  
  20. markno = 0                             /* global mark count */
  21. 'extract prefixentry'                  /* get text in prefix entry field */
  22. parse upper var prefixentry pe         /* uppercase text */
  23. count = getcount(pe)                   /* pull out numeric part of command */
  24.  
  25. select
  26.    /* Add command.  This command inserts one or more lines into the file.
  27.       Parameters: none */
  28.    when "ADD" = cmd then do
  29.  
  30.       'set prefixentry'                /* reset prefix entry field */
  31.       'extract class'                  /* get the class of this line */
  32.       if pos("PFXSHOW",class) \= 0 then do
  33.                                        /* this is an exclude header */
  34.          if nextline("next visible") then
  35.                                        /* move to next visible line */
  36.             'prev class PFXEXCLUDE'    /* find previous exclude line */
  37.          else do                       /* no more visible lines */
  38.             do forever                 /* loop through file */
  39.                if \nextline() then     /* if at end of file */
  40.                   leave                /* get out of loop */
  41.                'extract class'         /* get class of line */
  42.                if pos("PFXEXCLUDE",class) = 0 then do
  43.                                        /* if not exclude line */
  44.                   'prev'               /* go back one */
  45.                   leave                /* get out of loop */
  46.                end
  47.             end
  48.          end
  49.       end
  50.       'add 'count                      /* insert count lines */
  51.       exit                             /* done */
  52.    end
  53.  
  54.    /* Target command.  This command executes a block copy or move.
  55.       Parameters: before | after | overlay [block] */
  56.    when "TARGET" = cmd then do
  57.       parse var parm target block
  58.  
  59.       call setmark                     /* set a mark */
  60.  
  61.       if "BLOCK" = block then do
  62.          if \nextline() | findprefix(substr(pe,1,2)) = "" then
  63.             call errormsg(2 pe)
  64.          call setmark                  /* mark end of block */
  65.       end
  66.  
  67.       'top'                            /* go to top of file */
  68.       src = findprefix("C M")          /* search for copy or move */
  69.       if src = "" then                 /* if not found issue error */
  70.          call errormsg(1 pe)
  71.       'block clear'                    /* clear current block */
  72.       'block mark element'             /* mark the current element */
  73.       c1 = substr(src,1,1)             /* get first char of copy or move */
  74.       if c1 = "C" then call setmark    /* if copy, set another mark */
  75.       if c1 = substr(src,2,1) then do  /* if block copy or move... */
  76.          if \nextline() |,
  77.             findprefix(substr(src,1,2)) = "" then call errormsg(2 src)
  78.                                        /* find matching block */
  79.          'block mark element'          /* mark block */
  80.          if c1 = "C" then call setmark /* if copy, set another mark */
  81.       end
  82.       if c1 = "C" then                 /* set type of block operation */
  83.          action = "COPY"
  84.       else
  85.          action = "MOVE"
  86.  
  87.       overlay = "OVERLAY" = target     /* set overlay flag */
  88.       if overlay then                  /* if overlay... */
  89.          target = before               /* copy/move before */
  90.  
  91.       'mark find PFXMARK1'             /* locate target */
  92.       'block 'action target' clear'    /* issue copy or move */
  93.       if RC = -3 then                  /* if copy/move into itself, error */
  94.          call errormsg(6 action)
  95.  
  96.       if overlay then do               /* if overlay command */
  97.          'mark find PFXMARK1'          /* find overlay line */
  98.          'block mark element'          /* set the block on the line */
  99.          if block = "BLOCK" then do    /* if this is a block overlay */
  100.             'mark find PFXMARK2'       /* find the closing block */
  101.             'block mark element'       /* mark the whole block */
  102.          end
  103.          'block delete'                /* delete the overlayed lines */
  104.       end
  105.  
  106.    end
  107.  
  108.    /* Delete command.  This command deletes one or more lines.
  109.       Parameters:  [block] - indicate block delete */
  110.    when "DELETE" = cmd then do
  111.       'block clear'                    /* clear the current block */
  112.       'block mark element'             /* mark this element */
  113.       if parm = "BLOCK" then do        /* if block delete... */
  114.          if \nextline() | findprefix("DD") = "" then call errormsg(2 pe)
  115.                                        /* look for end of block */
  116.       end
  117.       else do                          /* else not block delete */
  118.          lines = count - 1
  119.          if lines > 0 then
  120.             'scroll down' lines        /* find last line to be deleted */
  121.       end
  122.       'extract class'                  /* get the class of the last line */
  123.       if pos("PFXSHOW",class) \= 0 then do
  124.                                        /* this is an exclude header */
  125.          if nextline("next visible") then
  126.                                        /* move to next visible line */
  127.             'prev class PFXEXCLUDE'    /* find previous exclude line */
  128.          else do                       /* no more visible lines */
  129.             do forever                 /* loop through file */
  130.                if \nextline() then     /* if at end of file */
  131.                   leave                /* get out of loop */
  132.                'extract class'         /* get class of line */
  133.                if pos("PFXEXCLUDE",class) = 0 then do
  134.                                        /* if not exclude line */
  135.                   'prev'               /* go back one */
  136.                   leave                /* get out of loop */
  137.                end
  138.             end
  139.          end
  140.       end
  141.       'extract deleting'               /* get deleting command */
  142.       'set deleting'                   /* remove it */
  143.       'block mark element'             /* mark the delete block */
  144.       'block delete'                   /* delete the block */
  145.       if headers() then                /* if there are still header lines */
  146.          'set deleting' deleting       /* restore deleting command */
  147.       exit                             /* all done */
  148.    end
  149.  
  150.    /* Show command.  This command shows one or more excluded lines.
  151.       Parameters: all | first | last - indicates which part of the excluded
  152.                                        block to show. */
  153.    when "SHOW" = cmd then do
  154.       'extract class'                  /* get class of current line */
  155.       if pos("PFXSHOW",class) == 0 then
  156.          call errormsg(3)              /* issue error if not exclude header */
  157.       call setmark                     /* set a mark on this line */
  158.       'set prefixentry'                /* clear the prefix entry text */
  159.  
  160.       if parm = "LAST" then do         /* if show last command */
  161.          do forever                    /* look for end of block */
  162.             if \nextline() then leave  /* if no more lines, leave */
  163.             'extract class'            /* get class of line */
  164.             if pos("PFXEXCLUDE",class) = 0 then do
  165.                                        /* if not part of block, leave */
  166.                'prev'
  167.                leave
  168.             end
  169.          end
  170.          dir = 'prev'                  /* set direction */
  171.       end
  172.       else do
  173.          dir = 'next'                  /* set direction */
  174.          'next'
  175.       end
  176.  
  177.       if parm = "ALL" then             /* if showing whole block */
  178.          'extract elements into count' /* set count to file size */
  179.  
  180.       do i = 1 to count                /* loop through the lines */
  181.          'extract class'               /* get class of line */
  182.          if pos("PFXEXCLUDE",class) == 0 then leave
  183.                                        /* if not an excluded line, leave */
  184.          parse var class pre "PFXEXCLUDE" post
  185.          'set class 'pre post          /* remove PFXEXCLUDE from class */
  186.          if \nextline(dir) then leave  /* if no more lines, leave */
  187.       end
  188.  
  189.       if "FIRST" = parm then do        /* if show fisrt command */
  190.          call beginchange              /* make sure changes not recorded */
  191.          'prev'                        /* back up a line */
  192.          'add'                         /* add a new exclude header */
  193.          'set class PFXSHOW'           /* set exclude header class */
  194.          'set show on'                 /* make it a show line */
  195.          call setmark                  /* mark this line */
  196.          'mark find PFXMARK1'          /* find old header */
  197.          call deleteheader             /* delete the header */
  198.          'mark find PFXMARK2'          /* find new header */
  199.          'mark clear PFXMARK2'         /* change mark name to PFXMARK1 */
  200.          markno = 0
  201.          call setmark
  202.          call endchange                /* restore recording status */
  203.       end
  204.       else                             /* not a show first */
  205.          'mark find PFXMARK1'          /* find header */
  206.  
  207.       call excludeheader               /* set exclude header text */
  208.    end
  209.  
  210.    /* Exclude command.  This command excludes one or more lines.
  211.       Parameters - [ALL | BLOCK] - indicates exclude all or block exclude */
  212.    when "EXCLUDE" = cmd then do
  213.       'extract classes'                /* Add PFXEXCLUDE and PFXSHOW classes */
  214.       if pos("PFXEXCLUDE",classes) = 0 then
  215.          'set classes 'classes' PFXSHOW PFXEXCLUDE'
  216.       'extract highlight'              /* Add PFXSHOW to highlight classes */
  217.       if pos("PFXSHOW",highlight) = 0 then
  218.          'set highlight 'highlight' PFXSHOW'
  219.       'extract exclude'                /* Add PFXEXCLUDE to exclude classes */
  220.       if pos("PFXEXCLUDE",exclude) = 0 then
  221.          'set exclude 'exclude' PFXEXCLUDE'
  222.       'extract protect'                /* Add PFXSHOW to protect classes */
  223.       if pos("PFXSHOW",protect) = 0 then
  224.          'set protect 'protect' PFXSHOW'
  225.  
  226.       'extract class'                  /* get class of current line */
  227.       if pos("PFXEXCLUDE",class) > 0 then do
  228.          'set prefixentry'             /* clear prefix entry field */
  229.          exit                          /* quit if line already hidden */
  230.       end
  231.  
  232.       call setmark                     /* set a mark */
  233.       'extract element into startline' /* get element number */
  234.  
  235.       if parm = "BLOCK" then do        /* if block exclude... */
  236.          if \nextline() |,
  237.             findprefix(substr(pe,1,2)) = "" then call errormsg(2 pe)
  238.                                        /* if block not found issue error */
  239.          'set prefixentry'             /* clear prefix entry field text */
  240.          'extract element into endline'/* get element number of end of block */
  241.          count = endline - startline + 1
  242.                                        /* calculate number of lines to exclude*/
  243.       end
  244.       else if parm = "ALL" then        /* if excluding all the lines */
  245.          'extract elements into count' /* get file size */
  246.  
  247.       call beginchange                 /* make sure changes not recorded */
  248.       'mark find PFXMARK1'             /* find first line to exclude */
  249.       'splitjoin split'                /* open a new line before it */
  250.       'set class PFXSHOW'              /* set exclude header class */
  251.       'set show on'                    /* make it a show line */
  252.       call endchange                   /* restore recording */
  253.  
  254.       'next'                           /* move to next line */
  255.       do i = 1 to count                /* loop through and exclude the lines */
  256.          'extract class'
  257.          if pos("PFXSHOW",class) > 0 then leave
  258.          'set class 'class' PFXEXCLUDE'
  259.          if \nextline() then leave
  260.       end
  261.  
  262.       call excludeheader               /* set exclude header */
  263.    end
  264.  
  265.    /* Shift command.  This command shifts one or more lines.
  266.       Parameters: right | left - indicates shift direction
  267.                   trunc | notrunc - indicates if shift should truncate line
  268.                   [block] - indicates block shift */
  269.    when "SHIFT" = cmd then do
  270.       parse var parm dir trunc type
  271.  
  272.       call setmark                     /* set a mark on this line */
  273.       'block clear'                    /* clear the current block */
  274.       'block mark element'             /* mark this line */
  275.  
  276.       if type = "BLOCK" then do        /* if block shift */
  277.          if \nextline() |,
  278.             findprefix(substr(pe,1,2)) = "" then call errormsg(2 pe)
  279.                                        /* search for end of block */
  280.          'set prefixentry'             /* clear prefix entry field text */
  281.          'block mark element'          /* mark the block */
  282.       end
  283.  
  284.       truncate = trunc \= "NOTRUNC"    /* set truncation flag */
  285.       if truncate then do              /* if truncate... */
  286.          'extract limiterror into savelimiterror'
  287.                                        /* save limiterror mode */
  288.          'set limiterror truncate'     /* set limiterror mode to truncate */
  289.          trunc = ""                    /* no option needed for turncate */
  290.       end
  291.  
  292.       'block shift 'dir count trunc' clear'
  293.                                        /* issue shift command */
  294.  
  295.       if truncate then                 /* if truncate, restore limiterror */
  296.          'set limiterror 'savelimiterror
  297.    end
  298.  
  299.    /* Duplicate command.  This command duplicates the current line one or more times
  300.       Parameters:  none */
  301.    when "DUPLICATE" = cmd then do
  302.       call setmark                     /* set a mark on this line */
  303.       'block clear'                    /* clear the current block */
  304.       'block mark element'             /* mark this line */
  305.  
  306.       if parm = "BLOCK" then do        /* if block repeat... */
  307.                                        /* look for end of block */
  308.          if \nextline() | findprefix(substr(pe,1,2)) = "" then
  309.             call errormsg(2 pe)
  310.          'set prefixentry'             /* clear prefix entry field */
  311.          'block mark element'          /* mark the block */
  312.       end
  313.  
  314.       do i = 1 to count                /* copy the line count times */
  315.          'block copy after'
  316.       end
  317.       'block clear'                    /* clear the block */
  318.    end
  319.  
  320.    /* Current command.  This command sets the current line.
  321.       Parameters:  none */
  322.    when "CURRENT" = cmd then do
  323.       call setmark                     /* set a mark on this line */
  324.  
  325.       'set focus.next 1'               /* set to top of window */
  326.       'mark find PFXMARK1'             /* make this the current line */
  327.    end
  328.  
  329.    /* Case command.  This command changes the case of the specified line
  330.       Parameters: upper [block]| lower [block] - indicates desired case */
  331.    when "CASE" = cmd then do
  332.       parse var parm case block
  333.       'set prefixentry'                /* clear prefix entry field */
  334.       'block clear'                    /* clear the current block */
  335.       'block mark element'             /* mark this line */
  336.       if block = "BLOCK" then do
  337.          if case = "UPPER" then do       /* look for block end */
  338.             if \nextline() | findprefix("UCC") = "" then call errormsg(2 pe)
  339.          end
  340.          else if case = "LOWER" then do       /* look for block end */
  341.             if \nextline() | findprefix("LCC") = "" then call errormsg(2 pe)
  342.          end
  343.       end
  344.       else do
  345.          extract element into start
  346.          end = start + count -1              /* get number of lines affected */
  347.          if end > start then
  348.             'find element' end           /* move to last line            */
  349.       end
  350.       'extract class'                  /* get the class of the last line */
  351.       if pos("PFXSHOW",class) \= 0 then do
  352.                                        /* this is an exclude header */
  353.          if nextline("next visible") then
  354.                                        /* move to next visible line */
  355.             'prev class PFXEXCLUDE'    /* find previous exclude line */
  356.          else do                       /* no more visible lines */
  357.             do forever                 /* loop through file */
  358.                if \nextline() then     /* if at end of file */
  359.                   leave                /* get out of loop */
  360.                'extract class'         /* get class of line */
  361.                if pos("PFXEXCLUDE",class) = 0 then do
  362.                                        /* if not exclude line */
  363.                   'prev'               /* go back one */
  364.                   leave                /* get out of loop */
  365.                end
  366.             end
  367.          end
  368.       end
  369.       'set prefixentry'                /* clear prefix entry field */
  370.       'block mark element'             /* mark the case block   */
  371.       'block 'case' clear'             /* set the case          */
  372.       exit
  373.    end
  374. end
  375.  
  376. call setmark                           /* save the current position */
  377. do i = 1 to (markno - 1)               /* loop through the marked lines */
  378.    'extract mark.PFXMARK'i' into markcol'
  379.    if markcol \= 0 then do             /* if mark not deleted */
  380.       'mark find PFXMARK'i             /* find the mark */
  381.       'set prefixentry'                /* clear the prefix entry field */
  382.    end
  383. end
  384. 'mark find PFXMARK'markno              /* restore the current position */
  385.  
  386. cleanup:
  387.  
  388. do i = 1 to markno                     /* loop through and delete marks */
  389.    'mark clear PFXMARK'i
  390. end
  391.  
  392. exit                                   /* all done */
  393.  
  394. /******************************************************************************
  395.  *                                                                            *
  396.  * function getcount(str)                                                     *
  397.  *                                                                            *
  398.  * This function returns the numeric part of a character string.  If there is *
  399.  * no numeric part, then 1 is returned.                                       *
  400.  *                                                                            *
  401.  ******************************************************************************/
  402. getcount:
  403.  
  404. procedure
  405.  
  406. arg count
  407.  
  408. do while datatype(substr(count,1,1)) \= "NUM"
  409.    if length(count) = 1 then
  410.       count = 1
  411.    else
  412.       count = substr(count,2)
  413. end
  414.  
  415. do while datatype(substr(count,length(count))) \= "NUM"
  416.    if length(count) = 1 then
  417.       count = 1
  418.    else
  419.       count = delstr(count,length(count))
  420. end
  421.  
  422. return abs(count)
  423.  
  424. /******************************************************************************
  425.  *                                                                            *
  426.  * setmark routine                                                            *
  427.  *                                                                            *
  428.  * This routine sets a mark on the current line.  It uses the global variable *
  429.  * markno to give the mark a unique name.                                     *
  430.  *                                                                            *
  431.  ******************************************************************************/
  432. setmark:
  433.  
  434. procedure expose markno
  435.  
  436. markno = markno + 1
  437. 'extract element into e'
  438. 'mark set PFXMARK'markno e '-1'
  439. return
  440.  
  441. /******************************************************************************
  442.  *                                                                            *
  443.  * function findprefix(str)                                                   *
  444.  *                                                                            *
  445.  * This function looks for a line whose prefix entry field contains text that *
  446.  * begins with str.  If str contains more than one string, then the first     *
  447.  * line that matches either is returned.  The actual prefix text is returned  *
  448.  * by this function.                                                          *
  449.  *                                                                            *
  450.  ******************************************************************************/
  451. findprefix:
  452.  
  453. procedure
  454.  
  455. arg parm
  456.  
  457. do forever
  458.    'extract prefixentry into pe'
  459.    parse upper var pe upperpe
  460.    cmds = parm
  461.    do while length(cmds) > 0
  462.       parse var cmds cmd cmds
  463.       if length(upperpe) >= length(cmd) then
  464.          if cmd = substr(upperpe,1,length(cmd)) then
  465.             return upperpe
  466.    end
  467.    'find prefixentry'
  468.    if RC \= 0 then return ""
  469. end
  470.  
  471. /******************************************************************************
  472.  *                                                                            *
  473.  * beginchange routine                                                        *
  474.  *                                                                            *
  475.  * This routine changes the recording state so that changes will not be       *
  476.  * recorded.                                                                  *
  477.  *                                                                            *
  478.  ******************************************************************************/
  479. beginchange:
  480.  
  481. procedure expose savechanges saverecording
  482.  
  483. 'extract changes into savechanges'
  484. 'extract recording into saverecording'
  485.  
  486. 'set recording off'
  487. return
  488.  
  489. /******************************************************************************
  490.  *                                                                            *
  491.  * endchange routine                                                          *
  492.  *                                                                            *
  493.  * This routine restored the recording state to that before beginchange was   *
  494.  * called.                                                                    *
  495.  *                                                                            *
  496.  ******************************************************************************/
  497. endchange:
  498.  
  499. procedure expose saverecording savechanges
  500.  
  501. 'set recording 'saverecording
  502. 'set changes 'savechanges
  503. return
  504.  
  505. /******************************************************************************
  506.  *                                                                            *
  507.  * excludeheader routine                                                      *
  508.  *                                                                            *
  509.  * This routine counts the number of excluded line is a block and sets the    *
  510.  * exclude header text appropriately.                                         *
  511.  *                                                                            *
  512.  ******************************************************************************/
  513. excludeheader:
  514.  
  515. procedure
  516.  
  517. 'mark find PFXMARK1'
  518. lines = 0
  519. do forever
  520.    if \nextline() then leave
  521.    'extract class'
  522.    if pos("PFXEXCLUDE",class) == 0 then leave
  523.    lines = lines + 1
  524. end
  525.  
  526. call beginchange
  527. 'mark find PFXMARK1'
  528. if 0 = lines then do
  529.    call deleteheader
  530.    call endchange
  531.    exit
  532. end
  533. 'extract limiterror into savelimiterror'
  534. 'set limiterror ignore'
  535. if 1 = lines then
  536.    'set content 'ispfmsg(4)
  537. else
  538.    'set content 'ispfmsg(5 lines)
  539. 'set limiterror 'savelimiterror
  540. call endchange
  541.  
  542. 'extract deleting'
  543. if deleting = "" then do
  544.    'macroload pfxdel.lx'
  545.    'set deleting pfxdel'
  546. end
  547.  
  548. return
  549.  
  550. /******************************************************************************
  551.  *                                                                            *
  552.  * deleteheader routine                                                       *
  553.  *                                                                            *
  554.  * This routine deletes the current exclude header line.                      *
  555.  *                                                                            *
  556.  ******************************************************************************/
  557. deleteheader:
  558.  
  559. procedure
  560.  
  561. 'extract deleting'
  562. 'set deleting'
  563. 'delete'
  564. if headers() then
  565.    'set deleting 'deleting
  566.  
  567. return
  568.  
  569. /******************************************************************************
  570.  *                                                                            *
  571.  * function headers()                                                         *
  572.  *                                                                            *
  573.  * This function returns TRUE if there are any headers remaining.             *
  574.  *                                                                            *
  575.  ******************************************************************************/
  576. headers:
  577.  
  578. procedure
  579.  
  580. 'extract classes'
  581. if (pos("PFXSHOW",classes) = 0) then
  582.    return 0
  583.  
  584. 'extract element into e'
  585. 'mark set PFXMARKH' e '-1'
  586. 'top'
  587. 'next class PFXSHOW'
  588. 'extract class'
  589. 'mark find PFXMARKH'
  590. 'mark clear PFXMARKH'
  591.  
  592. return (pos("PFXSHOW",class) \= 0)
  593.  
  594. /******************************************************************************
  595.  *                                                                            *
  596.  * function nextline(dir)                                                     *
  597.  *                                                                            *
  598.  * This function accepts a direction (prev or next) and move to the previous  *
  599.  * or next line.  It returns TRUE if the operation completed successfully.    *
  600.  *                                                                            *
  601.  ******************************************************************************/
  602. nextline:
  603.  
  604. procedure
  605.  
  606. arg dir parm
  607.  
  608. if dir \= "PREV" then
  609.    dir = 'next'
  610.  
  611. 'extract element into preve'
  612. dir parm
  613. 'extract element'
  614. return element \= preve
  615.  
  616. /******************************************************************************
  617.  *                                                                            *
  618.  * errormsg(msgno insert) routine                                             *
  619.  *                                                                            *
  620.  * This routine issues an error message msgno and exits.                      *
  621.  *                                                                            *
  622.  ******************************************************************************/
  623. errormsg:
  624.  
  625. arg msgno insert
  626.  
  627. 'msg 'ispfmsg(msgno insert)
  628. signal cleanup
  629.  
  630.