Raised This Month: $51 Target: $400
 12% 

How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 01-08-2016 , 09:13   How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?
Reply With Quote #1

Hi, I know how catch them and format my string. Example:
Code:
stock client_print_color_internal( player_id, message[], any: ... ) {     new formated_message[ MAX_COLOR_MESSAGE ]     vformat( formated_message, charsmax( formated_message ), message, 3 )     client_print_color( player_id, print_team_default, formated_message ) }

I know how catch them one by one. Example:
Code:
stock client_print_color_internal( player_id, message[], any: ... ) {     new params_number = numargs();     new argument_index     if( params_number >= 3 )     {         for( argument_index = 2; argument_index < params_number; argument_index++ )         {         ... too much code, more optimized to use vformat for once. }

But how to pass all they at once? Example:
Code:
stock client_print_color_internal( player_id, message[], any: ... ) {     client_print_color( player_id, print_team_default, message, any ) }

Obs: This client_print_color is just an example, it is not the intend to use.
__________________
Plugin: Sublime Text - ITE , Galileo
Multi-Mod: Manager / Plugin / Server

Support me on Patreon, Ko-fi, Liberapay or Open Collective

Last edited by addons_zz; 01-08-2016 at 09:16. Reason: spelling fix
addons_zz is offline
klippy
AlliedModders Donor
Join Date: May 2013
Location: Serbia
Old 01-08-2016 , 09:45   Re: How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?
Reply With Quote #2

I don't think there's a way without using the dirty #emit. What are you really trying to do?
klippy is offline
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 01-08-2016 , 10:21   Re: How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?
Reply With Quote #3

Nothing obscure, just easily re-pass, as in distribute along functions, if I do not like to use them, at my actual/current function.

Obs: With easily I mean without performance loss, as receiving and re-passing a string by reference.
__________________
Plugin: Sublime Text - ITE , Galileo
Multi-Mod: Manager / Plugin / Server

Support me on Patreon, Ko-fi, Liberapay or Open Collective

Last edited by addons_zz; 01-08-2016 at 10:42. Reason: with easily
addons_zz is offline
klippy
AlliedModders Donor
Join Date: May 2013
Location: Serbia
Old 01-08-2016 , 14:47   Re: How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?
Reply With Quote #4

I have no idea why did I do this, I guess I have too much free time on my hands...
Did this just for fun, I wouldn't really advise you to use it... But hey, it works!

PHP Code:
#include <amxmodx>


#define PLUGIN "New Plug-In"
#define VERSION "v1.0.0beta"
#define AUTHOR "KliPPy"

#pragma semicolon true


public plugin_init() {
    
register_plugin(PLUGINVERSIONAUTHOR);
    
    
register_clcmd("say va""cmdVa");
}

public 
cmdVa() {
    
pass_variadic("%s %i %s %i""Hello world"69"#emit is dirty"1337);
}

// Unfortunately, the compiler crashes if we try to SYSREQ.C a native that hasn't been used before in a script
// This is just a little fix for that
public __may_never_be_called() {
    
client_print(00, {0});
}

pass_variadic(const szFormat[], any: ...) {

    
// We want to create such native call:
    // client_print(0, print_chat, szFormat, ...);
    
    
new iArgnum numargs();
    
// +2 because we have to pass "print_chat" and "0" to a native
    
new iBytesnum = (iArgnum 2) * 4;
    
// We have to declare iArg here or we'll corrupt the stack.
    // No variable declarations/freeing can be done while we are pushing parameters
    
new iArg;
    
    
// We push each "variadic" parameters to the stack
    
for(iArg iArgnum 8iArg 12iArg -= 4) {
        
#emit LCTRL 5
        #emit LOAD.S.alt iArg
        #emit ADD
        #emit LOAD.I
        #emit PUSH.pri
    
}
    
    
// Okay, we've pushed all "variadic" parameters, let's push szFormat now
    #emit PUSH.S szFormat
    
    // We have yet to push print_chat and 0
    #emit PUSH.C print_chat
    #emit PUSH.C 0
    
    // Almost done, now we have to push the the number of bytes we've previously pushed to the native
    // It is equal to argument count * 4
    #emit PUSH.S iBytesnum
    
    // Finally, call the native
    #emit SYSREQ.C client_print
    
    // Now we have to free memory on stack used by parameters; we'll do it by moving the stack pointer up
    #emit LOAD.S.pri iBytesnum
    #emit ADD.C 4
    #emit MOVE.alt
    #emit LCTRL 4
    #emit ADD
    #emit SCTRL 4

klippy is offline
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 01-08-2016 , 16:45   Re: How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?
Reply With Quote #5

Awesome and thanks. It is very more optimized than what I was thinking using 'native getarg(arg, index = 0);' to retried all arguments, including strings, floats and integers then to re-pass them.

And about the preprocessor, is implemented or can be, such like this below using variadic arguments?
Quote:
Originally Posted by addons_zz View Post
Code:
#if AMXX_VERSION_NUM < 183 \     #define LANG_PLAYER_COLORED players_ids[ i ]     #define PRINT_COLORED_TEXT(%1,...) \     { \         new i = 0; \         new players_ids[ 32 ]; \         players_ids[i] = %1; \         \         if( players_ids[i] ) \         { \             client_print_color_internal( %1, __VA_ARGS__ ); \         } \         else \         { \             new playerIndex_idsCounter; \             \             get_players( players_ids, playerIndex_idsCounter, "ch" ); \             \             for( ; i < playerIndex_idsCounter; i++ ) \             { \                 client_print_color_internal( %1, __VA_ARGS__ ); \             } \         } \     } #else     #define LANG_PLAYER_COLORED LANG_PLAYER     #define PRINT_COLORED_TEXT(%1,...) \         client_print_color( %1, print_team_default, __VA_ARGS__ ); #endif
__________________
Plugin: Sublime Text - ITE , Galileo
Multi-Mod: Manager / Plugin / Server

Support me on Patreon, Ko-fi, Liberapay or Open Collective

Last edited by addons_zz; 01-09-2016 at 03:47. Reason: spelling fix
addons_zz is offline
klippy
AlliedModders Donor
Join Date: May 2013
Location: Serbia
Old 01-08-2016 , 17:05   Re: How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?
Reply With Quote #6

I have no idea what you are trying to do with that macro, but variadic macros are not supported in Pawn.
Also, in Pawn macros do not expand the same way they do in C++, and because of that we don't even need variadic macros. This should work with no problems:
Code:
#define PRINT_COLORED_TEXT(%0) client_print_color_internal(%0)
If you, for example, write this in your code:
Code:
PRINT_COLORED_TEXT(id, "%s %s", "Yoo bro", "I'm awesome");
It will simply expand to:
Code:
client_print_color_internal(id, "%s %s", "Yoo bro", "I'm awesome");
Pawn preprocessor is not aware of arguments in macros. It sees everything between ( and ) (if you define a macro with a single argument) as a single argument, commas don't mean anything to it.

Last edited by klippy; 01-08-2016 at 17:11.
klippy is offline
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 01-08-2016 , 17:14   Re: How to repass variadic arguments (ellipsis) on Amx Mod X Pawn?
Reply With Quote #7

Quote:
Originally Posted by KliPPy View Post
Pawn preprocessor is not aware of arguments in macros. It sees everything between ( and ) (if you define a macro with a single argument) as a single argument, commas don't mean anything to it.
Sure they mean, if do not, I could not write this:
Code:
#define PRINT_COLORED_MESSAGE(%1,%2) \     { \         message_begin( MSG_ONE_UNRELIABLE, get_user_msgid( "SayText" ), _, %1 ); \         write_byte( %1 ); \         write_string( %2 ); \         message_end(); \     } ...     PRINT_COLORED_MESSAGE( player_id, formated_message ) ...
Quote:
Originally Posted by KliPPy View Post
I have no idea what you are trying to do with that macro, but variadic macros are not supported in Pawn.
And that example was bad, this should clear things:
Code:
#if AMXX_VERSION_NUM < 183     #define PRINT_COLORED_TEXT(%1,...) \         client_print_chat( %1, __VA_ARGS__ ); #else     #define PRINT_COLORED_TEXT(%1,...) \         client_print_color( %1, print_team_default,__VA_ARGS__ ); #endif
Quote:
Originally Posted by KliPPy View Post
Also, in Pawn macros do not expand the same way they do in C++, and because of that we don't even need variadic macros. This should work with no problems:
Code:
#define PRINT_COLORED_TEXT(%0) client_print_color_internal(%0)
I already use it as a whole arguments as you showed, example:
Spoiler
__________________
Plugin: Sublime Text - ITE , Galileo
Multi-Mod: Manager / Plugin / Server

Support me on Patreon, Ko-fi, Liberapay or Open Collective

Last edited by addons_zz; 01-09-2016 at 12:14. Reason: spelling fix
addons_zz is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 12:00.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode