how to return a value from a called script with lauterbach practice scripts - dialog

I tried to follow the lib.cmm script, from lines 210-214, to return a value from a DO called script to my calling script, but get 'stack underflow' on my RETURN xx statement. My called script is an edited version of t32/demo/practice/dialogs/dialog_list.cmm.
What I'm trying to do should be easy, but I cannot determine how/why what I have done doesn't work nor how it differs from the ENTERDLG function in lib.cmm (in terms of return values).
Here are my two file's contents:
caller:
area.reset
LOCAL &GPU_choice
DO choose_CPU.cmm ENTERDLG
ENTRY %LINE &CPU_choice
print "cpu = &CPU_choice"
callee:
ENTERDLG:
LOCAL &CPU_choice
DIALOG
(&+
HEADER "Flash Programming"
POS 0. 0. 25. 1.
TEXT ""
POS 1. 0. 23. 1.
TEXT "CPU Type:"
POS 1. 1. 23. 3.
OptionA.SEL: LISTBOX "CPU1,CPU2" ""
;buttons OK (Default) and Cancel
POS 1. 11. 10. 1.
DEFBUTTON "OK" "CONTinue"
POS 14. 11. 10. 1.
BUTTON "Cancel" "GOTO cancel"
;define action when window is closed
CLOSE "GOTO cancel"
)
;set default selections
DIALOG.SET OptionA.SEL "CPU1"
;STOP command halts script execution
STOP
;script will continue here when "OK" button is clicked
;get selection
&CPU_choice=DIALOG.STRING(OptionA.SEL);
;close dialog window
DIALOG.END
RETURN &CPU_choice <===============this line gives "stack underflow error"
ENDDO
;script continues here when Cancel is clicked"
cancel:
DIALOG.END
DIALOG.OK "Cancelled"
ENDDO

RETURN is for returning a value from a routine called with GOSUB inside the same script.
To return a value to the script, which called the current script with DO, you have to pass the result with the ENDDO command.
So in your example replace "RETURN &CPU_choice" with:
ENDDO &CPU_choice
See also https://www.lauterbach.com/reference_card_web.pdf (2nd page in the middle)

Related

How to find whether a certain bluetooth device is connected?

I want to use applescript to do a periodic (every second) check to see if a specific bluetooth devices is connected, and if so, to flash up a quick notification. To frame it, I want a popup when my Airpods connect, since sometimes when I pull them out, the connect to my computer, and sometimes to my iPhone.
I've got everything figured out, except for the bluetooth check part. I've used this as a starting point, but can't get it to work. Any help would be appreciated.
repeat
set statusOld to checkStatus()
set statusNew to checkStatus()
repeat while statusOld is equal to statusNew
delay 1 --for 1 second checks
set statusNew to checkStatus()
end repeat
if statusNew is true then
display dialog "Device Added - put some real code here"
else
display dialog "Device Removed - put some real code here"
end if
end repeat
on checkStatus()
(*Delete the 2 lines below when done testing*)
--set myString to button returned of (display dialog "Connected?" buttons {"Yes", "No"})
--set myString to "name: DR-BT101 Connected: " & myString
(*uncomment line below when done testing*)
set myString to do shell script "system_profiler SPBluetoothDataTyp"
--initial check if it's not even there
if myString does not contain "Christian’s AirPods" then
return false
else
--find out if connected/disconnected
set AppleScript's text item delimiters to "name:"
set myList to the text items of myString --each item of mylist is now one of the devices
set numberOfDevices to count of myList
set counter to 1
repeat numberOfDevices times --loop through each devices checking for Connected string
if item counter of myList contains "Christian’s AirPods" then
if item counter of myList contains "Connected: Yes" then
return true
else if item counter of myList contains "Connected: No" then
return false
else
display dialog "Error Parsing" --this shouldn't happen
end if
end if
set counter to counter + 1
end repeat
end if
end checkStatus
You're missing the e:
set myString to do shell script "system_profiler SPBluetoothDataType"
^
I'm working on something similar. This seems to work well on macOS Mojave:
use framework "IOBluetooth"
use scripting additions -- https://stackoverflow.com/a/52806598/6962
on isDeviceConnected(substring)
repeat with device in (current application's IOBluetoothDevice's pairedDevices() as list)
if device's isConnected and (device's nameOrAddress as string) contains substring then return true
end repeat
return false
end isDeviceConnected
-- Usage example:
isDeviceConnected("AirPods")
I combined it with a launch agent like this: https://gist.github.com/henrik/3d4c622a5567cdf2bf461352f48ad4dd

How to wait for user input inside function using c#

I have One Window application by Which User Can Print Their Product Barcode Value And Also Can Scan it,
Now i am searching for some threading or some other way,
If user Enter 5 value for Print after Printing First value, Function wait for user input in text box (i call textbox up event for capturing scanning value)
and if value is correct so, my function continue its execution or wait until user Scan Proper barcode,
so how can i make method or function which can wait for user input and then continue executions.
private void myFunction1()
{
for (i = 0; i < intPrintNo; i++) // Number Of Print
{
// here I write Code For Print My Barcode
// Now I want to wait For user Input in my text box
jumphere :
txtBarcode.Text = "";
txtBarcode.Enabled = true;
txtBarcode.Visible = true;
txtBarcode.Focus();
if (keyUp()== false)
{
txtBarcode.Text = "";
txtBarcode.Enabled = true;
goto jumphere;
}
// If return True than for loop Continue for next Printing
}
}
From what i've understood from your question, you want to print the barcode of value specified by the user and then user can scan the same to verify if printed properly or not.
You can achieve this functionality in Windows forms using following steps
User enters the value (to print barcode) in txtInput
Presses print button (btnPrint)
The print button event handler will first disable itself and the input textbox (btnPrint.Enabled = txtInput.Enabled = false; Application.DoEvents();) and then print the barcode and set focus on textbox txtVerify.
User will scan the barcode in textbox txtVerify.
User will click on verify button (btnVerify) which will compare the value in txtInput and txtVerify.
If everything fine, clear the txtInput, txtVerify, enable txtInput and btnPrint, set focus to txtInput for next value
If error, do the needful.
EDIT: As per OPs comment (minimum user effort)
You can change the setting of barcode scanner to suffix newline (Enter) after every scan (you can find how to do this setting in the manual provided with the barcode)...... so now,
step 4. User will scan the barcode in textbox txtVerify (the scanning will provide Enter press at the end of scan). txtVerify.TextChanged event handler will check if key pressed in Enter, if so, call the code to verify (compare the values in txtInput and txtVerify)
step 5. Remove this step from above
step 6. If everything fine, clear the txtInput, txtVerify, enable txtInput and btnPrint, set focus to txtInput for next value
step 7. If error, do the needful.
Also, you can modify the first textbox to print the barcode when user presses enter key (so, no need to click on Print button)
So, after above modifications, the user will enter the text press enter (this will print barcode) then scan (as focus is already in txtVerify). If everything is fine, new value can be entered.
To reset the screen, you can provide a 'Reset' button.
Glad to help! Please remember to accept the answer if you found it helpful.

autohotkey assign a text expression to a variable

In an autohotkey script I was trying to assign a text string to a variable. Can anyone spot why this doesn't work, it looks just like some provided examples? I don't need the variable anymore, but now I'm just curious what I did wrong...
myvar := % "foo" ; creates global variable myvar, but has no contents
I know you could just say myvar = foo
but leaving quotes off a fixed text string just makes me cringe. I even had it working but didnt' save my file before making 'a few harmless cosmetic edits.' I click on the "H" task
icon near the clock, use menu File / show variables to verify the empty contents...
Okay, so we assign a value to a variable:
eval_this:= "harry"
If you do it this way, you just read the contents of the variable:
msgbox %eval_this% ;=harry
Of course, here, the text is not evaluated - "eval_this" is just text to ahk:
msgbox eval_this ;= eval_this
This method is called a "Forced Expression" - which is what you are looking to do. It tries to read the text string as if it were code. It isn't reading the contents of any variable, it is looking at the text and forcing it to become a variable (it's sort of the same thing, but not really)
msgbox % eval_this ;= harry
This also gets us harry, and you can see how we are reading the variable:
test := eval_this
msgbox %test% ;=harry
Same thing, different approach (forcing the text to become a variable):
test = % eval_this
msgbox %test% ;=harry
Consider this, where we force both text strings into their actual values
eval_this := "harry"
this_too := " and bob"
test = % eval_this this_too
msgbox %test% ;= harry and bob
Okay, now that you've got all that, here is a practical application. We will force the value of the text string to be a variable. Since we've actually defined what "alert" is, then the gosub will call that definition. Pop this into a script and run it:
eval_this := "alert"
gosub % eval_this
exit ;we are finished with the demo, so end here
alert:
msgbox harry
return

GoTo <Line number> in VBA

From the VBA help file:
GoTo Statement
Branches unconditionally to a specified line within a procedure.
Syntax
GoTo _line_
The required line argument can be any line label or line number.
Remarks
GoTo can branch only to lines within the procedure where it appears.
My question is, how can I jump to a line number using GoTo? (I know how to jump to a label.)
(Note: I'm asking this for curiosity's sake. I have no intention of actually using GoTo this way.)
I understand your dislike of the answer "start the line with a line number", but you can't argue with facts. That is exactly what they mean.
The syntax of VBA/VB6 is designed to be backwards-compatible with the syntax of QuickBasic, and before that with the syntax of GW-Basic/MS-Basic, which dates to the late 1970's and even earlier: the original Dartmouth BASIC Language was created in the '60s.
In MS-Basic, like in every other Basic implementation of the era, every line you added to a program had to start with a line number. The line number told the Basic interpreter two things: a) that you were storing the line (otherwise the interpreter would execute it immediately), and b) in what position of the program the line belonged. Why do something so arcane? because when Basic was invented it was intended to be interactive, in a world where the only form of interactivity was a command-line prompt, on a teletype-style printing terminal.
And there were no labels.
A typical Basic session might have looked like this, where > stands for a command processor prompt (this is made-up, but close enough to how it worked). Remember: there are no cursor keys or screens. You are typing on a typewriter - with a roll of paper instead of a screen - and the typewriter responds back at you by printing on the paper as well!:
Welcome to B.A.S.I.C.
Ok <--- Ok told you the interpreter was ready
>LIST <--- print the program
Ok <--- No program, so nothing to list.
>PRINT 2 + 7 <--- No line number, so execute immediately
9 <--- The command executes
Ok
>30 PRINT 2 + 7 <--- Line number, so store the command in position 30
Ok
>10 I = 42 <--- Line number, so store in line 10
Ok
>20 PRINT I + 12 <--- Store on line 20, so insert between 10 and 30
Ok
>LIST <--- Print the program so far
10 I = 42
20 PRINT I + 12
30 PRINT 2 + 7
Ok
>RUN <--- Execute the stored program now
54 <--- line 10 has no output. Line 20 outputs this
9 <--- line 30 outputs this
Ok <--- Done running the program
>20 <--- an empty line number: it means delete the line
Ok
>LIST
10 I = 42
30 PRINT 2 + 7 <--- line 20 is gone!
Primitive? Maybe, but you have to start somewhere.
Back then, you always used GOTO by providing the line number where you wanted the code to jump. It was just how it worked. For example:
10 PRINT "Testing, "
20 I = 1
30 PRINT I; ","
40 IF I >= 3 THEN 60
50 GOTO 30
60 END
QuickBasic was an enhanced version of Basic published by Microsoft that supported optionally compiling programs into executables, rather than running then in the interpreter interactively. Among other enhancements, it also added these two features:
Because it ran full-screen with a fully-featured GUI text editor, it didn't need line numbers to designate where each new line went; you just moved the cursor and typed: traditional line numbers were now optional. In fact, they were discouraged because in a full-featured editor, they just got in the way. But they couldn't just remove them because they were so central to BASIC compatibility, so they were still supported. And they still are, even in VBA.
Since they didn't want you to use line numbers, they needed an alternative for commands that required line numbers as targets, such as GOTO. you were now allowed to place line text labels that could be used as targets for GOTO, etc.
So, you can see that line numbers are not just "line labels made out of digits". They are actually an alternative syntax that has been maintained for compatibility with older versions of the language.
That's it. The help file is simply telling you about the "modern" syntax of GOTO (with text labels), and that - if you really want to - you can still use the legacy syntax with line numbers and legacy GOTO syntax that was invented in the mid-1960's.
Sub Jump()
10 Dim A As Integer
20 A = 25
30 GoTo 50
40 A = 50
50 Debug.Print A
End Sub
It's a throwback to the old (really old) BASIC days, where line numbers were required. Now labels are used.
Sub Jump2()
Dim A As Integer
A = 25
GoTo JumpToHere
A = 50
JumpToHere:
Debug.Print A
End Sub
But using GoTo is considered poor programming, with the exception of OnError GoTo ...
One very useful purpose for old fashion line numbers is for error handling. Many folks utilize a standard error handler of the Sort:
proc name (args)
on error goto handler
code
.
.
exit proc
handler:
debug.print err.number & "(" & err.description & ") in Module: " & ModuleName & "- Proc:" & ProcName at & now
resume next
Exit Proc
Which can be made somewhat more useful In the code Is line numbered, as the ErrLine Property will return the line number
of the offending executable line.
debug.print err.number & "(" & err.description & ") - on Line " & errLine & " in Module: " & ModuleName & "- Proc:" & ProcName at & now
declaring the line number and declaring a lable is basicly the same
but using a line number as a big advantage: it does not use memory!
if your "our of memory" you will not be able to declare a lable
but you will be able to declare a line numer and use that as a "goTo"
sub mySub()
....
on error goto 100
...
exit sub
100: msgbox("Error")
end sub
I read many comments about GOTO being poor programming..
Back in the olden days when
a Hewlit Packard 25 had 25 memories to store all instructions and variables
BASIC was still Beginners All purpose Symbolic Instruction Code and
much better than doing things in 6502 Assembler
I went to computer conference where the
one of the experts was takling about a new language that used blocks and
None of GOTO GOSUB AND RETURN .. yea PASCAL
At the time I KNEW it was impossible to have such a language
but since have spent about 20 years teaching
and designing commercial software in PASCAL
With MS backing their Office with VBA of course Pascal has become rare
even though Delphi was still used as a early years teaching language.
To cut IT short
If you consider the machine code constructed for IF then else end if
and the fact that VBA still evaluates ALL of AND OR NOT XOR in an
If ....... Then when you need to evaluate one a few million times
the then GOTO can save you a few seconds.
However on the topic of ON Error Resume Next
many use these to test if a workbook is open or a Sheets exists
on a closed workbook... ...etc etc ..
In some cases that is poor programming in that the program has to
check all before showing an error whereas
for each ....
while Not Found
found = a = b
wend
only has to check until found
My first teaching computer was a PDP 8 ... 8Kb ..
Punched tape teletype for printing and I/O .. 7 Octal switches to boot.
Then moved up to Comodore 64 ..
Current 16 GB computer has memory of 250,000 of them.
a topical comment
with the FBI CIA etc .....Homeland Security Trumps them all.

Applescript for copying the current line of text?

I'd like to create an applescript that will copy the entire line that the carat is currently on. After doing a fair amount of googling, however, I have come up empty. Any ideas?
(*
Save this as an application
Right click the application and select "Show Package Contents"
Add this to Info.plist between <dict> and </dict>
<key>LSBackgroundOnly</key>
<true/>
launch the application with spotlight (command space)
*)
tell application "System Events"
key code 123 using {command down, shift down}
key code 124 using {command down, shift down}
keystroke "c" using {command down}
end tell
Below is some code I wrote for Xcode 9 (I finally got it working as of updated 3-5-18). I wanted a feature that every text editor I've used in the past 25 years. A copy with no selection would copy the current line. The code figures out what paragraph (line) the caret is on and if there is any text selected. The same code can be modified to include Cut.
I execute this code using Keyboard Maestro. Add the below (3) actions. You must disable the "Execute Applescript" macro before executing it otherwise the Command+C that is sent from within the code will cause an infinite loop:
Disable Macro "the current macro"
Execute Applescript "paste the AppleScript code in the edit box"
Enable Macro "the current macro"
Also, enable Xcode 9 key bindings to have Command+L do a select line. Use the "Text" tab to see less actions.
I also add the following to the DefaultKeyBinding.dict file.
https://www.maketecheasier.com/fix-home-end-button-for-external-keyboard-mac/
{
/* Remap Home/End keys to be like Windows */
"\UF729" = "moveToBeginningOfLine:"; /* Home */
"\UF72B" = "moveToEndOfLine:"; /* End */
"$\UF729" = "moveToBeginningOfLineAndModifySelection:"; /* Shift + Home */
"$\UF72B" = "moveToEndOfLineAndModifySelection:"; /* Shift + End */
/* page up/down and move the caret like Windows*/
"\UF72C" = "pageUp:";
"\UF72D" = "pageDown:";
/* Option Home/End keys Beginning/End of Document like Mac */
"~\UF729" = "moveToBeginningOfDocument:"; /* Ctrl + Home */
"~\UF72B" = "moveToEndOfDocument:"; /* Ctrl + End */
"$~\UF729" = "moveToBeginningOfDocumentAndModifySelection:"; /* Shift + Ctrl + Home */
"$~\UF72B" = "moveToEndOfDocumentAndModifySelection:"; /* Shift + Ctrl + End */
/* Ctrl Home/End keys Beginning/End of Document like Mac */
"^\UF729" = "moveToBeginningOfDocument:"; /* Ctrl + Home */
"^\UF72B" = "moveToEndOfDocument:"; /* Ctrl + End */
"$^\UF729" = "moveToBeginningOfDocumentAndModifySelection:"; /* Shift + Ctrl + Home */
"$^\UF72B" = "moveToEndOfDocumentAndModifySelection:"; /* Shift + Ctrl + End */
}
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use application "Xcode-beta"
global appName
set appName to "Xcode-beta"
-- for some reason pressing command+C only works ever other time without this
--delay 0.1
tell application appName
activate
set theDocuments to every source document
-- exit if no source documents are found
if theDocuments is equal to {} then
-- copy command must go somewhere i.e. the user might have copied an Icon.
tell application "System Events" to keystroke "c" using {command down}
do shell script "logger -t 'AS DEBUG' " & "Applescript CopyCurrentLine - exit if no source documents are found"
return -- exit script
end if
-- Note:
-- window 1 is where source documents live
-- It sure would've been nice if window contained a reference to its source document but it doesn't
-- if window has been edited its' name ends with " — Edited" and it needs to be trimed off
set windowName to name of window 1
if windowName ends with " — Edited" then
set windowName to my trimText(windowName, " — Edited", "end")
end if
-- try to find the windows' current source document by matching window name to source document name
repeat with theDoc in theDocuments
set theDocName to name of theDoc
if theDocName is equal to windowName then
exit repeat -- found the document
else
set theDocName to "" -- didn't find the document
end if
end repeat
-- exit if the window is not a source document
if theDocName is equal to "" then
-- copy command must go somewhere i.e. the user might have copied an Icon.
tell application "System Events" to keystroke "c" using {command down}
do shell script "logger -t 'AS DEBUG' " & "Applescript CopyCurrentLine - exit if the window is not a source document"
return -- exit script
end if
--set theDoc to last source document
set docText to the text of theDoc
-- get location of selected text
set {startPos, endPos} to selected character range of theDoc
if (my isSelectedTextRangeEmpty(theDoc)) then
-- select current line
-- I set a keybinding in Xcode so Command+L would call the Command 'Select Line'
tell application "System Events" to keystroke "l" using {command down}
end if
-- copy the selection to the clipboard
set selectedText to my getSelectedText(theDoc, docText)
-- restore insertion point to original location
set selected character range of theDoc to {startPos, endPos}
set the clipboard to selectedText
end tell
on getSelectedText(theContainer, docText)
-- get the selected text
set {startPos, endPos} to selected character range of theContainer
if {endPos < startPos} then
return ""
else
return (text startPos thru endPos) in docText
end if
end getSelectedText
on isSelectedTextRangeEmpty(theContainer)
set selectedCharacterRange to selected character range of theContainer
set {startPos, endPos} to selectedCharacterRange
if {endPos < startPos} or ¬
(selectedCharacterRange is equal to {}) or ¬
(length of selectedCharacterRange is equal to 0) then
return true
else
return false
end if
end isSelectedTextRangeEmpty
on trimText(theText, theCharactersToTrim, theTrimDirection)
-- "beginning", "end", "both"
set theTrimLength to the length of the theCharactersToTrim
-- TRIM BEGINNING
if the theTrimDirection is in {"beginning", "both"} then
repeat while theText begins with the theCharactersToTrim
try
set theText to characters (theTrimLength + 1) thru -1 of theText as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
-- TRIM ENDING
if the theTrimDirection is in {"end", "both"} then
repeat while theText ends with the theCharactersToTrim
try
set theText to characters 1 thru -(theTrimLength + 1) of theText as string
on error
-- the text contains nothing but the trim characters
return ""
end try
end repeat
end if
return theText
end trimText

Resources