diff --git a/doc/prog/makefile_libs.tex b/doc/prog/makefile_libs.tex index 036a66d7f9..4fb80b22da 100644 --- a/doc/prog/makefile_libs.tex +++ b/doc/prog/makefile_libs.tex @@ -12,7 +12,7 @@ The working assumption in documenting the NWChem code is that the developers will be relatively sophisticated hackers, used to deciphering C and Fortran source code and makefile scripts. The steps for building -an executable version of the code are as automated as possible, with +an executable version of the code are as automated as is practical, with upward of a hundred individual makefiles in the source code directory tree. The developer is advised to look carefully at the top-level makefile @@ -45,10 +45,10 @@ development). Only those routines which are performance hot spots are optimized. This helps avoid stupid compiler bugs which, by empirical observation, are more likely to show up on things other than hard-working number crunching. Each makefile contains an {\tt OBJ\_OPTIMIZE} -macro which should name those routines that {\tt should} be built with +macro which should name those routines that {\em should} be built with optimization. All the rest should be listed in the OBJ macro. The extra arguments used when compiling optimized code are the -platform-dependent [FC]OPTIMIZE macros in config/makefile.h. If you +platform-dependent [FC]OPTIMIZE macros in \verb+config/makefile.h+. If you want to turn off all optimization, change these and rebuild. At present, the package is almost entirely self-contained. The only diff --git a/doc/prog/newdoc.tex b/doc/prog/newdoc.tex index e99ea9c5c9..15fbdf6dd2 100644 --- a/doc/prog/newdoc.tex +++ b/doc/prog/newdoc.tex @@ -12,16 +12,15 @@ structure and organization of new code. Activities that require documentation fall into three broad categories; \begin{enumerate} -\item development of a new molecular calculation module -\item modification or enhancement of an existing molecular calculation module -\item modification or enhancement of elements of any of the toolkits -(i.e., the molecular modeling -tools, the software development toolkit, or the utilities) +\item development of a new capability (such as a new molecular calculation +module) within any of the architecture levels, +\item development of a new subroutine or function, +\item modification or enhancement of an existing molecular calculation module, +API,object or subroutine \end{enumerate} -The following subsections present guidelines and templates -to help the developer produce useful documentation for work in each of -these categories. The basic philosophy of documentation in NWChem +Basically, whenever functionality is added or modified in the program, it +must be documented. The basic philosophy of documentation in NWChem is to have as much of the documentation as possible in the source code itself. This is where one most likely would be looking when most in need of guidance. This approach also holds forth the shining hope that @@ -31,11 +30,37 @@ this manual. However, for the high level modules in the code, the level of detail required for the documentation to be useful will generally result in too much verbage to be readily included in the the source code as comment lines. So some -additional documentation will always be necessary. +additional documentation may always be necessary. -\section{Documentation of a New Molecular Calculation Module} +There are two seperate issues that must be discussed for documentation. +The first is the content of the documentation. The second is the +way the documentation must be formatted (i.e. a style guide). Both of +these will be discussed in the following sections. + +\section{Content of the Documentation} \label{sec:standalone} +The level of documentation is, by necessity, different for molecular +calculation modules, +modeling or development tools, +and subroutines or functions. +The molecular calculation modules represent a high level of functionality +and can be considered as requiring the highest level of documentation. +These modules in general require documentation of the underlying theory +and overall solution +method, as well as details of the implementation of the algorithm. +The modeling or development tools are used by various modules and may also use +other modules. These tools also require a relatively high level of documentation. +The documentation must describe the use and function of the +tool and give detailed information on the abstract programming interfaces. +Individual subroutines or functions that are not in themselves main modules or +tools in general require only descriptive documentation. This usually consists +of, at minimum, their input and output, and some +description of their purpose. +The following subsections delineate the information that should be +documented at each level. + +\subsection{Documentation of a Molecular Calculation Module} The documentation of a new molecular calculation module for NWChem will generally require creating a stand-alone Latex document. This document should reside in the directory containing the source code for the module (or in a subdirectory @@ -47,19 +72,15 @@ LaTex document, put the documentation directly in the main subroutine of the module. Whichever approach is used, however, the documentation should conform to the following template. -\subsection{Template for Documentation of a Molecular Calculation Module} - -This template shows the required format for documentation of a molecular -calculation module for NWChem. This template can be used for in-source -documentation, or in a stand-alone Latex document. If the developer chooses to write -a stand-alone LaTex document, the file should reside in the same directory as -the source code, and the name of the file should be given the suffix -{\tt .doc}. Chapter \ref{sec:modules} contains documentation of existing +Chapter \ref{sec:modules} contains documentation of existing molecular calculation modules in the code, and can be refered to for guidance -on style and appropriate level of detail. (However, developers are encouraged +on style and appropriate level of detail when developing the documentation +for a new module. In its current form (as of 11/10/98), this documentation is +relatively sparse and incomplete, and should not be looked upon as +an ideal to be emulated. Developers are encouraged to write in their own unique style, so long as the necessary information is -communicated in a clear and concise manner. {\em "A foolish consistency is the bugaboo -of small minds."}) +communicated in a clear and concise manner. ({\em "A foolish consistency is +the hobgoblin of small minds."}) \subsubsection{Module Documentation Template} @@ -89,7 +110,8 @@ NWChem. \item Describe the numerical solution used by the module, including how it interfaces with the NUMA model for memory management used by NWChem. \item If the new module calls other modules in the code, describe in detail how -this interface occurs (e.g., what does it write to the runtime data base?). +this interface occurs (e.g., is there a specific calling order that the +module relies on?). \end{itemize} \item Performance Evaluation @@ -108,24 +130,28 @@ When modifying or enhancing an existing module, the documentation should also be updated to match the new form of the module. If by chance the module does not yet have adequate documentation, this is an opportunity for you to gain merit (in this world -{\em and} the next) by providing the missing information as well as supplying the +{\em and} the next) by providing the missing information, +in addition to supplying the documentation for the new coding. -\section{Documentation of New Modeling or Development Tools} +\subsection{Documentation of Modeling or Development Tools} -In-source documentation generally makes the most sense for new modeling tools -or development tools, but the developer is free to write as much as he or she -wishes. Stand-alone LaTex documents will not be spurned. However, the -in-source documentation should also be done for modules at this level, since +This section +presents a content template for documentation of new modeling or +development tools. The template can be used for in-source documentation, +or as the outline for a separate LaTeX document. +In-source documentation generally makes the most sense for modeling tools +or development tools. The developer is also free to write a +stand-alone LaTex document, as these will not be spurned. However, the +in-source documentation is the prefered method of documentation +for modules at this level, since this is perhaps the only way to stack the odds in favor of continual updating -of the documentation as the coding is changed. The following subsections -present a template for documentation of new modeling tools, and the -required syntax for in-source documentation on the level of subroutines and -functions. +of the documentation as the code is changed. Any documentation separate from +the source code +should reside in the same directory as the source code, to keep from losing it +in the forest of the NWChem directory tree. -\subsection{Template for Documentation of New Modeling Tools} - -This template is based on the structure of the in-source documentation +The template is based on the structure of the in-source documentation developed by Ricky Kendall for the Integral API. The format is general enough, however, to be applicable to almost any feature that might be added to the Molecular Modeling Toolkit or @@ -137,7 +163,7 @@ and functions. Documentation of a code or module can be thought of as a dialogue between the -developer and future developers or users of the code in which the original developer +developer and future developers or users of the code, in which the original developer must guess the questions the other person will ask. Fortunately, this is not all that difficult. If the documentation is written to answer these questions, then it is quite likely that the next person to pick up the @@ -166,13 +192,14 @@ bibliography (if available); note any significant geneological information, if r the code does, and how it does it. Describe how it interacts with the rest of NWChem. If there are any special requirements or limitations on the use of the feature(s) of this coding, this is the place to -mention them. +mention them. If there is an order in which certain subroutines should be +called (i.e. initialize, modify and delete), this should be listed here also. \end{itemize} \item Modifications \begin{itemize} -\item Can this coding be changed? (Describe any special considerations for +\item Can this code be changed? (Describe any special considerations for modifying the code, especially if there are hidden repercussions of choices made at this level in the code. Note any compatibility problems with other modules in the code.) @@ -181,57 +208,74 @@ in the code.) \item Annotated List of All Subroutines and Functions \begin{itemize} +\item Instead of the list, there may instead be a pointer to a more complete +description of the subroutines and functions in another document or an appendix. +This list may also be automatically generated from the in-source documentation +of routines (listed below). \item How many subroutines/functions are there in this element? (Note the number; if it is large, try to organize them into some sort of logical groupings, for ease of -reference and to clarify the structure of the coding. If there is no obvious structure, +reference and to clarify the structure of the code. If there is no obvious structure, present them in alphabetical order.) \item What are the subroutines/functions in this element? (For each subroutine -or function, - -\begin{itemize} -\item write a terse description of what it is for and what it does -\item reproduce the header line verbatim -\item construct a list of all arguments in the call list, and give -each argument with a concise (but informative) definition -\item identify each argument as input or output -\item note the return value(s) of the function itself, in addition to -the argument list -\end{itemize} +or function, include the information specified in Section \ref{sec:content}.) \end{itemize} \end{itemize} -\subsection{Syntax for In-Source Documentation of Routines} +\subsection{Content for In-Source Documentation of Routines} +\label{sec:content} This is the base level of documentation, and is the one level that is almost guaranteed to actually be read by a new developer. Therefore, it is very important that the documentation at this level be as clear and complete as possible. At the very minimum, the in-source documentation should consist of -comment lines -containing -the following information: +lines containing the following information: +{\bf Required:} \begin{itemize} -\item a verbatim reproduction of the routine header line +\item a verbatim reproduction of the function or subroutine statement \item a list of all arguments, identifying for each argument \begin{itemize} \item its data type -\item its status as input or output data +\item its status as input, output, or input/output data. If the argument is a + handle to an object, the status of the handle as well as the object should + be noted by handle\_status(object\_status). For example, if the handle + and the data in an object will be created in a subroutine, use the notation + \verb+output(output)+. \item a concise (but informative) definition \end{itemize} \item a terse description of what the routine does \item a description of the return value(s) of the function itself (if any) +\item a description of the calling protocol for the subroutine; that is, whether +\begin{itemize} +\item it can be called by node 0 (master) only, +\item it must be called collectively (collective), +\item it may be called by any node, + in a noncollective manner (noncollective - note that this is the default) +\end{itemize} +\item a description of the status of the subroutine as private/public to an API or object +\end{itemize} + +{\bf Strongly Suggested:} +\begin{itemize} \item a description of action on detecting an error condition \item a terse description of input and output parameters the function gets from or gives to an API +\item a description of any side effects to file, common blocks or the RTDB +\item a description of any dependencies that the subroutine has, such as + certain subroutines must be called before or after calling the current + subroutine +\item a list of available print levels (We are working on a script to pull this information +"automagically" out of the code.) \end{itemize} Examples of nicely documented routines can be found in some directories of the NWChem source tree. (There are also many poor examples, so please follow the above template and do not rely on the form of existing code for guidance.) Some examples are reproduced -here, to illustrate good to adequate documentation. (There are no really +here, to illustrate the current state of in-source documentation in the code. +(There are no outstandingly excellent examples in the code, as yet. Think of it as your opportunity to shine.) @@ -241,14 +285,18 @@ Example 1: in-source documentation of function {\tt rtdb\_parallel} \begin{verbatim} logical function rtdb_parallel(mode) logical mode [input] -\end{verbatim} -This function sets the parallel access mode of all databases to {\tt mode} and returns the -previous setting. If {\tt mode} is true then accesses are in parallel, otherwise they are -sequential. -{\em Comment:} This function comes close to meeting the requirements of the -desired level of documentation. It is lacking only a definition of the argument {\tt mode}, -and it could be argued that in this case the definition is obvious. +c This function sets the parallel access mode of all databases to {\tt mode} +c and returns the previous setting. If {\tt mode} is true then accesses are +c in parallel, otherwise they are sequential. +\end{verbatim} + +{\em Comment:} This function meets about half of the requirements of the +desired level of documentation. It lacks a definition of the argument {\tt mode} +(although it could be argued that in this case the definition is obvious). +It does not provide a definition +of the "colectiveness" of the call to the function, nor a definition of +private/public routine to the rtdb module. Example 2: in-source documentation of function {\tt task\_energy} @@ -276,8 +324,8 @@ c \end{verbatim} -{\em Comment:} This is also a fairly good example. It is a little terse for the non-telepathic -perhaps, but contains the essential information (or most of it, anyway) on the +{\em Comment:} This is also a fairly typical example. It is a little terse for the non-telepathic +perhaps, but contains most of the essential information on the {\tt task} that executes the operation {\tt energy}. @@ -290,23 +338,24 @@ Example 3: in-source documentation of routine {\tt sym\_symmetrize} integer basis ! [input] Basis handle integer g_a ! [input] Global array to be symmetrized logical odensity ! [input] true=density, false=hamiltonian -\end{verbatim} -Symmetrize a skeleton AO matrix (in global array with handle -\verb+g_a+) in the given basis set. This is nothing more than -applying the projection operator for the totally symmetric -representation. -\begin{verbatim} - B = (1/2h) * sum(R) [RT * (A + AT) * R] -\end{verbatim} -where \verb+R+ runs over all operators in the group (including -identity) and \verb+h+ is the order of the group. -Note that density matrices tranform according to slightly different -rules to Hamiltonian matrices if components of a shell (e.g., -cartesian d's) are not orthonormal. (see Dupuis and King, IJQC 11, -613-625, 1977). Hence, specify \verb+odensity+ as \TRUE\ for -density-like matrices and \FALSE\ for all other totally symmetric -Hamiltonian-like operators. +c Symmetrize a skeleton AO matrix (in global array with handle g_a) +c in the given basis set. This is nothing more than applying the +c projection operator for the totally symmetric representation, +c +c B = (1/2h) * sum(R) [RT * (A + AT) * R] +c +c where R runs over all operators in the group (including identity), +c and h is the order of the group. +c +c Note that density matrices tranform according to slightly different +c rules to Hamiltonian matrices if components of a shell (e.g., +c cartesian d's) are not orthonormal. (see Dupuis and King, IJQC 11, +c 613-625, 1977). Hence, specify \verb+odensity+ as \TRUE\ for +c density-like matrices and \FALSE\ for all other totally symmetric +c Hamiltonian-like operators. +c +\end{verbatim} {\em Comment:} This is about as good as it gets. diff --git a/doc/prog/nwarch.tex b/doc/prog/nwarch.tex index 866fa797fb..f5ad6417b4 100644 --- a/doc/prog/nwarch.tex +++ b/doc/prog/nwarch.tex @@ -22,7 +22,7 @@ The fourth tier is the {\em Software Development Toolkit}, which is the basic foundation of the code. The fifth tier provides the {\em Utility Functions} needed by nearly all modules -in the code. These include such functionality as printing +in the code. These include such functionality as input processing, output processing, and timing. In addition to using a modular approach for the design, NWChem is built @@ -52,6 +52,26 @@ the various modules, tools, and "objects" are described in detail. \subsection{Object Oriented Design} \label{sec:ood} +The basic principles of object-oriented software development are abstraction, +hierarchy, encapsulation, and modularity. {\em Abstraction} is the separation of the +problem to be solved from the process used to solve it, which facilitates the +introduction of new methods as programming tools and hardware capabilities +evolve. In complex systems, abstraction can be carried out on many levels, +resulting in a hierarchy that allows connections between many different components +and the development of further abstractions. {\em Encapsulation} is the creation +of isolated data structures or other objects in such a way that they can be +manipulated only in carefully controlled and well-defined ways, which helps to +reduce the problems due to unexpected interactions between components that are +supposed to be independent. {\em Modularity}, which is the use of relatively +small program units having well-defined functionality, can also help reduce +interaction problems. It can also aid overall code efficiency, if the modules +are written to be easily reused. + +In an object oriented language such as C++, this methodology can be a feature +of the actual coding of the program. NWChem is written in a mixture of C and +Fortran, however, and uses object oriented ideas at the design stage. +This requires some self-discipline on the part of the developers, but the +effort is well rewarded in improved implementation and easier code maintenance. In a programming language such as Fortran77, which is not object oriented by design, the concept of objects can be simulated by developing a well defined interface diff --git a/doc/prog/print_control.tex b/doc/prog/print_control.tex index 0ed5603857..7def49c6e9 100644 --- a/doc/prog/print_control.tex +++ b/doc/prog/print_control.tex @@ -17,16 +17,17 @@ inconsistent data, or failure to converge) \end{itemize} \item Printing of specific quantities can be directly enabled or disabled from the input using already existing input routines -\item Modules operate independently and printing will eventually be +\item Modules operate independently and printing is controllable via context \end{enumerate} -This is an example of how it works. Inside the SCF input +The following example shows how it works. Inside the SCF input, + include the directive \begin{verbatim} print low basis "final eigenvectors" noprint title \end{verbatim} -This sets the overall SCF printlevel to low, forces printing of the +This sets the overall SCF print level to low, forces printing of the final eigenvectors and basis, and disables printing of the title. The implementation is very simple. Each module defines (using @@ -85,7 +86,7 @@ At the end of a module, the output file can be invoked by the call, \fussy - An examle of this usage is as follows; + An example of this usage is as follows; \begin{verbatim} #include "util.fh" @@ -126,12 +127,13 @@ and to declare \verb+util_print+ as an external logical valued function. character*(*) name [input] integer level [input] \end{verbatim} -If \verb+level+ is less than or equal to the current print level -(which is set by either \verb+util_print_rtdb_load+, or -\verb+util_print_set_level+), or the printing of \verb+name+ was -explicitly enabled, and the printing of \verb+name+ has not been -explicitly disabled, then \TRUE is returned. Otherwise +The value \TRUE is returned if \verb+level+ is less than or equal to the current print level +or the printing of \verb+name+ was +explicitly enabled and the printing of \verb+name+ has not been +explicitly disabled. Otherwise \FALSE is returned. +The current print level is set by either \verb+util_print_rtdb_load+ or +\verb+util_print_set_level+. \fussy @@ -159,8 +161,7 @@ A call to this routine is usually immediately followed by a call to subroutine util_print_pop \end{verbatim} Call this routine immediately before exit from a module to pop the -print stack to the previous context. Once context is properly -functioning the push/pop routines may disappear. +print stack to the previous context. \subsubsection{{\tt util\_print\_rtdb\_load}} \begin{verbatim} diff --git a/doc/prog/prog.tex b/doc/prog/prog.tex index 738cbbbf5a..1bd36398f3 100644 --- a/doc/prog/prog.tex +++ b/doc/prog/prog.tex @@ -1,4 +1,4 @@ -% $Id: prog.tex,v 1.8 1998-10-01 05:15:41 windus Exp $ +% $Id: prog.tex,v 1.9 1998-12-11 18:59:46 d35162 Exp $ \documentstyle[fullpage,12pt,fleqn]{book} \setlength{\parskip}{6pt} @@ -66,15 +66,18 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Software Development Toolkit} -\input{rtdb} -\section{Non-Uniform Memory Allocation (NUMA)} +%\section{Non-Uniform Memory Allocation (NUMA)} \input{numa} +\subsection{Message Passing} +\input{tcgmsg} \subsection{Memory Allocator (MA)} \input{ma} \subsection{Global Arrays (GA)} \input{ga} \subsection{ChemI/O} \input{ChemIO} +\section{The Run Time Data Base (RTDB)} +\input{rtdb} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/doc/prog/rtdb.tex b/doc/prog/rtdb.tex index 4e2b0994e2..1a937ce293 100644 --- a/doc/prog/rtdb.tex +++ b/doc/prog/rtdb.tex @@ -1,25 +1,11 @@ -% intro to this chapter -\label{sec:sdt} - -The Software Development Toolkit is the foundation of the functional architecture -in NWChem. It provides the means for interfacing between the calculation modules -of the code and the system hardware. The runtime data base -stores the information needed to run particular calculations, and allows -different modules to have access to the same information. The memory -management routines enable efficient execution in parallel environments. - -This chapter describes the elements of the Software Development Toolkit -in detail. - -\section{The RunTime DataBase (RTDB)} - \label{sec:rtdb} -NWchem consists of independent modules (e.g., input, SCF, RIMP2) that -communicate through a database (similar in spirit to the GAMESS -dumpfile or the Gaussian checkpoint file). The only way modules can -share data is via the database, or via files whose names are stored in -the database (which may have default values). Information is stored +The run time data base is the parameter and information repository for +the independent modules (e.g., SCF, RIMP2) comprising NWChem. +This approach is similar in spirit to the GAMESS +dumpfile or the Gaussian checkpoint file. The only way modules can +share data is via the database or via files, the names of which are stored in +the database (and may have default values). Information is stored directly in the database as typed arrays, each of which is described by \begin{enumerate} \item a name, which is a simple string of ASCII characters (e.g., @@ -46,14 +32,12 @@ that of provided arrays \end{itemize} -Alternatively, database operations can occur sequentially, meaning +Alternatively, database operations can occur sequentially. This means that -\begin{itemize} -\item only process zero can read/write the database and this happens - with no communication or synchronization with other processes -\item read/write operations by any other process than process zero is - an error -\end{itemize} +only process zero can read/write the database, and this happens + with no communication or synchronization with other processes. +Any read/write operations by any process other than process zero is + an error. Usually, all processes will want the same data at the same time from the database, and all processes will want to know of the success or @@ -74,14 +58,19 @@ following parameters \item {\tt rtdb\_max\_file} --- an integer parameter that defines the maximum length of a file name \end{itemize} -The Fortran routines return logical values; \TRUE on success, \FALSE +The Fortran routines return logical values; \TRUE on success, \FALSE on failure. The C routines return integers; 1 on success, or 0 on failure. All \verb+rtdb_*+ functions are also mirrored by routines \verb+rtdb_par_*+ in which process 0 performs the operation and all other processes are broadcast the result of a read and discard writes. +\subsection{Functions to Control Access to the Runtime Database} -\subsection{{\tt rtdb\_parallel}} +The functions that control opening, closing, writing to and reading information +from the runtime database are described in this section. + + +\subsubsection{{\tt rtdb\_parallel}} C routine: @@ -100,7 +89,7 @@ This function sets the parallel access mode of all databases to {\tt mode} and r previous setting. If {\tt mode} is true then accesses are in parallel, otherwise they are sequential. -\subsection{{\tt rtdb\_open}} +\subsubsection{{\tt rtdb\_open}} C routine: @@ -134,7 +123,7 @@ This function opens a database. It requires the following arguments: references to the database \end{itemize} -\subsection{{\tt rtdb\_close}} +\subsubsection{{\tt rtdb\_close}} C routine: @@ -164,7 +153,7 @@ When closing a database file that has been opened with the {\tt rtdb\_open} argu {\tt rtdb\_close} is automatically set to {\tt delete}. Database files needed for restart must not be opened as {\tt scratch} files. -\subsection{{\tt rtdb\_put}} +\subsubsection{{\tt rtdb\_put}} C routine: @@ -196,7 +185,7 @@ It requires the following arguments: \item {\tt array} --- array of length {\tt nelem} containing data to be inserted \end{itemize} -\subsection{{\tt rtdb\_get}} +\subsubsection{{\tt rtdb\_get}} C routine: @@ -227,7 +216,7 @@ This function gets an entry from the data base. It requires the following argume \item {\tt array} --- buffer of length {\tt nelem} defined by calling routine to store the returned data \end{itemize} -\subsection{{\tt rtdb\_cput} and {\tt rtdb\_cget}} +\subsubsection{{\tt rtdb\_cput} and {\tt rtdb\_cget}} \begin{verbatim} logical function rtdb_cput(handle, name, nelem, buf) @@ -252,7 +241,7 @@ variables. The functions have identical argument lists, the only difference bet buffer in calling routine to store returned character data (for {\tt rtdb\_cget}. \end{itemize} -\subsection{{\tt rtdb\_ma\_get}} +\subsubsection{{\tt rtdb\_ma\_get}} C routine: @@ -286,7 +275,7 @@ the following arguments: \end{itemize} -\subsection{{\tt rtdb\_get\_info}} +\subsubsection{{\tt rtdb\_get\_info}} C routine: @@ -322,7 +311,7 @@ It requires the following arguments: character string or FORTRAN character variable) \end{itemize} -\subsection{{\tt rtdb\_first} and {\tt rtdb\_next}} +\subsubsection{{\tt rtdb\_first} and {\tt rtdb\_next}} C routines: @@ -376,7 +365,7 @@ entries in the database. The coding for this can be implemented as follows; printf("entry %d has name '%s'\n", n, name); \end{verbatim} -\subsection{{\tt rtdb\_delete}} +\subsubsection{{\tt rtdb\_delete}} C routine: @@ -404,7 +393,7 @@ success or failure of the delete operation. The function returns as \item 0 if key was not present, or if an error occured \end{itemize} -\subsection{{\tt rtdb\_print}} +\subsubsection{{\tt rtdb\_print}} C routine: