Ada 95 Quality and Style Guide Chapter 2

Chapter 2: Source Code Presentation - TOC - 2.1 CODE FORMATTING

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

    Specifically, the following indentation conventions are recommended, as shown in the examples throughout this book. Note that the minimum indentation is described. More spaces may be required for the vertical alignment recommended in subsequent guidelines.

    - 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

        Default_String : constant String :=
              "This is the long string returned by" &
              " default.  It is broken into multiple" &
              " Ada source lines for convenience.";
    
           if Input_Found then
              Count_Characters;
           else  --not Input_Found
    
              Reset_State;
              Character_Total :=
                First_Part_Total  * First_Part_Scale_Factor  +
                Second_Part_Total * Second_Part_Scale_Factor +
                Default_String'Length + Delimiter_Size;
           end if;
        end loop;
    

    rationale

    Indentation improves the readability of the code because it gives you a visual indicator of the program structure. The levels of nesting are clearly identified by indentation, and the first and last keywords in a construct can be matched visually.

    While there is much discussion on the number of spaces to indent, the reason for indentation is code clarity. The fact that the code is indented consistently is more important than the number of spaces used for indentation.

    Additionally, the Ada Reference Manual (1995, §1.1.4) states that the layout shown in the examples and syntax rules in the manual is the recommended code layout to be used for Ada programs: "The syntax rules describing structured constructs are presented in a form that corresponds to the recommended paragraphing . . . . Different lines are used for parts of a syntax rule if the corresponding parts of the construct described by the rule are intended to be on different lines . . . . It is recommended that all indentation be by multiples of a basic step of indentation (the number of spaces for the basic step is not defined)."

    It is important to indent continuation lines differently from nested control structures to make them visually distinct. This prevents them from obscuring the structure of the code as you scan it.

    Listing context clauses on individual lines allows easier maintenance; changing a context clause is less error-prone.

    Indenting with spaces is more portable than indenting with tabs because tab characters are displayed differently by different terminals and printers.

    exceptions

    If you are using a variable width font, tabs will align better than spaces. However, depending on your tab setting, lines of successive indentation may leave you with a very short line length.

    automation notes

    The guidelines in this section are easily enforced with an automatic code formatter.


    < Previous Page Search Contents Index Next Page >
    1 2 3 4 5 6 7 8 9 10 11
    TOC TOC TOC TOC TOC TOC TOC TOC TOC TOC TOC
    Appendix References Bibliography