|
View previous topic :: View next topic
|
| Author |
Message |
Pedro
Global Moderator

Joined: 01 Sep 2006 Posts: 2624 Location: Silicon Valley
|
|
|
|
I have several large programs that print to the same file.
Each program has:
| Code: |
| Dcl mymsgs FILE Stream Output Print; |
I was originally doing this:
| Code: |
PUT FILE(mymsgs) LIST('text1');
call prog2
Put FILE(mymsgs) LIST('text3');
where external prog2 did:
PUT FILE(mymsgs) LIST('text2');
|
but the result was out of order:
text2
text1
text3
So I added FLUSH statements:
| Code: |
PUT FILE(mymsgs) LIST('text1');
FLUSH FILE(mymsgs) ;
call prog2
FLUSH FILE(mymsgs) ;
Put FILE(mymsgs) LIST('text3');
where external prog2 did:
PUT FILE(mymsgs) LIST('text2');
|
Great! now I get the text in the correct order.
But I did all of my testing to:
| Code: |
| //MYMSGS DD SYSOUT=* |
Now, when I use a data set instead of SYSOUT=*, I am only seeing some of the text from prog2.
| Code: |
//MYMSGS DD DISP=(NEW,CATLG),DSN=MY.OUTPUT,
// SPACE=(CYL,(2,1)) |
Does anybody have any insight as to why I do not get all of the output? |
|
| Back to top |
|
 |
steve-myers
Active Member
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
|
|
|
|
Yes.
When you send a message to a JES2 data set, the message is added to any messages already in the data set.
In your arrangement, the first program opened, then closed the data set, and then the second program did the same. When you have a real data set (as opposed to a JES data set, which is a little different) the second use of the data set restarts output to the data set. In other words, the data already in the data set is trashed, as you observed.
One possible fix, provided MY.OUTPUT does not actually exist, is to specify DISP=(MOD.CATLG) rather than DISP=(NEW,CATLG)
For what it's worth, I suspect JES2 would tell you it's working as designed. Whether the design is appropriate is another question, and probably goes back to the design history of HASP and was forwarded to JES2. When HASP developed the idea of data sets, when the JCL specified SYSOUT=X, the DD statement was allocated to a pseudo printer, and OPEN/CLOSE boundaries were effectively ignored and HASP treated the device like a real printer. Come JES2, they decided it should behave the same way. |
|
| Back to top |
|
 |
prino
Senior Member

Joined: 07 Feb 2009 Posts: 1323 Location: Vilnius, Lithuania
|
|
|
|
Don't have time to test this now, in a few minute we're off to the Netherlands for a birthday, but I find it very strange that printing to a file would not gave the same results as printing to sysout. and in the 32+ years I've used PL/I, I've never had to resort to using FLUSH, even for programs with dozens of external subroutines.
What you might try is opening myfile explicitly in your main program. Files are by default external, so if the definitions in each module are the same, there should be no problems. |
|
| Back to top |
|
 |
steve-myers
Active Member
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
|
|
|
|
| Enterprise PL/I Language Reference wrote: |
| The FLUSH statement flushes the buffers associated with an open output file (or with all open output files if * is specified). This normally happens when the file is closed or the program ends, but the FLUSH statement ensures the buffers are flushed before any other processing occurs. |
The manual seems to me to be saying the FLUSH statement accomplishes this task by immediately closing a PL/I file.
Now I mostly work in Assembler, and I've noticed when using QSAM "locate mode" PUT macros that a line in progress does not actually get written until the related DCB is closed or the next PUT macro is issued. This makes sense: "locate mode" PUT returns the address of an I/O area to fill and the only way to be certain this is complete is to issue a new PUT or to close the DCB. "Move mode" PUTs usually seem to be more immediate. Even so, if it's filling an I/O buffer the buffer won't get written until it's filled or the related DCB is closed. |
|
| Back to top |
|
 |
Pedro
Global Moderator

Joined: 01 Sep 2006 Posts: 2624 Location: Silicon Valley
|
|
|
|
More investigation is needed. The default for OPEN FILE is BUFFERED (vs. UNBUFFERED). I will try using the UNBUFFERED.
Also, in the declare, I used STREAM instead of RECORD. Is there a recommendation? |
|
| Back to top |
|
 |
prino
Senior Member

Joined: 07 Feb 2009 Posts: 1323 Location: Vilnius, Lithuania
|
|
|
|
I've done a quick check, and all is well:
| Code: |
//PRINOCOM JOB (PRINO),
// 'RAHP COMP/LINK',
// CLASS=A,
// MSGCLASS=H,
// MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*********************************************************************
//IEFBR14 EXEC PGM=IEFBR14
//SYSLIN DD DSN=&&OBJECT,
// DISP=(,PASS),
// UNIT=SYSDA,
// SPACE=(CYL,(2,2,1)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920)
//*********************************************************************
//IBMZPLI EXEC PGM=IBMZPLI,
// REGION=0M,
// PARM=('+DD:PLISTD +DD:PLIUSER')
//*
//STEPLIB DD DSN=PLI.V4R5M0.SIBMZCMP,
// DISP=SHR
//*
//SYSUEXIT DD DSN=NULLFILE,
// DISP=SHR
//*
//SYSPRINT DD SYSOUT=*
//*
//SYSUT1 DD UNIT=SYSDA,
// SPACE=(CYL,(5,5))
//*
//PLISTD DD DSN=&SYSUID..RAHP.DATA(PXEP45Z),
// DISP=SHR
//*
//PLIUSER DD *
nolist
test(all,sym,separate,sepname) sysparm('TEST') opt(0)
notest sysparm('') opt(3)
//*
//SYSIN DD *
/* Roberts Q&D PL/I test program */
test: proc(parm) options(main) reorder;
dcl parm char (100) var;
dcl plixopt char (100) var ext
init ('ISASIZE(64K) HEAP(128K,64K)');
dcl sysprint file;
on error snap
begin;
on error snap system;
call plidump('HB');
end;
dcl test2 entry(*);
dcl orecord file record output env(fb recsize(80) total);
dcl ostream file stream print;
dcl orec char (80) init ('test 1');
put skip list(orec);
put skip file(ostream) list(orec);
write file(orecord) from(orec);
call test2('plork');
orec = 'test 3';
put skip list(orec);
put skip file(ostream) list(orec);
write file(orecord) from(orec);
end test;
//*
//SYSLIN DD DSN=&&OBJECT(OBJ),
// DISP=(OLD,PASS)
//*
//SYSPUNCH DD DUMMY
//*********************************************************************
//IBMZPLI EXEC PGM=IBMZPLI,
// REGION=0M,
// PARM=('+DD:PLISTD +DD:PLIUSER')
//*
//STEPLIB DD DSN=PLI.V4R5M0.SIBMZCMP,
// DISP=SHR
//*
//SYSUEXIT DD DSN=NULLFILE,
// DISP=SHR
//*
//SYSPRINT DD SYSOUT=*
//*
//SYSUT1 DD UNIT=SYSDA,
// SPACE=(CYL,(5,5))
//*
//PLISTD DD DSN=&SYSUID..RAHP.DATA(PXEP45Z),
// DISP=SHR
//*
//PLIUSER DD *
nolist
test(all,sym,separate,sepname) sysparm('TEST') opt(0)
notest sysparm('') opt(3)
nooptions;
//*
//SYSIN DD *
/* Roberts Q&D PL/I test2 program */
test2: proc(parm) reorder;
dcl parm char (100) var;
dcl sysprint file;
dcl orecord file record output env(fb recsize(80) total);
dcl ostream file stream print;
dcl orec char (80) init ('test 2');
put skip list(orec);
put skip file(ostream) list(orec);
write file(orecord) from(orec);
end test2;
//*
//SYSLIN DD DSN=&&OBJECT(OBJ2),
// DISP=(OLD,PASS)
//*
//SYSPUNCH DD DUMMY
//*********************************************************************
//IEWL EXEC PGM=IEWL,
// PARM=('LET,LINECT=0,LIST,XREF',
// 'AMODE=31,RMODE=ANY')
//*
//SYSLIN DD *
INCLUDE OBJECT(OBJ)
INCLUDE OBJECT(OBJ2)
NAME TEST(R)
//*
//OBJECT DD DSN=&&OBJECT,
// DISP=(OLD,PASS)
//*
//SYSLIB DD DSN=CEE.SCEELKED,
// DISP=SHR
//*
//SYSUT1 DD UNIT=SYSDA,
// SPACE=(CYL,(5,1))
//*
//SYSLMOD DD DSN=&&LOAD,
// DISP=(,PASS),
// UNIT=SYSDA,
// SPACE=(CYL,(2,2,1)),
// DCB=(RECFM=U,LRECL=27988,BLKSIZE=0)
//*
//SYSPRINT DD SYSOUT=*,
// DCB=(RECFM=FBA,LRECL=121,BLKSIZE=27951)
//*********************************************************************
//GO EXEC PGM=TEST
//STEPLIB DD DSN=&&LOAD,
// DISP=(OLD,PASS)
//*
//SYSPRINT DD SYSOUT=*
//OSTREAM DD SYSOUT=*
//ORECORD DD SYSOUT=* |
and the output:
| Code: |
SDSF JOB DATA SET DISPLAY - JOB PRINOCOM (JOB14398) LINE 1-9 (9)
COMMAND INPUT ===>
PREFIX=* DEST=(ALL) OWNER=PRINO SYSNAME=
NP DDNAME StepName ProcStep DSID Owner C Dest Rec-Cnt Page-Cnt Byte-Cnt
JESMSGLG JES2 2 PRINO H LOCAL 16 888
JESJCL JES2 3 PRINO H LOCAL 109 4,403
JESYSMSG JES2 4 PRINO H LOCAL 103 5,499
SYSPRINT IBMZPLI 106 PRINO H LOCAL 414 13,830
SYSPRINT IBMZPLI 107 PRINO H LOCAL 240 7,658
SYSPRINT IEWL 108 PRINO H LOCAL 270 20,001
SYSPRINT GO 109 PRINO H LOCAL 3 48
OSTREAM GO 110 PRINO H LOCAL 3 48
ORECORD GO 111 PRINO H LOCAL 3 45 |
And the joblog from the end of the IEWL step:
| Code: |
IEW2008I 0F03 PROCESSING COMPLETED. RETURN CODE = 0.
----------------------
MESSAGE SUMMARY REPORT
----------------------
TERMINAL MESSAGES (SEVERITY = 16)
NONE
SEVERE MESSAGES (SEVERITY = 12)
NONE
ERROR MESSAGES (SEVERITY = 08)
NONE
WARNING MESSAGES (SEVERITY = 04)
NONE
INFORMATIONAL MESSAGES (SEVERITY = 00)
2008 2278 2322
**** END OF MESSAGE SUMMARY REPORT ****
1test 1
test 2
test 3
1test 1
test 2
test 3
test 1
test 2
test 3 |
In other words, (and expecting nothing else), perfectly OK.
ORECORD (obviously) doesn't have the leading ASA character.
Changing //OSTREAM to a temporary dataset and following that with a SORT (SORT FIELDS=COPY) to SORTSOUT DD SYSOUT=* will add additional blank lines to the output, caused by the SKIP in the "put skip file(ostream) list(orec);" statements. |
|
| Back to top |
|
 |
Pedro
Global Moderator

Joined: 01 Sep 2006 Posts: 2624 Location: Silicon Valley
|
|
|
|
I probably have multiple problems... at least one problem is that when the second program is called, it receives an undefined file condition.
I issue a PUT statement right before calling the second program (I see it in the data set) and the first statement in the second program is a PUT, which I do not get.
fyi. I am adding a new function to existing PLI programs, several of which are 10K lines of code or more. I think something in the complexity of the setup is interfering with the PUT functions / file allocations. |
|
| Back to top |
|
 |
prino
Senior Member

Joined: 07 Feb 2009 Posts: 1323 Location: Vilnius, Lithuania
|
|
|
|
| Pedro wrote: |
| I probably have multiple problems... at least one problem is that when the second program is called, it receives an undefined file condition. |
And the file is declared the same as in the main procedure?
| Pedro wrote: |
| I issue a PUT statement right before calling the second program (I see it in the data set) and the first statement in the second program is a PUT, which I do not get. |
You have an
| Code: |
on error
begin;
on error system
"put whatever message"
close file(sysprint);
end; |
| Pedro wrote: |
| fyi. I am adding a new function to existing PLI programs, several of which are 10K lines of code or more. I think something in the complexity of the setup is interfering with the PUT functions / file allocations. |
Highly unlikely, but you might try compiling "OPT(0)" and run the program again, although it's only once, using the old OS compiler, that this actually solved the problem. Enterprise PL/I can handle programs with 40k lines, we have someone on "that" system with a program that long, still using EPLI V3.3! |
|
| Back to top |
|
 |
Pedro
Global Moderator

Joined: 01 Sep 2006 Posts: 2624 Location: Silicon Valley
|
|
|
|
I have separately linked programs, with several separate load modules.
There was some improvement after I closed the file before calling the second program, then opening it again later after the return. That was probably the origin of the problem. Now I have to figure out where else I need to do the same. |
|
| Back to top |
|
 |
|
|
 |
All times are GMT + 6 Hours |
|