News:

Accounts with zero posts and zero activity during the last months will be deleted periodically to fight SPAM!

Main Menu

X Macro

Started by photon3108, March 05, 2014, 03:07:05 AM

Previous topic - Next topic

photon3108

Does the autocomplete of CodeBlocks support X Macro?

ollydbg

What does "X Macro" means?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

photon3108

http://en.wikipedia.org/wiki/X_Macro

It's a C marco skill. Some people use it to generate the code of enum and array in compile-time.
Because they generate enumerator in compile-time, I can't use autocomplete to select it.

ollydbg

OK, I see.
The reason is that our parser(preprocessor) don't do a semantic check on every identifier, CB has macro expansion method, but it does not expand macro usage always.
For example, when the parser see a identifier like token:

LIST_OF_VARIABLES

It just see it as a simple type name or a variable name.

But what a compiler(gcc) do is to check every identifier to see whether it is a macro usage, and if it is true, then expand the macro.

I think we can enable it, but it will let the parser a bit slower, as you can think, checking of every identifier token takes much time, right?
Here is a test (cctest) file that we can test your request:

/* x macro
* https://en.wikipedia.org/wiki/X_Macro
*/


#define LIST_OF_VARIABLES \
    X(value1) \
    X(value2) \
    X(value3)

#define X(name) int name;
LIST_OF_VARIABLES
#undef X

// val  //value1,value2,value3


Currently, it get failed, but if we try to expand the LIST_OF_VARIABLES, I think it should be OK.

Also, for some enum definition:


// test parsing of enumerator assignments


#define SHIFT(_x) (1 << (_x))
enum PowerEnum
{
    powFirst    = SHIFT(1),
    powSecond   = SHIFT(2),
    powThird    = SHIFT(3),
    powFourth   = SHIFT(4),
    powFifth    = SHIFT(5)
};

the value is calculated, because we enable the macro expansion on enumerator definition. So you will see such tip: (image shot below)



You see, the tip show a value 32, which is calculated "1<<5".

Maybe, we can trigger macro expansion on a token which is totally capital characters?

If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Huki

Quote from: ollydbg on March 05, 2014, 04:11:13 AM
I think we can enable it, but it will let the parser a bit slower, as you can think, checking of every identifier token takes much time, right?
Here is a test (cctest) file that we can test your request:

/* x macro
* https://en.wikipedia.org/wiki/X_Macro
*/


#define LIST_OF_VARIABLES \
    X(value1) \
    X(value2) \
    X(value3)

#define X(name) int name;
LIST_OF_VARIABLES
#undef X

// val  //value1,value2,value3


Currently, it get failed, but if we try to expand the LIST_OF_VARIABLES, I think it should be OK.
This feature is present in my cc_parser_general.patch (checks each identifier for preprocessor token if the m_Options.parseComplexMacros is on). It's a rather long patch with several other features, I'm trying to get the small ones (and bug fixes) in first. :)

photon3108

#5
Quoteollydbg
I think we can enable it, but it will let the parser a bit slower, as you can think, checking of every identifier token takes much time, right?
Thanks for your reply.
Yes, of course. Maybe we could put it into low priority queue of parsing and let high priority one goes first.
Actually, I don't mind wait for 10 mins or more and in the meantime I could write other codes because typing
each characters each time is really annoying without autocomplete.

Quoteollydbg
Maybe, we can trigger macro expansion on a token which is totally capital characters?
X Macros have some coding patterns but sometimes they vary. In case of resolving the same problem twice,
dealing them both, pattern and no pattern, and put the pattern one into high priority may be a good idea.

QuoteHuki
This feature is present in my cc_parser_general.patch (checks each identifier for preprocessor token if the m_Options.parseComplexMacros is on). It's a rather long patch with several other features, I'm trying to get the small ones (and bug fixes) in first.
Thanks for your reply.
I wrote another example. It may be helpful to test the patch.

#include <stdio.h>
#include <stdlib.h>

/* X Macro */
#define LEVEL_LIST(XX) \
    XX(1, all, All) \
    XX(3, debug, Debug) \
    XX(5, info, Info) \
    XX(7, warn, Warning) \
    XX(9, error, Error) \
    XX(12, fatal, FatalFailure) \
    XX(15, off, Off) \

/* Example: Define a enumeration. */
#define XX(idx, name, msg, ...) level_##name = idx,
typedef enum {
    LEVEL_LIST(XX)
} level_e;
#undef XX

/* Example: Define an array. */
#define XX(idx, name, msg, ...) [idx] = #msg,
static const char *g_levelmsg_list[] = {
   LEVEL_LIST(XX)
};
#undef XX

int main()
{
   printf("%s:%d, %s\n", __FUNCTION__, __LINE__, g_levelmsg_list[level_info]);
   return EXIT_SUCCESS;
}

ollydbg

Hi, Huki, I really forgot your cc_parser_general.patch, sorry.
I'm not sure how we can handle the #undefine XX directive, as photon3108's sample code contains many #define XX #undefine XX. We need at least pick the latest XX definition when we try to expand the macros.

I have an impression that the most time of parsing is not the syntax check, but the loading of many source files from hard disk to memory.  ;)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

photon3108

Before CodeBlocks accepts Huki's X-Macro patch, I provide a temporary solution.

Quote
0. aa.h is my example.
   (At sixth post.)
1. gcc -E aa.h -o bb.h
2. You can pick up something what you need in bb.h.
   (e.g. The x-macro which has been extended. Search 'level_e')
3. Add extended x-macro to code-complete-helper.h.
   (You create this file and want to use it to help CodeBlocks)
4. Add code-complete-helper.h to CodeBlocks Project.
   (You don't need #include it to your program)
5. Press 'Reparse this project' in your project menu.

ollydbg

Just some heads up, and we are discussion a similar issue:
Code completion does not solve STDMETHOD macro for COM interfaces
I think the final solution should expand every macro usage if possible. ;)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

photon3108