Doxygen - Expand macros but ignore #if? - macros

Is it possible to tell Doxygen to expand macros but ignore other preprocessor directives?
Take the following into account:
#if defined(linux)
#define OS_LINUX
int function() { /* ... */ }
// Other functions defined for Linux
#elif defined(__WIN32__)
#define OS_WINDOWS
int function() { /* ... */ }
// Other functions defined for Windows
#else
#error "OS unsupported."
#endif
In this case, I want the functions for both Windows and Linux to show up, but I also want the macros OS_LINUX and OS_WINDOWS to show up in the documentation as well. Is there a way to document both macros while ignoring the #ifs?

No, you cannot do that you will have to build the documentation for each configuration separately. However if both Windows and Linux have the same interfaces defined, the documentation will surely be the same for both functions in any case?
By default if Doxygen finds documentation for a declaration in a header and documentation for corresponding definitions in source-files, the documentation in the header will be used. In this case you can use this to your advantage by only placing Doxygen mark-up in the header files. Normally the interfaces will be identical cross-platform and you will have a single header, but multiple implementations for each platform, either in separate sources or using conditional compilation.

Related

How to customize eclipse CDT code templates

I need the code I am writing for a project to match some style guidelines. However the standard templates included with CDT don't match this style. Especially the layout of the header guards is not the way it should be. I had a look at the template and for my Eclipse it looks like this:
${filecomment}
#ifndef ${include_guard_symbol}
#define ${include_guard_symbol}
${typecomment}
${declarations}
#endif /* ${include_guard_symbol} */
So I am guessing the variable ${include_guard_symbol} is set somewhere in the CDT, but is it possible to change this setting without needing to modify the CDT itself?
On a slightly different, but related note:
Is it possible to add your own templates, so you just could add new files of other types (test-cases, specialized classes etc) using the normal new dialog for the project?
We've had a similar struggle on our project. One solution is to throw out ${include_guard_symbol} in the template all together, and define it yourself, possibly using some of the other predefined variables. Something like this:
${filecomment}
#ifndef MyProject_${file_base}_h
#define MyProject_${file_base}_h
${typecomment}
${declarations}
#endif /* MyProject_${file_base}_h */
So for a header file named inc/Foo.h, the include guard would be inserted like this:
#ifndef MyProject_Foo_h
#define MyProject_Foo_h
Unfortunately, there doesn't seem to be a way to customize much beyond that. For example, if I defined a class nested in a namespace, I might want to put the namespace as part of the include guard. I can't find a way to do that in eclipse, currently.
So in the Preferences dialog under C/C++ -> Code Style -> Code Templates you can modify the template to be closer to what you need, for example if you need the namespace in the guard, you can do something like.
${filecomment}
#ifndef ${namespace_name}_${include_guard_symbol}
#define ${namespace_name}_${include_guard_symbol}
${includes}
${namespace_begin}
${declarations}
${namespace_end}
#endif /* ${namespace_name}_${include_guard_symbol} */

How does XCode handle #import header statements in with multiple targets?

I have an XCode project with 2 targets (both are iPhone apps sharing 95% of the same code).
However, one module isn't "shareable"; the implementations are too different.
My solution (that is not working) was to add 2 subdirectories to my Classes/ folder in my project directory - one for each target. In each directory, I've placed a view controller class, called ExampleSentencesViewController. Of course, each file is compiled as part of only one of the targets - I'm looking for an "automatic switching" of which implementation to use based on the target.
Inside each target's settings, I added each directory to the "Header Search Paths" setting (each path for each target).
Oddly, it only compiles for the original target. The target I added later won't compile, claiming that I've included the same header twice (there ARE two files, to be fair). How do I get XCode to forget about the original header??
I've tried deleting the .h files out of my project, but that does not seem to help.
Any help is appreciated.
fully qualify the header paths in the separate implementation files, based on one of your defined search directories:
#include <MONProject/Source/ExampleSentencesViewController.h>
vs
#include <MONSecondProject/Source/ExampleSentencesViewController.h>
update based on clarification:
ideally, you'd create a static library for the shared code.
for a simple case... you could take the direct approach by populating a header in your project's root, named ExampleSentencesViewController.h, and populating it like so:
/* you must define either MON_BUILD_MON_FIRST_PROJECT or MON_BUILD_MON_SECOND_PROJECT at the target level */
#if (defined(MON_BUILD_MON_FIRST_PROJECT) && defined(MON_BUILD_MON_SECOND_PROJECT))
#error invalid configuration: you cannot specify both projects to be compiled
#elif defined(MON_BUILD_MON_FIRST_PROJECT)
/* some fully qualified path: */
#include <MONFirstProject/ExampleSentencesViewController.h>
#elif defined(MON_BUILD_MON_SECOND_PROJECT)
/* some other fully qualified path: */
#include <MONSecondProject/ExampleSentencesViewController.h>
#else
#error uh... which project are you trying to build?
#endif
or you could just use these defines to conditionally enable/disable the interface and implementation of the classes with duplicate names (and then just include them both in the project's declaration of:
/* MONFirstProject/ExampleSentencesViewController.h> */
#if defined(MON_BUILD_MON_FIRST_PROJECT)
#interface ExampleSentencesViewController : NSViewController
/* ... */
#end
#endif
…but this will require to include both headers in your distribution (if applicable).
some of the finer details of inclusion can vary based on how you've declared your search paths (e.g., are they recursive or not?) and whether you use copy headers build phases in your xcodeproj. maintaining both projects which share code can become messy if you've been too relaxed in your include directives, discovery options, preprocessor declarations (conditional compilation/visibility) and/or build configurations so... that's why i recommend a library for the shared bits. this conditional stuff (in the two previous examples) is error prone and doesn't evolve or scale well. doing this is also a good way to confuse other tools in the development toolkit.
in fact, i prefer this over the preprocessor (assuming you're able to distribute both classes):
- (UIViewController *)newViewControllerForMyAwesomeView {
if (IsAppMONFirstProject) {
return [[MONFirstProjectViewController alloc] init...];
}
else if (IsAppMONSecondProject) {
return [[MONSecondProjectViewController alloc] init...];
}
else {
assert(0 && "definitely break up your code, now that it is referenced by 3 or more projects");
return 0;
}
}
if you're merely maintaining two versions of the same title, then practices will be much different.
anyways... this should be enough ideas to solve your problem - you just have to determine the lesser evil.

Doxygen autolink not working to global enum types

I am trying to use Doxygen Automatic link generation to document some enum types. However, it is not generating links for the global enum types. It does generates links for the global struct types. Is there something I am missing? I am using the example provided on the link above. As required, I have documented the file in which the types are defined.
update1: I am using Doxygen version 1.6.3
update2: global structs are ok
Yeah, I had that same issue; i think doxygen thinks they are private or something stupid like that. Try using the \public. Don't forget to do the /*! on the first line
/*! \public
* Enum description goes here
*/
typedef enum {
/**
* Printer control language ZPL
*/
PRINTER_LANGUAGE_ZPL,
/**
* Printer control language CPCL
*/
PRINTER_LANGUAGE_CPCL
} PrinterLanguage;
I was having the same issue. Some header files generated a link for enums and other header files did not. You must explicitly document the file.
Here is a excerpt from this page int the documentation.
http://www.doxygen.nl/manual/docblocks.html#memberdoc
To document a global C function, typedef, enum or preprocessor
definition you must first document the file that contains it (usually
this will be a header file, because that file contains the information
that is exported to other source files).
Attention
Let's repeat that, because it is often overlooked: to document global objects (functions, typedefs, enum, macros, etc), you must
document the file in which they are defined. In other words, there
must at least be a
/*! \file */
or a
/** #file */
line in this file.

How to use #if directives in C#(3.0)

I just found two piece of code
#if CONSOLE // defined by the console version using
ournamespace.FactoryInitializer;
#endif
and
#if _NET_1_1
log4net.Config.DOMConfigurator.ConfigureAndWatch(new System.IO.FileInfo(s) );
#else
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(s) );
#endif
Can any one please tell me with a running sample( please provide a simple one) what is the significance of those code snippets and when and how to use those?
Thanks.
Sure. These refer to conditional compilation symbols which can be defined at compile-time and which control what code is actually built. Here's an example:
using System;
class Test
{
static void Main()
{
#if FOO
Console.WriteLine("FOO was defined");
#endif
#if BAR
Console.WriteLine("BAR was defined");
#endif
}
}
If you compile this with
csc Test.cs
It won't print anything. If you compile it with
csc Test.cs /D:FOO
then it will print "FOO was defined" - and obviously the same is true for BAR.
Note that these aren't the same as C++ macros - a symbol is either defined or not; it doesn't have a "replacement value" as such.
In Visual Studio, you specify which symbols should be defined in the Build tab of the project properties. Additionally, at the very start of the file you can explicitly define and undefine symbols:
#define FOO
#undef BAR
This can be important when calling methods decorated with ConditionalAttribute - such calls are ignored by the compiler if the appropriate symbol isn't defined. So if you wanted to make sure that all your Debug.Print calls came through even if you hadn't defined the DEBUG symbol for the rest of the project, you could use:
#define DEBUG
...
Debug.Print("Foo");
Personally, I don't use all this very much. Aside from anything else, it makes it easier to understand the code if you know that it will all be compiled and run at execution time.
EDIT: Just to clarify a little on terminology - #if, #line, #pragma etc are all preprocessor directives; FOO and BAR (in this case) are the conditional compilation symbols.
They're used for conditional compilation.
If CONSOLE (known as a conditional compilation symbol) is defined for the first example with #define CONSOLE, the code within #if CONSOLE and #endif will be compiled and built into the assembly, otherwise the compiler ignores the code within them.
Undefining a conditional compile symbol is via #undef e.g #undef CONSOLE. The language specification also states :
There is no requirement that
conditional compilation symbols be
explicitly declared before they are
referenced in pre-processing
expressions. Instead, undeclared
symbols are simply undefined and thus
have the value false.
Those are called preprocessor directives. Quote from the docs:
'#if' lets you begin a conditional directive,
testing a symbol or symbols
to see if they evaluate to true. If
they do evaluate to true, the compiler
evaluates all the code between the #if
and the next directive.
So basically when you compile your program with /define:symbol switch it will either evaluate the if statement or not. For example:
csc foo.cs /define:DEBUG
allows you to define the DEBUG directive and enter the #if DEBUG branch. Remember that contrary to the if statement those are purely compile time and the body of the else statement won't even be included in your compiled assembly.
Your project can have multiple configurations, the most common are Debug and Release.
In Debug mode you can output debug strings, do additional checking etc.
For example:
void a(int x){
#if DEBUG
System.Diagnostics.Debug.WriteLine("a("+x+")");
#endif
//Do stuff.
}
You can define directives project-wide in the project's properties and make debug/release builds, or you could make an application that uses different libraries for some output (OpenGL/XNA). Or as you have, #if _NET_1_1 checks if a symbol _NET_1_1 is defined, assuming that .NET FX 1.1 is used, and uses proper classes, so you can target multiple framework versions in multiple project configurations.

Exclude some classes from doxygen documentation

I am building a Qt based project, and many Qt classes are found in the target documentation.
How can I tell Doxygen to disable documentation generation for some classes? For Q.*?
Working under the assumption that what you have is something like this: (The question is a little unclear in this regard)
/**
* Some documentation for class X
*/
class X: public osg::Drawable {
...
}
And your problem is that you want to include documentation for class X, but not for class osg::Drawable, the proper technique is to use EXCLUDE_SYMBOLS. For example, in the case above use
EXCLUDE_SYMBOLS = osg::Drawable
If you want to be slightly more rigorous, you can use
EXCLUDE_SYMBOLS = osg::Drawable \
Drawable
Wild-cards are also allowed, so this will also work
EXCLUDE_SYMBOLS = osg::*
If \internal tag does not work, you can try \cond ... \endcond tags for marking a portion of code to be hidden from Doxygen.
EDIT
If you want to exclude specific files, you can use EXCLUDE_PATTERNS variable in Doxyfile configuration file.
Its not the best way but one can mark some portion of the documentation (class, members, ...) with the private. This prevents the piece of code from being included in the output documentation. (I use this to hide copy/move constructors/operators from appearing in the API documentation.)
/*!
* \brief This is included.
*/
class API
{
public:
/*!
* \brief So is this.
*/
API() noexcept;
/// \private
~API() noexcept; /* But this not, though technically public. */
private:
int m_version; /* This is not either. */
}
One should note though that this is a Doxygen extension for PHP, which according to the documentation they should not be used.
For PHP files there are a number of additional commands, that can be used inside classes to make members public, private, or protected even though the language itself doesn't support this notion.
The other option is to use the solution mouviciel provided, but it requires at least two lines.
Though not the correct answer for the detailed question it might be helpful for readers of the question title (like me). It works for classe too!