Re: Class Notes for a PL/I Course.
"Giuseppe Vitillaro giuseppe-yuD/ahkh7LvrZ44/[email protected] [H390-MVS]" <[email protected]> Thu, 3 Oct 2019 19:46:07 +0200 (CEST)
| Newsgroups | gmane.comp.emulators.hercules390.mvs |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 3 Oct 2019, Bernd Oppolzer berndoppolzer-/[email protected] [H390-MVS] wrote: > Am 03.10.2019 um 12:42 schrieb Giuseppe Vitillaro giuseppe-yuD/ahkh7LvrZ44/[email protected] > [H390-MVS]: >> >> On Thu, 3 Oct 2019, Bernd Oppolzer berndoppolzer-/[email protected] [H390-MVS] >> wrote: >> > >> > Kind regards >> > >> >> I guess declaring this way a variable in the main program: >> >> DECLARE ZAZA CHARACTER(10) STATIC EXTERNAL INITIAL ( 'GIGIO' ); >> >> and using it in an external procedure in this way: >> >> ZZ: PROCEDURE; >> DECLARE ZAZA CHARACTER(10) EXTERNAL; >> PUT FILE(SYSPRINT) SKIP EDIT ('ZAZA=', ZAZA ) (2(A)); >> RETURN; >> END ZZ; >> >> it is the best which can be done in PL/I(F) to get something >> which looks like a global C variable? >> > > The short answer is: yes, this is the best. > > The long answer is: this does not really help you, if you want to > do some sort of dynamic linking, because you need the linker to > resolve those external references. > > BTW: STATIC in the main program is not needed or even forbidded, > because EXTERNAL variables are STATIC by default. > > >> >> Another thing I'm looking for is something like >> the C typedef syntax. >> >> The "LIKE" syntax looks to do something similar, >> but for an already "allocated" variable, if >> the variable is not actually a pointer. >> >> Anything better can be done with PL/I (F)? >> >> Peppe. >> >> > > This is somehow related to the question above. > > If you want parameters to be passed between external functions, > they may be structures - in the general case. > > The C way to do this would be > > - have a typedef of the struct in an include file > - then use this include file on both sides > - pass pointers of this struct between caller and called function > > This way the called function can read and write values from and > to the parameter structure. > > In traditional PL/1, there is no typedef. There is simply no concept > of type. See the funny assignment of structures (called aggregates), > where it is only needed that the layout of the structures are > congruent in a certain way, but the types of the components may differ. > > Or the second variant: BY NAME. > > This is all very different from what other languages do. > > So what is done "in real word" is often the following: > > we use %INCLUDE files, too. This works in PL/1, even if you don't > use the preprocessor (which is another very interesting topic; > the PL/1 preprocessor is much more powerful than the C macro processor, > for example). > > in these %INCLUDE files, we define PL/1 structures (or aggregates) > without the structure header, that is, without the DCL and the level 1 > definition. Only level 3 or 5 ... > > these structure bodies are used at both sides (caller and callee). > > But the caller declares: > > DCL 1 PARM_STRUCT AUTO, > %INCLUDE (PARMINC);; > > and the callee declares: > > DCL 1 PARM_STRUCT BASED (PARM_PTR), > %INCLUDE (PARMINC);; > > and the call looks like this: > > CALL CALLEE (ADDR (PARM_STRUCT)); > > that is, only parameters are passed. > > It is possible to pass structures, but then you will get real trouble > with structure aggregates. > > Passing pointers to structures will work well, when calling other > languages, too. There will be some issues with component alignment > (the PL/1 methods differ from that of other languages), but that > can be solved. > > This is not typedef, but it works a little bit like typedef :-) > == COBOL copybooks :-) > > HTH, > kind regards > > Bernd > > > > Got it, Benrd, thanks again. Yep, this looks like near what we do in C with a typedef to a structure and using a pointer is a nice trick ;-) In the meanwhile I did some progress with my VS2FB/FB2VS exercise. The ability of PL/I(F) to manage at the same time a FILE STREAM and a FILE RECORD is a wonderful feature, which makes storing a VS dataset into an FB(80) dataset as simple as, I guess, it can be under MVS. What I've now, basically, are two I/O loops, one for storing a VS FILE RECORD into an FB FILE STREAM: DECLARE OUTF FILE STREAM OUTPUT; DECLARE INPF FILE RECORD INPUT ENV(VS); .... LP = ADDR(L); DO WHILE(TRUE); READ FILE(INPF) INTO(BUF); L = LENGTH(BUF); PUT FILE(OUTF) EDIT(SP,BUF) (A(2),A); END; and the other one for restoring the FB FILE STREAM back into a VS FILE RECORD: DECLARE INPF FILE STREAM INPUT; DECLARE OUTF FILE RECORD OUTPUT ENV(VS); ,,, LP = ADDR(L); DO WHILE(TRUE); GET FILE(INPF) EDIT ( SP ) ( A(2) ); IF ( L = 0 ) THEN GOTO EOF; GET FILE(INPF) EDIT ( BUF ) ( A(L) ); WRITE FILE(OUTF) FROM ( BUF ); END; where the last FB record has a plain zero length marking the logical EOF of the VS dataset. The PL/I(F) limitation to a "CHAR(32767) VARYING" should not be a problem here, I hope, because the max VS LRECL I may expect is actually 32760, isn't it? The only "glitch" in this code I can foresee, which actually works over an IEBCOPY output VS dataset, is in the conversion between the "FIXED BIN(15)" variable L and its corresponding "CHARACTER(2)" SP binary representation. What I'm doing now, which I guess is really my C habit, is using the LP pointer in this way: DECLARE L FIXED BIN(15); DECLARE LP POINTER; DECLARE SP CHARACTER(2) BASED(LP); which makes SP overloading the same memory area of the L record lenght variable once LP is initialized to the ADDRess of L. Is there any "clean way" to make such a conversion with PL/I (F), at runtime? Beside that, now, I can easily store my IEBCOPY datasets into FB datasets, possibly members of a PDS FB(80), and trasfer them to my Linux filesystems, a simple way to store backups of my PDS under MVS and Linux, without using XFER370 and its bad habits, which I really hate ;-) By the way, it is fast as an hell, with a large enough FB(80) BLKSIZE, almost as XFER370. Any way to make it faster with PL/I(F)? Just for reference, if anyone would even wish to a have a look to my poor PL/I coding the JCL test streams are stored at these URLs: http://www.vitillaro.org/curr/VS2FB http://www.vitillaro.org/curr/FB2VS Peppe.