Cobol v6.2 NUMCHECK option compatibility - cobol

We can't turn off the NUMCHECK option for our new COBOL V6.2 compiler because we can't trust the content of our numeric variables. When we turn it on, it's not fully compatible with the COBOL 4 we had previously at our organization.
When an unsigned packed variable contains X'123C' , COBOL 4 would have accepted it and let us continue, but COBOL 6.2 with NUMCHECK(PAC,ABD) abends, and only willing to accept X'123F'. This is a real issue for us regarding assembler invoking COBOL, or reading from files and etc.
Is there another option or maybe even a PTF that corrects this behavior?
Can you point us to other incompatibilities like this one when NUMCHECK is on, if they exist? Thank you! Zohar

This is working as documented. I know that's not what you wanted to hear, but sometimes that's just the way it is. Your application is abending because the NUMCHECK compile option has detected what it sees as invalid data.
Note that the NUMCLS installation option for IBM COBOL 6.2 governs the behavior of the IF NUMERIC class test, an implicit version of which is generated by the NUMCHECK compile option. If your packed data is defined without sign, i.e.
77 XYZ PIC 999 COMP-3.
then the documentation indicates a sign nibble of x'F' is the only sign nibble which will pass an IF NUMERIC class test. Any other value for the sign nibble is considered invalid.
Excerpt from IBM Documentation for Enterprise COBOL 6.2...
Table 1. NUMCLS(PRIM) and valid signs
NUMPROC(NOPFD) NUMPROC(PFD)
Signed C, D, F C, D, +0 (positive zero)
Unsigned F F
Table 2. NUMCLS(ALT) and valid signs
NUMPROC(NOPFD) NUMPROC(PFD)
Signed A to F C, D, +0 (positive zero)
Unsigned F F
The wording for the documentation for the NUMCLS option for IBM COBOL 4.2 is definitely different...
Processing with ALT accepts hexadecimal A through F as valid.
Processing with PRIM accepts hexadecimal C, D, and F as valid.
You might want to check at https://www.ibm.com/support/pages/node/604539#112918 to see if any of the PTFs apply to your situation.
You could attempt to raise an issue with IBM, but here's the problem: if you have unsigned data, then an argument can be made that having a sign nibble indicating a positive (x'C') or negative (x'D') sign is invalid. I suspect this is part of the reason the NUMCHECK option works the way it does.
Possible solutions include having your Assembler programs invoking your COBOL programs do a sign fix on any packed data they pass. Maybe an OI on the last byte. You might be able to write control cards for your shop's SORT utility to fix packed data in your flat files. You could change your unsigned packed data items in your COBOL programs to be signed.
It all depends on what behavior you desire. You say you cannot trust the content of your numeric variables. If that means you sometimes have a sign nibble of x'A' instead of x'C' for a positive value, you can use NUMPROC(NOPFD) if NUMCLS(ALT) is in effect.
Another possible solution to your situation, if NUMCLS(ALT) is in effect, is to compile with NUMPROC(NOPFD) and use signed fields to initially hold your data. According to the documentation, moving the data to an unsigned field will fix the sign. Note that NUMPROC(NOPFD) does not perform as well as NUMPROC(PFD).
Following is an expansion of my understanding of the documentation of which sign nibbles result in an IF NUMERIC test being true. I have no way to test this, it's just my attempt to translate the documentation's implicit language into an explicit table. It does highlight the differences between IBM Enterprise COBOL 4.x and IBM Enterprise COBOL v5 and later.
SIGN COBOL 5+ COBOL 4
NUMCLS NUMPROC SIGNED NIBBLE NUMERIC NUMERIC
ALT NOPFD YES X'A' TRUE TRUE
ALT NOPFD YES X'B' TRUE TRUE
ALT NOPFD YES X'C' TRUE TRUE
ALT NOPFD YES X'D' TRUE TRUE
ALT NOPFD YES X'E' TRUE TRUE
ALT NOPFD YES X'F' TRUE TRUE
ALT NOPFD NO X'A' FALSE TRUE
ALT NOPFD NO X'B' FALSE TRUE
ALT NOPFD NO X'C' FALSE TRUE
ALT NOPFD NO X'D' FALSE TRUE
ALT NOPFD NO X'E' FALSE TRUE
ALT NOPFD NO X'F' TRUE TRUE
ALT PFD YES X'A' FALSE FALSE
ALT PFD YES X'B' FALSE FALSE
ALT PFD YES X'C' TRUE TRUE
ALT PFD YES X'D' TRUE TRUE
ALT PFD YES X'E' FALSE FALSE
ALT PFD YES X'F' FALSE FALSE
ALT PFD NO X'A' FALSE FALSE
ALT PFD NO X'B' FALSE FALSE
ALT PFD NO X'C' FALSE FALSE
ALT PFD NO X'D' FALSE FALSE
ALT PFD NO X'E' FALSE FALSE
ALT PFD NO X'F' TRUE TRUE
PRIM NOPFD YES X'A' FALSE FALSE
PRIM NOPFD YES X'B' FALSE FALSE
PRIM NOPFD YES X'C' TRUE TRUE
PRIM NOPFD YES X'D' TRUE TRUE
PRIM NOPFD YES X'E' FALSE FALSE
PRIM NOPFD YES X'F' TRUE TRUE
PRIM NOPFD NO X'A' FALSE FALSE
PRIM NOPFD NO X'B' FALSE FALSE
PRIM NOPFD NO X'C' FALSE TRUE
PRIM NOPFD NO X'D' FALSE TRUE
PRIM NOPFD NO X'E' FALSE FALSE
PRIM NOPFD NO X'F' TRUE TRUE
PRIM PFD YES X'A' FALSE FALSE
PRIM PFD YES X'B' FALSE FALSE
PRIM PFD YES X'C' TRUE TRUE
PRIM PFD YES X'D' TRUE TRUE
PRIM PFD YES X'E' FALSE FALSE
PRIM PFD YES X'F' FALSE FALSE
PRIM PFD NO X'A' FALSE FALSE
PRIM PFD NO X'B' FALSE FALSE
PRIM PFD NO X'C' FALSE FALSE
PRIM PFD NO X'D' FALSE FALSE
PRIM PFD NO X'E' FALSE FALSE
PRIM PFD NO X'F' TRUE TRUE

I don't have the reputation yet to add a comment, so I'll have to add another answer. I'm one of the Enterprise COBOL developers though, and what I can say is that the V4.2 docs are a little less clear and the wording has been changed for V6, but the behaviour of the compiler has not. The behaviour both compilers use matches the V5 column in cschneid's table above.
For numeric class tests, unsigned packed and zoned data items always require a sign of x'F', no matter what the NUMPROC or NUMCLS settings are. Signed items allow C and D always, F with NUMPROC(NOPFD) (regardless of the NUMCLS setting), and A, B, and E only for NUMCLS=ALT,NUMPROC(NOPFD). The documentation in the customization guide for NUMCLS is only talking about signed class tests.
As for the original issue: NUMCHECK behaves exactly like an IS NUMERIC test, and in both cases, a sign of x'C' is considered invalid for an unsigned data item and an IS NUMERIC test or NUMCHECK will find the value not numeric/invalid. The behaviour you get for all other COBOL statements (compares, arithmetic, MOVEs, etc.) with a sign of x'C' is undefined under NUMPROC(PFD) and may vary between V4/V6, between OPT levels in V6, between ARCH levels in V6, etc. Under NUMPROC(NOPFD) and in some cases NUMPROC(MIG) in V4 (MIG is unsupported in V6), the sign of an unsigned item is forced to 0xF before the value in that data item is used, so this guarantees a certain behaviour, as well as behavioural compatibility. NUMCHECK however, is made to match the IS NUMERIC class test and also to find invalid data so it can be corrected (otherwise there's no point using NUMCHECK, as the tests it adds to your program will negatively impact performance), so it's going to flag all invalid data, even data that seemed to "work correctly" in V4 (which really means that while the behaviour under NUMPROC(PFD) is undefined, it was at least consistent).

Related

why am i getting a syntax error in my logitech g lua script?

i have been learning lua to code an auto clicker for my g903 that works when the right mouse button is held and can be toggled with the capslock key.
any help or insight would be appreciated
EnablePrimaryMouseButtonEvents(true);
function OnEvent(event,arg)=true
if IsKeyLockOn("capslock"=true then
if IsMouseButtonPressed(3)=true then
repeat
if IsMouseButtonPressed(1)=true then
repeat
PressAndReleaseMouseButton(1)
Sleep(math.random(20,80))
until IsMouseButtonPressed(1)=false
end
until IsMouseButtonPressed(3)=false
end
end
end
function OnEvent(event,arg) is the beginning of a function definition. You cannot assing true here as attempted in function OnEvent(event,arg)=true. This will give an error for an unexpected symbol near '='. Lua cannot make sense of this.
In if IsKeyLockOn("capslock"=true then you're missing a cosing parenthesis. After adding that it is still incorrect as for all the following lines:
if IsKeyLockOn("capslock")=true then
if IsMouseButtonPressed(3)=true then
if IsMouseButtonPressed(1)=true then
you get an error 'then' exepected near '='
until IsMouseButtonPressed(1)=false
until IsMouseButtonPressed(3)=false
you get an error '' expected near 'until'
You are confusing the assignment operator = with the equality operator ==.
See Relational Operators and Assignment
As a side note, these functions are already returning true or false.
You don't have to explicitly check wether the return value equals true. There are only two possible outcomes. true == true -> true or false == true -> false. So you can use the return value directly and simply write if IsMouseButtonPressed(1) then.
If you want to do someting in the false case it is common practice to simply negate the return value. not false -> true
In this case you simply write if not if not IsMouseButtonPressed(1) then instead of if IsMouseButtonPressed(1) == false then.

Detecting instance of data change

Is there a good way to write a query in influxdb that will show you a change of state from the previous value? I am looking to query my database for times of where a server has turned off.
For example if I had the following database:
Time | Server_1_ON | Server_2_ON
-------------------------------------------------
2019-08-18T14:43:00Z | True | True
2019-08-18T14:43:05Z | True | True
2019-08-18T14:43:10Z | True | False
2019-08-18T14:43:15Z | True | False
2019-08-18T14:43:20Z | True | False
2019-08-18T14:43:25Z | True | True
2019-08-18T14:43:30Z | True | True
2019-08-18T14:43:35Z | True | False
I would want to be able to detect that server 2 had turned off twice, and return the two rows
2019-08-18T14:43:10Z | True | False
2019-08-18T14:43:35Z | True | False
I could achieve the same results by writing a query to
SELECT * WHERE "Server_2_ON" = False
and then filtering out duplicate results. But this is a multi-step process.
If this is not easily possible in influxdb, is there another database that is more suited to this style of query?
If your measurements were integer (1 to represent ON / 0 for OFF) instead of boolean, you could use the difference function.
To select any change in either measurement:
WHERE (DIFFERENCE(Server_1_ON) != 0
OR DIFFERENCE(Server_2_ON) != 0)
to select change from on to off in either measurement:
WHERE (DIFFERENCE(Server_1_ON) = -1
OR DIFFERENCE(Server_2_ON) = -1)
Note that in InfluxDb v1.x it is not possible to cast from Boolean to Integer, so for this to work you will need to change the stored data type to int. See can I change a field’s data type?
"There is no way to cast a float or integer to a string or Boolean (or
vice versa). The simplest workaround is to begin writing the new data type to a different field in the same series.
In InfluxDb v2.0 (still alpha) it is possible to cast Boolean to Int (see INT function).
(I have just started to investigate InfluxDb. I don't like it so far. But it seems that's just me, for according to this article in DZone it's currently the no 1 Time Series Database.)

Why does "not nil" return true in Lua?

I have used repl.it to see what it returned, just for the sake of curiosity, and it turned out that
not nil
returnes true
Why is it? Is it because in Lua everything should be rather true or false in the end?
Repl.it link: https://repl.it/repls/SanePastelHarrier
Because nil is false when converted to boolean:
2.2 Booleans
The boolean type has two values, false and true, which represent the traditional boolean values. However, booleans do not
hold a monopoly of condition values: in Lua, any value may represent a
condition. Conditionals (such as the ones in control structures)
consider both false and nil as false and anything else as true.
Beware that, unlike some other scripting languages, Lua considers both zero
and the empty string as true in conditional tests.
And not treats its argument as a boolean:
3.3 Logical Operators
The logical operators areand, or, and not. Like control structures, all logical operators consider both false and nil
as false, and anything else as true.

Why do nonzero numbers fail to set a BOOL property to YES?

It is my understanding that in Objective C, which is based off of C, all BOOLs are basically shorts (-127 to 128), with zero being the only value for "FALSE", or "NO". However, when I recently tried to set a button's selected value based off of a bitmask, it fails. Why?
NSInteger bitfield = 127;
NSInteger bitmask = 1 << 6; // 64
myButton.selected = bitfield & bitmask; // selected will remain NO
That's because BOOL is not bool.
BOOL is a just a non-standard (Objective-C-specific) typedef for a (non-bool) integral type (as far as I know, it's always signed char but I might be wrong). As such, it does not behave as a true Boolean data type, but rather as its underlying integral type. So, if you assign 64 to it, it will store 64 (and not true or 1). It is possible that, as a result of this, an operation that always assumes the true value to be 1 (i. e. the LSB set) will fail to recognize 64 as such.
In contrast, if you replaced BOOL with the true C99 Boolean type, which is _Bool or bool, then you would experience the expected behavior. I. e., assigning any non-zero value to the variable would have it store true or 1, regardless to whether that value was really 1.

Lua ""==true equals ""==false

I'm having trouble understanding how the expressions ""==true and ""==false both evaluate to false.
Trying the following in the lua interpreter and ilua result in the same output:
> =""==true
false
> =""==false
false
Or executing the following:
print(""==true)
print(""==false)
print(""==nil)
Outputs
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
false
false
false
>
Another example:
> =""~=true
true
> =""==false
false
When the following code is run:
if "" then -- if ""==true
print "was true"
end
if not "" then -- if ""==false
print "was not true"
end
The output is (seemingly inconsistently)
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
was true
>
As expected per the Lua FAQ which states
C-like languages regard 0 as equivalent to false, but this is not true
for Lua. Only an explicit false or nil are equivalent to false. When
in doubt, make the condition explicit, e.g. if val == nil then ... end
unless the value is actually boolean.
How can a value be not equal to true,false or nill?
All Lua values when used as Booleans evaluate to true, except nil and false. This does not mean that values that evaluate to true are equal to true. If you want to convert a value v to Boolean, use not not v.
The type of "" is string, not boolean, so it's not equal to either true or false.
To be more general, when Lua compares two values, it tests their type first, if the type mismatch, Lua thinks the two values as not equal immediately.
When used as control expression, the only false values in Lua are false and nil, everything else is evaluated as true value. Some popular confusions include the number 0, the empty string "", the string "0", they are all true values. Note again that false and nil are not equal because they are different types.
So back to the example, in the code
if "" then -- if ""==true
print "was true"
end
Lua tests if "" is false or nil, since it's neither, then Lua treats the condition as true value.
Disclaimer: I have no experience with lua, this is an educated guess
This is probably because "" is an empty string, so Lua probably evaluates it as a string with length of zero. Since it's a valid object it's not going to be equal to true, false, or nil, it'll be equal to a string with length zero.
Disclaimer: the only thing I know about Lua is that I don't know anything about Lua.
It appears that Lua treats equality comparisons using == and comparisons done in control structures (if, while, for, etc.) differently.
According to the Lua 5.1 manual (section 2.4.4, Control Structures),
The condition expression of a control structure can return any value.
Both false and nil are considered false. All values different from nil
and false are considered true (in particular, the number 0 and the
empty string are also true).
It seems like this is consistent with what you are seeing. That is:
"" == false => false
"" == true => false
"" == nil => false
Because the comparison operator seems to be checking the type and the value.
However, if you use the variable in a conditional in a control structure, the behavior is slightly different. That is,
if "" then
print "Hello world!"
end
Will print Hello world!, because the empty string is different from both nil and false, and thus evaluates to a truthy value.

Resources