• [ooRexx] An observation in "parse var" which made me curious

    From Jesper K Brogaard@21:1/5 to All on Sun Jan 28 00:00:29 2018
    I am looking at substituting variables in strings with values. I intend
    to mark the variables with e.g. '[' and ']', similar to html tags.

    Given str = "aaa[aaa]aaa[bbb]bbb", I have two variables aaa and bbb.

    I can get the first variable with "parse var str temp1 '[' varname ']'
    temp2".

    But if I want to avoid hardcoded start and end marks by using names like startMark = '[' and endMark = ']' then "parse var str temp1 startMark
    varname startMark temp2" does not work anymore.

    Is there anyone who can explain the difference in the behaviour between
    using hardcoded marks and names for them?


    --
    Venlig hilsen / Best regards
    Jesper K. Brogaard

    (remove upper case letters in my e-mail address)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rick McGuire@21:1/5 to All on Sat Jan 27 15:34:29 2018
    you need to place the variable search strings in parens

    parse var str temp1 (startMark) varname (endMark) temp2

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesper K Brogaard@21:1/5 to All on Sun Jan 28 09:18:40 2018
    Den 28-01-2018 kl. 00:34 skrev Rick McGuire:
    you need to place the variable search strings in parens

    parse var str temp1 (startMark) varname (endMark) temp2


    Thank you very much Rick McGuire.

    Your reply helped me finding the documentation about it: "9.4. Parsing
    with Variable Patterns" in the Reference.

    Here you see my code (without error handling, etc.):

    substitute: procedure expose S.
    arg lin

    startMark = '<'
    endMark = '>'

    do while lin~pos(startMark) > 0
    parse var lin temp1 (startMark) varname (endMark) temp2
    lin = temp1 || S.varname || temp2
    end

    return lin


    --
    Venlig hilsen / Best regards
    Jesper K. Brogaard

    (remove upper case letters in my e-mail address)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From LesK@21:1/5 to Jesper K Brogaard on Sun Jan 28 17:32:50 2018
    On 1/28/2018 3:18 AM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 00:34 skrev Rick McGuire:
    you need to place the variable search strings in parens

       parse var str temp1 (startMark) varname (endMark) temp2


    Thank you very much Rick McGuire.

    Your reply helped me finding the documentation about it: "9.4. Parsing
    with Variable Patterns" in the Reference.

    Here you see my code (without error handling, etc.):

    substitute: procedure expose S.
                arg lin

        startMark = '<'
        endMark   = '>'

        do while lin~pos(startMark) > 0
            parse var lin temp1 (startMark) varname (endMark) temp2
            lin = temp1 || S.varname || temp2
        end

        return lin


    I'd like to see a snippet of code that uses this subroutine.

    --

    Les (Change Arabic to Roman to email me)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesper K Brogaard@21:1/5 to All on Mon Jan 29 00:32:32 2018
    Den 28-01-2018 kl. 23:32 skrev LesK:
    On 1/28/2018 3:18 AM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 00:34 skrev Rick McGuire:
    you need to place the variable search strings in parens

       parse var str temp1 (startMark) varname (endMark) temp2


    Thank you very much Rick McGuire.

    Your reply helped me finding the documentation about it: "9.4. Parsing
    with Variable Patterns" in the Reference.

    Here you see my code (without error handling, etc.):

    substitute: procedure expose S.
                 arg lin

         startMark = '<'
         endMark   = '>'

         do while lin~pos(startMark) > 0
             parse var lin temp1 (startMark) varname (endMark) temp2
             lin = temp1 || S.varname || temp2
         end

         return lin


    I'd like to see a snippet of code that uses this subroutine.


    Of course you can:

    S. = '???????'
    S.zuser = 'XYZ' -- userid()~upper
    S.project = 'PROJ123'
    S.delta = 'SUBDIR'
    S.class = 'A'
    S.msgclass = 'B'

    input = .stream~new('skeleton.jcl')
    input~open('read')

    output = .stream~new('new.jcl')
    output~open('write replace')

    do while input~lines <> 0
    lineFromInput = input~linein()
    newLine = substitute(lineFromInput)
    output~lineout(newLine)
    -- or in one line: output~lineout(substitute(input~linein()))
    end

    input~close()
    output~close()

    exit(0)

    'skeleton.jcl' contains lines like these

    //<ZUSER>DENV JOB (XF02-00R),'ALLOC <DELTA>',MSGLEVEL=(1,1),
    // CLASS=<CLASS>,MSGCLASS=<MSGCLASS>,
    // REGION=4096K,NOTIFY=<ZUSER>
    ...
    //CICSLOAD DD DSN=PN00.<PROJECT>.<DELTA>.CICSLOAD,
    ...

    which will these lines after having been modified by the subroutine

    //XYZDENV JOB (XF02-00R),'ALLOC SUBDIR',MSGLEVEL=(1,1),
    // CLASS=A,MSGCLASS=B,
    // REGION=4096K,NOTIFY=XYZ
    ...
    //CICSLOAD DD DSN=PN00.PROJ123.SUBDIR.CICSLOAD,
    ...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From LesK@21:1/5 to Jesper K Brogaard on Mon Jan 29 02:48:43 2018
    On 1/28/2018 6:32 PM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 23:32 skrev LesK:
    On 1/28/2018 3:18 AM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 00:34 skrev Rick McGuire:
    you need to place the variable search strings in parens

       parse var str temp1 (startMark) varname (endMark) temp2


    Thank you very much Rick McGuire.

    Your reply helped me finding the documentation about it: "9.4.
    Parsing with Variable Patterns" in the Reference.

    Here you see my code (without error handling, etc.):

    substitute: procedure expose S.
                 arg lin

         startMark = '<'
         endMark   = '>'

         do while lin~pos(startMark) > 0
             parse var lin temp1 (startMark) varname (endMark) temp2
             lin = temp1 || S.varname || temp2
         end

         return lin


    I'd like to see a snippet of code that uses this subroutine.


    Of course you can:

    S.         = '???????'
    S.zuser    = 'XYZ'         --  userid()~upper
    S.project  = 'PROJ123'
    S.delta    = 'SUBDIR'
    S.class    = 'A'
    S.msgclass = 'B'

    input = .stream~new('skeleton.jcl')
    input~open('read')

    output = .stream~new('new.jcl')
    output~open('write replace')

    do while input~lines <> 0
        lineFromInput = input~linein()
        newLine       = substitute(lineFromInput)
        output~lineout(newLine)
        -- or in one line: output~lineout(substitute(input~linein()))
    end

    input~close()
    output~close()

    exit(0)

    'skeleton.jcl' contains lines like these

    //<ZUSER>DENV JOB  (XF02-00R),'ALLOC <DELTA>',MSGLEVEL=(1,1), //         CLASS=<CLASS>,MSGCLASS=<MSGCLASS>,
    //         REGION=4096K,NOTIFY=<ZUSER>
    ....
    //CICSLOAD DD DSN=PN00.<PROJECT>.<DELTA>.CICSLOAD,
    ....

    which will these lines after having been modified by the subroutine

    //XYZDENV JOB  (XF02-00R),'ALLOC SUBDIR',MSGLEVEL=(1,1),
    //         CLASS=A,MSGCLASS=B,
    //         REGION=4096K,NOTIFY=XYZ
    ....
    //CICSLOAD DD DSN=PN00.PROJ123.SUBDIR.CICSLOAD,
    ....

    Thanks. Very interesting.

    Btw: ooRexx 5.0.0 adds a new directive ::RESOURCE which allows you to
    include things like your skeleton in your code.

    If you want a similar facility with Classic Rexx on ZOS, see Frank
    Clarke's presentation "Embedding Assets in REXX code" at the 2013 Rexx Symposium:

    http://www.rexxla.org/events/2013/schedule.html

    --

    Les (Change Arabic to Roman to email me)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Prins@21:1/5 to LesK on Mon Jan 29 11:34:06 2018
    On 2018-01-29 07:48, LesK wrote:
    On 1/28/2018 6:32 PM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 23:32 skrev LesK:
    On 1/28/2018 3:18 AM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 00:34 skrev Rick McGuire:
    you need to place the variable search strings in parens

       parse var str temp1 (startMark) varname (endMark) temp2


    Thank you very much Rick McGuire.

    Your reply helped me finding the documentation about it: "9.4. Parsing with
    Variable Patterns" in the Reference.

    Here you see my code (without error handling, etc.):

    substitute: procedure expose S.
                 arg lin

         startMark = '<'
         endMark   = '>'

         do while lin~pos(startMark) > 0
             parse var lin temp1 (startMark) varname (endMark) temp2
             lin = temp1 || S.varname || temp2
         end

         return lin


    I'd like to see a snippet of code that uses this subroutine.


    Of course you can:

    S.         = '???????'
    S.zuser    = 'XYZ'         --  userid()~upper
    S.project  = 'PROJ123'
    S.delta    = 'SUBDIR'
    S.class    = 'A'
    S.msgclass = 'B'

    input = .stream~new('skeleton.jcl')
    input~open('read')

    output = .stream~new('new.jcl')
    output~open('write replace')

    do while input~lines <> 0
         lineFromInput = input~linein()
         newLine       = substitute(lineFromInput)
         output~lineout(newLine)
         -- or in one line: output~lineout(substitute(input~linein()))
    end

    input~close()
    output~close()

    exit(0)

    'skeleton.jcl' contains lines like these

    //<ZUSER>DENV JOB  (XF02-00R),'ALLOC <DELTA>',MSGLEVEL=(1,1),
    //         CLASS=<CLASS>,MSGCLASS=<MSGCLASS>,
    //         REGION=4096K,NOTIFY=<ZUSER>
    ....
    //CICSLOAD DD DSN=PN00.<PROJECT>.<DELTA>.CICSLOAD,
    ....

    which will these lines after having been modified by the subroutine

    //XYZDENV JOB  (XF02-00R),'ALLOC SUBDIR',MSGLEVEL=(1,1),
    //         CLASS=A,MSGCLASS=B,
    //         REGION=4096K,NOTIFY=XYZ
    ....
    //CICSLOAD DD DSN=PN00.PROJ123.SUBDIR.CICSLOAD,
    ....

    Thanks. Very interesting.

    Btw: ooRexx 5.0.0 adds a new directive ::RESOURCE which allows you to include things like your skeleton in  your  code.

    If you want a similar facility with Classic Rexx on ZOS, see Frank Clarke's presentation "Embedding Assets in REXX code" at the  2013 Rexx Symposium:

     http://www.rexxla.org/events/2013/schedule.html

    Or you can use the method I'm using in

    <https://prino.neocities.org/zOS/e123.exec.html>

    using (auto-)generated queue statements (a method that can even be used to embed
    load libraries inside an EXEC) using

    <https://prino.neocities.org/zOS/epanq.exec.html>

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From ErichSt@21:1/5 to All on Mon Jan 29 04:10:11 2018
    Note that ooRexx incubator has a simple template class that replaces variables of the form $(...)

    See https://sourceforge.net/p/oorexx/code-0/HEAD/tree/incubator/texttemplate/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesper K Brogaard@21:1/5 to All on Tue Jan 30 23:57:35 2018
    Den 29-01-2018 kl. 12:34 skrev Robert Prins:
    On 2018-01-29 07:48, LesK wrote:
    On 1/28/2018 6:32 PM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 23:32 skrev LesK:
    On 1/28/2018 3:18 AM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 00:34 skrev Rick McGuire:
    you need to place the variable search strings in parens

       parse var str temp1 (startMark) varname (endMark) temp2


    Thank you very much Rick McGuire.

    Your reply helped me finding the documentation about it: "9.4.
    Parsing with Variable Patterns" in the Reference.

    Here you see my code (without error handling, etc.):

    substitute: procedure expose S.
                 arg lin

         startMark = '<'
         endMark   = '>'

         do while lin~pos(startMark) > 0
             parse var lin temp1 (startMark) varname (endMark)
    temp2
             lin = temp1 || S.varname || temp2
         end

         return lin


    I'd like to see a snippet of code that uses this subroutine.


    Of course you can:

    S.         = '???????'
    S.zuser    = 'XYZ'         --  userid()~upper
    S.project  = 'PROJ123'
    S.delta    = 'SUBDIR'
    S.class    = 'A'
    S.msgclass = 'B'

    input = .stream~new('skeleton.jcl')
    input~open('read')

    output = .stream~new('new.jcl')
    output~open('write replace')

    do while input~lines <> 0
         lineFromInput = input~linein()
         newLine       = substitute(lineFromInput)
         output~lineout(newLine)
         -- or in one line: output~lineout(substitute(input~linein()))
    end

    input~close()
    output~close()

    exit(0)

    'skeleton.jcl' contains lines like these

    //<ZUSER>DENV JOB  (XF02-00R),'ALLOC <DELTA>',MSGLEVEL=(1,1),
    //         CLASS=<CLASS>,MSGCLASS=<MSGCLASS>,
    //         REGION=4096K,NOTIFY=<ZUSER>
    ....
    //CICSLOAD DD DSN=PN00.<PROJECT>.<DELTA>.CICSLOAD,
    ....

    which will these lines after having been modified by the subroutine

    //XYZDENV JOB  (XF02-00R),'ALLOC SUBDIR',MSGLEVEL=(1,1),
    //         CLASS=A,MSGCLASS=B,
    //         REGION=4096K,NOTIFY=XYZ
    ....
    //CICSLOAD DD DSN=PN00.PROJ123.SUBDIR.CICSLOAD,
    ....

    Thanks. Very interesting.

    Btw: ooRexx 5.0.0 adds a new directive ::RESOURCE which allows you to
    include things like your skeleton in  your  code.

    If you want a similar facility with Classic Rexx on ZOS, see Frank
    Clarke's presentation "Embedding Assets in REXX code" at the  2013
    Rexx Symposium:

      http://www.rexxla.org/events/2013/schedule.html

    Or you can use the method I'm using in

    <https://prino.neocities.org/zOS/e123.exec.html>

    using (auto-)generated queue statements (a method that can even be used
    to embed load libraries inside an EXEC) using

    <https://prino.neocities.org/zOS/epanq.exec.html>

    Robert

    Thank you Robert Prins, I will study the method.

    --
    Venlig hilsen / Best regards
    Jesper K. Brogaard

    (remove upper case letters in my e-mail address)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesper K Brogaard@21:1/5 to All on Tue Jan 30 23:55:04 2018
    Den 29-01-2018 kl. 08:48 skrev LesK:
    On 1/28/2018 6:32 PM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 23:32 skrev LesK:
    On 1/28/2018 3:18 AM, Jesper K Brogaard wrote:
    Den 28-01-2018 kl. 00:34 skrev Rick McGuire:
    you need to place the variable search strings in parens

       parse var str temp1 (startMark) varname (endMark) temp2


    Thank you very much Rick McGuire.

    Your reply helped me finding the documentation about it: "9.4.
    Parsing with Variable Patterns" in the Reference.

    Here you see my code (without error handling, etc.):

    substitute: procedure expose S.
                 arg lin

         startMark = '<'
         endMark   = '>'

         do while lin~pos(startMark) > 0
             parse var lin temp1 (startMark) varname (endMark)
    temp2
             lin = temp1 || S.varname || temp2
         end

         return lin


    I'd like to see a snippet of code that uses this subroutine.


    Of course you can:

    S.         = '???????'
    S.zuser    = 'XYZ'         --  userid()~upper
    S.project  = 'PROJ123'
    S.delta    = 'SUBDIR'
    S.class    = 'A'
    S.msgclass = 'B'

    input = .stream~new('skeleton.jcl')
    input~open('read')

    output = .stream~new('new.jcl')
    output~open('write replace')

    do while input~lines <> 0
         lineFromInput = input~linein()
         newLine       = substitute(lineFromInput)
         output~lineout(newLine)
         -- or in one line: output~lineout(substitute(input~linein()))
    end

    input~close()
    output~close()

    exit(0)

    'skeleton.jcl' contains lines like these

    //<ZUSER>DENV JOB  (XF02-00R),'ALLOC <DELTA>',MSGLEVEL=(1,1),
    //         CLASS=<CLASS>,MSGCLASS=<MSGCLASS>,
    //         REGION=4096K,NOTIFY=<ZUSER>
    ....
    //CICSLOAD DD DSN=PN00.<PROJECT>.<DELTA>.CICSLOAD,
    ....

    which will these lines after having been modified by the subroutine

    //XYZDENV JOB  (XF02-00R),'ALLOC SUBDIR',MSGLEVEL=(1,1),
    //         CLASS=A,MSGCLASS=B,
    //         REGION=4096K,NOTIFY=XYZ
    ....
    //CICSLOAD DD DSN=PN00.PROJ123.SUBDIR.CICSLOAD,
    ....

    Thanks. Very interesting.

    Btw: ooRexx 5.0.0 adds a new directive ::RESOURCE which allows you to include  things like your skeleton in  your  code.

    If you want a similar facility with Classic Rexx on ZOS, see Frank
    Clarke's presentation "Embedding Assets in REXX code" at the  2013 Rexx Symposium:

     http://www.rexxla.org/events/2013/schedule.html

    Thank you Lesk, I will study the suggested subjects.

    There is already a lot of variable substituting (is it the correct
    term?) on the mainframe, made with ISPF. There are sent JCL to the
    mainframe to activate various tasks, and my script is an idea to
    refactor some existing code.


    --
    Venlig hilsen / Best regards
    Jesper K. Brogaard

    (remove upper case letters in my e-mail address)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jesper K Brogaard@21:1/5 to All on Wed Jan 31 00:17:14 2018
    Den 29-01-2018 kl. 13:10 skrev ErichSt:
    Note that ooRexx incubator has a simple template class that replaces variables of the form $(...)

    See https://sourceforge.net/p/oorexx/code-0/HEAD/tree/incubator/texttemplate/

    Thank you ErichSt. I did not know the incubator.

    My solution looks like the transform method. I think transform is more
    robust, but my solution is simpler because I'm using the parse
    statement. I also need some error handling. I was considering using
    changestr but chose to concatenate the the string parts into one string.

    --
    Venlig hilsen / Best regards
    Jesper K. Brogaard

    (remove upper case letters in my e-mail address)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)