Doxygen



Introduction

  • This is an old version of the Project 1 starter code, presented in order to demonstrate doxygen (i.e., don't cut and paste this code into a current project!). As a note, README.dox is a text file with a single block of C-style comments in it.
  • Set to CMAKECURRENTBINARYDIR by this module. Note that if the project provides its own value for this and it is a relative path, it will be converted to an absolute path relative to the current binary directory.
  • Doxygen Awesome is a custom CSS theme for doxygen html-documentation with lots of customization parameters. I really like how the doxygen html-documentation is structured! But IMHO it looks a bit outdated. This theme is an attemt to update the visuals of doxygen without changing it's overall layout too much.

Throught this course you will be working on big software projects and an important part of any large project is documentation. Documentation is especially important in group projects, like many of the projects in this class. Imagine how useful a browsable index will be when your partner is asleep and you're trying to figure out his/her code. In order to ensure that your source code has adequate documentation, we will be requiring that your code be fully documented using doxygen, a documentation system for C similar to JavaDoc. This document serves as a brief overview of doxygen and the features you will use on a regular basis. For a more detailed description of doxygen and all of its features visit the doxygen homepage. You can get detailed documentation and information about compiling and installing doxygen on a home system.

There are two types of comments we want in your code. The first kind are comments at the beginning of each file which describes the file and lists things like author and known bugs. The second kind of comments are those that describe your functions and data structures. We want you to put comments on all your functions and data structures. You do not have to comment individual variable instances but are welcome to if you'd like. The rest of this document talks about the doxygen commands that you need for each of the two kinds. First, we'll describe what we expect to see and then talk about the specific commands that you need to use including simple examples. Lastly there will be a larger example showing all of commands together.

Comments for Files

Each file needs to begin with the @file command stating the name of the file. This should be followed by a brief description of the file using the @brief command. If necessary, you can follow this with a more detailed description. Next you should put your name and andrew id, along with your partners name and andrew id, using the @author tag. This needs to be followed with a bugs section with a list of known bugs using the @bug command. If there are no known bugs, explicitly state that using the @bug command.

Doxygen will pass the text on to dot and include the resulting image (and image map) into the output. The nodes of a graph can be made clickable by using the URL attribute. By using the command ref inside the URL value you can conveniently link to an item inside doxygen. Here is an example.

Comments for Functions and Data Structures

Before each function, data structure, and macro you should put a comment block giving at least a brief description using the @brief command. A brief description will suffice for your data structures but for you macros and functions you will need to use a few more commands. After your description, you should use the @param command to describe all of the parameters to your function. These descriptions should be followed by a description of the return value using the @return command. Note: When we say 'each' function, that is not a strong statement. You can leave out simple helper functions, like a max() macro, so you don't waste time.

You can choose to comment your functions either in the header files where they are declared, in the source files where they are implemented or both. This is a matter of taste. If you put it in the header file, like in the example, then you should be sure to remember to update the comments with the latest details of the implemenation. If you choose to put the comments in both places note that if there is a difference between the two sets of comments, the block at the declaration will superceed the one at the implementation. The long and short of this is that you should not put the comments in both. For assembly files, you can put the comments in the header file where they are declared.

Here is what we expect to see in the non-brief section of the function:

  • Anything a user needs to know to decide whether this is the right function for them to use for a given job.
  • Usage preconditions: must be called with interrupts disabled, etc.
  • Any use of an unusual algorithm (in which case, cite it -- academic format or page title and URL)
  • Why the code was written in a non-obvious structure.
  • Warnings about how to extend the function without breaking it.
Not all of that will be needed for every function. Just make sure it is enough to make it clear what the function does and how it does it. Don't worry to much about this documentation stuff. If we feel that it is not up to what we want, we'll let you know with your grade report and probably won't take points off right now, but may in future projects. Make sure that the documentation is there and that it makes sense.

Coding Style / Coding Standards

At some point in your career you may well be required, or at least expected to adhere to an explicit coding standard document. If you are ever present at the inception of a large project, you will have the opportunity to watch the inevitable flame war over tab stops and brace placement. Don't worry--for 15-410, we aren't going to tie you down that much.

However, you should use a consistent and defensible style. It would probably be a good experience for you to read a few coding style documents to see how they differ and how you feel about the differences. When you begin work with your partner on Project 2 you will have an opportunity to discuss this issue. We won't require the two of you to use exactly the same style, but it would probably make sense for style to not vary wildly within a single file. For open source projects (i.e., potentially many authors over many years), one popular approach is for the 'primary author' of each file to set the style (within reason) and other developers to try to emulate that style (again, within reason, but it really is good form for any change you suggest to blend in with the code that's already there).

Here are some coding style documents you may find useful. This purports to be a (the?) Linux kernel coding style document. To the eyes of an old BSD hand, this looks a little cavalier, which is unsurprising. The BSD Kernel Normal Form (KNF) is also worth a look. Many moons ago C programmers inside AT&T put together the Indian Hill C Style guide, which has been updated to yield a generically titled Recommended C Style and Coding Standards guide. Here are Style guides for Google-originated open-source projects, and here are Lester McCann's suggestions 'Toward Developing Good Programming Style'. Of course, they contradict each other and probably every other coding style document on the planet, but you shouldn't let that bother you, and you should be able to detect a common core.

You may also wish to consult How NOT to go about a programming assignment by Agustín Cernuda del Río.

What really matters is:

Modularity
The scheduler functions are in a file full of scheduler functions and nothing else; each function is coded up once; etc.
Documentation
This can be read at multiple levels. For example, people can read a short file to find out if your program is right for them; can read about a module or package to see if they want to steal it for their own programs; can read about a function to decide whether they need to read the code, etc.
Maintainability
Including basic things such as essentially never putting a hardwired constant such as 1128 into a file, and never using it twice, and never ever putting 1127 into your code because it's 1128 - 1. But you knew all that from 15-213, right? Since you asked, the right way to handle 1128 would be
(GREY << COLOR_SHIFT) | (ELEPHANT << ANIMAL_SHIFT) | 16 /* tons */
Dead Code
There are two very different kinds of 'dead code' which students tend to turn in. One kind is 'debug code' which was briefly useful but never will be again, stuff like
// printf('!!!! joe = %dn', 4 * i / 0);
or
int threadstatus = THR_RUNNING; // THR_RUNNING|128
or
// if (threadid 17) MAGIC_BREAK;
Realistically, even if something like that helped you track down a bug once, you wouldn't re-activate it to find the next one. Since this code will never be run again, leaving it around can't do anything except distract and slow down your audience. Don't turn it in.
In the other direction, occasional assert()s are fine. In fact, sensibly done, they actually help document the code. See the section on asserts.
Overall, if debug code is genuinely likely to be useful to readers or maintainers, that argues in favor of keeping it, but the vast majority of what gets stuck in temporarily is just noise, and should be deleted.
Asserts
Asserts are statements that check that the assumptions that were made in your program are not violated. For example, let's say you have a variable *nodeptr. If, by design, nodeptr can never point to NULL, then a statement like
ASSERT (nodeptr);
or, in the Linux idiom,
if (!nodeptr)
BUG();

is a way of verifying that this assumption is not violated. This is useful in two ways. Firstly, it documents your assumption. Secondly, in future, if anyone modifying your code violates this assumption, (s)he is informed of this early, rather than having to discover this through a debugging session. Hardcore performance evangelists will argue that such code will almost never be executed, and that the extra conditional statement just serves to affect the branch prediction accuracy. People with such concerns should look at the likely() and unlikely() preprocessor macros in the Linux kernel and the associated gcc builtin function __builtin_expect(). However, people who don't have measurable performance problems should probably avoid littering their code with cryptic incantations without actual benefit.

Descriptions of Commands

Go here: http://www.stack.nl/~dimitri/doxygen/commands.html for descriptions of the commands mentioned.

Putting it All Together

Here is a short example showing all the elements together. This is an old version of the Project 1 starter code, presented in order to demonstrate doxygen (i.e., don't cut and paste this code into a current project!). As a note, README.dox is a text file with a single block of C-style comments in it.

Doxygen Style Comment

Click here for the corresponding html document that is created by doxygen.