Highlighting entire c/cpp macro definition in emacs? - c

In vim, entire c macro definition is fully highlighted with different color. How do i get similar style in emacs?. You can refer below screenshot showing that in vim(right side), entire EXAMPLE_MACRO is highlighted and showing that CALL_MACRO(0) is part of the definition.
#include <stdio.h>
#define CALL_MACRO(x) \
EXAMPLE_MACRO(x) \
int
main(int argc, char *argv[])
{
#define EXAMPLE_MACRO(x) \
if (x) { \
printf("\n Condition is true"); \
} else { \
printf("\n Condition is false"); \
} \
\
CALL_MACRO(0);
CALL_MACRO(1);
#undef EXAMPLE_MARCO
}
major-mode for above code is c-mode.
Please note above code doesn't compile.
I found below code which can make #if 0 and #endif to be shown as font-lock.
(defun my-c-mode-font-lock-if0 (limit)
(save-restriction
(widen)
(save-excursion
(goto-char (point-min))
(let ((depth 0) str start start-depth)
(while (re-search-forward "^\\s-*#\\s-*\\(if\\|else\\|endif\\)" limit 'move)
(setq str (match-string 1))
(if (string= str "if")
(progn
(setq depth (1+ depth))
(when (and (null start) (looking-at "\\s-+0"))
(setq start (match-end 0)
start-depth depth)))
(when (and start (= depth start-depth))
(c-put-font-lock-face start (match-beginning 0) 'font-lock-comment-face)
(setq start nil))
(when (string= str "endif")
(setq depth (1- depth)))))
(when (and start (> depth 0))
(c-put-font-lock-face start (point) 'font-lock-comment-face)))))
nil)
(defun my-c-mode-common-hook ()
(font-lock-add-keywords
nil
'((my-c-mode-font-lock-if0 (0 font-lock-comment-face prepend))) 'add-to-end))
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
I'm not sure if above code can be modified to highlight multiline macro.
scottmcpeak.com/elisp/scott.emacs.el
There is mention of
;'("^([ \t]#.(\\\n.))" 1 font-lock-preprocessor-face)
; this 2nd line is my attempt to get it to recognize multiline macros
; and highlight them entirely as preprocessor (doesn't work..)

I just came across an awesome package by #Lindydancer called prepaint.el, that does exactly what you want. It highlights macros differently, including multi-line macros and also preserves the keyword highlighting in the macros.

Related

portability and safety of C macro using lambda parameter

Preface
I know that there are several libraries for auto-testing available.
Let's ignore that for this question, please.
Motivation
Implementing some library I got tired of manual testing, so I started to write a "self-test" program, starting with code using many assert()s.
Unfortunately when an assert() fails, only limited information is shown on the screen, and I would typically have to use the debugger to examine the core dump to get more details of the failure.
So I added a macro that allows a printf()-like output (implemented via the E() (for error) macro) when an assertion fails; I named that macro VA() (for verbose assertion):
#define VA(assert_cond, msg, ...) do { \
if ( !(assert_cond) ) E(msg, ##__VA_ARGS__); \
assert(assert_cond); \
} while (0)
Using that would look like this:
VA(FASTWORD(FASTWORD_BITS - 1) == 0, "%s: FASTWORD() failed", __func__);
As the self-test program used array-like data structures, I needed to inspact those as well, so I output those before doing the tests, resulting in a lot of output even when all tests succeed.
So I invented another macro, VFA() (verbose failed assertion) that uses a "lambda parameter" like this:
#define VFA(assert_cond, cmd, msg, ...) do { \
if ( !(assert_cond) ) { \
E(msg, ##__VA_ARGS__); \
cmd; \
} \
assert(assert_cond); \
} while (0)
While writing that I wondered how the preprocessor would parse commata for a use case like this:
VFA(fw[0] == out_fw0 && fw[1] == out_fw1,
dump_fastwords_range(fw, 4, pos, (pos + count) % FASTWORD_BITS),
"%s: __clear_fw_bits_up(%d, %d) failed", context, pos, count);
I mean it could be possible that the condition could be the first parameter, dump_fastwords_range(fw could be the second, 4 could be the third, and so on...
However that is not the case with gcc at least.
The other thing is cmd; in the macro:
My first version did not include the semicolon, so I would have to write (which looks really ugly):
VFA(fw[0] == out_fw0 && fw[1] == out_fw1,
dump_fastwords_range(fw, 4, pos, (pos + count) % FASTWORD_BITS);,
"%s: __clear_fw_bits_up(%d, %d) failed", context, pos, count);
OK, here's another use example of my macro:
VFA(fw[0] == out_fw0 && fw[1] == out_fw1,
{
const unsigned first = pos >= count ?
pos - count : FASTWORD_BITS + pos - count + 1;
dump_fastwords_range(fw, 4, first, pos);
},
"%s: __clear_fw_bits_dn(%d, %d) failed", context, pos, count);
Questions
The questions I have are:
Is parsing of the macro parameters portable across compilers?
Will the cmd use create any trouble, considering the parameter could be rather complex (as the last example suggests)?
Is parsing of the macro parameters portable across compilers?
No. ##__VA_ARGS__ is a non-portable gcc extension. What does ##__VA_ARGS__ mean?
Will the cmd use create any trouble, considering the parameter could be rather complex (as the last example suggests)?
Items within () of that macro parameter will mean that it all gets treated like a single pre-processor token and expanded as such. You can peek at the pre-processor output if you are curious. Formally this is specified in C17 6.10.3/10:
Each subsequent instance of the
function-like macro name followed by a ( as the next preprocessing token introduces the
sequence of preprocessing tokens that is replaced by the replacement list in the definition
(an invocation of the macro). The replaced sequence of preprocessing tokens is
terminated by the matching ) preprocessing token, skipping intervening matched pairs of left and right parenthesis preprocessing tokens.
So it shouldn't create any trouble unless you do truly evil stuff like using goto or setjmp etc from inside it.

Reuse variable in macro with modification

I'm trying to make a linked list for error handling in C. Functions would return the head element of the error list, or NULL.
I need macros to add file name, line numbers, ...
#define MAKE_ERR(MSG) \
_err_malloc(__FILE__, __LINE__, __PRETTY_FUNCTION__, MSG, NULL)
#define PUSH_ERR(NEXT, MSG) \
_err_malloc(__FILE__, __LINE__, __PRETTY_FUNCTION__, MSG, NEXT)
and I would like to make it easy to add the current frame as messages go up the stack:
#define FORWARD_ERR(NEXT) \
(NEXT ? PUSH_ERR(NEXT, NULL) : NULL)
err_t* foo();
err_t* bar() {
return FORWARD_ERR(foo());
}
The problem is that FORWARD_ERR uses NEXT twice.
I would like to use FORWARD_ERR as an expression. I can easily make it a block:
#define FORWARD_ERR(NEXT) \
{ err_t* N = (NEXT); return (N ? PUSH_ERR(N, NULL) : NULL) }
but I don't think that's a good solution.
I was trying to get it working with the Elvis operator a ?: b, but couldn't get it to work.
Clang and GCC both support statement expressions, which would let you do something like this:
#define FORWARD_ERR(NEXT) \
({ err_t* N = (NEXT); N ? PUSH_ERR(N, NULL) : NULL; })
Which lets you use it as an expression the way you want to but doesn't force you to embed the return statement inside your macro.

how to pass arguments to function and use these arguments in macro function inside it

I want to do something like that
#define GREATER_THAN_ZERO(a) a>0? 1:0
and use this macro inside another function like that
void test(int x)
{ if (GREATER_THAN_ZERO(x) == 1) printf("more than zero");
else printf("less than zero");
}
But when I use test function it always prints "less than zero"
NOTE: this is an example not the real case but I want to do something like that (use macro inside a function)
Can anyone help me please?
EDIT
I have configuration file like that
#define LED_u8_MODE_0 LED_u8_REVERSE
#define LED_u8_MODE_1 LED_u8_NORMAL
and in program I have a macro function
#define LED_u8_GET_MODE(LED_u8_INDX) (LED_u8_INDX == 0)? LED_u8_MODE_0: \
(LED_u8_INDX == 1)? LED_u8_MODE_1: \
(LED_u8_INDX == 2)? LED_u8_MODE_2: \
(LED_u8_INDX == 3)? LED_u8_MODE_3: 800
then I use it inside this function
void LED_voidSetLedOnWithIndx(u8 Copy_u8LedIndx)
{
if(LED_u8_GET_MODE(Copy_u8LedIndx) == LED_u8_NORMAL)
{
DIO_voidSetPinValue(Copy_u8LedIndx, DIO_u8_HIGH);
}
else //if(LED_u8_GET_MODE(Copy_u8LedIndx) == LED_u8_REVERSE)
{
DIO_voidSetPinValue(Copy_u8LedIndx, DIO_u8_LOW);
}
}
I can't reproduce the problem with the code you posted, but you mentioned it's not the real case, and I do have an idea of the problem.
The expression is not being associated as you intended. When expanded, the expression is:
x>0? 1:0 == 1
which groups as:
x>0? 1:(0 == 1)
which is equivalent to:
x>0? 1:0
This still works as intended. But if you instead had:
if (GREATER_THAN_ZERO(x) == 0)
then you would end up with:
x>0? 1:0 == 0
or:
x>0? 1:(0 == 0)
which is always 1.
There are two fundamental problems with the macro definition: (1) it isn't protecting its argument from mis-association, and (2) it isn't protecting the result from mis-association.
The proper way to write it would be:
#define GREATER_THAN_ZERO(a) ((a) > 0 ? 1 : 0)
The parentheses around (a) allow you to pass an expression as the argument without worrying about it being re-associated. The parentheses around the entire macro body allow you to use the macro in an expression without it being re-associated.
In this particular case, the ?: operator is redundant, since n > 0 always returns either 0 or 1, so you could just use:
#define GREATER_THAN_ZERO(a) ((a) > 0)
with identical results.
Similarly, the comparison of the result with 1 serves no purpose and suggests that something unusual is going on. It is much more natural to simply write:
if (GREATER_THAN_ZERO(x))
This implicitly tests to see if it's non-zero. Remember, if (n) is equivalent to if (n != 0).
Too large for a comment, so as answer: I recommend a different formatting (with parentheses adjusted, though):
#define LED_u8_GET_MODE(LED_u8_INDX) \
( \
(LED_u8_INDX) == 0 \
? (LED_u8_MODE_0) \
: (LED_u8_INDX) == 1 \
? (LED_u8_MODE_1) \
: (LED_u8_INDX) == 2 \
? (LED_u8_MODE_2) \
: (LED_u8_INDX) == 3 \
? (LED_u8_MODE_3) \
: 800 \
)
Or do you disagree that this is easier to read?
Still, those many ternary operators are difficult to read and handle, I'd rather consider replacing the entire macro with an inline function:
inline int ledGetMode(int index)
// (if need be, adjust parameter and return value types appropriately)
{
switch(index)
{
case 0:
return LED_u8_MODE_0;
// ...
default:
return 800;
}
}
Looks much cleaner and should, as inline, not have any overhead over the macro...
The main advantage, though, is that you simply skip any trouble with bad association of parameters or result and with multiple evaluation of the parameters!

Variable arity functions in Racket/C FFI

Declaring functions with Racket's FFI is simple enough to do with _fun and define-ffi-definer. (A tutorial can be found on the PRL blog) For example, I can make a binding for atoi:
#lang racket
(require ffi/unsafe
ffi/unsafe/define)
(define-ffi-definer define-libc #f)
(define-libc atoi (_fun _string -> _int))
And now I can call atoi with Racket strings:
> (atoi "5")
5
The problem now is, how do I call C functions with a variable arity, such as printf, who's signature is:
int printf(const char *format, ...);
I would guess that (since the linking happens dynamically), the Racket code should have a 'rest' argument at the end, which takes an array (pointer) for the rest of the arguments, that is either null terminated or (more likely), indicated by yet another argument. However, I can't think of any good ways to test this.
So, how do you handle variable arity functions with the Racket-C FFI?
Look at this solution c-printf:
(provide c-printf)
(define interfaces (make-hash))
(define (c-printf fmt . args)
(define itypes
(cons _string
(map (lambda (x)
(cond [(and (integer? x) (exact? x)) _int]
[(and (number? x) (real? x)) _double*]
[(string? x) _string]
[(bytes? x) _bytes]
[(symbol? x) _symbol]
[else (error 'c-printf
"don't know how to deal with ~e" x)]))
args)))
(let ([printf (hash-ref interfaces itypes
(lambda ()
;; Note: throws away the return value of printf
(let ([i (get-ffi-obj "printf" #f
(_cprocedure itypes _void))])
(hash-set! interfaces itypes i)
i)))])
(apply printf fmt args)))

getting the variable values in #define definition

Here is what I am trying to do.
step1) I want to call a macro with a conditional statement(simple are compounded) like
for eg:
MACRO1(a==1)
MACRO1((i!=NULL) && (j>10))
step2) Here is how i am defining this macro
#define MACRO1(condition) \
if(!(condition)) ??????????????????????????
Here in the definition of the macro, if the condition statement fails. I want to print the variable values so that I will be useful to know the exact reason.
I used #condition in the definition, but it just printing the condition, instead of the values of the variables used in the condition. Please help.
You could do something along these lines:
#define MACRO1(condition, msg) \
if(!(condition)) { printf msg; }
and use it as follows:
MACRO1(a==1, ("a: %d\n", a))
MACRO1((i != NULL) && (j>10), ("i: %p, j: %d\n", i, j));
The C preprocessor is just a simple substitution engine, without the capability of analyzing the contents of expressions.
You shouldn't define macros that look like a function, but behave differently, in particular in your case may change control flow: an else that follows a macro that contains an if can apply to something different than the programmer (yourself after a week) thinks. Protect the if such that a dangling else will not apply to it
#define MACRO1(COND, ...) \
do { \
if (!(COND)) printf(stderr, "condition " #COND ": " __VA_ARGS_); \
} while (0)
This macro should always be called with a format string as second argument and the names of the variables that you want to see
MACRO1((toto != 78.0), "toto=%9\n", toto);
this should print you something like
condition (toto != 78.0): toto=3.14
There is no way that I know of to separate the variables from the condition.
However, you can pass them in as extra parameters:
#define MACRO(condition, printsyntax, ...) \
if(!(condition)) {\
printf("condition %s not met! (" printsyntax ")\n", #condition, __VA_ARGS__); \
};
You would use it as:
MACRO((i!=NULL) && (j>10), "i=%p, j=%d", i, j)
with an example result being:
condition (i!=NULL) && (j>10) not met! (i=(nil), j=11)
The compiler will splice together the constant strings into one string for the printf,
the condition will automatically be printed and the rest of the arguments are your job to get right.
Edit
After Jens' remark about the else I modified the code a bit to not allow for such structures without using do{}while();.

Resources