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

Method AddFunc

source/script.cpp:6827–6935  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6825
6826
6827UserFunc *Script::AddFunc(LPCTSTR aFuncName, size_t aFuncNameLength, Object *aClassObject)
6828// Returns the address of the new function or NULL on failure.
6829// The caller must already have verified that this isn't a duplicate function.
6830{
6831 if (aFuncNameLength == -1) // Caller didn't specify, so use the entire string.
6832 aFuncNameLength = _tcslen(aFuncName);
6833
6834 if (aFuncNameLength > MAX_VAR_NAME_LENGTH) // FindFunc(), BIF_OnMessage() and perhaps others rely on this limit being enforced.
6835 {
6836 ScriptError(_T("Function name too long."), aFuncName);
6837 return nullptr;
6838 }
6839
6840 // ValidateName requires that the name be null-terminated, but it isn't in this case.
6841 // Doing this first saves doing tcslcpy() into a temporary buffer, and won't leak memory
6842 // since the script currently always exits if an error occurs anywhere below:
6843 LPTSTR new_name = SimpleHeap::Alloc(aFuncName, aFuncNameLength);
6844
6845 if (!aClassObject && *new_name && !Var::ValidateName(new_name, DISPLAY_FUNC_ERROR)) // Variable and function names are both validated the same way.
6846 return nullptr; // Above already displayed the error for us.
6847
6848 auto the_new_func = new UserFunc(new_name);
6849 if (!the_new_func)
6850 {
6851 ScriptError(ERR_OUTOFMEM);
6852 return nullptr;
6853 }
6854
6855 if (aClassObject)
6856 {
6857 LPTSTR key = _tcsrchr(new_name, '.'); // DefineFunc() always passes "ClassName.MethodName".
6858 ++key;
6859 if (!Var::ValidateName(key, DISPLAY_METHOD_ERROR))
6860 return nullptr;
6861 if (mClassProperty)
6862 {
6863 bool is_getter = ctoupper(*key) == 'G';
6864 if (is_getter ? mClassProperty->Getter() : mClassProperty->Setter())
6865 {
6866 ScriptError(ERR_DUPLICATE_DECLARATION, new_name);
6867 return nullptr;
6868 }
6869 if (is_getter)
6870 mClassProperty->SetGetter(the_new_func);
6871 else
6872 mClassProperty->SetSetter(the_new_func);
6873 }
6874 else
6875 {
6876 switch (aClassObject->GetOwnPropType(key))
6877 {
6878 case Object::PropType::Object:
6879 case Object::PropType::DynamicMethod: // call
6880 case Object::PropType::DynamicMixed: // get/set and call
6881 ScriptError(ERR_DUPLICATE_DECLARATION, new_name);
6882 return nullptr;
6883 }
6884 if (!aClassObject->DefineMethod(key, the_new_func))

Callers

nothing calls this directly

Calls 12

ctoupperFunction · 0.85
GetterMethod · 0.80
SetterMethod · 0.80
SetGetterMethod · 0.80
SetSetterMethod · 0.80
GetOwnPropTypeMethod · 0.80
DefineMethodMethod · 0.80
MakeReadOnlyMethod · 0.80
IsAssumeGlobalMethod · 0.80
AddRefMethod · 0.45
AssignMethod · 0.45
InsertMethod · 0.45

Tested by

no test coverage detected