SDSS Science Archive, Standards & Guidelines


The Science Archive will be programmed entirely in C++, except for the Graphical User Interface which will initially be written in Tcl/Tk The official documentation will be written in HTML, and converted into other formats as needed. We will use the survey standard revision levels for supporting the following software: Tcl/Tk, Perl, Shell Scripts, and SDSSTools. Initially, however, we require both Perl5, Tcl/Tk v8.0, and HTML as outlined below. The following Standards and Guidelines are designed to enhance portability and readability, as well as simplify the development process.

Table Of Contents

Programming Guidelines

Documentation Guidelines


Naming Conventions

Preamble

The purpose of this style guide is not to force each of the programmers to adopt a style such that all the Science Archive code appears to have been written by one person. Rather, each programmer is encouraged to find his own best style and use it consistently. The rules and guidelines below were reached by consensus to avoid differences in style that would be outright confusing, and to introduce some conventions that should improve the readers' comprehension of all code, regardless of author.

sx Prefix

The sx prefix is mandatory for global type names and functions inside the SX package. For helper packages that may be used outside of the SX by others it is optional (example: HTM index). SX_ may be used as a prefix for preprocessor macros, but is not required. The sx prefix should not be used in any other context.

Capitalization

Preprocessor macros should be entirely capitalized, with component words separated by underscore. Exceptions to this rule should be made only with good reason. Macros can interact with the rest of the code in surprising ways, and so it is important to highlight them.

Capitalize the first letter following the sx prefix for all global type names and functions. An exception to this rule is made when the _t suffix is used to indicate that the symbol is a type name. Other symbols, such as variables and enumerators, should not begin with a capital.

After the first component word in any symbol, capitalize the first letter of each remaining component word. Do not use the underscore to separate component words, except as indicated above.

Underscore as Prefix and Suffix

All non-const class data members (public and private) and all non-const global variables are suffixed with underscore. All function arguments passed as variable parameters (non-const pointer or reference) are prefixed with underscore. Do not use a leading or trailing underscore in any other context. The purpose of this convention is to highlight when assignment to a symbol will affect an object of non-local scope.

A function argument passed as a non-const reference may not be a true variable parameter; in such cases the prefixed underscore is not appropriate and should not be used. This may occur in cases where the compiler will not permit a const reference for technical reasons. For instance, a class may change its state during use in ways that are not intended to be perceptible to the user, but because it does change its state during use it cannot be passed as const.

Prefix Code Letters

All global variables and enumerators are prefixed with the letter g, which must precede any other prefix codes. This is the only mandatory prefix code other than the sx prefix. Other codes are optional and usage will vary according to the individual style of the programmer. Prefix code letters are never capitalized and may be combined in any order (provided that g, if present, is first). In variable parameter names the leading underscore precedes all prefix codes (note that prefix code g may not be used in function argument names). Unlike the sx prefix, prefix codes do count as the non-capitalized first letters of a non-type symbol. Programmers should not feel free to invent new prefix codes without first adding them to this guide, with consent from the rest of the team. The valid prefix codes are:
PREFIX
g Global (mandatory)
n Number of
p Pointer to
v Vector of
m Matrix of

Examples
gDBName Global DB name
gnGalaxies Global number of galaxies
pMember Pointer to member
vFlux Vector of fluxes
pvNames Pointer to vector of names
mMeanValue Matrix of mean values

Combining these codes is a good way to generate very obscure names; instead, consider using ordinary words to convey the desired meaning. The current set of allowed prefixes intentionally excludes vowels to preclude forming words using prefix combinations.

Predefined Data-types

The following data-types have been predefined to increase portability and for compatibility with Objectivity that defines most of these datatypes, too.

Data Type Comments
bool/char/int8 boolean/byte type (true/false)
int16 16 bit signed integer
uint16 16 bit unsigned integer
int32 32 bit signed integer
uint32 32 bit unsigned integer
int64 64 bit integer
float32 single precision float
float64 double precision float
char[n] string (array of n bytes)

Rogue Wave Tools Summary

Tools.h++

Note The Use of RW Tools is NOT RECOMMENDED. RW was chosen to be used in SX because of many portability issues, especially to Windows NT. However, these very portability issues turned out to be a pain rather than an advantage. Do not use RW where you can do without.

The only recommended use of RW is in two categories: Threads++ for multithreading and Net++ for socket communications. In these cases, portability to NT justifies their usage.

Do not use RW vector, list, etc. classes. Use the homemade ValVec and PtrVec templates instead.

General Information

Rogue Wave Tools.h++ classes are grouped into four categories: Utility Classes, Template based classes, Smalltalk like classes, and Generic Collection classes. To use the Smalltalk like classes, the new class must inherit from RWCollectable. The derived objects are then collected through their pointers to this common base class. The generic collection classes mimic templates through the use of preprocessor macros. This can make debugging difficult. As a result, unless absolutely necessary, the utility and template based classes are the recommended subsets of the tools.h++ library.

Template Types

Template collections take three forms within the tools.h++ library: Intrusive Lists (Isv), Value-Based (Val), and Pointer-Based (Ptr).

Intrusive Lists:

Value-Based Collections: Pointer-Based Collections: Types of Template Collections

Utility Classes

RWBench
Automate Benchmarking Process
RWDate
Represent Date
RWTime
Represent Time
RWTimer
Measure elapsed CPU Time.
RWCString
Single Byte Character String
RWCSubString
Address subsection of RWCString
RWCTokenizer
Tokenize RWCString
RWCRegexp
Regular Expression For use with RWCString
RWBitVec
Bit Vector, "Flag"

Net.h++

General Overview

Rogue Wave net.h++ classes provide a layered, modular, open interface to network communications. At the lowest level, the modular framework consists of wrapping the communication system calls in resource classes. These resource classes are then used in a more abstract portal layer, where the actual type of interprocess communication is unknown. The portal layer supports both formatted and unformatted I/O stream interfaces. Unfortunately, the only supplied communication service provided is Berkeley Sockets. However, the open design easily allows for the inclusion of additional services, such as pipes and FIFOs.

Overview of Architecture

RWPortal
This class serves as an interface class to the communications channel.
RWPortalImpl
This class provides the implementation to the communications channel.
To add communications channels, first wrap low level system functionality in a class (RWSocket). Then create the interface by inheriting from the Portal and the wrapped classes (RWSocketPortal), and the define the implementation by inheriting from the portal implementation (RWSockPortalImpl). The actual implementations can then be interfaced to using the base class interface provided by RWPortal.

Communication Methods

Design Guidelines

General Design

Push Policy Up & Implementation Down.

Policy
The policy refers to the appearance of an interface, allowable exceptions, inheritance hierarchies, and class design.
Implementation
The implementation refers to algorithmic choices, communication protocols, and class implementation.

Const Design

As a general rule, use const wherever possible. Also strive to ensure that const satisfies both the language required bitwise constness, but also logical constness.

Class Design

There are two golden rules:
  1. Use an existing class rather than write a new one.
  2. If you can't use an existing class, then see rule number 1.
Additional rules:
  1. Don't use Patterns.
  2. Avoid multiple inheritance and templates

Constructors/Destructors

When writing constructor functions, use initialization rather than assignment. Initialization is required for const data members, and is generally more efficient. Destructors should be declared virtual for any possible base classes.

Operator Overloading

Overload operators cautiously, do not redefine operators in a nonintuitive fashion. Be sure to check for assignment to *this.

Class Interface

The public interface to the class should be solely through the provided member functions. Do not allow any friend functions, use global functions that then use member accessor/mutator functions. Also, beware of public virtual functions as they can be overridden in a derived class, circumventing functionality that might be required for correct behavior. Do not place any data members in the public interface. Explicitly disallow the use of undesired, implicitly generated (by the compiler) member functions, by declaring the function as private, and never providing a definition.

Style Guidelines

Source code and revision history shall be kept under CVS management. The CVS is hosted at Fermilab.

Default Class Declaration File

Note the embedded HTML that is used by cxx2html to produce class documentation.
//# 	Filename: 	sxCode.h
//#
//#	A Brief Description of this Files Contents.
//#
//#   	Author:		Ani R. Thakar
//#	
//#	Date:		October 13, 1999
//#
//#
//#
//# (c) Copyright The Johns Hopkins University 1999
//# All Rights Reserved
//#
//# The software and information contained herein are proprietary to The
//# Johns Hopkins University, Copyright 1999.  This software is furnished
//# pursuant to a written license agreement and may be used, copied,
//# transmitted, and stored only in accordance with the terms of such
//# license and with the inclusion of the above copyright notice.  This
//# software and information or any other copies thereof may not be
//# provided or otherwise made available to any other person.
//#
//#
//#	Modification History:
//#

#!defined (SX_DEFAULT)
#define SX_DEFAULT


Include Files

Static Variables


// Forward Declarations


Forward Declarations


//
// <SUMMARY>A Short Summary of this Class</SUMMARY>
//
// Now Provide a more detailed description of this class.
// Remember that this description becomes the documented description
// of the class.
//
// If you wish to use code or pseudo-code to explain an algorithmic
// detail enclose the code comment fragment as below.
//
// <SRCBLOCK>
// sxMatrix<sxFloat64> galacticToEquatorial ;
// </SRCBLOCK>
// 


Class Declaration


// When commenting the Member Functions/Constructors, be sure to place your
// comment before the code being commented.
//
// If the same comment code applies to more than one function, use the
// group comment structure.
//
// General Group Comments
// <GROUP>
// Specific Comment related to Function One


void functionOne(void) ;


// Specific Comment related to Function Two


void functionTwo(void) ;


// <GROUP>
//


Inline Function Definitions

#endif DEFAULT_H

Default Class Implementation File


//# 	Filename: 	sxDefault.cpp
//#
//#	A Brief Description of this Files Contents.
//#
//#   	Author:		Peter Z. Kunszt
//#	
//#	Date:		October 13, 1999
//#
//#
//#
//# (c) Copyright The Johns Hopkins University 1999
//# All Rights Reserved
//#
//# The software and information contained herein are proprietary to The
//# Johns Hopkins University, Copyright 1999.  This software is furnished
//# pursuant to a written license agreement and may be used, copied,
//# transmitted, and stored only in accordance with the terms of such
//# license and with the inclusion of the above copyright notice.  This
//# software and information or any other copies thereof may not be
//# provided or otherwise made available to any other person.
//#
//#
//#	Modification History:
//#

Default Makefile

The makefiles used for the SDSS Science Archive are implemented using perl. We have a proprietary script, sxmake and sxMakeFilter, that take care of compiling the code.

C++ Template Guidelines

Avoid Templates wherever possible.

General Information

Template Functions and Classes are useful methods for constructing container classes that are easily designed and implemented, while maintaining static type checking and run-time efficiency. Objectivity v5.1 supports the use of templates. Additionally, the Rogue Wave Tools.h++ template based classes are used within the Science Archive Software, while Rogue Wave Net.h++ uses templates within its implementation.

Template Examples

RWTBitVec<43>
Create a bit vector that is 43 bits long.
RWTPtrOrderedVector<sxFloat64>
Create a Pointer Based Ordered Vector of doubles.
RWTValSlist<RWDate>
Create a Value Based Singly Linked List of Dates.
RWTIsvDlistIterator<RWCString>
Create an iterator for traversing an Intrusive doubly linked list of strings.
RWStack<sxInt32, RWTValOrderedVector<sxInt32>>
Create a stack of integers using a Value Based Ordered Vector.

C++ Exception Handling

General Information

The Exception Handling Mechanism provides a powerful method for handling errors while attempting to maintain the state of the process. One of the main concerns, however, is with resource acquisition/exhaustion. Essentially, the problem is controlling resource leaks, which can arise when a resource is allocated, and an exception arises before it can be initialized. For example, when opening a socket connection, if the connection process throws an exception, the socket resources will not be released as the throw will circumvent any error detection code that follows.

The optimal solution to this problem is to wrap all resource allocations in a class with a destructor that properly releases the acquired resources. Thus to acquire a resource, one constructs an appropriate object. When the object's destructor is called, the resource is released to the system. Formally, this technique is referred to as "Resource Acquisition is Initialization". Within the SDSS Science Archive System, it is an error to allow exceptions to produce resource leaks.

One should not take the idea of using exceptions for error handling too far. It is generally recognized that it is extremely hard to recover from unexpected errors, and that the exception mechanism adds its own layer of subtle issues. There will be certain natural control boundaries in any program, where arbitrary exceptions may be caught and handled reliably. There will also be situations in many programs, where a specific exception can be handled reliably. For the most part, however, exceptions should be treated as a better way to report an unusual or unexpected error.

Guidelines

prototyping

The language provides a syntax for specifying what exceptions a function may throw as part of its interface. If a function does not specify its exception interface it is assumed to be capable of throwing arbitrary exceptions. However, if a function does specify any exceptions that it may throw, it is assumed to throw no others. The consequence of a function throwing an exception not specified in its prototype is (by default) termination of the application via the unexpected() function. In practice the only way for a programmer to avoid this highly undesirable outcome is to wrap all function definitions in a handler for arbitrary exceptions. Further, the lack of compiler support for function-try blocks restricts the programmer's use of initializers in constructors. We conclude that specifying the exception interface of a function as part of its prototype places too great a burden on the programmer, at least given the current state of the C++ library and other third-party products. Science Archive functions should not prototype their exceptions unless there is a very good reason to do so, and the programmer really has gone that extra length to avoid needless termination of the application.

throwing

There is no clear rule for when to throw an exception versus when to return an error code of some sort. Generally, exceptions should be reserved for problems that are not supposed to happen. A reasonable rule-of-thumb is: if most programmers, when calling your function, are unlikely to bother checking that it succeeded, then specify no return value (void) and throw exceptions. However, if there is a very real expectation that your function will be unable to perform its nominal task, then failure should be indicated through the formal interface.

There is also a nebulous category of functions which do have ordinary modes of failure, but for which returning an error code would simply be inconvenient. Typically such functions return a type that has no natural invalid value. The error code must then be passed as a variable argument, which may be viewed as a pedantic encumbrance upon the function's interface. There is value in creating an ergonomic interface, and the choice between exceptions and error codes should be decided on the basis of how the function is used.

We recommend the use of exceptions in constructors when an object is rendered unusable by an error. Otherwise, more traditional techniques are probably appropriate. Destructors should never throw exceptions, and should be written to avoid the possibility of indirectly raising an exception. This is important because destructors get called as an exception propagates up the call stack, and raising an exception while another exception is being handled causes the application to abort.

Science Archive functions should throw exceptions derived from class sxException. This class is itself derived from std::exception, the base of all exceptions from the Standard C++ Library. A small kit of basic general-purpose Science Archive exceptions is provided by the sxGeneral package. See sxException.h. Programmers should feel free to derive their own exceptions when greater specificity is required.

catching

All Science Archive applications are required to enclose the body of main() in a handler for objects of type exception and at least print the exception's message. Whenever an exception is caught, the programmer should assume that it contains a message of diagnostic value. By the same token, exceptions should always be constructed with as useful a message as can be provided conveniently. If a handler rethrows an exception, it should not also print the message. All library functions should avoid printing to stderr, even when it seems like a good idea (or else add a verbose switch to the interface). Exceptions provide a mechanism for preserving the text of a useful diagnostic while delegating responsibility for output to the application.

int main()
{
   try { ... }
   catch (exception &x) {
      cerr << "EXCEPTION " << x.what() << endl;
      return 1;
   }
}

Debugging/Testing Guidelines

General Information

In order to reduce the work involved in porting and maintaining the Science Archive Software, certain guidelines must be followed. When implementing a class, test code must also be written that tests all non-virtual constructors, destructors, and member functions. This test code will be checked into the cvs repository along with the actual module source code. Any time that a CVS checked in code is modified, as with a bug fix, the modifications must be clearly commented in the modification section of the files header comment section. The Total Coverage Analysis log should be considered part of the module and checked into the repository. In addition, decladebug, a DEC C++ version of dbx, will be used for all traditional run-time debugging.

Insight

Insure++ is a source code level commercial debugger/test package. At compile time, insure++ provides lint-like error checking, retaining extra information for run time debugging. At run time, additional errors are caught and the retained information is provided to reduce the guesswork involved in identifying errors. During the execution of a program, a log is maintained of the actual lines of code that were executed. This provides a coverage analysis that aids in reducing hidden bugs and untested code. An additional tool, inuse, monitors memory allocation/deallocation while a process is executing to identify memory leaks. insure++ is automatically used when the debug tag is used with make.

HTML Standards

An HTML document is composed of a single <html> ... </html> element, which is composed of a head, <head> ... </head>, element and a body, <body> ... </body> element. As new additions (eg. math notation) to the HTML language become standardized, these features will be included in the acceptable html elements section after review. All standard element attributes (eg ALIGN = CENTER) are by default included within the required HTML constructs.

Html Head Elements

<ISINDEX>
Indicates this document describes a searchable database.
<TITLE> ... </TITLE>
The Title For the current document.
<BASE HREF = "URL">
Provides an absolute URL to which all relative URL's are appended.

Html Body Elements

<BGCOLOR>
Specify Background Color.
<TEXT>
Specify Text Color.
<LINK>
Specify the Link Color.
<VLINK>
Specify the Visited Link Color.
<ALINK>
Specify the Active Link Color.

Text Elements

<BR>
Indicate Line Break.
<P>
Indicate Paragraph End.
<PRE> ... </PRE>
Display Pre-formatted Text. Embedded HTML will be recognized.
<XMP> ... </XMP>
Display Pre-formatted Text. Embedded HTML will be not recognized.
<BLOCKQUOTE> ... <BLOCKQUOTE>
Display quoted text.

Hyper-Links

<A NAME = "ANCHOR">
Define a named anchor within a document.
<A HREF = "#ANCHOR">
Define a link to a named anchor within the document.
<A HREF = "URL">
Define a link to another document/resource.
<A HREF = "URL#NAME">
Define a link to a named anchor in another document.

Headers

<H#></H#>
# is a number from one to six, with one being the most prominent. The header numbering should be strictly followed to simplify the document conversion process.

Logical Styles

<EM> ... </EM>
Emphasis.
<STRONG> ... </STRONG>
Strong Emphasis.
<CODE> ... </CODE>
Display an HTML Element.
<CITE> ... </CITE>
Display a citation.

Physical Styles

<B> ... </B>
Boldface.
<I> ... </I>
Italics.
<U> ... </U>
Underline
<SUB> ... </SUB>
Subscript
<SUP> ... </SUP>
Superscript

List Types

Definition List
<DL>
Begin Definition List.
<DT>
Term to be Defined.
<DD>
Definition.
</DL>
End Definition List.
Unordered List
<UL>
Begin Unordered List
<LI>
List Item.
</UL>
End Unordered List.
Ordered List
<OL>
Begin Ordered List.
<LI>
List Item
</OL>
End Ordered List.

Tables

<TABLE> ... </TABLE>
Begin/End a Table.
<TR> ... </TR>
Begin/End a new Table Row.
<TH> ... </TH>
Table Header.
<TD> ... </TD>
Table Data.

Keywords

&keyword
Represent Keyword: &, <, >

Default html Implementation File



<!--DOCTYPE HTML PUBLIC -->

<html>

<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="Author" content="Peter Kunszt">
   <title>Title of this document</title>
   <base href="http://www.sdss.jhu.edu/">
<!--
Author:		Peter Z. Kunszt
Created:	October 16, 1999
		
Notes:		Comments are appreciated.
-->
<!-- Changed by: Ani R. Thakar, 17-Oct-1995 -->

</head>

<body text="#111111" bgcolor="#FFFFFF" link="#333399" vlink="#663366" alink="#CC0000">

<h1>
<img src = "images/sx/sxlogo1.gif">  
<font color="#7700EE">Title of this Documnet</font></h1>
<img src="images/bars/rule.gif" >

<h2> Section Title</h2>

<p>
Your Text comes here

<h2> Section Title</h2>

<h3> Subsection Title</h3>



<img SRC="images/bars/rule.gif" >
<h6>
&copy;
<A HREF = "copyright.html">
Copyright
</A>
The Johns Hopkins University 1999, All Rights Reserved.<br>

<a href="mailto:kunszt@pha.jhu.edu">Peter Z. Kunszt</a>,
<a href="mailto:thakar@pha.jhu.edu">Ani R. Thakar</a>,
<br>
Last Modified: October 14, 1999.
</h6>

</body>
</html>


HTML Converters

When formal documentation is required, the html documentation will be converted into Latex, or Postscript as needed.

HTML To Latex

htmlatex.pl -> Perl script.

HTML To Postscript

References

Keffer, Thomas, C++ Design, Implementation, and Style Guide, Rogue Wave Technical Report 94-02.

Meyer, Bertrand, Object-Oriented Software Construction, Prentice Hall International

Stroustrup, Bjarne, The C++ Programming Language, 2nd ed., Adison-Wesley.

© Copyright The Johns Hopkins University 1999, All Rights Reserved.
Peter Z. Kunszt, Ani R. Thakar,
Initial Document: Robert J. Brunner, 1995 Last Modified: October 16, 1999 [PK]