Deleting from a dialog list merges the list? - mirc

Although I'm not not to programming for mIRC, I am new to working with dialog boxes as I previously had no use for them and my clients did not need to use them, therefore until now, I have not delved into them previously.
alias ss {
dialog -dm setup setup
}
dialog setup {
; === Window ===
title "Script Setup"
size -1 -1 420 335
button "OK",1,145 307 73 21, OK
button "Cancel",2,226 307 73 21
button "Help",3,307 307 73 21
; ==============
box "Personal Preferences",4, 3 3 493 293
combo 5,128 60 185 210,sort
button "Add",6, 323 83 73 21
button "Edit",7, 323 112 73 21
button "Delete",8, 323 141 73 21
button "Reset List",9, 323 170 73 21
}
alias -l update.setup {
did -r setup 5
set %temp.total $count(%setup.list,$chr(44))
set %temp.count 0
:start
inc %temp.count 1
did -a setup 5 $gettok(%setup.list,%temp.count,44)
if (%temp.count < %temp.total) { goto start }
}
on *:DIALOG:setup:edit:*: {
if ($did == 5) {
set %setup.temp.channel $did(5).text
}
}
on *:DIALOG:setup:sclick:*: {
; ====== Channel List Btn's ======
; === Add ===
if ($did == 6) {
set %setup.list %setup.list $+ %setup.temp.channel $+ ,
update.setup
}
; === Edit ===
if ($did == 7) {
}
; === Delete ===
if ($did == 8) {
set -u3 %setup.tc %setup.channel.selected $+ ,
set %setup.list $remove(%setup.list,%setup.tc)
update.setup
}
; === Reset ===
if ($did == 9) {
unset %setup.list
update.setup
}
}
I'm trying to make a dialog which functions the same as the options window for adding a new server, however this is to add a new channel whereas I'd actually want there to be no text input on the version above, but instead another dialog open upon clicking on add or edit.
The above would simply be an additional question of which would save myself time setting up another question on here, however my current problem which leads onto this is that upon clicking to delete a channel, no channel deletes and instead the current list merges.
Thank you for any help and/or advice and for providing any time to follow up my question.
Best Regards,
Tim

You've got several major issues at your script.
A. You're not displaying the list at dialog initialization.
Solution:
on *:dialog:setup:init:*: update.setup
B. When you got "Ok", "Cancel" buttons, make sure you give them the associated command:
button "Cancel",2,226 307 73 21, cancel
C. Add/Delete/Edit commands
for all the following command i used purely "Token Identifiers" so i could maximize the usage of mIRC built in functions. (for further information write at mIRC /help token identifiers)
1. Added testing if entry was already inside our list. this protection help us to avoid identical channel inside our list, and help us better use the remove token.
2. Used "$remtok" identifier for "Delete" command.
3. Used "$input" identifier for simple elegant entry editing. the current editing isn't good programming practice + will cause several bugs.
* After every command i placed "update.setup" so it will "refresh" our list with every list change.
D. Proper conditions
Use "if..elseif..else" logic, DO NOT use "if..if..if" method.
E. /ss alias
Change alias logic, now it will create new dialog or if dialog is already open it will maximize and display it.
Bonus: Tweeked the "update.setup" alias
Complete Code
alias ss {
dialog $iif($dialog(setup), -ve, -dmv) setup setup
}
dialog setup {
; === Window ===
title "Script Setup"
size -1 -1 420 335
button "OK",1,145 307 73 21, OK
button "Cancel",2,226 307 73 21, cancel
button "Help",3,307 307 73 21
; ==============
box "Personal Preferences",4, 3 3 493 293
combo 5,128 60 185 210,sort
button "Add",6, 323 83 73 21
button "Edit",7, 323 112 73 21
button "Delete",8, 323 141 73 21
button "Reset List",9, 323 170 73 21
}
alias -l update.setup {
did -r setup 5
var %i = 1, %n = $numtok(%setup.list, 44)
while (%i <= %n) {
did -a setup 5 $gettok(%setup.list, %i, 44)
inc %i
}
}
on *:dialog:setup:init:*: update.setup
; ====== Channel List Btn's ======
on *:DIALOG:setup:sclick:*: {
; === Add ===
if ($did == 6) {
if (!$istok(%setup.list,$did(5),44)) {
set %setup.list $addtok(%setup.list, $did(5), 44)
update.setup
}
}
; === Edit ===
elseif ($did == 7) {
var %temp.editChannel = $did(5)
if ($input(Channel to be edited., ye, Channel Editing, %temp.editChannel)) {
set %setup.list $reptok(%setup.list, %temp.editChannel, $v1, 1, 44)
update.setup
dialog -ev setup
}
}
; === Delete ===
elseif ($did == 8) {
set %setup.list $remtok(%setup.list, $did(5), 1, 44)
update.setup
}
; === Reset ===
elseif ($did == 9) {
unset %setup.list
update.setup
}
}

Related

How to get the difference between two columns using Talend

I Have two excel sheets that i want to compare using talend job
First excel named Compare_Me_1
PN
STT
Designation
AY73101000
20
RC0402FR-0743K2L
AY73101000
22
RK73H1ETTP4322F
AY73101000
22
ERJ-2RKF4322X
Ac2566
70
CRCW040243K2FKED
Second excel named Compare_Me_2
PN
STT
Designation
AY73101000
20
RC0402FR-0743K2L
AY73101000
22
RK73H1ETTP4322F
AY73101000
21
ERJ-2RKF4322X
Ac2566
70
CRCW040243K2FKED
what i want to achieve is this output
PN1
STT1
STT2
STT_OK_Ko
Designation1
Designation2
Designation_Ok_Ko
AY73101000
20
20
ok
RC0402FR-0743K2L
RC0402FR-0743K2L
ok
AY73101000
22
22
ok
RK73H1ETTP4322F
RK73H1ETTP4322F
ok
AY73101000
22
21
ko
ERJ-2RKF4322X
ERJ-2RKF4322X
ok
Ac2566
70
70
ok
CRCW040243K2FKED
CRCW040243K2FKED
ok
So to achieve this i developed a talend job that looks like below :
In My tMap i linked PN with a leftouterjoin and All Matches correspandance .
And to get for example STT_Ok_KO i used bellow code to compare my two input :
(!Relational.ISNULL(row14.STT) && !Relational.ISNULL(row13.STT) &&
row14.STT.equals(row13.STT) ) ||
(Relational.ISNULL(row14.STT) && Relational.ISNULL(row13.STT))
?"ok":"ko"
Is this the correct way to achieve my ouput ? If not , recommand me to use an other method
Any suggest is welcome .
You probably need to follow the long steps below :

How does mro, goto, and set_subname interact?

This is a complex question with regard to mro.pm, and the interplay with set_subname, and goto
In troubleshooting a problem, I think the core of my misunderstanding relates to how mro.pm works -- especially with regard to set_subname.
What is the difference between these three constructs,
Plain call to set_subname
*Foo::bar = set_subname( 'Foo::bar', $codeRef );
Anon sub which wraps a set_subname
*Foo::bar = sub {
my $codeRef2 = set_subname('Foo::bar', $codeRef);
goto $codeRef2
};
Anon sub which has its name set with set_subname
*Foo::bar = set_subname(
'Foo::bar',
sub { goto $codeRef }
);
Specifically, the Mojo test suits fails with either of these modifications with anon subs applied to Mojo::Utils's monkey_patch Running the two variants above against t/mojo/websocket_proxy.t,
With the 2 (second) option I have
*{"${class}::$k"} = sub {
my $cr = set_subname("${class}::$k", $patch{$k});
goto $cr;
};
And I get
Mojo::Reactor::Poll: Timer failed: Can't locate object method "send" via package "Mojo::Transaction::HTTP" at t/mojo/websocket_proxy.t line 66.
With the 3 (third) option I have,
*{"${class}::$k"} = set_subname("${class}::$k", sub { goto $patch{$k} })
And I get
No next::method 'new' found for Mojolicious::Routes at /usr/lib/x86_64-linux-gnu/perl/5.28/mro.pm line 30.
Obviously, the first version works (it's from the code I linked), the question is why are the other two variants giving me different errors (especially the second variant) and what's happening there -- why don't they work?
Your second option is not working because the sub you are using as a wrapper does not match the prototype of the inner sub. monkey_patch is not only used for methods, and this changes how some functions are parsed. In particular, Mojo::Util::steady_time has an empty prototype and is often called without using parenthesis.
*{"${class}::$k"} = Sub::Util::set_prototype(
Sub::Util::prototype( $patch{$k} ),
Sub::Util::set_subname(
"${class}::$k",
sub {
my $cr = Sub::Util::set_subname("${class}::$k", $patch{$k});
goto $cr;
}
)
);
The third construct is not working because you are using goto to remove the renamed wrapper sub from the call stack, leaving only the inner sub which has no name. This breaks next::method's ability to find the correct method name.
That is indeed complicated, but maybe you overcomplicated it?
Remember that MRO is only concerned with locating a method, which is just a symbol table entry to a coderef, through a defined order of package names. The internal subname only has to do with what caller() reports AFAIK.
From: Mojo
*{"${class}::$_"} = ## symbol table entry
set_subname("${class}::$_", ## an internal name
$patch{$_}) ## for a code ref
for keys %patch;
HTH
Edit After Seeing Error Messages:
The subroutines have not been validly installed. I suspect that since in option 2 and 3 you are deferring the calls to set_subname() to call time, the coderef $patch{$k} never has a subname assigned to it and that breaks a link in the chain of mro::_nextcan()'s XS magic. Particularly if $patch{$k} calls next::method. The closures seem to be valid though.
Although I must say my testing seems to show that option 2 is valid.
Enter command: my ($class, $k) = qw/W S/; my %patch = (S =>
sub {print "patch here\n"; decall;}); *{"${class}::$k"} =
sub { print "goto'r here\n"; my $cr = set_subname("${class}::$k",
$patch{$k}); goto $cr;};
Enter command: decall
0 "console"
1 "console.pl"
2 "114"
3 "(eval)"
4 "0"
5 0
6 "package W; decall"
7 ""
8 "256"
9 "\020\001\000\000\000P\004\000\000\000\000\000\000U\025U\005"
10 0
Enter command: S
goto'r here
patch here
0 "W"
1 "(eval 110)"
2 "1"
3 "W::S"
4 "1"
5 0
6 0
7 0
8 "256"
9 "\020\001\000\000\000P\004\000\000\000\000\000\000U\025U\005"
10 0
You might have to start looking farther afield for the problem with option 2.
After modifying Mojo/Util.pm with
foreach my $k (keys %patch) {
*{"${class}::$k"} = sub {
my $cr = set_subname("${class}::$k", $patch{$k});
goto $cr;
};
}
and isolating the test case, I get:
$ perl -MCarp::Always t/mojo/websocket_proxy2.t
Mojo::Reactor::Poll: Timer failed: Can't locate object method "send" via package "Mojo::Transaction::HTTP" at t/mojo/websocket_proxy2.t line 59.
main::__ANON__(Mojo::UserAgent=HASH(0x60280dad0), Mojo::Transaction::HTTP=HASH(0x6029ee7b0)) called at blib/lib/Mojo/UserAgent.pm line 252
Mojo::UserAgent::_finish(Mojo::UserAgent=HASH(0x60280dad0), "927210c53042c6142eda3f4010c8b17c", 1) called at blib/lib/Mojo/UserAgent.pm line 220
Mojo::UserAgent::_error(Mojo::UserAgent=HASH(0x60280dad0), "927210c53042c6142eda3f4010c8b17c", "Connect timeout") called at blib/lib/Mojo/UserAgent.pm line 128
Mojo::UserAgent::__ANON__(Mojo::IOLoop=HASH(0x601f9abb8), "Connect timeout", undef) called at blib/lib/Mojo/IOLoop.pm line 63
Mojo::IOLoop::__ANON__(Mojo::IOLoop::Client=HASH(0x601e34598)) called at blib/lib/Mojo/EventEmitter.pm line 15
Mojo::EventEmitter::emit(Mojo::IOLoop::Client=HASH(0x601e34598), "error", "Connect timeout") called at blib/lib/Mojo/IOLoop/Client.pm line 39
Mojo::IOLoop::Client::__ANON__(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/Reactor/Poll.pm line 143
eval {...} called at blib/lib/Mojo/Reactor/Poll.pm line 143
Mojo::Reactor::Poll::_try(Mojo::Reactor::Poll=HASH(0x6001a8390), "Timer", CODE(0x601e24ca0)) called at blib/lib/Mojo/Reactor/Poll.pm line 81
Mojo::Reactor::Poll::one_tick(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/Reactor/Poll.pm line 99
Mojo::Reactor::Poll::start(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/IOLoop.pm line 134
Mojo::IOLoop::start("Mojo::IOLoop") called at t/mojo/websocket_proxy2.t line 62
at blib/lib/Mojo/IOLoop.pm line 23.
Mojo::IOLoop::__ANON__(Mojo::Reactor::Poll=HASH(0x6001a8390), "Timer failed: Can't locate object method \"send\" via package \"Mojo::Transaction::HTTP\" at t/mojo/websocket_proxy2.t line 59.\x{a}\x{9}main::__ANON__(Mojo::UserAgent=HASH(0x60280dad0), Mojo::Transaction::HTTP=HASH(0x6029ee7b0)) called at blib/lib/Mojo/UserAgent.pm line 252\x{a}\x{9}Mojo::UserAgent::_finish(Mojo::UserAgent=HASH(0x60280dad0), \"927210c53042c6142eda3f4010c8b17c\", 1) called at blib/lib/Mojo/UserAgent.pm line 220\x{a}\x{9}Mojo::UserAgent::_error(Mojo::UserAgent=HASH(0x60280dad0), \"927210c53042c6142eda3f4010c8b17c\", \"Connect timeout\") called at blib/lib/Mojo/UserAgent.pm line 128\x{a}\x{9}Mojo::UserAgent::__ANON__(Mojo::IOLoop=HASH(0x601f9abb8), \"Connect timeout\", undef) called at blib/lib/Mojo/IOLoop.pm line 63\x{a}\x{9}Mojo::IOLoop::__ANON__(Mojo::IOLoop::Client=HASH(0x601e34598)) called at blib/lib/Mojo/EventEmitter.pm line 15\x{a}\x{9}Mojo::EventEmitter::emit(Mojo::IOLoop::Client=HASH(0x601e34598), \"error\", \"Connect timeout\") called at blib/lib/Mojo/IOLoop/Client.pm line 39\x{a}\x{9}Mojo::IOLoop::Client::__ANON__(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/Reactor/Poll.pm line 143\x{a}\x{9}eval {...} called at blib/lib/Mojo/Reactor/Poll.pm line 143\x{a}\x{9}Mojo::Reactor::Poll::_try(Mojo::Reactor::Poll=HASH(0x6001a8390), \"Timer\", CODE(0x601e24ca0)) called at blib/lib/Mojo/Reactor/Poll.pm line 81\x{a}\x{9}Mojo::Reactor::Poll::one_tick(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/Reactor/Poll.pm line 99\x{a}\x{9}Mojo::Reactor::Poll::start(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/IOLoop.pm line 134\x{a}\x{9}Mojo::IOLoop::start(\"Mojo::IOLoop\") called at t/mojo/websocket_proxy2.t line 62\x{a}") called at blib/lib/Mojo/EventEmitter.pm line 15
Mojo::EventEmitter::emit(Mojo::Reactor::Poll=HASH(0x6001a8390), "error", "Timer failed: Can't locate object method \"send\" via package \"Mojo::Transaction::HTTP\" at t/mojo/websocket_proxy2.t line 59.\x{a}\x{9}main::__ANON__(Mojo::UserAgent=HASH(0x60280dad0), Mojo::Transaction::HTTP=HASH(0x6029ee7b0)) called at blib/lib/Mojo/UserAgent.pm line 252\x{a}\x{9}Mojo::UserAgent::_finish(Mojo::UserAgent=HASH(0x60280dad0), \"927210c53042c6142eda3f4010c8b17c\", 1) called at blib/lib/Mojo/UserAgent.pm line 220\x{a}\x{9}Mojo::UserAgent::_error(Mojo::UserAgent=HASH(0x60280dad0), \"927210c53042c6142eda3f4010c8b17c\", \"Connect timeout\") called at blib/lib/Mojo/UserAgent.pm line 128\x{a}\x{9}Mojo::UserAgent::__ANON__(Mojo::IOLoop=HASH(0x601f9abb8), \"Connect timeout\", undef) called at blib/lib/Mojo/IOLoop.pm line 63\x{a}\x{9}Mojo::IOLoop::__ANON__(Mojo::IOLoop::Client=HASH(0x601e34598)) called at blib/lib/Mojo/EventEmitter.pm line 15\x{a}\x{9}Mojo::EventEmitter::emit(Mojo::IOLoop::Client=HASH(0x601e34598), \"error\", \"Connect timeout\") called at blib/lib/Mojo/IOLoop/Client.pm line 39\x{a}\x{9}Mojo::IOLoop::Client::__ANON__(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/Reactor/Poll.pm line 143\x{a}\x{9}eval {...} called at blib/lib/Mojo/Reactor/Poll.pm line 143\x{a}\x{9}Mojo::Reactor::Poll::_try(Mojo::Reactor::Poll=HASH(0x6001a8390), \"Timer\", CODE(0x601e24ca0)) called at blib/lib/Mojo/Reactor/Poll.pm line 81\x{a}\x{9}Mojo::Reactor::Poll::one_tick(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/Reactor/Poll.pm line 99\x{a}\x{9}Mojo::Reactor::Poll::start(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/IOLoop.pm line 134\x{a}\x{9}Mojo::IOLoop::start(\"Mojo::IOLoop\") called at t/mojo/websocket_proxy2.t line 62\x{a}") called at blib/lib/Mojo/Reactor/Poll.pm line 143
Mojo::Reactor::Poll::_try(Mojo::Reactor::Poll=HASH(0x6001a8390), "Timer", CODE(0x601e24ca0)) called at blib/lib/Mojo/Reactor/Poll.pm line 81
Mojo::Reactor::Poll::one_tick(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/Reactor/Poll.pm line 99
Mojo::Reactor::Poll::start(Mojo::Reactor::Poll=HASH(0x6001a8390)) called at blib/lib/Mojo/IOLoop.pm line 134
Mojo::IOLoop::start("Mojo::IOLoop") called at t/mojo/websocket_proxy2.t line 62
I can also confirm that setting the prototype fixes it.

Why are spacebar events suppressed when running this script?

I made a script to tile windows with my left hand in windows 10, using a dvorak keyboard layout. It works as expected except, it keeps the spacebar events from getting to any program other than the script itself. This is the keyboard log when running the script:
20 039 s d 0.09 Space
20 039 s u 0.08 Space
20 039 s d 0.08 Space
20 039 s u 0.08 Space
20 039 s d 0.08 Space
20 039 s u 0.09 Space
20 039 s d 0.08 Space
20 039 s u 0.09 Space
20 039 s d 31.14 Space
20 039 s u 0.11 Space
20 039 s d 0.09 Space
20 039 s u 0.11 Space
Both space events are detected correctly, but remain suppressed. Terminating the script manually solves the problem.
#MaxThreads 255 ; for the purpose of troubleshooting
#e::return
#.::return
#o::return
#u::return
Space & u::
Space & .::
Space & o::
Space & e::
send {LWin Down}
spcup()
exit
spcup()
{
while GetKeyState("Space", "P") {
rite := GetKeyState("u", "P")
left := GetKeyState("o", "P")
up := GetKeyState(".", "P")
down := GetKeyState("e", "P")
if (rite=1) {
Sleep 75
Send {Right}
Sleep 75
}
else if (left=1) {
Sleep 75
Send {Left}
Sleep 75
}
else if (up=1) {
Sleep 75
Send {Up}
Sleep 75
}
else if (down=1) {
Sleep 75
Send {Down}
Sleep 75
}
else if !GetKeyState("Space", "P") {
sleep 75
Send {LWinUp}
exit
}
}
}
PS, I used space because my left windows key is physically damaged.
Binding Space to itself adding a "Space::Space" line, works partially, only the up event is registered as a hotkey, so it fires only on release of spacebar producing this:
20 039 s d 0.25 Space
20 039 h u 0.16 Space
20 039 i d 0.00 Space
20 039 i u 0.00 Space
s=suppressed
h=hotkey
i=ignored(sent by autohotkey itself)
"Solved", kind of. No way for a prefix key to maintain it's original function without ~, hence sending it to the active window, which is unwanted.
isWindowFullScreen()
{
;checks if the specified window is full screen
;use WinExist of another means to get the Unique ID (HWND) of the desired window
if WinExist("A") {
WinGet, style, Style, A
WinGetPos ,,,winW,winH, A
; 0x800000 is WS_BORDER.
; 0x20000000 is WS_MINIMIZE.
; no border and not minimized
retVal := ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? 0 : 1
Return, retVal
}
else {
return
}
}
#if isWindowFullScreen() = 0
#e::return
#.::return
#o::return
#u::return
#Space::return
Space::Space
Space & u::
Space & .::
Space & o::
Space & e::
send {LWin Down}
spcup()
exit
spcup()
{
while GetKeyState("Space", "P") {
loop {
rite := GetKeyState("u", "P")
left := GetKeyState("o", "P")
up := GetKeyState(".", "P")
down := GetKeyState("e", "P")
if (left=1) {
Sleep 75
Send {Left}
Sleep 75
}
else if (up=1) {
Sleep 75
Send {Up}
Sleep 75
}
else if (down=1) {
Sleep 75
Send {Down}
Sleep 75
}
else if (rite=1) {
Sleep 75
Send {Right}
Sleep 75
}
} until !GetKeyState("Space", "P")
Sleep 75
Send {LWinUp}
exit
}
}
From the help documentation:
Numpad0 & Numpad1::MsgBox You pressed Numpad1 while holding down Numpad0.
Numpad0 & Numpad2::Run Notepad
The prefix key loses its native function: In the above example,
Numpad0 becomes a prefix key; but this also causes Numpad0 to lose its
original/native function when it is pressed by itself. To avoid this,
a script may configure Numpad0 to perform a new action such as one of
the following:
Numpad0::WinMaximize A ; Maximize the active/foreground window.
Numpad0::Send {Numpad0} ; Make the release of Numpad0 produce a
Numpad0 keystroke. See comment below.
Fire on release: The presence of one of the above custom combination
hotkeys causes the release of Numpad0 to perform the indicated action,
but only if you did not press any other keys while Numpad0 was being
held down. [v1.1.14+]: This behaviour can be avoided by applying the
tilde prefix to either hotkey.
Adding a tilde prefix ~ to each of your Space & hotkeys should make it behave as you expect. Alternatively, you could add ~Space::Return.
Note that this will always send a space, which may have unintended consequences in different applications. For instance, in a browser it will scroll down similar to pressing the
page down key.
Here is a condensed version of your code that I used for testing:
~Space & u::
~Space & .::
~Space & o::
~Space & e::
aReplace := [[ "u" , "Right" ] , [ "o" , "Left" ] , [ "." , "Up" ] , [ "e" , "Down" ]]
Loop , % aReplace.Length()
sReplace := ( SubStr( A_ThisHotkey , 0 , 1 ) = aReplace[ A_Index , 1 ] ) ? aReplace[ A_Index , 2 ] : sReplace
Send , #{%sReplace%}
Return

Example of 'a subroutine may have several entry and exit points'

I'm reading the paper of Non structured programming, and found it says:
Unlike a procedure, a subroutine may have several entry and exit points, and a direct jump into or out of subroutine is (theoretically) allowed
I can't understand it, could anyone give me an code sample of:
a subroutine may have several entry and exit points
a direct jump into or out of subroutine
Thanks
10 A = 1
20 GOSUB 100
30 A = 2
40 GOSUB 110
50 A = 3
60 GOTO 130
70 END
100 PRINT A
110 PRINT "HELLO"
120 IF A = 1 THEN RETURN
130 PRINT "THERE"
140 IF A = 3 THEN GOTO 70
150 RETURN
The subroutine has three entry points (lines 100, 110, and 130) and three exit points (lines 120, 140, and 150). There is a direct jump into line 130 (from line 60) and a direct jump out (at line 140).

Function not returning a variable for a autohotkey definition

I've been trying to make an auto-clicker for grinding but it just stops in the middle and I don't understand why. Here's what I have so far:
^!n:: ;Ctr+Alt+n
FindColour(0x4447FB, 338, 491) ; Enter Building
Sleep 1500
FindColour(0x4145F1, 387, 420) ; Left Attack
Battle(1,1,1,1,0)
Sleep 1500
FindColour(0x4447FB, 602, 335) ; Far Attack
; Do Attack
Sleep 1500
FindColour(0x4447FC, 555, 527) ; Bottom Attack
; Do Attack
Sleep 1500
FindColour(0x4347FB, 338, 537) ; Leave Building
Sleep 1500
FindColour(0xF9F9F5, 239, 561) ; Reset Point
Sleep 1500
Return
FindColour(Colour, x, y){ ; Wait until the correct colour appears before clicking
Col = 0x000000
MouseMove, %x%, %y%
Loop
{
PixelGetColor, Col, %x%, %y%
If Col = %Colour%
{
Click %x% %y%
Return
}
Sleep 10
}
Return
}
Battle(a, b, c, d, e){ ; e isn't needed yet
x = 488
y := FindStart()
Col = 0x3F18D0
MsgBox %y%
Loop %a%
{
FindColour(%Col%, %x%, %y%)
Sleep 100
Click 606 276
}
Loop %b%
{
FindColour(%Col%, %x%, %y%)
Sleep 100
Click 547 371
}
Loop %c%
{
FindColour(%Col%, %x%, %y%)
Sleep 100
Click 676 491
}
Loop %d%
{
FindColour(%Col%, %x%, %y%)
Sleep 100
Click 774 309
}
; End
Return
}
FindStart(){
x = 488
y = 200
Loop 300
{
MouseMove, %x%, %y%
Sleep 20
PixelGetColor, Col, %x%, %y%
If Col = 0x3D00FF
{
y += 23
Return %y%
}
Else
{
y += 1
}
}
MsgBox Start not found
}
It's fine until it runs FindStart(). I watch the cursor slowly make its way down the screen to the correct pixel (which moves each battle, thus the function), at which point it stops. I placed the line "MsgBox %y%" after FindStart() is called to check anything happens after the function is called but the msgbox never appears.
What am I missing?
I found the solution. It turns out that variables sent when calling a function should not be enclosed in percentage signs.