| Copyright © 1998-2006 Dipl.-Inform. Kai Hofmann. All rights reserved! | |||||||
This text is to introduce a new standard for source code documentation. It is based on the idea of the Autodoc Style Guide by Commodore Electronics Ltd, dated June 1990. We will call it Autodoc - 2.0, because a scant version by Amiga Inc. already exists.
To begin with, its for you. You need a guideline on how to write a source code
documentation.
Furthermore, it is a guideline for other programmers as well who might use your
code (i.e. a library of special kinds of operations or functions).
So, you can see this as a standard helping all/most programmers developing
software and helping people interested in reusing software. You can get an idea
of 'how' to write ones documentation for source code so that it could be
used and understood by others.
You know about the software-crisis, don't you? Part of this crisis is the fact that program code is not documented. It is therefore extremely difficult if almost impossible to edit code written by another person, or to edit code which is many years old. This can happen since you or other persons (after many years) do not know what a function or an object does and what the main idea actually was supposed to accomplish. So, with this standard you now have the possibility to include documentation for your functions/classes directly into the source code in order for the users to get the idea of what and why something is being done. Another important advantage is that you don't have to work on two copies of the documentation at once. Normally the documentation is a seperate document, and most programmers also put documentation into their program. That is twice the work, and it is difficult to keep these two documents consistent. Autodocs solves this problem by defining a way to include the documentation in the source code and providing a way to extract it.
You could put your autodocs everywhere, where your programming language lets you put in comments. But, there is a special place where it is recommended to put an autodoc - if it is possible.
Put it between the function header definition and the implementation block!
There are two reasons for putting an autodoc there.
Autodocs should be read easily - therefore they have to be formatted extremely well. Autodoc 2.0 entry comes with a start line, a body and an end line - maybe sometimes even with a private comment in an area mapped out for it.
There can be a variation of lines, each line will be unlimited in length, but a maximum of 79 characters is recommended, since by using 79 characters a maximum of characters per line will make it possible to print out the autodo as well as the source code included in it on an 80 character per line printer (i.e. a normal printer these days:-) without any problems!
Before I proceed I like to tell you about different programming languages. As you know we want to include the autodocs directly in the source code; therefore we have to use the comment features of the different languages.
There are two ways of defining something as a comment. Lets look at it quickly.
The first one (we think this might be the best one) there are comments
which start with a special character combination and end with another - like in
C, C++ and Arexx '/*' and '*/', in Pascal, Modula-II, Oberon '(*' and '*)' or
'<!--' and '-->' in SGML, '{' and '}' in ASpecT.
Therefore we can open a comment, write down the autodoc completely and close it
afterwards.
The second one for writing comments is not so easy, but it is used very often.
Comments are started by a special character sequence and end with the next line
break ('\n') like it is used in Shell scripts, Cobol, PostScript, LaTeX, C++,
Miranda, Basic etc.
To make it possible to use autodocs with this second style of comments each
line of an autodoc will be parsed after the first '*', so you might first
begin your comment by using ';', '#' or 'REM' and then follow with an
asterisk and the autodoc line contents.
Each line of an autodoc, that will not start with an asterisk will be reported as a warning and then ignored.
Lets see now how to start an autodoc.
An autodoc normally starts with 7 asterisks followed by a space. Normally it means
that the first '*' could be any character, so that you could use a '/' or a '('
or a '{' as the first character. This makes it possible to make the startline
of the autodoc the same as the startline of the comment!
After this the next three '*' are fixed and then the next two '*' have a special
meaning. The first one can be set to 'o' what means that it is an old autodoc
that will be only there for backward compatibility. The second asterisk has a
special meaning, also.
You can write an 'i' there instead of the asterisks to mark an autodoc as an
internal autodoc!
The last asterisk is fixed again as well as the following space.
Here are some examples for errorfree starts of an autodoc ('_' is the space!):
*******_/******_(******_*****i*_/****i*_(****i*_/***o**_/***oi*_#******_REM *******_An internally marked autodoc will only be extracted if you explicitely tell the utility extracting the docs that you want the internal autodocs. This will give you the possibility to hide autodocs from help functions about which other developers who only use your code, need to know nothing at all.
The same thing happens to the autodocs marked as old. They will only appear in the output of the extractor utility if you request it. Otherwise they will be left out, since there is no need for them any longer.
After the start a heading description will follow (see below for more) and than
(after a space) you can include into '[]' the version and revision number, in
which the function etc. you describe, will first appear. After another space
you can fill up the line with asterisks - any other characters will be
treated as errors.
Example:
/****** library/function() [1.5] *****************************************/****** library/function() ***********************************************/****** library/function() [1.5]/****** library/function()From now on each line of the autodoc will start with an asterisk. After the start of the autodoc a blank line (this means a line with the asterisk at the start and nothing else in it) has to occur. The next lines will all follow this pattern.
The first line will define a keyword (keywords are defined below) which will identify what information will follow. The keyword has to be written in uppercase and will follow the asterisk after three blanks!
Example:
* NAME
The next line(s) will contain the information required by the
keyword belonging to it. This information has to be written after the '*'
and a tabulator '\t' or if there is no tabulator, by 7 spaces!
Example:
* Test
* Test
* This test statement was broken up* into two lines.
After you have written all lines of information for the keyword, there has to follow a blank line again (remember: a blank line means a line with only one asterisk in it!).
Now other keyword definitions might follow.
Example:
* NAME
* test
*
* IDEA
* No idea ;-)
*
After you have written all your text, the 'end-of-autodoc' line will follow.
This line is defined as a line of a minimum of 3 asterisks. It means you might fill up the line with as many asterisks as you want. It can be followed possibly by the counter-part of the comment start found at the first position of the autodoc start line. But, keep in mind, that every other character will be treated as an error (please remember - 79 characters are recomended).
Examples:
******/***)******************************************************************/*****************************************************************************After this last line you might continue with private comments. These can start with an asterisk. They will never be extracted by the extractor utility.
Examples:
***
*
* private comments
*
*/
***
private comments
*
The heading description is needed to identify the library or source code file to which your code belongs. It also is needed to identify the function, class, method or record which will be described by the autodoc.
The first part is the library or source code filename followed by a '/'.
One of the following things can follow:
VAR' followed by the name of a variable.RECORD' followed by the name of a record/structure.UNION' followed by the name of a union.SET' followed by the name of a set.--'s (see below for more).CLASS' followed by the classname followed by a '/' and then one of the six points above or one of the following two keywords which are only valid in a class autodoc:
ATTR' followed by the name of an attribute.METHOD' followed by the name of a method.Examples:
exec.library/AbortIO()exec.library/RECORD IORequestdate/GregorianLeapYear()date/--background--dateclass/CLASS date/date()dateclass/CLASS date/date(jd)dateclass/CLASS date/date(day,month,year)audio.device/CLASS audio/METHOD CD_ASKDEFAULTKEYMAPdateclass/CLASS date/METHOD DATE_WRITEASSTRINGNow a comment about the special identifiers surrounded by '--'s!
These identifiers are used for background information (only one of a type is allowed per source file). I defined the following ones (may be extended in the future):
DEBUG' etc.Here are the descriptions of the defined keywords.
NAME
Put your function name etc. here. Instead of using the --background-- heading you should use the name of your module.
The name is followed by ' -- ' and then by a short description of what it is doing. After the description you might include in parenthesis '()' the version number of the operating systems which will be supported first. In the case of developing system independent code there is no need to make use of this version number feature.
The description should be a real sentence. If it is impossible to write a short sentence, use periods.
Examples:
* NAME
* GregorianLeapYear() -- Calculate the Gregorian leap year (V33)
* NAME
* Date -- This module was designed to help calc.calendar dates
* NAME
* struct CD -- Structure to archive a CD (V33)
* NAME
* date -- Class to calculate dates
* NAME
* date/operator+() -- Add a difference to a date
SYNOPSIS
The synopsis will describe three things. At first the calling conventions, followed by the assembly registers (only if you develop a library!). Finally describe a prototype of your function (ANSI style is prefered!).
For vars, records, unions and sets use only the prototype style.
Please use understandable name tokens for the calling convention!
If you are developing your code in different programming languages you might only use a C style, or use other languages as appropriate in a new line (see example below). The prototype has to be 'ready to compile'!
Examples:
* SYNOPSIS
* leapyear = JulianLeapYear(year);
* d0 d0
*
* bool JulianLeapYear(const int year);
* SYNOPSIS
* leapyear = JulianLeapYear(year);
*
* bool JulianLeapYear(const int year);
* SYNOPSIS
* struct CD {
* char name[40],
* Titel *first,
* unsigned short playlength
* };
* SYNOPSIS
* leapyear = JulianLeapYear(year); \* C *\
* leapyear := JulianLeapYear(year); \* Modula-2 *\
*
* bool JulianLeapYear(const int year); \* C *\
* PROCEDURE JulianLeapYear(year : INTEGER) : BOOLEAN; \* Modula-2 *\
FUNCTION
Describe what your function does or what your record/module is to be used for.
You should use commonly accepted English with a minimum of jargon, but don't sacrifice clarity and accuracy. Use as many lines as you need.
Example:
* FUNCTION
* JulianLeapYear checks if a year is a leap year in the Julian calendar.
* For years after Chr. it checks if the year is devideable by 4.
* For years before Chr. a leap year must have a modulo 4 value of 1.
INPUTS
Describe the range and domain of each input parameter of your function/procedure.
Use the name tokens from the SYNOPSIS calling convention. After this use a '-' and then write your description. If your description will be longer than one line, please be free to use more lines, but you should use an extra indent of 4 spaces.
Example:
* INPUTS
* year - The year which should be checked (from -32768 to 32767)
* Only values from 8 to 32767 are valid, because of
* the variant that was done by Augustus!
RESULT
Same as for INPUTS - describe the range and domain of each output parameter (remember: result parameters are not only function results! - pointer parameter are often results too.). Use the name tokens from the SYNOPSIS calling convention, followed by a '-'.
Don't forget to use an indent of 4 spaces for extra lines.
Example:
* RESULT
* leapyear - TRUE if the year is a leap year, otherwise false.
ELEMENTS
Same as INPUT/RESULTS, but for records and unions.
Describe each element of the record with its range and domain. Use the name tokens from the SYNOPSIS prototype, followed by a '-'.
Use an indent of 4 spaces for extra lines.
SYNTAX
This is an optional extention to the INPUT section.
Describe parameters which will be sent to a function by strings, like its done by C's printf() for the % commands.
Describe each text-command - use the token of it followed by a '-', and use an extra indent of 4 spaces for extra lines.
EXAMPLE
Include an optional short example. This must be ready to compile! So please test it first!
Use '...' to indicate removed sections, and don't edit the example, except you test it again!
Keep track of comment problems - because it is not possible to have nested comments in ANSI-C (bad thing) - use a reversed / (\) for comments, this will be converted by the extractor utility!
Example:
* EXAMPLE
* ...
* \* My birthday compared with today *\
* if (Compare2Dates(18,9,1970,22,1,1994) == -1)
* printf("<\n");
* else
* printf(">=\n");
* ...
NOTES
Write down helpful things like hints, tricks, warnings, traps etc.
Example:
* NOTES
* This function is only needed/available if you do not compile this
* with a SAS-C Compiler (using autoinitialization!)
* If you are not using SAS-C - don't forget to initialize this module with
* this function - or you will get into trouble!!!
BUGS
If there are known bugs, you could describe them in detail here. Please try to list how the bug can be avoided, if it is possible to make workarounds. Please include this information for different versions!
Example:
* BUGS
* There is no check if the dates are valid!
SEE ALSO
List all related functions/records etc. to describe the current function, separated by comas.
Place the names of functions here, if these could be found in other files - include the name of the header file first (if there is one - if not, use the main file), followed by a '/' and the function/record etc. name.
If the file is to be found in another directory, please use a relative path (Unix style preferred). If you want to refer to compiler/system libraries here include them in '<>'.
Example:
* SEE ALSO
* GregorianMonthDays(),JulianYearDays(),HeisYearDays()
* <stdio.h>,RECORD date,../test/test.h/month(),header.h
VERSION
Here you should include the version of your module/function/record etc.
A good thing to do this is by using a version number separated by a '.' from a revision number (see example).
Example:
* VERSION
* 33.155
This is the 33 version in the 155 revision.
HISTORY
Its a nice thing to have complete development history. This should be placed here in the following style:
First, write the date of the modification (ISO 8601:1988 style prefered), followed by a '-' and a tabulator. Now describe what you modified. For extra lines use tabulators for the correct indent.
Example:
* HISTORY
* 03.06.1995 - Procedures: TimeDiff(), DiffTime() initiated.
* Fixing small bugs in datetest.c and implementing
* C++ support
* 18.06.1995 - Again small fixes in GregorianDayDiff(),
* HeisDayDiff()
RELEASE
This is like HISTORY, but for released versions of your product only. Please use first the date of the release (ISO 8601:1988 style prefered), followed by a ':' and the version number of the code (version.release style). This is followed by a '-' and a tabulator, then write the release version (i.e. V1.2) and where it was released. Please use tabulator indents for extra lines.
Example:
* RELEASE
* 13.04.1994 : 33.087 - V1.0 First release on Aminet3 & SaarAG 707
* 13.08.1994 : 33.088 - V1.1 Second release on Aminet4, SaarAG 793,
* Fred Fish & SimTel
TODO
That is for things you want to do in the future, so that you will not forget them.
Example:
* TODO
* Country dependend for 1582
* Rising/setting of moon and sun
* Tcl interface
COPYRIGHT
Include the copyright notice for your module/software.
Example:
* COPYRIGHT
* This software is copyrighted 1994-95 by Kai Hofmann.
* All rights reserved!
*
* ...
DISCLAIMER
This section is reserved for a disclaimer (like the GNU one).
Example:
* DISCLAIMER
* THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
* ...
DISTRIBUTION
This is reserved for the distribution text.
Example:
* DISTRIBUTION
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to copy and distribute this software and its
* documentation for any purpose, provided that the above copyright
* notice and the following paragraphs appear in all copies of this
* software, to:
* - All who will distribute this software for free!
ADDITIONAL INFORMATION
Include additional information for your software, like how to make payments etc.
Example:
* ADDITIONAL INFORMATION
* Kindly send US dollars to a friend of mine in the USA who will
* forward it to me in a timely manner. Please send checks or money
* orders only.
* Contact me via email for specifics!
AUTHOR
Include your name, address, phone number, email or WWW pages for contacts. Place a bank account for payments if so desired.
Example:
* AUTHOR
* Kai Hofmann
* Arberger Heerstr. 92
* 28307 Bremen
* Germany
*
* EMail: hofmann@hofmann-int.de
*
* WWW : http://www.hofmann-int.de/
THANKS
Include thank you statements to people who helped you - if so desired.
Example:
* THANKS
* Rita Reichl - For the revision of this document
* Frans Slothouber - For the robodoc utility and for
* revision of this document
COMPILING
Talk about special features how to compile your source code.
Example:
* COMPILING
* - Compile this code as normal C or as C++
* - _ISO8859_Latin1 should be defined if your system supports this
* font encoding technology!
The following keywords are defined to make it possible to include an announce in the autodocs (don't forget to use the keywords VERSION, AUTHOR and DISTRIBUTION):
TITLE
The name of your software
Example:
* TITLE
* date.library
RELEASE DATE
The release date of your software.
Example:
* RELEASE DATE
* 29.06.1995
DESCRIPTION
Describe what your software is doing (this is like the FUNCTION keyword, but for the complete software!)
Example:
* DESCRIPTION
* A portable ANSI-C/C++ library that provides low level functions for
* date calculations.
* It includes the following features:
*
* - Support for six different date/time measurement systems:
* Julian, Gregorian, Heis, Julian Day, Modified Julian Day,
* Scaliger Year (other systems will follow).
* - Month/Weekday and other date/time string support for 12 languages.
* ...
NEW FEATURES
Describe new features which were added since the last release.
Example:
* NEW FEATURES
* - Bug fixes
* - Supporting more languages
* - Functions for checking validity of dates/times
SPECIAL REQUIREMENTS
Write about requirements which are needed by your software - like a special Operating System version etc.
Example:
* SPECIAL REQUIREMENTS
* ANSI-C or C++ Compiler.
* Amiga OS3.1+
* 68030 with MMU
AVAILABILITY
Please include places where your software is located (this could be a ftp site, or a dealer). For ftp sites etc. please use the Universal Resource Location style!
Example:
* AVAILABILITY
* ftp://wuarchive.wustl.edu/pub/aminet/dev/c/date.lha
* And all other Aminet sites.
PRICE
If your software is not Public Domain please include your ideas here.
Example:
* PRICE
* For NON-COMMERCIAL USE this is Giftware!
* (Non-commercial includes Giftware and Shareware!)
*
* Permission for COMMERCIAL USE is only given by an extra available
* commercial license that must be validated!
* Contact me directly for this license, because it will be individually
* handed out per your needs!