[Solved] Using a #define in a #define
#1

Alright, I've been googling quite alot but I couldn't find anything giving me an answer to this yet. I am still searching but I thought that I might as well as you guys if you already had this question bother you and if you know more then I do.

My question is if it is possible to use a define in a define, e.g:
pawn Код:
#define Something(%1) \
#if defined Somethingelse \
  // do something with %1 \
#endif
Everytime I seem to try it with anything I could think of, I end up having these two errors:

Код:
error 075: input line too long (after substitutions)
error 010: invalid function or declaration
Which is:
Error 075:
Either the source file contains a very long line, or text substitutions
make a line that was initially of acceptable length grow beyond its
bounds. This may be caused by a text substitution that causes
recursive substitution (the pattern matching a portion of the
replacement text, so that this part of the replacement text is also
matched and replaced, and so forth).
Error 010:
The compiler expects a declaration of a global variable or of a
function at the current location, but it cannot interpret it as such.

Well, this is slightly what I am trying to do:

pawn Код:
#define Something(%1) \
#if defined Somethingelse \
  new %1; \
#endif
Reply
#2

To do this, compiler source code must be changed because it searches for keywords(such as #define, #if, etc.) and if matched, it does what writes, simple as that.
In other words, function-like/object-like macro cant contain itself...
Reply
#3

Damnit...

Thanks for the reply mate
Reply
#4

Thanks Alex, but that wasn't what I was looking for. It wasn't a variable that bothered me in pawn, it was a const expression when declaring a variable type. Anyway. It doesn't seem to work yet. Doesn't make me give up though, gonna find a work around for it.
Solved anyway.
Reply
#5

Right..,

Well.. I did some small tests when you explained me the & operator. Well, this was a small test I had done:

pawn Код:
#include <a_samp>

main()
{
  new ExE_Count_Test = strlen("012345678901234567890123456789012345678901234567890123456789012");
  if(!(512&ExE_Count_Test))
  {  
    if(!(256&ExE_Count_Test))
    {  
      if(!(128&ExE_Count_Test))
      {  
        if(!(64&ExE_Count_Test))
        {
          if(!(32&ExE_Count_Test))
          {
            if(!(16&ExE_Count_Test))
            {
              if(!(8&ExE_Count_Test))
              {
                if(!(4&ExE_Count_Test))
                {
                  if(!(2&ExE_Count_Test))
                  {
                     print("String to small, could not be created!");
                     return 1;
                 }
                 new Test[4];
                 print("Created it with 4");
                 return 1;
               }
               new Test[8];
               print("Created it with 8");
               return 1;
              }  
              new Test[16];
                print("Created it with 16");
              return 1;
            }
            new Test[32];
            print("Created it with 32");
             return 1;
          }
          new Test[64];
          print("Created it with 64");
          return 1;
        }
        new Test[128];
        print("Created it with 128");
         return 1;
      }
      new Test[256];
      print("Created it with 256");
      return 1;
    }
    new Test[512];
    print("Created it with 512");
     return 1;
  }
  return 1;
}
(Couldn't get the indent any better...sa-mp forums = no code lol)

Then I thought this could be useful on making a string and people wouldn't have to "count" how long it is anymore or anything, it would auto-create the string as needed. (Yes, I am a lazy bastard).

So, I continued with the thought and did some weird #defines, like this one here:

pawn Код:
#define ExE_Initstr(%1,%2); \
new ExE_Count_%1 = strlen(%2); \
if(256&ExE_Count_%1) { #define EXECOUNT 512 } \
if(128&ExE_Count_%1) { #define EXECOUNT 256 } \
if(64&ExE_Count_%1) { #define EXECOUNT 128 } \
if(32&ExE_Count_%1) { #define EXECOUNT 64 } \
if(16&ExE_Count_%1) { #define EXECOUNT 32 } \
if(8&ExE_Count_%1) { #define EXECOUNT 16 } \
if(4&ExE_Count_%1) { #define EXECOUNT 8 } \
if(2&ExE_Count_%1) { #define EXECOUNT 4 }
And combined that with:

pawn Код:
#define ExE_Createstr(%1); \
new %1[EXECOUNT];
Though it continued to get even more stupid, while the solution was right infront of my face... I did even worse things like:

pawn Код:
#define ExE_Createstr(%1); ExE_Check1 ExE_Check2(%1) ExE_Check3 ExE_Check4
#define ExE_Check1 #if defined EXECOUNT_512
#define ExE_Check2(%1) new %1[512];
#define ExE_Check3 #undef EXECOUNT_512
#define ExE_Check4 #endif
Right.. I did more but I am not going to get into to much detail. Now I figured a way easier way which works just as good...

pawn Код:
#include <a_samp>

new ExE_Count;


stock ExE_Initstr(str[])
{
  ExE_Count=0;
  ExE_Count=strlen(str);
  if(256&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 512
  }
  if(128&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 256
  }
  if(64&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 128
  }
  if(32&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 64
  }
  if(16&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 32
  }
  if(8&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 16
  }
  if(4&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 8
  }
  if(2&ExE_Count)
  {
    #if defined EXECOUNT
      #undef EXECOUNT
    #endif
    #define EXECOUNT 4
  }
}

#define ExE_Createstr(%1,%2); \
ExE_Initstr(%2);\
new %1[EXECOUNT];


main()
{
  ExE_Createstr(Testing, "Hello, This is a Test for a small string optimization which is easy to use.. even though its retarded lol");
  format(Testing, sizeof(Testing), "Hello, This is a Test for a small string optimization which is easy to use.. even though its retarded lol");
  print(Testing);
  return 1;
}
That works fine. You can also make a permission system in the same way. Just making perms like, e.g.

pawn Код:
#define PERM_A 1
#define PERM_B 2
#define PERM_C 4
Then you add them together, like, if you wana give him perm A and C, you add 4+1 = 5. Now you just check like:
pawn Код:
if(!(5&PERM_C))
{
  print("He aint got perm C");
}
else
{
  print("Hes got perm C");
}
Output:
Код:
Hes got perm C
Anyway.. this case is solved.. sorry if I went to much in detail and it probably was unnecessary.
Reply
#6

Or changing compiler's sources to support dynamic arrays
Reply
#7

I did figure that too. I was testing my script AFTER I had posted it and ended up always being on the 4. Well, debugged a bit, read there and here and figured it... Oh well. I am going to have a look in your malloc system I guess.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)