Doxygen documenting commented #define - c++

I'm new to Doxygen and recently run into a problem which I could not solve.
I have this piece of documented code:
/*!
\def nAsserts
Uncomment that line so that all asserts would be removed
*/
//#define nAsserts
and it's supposed to tell the user to uncomment that line when they wish to remove all asserts but doxygen is returning me a warning:
warning: documentation for unknown define nAsserts found
I think the problem is that doxygen ignores all commented codes so is that any way to fix this or work around it?

Not sure if it is a best option, but you can use the approach below.
Modify configuration file to include PREDEFINED parameter:
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = "DOXYGEN=1"
In your code, do the following:
#if DOXYGEN
#define nAsserts
#endif
Doxygen follows own preprocessor and can conditionally include/exclude source module sections.

Related

How can I silence all errors of a particular kind in clang-tidy?

I'm currently working on a university assignment where it is mandated that we use C-style arrays for our code. Infuriatingly, they have left the default setting for warning about C-style arrays, which means that every time I use a one I need to add a // NOLINTNEXTLINT(modernize-avoid-c-arrays), which is absolutely terrible in terms of readability.
I have tried silencing the errors using // NOLINTBEGIN(modernize-avoid-c-arrays), but since that was only introduced in clang-tidy-14, it isn't supported by our course-mandated clang-tidy-11.
As such, my only option for a clean way of silencing these errors is by modifying the configuration file. Unfortunately, I haven't found any information on how to silence errors of a particular type in the configuration file. In fact, I haven't found any documentation on the expected structure of the .clang-tidy file at all, except for some example files, none of which appear to silence any errors.
How can I silence the modernize-avoid-c-arrays error on a project-wide basis from my .clang-tidy file?
Disable a check
To disable a check in .clang-tidy, add a Checks: line, and as its
value put the name of the check, preceded by a hyphen (meaning to
disable rather than enable). For example, here is a complete
.clang-tidy file that first enables all of the modernize-* checks
(since they are not enabled by default), then disables
modernize-avoid-c-arrays:
Checks: 'modernize-*,-modernize-avoid-c-arrays'
Documentation of .clang-tidy format
The .clang-tidy format is (tersely!) specified in the
output of clang-tidy --help:
--config-file=<string> -
Specify the path of .clang-tidy or custom config file:
e.g. --config-file=/some/path/myTidyConfigFile
This option internally works exactly the same way as
--config option after reading specified config file.
Use either --config-file or --config, not both.
However, the --config-file option and its documentation are missing
in Clang+LLVM-11, so that may be why you didn't find it. They are in
Clang+LLVM-14 (I'm not sure which version introduced that option).
Nevertheless, Clang+LLVM-11 responds to the presence of .clang-tidy.
You can use the --dump-config option to have clang-tidy print its
current configuration in the .clang-tidy syntax, then trim or edit as
desired.
Related:
github gist: A general clang-tidy configuration file
SO question: Clang Tidy config format
Complete example
Input source code:
// test.cpp
// Test input for clang-tidy.
void f()
{
int arr[3];
bool b = 1;
}
// EOF
Run using the above .clang-tidy:
$ /home/scott/opt/clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/clang-tidy test.cpp --
1 warning generated.
/home/scott/wrk/learn/clang/clang-tidy-config/test.cpp:7:12: warning: converting integer literal to bool, use bool literal instead [modernize-use-bool-literals]
bool b = 1;
^
true
Without disabling modernize-avoid-c-arrays, two warnings would be
printed. (And without enabling modernize-*, nothing is printed.)

What kind of code is in that file *.cpp.. #define mdTyVzgFy4_0UFy9GimmM

I just downloaded an open source code from a library called aruco for QR code detection written in C++, and while I was examing the code I found some files that doesn't look like c++..
Would anyone understand what kind of code is that? It looks like that
#define mUXyv8dbk5ppT_acPhWw1 mFzTZaNOrvPJ32i9gU3Wr9J28M8DBzQ(a,:,[,+,c,+,:,^,Z,Z,/,-,r,O,[,;,9,e,;,P)
#define mmdgJNaGE2dbCM6TccQ56 mkzSZJDew824aa0gKauM6fZ2VRvPUyZ(^,Q,5,r,j,P,t,B,c,;,T,A,o,W,},u,*,e,7,/)
#define mVBw_rTkATYMOTRmsNe_B mGJoExPsp9LQpgvTNdOhH4AqaFjFPrq(+,W,4,t,i,o,d,2,e,P,1,A,:,a,E,S,v,F,Y,V)
#define mH9xkXr1In9WhMDYLLAkQ mhN2hPhnFFq5alNSwVOjtfx8xECWu2g(R,r,R,z,t,2,i,b,!,k,S,n,e,C,k,K,5,o,K,a)
#define mSye5PefiM2uFq__QqZRQ m_dk3EP_dRaChCeAYkjUT4mGB6eHLjG(s,Y,^,r,*,P,D,X,y,^,b,},k,4,a,=,i,X,!,v)
#define mJpQJFURUc57_1UwCTPvr mByXC_NAGVGzCcmUEv_c9mAYK8t5jBN(t,R,.,>,!,i,W,0,R,C,*,Y,A,>,K,h,T,-,*,8)
#define my9E4sAt6II28meWefBqO mu1aRcYPGwwmkdvLrXjWyYkshrNbQfZ(8,N,+,t,},r,I,T,=,C,*,h,!,m,{,/,D,y,_,T)
#define mRtPBvwiZzHWglctKPmaF msiqIfe8Aci2FIHOTIR3qsdKyqc9jUO(7,i,j,^,_,^,6,},I,<,E,-,/,d,j,=,:,N,+,s)
#endif
#ifndef _ARUCO_MarkerDetector_Impl_H
#define _ARUCO_MarkerDetector_Impl_H
#include "aruco_export.h"
#include "markerdetector.h"
#include <opencv2/imgproc/imgproc.hpp>
mH83V9yQZ4TlJHtn2Baef
aruco
mBduW7dqSuFrUAvwh7kHo
mTj14DRd7xgEPvsp5xhPs
CameraParameters mVlbuMLWi_vwpED0hDKIw
mrJuVHPe96ExiggCdsmDG
MarkerLabeler mv0LWHXRSvGJF76ckeLfO
mPXYuzTL9RZjjZA9XYUV9
MarkerDetector_Impl
mYwjl00gOK3Vja3UkLMIP
friend mukY8albO2VdJSsWPXwW4
MarkerDetector mD07x3flmZMPVC6kwqG6P
public:
MarkerDetector_Impl mnODdIJiXbJxgUNOnnK7Q
mYCDBBfn03HaGvoHBxAMq
MarkerDetector_Impl mK8B3zN6mQAB0xYXFlxGO
int dict_type, mYJJZNT6RsQUQcGvcjw6s
error_correction_rate mRUhvrauugCIk8ZFUtFF5
0 mswZzmsb_awITT3YY34kR
What kind of code is in that file *.cpp.. #define mdTyVzgFy4_0UFy9GimmM
#define mdTyVzgFy4_0UFy9GimmM is a pre-processor directive that defines a macro. Macros are used to replace text during pre-processing.
Would anyone understand what kind of code is that?
Probably no human can understand it. And that is probably the reason why that has been done in the first place: It seems to be an attempt to obfuscate the source code.
You can use a pre-processor to generate the processed code to see what the compiler sees. For example, gcc -E. Note that the pre-processor will expand the include directives, so you'll need to scroll past the included files first.
Would anyone understand what kind of code is that?
Yes! Wow this is fun. That is indeed an obfuscated source code.
It is still C/C++. It is using pre-processor definitions. Basically it is a key that can be used multiple times. (like a variable).
The compiler will search for all preprocessor definitions and replaces them by the actual text.
I guess you want to deobfuscate it to have a closer look in the source code.
For gcc and clang, you can use the -E option (see similar answer) to output the preprocessor output without compiling.
To also show comments like in your sample output, you can add in the -CC and -P flags:
clang++ -E -CC -P fileA.cpp
All of the processor options for -E can be found on here, on
gcc.gnu.org.
-CC Do not discard comments, including during macro expansion. This is like -C, except that comments contained within macros are also passed
through to the output file where the macro is expanded.
-P Inhibit generation of linemarkers in the output from the preprocessor. This might be useful when running the preprocessor on
something that is not C code, and will be sent to a program which
might be confused by the linemarkers.
For the Visual C++ compiler, you can use /E.

Avoid gcc warning for (generated) tokens after preprocessing directive?

Microsoft's MIDL compiler generates C/C++ source code files that are slightly invalid, like the code in this extract:
#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
#endif !_MIDL_USE_GUIDDEF_
The tokens after #endif are ignored by Visual C++, but the Holy Standard require nothing there, and so g++ errs out, and even gcc (compiling as C) yields a warning:
H:\dev\tools\better keyboard\test>gcc com_server\com_server_i.c -c
com_server\com_server_i.c:68:8: warning: extra tokens at end of #endif directive
#endif !_MIDL_USE_GUIDDEF_
^
H:\dev\tools\better keyboard\test>_
It gets tiresome and annoying to manually fix up that code each time that it's generated.
Is there some better way to avoid this apparently unnamed warning, assuming that gcc must compile the code?
I have looked at an existing question roughly about this, but to no avail.
Converting comments into an answer.
The simplest mechanism is probably to post-process the generated code:
sed -i.bak -e 's/^#endif .*/#endif/' com_server/com_server_i.c
or equivalent. Or you can preserve the material after the #endif but put a comment there:
sed -i.bak -e 's%^#endif \(.*\)%#endif // \1%' com_server/com_server_i.c
If you're using a makefile, it is pretty easy to add the post-processing as an extra operation after the invocation of the MIDL compiler.
The cross-referenced question won't readily help; the ! cannot be removed by macro definition. Actually, the presence of a macro after the #endif elicits the warning even if the macro expands to nothing.
Have you checked the Microsoft bug reports for the MIDL compiler (to see whether it is a known problem that they decline to fix)? And have you checked the options to the MIDL compiler to see if there's anything that would fix this?

How to use doxygen preprocessor on this example fortran code?

In a fortran source file named lib_angles.f90, I have the following function declaration,
#ifdef NDEBUG
pure function la_get_quadrant(A)
#else
function la_get_quadrant(A)
#endif
I use the following settings in the config file,
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
PREDEFINED = NDEBUG
Running the latest version of doxygen (1.8.5) yields the following output,
(...)
Reading /home/pmginacio/bin/doc/test/lib_angles.f90...
Parsing file /home/pmginacio/bin/doc/test/lib_angles.f90...
********************************************************************
Error in file /home/pmginacio/bin/doc/test/lib_angles.f90 line: 38, state: 4
********************************************************************
Segmentation fault (core dumped)
The problem seems lie with the preprocessor who is not selecting one of the function declarations. When I comment one of them in the code,
#ifdef NDEBUG
pure function la_get_quadrant(A)
#else
!function la_get_quadrant(A)
#endif
doxygen executes normally.
Why? How should one use the preprocessor?

C++ command line debug argument

How can I change the value of a boolean macro when I run my program through the command line? For instance, suppose I have the following macro in my cpp file, call it MyCpp.cpp
#define DEBUG 1
How can I change this when I run my program? through the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp
I am pretty sure you specify some kind of command line option, does this ring any bells?
Also, I do NOT want to use argv[]
First, change your source code:
#ifndef DEBUG
# define DEBUG 1
#endif
Now you can say on the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp -DDEBUG=5
# ^^^^^^^^^
The command line argument -DFOO=bar has the same effect as putting #define FOO bar in your source code; you need the #ifndef guard to avoid an illegal redefinition of the macro.
Sometimes people use an auxiliary macro to prevent the definition of another macro:
#ifndef SUPPRESS_FOO
# define FOO
#endif
// ... later
#ifdef FOO
// ...
#endif
Now say -DSUPPRESS_FOO to not define FOO in the code...
How can I change the value of a boolean macro when I run my program through the command line?
As it stands, you can't. You are using a preprocessor symbol so the decision as to whether debug information should be printed is a compile time decision. You are going to have to change that compile-time DEBUG symbol to a run-time variable that you set by parsing the command line, via some configuration file read in at run time, or both.
Parsing the command line isn't that hard. There are plenty of low-level C-style tools to help you do that. Boost has a much more powerful C++ based scheme. The trick then is to change those compile-time debug decisions to run-time decisions. At the simplest, it's not that hard: Just replace that DEBUG preprocessor symbol with a global variable. You can get quite a bit more sophisticated than this of course. Eventually you'll have a configurable logging system. Boost has that, too.
Please note the following. If you have in your c/cpp file or one of your included header files:
#define DEBUG 1
then you cannot modify this definition using the command line of the compiler (makefile). There is simply no chance. The cpp file will simply overwrite the command line setting.