Thank you all for the advice! I really appreciate it and the example of free! I haven't used free before and this will help me understand it better!
I am familiar with C programming Jon, but I haven't done any work with it since college in 07. I learned C++ if that helps answer your question :)
It seems you are scanning a member in a source file - is this correct?
Can you guarantee that the source from HP is always in this layout?
Always a DATAIN with a DATAOUT on the next line?
Yes I am scanning a member in a source file and I can guarantee that if there is a DATAIN, the following line with be DATAOUT. There are other commands that are dealing with file, but I am taking piece by piece so that I do not confuse myself or leave anything out.
-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Buck Calabro
Sent: Monday, September 30, 2013 12:34 PM
To: rpg400-l@xxxxxxxxxxxx
Subject: Re: Scanning Information for 2 Lines of Code and Migrating into 1
On 9/30/2013 1:13 PM, Kari Zeglin wrote:
I am a newbie at RPGLE. What I am doing is a migration conversion program from the HP to IBM for my work. I currently have the program scan for one line and change the HP command to an AS400 one. I have it working perfectly in most areas but one..
I need to scan these two lines as example:
FILE DATAIN=FEDRECD1
FILE DATAOUT=FEDSRTD
From there I need to turn those two lines into:
CPYF FROMFILE(FEDRECD1) TOFILE(QTEMP/FEDSRTD) +
CRTFILE(*YES)
I can get my output to be, using EVAL %SUBST : CPYF FROMFILE(FEDRECD1) TO FILE(QTEMP/ )+
'Need' is one of those words that can be misleading to geeks :-) There is no technical reason that the CL must be on two lines - the entire command will comfortably fit on one 80 column line.
CRTFILE(*YES)
Here is my code on scanning:
C 'FILE' SCAN SRCDTA POSIT 90
C *IN90 IFEQ '1'
C 'DATAIN' SCAN SRCDTA POSIT 90
C *IN90 IFEQ '1'
C EXSR FCO
C ELSE
C 'DATAOUT' SCAN SRCDTA POSIT 90
C *IN90 IFEQ '1'
C EXSR FCOP
....
If you're new to RPG, may I gently suggest that you use /free syntax? I think you will adapt to the modern dialect easier.
My question is what can I use/do to have my program scan these two lines of code and get it into one line, or have my separate SR's talk to get DATAIN/OUT in the correct positions on one line?
In computer science parlance you'd like to use a finite state machine to keep track of whether you'd read a FILE DATAIN or FILE DATAOUT line.
But since there are only two 'states' you can mostly do that with a boolean variable like an indicator.
Here is a /free version of one way to go about this chore:
d datain s 32 inz('FILE DATAIN=FEDRECD1')
d dataout s 32 inz('FILE DATAOUT=FEDSRTD')
d datain_name s 10 varying inz
d dataout_name s 10 varying inz
d have_dataout s n inz
d srcdta s 80
d cmd s 80
d i s 10i 0
c/free
// pretend we've just read a source line into SRCDTA
srcdta = datain;
exsr parser;
// pretend we've just read another source line into SRCDTA
srcdta = dataout;
exsr parser;
// build the output command
if have_dataout;
cmd = 'CPYF FROMFILE(' + datain_name +
') TOFILE(QTEMP/' + dataout_name +
') CRTFILE(*YES)';
have_dataout = *off;
// write the command to the CL source member
// reset the name storage variables for the next pass
datain_name = '';
dataout_name = '';
endif;
*inlr = *on;
// parse incoming source lines
begsr parser;
// is it a file statement?
if %scan('FILE': srcdta) > 0;
// is it a datain?
i = %scan('DATAIN': srcdta);
if i > 0;
datain_name = %trimr(%subst(srcdta: i+7: %size(datain_name)));
endif;
// is it a dataout?
i = %scan('DATAOUT': srcdta);
if i > 0;
dataout_name = %trimr(%subst(srcdta: i+8:
%size(dataout_name)));
have_dataout = *on;
endif;
endif;
endsr;
/end-free
The only tricky bit is the statement with multiple built in functions.
I find that reading from the inside out works for me. So
datain_name = %trimr(%subst(srcdta: i+7: %size(datain_name)));
Start with %substr. That takes the substring of SRCDTA starting at i+7.
Why i+7? Because the previous line's %scan() found 'DATAIN' which is 6 long, plus one for the equals sign which brings us to the beginning of the actual input file name. The next argument tells %substr how many characters to pull. Instead of hard coding 10, I used the %size() BIF to let the compiler fill in the length for me. That way if the names change (say to 8 long) all you need to do is change the D-specification and the calculations won't need to be touched.
So now we have extracted out the 10 characters of the input file name.
Now %trimr strips the blanks off of it. This only works because DATAIN_NAME is declared VARYING, and so is not a fixed-length variable.
All of the 'decision making' if you want to call it that, is based on the variable HAVE_DATAOUT.
There are... opportunities for improvement here. What happens if DATAOUT comes before DATAIN? What happens if there's a DATAIN but no DATAOUT? What happens if there's a DATAIN, some other HP command and then a DATAOUT? A true finite state machine would be able to track (and
trap!) these things, but I wanted to get some ideas your way rather than bury you in details. Which I fear I may have done anyway :-/
--buck
--
This is the RPG programming on the IBM i (AS/400 and iSeries) (RPG400-L) mailing list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
visit:
http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at
http://archive.midrange.com/rpg400-l.
As an Amazon Associate we earn from qualifying purchases.