@device(imprint10)
@make(report)
@definefont(Userfont, 1=<Typecase ComputerModernBold10R36>,
                      2=<Typecase ComputerModernBold10R20>,
                      3=<Typecase ComputerModernBold10R18>,
                      4=<typecase computermodernbold10R14>,
                      5=<typecase computermodernbold10R12>,
                      6=<typecase computermodernbold10R10>)
@modify(hd2, font userfont, facecode 2, flushright, below 1 inch)
@modify(hd3, font userfont, facecode 4, leftmargin -2)
@modify(copyrightnotice, flushright, fixed -1 inch)
@modify(format, font smallbodyfont)
@Style(Font computermodernroman11)
@Style(spacing 1,indent 0)
@Style(leftmargin 1.0inch)
@Style(Linewidth 6.5inches)
@pageheading(center=" ")
@pagefooting(left="MIT Project Athena", center="@value(page)", right="Revision A, Sept. 1985")
@Blankspace(1.25 inch)
@begin(MajorHeading,Flushright,Font Userfont, FaceCode 1, below .3)
Essential Fortran
@end(Majorheading)
@blankspace(.75 inch)
@begin(flushright, Font Userfont, FaceCode 4)
Linda B. Merims
MIT Project Athena
Revision A
September 1, 1985
@end(flushright)
@copyrightNotice(Massachusetts Institute of Technology)
@newpage
@section(Introduction)
@i(Essential Fortran) shows you how to login to the Unix computer system,
create a short sample Fortran program, compile it,
and then run the compiled program.
It is intended for students who must run Fortran programs
as part of their coursework, who want to get started 
as quickly and simply as possible.  @i(Essential Fortran's) emphasis is on
following the example by rote; there is little explanation of what
you are doing.  The latter part of the document
contains more advanced information on run-time debugging, linking, and file
I/O.  @i(Essential Fortran) does not
teach you the Fortran language.  
For more information on this and any of the steps shown here, see the
free Athena documents mentioned in the text and in the section
labelled "For More Information."

@section(Antecedents)

Before you can use the Athena system, you must know all of the following.
If you are a student in a class, your instructor should provide you
with this information.  You probably specified your username and password
yourself.
@begin(format, leftmargin +3)
@tabclear
@tabset(2.5 inches)
your username:@\a 3-8 letter "name" that identifies you to the system
your password:@\a short password to keep your username private
host machine:@\the name of the machine(s) that your username works on
cluster room number:@\the room with terminals to your host machine
cluster door combination:@\the numeric key to unclock the cluster door
@end(format)

@begin(heading, flushleft)
Login
@end(heading)
Go to your assigned terminal cluster, let yourself in, and find a terminal
you want to use.  Press the big RETURN key
at the right of the main keyboard until you
see the "Athena Login" banner.  
Follow the scenario below.  What @i(you) type to
the machine is shown in @b(boldface).  
@begin(format, leftmargin +3)
@tabclear
@tabset (3.2 inch)
Athena Login Server (MIT-HERA.MIT.EDU:tty01)@\<--Athena login banner

Machine name: @b(yourhost)@\<--substitute your host machine name (hera, etc.)
@\<--then press the RETURN key
MIT-HERA.MIT.EDU login: @b(yourusername)@\<--type your username in all lowercase. press RETURN
Password:@p(yourpassword)@\<--type your password.  it won't show.  press RETURN

Last login: Mon Jan 28  13:22:44 from mit-heracles
Athena UNIX #3-19-00 (priam:ATHENA:dgg) Tues Dec 18...
@\<--login information and bulletin board messages.  
@\     your screen will usually blank out before it
Welcome to Project Athena@\     displays the next line

yourhost%@\<--the system "prompt" means the system is waiting
@\     for you to type a command
@end(format)


If you get stuck in the middle of the login process, you can restart from
the beginning by typing a @b(CTRL-D).  CTRL-D is a "control
character," read as "control-D".  To type a control character, hold down
the key labelled CTRL at the lower left of the keyboard, keep holding
it down, and press D.  See the consultant on duty or your
instructor if you have trouble with any of this.

When you see the system prompt, @i(yourhost%), you have
successfully logged in and
can type commands.

When you enter commands, you must follow these Unix rules:
@itemize[
You must type commands in @b(all lowercase) letters,
exactly as shown.

Finish every command by pressing the RETURN key. 

To backup and fix a typo, press the key near the upper right corner
of the main keyboard labelled DELETE or <--.

To cancel any command, type a CTRL-C.  Again, to type a control character,
hold down the key labeled CTRL at the lower left of the keyboard, keep
holding it down, and press C.
]

@b(To leave Unix, type: @p[logout])
The Athena documents @i(Essential Unix) and the @i(Unix
Quick Reference) card explain more about using Unix.  They are available
for free in the Athena terminal clusters.

@section(Creating the Fortran Program)

To illustrate what it is like to create a Fortran program, compile and
execute it, we will use the following small program that converts
fahrenheit temperatures to centrigrade:
@begin(example, font smallbodyfont)
C
C   Convert Fahrenheit temperatures to Centigrade: C = 5/9 (F - 32)
C
C234567----------------------------------------------------------------|------

      real  ftemp, ctemp

      print *, 'Type in a Fahrenheit temperature, then press RETURN'
      read  *, ftemp

      ctemp = (5.0/9.0) * ( ftemp - 32.0 )

      print *, ftemp, 'Fahrenheit is', ctemp, 'Centrigrade'
      print *, 'Exiting.  Bye.'
      end
@end(example)

Once you have logged in, your first step is to
type your Fortran program into a @b(file).  (The assumption is that
you have already written the program out longhand and you just
need to type it into a computer file.)

To type your program into a file,
you call up the @b(emacs text editor) and give it a @b(filename)
to use.  You can name your files anything you like.  However, all
Fortran program files @b(MUST) be suffixed with a @b(.f) "file type."
If you don't give it a .f type, whenever you try to compile the program
it will always fail with the message, "ld:@i(filename):Bad magic number."

The file will be named ftoc.f.

@subsection(Starting Emacs)
To enter emacs, type the @i(emacs) command and the name of the file you
want to edit, then press the RETURN key.
If the filename is new, emacs will create it.
@begin(format)
yourhost% @b(emacs  ftoc.f)
@end(format)
Your screen will blank out, and then (after some seconds) come back with
a new screen that looks something like:
@begin(verbatim)
                    ------------------------------------------
                    | _                                      |
                    |                                        |
                    |                                        |
                    |                                        |
                    |                                        |
                    |                                        |
                    |                                        |
                    |                                        |
                    |                                        |
                    |EMACS (Fundamental) Main: ftoc.f -0%-   |
                    |                                        |
                    ------------------------------------------
@end(verbatim)
The real screen is usually 24 lines long and 80 characters wide.
Everything above the line is a "blank page" that you can fill up with
text.  The line shows emacs status information.  If emacs
has any questions to ask you, it will prompt you for answers
at the bottom of the screen.

@subsection(Fortran Format)
With this and all Fortran programs, you need to be careful about
which columns you put things in.  If you violate the rules,
the errors that result are usually copious, obscure, and
hard to diagnose correctly.    Notice
below how the programmer uses a comment card to help her line things up.
The screen is 80 columns wide
(like an old data card).  This is the format to follow:
@begin(description, spread 0)
@b(Columns@\What it contains)

1@\If a C is present, for "comment," the rest of the line is ignored.

2-5@\Fortran statement numbers.

6@\If not blank, this card is a continuation of the previous card.

7-72@\Program statements, indented as necessary.

73-80@\@b(MUST) be left blank.  Fortran ignores them.
@end(description)

@subsection(Typing in Text)
Type in the fahrenheit to centrigrade program as shown below.
@begin(example, above 1 line, below 0 line, font smallbodyfont)

--------------------------------------------------------------------------------
|C                                                                             |
|C   Convert Fahrenheit temperatures to Centigrade: C = 5/9 (F - 32)           |
|C                                                                             |
|C234567----------------------------------------------------------------|------|
|                                                                              |
|       real  ftemp, ctemp                                                     |
|                                                                              |
|       print *, 'Type in a Fahrenheit temperature, then press RETURN'         |
|       read  ftemp                                                            |
|                                                                              |
|       ctemp = (5.0/9.0) * ( ftemp - 32.0 )                                   |
|                                                                              |
|       print *, ftemp, 'Fahrenheit is', ctemp, 'Centrigrade'                  |
|       print *, 'Exiting.  Bye.'                                              |
|       end                                                                    |
|                                                                              |
|                                                                              |
|                                                                              |
|                                                                              |
|                                                                              |
|                                                                              |
|EMACS (Fundamental) Main:  ftoc.mss --95%--                                   |
|                                                                              |
|                                                                              |
--------------------------------------------------------------------------------
@end(example)
@begin(description)
@b(To enter text)@\Just start typing.  When you get to the end of the line, press the
RETURN key, just as you would on an electric typewriter.

@b(Blankspace)@\Use the SPACEBAR to make blanks.  In @i(emacs), there
is a difference between a blank (made with the SPACEBAR) and
nothing at all. 

@b(Blanklines)@\Make blank lines just as you would on a typewriter, press
the RETURN key an extra time.

@b(Typos)@\If you make a mistake while typing along, use the
DELETE key at the upper right of the main keyboard (sometimes
labeled <--) to backup and fix the mistake.
@end(description)

@subsection(Fixing Text)
To edit existing text (fix typos, add or delete words or lines, etc.),
you move the @b(cursor) around the "page" until it points to where you want to
make a change and then you enter a command.
@begin(description)
@b(Move the cursor)@\You move the cursor with the arrow keys at the right
of the keyboard.  Notice how the cursor "wraps around" when you go over
the end of a line.  Please note that on some terminals there is a <--
delete key and a <-- arrow key.  They are different.

@b(Inserting letters)@\Move the cursor to where you want the new characters.
Type them.  The rest of the text shifts over to accommodate them.

@b(Inserting lines)@\Move the cursor to where you want the new line to be.
Press RETURN.  A new line will open up.  You may have to move the cursor one
spot to the beginning of the new line.

@b(Deleting letters)@\Move to just @i(after) the character you want to remove.
Press the DELETE key.

@b(Deleting lines)@\You can delete a whole line by just typing enough DELETEs
to devour it.  Alternatively, move the cursor to the beginning
of the line, hold down the CTRL key (lower left of the keyboard), and
while still holding it down, press K.  Press CTRL-K again to get rid of
the space the line occupied.
@end(description)

@subsection(Exit Emacs)
To leave @i(emacs), type @i(two) CTRL-Cs.  Hold down the CTRL key at
the lower left of the keyboard while you press C.  Release and repeat.
At the bottom of the screen you'll see:
@begin(format, leftmargin +3)
Buffer Main modified since last write to file ftoc.f, write?  @b(y)
@end(format)
Nothing you have done is permanent until you reply y for yes to this
question.  Reply no, and everything will be thrown away.  If @i(emacs)
asks you about adding newlines, reply y for yes.

For more information on emacs, see the free Athena documents
@i(Essential Emacs) and its accompanying @i(Emacs Quick Reference) card,
available in most Athena terminal clusters.

@section(Compiling the Program)

The next step is to use a @b(compiler) to translate the Fortran ftoc.f
@b(source file) that you can read into the @b(binary file) form
that the machine can understand.
This is called "compiling a program."  The Unix Fortran compiler is
called @p(f77).  It usually takes several tries--perhaps many--to
succesfully compile a program because the compiler will find mistakes
in the program.  Here is a first try at compiling the file ftoc.f:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.25 inches)
yourhost% @b(f77 ftoc.f)@\<--run f77 on the ftoc.f file
ftoc.f@\<--compiler starts sending messages of its progress
   MAIN:
   Error on line 9 of ftoc.f: bad format descriptor@\<--compiler finds error

   Error.  No assembly.@\<--compiler finishes without making a binary file
yourhost%
@end(format)
The @i(f77) compiler found an error in line 9 of the program, printed 
a message, "bad format descriptor," and then quit.  The "Error.  No assembly."
message means that @i(f77) did not bother to make a machine-readable binary
file because it wouldn't have worked.

You should
now look at line 9 of your source program in ftoc.f with
the @i(emacs) text editor to see what could be wrong. 

@section(Debugging)


Whenever you debug a program there are two main questions
to answer:  @i(where) did the error occur and @i(what) was the
mistake.

Fortran @i(f77) compiler error messages tell you the line number
where it found the error.  But how, when there is more than just a few
lines, do you find this line in the original file, short of counting them
with your finger? 

@subsection(Emacs Editor)

You can get the @i(emacs) 
editor to display a file with line
numbers.
Call up emacs with the file ftoc.f:
@format[
yourhost%  @b(emacs   ftoc.f)
]
As always when you start @i(emacs), there will be a long pause, the
screen will blank out, and then ftoc.f is displayed.

Now, tell @i(emacs) to display the file with line numbers as follows:
@begin(enumerate, above 0 line, below 0 line,spread 0)
Press the ESC key.  You may have to hunt for it.  It will either be
in the upper left corner of the keyboard, or on terminals with
a row of buttons across the top (VT240, VT220, VS100) it is the F11
key.

Press X.  Emacs will promt M-X at the bottom of the screen.

Now type out:  Line number mode  ,and press RETURN.  It will look something
like:
@end(enumerate)

@begin(example, font smallbodyfont, above 1, below 1)
--------------------------------------------------------------------------------
|1    C                                                                        |
|2    C   Convert Fahrenheit temperatures to Centigrade: C = 5/9 (F - 32)      |
|3    C                                                                        |
|4    C234567----------------------------------------------------------------|-|
|5                                                                             |
|6           real  ftemp, ctemp                                                |
|7                                                                             |
|8           print *, 'Type in a Fahrenheit temperature, then press RETURN'    |
|9           read  ftemp                                                       |
|10                                                                            |
|11          ctemp = (5.0/9.0) * ( ftemp - 32.0 )                              |
|12                                                                            |
|13          print *, ftemp, 'Fahrenheit is', ctemp, 'Centrigrade'             |
|14          print *, 'Exiting.  Bye.'                                         |
|15          end                                                               |
|16                                                                            |
|                                                                              |
|                                                                              |
|                                                                              |
|EMACS (Fundamental) Main:  ftoc.mss --95%--                                   |
|                                                                              |
|                                                                              |
--------------------------------------------------------------------------------
@end(example)

These line numbers are not part of the file, nor can you
edit them.  They are illustrative only.  The numbers will not be saved
when you
leave @i(emacs).

The error message read, "Error on line 9 of ftoc.f: bad format descriptor."
Line 9 is the @b(read) statement.  You must now puzzle out what
the error message means.  "Bad format descriptor" means that @i(f77) 
doesn't like something about the format part of the read statement.
The format
part of a read statement is nearly always the
next thing on the line after the
word "read."  It tells Fortran what the output should look like (how it
should be spaced, where to put the decimal point, etc.) 
In this case,  the * (use your default formatting rules) was left out by
mistake.
Fortran is having trouble figuring how what an "ftemp" format should
be, not realizing it is a variable, not a format. 

To fix this error, you must type the "*, " in with @i(emacs).  Move the 
cursor with the arrow keys to the "f" of "ftemp" and type the "*, ".
To exit @i(emacs), type CTRL-C CTRL-C.

@subsection(Hardcopy Output)

It is often much easier to debug a program off a paper copy;  you
see more of the program at once.  To produce a line-numbered paper
copy of your source program, type:
@begin(format, leftmargin +3)
host%  @b(cat -n @p(filename.f) | lpr)
@end(format)
The "cat -n" lists the file out line-numered.  The "lpr" sends it
to the default printer for your cluster.  Don't for get the
@b(|) or it won't work.  You won't see
anything on the terminal screen.  Look for your username
on the front page of the output.  When you know the problem,
fix it with @i(emacs).  See the @i(Unix Quick Reference)
card or @i(Essential Unix) for more information on @i(lpr).

@subsection(Rules of Thumb)

It takes practise and experience to learn how to debug.
Most errors are not so straight-forward. 
"Appendix A" is an alphabetic list of most of @i(f77)'s compiler
error messages along with a short explanation of what specific
problem causes the error.
After a while, you will become quite deft at interpreting error
messages.  You will be able to 
just glance at most messages and see the real mistake.
Here are a few guidelines on debugging:
@itemize[
Accept that @i(there really
is something wrong) with your program.
Don't insist that the compiler is
making a mistake.

Work from the top down.  Often later error messages are
just secondary effects of earlier errors.  Fix the first error,
and the rest may disappear.

Study the error message.  Look for a keyword
that rings a bell in your head to isolate which piece of the statement
may be causing the trouble.  If none of the words sound familiar,
look them up in your Fortran book's index. 
In the example above, the keyword was "format."  Compare what you have to
examples in your Fortran book.  If necessary, go character-by-character.
A single comma in the wrong place can be fatal.

@multiple{
Like a doctor diagnosing a
patient's symptoms, be a little open-minded and skeptical about
what the compiler tells you.  A patient who has been playing tennis
may come in asking for codeine for a sore arm--when they
may actually be experiencing angina.
Compilers are like that, what they complain about is
not always what's really wrong, just sort-of.

Error messages only tell you how the real problem manifested itself
as a symptom.  If you get error messages complaining about bad arrays
and you don't @I(have) any arrays, it means that you've got something
that, because of an error, @i(looks) like an array.

Error messages only
tell you when the compiler @i(first noticed) something was wrong.
It may be that there is nothing wrong with the statement itself,
but there could be something wrong with the statement immediately
before it, or even earlier.  This may just be the first place that
the consequences of the mistake show up.
}
@end(itemize)


@section(A Successful Compilation)

To compile the ftoc.f program again:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.5 inches)
yourhost% @b(f77 ftoc.f)@\<--compile again
ftoc.f
   MAIN:
yourhost%@\<--no news is good news.  no compile errors found
@end(format)

When there are no serious errors, only warnings, the @i(f77) compiler
produces a new output file containing the compiled version of the ftoc
program.  This @b(binary file)
is what you run to actually execute the ftoc program.  You may also
hear binary files referred to as "executable images",
and, occasionally, "load modules".
The binary file will, by default, be named @b(a.out).

You can get @i(f77) to name the binary file something different.
You will have to begin doing this when you have more than one program
file because whenever you @i(f77) a file it will overwrite
the existing a.out.
  When
you compile the program, add the @b(-o @p(filename)) option.  This
tells @i(f77) to call the output file @i(filename) instead of
a.out.  For example:
@begin(format, leftmargin +3)
yourhost% @b[f77  -o ftoc  ftoc.f]
@end(format)
will produce a binary called just ftoc.  (This follows Unix
naming conventions.)  Notice that the "-o ftoc" comes @i(before) the
ftoc.f file.  

To see what files you have, use the Unix @p(ls) command (for "list"):
@begin(format, leftmargin +3)
yourhost% @b(ls)
a.out  ftoc.f  ftoc.o
@end(format)
(The ftoc.o file is an intermediate version of your program that
@i(f77) produces called an @b(object) file.  You can ignore it for now.)

The free Athena documents @i(Essential Unix) and the @i(Unix Quick
Reference) card explain more about Unix file maintenance commands.

@section(Executing the Program)

After a "clean compile," you are ready to actually execute your
program and convert some fahrenheit temperatures to centigrade.
To execute any program, you type the name of its binary file--in
this case a.out--just as though it were another Unix command:

@begin(format, leftmargin +3)
@tabclear
@tabset(4 inches)
yourhost% @b(a.out)@\<--type:  a.out  and press RETURN
Type in a Fahrenheit temperature, then press RETURN@\<--program prints instructions
32@\<--you type in a number
32.0000  Fahrenheit is  0.0000  Centrigrade@\<--program prints results
Exiting. Bye.@\<--and exits
yourhost%
@end(format)

Things may not go this smoothly.  Even though it "compiled cleanly,"
the program may still have so-called @b(run-time) errors.

@section(Run-Time Debugging)

@b(Run-time) errors are not errors in syntax, but errors in logic
that the compiler cannot check.  They only show up when you try
to execute the program.  If you are @i(un)lucky, they do not show
up at all.  Run-time
errors are hard to diagnose.
There are very few run-time error messages, so it is hard to
tell @i(what) went wrong; and the Unix system
does not tell you in which statement an error occurred, so
it is also hard to tell @i(where) it went wrong.  "Appendix B" lists
such run-time error messages as there are, and we will show you
one way to find out the line number where an error occurred.

Run-time debugging is a large topic.  Run-time errors manifest themselves
in myriad ways.  We cover only the most obvious problems here.

@subsection(Typical Problems)

When you run a program, you usually see one of four things:

@begin(itemize)
Nothing happens for a @i(long) time.
You don't get back a system prompt indicating
that execution has finished, you don't get anything.   This usually
means one of two things is happening:
@begin(enumerate)
You have a @b(read) statement that is waiting for you to type
something and press RETURN.  You didn't precede it with a @b(write)
statement to tell you what to type.

Your program is infinite looping.  Kill it with a CTRL-C. 
@end(enumerate)

Your program starts spilling copious output at you and won't stop.
The output looks repetitious.  This usually means your program is
infinite looping.  Kill it with a CTRL-C.  Notice which @b(write)
or @b(print) lines keep repeating as they show indirectly which loop's
control variable or which @b(if-then-else) has gone awry.

Nothing really bad happens.  There are no error
messages, you just don't get the results you
expected.  The only way to solve this is to trace the execution
of the program:  either by adding print statements, or through
the @i(dbx) symbolic debugger described below.

When you run the program, you get a message  like the following:
@begin(example, font smallbodyfont)
***Arithmetic Exception:  floating divide by zero
Illegal instruction (core dumped)
@end(example)
The first lines may change; the last is always the same:  "core dumped."
Your program has encountered an error so severe that the Unix
system has terminated its execution.  In the vernacular, your
program has "bombed" or "died."  The "core dumped" means specifically
that Unix has created a file called @p(core) in the current directory
that is a hex core dump of your program when it died.  Experienced
programmers can autopsy core dumps to find out what went wrong with a
program, but it is not an easy thing to do.  The main thing to realize
is that the @i(core) file takes up a great deal of file space.  You
will want to delete it unless you have a purpose in mind for it.
@end(itemize)
@newpage
@subsection(Where?)

Notice that the "core dumped" message above was fairly specific about
@i(what) was wrong:  you tried to divide by zero.  It does not tell
@i(where) the problem happened.  Here is how to find out where:

Here is the Fortran program that caused the error:
@begin(example,font smallbodyfont)
 1 C                                           2
 2 C   Program to solve quadratic equation:  ax  + bx + c
 3 C
 4 C               ---------
 5 C          +   / 2
 6 C       -b - \/ b  - 4ac
 7 C   x = -----------------
 8 C              2a
 9 C
10 C234567*********************************************************************
11 C Declarations
12
13        real  a, b, c, x1, x2, underradical
14
15 C Ask for initial values from user, then read what he typed
16
17        print *, 'Type in a b and c separated by blanks, then hit RETURN'
18        read  *, a, b, c
19
20 C Now go ahead and compute values
21
22        underradical = ( b**2 ) - ( 4 * a * c)
23        x1 = ( -(b) - (sqrt(underradical)) )  /  ( 2 * a )
24        x2 = ( -(b) + (sqrt(underradical)) )  /  ( 2 * a )
25
26 C Print results
27
28        print *, 'The two roots are:', x1, x2
29      
30 C And leave
31
32  200   print *, 'Exiting.  Bye.'
33        end
@end(example)

This program calculates the roots of a quadratic
equation.  You may be able to see the problem immediately.  In trivial programs
such as this, that is often true.  But you will need the technique
below when you have a program
with dozens of divide statements.

The program compiled cleanly:
@begin(format, leftmargin +3)
host%  @b(f77  quad.f)
quad.f:
   MAIN:
host%
@end(format)
When executed, the following occurred:
@begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inch)
host% @b(a.out)
  Type in a b and c separated by blanks, then hit RETURN
@b(0 5 7)@\<--user replies to query
*** Arithmetic Exception: Floating divide by zero
Illegal instruction (core dumped)@\<--program dies
host&
@end(format)

Now, to locate the problem:

@begin(enumerate)
Recompile the program, but add a new option @b(-g)  This tells the
compiler to produce debugging information. You @i(must)
add the -g option.@begin(format, leftmargin +3)
host%  @b(f77 -g  quad.f)
@end(format)

Start up the @p(dbx) debugger program on the @i(binary
file).  This is a powerful tool
that aids in run-time debugging.  We will show it doing only
its most simple function.@begin(format, leftmargin +3)
@tabclear
@tabset( 3.0 inch)
host% @B(dbx a.out)@\<--start dbx on a.out
dbx version of 8/14/85  13.01  (mit-paris).
Type 'help' for help. @\<--dbx announces itself
reading symbolic information ...@\    ending with the (dbx) prompt
(dbx)@\<--you now type dbx debug commands
@end(format)

Tell @i(dbx) to start running the program, and respond @i(exactly)
as before: @begin(format, leftmargin +3)
@tabclear
@tabset(3.0 inch)
(dbx) @b(run) @\<--run the program
 Type in a b and c separated by blanks, then hit RETURN
@b(0 5 7)@\<--reply exactly as before

floating point exception in MAIN at line 23
  23     x1 = ( -(b) - (sqrt(underradical)) ) / ( 2 * a )
(dbx)@\<--Aha! The offending line
@end(format)
The error message is more obscure than before, but the line
that causes the problem prints.  By looking at the divisor, we
can deduce that @i(a) must be zero.  Well, yes, of course, that's
what we said.  Clearly, the problem with
@i(quad.f) is that  we need to test for the case where @i(a)
is zero (figure is not a parabola, but a line) and do something
special about it.  We could also tell @i(dbx) to print the value of
variables: @begin(format, leftmargin +3)
@tabclear
@tabset( 3.0 inch)
(dbx) @b(print a)
0.0
(dbx) @b(quit)@\<--Leave dbx with quit command
@end(format)
@end(enumerate)

The modified @i(quad.f) would look like this:
@begin(example, font smallbodyfont)
C                                           2
C   Program to solve quadratic equation:  ax  + bx + c
C
C               ---------
C          +   / 2
C       -b - \/ b  - 4ac
C   x = -----------------
C              2a
C
C234567**********************************************************************
C Declarations

      real  a, b, c,  x2, underradical

C Ask for initial values from user, then read what he typed

      print *, 'Type in a b and c separated by blanks, then hit RETURN'
      read  *, a, b, c

C Check if a=0  (line, not parabola)  

      if ( a .EQ. 0) then
         print *, 'a is 0, this is a line'
         go to 200
      endif

C Now go ahead and compute values

      x1 = ( -(b) - (sqrt(underradical)) )  /  ( 2 * a )
      x2 = ( -(b) + (sqrt(underradical)) )  /  ( 2 * a )

C Print results

      print *, 'The two roots are:', x1, x2
      
C And leave

200   print *, 'Exiting.  Bye.'
      end

@end(example)

There is another run-time bug hiding in this program.  The program
does not check to see if the value under the radical is negative,
leading to an attempt to take the square root of a negative number,
producing an irrational result.  On some computer systems, the
built-in @i(sqrt) function would check for this case and flag
an error.  The Unix
@i(sqrt) function just returns 0.  Without an explicit, programmer-supplied
check, this program will quietly produce incorrect results.

For more information on the @i(dbx) debugger, type: @i(man dbx)
This description, however, does not show the order in which you
must enter commands to get @i(dbx) to do what you want.  Here is one
way to get @i(dbx) to step through the lines of a program:
@begin(enumerate,spread 0)
Make sure that you compiled the program with the @b(-g) option.

Find the line number of the first @i(executable) statement after
the variable declarations.  (@i(cat -n sourcefile.f | more) works).
Call this @p(line#).

Start dbx:  @B(dbx a.out)

Say:  (dbx) @B(stop at @p(line#))

Say:  (dbx) @b(run)

Then, to proceed through each source statement, keep repeating: (dbx)  @b(step)

Leave @i(dbx) with: (dbx)  @b(quit)
@end(enumerate)
@section(Linking to Libraries)

You don't have to write Fortran code "from scratch" for everything
you want to do.  Any respectable system comes with an 
assortment of libraries that you can call
from Fortran to do anything from take a
square root to compute an eigenvalue to draw an x-y plot from
an array of data.  There are many such libraries on Athena.
Some come with the Unix system, others Athena  added as extras,
such as the NAG library of mathematical routines and the Penplot
graphics package.  Most of the "public" libraries are kept
in the directories @i(/lib), @i(/usr/lib), or @i(/usr/athena/lib).
You can construct your own private libraries with the @i(ar)
utility.  Many courses have done this.

Consult your Fortran text for the general rules 
on how to call functions and subroutines within a program.
The important things to get right are the name of the function/subroutine,
and the number and type of its arguments.  @i(f77) and the
run-time system do not check that you have called a function
with the proper number of arguments or that the types
(integer, real, etc.) match.  This frequently causes obscure run-time
bugs.

To use a library, you must link to it at compile time, as follows:
@begin(format, leftmargin +3)
f77  @i(options)  @i(sourcefile.f)  @b(-l)@p(libname)
@end(format)
The @b(-l) option specifies the library to link to.  All -l
options must come at the @i(end) of the compile command, after
all filenames.  There can be @i(no blanks) between the -l
and the library name.  You can specify more than one library; they
will be linked in the order given.

To link to the NAG library:
@begin(format, leftmargin +3)
host%  @b(f77  @p(options)  @p(sourcefile.f)  -lnag)
@end(format)

To link to Penplot:
@begin(format, leftmargin +3)
host% @b(f77  @p(options)  @p(sourcefile.f)  -lpenplot)
@end(format)

The -l option, by default, searches the @i(/lib, /usr/lib), and
@i(/usr/athena/lib) directories for files of the form:
@b(lib@p(name).a).  E.g., -lnag will look in the three library 
directories until it finds a file named @i(libnag.a).

You can link to private libraries, such as those created for a
class, provided that you have read permission on the file.  To
link to a private library, just give the complete filename
of the file that contains the library.  Do not use -l.  For
example:
@begin(format, leftmargin +3)
host% @b(f77  mysource.f  /projects/16_011/lib/draw.a)
@end(format)
would link @i(mysource.f) to the @i(draw.a) library under 16_011's
project library subdirectory.

@subsection(Linking Errors)

-l is actually an option to a separate linking program, @p(ld),
not to the @i(f77) compiler.  @i(f77) always calls @i(ld) as
its last step (unless you specify -c for "compile only").  When
@i(f77) calls @i(ld), it tells it which libraries to search.
@i(f77) always has @i(ld) search:  @i(/usr/libc) (Unix
Programmer's Manual sections 3, 3S, 3N, 3X, and 3C), @i(/usr/libm)
(the math library, manual section 3M), @i(/usr/libU77, /usr/libF77),
and @i(/usr/libI77) (the Fortran libraries, manual section 3F).
You should realize that, if you ever use @i(ld) separately,
without @i(f77), @i(ld) will @i(not) look in these files
automatically; many things will become undefined.  If you have
doubts about which libraries are being linked in, use the
@b(-t) (for "trace") option on the compile command.

If @i(ld) finds linking errors ("Undefined:" error messages),
it will still produce a binary file named @i(a.out)
(or whatever you specified),
but it will set its file protection to "no owner execute."  
If you try to run such a file anyway, you will get a "Permission denied."
error message.  Verify that this is the problem with:
@begin(example, font smallbodyfont)
ls -l a.out
-rw-------  1  you   37888 Sep 1 16:15 a.out*
   |
   | No "x" for owner execute
@end(example) 


@section(Simple File I/O)

By default, Fortran reads its input from the keyboard, and writes its output
and errors to the terminal screen.  More precisely, Unit 0 (errors) is
assigned to the Unix data stream @i(stderr), Unit 5 (input) is assigned to
Unix data stream @i(stdin), and Unix 6 (output) is assigned to the Unix 
stream @i(stdout).  This means that you can easily redirect your input
and output away from the keyboard and screen and have it come to and
from files using the Unix I/O redirection mechanisms.

If a compiled program @i(myfile) contained the two statements:
@begin[example,font smallbodyfont]
read  *,a
write *,a
@end(example)
and was subsequently executed as follows:
@begin(example, font smallbodyfont)
host% myprogram
@end(example)
it would read its input data from the keyboard and write it to the
screen.

If it were invoked as follows:
@begin(example, font smallbodyfont)
host%  myprogram  <testdata   >results
@end(example)
it would read from the file @i(testdata) in the current directory
and write to a file @i(results), also in the current directory.  Much
more elaborate I/O operations to files are possible.  See the
document "Introduction to the f77 I/O Library," part of the Athena
@i(Fortran) manual for details.


@section(For More Information)

If you plan to do much Fortran programming, you will need to buy
a good book on Fortran 77, both to teach yourself the language,
and to use as a reference manual for syntax questions.  There are
dozens of Fortran 77 books.  We recommend @i(Fortran 77 for Humans),
Second Edition, by Page, Didday and Alpert, West Publishing Co.,
ISBN 0-314-69672-5.@foot{Be careful not to get @i(Fortran for Humans)
by the same author; it is for a very different, outdated version
of Fortran}
Note in particular the "Quick Reference Index" on its last page.

The IS Publications Office in 11-209 (M-F, 11 am to 3 pm) sells
this book.  It is used as a text for 2.10, and so the Coop usually
has it as well.  Reference copies are available in each cluster
in the manual rack.

To learn more about the @i(f77) compiler, there is:  
@begin(itemize)
Type:  @i(man f77)  This will show you the other options on the
@i(f77) command.

The Athena @i(Fortran) manual contains two documents:  "A Portable
Fortran 77 Compiler" and "An Introduction to the f77 I/O Library."
You should get these if you will be doing serious Fortran work.
They tell you things such as this compiler's extensions to the Fortran 77
standard, and details of I/O to files.  Reference
copies are in each terminal cluster manual rack.  You can buy
the manual at the IS Publications Office.
@end(itemize)

Very specific information on libraries is found in the Unix Programmer's
Manual, section 3.  Athena sells this as its @i(Unix Functions) manual
through IS Publications.  Reference copies are in the racks.  The easiest
way, though, is to examine the material online.  Type:  @i(man 3 intro)
for the introduction to libraries.  @i(man ar) describes sketchily
how to make libraries.  @i(man nm) describes how to examine their
contents.  Penplot and NAG are documented in available in the cluster
reference racks.  The NAG manual is a large green, 6-volume set.
The small Penplot manual is also sold at IS Publications.

The @i(dbx) debugger is only described on its man page; type @i(man dbx).

@newpage
@section(Appendix A: Compile Errors)
 
@begin(format, flushright, font bodyfont)
@i(These appendicies showing f77 
error messages were originally compiled
for subject 2.10 by John Kyratzoglou and
Dan Ottenheimer)

@end(format)


@BEGIN(DESCRIPTION) 
ASSIGNMENT TO AN UNDIMENSIONED ARRAY
@\An assumed array name was used, where the array name was not declared
in a declaration statement.

BAD ARGUMENT TYPE TO INTRINSIC FUNCTION
@\A function reference was made, using an intrinsic function name,
but the argument list does not agree in order, number or type with the 
intrinsic function requirements.

BAD MAGIC NUMBER
@\For a FORTRAN file the extension must be @B<.f>. For a C file the 
extension must be @B<.c>.

DECLARATION ERROR DECLARATION AMONG EXECUTABLES
@\The order of the statements was not as specified in 
the FORTRAN Language Reference Manual. The statement found out of order is 
ignored.
@begin(example) 
        Example :
                 N = 10
                 REAL X(N)
@end(example)
Here an executable statement precedes  a declaration statement.

DECLARATION ERROR DECLARATION :INCOPATIBLE TYPE DECLARATION
@\The same variable appears in more than one but different data type 
declaration statements. As an example,
@begin(example)
       REAL X(5)
       INTEGER X(5)
@end(example)

DECLARATION ERROR FOR AN ENTITY, USED AS VARIABLE
@\An entity has been used incorrectly; for example, the name of a 
subprogram was used where an arithmetic expression is required.

DECLARATION ERROR FOR ENTITY: INCONSISTENT EQUIVALENCE
    @\EQUIVALENCE statements specify inconsistent relationships between
variables or array elements. As an example,
@example{
EQUIVALENCE (A(1), A(2))}

DECLARATION ERROR LENGTH MUST BE A POSITIVE INTEGER CONSTANT
@\An unacceptable length has been specified in a data type declaration.
This statement is not allowed.
@begin(example)
  Examples:
           INTEGER NUM*3
           CHARACTER*  NAME
@end(example)

DECLARATION ERROR FOR VARIABLE, IMPROPERLY DIMENSIONED ARRAY
@\A reference was made to an adjustable array in a context where such
a reference is not allowed. Example:
@begin(example)
         parameter(nc=20, nchar=3)
         real x(n)
@end(example)
The variable n specified  giving the array size must be either 
initialized in the parameter statement or must be subprogram dummy 
argument or appear in common.

DO LOOP OR BLOCK IF NOT CLOSED
@\The terminal statement of a DO loop or the END IF statement of an 
IF block was not found.

EXECUTION ERROR ENDIF OUT OF PLACE
@\Invalid control structure using ELSEIF, ELSE, or ENDIF. The order 
of the above statements is incorrect.

EXECUTION ERROR LABEL ALREADY DEFINED
@\The same label appears on more than one statement.

EXECUTION ERROR, UNCLASSIFIABLE STATEMENT
@\Compiler cannot figure out what kind of statement it is.  Sometimes
caused by misspelled keywords or unbalanced quotes that create nonsense
statement fragments.

EXECUTION ERROR, UNLABELED FORMAT STATEMENT
@\A required label in a format statement was ommitted.

FLOATING EXCEPTION DURING CONSTANT EVALUATION
@\The specified value of a constant is too large or too small to 
be represented.

IMPOSSIBLE CONVERSION @begin(multiple)
@\An expression that must be arithmetic(INTEGER, REAL, LOGICAL) was
of type CHARACTER.

An expression that must be of type CHARACTER was another data type.

A variable is not declared properly.
@end(multiple)

IMPOSSIBLE STORAGE CLASS 8 IN ROUTINE
@\Often caused by attempt
to use a non-array variable as an array.  Often paired with
"DECLARATION ERROR" message.

INVALID CONTROL ACCESS FOR STATEMENT
@\The ACCESS= keyword specified in an I/O statement was the one assumed
when the file was created.

INVALID CONTROL END FOR STATEMENT 
@\The END=keyword was used illegally in a WRITE or direct access READ
statement.

LABEL ALREADY THAT OF A FORMAT
@\Labels of executable statements have been confused with labels of
FORMAT statements or with labels of non executable statements.

LOGICAL DATUM ASSIGNED TO A REAL VARIABLE
@\In a data statement a logical constant was assigned to a real variable.
Example:
@example( data bzro /.true./)

LD:@i(filename): CANNOT OPEN
@\File type of @i(filename) was not specified during the creation 
of a FORTRAN or C file. As a result during the execution of the shell
command 
@begin(example)
      % f77 for.
    or
      % f77 for
@end(example)
the file could not be opened and compiled.

LOCAL VARIABLE "X" NEVER USED
@\A particular variable was referenced but never used in the program.

MISSING END STATEMENT
@\An END statement was missing at the end of the last input file.

MISSING STATEMENT NUMBER
      @\Reference has been made to statement label that is not defined in the
program unit.

MORE DATA VALUES THAN DATA ITEMS
@\The number of variables or array elements to be initialized must
match the number of constants specified in data initialization.

NAME " name " TRUNCATED TO 16
@\" name " was longer than 16 characters and has been truncated.

NONDIGIT IN STATEMENT NUMBER FIELD
@\An improperly formed statement label(namely one containing letters)
has been detected in columns 1 to 5 of an initial line. The statement label
was ignored. 
 
NONLOGICAL EXPRESSION IN IF STATEMENT
@\An expression that must be of type LOGICAL  was another data type.

NONLOGICAL OPERANT OF LOGICAL OPERATOR
@\An invalid operation was specified as .AND. of two real variables.

NUMERIC DATUM ASSIGNED TO A CHARACTER VARIABLE
@\Character data with a length greater than one was initialize with 
a numeric value in a DATA statement. As an example:
@example{
character*10 name
data name /14/}

REPEATED KEYWORD
@\Each keyword subparameter in an I/O statement or auxiliary I/O
statement can be specified only once.

SUBSCRIPTS ON A SIMPLE VARIABLE
@\A variable that is not defined as an array cannot appear with subscripts.

SYNTAX ERROR
@\This is the catch-all error message for syntax problems.
Some frequent causes:
@begin(itemize)
@\An expression or a term of an expression has been ommitted ( missing 
variable or constant).
@begin(example)
 Example : RESULT =    * TIME
           SUMMATION =      
	   WRITE(6, FMT='(1X, F3.1)') SUM
@end(example)

Superfluous text was found at the end of a syntactically correct
statement. Check for typing or syntax errors (extra characters following 
a valid statement).
@example( Example :  ICOUNT = ICOUNT+1, )

A required variable or subprogram name was not found.

Two terms of an expression are not sepatated by an operator or a
punctuation mark(such as comma) has been omitted.

A floating-point constant was specified in E notation but the 
exponent was omitted.

A required constant was not found.

A character constant must be enclosed in parenthesis.

An invalid operation was attempted in an implied-DO list in a 
DATA statement, for instance a function reference in the subscript or
substring expression of an array or character substring reference. Example:
@example{DATA (A(SIN(REAL(I))), I=1, 10 )   /100.0/}

Extra comma in format list.
@end(itemize)

TERMINATION CODE 139
@\The upper bound of a dimension declarator must be equal to or
greater than the lower bound.

THERE IS A BRANCH TO STATEMENT LABEL FROM OUTSIDE BLOCK
@\DO or IF statement incorrectly nested.

UNBALANCED PARENTHESIS, STATEMENT SKIPPED
@\Two terms of an expression are not
separared by an operator or a punctuation mark (such as comma,parenthesis)
has been omitted.

UNBALANCED QUOTES; CLOSING QUOTE SUPPLIED, (SYNTAX ERROR)
@\A missing quote was detected  and supplied by the system.

UNDEFINED:
@\Followed by a list of routine names.  The linker @i(ld) cannot
find the routines in the libraries searched.  To check which
libraries were searched, recompile with -t option.

UNDEFINED ENTITY :
@\A control parameter expression in an implied-DO list in a DATA
statement contains a name which is not the name of a control variable 
of an implied-DO list which has the name of its scope. Example:
@EXAMPLE{ DATA (A(J), J=1,10),(B(I), I=J,K) /100./ }

WRITE SFE:[100] ERROR IN FORMAT
ILLEGAL INSTRUCTION
@\@BEGIN(itemize, spread 0)
Extra comma in format list

Extra number in format list

An invalid character or a syntax error was detected in a FORMAT 
statement.
@end(itemize)

WRONG NUMBER OF SUBSCRIPTS
@\More or fewer dimensions are referenced than were declared for the
array.

ZERO STEP IN IMPLIED DO LOOP
    @\An invalid control parameter was detected in an implied-DO list
in a data statement; for instance an increment of zero.


@end(description)


@section(Appendix B:  Run-Time Errors)

@begin(description)
ASSIGNMENT TO AN UNDIMENSIONED ARRAY
@\An assumed array name was used, where the array name was not declared.

ARITHMETIC EXCEPTION: FLOATING DIVIDE BY ZERO
@\During a floating point arithmetic operation, an attempt was made to
divide by zero.

ARITHMETIC EXCEPTION :FLOATING POINT OVERFLOW
@\During an arithmetic operation, a floating point value exceeded
the largest representable value for that data type.

BUS ERROR
@\The number of arguments in the dummy argument list is greater than
the number of arguments in the actual argument list in a main/subprogram
to subprogram interface (access violation, RM=01).

READ UNEXPECTED CHARACTER
@\During a formatted operation, an invalid character was detected
in an input field, or the input value overflowed the range representable
in the input variable (Input conversion error).

* * * (ASTERISKS)
@\During a formatted output operation the value of a particular number 
could not be output in the specified field length without loss of
significant digits. The field is filled with asterisks (Output conversion
error).

DOFIO :[-1] END OF FILE DURING READ
@\An end-of-file condition was encountered during execution of
a READ statement that did not contain an END, ERR or IOSTAT specification.

IERR = -1
@\Attempt to access a nonexistent record.

IERR = 104
@\Mixed access modes. An attempt was made to use formatted and 
unformatted operations on the same unit.

IERR = 103
@\access='sequential' was performed on a direct access file.

ILLEGAL UNIT NUMBER
@\A logical unit number greater than 99 or less than zero was used
in an I/O statement.

PERMISSION DENIED.
@\There were errors during linking when you compiled the program.
("Undefined:")  The linker has set the file's protection to
"no owner execute."

@end(description)

@section(Errors Undetected by f77 )

@begin(enumerate)

The control variable of a DO loop has been altered within the range 
of the DO statement. Assignment to DO variable within loop. Example:
@begin(example) 
       do 14 i=1,20
         i = 20       	
         x(i) = 0
    14 continue
@end(example)

Extra comma in format list.
Example :
@begin(example)
       Format(1x, a, f3.1,)
@end(example)

Missing separator between format items. A required separator character
has been omitted between fields in a FORMAT statement. Example:
@begin(example)
       Format(1x, a  f3.1)
@end(example)

A variable appears in more than one data type declaration statement. Or
a name appears in two or more inconsistent declarations statements
(Multiple declaration of name).
@begin(example)
         real x(5), x(5)
   or
         real x(5) , ....
         real x(5) , ....
@end(example)

Missing number in format list
@begin(example)
Example :    FORMAT(1x, a, f6. )
@end(example)
The system assumes that the number of characters to the right of decimal
point is one and there is an accuracy error involved.

Using an array within a program without declaring it with a DIMENSION 
statement.
@Begin(Example)
Example:
  c
       do 14 j=1,20
        x(j) = 10.5
        write(6, fmt=*) x(j)
  14  continue
  c
      stop
      end
@end(example)
          
@end(enumerate) 
