1
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
4
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5
<meta name="Author" content="Joachim Gabler">
6
<meta name="GENERATOR" content="Mozilla/4.76C-CCK-MCD [en] (X11; U; SunOS 5.8 sun4u) [Netscape]">
11
Source code documentation using adoc</h1>
12
An essential characteristic of high quality source code is a comprehensive
14
<p>For the Grid Engine development, we started some time ago to use so
15
called Autodoc Headers that are interpreted by the adoc utility.
16
<p>Adoc was originally written by Tobias Ferber and published unter the
18
<br>It can create ASCII and Texinfo output, Texinfo can be used to
19
publish the documentation in a lot of different output formats including
20
HTML, PDF, GNU Info, DVI etc.
21
<p>It's functionality is a little bit rudimentory and can not really compete
22
with tools like doxygen or the javadoc tool, but it has the advantage,
23
that it can be used to parse not only C or Java source code, but also any
24
scripting languages like tcl, shell etc. using the same syntax.
25
<p>The source code of adoc can be found in the directory <tt>source/3rdparty/adoc</tt>.
26
<br>We modified it to support 3 levels of chapters/sections instead of
30
Generating the documentation</h2>
31
The documentation can be generated automatically using the aimk script
32
(<tt>source/aimk</tt>).
33
<br>Calling <tt>aimk -adoc</tt> will
36
compile the adoc tool</li>
39
generate 3 texinfo files:</li>
43
documentation of the library functions (<tt>libs.texi</tt>)</li>
46
documentation of the core system (<tt>core.texi</tt>)</li>
49
documentation of the testsuite (<tt>testsuite.texi</tt>)</li>
52
The texinfo files can be used to generate a readable documentation in different
57
Generate HTML-Documentation:</li>
59
<br><tt>texi2html libs.texi</tt>
60
<br>Writes a file <tt>libs.html</tt> containing the documentation and a
61
file <tt>libs_toc.html</tt> containing a table of contents with links to
64
Generate Documentation in PDF Format:</li>
66
<br><tt>texi2pdf libs.texi</tt>
67
<br>Creates a file <tt>libs.pdf</tt></ul>
70
Writing documentation</h2>
71
Each function of C, TCL or shell code should have an autodoc header, especially
72
these in function libraries.
73
<br>The header can be inserted from a template (see<tt><font color="#000000">doc/devel/c-header</font></tt>for
74
C-Syntax, <tt><font color="#000000">doc/devel/sh-header</font></tt>for
75
TCL and shell syntax) or by using a tcl script defined as editor macro.
77
Macro for automated insertion of autodoc headers</h3>
78
The distribution contains a small tcl script that may be used to
79
automatically insert an autodoc header into a source file (see <tt>doc/testsuite/adoc/doc_tool.tcl</tt>).
80
<br>It creates an autodoc header and automatically enters data for the
81
category and function name, and the autodoc sections <tt>NAME</tt>, <tt>SYNOPSIS</tt>,
84
<p>It can be called as macro from the editor, if the editor has some means
85
to include macros and the call of external programs.
86
<p>The doc_tool.tcl has a variety of options to parse and modify source
87
code for source code documentation purposes.
89
Insertion of autodoc headers in the vim editor</h4>
90
To install such a macro in the vim editor, edit the .vimrc file in your
91
homedirectory and add the following line:
92
<p><tt>map ^P :-r !doc_tool mode C output stdout no_warnings func <cword>
94
<p>To enter the ^P and ^M, in vi press CTRL-V CTRL-p / CTRL-V CTRL-m.
95
<p>If you place the cursor on a C function prototype and press F11,
96
a new partly filled out autodoc header for the function will be inserted
98
<p>Newer vim versions (beginning with 6.0?) seem to use another syntax
99
in the .vimrc file. Add the following line to your .vimrc file (install
100
macro on F9, F11 as in the previous example didn't work for some reason:
101
<p><tt>map <unique> <F9> :-r !doc_tool mode C output stdout no_warnings
102
func <cword> %:p^M</tt>
104
Choosing a function identifier</h3>
105
The current structure of the source code documentation provides 3 individual
106
files - documentation of libraries, the core system binaries and the testsuite.
107
<br>Within each document, we have 3 hiearchical levels of sections - in
108
texinfo: chapter, section and subsection.
109
<p>The current documentation is structured not to reflext strictly the
110
directory structure of the code in the section hierarchy, but the structure
111
reflects categories of code within a certain directory based structure.
112
<p>Each source file contains functions belonging to exactly one function
115
<br>The module qsh has the function category <tt>Interactive/qsh</tt>:
116
It is a tool to create an interactive job in Grid Engine, its name is qsh.
117
<p>Possible function identifiers then are
118
<br><tt>Interactive/qsh/--Interactive</tt>
119
<br><tt>Interactive/qsh/add2env()</tt>
121
<p>To enable the doc_tool.tcl to insert adoc headers with the correct function
122
categoriy filled in automatically, there exists a file doc/devel/doc_tool.cat
123
that maps directories and optionally filenames to function categories.
124
One line contains one mapping.
126
<br><tt>source/clients/qsh Interactive/qsh</tt>
127
<br><tt>source/clients/qrsh Interactive/qrsh</tt>
128
<br><tt>source/daemons/execd execd</tt>
129
<br><tt>source/daemons/execd/load_avg.* execd/load</tt>
130
<br><tt>source/daemons/execd/sge_load_sensor.* execd/load</tt>
134
Function categories for the library documentation</h4>
158
hash - cull specific hash table extensions, based on uti/hash</li>
225
htable - generic hash table implementation</li>
255
string- string parsing functions</li>
269
Function categories for the core system documentation</h4>
363
Function categories for the testsuite documentation</h4>
383
performance_cluster</li>
386
performance_scheduler</li>
441
Filling out the autodoc header</h3>
442
The following sections of an autodoc header should always be filled out:
445
<b><tt>NAME</tt></b></li>
447
<br>The function name and a short (one line) description
449
<b><tt>SYNOPSIS</tt></b></li>
451
<br>The function prototype, optionally preceeded by an include statement,
452
if needed and compiler/linker options, see <a href="#Examples for adoc headers">Examples
455
<b><tt>FUNCTION</tt></b></li>
457
<br>A complete function description.
459
<b><tt>INPUTS</tt></b></li>
461
<br>Description of all input parameters
463
<b><tt>RESULT</tt></b></li>
465
<br>Description of the result</ul>
467
<p><br>These sections are optional :
470
<b><tt>EXAMPLE</tt></b></li>
472
<br>How to use the function
474
<b><tt>NOTES</tt></b></li>
476
<br>Notes for further development, hints for the usage etc.
478
<b><tt>BUGS</tt></b></li>
480
<br>adoc provides a BUGS section to document known bugs - please do not
481
create BUGS sections - use IssueZilla instead.
483
<b><tt>SEE ALSO</tt></b></li>
485
<br>References to other functions, man pages etc.</ul>
489
Introduction pages for Categories</h3>
490
A category usually reflects some hierarchy in the source code tree, often
491
an individual binary, and deserves to have an introductory autodoc header
492
before the detailed function descriptions.
493
<p>Therefor an autodoc header should be written for each category that
494
gives a short overview of the category and may refer to other autodoc headers
496
<p>The header of such an introductory page has the form
497
<br><tt>/****** chapter/section/--topic *****************</tt>
498
<p>The hyphens (-) before the topic influence autodoc's sorting algorithm:
499
The introductory page will always be the the first page of a section.
503
Documentation of defines, global variables etc.</h3>
504
It is desirable to have documentation also for constants/defines, global
505
variables, structures, typedefs etc.
506
<p>The following special function identifiers are used for this type of
509
<br>-topic-Global_Variables
513
<p>Again, the hyphen before the identifiers name influence adoc's sorting
517
<a NAME="Examples for adoc headers"></a>Examples for adoc headers</h2>
520
An introduction header</h3>
521
<tt>/****** Interactive/qmake/--qmake ***************************************</tt>
523
<br><tt>* NAME</tt>
524
<br><tt>* qmake -- Scheduled parallel distributed
527
<br><tt>* SYNOPSIS</tt>
528
<br><tt>* qmake <sge options> -- <gmake options></tt>
530
<br><tt>* FUNCTION</tt>
531
<br><tt>* Scheduled, parallel, distributed make.</tt>
532
<br><tt>* qmake is implemented based on GNU make
533
3.78.1 using the remote stub</tt>
534
<br><tt>* mechanism of gmake.</tt>
535
<br><tt>* qmake will start a parallel job and run
536
make tasks as task in the</tt>
537
<br><tt>* parallel job using the Grid Engine qrsh
538
-inherit command.</tt>
540
<br><tt>* INPUTS</tt>
541
<br><tt>* sge options - all options that can be
542
specified with qsub command</tt>
543
<br><tt>* gmake options - all possible gmake
546
<br><tt>* RESULT</tt>
547
<br><tt>* returncode from gmake or EXIT_FAILURE,
548
if remote mechanism fails.</tt>
549
<br><tt>* On error, an appropriate error description
550
is written to stderr.</tt>
552
<br><tt>* EXAMPLE</tt>
553
<br><tt>* qmake -cwd -v PATH -- -j 5</tt>
554
<br><tt>* Build sge system: aimk -qmake -parallel
557
<br><tt>* NOTES</tt>
558
<br><tt>* not yet internationalized</tt>
560
<br><tt>****************************************************************************</tt>
564
A header describing defines</h3>
565
<tt>/****** Interactive/qmake/-qmake-Defines ***************************************</tt>
567
<br><tt>* NAME</tt>
568
<br><tt>* Defines -- constant and macro definitions</tt>
570
<br><tt>* SYNOPSIS</tt>
571
<br><tt>* #define LOCK_SLEEP_TIME 500</tt>
572
<br><tt>* #define WAIT_SLOT_TIME
575
<br><tt>* FUNCTION</tt>
576
<br><tt>* LOCK_SLEEP_TIME - Defines how long qmake
578
<br><tt>*
579
after an unsuccessful try to get a lock to the</tt>
580
<br><tt>*
582
<br><tt>* WAIT_SLOT_TIME - Time to wait,
583
if no slot is free in hostfile</tt>
585
<br><tt>****************************************************************************</tt>
589
A function description</h3>
590
<tt>/****** Interactive/qmake/remote_exit() ***************************************</tt>
592
<br><tt>* NAME</tt>
593
<br><tt>* remote_exit() -- exit qmake</tt>
595
<br><tt>* SYNOPSIS</tt>
596
<br><tt>* static void remote_exit(int code, const
598
<br><tt>*
599
const char *reason);</tt>
601
<br><tt>* FUNCTION</tt>
602
<br><tt>* Outputs the error messages passed as
603
parameters to stderr</tt>
604
<br><tt>* and then exits with the error code passed
607
<br><tt>* INPUTS</tt>
608
<br><tt>* code - exit code</tt>
609
<br><tt>* message - message to output before exit,
610
should describe the</tt>
611
<br><tt>*
612
situation when error occurs</tt>
613
<br><tt>* reason - description of the error
614
reason, e.g. result from</tt>
615
<br><tt>*
616
system call strerror(errno)</tt>
618
<br><tt>* RESULT</tt>
619
<br><tt>* program exits</tt>
621
<br><tt>* EXAMPLE</tt>
622
<br><tt>* #include <stdlib.h></tt>
623
<br><tt>* #include <string.h></tt>
624
<br><tt>* #include <errno.h></tt>
626
<br><tt>* ...</tt>
628
<br><tt>* if(write(filehandle, buffer, size) !=
630
<br><tt>* remote_exit(EXIT_FAILURE,
631
"writing to file failed", strerror(errno));</tt>
632
<br><tt>* }*</tt>
633
<br><tt>****************************************************************************</tt>
637
Description of a Cull object/class</h3>
638
<tt>/****** gdi/range/--RN_Type ***************************************************</tt>
639
<br><tt>* NAME</tt>
640
<br><tt>* RN_Type - CULL range element</tt>
642
<br><tt>* ELEMENTS</tt>
643
<br><tt>* SGE_ULONG(RN_min)</tt>
644
<br><tt>* minimum or start value
645
of an id range (e.g. 1)</tt>
647
<br><tt>* SGE_ULONG(RN_max)</tt>
648
<br><tt>* maximum or end value
649
of an id range (e.g. 9)</tt>
651
<br><tt>* SGE_ULONG(RN_step)</tt>
652
<br><tt>* stepsize (e.g. 2)</tt>
654
<br><tt>* FUNCTION</tt>
655
<br><tt>* CULL element holding values which define
657
<br><tt>* (e.g. 1-9:2 => 1, 3, 5, 7, 9).</tt>
658
<br><tt>* Lists of this CULL element are hold within
659
a CULL job element</tt>
660
<br><tt>* (JB_Type) to hold job array task ids.</tt>
661
<br><tt>* Several functions may be used to access/modify/delete
663
<br><tt>* elements and range lists. You may find
664
them in the 'SEE ALSO'</tt>
665
<br><tt>* section. It is highly advised to use
666
these access functions</tt>
667
<br><tt>* because they assure and require a defined
669
<br><tt>* elements and lists.</tt>
671
<br><tt>* Range elements and lists stored in other
672
CULL elements fullfill</tt>
673
<br><tt>* following conditions:</tt>
675
<br><tt>* - min <= max</tt>
676
<br><tt>* - step >= 1</tt>
677
<br><tt>* - real range elements
678
(e.g. 1-9:2 instead of 1-10:2)</tt>
679
<br><tt>* - min-ids within range
680
elements part of the same</tt>
681
<br><tt>* list are
682
in ascending order: min_id(n) < min_id(n+1)</tt>
683
<br><tt>* (e.g. NOT
685
<br><tt>* - ids within range
686
elements part of the same</tt>
687
<br><tt>* list are
688
non-overlapping: max_id(n) < min_id(n+1)</tt>
689
<br><tt>* (e.g. 1-9:2;
690
11-20:1; 25-28:3)</tt>
692
<br><tt>* SEE ALSO</tt>
693
<br><tt>* gdi/range/RN_Type</tt>
694
<br><tt>* gdi/range/range_list_calculate_union_set()</tt>
695
<br><tt>* gdi/range/range_list_calculate_difference_set()</tt>
696
<br><tt>* gdi/range/range_list_calculate_intersection_set()</tt>
697
<br><tt>* gdi/range/range_list_compress()</tt>
698
<br><tt>* gdi/range/range_list_get_first_id()</tt>
699
<br><tt>* gdi/range/range_list_get_last_id()</tt>
700
<br><tt>* gdi/range/range_list_get_number_of_ids()</tt>
701
<br><tt>* gdi/range/range_list_initialize()</tt>
702
<br><tt>* gdi/range/range_list_insert_id()</tt>
703
<br><tt>* gdi/range/range_list_is_id_within()</tt>
704
<br><tt>* gdi/range/range_list_move_first_n_ids()</tt>
705
<br><tt>* gdi/range/range_list_print_to_string()</tt>
706
<br><tt>* gdi/range/range_list_remove_id()</tt>
707
<br><tt>* gdi/range/range_correct_end()</tt>
708
<br><tt>* gdi/range/range_get_all_ids()</tt>
709
<br><tt>* gdi/range/range_get_number_of_ids()</tt>
710
<br><tt>* gdi/range/range_is_overlapping()</tt>
711
<br><tt>* gdi/range/range_is_id_within()</tt>
712
<br><tt>* gdi/range/range_set_all_ids()</tt>
713
<br><tt>* gdi/range/range_sort_uniq_compress()</tt>
714
<br><tt>* gdi/job/JB_Type</tt>
715
<br><tt>******************************************************************************/</tt>
717
Documentation of a TCL function</h3>
718
#<tt>****** library/control/ps_grep() ******</tt>
720
<br><tt># NAME</tt>
721
<br><tt># ps_grep -- call get_ps_info and return
722
only expected ps information</tt>
724
<br><tt># SYNOPSIS</tt>
725
<br><tt># ps_grep { forwhat { host "local" } {
726
variable ps_info } }</tt>
728
<br><tt># FUNCTION</tt>
729
<br><tt># This procedure will call the get_ps_info
730
procedure. It will parse the</tt>
731
<br><tt># get_ps_info result for the given strings
732
and return only those process</tt>
733
<br><tt># ids which match.</tt>
735
<br><tt># INPUTS</tt>
736
<br><tt># forwhat
737
- search string (e.g. binary name)</tt>
738
<br><tt># { host "local" }
739
- host on which the ps command should be called</tt>
740
<br><tt># { variable ps_info } - variable name
741
to store the result (default ps_info)</tt>
743
<br><tt># RESULT</tt>
744
<br><tt># returns a list of indexes where the search
745
string matches the ps output.</tt>
747
<br><tt># EXAMPLE</tt>
749
<br><tt># set myprocs [ ps_grep "execd" "fangorn" ]</tt>
751
<br><tt># puts "execd's on fangorn index list: $myprocs"</tt>
753
<br><tt># foreach elem $myprocs {</tt>
754
<br><tt># puts $ps_info(string,$elem)</tt>
755
<br><tt># }</tt>
757
<br><tt># output of example:</tt>
759
<br><tt># execd's on fangorn index list: 34 39 50 59 61</tt>
760
<br><tt># 2530 140 1
761
259 S Sep12 1916 00:00:14 /sge_s/glinux/sge_execd</tt>
762
<br><tt># 7700 142 1
763
339 S Sep13 2024 00:03:49 /vol2/bin/glinux/sge_execd</tt>
764
<br><tt># 19159 0
765
1 0 S Sep14 1772 00:31:09 /vol/bin/glinux/sgeee_execd</tt>
766
<br><tt># 24148 0
767
1 0 S Sep14 2088 00:06:23 bin/glinux/sge_execd</tt>
768
<br><tt># 15085 0
769
1 0 S Sep14 1904 00:27:04 /vol2/glinux/sgeee_execd</tt>
771
<br><tt># NOTES</tt>
772
<br><tt># look at get_ps_info procedure for more information!</tt>
774
<br><tt># SEE ALSO</tt>
775
<br><tt># library/control/get_ps_info()</tt>
776
<br><tt>#*******************************</tt>
778
Documentation of a shell script</h3>
779
<tt>#****** utilities/preemption/high_prolog.sh ***************************************</tt>
781
<br><tt># NAME</tt>
782
<br><tt># high_prolog.sh -- prolog for high priority
785
<br><tt># SYNOPSIS</tt>
786
<br><tt># high_prolog.sh</tt>
788
<br><tt># FUNCTION</tt>
789
<br><tt># If the number of slots occupied in queues
790
belonging to the preemption</tt>
791
<br><tt># mechanism exceeds the number of slots
792
reserved, an appropriate number</tt>
793
<br><tt># of low priority jobs/tasks are suspended.</tt>
794
<br><tt># The jobid's of the jobs suspended are
795
written to a job context variable</tt>
796
<br><tt># "suspended" separated by a colon (:).</tt>
798
<br><tt># If the number of slots occupied is equal
799
or exceeds the number of</tt>
800
<br><tt># reserved slots, the low priority queues
803
<br><tt># SEE ALSO</tt>
804
<br><tt># utilities/preemption/--Preemption</tt>
805
<br><tt># utilities/preemption/high_epilog.sh</tt>
806
<br><tt># utilities/preemption/low_prolog.sh</tt>
807
<br><tt># utilities/preemption/low_epilog.sh</tt>
809
<br><tt>#***************************************************************************</tt>