home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / njpipes.zip / template4.nrx < prev   
Text File  |  1998-10-11  |  6KB  |  189 lines

  1. /* You MUST move this into the stages directory for the stageExit to get called */
  2. package stages
  3.  
  4. options binary
  5.  
  6. import pipes.
  7.  
  8. /* note the 'uses utils, IRange' this is added for the stageExit which uses
  9.  * of the static mentods in utils
  10.  */
  11.  
  12. class template4 extends stage uses utils, IRange
  13.  
  14. /* objects shared between the ...setup and run methods */
  15.  
  16. properties private
  17.  
  18. args = rexx
  19. rc   = int
  20. ir   = IRange[]
  21. d    = rexx
  22.  
  23. /* method to initialize a stage.  Only called once unless the arg() changes */
  24.  
  25. method template4_setup() private signals StageError
  26.  
  27.    if args=null then      -- args can be set by the stageExit too
  28.       args = arg()
  29.  
  30.    ir = GetIRanges(args)  -- get a possible IRange
  31.    nr = ir[0].Number()    -- extract the number of subranges
  32.  
  33.    if nr=0 then
  34.       signal StageError(11,'Error - template4 expects a range, found: 'args)
  35.  
  36.    d = ir[0].Residue()    -- whats left of args after the IRange
  37.  
  38.    d = DString(d).String  -- extract a delimited string from the residue
  39.  
  40.    if d='' then
  41.       signal StageError(11,'template4 expects a range & data.  Just found a range.')
  42.  
  43.  
  44. /* run a basic stage that has very little setup to do */
  45.  
  46. method run()
  47.  
  48.    /* insert objects that need to be reset every invokation here */
  49.  
  50.    s0   = boolean 1       -- out stream 0 may exist
  51.    s1   = boolean 1       -- out stream 1 may exist
  52.    args = null            -- make a null to template4_setup() will call arg()
  53.  
  54.    do -- to catch the terminating StageError
  55.  
  56.       /* call doSetup to setup the stage */
  57.  
  58.       if doSetup() then
  59.          template4_setup()
  60.  
  61.       /* body of the stage is here */
  62.  
  63.       loop forever
  64.  
  65.          aobj = peekto()             -- pass an object but test a rexx object
  66.          robj = rexx aobj            -- ie the objects piped are strings...
  67.          if theRange(robj).pos(d)>0 then
  68.             do
  69.                if s0 then do
  70.                   selectOutput(0)
  71.                   output(aobj)
  72.                catch StageError      -- Using this structure if we capture
  73.                   s0 = 0             -- the StageError(s) can and will end
  74.                end                   -- up reporting a RC=4 instead of RC=12
  75.             end                      -- geting the RC via mrc will work...
  76.          else
  77.             if s1 then do
  78.                selectOutput(1)
  79.                output(aobj)
  80.             catch StageError
  81.                s1 = 0
  82.             end
  83.          readto()
  84.  
  85.       /* catch any cast exceptions that occur and issue a StageError */
  86.  
  87.       catch ClassCastException
  88.          signal StageError(13,'Error - Input not convertable to rexx')
  89.       end
  90.  
  91.    catch StageError
  92.    end
  93.  
  94.    rc = mrc()     -- extract maxium rc from all StageErrors raised by njPipes
  95.  
  96. exit(rc*(rc<>12))
  97.  
  98.  
  99. /* this method may get overridden by the stageExit, depending on the IRange */
  100.  
  101. method theRange(a=rexx) returns rexx
  102.  
  103.    -- extract the rexx string using the IRange.  BuildIRange allows out of
  104.    -- order and overlaping ranges.  Use BuildIRangeStrict to limit it to
  105.    -- inorder, nonoverlaping ranges.
  106.  
  107.    -- BuildIRange would allow a range like (3.5 2.2) and BuildIRangeStrict
  108.    -- would complain since this is out of order and the subranges overlap.
  109.  
  110.    return ir[0].BuildIRange(a)
  111.  
  112.  
  113. /* stageExit(pInfo=Rexx,o=Rexx) returns boolean signals StageError
  114.  *
  115.  * This method is an exit called by the compiler.  With it you can change
  116.  * the unprocessed pipe definition, the definition of the current stage,
  117.  * and you can pass generated code back to the compiler.  To use it override
  118.  * it.  See stages\append, stages\prefix and stages\specs for examples of its
  119.  * use.
  120.  *
  121.  * stageExit is ONLY called for stages in the stage directory
  122.  *
  123.  * pInfo     = name of pipe,
  124.  * pInfo[1]  = stage number in pipe
  125.  * pInfo[2]  = stage label, null if no label
  126.  * pInfo[3]  = stage name
  127.  * pInfo[4]  = stage arguements
  128.  * pInfo[5]  = rest of pipe
  129.  * pInfo[6]  = sep
  130.  * pInfo[7]  = end
  131.  * pInfo[8]  = not modifier active
  132.  * pInfo[9]  = stage is a driver (no input streams)
  133.  * pInfo[10] = stage is a sink (no output streams)
  134.  * o         = ''
  135.  * o[0]      = 0
  136.  *
  137.  * When compilerExit returns with true, the compiler expects:
  138.  *
  139.  * pInfo[2]  = stage label
  140.  * pInfo[3]  = name of stage
  141.  * pInfo[4]  = stage arguements - note 'arg(_)' is magic and passes the pipe's
  142.  *             arguement to the stage unchanged.  See the specs stage.
  143.  * pInfo[5]  = rest of the pipe
  144.  * pInfo[8]  = not modifier active.   See nfind, nlocate.
  145.  * pInfo[11] = IF you change the name of THIS stage to an existing stage, call
  146.  *             the stageExit in pInfo[11].  The current stage should not be
  147.  *             generating code and the new stage might.  See nfind, nlocate.
  148.  * o[0]      = number of lines generated for classes
  149.  * o[n]      = line n of generated code
  150.  *
  151.  */
  152.  
  153. method stageExit(pInfo=Rexx,o=Rexx) returns boolean signals StageError
  154.  
  155. pid  = pInfo            -- pipe name
  156. stg  = pInfo[3]         -- stage name
  157. args = pInfo[4]         -- arguement, note that this is an instance object
  158.  
  159. template4_setup()       -- signal a stageExit if there is no IRange
  160.  
  161. try = ir[0].BuildIRangeExit(rexx 'ir',rexx 'a')  -- will generating a class to
  162. if try.pos('.sub')=0 then                        -- override the method help?
  163.    return 0                                      -- no, not this time...
  164.  
  165. /* here we build code and pass it back to the compiler */
  166.  
  167. cname = stageName(pid'_'stg,pid,pInfo[1])    -- the standard way to ask njPipes
  168.                                              -- for the name of a new class
  169.  
  170. n = o[0]
  171.  
  172. o[n+1] ='class 'cname' extends 'stg' private'
  173. o[n+3] ='method theRange(a=rexx) returns rexx'
  174. o[n+5] ='   return 'try
  175. n = n+6
  176.  
  177. o[0] = n           -- save the number of lines generated
  178.  
  179. pInfo[3] = cname   -- call this stage instead, there is no need to set pInfo[11]
  180.                    -- since cname is created here and its stageExit is this one
  181.  
  182. return 1           -- tell the compiler to look at what we built
  183.  
  184. /*
  185.  * There is no need to override rexxArg or stageArg since we are not being
  186.  * passed a rexx object's name or a stage name.
  187.  *
  188.  */
  189.