diff --git a/plugins/basebans.sp b/plugins/basebans.sp index dc5b254c..363a2f5b 100644 --- a/plugins/basebans.sp +++ b/plugins/basebans.sp @@ -118,18 +118,21 @@ LoadBanReasons() decl String:sectionName[255]; if(!KvGetSectionName(g_hKvBanReasons, sectionName, sizeof(sectionName))) { - return SetFailState("Error in %s: File corrupt or in the wrong format", g_BanReasonsPath); + SetFailState("Error in %s: File corrupt or in the wrong format", g_BanReasonsPath); + return; } if(strcmp(sectionName, "banreasons") != 0) { - return SetFailState("Error in %s: Couldn't find 'banreasons'", g_BanReasonsPath); + SetFailState("Error in %s: Couldn't find 'banreasons'", g_BanReasonsPath); + return; } //Reset kvHandle KvRewind(g_hKvBanReasons); } else { - return SetFailState("Error in %s: File not found, corrupt or in the wrong format", g_BanReasonsPath); + SetFailState("Error in %s: File not found, corrupt or in the wrong format", g_BanReasonsPath); + return; } } diff --git a/plugins/include/clientprefs.inc b/plugins/include/clientprefs.inc index 3f9db9ce..ce4a66ca 100644 --- a/plugins/include/clientprefs.inc +++ b/plugins/include/clientprefs.inc @@ -168,7 +168,13 @@ forward OnClientCookiesCached(client); * @param maxlen Max length of the output buffer. * @noreturn */ -functag public void CookieMenuHandler(client, CookieMenuAction:action, any:info, String:buffer[], maxlen); +typedef CookieMenuHandler = function void ( + int client, + CookieMenuAction action, + any info, + char[] buffer, + int maxlen +); /** * Add a new prefab item to the client cookie settings menu. diff --git a/plugins/include/commandfilters.inc b/plugins/include/commandfilters.inc index 7b40b92f..32e3d9c6 100644 --- a/plugins/include/commandfilters.inc +++ b/plugins/include/commandfilters.inc @@ -140,7 +140,7 @@ stock ReplyToTargetError(client, reason) * @param clients Array to fill with unique, valid client indexes. * @return True if pattern was recognized, false otherwise. */ -functag public bool:MultiTargetFilter(const String:pattern[], Handle:clients); +typedef MultiTargetFilter = function bool (const char[] pattern, Handle clients); /** * Adds a multi-target filter function for ProcessTargetString(). diff --git a/plugins/include/console.inc b/plugins/include/console.inc index 617bcee9..6323102e 100644 --- a/plugins/include/console.inc +++ b/plugins/include/console.inc @@ -328,7 +328,7 @@ native FormatActivitySource(client, target, const String:namebuf[], maxlength); * @return An Action value. Not handling the command * means that Source will report it as "not found." */ -functag public Action:SrvCmd(args); +typedef SrvCmd = function Action (int args); /** * Creates a server-only console command, or hooks an already existing one. @@ -352,7 +352,7 @@ native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:descriptio * @return An Action value. Not handling the command * means that Source will report it as "not found." */ -functag public Action:ConCmd(client, args); +typedef ConCmd = function Action (int client, int args); /** * Creates a console command, or hooks an already existing one. @@ -456,7 +456,7 @@ native Handle:FindConVar(const String:name[]); * @param newValue String containing the new value of the convar. * @noreturn */ -functag public void ConVarChanged(Handle:convar, const String:oldValue[], const String:newValue[]); +typedef ConVarChanged = function void (Handle convar, const char[] oldValue, const char[] newValue); /** * Creates a hook for when a console variable's value is changed. @@ -905,7 +905,7 @@ native RemoveServerTag(const String:tag[]); * @param argc Argument count. * @return Action to take (see extended notes above). */ -functag public Action:CommandListener(client, const String:command[], argc); +typedef CommandListener = function Action (int client, const char[] command, int argc); #define FEATURECAP_COMMANDLISTENER "command listener" diff --git a/plugins/include/dbi.inc b/plugins/include/dbi.inc index 090bd3a4..79d86ffd 100644 --- a/plugins/include/dbi.inc +++ b/plugins/include/dbi.inc @@ -643,7 +643,7 @@ native SQL_UnlockDatabase(Handle:database); * @param data Data passed in via the original threaded invocation. * @noreturn */ -functag public void SQLTCallback(Handle:owner, Handle:hndl, const String:error[], any:data); +typedef SQLTCallback = function void (Handle owner, Handle hndl, const char[] error, any data); /** * Tells whether two database handles both point to the same database @@ -713,7 +713,7 @@ native Transaction:SQL_CreateTransaction(); * @param queryData An array of each data value passed to SQL_AddQuery(). * @noreturn */ -functag public void SQLTxnSuccess(Handle:db, any:data, numQueries, Handle:results[], any:queryData[]); +typedef SQLTxnSuccess = function void (Handle db, any data, int numQueries, Handle[] results, any[] queryData); /** * Callback for a failed transaction. @@ -726,7 +726,7 @@ functag public void SQLTxnSuccess(Handle:db, any:data, numQueries, Handle:result * @param queryData An array of each data value passed to SQL_AddQuery(). * @noreturn */ -functag public void SQLTxnFailure(Handle:db, any:data, numQueries, const String:error[], failIndex, any:queryData[]); +typedef SQLTxnFailure = function void (Handle db, any data, int numQueries, const char[] error, int failIndex, any[] queryData); /** * Adds a query to a transaction object. diff --git a/plugins/include/float.inc b/plugins/include/float.inc index d2c2134c..d1c5c2e0 100644 --- a/plugins/include/float.inc +++ b/plugins/include/float.inc @@ -35,6 +35,7 @@ #endif #define _float_included +#if !defined __sourcepawn2__ /** * Converts an integer into a floating point value. * @@ -42,6 +43,7 @@ * @return Floating point value. */ native Float:float(value); +#endif /** * Multiplies two floats together. diff --git a/plugins/include/functions.inc b/plugins/include/functions.inc index e928213b..ee45e5b7 100644 --- a/plugins/include/functions.inc +++ b/plugins/include/functions.inc @@ -357,7 +357,7 @@ native Call_Cancel(); * @param numParams Number of parameters passed to the native. * @return Value for the native call to return. */ -functag public int NativeCall(Handle:plugin, numParams); +typedef NativeCall = function int (Handle plugin, int numParams); /** * Creates a dynamic native. This should only be called in AskPluginLoad(), or @@ -508,7 +508,7 @@ native FormatNativeString(out_param, * @param data Data passed to the RequestFrame native. * @noreturn */ -functag public void RequestFrameCallback(any:data); +typedef RequestFrameCallback = function void (any data); /** * Creates a single use Next Frame hook. diff --git a/plugins/include/logging.inc b/plugins/include/logging.inc index 80319c27..cfe2cd5f 100644 --- a/plugins/include/logging.inc +++ b/plugins/include/logging.inc @@ -123,7 +123,7 @@ forward Action:OnLogAction(Handle:source, * @return Plugin_Handled or Plugin_Stop will prevent the message * from being written to the log file. */ -functag public Action:GameLogHook(const String:message[]); +typedef GameLogHook = function Action (const char[] message); /** * Adds a game log hook. diff --git a/plugins/include/menus.inc b/plugins/include/menus.inc index a1858566..6e6cabbc 100644 --- a/plugins/include/menus.inc +++ b/plugins/include/menus.inc @@ -151,7 +151,7 @@ enum MenuSource * @param param1 First action parameter (usually the client). * @param param2 Second action parameter (usually the item). */ -functag public int MenuHandler(Menu:menu, MenuAction:action, param1, param2); +typedef MenuHandler = function int (Menu menu, MenuAction action, int param1, int param2); /** * Creates a new, empty menu using the default style. @@ -527,12 +527,14 @@ stock bool:VoteMenuToAll(Handle:menu, time, flags=0) * defines. * @noreturn */ -functag public void VoteHandler(Menu:menu, - num_votes, - num_clients, - const client_info[][2], - num_items, - const item_info[][2]); +typedef VoteHandler = function void ( + Menu menu, + int num_votes, + int num_clients, + const int client_info[][2], + int num_items, + const int item_info[][2] +); /** * Sets an advanced vote handling callback. If this callback is set, diff --git a/plugins/include/sdktools_entoutput.inc b/plugins/include/sdktools_entoutput.inc index 5ecfbafe..7c00f39f 100644 --- a/plugins/include/sdktools_entoutput.inc +++ b/plugins/include/sdktools_entoutput.inc @@ -44,7 +44,7 @@ * @param delay Delay in seconds? before the event gets fired. * @noreturn */ -functag public void EntityOutput(const String:output[], caller, activator, Float:delay); +typedef EntityOutput = function void (const char[] output, int caller, int activator, float delay); /** * Add an entity output hook on a entity classname diff --git a/plugins/include/sdktools_sound.inc b/plugins/include/sdktools_sound.inc index 59d14917..12a5b7b0 100644 --- a/plugins/include/sdktools_sound.inc +++ b/plugins/include/sdktools_sound.inc @@ -283,7 +283,16 @@ native Float:GetDistGainFromSoundLevel(soundlevel, Float:distance); * @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it, * Plugin_Changed when any parameter has been modified. */ -functag public Action:AmbientSHook(String:sample[PLATFORM_MAX_PATH], &entity, &Float:volume, &level, &pitch, Float:pos[3], &flags, &Float:delay); +typedef AmbientSHook = function Action ( + char sample[PLATFORM_MAX_PATH], + int &entity, + float &volume, + int &level, + int &pitch, + float pos[3], + int &flags, + float &delay +); /** * Called when a sound is going to be emitted to one or more clients. @@ -301,7 +310,17 @@ functag public Action:AmbientSHook(String:sample[PLATFORM_MAX_PATH], &entity, &F * @return Plugin_Continue to allow the sound to be played, Plugin_Stop to block it, * Plugin_Changed when any parameter has been modified. */ -functag public Action:NormalSHook(clients[64], &numClients, String:sample[PLATFORM_MAX_PATH], &entity, &channel, &Float:volume, &level, &pitch, &flags); +typedef NormalSHook = function Action ( + int clients[64], + int &numClients, + char sample[PLATFORM_MAX_PATH], + int &entity, + int &channel, + float &volume, + int &level, + int &pitch, + int &flags +); /** * Hooks all played ambient sounds. diff --git a/plugins/include/sdktools_tempents.inc b/plugins/include/sdktools_tempents.inc index fc741362..2e989f7e 100644 --- a/plugins/include/sdktools_tempents.inc +++ b/plugins/include/sdktools_tempents.inc @@ -44,7 +44,7 @@ * @param delay Delay in seconds to send the TE. * @return Plugin_Continue to allow the transmission of the TE, Plugin_Stop to block it. */ -functag public Action:TEHook(const String:te_name[], const Players[], numClients, Float:delay); +typedef TEHook = function Action (const char[] te_name, const int[] Players, int numClients, float delay); /** * Hooks a temp entity. diff --git a/plugins/include/sorting.inc b/plugins/include/sorting.inc index cc2549cd..161aff00 100644 --- a/plugins/include/sorting.inc +++ b/plugins/include/sorting.inc @@ -98,7 +98,7 @@ native SortStrings(String:array[][], array_size, SortOrder:order = Sort_Ascendin * 0 if first is equal to second * 1 if first should go after second */ -functag public int SortFunc1D(elem1, elem2, const array[], Handle:hndl); +typedef SortFunc1D = function int (int elem1, int elem2, const int[] array, Handle hndl); /** * Sorts a custom 1D array. You must pass in a comparison function. @@ -163,7 +163,7 @@ native SortADTArray(Handle:array, SortOrder:order, SortType:type); * 0 if first is equal to second * 1 if first should go after second */ -functag public int SortFuncADTArray(index1, index2, Handle:array, Handle:hndl); +typedef SortFuncADTArray = function int (int index1, int index2, Handle array, Handle hndl); /** * Custom sorts an ADT Array. You must pass in a comparison function. @@ -173,4 +173,4 @@ functag public int SortFuncADTArray(index1, index2, Handle:array, Handle:hndl); * @param hndl Optional Handle to pass through the comparison calls. * @noreturn */ -native SortADTArrayCustom(Handle:array, SortFuncADTArray:sortfunc, Handle:hndl=INVALID_HANDLE); \ No newline at end of file +native SortADTArrayCustom(Handle:array, SortFuncADTArray:sortfunc, Handle:hndl=INVALID_HANDLE); diff --git a/plugins/include/textparse.inc b/plugins/include/textparse.inc index 1ef70c3b..95dcb4ed 100644 --- a/plugins/include/textparse.inc +++ b/plugins/include/textparse.inc @@ -108,7 +108,7 @@ native bool:SMC_GetErrorString(SMCError:error, String:buffer[], buf_max); * @param smc The SMC Parse Handle. * @noreturn */ -functag public void SMC_ParseStart(Handle:smc); +typedef SMC_ParseStart = function void (Handle smc); /** * Sets the SMC_ParseStart function of a parse Handle. @@ -128,7 +128,7 @@ native SMC_SetParseStart(Handle:smc, SMC_ParseStart:func); * @param failed True if parsing failed, false otherwise. * @noreturn */ -functag public void SMC_ParseEnd(Handle:smc, bool:halted, bool:failed); +typedef SMC_ParseEnd = function void (Handle smc, bool halted, bool failed); /** * Sets the SMC_ParseEnd of a parse handle. @@ -149,7 +149,7 @@ native SMC_SetParseEnd(Handle:smc, SMC_ParseEnd:func); * @param opt_quotes True if the section name was quote-enclosed in the file. * @return An SMCResult action to take. */ -functag public SMCResult:SMC_NewSection(Handle:smc, const String:name[], bool:opt_quotes); +typedef SMC_NewSection = function SMCResult (Handle smc, const char[] name, bool opt_quotes); /** * Called when the parser finds a new key/value pair. @@ -162,7 +162,7 @@ functag public SMCResult:SMC_NewSection(Handle:smc, const String:name[], bool:op * @param value_quotes Whether or not the value was enclosed in quotes. * @return An SMCResult action to take. */ -functag public SMCResult:SMC_KeyValue(Handle:smc, const String:key[], const String:value[], bool:key_quotes, bool:value_quotes); +typedef SMC_KeyValue = function SMCResult (Handle smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes); /** * Called when the parser finds the end of the current section. @@ -170,7 +170,7 @@ functag public SMCResult:SMC_KeyValue(Handle:smc, const String:key[], const Stri * @param smc The SMC Parse Handle. * @return An SMCResult action to take. */ -functag public SMCResult:SMC_EndSection(Handle:smc); +typedef SMC_EndSection = function SMCResult (Handle smc); /** * Sets the three main reader functions. @@ -191,7 +191,7 @@ native SMC_SetReaders(Handle:smc, SMC_NewSection:ns, SMC_KeyValue:kv, SMC_EndSec * @param lineno The line number it occurs on. * @return An SMCResult action to take. */ -functag public SMCResult:SMC_RawLine(Handle:smc, const String:line[], lineno); +typedef SMC_RawLine = function SMCResult (Handle smc, const char[] line, int lineno); /** * Sets a raw line reader on an SMC parser Handle. diff --git a/plugins/include/topmenus.inc b/plugins/include/topmenus.inc index 5fdbf57b..136c97e5 100644 --- a/plugins/include/topmenus.inc +++ b/plugins/include/topmenus.inc @@ -127,12 +127,14 @@ enum TopMenuObject * @param maxlength Output buffer (if used). * @noreturn */ -functag public void TopMenuHandler(Handle:topmenu, - TopMenuAction:action, - TopMenuObject:topobj_id, - param, - String:buffer[], - maxlength); +typedef TopMenuHandler = function void ( + Handle topmenu, + TopMenuAction action, + TopMenuObject topobj_id, + int param, + char[] buffer, + int maxlength +); /** * Creates a TopMenu. diff --git a/plugins/include/usermessages.inc b/plugins/include/usermessages.inc index cd73ffef..ce48937b 100644 --- a/plugins/include/usermessages.inc +++ b/plugins/include/usermessages.inc @@ -140,7 +140,7 @@ native EndMessage(); * blocks the message from being sent, and Plugin_Continue * resumes normal functionality. */ -functag public Action:MsgHook(UserMsg:msg_id, Handle:msg, const players[], playersNum, bool:reliable, bool:init); +typedef MsgHook = function Action (UserMsg msg_id, Handle msg, const int[] players, int playersNum, bool reliable, bool init); /** * Called when a message hook has completed. @@ -149,7 +149,7 @@ functag public Action:MsgHook(UserMsg:msg_id, Handle:msg, const players[], playe * @param sent True if message was sent, false if blocked. * @noreturn */ -functag public void MsgPostHook(UserMsg:msg_id, bool:sent); +typedef MsgPostHook = function void (UserMsg msg_id, bool sent); /** * Hooks a user message. diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index 42d99474..0e9fa60c 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -357,7 +357,7 @@ typedef struct { /* Tokens recognized by lex() * Some of these constants are assigned as well to the variable "lastst" (see SC1.C) */ -enum { +enum TokenKind { /* value of first multi-character operator */ tFIRST = 256, /* multi-character operators */ @@ -431,6 +431,7 @@ enum { tSWITCH, tTAGOF, tTHEN, + tTYPEDEF, tVOID, tWHILE, /* compiler directives */ diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index 9fda0d3f..8c64442d 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -143,6 +143,7 @@ static void dogoto(void); static void dolabel(void); static void doreturn(void); static void dofuncenum(int listmode); +static void dotypedef(); static void domethodmap(LayoutSpec spec); static void dobreak(void); static void docont(void); @@ -1558,6 +1559,9 @@ static void parse(void) case tFUNCTAG: dofuncenum(FALSE); break; + case tTYPEDEF: + dotypedef(); + break; case tSTRUCT: declstruct(); break; @@ -2996,6 +3000,13 @@ static int consume_line() static int parse_new_typename(const token_t *tok) { + token_t tmp; + + if (!tok) { + lextok(&tmp); + tok = &tmp; + } + switch (tok->id) { case tINT: return 0; @@ -4176,6 +4187,85 @@ cleanup: } } +/** + * function-type ::= "(" function-type-inner ")" + * | function-type-inner + * function-type-inner ::= "function" type-expr "(" new-style-args ")" + */ +static void parse_function_type(functag_t *type) +{ + memset(type, 0, sizeof(*type)); + + int lparen = matchtoken('('); + needtoken(tFUNCTION); + + type->ret_tag = parse_new_typename(NULL); + type->type = uPUBLIC; + + needtoken('('); + + while (!matchtoken(')')) { + declinfo_t decl; + + // Initialize. + memset(&decl, 0, sizeof(decl)); + decl.type.ident = iVARIABLE; + + parse_new_decl(&decl, NULL, DECLFLAG_ARGUMENT); + + // Eat optional symbol name. + matchtoken(tSYMBOL); + + // Error once when we're past max args. + if (type->argcount == sARGS_MAX) { + error(45); + continue; + } + + funcarg_t *arg = &type->args[type->argcount++]; + arg->tagcount = 1; + arg->tags[0] = decl.type.tag; + arg->dimcount = decl.type.numdim; + memcpy(arg->dims, decl.type.dim, arg->dimcount * sizeof(decl.type.dim[0])); + arg->fconst = (decl.type.usage & uCONST) ? TRUE : FALSE; + if (decl.type.ident == iARRAY) + arg->ident = iREFARRAY; + else + arg->ident = decl.type.ident; + + if (!matchtoken(',')) { + needtoken(')'); + break; + } + } + + if (lparen) + needtoken(')'); + + require_newline(TRUE); + errorset(sRESET, 0); +} + +static void dotypedef() +{ + token_ident_t ident; + if (!needsymbol(&ident)) + return; + + int prev_tag = pc_findtag(ident.name); + if (prev_tag != -1 && !(prev_tag & FUNCTAG)) + error(94); + + needtoken('='); + + funcenum_t *def = funcenums_add(ident.name); + + functag_t type; + parse_function_type(&type); + functags_add(def, &type); +} + + /** * dofuncenum - declare function enumerations */ diff --git a/sourcepawn/compiler/sc2.c b/sourcepawn/compiler/sc2.c index 8b10176b..f1b6505d 100644 --- a/sourcepawn/compiler/sc2.c +++ b/sourcepawn/compiler/sc2.c @@ -1961,7 +1961,7 @@ char *sc_tokens[] = { "public", "return", "sizeof", "sleep", "static", "stock", "struct", "switch", - "tagof", "*then", + "tagof", "*then", "typedef", "void", "while", "#assert", "#define", "#else", "#elseif", "#emit", "#endif", "#endinput", @@ -1969,7 +1969,7 @@ char *sc_tokens[] = { "#tryinclude", "#undef", ";", ";", "-integer value-", "-rational value-", "-identifier-", "-label-", "-string-" - }; +}; static full_token_t *advance_token_ptr() { diff --git a/sourcepawn/compiler/sctracker.h b/sourcepawn/compiler/sctracker.h index 256ec266..439d97b4 100644 --- a/sourcepawn/compiler/sctracker.h +++ b/sourcepawn/compiler/sctracker.h @@ -22,7 +22,7 @@ typedef struct funcarg_s int tagcount; int tags[sTAGS_MAX]; int dimcount; - cell dims[sDIMEN_MAX]; + int dims[sDIMEN_MAX]; int ident; int fconst; int ommittable;