I am having some trouble figuring out how to get IEBGENER working in the way that I want it to. I should preface all this by saying that I am running IEBGENER in a z/OS environment on an academic mainframe.
I have three JCL procedures (PROC) inline to some COBOL code that I am working with, and I need IEBGENER as one of the first steps to put my PROC into a "permanent procedure library under my MVS ID" as well as put my COBOL source "into a permanent sequential data set under my MVS ID".
The instructor mentions to "remember to code the correct LRECL and BLKSIZE information for these data sets."
I am not very familiar with IEBGENER and haven't found anything that really explains to me how to do what I am trying to do.
Any "Big Iron" people able to help?
As mentioned, IEBGENER is a copy program. It takes an input on SYSUT1 and "generates" it to output dataset SYSUT2. In your instance, since you are copying 2 files, its easiest to have 2 GENER steps, each one producing one output dataset.
The only tricky part here is to get the output datasets in the right format. So, to gener into the proclib, assuming that it is not currently cataloged, your SYSUT2 would look something like this:
//SYSUT2 DD DSN=&SYSUID.PROCLIB,
// DISP=(NEW,CATLG,DELETE),
// DCB=(RECFM=FB,LRECL=80,DSORG=PO)
The sequential dataset for the source output would look similar, but no DSORG subparameter on the DCB option. The option of PO there says to create a PDS as opposed to a QSAM file. On modern z/OS installations, BLKSIZE is not necessary to code, as the system will calculate the optimum size if you don't specify it.
this is how to use IEBGENER (as mentioned, should be on the IBM docs site):
//COPY EXEC PGM=IEBGENER
//SYSUT1 DD DSN=MY.INPUT.FILE,DISP=SHR
//SYSUT2 DD DSN=MY.OUTPUT.FILE,DISP=NEW,SPACE=....
//SYSIN DD DUMMY
IEBGENER is "just a" copy program and about all it takes is an input file, output file, and a control file
I'm not sure what you think is "specific", isn't it just a matter of knowing which names to use?
edit: if what you want is defining your input inline, try this:
//SYSUT1 DD *
...
/*
or better yet, if your input contains JCL as well:
//SYSUT1 DD DATA,DELIMITER=XX
...
XX
Still not exceptional JCL, though.
Here is the link to IBM Z/OS manuals
http://www-03.ibm.com/systems/z/os/zos/bkserv/v1r10books.html
search for JCL and you will find the manuals for JCL.
IEBGENER is a IBM supplied copy program to copy data from one dataset (file) to another dataset. You will have input file, output file and control file.
LRECL and BLKSIZe are dataset parameters. If the input file and output file parameters do not match, data may not get copied correctly. I didn't understand your questions completely. Can you elaborate on what exactly you need to do with IEBGENER.
A couple of minor points:
DCB=(RECFM=FB,LRECL=80,DSORG=PO)
DCB= is not required anymore, just code
RECFM=FB,LRECL=80,DSORG=PO
Also:
Because the records are fixed-format,
the BLKSIZE must be an even multiple
of 80. Very often, people use a value
of 3120. The reasons for this are
hidden in the mists of antiquity. I
tend to use 27920, to get the most
efficient space usage on a 3390
device.
It should not be necessary to specify a blocksize for a new DASD (disc) dataset. System determined blocksize will automatically give you the best blocksize (which would indeed be 27920 for a LRECL of 80 on a 3390)
Just so you don't need to worry about the DCB parameter, it's nice trick to point to the value from the input dataset.
//STEP100 EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD DISP=SHR,DSN=INPUT.FILE
//SYSUT2 DD DSN=OUTPUT.FILE,
// DISP=(,CATLG,DELETE),
// SPACE=(TRK,(300,50),RLSE),
// DCB=*.SYSUT1
//SYSIN DD DUMMY
It sounds as if your instructor is reminding you to give the correct LRECL and BLKSIZE to the "permanent procedure library" and "permanent sequential data set". Historically, such data sets are RECFM=FB, LRECL=80.
Because the records are fixed-format, the BLKSIZE must be an even multiple of 80. Very often, people use a value of 3120. The reasons for this are hidden in the mists of antiquity. I tend to use 27920, to get the most efficient space usage on a 3390 device.
IEBGENER is one of the most underrated and misunderstood utilities IBM has.
Here is the hyperlink for the best documentation: IEBGENER.
IEBGENER is not merely a file-to-file utility that only does copies. It can easily and more efficiently create variable blocked files. It can with the proper buffering actually be your fastest file-to-file copy utility as it used to not be internally buffered very well though now I believe it is so it is now automatically just about the fastest. The //SYSPRINT messages - sadly - are extremely cryptic if not actually annoyingly ridiculous. Many shops have an accelerator called BETERGENER as most programmers had no idea how to buffer IEBGENER and since IBM is catering to the pampered new programmers who want MVS to look like and act like Windows, using IEBGENER is more user friendly. yuck
Related
I am responsible for converting an old UNIX based COBOL batch application that was developed by a consultant back in the 1990s to a Windows environment but still in COBOL using Microfocus (Eclipse, etc).
This is a pretty straight-forward task except for one little glitch.
The old application never did any explicit file handling within the COBOL. That is there are no FDs, OPENs, READs, WRITEs or CLOSE commands in the COBOL programs. Instead they wrote a C program that would do one of those different functions based on parameters passed to it (including, but not limited to file name, rec length, and the function desired.)
I would like to rewrite that subroutine in COBOL, which would require very little modifications to the COBOL main programs being converted. That is, it would still call that subroutine, but it would now be in COBOL instead of C.
But the challenge is how to write that subroutine so that it is able to act on most any file. I would think I have to go the route of variable length records because they could literally be any length up to to-be-determined maximum size, but seems like it would be vulnerable to error (as it tries to open different types of files).
Does anybody have any experience on this or ideas on a task like this? If not,l I may have to go the blunt force route of replacing each call statement to that subroutine with the specific COBOL command (Open, Read, etc) that needs to be performed and obviously FD and SELECT for every file would need to be added to the main program.
Thanks in advance.
You might be able to
CALL "subprogram" USING fd-name
where fd-name is
FD fd-name.
...
So, yes? maybe?, you might be able to pull off a subprogram that can take generic COBOL files. But, then you get into matching record layouts and other fun things, so, be wary. This might not work COBOL to COBOL, but it does work COBOL to C and back, as you end up passing a reference to the file control block.
You'll likely be better off looking into stock system libraries. Things like CBL_OPEN_FILE and CBL_READ_FILE if they are available. This will give you a much closer match to streaming IO that will be assumed in the current C subprogram.
Or, as Bill is suggesting in the comments, try and figure out why C was used and if you don't want the foreign functions, just dig in and write new COBOL procedures, as that will likely read better in the end.
I have a program that generates random pin codes. These pins are generated in Java, then stored in the mainframe, via a NATURAL program. From there, they are eventually physically printed by a batch JCL job that calls an MVS SCRIPT to print the form, with the pin code on it.
I've come across some issues with special characters before such as: |{}![]^~<>; that for one reason or another do not print properly. I've also removed 0OQ1l for OCR reasons.
Recently, an error came to my attention with another character that doesn't print properly, . but the . character only fails when it is the first character of the PIN Code.
So since I've run into this issue I thought I would see if I could find other special jcl, Natural or MVS Script characters that might interfere with my programs operation so that I can test them now and hopefully not run into this issue later or have to fallback to only using OCR'ed AlphaNumeric characters.
EDIT
Java - Web Application Runs Under Tomcat 6.x on a Solaris Server.
Natural - The Natural Program is called using webmethods Broker generated classes (POJOs).
My understanding is it uses RPC for actual communication.
The program verifies some data and stores the Pin in combination with a GUID on a record, in ADABAS.
There is a batch job that runs to print the forms. The Batch job is written in JCL.
My Understanding from the maintainer of the Batch Job, and the Forms stuff is the actual language to describe the forms themselves and how they get printed is an outdated/unsupported language called MVS SCRIPT.
the Bottom section of the script looks like this:
//**********************************************************************
//* PRINT SORTED FORMS TO #### USING MVS SCRIPT
//**********************************************************************
PRINTALL EXEC PGM=DSMSPEXEC,PARM='LIST'
//* less 'interesting' lines omitted
SYSPRINT DD SYSOUT=*
PRINT1 DD SYSOUT=A, OUTPUT=*.C####,
RECFM=VBM,LRECL=####,BLKSIZE=####
//* less 'interesting' lines omitted
//SYSIN DD *
AUTH /* redacted */
SCRIPT FROM(MYFORMS) (MESSAGE(ID TRACE) CONT -
FILE(PRINT1) PROFILE(redacted) -
NOSEGLIB DEVICE(PG4A) CHARS(X0A055BC))
.C#### is an actual number and is a variable that points to the chosen printer.
NOTE: I'm a Web Programmer, I don't speak mainframe, JCL, MVS, etc.
I think you will find the program (pgm=) is DSMSPEXC and not DSMSPEXEC.
I am guessing (could be wrong) we are talking about Script/DCF (which later became IBM Bookmaster / Bookmanager on other platforms).
Script/DCF is basically a GML based language. It was from GML that SGML was derived (HTML and XML are prominent examples of SGML languages).
In Script : starts a tag, . ends a tag. There are also macro's which have a . in column 1
.* ".*" in column 1 starts a line comment
.* .fo off is Format off (like <pre> in html)
.fo off
.* Starting an ordered list
:ol.
:li.Item in orded list
:eol.
i.e.
Script HTML
: < - Starts tag
. > - end of tag Script/DCF is generally pretty tolerant of .
& & - Starts a variable
There are variables (&gml. = :) for most of the special characters.
Characters to worry about are
: - always
& - always
. - in column one or after a :.
Other characters should be ok provided there are no translation errors. There charset X0A055BC (Mainframe SONORAN SANS SERIF ??) might not have all the special chars in it.
There are manuals around for Script/DCF tags.
Your data is not going to affect the JCL in any way.
I don't know about ADABAS or NATURAL. If you ask here, http://www.ibmmainframeforum.com/viewforum.php?f=25, specifically about that part, with as much detail as you can provide, there is a very expert guy, RDZbrog, who can probably answer that for you.
For the SCRIPT/VS itself, as Bruce Martin has pointed out, there may be some issues. With .xx and :xx there is not a clash with normal text. But you don't have normal text. With the &, which indicates a SCRIPT variable, it is more likely to be problematic and at any location.
I would fire some test data through: Your PINs with position one being all available punctuation preceding "fo" and "ol", and the same with those sequences "embedded" in your PINs. Also include a double & and a triple &.
Your query should be resolved in your specification. It is not, but I'm sure you'll get all the documentation updated when you get a resolution.
I am trying to print AFP to sysout but the FORMS parameter is not known (and cannot be known) by the JCL. My current solution is to create dynamic JCL and spin it to INTRDR, but this is a weak solution because the job will not be under the control of our scheduler... and thus, an abend or other issue will go unnoticed by night-time operators.
I started concocting a way to print the AFP via a COBOL program. I use BPXWDYN to create the SYSOUT DD dynamically, which allows me to set the FORMS parameter however I want. But the next step is dumping the AFP to that DD.
I thought I could call IEBGENER dynamically from my COBOL program, but that pulls a S0C4.
I can move the AFP records from one DD to the other in the COBOL program, but that limits me to one LRECL... and I have many different LRECL definitions for AFP throughout my system, and COBOL MUST know the LRECL at compile time.
Any thoughts? Is it possible to call IEBGENER dynamically and not get the S0C4? Any other ideas I haven't thought of?
Thanks in advance...
Have you thought of writing a small assembler program? You can specify the LRECL in your BPXWDYN call, and the DCB does not need to specify an LRECL; it will get it from the DCB parameters at OPEN time. A program to simulate IEBGENER is quite trivial.
Alternatively, look at calling SORT with a FIELDS=COPY parameter. SORT doesn't need the LRECL either. Or write a REXX script.
There are many ways of doing this; you just need to look outside the COBOL box.
Your question is not extremely clear but I'm wondering if you should consider using the ACIF utility program called APKACIF instead of IEBGENR. The utility will merge your data and resolve the AFP FORMDEF, PAGEDEF objects to a dataset or print stream.
I'm developing an application that parses Cobol programs. In these programs some respect the traditional coding style (programm text from column 8 to 72), and some are newer and don't follow this style.
In my application I need to determine the coding style in order to know if I should parse content after column 72.
I've been able to determine if the program start at column 1 or 8, but prog that start at column 1 can also follow the rule of comments after column 72.
So I'm trying to find rules that will allow me to determine if texts after column 72 are comments or valid code.
I've find some but it's hard to tell if it will work everytime :
dot after column 72, determine the end of sentence but I fear that dot can be in comments too
find the close character of a statement after column 72 : " ' ) }
look for char at columns 71 - 72 - 73, if there is not space then find the whole word, and check if it's a key word or a var. Problem, it can be a var from a COPY or a replacement etc...
I'd like to know what do you think of these rules and if you have any ideas to help me determine the coding style of a Cobol program.
I don't need an API or something just solid rules that I will be able to rely on.
I think you need to know the COBOL compiler for each program. Its documentation should tell you what conventions/configurations/switches it uses to decide if the source code ends at column 72 or not.
So.... which compiler(s)?
And if you think the column 72 issue is a pain, wait till you get around to actually parsing the COBOL itself. If you are not well prepared to handle the lexical issues of the language, you are probably very badly prepared to handle the syntactic ones.
There is no absolutely reliable way to determine if a COBOL program
is in fixed or free format based only on the source code. Heck it is sometimes difficult to identify
the programming language based only on source code. Check out
this classic polyglot - it is valid under 8 different language compilers. That
said, you could try a few heuristics that might yield
the correct answer more often than not.
Compiler directives imbedded in source code
Watch for certain compiler directives that determine code format.
Unfortunately, every compiler vendor uses their own flavour of directive.
For example, Microfocus COBOL uses the
SOURCEFORMAT directive. This directive will appear near the top of the program so a short pre-scan
could be used to find it. On the other hand, OpenCobol uses >>SOURCE FORMAT IS FREE and
>>SOURCE FORMAT IS FIXED to toggle between free and fixed format, different parts of the same program
could be formatted differently!
The bottom line here is that you will have to support the conventions of multiple COBOL compilers.
Compiler switches
Source code format can be also be specified using a compiler switch. In this case, there are no concrete
clues to go on. However, you can be reasonably sure that the entire source program will be either
fixed or free. All you can do here is guess. Unless the programmer is out to "mess with
your head" (and some will), a program in free format will have the keywords IDENTIFICATION DIVISION or ID DIVISION, starting before column 8.
Every COBOL program will begin with these keywords so you can use them as the anchor point for determining code format in the
absence of imbedded compiler directives.
Warning - this is far from fool proof, but might be a good start.
There won't be an algorithm to do this with 100% certainty, because if comments can be anything, they can also be compilable COBOL code. So you could theoretically write a program that means one thing if the comments are ignored, and something else entirely if the comments are treated as part of the COBOL.
But that's extremely unlikely. What's most likely to happen is that if you try to compile the code under the wrong convention, it will simply fail. So the only accurate way to do this is to try compiling/parsing the program one way, and if you come to a line that can't make sense, switch to the other style. You could also support passing an argument to the compiler when the style is already known.
You can try using heuristics like what you've described, but that will never be totally accurate. The most they can give you is a probability that the code is one or the other style, which will increase as they examine more and more lines of code. They could be useful for helping you guess the style before you start compiling, or for figuring out when the problem is really just a typo in the code.
EDIT:
Regarding ideas for heuristics, it's hard to say. If there were a standard comment sigil like // or # in other languages, this would be a lot easier (actually, there is, but it sounds like your code doesn't follow this convention). The only thing I can think of would be to check whether every line (or maybe 99% of lines, and not counting empty lines or lines commented with *) has a period somewhere before position 72.
One thing you DON'T want to do is apply any heuristics to the part after position 72. That is, you don't want to be checking the comments to see if they're valid COBOL. You want to check what you know is COBOL first, and see if that works by itself. There are several reasons for this:
Comments written in English are likely to have periods and quotes in them, so your first and second bullet points are out.
Natural languages are WAY harder to parse than something like COBOL.
The comments could easily have COBOL in them (maybe someone commented out the previous version of the line).
An important rule for comments is that they should never affect what the program does. If changing the comments can change how the program is compiled, you violate that.
All that in mind, my opinion is that you shouldn't use heuristics at all. You should always try to compile the program under both conventions unless one is explicitly specified. There's a chance that code will compile successfully under both conventions, and then you'll have two different programs and no way to tell which one is correct.
If that happens, you need to compare the two results (perhaps with a hash or something) to see if they're the same program. If they're the same, great, but if not, you'll need to force the user to explicitly choose a convention.
Most COBOL compilers will allow you to generate and analyze the post text manipulation phase.
The text preprocessor output can be seen (using OpenCOBOL for the example)
cobc -E program.cob
The text manipulation processor deals with any COPY ... REPLACING compiler directives, as well as converting SOURCE FORMAT IS FIXED (with line continuations, string literal concatenations, comment line removal, among other things) to the actual free format that the compiler lexical analyzer needs. A lot of the OpenCOBOL toolkits (Cross referencer and Animator, to name two) use source code AFTER the preprocessor pass. I don't think you'll lose any street cred if your parser program relies on post processed source code files.
Are there any conventions for formatting console output from a command line app for readability and consistency? For instance, do you indent sub-information, when do you print a blank line, if ever, how should you accent important statements.
I've found output can quickly degenerate into a chaotic blur. I'm interested in hearing about what other people do.
Update: Really this is for embedded software which spits debug status out a terminal, but it's pretty much like a console app, and I figured everyone would be more familiar with that. Thanks so far.
I'd differentiate two kinds of programs:
Do you print information that might be used by a script (i.e. it should be parseable)? Then define a pretty strict format and use only that (for example fixed field separators).
Do you print information that need not be parsed by a script (or is there an alternative script-parseable format already)? Then write what comes natural:
My suggestions:
write it so that you would like to read it
indent sub-information 2 or 4 spaces, definitely not more
separate blocks of information by one empty line at most
respect the COLUMN environment variable (and possible ROWS if it applies to your output).
If this is for a *nix environment, then I'd recommend reading Basics of Unix Philosophy. It's not specific to output but there are some good guidelines for command line programs in general.
Expect the output of every program to become the input to another, as yet unknown, program. Don't clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don't insist on interactive input.