Reputation: 371
I'm trying to copy code of a RPG ILE program same as in the video: https://www.youtube.com/watch?v=F2bS3kRpC8Q&list=PL34QvIMpkj1lOoWJuyx2BHbXwYC7llIpe (Minute 34:18)
This is the code I wrote:
H
* Global variables (accessible to all sub procedures local to this pro
D Sum S 4P 0
* SubProcedure prototype OK
DSubProcedure1 PR 4P 0
D 4P 0 VALUE
D 4P 0 VALUE
/Free
Sum = 0; // Initialize global variable
Sum = SubProcedure1(5:10);
DSPLY Sum;
*INLR = *ON;
/End-Free
*
* SubProcedure Begin
PSubProcedure1 B
* SubProcedure Input
DSubProcedure1 PI 4P 0
D num1 4P 0 VALUE
D num2 4P 0 VALUE
* local variable to this subprocedure only (scope limited)
D Sum S 4P 0
/Free
Sum = num1 + num2;
Return Sum;
/End-Free
When compile, I get this message from the spooled file:
5770WDS V7R5M0 220415 RN IBM ILE RPG REUY851/ILEPGM1
Command . . . . . . . . . . . . : CRTBNDRPG
Issued by . . . . . . . . . . : REUY85
Program . . . . . . . . . . . . : ILEPGM1
Library . . . . . . . . . . . : REUY851
Text 'description' . . . . . . . : *SRCMBRTXT
Source Member . . . . . . . . . : ILEPGM1
Source File . . . . . . . . . . : QRPGLESRC
Library . . . . . . . . . . . : REUY851
CCSID . . . . . . . . . . . . : 273
Text 'description' . . . . . . . : RPG ILE PROGRAM WITH SUBPROCEDURE
Last Change . . . . . . . . . . : 04/17/23 05:03:29
Generation severity level . . . : 10
Default activation group . . . . : *YES
Compiler options . . . . . . . . : *XREF *GEN *NOSECLVL *SHOWC
*EXPDDS *EXT *NOSHOWSKP *NOSRC
*DEBUGIO *UNREF *NOEVENTF
Debugging views . . . . . . . . : *STMT
Debug encryption key . . . . . . : *NONE
Output . . . . . . . . . . . . . : *PRINT
Optimization level . . . . . . . : *NONE
Source listing indentation . . . : *NONE
Type conversion options . . . . : *NONE
Sort sequence . . . . . . . . . : *HEX
Language identifier . . . . . . : *JOBRUN
Replace program . . . . . . . . : *NO
User profile . . . . . . . . . . : *USER
Authority . . . . . . . . . . . : *LIBCRTAUT
Truncate numeric . . . . . . . . : *YES
Fix numeric . . . . . . . . . . : *NONE
Target release . . . . . . . . . : *CURRENT
Allow null values . . . . . . . : *NO
Define condition names . . . . . : *NONE
Enable performance collection . : *PEP
Profiling data . . . . . . . . . : *NOCOL
Licensed Internal Code options . :
Generate program interface . . . : *NO
Include directory . . . . . . . :
Preprocessor options . . . . . . : *NONE
REQUIRE PROTOTYPE FOR EXPORT . . : *NO
-=* http://pub400.com *=-
5770WDS V7R5M0 220415 RN IBM ILE RPG REUY851/ILEPGM1
Line <---------------------- Source Specifications -------------------------
Number ....1....+....2....+....3....+....4....+....5....+....6....+....7....+.
S o u r c e L i s t i n g
1 H
2 * Global variables (accessible to all sub procedures local to this pro
3 D Sum S 4P 0
4 * SubProcedure prototype OK
5 DSubProcedure1 PR 4P 0
======> aaaaaaaaaaaaa
*RNF3788 30 a 000500 DFTACTGRP(*NO) must be specified for a prototype th
not have the EXTPGM keyword.
6 D 4P 0 VALUE
7 D 4P 0 VALUE
8 /Free
9 Sum = 0; // Initialize global variable
10 Sum = SubProcedure1(5:10);
11 DSPLY Sum;
12 *INLR = *ON;
13 /End-Free
14 *
15 * SubProcedure Begin
16 PSubProcedure1 B
17 * SubProcedure Input
18 DSubProcedure1 PI 4P 0
19 D num1 4P 0 VALUE
20 D num2 4P 0 VALUE
21 * local variable to this subprocedure only (scope limited)
22 D Sum S 4P 0
23 /Free
24 Sum = num1 + num2;
25 Return Sum;
26 /End-Free
*RNF1502 20 16 001600 The Procedure specification ending the previous pro
is missing.
* * * * * E N D O F S O U R C E * * * * *
-=* http://pub400.com *=-
5770WDS V7R5M0 220415 RN IBM ILE RPG REUY851/ILEPGM1
A d d i t i o n a l D i a g n o s t i c M e s s a g e s
Msg id Sv Number Seq Message text
*RNF7503 30 10 001000 Expression contains an operand that is not defined.
* * * * * E N D O F A D D I T I O N A L D I A G N O S T I C M E S S
-=* http://pub400.com *=-
5770WDS V7R5M0 220415 RN IBM ILE RPG REUY851/ILEPGM1
C r o s s R e f e r e n c e
File and Record References:
File Device References (D=Defined)
Record
No references in the source.
Global Field References:
Field Attributes References (D=Defined M=Modified
*INLR N(1) 12M
SUBPROCEDURE1 P(4,0) 5D 10 16 18
PROTOTYPE
SUM P(4,0) 3D 9M 10M 11
Field References for subprocedure SUBPROCEDURE1
Field Attributes References (D=Defined M=Modified
NUM1 P(4,0) 19D 24
NUM2 P(4,0) 20D 24
SUM P(4,0) 22D 24M 25
Indicator References:
Indicator References (D=Defined M=Modified
LR 12M
* * * * * E N D O F C R O S S R E F E R E N C E * * * * *
-=* http://pub400.com *=-
5770WDS V7R5M0 220415 RN IBM ILE RPG REUY851/ILEPGM1
E x t e r n a l R e f e r e n c e s
Statically bound procedures:
Procedure References
No references in the source.
Imported fields:
Field Attributes Defined
No references in the source.
Exported fields:
Field Attributes Defined
No references in the source.
* * * * * E N D O F E X T E R N A L R E F E R E N C E S * * * * *
-=* http://pub400.com *=-
5770WDS V7R5M0 220415 RN IBM ILE RPG REUY851/ILEPGM1
M e s s a g e S u m m a r y
Msg id Sv Number Message text
*RNF1502 20 1 The Procedure specification ending the previous procedure i
missing.
*RNF3788 30 1 DFTACTGRP(*NO) must be specified for a prototype that does
not have the EXTPGM keyword.
*RNF7503 30 1 Expression contains an operand that is not defined.
* * * * * E N D O F M E S S A G E S U M M A R Y * * * * *
-=* http://pub400.com *=-
5770WDS V7R5M0 220415 RN IBM ILE RPG REUY851/ILEPGM1
F i n a l S u m m a r y
Message Totals:
Information (00) . . . . . . . : 0
Warning (10) . . . . . . . : 0
Error (20) . . . . . . . : 1
Severe Error (30+) . . . . . . : 2
--------------------------------- -------
Total . . . . . . . . . . . . . : 3
Source Totals:
Records . . . . . . . . . . . . : 26
Specifications . . . . . . . . : 15
Data records . . . . . . . . . : 0
Comments . . . . . . . . . . . : 6
* * * * * E N D O F F I N A L S U M M A R Y * * * * *
Maybe is some about configuration for compiling, I don't know, but when I compile source member with 14 and press F4 and change activation group to NO, It doesn't save changes.
Upvotes: 1
Views: 587
Reputation: 11493
So you are using IBM i v7.5, and programming like you are stuck at v6.1 so there are several things you want to do here. First, stop using fixed format code all together. You no longer need to code H, D, and P specs in fixed format. Second you no longer need /Free
and /End-Free
. Just put **free
as the first line of your program. But, if you insist on a mix of fixed format and free format code, just omit the **free
and code the lines. You still do not need /Free
or /End-Free
, the compiler can tell the difference and they just clutter the code.
So it should look like this:
**free
ctl-opt DatFmt(*iso) TimFmt(*iso)
DftActGrp(*No) ActGrp(*New)
Option(*NoDebugIo: *SrcStmt: *NoUnref)
Main(main);
// Global variables (accessible to all sub procedures local to this pro
dcl-s Sum Packed(4:0) inz(0);
// Main procedure
dcl-proc main;
Sum = SubProcedure1(5:10);
dsply Sum;
// *INLR = *ON; This is unnecessary
end-proc;
// SubProcedure Begin
dcl-proc SubProcedure1;
dcl-pi *n Packed(4:0);
num1 Packed(4:0) value;
num2 Packed(4:0) value;
end-pi;
return num1 + num2;
end-proc;
So lets look at this line by line:
**free
This tells the compiler that the program is entirely free format, fixed format lines are not allowed, and that the cycle is not going to be involved. So, things that use or control the cycle like *INLR have no meaning. There is also no columnar importance at all for the code. Your code go from column 1 all the way to the end of the record line. There are no sequence or comment columns, and the record length can be greater than 80.
ctl-opt DatFmt(*iso) TimFmt(*iso)
DftActGrp(*No) ActGrp(*New)
Option(*NoDebugIo: *SrcStmt: *NoUnref)
Main(main);
This is what used to be the H spec. You can use this for every program, but modules will want NoMain
instead of Main()
. In addition you will want to use ActGrp(*Caller)
for modules. I usually use the program name as the main procedure name. The reason for that is that if you are copying in program prototypes, every program needs a different prototype name. And you really want to use prototypes in a separate copy source to provide parameter checking in calling programs as Barbara said in the comments.
dcl-s Sum Packed(4:0) inz(0);
This is the D spec for the global variable, the variable is defined and initialized all in one step. There is no longer a need for a prototype for procedures defined in the program source, so that is dropped.
dcl-proc main;
Sum = SubProcedure1(5:10);
dsply Sum;
end-proc;
The main procedure source is now enclosed is a procedure definition. I named it main here, but I usually name it after my program. Notice it starts with a dcl-proc
and ends with end-proc
.
dcl-proc SubProcedure1;
dcl-pi *n Packed(4:0);
num1 Packed(4:0) value;
num2 Packed(4:0) value;
end-pi;
return num1 + num2;
end-proc;
Finally, the sub-procedure definition starts with dcl-proc
and ends with end-proc
just like the main procedure. These are the P specs in fixed format, one with a B and the other with an E. You don't even need the intermediate declaration of sum in this case because the expression is simple enough to just return the result.
Edit: The reported bug wasn't a bug, but there were a couple typos that occurred as a result of me coding recently in Java (, instead of : separating parameters), fixed now with a compile just to prove it works.
Upvotes: 2
Reputation: 3212
When you compile with CRTBNDRPG and you have procedures in the body of the module, you must have DFTACTGRP set to *NO to compile.
There is multiple way to do it, you can set the value using the command like you did or
H dftactgrp(*no)
You also can condition it's presence in the source depending on the command you use
/IF DEFINED(*CRTBNDRPG)
H dftactgrp(*no)
/ENDIF
The reason why it didn't work for you is that there was another error behing this one : is a missing line in the source that closes the procedure definition
PSubProcedure1 E
Upvotes: 3