Free-format prototype with variables already defined? - rpgle

I have an RPGLE program that I'm trying to convert from fixed-format to free-format. In general, I know that defining entry variables is done using prototypes like so:
dcl-pr myprogram;
I#Entry1 char(5);
end-pr;
dcl-pi myprogram;
InEntry1 char(5);
end-pi;
But what I don't know is how to do this when the field is already defined. We have a standard definitions file that we copy into programs such as the one I am writing, which has the field I'm using as the enter variable already defined and copied in. In fixed-format, this is just
C *Entry PList
C Parm InEntry1
I have already tried just doing the copy before the prototype entry and leaving the specification blank, but that caused errors. I know I could just use the 'LIKE' keyword and change the variable names, but for readability's sake I would prefer to avoid doing that, and I don't know what problems that may cause down the road.
Just in case it's necessary, there are two variables I'm trying to get in: a data structure and a zoned decimal.
How can I use a variable that is already defined as an entry variable in free-format RPGLE, whether using prototypes or some other way that I do not know of?

The "right" way to handle this would be to create a new version of your standard definitions file (StdDefs==>StdDefs2) to declare the variables under a new name (perhaps with a _t suffix) and the TEMPLATE keyword.
Then in your refactored PR/PI, you use LIKE or LIKEDS.
so your original program looks somthing like
/copy StdDefs
C *Entry PList
C Parm InEntry1
Your refactored one with PR/PI looks like
/copy StdDefs2
/copy Mypr
dcl-pi myprogram;
InEntry1 like(inEntry_t);
end-pi;
Note that best practice is to have the PR in a separate member that's /COPY'd into both caller and callee.

Could not find a solution without declaring another variable with like. And assign the new variable to the old at the begenning of the program, and vice versa at the end.

Related

How can I correctly create a new variable in vvar.h for my new VSDO func?

I am trying to declare a new variable in vvar.h and define it near my new VDSO function. So that I could use this variable in my vdso function.
I have a question about VVar. According to the description in arch/x86/include/asm/vvar.h, when I declare here a new variable as DECLARE_VVAR(0, int, count), I should use DEFINE_VVAR(type, name) to define this variable somewhere else.
The problem is after I defined this variable somewhere else, like DEFINE_VVAR(int, count), when I am trying to assign an integer value to this variable count, it is failed. This is because after kernel version 5.2 #define DEFINE_VVAR(type, name) has been changed from #define DEFINE_VVAR(type, name) type name to #define DEFINE_VVAR(type, name) type name[CS_BASES]. Right now this variable count is an integer array instead of type integer. Therefore I can't assign a integer value to it. Do you know how to fix it?
VVAR.h: https://elixir.bootlin.com/linux/v5.12/source/arch/x86/include/asm/vvar.h#L43
Typically, you cannot add a variable simply through DECLARE_VVAR macro.
The first thing you have to be aware of is that .vvar is a page of memory located inside the memory (more specifically, before .vdso) and could access by both kernel and userland. You can see this inside the linker script https://elixir.bootlin.com/linux/latest/source/arch/x86/entry/vdso/vdso-layout.lds.S. For now, kernel already has a data structure `struct video to format the data inside this page.
Second, assume you want to add a variable inside the .vvar page and access it in your new vdso function, the easiest way is to add it inside the sturct vdso structure of include/vdso/datapage.h: https://elixir.bootlin.com/linux/latest/source/include/vdso/datapage.h. After that, you can update them inside the kernel (for example, in schedule) in the same way as other vvar variables.
Second, if you want to own your own vvar page, you have to define your own vvar data structure inside the datapage.h and do not forget DEFINE_VVAR in vsyscall.h: https://elixir.bootlin.com/linux/latest/source/arch/x86/include/asm/vdso/vsyscall.h ALso, since the vvar memory layout is compact, you also need to allocate another page through linker script: https://elixir.bootlin.com/linux/latest/source/arch/x86/entry/vdso/vdso-layout.lds.S by change vvar_start = . - 4 * PAGE_SIZE; into vvar_start = . - 5 * PAGE_SIZE;

How do I print a value in an array in DDS

I know this question isn't directly RPG language oriented, but I have no idea where I would turn otherwise.
I've created a PRTF in RDi for my project in class. I've set up several arrays in the RPGLE file to hold some numbers and several more like this example.
Dcl-s Freshman Packed(5:0) Dim(4);
How do I specify that I want to print Freshman(2) in my PRTF?
I have tried things similar to these in the Functions section: Freshman(1), REFFLD(Freshman(1)), REFFLD(Freshman/1)
A DDS based object (PRTF/DSPF/PF/LF) can only use a database file as a reference.
Otherwise, you need to define the field explicitly in the PRTF.
A FRSHMAN 5S 0 182
Now your RPG program could use the DDS defined field as a reference...
Dcl-s Freshman like(frshman) Dim(4);
or you could leave it explicitly defined as originally posted.
Either way, you'd need to manually move the data in your RPG program.
frshman = Freshman(1);

squeak(smalltallk) how to 'inject' string into string

I'm writing a class named "MyObject".
one of the class methods is:
addTo: aCodeString assertType: aTypeCollection
when the method is called with aCodeString, I want to add (in runtime) a new method to "MyObject" class which aCodeString is it's source code and inject type checking code into the source code.
for example, if I call addTo: assertType: like that:
a := MyObject new.
a addTo: 'foo: a boo:b baz: c
^(a*b+c)'
assertType: #(SmallInteger SmallInteger SmallInteger).
I expect that I could write later:
answer := (a foo: 2 boo: 5 baz: 10).
and get 20 in answer.
and if I write:
a foo: 'someString' boo: 5 baz: 10.
I get the proper message because 'someString' is not a SmallInteger.
I know how to write the type checking code, and I know that to add the method to the class in runtime I can use 'compile' method from Behavior class.
the problem is that I want to add the type checking code inside the source code.
I'm not really familiar with all of squeak classes so I'm not sure if I rather edit the aCodeString as a string inside addTo: assertType: and then use compile: (and I don't know how to do so), or that there is a way to inject code to an existing method in Behavior class or other squeak class.
so basically, what I'm asking is how can I inject string into an existing string or to inject code into an existing method.
There are many ways you could achieve such type checking...
The one you propose is to modify the source code (a String) so as to insert additional pre-condition type checks.
The key point with this approach is that you will have to insert the type checking at the right place. That means somehow parsing the original source (or at least the selector and arguments) so as to find its exact span (and the argument names).
See method initPattern:return: in Parser and its senders. You will find quite low level (not most beautiful) code that feed the block (passed thru return: keyword) with sap an Array of 3 objects: the method selector, the method arguments and the method precedence (a code telling if the method is connected to unary, binary or keyword message). From there, you'll get enough material for achieving source code manipulation (insert a string into another with copyReplace:from:to:with:).
Do not hesitate to write small snippets of code and execute in the Debugger (select code to debug, then use debug it menu or ALT+Shift+D). Also use the inspectors extensively to gain more insight on how things work!
Another solution is to parse the whole Abstract Syntax Tree (AST) of the source code, and manipulate that AST to insert the type checks. Normally, the Parser builds the AST, so observe how it works. From the modified AST, you can then generate new CompiledMethod (the bytecode instructions) and install it in methodDictionary - see the source code of compile: and follow the message sent until you discover generateMethodFromNode:trailer:. This is a bit more involved, and has a bad side effect that the source code is now not in phase with generated code, which might become a problem once you want to debug the method (fortunately, Squeak can used decompiled code in place of source code!).
Last, you can also arrange to have an alternate compiler and parser for some of your classes (see compilerClass and/or parserClass). The alternate TypeHintParser would accept modified syntax with the type hints in source code (once upon a time, it was implemented with type hints following the args inside angle brackets foo: x <Integer> bar: y <Number>). And the alternate TypeHintCompiler would arrange to compile preconditions automatically given those type hints. Since you will then be very advanced in Squeak, you will also create special mapping between source code index and bytecodes so as to have sane debugger and even special Decompiler class that could recognize the precondition type checks and transform them back to type hints just in case.
My advice would be to start with the first approach that you are proposing.
EDIT
I forgot to say, there is yet another way, but it is currently available in Pharo rather than Squeak: Pharo compiler (named OpalCompiler) does reify the bytecode instructions as objects (class names beginning with IR) in the generation phase. So it is also possible to directly manipulate the bytecode instructions by proper hacking at this stage... I'm pretty sure that we can find examples of usage. Probably the most advanced technic.

expression engine dynamic variable names: {slide_{index}_title}

I am using a simple looping plugin so that my template looks like this:
{exp:loop_plus start="1" end="4" increment="1"}
<h3>{slide_{index}_title}</h3>
{/exp:loop_plus}
However, I am ending up with the following output:
<h3>{slide_1_title}</h3>
<h3>{slide_2_title}</h3>
<h3>{slide_3_title}</h3>
<h3>{slide_4_title}</h3>
Is there any way I can have dynamic variable names like this? I am not looking for alternative methods for building a slider, I simply would like to know if the dynamic variable names like this is possible. Thanks!
I'm assuming that Loop Plus (http://devot-ee.com/add-ons/loop-plus) sets the {index} part, so the question is what is defining {slide_1_title}...?
Assuming you have an entry field or variable with this defined, what you have is correct, but if it's not working, it means there's a parsing order issue.
Let's assume the code you supplied is wrapped in a {exp:channel:entries} tag pair, what happens is EE will try to parse the variable first, so will see: {slide_{index}_title} which doesn't exist. The {exp:loop_plus} add-on will then parse it, converting it to {slide_1_title} (but to late as channel:entries has already tried to parse it), which is what is finally output to the template.
So what you want to ensure is that EE parses {exp:loop_plus} before {exp:channel:entries}, do this using parse="inward" tag:
{exp:loop_plus start="1" end="4" increment="1" parse="inward"}
<h3>{slide_{index}_title}</h3>
{/exp:loop_plus}
This is a global EE parameter that EE uses to control parse order - you won't find it documented under the specific add-on. By adding the parameter, it means this child tag will get parsed before it's parent.
One way you could do it is to declare a preload_replace variable in your template and use it in your custom field name.
So something like:
{preload_replace:my_var_prefix="whatever"}
And then in your loop, you could then use:
{slide_{my_var_prefix}_title}

How to get the filename and line number of a particular JetBrains.ReSharper.Psi.IDeclaredElement?

I want to write a test framework extension for resharper. The docs for this are here: http://confluence.jetbrains.net/display/ReSharper/Test+Framework+Support
One aspect of this is indicating if a particular piece of code is part of a test. The piece of code is represented as a IDeclaredElement.
Is it possible to get the filename and line number of a piece of code represented by a particular IDeclaredElement?
Following up to the response below:
#Evgeny, thanks for the answer, I wonder if you can clarify one point for me.
Suppose the user has this test open in visual studio: https://github.com/fschwiet/DreamNJasmine/blob/master/NJasmine.Tests/SampleTest.cs
Suppose the user right clicks on line 48, the "player.Resume()" expression.
Will the IDeclaredElement tell me specifically they want to run at line 48? Or is it going to give me a IDeclaredElement corresponding to the entire class, and a filename/line number range for the entire class?
I should play with this myself, but I appreciate tapping into what you already know.
Yes.
The "IDeclaredElement" entity is the code symbol (class, method, variable, etc.). It could be loaded from assembly metadata, it could be declared in source code, it could come from source code implicitly.
You can use
var declarations = declaredElement.GetDeclarations()
to get all AST elements which declares it (this could return multiple declarations for partial class, for example)
Then, for any IDeclaration, you can use
var documentRange = declaration.GetDocumentRange()
if (documentRange.IsValid())
Console.WriteLine ("File: {0} Line:{1}",
DocumentManager.GetInstance(declaration.GetSolution()).GetProjectFile(documentRange.Document).Name,
documentRange.Document.GetCoordsByOffset(documentRange.TextRange.StartOffset).Line
);
By the way, which test framework extension are you developing?
Will the IDeclaredElement tell me specifically they want to run at
line 48?
Once more: IDeclaredElement has no positions in the file. Instead, it's declaration have them.
For every declaration (IDeclaration is a regular AST node) there is range in document which covers it. In my previous example, I used TextRange.StartOffset, though you can use TextRange.EndOffset.
If you need more prcise position in the file, please traverse AST tree, and check the coordinates in the document for specific expression/statement

Resources