Why is doxygen truncating a parameterized macro function attribute? - doxygen

Given the following macro definition:
#if defined(__GNUC__) && __GNUC__ >= 4
#define WL_PRINTF(x, y) __attribute__((__format__(__printf__, x, y)))
#else
#define WL_PRINTF(x, y)
#endif
And given the following use, as a gcc function attribute:
typedef void (*wl_log_func_t)(const char *, va_list) WL_PRINTF(1, 0);
Doxygen seems to be truncating part of the function attribute, appearing like this:
And this:
Doxygen also truncates it similarly in other cases where I use the macro function attribute, so the problem seems consistent (it's not about this being a (typedef). It documents the macro itself just fine.
My .doxygen config is:
PROJECT_NAME = "Wayland"
PROJECT_NUMBER = 1.12.90
OUTPUT_DIRECTORY = ../../doc/doxygen
JAVADOC_AUTOBRIEF = YES
TAB_SIZE = 8
QUIET = YES
HTML_TIMESTAMP = YES
GENERATE_LATEX = NO
MAN_LINKS = YES
PREDEFINED = WL_EXPORT=
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
DOT_MULTI_TARGETS = YES
ALIASES += comment{1}="/* \1 *<!-- -->/"
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_ALL = YES
EXTRACT_STATIC = YES
GENERATE_HTML = NO
GENERATE_XML = NO
GENERATE_MAN = NO
Is there some neat way to trick Doxygen into not truncating this?

This seems to be a constraint (pronounced 'bug') in doxygen that causes it to truncate. The alternative is to remove the generation of the function attribute entirely, by adding the macro to the PREDEFINED config.

Related

Autonumbering equations in doxygen

Is is possible to number automatic number equations in doxygen markdown documentation?
Example:
page1.md:
This is Equation 1:
\f[
\label{Eq:1}
\bbox[Pearl, 10px,border:1px solid black]
{
\rho = \frac{m}{V}
}
\f]
If I put a \tag{#numberOfTheEquation} I will get the number.
But has you build the document it is very inconvenient to change every equation number if one inserts a new equation in the middle of the document.
Best Regards!
When we have a file like:
/** \file
# Math references
\f{equation}{
\alpha = \beta * \gamma
\label{eq:my_system}
\f}
The reference: \f$\eqref{eq:my_system}\f$
*/
We can use a Doxyfile like:
USE_MATHJAX = YES
EXTRA_PACKAGES = amsmath amssymb
MATHJAX_EXTENSIONS = amssymb amsmath
MATHJAX_CODEFILE = mycode.js
with mycode.js:
MathJax.Hub.Config({
TeX: { equationNumbers: { autoNumber: "AMS" } }
});
This will result in:

Matlab Load from relative path

function []= read_c3d_feat(output_list_relative)
dir_list = importdata(output_list_relative);
dim_feat = 512;
for i = 1 : size(dir_list, 1)
dir_str = char(dir_list(i));
feat_files = dir([dir_str, '/*.res5b']);
num_feat = length(feat_files);
feat = zeros(num_feat, dim_feat);
for j = 1 : num_feat
feat_path = strcat(dir_str, '/', feat_files(j).name);
...............
....................so on
Give me error like
Error using dir
Invalid path. The path must not contain a null character.
Error in read_c3d_feat (line 12)
feat_files = dir([dir_str, '/*.res5b']);
Your dir_list variable must have strings which contain null characters, as the error tells you. If you try using hard-coded strings you will see it works:
function read_c3d_feat(output_list_relative)
dir_list = {'21';'45';'18'};
for i = 1:size(dir_list, 1)
dir_str = dir_list{i}; % Loops through '21','45','18'
% The dir function now works because we know dir_str is a valid string
feat_files = dir([dir_str, '/*.res5b']);
end
end
This means you need to debug your code and find out what this line is actually assigning to dir_list:
dir_list = importdata(output_list_relative);
Note that if dir_list is a cell of text entries, you should be indexing it with curly braces as above. If instead it is a matrix (because all of the entries seem to be numerical anyway) then you should be using num2str when passing to dir:
function read_c3d_feat(output_list_relative)
dir_list = importdata(output_list_relative);
dim_feat = 512;
for i = 1:size(dir_list, 1)
feat_files = dir([num2str(dir_list(i)), '/*.res5b']);
% ...

What is RMAGICAL?

I'm trying to understand some XS code that I inherited. I've been trying to add comments to a section that invokes Perl magic stuff, but I can't find any documentation to help me understand this line:
SvRMAGICAL_off((SV *) myVar);
What is RMAGICAL for? When should one turn in on or off when working with Perl magic variables?
Update
Perlguts Illustrated is very interesting and has a little bit of info on RMAGICAL (the 'R' is for 'random'), but it doesn't say when to mess with it: http://cpansearch.perl.org/src/RURBAN/illguts-0.42/index.html
It's a flag that indicates whether a variable has "clear" magic, magic that should be called when the variable is cleared (e.g. when it's destroyed). It's used by mg_clear which is called when one attempts to do something like
undef %hash;
delete $a[4];
etc
It's derived information calculated by mg_magical that should never be touched. mg_magical will be called to update the flag when magic is added to or removed from a variable. If any of the magic attached to the scalar has a "clear" handler in its Magic Virtual Table, the scalar gets RMAGICAL set. Otherwise, it gets turned off. Effectively, this caches the information to save Perl from repeatedly checking all the magic attached to a scalar for this information.
One example use of clear magic: When a %SIG entry is cleared, the magic removes the signal handler for that signal.
Here's mg_magical:
void
Perl_mg_magical(pTHX_ SV *sv)
{
const MAGIC* mg;
PERL_ARGS_ASSERT_MG_MAGICAL;
PERL_UNUSED_CONTEXT;
SvMAGICAL_off(sv);
if ((mg = SvMAGIC(sv))) {
do {
const MGVTBL* const vtbl = mg->mg_virtual;
if (vtbl) {
if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP))
SvGMAGICAL_on(sv);
if (vtbl->svt_set)
SvSMAGICAL_on(sv);
if (vtbl->svt_clear)
SvRMAGICAL_on(sv);
}
} while ((mg = mg->mg_moremagic));
if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG)))
SvRMAGICAL_on(sv);
}
}
The SVs_RMG flag (which is what SvRMAGICAL tests for and SvRMAGICAL_on/SvRMAGICAL_off sets/clears) means that the variable has some magic associated with it other than a magic getter method (which is indicated by the SVs_GMG flag) and magic setter method (indicated by SVs_SMG).
I'm getting out of my depth, here, but examples of variables where RMAGIC is on include most of the values in %ENV (the ones that are set when the program begins, but not ones you define at run-time), the values in %! and %SIG, and stash values for named subroutines (i.e., in the program
package main;
sub foo { 42 }
$::{"foo"} is RMAGICAL and $::{"bar"} is not). Using Devel::Peek is a little bit, but not totally enlightening about what this magic might be:
$ /usr/bin/perl -MDevel::Peek -e 'Dump $ENV{HOSTNAME}'
SV = PVMG(0x8003e910) at 0x800715f0
REFCNT = 1
FLAGS = (SMG,RMG,POK,pPOK)
IV = 0
NV = 0
PV = 0x80072790 "localhost"\0
CUR = 10
LEN = 12
MAGIC = 0x800727a0
MG_VIRTUAL = &PL_vtbl_envelem
MG_TYPE = PERL_MAGIC_envelem(e)
MG_LEN = 8
MG_PTR = 0x800727c0 "HOSTNAME"
Here we see that the scalar held in $ENV{HOSTNAME} has an MG_TYPE and MG_VIRTUAL that give you the what, but not the how and why of this variable's magic. On a "regular" magical variable, these are usually (always?) PERL_MAGIC_sv and &PL_vtbl_sv:
$ /usr/bin/perl -MDevel::Peek -e 'Dump $='
SV = PVMG(0x8008e080) at 0x80071de8
REFCNT = 1
FLAGS = (GMG,SMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x80085aa8
MG_VIRTUAL = &PL_vtbl_sv
MG_TYPE = PERL_MAGIC_sv(\0)
MG_OBJ = 0x80071d58
MG_LEN = 1
MG_PTR = 0x80081ad0 "="
There is one place in the perl source where SvRMAGICAL_off is used -- in perlio.c, in the XS(XS_io_MODIFY_SCALAR_ATTRIBUTES).
XS(XS_io_MODIFY_SCALAR_ATTRIBUTES)
{
dXSARGS;
SV * const sv = SvRV(ST(1));
AV * const av = newAV();
MAGIC *mg;
int count = 0;
int i;
sv_magic(sv, MUTABLE_SV(av), PERL_MAGIC_ext, NULL, 0);
SvRMAGICAL_off(sv);
mg = mg_find(sv, PERL_MAGIC_ext);
mg->mg_virtual = &perlio_vtab;
mg_magical(sv);
Perl_warn(aTHX_ "attrib %" SVf, SVfARG(sv));
for (i = 2; i < items; i++) {
STRLEN len;
const char * const name = SvPV_const(ST(i), len);
SV * const layer = PerlIO_find_layer(aTHX_ name, len, 1);
if (layer) {
av_push(av, SvREFCNT_inc_simple_NN(layer));
}
else {
ST(count) = ST(i);
count++;
}
}
SvREFCNT_dec(av);
XSRETURN(count);
}
where for some reason (again, I'm out of my depth), they want that magic turned off during the mg_find call.

genstrings does not work with macro for NSLocalizedString

I would like to shorten "NSLocalizedString" to "_" so I'm using macro
_(x) NSLocalizedString(#x, #__FILE__)
.
But now, when I want to generate strings for localization with
find . -name \*.m | xargs genstrings
it generates nothing.
Any help?
You can tell genstrings to look for a different function by using the '-s' argument:
genstring -s MyFunctionName ....
However, MyFunctionName must follow the same naming and argument conventions as one of the built in NSLocalizeString macros.
In your case, you can not just specify the string key, you must also specify the documentation string. In fact, you should never generate a strings file without both the string and documentation. There are many languages where the actual phrase or word will depend on context. German is a great example where a car is "das auto" and more than one is "die autos". There are many more examples that include changes for gender, number, time, question versus statement, and yes versus no. The documentation string helps your translator figure out what translation to use.
In addition, the best practice is to use a key that is different from the native language word. That says use NSLocalizedStringWithDefaultValue(key, table, bundle, val, comment).
You can specify nil for the table and [NSBundle mainBundle] for the bundle argument.
You can wrap this in a shorthand, but you still have to follow the StringWithDefaultValue name and the arguments for genstrings to work.
I strongly recommend you look at the WWDC 2012 session on Localization Tips and Tricks.
Maurice
You can use the -s option of genstrings. From the man page :
-s routine
Substitutes routine for NSLocalizedString. For example, -s MyLocalString will catch calls to MyLocalString and MyLocalStringFromTable.
So I think you could try :
genstrings -s _
I had the same problem when my NSLocalizedString macro was taking 1 argument instead of 2 like genstrings expects, so i wrote i python script that does the job.
the first argument for the script is the macro name and the second is the path to your project.
import fnmatch
import os
from xml.dom import minidom
function = sys.argv[1]
rootdir = sys.argv[2]
# Generate strings from .m files
files = []
for root, dirnames, filenames in os.walk(rootdir):
for filename in fnmatch.filter(filenames, '*.m'):
files.append(os.path.join(root, filename))
strings = []
for file in files:
lineNumber = 0
for line in open(file):
lineNumber += 1
index = line.find(function)
if (index != -1):
callStr = line[index:]
index = callStr.find('#')
if (index == -1):
print 'call with a variable/macro. file: ' + file + ' line: %d' % lineNumber
else:
callStr = callStr[index+1:]
index = callStr.find('")')
callStr = callStr[:index+1]
if callStr not in strings:
strings.append(callStr)
# Write strings to file
f = open('Localizable.strings', 'w+')
for string in strings:
f.write(string + ' = ' + string + ';\n\n')
f.close()
I have improved Or Arbel's script to include the cases where there's multiple macro-calls on a single line:
import fnmatch
import os
from xml.dom import minidom
import sys
function = sys.argv[1]
rootdir = sys.argv[2]
# Generate strings from .m files
files = []
for root, dirnames, filenames in os.walk(rootdir):
for filename in fnmatch.filter(filenames, '*.m'):
files.append(os.path.join(root, filename))
strings = []
for file in files:
lineNumber = 0
for line in open(file):
lineNumber += 1
index = line.find(function)
startIndex = 0
while (index != -1):
startIndex = index+1
callStr = line[index:]
index = callStr.find('#')
if (index == -1):
print 'call with a variable/macro. file: ' + file + ' line: %d' % lineNumber
else:
callStr = callStr[index+1:]
index = callStr.find('")')
callStr = callStr[:index+1]
if callStr not in strings:
strings.append(callStr)
index = line.find(function, startIndex)
# Write strings to file
f = open('Localizable.strings', 'w+')
for string in strings:
f.write(string + ' = ' + string + ';\n\n')
f.close()

How do I change the name of Emacs auto-recovery file?

At the moment it saves the file with format:
.#main.c -> sara#sara.home.com.27017:1231918415
This makes it problematic since it ends with ".c".
I need it to be .#main.c#
Update: I have emacs 22.1
That's not the auto-recovery file, that's the link used as a locking token for the file.
update
If I tell you, will you introduce me to Summer Glau?
It's probably not going to be easy to change that; I just dug a bit and it looks like it's set in the C code. But let's ask the next question: why do you want to? I'm guessing you're hitting a regular expression for .c files that you don't want to match these. If so, note that all these lockfile links start with .# -- invariably, that's hardcoded -- so you could always exclude files with names that match "^.#" (depending on which regex syntax you use.)
If you really want to hack at it, it's in filelock.c at about line 320 in EMACS 22. Here's the code:
/* Write the name of the lock file for FN into LFNAME. Length will be
that of FN plus two more for the leading `.#' plus 1 for the
trailing period plus one for the digit after it plus one for the
null. */
#define MAKE_LOCK_NAME(lock, file) \
(lock = (char *) alloca (SBYTES (file) + 2 + 1 + 1 + 1), \
fill_in_lock_file_name (lock, (file)))
static void
fill_in_lock_file_name (lockfile, fn)
register char *lockfile;
register Lisp_Object fn;
{
register char *p;
struct stat st;
int count = 0;
strcpy (lockfile, SDATA (fn));
/* Shift the nondirectory part of the file name (including the null)
right two characters. Here is one of the places where we'd have to
do something to support 14-character-max file names. */
for (p = lockfile + strlen (lockfile); p != lockfile && *p != '/'; p--)
p[2] = *p;
/* Insert the `.#'. */
p[1] = '.';
p[2] = '#';
p = p + strlen (p);
while (lstat (lockfile, &st) == 0 && !S_ISLNK (st.st_mode))
{
if (count > 9)
{
*p = '\0';
return;
}
sprintf (p, ".%d", count++);
}
}
You can upgrade to emacs 24.3 and add to your .emacs file the following line:
(setq create-lockfiles nil)
That's strange, the default should have # at each end..
You can customize the name by redefining the auto-save-file-name-p and make-auto-save-file-name functions. In GNU emacs you would add the elisp to your .emacs file.