jmp script logic works as jsl but not as add-in - sas-jmp

I run JMP 15.2.0 and my jsl script includes this section of code, which has a minor bug:
for each row(
if (:ColumnA == 99, ColumnA = .)
);
The 2nd ColumnA should have a leading : in order to replace 99's with null. But for some reason this works, despite the bug, when run via JMP as a script, yet not when installed as an "Add-In".
Why would the exact same script work (i.e., 99's get nullified as intended) when run as a script, but not as an "Add-In" (99's remain and no error appears in the log)?
Shouldn't jsl be interpreted the same whether run through JMP as a script or as an "Add-In"? Could my JMP instance be somehow set to use different engines for different modes? Has anyone else observed this confounding JMP strangeness?

The reason this happens is due to how JMP handles scope. When you give an unscoped variable (is not of the form ns:var, :var, ::var), then JMP has a sequence to try to find the proper scope for the variable of interest. It goes something like this
Check local namespace -- if found, done
Check Current Data Table columns, if found, done
Check here namespace -- if found, done
Check global namespace -- if found, done
Since you did not define "Column A" anywhere in your script, the only valid name for which "Column A" applies is the column name.
Inside of a "For Each Row" statement the order is to check column names first (higher precedence than any other scope).
Update:
Note that the above list is for explicitly unscoped variables without any 'unscoped variable handling' -- that is, no "Names Default to Here( 1 )" line. Note that if you have that line starting the script then it does not affect the data table, as the unscoped "ColumnA" variable only ever gets placed within the Here namespace. JMP doesn't do scope-walking to see if it can find a "ColumnA" variable in the various listed namespaces above.
I've included a picture of the most common way of attaching a script to an addin -- this is what I'm assuming you're doing. Notice that by default the line 'Use the "Here" namespace for unqualified JSL variable names' is checked -- unqualified means has no colon (unscoped). This check-box is forcing JMP to only look at Here:ColumnA when seeing the unscoped variable. You need to run the script without any automatic scope control to work as it does when run as a standalone.
Addin scripts by default link unscoped variables to the "Here" namespace, making it so that unscoped column names don't work

Current data table(dt);
for each row(dt,
if (: ColumnA == 99, :ColumnA = .););

Related

What is the meaning of MAKEINTRESOURCE((id>>4)+1)?

I am trying to mimic the behavior of CString::LoadString(HINSTANCE hInst, DWORD id, WORD langID) without introducing a dependency on MFC into my app. So I walked through the source. The first thing it does is to immediately call AtlGetStringResourceImage(hInst, id, langID), and then this in turn contains the following line of code:
hResource = ::FindResourceExW(hInst, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((id>>4)+1), langID);
(It's not verbatim like this, but I trimmed out some unimportant stuff).
What is the meaning of shifting the ID by 4 and adding 1? According to the documentation of FindResourceEx, you should pass in MAKEINTRESOURCE(id), and I can't find any example code that is manipulating the id before passing it to MAKEINTRESOURCE. At the same time, if I make my code call MAKEINTRESOURCE(id) then it doesn't work and FindResourceEx returns null, whereas if I use the above shift + add, then it does work.
Can anyone explain this?
From the STRINGTABLE resource documentation:
RC allocates 16 strings per section and uses the identifier value to determine which section is to contain the string. Strings whose identifiers differ only in the bottom 4 bits are placed in the same section.
The code you are curious about locates the section a given string identifier is stored in by ignoring the low 4 bits.

what kind of variable/function/object is session("var") = "Value"

I am trying to make modifications to a vbscript that uses the line:
Session("Variable") = "MyVariable String"
This line requires it to be ran within a different program which is not available where I am doing my development. This line is NOT important to the development that I am doing and I just need it to NOT blow up with 'undefined variable session' when I am running with 'Option explicit'. What class, dictionary, variable type, or whatever do I need to create in order for that line to work without warnings/errors? I am currently just commenting them out, but when I copy and paste my code back in production I have to go back through and hope that I have uncommitted all of them back out. I'd rather just add a for instance "Set Session = New FooSomething" at the top of the code that will make it work and just remove that line when I add to production code. Thanks for your time.

Assign a string value as a result of a command

I want to put a string result of a command in WinDbg in a variable for a later use.
For example, in a memory breakpointI want to save the result of - lm1ma eip that returns me the current module, for later comparison in $spat command.
If anyone knows a better way to achieve the goal of determining if the current debugged module is a specific module, inside a conditional breakpoint, it could be also helpful.
Use as /c Name CommandString.
It creates an alias to the results of executing the specified command.
https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/as--as--set-alias-

How do I remove the 'Done' message after my program has executed?

I made a program that is similar to clearing RAM. However, it always leaves a "Done" message followed by a dotted line after being executed. In addition, if you scroll up, you can see that the program was executed. Is there a way to remove both of these things? If you can't hide the fact that a program was executed, could you suppress the 'Done' message?
I have tried adding ClearHome" and " as the last line of my program, and neither stops the Done message from displaying.
Bonus points if your solution can be contained within the original program.
In a separate program, type the following line of code:
AsmPrgmFDCB00AEC9
Then at the end of the original program, type the following line of code:
Asm(prgmPROGRAMNAME
It is recommended that you test this out first with all programs archived, just running the above line of code alone, in case it fails. Hex codes like that one have been known to fail, and sometimes clears the RAM.
You can also try these other hex codes, but always keep in mind the warning above. My RAM has been cleared by this before, so use caution:
http://tibasicdev.wikidot.com/hexcodes
This works on TI 83 and 84, may be different with other calculator types.
EDIT:
I found a way to do this without an external program, and is much simpler.
Just add the following line of code to the end of your program:
Output(1,1," //no space, just a quote
You may or may not have to add ClrHome before that line of code.
This should prevent the Done message from appearing at the end.
Hope this helps!
Put an empty string at the end of your program, so your last line looks like this:
""
Or this
"
The empty string is stored to ans and will be displayed as a blank line rather than the Done message.
There is also an assembly hexcode to do this without leaving the blank line at the top:
FDCB00AEC9
When run at the end of the program using one of the various methods of running assembly, it will leave you with a blank, fully operational homescreen.
Outputting an empty string will prevent the Done message and also preserve Ans, in case a calling program is expecting to use it.
Output(Y,X,"")
See http://tibasicdev.wikidot.com/output for more details on Output(.
In your situation, run Clear Entries (found under Mem), then scroll up so that the Done message is selected and press Clear to get rid of it.

Adding entry to task_struct and initializing to default value

I want to add an entry to process control block structure (task_struct). Let say a way to tag some process. I want to initialize this field to 0 for all the process except "some special processes", later by calling sched_setscheduler() I will set this flag for the "special processes".
Does anybody have an idea how to assign a default value to a member variable in task_struct?
I'm assuming you are talking about a recent Linux kernel, because implementation detail changes over time.
There are two options. The first - you can set the value of the variable in the init_task global. See how it is done in the linux/init_task.h header. The second option is to add code to copy_process, which you might want to do anyway in order to properly handle the fork() inheritance of the field you are adding.

Resources