MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / RegExCallout

Function RegExCallout

source/script2.cpp:11920–12031  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

11918};
11919
11920int RegExCallout(pcret_callout_block *cb)
11921{
11922 // It should be documented that (?C) is ignored if encountered by the hook thread,
11923 // which could happen if SetTitleMatchMode,Regex and "#HotIf Winactive/Exist" are used.
11924 // This would be a problem if the callout should affect the outcome of the match or
11925 // should be called even if #HotIf WinA/E. will ultimately prevent the hotkey from firing.
11926 // This is because:
11927 // - The callout cannot be called from the hook thread, and therefore cannot affect
11928 // the outcome of #HotIf WinA/E. when called by the hook thread.
11929 // - If #HotIf WinA/E does NOT prevent the hotkey from firing, it will be reevaluated from
11930 // the main thread before the hotkey is actually fired. This will allow any
11931 // callouts to occur on the main thread.
11932 // - By contrast, if #HotIf WinA/E DOES prevent the hotkey from firing,
11933 // #HotIf WinA/E will not be reevaluated from the main thread,
11934 // so callouts cannot occur.
11935 if (GetCurrentThreadId() != g_MainThreadID)
11936 return 0;
11937
11938 if (!cb->callout_data)
11939 return 0;
11940 RegExCalloutData &cd = *(RegExCalloutData *)cb->callout_data;
11941
11942 auto callout_func = (IObject *)cb->user_callout;
11943 if (!callout_func)
11944 {
11945 Var *pcre_callout_var = g_script.FindVar(_T("pcre_callout"), 12, FINDVAR_FOR_READ); // This may be a local of the UDF which called RegExMatch/Replace().
11946 if (!pcre_callout_var)
11947 return 0; // Seems best to ignore the callout rather than aborting the match.
11948 callout_func = pcre_callout_var->ToObject();
11949 if (!callout_func)
11950 {
11951 if (!pcre_callout_var->HasContents()) // Var exists but is empty.
11952 return 0;
11953 // Could be an invalid name, or the name of a built-in function.
11954 cd.result_token->Error(_T("Invalid pcre_callout"));
11955 return PCRE_ERROR_CALLOUT;
11956 }
11957 }
11958
11959 // Adjust offset to account for options, which are excluded from the regex passed to PCRE.
11960 cb->pattern_position += cd.options_length;
11961
11962 // Save EventInfo to be restored when we return.
11963 EventInfoType EventInfo_saved = g->EventInfo;
11964
11965 g->EventInfo = (EventInfoType) cb;
11966
11967 /*
11968 callout_number: should be available since callout number can be specified within (?C...).
11969 subject: useful when behaviour might depend on text surrounding a capture.
11970 start_match: as above. equivalent to return value of RegExMatch, so should be available somehow.
11971
11972 pattern_position: useful to debug regexes when combined with auto-callouts. otherwise not useful.
11973 next_item_length: as above. combined 'next_item' instead of these two would be less useful as it cannot distinguish between multiple identical items, and would sometimes be empty.
11974
11975 capture_top: not sure if useful? helps to distinguish between empty capture and non-capture. could maybe use callout number to determine this instead.
11976 capture_last: as above.
11977

Callers

nothing calls this directly

Calls 8

RegExCreateMatchArrayFunction · 0.85
CallMethodFunction · 0.85
FindVarMethod · 0.80
HasContentsMethod · 0.80
ErrorMethod · 0.80
MemoryErrorMethod · 0.80
SetExitResultMethod · 0.80
ToObjectMethod · 0.45

Tested by

no test coverage detected