Ada 95 Quality and Style Guide Chapter 2
CHAPTER 2
Source Code Presentation
The physical layout of source text on the page
or screen has a strong effect on its readability. This chapter
contains source code presentation guidelines intended to make
the code more readable.
In addition to the general purpose guidelines, specific recommendations
are made in the "instantiation" sections. If you disagree
with the specific recommendations, you may want to adopt your
own set of conventions that still follow the general purpose guidelines.
Above all, be consistent across your entire project.
An entirely consistent layout is hard to achieve or check manually.
Therefore, you may prefer to automate layout with a tool
for parameterized code formatting or incorporate the guidelines
into an automatic coding template. Some of the guidelines and
specific recommendations presented in this chapter cannot be enforced
by a formatting tool because they are based on the
semantics, not the syntax, of the Ada code. More details are given
in the "automation notes" sections.
2.1 CODE FORMATTING
The "code formatting" of Ada source code affects how
the code looks, not what the code does. Topics included here are
horizontal spacing, indentation, alignment, pagination, and line
length. The most important guideline is to be consistent throughout
the compilation unit as well as the project.
2.1.1 Horizontal Spacing
guideline
- Use consistent spacing around delimiters.
- Use the same spacing as you would in regular prose.
instantiation
- Before and after the following delimiters and binary
operators:
+ - * / &
< = > /= <= >=
:= => | ..
:
<>
- Outside of the quotes for string (")
and character (') literals, except where prohibited.
- Outside, but not inside, parentheses.
- After commas (,) and semicolons (;).
- After the plus (+) and minus (-) signs when
used as unary operators.
- After a function call.
- Inside of label delimiters (<<
>>).
- Before and after the exponentiation operator (**),
apostrophe ('), and period
(.)
- Between multiple consecutive opening or closing parentheses.
- Before commas (,) and semicolons
(;).
example
rationale
exceptions
automation notes
2.1.2 Indentation
guideline
- Indent and align nested control structures,
continuation
lines, and embedded units consistently.
- Distinguish between indentation for nested control structures
and for continuation lines.
- Use spaces for indentation, not the tab
character (Nissen and Wallis 1984, §2.2).
instantiation
- Use the recommended paragraphing shown in
the Ada Reference Manual (1995).
- Use three spaces as the basic unit of indentation for nesting.
- Use two spaces as the basic unit of indentation for continuation
lines.
A label is outdented three spaces:
begin
<<label>> | <long statement with line break>
<statement> | <trailing part of same statement>
end;
The if statement and the plain loop:
if <condition> then | <name>:
<statements> | loop
elsif <condition> then | <statements>
<statements> | exit when <condition>;
else | <statements>
<statements> | end loop <name>;
end if; |
Loops with the for and while
iteration schemes:
<name>: | <name>:
for <scheme> loop | while <condition> loop
<statements> | <statements>
end loop <name>; | end loop <name>;
The block and the case
statement as recommended in the Ada Reference Manual (1995):
<name>: | case <expression> is
declare | when <choice> =>
<declarations> | <statements>
begin | when <choice> =>
<statements> | <statements>
exception | when others =>
when <choice> => | <statements>
<statements> | end case; --<comment>
when others => |
<statements> |
end <name>; |
These case statements save space
over the Ada Reference Manual (1995) recommendation and depend
on very short statement lists, respectively. Whichever you choose,
be consistent:
case <expression> is | case <expression> is
when <choice> => | when <choice> => <statements>
<statements> | <statements>
when <choice> => | when <choice> => <statements>
<statements> | when others => <statements>
when others => | end case;
<statements> |
end case; |
The various forms of selective
accept and the timed and conditional
entry calls:
select | select
when <guard> => | <entry call>;
<accept statement> | <statements>
<statements> | or
or | delay <interval>;
<accept statement> | <statements>
<statements> | end select;
or |
when <guard> => | select
delay <interval>; | <entry call>;
<statements> | <statements>
or | else
when <guard> => | <statements>
terminate; | end select;
else |
<statements> | select
end select; | <triggering alternative>
| then abort
| <abortable part>
| end select;
The accept statement:
accept <specification> do | separate (<parent unit>)
<statements> | <proper body>
end <name>; |
A subunit:
separate (<parent unit>)
<proper body>
end <name>;
Proper bodies of program
units:
procedure <specification> is | package body <name> is
<declarations> | <declarations>
begin | begin
<statements> | <statements>
exception | exception
when <choice> => | when <choice> =>
<statements> | <statements>
end <name>; | end <name>;
|
function <specification> | task body <name> is
return <type name> is | <declarations>
<declarations> | begin
begin | <statements>
<statements> | exception
exception | when <choice> =>
when <choice> => | <statements>
<statements> | end <name>;
end <name>; |
Context
clauses on compilation units are arranged as a table. Generic
formal parameters do not obscure the unit itself. Function,
package, and task
specifications use standard indentation:
with <name>; use <name>; | function <specification>
with <name>; | return <type>;
with <name>; |
| package <name> is
| <declarations>
| private
<compilation unit> | <declarations>
| end <name>;
|
generic | task type <name> is
<formal parameters> | <entry declarations>
<compilation unit> | end <name>;
Instantiations of generic units
and record indentation:
procedure <name> is |type ... is
new <generic name> <actuals> | record
| <component list>
function <name> is | case <discriminant name> is
new <generic name> <actuals> | when <choice> =>
| <component list>
package <name> is | when <choice> =>
new <generic name> <actuals> | <component list>
| end case;
| end record;
Indentation for record
alignment:
for <name> use
record <mod clause>
<component clause>
end record;
Tagged types and type extension:
type ... is tagged
record
<component list>
end record;
type ... is new ... with
record
<component list>
end record;
example
rationale
exceptions
automation notes
2.1.3 Alignment of Operators
guideline
- Align operators vertically
to emphasize local program structure and semantics.
example
rationale
exceptions
automation notes
2.1.4 Alignment of Declarations
guideline
- Use vertical alignment to enhance the
readability of declarations.
- Provide, at most, one declaration per line.
- Indent all declarations in
a single declarative part at the same level.
instantiation
- Align the colon delimiters.
- Align the := initialization delimiter.
- When trailing comments are used, align the comment
delimiter.
- When the declaration overflows a line, break the line and add
an indentation level for those lines that wrap. The preferred
places to break, in order, are: (1) the comment delimiter; (2)
the initialization
delimiter; (3) the colon delimiter.
- For enumeration type declarations
that do not fit on a single line, put each literal on a separate
line, using the next level of indentation. When appropriate, semantically
related literals can be arranged by row or column to form a table.
example
rationale
automation notes
2.1.5 More on Alignment
guideline
- Align parameter
modes and parentheses
vertically.
instantiation
- Place one formal parameter specification
per line.
- Vertically align parameter names, colons,
the reserved word in, the reserved
word out, and parameter
subtypes.
- Place the first parameter specification on the same line as
the subprogram or entry name. If any parameter subtypes are forced
beyond the line length limit, place the first parameter specification
on a new line indented the same as a continuation line.
example
rationale
notes
exceptions
automation notes
2.1.6 Blank Lines
guideline
- Use blank lines to group logically related lines of text (NASA
1987).
example
rationale
automation notes
2.1.7 Pagination
guideline
- Highlight the top of each package
or task specification, the top
of each program unit body, and the end
statement of each program unit.
instantiation
- Use file prologues, specification
headers, and body headers to highlight
those structures as recommended in Guideline 3.3.
- Use a line of dashes, beginning at the same column as the current
indentation to highlight the definition of nested units
embedded in a declarative part. Insert the line of dashes immediately
before and immediately after the definition.
- If two dashed lines are adjacent, omit the longer of the two.
example
rationale
notes
automation notes
2.1.8 Number of Statements Per Line
guideline
- Start each statement on a new line.
- Write no more than one simple statement
per line.
- Break compound statements over multiple lines.
example
rationale
notes
automation notes
exceptions
2.1.9 Source Code Line Length
guideline
- Adhere to a maximum line length
limit for source code (Nissen and Wallis 1984, §2.3).
instantiation
- Limit source code line lengths to a maximum of 72 characters.
rationale
notes
automation notes
2.2 SUMMARY
code formatting
- Use consistent spacing around delimiters.
- Use the same spacing as you would in regular prose.
- Indent and align nested control structures,
continuation
lines, and embedded units consistently.
- Distinguish between indentation for nested control structures
and for continuation lines.
- Use spaces for indentation, not the tab
character (Nissen and Wallis 1984, §2.2).
- Align operators vertically
to emphasize local program structure and semantics.
- Use vertical alignment to enhance the
readability of declarations.
- Provide, at most, one declaration per line.
- Indent all declarations in
a single declarative part at the same level.
- Align parameter
modes and parentheses
vertically.
- Use blank lines to group logically related lines of text (NASA
1987).
- Highlight the top of each package
or task specification, the top
of each program unit body, and the end
statement of each program unit.
- Start each statement on a new line.
- Write no more than one simple statement
per line.
- Break compound statements over multiple lines.
- Adhere to a maximum line length
limit for source code (Nissen and Wallis 1984, §2.3).