|
Post by Stefan on Mar 25, 2022 10:43:09 GMT -5
George,
I'm on the 22082 beta version, but I reckon this applies to others too.
I was looking to fix an issue with the capture of pending line commands in my LP macro. I realised that Get_Src_LCmd$ does NOT capture the entire line command.
For instance, if the user enters C99, Get_Src_LCmd$ will return C, not C99. A quick peek in the doc reveals I need to call Get_Src_Op as well to capture the 99.
Problem (1) Get_Src_Op always returns 0. Problem (2) Get_Src_LMod$ always returns 2 blanks. (But I can't remember what the +,- and K indicators do, so this may be working as designed)
Problem (3) Get_Src2_LPtr is not 'adjusted' according to the range the user enters via an OP value or a MOD$ setting, eg:
- a specification like C\ on line 10 does indeed set Get_Src1_LPtr to 2 (ie. first data line) but also sets the value of Get_Src2_LPtr to 2 when it should be 10 (the line where the command was entered) - a specification like C/ on line 10 does indeed set Get_Src1_LPtr to 10 (ie. line where command was entered) but also sets Get_Src2_LPtr to 10, when it should be the number of the last line in the file.
The related Get_Dest_xxxx function appear similarly afflicted, but at least in Get_Dest_Op appears to work in that it returns 4 when 'A4' was specified.
I cannot tell from the HELP document if a block line CC...CC should also 'adjust' the Get_Src2_LPtr to reflect the range, but it does not do so.
Here's a simple bit of code to save you some typing if you wish to experiment SPF_DEBUG("SRCE Lcmd=["+Get_Src_LCmd$+"] Op=["+Get_Src_Op+"] LMod=["+Get_Src_LMod$+"] LPrt1=["+Get_Src1_LPtr+"] LPtr2=["+Get_Src1_LPtr+"]") SPF_DEBUG("DEST Lcmd=["+Get_Dest_LCmd$+"] Op=["+Get_Dest_Op+"] LMod=["+Get_Dest_LMod$+"] LPtr1=["+Get_Dest1_LPtr+"] LPtr2=["+Get_Dest1_LPtr+"]") HALT
In general, I find it confusing that for C\ or C/, the Help Document says the returned line pointers should be 'adjusted' to reflect the line range. Why wouldn't the same apply to a block command like CC...CC or AA...AA, or a command like C99 for A25 for that matter?
|
|
|
Post by George on Mar 25, 2022 13:36:41 GMT -5
Stefan: a) your sample code gets SRC1_LPtr and Dest1_LPtr twice instead of SRC1/SRC2 and Dest1/Dest2, this confuses things.
b) Get_Src_Op is poorly named, it doesn't really get the raw operand, it gets the effective REPEAT value.
c) For the / and \ operands it doesn't say the pointers should be adjusted, but they "are processed, if present, and this gets reflected in first and last LPTR values for the line range" i.e. the SRC1/SRC2 values are already adjusted.
Yes, poorly described, but it takes an advanced macro writer to even attempt to use these. I guess our hope was that such a person would soon "figure it out". Yes, the lazy documentor's excuse.
George
|
|
|
Post by Stefan on Mar 25, 2022 14:36:37 GMT -5
How embarrassing. Too much cut and paste without due diligence. Apologies for the mess-up with the ...Src2_LPtr, etc.
"...such a person might have figured it out" if he hadn't been too careless to type in the correct variables.
Thanks for straightening me out.
By the way... if I can get my act together, you will like the the next version of the LP macro
With the right KEYMAP definition, you should be able to right-click on a routine call, jump to that routine's definition, look up or modify whatever you need and then jump back to the line with the routine call. Just need to figure out the neatest way to bookmark across separate LP invocations.
|
|
|
Post by George on Mar 25, 2022 15:45:07 GMT -5
LP is getting pretty cool. I look forward to the new version.
George
|
|
|
Post by Stefan on Mar 26, 2022 9:09:56 GMT -5
George,
I believe there's an issue with the Get_Src_Op
Get_SRC_OP returns inconsistent values.
Line command Get_Src_Op good or bad?
============ ========== ============
C 0 < debatable - see below
C1 1 < OK
C<othnums> 0 < oops
CC 0 < debatable
CC1 1 < OK
CC<othnums> <othnums> < OK
Enter a line command like C5, and observe that...
Get_Src1_LPtr returns the line on which the command was entered < OK
Get_Src2_LPtr returns a value equal to Get_Src1_LPtr + (5 - 1) < OK
Get_Src_LCmd$ returns C < arguably should be C5 as that was the command
Get_Src_OP returns 0 < debatable
Do the same thing with a line command like CC5.
Now Get_Src_Op returns 5 and the LPTR variables define the range according to where the other CC terminates the block CC...CC command. Similarly for the Get_Dest_Op.
Hence the Get_..._OP function is not related to the range of lines in the operation. It is a do-it count ie. how many times the command should be executed. (CC5...CC will copy the lines in the CC..CC block to the target location 5 times.)
Now in the original case (our C5 command) the 5 is not a do-it count, it defines the range (C5 copies the 5 lines starting from here, once). This might explain why Get_Src_OP does not return the value 5, but I believe the value 0 is also incorrect.
I draw two conclusions from these observations:
(1) A Get_..._OP value of 0 is invalid because the (e.g.) COPY takes place at least once. Thus the do-it count must be at least 1 for consistency. (2) There is no way to capture a line command like 'C5' inside a macro, at least, not without longwinded checking of the other variables to deduce what's going on.
By the eway, I believe the above means that the lcRV.macro in the SAMPLES may also be incorrect.
Incidentally... It wasn't until the end of playing with this that I noticed that I was using a macro called IT.MACRO. I do NOT have a SET PENDING.IT=Y variable definition, yet the IT macro was allowed to execute without that setting while line commands were pending.
This is in the 22082 beta version.
Did your recent modification to fix this get dropped out of this beta by mistake?
|
|
|
Post by George on Mar 26, 2022 9:38:58 GMT -5
Stefan: Just as the Doc says that / and \ are processed and the result is in the Src1 and Src2 values, so it is with ANY of the line operands that define the line range.
The badly named Get...OP (should be Repeat) is only non-zero when there IS an operand which is a Repeat value.
So should C3 -> A have a Repeat value of 1? That's a 'maybe', but the macros pick up internal working variables, so I'm not inclined to alter those. I guess you can always just treat 0 as a 1. Besides, if you're replacing line commands, you only need to replace the repeat value if it was originally coded, in which case ...OP is valid.
As far as getting the RAW line input, it no longer exists at macro time, it's been parsed away. If you're restoring line commands, why not just restore a set that does the same thing. e.g. C5 -> A would become CC/CC -> A
BTW, there is no LCRV.MACRO in the distribution, just an RV.MACRO.
Re: the SET PENDING - were the commands really Pending, or were they a complete set (which is not a Pending).
George
|
|
|
Post by Stefan on Mar 26, 2022 11:58:39 GMT -5
I guess that depends on what counts as a "complete set". I might be mistaken about how this is meant to work.
In the normal run of play (ie without macros) a block like a "CC...CC sequence", or a single "Cx" command, is not considered a complete sequence without a target definition. Similarly, a target line command without a 'source' definition is considered incomplete. In these cases, some version of the 'line command pending' message appears and most primary commands are refused (unless it's a 'positioning' command like FIND, LOCATE, scrolling, RESET, etc) And this normally also applies to primary command macros.
If a "complete set" is entered, the line command set would be executed BEFORE the command entered on the primary command line.
If a macro wishes to 'process' or simply ignore and then re-instate line commands before finishing, it must be allowed to execute even though the line commands entered are an incomplete set. I thought that the SET PENDING.xxx=Y construct was there to specifically permit the named command to execute under these circumstance.
The SET PENDING implementation in v22082 beta appears to have no influence on the question whether a macro can run or not, when line commands are "pending". With or without a SET PENDING, my macros run.
PS: And you're quite right. I meant the RV.MACRO. I gave it an lc prefix to remind me it is a example of a line command macro.
|
|
|
Post by George on Mar 26, 2022 14:16:35 GMT -5
Stefan: As to why macros with no Pending SET still continue, it will have to wait till I feel more like walking a transaction through the code in Debug mode. It's such a soul-destroying task I have to be in the right mood to tackle it. Today is not one of those days.
George
|
|
|
Post by George on Mar 27, 2022 11:11:00 GMT -5
Stefan: I've been reviewing this whole area, some interesting "Oh, I remember that now!" moments. Get_Src_OpThis is actually quite accurately named. A bit of history is needed. - Line commands have always been executed before Primary commands.
- When Line Macros were introduced, they followed the same rules.
- The Get_Src... and Get_Dest... macro functions were created to allow Line Macros to fetch their operands and working values. They would never normally get used by Primary Command Macros, because the Line Command Macros would have already been executed.
- The numeric portion of a Line Command can be either: a line range specifier (e.g. M4), a repeat factor (e.g. CC4), a length specifier (e.g. TF70) or whatever else the command wants it to be. So it is just an Operand since there is no particular way to 'know' how it is used. Get_Src1_Op is a reasonable name. And numeric operands when not entered default to 0. Repeat is a numeric operand.
No easy access to 'raw' line command. Unfortunately true, you'll have to re-create the command from what's available.
Pending and Primary commands. Still to be looked in to.
George
|
|
|
Post by George on Mar 27, 2022 12:18:44 GMT -5
Stefan: Re: Pending stuff and Primary macros.
OK, I plain and simply give up. There is an intricate 'dance' that goes on between line command parsing, and whether or not the equivalent of 'pending' is an error or not.
e.g. a Primary CUT/CREATE/REPLACE/etc type command accesses line ranges via CC/CC marked lines. The "Pending" error is suppressed since it is perfectly valid to have no destination operand. This is marked by a flag in the main command table which allows certain commands to utilize this pending-but-not-pending technique.
Then along came macros, and their desire to use CC/CC line marking, and it got more convoluted, there was no table of which macro was allowed or not. Now you want incomplete pending blocks to also be allowed through.
This whole area is the most complicated internal part of SPFLite, and it's been completely re-written three times now. I simply avoid it like the plague.
A few years ago I was supporting a fellow in Texas who was attempting to re-write SPFLite in Java, and he was considered a Java guru. He was making good progress till he hit the Line Command jungle. After about 4-5 months of attempts, he packed in the entire project, said the complexity just got out of control.
So what we've got is going to have to be IT.
George
|
|
|
Post by Stefan on Mar 30, 2022 11:58:31 GMT -5
NO problem, George. Thanks for looking into it.
|
|