ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Old-timey RPG Data Structure

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Old-timey RPG Data Structure

    In converting some very old RPG:
    Code:
    [FONT=courier new]D                 DS                        
    D @NN                     1     80  0 DIM(10)
    D  NNN001                 1      8  0        
    D  NNN002                 9     16  0        
    D  NNN003                17     24  0        
    D  NNN004                25     32  0        
    D  NNN005                33     40  0        
    D  NNN006                41     48  0        
    D  NNN007                49     56  0        
    D  NNN008                57     64  0        
    D  NNN009                65     72  0        
    D  NNN010                73     80  0[/FONT]
    ... to free-format RPG/ILE (using a tool), I'm getting a (justifiable) error on the converted code:
    Code:
    // Free-format:
    [FONT=courier new]DCL-DS *n;                    
      @NN       ZONED(80) DIM(10) POS(1);  // RNF0503. Length of numeric item is greater than 63 digits
      NNN001    ZONED(8)  POS(1);      
      NNN002    ZONED(8)  POS(9);      
      NNN003    ZONED(8)  POS(17);    
      NNN004    ZONED(8)  POS(25);    
      NNN005    ZONED(8)  POS(33);    
      NNN006    ZONED(8)  POS(41);    
      NNN007    ZONED(8)  POS(49);    
      NNN008    ZONED(8)  POS(57);    
      NNN009    ZONED(8)  POS(65);    
      NNN010    ZONED(8)  POS(73);    
    END-DS;[/FONT]
    Of course, you can't have an 80-byte zoned numeric. But could the original have compiled many years ago? Did the compiler accept the @NN definition, assuming from the DIM(10) keyword that it defined ten equal-sized sub-fields (ZONED(8:0))? Is this how RPG worked when using the starting-and-ending-position notation? I find this fascinating!

    And I'm assuming the following would work with the original code? Yes?
    Code:
    [FONT=courier new]DCL-DS *n;                    
      @NN       ZONED(8)  DIM(10);
      NNN001    ZONED(8)  POS(1); 
      NNN002    ZONED(8)  POS(9); 
      NNN003    ZONED(8)  POS(17);
      NNN004    ZONED(8)  POS(25);
      NNN005    ZONED(8)  POS(33);
      NNN006    ZONED(8)  POS(41);
      NNN007    ZONED(8)  POS(49);
      NNN008    ZONED(8)  POS(57);
      NNN009    ZONED(8)  POS(65);
      NNN010    ZONED(8)  POS(73);
    END-DS;[/FONT]

  • #2
    I'd define it as follows:
    Code:
    DCL-DS *n;
       NNN001   ZONED(8);
       NNN002   ZONED(8);
       NNN003   ZONED(8);
       NNN004   ZONED(8);
       NNN005   ZONED(8);
       NNN006   ZONED(8);
       NNN007   ZONED(8);
       NNN008   ZONED(8);
       NNN009   ZONED(8);
       NNN010   ZONED(8);
       @NN      ZONED(8) DIM(10) Pos(1);
    END-DS;
    Birgitta
    Last edited by B.Hauser; December 13, 2018, 12:23 AM.

    Comment


    • Jerry G
      Jerry G commented
      Editing a comment
      Thanks, Birgitta. I like that! :-)

  • #3
    Well, hopefully there will be ZERO need for this information ... but, to follow up: I tried various configurations, including the following:
    Code:
    D                 DS                         
    D @NC1                    1     10    DIM(10)
    D  NNCK01                 1      1           
    ...
    D  NNCK10                10     10           
     *
    D                 DS                         
    D @NN1                    1     80  0 DIM(10)
    D  NNN001                 1      8  0        
    ...
    D  NNN010                73     80  0        
     *
    D                 DS                         
    D @NC7                    1     14    DIM(07)
    D  NNCR01                 1      1           
    D  NNCR02                 2      2           
    ...
    D  NNCR14                14     14           
    D                 DS                         
    D @NN7                    1    112  0 DIM(07)
    D  NNNF01                 1      8  0        
    D  NNNF02                 9     16  0        
    ...
    D  NNNF14               105    112  0
    I saw this in the compile listing:
    Code:
    Field             Attributes   
    @NC1(10)          A(1)         
    @NC7(7)           A(2)         
    @NN1(10)          S(8,0)       
    @NN7(7)           S(16,0)
    ...
    NNCK01            A(1)         
    NNCR01            A(1)         
    NNNF01            S(8,0)       
    NNN001            S(8,0)
    Looking at the arrays @NC7 and @NN7, it looks like the field lengths were determined by simply dividing the total length by the DIM value. (All the "NNNF0n" fields are S(8,0), while the elements of the 112-byte "@NN7" array, defined as having only 7 elements, are twice as big, S(16,0).)
    So much for RPG minutiae. ;-)

    [ n.b. If the array is defined with a size not an even multiple of the number of items defined, you get error "RNF3728: Number of array elements is not a proper multiple of field size; array keywords are ignored."]

    Comment


    • #4
      I put it in and did the conversion using RPG Toolbox and I get:

      Code:
             Dcl-Ds *N;
               @Nn Zoned(8) Dim(10) Pos(1);
               Nnn001 Zoned(8) Pos(1);
               Nnn002 Zoned(8) Pos(9);
               Nnn003 Zoned(8) Pos(17);
               Nnn004 Zoned(8) Pos(25);
               Nnn005 Zoned(8) Pos(33);
               Nnn006 Zoned(8) Pos(41);
               Nnn007 Zoned(8) Pos(49);
               Nnn008 Zoned(8) Pos(57);
               Nnn009 Zoned(8) Pos(65);
               Nnn010 Zoned(8) Pos(73);
             End-Ds;
      I'd say your tool has an undocumented feature.... The above works just fine!

      Comment


      • Jerry G
        Jerry G commented
        Editing a comment
        I used the ARCAD Transformer RPG tool, which I generally like. But it looks like they dropped the ball with their "ZONED(80)" vs. RPG Toolbox's "ZONED(8)".

    • #5
      Though, this is just my idiosyncrasy - I'd change it to:

      Code:
             Dcl-Ds *N;
               Nnn001 Zoned(8);
               Nnn002 Zoned(8);
               Nnn003 Zoned(8);
               Nnn004 Zoned(8);
               Nnn005 Zoned(8);
               Nnn006 Zoned(8);
               Nnn007 Zoned(8);
               Nnn008 Zoned(8);
               Nnn009 Zoned(8);
               Nnn010 Zoned(8);
               @Nn Zoned(8) Dim(10) Pos(1);
             End-Ds;
      Or even better:
      Code:
             Dcl-Ds *N;
               Nnn;
                 Nnn001 Zoned(8);
                 Nnn002 Zoned(8);
                 Nnn003 Zoned(8);
                 Nnn004 Zoned(8);
                 Nnn005 Zoned(8);
                 Nnn006 Zoned(8);
                 Nnn007 Zoned(8);
                 Nnn008 Zoned(8);
                 Nnn009 Zoned(8);
                 Nnn010 Zoned(8);
               @Nn Zoned(8) Dim(10) Overlay(Nnn);
             End-Ds;
      I know - I'm weird, I can't help it... LOL. I like the latter because it's extremely clear what you're doing....

      Comment


      • #6
        Rocky, that second version won't work. You haven't told it that the Nnn* subfields overlay Nnn. So they follow Nnn.

        Here's a test, with a slightly reduced form of your program, and using char instead of zoned to make it easier to see.

        Code:
        Dcl-ds ds;
           Nnn;
             Nnn001 char (8);
             Nnn002 char (8);
             Nnn003 char (8);
             Nnn004 char (8);
           @Nn char(8) Dim(4) Overlay(Nnn);
        End-Ds;
        nnn001 = 'nnn001';
        nnn002 = 'nnn002';
        nnn003 = 'nnn003';
        nnn004 = 'nnn004';
        @nn(1) = '@nn(1)';
        @nn(2) = '@nn(2)';
        @nn(3) = '@nn(3)';
        @nn(4) = '@nn(4)';
        return;
        In debug, after the assignments:
        Code:
        > EVAL ds:c
          DS:C =
                    ....5...10...15...20...25...30...35...40...45...50...55...60  
               1   '@nn(1)  @nn(2)  @nn(3)  @nn(4)  nnn001  nnn002  nnn003  nnn0'  
              61   '04  '

        Comment


        • #7
          Barbara,

          True - in my haste I neglected the overlay's....

          Code:
                /IF DEFINED(*CRTBNDRPG)
                  CTL-OPT DFTACTGRP(*NO) ACTGRP('CCGOV');
                /ENDIF
                 CTL-OPT Option(*NoDebugIO)        ;
                 Dcl-Ds *N;
                   Nnn;
                     Nnn001 Zoned(8) Overlay (Nnn);
                     Nnn002 Zoned(8) Overlay (Nnn:*Next);
                     Nnn003 Zoned(8) Overlay (Nnn:*Next);
                     Nnn004 Zoned(8) Overlay (Nnn:*Next);
                     Nnn005 Zoned(8) Overlay (Nnn:*Next);
                     Nnn006 Zoned(8) Overlay (Nnn:*Next);
                     Nnn007 Zoned(8) Overlay (Nnn:*Next);
                     Nnn008 Zoned(8) Overlay (Nnn:*Next);
                     Nnn009 Zoned(8) Overlay (Nnn:*Next);
                     Nnn010 Zoned(8) Overlay (Nnn:*Next);
                   @Nn Zoned(8) Dim(10) Overlay(Nnn);
                 End-Ds;
          
                 Dcl-S i Int(3);
          
                 @Nn(1) = 2;
                 For i = 2 to %Elem(@Nn);
                    @Nn(i) = @Nn(i - 1) * i;
                 EndFor;
                 *INLR = *ON;
          Nnn will have the values of the array. Thanks for the catch.

          Comment


          • #8
            Barbara,

            Oddly enough I did a little experiment. I the following code:

            Code:
                  /IF DEFINED(*CRTBNDRPG)
                    CTL-OPT DFTACTGRP(*NO) ACTGRP('CCGOV');
                  /ENDIF
                   CTL-OPT Option(*NoDebugIO)        ;
            
                   Dcl-Ds *N;
                     Nnn;
                       Nnn001 Zoned(8);
                       Nnn002 Zoned(8);
                       Nnn003 Zoned(8);
                       Nnn004 Zoned(8);
                       Nnn005 Zoned(8);
                       Nnn006 Zoned(8);
                       Nnn007 Zoned(8);
                       Nnn008 Zoned(8);
                       Nnn009 Zoned(8);
                       Nnn010 Zoned(8);
                     @Nn Zoned(8) Dim(10) Overlay(Nnn);
                   End-Ds;
            
                   Dcl-S i Int(3);
            
                   @Nn(1) = 2;
                   For i = 2 to %Elem(@Nn);
                      @Nn(i) = @Nn(i - 1) * i;
                   EndFor;
                   *INLR = *ON;
            I run it via debug and Nnn has the value:
            00000002000000040000001200000048000002400000144000 010080000806400072576007257600

            Which is exactly the values desired.

            Comment


            • #9
              However, it does seem like an anomaly, it would be much clearer to add the OVERLAY statements...

              Comment


              • #10
                nnn and @nn do occupy the same storage, so when you set the @nn array values, that will also set nnn. But nnn001 follows nnn in the data structure. If you check nnn001, nnn002 etc in debug you will see that they contain blanks.

                Comment


                • #11
                  Gotcha - I do use the OVERLAY, I was just in a hurry in my original post and forgot to add them in.

                  Comment

                  Working...
                  X