LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Document tags (HHIFN, HIRET, HIPAR, etc.) and #define macro-generated functions?

A project I was working on needed hundreds of messaging functions, where the only thing really different was the name, message type, data structures and sizes. I created a #define macro to build them all and it works great. I then wondered if I could embed the documentation tags in the macro and have help for all these functions. No luck.

 

Does anyone know if it's possible to do this?

#define GENERATE_FUNCTION(cmdCode, structName) \
    bool Control##cmdCode(uint8_t boardNumber, bool useMultiplexer, struct_name payload) \
    { \
        // Some function here... \
    }
 
I was hoping to put the documentation tags in there, and that they would be processed after the C preprocessing happens, but it looks like this is not the case.
 
#define GENERATE_FUNCTION(cmdCode, structName) \
/// HIFN Send cmdCode to Control board. \
/// HIRET true for success, false for error. \
/// HIPAR boardNumber/Control board number (0-max). \
/// HIPAR useMultiplexer/Send through Multiplexer. \
/// HIPAR payload/Structure payload struct_name. \
    bool Control##cmdCode(uint8_t boardNumber, bool useMultiplexer, struct_name payload) \
    { \
        // Some function here... \
    }

 

Anyone know if this is possible?

0 Kudos
Message 1 of 8
(1,338 Views)

I was revisiting this today, and wanted to add another thing I tired -- putting the tags before the macro:

/// HIFN This function does some thing.
/// HIRET true for success, false for failure.
GENERATE_FUNCTION (SOME_THING_NAME, SomeStructName);

I assume LabWindows scans before preprocessing is done, so I expect if there was a way to alter that to be done after preprocessing, these might work.

0 Kudos
Message 2 of 8
(1,003 Views)

As far as I know documentation tags are only (*) for functions, not macros so I'm not sure how you'd want to interact with them.

 

(*) They are also used in header files to auto-build function panels, but I've always found this part complex and poorly documented.

0 Kudos
Message 3 of 8
(977 Views)

@gdargaud wrote:

As far as I know documentation tags are only (*) for functions, not macros so I'm not sure how you'd want to interact with them.

 

(*) They are also used in header files to auto-build function panels, but I've always found this part complex and poorly documented.


For anyone else who stumbles in to this, here is what I now know...

Based on feedback from others, and experiments, I think there are two things that prevent them from working like I need. First, if you put them in a macro like this:

#define GENERATE_FUNCTION(cmdCode) \
/// HIFN Test function. \
/// HIRET true for success, false for failure. \
/// HIPAR number/just a number... \
    bool Control##cmdCode(uint8_t boardNumber, bool useMultiplexer) \
    { \
        return ControlDATA_CMD(boardNumber, useMultiplexer, cmdCode); \
    }

...the preprocessor will remove comments, so all the /// lines would go away, plus the macro gets concatenated in to one long line so even if they were left, it would look like this and not work:

 

#define GENERATE_CONTROL_DATA_CMD_FUNCTION(cmdCode) /// HIFN Test function. /// HIRET true for success, false for failure. /// HIPAR number/just a number... bool Control##cmdCode(uint8_t boardNumber, bool useMultiplexer) { return ControlDATA_CMD(boardNumber, useMultiplexer, cmdCode); }

 

When using them as-designed, the system looks ahead at the function. For example:

/// HIFN Test function,
/// HIRET true for success, false for failure. \
/// HIPAR number/just a number...
void test(void)
{
}

That will NOT produce a documentation entry as expected. It does not blindly put in what you tell it in the /// - the function has to actually match. As soon as you make it match, it shows up:

 

/// HIFN Test function,
/// HIRET true for success, false for failure. \
/// HIPAR number/just a number...
bool test(int number)
{
    return true;
}

Even putting them in the code above a macro won't work because (we assume) it processes these doc tags before processing the macros:

#define FUNCTION_MACRO \
bool function(int number) \
{ \
    return true; \
}

/// HIFN Test function,
/// HIRET true for success, false for failure. \
/// HIPAR number/just a number...
FUNCTION_MACRO

But, you can take the pre-processed output file and run that separately and get what you expect. That is not practical.

 

In my case, there are hundreds of message functions that get named for the message. A specific structure (payload) is passed in, and a specific one is returned, but all the code inside is the same. Thus, macros saved weeks of typing.

 

However, if we want automated documentation, I'd have to at least write stub functions for hundreds of functions and tag them each manually. This is when I miss having a tech doc department that could just take care of it for me 😉

 

My approach is going to be to have ChatGPT write me a PowerShell script to preprocess all of this for me and spit it out in a file that I can process as a separate project, just to get the doc files built. (I previously used ChatGPT to write a script that pulls out all the defines and structures from hundreds of files so there could be one master .h to include with a DLL -- this is what happens when embedded C programmers get to work on Windows code and don't know what they are doing 😉

 

And so we move forward...

0 Kudos
Message 4 of 8
(970 Views)

You know that pressing [Ctrl-shift-G] while on a function definition will create all the documentation tags boilerplate above ? It saves a lot on the typing, you only need to fill in the actual meaningful comments.

Message 5 of 8
(949 Views)

It is a useful shortcut! I have that in my file templates so if any other developer makes an new file they know about it:

//*****************************************************************************
// @brief
//
// @param
//
// @return
//*****************************************************************************
// Ctrl-Shift-G before Function() to get this template:
/// HIFN Document your function here.
/// HIFN You may use multiple lines for documentation.
/// HIRET Document return value here.
/// HIRET You may use multiple lines for documentation.
/// HIPAR param1/Document parameter here.
/// HIPAR param2/Document parameter here.
// int Function (int param1, int param2)
// {
// 	return 42;
// }

 

 

0 Kudos
Message 6 of 8
(874 Views)

After a bit of work with ChatGPT, I have a PowerShell script that handles my specific need to add documentaiton comments to functions created by Macros. It works as a pre-processor, and I can feed it my .h and .c file and it outputs a single file that turns the macros in to functions with the template doc header created.

 

From there, I add any needed stub functions in a main.c just to make it build and now I can generate help files.

 

This is much much better than me having to go in and manually create hundreds, if not thousands, of functions by hand just to get docs.

 

We run LabWindows 2017, but I am sure I could get management to upgrade us if the newer versions handles docs after the pre-processor step.

 

I also don't see tags for documenting structures and such. If a function receives or returns a structure -- such as C functions like "localtime()" and the "tm" structure - docs typically have a link that opens the structure definition.I see the built-in help in LabWindows just has it described in the function text:

 

"The struct tm contains the following members:"

 

And they just duplicate that text in other functions that use it, rather than making "struct tm" a link so it does not have to be maintained in multiple places. Since they can't do it in their own docs, I assume we can't do it in ours.

 

But, at least this is progress for my task. I was not looking forward to spending the next few months doing this manually... We do not have a tech doc department 😉

0 Kudos
Message 7 of 8
(873 Views)

Addendum... unfortunately, the use of "//" at the start of these tags makes the compiler remove them, which means you cannot embed them in function macros since they get compiled out, and the macro breaks (a "\" at the end of the line won't concatenate the next line,since the whole line is a comment).

#define GENERATE_FUNCTION(cmdCode, struct_name) \
    /// HIFN You cannot do this... \
    bool Control##cmdCode(uint8_t a, bool b, struct_name payload) \
    { \
        ...stuff... \
    }

If they would allow some method of using the /* comments */ then they could be embedded, since the "\" could be included:

#define GENERATE_FUNCTION(cmdCode, struct_name) \
    /*/// HIFN This could work...*/ \
    bool Control##cmdCode(uint8_t a, bool b, struct_name payload) \
    { \
        ...stuff... \
    }

 ...though that would break being able to comment out tags when you really did not want them included.. But, something along those lines ... like looking for "/*///" with no space or something.

 

This has been a fun one to try to figure out.

0 Kudos
Message 8 of 8
(845 Views)