Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
User name:
Password:
Save Password
Forgot your password?

 All Forums
 Visual Assist
 Feature Requests
 Parse multi-line #define calls
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

Hexagonal
Senior Member

35 Posts

Posted - Jan 16 2012 :  10:50:31 AM  Show Profile  Reply with Quote
Hi.

I had hard time to find why VA doesn't expand my macros and doesn't make syntax coloring.

One reason is multi-line macro call:

Example 1:

#define TEST_MACRO(Kit) struct Kit
TEST_MACRO(MyStruct);
MyStruct myInstance; // <== MyStruct is highlighted


Example 2:

#define TEST_MACRO(Kit) struct Kit

TEST_MACRO
(
  MyStruct
);

MyStruct myInstance; // <== MyStruct is NOT highlighted


VA team, please implement it, because for macros with many parameters, it's plain impossible to use single-line call.

One example is a list of Type/name pairs, which can easily result in 10-20 parameters. Or look to BOOST.PREPROCESSOR, very widely used library.

Edited by - Hexagonal on Jan 16 2012 10:54:52 AM

feline
Whole Tomato Software

United Kingdom
18952 Posts

Posted - Jan 16 2012 :  6:20:04 PM  Show Profile  Reply with Quote
I am confused, in your first macro example you are passing the expected parameter, but in your second example you are not passing any parameter. Unless I am missing something, this is not going to produce valid code.

Adding a parameter helps with some of the colouring, but it does not really fix this. I assume in reality you are doing something more complex than just using a macro to add the keyword "struct", since this seems like a needless complication.

zen is the art of being at one with the two'ness
Go to Top of Page

Hexagonal
Senior Member

35 Posts

Posted - Jan 17 2012 :  01:54:49 AM  Show Profile  Reply with Quote
Hi Feline!

Yes, in reality such macros are more complex and make more sense. It's just an example.

From the C++ preprocessor point of view, example1 and example2 are identical. Both do call the macro with one parameter. Both are valid and compile okay.

It's like calling function in C, whitespace doesn't really matter.
All following examples are valid:


#define TEST(Type, val) \  Type val;

TEST(int, var1)

TEST (int, var2)

TEST (
  int, 
  var3)

TEST 
(
  int,
  var4
)

TEST 

  (

    int,

    var5

  )


ISO/IEC 9899:TC2 says in 6.10.3.10: "Within the sequence of preprocessing tokens making up an
invocation of a function-like macro, new-line is considered a normal white-space
character."

Even for macro definition, if I understand correctly, the only requirement is that the macro name should be immediately followed by (,
all other can be split with whitespace, and newline can be continued with \\ character.

MAX example that compiles okay with VISUAL C (you can check it yourself):


  #  define \  \  TEST( \    Type, \    var \  ) \  \  Type var;

  TEST
  (
     int, 
     myVar
  )


Edited by - Hexagonal on Jan 17 2012 01:55:45 AM
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18952 Posts

Posted - Jan 17 2012 :  3:28:27 PM  Show Profile  Reply with Quote
We might be talking about different things here. Looking at your first examples, I suspect the reason VA is having problems is that you have replaced the keyword "struct" with a macro. If the code is run through a pre-processor then this is no problem at all, but VA has to try and parse the code directly, since this is the code you are working on.

Traditionally using a macro to replace words like "struct" and "class" causes our parser problems, and this is independent of how many lines the macro is spread over.

In your first original example the macro is not actually involved in implementing a structure, all VA has to work out that there is a type name in there. In the second original example the macro is involved in implementing a structure, which is a much harder thing to understand without a full pre-processor.

So are you seeing problems when you are using macros to help create structures, or only when using macros for other, possibly simpler things?

zen is the art of being at one with the two'ness
Go to Top of Page

Hexagonal
Senior Member

35 Posts

Posted - Jan 18 2012 :  01:54:28 AM  Show Profile  Reply with Quote
Actually, yes, the structures create the most problems. Complicated macros are used in different areas (automated loops, etc), but structures have important post-effect: they are not colored and member suggestions don't work.

Isn't it possible to embed a full preprocessor? There are open-source implementations, even with BSD license, so you can use it for free in commercial project. It's fast, ISO compliant, etc.
(To map the preprocessed code back to the source code is easy because it inserts #line directives in output.)

Honestly, the absence of good preprocessor is the main current VA drawback (for C/C++).

Even if you don't have access to all the project's predefined macros, it's much better to have at least #defines working.

What for dealing with incomplete code: for us users 95% correct preprocessing is still better than current 50%...

Anyway, in the first post: "example1" works and "example2" does not. The only difference is macro call spacing, right?
For example1, VA works 100% okay: highlights, makes member suggestions, etc.

Edited by - Hexagonal on Jan 18 2012 02:00:00 AM
Go to Top of Page

Hexagonal
Senior Member

35 Posts

Posted - Jan 18 2012 :  02:10:39 AM  Show Profile  Reply with Quote
Maybe I need to provide more meaningful example (typical structure creation, simplified):

#define KIT_SIMPLE2(Kit, Type0, name0, Type1, name1) \  \  struct Kit \  { \    \    Type0 name0; \    Type1 name1; \    \    inline Kit \    ( \      const Type0& name0, \      const Type1& name1 \    ) \      : \      name0(name0), \      name1(name1) \    { \    } \    \    template <typename OtherKit> \    inline Kit(const OtherKit& otherKit) \      : \      name0(otherKit.name0), \      name1(otherKit.name1) \    { \    } \    \  }

KIT_SIMPLE2(MyKit1, const void*, myPointer1, int, myParam1);

KIT_SIMPLE2
(
  MyKit2, 
  const void*, myPointer2, 
  int, myParam2
);

void testFunc(const MyKit1& kit1, const MyKit2& kit2)
{
  // <== Test here
  // Kit1: Highlight and member suggestion work.
  // Kit2: Highlight doesn't works (but member suggestion works, strangely!)
}

Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18952 Posts

Posted - Jan 18 2012 :  4:19:58 PM  Show Profile  Reply with Quote
Reading your original post again I have worked out what is confusing me, I mis-read it, taking the normal brackets for curly brackets. My mistake, apologies for that.

It looks like the problem is more specific, and smaller than it first appeared. Can you try the following test code on your system, and see how many of these structure types are not understood:

#define TEST_MACRO(Kit) struct Kit
TEST_MACRO(MyStructSingleLine);
TEST_MACRO(MyStructTwoLine
		   );
TEST_MACRO(
	MyStructThreeLine
);
TEST_MACRO
(
	MyStructFourLine
);

static void testUsingMacroDeclaredStruct()
{
	MyStructSingleLine testSingleLine;
	MyStructTwoLine testTwoLine;
	MyStructThreeLine testThreeLine;
	MyStructFourLine testFourLine;
}


for me the only one that is not understood is "testFourLine". If you are seeing the same results, can you try moving the opening round bracket onto the same line as the macro call, and see if this helps you?

As for running the code through a full blown dedicated pre-processor, this has been suggested before, but it brings its own problems. Firstly, the macros would disappear, so they would all be unknown symbols in the code. If the macros are used at all often that is going to cause problems. Next macro heavy code is likely to change a lot, and a lot of code disappear and reappear.

Then you have the problem of #if statements. Do you preprocess debug or release mode? What about all of the other conditions, and the fact that all of the inactive code simply "disappears", never to be seen again?

VA would need to parse both the raw code, which you are actually editing, and the preprocessed code, and somehow merge them back together.

The preprocessor overhead might be fairly large in some situations as well, since you have to reparse and consider the full #include chain to make sure all macros are expanded correctly, every time the code is edited. So the idea is one to consider, but not one to try lightly. Unfortunately it is not quite a simple magic answer.

zen is the art of being at one with the two'ness
Go to Top of Page

Hexagonal
Senior Member

35 Posts

Posted - Jan 19 2012 :  05:33:20 AM  Show Profile  Reply with Quote
Hi Feline.

Yes, on my system it works exactly the same way, and I can move the bracket, thank you.

Yes, I also was thinking it would require to "merge" the results. To gather macro names/signatures, it scans original code; for all the rest, it scans preprocessed code.

Conditional compilation (#if/#elseif/#else/#endif) creates a problem.
The simple solution is allowing the user to specify an initial set of global #defines for Visual Assist. It's good enough.

Main VA help is coloring, suggestions, for global identifiers and members, and function signatures. I understand that there is also such a feature as "suggestion of pieces of code" and it should work by scanning original code, but nevertheless.

Anyway, even if you don't implement full preprocessor, could you consider extending of currently supported syntax?

This is really valid code, on all compilers:

  #  define \  \  TEST( \    Type, \    var \  ) \  \  Type var;

  TEST
  (
     int, 
     myVar
  )


Especially the macro call syntax, the only real limitation is "name right before lparen", as in the example.

Edited by - Hexagonal on Jan 19 2012 06:24:47 AM
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18952 Posts

Posted - Jan 20 2012 :  10:55:03 AM  Show Profile  Reply with Quote
VA should handle the macro calls without having to put the opening bracket on the same line as the macro name:

case=53271

at least moving just this bracket is a fairly easy work around for now, and I am glad this works for you.

zen is the art of being at one with the two'ness
Go to Top of Page

Hexagonal
Senior Member

35 Posts

Posted - Jan 24 2012 :  01:10:23 AM  Show Profile  Reply with Quote
Thank you, Feline!
Go to Top of Page

Hexagonal
Senior Member

35 Posts

Posted - May 28 2012 :  03:10:41 AM  Show Profile  Reply with Quote
Hi Feline.

The issue is not yet fixed in the 1906 release.
How does case 53271 do?
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
18952 Posts

Posted - May 28 2012 :  12:42:00 PM  Show Profile  Reply with Quote
Unfortunately case=53271 has not yet been fixed. It is still in our list of things to fix, and this thread should be updated when this is done.

zen is the art of being at one with the two'ness
Go to Top of Page

Hexagonal
Senior Member

35 Posts

Posted - Jun 06 2012 :  02:40:59 AM  Show Profile  Reply with Quote
Thanks!
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
© 2023 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000