Need RPGFREE help - IBM AS400

This is a discussion on Need RPGFREE help - IBM AS400 ; How can I get the variable answer to come out in qprint?? I can get the answer to come up in STRDBG, any help would be appreciated or help to point me in the correct direction, i did not want ...

+ Reply to Thread
Results 1 to 13 of 13

Thread: Need RPGFREE help

  1. Need RPGFREE help

    How can I get the variable answer to come out in qprint?? I can get
    the answer to come up in STRDBG, any help would be appreciated or help
    to point me in the correct direction, i did not want to use an
    external defined printer file, I was hoping I could just move the
    answer field to qprint and it would come out, no luck so far.

    FQPRINT O F 132
    PRINTER
    DNUM1 S 5 2
    Inz(93.45)
    DNUM2 S 7 2
    Inz(13754.76)
    DANSWER S 11
    2
    /
    FREE
    //
    Addition
    Answer = Num1 +
    Num2;
    /END-
    FREE
    C SETON LR


  2. Re: Need RPGFREE help

    You need to reference the printerfile. You have only defined it, but
    have no output statements.

    If you check your compilation listing, you'll find the the printerfile
    is dropped altogether since you have no references to it.

    You need to define some output statements in the bottom of you
    program. Check the manuals for examples.

    Regards
    Niels


  3. Re: Need RPGFREE help

    jacko wrote:
    > How can I get the variable answer to come out in qprint??


    Here is one way. Add the lines that I marked with ***

    FQPRINT O F 132 printer

    *** D qprintDs DS 132

    DNUM1 S 5 2 INZ(93.45)
    DNUM2 S 7 2 INZ(13754.76)
    DANSWER S 11 2
    /FREE
    // Addition
    Answer = Num1 + Num2;

    *** qprintDs = 'Answer = ' + %char(Answer);
    *** write QPRINT qprintDs;

    *INLR = '1';
    /END-FREE

  4. Re: Need RPGFREE help

    jacko wrote:

    > How can I get the variable answer to come out in qprint?? I can get
    > the answer to come up in STRDBG, any help would be appreciated or help
    > to point me in the correct direction, i did not want to use an
    > external defined printer file, I was hoping I could just move the
    > answer field to qprint and it would come out, no luck so far.


    Straightforward answer is to:

    1. Prototype the printf() API
    2. Call the API to do the printing
    3. Delete the QPRINT F-specs since you don't seem to be doing any I/O to it
    4. compile your program as CRTBNDRPG with DFTACTGRP(*NO) ACTGRP(*NEW)
    BNDDIR(QC2LE)
    5. Issue this override before calling your program:

    ==> OVRPRTF FILE(STDOUT) TOFILE(QPRINT) DFRWRT(*NO)
    SPLFNAME(PRINTDEMO) OVRSCOPE(*JOB) OPNSCOPE(*JOB)

    Now, with that override in place, when you call your program the
    printf() output will go to QPRINT. Since the program will run in a *NEW
    activation group, stdout will be closed automatically as soon as the
    program ends. You should see the PRINTDEMO spooled file in the list of
    spooled files for your job.

    Although that's hardly the "correct" answer for ILE RPG, it does seem to
    be more or less the answer that comes closest to what you asked for.
    Others will probably give answers that show the "correct" way to it. My
    advice is to do it their way rather than mine. :-)


    --
    Tom Liotta
    http://zap.to/tl400

  5. Re: Need RPGFREE help

    On Oct 25, 3:39 am, Thomas wrote:
    > jacko wrote:
    > > How can I get the variable answer to come out in qprint?? I can get
    > > the answer to come up in STRDBG, any help would be appreciated or help
    > > to point me in the correct direction, i did not want to use an
    > > external defined printer file, I was hoping I could just move the
    > > answer field to qprint and it would come out, no luck so far.

    >
    > Straightforward answer is to:
    >
    > 1. Prototype the printf() API
    > 2. Call the API to do the printing
    > 3. Delete the QPRINT F-specs since you don't seem to be doing any I/O to it
    > 4. compile your program as CRTBNDRPG with DFTACTGRP(*NO) ACTGRP(*NEW)
    > BNDDIR(QC2LE)
    > 5. Issue this override before calling your program:
    >
    > ==> OVRPRTF FILE(STDOUT) TOFILE(QPRINT) DFRWRT(*NO)
    > SPLFNAME(PRINTDEMO) OVRSCOPE(*JOB) OPNSCOPE(*JOB)
    >
    > Now, with that override in place, when you call your program the
    > printf() output will go to QPRINT. Since the program will run in a *NEW
    > activation group, stdout will be closed automatically as soon as the
    > program ends. You should see the PRINTDEMO spooled file in the list of
    > spooled files for your job.
    >
    > Although that's hardly the "correct" answer for ILE RPG, it does seem to
    > be more or less the answer that comes closest to what you asked for.
    > Others will probably give answers that show the "correct" way to it. My
    > advice is to do it their way rather than mine. :-)
    >
    > --
    > Tom Liottahttp://zap.to/tl400


    Tom, can you show an example of using the prototype printf() api.


  6. Re: Need RPGFREE help

    Or, just add these lines to the end of your program, and you don't
    need any prototypes at all.

    OQPRINT T LR 01
    O 'Answer is '
    O Answer J


  7. Re: Need RPGFREE help

    jacko wrote:
    > On Oct 25, 3:39 am, Thomas wrote:
    >> jacko wrote:
    >>> How can I get the variable answer to come out in qprint?? I can get
    >>> the answer to come up in STRDBG, any help would be appreciated or help
    >>> to point me in the correct direction, i did not want to use an
    >>> external defined printer file, I was hoping I could just move the
    >>> answer field to qprint and it would come out, no luck so far.

    >> Straightforward answer is to:
    >>
    >> 1. Prototype the printf() API
    >> 2. Call the API to do the printing
    >> 3. Delete the QPRINT F-specs since you don't seem to be doing any I/O to it
    >> 4. compile your program as CRTBNDRPG with DFTACTGRP(*NO) ACTGRP(*NEW)
    >> BNDDIR(QC2LE)
    >> 5. Issue this override before calling your program:
    >>
    >> ==> OVRPRTF FILE(STDOUT) TOFILE(QPRINT) DFRWRT(*NO)
    >> SPLFNAME(PRINTDEMO) OVRSCOPE(*JOB) OPNSCOPE(*JOB)
    >>
    >> Now, with that override in place, when you call your program the
    >> printf() output will go to QPRINT. Since the program will run in a *NEW
    >> activation group, stdout will be closed automatically as soon as the
    >> program ends. You should see the PRINTDEMO spooled file in the list of
    >> spooled files for your job.
    >>
    >> Although that's hardly the "correct" answer for ILE RPG, it does seem to
    >> be more or less the answer that comes closest to what you asked for.
    >> Others will probably give answers that show the "correct" way to it. My
    >> advice is to do it their way rather than mine. :-)
    >>

    > Tom, can you show an example of using the prototype printf() api.


    Example --

    *--- Begin paste
    D Num1 s 5 2 inz( 93.45 )
    D Num2 s 7 2 inz( 13754.76 )
    D Answer s 11 2

    D format s 32 inz( 'Answer is: %#D(11,2)' )

    D nl s 1 inz( x'15' )

    D* int printf( const char *fmt, arg-list )
    D*--------------------------------------------------------------
    D printf pr 10i 0 extproc( 'printf' )
    D fmt * value options( *string )
    D arglst 11 2 value options( *nopass )
    D*--------------------------------------------------------------

    /free
    Answer = Num1 + Num2 ;

    *inlr = *on ;
    format = %trim( format ) + nl ;
    callp printf( %addr(format): Answer ) ;

    return ;
    /end-free
    *--- End paste

    That might wrap in the NG, but should be reasonable.

    --
    Tom Liotta
    http://zap.to/tl400

  8. Re: Need RPGFREE help

    Thomas wrote:
    > ...
    > format = %trim( format ) + nl ;
    > callp printf( %addr(format): Answer ) ;


    Tom, passing %addr(format) requires that you also add x'00' to the end
    of the "format" variable. Printf doesn't stop when it hits a newline;
    you could have several newlines in your format. Printf only stops when
    it hits a null terminator.

    This would work, taking advantage of options(*string):
    format = %trim( format ) + nl + x'00';
    callp printf (%addr(format) : Answer)

    This would be easier, taking advantage of options(*string):
    callp printf (%trim(format) + nl : Answer)

    This would be even easier, making it unnecessary to have the "format"
    variable at all:
    callp printf ('Answer is ' + %char(Answer) + nl);

    --
    Barbara

  9. Re: Need RPGFREE help

    Barbara Morris wrote:
    > Thomas wrote:
    >> ...
    >> format = %trim( format ) + nl ;
    >> callp printf( %addr(format): Answer ) ;

    >
    > Tom, passing %addr(format) requires that you also add x'00' to the end
    > of the "format" variable.


    Barbara:

    I can't disagree... not with you, anyway.

    However, the posted code is directly from working source (when compiled
    as noted earlier and with the earlier OVRPRTF.) Also, I assumed the
    [options( *string )] for the parameter in the prototype was why it was
    working.

    No?

    It wouldn't surprise if it wasn't, considering how it was all coded. I
    haven't quite reasoned how the compiler made it work. I originally had
    coded the [+ x'00'] and took it off to see if [options( *string )]
    worked. When it did, I thought it looked nicer. I wasn't expecting it to
    work with the pointer by value.

    But when it worked, I stopped looking.

    Actually, I use printf() much more often to give print capability to ILE
    CL. When I saw the question, I simply tried it in RPG. The output was
    exactly what I expected.

    Now, I'll have to triple-check...

    --
    Tom Liotta
    http://zap.to/tl400


  10. Re: Need RPGFREE help

    Barbara Morris wrote:

    > This would be even easier, making it unnecessary to have the "format"
    > variable at all:
    > callp printf ('Answer is ' + %char(Answer) + nl);


    Barbara:

    This one I really like because it didn't even occur to me. I got too
    involved in getting the formatting of packed-decimal working. IBM (or
    almost any) documentation of packed-decimal handling in a format string
    is limited at best.

    But next time, there's no contest!

    --
    Tom Liotta
    http://zap.to/tl400

  11. Re: Need RPGFREE help

    Thomas wrote:
    >
    > However, the posted code is directly from working source (when compiled
    > as noted earlier and with the earlier OVRPRTF.) Also, I assumed the
    > [options( *string )] for the parameter in the prototype was why it was
    > working.
    >


    Tom, OPTIONS(*STRING) only takes effect when you pass a character
    expression. When you pass a pointer, the compiler assumes that you have
    taken care of the null-terminator yourself.

    Your program worked because you were lucky, or maybe because you were
    unlucky. When you pass the address of your "format" variable, you
    actually pass the address of your variable and all the storage that
    follows it. If the storage that follows it happens to start with x'00',
    then your code would work ... for now [Cue scary music] ... That's where
    "unlucky" comes in. Since you can't control what follows your "format"
    variable in storage, your code could stop working at any time, and some
    extra junk could start appearing in your output.

    Below is a program that demonstrates this. It prints out this:

    --------- start --------
    Hello
    there
    Hello
    there
    oops--------- end ----------

    At first, I was confused about the second "Hello" being indented, but
    then I realized it was because my "format" variable has trailing blanks
    that printf would see before it saw the x'00' in my "after" variable.
    Those blanks would be saved up in the printf output until the next
    newline was printed.

    H dftactgrp(*no) bnddir('QC2LE')

    D printf pr 10i 0 extproc('printf')
    D fmt * value options(*string)
    D extra * value options(*string:*nopass)
    D NEWLINE c x'15'

    D ds
    D format 50a
    D after 10a

    /free
    printf ('--------- start --------' + NEWLINE);

    // force the storage after format to contain x'00'

    format = 'Hello' + NEWLINE + 'there' + NEWLINE;
    after = x'00';
    printf (%addr(format));

    // change the storage after format to not be x'00'
    after = 'oops' + x'00';
    printf (%addr(format));
    printf ('--------- end ----------' + NEWLINE);

    *inlr = '1';

  12. Re: Need RPGFREE help

    Barbara Morris wrote:
    > Thomas wrote:
    >>
    >> However, the posted code is directly from working source (when
    >> compiled as noted earlier and with the earlier OVRPRTF.) Also, I
    >> assumed the [options( *string )] for the parameter in the prototype
    >> was why it was working.
    >>

    >
    > Tom, OPTIONS(*STRING) only takes effect when you pass a character
    > expression. When you pass a pointer, the compiler assumes that you have
    > taken care of the null-terminator yourself.
    >
    > Your program worked because you were lucky, or maybe because you were
    > unlucky. When you pass the address of your "format" variable, you
    > actually pass the address of your variable and all the storage that
    > follows it. If the storage that follows it happens to start with x'00',
    > then your code would work ...


    Barbara:

    A superb explanation and a great example, as usual.

    Now I'm thinking that [options( *string )] should throw a warning
    message (or perhaps *INFO) when there's a questionable data type
    associated with it. Looks like a potential DCR.

    Thanks for your contribution.

    --
    Tom Liotta
    http://zap.to/tl400

  13. Re: Need RPGFREE help

    Thomas wrote:
    > Barbara Morris wrote:
    >> Thomas wrote:
    >>>
    >>> However, the posted code is directly from working source (when
    >>> compiled as noted earlier and with the earlier OVRPRTF.) Also, I
    >>> assumed the [options( *string )] for the parameter in the prototype
    >>> was why it was working.
    >>>

    >>
    >> Tom, OPTIONS(*STRING) only takes effect when you pass a character
    >> expression. When you pass a pointer, the compiler assumes that you
    >> have taken care of the null-terminator yourself.
    >>
    >> Your program worked because you were lucky, or maybe because you were
    >> unlucky. When you pass the address of your "format" variable, you
    >> actually pass the address of your variable and all the storage that
    >> follows it. If the storage that follows it happens to start with
    >> x'00', then your code would work ...

    >
    > Now I'm thinking that [options( *string )] should throw a warning
    > message (or perhaps *INFO) when there's a questionable data type
    > associated with it. Looks like a potential DCR.


    Well, I clearly was responding faster than I was thinking on that one...

    Never mind. It was a long day.

    --
    Tom Liotta
    http://zap.to/tl400

+ Reply to Thread