Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
 All Forums
 Visual Assist
 Technical Support
 Hiding wrapper macros from the VAX parser?

You must be registered to post a reply.
Click here to register.

Screensize:
UserName:
Password:
Format: BoldItalicizeUnderlineStrikethrough Align leftCenterAlign right Insert horizontal ruleUpload and insert imageInsert hyperlinkInsert email addressInsert codeInsert quoted textInsert listInsert Emoji
   
Message:

Forum code is on.
Html is off.

 
Check to subscribe to this topic.
   

T O P I C    R E V I E W
pbrown Posted - Sep 19 2008 : 12:55:14 PM
I have a project that includes a set of macros that wrap system library functions that are define in a combination of standard headers and headers in the project itself. For example, such a wrapper might have lines like:

#define malloc wrapped_malloc

When writing real project code, you would write stuff like:

void *ptr = malloc(128);

which would be redirected to wrapped_malloc() instead.

When writing code invoking malloc, VAX would normally put up the parameter list from the prototype. However, because of the wrappers, there are multiple definitions of malloc, and VAX pops up the useless wrapper one by default. The definition is "1 of 2", and if I push the down arrow, it picks the real definition. Note that malloc is a bad example here, as there is only one parameter with an obvious meaning. The real project has many wrappers, including ones for functions with quite a few parameters.

I don't really want to do the scrolling thing -- I want VAX to ignore the wrappers completely.

I can successfully hide the wrappers if I do BOTH of these things:

* remove the wrappers from the project file
* comment out the #include of the wrapper files

The former isn't a big deal, but the latter is since the code doesn't compile if I kill the #include. Doing only one of these two fails to hide the wrappers.

I've tried wrapping the #include with #ifdef's using a symbol in stdafx.h. I've tried the FAQ registry hack for deep macro expansion. #if 0 doesn't even work. I assume that the reason that none of these work is that VAX's quick-and-dirty parser ignores #ifdef's entirely.

I hope my description makes sense. Can anyone think of a way to kill these symbols?
9   L A T E S T    R E P L I E S    (Newest First)
feline Posted - Sep 26 2008 : 09:50:50 AM
I agree that an ability to tell VA to ignore specific pieces of code would fix your problem. However this is something that is only going to help a very small number of users, in fairly specific situations. Our general problem is getting VA to parse more code, not less

I have thought of a simple solution, how about simply doing:

#define VA_IGNORE_INCLUDE_FILE_NAME "special_file.h"

#include VA_IGNORE_INCLUDE_FILE_NAME


since you can use #ifdef #endif blocks around #include statements under Unix (I have done this) GCC should have no problems with this code, since macro's should be evaluated before #include lines are expanded.

I have just checked and this compiles quite happily in VS2005.

If this works for you, you just need to add a suitable dummy #define into VA's StdAfx.h file.
pbrown Posted - Sep 25 2008 : 1:45:50 PM
I don't think you can define a macro to expand to an #include construct that actually gets interpreted as an include by a real preprocessor. Even if you could, I couldn't get away with adding such a hack to our code.

"#pragma include_alias" won't work for me because the code also needs to compile on GCC.

Looks like there's probably no easy approach that will work for me, short of moving the files. This isn't a huge deal for me. This issue seems to be highly correlated with the following feature request thread:

http://forum.wholetomato.com/forum/topic.asp?TOPIC_ID=5931
feline Posted - Sep 25 2008 : 07:54:33 AM
*sigh* I had hoped that would work better.

My next idea was to do something like:

#define VA_IGNORE_THIS_INCLUDE #include "special_file.h"

but I cannot remember how to make this work. I believe there is a technique you can use to place a # into a macro, but I am not sure what it is, and a quick web search has not found it. However I have found something else. Can you try this code instead please:

#pragma include_alias( "va_ignore_header.h", "special_file.h" )
#include "va_ignore_header.h"

This compiles quite happily for me in VS2005, and VA does not understand / cannot find the file "va_ignore_header.h". So if your compiler supports this #pragma command then this may work for you as well.
pbrown Posted - Sep 25 2008 : 12:56:47 AM
This technique doesn't seem to work with the current parser (I'm using 1649). I added the lines to stdafx.h, rebuilt the database, and opened my project.

I wrapped my header files inside the START/END definitions, after removing a few C-style comments that might confuse the parser -- after my changes, only C++-style line comments were used. That seemed to be the safest thing to do, since the wrapper files are still in the project, and the headers are included in a few other C files, besides my uber-header. I still get four prototypes.

I did a simple experiment, adding the following code:

VAX_IGNORE_CODE_START
int foo;
VAX_IGNORE_CODE_END
int getfoo(void) 
{
  return foo;
}

Alt-G could still find "foo", even after manually asking for a reparse of that file. Commenting the "int foo" line out hid it, and uncommenting brought it back. The interesting thing is that VAX_IGNORE_CODE_START was in italics (stable symbol) and Alt-G found it in stdafx.h. VAX_IGNORE_CODE_END was not in italics and not found by Alt-G.

If I changed my stdafx.h to

#define VAX_IGNORE_CODE_START /*
/**/
#define VAX_IGNORE_CODE_END */

Note that I'm adding a comment line that would close the opened comment on the "START" line, both the START/END markers show up in italic in my test code and can be found with Alt-G. But it still fails to hide my definition of "foo".
feline Posted - Sep 24 2008 : 07:49:04 AM
You may be able to hide the #include lines from VA in the current build. If you edit VA's "StdAfx.h" file as explained in this FAQ entry:

http://docs.wholetomato.com?W302

and add the entry:

#define VAX_IGNORE_CODE_START /*
#define VAX_IGNORE_CODE_END */

at the bottom. This file is used to help VA's parser with difficult code, and can be used to work around odd effects. After modifying this file you need to rebuild the VA symbol database for the changes to take effect:

VA Options -> Performance -> General -> Rebuild symbol databases

Then wrap the #include line with these #defines so it becomes:

VAX_IGNORE_CODE_START
#include "special_file.h"
VAX_IGNORE_CODE_END


Note you will probably need to add:

#define VAX_IGNORE_CODE_START
#define VAX_IGNORE_CODE_END

to your solution so that it will compile correctly.

I have not tested this situation here, but I have used this method before to hide code from VA, so it stands a good chance of working.
pbrown Posted - Sep 23 2008 : 9:47:53 PM
I had thought about the "put it in a directory the IDE project doesn't know about" suggestion. That would be trivial if I was starting a new project. But the wrappers live in the same directory as a bunch of headers I do care about. The project is shared with enough people that I would have a hard time sneaking the files into a separate directory, or cooking up some bogus excuse to move them. :-)

For the "IDE standard include path" suggestion, I assume it would have the same problem as the bogus directory suggestion -- it would effectively hide any files in that directory, including the non-wrapper headers I do care about.

Since I do have the flexibility of controlling the project settings and the makefile settings independently, it doesn't seem like the IDE approach would ever be better than the "va_ignore_this" directory approach.
feline Posted - Sep 23 2008 : 3:37:17 PM
I think the solution is to remove the header file from the project And move it to a directory that VA does not know about. So your code will contain the line:

#include "special_file.h"

but this file will live in the directory "va_ignore_this\\"

If you simply update the project settings in the IDE so that the IDE its self can find this header file then VA will be able to find it, since it reads the IDE settings.

Can you reference this "new" directory in your build process, but not in the IDE?

The other approach is to add this directory to the IDE's include directory list:

IDE tools menu -> Options -> Projects and Solutions -> VC++ Directories -> Show directories for = Include files

and set:

VA Options -> Projects -> C/C++ Directories -> Platform

to custom and make sure that this directory is not in the list. Once you can place the caret into the file name in the #include line and VA does not show you the file's path in the context and definition fields then this should work.

However please note that if you open this header file in the IDE to add a new macro VA will parse it, which is the very thing you are trying to avoid.

Does this make sense?
pbrown Posted - Sep 21 2008 : 1:38:56 PM
Sadly, the stdafx.h technique you suggested has the opposite of the intended effect. Prior to the change, I had 4 completions in the real project. There are three separate wrapper #defines, one of which is selected by another #define. The fourth completion was the function prototype. After the stdafx.h change, three wrappers were still presented, but the system header prototype was gone.

Had it worked, it still wouldn't won't work that well for my specific case, as there are several hundred functions that are wrapped this way, and that list grows occasionally.

Is there any specific rhyme or reason to the order in which symbols are presented? For example, are #defines always before function prototypes? Are definitions from files in the project used in the order they appear in the project file? If definitions are picked up from the #include files, does the order in which they are included matter?

I do have some flexibility in the project file definition. The actual build is based on a command-line build system. I build my project files via a script that looks for C/H files in some directories. I could easily exclude the wrapper files from the project, but as mentioned, that doesn't help since they still need to be #included. I also have some flexibility in the code. These wrappers are #included by an uber-header that serves as a PCH. I would probably be able to stick some dummy #include lines into this header if it helps outsmart VAX's parser. For example, if things depend on #include order, I could put some fake #includes in the "right place".

#ifdef NEVER_GOING_TO_BE_INCLUDED
#include "special_file.h"
#endif

One other possibility, which I assume is not supported by the current build, would be some sort of directive to have the parser ignore blocks of code

// VAX_IGNORE_CODE_START
...
// VAX_IGNORE_CODE_END
accord Posted - Sep 19 2008 : 2:57:07 PM
About #ifdef: Visual Assist parses both active and inactive codepaths to be able to help when you working with them.

I have an idea to make the original functions the default: Visual Assist have a file called "stdafx.h". It was designed to help parsing difficult codes:

http://docs.wholetomato.com?W302

But we will use this file for a different reason: to make the original function's parameter tooltip the default.
Here is how to do it: if you put your wrapper defines to this file, like:

#define malloc wrapped_malloc

you will get the original functions by default. This is because Visual Assist parses this stdafx.h first, and always the lastly defined functions will be the default. In this case Visual Assist will parse your wrappers first, and then system headers later. So it will find malloc's definition after the wrapper. Lastly it will find your defines also in project's header, but already defined #defines are skipped.
(You got wrapper parameter infos by default, because system headers are parsed before project's headers.)

This is only a theory, but it should work, so I think it worth a try
I hope this all makes sense.

© 2023 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000