difference between RPG copybook and program - rpgle

Could you give me some idea as to looking at file how can I differentiate between RPG copybook and program?
For example, in c, if you have main in the file, you know that it can be used as program.
Thanks in advance.

That's an interesting question...it is usually pretty obvious.
I suppose the quick answer is that copy books won't contain different types of specifications. An RPG IV program can have H, F, D, I, C, O, and P specifications , or their free-form equivalents. (The specification type is determined by the letter in column 6 of fixed format source). The order is important and you can't intermix the types. If you're looking at source that has only one type of specifications, it's probably designed as a copybook. Since the executable code is contained in C (Calculation) and/or P (Procedure) specs, a source without any C or P specs is a copybook. While it's usually bad practice to have C or P Specs in a copybook, RPG does allow it and I've seen it done. But again, the only thing in the copy book would be C or P specs.
EDIT You could have a copybook with for instance F & D specs, but the only place it could be included is at the end of a program's F specs prior to any D specs. You could have a copybook that makes use of compiler directives /IF DEFINED to control what part of the copybook is included where.
EDIT2 Turns out IBM added the ability to intermix F & D specs in version 7.1 and higher. A source member with just F & D specs would be a copybook So the short answer becomes, a source member with both definition (H, F, D, I, O) specs and executable (C & P) specs is designed to be compiled.
The longer answer, an RPG program also has a "main". Originally, the only option was what's known now as "cycle-main". IE. the "main" procedure is the implicitly generated "cycle" code that is built into RPG programs.
Then along came RPG IV and ILE. IBM added a control specification keyword, NOMAIN.
H NOMAIN
//or in freeform
ctl-opt nomain;
This resulted in a non-executable module without a "main" procedure; the code normally generated by the compiler for the "cycle" is left out. The resulting *MODULE object would need to be bound into a *PGM object with another *MODULE that provide a main procedure.
Or it could be bound with zero or more other *MODULE objects into a *SRVPGM object; *SRVPGM are just collections of procedures. Think of them like Windows DLLs.
Then IBM added the option of having a "linear-main" RPG IV program.
H MAIN(MYMAIN)
// or freeform
ctl-opt main(MYMAIN);
Thus the main procedure is whichever procedure you designate. The generated "cycle" code is again left out of the executable.
So the existence of either the NOMAIN or MAIN keywords would indicate that a source member is designed to be compiled; assuming there's more too the source. It's possible there's a "standard options" include file that would include one of those.
The lack of those two keywords would indicate you're dealing with either a cycle main or an include file.
If it's a cycle main program and it takes parameters as input, you'll be able to see the entry parameter list
//Fixed format, old school RPG III, IV
C *ENTRY PLIST
C PARM LCMPNO 2
C PARM LNTACT 1
// fixed format, RPG IV using a "Procedure Interface (PI) to replace *ENTRY PLIST
D CheckDate PI
D lDateIs 4a
// free format RPG IV
dcl-pi CheckDate;
lDateIs char(4);
end-pi;
Note that a key difference in the source between a "cycle-main" program that uses the PI instead of *ENTRY PLIST and a linear main is that a linear main procedure is surrounded by an explicit procedure definition.
// linear main
h main(CHECKDATE)
p CheckDate b
d CheckDate PI
d lDateIs 4a
//do something
*INLR = *ON
return;
p CheckDate e
//cycle main with PI
d lDateIs 4a
//do something
*INLR = *ON
return;

Starting in 7.1 (with the free-form PTFs from 2013), you can mix F and D specs (even in fixed form code).

rpg copy book is pretty close to imports in modern programing languages

A copy book should be used more like a header file in C or C++. Unfortunately it will not have that helpful .h extender to keep things separate. Shop standards can be helpful here. You can keep copybooks in a separate source file or even name them with a specific prefix or suffix to indicate that it is a copybook. I have seen suffixes like _ or _h used on copybooks where the base name is the same as the source member that it is acting as a header file for. Or in the case that copybooks and program source are stored in different source files, a program and it's header file would have the same name.
Like C, RPG4 can have source files that can be compiled into programs and source files that can be compiled into modules (a module is an IBM i term, much like a the unlinked .obj file generated by a C compiler on other platforms) or programs which are fully linked executables. In order for an RPG source to be compiled to a fully linked executable it needs a main procedure. Charles explained the main and nomain keywords for h specs. If the program source doesn't have the nomain keyword, it can be generated as a fully linked program. Be careful though, even though it isn't common, the h specs can be somewhere else, like in their own copybook, or in a dataarea.

Related

Switch Case Conditional output in Latex

I want to write a report which has a structure like this:
\begin{document}
\input[option=a]{class}
\input[option=b]{class}
\input[option=c]{class}
\input[option=d]{class}
\end{document}
class.tex has content like this:
here are some shared content
switch(option)
case a
some text a
case b
some text b
case c
some text c
case d
some text d
endswitch
Here maybe more shared content.
Is there any way to do this in Latex?
A simplified way of doing this could be with logic statements using if else fi logic
at the top of the .tex file set up a switch with
\newif\ifswitch
The default value will be false. To set the value to be true use
\switchtrue
Then in the text of the document use
\ifswitch
<<text to include if switch is true>>
\else
<<text to include if switch is false>>
\fi % ends the if statement
So for your particular question you could have a set of switches
\newifConditionA
\newifConditionB
\newifConditionC
\newifConditionD
This is not as elegant as using a switch statement, but allows conditions where you want text from A and C at the same time for example.
Reference where this is discussed is here for
two versions of a document with 'if else' logic statements
You can use the following (crude) method of identifying the textual components between which you want to extract stuff from a file:
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{class.tex}
switch(option)
case a
some text a
case b
some text b
case c
some text c
case d
some text d
endswitch
\end{filecontents*}
\usepackage{catchfile}
% \inputclass{<file>}{<from>}{<to>}
\newcommand{\inputclass}[2]{%
\CatchFileDef{\class}{class.tex}{}%
\long\def\classsegment##1#1 ##2 #2##3\relax{##2}%
\show\classsegment
\expandafter\classsegment\class\relax
}
\begin{document}
\inputclass{case c}{case d}
\inputclass{case a}{case b}
\inputclass{case d}{endswitch}
\inputclass{case b}{case c}
\end{document}
Related:
How to extract information between two unique words in a large text file
How to extract data between two different xml tags
\input only part of a file
The last one is a more adaptable approach using the catchfilebetweentags package. This requires the insertion of appropriate tags within your code, which might not be as helpful. You could also use listings to include specific lines of code from an external file.
As I understand it, what you want is to update the function for each different part of the text, while defining the function in just one place.
The easy way to do this is to renew a variable command at the start of each section.
At start:
\newcommand{\VARIABLENAME}{VARIABLE_1}
At section:
\renewcommand{\VARIABLENAME}{VARIABLE_2}
There are more advanced ways of doing this as well, involving defining variables but for all it is worth, this is more readable and simpler to implement.
Note: If you are planning to make something more dynamic then just a class, I recommend implementing something in another language such as python to write the file in LaTex as it usually gives a lot more room for modification.

Is it possible / easy to include some mruby in a nim application?

I'm currently trying to learn Nim (it's going slowly - can't devote much time to it). On the other hand, in the interests of getting some working code, I'd like to prototype out sections of a Nim app I'm working on in ruby.
Since mruby allows embedding a ruby subset in a C app, and since nim allows compiling arbitrary C code into functions, it feels like this should be relatively straightforward. Has anybody done this?
I'm particularly looking for ways of using Nim's funky macro features to break out into inline ruby code. I'm going to try myself, but I figure someone is bound to have tried it and /or come up with more elegant solutions than I can in my current state of learning :)
https://github.com/micklat/NimBorg
This is a project with a somewhat similar goal. It targets python and lua at the moment, but using the same techniques to interface with Ruby shouldn't be too hard.
There are several features in Nim that help in interfacing with a foreign language in a fluent way:
1) Calling Ruby from Nim using Nim's dot operators
These are a bit like method_missing in Ruby.
You can define a type like RubyValue in Nim, which will have dot operators that will translate any expression like foo.bar or foo.bar(baz) to the appropriate Ruby method call. The arguments can be passed to a generic function like toRubyValue that can be overloaded for various Nim and C types to automatically convert them to the right Ruby type.
2) Calling Nim from Ruby
In most scripting languages, there is a way to register a foreign type, often described in a particular data structure that has to be populated once per exported type. You can use a bit of generic programming and Nim's .global. vars to automatically create and cache the required data structure for each type that was passed to Ruby through the dot operators. There will be a generic proc like getRubyTypeDesc(T: typedesc) that may rely on typeinfo, typetraits or some overloaded procs supplied by user, defining what has to be exported for the type.
Now, if you really want to rely on mruby (because you have experience with it for example), you can look into using the .emit. pragma to directly output pieces of mruby code. You can then ask the Nim compiler to generate only source code, which you will compile in a second step or you can just change the compiler executable, which Nim will call when compiling the project (this is explained in the same section linked above).
Here's what I've discovered so far.
Fetching the return value from an mruby execution is not as easy as I thought. That said, after much trial and error, this is the simplest way I've found to get some mruby code to execute:
const mrb_cc_flags = "-v -I/mruby_1.2.0_path/include/ -L/mruby_1.2.0_path/build/host/lib/"
const mrb_linker_flags = "-v"
const mrb_obj = "/mruby_1.2.0_path/build/host/lib/libmruby.a"
{. passC: mrb_cc_flags, passL: mrb_linker_flags, link: mrb_obj .}
{.emit: """
#include <mruby.h>
#include <mruby/string.h>
""".}
proc ruby_raw(str:cstring):cstring =
{.emit: """
mrb_state *mrb = mrb_open();
if (!mrb) { printf("ERROR: couldn't init mruby\n"); exit(0); }
mrb_load_string(mrb, `str`);
`result` = mrb_str_to_cstr(mrb, mrb_funcall(mrb, mrb_top_self(mrb), "test_func", 0));
mrb_close(mrb);
""".}
proc ruby*(str:string):string =
echo ruby_raw("def test_func\n" & str & "\nend")
"done"
let resp = ruby """
puts 'this was a puts from within ruby'
"this is the response"
"""
echo(resp)
I'm pretty sure that you should be able to omit some of the compiler flags at the start of the file in a well configured environment, e.g. by setting LD_LIBRARY_PATH correctly (not least because that would make the code more portable)
Some of the issues I've encountered so far:
I'm forced to use mrb_funcall because, for some reason, clang seems to think that the mrb_load_string function returns an int, despite all the c code I can find and the documentation and several people online saying otherwise:
error: initializing 'mrb_value' (aka 'struct mrb_value') with an expression of incompatible type 'int'
mrb_value mrb_out = mrb_load_string(mrb, str);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~
The mruby/string.h header is needed for mrb_str_to_cstr, otherwise you get a segfault. RSTRING_PTR seems to work fine also (which at least gives a sensible error without string.h), but if you write it as a one-liner as above, it will execute the function twice.
I'm going to keep going, write some slightly more idiomatic nim, but this has done what I needed for now.

Why do I have to specify an ExtPgm parameter for the Main Procedure?

My program, PKGDAYMONR has the control option:
ctl-opt Main( CheckDailyPackages )
The CheckDailyPackages procedure has the following PI:
dcl-pi *n ExtPgm( 'PGMNAME' );
As you can see the ExtPgm parameter is not the name of the program. In fact, it’s what came over in the template source and I forgot to change it. Despite the wrong name in ExtPgm, the program runs without a problem.
If I remove that parameter and leave the keyword as just ExtPgm, I get the following message:
RNF3573: A parameter is required for the EXTPGM keyword when the
procedure name is longer than 10.
If I drop ExtPgm from the Procedure Interface altogether, it also complains:
RNF3834: EXTPGM must be specified on the prototype for the MAIN()
procedure.
So why is it that I have to specify a parameter if it doesn't matter what value I enter?
O/S level: IBM i 7.2
Probably worth pursuing as a defect with the service provider; presumably for most, that would be IBM rather than a third-party, as they would have to contact IBM anyhow, given the perceived issue is clearly with their compiler. Beyond that, as my "Answer", I offer some thoughts:
IMO, and in apparent agreement with the OP, naming the ExtPgm seems pointless in the given scenario. I think the compiler is confused while trying to enforce some requirements in validations of the implicitly generated Prototype for the linear-main for which only a Procedure Interface is supplied; i.e. enforcing requirements that are appropriate for an explicit Prototype, but requirements that could be overlooked [thus are no longer requirements] in the given scenario.? I am suggesting that while the RNF3573 would seem appropriate for diagnosing EXTPGM specifications of an explicit Prototype, IMO that same effect is inappropriate [i.e. the validation should not be performed] for an implicit prototype that was generated by the compiler.
FWiW: Was the fixed-format equivalent of that free-form code tested, to see if the same or a different error was the effect? The following source code currently includes the EXTPGM specification with 'PGMNAME' as the argument [i.e. supplying any bogus value of 10-byte naming to supplicate the compiler, just as is being done in the scenario of the OP, solely to effect a successful compile], but could be compiled with the other variations with changes to the source, mimicking what was done with free-form variations, to test if the same\consistent validations and errors are the effect:
- just EXTPGM keyword coded (w/out argument); is RNF3573 the effect?
- the EXTPGM keyword could be omitted; is RNF3834 the effect?
- the D-spec removed entirely (if there are no parameters defined); ¿that was not one of the variations noted in the OP as being tried, so... the effect?
H MAIN(CheckDailyPackages)
*--------------------------------------------------
* Program name: CheckDailyPackages (PGMNAME)
*--------------------------------------------------
P CheckDailyPackages...
P B
D PI EXTPGM('PGMNAME')
/free
// Work is done here
/end-free
P CheckDailyPackages...
P E
I got a response from IBM and essentially Biswa was on to something, it simply wasn't clear (in my opinion) about the answer.
Essentially the EXTPGM is required on long Main procedure names in order to support recursive program calls.
This is the response I received from IBM explaining the reason for the scenario:
The incorrect EXTPGM would only matter if there was a call to the main
procedure (the program) within the module.
When the compiler processes the procedure interface, it doesn't know
whether there might be a call that appears later in the module.
EXTPGM keyword is used to define the external name of the program which you want to prototype. If you mention the EXTPGM then the program will be called dynamically.
Let us take an example in order to explain your query.
PGMA
D cmdExc PR ExtPgm('QSYS/QCMDEXC')
D 200A const
D 15P05 const
c callp cmdExc('CLRPFM LIB1/PF1':200)
C Eval *INLR = *ON
In the above example CmdExc used for the dynamic call to QSYS/QCMDEXC.
When we use the same program name as the EXTPGM parameter it acts as an entry point to the program when called from other programs or procedure.
But in any case when we mention any name as the sample parameter the EXTPGM will not give any error in compilation, but it gives the error during run time as it tries to resolve the name during run time.

How to duplicate a RuleContext

Is there any way to duplicate a ParserRule? I need a real deep copy, so copyFrom() doesn't do the trick. Or must I re-parse the code?
An alternative idea how to solve the following would also be much appreciated:
I am working on a compiler, translating old legacy code to modern programming languages, in this case EGL -> Java.
EGL has a concept called Standalone Function, which are similar to C-macros. This means that code inside the functions can reference symbols in the calling scope. So both defining and resolving of symbols and type promotion are context-dependent.
In ANTLR3, we solved this by dupTree(), and simply made a copy to work on in each calling scope.
Dynamic types is not an option.
Example (pseudo code) to illustrate:
Program A
int var = 4;
saf(); # Prints 5
end A;
Program B
String var = "abc";
saf(); # Prints abc1
end B;
function saf()
int j = 1;
print(var + j);
end saf;
As of version 4.2, ANTLR 4 does not include any API for manipulating the structure of a parse tree after the parse is complete. This is an area we are currently exploring, especially considering the possibilities created by the new pattern matching syntax.
For duplicating trees, I recommend you implement the visitor interface created when you generated your parser. This will allow you to call visit on any node in your parse tree to create a deep copy of that node.

Use Alex macros from another file

Is there any way to have an Alex macro defined in one source file and used in other source files? In my case, I have definitions for $LowerCaseLetter and $UpperCaseLetter (these are all letters except e and O, since they have special roles in my code). How can I refer to these macros from other .x files?
Disproving something exists is always harder than finding something that does exist, but I think the info below does show that Alex can only get macro definitions from the .x file it is reading (other than predefinied stuff like $white), and not via includes from other files....
You can get the sourcecode for Alex by doing the following:
> cabal unpack alex
> cd alex-3.1.3
In src/Main.hs, predefined macros are first set in variables called initSetEnv (charset macros $white, $printable, and "."), and initREEnv (regexp macros, there are none). This gets passed into runP, in src/ParseMonad.hs, which is used to hold the current parsing state, including all defined macros. The initial state is set using the values passed in, but macros can be added using a function called newSMac (or newRMac for regular expression macros).
Since this seems to be the only way that macros can be set, it is then only a matter of some grep bookkeeping to verify the only ways that macros can be added is through an actual macro definition in the source .x file. Unsurprisingly, Alex recursively uses its own .x/.y files for .x source file parsing (src/parser.y, src/Scan.x). It is a couple of levels of indirection away, but you can verify that the only way newSMac can be called is through the src/Scan.x macro
#smac = \$ #id | \$ \{ #id \}
<0> #smac #ws? \= { smacdef }
Other than some obvious predefined stuff, I don't believe reuse in lexers is all that typical anyway, because at the token level things are usually pretty simple (often simple tokens like SPACE, WORD, NUMBER, and a few operators, symbols and parens are all that are needed). The complexity comes at the parsing stage, although for technical reasons, parser-includes aren't that common either (see scannerless parsing for a newer technology that does allow reuse through nesting, like javascript embedded in html.... The tools for scannerless parsing are still pretty primitive though).

Resources