Currently using Doxygen 1.8.13
We have:
abstract base/interface class
multiple implementation classes
need to generate external and more detailed internal documentation (driven by ASPICE requirements)
So, we doxygen-ate the abstract base class with the calling contract in interface.h. This would seen by external documentation.
For the implementation classes, we want to add information related to those interfaces w/regards to the implementation functionality as seen by the caller. We'd prefer to add this to implementation.cpp above each function. Again, seen by external documentation.
THEN we want to have add detailed design and implementation information including cross referencing GUIDS, etc. to maintain tracibility with requirements and test plans, etc. Stuff nobody but QA and auditors want to see. We'd like to have this in a separate file implementation.dox so as to not clutter up the code with too much (also we deliver some of our SDK as source and don't really want to deliver this information to customers).
So we'd have two doxyfiles, one that includes the implementation.dox and one that doesn't.
So the behavior I've seen:
the implementation automatically inherits the brief and detailed documentation (unfortunately not the parameters) UNLESS you add more information, then it simply replaces. So you can use #copydoc <base method> to get the original information then add your own.
If in our implementation.dox file, we do #fn <method>, then this replaces both unless again, we use #copydoc, but we can't #copydoc the implementation information because we're apparently defining it.
So...is there a way to accomplish what we want without pre processing via scripting or whacky #include/preprocessor fun. is there an #appendto or something like that? Or are we trying something that is round hole & square peg?
Related
The DYNAMIC FACTORY pattern describes how to create a factory that
allows the creation of unanticipated products derived from the same
abstraction by storing the information about their concrete type in
external metadata
from : http://www.wirfs-brock.com/PDFs/TheDynamicFactoryPattern.pdf
The PDF says:
Configurability
. We can change the behavior of an application by just changing its configuration
information. This can be done without the need to change any source code (just change the descriptive information about the type in the metadata repository) or to restart the application (if caching is not used – if caching is used the cache will need to be flushed).
It is not possible to introduce new types to a running C++ program without modifying source code. At the very least, you'd need to write a shared library containing a factory to generate instances of the new type: but doing so is expressly rules out by the PDF:
Extensibility / Evolvability
. New product types should be easily
added without requiring neither a
new factory class nor modifying
any existing one.
This is not practical in C++.
Still, the functionality can be achieved by using metadata to guide some code writing function, then invoking the compiler (whether as a subprocess or a library) to create a shared library. This is pretty much what the languages mentioned in the PDF are doing when they use reflection and metadata to ask the virtual machine to create new class instances: it's just more normal in those language environments to need bits of the compiler/interpreter hanging around in memory, so it doesn't seem such a big step.
Yes...
Look at the Factories classes in the Qtilities Qt library.
#TonyD regarding
We can change the behavior of an application by just changing its configuration information.
It is 100% possible if you interpret the sentence in another way. What I read and understand is you change a configuration file (xml in the doc) that gets loaded to change the behaviour of the application. So perhaps your application has 2 loggers, one to file and one to a GUI. So the config file can be edited to choose one or both to be used. Thus no change of the application but the behaviour is changed. The requirement is that anything that you can configure in the file is available in the code, so to say log using network will not work since it is not implemented.
New product types should be easily added without requiring neither a new factory class nor modifying any existing one.
Yes that sounds a bit impossible. I will accept the ability to add ones without having to change the original application. Thus one should be able to add using plugins or another method and leave the application/factory/existing classes in tact and unchanged.
All of the above is supported by the example provided. Although Qtilities is a Qt library, the factories are not Qt specific.
I have read the Why can templates only be implemented in the header file? and Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?
If I create the templates then I am to provide access also to their cpp-files additionally to their h-files, or write the definitions directly in the header file.
Therefore, if I want to allow to use fully my templates in other applications, then I can't hide their implementation from outside eyes (for protection of intellectual property). Am I right?
In general you're right... the implementation must be exposed.
If your client only needs to instantiate them for a finite set of specific types that they can list for you, you can provide them with a pre-compiled object/library containing the implementations of the instantiations for just those types: see https://isocpp.org/wiki/faq/templates#separate-template-fn-defn-from-decl
Obfuscation is another possibility - let them see the code, but make it confusing and unmaintainable.
If neither of those options suit, consider whether you can provide a templated adapter that creates a run-time polymorphic interface over their user-provided type, capturing the specific set of functions your algorithms need. Accept those adapters as a front-end to your code. This does have runtime costs.
Intellectual property is mostly protected by legal means, not technical ones.
(e.g. the technical possibility to read some header files do not give me the right to use it, or to copy its code elsewhere)
However, you might consider code obfuscation techniques. You might even customize your recent GCC for that purpose, i.e. write your MELT free software extension. It could mean weeks (or months) of work.
Alternatively, consider publishing your header-only template C++ library as free software... (perhaps with GPL license).
But IANAL. You should ask your lawyer.
This is a potentially dangerous question because interdisciplinary questions and answers will be biased, but I'll have a stab at it anyway. All in good spirit!
So, here we go. I'm writing a major editing mode for Emacs for the language that it has almost no support for yet. And I'm at the point, where I have to decide on a way to generate project files. Below is the syllabus of the task ahead:
The templates have to represent project directory tree, not only single files.
The resulting files are of various formats, potentially including SGML-like languages, but not limited to this variety. They also have to generate C-like source code and, eLisp source code and plain text files, like README, for example.
The templates must be processed in a batch upon user-initiated action (as in user wants to create a project - several files must be created in the user-appointed directory). It may be beneficial to have an ability to supervise the creation, but this is less important then the ability to run the process entirely automatically.
Bonus features:
The template language has already a user base (with a potential of reuse of existing templates).
The templates can be used for code snippets (contain blanks which are filled interactively once the user invokes code-generating routine while editing the file).
Obvious things like cross-platform-ness, ease of use both through graphical interface and command line.
I made a research, but I won't share my results (yet) so I won't bias the answers. The problem with answering this question is not that the answer is hard to find, but that it is hard to chose one from many.
I'm developing a system based on Mustache for exactly the use case that you've described. The template language itself is a very simple extension of Mustache called Groome.
I also released a command-line tool called Molt that renders Groome templates. I'd be curious to know if it does everything that you need. I'm still adding features to the tool and haven't yet announced it. Thanks.
I went to solve a similar problem several years aback, where I wanted to use Emacs to generate code out of a UML diagram (cogre), and also generate Makefiles from project specifications. I first tried to use Tempo, but when I tried to get the templates to nest, I ran into problems. I also looked into skeleton, but that didn't quite fit the plan either.
I ended up using Google Templates for a little bit, and liked the syntax, and developed SRecode instead, and just borrowed the good bits from Google templates. SRecode was written specifically for machine-generated code. The interaction for template insertion (aka - what tempo was written for) isn't first class in SRecode. For generating code from a data structure, however, it is very robust, and has a lot of features, and automatically filled variables. It works closely with your major mode, and allows many nested templates, with control over the nested dictionary values. There is a subsystem that will use Semantic tags and generate code from them for a couple languages. That means you can parse code in one language with Semantic, and generate code in another language with SReocde using those tags. Nifty! Many parts of CEDET Reference manuals were built that way.
The templates themselves allow looping, if statements, and include statements. There are a couple examples in SRecode for making an 'application', such as the comment writer, and EDE uses it to create Makefiles, which is almost exactly what you are trying to do.
Another option is Generator, which offers “language-agnostic project bootstrapping with an emphasis on simplicity”. Installation requires Node.js and npm.
Generator’s emphasis on simplicity means it is very easy to learn how to make a template. Generator also saves you from having to reference templates by file paths – it looks for templates in ~/.generator.
However, there is no way to write README or LICENSE files for the template itself without those files being copied to the generated project. Also, post-generation commands written in the Makefile will be copied to the generated Makefile, even after they are no longer of use. Finally, the ad-hoc templating language doesn’t provide a way to escape its __lowercasevariables__ – though I can’t think of a language where that limitation would be a problem.
I know how to perform this for C++/CLI and .NET in general but, C++ doesn't have Attributes. The scenario is this:
We want to provide some methods in the binary but we don't want all of our customers to use them. If a customer needs it, we can either tell him what the signature is or, send him another non-binary file.
I don't think you can control that. Since you have to publish the header files for the library, then you will expose the entire interface, even if not through intellisense.
However, you should think that there are other tools doing the same thing, used by many developers (e.g. Visual Assist).
If you need to hide some implementation details, a better solution is to apply pimpl idiom and provide in header files the interface classes, with the "public", usable methods.
The implementation classes will be included only from the cpp files containing that are compiled, and only forward declared in the public header files.
I'm interested in hearing what routines you have for cleaning up public header files you
distribute to customers.
Some things I'd like to hear your opinions on are:
Comments not meant for external consumption. Generally I like keeping documentation close
to the code and comments like this might not be a good idea to share:
/**
* #todo Should we change the signature of this function to
* make it obvious that xxx is really yyy?
*/
or perhaps:
/**
* #todo Add support for feature X
*/
Inconsistent tab styles:
void functionA(int a,
int b,
int c,
int d);
void functionB(int a,
int b,
int c);
Are there any tools for preparing headers or code in general for release?
You should ALWAYS, on any project involving multiple developers for any extended period of time and the subsequent release of that source code, SCAN FOR OBSCENITIES (and other things you shouldn't have said, e.g., "My boss made me do this", "This code is terrible", etc). Also, spell-checking the comments can be helpful, as people incorrectly spelling words saps from your credibility.
Please make sure that your headers don't generate any compiler warnings.
Always have somebody (preferably more than one) go through the header to look for anything that looks unprofessional. You can use code formatters and other automatic tools first.
For comments, have them look for anything unprofessional or tentative. Correct misspellings. Make sure they're accurate. Have a standard way to format them, and stick to it.
Check all identifier names. They should conform to a style guide and be professionally named.
Make sure all necessary comments are there. This includes copyright and contact information at the top. Come up with a standard method of documenting classes and such, and enforce it.
Basically, from my point of view, you want your headers to look like they were produced by drones without creativity or a sense of humor, but who are perfectly consistent (sort of like CPA stereotypes). (It's sort of like asking your developers to wear suits while customers are visiting the office - the customers will be happier if they don't see what your developers are really like.)
It'd generally be better if you had coding standards/formats for documents customers will see that the developers themselves follow when they first create the code, so you're not spending time cleaning up code before release, such as now.
Also, Visual Studio and several other IDE's have an "Auto Formatting" option where you can set up a style and it is applied to your code (tabs, spaces, that sort of thing). I think that's mostly what you're asking for here.
In my experience having an internally used header routinely and automatically cleaned up for public consumption is a hard task, and definitely error prone. Eventually the inconsistent format or the inappropriate comment will inevitable creep through.
In many cases you are probably better off wrapping everything into a small and clean interface, whose header is always maintained as clean and as commented as possible; modifications to that file should undergo, for instance, a particularly careful review process.
I'm not very familiar with the subject, but for open source projects you often have the licence and copyright statement at the top of the header. This can avoid several juridic issues.
Just as important as removing crufty comments is adding necessary ones. Things you might need to add:
copyright/terms-of-use header
contact information for support
links to documentation if it is being made available online
documentation of public interfaces (return values, parameters, pre- and post-conditions, etc)
warnings on functions/methods that are exposed but not intended for production use
G'day,
In C++ I like to use the Handle-Body idiom to decouple the implementation as much as possible from the public interface.
You should also make sure that any boilerplate, e.g. copyright notices, is consistent and up to date, e.g. copyright doesn't expire in 2008 for code released today.
Be consistent across all public header files for naming conventions, formatting, layout and class design otherwise it leaves an unprofesional impression on customers.
Make sure that there are no "using" declarations in your header files. Misuse of "using" dec's can seriously screw things up with inadvertent side effects.
As mentioned previously, make sure that your headers don't generate any warnings.
Finally. make sure you've got some good API documentaion to go with your header files.
Don't be like a company who provides a well known postcode lookup product. First version of the C API came with minimal documentation that was heavily based on the Windows GUI version. The header files simply consisted of functions whose parameters only had types and no names. And no comments at all.
Only way to work out what the functions actually did was to reverse engineer a simple lookup example program provided and reverse engineer it.
Still, after managing to do that I saved BBC's Children in Need tens of thousands of pounds per year because the addresses provided for fund-raising packs were more likely to be correct than in previous years!