diff --git a/en/tutorials/Makefile b/en/tutorials/Makefile
index 40a10bc3f1..e414259fe1 100644
--- a/en/tutorials/Makefile
+++ b/en/tutorials/Makefile
@@ -1,5 +1,5 @@
 DOCS=		index.sgml
-SUBDIR=		disklessx newuser
-DOCSUBDIR=	ddwg devel fonts mh multios ppp
+SUBDIR=		devel disklessx newuser
+DOCSUBDIR=	ddwg fonts mh multios ppp
 
 .include "../web.mk"
diff --git a/en/tutorials/devel/Makefile b/en/tutorials/devel/Makefile
index 6cc882035c..9429f7790d 100644
--- a/en/tutorials/devel/Makefile
+++ b/en/tutorials/devel/Makefile
@@ -1,5 +1,5 @@
-DOC=		devel
-SRCS=		devel.sgml
+DOCS=	devel.docb
+INDEXLINK=	devel.html
 
-.include <bsd.sgml.mk>
+.include "../../web.mk"
 
diff --git a/en/tutorials/devel/devel.docb b/en/tutorials/devel/devel.docb
new file mode 100644
index 0000000000..524d8730f3
--- /dev/null
+++ b/en/tutorials/devel/devel.docb
@@ -0,0 +1,1835 @@
+<!-- $FreeBSD$ -->
+<!-- The FreeBSD Documentation Project -->
+
+<!DOCTYPE BOOK PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
+<book>
+<bookinfo>
+<bookbiblio>
+<title>A User's Guide to FreeBSD Programming Tools</title>
+
+<authorgroup>
+<author>
+<firstname>James</firstname>
+<surname>Raynard</surname>
+<affiliation>
+<address>
+<email>jraynard@freebsd.org</email>
+</address>
+</affiliation>
+</author></authorgroup>
+
+<pubdate>January 19, 1997</pubdate>
+
+<copyright>
+<year>1997</year>
+<holder>James Raynard</holder>
+</copyright>
+
+<abstract><para>This document is an introduction to using some of the programming
+tools supplied with FreeBSD, although much of it will be applicable to
+many other versions of Unix. It does <emphasis>not</emphasis> attempt to describe
+coding in any detail. Most of the document assumes little or no
+previous programming knowledge, although it is hoped that most
+programmers will find something of value in it</para></abstract>
+</bookbiblio>
+</bookinfo>
+
+<chapter>
+<title>Introduction<anchor id=foo></title>
+  
+<para>FreeBSD offers an excellent development environment. Compilers
+for C, C++, and Fortran and an assembler come with the basic system,
+not to mention a Perl interpreter and classic Unix tools such as
+<command>sed</> and <command>awk</>. If that is not enough, there are
+many more compilers and interpreters in the Ports collection. FreeBSD
+is very compatible with standards such as <acronym>POSIX</> and
+<acronym>ANSI</> C, as well with its own BSD heritage, so it is
+possible to write applications that will compile and run with little
+or no modification on a wide range of platforms.</para>
+
+<para>However, all this power can be rather overwhelming at first if
+you've never written programs on a Unix platform before. This
+document aims to help you get up and running, without getting too
+deeply into more advanced topics. The intention is that this document
+should give you enough of the basics to be able to make some sense of
+the documentation.</para>
+
+<para>Most of the document requires little or no knowledge of
+programming, although it does assume a basic competence with using
+Unix and a willingness to learn!</para>
+  
+</chapter>
+
+<chapter>
+<title>Introduction to Programming</title>
+
+<para>A program is a set of instructions that tell the computer to do
+various things; sometimes the instruction it has to perform depends
+on what happened when it performed a previous instruction. This
+section gives an overview of the two main ways in which you can give
+these instructions, or <quote>commands</quote> as they are usually
+called. One way uses an <firstterm>interpreter</>, the other a
+<firstterm>compiler</>. As human languages are too difficult for a
+computer to understand in an unambiguous way, commands are usually
+written in one or other languages specially designed for the
+purpose.</para>
+
+
+  
+<sect1>
+<title>Interpreters</title>
+
+<para>With an interpreter, the language comes as an environment, where you
+type in commands at a prompt and the environment executes them for
+you. For more complicated programs, you can type the commands into a
+file and get the interpreter to load the file and execute the commands
+in it. If anything goes wrong, many interpreters will drop you into a
+debugger to help you track down the problem.</para>
+  
+<para>The advantage of this is that you can see the results of your
+commands immediately, and mistakes can be corrected readily. The
+biggest disadvantage comes when you want to share your programs with
+someone. They must have the same interpreter, or you must have some
+way of giving it to them, and they need to understand how to use it.
+Also users may not appreciate being thrown into a debugger if they
+press the wrong key! From a performance point of view, interpreters
+can use up a lot of memory, and generally do not generate code as
+efficiently as compilers.</para>
+
+<para>In my opinion, interpreted languages are the best way to start
+if you have not done any programming before. This kind of environment
+is typically found with languages like Lisp, Smalltalk, Perl and
+Basic. It could also be argued that the Unix shell (<command>sh</>,
+<command>csh</>) is itself an interpreter, and many people do in fact
+write shell <quote>scripts</quote> to help with various
+<quote>housekeeping</> tasks on their machine. Indeed, part of the
+original Unix philosophy was to provide lots of small utility
+programs that could be linked together in shell scripts to perform
+useful tasks.</para>
+  
+</sect1>
+
+<sect1>
+<title>Interpreters available with FreeBSD</title>
+
+<para>Here is a list of interpreters that are available as <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
+packages</ulink>, with a brief discussion of some of the more popular
+interpreted languages. </para>
+
+<para>To get one of these packages, all you need to do is to click on
+the hotlink for the package, then run
+<screen>$ <userinput>pkg_add <replaceable>package name</></userinput></screen>
+</para>
+  
+<para>as root. Obviously, you will need to have a fully functional FreeBSD
+2.1.0 or later system for the package to work!</para>
+  
+<para>
+<variablelist>
+<varlistentry><term><acronym>BASIC</></term>
+
+<listitem><para>Short for Beginner's All-purpose Symbolic Instruction
+Code. Developed in the 1950s for teaching University students to
+program and provided with every self-respecting personal computer in
+the 1980s, <acronym>BASIC</> has been the first programming language
+for many programmers. It's also the foundation for <trademark>Visual
+Basic</>.</para>
+
+<para>The <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/bwbasic-2.10.tgz">Bywater
+Basic Interpreter</ulink> and the <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/pbasic-2.0.tgz">Phil
+Cockroft's Basic Interpreter</ulink> (formerly Rabbit Basic) are
+available as FreeBSD <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
+packages</ulink></para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Lisp</term>
+<listitem><para>A language that was developed in the late 1950s as an alternative to
+the <quote>number-crunching</quote> languages that were popular at the time.
+Instead of being based on numbers, Lisp is based on lists; in fact
+the name is short for <quote>List Processing</quote>. Very popular in AI
+(Artificial Intelligence) circles.</para>
+  
+<para>Lisp is an extremely powerful and sophisticated language, but
+can be rather large and unwieldy. </para>
+
+<para>FreeBSD has <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/gcl-2.0.tgz">GNU
+Common Lisp</ulink> available as a package.</para>
+  
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Perl</term>
+<listitem><para>Very popular with system administrators for writing
+scripts; also often used on World Wide Web servers for writing <acronym>CGI</>
+scripts.</para>
+
+<para>Version 4, which is probably still the most widely-used
+version, comes with FreeBSD; the newer <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/perl-5.001.tgz">Perl
+Version 5</ulink> is available as a package.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Scheme</term>
+<listitem><para>A dialect of Lisp that is rather more compact and
+cleaner than Common Lisp. Popular in Universities as it is simple
+enough to teach to undergraduates as a first language, while it has a
+high enough level of abstraction to be used in research work.</para>
+
+<para>FreeBSD has packages of the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/elk-3.0.tgz">Elk Scheme Interpreter</ulink>, the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/mit-scheme-7.3.tgz">MIT Scheme Interpreter</ulink> and the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/scm-4e1.tgz">SCM Scheme Interpreter</ulink>.</para>
+  
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Icon</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/icon-9.0.tgz">The Icon Programming Language</ulink>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Logo</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/ucblogo-3.3.tgz">Brian Harvey's LOGO Interpreter</ulink>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Python</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/python-1.2">The Python Object-Oriented Programming Language</ulink></para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+  
+</sect1>
+
+<sect1>
+<title>Compilers</title>
+
+<para>Compilers are rather different. First of all, you write your
+code in a file (or files) using an editor. You then run the compiler
+and see if it accepts your program. If it did not compile, grit your
+teeth and go back to the editor; if it did compile and gave you a
+program, you can run it either at a shell command prompt or in a
+debugger to see if it works properly.<footnote><para>If you run it in
+the shell, you may get a core dump.</para></footnote></para>
+
+<para>Obviously, this is not quite as direct as using an interpreter.
+However it allows you to do a lot of things which are very difficult
+or even impossible with an interpreter, such as writing code which
+interacts closely with the operating system&mdash;or even writing
+your own operating system! It's also useful if you need to write very
+efficient code, as the compiler can take its time and optimise the
+code, which would not be acceptable in an interpreter. And
+distributing a program written for a compiler is usually more
+straightforward than one written for an interpreter&mdash;you can just
+give them a copy of the executable, assuming they have the same
+operating system as you.</para>
+
+<para>Compiled languages include Pascal, C and C++. C and C++ are rather
+unforgiving languages, and best suited to more experienced
+programmers; Pascal, on the other hand, was designed as an educational
+language, and is quite a good language to start with. Unfortunately,
+FreeBSD doesn't have any Pascal support, except for a Pascal-to-C
+converter in the ports.</para>
+  
+<para>As the edit-compile-run-debug cycle is rather tedious when
+using separate programs, many commercial compiler makers have
+produced Integrated Development Environments (<acronym>IDE</acronym>s
+for short). FreeBSD does not have an <acronym>IDE</> as such; however
+it is possible to use Emacs for this purpose. This is discussed in
+<xref linkend="emacs">.</para>
+  
+</sect1>
+</chapter>
+
+<chapter>
+<title>Compiling with <command>cc</command></title>
+
+<para>This section deals only with the GNU compiler for C and C++,
+since that comes with the base FreeBSD system. It can be invoked by
+either <command>cc</> or <command>gcc</>. The details of producing a
+program with an interpreter vary considerably between interpreters,
+and are usually well covered in the documentation and on-line help
+for the interpreter.</para>
+
+<para>Once you've written your masterpiece, the next step is to convert it
+into something that will (hopefully!) run on FreeBSD. This usually
+involves several steps, each of which is done by a separate
+program.</para>
+
+<procedure>
+<step><para>Pre-process your source code to remove comments and do other
+tricks like expanding macros in C.
+</para></step>
+
+<step><para>Check the syntax of your code to see if you have obeyed the
+rules of the language. If you have not, it will complain!
+</para></step>
+
+<step><para>Convert the source code into assembly
+language&mdash;this is very close to machine code, but still
+understandable by humans. Allegedly.<footnote><para>To be strictly
+accurate, <command>cc</> converts the source code into its own,
+machine-independent <firstterm>p-code</> instead of assembly language
+at this stage.</para></footnote></para></step>
+
+<step><para>Convert the assembly language into machine
+code&mdash;yep, we are talking bits and bytes, ones and zeros
+here.</para></step>
+
+<step><para>Check that you have used things like functions and global
+variables in a consistent way. For example, if you have called a
+non-existent function, it will complain.</para></step>
+
+<step><para>If you are trying to produce an executable from several
+source code files, work out how to fit them all together.</para></step>
+
+<step><para>Work out how to produce something that the system's run-time
+loader will be able to load into memory and run.</para></step>
+
+<step><para>Finally, write the executable on the file
+system.</para></step>
+
+</procedure>
+  
+<para>The word <firstterm>compiling</> is often used to refer to just
+steps 1 to 4&mdash;the others are referred to as
+<firstterm>linking</>. Sometimes step 1 is referred to as
+<firstterm>pre-processing</> and steps 3-4 as
+<firstterm>assembling</>.</para>
+
+<para>Fortunately, almost all this detail is hidden from you, as
+<command>cc</> is a front end that manages calling all these programs
+with the right arguments for you; simply typing
+<screen>$ <userinput>cc foobar.c</></screen></para>
+  
+<para>will cause <filename>foobar.c</> to be compiled by all the
+steps above. If you have more than one file to compile, just do
+something like
+<screen>$ <userinput>cc foo.c bar.c</></screen>
+</para>
+  
+<para>Note that the syntax checking is just that&mdash;checking the
+syntax. It will not check for any logical mistakes you may have made,
+like putting the program into an infinite loop, or using a bubble
+sort when you meant to use a binary sort.<footnote><para>In case you
+didn't know, a binary sort is an efficient way of sorting things into
+order and a bubble sort isn't.</para></footnote></para>
+
+<para>There are lots and lots of options for <command>cc</>, which
+are all in the man page.  Here are a few of the most important ones,
+with examples of how to use them.</para>
+
+<variablelist>
+<varlistentry><term><option>-o <replaceable>filename</replaceable></></term>
+
+<listitem><para>The output name of the file. If you do not use this
+option, <command>cc</> will  produce an executable called
+<filename>a.out</>.<footnote><para>The reasons for this are buried in
+the mists of history.</para></footnote></para>
+
+<informalexample>
+<screen>$ <userinput>cc foobar.c</>               <lineannotation>executable is <filename>a.out</></>
+$ <userinput>cc -o foobar foobar.c</>     <lineannotation>executable is <filename>foobar</></></screen>
+</informalexample>
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-c</option></term>
+<listitem><para>Just compile the file, do not link it. Useful for toy
+programs where you just want to check the syntax, or if you are using
+a <filename>Makefile</filename>.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -c foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce an <firstterm>object file</> (not an
+executable) called <filename>foobar.o</filename>. This can be linked
+together with other object files into an executable.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-g</option></term>
+
+<listitem><para>Create a debug version of the executable. This makes
+the compiler put information into the executable about which line of
+which source file corresponds to which function call. A debugger can
+use this information to show the source code as you step through the
+program, which is <emphasis>very</emphasis> useful; the disadvantage
+is that all this extra information makes the program much bigger.
+Normally, you compile with <option>-g</option> while you are
+developing a program and then compile a <quote>release
+version</quote> without <option>-g</option> when you're satisfied it
+works properly.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -g foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce a debug version of the
+program.<footnote><para>Note, we didn't use the <option>-o</option>
+flag to specify the executable name, so we will get an executable
+called <filename>a.out</filename>. Producing a debug version called
+<filename>foobar</filename> is left as an exercise for the
+reader!</para></footnote></para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-O</option></term>
+
+<listitem><para>Create an optimised version of the executable. The
+compiler performs various clever tricks to try and produce an
+executable that runs faster than normal. You can add a number after
+the <option>-O</option> to specify a higher level of optimisation,
+but this often exposes bugs in the compiler's optimiser. For
+instance, the version of <command>cc</command> that comes with the
+2.1.0 release of FreeBSD is known to produce bad code with the
+<option>-O2</option> option in some circumstances.</para>
+
+<para>Optimisation is usually only turned on when compiling a release
+version.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -O -o foobar foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce an optimised version of
+<filename>foobar</filename>.</para>
+
+</listitem>
+</varlistentry>
+</variablelist>
+
+<para>The following three flags will force <command>cc</command> to
+check that your code complies to the relevant international standard,
+often referred to as the <acronym>ANSI</acronym> standard, though
+strictly speaking it is an <acronym>ISO</acronym> standard.</para>
+
+<variablelist>
+
+<varlistentry><term><option>-Wall</option></term>
+
+<listitem><para>Enable all the warnings which the authors of
+<command>cc</command> believe are worthwhile. Despite the name, it
+will not enable all the warnings <command>cc</command> is capable
+of.</para></listitem>
+
+</varlistentry>
+
+<varlistentry><term><option>-ansi</option></term>
+
+<listitem>
+<para>Turn off most, but not all, of the non-<acronym>ANSI</>&nbsp;C
+features provided by <command>cc</command>. Despite the name, it does
+not guarantee strictly that your code will comply to the
+standard.</para>
+</listitem>
+
+</varlistentry>
+
+<varlistentry><term><option>-pedantic</option></term>
+
+<listitem>
+<para>Turn off <emphasis>all</emphasis>
+<command>cc</command>'s non-<acronym>ANSI</>&nbsp;C features.</para>
+</listitem>
+
+</varlistentry>
+</variablelist>
+
+<para>Without these flags, <command>cc</command> will allow you to
+use some of its non-standard extensions to the standard. Some of
+these are very useful, but will not work with other compilers&mdash;in
+fact, one of the main aims of the standard is to allow people to
+write code that will work with any compiler on any system. This is
+known as <firstterm>portable code</firstterm>.</para>
+
+<para>Generally, you should try to make your code as portable as
+possible, as otherwise you may have to completely re-write the
+program later to get it to work somewhere else&mdash;and who knows
+what you may be using in a few years time?</para>
+  
+<informalexample>
+<screen>$ <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
+</informalexample>
+
+<para>This will produce an executable <filename>foobar</filename>
+after checking <filename>foobar.c</filename> for standard
+compliance.</para>
+  
+<variablelist>
+
+<varlistentry><term><option>-l<replaceable>library</replaceable></option></term>
+
+<listitem><para>Specify a function library to be used during when
+linking.</para>
+
+<para>The most common example of this is when compiling a program that
+uses some of the mathematical functions in C. Unlike most other
+platforms, these are in a separate library from the standard C one
+and you have to tell the compiler to add it.</para>
+  
+<para>The rule is that if the library is called
+<filename>lib<replaceable>something</replaceable>.a</filename>, you
+give <command>cc</command> the argument
+<option>-l<replaceable>something</replaceable></option>. For example,
+the math library is <filename>libm.a</filename>, so you give
+<command>cc</command> the argument <option>-lm</option>. A common
+<quote>gotcha</quote> with the math library is that it has to be the
+last library on the command line.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
+</informalexample>
+
+<para>This will link the math library functions into
+<filename>foobar</filename>.</para>
+
+<para>If you are compiling C++ code, you need to add
+<option>-lg++</option>, or <option>-lstdc++</option> if you are using
+FreeBSD 2.2 or later, to the command line argument to link the C++
+library functions. Alternatively, you can run <command>c++</command>
+instead of <command>cc</command>, which does this for you.
+<command>c++</command> can also be invoked as <command>g++</command>
+on FreeBSD.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.cc -lg++</userinput>     <lineannotation>For FreeBSD 2.1.6 and earlier</>
+$ <userinput>cc -o foobar foobar.cc -lstdc++</userinput>  <lineannotation>For FreeBSD 2.2 and later</>
+$ <userinput>c++ -o foobar foobar.cc</userinput></screen>
+</informalexample>
+
+<para>Each of these will both produce an executable
+<filename>foobar</filename> from the C++ source file
+<filename>foobar.cc</filename>. Note that, on Unix systems, C++
+source files traditionally end in <filename>.C</filename>,
+<filename>.cxx</filename> or <filename>.cc</filename>, rather than
+the <trademark>MS-DOS</trademark> style <filename>.cpp</filename>
+(which was already used for something else). <command>gcc</command>
+used to rely on this to work out what kind of compiler to use on the
+source file; however, this restriction no longer applies, so you may
+now call your C++ files <filename>.cpp</filename> with
+impunity!</para>
+
+</listitem>
+</varlistentry>
+</variablelist>
+  
+<sect1>
+<title>Common <command>cc</command> Queries and Problems</title>
+
+<para>Q. I am trying to write a program which uses the
+<function>sin()</function> function and I get an error like this.
+What does it mean?
+<informalexample>
+<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment</screen>
+</informalexample>
+</para>
+  
+<para>A. When using mathematical functions like
+<function>sin()</function>, you have to tell <command>cc</command> to
+link in the math library, like so:
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
+</informalexample></para>
+
+<para>Q. All right, I wrote this simple program to practice using
+<option>-lm</option>. All it does is raise 2.1 to the power of 6.
+<informalexample>
+<programlisting>#include &lt;stdio.h&gt;
+
+int main() {
+	float f;
+
+	f = pow(2.1, 6);
+	printf("2.1 ^ 6 = %f\n", f);
+	return 0;
+}</programlisting>
+</informalexample>
+and I compiled it as:
+<informalexample>
+<screen>$ <userinput>cc temp.c -lm</userinput></screen>
+</informalexample>
+like you said I should, but I get this when I run it:
+<informalexample>
+<screen>$ <userinput>./a.out</userinput>
+2.1 ^ 6 = 1023.000000</screen>
+</informalexample>
+</para>
+  
+<para>This is <emphasis>not</emphasis> the right answer! What is
+going on?</para>
+
+<para>A. When the compiler sees you call a function, it checks if it
+has already seen a prototype for it. If it has not, it assumes the
+function returns an <type>int</type>, which is
+definitely not what you want here.</para>
+
+<para>Q. So how do I fix this?</para>
+  
+<para>A. The prototypes for the mathematical functions are in
+<filename>math.h</filename>. If you include this file, the compiler
+will be able to find the prototype and it will stop doing strange
+things to your calculation!
+<informalexample>
+<programlisting>#include &lt;math.h&gt;
+#include &lt;stdio.h&gt;
+
+int main() {
+...</programlisting>
+</informalexample>
+</para>
+  
+<para>After recompiling it as you did before, run it:
+<informalexample>
+<screen>$ <userinput>./a.out</userinput>
+2.1 ^ 6 = 85.766121</screen>
+</informalexample>
+</para>
+  
+<para>If you are using any of the mathematical functions,
+<emphasis>always</emphasis> include <filename>math.h</filename> and
+remember to link in the math library.</para>
+
+<para>Q. I compiled a file called <filename>foobar.c</filename> and I
+cannot find an executable called <filename>foobar</filename>. Where's
+it gone?</para>
+
+<para>A. Remember, <command>cc</command> will call the executable
+<filename>a.out</filename> unless you tell it differently. Use the
+<option>-o&nbsp;<replaceable>filename</replaceable></option> option:
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c</userinput></screen>
+</informalexample>
+</para>
+
+<para>Q. OK, I have an executable called <filename>foobar</filename>,
+I can see it when I run <command>ls</command>, but when I type in
+<command>foobar</command> at the command prompt it tells me there is
+no such file. Why can it not find it?</para>
+
+<para>A. Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
+current directory when it is trying to find out which executable you
+want it to run, unless you tell it to. Either type
+<command>./foobar</command>, which means <quote>run the file called
+<filename>foobar</filename> in the current directory</quote>, or
+change your <systemitem class=environvar>PATH</systemitem>
+environment variable so that it looks something like
+<informalexample>
+<screen>bin:/usr/bin:/usr/local/bin:.</screen>
+</informalexample>
+The dot at the end means <quote>look in the current directory if it is not in
+any of the others</quote>.</para>
+  
+<para>Q. I called my executable <filename>test</filename>, but
+nothing happens when I run it. What is going on?</para>
+
+<para>A. Most Unix systems have a program called
+<command>test</command> in <filename>/usr/bin</filename> and the
+shell is picking that one up before it gets to checking the current
+directory. Either type:
+<informalexample>
+<screen>$ <userinput>./test</userinput></screen>
+</informalexample>
+or choose a better name for your program!</para>
+  
+<para>Q. I compiled my program and it seemed to run all right at
+first, then there was an error and it said something about <errorname>core
+dumped</errorname>. What does that mean?</para>
+
+<para>A. The name <firstterm>core dump</firstterm> dates back to the
+very early days of Unix, when the machines used core memory for
+storing data. Basically, if the program failed under certain
+conditions, the system would write the contents of core memory to
+disk in a file called <filename>core</filename>, which the programmer
+could then pore over to find out what went wrong.</para>
+
+<para>Q. Fascinating stuff, but what I am supposed to do now?</para>
+  
+<para>A. Use <command>gdb</command> to analyse the core (see <xref
+linkend="debugging">).</para>
+  
+<para>Q. When my program dumped core, it said something about a
+<errorname>segmentation fault</errorname>. What's that?</para>
+
+<para>A. This basically means that your program tried to perform some sort
+of illegal operation on memory; Unix is designed to protect the
+operating system and other programs from rogue programs.</para>
+  
+<para>Common causes for this are:
+<itemizedlist>
+<listitem><para>Trying to write to a <symbol>NULL</symbol> pointer, eg
+<programlisting>char *foo = NULL;
+strcpy(foo, "bang!");</programlisting>
+</para></listitem>
+
+<listitem><para>Using a pointer that hasn't been initialised, eg
+<programlisting>char *foo;
+strcpy(foo, "bang!");</programlisting>
+The pointer will have some random value that, with luck,
+will point into an area of memory that isn't available to
+your program and the kernel will kill your program before
+it can do any damage. If you're unlucky, it'll point
+somewhere inside your own program and corrupt one of your
+data structures, causing the program to fail
+mysteriously.</para></listitem>
+
+<listitem><para>Trying to access past the end of an array, eg
+<programlisting>int bar[20];
+bar[27] = 6;</programlisting></para></listitem>
+
+<listitem><para> Trying to store something in read-only memory, eg
+<programlisting>char *foo = "My string";
+strcpy(foo, "bang!");</programlisting>
+Unix compilers often put string literals like
+<literal>"My string"</literal> into
+read-only areas of memory.</para></listitem>
+
+<listitem><para>Doing naughty things with
+<function>malloc()</function> and <function>free()</function>, eg
+<programlisting>char bar[80];
+free(bar);</programlisting>
+or
+<programlisting>char *foo = malloc(27);
+free(foo);
+free(foo);</programlisting>
+</para></listitem>
+
+</itemizedlist></para>
+
+<para>Making one of these mistakes will not always lead to an
+error, but they are always bad practice. Some systems and
+compilers are more tolerant than others, which is why programs
+that ran well on one system can crash when you try them on an
+another.</para>
+  
+<para>Q. Sometimes when I get a core dump it says <errorname>bus
+error</errorname>. It says in my Unix book that this means a hardware
+problem, but the computer still seems to be working. Is this
+true?</para>
+
+<para>A. No, fortunately not (unless of course you really do have a hardware
+problem&hellip;). This is usually another way of saying that you
+accessed memory in a way you shouldn't have.</para>
+  
+<para>Q. This dumping core business sounds as though it could be quite
+useful, if I can make it happen when I want to. Can I do this, or
+do I have to wait until there's an error?</para>
+  
+<para>A. Yes, just go to another console or xterm, do
+<screen>$ <userinput>ps</userinput></screen>
+to find out the process ID of your program, and do
+<screen>$ <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
+where <parameter><replaceable>pid</replaceable></parameter> is the
+process ID you looked up.</para>
+  
+<para>This is useful if your program has got stuck in an infinite
+loop, for instance. If your program happens to trap
+<symbol>SIGABRT</symbol>, there are several other signals which have
+a similar effect.</para>
+
+</sect1>
+</chapter>
+
+
+<chapter>
+<title>Make</title>
+
+<sect1>
+<title>What is <command>make</command>?</title>
+
+<para>When you're working on a simple program with only one or two source
+files, typing in
+<screen>$ <userinput>cc file1.c file2.c</userinput></screen>
+is not too bad, but it quickly becomes very tedious when there are
+several files&mdash;and it can take a while to compile, too.</para>
+  
+<para>One way to get around this is to use object files and only recompile
+the source file if the source code has changed. So we could have
+something like:
+<screen>$ <userinput>cc file1.o file2.o</userinput> &hellip; <userinput>file37.c</userinput> &hellip</screen>
+if we'd changed <filename>file37.c</filename>, but not any of the
+others, since the last time we compiled.  This may speed up the
+compilation quite a bit, but  doesn't solve the typing
+problem.</para>
+
+<para>Or we could write a shell script to solve the typing problem, but it
+would have to re-compile everything, making it very inefficient on a
+large project.</para>
+  
+<para>What happens if we have hundreds of source files lying about? What if
+we're working in a team with other people who forget to tell us when
+they've changed one of their source files that we use?</para>
+  
+<para>Perhaps we could put the two solutions together and write something
+like a shell script that would contain some kind of magic rule saying
+when a source file needs compiling. Now all we need now is a program
+that can understand these rules, as it's a bit too complicated for the
+shell.</para>
+  
+<para>This program is called <command>make</command>. It reads in a
+file, called a <firstterm>makefile</firstterm>, that tells it how
+different files depend on each other, and works out which files need
+to be re-compiled and which ones don't. For example, a rule could say
+something like <quote>if <filename>fromboz.o</filename> is older than
+<filename>fromboz.c</filename>, that means someone must have changed
+<filename>fromboz.c</filename>, so it needs to be
+re-compiled.</quote> The makefile also has rules telling make
+<emphasis>how</emphasis> to re-compile the source file, making it a
+much more powerful tool.</para>
+
+<para>Makefiles are typically kept in the same directory as the
+source they apply to, and can be called
+<filename>makefile</filename>, <filename>Makefile</filename> or
+<filename>MAKEFILE</filename>. Most programmers use the name
+<filename>Makefile</filename>, as this puts it near the top of a
+directory listing, where it can easily be seen.<footnote><para>They
+don't use the <filename>MAKEFILE</filename> form as block capitals
+are often used for documentation files like
+<filename>README</filename>.</para></footnote></para>
+  
+</sect1>
+
+<sect1>
+<title>Example of using <command>make</command></title>
+
+<para>Here's a very simple make file:
+<programlisting>foo: foo.c
+	cc -o foo foo.c</programlisting>
+It consists of two lines, a dependency line and a creation line.</para>
+  
+<para>The dependency line here consists of the name of the program
+(known as the <firstterm>target</firstterm>), followed by a colon,
+then whitespace, then the name of the source file. When
+<command>make</command> reads this line, it looks to see if
+<filename>foo</filename> exists; if it exists, it compares the time
+<filename>foo</filename> was last modified to the time
+<filename>foo.c</filename> was last modified. If
+<filename>foo</filename> does not exist, or is older than
+<filename>foo.c</filename>, it then looks at the creation line to
+find out what to do. In other words, this is the rule for working out
+when <filename>foo.c</filename> needs to be re-compiled.</para>
+
+<para>The creation line starts with a <token>tab</token> (press the
+<keycap>tab</keycap> key) and then the command you would type to
+create <filename>foo</filename> if you were doing it at a command
+prompt. If <filename>foo</filename> is out of date, or does not
+exist, <command>make</command> then executes this command to create
+it. In other words, this is the rule which tells make how to
+re-compile <filename>foo.c</filename>.</para>
+
+<para>So, when you type <userinput>make</userinput>, it will make
+sure that <filename>foo</filename> is up to date with respect to your
+latest changes to <filename>foo.c</filename>. This principle can be
+extended to <filename>Makefile</filename>s with hundreds of
+targets&mdash;in fact, on FreeBSD, it is possible to compile the
+entire operating system just by typing <userinput>make
+world</userinput> in the appropriate directory!</para>
+
+<para>Another useful property of makefiles is that the targets don't have
+to be programs. For instance, we could have a make file that looks
+like this:
+<programlisting>foo: foo.c
+	cc -o foo foo.c
+
+install:
+	cp foo /home/me</programlisting></para>
+  
+<para>We can tell make which target we want to make by typing:
+<screen>$ <userinput>make <replaceable>target</replaceable></userinput></screen>
+<command>make</command> will then only look at that target and ignore any
+others. For example, if we type <userinput>make foo</userinput> with the 
+makefile above, make will ignore the <action>install</action> target.</para>
+  
+<para>If we just type <userinput>make</userinput> on its own, make
+will always look at the first target and then stop without looking at
+any others. So if we typed <userinput>make</userinput> here, it will
+just go to the <action>foo</action> target, re-compile
+<filename>foo</filename> if necessary, and then stop without going on
+to the <action>install</action> target.</para>
+
+<para>Notice that the <action>install</action> target doesn't
+actually depend on anything! This means that the command on the
+following line is always executed when we try to make that target by
+typing <userinput>make install</userinput>. In this case, it will
+copy <filename>foo</filename> into the user's home directory. This is
+often used by application makefiles, so that the application can be
+installed in the correct directory when it has been correctly
+compiled.</para>
+
+<para>This is a slightly confusing subject to try and explain. If you
+don't quite understand how <command>make</command> works, the best
+thing to do is to write a simple program like <quote>hello
+world</quote> and a make file like the one above and experiment. Then
+progress to using more than one source file, or having the source
+file include a header file. The <command>touch</command> command is
+very useful here&mdash;it changes the date on a file without you
+having to edit it.</para>
+  
+</sect1>
+
+<sect1>
+<title>FreeBSD Makefiles</title>
+
+<para>Makefiles can be rather complicated to write. Fortunately,
+BSD-based systems like FreeBSD come with some very powerful ones as
+part of the system.  One very good example of this is the FreeBSD
+ports system. Here's the essential part of a typical ports
+<filename>Makefile</filename>:
+<programlisting>MASTER_SITES=   ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
+DISTFILES=      scheme-microcode+dist-7.3-freebsd.tgz
+
+.include &lt;bsd.port.mk&gt;</programlisting></para>
+  
+<para>Now, if we go to the directory for this port and type
+<userinput>make</userinput>, the following happens:</para>
+
+<procedure>
+<step><para>A check is made to see if the source code for this port is
+already on the system.</para></step>
+
+<step><para>If it isn't, an FTP connection to the URL in
+<symbol>MASTER_SITES</symbol> is set up to download the
+source.</para></step>
+
+<step><para>The checksum for the source is calculated and compared it with
+one for a known, good, copy of the source. This is to make sure that
+the source was not corrupted while in transit.</para></step>
+
+<step><para>Any changes required to make the source work on FreeBSD are
+applied&mdash;this is known as <firstterm>patching</firstterm>.</para></step>
+
+<step><para>Any special configuration needed for the source is done.
+(Many Unix program distributions try to work out which version of
+Unix they are being compiled on and which optional Unix features are
+present&mdash;this is where they are given the information in the
+FreeBSD ports scenario).</para></step>
+
+<step><para>The source code for the program is compiled. In effect,
+we change to the directory where the source was unpacked and do
+<command>make</command>&mdash;the program's own make file has the
+necessary information to build the program.</para></step>
+
+<step><para>We now have a compiled version of the program. If we
+wish, we can test it now; when we feel confident about the program,
+we can type <userinput>make install</userinput>. This will cause the
+program and any supporting files it needs to be copied into the
+correct location; an entry is also made into a <database>package
+database</database>, so that the port can easily be uninstalled later
+if we change our mind about it.</para></step>
+
+</procedure>
+  
+<para>Now I think you'll agree that's rather impressive for a four
+line script!</para>
+
+<para>The secret lies in the last line, which tells
+<command>make</command> to look in the system makefile called
+<filename>bsd.port.mk</filename>. It's easy to overlook this line,
+but this is where all the clever stuff comes from&mdash;someone has
+written a makefile that tells <command>make</command> to do all the
+things above (plus a couple of other things I didn't mention,
+including handling any errors that may occur) and anyone can get
+access to that just by putting a single line in their own make
+file!</para>
+
+<para>If you want to have a look at these system makefiles, they're
+in <filename>/usr/share/mk</filename>, but it's probably best to wait
+until you've had a bit of practice with makefiles, as they are very
+complicated (and if you do look at them, make sure you have a flask
+of strong coffee handy!)</para>
+
+</sect1>
+
+<sect1>
+<title>More advanced uses of <command>make</command></title>
+
+<para><command>Make</command> is a very powerful tool, and can do much
+more than the simple example above shows. Unfortunately, there are
+several different versions of <command>make</command>, and they all
+differ considerably. The best way to learn what they can do is
+probably to read the documentation&mdash;hopefully this introduction will
+have given you a base from which you can do this.</para>
+
+<para>The version of make that comes with FreeBSD is the <application>Berkeley
+make</application>; there is a tutorial for it in
+<filename>/usr/share/doc/psd/12.make</filename>. To view it, do
+<screen>$ <userinput>zmore paper.ascii.gz</userinput></screen>
+in that directory.</para>
+  
+<para>Many applications in the ports use <application>GNU
+make</application>, which has a very good set of <quote>info</quote>
+pages. If you have installed any of these ports, <application>GNU
+make</application> will automatically have been installed as
+<command>gmake</command>. It's also available as a port and package
+in its own right.</para>
+
+<para>To view the info pages for <application>GNU make</application>,
+you will have to edit the <filename>dir</filename> file in the
+<filename>/usr/local/info</filename> directory to add an entry for
+it. This involves adding a line like
+<programlisting> * Make: (make).                 The GNU Make utility.</programlisting>
+to the file. Once you have done this, you can type
+<userinput>info</userinput> and then select
+<guimenuitem>make</guimenuitem> from the menu (or in
+<application>Emacs</application>, do <userinput>C-h
+i</userinput>).</para>
+
+</sect1>
+</chapter>
+
+<chapter id="debugging">
+<title>Debugging</title>
+
+<sect1>
+<title>The Debugger</title>
+
+<para>The debugger that comes with FreeBSD is called
+<command>gdb</command> (<application>GNU
+debugger</application>). You start it up by typing
+<screen>$ <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
+although most people prefer to run it inside
+<application>Emacs</application>. You can do this by:
+<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen></para>
+  
+<para>Using a debugger allows you to run the program under more
+controlled circumstances. Typically, you can step through the program
+a line at a time, inspect the value of variables, change them, tell
+the debugger to run up to a certain point and then stop, and so on.
+You can even attach to a program that's already running, or load a
+core file to investigate why the program crashed. It's even possible
+to debug the kernel, though that's a little trickier than the user
+applications we'll be discussing in this section.</para>
+
+<para><command>gdb</command> has quite good on-line help, as well as
+a set of info pages, so this section will concentrate on a few of the
+basic commands.</para>
+
+<para>Finally, if you find its text-based command-prompt style
+off-putting, there's a graphical front-end for it <ulink
+URL="http://www.freebsd.org/ports/devel.html">xxgdb</ulink>
+in the ports collection.</para>
+
+<para>This section is intended to be an introduction to using
+<command>gdb</command> and does not cover specialised topics such as
+debugging the kernel.</para>
+  
+</sect1>
+
+<sect1>
+<title>Running a program in the debugger</title>
+
+<para>You'll need to have compiled the program with the
+<option>-g</option> option to get the most out of using
+<command>gdb</command>. It will work without, but you'll only see the
+name of the function you're in, instead of the source code. If you
+see a line like:
+<screen>&hellip; (no debugging symbols found) &hellip;</screen>when
+<command>gdb</command> starts up, you'll know that the program wasn't
+compiled with the <option>-g</option> option.</para>
+  
+<para>At the <command>gdb</command> prompt, type <userinput>break
+main</userinput>. This will tell the debugger to skip over the
+preliminary set-up code in the program and start at the beginning of
+your code. Now type <userinput>run</userinput> to start the
+program&mdash;it will start at the beginning of the set-up code and
+then get stopped by the debugger when it calls
+<function>main()</function>. (If you've ever wondered where
+<function>main()</function> gets called from, now you know!).</para>
+
+<para>You can now step through the program, a line at a time, by
+pressing <command>n</command>.  If you get to a function call, you can
+step into it by pressing <command>s</command>. Once you're in a
+function call, you can return from stepping into a function call by
+pressing <command>f</command>. You can also use <command>up</command> and
+<command>down</command> to take a quick look at the caller.</para>
+
+<para>Here's a simple example of how to spot a mistake in a program
+with <command>gdb</command>. This is our program (with a deliberate
+mistake):
+<programlisting>#include &lt;stdio.h&gt;
+
+int bazz(int anint);
+
+main() {
+	int i;
+
+	printf("This is my program\n");
+	bazz(i);
+	return 0;
+}
+
+int bazz(int anint) {
+	printf("You gave me %d\n", anint);
+	return anint;
+}</programlisting>
+</para>
+  
+<para>This program sets <symbol>i</symbol> to be <literal>5</literal>
+and passes it to a function <function>bazz()</function> which prints
+out the number we gave it.</para>
+
+<para>When we compile and run the program we get
+<screen>$ <userinput>cc -g -o temp temp.c</userinput>
+$ <userinput>./temp</userinput>
+This is my program
+anint = 4231</screen></para>
+  
+<para>That wasn't what we expected! Time to see what's going
+on!<screen>$ <userinput>gdb temp</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>break main</>				<lineannotation>Skip the set-up code</>
+Breakpoint 1 at 0x160f: file temp.c, line 9.	<lineannotation><command>gdb</command> puts breakpoint at <function>main()</></>
+(gdb) <userinput>run</>					<lineannotation>Run as far as <function>main()</></>
+Starting program: /home/james/tmp/temp		<lineannotation>Program starts running</>
+
+Breakpoint 1, main () at temp.c:9		<lineannotation><command>gdb</command> stops at <function>main()</></>
+(gdb) <userinput>n</>						<lineannotation>Go to next line</>
+This is my program				<lineannotation>Program prints out</>
+(gdb) <userinput>s</>						<lineannotation>step into <function>bazz()</></>
+bazz (anint=4231) at temp.c:17			<lineannotation><command>gdb</command> displays stack frame</>
+(gdb)</screen></para>
+
+  
+<para>Hang on a minute! How did <symbol>anint</symbol> get to be
+<literal>4231</literal>? Didn't we set it to be <literal>5</literal>
+in <function>main()</function>? Let's move up to
+<function>main()</function> and have a look.</para>
+
+<para><screen>(gdb) <userinput>up</>					<lineannotation>Move up call stack</>
+#1  0x1625 in main () at temp.c:11		<lineannotation><command>gdb</command> displays stack frame</>
+(gdb) <userinput>p i</>					<lineannotation>Show us the value of <symbol>i</></>
+$1 = 4231					<lineannotation><command>gdb</command> displays <literal>4231</></></screen>
+Oh dear! Looking at the code, we forgot to initialise
+<symbol>i</symbol>. We meant to put
+<programlisting><lineannotation>&hellip;</>
+main() {
+	int i;
+
+	i = 5;
+	printf("This is my program\n");
+<lineannotation>&hellip</></programlisting>
+but we left the <literal>i=5;</literal> line out.  As we didn't
+initialise <symbol>i</symbol>, it had whatever number happened to be
+in that area of memory when the program ran, which in this case
+happened to be <literal>4231</literal>.</para>
+
+<note><para><command>gdb</command> displays the stack frame
+every time we go into or out of a function, even if we're using
+<command>up</command> and <command>down</command> to move around the
+call stack.  This shows the name of the function and the values of
+its arguments, which helps us keep track of where we are and what's
+going on. (The stack is a storage area where the program stores
+information about the arguments passed to functions and where to go
+when it returns from a function call).</para></note>
+
+</sect1>
+
+<sect1>
+<title>Examining a core file</title>
+
+<para>A core file is basically a file which contains the complete
+state of the process when it crashed. In <quote>the good old
+days</quote>, programmers had to print out hex listings of core files
+and sweat over machine code manuals, but now life is a bit easier.
+Incidentally, under FreeBSD and other 4.4BSD systems, a core file is
+called <filename><replaceable>progname</>.core</> instead of just
+<filename>core</filename>, to make it clearer which program a core
+file belongs to.</para>
+
+<para>To examine a core file, start up <command>gdb</command> in the
+usual way. Instead of typing <command>break</command> or
+<command>run</command>, type
+<screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
+If you're not in the same directory as the core file, you'll have to
+do <userinput>dir /path/to/core/file</userinput> first.</para>
+  
+<para>You should see something like this:
+<screen>$ <userinput>gdb a.out</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>core a.out.core</userinput>
+Core was generated by `a.out'.
+Program terminated with signal 11, Segmentation fault.
+Cannot access memory at address 0x7020796d.
+#0  0x164a in bazz (anint=0x5) at temp.c:17
+(gdb)</screen></para>
+  
+<para>In this case, the program was called
+<filename>a.out</filename>, so the core file is called
+<filename>a.out.core</filename>. We can see that the program crashed
+due to trying to access an area in memory that was not available to
+it in a function called <function>bazz</function>.</para>
+
+<para>Sometimes it's useful to be able to see how a function was
+called, as the problem could have occurred a long way up the call
+stack in a complex program. The <command>bt</command> command causes
+<command>gdb</command> to print out a back-trace of the call
+stack:
+<screen>(gdb) <userinput>bt</userinput>
+#0  0x164a in bazz (anint=0x5) at temp.c:17
+#1  0xefbfd888 in end ()
+#2  0x162c in main () at temp.c:11
+(gdb)</screen>The <function>end()</function> function is called when
+a program crashes; in this case, the <function>bazz()</function>
+function was called from <function>main()</function>.</para>
+
+</sect1>
+
+<sect1>
+<title>Attaching to a running program</title>
+
+<para>One of the neatest features about <command>gdb</command> is
+that it can attach to a program that's already running. Of course,
+that assumes you have sufficient permissions to do so. A common
+problem is when you are stepping through a program that forks, and
+you want to trace the child, but the debugger will only let you trace
+the parent.</para>
+
+<para>What you do is start up another <command>gdb</command>, use
+<command>ps</command> to find the process ID for the child, and
+do<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>  
+in <command>gdb</command>, and then debug as usual.</para>
+  
+<para><quote>That's all very well,</quote> you're probably thinking,
+<quote>but by the time I've done that, the child process will be over
+the hill and far away</quote>. Fear not, gentle reader, here's how to
+do it (courtesy of the <command>gdb</command> info pages):
+<screen><lineannotation>&hellip</lineannotation>
+if ((pid = fork()) < 0)		/* _Always_ check this */
+	error();
+else if (pid == 0) {		/* child */
+	int PauseMode = 1;
+
+	while (PauseMode)
+		sleep(10);	/* Wait until someone attaches to us */
+	<lineannotation>&hellip</lineannotation>
+} else {			/* parent */
+	<lineannotation>&hellip</lineannotation></screen>
+Now all you have to do is attach to the child, set
+<symbol>PauseMode</symbol> to <literal>0</literal>, and
+wait for the <function>sleep()</function> call to return!</para>
+  
+</sect1>
+</chapter>
+
+<chapter id="emacs">
+<title>Using Emacs as a Development Environment</title>
+
+<sect1>
+<title>Emacs</title>
+
+<para>Unfortunately, Unix systems don't come with the kind of
+everything-you-ever-wanted-and-lots-more-you-didn't-in-one-gigantic-package
+integrated development environments that other systems
+have.<footnote><para>At least, not unless you pay out very large sums
+of money.</para></footnote> However, it is possible to set up your
+own environment. It may not be as pretty, and it may not be quite as
+integrated, but you can set it up the way you want it. And it's free.
+And you have the source to it.</para>
+
+<para>The key to it all is Emacs. Now there are some people who
+loathe it, but many who love it. If you're one of the former, I'm
+afraid this section will hold little of interest to you. Also, you'll
+need a fair amount of memory to run it&mdash;I'd recommend 8MB in
+text mode and 16MB in X as the bare minimum to get reasonable
+performance.</para>
+
+<para>Emacs is basically a highly customisable editor&mdash;indeed,
+it has been customised to the point where it's more like an operating
+system than an editor! Many developers and sysadmins do in fact
+spend practically all their time working inside Emacs, leaving it
+only to log out.</para>
+
+<para>It's impossible even to summarise everything Emacs can do here, but
+here are some of the features of interest to developers:
+<itemizedlist>
+
+<listitem><para>Very powerful editor, allowing search-and-replace on
+both strings and regular expressions (patterns), jumping to start/end
+of block expression, etc, etc.</para></listitem>
+
+<listitem><para>Pull-down menus and online help.</para></listitem>
+
+<listitem><para>Language-dependent syntax highlighting and
+indentation.</para></listitem>
+
+<listitem><para>Completely customisable.</para></listitem>
+
+<listitem><para>You can compile and debug programs within
+Emacs.</para></listitem>
+
+<listitem><para>On a compilation error, you can jump to the offending
+line of source code.</para></listitem>
+
+<listitem><para>Friendly-ish front-end to the <command>info</command>
+program used for reading GNU hypertext documentation, including the
+documentation on Emacs itself.</para></listitem>
+
+<listitem><para>Friendly front-end to <command>gdb</command>,
+allowing you to look at the source code as you step through your
+program.</para></listitem>
+
+<listitem><para>You can read Usenet news and mail while your program
+is compiling.</para></listitem>
+
+</itemizedlist>And doubtless many more that I've overlooked.</para>
+
+<para>Emacs can be installed on FreeBSD using <ulink
+URL="http://www.freebsd.org/ports/editors">the Emacs
+port</ulink>.</para>
+
+<para>Once it's installed, start it up and do <userinput>C-h
+t</userinput> to read an Emacs tutorial&mdash;that means hold down
+the <keycap>control</keycap> key, press <keycap>h</keycap>, let go of
+the <keycap>control</keycap> key, and then press <keycap>t</keycap>.
+(Alternatively, you can you use the mouse to select <guimenuitem>Emacs
+Tutorial</guimenuitem> from the <guimenu>Help</guimenu> menu).</para>
+
+<para>Although Emacs does have menus, it's well worth learning the
+key bindings, as it's much quicker when you're editing something to
+press a couple of keys than to try and find the mouse and then click
+on the right place. And, when you're talking to seasoned Emacs users,
+you'll find they often casually throw around expressions like
+<quote><literal>M-x replace-s RET foo RET bar RET</literal></quote>
+so it's useful to know what they mean. And in any case, Emacs has far
+too many useful functions for them to all fit on the menu
+bars.</para>
+
+<para>Fortunately, it's quite easy to pick up the key-bindings, as
+they're displayed next to the menu item. My advice is to use the
+menu item for, say, opening a file until you understand how it works
+and feel confident with it, then try doing C-x C-f. When you're happy
+with that, move on to another menu command.</para>
+
+<para>If you can't remember what a particular combination of keys
+does, select <guimenuitem>Describe Key</guimenuitem> from the
+<guimenu>Help</guimenu> menu and type it in&mdash;Emacs will tell you
+what it does. You can also use the <guimenuitem>Command
+Apropos</guimenuitem> menu item to find out all the commands which
+contain a particular word in them, with the key binding next to
+it.</para>
+
+<para>By the way, the expression above means hold down the
+<keysym>Meta</keysym> key, press <keysym>x</keysym>, release the
+<keysym>Meta</keysym> key, type <userinput>replace-s</userinput>
+(short for <literal>replace-string</literal>&mdash;another feature of
+Emacs is that you can abbreviate commands), press the
+<keysym>return</keysym> key, type <userinput>foo</userinput> (the
+string you want replaced), press the <keysym>return</keysym> key,
+type bar (the string you want to replace <literal>foo</literal> with)
+and press <keysym>return</keysym> again. Emacs will then do the
+search-and-replace operation you've just requested.</para>
+
+<para>If you're wondering what on earth the <keysym>Meta</keysym> key
+is, it's a special key that many Unix workstations have.
+Unfortunately, PC's don't have one, so it's usually the
+<keycap>alt</keycap> key (or if you're unlucky, the <keysym>escape</keysym>
+key).</para>
+
+<para>Oh, and to get out of Emacs, do <command>C-c C-x</command>
+(that means hold down the <keysym>control</keysym> key, press
+<keysym>c</keysym>, press <keysym>x</keysym> and release the
+<keysym>control</keysym> key). If you have any unsaved files open,
+Emacs will ask you if you want to save them. (Ignore the bit in the
+documentation where it says <command>C-z</command> is the usual way
+to leave Emacs&mdash;that leaves Emacs hanging around in the
+background, and is only really useful if you're on a system which
+doesn't have virtual terminals).</para>
+
+</sect1>
+
+<sect1>
+<title>Configuring Emacs</title>
+
+<para>Emacs does many wonderful things; some of them are built in,
+some of them need to be configured.</para>
+
+<para>Instead of using a proprietary macro language for
+configuration, Emacs uses a version of Lisp specially adapted for
+editors, known as Emacs Lisp. This can be quite useful if you want to
+go on and learn something like Common Lisp, as it's considerably
+smaller than Common Lisp (although still quite big!).</para>
+
+<para>The best way to learn Emacs Lisp is to download the <ulink
+URL="ftp://prep.ai.mit.edu:pub/gnu/elisp-manual-19-2.4.tar.gz">Emacs
+Tutorial</ulink></para>
+
+<para>However, there's no need to actually know any Lisp to get
+started with configuring Emacs, as I've included a sample
+<filename>.emacs</filename> file, which should be enough to get you
+started. Just copy it into your home directory and restart Emacs if
+it's already running; it will read the commands from the file and
+(hopefully) give you a useful basic setup.</para>
+
+</sect1>
+
+<sect1>
+<title>A sample <filename>.emacs</filename> file</title>
+
+<para>Unfortunately, there's far too much here to explain it in detail;
+however there are one or two points worth mentioning.</para>
+  
+<para>
+<itemizedlist>
+
+<listitem><para>Everything beginning with a <literal>;</> is a
+comment and is ignored by Emacs.</para></listitem>
+
+<listitem><para>In the first line, the
+<literal>-*-&nbsp;Emacs-Lisp&nbsp;-*-</literal> is so that we can
+edit the <filename>.emacs</filename> file itself within Emacs and get
+all the fancy features for editing Emacs Lisp. Emacs usually tries to
+guess this based on the filename, and may not get it right for
+<filename>.emacs</filename>. </para></listitem>
+
+<listitem><para>The <keysym>tab</keysym> key is bound to an
+indentation function in some modes, so when you press the tab key, it
+will indent the current line of code. If you want to put a
+<token>tab</token> character in whatever you're writing, hold the
+<keysym>control</keysym> key down while you're pressing the
+<keysym>tab</keysym> key.</para></listitem>
+
+<listitem><para>This file supports syntax highlighting for C, C++,
+Perl, Lisp and Scheme, by guessing the language from the
+filename.</para></listitem>
+
+<listitem><para>Emacs already has a pre-defined function called
+<function>next-error</function>. In a compilation output window, this
+allows you to move from one compilation error to the next by doing
+<command>M-n</command>; we define a complementary function,
+<function>previous-error</function>, that allows you to go to a
+previous error by doing <command>M-p</command>. The nicest feature of
+all is that <command>C-c C-c</command> will open up the source file
+in which the error occurred and jump to the appropriate
+line.</para></listitem>
+
+<listitem><para> We enable Emacs's ability to act as a server, so
+that if you're doing something outside Emacs and you want to edit a
+file, you can just type in 
+<screen>$ <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
+and then you can edit the file in your Emacs!<footnote><para>Many
+Emacs users set their <systemitem
+class=environvar>EDITOR</systemitem> environment to
+<literal>emacsclient</literal> so this happens every time they need
+to edit a file.</para></footnote></para></listitem>
+
+</itemizedlist>
+</para>
+  
+<example>
+<title>A sample <filename>.emacs</filename> file</title>
+<screen>;; -*-Emacs-Lisp-*-
+
+;; This file is designed to be re-evaled; use the variable first-time
+;; to avoid any problems with this.
+(defvar first-time t 
+  "Flag signifying this is the first time that .emacs has been evaled")
+
+;; Meta
+(global-set-key "\M- " 'set-mark-command)
+(global-set-key "\M-\C-h" 'backward-kill-word)
+(global-set-key "\M-\C-r" 'query-replace)
+(global-set-key "\M-r" 'replace-string)
+(global-set-key "\M-g" 'goto-line)
+(global-set-key "\M-h" 'help-command)
+
+;; Function keys
+(global-set-key [f1] 'manual-entry)
+(global-set-key [f2] 'info)
+(global-set-key [f3] 'repeat-complex-command)
+(global-set-key [f4] 'advertised-undo)
+(global-set-key [f5] 'eval-current-buffer)
+(global-set-key [f6] 'buffer-menu)
+(global-set-key [f7] 'other-window)
+(global-set-key [f8] 'find-file)
+(global-set-key [f9] 'save-buffer)
+(global-set-key [f10] 'next-error)
+(global-set-key [f11] 'compile)
+(global-set-key [f12] 'grep)
+(global-set-key [C-f1] 'compile)
+(global-set-key [C-f2] 'grep)
+(global-set-key [C-f3] 'next-error)
+(global-set-key [C-f4] 'previous-error)
+(global-set-key [C-f5] 'display-faces)
+(global-set-key [C-f8] 'dired)
+(global-set-key [C-f10] 'kill-compilation)
+
+;; Keypad bindings
+(global-set-key [up] "\C-p")
+(global-set-key [down] "\C-n")
+(global-set-key [left] "\C-b")
+(global-set-key [right] "\C-f")
+(global-set-key [home] "\C-a")
+(global-set-key [end] "\C-e")
+(global-set-key [prior] "\M-v")
+(global-set-key [next] "\C-v")
+(global-set-key [C-up] "\M-\C-b")
+(global-set-key [C-down] "\M-\C-f")
+(global-set-key [C-left] "\M-b")
+(global-set-key [C-right] "\M-f")
+(global-set-key [C-home] "\M-&lt;")
+(global-set-key [C-end] "\M-&gt;")
+(global-set-key [C-prior] "\M-&lt;")
+(global-set-key [C-next] "\M-&gt;")
+
+;; Mouse
+(global-set-key [mouse-3] 'imenu)
+
+;; Misc
+(global-set-key [C-tab] "\C-q\t")	; Control tab quotes a tab.
+(setq backup-by-copying-when-mismatch t)
+
+;; Treat 'y' or &lt;CR&gt; as yes, 'n' as no.
+(fset 'yes-or-no-p 'y-or-n-p)
+    (define-key query-replace-map [return] 'act)
+    (define-key query-replace-map [?\C-m] 'act)
+
+;; Load packages
+(require 'desktop)
+(require 'tar-mode)
+
+;; Pretty diff mode
+(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files-remote "ediff"
+  "Intelligent Emacs interface to diff") </screen>
+
+<screen>(if first-time
+    (setq auto-mode-alist
+	  (append '(("\\.cpp$" . c++-mode)
+		    ("\\.hpp$" . c++-mode)
+                    ("\\.lsp$" . lisp-mode)
+		    ("\\.scm$" . scheme-mode)
+		    ("\\.pl$" . perl-mode)
+		    ) auto-mode-alist)))
+
+;; Auto font lock mode
+(defvar font-lock-auto-mode-list 
+  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
+  "List of modes to always start in font-lock-mode")
+
+(defvar font-lock-mode-keyword-alist
+  '((c++-c-mode . c-font-lock-keywords)
+    (perl-mode . perl-font-lock-keywords))
+  "Associations between modes and keywords")
+
+(defun font-lock-auto-mode-select ()
+  "Automatically select font-lock-mode if the current major mode is
+in font-lock-auto-mode-list"
+  (if (memq major-mode font-lock-auto-mode-list) 
+      (progn
+	(font-lock-mode t))
+    )
+  )
+
+(global-set-key [M-f1] 'font-lock-fontify-buffer)
+
+;; New dabbrev stuff
+;(require 'new-dabbrev)
+(setq dabbrev-always-check-other-buffers t)
+(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+(add-hook 'emacs-lisp-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
+	     (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'c-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
+	     (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'text-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) t)
+	     (set (make-local-variable 'dabbrev-case-replace) t)))
+
+;; C++ and C mode...
+(defun my-c++-mode-hook ()
+  (setq tab-width 4)
+  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key c++-mode-map "\C-ce" 'c-comment-edit)
+  (setq c++-auto-hungry-initial-state 'none)
+  (setq c++-delete-function 'backward-delete-char)
+  (setq c++-tab-always-indent t)
+  (setq c-indent-level 4)
+  (setq c-continued-statement-offset 4)
+  (setq c++-empty-arglist-indent 4))
+
+(defun my-c-mode-hook ()
+  (setq tab-width 4)
+  (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key c-mode-map "\C-ce" 'c-comment-edit)
+  (setq c-auto-hungry-initial-state 'none)
+  (setq c-delete-function 'backward-delete-char)
+  (setq c-tab-always-indent t)
+;; BSD-ish indentation style
+  (setq c-indent-level 4)
+  (setq c-continued-statement-offset 4)
+  (setq c-brace-offset -4)
+  (setq c-argdecl-indent 0)
+  (setq c-label-offset -4))
+
+;; Perl mode
+(defun my-perl-mode-hook ()
+  (setq tab-width 4)
+  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (setq perl-indent-level 4)
+  (setq perl-continued-statement-offset 4))
+
+;; Scheme mode...
+(defun my-scheme-mode-hook ()
+  (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
+
+;; Emacs-Lisp mode...
+(defun my-lisp-mode-hook ()
+  (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
+  (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
+
+;; Add all of the hooks...
+(add-hook 'c++-mode-hook 'my-c++-mode-hook)
+(add-hook 'c-mode-hook 'my-c-mode-hook)
+(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
+(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'perl-mode-hook 'my-perl-mode-hook)
+
+;; Complement to next-error
+(defun previous-error (n)
+  "Visit previous compilation error message and corresponding source code."
+  (interactive "p")
+  (next-error (- n)))</screen>
+
+<screen>;; Misc...
+(transient-mark-mode 1)
+(setq mark-even-if-inactive t)
+(setq visible-bell nil)
+(setq next-line-add-newlines nil)
+(setq compile-command "make")
+(setq suggest-key-bindings nil)
+(put 'eval-expression 'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+(put 'set-goal-column 'disabled nil)
+
+;; Elisp archive searching
+(autoload 'format-lisp-code-directory "lispdir" nil t)
+(autoload 'lisp-dir-apropos "lispdir" nil t)
+(autoload 'lisp-dir-retrieve "lispdir" nil t)
+(autoload 'lisp-dir-verify "lispdir" nil t)
+
+;; Font lock mode
+(defun my-make-face (face colour &amp;optional bold)
+  "Create a face from a colour and optionally make it bold"
+  (make-face face)
+  (copy-face 'default face)
+  (set-face-foreground face colour)
+  (if bold (make-face-bold face))
+  )
+
+(if (eq window-system 'x)
+    (progn
+      (my-make-face 'blue "blue")
+      (my-make-face 'red "red")
+      (my-make-face 'green "dark green")
+      (setq font-lock-comment-face 'blue)
+      (setq font-lock-string-face 'bold)
+      (setq font-lock-type-face 'bold)
+      (setq font-lock-keyword-face 'bold)
+      (setq font-lock-function-name-face 'red)
+      (setq font-lock-doc-string-face 'green)
+      (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
+
+      (setq baud-rate 1000000)
+      (global-set-key "\C-cmm" 'menu-bar-mode)
+      (global-set-key "\C-cms" 'scroll-bar-mode)
+      (global-set-key [backspace] 'backward-delete-char)
+					;      (global-set-key [delete] 'delete-char)
+      (standard-display-european t)
+      (load-library "iso-transl")))
+
+;; X11 or PC using direct screen writes
+(if window-system
+    (progn
+      ;;      (global-set-key [M-f1] 'hilit-repaint-command)
+      ;;      (global-set-key [M-f2] [?\C-u M-f1])
+      (setq hilit-mode-enable-list  
+	    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
+		  scheme-mode)
+	    hilit-auto-highlight nil
+	    hilit-auto-rehighlight 'visible
+	    hilit-inhibit-hooks nil
+	    hilit-inhibit-rebinding t)
+      (require 'hilit19)
+      (require 'paren))
+  (setq baud-rate 2400)			; For slow serial connections
+  )
+
+;; TTY type terminal
+(if (and (not window-system) 
+	 (not (equal system-type 'ms-dos)))
+    (progn
+      (if first-time
+	  (progn
+	    (keyboard-translate ?\C-h ?\C-?)
+	    (keyboard-translate ?\C-? ?\C-h)))))
+
+;; Under UNIX
+(if (not (equal system-type 'ms-dos))
+    (progn
+      (if first-time
+	  (server-start))))
+
+;; Add any face changes here
+(add-hook 'term-setup-hook 'my-term-setup-hook)
+(defun my-term-setup-hook ()
+  (if (eq window-system 'pc)
+      (progn
+;;	(set-face-background 'default "red")
+	)))
+
+;; Restore the "desktop" - do this as late as possible
+(if first-time
+    (progn
+      (desktop-load-default)
+      (desktop-read)))
+
+;; Indicate that this file has been read at least once
+(setq first-time nil)
+
+;; No need to debug anything now
+(setq debug-on-error nil)
+
+;; All done
+(message "All done, %s%s" (user-login-name) ".")
+</screen>
+</example>
+  
+</sect1>
+
+<sect1>
+<title>Extending the Range of Languages Emacs Understands</title>
+
+<para>Now, this is all very well if you only want to program in the
+languages already catered for in the <filename>.emacs</filename> file
+(C, C++, Perl, Lisp and Scheme), but what happens if a new language
+called <quote>whizbang</quote> comes out, full of exciting
+features?</para>
+
+<para>The first thing to do is find out if whizbang
+comes with any files that tell Emacs about the language. These
+usually end in <filename>.el</filename>, short for <quote>Emacs
+Lisp</quote>. For example, if whizbang is a FreeBSD
+port, we can locate these files by doing
+<screen>$ <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
+and install them by copying them into the Emacs site Lisp directory. On
+FreeBSD 2.1.0-RELEASE, this is
+<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
+
+<para>So for example, if the output from the find command was
+<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
+we would do
+<screen>$ <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
+</para>
+  
+<para>Next, we need to decide what extension whizbang source files
+have. Let's say for the sake of argument that they all end in
+<filename>.wiz</filename>. We need to add an entry to our
+<filename>.emacs</filename> file to make sure Emacs will be able to
+use the information in <filename>whizbang.el</filename>.</para>
+
+<para>Find the <symbol>auto-mode-alist entry</symbol> in
+<filename>.emacs</filename> and add a line for whizbang, such
+as:
+<programlisting><lineannotation>&hellip;</>
+("\\.lsp$" . lisp-mode)
+("\\.wiz$" . whizbang-mode)
+("\\.scm$" . scheme-mode)
+<lineannotation>&hellip;</></programlisting>  
+This means that Emacs will automatically go into
+<function>whizbang-mode</function> when you edit a file ending in
+<filename>.wiz</filename>.</para>
+
+<para>Just below this, you'll find the
+<symbol>font-lock-auto-mode-list</symbol> entry. Add
+<function>whizbang-mode</function> to it like so:
+<programlisting>;; Auto font lock mode
+(defvar font-lock-auto-mode-list 
+  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
+  "List of modes to always start in font-lock-mode")</programlisting>
+This means that Emacs will always enable
+<function>font-lock-mode</function> (ie syntax highlighting) when
+editing a <filename>.wiz</filename> file.</para>
+
+<para>And that's all that's needed. If there's anything else you want
+done automatically when you open up a <filename>.wiz</filename> file,
+you can add a <function>whizbang-mode hook</function> (see
+<function>my-scheme-mode-hook</function> for a simple example that
+adds <function>auto-indent</function>).</para>
+  
+</sect1>
+</chapter>
+
+<chapter>
+<title>Further Reading</title>
+
+<itemizedlist>
+<listitem><para>Brian Harvey and Matthew Wright
+<emphasis>Simply Scheme</emphasis>
+MIT 1994.<!-- <br> -->
+ISBN 0-262-08226-8</para></listitem>
+
+<listitem><para>Randall Schwartz
+<emphasis>Learning Perl</emphasis>
+O'Reilly 1993<!-- <br> -->
+ISBN 1-56592-042-2</para></listitem>
+
+<listitem><para>Patrick Henry Winston and Berthold Klaus Paul Horn
+<emphasis>Lisp (3rd Edition)</emphasis>
+Addison-Wesley 1989<!-- <br> -->
+ISBN 0-201-08319-1</para></listitem>
+
+<listitem><para>Brian W. Kernighan and Rob Pike
+<emphasis>The Unix Programming Environment</emphasis>
+Prentice-Hall 1984<!-- <br> -->
+ISBN 0-13-937681-X</para></listitem>
+
+<listitem><para>Brian W. Kernighan and Dennis M. Ritchie
+<emphasis>The C Programming Language (2nd Edition)</emphasis>
+Prentice-Hall 1988<!-- <br> -->
+ISBN 0-13-110362-8</para></listitem>
+
+<listitem><para>Bjarne Stroustrup
+<emphasis>The C++ Programming Language</emphasis>
+Addison-Wesley 1991<!-- <br> -->
+ISBN 0-201-53992-6</para></listitem>
+
+<listitem><para>W. Richard Stevens
+<emphasis>Advanced Programming in the Unix Environment</emphasis>
+Addison-Wesley 1992<!-- <br> -->
+ISBN 0-201-56317-7</para></listitem>
+
+<listitem><para>W. Richard Stevens
+<emphasis>Unix Network Programming</emphasis>
+Prentice-Hall 1990<!-- <br> -->
+ISBN 0-13-949876-1</para></listitem>
+
+</itemizedlist>
+
+</chapter>
+</book>
diff --git a/en/tutorials/devel/devel.sgml b/en/tutorials/devel/devel.sgml
deleted file mode 100644
index 0fde023afd..0000000000
--- a/en/tutorials/devel/devel.sgml
+++ /dev/null
@@ -1,1739 +0,0 @@
-<!DOCTYPE linuxdoc PUBLIC "-//FreeBSD//DTD linuxdoc//EN">
-<!-- $Id: devel.sgml,v 1.2 1996-10-06 20:17:10 jfieber Exp $ -->
-
-<!--
-  ++++++++++++++++++++++++++++++++++++++++++++++++++
-  ++ file: /home/james/docs/devel.sgml
-  ++
-  ++ Copyright James Raynard, Thursday 30th May 1996
-  ++
-  ++ Sgml doc for programming under FreeBSD.
-  -->
-
-<article>
-
-<title>A User's Guide to FreeBSD Programming Tools
-<author>James Raynard, <tt /jraynard@freebsd.org/
-<date>30th May 1996
-
-<abstract>
-
-This document is an introduction to using some of the programming
-tools supplied with FreeBSD, although much of it will be applicable to
-many other versions of Unix. It does <it /not/ attempt to describe
-coding in any detail. Most of the document assumes little or no
-previous programming knowledge, although it is hoped that most
-programmers will find something of value in it
-
-</abstract>
-
-<sect><heading>Introduction</heading>
-<p>
-
-FreeBSD offers an excellent development environment. Compilers for C,
-C++, and Fortran and an assembler come with the basic system, not to
-mention a Perl interpreter and classic Unix tools such as sed and awk.
-If that isn't enough, there are many more compilers and interpreters
-in the Ports collection. FreeBSD is very compatible with standards
-such as POSIX and ANSI C, as well with its own BSD heritage, so it is
-possible to write applications that will compile and run with little
-or no modification on a wide range of platforms.
-<p>
-However, all this power can be rather overwhelming at first if you've
-never written programs on a Unix platform before. This document aims
-to help you get up and running, without getting too deeply into more
-advanced topics. The intention is that this document should give you
-enough of the basics to be able to make some sense of the
-documentation.
-<p>
-Most of the document requires little or no knowledge of programming,
-although it does assume a basic competence with using Unix and a
-willingness to learn!
-
-<sect><heading>Introduction to Programming</heading>
-<p>
-A program is a set of instructions that tell the computer to do
-various things; sometimes the instruction it has to perform depends on
-what happened when it performed a previous instruction. This section
-gives an overview of the two main ways in which you can give these
-instructions, or ``commands'' as they're usually called. One way uses
-an interpreter, the other a compiler. As human languages are too
-difficult for a computer to understand in an unambiguous way, commands
-are usually written in one or other languages specially designed for
-the purpose.
-
-<sect1><heading>Interpreters</heading>
-<p>
-With an interpreter, the language comes as an environment, where you
-type in commands at a prompt and the environment executes them for
-you. For more complicated programs, you can type the commands into a
-file and get the interpreter to load the file and execute the commands
-in it. If anything goes wrong, many interpreters will drop you into a
-debugger to help you track down the problem.
-<P>
-The advantage of this is that you can see the results of your commands
-immediately, and mistakes can be corrected readily. The biggest
-disadvantage comes when you want to share your programs with
-someone. They must have the same interpreter (or you must have some
-way of giving it to them) and they need to understand how to use
-it. Also users may not appreciate being thrown into a debugger if they
-press the wrong key! From a performance point of view, interpreters
-can use up a lot of memory, and generally do not generate code as
-efficiently as compilers.
-<p>
-In my opinion, interpreted languages are the best way to start if you
-haven't done any programming before. This kind of environment is
-typically found with languages like Lisp, Smalltalk, Perl and
-Basic. It could also be argued that the Unix shell (sh, csh) is itself
-an interpreter, and many people do in fact write shell `scripts' to
-help with various ``housekeeping'' tasks on their machine. Indeed,
-part of the original Unix philosophy was to provide lots of small
-utility programs that could be linked together in shell scripts to
-perform useful tasks.
-<p>
-<sect1><heading>Interpreters available with FreeBSD</heading>
-<p>
-Here is a list of interpreters that are available as <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/" name="FreeBSD
-packages">, with a brief discussion of some of the more popular
-interpreted languages. 
-<p>
-To get one of these packages, all you need to do is to click on the
-hotlink for the package, then run
-
-<tscreen><verb>
-       pkg_add <package name>
-</verb></tscreen>
-
-as root. Obviously, you'll need to have a fully-functional FreeBSD
-2.1.0 system for the package to work!
-
-<descrip>
-<tag>Basic</tag>
-
-Short for Beginner's All-purpose Symbolic Instruction Code. Developed
-in the 1950s for teaching University students to program and provided
-with every self-respecting personal computer in the 1980s, BASIC has
-been the first programming language for many programmers. It's also
-the foundation for Visual Basic.
-
-The <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/bwbasic-2.10.tgz"
-name="Bywater Basic Interpreter"> and the <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/pbasic-2.0.tgz"
-name="Phil Cockroft's Basic Interpreter"> (formerly Rabbit Basic) are
-available as FreeBSD <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/" name="FreeBSD
-packages">
-
-<tag>Lisp</tag>
-
-A language that was developed in the late 1950s as an alternative to
-the ``number-crunching'' languages that were popular at the time.
-Instead of being based on numbers, Lisp is based on `lists'; in fact
-the name is short for "List Processing". Very popular in AI
-(Artificial Intelligence) circles.
-
-Lisp is an extremely powerful and sophisticated language, but can be
-rather large and unwieldy. 
-
-FreeBSD has <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/gcl-2.0.tgz" name="GNU
-Common Lisp"> available as a package.
-
-<tag>Perl</tag>
-
-Very popular with system administrators for writing scripts; also
-often used on World Wide Web servers for writing CGI scripts.
-
-Version 4, which is probably still the most widely-used version, comes
-with FreeBSD; the newer
-<htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/perl-5.001.tgz"
-name="Perl Version 5"> is available as a package.
-
-<tag>Scheme</tag>
-
-A dialect of Lisp that is rather more compact and cleaner than Common
-Lisp. Popular in Universities as it's simple enough to teach to
-undergraduates as a first language, while it has a high enough level
-of abstraction to be used in research work.
-
-FreeBSD has packages of the 
-<htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/elk-3.0.tgz" 
-name="Elk Scheme Interpreter">, the 
-<htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/mit-scheme-7.3.tgz"
-name="MIT Scheme Interpreter"> and the 
-<htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/scm-4e1.tgz"
-name="SCM Scheme Interpreter">.
-<!--
-<tag>TCL and Tk</tag>
-
-Programming with the X windowing system can best be described as
-rather character-forming.  As someone once said, if they designed cars
-the way X was designed, each car would have five steering wheels, all
-following completely different conventions, but you can use the
-radio-cassette player to change gears, which is a really useful
-feature when you think about it. Or perhaps not.
-<p>
-Fortunately, it doesn't have to be like that. A number of people have
-written "toolkits" for X, where all the interaction with X is hidden
-inside toolkit routines and you can just say, in effect, ``pop up a
-window and draw a line from point A to point B''. Many of these are
-`libraries' that have to be called from inside a C program, but one of
-the best known toolkits, John Ousterhout's Tk, provides a
-straightforward way to write GUI programs using a scripted
-language. And by one of those remarkable coincidences, he also happens
-to have written an embeddable language, TCL (Tool Command Language)
-which is very suitable for the purpose, although it is possible to use
-other interpreted languages such as Perl or Scheme to send commands to
-Tk.
-
-FreeBSD has a <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/tcl-7.4.2.tgz"
-name="Tool Command Language"> package.
--->
-<tag>Icon</tag>
-
-<htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/icon-9.0.tgz"
-name="The Icon Programming Language">.
-
-<tag>Logo</tag>
-
-<htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/ucblogo-3.3.tgz"
-name="Brian Harvey's LOGO Interpreter">.
-
-<tag>Python</tag>
-<htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/python-1.2"
-name="The Python Object-Oriented Programming Language">
-
-</descrip>
-
-<sect1><heading>Compilers</heading>
-<p>
-Compilers are rather different. First of all, you write your code in a
-file (or files) using an editor. You then run the compiler and see if
-it accepts your program. If it didn't compile, grit your teeth and go
-back to the editor; if it did compile and gave you a program, you can
-run it either at a shell command prompt or in a debugger to see if it
-works properly. (If you run it in the shell, you may get a core dump).
-<p>
-Obviously, this is not quite as direct as using an interpreter.
-However it allows you to do a lot of things which are very difficult
-or even impossible with an interpreter, such as writing code which
-interacts with the operating system - or even writing your own
-operating system! It's also useful if you need to write very efficient
-code, as the compiler can take its time and optimise the code, which
-wouldn't be acceptable in an interpreter. And distributing a program
-written for a compiler is usually more straightforward than one
-written for an interpreter - you can just give them a copy of the
-executable (assuming they have the same operating system as you).
-<p>
-Compiled languages include Pascal, C and C++. C and C++ are rather
-unforgiving languages, and best suited to more experienced
-programmers; Pascal, on the other hand, was designed as an educational
-language, and is quite a good language to start with. Unfortunately,
-FreeBSD doesn't have any Pascal support, except for a Pascal-to-C
-converter in the ports.
-<p>
-As the edit-compile-run-debug cycle is rather tedious when using
-separate programs, many commercial compiler makers have produced
-Integrated Development Environments (IDEs for short). FreeBSD doesn't
-have an IDE as such; however it's possible to use Emacs for this
-purpose. This is discussed under Emacs.
-
-<sect><heading>Compiling with cc</heading>
-<p>
-This section deals only with the GNU compiler for C and C++, since
-that comes with the base FreeBSD system. It can be invoked by either
-`cc' or `gcc'. The details of producing a program with an interpreter
-vary considerably between interpreters, and are usually well covered
-in the documentation and on-line help for the interpreter.
-<p>
-Once you've written your masterpiece, the next step is to convert it
-into something that will (hopefully!) run on FreeBSD. This usually
-involves several steps, each of which is done by a separate program.
-
-<enum>
-
-<item> Pre-process your source code to remove comments and do other
-tricks like expanding `macros' in C.
-
-<item> Check the syntax of your code to see if you have obeyed the
-rules of the language. If you haven't, it will complain!
-
-<item> Convert the source code into assembler - this is very close to
-machine code, but still understandable by humans. Allegedly.  (To be
-strictly accurate, cc converts the source code into its own,
-machine-independent p-code instead of assembler at this stage).
-
-<item> Convert the assembler into machine code - yep, we're talking
-bits and bytes, ones and zeros here.
-
-<item> Check that you've used things like functions and global
-variables in a consistent way (eg if you've called a non-existent
-function, it'll complain).
-
-<item> If you're trying to produce an executable from several source
-code files, work out how to fit them all together.
-
-<item> Work out how to produce something that the system's run-time
-loader will be able to load into memory and run.
-
-<item> (Finally!) Write the executable on the file system.
-</enum>
-
-The word ``compiling'' is often used to refer to just steps 1 to 4 -
-the others are referred to as ``linking''. Sometimes step 1 is
-referred to as ``pre-processing'' and steps 3-4 as ``assembling''.
-<p>
-Fortunately, almost all this detail is hidden from you, as cc is a
-front end that manages calling all these programs with the right
-arguments for you; simply typing
-
-<tscreen><verb>
-       cc foobar.c
-</verb></tscreen>
-
-will cause foobar.c to be compiled by all the steps above. If you have
-more than one file to compile, just do something like
-
-<tscreen><verb>
-       cc foo.c bar.c
-</verb></tscreen>
-
-Note that the syntax checking is just that - checking the syntax. It
-won't check for any logical mistakes you may have made, like putting
-the program into an infinite loop, or using a bubble sort when you
-meant to use a binary sort. {In case you didn't know, a
-binary sort is an efficient way of sorting things into order and a
-bubble sort isn't.}
-<p>
-There are lots and lots of options for cc, which are all in the man
-page.  Here are a few of the most important ones, with examples of how
-to use them.
-
-<descrip>
-<tag/-o/
-    The output name of the file. If you don't use this option, cc will 
-    produce an executable called `a.out' (the reasons for this are buried
-    in the mists of history).
-
-    Example:-
-<tscreen><verb>
-       cc foobar.c           executable is a.out
-       cc -o foobar foobar.c executable is foobar
-</verb></tscreen>
-
-<tag/-c/
-    Just compile the file, don't link it. Useful for toy programs where
-    you just want to check the syntax, or if you're using a Make file.
-
-    Example:-
-
-<tscreen><verb>
-       cc -c foobar.c
-</verb></tscreen>
-
-    This will produce an ``object file'' (not an executable) called
-    `foobar.o'. This can be linked together with other object files
-    into an executable.
-
-<tag/-g/
-
-    Create a debug version of the executable. This makes the compiler
-    put information into the executable about which line of which
-    source file corresponds to which function call. A debugger can use
-    this information to show the source code as you step through the
-    program, which is <it /very/ useful; the disadvantage is that all
-    this extra information makes the program much bigger. Normally,
-    you compile with -g while you're developing a program and then
-    compile a ``release version'' without -g when you're satisfied it
-    works properly.
-
-    Example:-
-
-<tscreen><verb>
-       cc -g foobar.c
-</verb></tscreen>
-
-    This will produce a debug version of the program. (Note, we didn't use
-    the -o flag to specify the executable name, so we'll get an executable
-    called `a.out'. Producing a debug version called `foobar' is left as an
-    exercise for the reader!)
-
-<tag/-O/
-    Create an optimised version of the executable. The compiler performs
-    various clever tricks to try and produce an executable that runs faster
-    than normal. You can add a number after the `O' to specify a higher
-    level of optimisation, but this often exposes bugs in the compiler's
-    optimiser. For instance, the version of cc that comes with the 2.1.0
-    release of FreeBSD is known to produce bad code with the `-O2'
-    option in some circumstances.
-
-    Optimisation is usually only turned on when compiling a release version.
-
-    Example:-
-
-<tscreen><verb>
-       cc -O -o foobar foobar.c
-</verb></tscreen>
-
-    This will produce an optimised version of `foobar'.
-<p>
-    The following three flags will force cc to check that your code
-    complies to the relevant international standard (often referred to
-    as the ``ANSI'' standard, though strictly speaking it's an ISO
-    standard).
-
-<tag/-Wall/
-    Enable all the warnings which the authors of cc believe are
-    worthwhile. Despite the name, it will not enable all the warnings
-    cc is capable of.
-
-<tag/-ansi/
-    Turn off most (but not all) of the non-standard features provided
-    by cc. Despite the name, it does not guarantee strictly that your
-    code will comply to the standard.
-
-<tag/-pedantic/
-    Turn off <it /all/ cc's non-standard features.
-<p>
-    Without these flags, cc will allow you to use some of its
-    non-standard extensions to the standard. Some of these are very
-    useful, but will not work with other compilers - in fact, one of
-    the main aims of the standard is to allow people to write code
-    that will work with any compiler on any system. (This is known as
-    ``portable code'').
-<p>
-    Generally, you should try to make your code as portable as
-    possible, as otherwise you may have to completely re-write the
-    program later to get it to work somewhere else - and who knows
-    what you may be using in a few years time?
-
-    Example:-
-<tscreen><verb>
-       cc -Wall -ansi -pedantic -o foobar foobar.c
-</verb></tscreen>
-    will produce an executable `foobar' after checking foobar.c for standard
-    compliance.
-
-<tag/-l/
-    Specify a library to be used during when linking.
-<p>
-    The most common example of this is when compiling a program that
-    uses some of the mathematical functions in C. Unlike most other
-    platforms, these are in a separate library from the standard C one
-    and you have to tell the compiler to add it.
-<p>
-    The rule is that if the library is called `libsomething.a', you
-    give cc the argument `-lsomething'. For example, the maths library
-    is `libm.a', so you give cc the argument `-lm'. A common
-    ``gotcha'' with the maths library is that it has to be the last
-    library on the command line.
-<p>
-    Example:-
-<tscreen><verb>
-       cc -o foobar foobar.c -lm
-</verb></tscreen>
-    will link the maths library functions into `foobar'.
-<p>
-    If you're compiling C++ code, you need to add `-lg++' to the
-    command line argument, to link the C++ library functions.
-    Alternatively, you can run c++ instead of cc, which does this for
-    you.
-<p>
-    Example:-
-<tscreen><verb>
-       cc -o foobar foobar.cc -lg++
-       c++ -o foobar foobar.cc
-</verb></tscreen>
-    will both produce an executable `foobar' from the C++ source file
-    `foobar.cc'. Note that, on Unix systems, C++ source files
-    traditionally end in `.C', `.cxx' or `.cc', rather than the
-    DOS-style `.cpp' (which was already used for something else). gcc
-    used to rely on this to work out what kind of compiler to use on
-    the source file; however, this restriction no longer applies, so
-    you may now call your C++ files `.cpp' with impunity!
-    {c++ can also be invoked as g++ on FreeBSD.}
-</descrip>
-
-<sect1><heading>Common cc Queries and Problems</heading>
-<p>
-Q. I'm trying to write a program which uses the sin() function and I get
-   an error like this. What does it mean?
-
-<tscreen><verb>
-       /var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment
-</verb></tscreen>
-
-A. When using mathematical functions like sin(), you have to tell cc to link
-   in the maths library, like so:-
-<tscreen><verb>
-       cc -o foobar foobar.c -lm
-</verb></tscreen>
-Q. All right, I wrote this simple program to practice using -lm. All
-it does is raise 2.1 to the power of 6.
-<code>
-#include <stdio.h>
-
-int main() {
-	float f;
-
-	f = pow(2.1, 6);
-	printf("2.1 ^ 6 = %f\n", f);
-	return 0;
-}
-</code>
-and I compiled it as
-
-<tscreen><verb>
-gcc temp.c -lm
-</verb></tscreen>
-
-like you said I should, but I get this when I run it:-
-<tscreen><verb>
-$ ./a.out
-2.1 ^ 6 = 1023.000000
-</verb></tscreen>
-
-This is <it /not/ the right answer! What the %$&#'s going on?
-<p>
-A. When the compiler sees you call a function, it checks if it's
-already seen a prototype for it. If it hasn't, it assumes the function
-returns an int, which is definitely not what you want here.
-<p>
-Q. So how do I fix this?
-<p>
-A. The prototypes for the mathematical functions are in math.h. If you
-include this file, the compiler will be able to find the prototype and
-it'll stop doing strange things to your calculation!
-
-<code>
-#include <math.h>
-#include <stdio.h>
-
-int main() {
-...
-</code>
-<p>
-<tscreen><verb>
-$ ./a.out
-2.1 ^ 6 = 85.766121
-</verb></tscreen>
-
-Morale: if you're using any of the mathematical functions, always
-include math.h and remember to link in the maths library.
-
-Q. I've compiled a file called `foobar.c' and I can't find an executable
-   called `foobar'. Where's it gone?
-<p>
-A. cc will call the executable `a.out' unless you tell it differently. Use
-   the -o option, eg
-<tscreen><verb>
-       cc -o foobar foobar.c
-</verb></tscreen>
-Q. OK, I've got an executable called `foobar', I can see it when I do
-   `ls', but when I type in 'foobar' at the command prompt it tells me
-   there's no such file. Why can't it find it?
-<p>
-A. Unlike DOS, Unix won't look in the current directory when it's
-   trying to find out which executable you want it to run, unless you
-   tell it to. Either type `./foobar', which means ``run the file
-   called `foobar' in the current directory'', or change your PATH
-   environment variable so that it looks something like
-<tscreen><verb>
-       bin:/usr/bin:/usr/local/bin:.
-</verb></tscreen>
-   (The dot at the end means ``look in the current directory if it's not in
-    any of the others'')
-<p>
-Q. I called my executable `test', but nothing happens when I run
-   it. What's going on?
-<p>
-A. Most Unix systems have a program called `test' in /usr/bin and the
-   shell's picking that one up before it gets to checking the current
-   directory. Either type 
-
-<tscreen><verb>
-       ./test
-</verb></tscreen>
-
- or choose a better name for your program!
-<p>
-Q. I compiled my program and it seemed to run all right at first, then
-   there was an error and it said something about ``core
-   dumped''. What does that mean?
-<p>
-A. The name ``core dump'' dates back to the very early days of Unix,
-   when the machines used core memory for storing data. Basically, if
-   the program failed under certain conditions, the system would write
-   the contents of core memory to disk in a file called ``core'',
-   which the programmer could then pore over to find out what went
-   wrong.
-<p>
-Q. Fascinating stuff, but what I am supposed to do now?
-<p>
-A. Use gdb to analyse the core (see Debugging).
-<p>
-Q. When my program dumped core, it said something about a segmentation
-   fault. What's that?
-<p>
-A. This basically means that your program tried to perform some sort
-   of illegal operation on memory; Unix is designed to protect the
-   operating system and other programs from ``rogue'' programs.
-<p>
-   Common causes for this are:-
-<itemize>
-	<item> Trying to write to a NULL pointer, eg
-<code>
-		char *foo = NULL;
-		strcpy(foo, "bang!");
-</code>
-	<item> Using a pointer that hasn't been initialised, eg
-<code>
-		char *foo;
-		strcpy(foo, "bang!");
-</code>
-	   The pointer will have some random value that, with luck,
-	   will point into an area of memory that isn't available to
-	   your program and the kernel will kill your program before
-	   it can do any damage. If you're unlucky, it'll point
-	   somewhere inside your own program and corrupt one of your
-	   data structures, causing the program to fail mysteriously.
-<p>
-	<item> Trying to access past the end of an array, eg
-<code>
-		int bar[20];
-		bar[27] = 6;
-</code>
-	<item> Trying to store something in read-only memory, eg
-<code>
-		char *foo = "My string";
-		strcpy(foo, "bang!");
-</code>
-	   (Unix compilers often put string literals like ``My string'' into
-	   read-only areas of memory).
-
-	<item> Doing naughty things with malloc() and free(), eg
-<code>
-		char bar[80];
-		free(bar);
-</code>
-	   or
-<code>
-		char *foo = malloc(27);
-		free(foo);
-		free(foo);
-</code>
-</itemize>
-	(Note making one of these mistakes will not always lead to an
-	error, but they are always bad practice. Some systems and
-	compilers are more tolerant than others, which is why programs
-	that ran well on one system can crash when you try them on an
-	another)
-<p>
-Q. Sometimes when I get a core dump it says ``bus error''. It says in
-   my Unix book that this means a hardware problem, but the computer
-   still seems to be working. Is this true?
-<p>
-A. No, fortunately not (unless of course you really do have a hardware
-   problem...). This is usually another way of saying that you
-   accessed memory in a way you shouldn't have.
-<p>
-Q. This dumping core business sounds as though it could be quite
-   useful, if I can make it happen when I want to. Can I do this, or
-   do I have to wait until there's an error?
-<p>
-A. Yes, just go to another console or xterm, do 
-
-<tscreen><verb>
-       ps
-</verb></tscreen>
-
-to find out the process ID of your program, and do
-
-<tscreen><verb>
-       kill -ABRT <pid>
-</verb></tscreen>
-
-   This is useful if your program has got stuck in an infinite loop,
-   for instance. (If your program traps SIGABRT, there are several
-   other signals which have a similar effect).
-
-<sect><heading>Make</heading>
-<p>
-<sect1><heading>What is make?</heading>
-<p>
-When you're working on a simple program with only one or two source
-files, typing in 
-
-<tscreen><verb>
-       cc file1.c file2.c
-</verb></tscreen>
-
-is not too bad, but it quickly becomes very tedious when there are
-several files - and it can take a while to compile, too.
-<p>
-One way to get around this is to use object files and only recompile
-the source file if the source code has changed. So we could have
-something like:-
-
-<tscreen><verb>
-       cc file1.o file2.o ... file37.c ...
-</verb></tscreen>
-
-if we'd changed file37.c, but not any of the others, since the last
-time we compiled.
-<p>
-This may speed up the compilation quite a bit, but doesn't solve the
-typing problem.
-<p>
-Or we could write a shell script to solve the typing problem, but it
-would have to re-compile everything, making it very inefficient on a
-large project.
-<p>
-What happens if we have hundreds of source files lying about? What if
-we're working in a team with other people who forget to tell us when
-they've changed one of their source files that we use?
-<p>
-Perhaps we could put the two solutions together and write something
-like a shell script that would contain some kind of magic rule saying
-when a source file needs compiling. Now all we need now is a program
-that can understand these rules, as it's a bit too complicated for the
-shell.
-<p>
-This program is called <tt /make/. It reads in a file, called a make
-file, that tells it how different files depend on each other, and
-works out which files need to be re-compiled and which ones don't. For
-example, a rule could say something like ``if fromboz.o is older than
-fromboz.c, that means someone must have changed fromboz.c, so it needs
-to be re-compiled.'' The make file also has rules telling make <it
-/how/ to re-compile the source file, making it a much more powerful
-tool.
-<p>
-Make files are typically kept in the same directory as the source they
-apply to, and can be called `makefile', `Makefile' or `MAKEFILE'. Most
-programmers use the name 'Makefile', as this puts it near the top of a
-directory listing, where it can easily be seen (they don't use the
-`MAKEFILE' form as block capitals are often used for documentation
-files like `README').
-
-<sect1><heading>Example of using make</heading>
-<p>
-Here's a very simple make file:-
-<tscreen><verb>
-foo: foo.c
-	cc -o foo foo.c
-</verb></tscreen>
-It consists of two lines, a dependency line and a creation line.
-<p>
-The dependency line here consists of the name of the program (known as
-``the target''), followed by a colon, then a gap, then the name of the
-source file. When make reads this line, it looks to see if `foo'
-exists; if it exists, it compares the time 'foo' was last modified to
-the time `foo.c' was last modified. If 'foo' does not exist, or is
-older than `foo.c', it then looks at the creation line to find out
-what to do. In other words, this is the rule for working out when
-foo.c needs to be re-compiled.
-<p>
-The creation line starts with a tab (press the tab key) and then the
-command you would type to create `foo' if you were doing it at a
-command prompt. If `foo' is out of date, or does not exist, `make'
-then executes this command to create it. In other words, this is the
-rule which tells make how to re-compile foo.c.
-<p>
-So, when you type `make', it will make sure that `foo' is up to date
-with respect to your latest changes to `foo.c'. This principle can be
-extended to Makefiles with hundreds of targets - in fact, on FreeBSD,
-it is possible to compile the entire operating system just by typing
-`make world' in the appropriate directory!
-<p>
-Another useful property of make files is that the targets don't have
-to be programs. For instance, we could have a make file that looks
-like this:-
-
-<tscreen><verb>
-foo: foo.c
-	cc -o foo foo.c
-
-install:
-	cp foo /home/me
-</verb></tscreen>
-
-We can tell make which target we want to make by typing 
-
-<tscreen><verb>
-       make <target>
-</verb></tscreen>
-
-make will then only look at that target and ignore any
-others. For example, if we type `make foo' with the make file above,
-make will ignore the 'install' target.
-<p>
-If we just type `make' on its own, make will always look at the first
-target and then stop without looking at any others. So if we typed
-`make' here, it will just go to the `foo' target, re-compile `foo' if
-necessary, and then stop without going on to the `install' target.
-<p>
-Notice that the `install' target doesn't actually depend on anything!
-This means that the command on the following line is always executed
-when we try to make that target by typing `make install'. In this
-case, it will copy `foo' into the user's home directory. This is often
-used by application make files, so that the application can be
-installed in the correct directory when it has been correctly
-compiled.
-<p>
-This is a slightly confusing subject to try and explain. If you don't
-quite understand how make works, the best thing to do is to write a
-simple program like ``hello world'' and a make file like the one above
-and experiment. Then progress to using more than one source file, or
-having the source file include a header file. (The `touch' command is
-very useful here - it changes the date on a file without you having to
-edit it).
-
-<sect1><heading>FreeBSD Make Files</heading>
-<p>
-Make files can be rather complicated to write. Fortunately, BSD-based
-systems like FreeBSD come with some very powerful ones as part of the
-system.
-<p>
-One very good example of this is the FreeBSD ports system. Here's the
-essential part of a typical ports Makefile:-
-
-<code>
-MASTER_SITES=   ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
-DISTFILES=      scheme-microcode+dist-7.3-freebsd.tgz
-
-.include <bsd.port.mk>
-</code>
-
-Now, if we go to the directory for this port and type make, the
-following happens:-
-
-<enum>
-
-<item> A check is made to see if the source code for this port is
-already on the system.
-
-<item> If it isn't, an FTP connection to the URL in ``MASTER_SITES''
-is set up to download the source.
-
-<item> The checksum for the source is calculated and compared it with
-one for a known, good, copy of the source. This is to make sure that
-the source was not corrupted while in transit.
-
-<item> Any changes required to make the source work on FreeBSD are
-applied - this is known as ``patching''.
-
-<item> Any special configuration needed for the source is done. (Many
-Unix program distributions try to work out which version of Unix they
-are being compiled on and which optional Unix features are present -
-this is where they are given the information in the FreeBSD ports
-scenario).
-
-<item> The source code for the program is compiled. In effect, we
-change to the directory where the source was unpacked and do 'make' -
-the program's own make file has the necessary information to build the
-program.
-
-<item> We now have a compiled version of the program. If we wish, we
-can test it now; when we feel confident about the program, we can type
-'make install'. This will cause the program and any supporting files
-it needs to be copied into the correct location; an entry is also made
-into a ``package database'', so that the port can easily be
-uninstalled later if we change our mind about it.
-
-</enum>
-
-Now I think you'll agree that's rather impressive for a four line
-script!
-<p>
-The secret lies in the last line, which tells make to look in the
-system make file called `bsd.port.mk'. It's easy to overlook this
-line, but this is where all the clever stuff comes from - someone has
-written a make file that tells make to do all the things above (plus a
-couple of other things I didn't mention, not to mention handling any
-errors that may occur) and anyone can get access to that just by
-putting a single line in their own make file!
-<p>
-If you want to have a look at these system make files, they're in
-/usr/share/mk, but it's probably best to wait until you've had a bit
-of practice with make files, as they are very complicated (and if you
-do look at them, make sure you have a flask of strong coffee handy!)
-
-<sect1><heading>More advanced uses of make</heading>
-<p>
-Make is a very powerful tool, and can do much more than the simple
-example above shows. Unfortunately, there are several different
-versions of make, and they all differ considerably. The best way to
-learn what they can do is probably to read the documentation -
-hopefully this introduction will have given you a base from which you
-can do this.
-<p>
-The version of make that comes with FreeBSD is the Berkeley make;
-there is a tutorial for it in /usr/share/doc/psd/12.make. To view it,
-do 
-
-<tscreen><verb>
-       zmore paper.ascii.gz
-</verb></tscreen>
-
-in that directory.
-<p>
-Many applications in the ports use GNU make, which has a very good set
-of `info' pages. If you have installed any of these ports, GNU make
-will automatically have been installed as `gmake'. It's also available
-as a port and package in it's own right.
-<p>
-To view the info pages for GNU make, you will have to edit the `dir'
-file in the /usr/local/info directory to add an entry for it. This
-involves adding a line like
-
-<tscreen><verb>
-       * Make: (make).                 The GNU Make utility.
- </verb></tscreen>
-
-to the file. Once you have done this, you can type `info' and then
-select make from the menu (or in Emacs, do C-h i).
-
-<sect><heading>Debugging</heading>
-<p>
-<sect1><heading>The Debugger</heading>
-<p>
-The debugger that comes with FreeBSD is called `gdb' (GNU debugger). You
-start it up by typing 
-
-<tscreen><verb> 
-       gdb <progname>
-</verb></tscreen>
-
-although most people prefer to run it inside Emacs. You can do this by
-
-<tscreen><verb>
-       M-x gdb RET <progname> RET.
-</verb></tscreen>
-
-Using a debugger allows you to run the program under more controlled
-circumstances. Typically, you can step through the program a line at a
-time, inspect the value of variables, change them, tell the debugger to run
-up to a certain point and then stop, and so on. You can even attach to a
-program that's already running, or load a core file to investigate why the
-program crashed.
-<p>
-It's even possible to debug the kernel, though that's a little trickier
-than the user applications we'll be discussing in this section.
-<p>
-gdb has quite good on-line help, as well as a set of info pages, so this
-section will concentrate on a few of the basic commands.
-<p>
-Finally, if you find its text-based command-prompt style off-putting,
-there's a graphical front-end for it <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/ports/devel/xxgdb.tgz"
-name="xxgdb"> in the ports.
-<p>
-This section is intended to be an introduction to using gdb and does
-not cover specialised topics such as debugging the kernel.
-
-<sect1><heading>Running a program in the debugger</heading>
-<p>
-You'll need to have compiled the program with the `-g' option to get the
-most out of using gdb. It will work without, but you'll only see the name
-of the function you're in, instead of the source code. If you see a line
-like 
-
-<tscreen><verb>
-       ...(no debugging symbols found)...
-</verb></tscreen>
-
-when gdb starts up, you'll know that the program wasn't compiled with
-the `-g' option.
-<p>
-At the gdb prompt, type `break main'. This will tell the debugger to
-skip over the preliminary set-up code in the program and start at the
-beginning of your code. Now type `run' to start the program - it will
-start at the beginning of the set-up code and then get stopped by the
-debugger when it calls main(). (If you've ever wondered where main()
-gets called from, now you know!).
-<p>
-You can now step through the program, a line at a time, by pressing
-`n'.  If you get to a function call, you can step into it by pressing
-`s'. Once you're in a function call, you can return from stepping into
-a function call by pressing `f'. You can also use `up' and `down' to
-take a quick look at the caller.
-<p>
-Here's a simple example of how to spot a mistake in a program with
-gdb. This is our program (with a deliberate mistake):-
-
-<code>
-#include <stdio.h>
-
-int bazz(int anint);
-
-main() {
-	int i;
-
-	printf("This is my program\n");
-	bazz(i);
-	return 0;
-}
-
-int bazz(int anint) {
-	printf("You gave me %d\n", anint);
-	return anint;
-}
-</code>
-
-This program sets i to be 5 and passes it to a function bazz() which prints
-out the number we gave it.
-<p>
-When we compile and run the program we get
-
-<tscreen><verb>
-       cc -g -o temp temp.c
-       ./temp
-       This is my program
-       anint = 4231
-</verb></tscreen>
-
-That wasn't what we expected! Time to see what's going on!
-
-<tscreen><verb>
-Current directory is ~/tmp/
-GDB is free software and you are welcome to distribute copies of it
- under certain conditions; type "show copying" to see the conditions.
-There is absolutely no warranty for GDB; type "show warranty" for details.
-GDB 4.13 (i386-unknown-freebsd), 
-Copyright 1994 Free Software Foundation, Inc...
-(gdb) break main				# Skip the set-up code
-Breakpoint 1 at 0x160f: file temp.c, line 9.	# gdb puts breakpoint at main()
-(gdb) run					# Run as far as main()
-Starting program: /home/james/tmp/temp		# Program starts running 
-
-Breakpoint 1, main () at temp.c:9		# gdb stops at main()
-(gdb) n						# Go to next line
-This is my program				# Program prints out "This .."
-(gdb) s						# step into bazz()
-bazz (anint=4231) at temp.c:17			# gdb displays stack frame
-</verb></tscreen>
-
-Hang on a minute! How did anint get to be 4231? Didn't we set it to be 5
-in main()? Let's move up to main() and have a look.
-
-<tscreen><verb>
-(gdb) up					# Move up call stack
-#1  0x1625 in main () at temp.c:11		# gdb displays stack frame
-(gdb) p i					# Show us the value of i
-$1 = 4231					# gdb displays 4231
-</verb></tscreen>
-
-Oh dear! Looking at the code, we forgot to initialise i. We meant to put
-
-<code>
-...
-main() {
-	int i;
-
-	i = 5;
-	printf("This is my program\n");
-...
-</code>
-
-but we missed the `i=5;' line out.  As we didn't initialise i, it had
-whatever number happened to be in that area of memory when the program
-ran, which in this case happened to be 4231.
-<p>
-Note that gdb displays the stack frame every time we go into or out of
-a function, even if we're using `up' and `down' to move around the
-call stack.  This shows the name of the function and the values of its
-arguments, which helps us keep track of where we are and what's going
-on. (The stack is a storage area where the program stores information
-about the arguments passed to functions and where to go when it
-returns from a function call).
-
-<sect1><heading>Examining a core file</heading>
-<p>
-A core file is basically a file which contains the complete state of
-the process when it crashed. In ``the good old days'', programmers had
-to print out hex listings of core files and sweat over machine code
-manuals, but now life is a bit easier. Incidentally, under FreeBSD and
-other 4.4BSD systems, a core file is called ``progname.core'' instead
-of just core, to make it clearer which program a core file belongs to.
-<p>
-To examine a core file, start up gdb in the usual way. Instead of
-typing `break' or `run', type
-
-<tscreen><verb>
-       core progname.core 
-</verb></tscreen>
-
-(if you're not in the same directory as the core file, you'll have to
-do `dir /path/to/core/file' first).
-<p>
-You should see something like this:-
-
-<tscreen><verb>
-Current directory is ~/tmp/
-GDB is free software and you are welcome to distribute copies of it
- under certain conditions; type "show copying" to see the conditions.
-There is absolutely no warranty for GDB; type "show warranty" for details.
-GDB 4.13 (i386-unknown-freebsd), 
-Copyright 1994 Free Software Foundation, Inc...
-(gdb) core a.out.core
-Core was generated by `a.out'.
-Program terminated with signal 11, Segmentation fault.
-Cannot access memory at address 0x7020796d.
-#0  0x164a in foobar (some_arg=0x5) at temp.c:17
-</verb></tscreen>
-
-In this case, the program was called `a.out', so the core file is
-called `a.out.core'. We can see that the program crashed due to trying
-to access an area in memory that was not available to it in a function
-called `bazz'.
-<p>
-Sometimes it's useful to be able to see how a function was called, as
-the problem could have occurred a long way up the call stack in a
-complex program. The `bt' command causes gdb to print out a back-trace
-of the call stack:-
-
-<tscreen><verb>
-(gdb) bt
-#0  0x164a in bazz (anint=0x5) at temp.c:17
-#1  0xefbfd888 in end ()
-#2  0x162c in main () at temp.c:11
-</verb></tscreen>
-
-The end() function is called when a program crashes; in this case, the
-bazz() function was called from main().
-
-<sect1><heading>Attaching to a running program</heading>
-<p>
-One of the neatest features about gdb is that it can attach to a
-program that's already running. (Of course, that assumes you have
-sufficient permissions to do so). A common problem is when you are
-stepping through a program that forks, and you want to trace the
-child, but the debugger will only let you trace the parent.
-<p>
-What you do is start up another gdb, use `ps' to find the process ID
-for the child, and do
-
-<tscreen><verb>
-       attach <pid>
-</verb></tscreen>
-
-in gdb, and then debug as usual.
-<p>
-``That's all very well,'' you're probably thinking, ``but by the time
-I've done that, the child process will be over the hill and far
-away''. Fear not, gentle reader, here's how to do it (courtesy of the
-gdb info pages):-
-
-<tscreen><verb>
-...
-if ((pid = fork()) < 0)		/* _Always_ check this */
-	error();
-else if (pid == 0) {		/* child */
-	int PauseMode = 1;
-
-	while (PauseMode)
-		sleep(10);	/* Wait until someone attaches to us */
-	...
-} else {			/* parent */
-	...
-</verb></tscreen>
-
-Now all you have to do is attach to the child, set PauseMode to 0, and
-wait for the sleep() call to return!
-
-<sect><heading>Using Emacs as a Development Environment</heading>
-<p>
-<sect1><heading>Emacs</heading>
-<p>
-Unfortunately, Unix systems don't come with the kind of
-everything-you-ever-wanted-and-lots-more-you-didn't-in-one-gigantic-package
-integrated development environments that other systems have (at least,
-not unless you pay out very large sums of money). However, it is
-possible to set up your own environment. It may not be as pretty, and
-it may not be quite as integrated, but you can set it up the way you
-want it. And it's free. And you have the source to it.
-<p>
-The key to it all is Emacs. Now there are some people who loathe it,
-but many who love it. If you're one of the former, I'm afraid this
-section will hold little of interest to you. Also, you'll need a fair
-amount of memory to run it - I'd recommend 8MB in text mode and 16MB
-in X as the bare minimum to get reasonable performance.
-<p>
-Emacs is basically a highly customisable editor - indeed, it has been
-customised to the point where it's more like an operating system than
-an editor! (Many developers and sysadmins do in fact spend practically
-all their time working inside Emacs, leaving it only to log out).
-<p>
-It's impossible even to summarise everything Emacs can do here, but
-here are some of the features of interest to developers:-
-
-<itemize>
-<item> Very powerful editor, allowing search-and-replace on both
-  strings and regular expressions (patterns), jumping to start/end of
-  block expression, etc, etc.
-
-<item> Pull-down menus and online help.
-
-<item> Language-dependent syntax highlighting and indentation.
-
-<item> Completely customisable.
-
-<item> You can compile and debug programs within Emacs.
-
-<item> On a compilation error, you can jump to the offending line of source
-  code.
-
-<item> Friendly-ish front-end to the `info' program used for reading GNU
-  hypertext documentation (including the documentation on Emacs).
-
-<item> Friendly front-end to GDB, allowing you to look at the source code
-  as you step through your program.
-
-<item> You can read Usenet news and mail while your program is compiling ;-)
-</itemize>
-
-And doubtless many more that I've overlooked.
-<p>
-Emacs can be installed on FreeBSD using <htmlurl
-url="ftp://ftp.freebsd.org:pub/FreeBSD/packages/editors/emacs"
-name="the Emacs package">.
-<p>
-Once it's installed, start it up and do C-h t to read an Emacs
-tutorial - that means hold down the control key, press `h', let go of
-the control key, and then press t. (Alternatively, you can you use
-the mouse to select ``Emacs Tutorial'' from the ``Help'' menu).
-<p>
-Although Emacs does have menus, it's well worth learning the key
-bindings, as it's much quicker when you're editing something to press
-a couple of keys than to try and find the mouse and then click on the
-right place. And, when you're talking to seasoned Emacs users, you'll
-find they often casually throw around expressions like
-
-<tscreen><verb>
-       M-x replace-s RET foo RET bar RET
-</verb></tscreen>
-
-so it's useful to know what they mean. And in any case, Emacs has far
-too many useful functions for them to all fit on the menu bars.
-<p>
-Fortunately, it's quite easy to pick up the key-bindings, as they're
-displayed next to the menu item. (My advice is to use the menu item
-for, say, opening a file until you understand how it works and feel
-confident with it, then try doing C-x C-f. When you're happy with
-that, move on to another menu command). 
-<p>
-If you can't remember what a particular combination of keys does,
-select ``Describe Key'' from the ``Help'' menu and type it in - Emacs
-will tell you what it does. You can also use the ``Command Apropos''
-menu item to find out all the commands which contain a particular word
-in them, with the key binding next to it.
-<p>
-By the way, the expression above means hold down the Meta key, press
-`x', release the Meta key, type replace-s (short for ``replace-string''
-- another feature of Emacs is that you can abbreviate commands), press
-the return key, type foo (the string you want replaced), press the
-return key, type bar (the string you want to replace ``foo'' with) and
-press return again. Emacs will then do the search-and-replace
-operation you've just requested.
-<p>
-If you're wondering what on earth the Meta key is, it's a special key
-that many Unix workstations have. Unfortunately, PC's don't have one,
-so it's usually the ``alt'' key (or if you're unlucky, the ``escape''
-key).
-<p>
-Oh, and to get out of Emacs, do C-c C-x (that means hold down the
-control key, press `c', press `x' and release the control key). If you
-have any unsaved files open, Emacs will ask you if you want to save
-them. (Ignore the bit in the documentation where it says C-z is the
-usual way to leave Emacs - that leaves Emacs hanging around in the
-background, and is only really useful if you're on a system which
-doesn't have virtual terminals).
-
-<sect1><heading>Configuring Emacs</heading>
-<p>
-Emacs does many wonderful things, some of them are built in, some of
-them need to be configured.
-<p>
-Instead of using a proprietary macro language for configuration, Emacs
-uses a version of Lisp specially adapted for editors, known as Emacs
-Lisp. This can be quite useful if you want to go on and learn
-something like Common Lisp, as it's considerably smaller than Common
-Lisp (although still quite big!).
-<p>
-The best way to learn Emacs Lisp is to download the <htmlurl
-url="ftp://prep.ai.mit.edu:pub/gnu/elisp-manual-19-2.4.tar.gz"
-name="Emacs Tutorial">
-<p>
-However, there's no need to actually know any Lisp to get started with
-configuring Emacs, as I've included a sample ``.emacs'' file, which
-should be enough to get you started. Just copy it into your home
-directory and restart Emacs if it's already running; it will read the
-commands from the file and (hopefully) give you a useful basic setup.
-
-<sect1><heading>A sample .emacs file</heading>
-<p>
-Unfortunately, there's far too much here to explain it in detail;
-however there are one or two points worth mentioning.
-
-<itemize>
-<item> Everything beginning with a `;' is a comment and is ignored by Emacs.
-
-<item> In the first line, the -*- Emacs-Lisp -*- is so that we can edit
-the .emacs file itself within Emacs and get all the fancy features for
-editing Emacs Lisp (Emacs usually tries to guess this based on the
-filename, and may not get it right for .emacs).
-
-<item> The `tab' key is bound to an indentation function in some modes, so
-when you press the tab key, it will indent the current line of
-code. If you want to put a tab character in whatever you're writing,
-hold the control key down while you're pressing the tab key.
-
-<item> This file supports syntax highlighting for C, C++, Perl, Lisp and
-Scheme (by guessing the language from the filename).
-
-<item> Emacs already has a pre-defined function called ``next-error''.
-In a compilation output window, this allows you to move from one
-compilation error to the next by doing M-n; we define a complementary
-function, ``previous-error'', that allows you to go to a previous
-error by doing M-p. The nicest feature of all is that C-c C-c will
-open up the source file in which the error occurred and jump to the
-appropriate line.
-
-<item> We enable Emacs's ability to act as a server, so that if you're doing
-something outside Emacs and you want to edit a file, you can just
-type in 
-<tscreen><verb>
-       emacsclient <filename>
-</verb></tscreen>
-
-and then you can edit the file in your Emacs! (Many Emacs users set
-their EDITOR environment to `emacsclient' so this happens every time
-they need to edit a file).
-</itemize>
-
-<tscreen><verb>
-;; -*-Emacs-Lisp-*-
-
-;; This file is designed to be re-evaled; use the variable first-time
-;; to avoid any problems with this.
-(defvar first-time t 
-  "Flag signifying this is the first time that .emacs has been evaled")
-
-;; Meta
-(global-set-key "\M- " 'set-mark-command)
-(global-set-key "\M-\C-h" 'backward-kill-word)
-(global-set-key "\M-\C-r" 'query-replace)
-(global-set-key "\M-r" 'replace-string)
-(global-set-key "\M-g" 'goto-line)
-(global-set-key "\M-h" 'help-command)
-
-;; Function keys
-(global-set-key [f1] 'manual-entry)
-(global-set-key [f2] 'info)
-(global-set-key [f3] 'repeat-complex-command)
-(global-set-key [f4] 'advertised-undo)
-(global-set-key [f5] 'eval-current-buffer)
-(global-set-key [f6] 'buffer-menu)
-(global-set-key [f7] 'other-window)
-(global-set-key [f8] 'find-file)
-(global-set-key [f9] 'save-buffer)
-(global-set-key [f10] 'next-error)
-(global-set-key [f11] 'compile)
-(global-set-key [f12] 'grep)
-(global-set-key [C-f1] 'compile)
-(global-set-key [C-f2] 'grep)
-(global-set-key [C-f3] 'next-error)
-(global-set-key [C-f4] 'previous-error)
-(global-set-key [C-f5] 'display-faces)
-(global-set-key [C-f8] 'dired)
-(global-set-key [C-f10] 'kill-compilation)
-
-;; Keypad bindings
-(global-set-key [up] "\C-p")
-(global-set-key [down] "\C-n")
-(global-set-key [left] "\C-b")
-(global-set-key [right] "\C-f")
-(global-set-key [home] "\C-a")
-(global-set-key [end] "\C-e")
-(global-set-key [prior] "\M-v")
-(global-set-key [next] "\C-v")
-(global-set-key [C-up] "\M-\C-b")
-(global-set-key [C-down] "\M-\C-f")
-(global-set-key [C-left] "\M-b")
-(global-set-key [C-right] "\M-f")
-(global-set-key [C-home] "\M-<")
-(global-set-key [C-end] "\M->")
-(global-set-key [C-prior] "\M-<")
-(global-set-key [C-next] "\M->")
-
-;; Mouse
-(global-set-key [mouse-3] 'imenu)
-
-;; Misc
-(global-set-key [C-tab] "\C-q\t")	; Control tab quotes a tab.
-(setq backup-by-copying-when-mismatch t)
-
-;; Treat 'y' or <CR> as yes, 'n' as no.
-(fset 'yes-or-no-p 'y-or-n-p)
-    (define-key query-replace-map [return] 'act)
-    (define-key query-replace-map [?\C-m] 'act)
-
-;; Load packages
-(require 'desktop)
-(require 'tar-mode)
-
-;; Pretty diff mode
-(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
-(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
-(autoload 'ediff-files-remote "ediff"
-  "Intelligent Emacs interface to diff") 
-</verb></tscreen>
-<tscreen><verb>
-(if first-time
-    (setq auto-mode-alist
-	  (append '(("\\.cpp$" . c++-mode)
-		    ("\\.hpp$" . c++-mode)
-                    ("\\.lsp$" . lisp-mode)
-		    ("\\.scm$" . scheme-mode)
-		    ("\\.pl$" . perl-mode)
-		    ) auto-mode-alist)))
-
-;; Auto font lock mode
-(defvar font-lock-auto-mode-list 
-  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
-  "List of modes to always start in font-lock-mode")
-
-(defvar font-lock-mode-keyword-alist
-  '((c++-c-mode . c-font-lock-keywords)
-    (perl-mode . perl-font-lock-keywords))
-  "Associations between modes and keywords")
-
-(defun font-lock-auto-mode-select ()
-  "Automatically select font-lock-mode if the current major mode is
-in font-lock-auto-mode-list"
-  (if (memq major-mode font-lock-auto-mode-list) 
-      (progn
-	(font-lock-mode t))
-    )
-  )
-
-(global-set-key [M-f1] 'font-lock-fontify-buffer)
-
-;; New dabbrev stuff
-;(require 'new-dabbrev)
-(setq dabbrev-always-check-other-buffers t)
-(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
-(add-hook 'emacs-lisp-mode-hook
-	  '(lambda () 
-	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
-	     (set (make-local-variable 'dabbrev-case-replace) nil)))
-(add-hook 'c-mode-hook
-	  '(lambda () 
-	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
-	     (set (make-local-variable 'dabbrev-case-replace) nil)))
-(add-hook 'text-mode-hook
-	  '(lambda () 
-	     (set (make-local-variable 'dabbrev-case-fold-search) t)
-	     (set (make-local-variable 'dabbrev-case-replace) t)))
-
-;; C++ and C mode...
-(defun my-c++-mode-hook ()
-  (setq tab-width 4)
-  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
-  (define-key c++-mode-map "\C-ce" 'c-comment-edit)
-  (setq c++-auto-hungry-initial-state 'none)
-  (setq c++-delete-function 'backward-delete-char)
-  (setq c++-tab-always-indent t)
-  (setq c-indent-level 4)
-  (setq c-continued-statement-offset 4)
-  (setq c++-empty-arglist-indent 4))
-
-(defun my-c-mode-hook ()
-  (setq tab-width 4)
-  (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
-  (define-key c-mode-map "\C-ce" 'c-comment-edit)
-  (setq c-auto-hungry-initial-state 'none)
-  (setq c-delete-function 'backward-delete-char)
-  (setq c-tab-always-indent t)
-;; BSD-ish indentation style
-  (setq c-indent-level 4)
-  (setq c-continued-statement-offset 4)
-  (setq c-brace-offset -4)
-  (setq c-argdecl-indent 0)
-  (setq c-label-offset -4))
-
-;; Perl mode
-(defun my-perl-mode-hook ()
-  (setq tab-width 4)
-  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
-  (setq perl-indent-level 4)
-  (setq perl-continued-statement-offset 4))
-
-;; Scheme mode...
-(defun my-scheme-mode-hook ()
-  (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
-
-;; Emacs-Lisp mode...
-(defun my-lisp-mode-hook ()
-  (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
-  (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
-  (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
-
-;; Add all of the hooks...
-(add-hook 'c++-mode-hook 'my-c++-mode-hook)
-(add-hook 'c-mode-hook 'my-c-mode-hook)
-(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
-(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
-(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
-(add-hook 'perl-mode-hook 'my-perl-mode-hook)
-
-;; Complement to next-error
-(defun previous-error (n)
-  "Visit previous compilation error message and corresponding source code."
-  (interactive "p")
-  (next-error (- n)))
-</verb></tscreen>
-<tscreen><verb>
-;; Misc...
-(transient-mark-mode 1)
-(setq mark-even-if-inactive t)
-(setq visible-bell nil)
-(setq next-line-add-newlines nil)
-(setq compile-command "make")
-(setq suggest-key-bindings nil)
-(put 'eval-expression 'disabled nil)
-(put 'narrow-to-region 'disabled nil)
-(put 'set-goal-column 'disabled nil)
-
-;; Elisp archive searching
-(autoload 'format-lisp-code-directory "lispdir" nil t)
-(autoload 'lisp-dir-apropos "lispdir" nil t)
-(autoload 'lisp-dir-retrieve "lispdir" nil t)
-(autoload 'lisp-dir-verify "lispdir" nil t)
-
-;; Font lock mode
-(defun my-make-face (face colour &amp;optional bold)
-  "Create a face from a colour and optionally make it bold"
-  (make-face face)
-  (copy-face 'default face)
-  (set-face-foreground face colour)
-  (if bold (make-face-bold face))
-  )
-
-(if (eq window-system 'x)
-    (progn
-      (my-make-face 'blue "blue")
-      (my-make-face 'red "red")
-      (my-make-face 'green "dark green")
-      (setq font-lock-comment-face 'blue)
-      (setq font-lock-string-face 'bold)
-      (setq font-lock-type-face 'bold)
-      (setq font-lock-keyword-face 'bold)
-      (setq font-lock-function-name-face 'red)
-      (setq font-lock-doc-string-face 'green)
-      (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
-
-      (setq baud-rate 1000000)
-      (global-set-key "\C-cmm" 'menu-bar-mode)
-      (global-set-key "\C-cms" 'scroll-bar-mode)
-      (global-set-key [backspace] 'backward-delete-char)
-					;      (global-set-key [delete] 'delete-char)
-      (standard-display-european t)
-      (load-library "iso-transl")))
-
-;; X11 or PC using direct screen writes
-(if window-system
-    (progn
-      ;;      (global-set-key [M-f1] 'hilit-repaint-command)
-      ;;      (global-set-key [M-f2] [?\C-u M-f1])
-      (setq hilit-mode-enable-list  
-	    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
-		  scheme-mode)
-	    hilit-auto-highlight nil
-	    hilit-auto-rehighlight 'visible
-	    hilit-inhibit-hooks nil
-	    hilit-inhibit-rebinding t)
-      (require 'hilit19)
-      (require 'paren))
-  (setq baud-rate 2400)			; For slow serial connections
-  )
-
-;; TTY type terminal
-(if (and (not window-system) 
-	 (not (equal system-type 'ms-dos)))
-    (progn
-      (if first-time
-	  (progn
-	    (keyboard-translate ?\C-h ?\C-?)
-	    (keyboard-translate ?\C-? ?\C-h)))))
-
-;; Under UNIX
-(if (not (equal system-type 'ms-dos))
-    (progn
-      (if first-time
-	  (server-start))))
-
-;; Add any face changes here
-(add-hook 'term-setup-hook 'my-term-setup-hook)
-(defun my-term-setup-hook ()
-  (if (eq window-system 'pc)
-      (progn
-;;	(set-face-background 'default "red")
-	)))
-
-;; Restore the "desktop" - do this as late as possible
-(if first-time
-    (progn
-      (desktop-load-default)
-      (desktop-read)))
-
-;; Indicate that this file has been read at least once
-(setq first-time nil)
-
-;; No need to debug anything now
-(setq debug-on-error nil)
-
-;; All done
-(message "All done, %s%s" (user-login-name) ".")
-
-</verb></tscreen>
-
-<sect1><heading>Extending the Range of Languages Emacs Understands</heading>
-<p>
-Now, this is all very well if you only want to program in the
-languages already catered for in the .emacs file (C, C++, Perl, Lisp
-and Scheme), but what happens if a new language called "whizbang"
-comes out, full of exciting features?
-<p>
-The first thing to do is find out if "whizbang" comes with any files
-that tell Emacs about the language. These usually end in ".el", short
-for "Emacs Lisp". For example, if "whizbang" is a FreeBSD port, we can
-locate these files by doing
-
-<tscreen><verb> 
-       find /usr/ports/lang/whizbang -name *.el -print
-</verb></tscreen>
-
-and install them by copying them into the Emacs site Lisp directory. On
-FreeBSD 2.1.0-RELEASE, this is /usr/local/share/emacs/site-lisp.
-
-So for example, if the output from the find command was 
-
-<tscreen><verb>
-       /usr/ports/lang/whizbang/work/misc/whizbang.el
-</verb></tscreen>
-
-we would do 
-
-<tscreen><verb>
-       cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp
-</verb></tscreen>
-
-Next, we need to decide what extension whizbang source files
-have. Let's say for the sake of argument that they all end in
-`.wiz'. We need to add an entry to our .emacs file to make sure Emacs
-will be able to use the information in whizbang.el.
-<p>
-Find the auto-mode-alist entry in .emacs and add a line for whizbang,
-such as:-
-
-<tscreen><verb>
-		...
-                    ("\\.lsp$" . lisp-mode)
-                    ("\\.wiz$" . whizbang-mode)
-		    ("\\.scm$" . scheme-mode)
-		...
-</verb></tscreen>
-
-This means that Emacs will automatically go into whizbang-mode when
-you edit a file ending in .wiz.
-<p>
-Just below this, you'll find the font-lock-auto-mode-list entry. Add
-whizbang-mode to it like so:-
-
-<tscreen><verb>
-;; Auto font lock mode
-(defvar font-lock-auto-mode-list 
-  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
-  "List of modes to always start in font-lock-mode")
-</verb></tscreen>
-
-This means that Emacs will always enable font-lock-mode (ie syntax
-highlighting) when editing a .wiz file.
-<p>
-And that's all that's needed. If there's anything else you want done
-automatically when you open up a .wiz file, you can add a
-whizbang-mode hook (see my-scheme-mode-hook for a simple example that
-adds auto-indent).
-
-<sect><heading>Further Reading</heading>
-<sect1><heading>Bibliography</heading>
-<p>
-<itemize>
-<item>
-Brian Harvey and Matthew Wright
-<em>Simply Scheme</em>
-MIT 1994.
-<newline>ISBN 0-262-08226-8
-</item>
-
-<item>
-Randall Schwartz
-<em>Learning Perl</em>
-O'Reilly 1993
-<newline>ISBN 1-56592-042-2
-</item>
-
-<item>
-Patrick Henry Winston and Berthold Klaus Paul Horn
-<em>Lisp (3rd Edition)</em>
-Addison-Wesley 1989
-<newline>ISBN 0-201-08319-1
-</item>
-
-<item>
-Brian W. Kernighan and Rob Pike
-<em>The Unix Programming Environment</em>
-Prentice-Hall 1984
-<newline>ISBN 0-13-937681-X
-</item>
-
-<item>
-Brian W. Kernighan and Dennis M. Ritchie
-<em>The C Programming Language (2nd Edition)</em>
-Prentice-Hall 1988
-<newline>ISBN 0-13-110362-8
-</item>
-
-<item>
-Bjarne Stroustrup
-<em>The C++ Programming Language</em>
-Addison-Wesley 1991
-<newline>ISBN 0-201-53992-6
-</item>
-
-<item>
-W. Richard Stevens
-<em>Advanced Programming in the Unix Environment</em>
-Addison-Wesley 1992
-<newline>ISBN 0-201-56317-7
-</item>
-
-<item>
-W. Richard Stevens
-<em>Unix Network Programming</em>
-Prentice-Hall 1990
-<newline>ISBN 0-13-949876-1
-</item>
-</itemize>
-</article>
diff --git a/en/tutorials/index.sgml b/en/tutorials/index.sgml
index ebbc838f65..0f785a2caf 100644
--- a/en/tutorials/index.sgml
+++ b/en/tutorials/index.sgml
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN" [
 <!ENTITY base CDATA "..">
-<!ENTITY date "$Date: 1997-01-18 02:24:07 $">
+<!ENTITY date "$Date: 1997-01-19 15:29:57 $">
 <!ENTITY title "FreeBSD Tutorials">
 <!ENTITY % includes SYSTEM "../includes.sgml"> %includes;
 ]>
@@ -19,9 +19,8 @@
       	    (<a href="mh/mh.ps">postscript</a>,
 		<a href="mh/mh-html.tar.gz">gzipd tar file</a>)</li>
 
-      <li><a href="devel/devel.html">A User's Guide to FreeBSD Programming Tools</a>
-      	    (<a href="devel/devel.ps">postscript</a>,
-		<a href="devel/devel-html.tar.gz">gzipd tar file</a>)</li>
+      <li><a href="devel/devel.html">A User's Guide to FreeBSD Programming
+	Tools</a></li>
 
       <li><a href="ddwg/ddwg.html">Writing device drivers for FreeBSD</a>
       	    (<a href="ddwg/ddwg.ps">postscript</a>,
diff --git a/en_US.ISO8859-1/articles/programming-tools/Makefile b/en_US.ISO8859-1/articles/programming-tools/Makefile
index 6cc882035c..9429f7790d 100644
--- a/en_US.ISO8859-1/articles/programming-tools/Makefile
+++ b/en_US.ISO8859-1/articles/programming-tools/Makefile
@@ -1,5 +1,5 @@
-DOC=		devel
-SRCS=		devel.sgml
+DOCS=	devel.docb
+INDEXLINK=	devel.html
 
-.include <bsd.sgml.mk>
+.include "../../web.mk"
 
diff --git a/en_US.ISO8859-1/articles/programming-tools/article.sgml b/en_US.ISO8859-1/articles/programming-tools/article.sgml
new file mode 100644
index 0000000000..524d8730f3
--- /dev/null
+++ b/en_US.ISO8859-1/articles/programming-tools/article.sgml
@@ -0,0 +1,1835 @@
+<!-- $FreeBSD$ -->
+<!-- The FreeBSD Documentation Project -->
+
+<!DOCTYPE BOOK PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
+<book>
+<bookinfo>
+<bookbiblio>
+<title>A User's Guide to FreeBSD Programming Tools</title>
+
+<authorgroup>
+<author>
+<firstname>James</firstname>
+<surname>Raynard</surname>
+<affiliation>
+<address>
+<email>jraynard@freebsd.org</email>
+</address>
+</affiliation>
+</author></authorgroup>
+
+<pubdate>January 19, 1997</pubdate>
+
+<copyright>
+<year>1997</year>
+<holder>James Raynard</holder>
+</copyright>
+
+<abstract><para>This document is an introduction to using some of the programming
+tools supplied with FreeBSD, although much of it will be applicable to
+many other versions of Unix. It does <emphasis>not</emphasis> attempt to describe
+coding in any detail. Most of the document assumes little or no
+previous programming knowledge, although it is hoped that most
+programmers will find something of value in it</para></abstract>
+</bookbiblio>
+</bookinfo>
+
+<chapter>
+<title>Introduction<anchor id=foo></title>
+  
+<para>FreeBSD offers an excellent development environment. Compilers
+for C, C++, and Fortran and an assembler come with the basic system,
+not to mention a Perl interpreter and classic Unix tools such as
+<command>sed</> and <command>awk</>. If that is not enough, there are
+many more compilers and interpreters in the Ports collection. FreeBSD
+is very compatible with standards such as <acronym>POSIX</> and
+<acronym>ANSI</> C, as well with its own BSD heritage, so it is
+possible to write applications that will compile and run with little
+or no modification on a wide range of platforms.</para>
+
+<para>However, all this power can be rather overwhelming at first if
+you've never written programs on a Unix platform before. This
+document aims to help you get up and running, without getting too
+deeply into more advanced topics. The intention is that this document
+should give you enough of the basics to be able to make some sense of
+the documentation.</para>
+
+<para>Most of the document requires little or no knowledge of
+programming, although it does assume a basic competence with using
+Unix and a willingness to learn!</para>
+  
+</chapter>
+
+<chapter>
+<title>Introduction to Programming</title>
+
+<para>A program is a set of instructions that tell the computer to do
+various things; sometimes the instruction it has to perform depends
+on what happened when it performed a previous instruction. This
+section gives an overview of the two main ways in which you can give
+these instructions, or <quote>commands</quote> as they are usually
+called. One way uses an <firstterm>interpreter</>, the other a
+<firstterm>compiler</>. As human languages are too difficult for a
+computer to understand in an unambiguous way, commands are usually
+written in one or other languages specially designed for the
+purpose.</para>
+
+
+  
+<sect1>
+<title>Interpreters</title>
+
+<para>With an interpreter, the language comes as an environment, where you
+type in commands at a prompt and the environment executes them for
+you. For more complicated programs, you can type the commands into a
+file and get the interpreter to load the file and execute the commands
+in it. If anything goes wrong, many interpreters will drop you into a
+debugger to help you track down the problem.</para>
+  
+<para>The advantage of this is that you can see the results of your
+commands immediately, and mistakes can be corrected readily. The
+biggest disadvantage comes when you want to share your programs with
+someone. They must have the same interpreter, or you must have some
+way of giving it to them, and they need to understand how to use it.
+Also users may not appreciate being thrown into a debugger if they
+press the wrong key! From a performance point of view, interpreters
+can use up a lot of memory, and generally do not generate code as
+efficiently as compilers.</para>
+
+<para>In my opinion, interpreted languages are the best way to start
+if you have not done any programming before. This kind of environment
+is typically found with languages like Lisp, Smalltalk, Perl and
+Basic. It could also be argued that the Unix shell (<command>sh</>,
+<command>csh</>) is itself an interpreter, and many people do in fact
+write shell <quote>scripts</quote> to help with various
+<quote>housekeeping</> tasks on their machine. Indeed, part of the
+original Unix philosophy was to provide lots of small utility
+programs that could be linked together in shell scripts to perform
+useful tasks.</para>
+  
+</sect1>
+
+<sect1>
+<title>Interpreters available with FreeBSD</title>
+
+<para>Here is a list of interpreters that are available as <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
+packages</ulink>, with a brief discussion of some of the more popular
+interpreted languages. </para>
+
+<para>To get one of these packages, all you need to do is to click on
+the hotlink for the package, then run
+<screen>$ <userinput>pkg_add <replaceable>package name</></userinput></screen>
+</para>
+  
+<para>as root. Obviously, you will need to have a fully functional FreeBSD
+2.1.0 or later system for the package to work!</para>
+  
+<para>
+<variablelist>
+<varlistentry><term><acronym>BASIC</></term>
+
+<listitem><para>Short for Beginner's All-purpose Symbolic Instruction
+Code. Developed in the 1950s for teaching University students to
+program and provided with every self-respecting personal computer in
+the 1980s, <acronym>BASIC</> has been the first programming language
+for many programmers. It's also the foundation for <trademark>Visual
+Basic</>.</para>
+
+<para>The <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/bwbasic-2.10.tgz">Bywater
+Basic Interpreter</ulink> and the <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/pbasic-2.0.tgz">Phil
+Cockroft's Basic Interpreter</ulink> (formerly Rabbit Basic) are
+available as FreeBSD <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
+packages</ulink></para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Lisp</term>
+<listitem><para>A language that was developed in the late 1950s as an alternative to
+the <quote>number-crunching</quote> languages that were popular at the time.
+Instead of being based on numbers, Lisp is based on lists; in fact
+the name is short for <quote>List Processing</quote>. Very popular in AI
+(Artificial Intelligence) circles.</para>
+  
+<para>Lisp is an extremely powerful and sophisticated language, but
+can be rather large and unwieldy. </para>
+
+<para>FreeBSD has <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/gcl-2.0.tgz">GNU
+Common Lisp</ulink> available as a package.</para>
+  
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Perl</term>
+<listitem><para>Very popular with system administrators for writing
+scripts; also often used on World Wide Web servers for writing <acronym>CGI</>
+scripts.</para>
+
+<para>Version 4, which is probably still the most widely-used
+version, comes with FreeBSD; the newer <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/perl-5.001.tgz">Perl
+Version 5</ulink> is available as a package.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Scheme</term>
+<listitem><para>A dialect of Lisp that is rather more compact and
+cleaner than Common Lisp. Popular in Universities as it is simple
+enough to teach to undergraduates as a first language, while it has a
+high enough level of abstraction to be used in research work.</para>
+
+<para>FreeBSD has packages of the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/elk-3.0.tgz">Elk Scheme Interpreter</ulink>, the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/mit-scheme-7.3.tgz">MIT Scheme Interpreter</ulink> and the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/scm-4e1.tgz">SCM Scheme Interpreter</ulink>.</para>
+  
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Icon</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/icon-9.0.tgz">The Icon Programming Language</ulink>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Logo</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/ucblogo-3.3.tgz">Brian Harvey's LOGO Interpreter</ulink>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Python</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/python-1.2">The Python Object-Oriented Programming Language</ulink></para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+  
+</sect1>
+
+<sect1>
+<title>Compilers</title>
+
+<para>Compilers are rather different. First of all, you write your
+code in a file (or files) using an editor. You then run the compiler
+and see if it accepts your program. If it did not compile, grit your
+teeth and go back to the editor; if it did compile and gave you a
+program, you can run it either at a shell command prompt or in a
+debugger to see if it works properly.<footnote><para>If you run it in
+the shell, you may get a core dump.</para></footnote></para>
+
+<para>Obviously, this is not quite as direct as using an interpreter.
+However it allows you to do a lot of things which are very difficult
+or even impossible with an interpreter, such as writing code which
+interacts closely with the operating system&mdash;or even writing
+your own operating system! It's also useful if you need to write very
+efficient code, as the compiler can take its time and optimise the
+code, which would not be acceptable in an interpreter. And
+distributing a program written for a compiler is usually more
+straightforward than one written for an interpreter&mdash;you can just
+give them a copy of the executable, assuming they have the same
+operating system as you.</para>
+
+<para>Compiled languages include Pascal, C and C++. C and C++ are rather
+unforgiving languages, and best suited to more experienced
+programmers; Pascal, on the other hand, was designed as an educational
+language, and is quite a good language to start with. Unfortunately,
+FreeBSD doesn't have any Pascal support, except for a Pascal-to-C
+converter in the ports.</para>
+  
+<para>As the edit-compile-run-debug cycle is rather tedious when
+using separate programs, many commercial compiler makers have
+produced Integrated Development Environments (<acronym>IDE</acronym>s
+for short). FreeBSD does not have an <acronym>IDE</> as such; however
+it is possible to use Emacs for this purpose. This is discussed in
+<xref linkend="emacs">.</para>
+  
+</sect1>
+</chapter>
+
+<chapter>
+<title>Compiling with <command>cc</command></title>
+
+<para>This section deals only with the GNU compiler for C and C++,
+since that comes with the base FreeBSD system. It can be invoked by
+either <command>cc</> or <command>gcc</>. The details of producing a
+program with an interpreter vary considerably between interpreters,
+and are usually well covered in the documentation and on-line help
+for the interpreter.</para>
+
+<para>Once you've written your masterpiece, the next step is to convert it
+into something that will (hopefully!) run on FreeBSD. This usually
+involves several steps, each of which is done by a separate
+program.</para>
+
+<procedure>
+<step><para>Pre-process your source code to remove comments and do other
+tricks like expanding macros in C.
+</para></step>
+
+<step><para>Check the syntax of your code to see if you have obeyed the
+rules of the language. If you have not, it will complain!
+</para></step>
+
+<step><para>Convert the source code into assembly
+language&mdash;this is very close to machine code, but still
+understandable by humans. Allegedly.<footnote><para>To be strictly
+accurate, <command>cc</> converts the source code into its own,
+machine-independent <firstterm>p-code</> instead of assembly language
+at this stage.</para></footnote></para></step>
+
+<step><para>Convert the assembly language into machine
+code&mdash;yep, we are talking bits and bytes, ones and zeros
+here.</para></step>
+
+<step><para>Check that you have used things like functions and global
+variables in a consistent way. For example, if you have called a
+non-existent function, it will complain.</para></step>
+
+<step><para>If you are trying to produce an executable from several
+source code files, work out how to fit them all together.</para></step>
+
+<step><para>Work out how to produce something that the system's run-time
+loader will be able to load into memory and run.</para></step>
+
+<step><para>Finally, write the executable on the file
+system.</para></step>
+
+</procedure>
+  
+<para>The word <firstterm>compiling</> is often used to refer to just
+steps 1 to 4&mdash;the others are referred to as
+<firstterm>linking</>. Sometimes step 1 is referred to as
+<firstterm>pre-processing</> and steps 3-4 as
+<firstterm>assembling</>.</para>
+
+<para>Fortunately, almost all this detail is hidden from you, as
+<command>cc</> is a front end that manages calling all these programs
+with the right arguments for you; simply typing
+<screen>$ <userinput>cc foobar.c</></screen></para>
+  
+<para>will cause <filename>foobar.c</> to be compiled by all the
+steps above. If you have more than one file to compile, just do
+something like
+<screen>$ <userinput>cc foo.c bar.c</></screen>
+</para>
+  
+<para>Note that the syntax checking is just that&mdash;checking the
+syntax. It will not check for any logical mistakes you may have made,
+like putting the program into an infinite loop, or using a bubble
+sort when you meant to use a binary sort.<footnote><para>In case you
+didn't know, a binary sort is an efficient way of sorting things into
+order and a bubble sort isn't.</para></footnote></para>
+
+<para>There are lots and lots of options for <command>cc</>, which
+are all in the man page.  Here are a few of the most important ones,
+with examples of how to use them.</para>
+
+<variablelist>
+<varlistentry><term><option>-o <replaceable>filename</replaceable></></term>
+
+<listitem><para>The output name of the file. If you do not use this
+option, <command>cc</> will  produce an executable called
+<filename>a.out</>.<footnote><para>The reasons for this are buried in
+the mists of history.</para></footnote></para>
+
+<informalexample>
+<screen>$ <userinput>cc foobar.c</>               <lineannotation>executable is <filename>a.out</></>
+$ <userinput>cc -o foobar foobar.c</>     <lineannotation>executable is <filename>foobar</></></screen>
+</informalexample>
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-c</option></term>
+<listitem><para>Just compile the file, do not link it. Useful for toy
+programs where you just want to check the syntax, or if you are using
+a <filename>Makefile</filename>.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -c foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce an <firstterm>object file</> (not an
+executable) called <filename>foobar.o</filename>. This can be linked
+together with other object files into an executable.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-g</option></term>
+
+<listitem><para>Create a debug version of the executable. This makes
+the compiler put information into the executable about which line of
+which source file corresponds to which function call. A debugger can
+use this information to show the source code as you step through the
+program, which is <emphasis>very</emphasis> useful; the disadvantage
+is that all this extra information makes the program much bigger.
+Normally, you compile with <option>-g</option> while you are
+developing a program and then compile a <quote>release
+version</quote> without <option>-g</option> when you're satisfied it
+works properly.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -g foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce a debug version of the
+program.<footnote><para>Note, we didn't use the <option>-o</option>
+flag to specify the executable name, so we will get an executable
+called <filename>a.out</filename>. Producing a debug version called
+<filename>foobar</filename> is left as an exercise for the
+reader!</para></footnote></para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-O</option></term>
+
+<listitem><para>Create an optimised version of the executable. The
+compiler performs various clever tricks to try and produce an
+executable that runs faster than normal. You can add a number after
+the <option>-O</option> to specify a higher level of optimisation,
+but this often exposes bugs in the compiler's optimiser. For
+instance, the version of <command>cc</command> that comes with the
+2.1.0 release of FreeBSD is known to produce bad code with the
+<option>-O2</option> option in some circumstances.</para>
+
+<para>Optimisation is usually only turned on when compiling a release
+version.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -O -o foobar foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce an optimised version of
+<filename>foobar</filename>.</para>
+
+</listitem>
+</varlistentry>
+</variablelist>
+
+<para>The following three flags will force <command>cc</command> to
+check that your code complies to the relevant international standard,
+often referred to as the <acronym>ANSI</acronym> standard, though
+strictly speaking it is an <acronym>ISO</acronym> standard.</para>
+
+<variablelist>
+
+<varlistentry><term><option>-Wall</option></term>
+
+<listitem><para>Enable all the warnings which the authors of
+<command>cc</command> believe are worthwhile. Despite the name, it
+will not enable all the warnings <command>cc</command> is capable
+of.</para></listitem>
+
+</varlistentry>
+
+<varlistentry><term><option>-ansi</option></term>
+
+<listitem>
+<para>Turn off most, but not all, of the non-<acronym>ANSI</>&nbsp;C
+features provided by <command>cc</command>. Despite the name, it does
+not guarantee strictly that your code will comply to the
+standard.</para>
+</listitem>
+
+</varlistentry>
+
+<varlistentry><term><option>-pedantic</option></term>
+
+<listitem>
+<para>Turn off <emphasis>all</emphasis>
+<command>cc</command>'s non-<acronym>ANSI</>&nbsp;C features.</para>
+</listitem>
+
+</varlistentry>
+</variablelist>
+
+<para>Without these flags, <command>cc</command> will allow you to
+use some of its non-standard extensions to the standard. Some of
+these are very useful, but will not work with other compilers&mdash;in
+fact, one of the main aims of the standard is to allow people to
+write code that will work with any compiler on any system. This is
+known as <firstterm>portable code</firstterm>.</para>
+
+<para>Generally, you should try to make your code as portable as
+possible, as otherwise you may have to completely re-write the
+program later to get it to work somewhere else&mdash;and who knows
+what you may be using in a few years time?</para>
+  
+<informalexample>
+<screen>$ <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
+</informalexample>
+
+<para>This will produce an executable <filename>foobar</filename>
+after checking <filename>foobar.c</filename> for standard
+compliance.</para>
+  
+<variablelist>
+
+<varlistentry><term><option>-l<replaceable>library</replaceable></option></term>
+
+<listitem><para>Specify a function library to be used during when
+linking.</para>
+
+<para>The most common example of this is when compiling a program that
+uses some of the mathematical functions in C. Unlike most other
+platforms, these are in a separate library from the standard C one
+and you have to tell the compiler to add it.</para>
+  
+<para>The rule is that if the library is called
+<filename>lib<replaceable>something</replaceable>.a</filename>, you
+give <command>cc</command> the argument
+<option>-l<replaceable>something</replaceable></option>. For example,
+the math library is <filename>libm.a</filename>, so you give
+<command>cc</command> the argument <option>-lm</option>. A common
+<quote>gotcha</quote> with the math library is that it has to be the
+last library on the command line.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
+</informalexample>
+
+<para>This will link the math library functions into
+<filename>foobar</filename>.</para>
+
+<para>If you are compiling C++ code, you need to add
+<option>-lg++</option>, or <option>-lstdc++</option> if you are using
+FreeBSD 2.2 or later, to the command line argument to link the C++
+library functions. Alternatively, you can run <command>c++</command>
+instead of <command>cc</command>, which does this for you.
+<command>c++</command> can also be invoked as <command>g++</command>
+on FreeBSD.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.cc -lg++</userinput>     <lineannotation>For FreeBSD 2.1.6 and earlier</>
+$ <userinput>cc -o foobar foobar.cc -lstdc++</userinput>  <lineannotation>For FreeBSD 2.2 and later</>
+$ <userinput>c++ -o foobar foobar.cc</userinput></screen>
+</informalexample>
+
+<para>Each of these will both produce an executable
+<filename>foobar</filename> from the C++ source file
+<filename>foobar.cc</filename>. Note that, on Unix systems, C++
+source files traditionally end in <filename>.C</filename>,
+<filename>.cxx</filename> or <filename>.cc</filename>, rather than
+the <trademark>MS-DOS</trademark> style <filename>.cpp</filename>
+(which was already used for something else). <command>gcc</command>
+used to rely on this to work out what kind of compiler to use on the
+source file; however, this restriction no longer applies, so you may
+now call your C++ files <filename>.cpp</filename> with
+impunity!</para>
+
+</listitem>
+</varlistentry>
+</variablelist>
+  
+<sect1>
+<title>Common <command>cc</command> Queries and Problems</title>
+
+<para>Q. I am trying to write a program which uses the
+<function>sin()</function> function and I get an error like this.
+What does it mean?
+<informalexample>
+<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment</screen>
+</informalexample>
+</para>
+  
+<para>A. When using mathematical functions like
+<function>sin()</function>, you have to tell <command>cc</command> to
+link in the math library, like so:
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
+</informalexample></para>
+
+<para>Q. All right, I wrote this simple program to practice using
+<option>-lm</option>. All it does is raise 2.1 to the power of 6.
+<informalexample>
+<programlisting>#include &lt;stdio.h&gt;
+
+int main() {
+	float f;
+
+	f = pow(2.1, 6);
+	printf("2.1 ^ 6 = %f\n", f);
+	return 0;
+}</programlisting>
+</informalexample>
+and I compiled it as:
+<informalexample>
+<screen>$ <userinput>cc temp.c -lm</userinput></screen>
+</informalexample>
+like you said I should, but I get this when I run it:
+<informalexample>
+<screen>$ <userinput>./a.out</userinput>
+2.1 ^ 6 = 1023.000000</screen>
+</informalexample>
+</para>
+  
+<para>This is <emphasis>not</emphasis> the right answer! What is
+going on?</para>
+
+<para>A. When the compiler sees you call a function, it checks if it
+has already seen a prototype for it. If it has not, it assumes the
+function returns an <type>int</type>, which is
+definitely not what you want here.</para>
+
+<para>Q. So how do I fix this?</para>
+  
+<para>A. The prototypes for the mathematical functions are in
+<filename>math.h</filename>. If you include this file, the compiler
+will be able to find the prototype and it will stop doing strange
+things to your calculation!
+<informalexample>
+<programlisting>#include &lt;math.h&gt;
+#include &lt;stdio.h&gt;
+
+int main() {
+...</programlisting>
+</informalexample>
+</para>
+  
+<para>After recompiling it as you did before, run it:
+<informalexample>
+<screen>$ <userinput>./a.out</userinput>
+2.1 ^ 6 = 85.766121</screen>
+</informalexample>
+</para>
+  
+<para>If you are using any of the mathematical functions,
+<emphasis>always</emphasis> include <filename>math.h</filename> and
+remember to link in the math library.</para>
+
+<para>Q. I compiled a file called <filename>foobar.c</filename> and I
+cannot find an executable called <filename>foobar</filename>. Where's
+it gone?</para>
+
+<para>A. Remember, <command>cc</command> will call the executable
+<filename>a.out</filename> unless you tell it differently. Use the
+<option>-o&nbsp;<replaceable>filename</replaceable></option> option:
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c</userinput></screen>
+</informalexample>
+</para>
+
+<para>Q. OK, I have an executable called <filename>foobar</filename>,
+I can see it when I run <command>ls</command>, but when I type in
+<command>foobar</command> at the command prompt it tells me there is
+no such file. Why can it not find it?</para>
+
+<para>A. Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
+current directory when it is trying to find out which executable you
+want it to run, unless you tell it to. Either type
+<command>./foobar</command>, which means <quote>run the file called
+<filename>foobar</filename> in the current directory</quote>, or
+change your <systemitem class=environvar>PATH</systemitem>
+environment variable so that it looks something like
+<informalexample>
+<screen>bin:/usr/bin:/usr/local/bin:.</screen>
+</informalexample>
+The dot at the end means <quote>look in the current directory if it is not in
+any of the others</quote>.</para>
+  
+<para>Q. I called my executable <filename>test</filename>, but
+nothing happens when I run it. What is going on?</para>
+
+<para>A. Most Unix systems have a program called
+<command>test</command> in <filename>/usr/bin</filename> and the
+shell is picking that one up before it gets to checking the current
+directory. Either type:
+<informalexample>
+<screen>$ <userinput>./test</userinput></screen>
+</informalexample>
+or choose a better name for your program!</para>
+  
+<para>Q. I compiled my program and it seemed to run all right at
+first, then there was an error and it said something about <errorname>core
+dumped</errorname>. What does that mean?</para>
+
+<para>A. The name <firstterm>core dump</firstterm> dates back to the
+very early days of Unix, when the machines used core memory for
+storing data. Basically, if the program failed under certain
+conditions, the system would write the contents of core memory to
+disk in a file called <filename>core</filename>, which the programmer
+could then pore over to find out what went wrong.</para>
+
+<para>Q. Fascinating stuff, but what I am supposed to do now?</para>
+  
+<para>A. Use <command>gdb</command> to analyse the core (see <xref
+linkend="debugging">).</para>
+  
+<para>Q. When my program dumped core, it said something about a
+<errorname>segmentation fault</errorname>. What's that?</para>
+
+<para>A. This basically means that your program tried to perform some sort
+of illegal operation on memory; Unix is designed to protect the
+operating system and other programs from rogue programs.</para>
+  
+<para>Common causes for this are:
+<itemizedlist>
+<listitem><para>Trying to write to a <symbol>NULL</symbol> pointer, eg
+<programlisting>char *foo = NULL;
+strcpy(foo, "bang!");</programlisting>
+</para></listitem>
+
+<listitem><para>Using a pointer that hasn't been initialised, eg
+<programlisting>char *foo;
+strcpy(foo, "bang!");</programlisting>
+The pointer will have some random value that, with luck,
+will point into an area of memory that isn't available to
+your program and the kernel will kill your program before
+it can do any damage. If you're unlucky, it'll point
+somewhere inside your own program and corrupt one of your
+data structures, causing the program to fail
+mysteriously.</para></listitem>
+
+<listitem><para>Trying to access past the end of an array, eg
+<programlisting>int bar[20];
+bar[27] = 6;</programlisting></para></listitem>
+
+<listitem><para> Trying to store something in read-only memory, eg
+<programlisting>char *foo = "My string";
+strcpy(foo, "bang!");</programlisting>
+Unix compilers often put string literals like
+<literal>"My string"</literal> into
+read-only areas of memory.</para></listitem>
+
+<listitem><para>Doing naughty things with
+<function>malloc()</function> and <function>free()</function>, eg
+<programlisting>char bar[80];
+free(bar);</programlisting>
+or
+<programlisting>char *foo = malloc(27);
+free(foo);
+free(foo);</programlisting>
+</para></listitem>
+
+</itemizedlist></para>
+
+<para>Making one of these mistakes will not always lead to an
+error, but they are always bad practice. Some systems and
+compilers are more tolerant than others, which is why programs
+that ran well on one system can crash when you try them on an
+another.</para>
+  
+<para>Q. Sometimes when I get a core dump it says <errorname>bus
+error</errorname>. It says in my Unix book that this means a hardware
+problem, but the computer still seems to be working. Is this
+true?</para>
+
+<para>A. No, fortunately not (unless of course you really do have a hardware
+problem&hellip;). This is usually another way of saying that you
+accessed memory in a way you shouldn't have.</para>
+  
+<para>Q. This dumping core business sounds as though it could be quite
+useful, if I can make it happen when I want to. Can I do this, or
+do I have to wait until there's an error?</para>
+  
+<para>A. Yes, just go to another console or xterm, do
+<screen>$ <userinput>ps</userinput></screen>
+to find out the process ID of your program, and do
+<screen>$ <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
+where <parameter><replaceable>pid</replaceable></parameter> is the
+process ID you looked up.</para>
+  
+<para>This is useful if your program has got stuck in an infinite
+loop, for instance. If your program happens to trap
+<symbol>SIGABRT</symbol>, there are several other signals which have
+a similar effect.</para>
+
+</sect1>
+</chapter>
+
+
+<chapter>
+<title>Make</title>
+
+<sect1>
+<title>What is <command>make</command>?</title>
+
+<para>When you're working on a simple program with only one or two source
+files, typing in
+<screen>$ <userinput>cc file1.c file2.c</userinput></screen>
+is not too bad, but it quickly becomes very tedious when there are
+several files&mdash;and it can take a while to compile, too.</para>
+  
+<para>One way to get around this is to use object files and only recompile
+the source file if the source code has changed. So we could have
+something like:
+<screen>$ <userinput>cc file1.o file2.o</userinput> &hellip; <userinput>file37.c</userinput> &hellip</screen>
+if we'd changed <filename>file37.c</filename>, but not any of the
+others, since the last time we compiled.  This may speed up the
+compilation quite a bit, but  doesn't solve the typing
+problem.</para>
+
+<para>Or we could write a shell script to solve the typing problem, but it
+would have to re-compile everything, making it very inefficient on a
+large project.</para>
+  
+<para>What happens if we have hundreds of source files lying about? What if
+we're working in a team with other people who forget to tell us when
+they've changed one of their source files that we use?</para>
+  
+<para>Perhaps we could put the two solutions together and write something
+like a shell script that would contain some kind of magic rule saying
+when a source file needs compiling. Now all we need now is a program
+that can understand these rules, as it's a bit too complicated for the
+shell.</para>
+  
+<para>This program is called <command>make</command>. It reads in a
+file, called a <firstterm>makefile</firstterm>, that tells it how
+different files depend on each other, and works out which files need
+to be re-compiled and which ones don't. For example, a rule could say
+something like <quote>if <filename>fromboz.o</filename> is older than
+<filename>fromboz.c</filename>, that means someone must have changed
+<filename>fromboz.c</filename>, so it needs to be
+re-compiled.</quote> The makefile also has rules telling make
+<emphasis>how</emphasis> to re-compile the source file, making it a
+much more powerful tool.</para>
+
+<para>Makefiles are typically kept in the same directory as the
+source they apply to, and can be called
+<filename>makefile</filename>, <filename>Makefile</filename> or
+<filename>MAKEFILE</filename>. Most programmers use the name
+<filename>Makefile</filename>, as this puts it near the top of a
+directory listing, where it can easily be seen.<footnote><para>They
+don't use the <filename>MAKEFILE</filename> form as block capitals
+are often used for documentation files like
+<filename>README</filename>.</para></footnote></para>
+  
+</sect1>
+
+<sect1>
+<title>Example of using <command>make</command></title>
+
+<para>Here's a very simple make file:
+<programlisting>foo: foo.c
+	cc -o foo foo.c</programlisting>
+It consists of two lines, a dependency line and a creation line.</para>
+  
+<para>The dependency line here consists of the name of the program
+(known as the <firstterm>target</firstterm>), followed by a colon,
+then whitespace, then the name of the source file. When
+<command>make</command> reads this line, it looks to see if
+<filename>foo</filename> exists; if it exists, it compares the time
+<filename>foo</filename> was last modified to the time
+<filename>foo.c</filename> was last modified. If
+<filename>foo</filename> does not exist, or is older than
+<filename>foo.c</filename>, it then looks at the creation line to
+find out what to do. In other words, this is the rule for working out
+when <filename>foo.c</filename> needs to be re-compiled.</para>
+
+<para>The creation line starts with a <token>tab</token> (press the
+<keycap>tab</keycap> key) and then the command you would type to
+create <filename>foo</filename> if you were doing it at a command
+prompt. If <filename>foo</filename> is out of date, or does not
+exist, <command>make</command> then executes this command to create
+it. In other words, this is the rule which tells make how to
+re-compile <filename>foo.c</filename>.</para>
+
+<para>So, when you type <userinput>make</userinput>, it will make
+sure that <filename>foo</filename> is up to date with respect to your
+latest changes to <filename>foo.c</filename>. This principle can be
+extended to <filename>Makefile</filename>s with hundreds of
+targets&mdash;in fact, on FreeBSD, it is possible to compile the
+entire operating system just by typing <userinput>make
+world</userinput> in the appropriate directory!</para>
+
+<para>Another useful property of makefiles is that the targets don't have
+to be programs. For instance, we could have a make file that looks
+like this:
+<programlisting>foo: foo.c
+	cc -o foo foo.c
+
+install:
+	cp foo /home/me</programlisting></para>
+  
+<para>We can tell make which target we want to make by typing:
+<screen>$ <userinput>make <replaceable>target</replaceable></userinput></screen>
+<command>make</command> will then only look at that target and ignore any
+others. For example, if we type <userinput>make foo</userinput> with the 
+makefile above, make will ignore the <action>install</action> target.</para>
+  
+<para>If we just type <userinput>make</userinput> on its own, make
+will always look at the first target and then stop without looking at
+any others. So if we typed <userinput>make</userinput> here, it will
+just go to the <action>foo</action> target, re-compile
+<filename>foo</filename> if necessary, and then stop without going on
+to the <action>install</action> target.</para>
+
+<para>Notice that the <action>install</action> target doesn't
+actually depend on anything! This means that the command on the
+following line is always executed when we try to make that target by
+typing <userinput>make install</userinput>. In this case, it will
+copy <filename>foo</filename> into the user's home directory. This is
+often used by application makefiles, so that the application can be
+installed in the correct directory when it has been correctly
+compiled.</para>
+
+<para>This is a slightly confusing subject to try and explain. If you
+don't quite understand how <command>make</command> works, the best
+thing to do is to write a simple program like <quote>hello
+world</quote> and a make file like the one above and experiment. Then
+progress to using more than one source file, or having the source
+file include a header file. The <command>touch</command> command is
+very useful here&mdash;it changes the date on a file without you
+having to edit it.</para>
+  
+</sect1>
+
+<sect1>
+<title>FreeBSD Makefiles</title>
+
+<para>Makefiles can be rather complicated to write. Fortunately,
+BSD-based systems like FreeBSD come with some very powerful ones as
+part of the system.  One very good example of this is the FreeBSD
+ports system. Here's the essential part of a typical ports
+<filename>Makefile</filename>:
+<programlisting>MASTER_SITES=   ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
+DISTFILES=      scheme-microcode+dist-7.3-freebsd.tgz
+
+.include &lt;bsd.port.mk&gt;</programlisting></para>
+  
+<para>Now, if we go to the directory for this port and type
+<userinput>make</userinput>, the following happens:</para>
+
+<procedure>
+<step><para>A check is made to see if the source code for this port is
+already on the system.</para></step>
+
+<step><para>If it isn't, an FTP connection to the URL in
+<symbol>MASTER_SITES</symbol> is set up to download the
+source.</para></step>
+
+<step><para>The checksum for the source is calculated and compared it with
+one for a known, good, copy of the source. This is to make sure that
+the source was not corrupted while in transit.</para></step>
+
+<step><para>Any changes required to make the source work on FreeBSD are
+applied&mdash;this is known as <firstterm>patching</firstterm>.</para></step>
+
+<step><para>Any special configuration needed for the source is done.
+(Many Unix program distributions try to work out which version of
+Unix they are being compiled on and which optional Unix features are
+present&mdash;this is where they are given the information in the
+FreeBSD ports scenario).</para></step>
+
+<step><para>The source code for the program is compiled. In effect,
+we change to the directory where the source was unpacked and do
+<command>make</command>&mdash;the program's own make file has the
+necessary information to build the program.</para></step>
+
+<step><para>We now have a compiled version of the program. If we
+wish, we can test it now; when we feel confident about the program,
+we can type <userinput>make install</userinput>. This will cause the
+program and any supporting files it needs to be copied into the
+correct location; an entry is also made into a <database>package
+database</database>, so that the port can easily be uninstalled later
+if we change our mind about it.</para></step>
+
+</procedure>
+  
+<para>Now I think you'll agree that's rather impressive for a four
+line script!</para>
+
+<para>The secret lies in the last line, which tells
+<command>make</command> to look in the system makefile called
+<filename>bsd.port.mk</filename>. It's easy to overlook this line,
+but this is where all the clever stuff comes from&mdash;someone has
+written a makefile that tells <command>make</command> to do all the
+things above (plus a couple of other things I didn't mention,
+including handling any errors that may occur) and anyone can get
+access to that just by putting a single line in their own make
+file!</para>
+
+<para>If you want to have a look at these system makefiles, they're
+in <filename>/usr/share/mk</filename>, but it's probably best to wait
+until you've had a bit of practice with makefiles, as they are very
+complicated (and if you do look at them, make sure you have a flask
+of strong coffee handy!)</para>
+
+</sect1>
+
+<sect1>
+<title>More advanced uses of <command>make</command></title>
+
+<para><command>Make</command> is a very powerful tool, and can do much
+more than the simple example above shows. Unfortunately, there are
+several different versions of <command>make</command>, and they all
+differ considerably. The best way to learn what they can do is
+probably to read the documentation&mdash;hopefully this introduction will
+have given you a base from which you can do this.</para>
+
+<para>The version of make that comes with FreeBSD is the <application>Berkeley
+make</application>; there is a tutorial for it in
+<filename>/usr/share/doc/psd/12.make</filename>. To view it, do
+<screen>$ <userinput>zmore paper.ascii.gz</userinput></screen>
+in that directory.</para>
+  
+<para>Many applications in the ports use <application>GNU
+make</application>, which has a very good set of <quote>info</quote>
+pages. If you have installed any of these ports, <application>GNU
+make</application> will automatically have been installed as
+<command>gmake</command>. It's also available as a port and package
+in its own right.</para>
+
+<para>To view the info pages for <application>GNU make</application>,
+you will have to edit the <filename>dir</filename> file in the
+<filename>/usr/local/info</filename> directory to add an entry for
+it. This involves adding a line like
+<programlisting> * Make: (make).                 The GNU Make utility.</programlisting>
+to the file. Once you have done this, you can type
+<userinput>info</userinput> and then select
+<guimenuitem>make</guimenuitem> from the menu (or in
+<application>Emacs</application>, do <userinput>C-h
+i</userinput>).</para>
+
+</sect1>
+</chapter>
+
+<chapter id="debugging">
+<title>Debugging</title>
+
+<sect1>
+<title>The Debugger</title>
+
+<para>The debugger that comes with FreeBSD is called
+<command>gdb</command> (<application>GNU
+debugger</application>). You start it up by typing
+<screen>$ <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
+although most people prefer to run it inside
+<application>Emacs</application>. You can do this by:
+<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen></para>
+  
+<para>Using a debugger allows you to run the program under more
+controlled circumstances. Typically, you can step through the program
+a line at a time, inspect the value of variables, change them, tell
+the debugger to run up to a certain point and then stop, and so on.
+You can even attach to a program that's already running, or load a
+core file to investigate why the program crashed. It's even possible
+to debug the kernel, though that's a little trickier than the user
+applications we'll be discussing in this section.</para>
+
+<para><command>gdb</command> has quite good on-line help, as well as
+a set of info pages, so this section will concentrate on a few of the
+basic commands.</para>
+
+<para>Finally, if you find its text-based command-prompt style
+off-putting, there's a graphical front-end for it <ulink
+URL="http://www.freebsd.org/ports/devel.html">xxgdb</ulink>
+in the ports collection.</para>
+
+<para>This section is intended to be an introduction to using
+<command>gdb</command> and does not cover specialised topics such as
+debugging the kernel.</para>
+  
+</sect1>
+
+<sect1>
+<title>Running a program in the debugger</title>
+
+<para>You'll need to have compiled the program with the
+<option>-g</option> option to get the most out of using
+<command>gdb</command>. It will work without, but you'll only see the
+name of the function you're in, instead of the source code. If you
+see a line like:
+<screen>&hellip; (no debugging symbols found) &hellip;</screen>when
+<command>gdb</command> starts up, you'll know that the program wasn't
+compiled with the <option>-g</option> option.</para>
+  
+<para>At the <command>gdb</command> prompt, type <userinput>break
+main</userinput>. This will tell the debugger to skip over the
+preliminary set-up code in the program and start at the beginning of
+your code. Now type <userinput>run</userinput> to start the
+program&mdash;it will start at the beginning of the set-up code and
+then get stopped by the debugger when it calls
+<function>main()</function>. (If you've ever wondered where
+<function>main()</function> gets called from, now you know!).</para>
+
+<para>You can now step through the program, a line at a time, by
+pressing <command>n</command>.  If you get to a function call, you can
+step into it by pressing <command>s</command>. Once you're in a
+function call, you can return from stepping into a function call by
+pressing <command>f</command>. You can also use <command>up</command> and
+<command>down</command> to take a quick look at the caller.</para>
+
+<para>Here's a simple example of how to spot a mistake in a program
+with <command>gdb</command>. This is our program (with a deliberate
+mistake):
+<programlisting>#include &lt;stdio.h&gt;
+
+int bazz(int anint);
+
+main() {
+	int i;
+
+	printf("This is my program\n");
+	bazz(i);
+	return 0;
+}
+
+int bazz(int anint) {
+	printf("You gave me %d\n", anint);
+	return anint;
+}</programlisting>
+</para>
+  
+<para>This program sets <symbol>i</symbol> to be <literal>5</literal>
+and passes it to a function <function>bazz()</function> which prints
+out the number we gave it.</para>
+
+<para>When we compile and run the program we get
+<screen>$ <userinput>cc -g -o temp temp.c</userinput>
+$ <userinput>./temp</userinput>
+This is my program
+anint = 4231</screen></para>
+  
+<para>That wasn't what we expected! Time to see what's going
+on!<screen>$ <userinput>gdb temp</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>break main</>				<lineannotation>Skip the set-up code</>
+Breakpoint 1 at 0x160f: file temp.c, line 9.	<lineannotation><command>gdb</command> puts breakpoint at <function>main()</></>
+(gdb) <userinput>run</>					<lineannotation>Run as far as <function>main()</></>
+Starting program: /home/james/tmp/temp		<lineannotation>Program starts running</>
+
+Breakpoint 1, main () at temp.c:9		<lineannotation><command>gdb</command> stops at <function>main()</></>
+(gdb) <userinput>n</>						<lineannotation>Go to next line</>
+This is my program				<lineannotation>Program prints out</>
+(gdb) <userinput>s</>						<lineannotation>step into <function>bazz()</></>
+bazz (anint=4231) at temp.c:17			<lineannotation><command>gdb</command> displays stack frame</>
+(gdb)</screen></para>
+
+  
+<para>Hang on a minute! How did <symbol>anint</symbol> get to be
+<literal>4231</literal>? Didn't we set it to be <literal>5</literal>
+in <function>main()</function>? Let's move up to
+<function>main()</function> and have a look.</para>
+
+<para><screen>(gdb) <userinput>up</>					<lineannotation>Move up call stack</>
+#1  0x1625 in main () at temp.c:11		<lineannotation><command>gdb</command> displays stack frame</>
+(gdb) <userinput>p i</>					<lineannotation>Show us the value of <symbol>i</></>
+$1 = 4231					<lineannotation><command>gdb</command> displays <literal>4231</></></screen>
+Oh dear! Looking at the code, we forgot to initialise
+<symbol>i</symbol>. We meant to put
+<programlisting><lineannotation>&hellip;</>
+main() {
+	int i;
+
+	i = 5;
+	printf("This is my program\n");
+<lineannotation>&hellip</></programlisting>
+but we left the <literal>i=5;</literal> line out.  As we didn't
+initialise <symbol>i</symbol>, it had whatever number happened to be
+in that area of memory when the program ran, which in this case
+happened to be <literal>4231</literal>.</para>
+
+<note><para><command>gdb</command> displays the stack frame
+every time we go into or out of a function, even if we're using
+<command>up</command> and <command>down</command> to move around the
+call stack.  This shows the name of the function and the values of
+its arguments, which helps us keep track of where we are and what's
+going on. (The stack is a storage area where the program stores
+information about the arguments passed to functions and where to go
+when it returns from a function call).</para></note>
+
+</sect1>
+
+<sect1>
+<title>Examining a core file</title>
+
+<para>A core file is basically a file which contains the complete
+state of the process when it crashed. In <quote>the good old
+days</quote>, programmers had to print out hex listings of core files
+and sweat over machine code manuals, but now life is a bit easier.
+Incidentally, under FreeBSD and other 4.4BSD systems, a core file is
+called <filename><replaceable>progname</>.core</> instead of just
+<filename>core</filename>, to make it clearer which program a core
+file belongs to.</para>
+
+<para>To examine a core file, start up <command>gdb</command> in the
+usual way. Instead of typing <command>break</command> or
+<command>run</command>, type
+<screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
+If you're not in the same directory as the core file, you'll have to
+do <userinput>dir /path/to/core/file</userinput> first.</para>
+  
+<para>You should see something like this:
+<screen>$ <userinput>gdb a.out</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>core a.out.core</userinput>
+Core was generated by `a.out'.
+Program terminated with signal 11, Segmentation fault.
+Cannot access memory at address 0x7020796d.
+#0  0x164a in bazz (anint=0x5) at temp.c:17
+(gdb)</screen></para>
+  
+<para>In this case, the program was called
+<filename>a.out</filename>, so the core file is called
+<filename>a.out.core</filename>. We can see that the program crashed
+due to trying to access an area in memory that was not available to
+it in a function called <function>bazz</function>.</para>
+
+<para>Sometimes it's useful to be able to see how a function was
+called, as the problem could have occurred a long way up the call
+stack in a complex program. The <command>bt</command> command causes
+<command>gdb</command> to print out a back-trace of the call
+stack:
+<screen>(gdb) <userinput>bt</userinput>
+#0  0x164a in bazz (anint=0x5) at temp.c:17
+#1  0xefbfd888 in end ()
+#2  0x162c in main () at temp.c:11
+(gdb)</screen>The <function>end()</function> function is called when
+a program crashes; in this case, the <function>bazz()</function>
+function was called from <function>main()</function>.</para>
+
+</sect1>
+
+<sect1>
+<title>Attaching to a running program</title>
+
+<para>One of the neatest features about <command>gdb</command> is
+that it can attach to a program that's already running. Of course,
+that assumes you have sufficient permissions to do so. A common
+problem is when you are stepping through a program that forks, and
+you want to trace the child, but the debugger will only let you trace
+the parent.</para>
+
+<para>What you do is start up another <command>gdb</command>, use
+<command>ps</command> to find the process ID for the child, and
+do<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>  
+in <command>gdb</command>, and then debug as usual.</para>
+  
+<para><quote>That's all very well,</quote> you're probably thinking,
+<quote>but by the time I've done that, the child process will be over
+the hill and far away</quote>. Fear not, gentle reader, here's how to
+do it (courtesy of the <command>gdb</command> info pages):
+<screen><lineannotation>&hellip</lineannotation>
+if ((pid = fork()) < 0)		/* _Always_ check this */
+	error();
+else if (pid == 0) {		/* child */
+	int PauseMode = 1;
+
+	while (PauseMode)
+		sleep(10);	/* Wait until someone attaches to us */
+	<lineannotation>&hellip</lineannotation>
+} else {			/* parent */
+	<lineannotation>&hellip</lineannotation></screen>
+Now all you have to do is attach to the child, set
+<symbol>PauseMode</symbol> to <literal>0</literal>, and
+wait for the <function>sleep()</function> call to return!</para>
+  
+</sect1>
+</chapter>
+
+<chapter id="emacs">
+<title>Using Emacs as a Development Environment</title>
+
+<sect1>
+<title>Emacs</title>
+
+<para>Unfortunately, Unix systems don't come with the kind of
+everything-you-ever-wanted-and-lots-more-you-didn't-in-one-gigantic-package
+integrated development environments that other systems
+have.<footnote><para>At least, not unless you pay out very large sums
+of money.</para></footnote> However, it is possible to set up your
+own environment. It may not be as pretty, and it may not be quite as
+integrated, but you can set it up the way you want it. And it's free.
+And you have the source to it.</para>
+
+<para>The key to it all is Emacs. Now there are some people who
+loathe it, but many who love it. If you're one of the former, I'm
+afraid this section will hold little of interest to you. Also, you'll
+need a fair amount of memory to run it&mdash;I'd recommend 8MB in
+text mode and 16MB in X as the bare minimum to get reasonable
+performance.</para>
+
+<para>Emacs is basically a highly customisable editor&mdash;indeed,
+it has been customised to the point where it's more like an operating
+system than an editor! Many developers and sysadmins do in fact
+spend practically all their time working inside Emacs, leaving it
+only to log out.</para>
+
+<para>It's impossible even to summarise everything Emacs can do here, but
+here are some of the features of interest to developers:
+<itemizedlist>
+
+<listitem><para>Very powerful editor, allowing search-and-replace on
+both strings and regular expressions (patterns), jumping to start/end
+of block expression, etc, etc.</para></listitem>
+
+<listitem><para>Pull-down menus and online help.</para></listitem>
+
+<listitem><para>Language-dependent syntax highlighting and
+indentation.</para></listitem>
+
+<listitem><para>Completely customisable.</para></listitem>
+
+<listitem><para>You can compile and debug programs within
+Emacs.</para></listitem>
+
+<listitem><para>On a compilation error, you can jump to the offending
+line of source code.</para></listitem>
+
+<listitem><para>Friendly-ish front-end to the <command>info</command>
+program used for reading GNU hypertext documentation, including the
+documentation on Emacs itself.</para></listitem>
+
+<listitem><para>Friendly front-end to <command>gdb</command>,
+allowing you to look at the source code as you step through your
+program.</para></listitem>
+
+<listitem><para>You can read Usenet news and mail while your program
+is compiling.</para></listitem>
+
+</itemizedlist>And doubtless many more that I've overlooked.</para>
+
+<para>Emacs can be installed on FreeBSD using <ulink
+URL="http://www.freebsd.org/ports/editors">the Emacs
+port</ulink>.</para>
+
+<para>Once it's installed, start it up and do <userinput>C-h
+t</userinput> to read an Emacs tutorial&mdash;that means hold down
+the <keycap>control</keycap> key, press <keycap>h</keycap>, let go of
+the <keycap>control</keycap> key, and then press <keycap>t</keycap>.
+(Alternatively, you can you use the mouse to select <guimenuitem>Emacs
+Tutorial</guimenuitem> from the <guimenu>Help</guimenu> menu).</para>
+
+<para>Although Emacs does have menus, it's well worth learning the
+key bindings, as it's much quicker when you're editing something to
+press a couple of keys than to try and find the mouse and then click
+on the right place. And, when you're talking to seasoned Emacs users,
+you'll find they often casually throw around expressions like
+<quote><literal>M-x replace-s RET foo RET bar RET</literal></quote>
+so it's useful to know what they mean. And in any case, Emacs has far
+too many useful functions for them to all fit on the menu
+bars.</para>
+
+<para>Fortunately, it's quite easy to pick up the key-bindings, as
+they're displayed next to the menu item. My advice is to use the
+menu item for, say, opening a file until you understand how it works
+and feel confident with it, then try doing C-x C-f. When you're happy
+with that, move on to another menu command.</para>
+
+<para>If you can't remember what a particular combination of keys
+does, select <guimenuitem>Describe Key</guimenuitem> from the
+<guimenu>Help</guimenu> menu and type it in&mdash;Emacs will tell you
+what it does. You can also use the <guimenuitem>Command
+Apropos</guimenuitem> menu item to find out all the commands which
+contain a particular word in them, with the key binding next to
+it.</para>
+
+<para>By the way, the expression above means hold down the
+<keysym>Meta</keysym> key, press <keysym>x</keysym>, release the
+<keysym>Meta</keysym> key, type <userinput>replace-s</userinput>
+(short for <literal>replace-string</literal>&mdash;another feature of
+Emacs is that you can abbreviate commands), press the
+<keysym>return</keysym> key, type <userinput>foo</userinput> (the
+string you want replaced), press the <keysym>return</keysym> key,
+type bar (the string you want to replace <literal>foo</literal> with)
+and press <keysym>return</keysym> again. Emacs will then do the
+search-and-replace operation you've just requested.</para>
+
+<para>If you're wondering what on earth the <keysym>Meta</keysym> key
+is, it's a special key that many Unix workstations have.
+Unfortunately, PC's don't have one, so it's usually the
+<keycap>alt</keycap> key (or if you're unlucky, the <keysym>escape</keysym>
+key).</para>
+
+<para>Oh, and to get out of Emacs, do <command>C-c C-x</command>
+(that means hold down the <keysym>control</keysym> key, press
+<keysym>c</keysym>, press <keysym>x</keysym> and release the
+<keysym>control</keysym> key). If you have any unsaved files open,
+Emacs will ask you if you want to save them. (Ignore the bit in the
+documentation where it says <command>C-z</command> is the usual way
+to leave Emacs&mdash;that leaves Emacs hanging around in the
+background, and is only really useful if you're on a system which
+doesn't have virtual terminals).</para>
+
+</sect1>
+
+<sect1>
+<title>Configuring Emacs</title>
+
+<para>Emacs does many wonderful things; some of them are built in,
+some of them need to be configured.</para>
+
+<para>Instead of using a proprietary macro language for
+configuration, Emacs uses a version of Lisp specially adapted for
+editors, known as Emacs Lisp. This can be quite useful if you want to
+go on and learn something like Common Lisp, as it's considerably
+smaller than Common Lisp (although still quite big!).</para>
+
+<para>The best way to learn Emacs Lisp is to download the <ulink
+URL="ftp://prep.ai.mit.edu:pub/gnu/elisp-manual-19-2.4.tar.gz">Emacs
+Tutorial</ulink></para>
+
+<para>However, there's no need to actually know any Lisp to get
+started with configuring Emacs, as I've included a sample
+<filename>.emacs</filename> file, which should be enough to get you
+started. Just copy it into your home directory and restart Emacs if
+it's already running; it will read the commands from the file and
+(hopefully) give you a useful basic setup.</para>
+
+</sect1>
+
+<sect1>
+<title>A sample <filename>.emacs</filename> file</title>
+
+<para>Unfortunately, there's far too much here to explain it in detail;
+however there are one or two points worth mentioning.</para>
+  
+<para>
+<itemizedlist>
+
+<listitem><para>Everything beginning with a <literal>;</> is a
+comment and is ignored by Emacs.</para></listitem>
+
+<listitem><para>In the first line, the
+<literal>-*-&nbsp;Emacs-Lisp&nbsp;-*-</literal> is so that we can
+edit the <filename>.emacs</filename> file itself within Emacs and get
+all the fancy features for editing Emacs Lisp. Emacs usually tries to
+guess this based on the filename, and may not get it right for
+<filename>.emacs</filename>. </para></listitem>
+
+<listitem><para>The <keysym>tab</keysym> key is bound to an
+indentation function in some modes, so when you press the tab key, it
+will indent the current line of code. If you want to put a
+<token>tab</token> character in whatever you're writing, hold the
+<keysym>control</keysym> key down while you're pressing the
+<keysym>tab</keysym> key.</para></listitem>
+
+<listitem><para>This file supports syntax highlighting for C, C++,
+Perl, Lisp and Scheme, by guessing the language from the
+filename.</para></listitem>
+
+<listitem><para>Emacs already has a pre-defined function called
+<function>next-error</function>. In a compilation output window, this
+allows you to move from one compilation error to the next by doing
+<command>M-n</command>; we define a complementary function,
+<function>previous-error</function>, that allows you to go to a
+previous error by doing <command>M-p</command>. The nicest feature of
+all is that <command>C-c C-c</command> will open up the source file
+in which the error occurred and jump to the appropriate
+line.</para></listitem>
+
+<listitem><para> We enable Emacs's ability to act as a server, so
+that if you're doing something outside Emacs and you want to edit a
+file, you can just type in 
+<screen>$ <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
+and then you can edit the file in your Emacs!<footnote><para>Many
+Emacs users set their <systemitem
+class=environvar>EDITOR</systemitem> environment to
+<literal>emacsclient</literal> so this happens every time they need
+to edit a file.</para></footnote></para></listitem>
+
+</itemizedlist>
+</para>
+  
+<example>
+<title>A sample <filename>.emacs</filename> file</title>
+<screen>;; -*-Emacs-Lisp-*-
+
+;; This file is designed to be re-evaled; use the variable first-time
+;; to avoid any problems with this.
+(defvar first-time t 
+  "Flag signifying this is the first time that .emacs has been evaled")
+
+;; Meta
+(global-set-key "\M- " 'set-mark-command)
+(global-set-key "\M-\C-h" 'backward-kill-word)
+(global-set-key "\M-\C-r" 'query-replace)
+(global-set-key "\M-r" 'replace-string)
+(global-set-key "\M-g" 'goto-line)
+(global-set-key "\M-h" 'help-command)
+
+;; Function keys
+(global-set-key [f1] 'manual-entry)
+(global-set-key [f2] 'info)
+(global-set-key [f3] 'repeat-complex-command)
+(global-set-key [f4] 'advertised-undo)
+(global-set-key [f5] 'eval-current-buffer)
+(global-set-key [f6] 'buffer-menu)
+(global-set-key [f7] 'other-window)
+(global-set-key [f8] 'find-file)
+(global-set-key [f9] 'save-buffer)
+(global-set-key [f10] 'next-error)
+(global-set-key [f11] 'compile)
+(global-set-key [f12] 'grep)
+(global-set-key [C-f1] 'compile)
+(global-set-key [C-f2] 'grep)
+(global-set-key [C-f3] 'next-error)
+(global-set-key [C-f4] 'previous-error)
+(global-set-key [C-f5] 'display-faces)
+(global-set-key [C-f8] 'dired)
+(global-set-key [C-f10] 'kill-compilation)
+
+;; Keypad bindings
+(global-set-key [up] "\C-p")
+(global-set-key [down] "\C-n")
+(global-set-key [left] "\C-b")
+(global-set-key [right] "\C-f")
+(global-set-key [home] "\C-a")
+(global-set-key [end] "\C-e")
+(global-set-key [prior] "\M-v")
+(global-set-key [next] "\C-v")
+(global-set-key [C-up] "\M-\C-b")
+(global-set-key [C-down] "\M-\C-f")
+(global-set-key [C-left] "\M-b")
+(global-set-key [C-right] "\M-f")
+(global-set-key [C-home] "\M-&lt;")
+(global-set-key [C-end] "\M-&gt;")
+(global-set-key [C-prior] "\M-&lt;")
+(global-set-key [C-next] "\M-&gt;")
+
+;; Mouse
+(global-set-key [mouse-3] 'imenu)
+
+;; Misc
+(global-set-key [C-tab] "\C-q\t")	; Control tab quotes a tab.
+(setq backup-by-copying-when-mismatch t)
+
+;; Treat 'y' or &lt;CR&gt; as yes, 'n' as no.
+(fset 'yes-or-no-p 'y-or-n-p)
+    (define-key query-replace-map [return] 'act)
+    (define-key query-replace-map [?\C-m] 'act)
+
+;; Load packages
+(require 'desktop)
+(require 'tar-mode)
+
+;; Pretty diff mode
+(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files-remote "ediff"
+  "Intelligent Emacs interface to diff") </screen>
+
+<screen>(if first-time
+    (setq auto-mode-alist
+	  (append '(("\\.cpp$" . c++-mode)
+		    ("\\.hpp$" . c++-mode)
+                    ("\\.lsp$" . lisp-mode)
+		    ("\\.scm$" . scheme-mode)
+		    ("\\.pl$" . perl-mode)
+		    ) auto-mode-alist)))
+
+;; Auto font lock mode
+(defvar font-lock-auto-mode-list 
+  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
+  "List of modes to always start in font-lock-mode")
+
+(defvar font-lock-mode-keyword-alist
+  '((c++-c-mode . c-font-lock-keywords)
+    (perl-mode . perl-font-lock-keywords))
+  "Associations between modes and keywords")
+
+(defun font-lock-auto-mode-select ()
+  "Automatically select font-lock-mode if the current major mode is
+in font-lock-auto-mode-list"
+  (if (memq major-mode font-lock-auto-mode-list) 
+      (progn
+	(font-lock-mode t))
+    )
+  )
+
+(global-set-key [M-f1] 'font-lock-fontify-buffer)
+
+;; New dabbrev stuff
+;(require 'new-dabbrev)
+(setq dabbrev-always-check-other-buffers t)
+(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+(add-hook 'emacs-lisp-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
+	     (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'c-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
+	     (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'text-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) t)
+	     (set (make-local-variable 'dabbrev-case-replace) t)))
+
+;; C++ and C mode...
+(defun my-c++-mode-hook ()
+  (setq tab-width 4)
+  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key c++-mode-map "\C-ce" 'c-comment-edit)
+  (setq c++-auto-hungry-initial-state 'none)
+  (setq c++-delete-function 'backward-delete-char)
+  (setq c++-tab-always-indent t)
+  (setq c-indent-level 4)
+  (setq c-continued-statement-offset 4)
+  (setq c++-empty-arglist-indent 4))
+
+(defun my-c-mode-hook ()
+  (setq tab-width 4)
+  (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key c-mode-map "\C-ce" 'c-comment-edit)
+  (setq c-auto-hungry-initial-state 'none)
+  (setq c-delete-function 'backward-delete-char)
+  (setq c-tab-always-indent t)
+;; BSD-ish indentation style
+  (setq c-indent-level 4)
+  (setq c-continued-statement-offset 4)
+  (setq c-brace-offset -4)
+  (setq c-argdecl-indent 0)
+  (setq c-label-offset -4))
+
+;; Perl mode
+(defun my-perl-mode-hook ()
+  (setq tab-width 4)
+  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (setq perl-indent-level 4)
+  (setq perl-continued-statement-offset 4))
+
+;; Scheme mode...
+(defun my-scheme-mode-hook ()
+  (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
+
+;; Emacs-Lisp mode...
+(defun my-lisp-mode-hook ()
+  (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
+  (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
+
+;; Add all of the hooks...
+(add-hook 'c++-mode-hook 'my-c++-mode-hook)
+(add-hook 'c-mode-hook 'my-c-mode-hook)
+(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
+(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'perl-mode-hook 'my-perl-mode-hook)
+
+;; Complement to next-error
+(defun previous-error (n)
+  "Visit previous compilation error message and corresponding source code."
+  (interactive "p")
+  (next-error (- n)))</screen>
+
+<screen>;; Misc...
+(transient-mark-mode 1)
+(setq mark-even-if-inactive t)
+(setq visible-bell nil)
+(setq next-line-add-newlines nil)
+(setq compile-command "make")
+(setq suggest-key-bindings nil)
+(put 'eval-expression 'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+(put 'set-goal-column 'disabled nil)
+
+;; Elisp archive searching
+(autoload 'format-lisp-code-directory "lispdir" nil t)
+(autoload 'lisp-dir-apropos "lispdir" nil t)
+(autoload 'lisp-dir-retrieve "lispdir" nil t)
+(autoload 'lisp-dir-verify "lispdir" nil t)
+
+;; Font lock mode
+(defun my-make-face (face colour &amp;optional bold)
+  "Create a face from a colour and optionally make it bold"
+  (make-face face)
+  (copy-face 'default face)
+  (set-face-foreground face colour)
+  (if bold (make-face-bold face))
+  )
+
+(if (eq window-system 'x)
+    (progn
+      (my-make-face 'blue "blue")
+      (my-make-face 'red "red")
+      (my-make-face 'green "dark green")
+      (setq font-lock-comment-face 'blue)
+      (setq font-lock-string-face 'bold)
+      (setq font-lock-type-face 'bold)
+      (setq font-lock-keyword-face 'bold)
+      (setq font-lock-function-name-face 'red)
+      (setq font-lock-doc-string-face 'green)
+      (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
+
+      (setq baud-rate 1000000)
+      (global-set-key "\C-cmm" 'menu-bar-mode)
+      (global-set-key "\C-cms" 'scroll-bar-mode)
+      (global-set-key [backspace] 'backward-delete-char)
+					;      (global-set-key [delete] 'delete-char)
+      (standard-display-european t)
+      (load-library "iso-transl")))
+
+;; X11 or PC using direct screen writes
+(if window-system
+    (progn
+      ;;      (global-set-key [M-f1] 'hilit-repaint-command)
+      ;;      (global-set-key [M-f2] [?\C-u M-f1])
+      (setq hilit-mode-enable-list  
+	    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
+		  scheme-mode)
+	    hilit-auto-highlight nil
+	    hilit-auto-rehighlight 'visible
+	    hilit-inhibit-hooks nil
+	    hilit-inhibit-rebinding t)
+      (require 'hilit19)
+      (require 'paren))
+  (setq baud-rate 2400)			; For slow serial connections
+  )
+
+;; TTY type terminal
+(if (and (not window-system) 
+	 (not (equal system-type 'ms-dos)))
+    (progn
+      (if first-time
+	  (progn
+	    (keyboard-translate ?\C-h ?\C-?)
+	    (keyboard-translate ?\C-? ?\C-h)))))
+
+;; Under UNIX
+(if (not (equal system-type 'ms-dos))
+    (progn
+      (if first-time
+	  (server-start))))
+
+;; Add any face changes here
+(add-hook 'term-setup-hook 'my-term-setup-hook)
+(defun my-term-setup-hook ()
+  (if (eq window-system 'pc)
+      (progn
+;;	(set-face-background 'default "red")
+	)))
+
+;; Restore the "desktop" - do this as late as possible
+(if first-time
+    (progn
+      (desktop-load-default)
+      (desktop-read)))
+
+;; Indicate that this file has been read at least once
+(setq first-time nil)
+
+;; No need to debug anything now
+(setq debug-on-error nil)
+
+;; All done
+(message "All done, %s%s" (user-login-name) ".")
+</screen>
+</example>
+  
+</sect1>
+
+<sect1>
+<title>Extending the Range of Languages Emacs Understands</title>
+
+<para>Now, this is all very well if you only want to program in the
+languages already catered for in the <filename>.emacs</filename> file
+(C, C++, Perl, Lisp and Scheme), but what happens if a new language
+called <quote>whizbang</quote> comes out, full of exciting
+features?</para>
+
+<para>The first thing to do is find out if whizbang
+comes with any files that tell Emacs about the language. These
+usually end in <filename>.el</filename>, short for <quote>Emacs
+Lisp</quote>. For example, if whizbang is a FreeBSD
+port, we can locate these files by doing
+<screen>$ <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
+and install them by copying them into the Emacs site Lisp directory. On
+FreeBSD 2.1.0-RELEASE, this is
+<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
+
+<para>So for example, if the output from the find command was
+<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
+we would do
+<screen>$ <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
+</para>
+  
+<para>Next, we need to decide what extension whizbang source files
+have. Let's say for the sake of argument that they all end in
+<filename>.wiz</filename>. We need to add an entry to our
+<filename>.emacs</filename> file to make sure Emacs will be able to
+use the information in <filename>whizbang.el</filename>.</para>
+
+<para>Find the <symbol>auto-mode-alist entry</symbol> in
+<filename>.emacs</filename> and add a line for whizbang, such
+as:
+<programlisting><lineannotation>&hellip;</>
+("\\.lsp$" . lisp-mode)
+("\\.wiz$" . whizbang-mode)
+("\\.scm$" . scheme-mode)
+<lineannotation>&hellip;</></programlisting>  
+This means that Emacs will automatically go into
+<function>whizbang-mode</function> when you edit a file ending in
+<filename>.wiz</filename>.</para>
+
+<para>Just below this, you'll find the
+<symbol>font-lock-auto-mode-list</symbol> entry. Add
+<function>whizbang-mode</function> to it like so:
+<programlisting>;; Auto font lock mode
+(defvar font-lock-auto-mode-list 
+  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
+  "List of modes to always start in font-lock-mode")</programlisting>
+This means that Emacs will always enable
+<function>font-lock-mode</function> (ie syntax highlighting) when
+editing a <filename>.wiz</filename> file.</para>
+
+<para>And that's all that's needed. If there's anything else you want
+done automatically when you open up a <filename>.wiz</filename> file,
+you can add a <function>whizbang-mode hook</function> (see
+<function>my-scheme-mode-hook</function> for a simple example that
+adds <function>auto-indent</function>).</para>
+  
+</sect1>
+</chapter>
+
+<chapter>
+<title>Further Reading</title>
+
+<itemizedlist>
+<listitem><para>Brian Harvey and Matthew Wright
+<emphasis>Simply Scheme</emphasis>
+MIT 1994.<!-- <br> -->
+ISBN 0-262-08226-8</para></listitem>
+
+<listitem><para>Randall Schwartz
+<emphasis>Learning Perl</emphasis>
+O'Reilly 1993<!-- <br> -->
+ISBN 1-56592-042-2</para></listitem>
+
+<listitem><para>Patrick Henry Winston and Berthold Klaus Paul Horn
+<emphasis>Lisp (3rd Edition)</emphasis>
+Addison-Wesley 1989<!-- <br> -->
+ISBN 0-201-08319-1</para></listitem>
+
+<listitem><para>Brian W. Kernighan and Rob Pike
+<emphasis>The Unix Programming Environment</emphasis>
+Prentice-Hall 1984<!-- <br> -->
+ISBN 0-13-937681-X</para></listitem>
+
+<listitem><para>Brian W. Kernighan and Dennis M. Ritchie
+<emphasis>The C Programming Language (2nd Edition)</emphasis>
+Prentice-Hall 1988<!-- <br> -->
+ISBN 0-13-110362-8</para></listitem>
+
+<listitem><para>Bjarne Stroustrup
+<emphasis>The C++ Programming Language</emphasis>
+Addison-Wesley 1991<!-- <br> -->
+ISBN 0-201-53992-6</para></listitem>
+
+<listitem><para>W. Richard Stevens
+<emphasis>Advanced Programming in the Unix Environment</emphasis>
+Addison-Wesley 1992<!-- <br> -->
+ISBN 0-201-56317-7</para></listitem>
+
+<listitem><para>W. Richard Stevens
+<emphasis>Unix Network Programming</emphasis>
+Prentice-Hall 1990<!-- <br> -->
+ISBN 0-13-949876-1</para></listitem>
+
+</itemizedlist>
+
+</chapter>
+</book>
diff --git a/en_US.ISO_8859-1/articles/programming-tools/Makefile b/en_US.ISO_8859-1/articles/programming-tools/Makefile
index 6cc882035c..9429f7790d 100644
--- a/en_US.ISO_8859-1/articles/programming-tools/Makefile
+++ b/en_US.ISO_8859-1/articles/programming-tools/Makefile
@@ -1,5 +1,5 @@
-DOC=		devel
-SRCS=		devel.sgml
+DOCS=	devel.docb
+INDEXLINK=	devel.html
 
-.include <bsd.sgml.mk>
+.include "../../web.mk"
 
diff --git a/en_US.ISO_8859-1/articles/programming-tools/article.sgml b/en_US.ISO_8859-1/articles/programming-tools/article.sgml
new file mode 100644
index 0000000000..524d8730f3
--- /dev/null
+++ b/en_US.ISO_8859-1/articles/programming-tools/article.sgml
@@ -0,0 +1,1835 @@
+<!-- $FreeBSD$ -->
+<!-- The FreeBSD Documentation Project -->
+
+<!DOCTYPE BOOK PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
+<book>
+<bookinfo>
+<bookbiblio>
+<title>A User's Guide to FreeBSD Programming Tools</title>
+
+<authorgroup>
+<author>
+<firstname>James</firstname>
+<surname>Raynard</surname>
+<affiliation>
+<address>
+<email>jraynard@freebsd.org</email>
+</address>
+</affiliation>
+</author></authorgroup>
+
+<pubdate>January 19, 1997</pubdate>
+
+<copyright>
+<year>1997</year>
+<holder>James Raynard</holder>
+</copyright>
+
+<abstract><para>This document is an introduction to using some of the programming
+tools supplied with FreeBSD, although much of it will be applicable to
+many other versions of Unix. It does <emphasis>not</emphasis> attempt to describe
+coding in any detail. Most of the document assumes little or no
+previous programming knowledge, although it is hoped that most
+programmers will find something of value in it</para></abstract>
+</bookbiblio>
+</bookinfo>
+
+<chapter>
+<title>Introduction<anchor id=foo></title>
+  
+<para>FreeBSD offers an excellent development environment. Compilers
+for C, C++, and Fortran and an assembler come with the basic system,
+not to mention a Perl interpreter and classic Unix tools such as
+<command>sed</> and <command>awk</>. If that is not enough, there are
+many more compilers and interpreters in the Ports collection. FreeBSD
+is very compatible with standards such as <acronym>POSIX</> and
+<acronym>ANSI</> C, as well with its own BSD heritage, so it is
+possible to write applications that will compile and run with little
+or no modification on a wide range of platforms.</para>
+
+<para>However, all this power can be rather overwhelming at first if
+you've never written programs on a Unix platform before. This
+document aims to help you get up and running, without getting too
+deeply into more advanced topics. The intention is that this document
+should give you enough of the basics to be able to make some sense of
+the documentation.</para>
+
+<para>Most of the document requires little or no knowledge of
+programming, although it does assume a basic competence with using
+Unix and a willingness to learn!</para>
+  
+</chapter>
+
+<chapter>
+<title>Introduction to Programming</title>
+
+<para>A program is a set of instructions that tell the computer to do
+various things; sometimes the instruction it has to perform depends
+on what happened when it performed a previous instruction. This
+section gives an overview of the two main ways in which you can give
+these instructions, or <quote>commands</quote> as they are usually
+called. One way uses an <firstterm>interpreter</>, the other a
+<firstterm>compiler</>. As human languages are too difficult for a
+computer to understand in an unambiguous way, commands are usually
+written in one or other languages specially designed for the
+purpose.</para>
+
+
+  
+<sect1>
+<title>Interpreters</title>
+
+<para>With an interpreter, the language comes as an environment, where you
+type in commands at a prompt and the environment executes them for
+you. For more complicated programs, you can type the commands into a
+file and get the interpreter to load the file and execute the commands
+in it. If anything goes wrong, many interpreters will drop you into a
+debugger to help you track down the problem.</para>
+  
+<para>The advantage of this is that you can see the results of your
+commands immediately, and mistakes can be corrected readily. The
+biggest disadvantage comes when you want to share your programs with
+someone. They must have the same interpreter, or you must have some
+way of giving it to them, and they need to understand how to use it.
+Also users may not appreciate being thrown into a debugger if they
+press the wrong key! From a performance point of view, interpreters
+can use up a lot of memory, and generally do not generate code as
+efficiently as compilers.</para>
+
+<para>In my opinion, interpreted languages are the best way to start
+if you have not done any programming before. This kind of environment
+is typically found with languages like Lisp, Smalltalk, Perl and
+Basic. It could also be argued that the Unix shell (<command>sh</>,
+<command>csh</>) is itself an interpreter, and many people do in fact
+write shell <quote>scripts</quote> to help with various
+<quote>housekeeping</> tasks on their machine. Indeed, part of the
+original Unix philosophy was to provide lots of small utility
+programs that could be linked together in shell scripts to perform
+useful tasks.</para>
+  
+</sect1>
+
+<sect1>
+<title>Interpreters available with FreeBSD</title>
+
+<para>Here is a list of interpreters that are available as <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
+packages</ulink>, with a brief discussion of some of the more popular
+interpreted languages. </para>
+
+<para>To get one of these packages, all you need to do is to click on
+the hotlink for the package, then run
+<screen>$ <userinput>pkg_add <replaceable>package name</></userinput></screen>
+</para>
+  
+<para>as root. Obviously, you will need to have a fully functional FreeBSD
+2.1.0 or later system for the package to work!</para>
+  
+<para>
+<variablelist>
+<varlistentry><term><acronym>BASIC</></term>
+
+<listitem><para>Short for Beginner's All-purpose Symbolic Instruction
+Code. Developed in the 1950s for teaching University students to
+program and provided with every self-respecting personal computer in
+the 1980s, <acronym>BASIC</> has been the first programming language
+for many programmers. It's also the foundation for <trademark>Visual
+Basic</>.</para>
+
+<para>The <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/bwbasic-2.10.tgz">Bywater
+Basic Interpreter</ulink> and the <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/pbasic-2.0.tgz">Phil
+Cockroft's Basic Interpreter</ulink> (formerly Rabbit Basic) are
+available as FreeBSD <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/">FreeBSD
+packages</ulink></para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Lisp</term>
+<listitem><para>A language that was developed in the late 1950s as an alternative to
+the <quote>number-crunching</quote> languages that were popular at the time.
+Instead of being based on numbers, Lisp is based on lists; in fact
+the name is short for <quote>List Processing</quote>. Very popular in AI
+(Artificial Intelligence) circles.</para>
+  
+<para>Lisp is an extremely powerful and sophisticated language, but
+can be rather large and unwieldy. </para>
+
+<para>FreeBSD has <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/gcl-2.0.tgz">GNU
+Common Lisp</ulink> available as a package.</para>
+  
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Perl</term>
+<listitem><para>Very popular with system administrators for writing
+scripts; also often used on World Wide Web servers for writing <acronym>CGI</>
+scripts.</para>
+
+<para>Version 4, which is probably still the most widely-used
+version, comes with FreeBSD; the newer <ulink
+URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/perl-5.001.tgz">Perl
+Version 5</ulink> is available as a package.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Scheme</term>
+<listitem><para>A dialect of Lisp that is rather more compact and
+cleaner than Common Lisp. Popular in Universities as it is simple
+enough to teach to undergraduates as a first language, while it has a
+high enough level of abstraction to be used in research work.</para>
+
+<para>FreeBSD has packages of the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/elk-3.0.tgz">Elk Scheme Interpreter</ulink>, the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/mit-scheme-7.3.tgz">MIT Scheme Interpreter</ulink> and the 
+<ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/scm-4e1.tgz">SCM Scheme Interpreter</ulink>.</para>
+  
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Icon</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/icon-9.0.tgz">The Icon Programming Language</ulink>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Logo</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/ucblogo-3.3.tgz">Brian Harvey's LOGO Interpreter</ulink>.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry><term>Python</term>
+<listitem><para><ulink URL="ftp://ftp.freebsd.org:pub/FreeBSD/packages/lang/python-1.2">The Python Object-Oriented Programming Language</ulink></para>
+</listitem>
+</varlistentry>
+
+</variablelist>
+</para>
+  
+</sect1>
+
+<sect1>
+<title>Compilers</title>
+
+<para>Compilers are rather different. First of all, you write your
+code in a file (or files) using an editor. You then run the compiler
+and see if it accepts your program. If it did not compile, grit your
+teeth and go back to the editor; if it did compile and gave you a
+program, you can run it either at a shell command prompt or in a
+debugger to see if it works properly.<footnote><para>If you run it in
+the shell, you may get a core dump.</para></footnote></para>
+
+<para>Obviously, this is not quite as direct as using an interpreter.
+However it allows you to do a lot of things which are very difficult
+or even impossible with an interpreter, such as writing code which
+interacts closely with the operating system&mdash;or even writing
+your own operating system! It's also useful if you need to write very
+efficient code, as the compiler can take its time and optimise the
+code, which would not be acceptable in an interpreter. And
+distributing a program written for a compiler is usually more
+straightforward than one written for an interpreter&mdash;you can just
+give them a copy of the executable, assuming they have the same
+operating system as you.</para>
+
+<para>Compiled languages include Pascal, C and C++. C and C++ are rather
+unforgiving languages, and best suited to more experienced
+programmers; Pascal, on the other hand, was designed as an educational
+language, and is quite a good language to start with. Unfortunately,
+FreeBSD doesn't have any Pascal support, except for a Pascal-to-C
+converter in the ports.</para>
+  
+<para>As the edit-compile-run-debug cycle is rather tedious when
+using separate programs, many commercial compiler makers have
+produced Integrated Development Environments (<acronym>IDE</acronym>s
+for short). FreeBSD does not have an <acronym>IDE</> as such; however
+it is possible to use Emacs for this purpose. This is discussed in
+<xref linkend="emacs">.</para>
+  
+</sect1>
+</chapter>
+
+<chapter>
+<title>Compiling with <command>cc</command></title>
+
+<para>This section deals only with the GNU compiler for C and C++,
+since that comes with the base FreeBSD system. It can be invoked by
+either <command>cc</> or <command>gcc</>. The details of producing a
+program with an interpreter vary considerably between interpreters,
+and are usually well covered in the documentation and on-line help
+for the interpreter.</para>
+
+<para>Once you've written your masterpiece, the next step is to convert it
+into something that will (hopefully!) run on FreeBSD. This usually
+involves several steps, each of which is done by a separate
+program.</para>
+
+<procedure>
+<step><para>Pre-process your source code to remove comments and do other
+tricks like expanding macros in C.
+</para></step>
+
+<step><para>Check the syntax of your code to see if you have obeyed the
+rules of the language. If you have not, it will complain!
+</para></step>
+
+<step><para>Convert the source code into assembly
+language&mdash;this is very close to machine code, but still
+understandable by humans. Allegedly.<footnote><para>To be strictly
+accurate, <command>cc</> converts the source code into its own,
+machine-independent <firstterm>p-code</> instead of assembly language
+at this stage.</para></footnote></para></step>
+
+<step><para>Convert the assembly language into machine
+code&mdash;yep, we are talking bits and bytes, ones and zeros
+here.</para></step>
+
+<step><para>Check that you have used things like functions and global
+variables in a consistent way. For example, if you have called a
+non-existent function, it will complain.</para></step>
+
+<step><para>If you are trying to produce an executable from several
+source code files, work out how to fit them all together.</para></step>
+
+<step><para>Work out how to produce something that the system's run-time
+loader will be able to load into memory and run.</para></step>
+
+<step><para>Finally, write the executable on the file
+system.</para></step>
+
+</procedure>
+  
+<para>The word <firstterm>compiling</> is often used to refer to just
+steps 1 to 4&mdash;the others are referred to as
+<firstterm>linking</>. Sometimes step 1 is referred to as
+<firstterm>pre-processing</> and steps 3-4 as
+<firstterm>assembling</>.</para>
+
+<para>Fortunately, almost all this detail is hidden from you, as
+<command>cc</> is a front end that manages calling all these programs
+with the right arguments for you; simply typing
+<screen>$ <userinput>cc foobar.c</></screen></para>
+  
+<para>will cause <filename>foobar.c</> to be compiled by all the
+steps above. If you have more than one file to compile, just do
+something like
+<screen>$ <userinput>cc foo.c bar.c</></screen>
+</para>
+  
+<para>Note that the syntax checking is just that&mdash;checking the
+syntax. It will not check for any logical mistakes you may have made,
+like putting the program into an infinite loop, or using a bubble
+sort when you meant to use a binary sort.<footnote><para>In case you
+didn't know, a binary sort is an efficient way of sorting things into
+order and a bubble sort isn't.</para></footnote></para>
+
+<para>There are lots and lots of options for <command>cc</>, which
+are all in the man page.  Here are a few of the most important ones,
+with examples of how to use them.</para>
+
+<variablelist>
+<varlistentry><term><option>-o <replaceable>filename</replaceable></></term>
+
+<listitem><para>The output name of the file. If you do not use this
+option, <command>cc</> will  produce an executable called
+<filename>a.out</>.<footnote><para>The reasons for this are buried in
+the mists of history.</para></footnote></para>
+
+<informalexample>
+<screen>$ <userinput>cc foobar.c</>               <lineannotation>executable is <filename>a.out</></>
+$ <userinput>cc -o foobar foobar.c</>     <lineannotation>executable is <filename>foobar</></></screen>
+</informalexample>
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-c</option></term>
+<listitem><para>Just compile the file, do not link it. Useful for toy
+programs where you just want to check the syntax, or if you are using
+a <filename>Makefile</filename>.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -c foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce an <firstterm>object file</> (not an
+executable) called <filename>foobar.o</filename>. This can be linked
+together with other object files into an executable.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-g</option></term>
+
+<listitem><para>Create a debug version of the executable. This makes
+the compiler put information into the executable about which line of
+which source file corresponds to which function call. A debugger can
+use this information to show the source code as you step through the
+program, which is <emphasis>very</emphasis> useful; the disadvantage
+is that all this extra information makes the program much bigger.
+Normally, you compile with <option>-g</option> while you are
+developing a program and then compile a <quote>release
+version</quote> without <option>-g</option> when you're satisfied it
+works properly.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -g foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce a debug version of the
+program.<footnote><para>Note, we didn't use the <option>-o</option>
+flag to specify the executable name, so we will get an executable
+called <filename>a.out</filename>. Producing a debug version called
+<filename>foobar</filename> is left as an exercise for the
+reader!</para></footnote></para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry><term><option>-O</option></term>
+
+<listitem><para>Create an optimised version of the executable. The
+compiler performs various clever tricks to try and produce an
+executable that runs faster than normal. You can add a number after
+the <option>-O</option> to specify a higher level of optimisation,
+but this often exposes bugs in the compiler's optimiser. For
+instance, the version of <command>cc</command> that comes with the
+2.1.0 release of FreeBSD is known to produce bad code with the
+<option>-O2</option> option in some circumstances.</para>
+
+<para>Optimisation is usually only turned on when compiling a release
+version.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -O -o foobar foobar.c</userinput></screen>
+</informalexample>
+  
+<para>This will produce an optimised version of
+<filename>foobar</filename>.</para>
+
+</listitem>
+</varlistentry>
+</variablelist>
+
+<para>The following three flags will force <command>cc</command> to
+check that your code complies to the relevant international standard,
+often referred to as the <acronym>ANSI</acronym> standard, though
+strictly speaking it is an <acronym>ISO</acronym> standard.</para>
+
+<variablelist>
+
+<varlistentry><term><option>-Wall</option></term>
+
+<listitem><para>Enable all the warnings which the authors of
+<command>cc</command> believe are worthwhile. Despite the name, it
+will not enable all the warnings <command>cc</command> is capable
+of.</para></listitem>
+
+</varlistentry>
+
+<varlistentry><term><option>-ansi</option></term>
+
+<listitem>
+<para>Turn off most, but not all, of the non-<acronym>ANSI</>&nbsp;C
+features provided by <command>cc</command>. Despite the name, it does
+not guarantee strictly that your code will comply to the
+standard.</para>
+</listitem>
+
+</varlistentry>
+
+<varlistentry><term><option>-pedantic</option></term>
+
+<listitem>
+<para>Turn off <emphasis>all</emphasis>
+<command>cc</command>'s non-<acronym>ANSI</>&nbsp;C features.</para>
+</listitem>
+
+</varlistentry>
+</variablelist>
+
+<para>Without these flags, <command>cc</command> will allow you to
+use some of its non-standard extensions to the standard. Some of
+these are very useful, but will not work with other compilers&mdash;in
+fact, one of the main aims of the standard is to allow people to
+write code that will work with any compiler on any system. This is
+known as <firstterm>portable code</firstterm>.</para>
+
+<para>Generally, you should try to make your code as portable as
+possible, as otherwise you may have to completely re-write the
+program later to get it to work somewhere else&mdash;and who knows
+what you may be using in a few years time?</para>
+  
+<informalexample>
+<screen>$ <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
+</informalexample>
+
+<para>This will produce an executable <filename>foobar</filename>
+after checking <filename>foobar.c</filename> for standard
+compliance.</para>
+  
+<variablelist>
+
+<varlistentry><term><option>-l<replaceable>library</replaceable></option></term>
+
+<listitem><para>Specify a function library to be used during when
+linking.</para>
+
+<para>The most common example of this is when compiling a program that
+uses some of the mathematical functions in C. Unlike most other
+platforms, these are in a separate library from the standard C one
+and you have to tell the compiler to add it.</para>
+  
+<para>The rule is that if the library is called
+<filename>lib<replaceable>something</replaceable>.a</filename>, you
+give <command>cc</command> the argument
+<option>-l<replaceable>something</replaceable></option>. For example,
+the math library is <filename>libm.a</filename>, so you give
+<command>cc</command> the argument <option>-lm</option>. A common
+<quote>gotcha</quote> with the math library is that it has to be the
+last library on the command line.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
+</informalexample>
+
+<para>This will link the math library functions into
+<filename>foobar</filename>.</para>
+
+<para>If you are compiling C++ code, you need to add
+<option>-lg++</option>, or <option>-lstdc++</option> if you are using
+FreeBSD 2.2 or later, to the command line argument to link the C++
+library functions. Alternatively, you can run <command>c++</command>
+instead of <command>cc</command>, which does this for you.
+<command>c++</command> can also be invoked as <command>g++</command>
+on FreeBSD.</para>
+
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.cc -lg++</userinput>     <lineannotation>For FreeBSD 2.1.6 and earlier</>
+$ <userinput>cc -o foobar foobar.cc -lstdc++</userinput>  <lineannotation>For FreeBSD 2.2 and later</>
+$ <userinput>c++ -o foobar foobar.cc</userinput></screen>
+</informalexample>
+
+<para>Each of these will both produce an executable
+<filename>foobar</filename> from the C++ source file
+<filename>foobar.cc</filename>. Note that, on Unix systems, C++
+source files traditionally end in <filename>.C</filename>,
+<filename>.cxx</filename> or <filename>.cc</filename>, rather than
+the <trademark>MS-DOS</trademark> style <filename>.cpp</filename>
+(which was already used for something else). <command>gcc</command>
+used to rely on this to work out what kind of compiler to use on the
+source file; however, this restriction no longer applies, so you may
+now call your C++ files <filename>.cpp</filename> with
+impunity!</para>
+
+</listitem>
+</varlistentry>
+</variablelist>
+  
+<sect1>
+<title>Common <command>cc</command> Queries and Problems</title>
+
+<para>Q. I am trying to write a program which uses the
+<function>sin()</function> function and I get an error like this.
+What does it mean?
+<informalexample>
+<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment</screen>
+</informalexample>
+</para>
+  
+<para>A. When using mathematical functions like
+<function>sin()</function>, you have to tell <command>cc</command> to
+link in the math library, like so:
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
+</informalexample></para>
+
+<para>Q. All right, I wrote this simple program to practice using
+<option>-lm</option>. All it does is raise 2.1 to the power of 6.
+<informalexample>
+<programlisting>#include &lt;stdio.h&gt;
+
+int main() {
+	float f;
+
+	f = pow(2.1, 6);
+	printf("2.1 ^ 6 = %f\n", f);
+	return 0;
+}</programlisting>
+</informalexample>
+and I compiled it as:
+<informalexample>
+<screen>$ <userinput>cc temp.c -lm</userinput></screen>
+</informalexample>
+like you said I should, but I get this when I run it:
+<informalexample>
+<screen>$ <userinput>./a.out</userinput>
+2.1 ^ 6 = 1023.000000</screen>
+</informalexample>
+</para>
+  
+<para>This is <emphasis>not</emphasis> the right answer! What is
+going on?</para>
+
+<para>A. When the compiler sees you call a function, it checks if it
+has already seen a prototype for it. If it has not, it assumes the
+function returns an <type>int</type>, which is
+definitely not what you want here.</para>
+
+<para>Q. So how do I fix this?</para>
+  
+<para>A. The prototypes for the mathematical functions are in
+<filename>math.h</filename>. If you include this file, the compiler
+will be able to find the prototype and it will stop doing strange
+things to your calculation!
+<informalexample>
+<programlisting>#include &lt;math.h&gt;
+#include &lt;stdio.h&gt;
+
+int main() {
+...</programlisting>
+</informalexample>
+</para>
+  
+<para>After recompiling it as you did before, run it:
+<informalexample>
+<screen>$ <userinput>./a.out</userinput>
+2.1 ^ 6 = 85.766121</screen>
+</informalexample>
+</para>
+  
+<para>If you are using any of the mathematical functions,
+<emphasis>always</emphasis> include <filename>math.h</filename> and
+remember to link in the math library.</para>
+
+<para>Q. I compiled a file called <filename>foobar.c</filename> and I
+cannot find an executable called <filename>foobar</filename>. Where's
+it gone?</para>
+
+<para>A. Remember, <command>cc</command> will call the executable
+<filename>a.out</filename> unless you tell it differently. Use the
+<option>-o&nbsp;<replaceable>filename</replaceable></option> option:
+<informalexample>
+<screen>$ <userinput>cc -o foobar foobar.c</userinput></screen>
+</informalexample>
+</para>
+
+<para>Q. OK, I have an executable called <filename>foobar</filename>,
+I can see it when I run <command>ls</command>, but when I type in
+<command>foobar</command> at the command prompt it tells me there is
+no such file. Why can it not find it?</para>
+
+<para>A. Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
+current directory when it is trying to find out which executable you
+want it to run, unless you tell it to. Either type
+<command>./foobar</command>, which means <quote>run the file called
+<filename>foobar</filename> in the current directory</quote>, or
+change your <systemitem class=environvar>PATH</systemitem>
+environment variable so that it looks something like
+<informalexample>
+<screen>bin:/usr/bin:/usr/local/bin:.</screen>
+</informalexample>
+The dot at the end means <quote>look in the current directory if it is not in
+any of the others</quote>.</para>
+  
+<para>Q. I called my executable <filename>test</filename>, but
+nothing happens when I run it. What is going on?</para>
+
+<para>A. Most Unix systems have a program called
+<command>test</command> in <filename>/usr/bin</filename> and the
+shell is picking that one up before it gets to checking the current
+directory. Either type:
+<informalexample>
+<screen>$ <userinput>./test</userinput></screen>
+</informalexample>
+or choose a better name for your program!</para>
+  
+<para>Q. I compiled my program and it seemed to run all right at
+first, then there was an error and it said something about <errorname>core
+dumped</errorname>. What does that mean?</para>
+
+<para>A. The name <firstterm>core dump</firstterm> dates back to the
+very early days of Unix, when the machines used core memory for
+storing data. Basically, if the program failed under certain
+conditions, the system would write the contents of core memory to
+disk in a file called <filename>core</filename>, which the programmer
+could then pore over to find out what went wrong.</para>
+
+<para>Q. Fascinating stuff, but what I am supposed to do now?</para>
+  
+<para>A. Use <command>gdb</command> to analyse the core (see <xref
+linkend="debugging">).</para>
+  
+<para>Q. When my program dumped core, it said something about a
+<errorname>segmentation fault</errorname>. What's that?</para>
+
+<para>A. This basically means that your program tried to perform some sort
+of illegal operation on memory; Unix is designed to protect the
+operating system and other programs from rogue programs.</para>
+  
+<para>Common causes for this are:
+<itemizedlist>
+<listitem><para>Trying to write to a <symbol>NULL</symbol> pointer, eg
+<programlisting>char *foo = NULL;
+strcpy(foo, "bang!");</programlisting>
+</para></listitem>
+
+<listitem><para>Using a pointer that hasn't been initialised, eg
+<programlisting>char *foo;
+strcpy(foo, "bang!");</programlisting>
+The pointer will have some random value that, with luck,
+will point into an area of memory that isn't available to
+your program and the kernel will kill your program before
+it can do any damage. If you're unlucky, it'll point
+somewhere inside your own program and corrupt one of your
+data structures, causing the program to fail
+mysteriously.</para></listitem>
+
+<listitem><para>Trying to access past the end of an array, eg
+<programlisting>int bar[20];
+bar[27] = 6;</programlisting></para></listitem>
+
+<listitem><para> Trying to store something in read-only memory, eg
+<programlisting>char *foo = "My string";
+strcpy(foo, "bang!");</programlisting>
+Unix compilers often put string literals like
+<literal>"My string"</literal> into
+read-only areas of memory.</para></listitem>
+
+<listitem><para>Doing naughty things with
+<function>malloc()</function> and <function>free()</function>, eg
+<programlisting>char bar[80];
+free(bar);</programlisting>
+or
+<programlisting>char *foo = malloc(27);
+free(foo);
+free(foo);</programlisting>
+</para></listitem>
+
+</itemizedlist></para>
+
+<para>Making one of these mistakes will not always lead to an
+error, but they are always bad practice. Some systems and
+compilers are more tolerant than others, which is why programs
+that ran well on one system can crash when you try them on an
+another.</para>
+  
+<para>Q. Sometimes when I get a core dump it says <errorname>bus
+error</errorname>. It says in my Unix book that this means a hardware
+problem, but the computer still seems to be working. Is this
+true?</para>
+
+<para>A. No, fortunately not (unless of course you really do have a hardware
+problem&hellip;). This is usually another way of saying that you
+accessed memory in a way you shouldn't have.</para>
+  
+<para>Q. This dumping core business sounds as though it could be quite
+useful, if I can make it happen when I want to. Can I do this, or
+do I have to wait until there's an error?</para>
+  
+<para>A. Yes, just go to another console or xterm, do
+<screen>$ <userinput>ps</userinput></screen>
+to find out the process ID of your program, and do
+<screen>$ <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
+where <parameter><replaceable>pid</replaceable></parameter> is the
+process ID you looked up.</para>
+  
+<para>This is useful if your program has got stuck in an infinite
+loop, for instance. If your program happens to trap
+<symbol>SIGABRT</symbol>, there are several other signals which have
+a similar effect.</para>
+
+</sect1>
+</chapter>
+
+
+<chapter>
+<title>Make</title>
+
+<sect1>
+<title>What is <command>make</command>?</title>
+
+<para>When you're working on a simple program with only one or two source
+files, typing in
+<screen>$ <userinput>cc file1.c file2.c</userinput></screen>
+is not too bad, but it quickly becomes very tedious when there are
+several files&mdash;and it can take a while to compile, too.</para>
+  
+<para>One way to get around this is to use object files and only recompile
+the source file if the source code has changed. So we could have
+something like:
+<screen>$ <userinput>cc file1.o file2.o</userinput> &hellip; <userinput>file37.c</userinput> &hellip</screen>
+if we'd changed <filename>file37.c</filename>, but not any of the
+others, since the last time we compiled.  This may speed up the
+compilation quite a bit, but  doesn't solve the typing
+problem.</para>
+
+<para>Or we could write a shell script to solve the typing problem, but it
+would have to re-compile everything, making it very inefficient on a
+large project.</para>
+  
+<para>What happens if we have hundreds of source files lying about? What if
+we're working in a team with other people who forget to tell us when
+they've changed one of their source files that we use?</para>
+  
+<para>Perhaps we could put the two solutions together and write something
+like a shell script that would contain some kind of magic rule saying
+when a source file needs compiling. Now all we need now is a program
+that can understand these rules, as it's a bit too complicated for the
+shell.</para>
+  
+<para>This program is called <command>make</command>. It reads in a
+file, called a <firstterm>makefile</firstterm>, that tells it how
+different files depend on each other, and works out which files need
+to be re-compiled and which ones don't. For example, a rule could say
+something like <quote>if <filename>fromboz.o</filename> is older than
+<filename>fromboz.c</filename>, that means someone must have changed
+<filename>fromboz.c</filename>, so it needs to be
+re-compiled.</quote> The makefile also has rules telling make
+<emphasis>how</emphasis> to re-compile the source file, making it a
+much more powerful tool.</para>
+
+<para>Makefiles are typically kept in the same directory as the
+source they apply to, and can be called
+<filename>makefile</filename>, <filename>Makefile</filename> or
+<filename>MAKEFILE</filename>. Most programmers use the name
+<filename>Makefile</filename>, as this puts it near the top of a
+directory listing, where it can easily be seen.<footnote><para>They
+don't use the <filename>MAKEFILE</filename> form as block capitals
+are often used for documentation files like
+<filename>README</filename>.</para></footnote></para>
+  
+</sect1>
+
+<sect1>
+<title>Example of using <command>make</command></title>
+
+<para>Here's a very simple make file:
+<programlisting>foo: foo.c
+	cc -o foo foo.c</programlisting>
+It consists of two lines, a dependency line and a creation line.</para>
+  
+<para>The dependency line here consists of the name of the program
+(known as the <firstterm>target</firstterm>), followed by a colon,
+then whitespace, then the name of the source file. When
+<command>make</command> reads this line, it looks to see if
+<filename>foo</filename> exists; if it exists, it compares the time
+<filename>foo</filename> was last modified to the time
+<filename>foo.c</filename> was last modified. If
+<filename>foo</filename> does not exist, or is older than
+<filename>foo.c</filename>, it then looks at the creation line to
+find out what to do. In other words, this is the rule for working out
+when <filename>foo.c</filename> needs to be re-compiled.</para>
+
+<para>The creation line starts with a <token>tab</token> (press the
+<keycap>tab</keycap> key) and then the command you would type to
+create <filename>foo</filename> if you were doing it at a command
+prompt. If <filename>foo</filename> is out of date, or does not
+exist, <command>make</command> then executes this command to create
+it. In other words, this is the rule which tells make how to
+re-compile <filename>foo.c</filename>.</para>
+
+<para>So, when you type <userinput>make</userinput>, it will make
+sure that <filename>foo</filename> is up to date with respect to your
+latest changes to <filename>foo.c</filename>. This principle can be
+extended to <filename>Makefile</filename>s with hundreds of
+targets&mdash;in fact, on FreeBSD, it is possible to compile the
+entire operating system just by typing <userinput>make
+world</userinput> in the appropriate directory!</para>
+
+<para>Another useful property of makefiles is that the targets don't have
+to be programs. For instance, we could have a make file that looks
+like this:
+<programlisting>foo: foo.c
+	cc -o foo foo.c
+
+install:
+	cp foo /home/me</programlisting></para>
+  
+<para>We can tell make which target we want to make by typing:
+<screen>$ <userinput>make <replaceable>target</replaceable></userinput></screen>
+<command>make</command> will then only look at that target and ignore any
+others. For example, if we type <userinput>make foo</userinput> with the 
+makefile above, make will ignore the <action>install</action> target.</para>
+  
+<para>If we just type <userinput>make</userinput> on its own, make
+will always look at the first target and then stop without looking at
+any others. So if we typed <userinput>make</userinput> here, it will
+just go to the <action>foo</action> target, re-compile
+<filename>foo</filename> if necessary, and then stop without going on
+to the <action>install</action> target.</para>
+
+<para>Notice that the <action>install</action> target doesn't
+actually depend on anything! This means that the command on the
+following line is always executed when we try to make that target by
+typing <userinput>make install</userinput>. In this case, it will
+copy <filename>foo</filename> into the user's home directory. This is
+often used by application makefiles, so that the application can be
+installed in the correct directory when it has been correctly
+compiled.</para>
+
+<para>This is a slightly confusing subject to try and explain. If you
+don't quite understand how <command>make</command> works, the best
+thing to do is to write a simple program like <quote>hello
+world</quote> and a make file like the one above and experiment. Then
+progress to using more than one source file, or having the source
+file include a header file. The <command>touch</command> command is
+very useful here&mdash;it changes the date on a file without you
+having to edit it.</para>
+  
+</sect1>
+
+<sect1>
+<title>FreeBSD Makefiles</title>
+
+<para>Makefiles can be rather complicated to write. Fortunately,
+BSD-based systems like FreeBSD come with some very powerful ones as
+part of the system.  One very good example of this is the FreeBSD
+ports system. Here's the essential part of a typical ports
+<filename>Makefile</filename>:
+<programlisting>MASTER_SITES=   ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
+DISTFILES=      scheme-microcode+dist-7.3-freebsd.tgz
+
+.include &lt;bsd.port.mk&gt;</programlisting></para>
+  
+<para>Now, if we go to the directory for this port and type
+<userinput>make</userinput>, the following happens:</para>
+
+<procedure>
+<step><para>A check is made to see if the source code for this port is
+already on the system.</para></step>
+
+<step><para>If it isn't, an FTP connection to the URL in
+<symbol>MASTER_SITES</symbol> is set up to download the
+source.</para></step>
+
+<step><para>The checksum for the source is calculated and compared it with
+one for a known, good, copy of the source. This is to make sure that
+the source was not corrupted while in transit.</para></step>
+
+<step><para>Any changes required to make the source work on FreeBSD are
+applied&mdash;this is known as <firstterm>patching</firstterm>.</para></step>
+
+<step><para>Any special configuration needed for the source is done.
+(Many Unix program distributions try to work out which version of
+Unix they are being compiled on and which optional Unix features are
+present&mdash;this is where they are given the information in the
+FreeBSD ports scenario).</para></step>
+
+<step><para>The source code for the program is compiled. In effect,
+we change to the directory where the source was unpacked and do
+<command>make</command>&mdash;the program's own make file has the
+necessary information to build the program.</para></step>
+
+<step><para>We now have a compiled version of the program. If we
+wish, we can test it now; when we feel confident about the program,
+we can type <userinput>make install</userinput>. This will cause the
+program and any supporting files it needs to be copied into the
+correct location; an entry is also made into a <database>package
+database</database>, so that the port can easily be uninstalled later
+if we change our mind about it.</para></step>
+
+</procedure>
+  
+<para>Now I think you'll agree that's rather impressive for a four
+line script!</para>
+
+<para>The secret lies in the last line, which tells
+<command>make</command> to look in the system makefile called
+<filename>bsd.port.mk</filename>. It's easy to overlook this line,
+but this is where all the clever stuff comes from&mdash;someone has
+written a makefile that tells <command>make</command> to do all the
+things above (plus a couple of other things I didn't mention,
+including handling any errors that may occur) and anyone can get
+access to that just by putting a single line in their own make
+file!</para>
+
+<para>If you want to have a look at these system makefiles, they're
+in <filename>/usr/share/mk</filename>, but it's probably best to wait
+until you've had a bit of practice with makefiles, as they are very
+complicated (and if you do look at them, make sure you have a flask
+of strong coffee handy!)</para>
+
+</sect1>
+
+<sect1>
+<title>More advanced uses of <command>make</command></title>
+
+<para><command>Make</command> is a very powerful tool, and can do much
+more than the simple example above shows. Unfortunately, there are
+several different versions of <command>make</command>, and they all
+differ considerably. The best way to learn what they can do is
+probably to read the documentation&mdash;hopefully this introduction will
+have given you a base from which you can do this.</para>
+
+<para>The version of make that comes with FreeBSD is the <application>Berkeley
+make</application>; there is a tutorial for it in
+<filename>/usr/share/doc/psd/12.make</filename>. To view it, do
+<screen>$ <userinput>zmore paper.ascii.gz</userinput></screen>
+in that directory.</para>
+  
+<para>Many applications in the ports use <application>GNU
+make</application>, which has a very good set of <quote>info</quote>
+pages. If you have installed any of these ports, <application>GNU
+make</application> will automatically have been installed as
+<command>gmake</command>. It's also available as a port and package
+in its own right.</para>
+
+<para>To view the info pages for <application>GNU make</application>,
+you will have to edit the <filename>dir</filename> file in the
+<filename>/usr/local/info</filename> directory to add an entry for
+it. This involves adding a line like
+<programlisting> * Make: (make).                 The GNU Make utility.</programlisting>
+to the file. Once you have done this, you can type
+<userinput>info</userinput> and then select
+<guimenuitem>make</guimenuitem> from the menu (or in
+<application>Emacs</application>, do <userinput>C-h
+i</userinput>).</para>
+
+</sect1>
+</chapter>
+
+<chapter id="debugging">
+<title>Debugging</title>
+
+<sect1>
+<title>The Debugger</title>
+
+<para>The debugger that comes with FreeBSD is called
+<command>gdb</command> (<application>GNU
+debugger</application>). You start it up by typing
+<screen>$ <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
+although most people prefer to run it inside
+<application>Emacs</application>. You can do this by:
+<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen></para>
+  
+<para>Using a debugger allows you to run the program under more
+controlled circumstances. Typically, you can step through the program
+a line at a time, inspect the value of variables, change them, tell
+the debugger to run up to a certain point and then stop, and so on.
+You can even attach to a program that's already running, or load a
+core file to investigate why the program crashed. It's even possible
+to debug the kernel, though that's a little trickier than the user
+applications we'll be discussing in this section.</para>
+
+<para><command>gdb</command> has quite good on-line help, as well as
+a set of info pages, so this section will concentrate on a few of the
+basic commands.</para>
+
+<para>Finally, if you find its text-based command-prompt style
+off-putting, there's a graphical front-end for it <ulink
+URL="http://www.freebsd.org/ports/devel.html">xxgdb</ulink>
+in the ports collection.</para>
+
+<para>This section is intended to be an introduction to using
+<command>gdb</command> and does not cover specialised topics such as
+debugging the kernel.</para>
+  
+</sect1>
+
+<sect1>
+<title>Running a program in the debugger</title>
+
+<para>You'll need to have compiled the program with the
+<option>-g</option> option to get the most out of using
+<command>gdb</command>. It will work without, but you'll only see the
+name of the function you're in, instead of the source code. If you
+see a line like:
+<screen>&hellip; (no debugging symbols found) &hellip;</screen>when
+<command>gdb</command> starts up, you'll know that the program wasn't
+compiled with the <option>-g</option> option.</para>
+  
+<para>At the <command>gdb</command> prompt, type <userinput>break
+main</userinput>. This will tell the debugger to skip over the
+preliminary set-up code in the program and start at the beginning of
+your code. Now type <userinput>run</userinput> to start the
+program&mdash;it will start at the beginning of the set-up code and
+then get stopped by the debugger when it calls
+<function>main()</function>. (If you've ever wondered where
+<function>main()</function> gets called from, now you know!).</para>
+
+<para>You can now step through the program, a line at a time, by
+pressing <command>n</command>.  If you get to a function call, you can
+step into it by pressing <command>s</command>. Once you're in a
+function call, you can return from stepping into a function call by
+pressing <command>f</command>. You can also use <command>up</command> and
+<command>down</command> to take a quick look at the caller.</para>
+
+<para>Here's a simple example of how to spot a mistake in a program
+with <command>gdb</command>. This is our program (with a deliberate
+mistake):
+<programlisting>#include &lt;stdio.h&gt;
+
+int bazz(int anint);
+
+main() {
+	int i;
+
+	printf("This is my program\n");
+	bazz(i);
+	return 0;
+}
+
+int bazz(int anint) {
+	printf("You gave me %d\n", anint);
+	return anint;
+}</programlisting>
+</para>
+  
+<para>This program sets <symbol>i</symbol> to be <literal>5</literal>
+and passes it to a function <function>bazz()</function> which prints
+out the number we gave it.</para>
+
+<para>When we compile and run the program we get
+<screen>$ <userinput>cc -g -o temp temp.c</userinput>
+$ <userinput>./temp</userinput>
+This is my program
+anint = 4231</screen></para>
+  
+<para>That wasn't what we expected! Time to see what's going
+on!<screen>$ <userinput>gdb temp</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>break main</>				<lineannotation>Skip the set-up code</>
+Breakpoint 1 at 0x160f: file temp.c, line 9.	<lineannotation><command>gdb</command> puts breakpoint at <function>main()</></>
+(gdb) <userinput>run</>					<lineannotation>Run as far as <function>main()</></>
+Starting program: /home/james/tmp/temp		<lineannotation>Program starts running</>
+
+Breakpoint 1, main () at temp.c:9		<lineannotation><command>gdb</command> stops at <function>main()</></>
+(gdb) <userinput>n</>						<lineannotation>Go to next line</>
+This is my program				<lineannotation>Program prints out</>
+(gdb) <userinput>s</>						<lineannotation>step into <function>bazz()</></>
+bazz (anint=4231) at temp.c:17			<lineannotation><command>gdb</command> displays stack frame</>
+(gdb)</screen></para>
+
+  
+<para>Hang on a minute! How did <symbol>anint</symbol> get to be
+<literal>4231</literal>? Didn't we set it to be <literal>5</literal>
+in <function>main()</function>? Let's move up to
+<function>main()</function> and have a look.</para>
+
+<para><screen>(gdb) <userinput>up</>					<lineannotation>Move up call stack</>
+#1  0x1625 in main () at temp.c:11		<lineannotation><command>gdb</command> displays stack frame</>
+(gdb) <userinput>p i</>					<lineannotation>Show us the value of <symbol>i</></>
+$1 = 4231					<lineannotation><command>gdb</command> displays <literal>4231</></></screen>
+Oh dear! Looking at the code, we forgot to initialise
+<symbol>i</symbol>. We meant to put
+<programlisting><lineannotation>&hellip;</>
+main() {
+	int i;
+
+	i = 5;
+	printf("This is my program\n");
+<lineannotation>&hellip</></programlisting>
+but we left the <literal>i=5;</literal> line out.  As we didn't
+initialise <symbol>i</symbol>, it had whatever number happened to be
+in that area of memory when the program ran, which in this case
+happened to be <literal>4231</literal>.</para>
+
+<note><para><command>gdb</command> displays the stack frame
+every time we go into or out of a function, even if we're using
+<command>up</command> and <command>down</command> to move around the
+call stack.  This shows the name of the function and the values of
+its arguments, which helps us keep track of where we are and what's
+going on. (The stack is a storage area where the program stores
+information about the arguments passed to functions and where to go
+when it returns from a function call).</para></note>
+
+</sect1>
+
+<sect1>
+<title>Examining a core file</title>
+
+<para>A core file is basically a file which contains the complete
+state of the process when it crashed. In <quote>the good old
+days</quote>, programmers had to print out hex listings of core files
+and sweat over machine code manuals, but now life is a bit easier.
+Incidentally, under FreeBSD and other 4.4BSD systems, a core file is
+called <filename><replaceable>progname</>.core</> instead of just
+<filename>core</filename>, to make it clearer which program a core
+file belongs to.</para>
+
+<para>To examine a core file, start up <command>gdb</command> in the
+usual way. Instead of typing <command>break</command> or
+<command>run</command>, type
+<screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
+If you're not in the same directory as the core file, you'll have to
+do <userinput>dir /path/to/core/file</userinput> first.</para>
+  
+<para>You should see something like this:
+<screen>$ <userinput>gdb a.out</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>core a.out.core</userinput>
+Core was generated by `a.out'.
+Program terminated with signal 11, Segmentation fault.
+Cannot access memory at address 0x7020796d.
+#0  0x164a in bazz (anint=0x5) at temp.c:17
+(gdb)</screen></para>
+  
+<para>In this case, the program was called
+<filename>a.out</filename>, so the core file is called
+<filename>a.out.core</filename>. We can see that the program crashed
+due to trying to access an area in memory that was not available to
+it in a function called <function>bazz</function>.</para>
+
+<para>Sometimes it's useful to be able to see how a function was
+called, as the problem could have occurred a long way up the call
+stack in a complex program. The <command>bt</command> command causes
+<command>gdb</command> to print out a back-trace of the call
+stack:
+<screen>(gdb) <userinput>bt</userinput>
+#0  0x164a in bazz (anint=0x5) at temp.c:17
+#1  0xefbfd888 in end ()
+#2  0x162c in main () at temp.c:11
+(gdb)</screen>The <function>end()</function> function is called when
+a program crashes; in this case, the <function>bazz()</function>
+function was called from <function>main()</function>.</para>
+
+</sect1>
+
+<sect1>
+<title>Attaching to a running program</title>
+
+<para>One of the neatest features about <command>gdb</command> is
+that it can attach to a program that's already running. Of course,
+that assumes you have sufficient permissions to do so. A common
+problem is when you are stepping through a program that forks, and
+you want to trace the child, but the debugger will only let you trace
+the parent.</para>
+
+<para>What you do is start up another <command>gdb</command>, use
+<command>ps</command> to find the process ID for the child, and
+do<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>  
+in <command>gdb</command>, and then debug as usual.</para>
+  
+<para><quote>That's all very well,</quote> you're probably thinking,
+<quote>but by the time I've done that, the child process will be over
+the hill and far away</quote>. Fear not, gentle reader, here's how to
+do it (courtesy of the <command>gdb</command> info pages):
+<screen><lineannotation>&hellip</lineannotation>
+if ((pid = fork()) < 0)		/* _Always_ check this */
+	error();
+else if (pid == 0) {		/* child */
+	int PauseMode = 1;
+
+	while (PauseMode)
+		sleep(10);	/* Wait until someone attaches to us */
+	<lineannotation>&hellip</lineannotation>
+} else {			/* parent */
+	<lineannotation>&hellip</lineannotation></screen>
+Now all you have to do is attach to the child, set
+<symbol>PauseMode</symbol> to <literal>0</literal>, and
+wait for the <function>sleep()</function> call to return!</para>
+  
+</sect1>
+</chapter>
+
+<chapter id="emacs">
+<title>Using Emacs as a Development Environment</title>
+
+<sect1>
+<title>Emacs</title>
+
+<para>Unfortunately, Unix systems don't come with the kind of
+everything-you-ever-wanted-and-lots-more-you-didn't-in-one-gigantic-package
+integrated development environments that other systems
+have.<footnote><para>At least, not unless you pay out very large sums
+of money.</para></footnote> However, it is possible to set up your
+own environment. It may not be as pretty, and it may not be quite as
+integrated, but you can set it up the way you want it. And it's free.
+And you have the source to it.</para>
+
+<para>The key to it all is Emacs. Now there are some people who
+loathe it, but many who love it. If you're one of the former, I'm
+afraid this section will hold little of interest to you. Also, you'll
+need a fair amount of memory to run it&mdash;I'd recommend 8MB in
+text mode and 16MB in X as the bare minimum to get reasonable
+performance.</para>
+
+<para>Emacs is basically a highly customisable editor&mdash;indeed,
+it has been customised to the point where it's more like an operating
+system than an editor! Many developers and sysadmins do in fact
+spend practically all their time working inside Emacs, leaving it
+only to log out.</para>
+
+<para>It's impossible even to summarise everything Emacs can do here, but
+here are some of the features of interest to developers:
+<itemizedlist>
+
+<listitem><para>Very powerful editor, allowing search-and-replace on
+both strings and regular expressions (patterns), jumping to start/end
+of block expression, etc, etc.</para></listitem>
+
+<listitem><para>Pull-down menus and online help.</para></listitem>
+
+<listitem><para>Language-dependent syntax highlighting and
+indentation.</para></listitem>
+
+<listitem><para>Completely customisable.</para></listitem>
+
+<listitem><para>You can compile and debug programs within
+Emacs.</para></listitem>
+
+<listitem><para>On a compilation error, you can jump to the offending
+line of source code.</para></listitem>
+
+<listitem><para>Friendly-ish front-end to the <command>info</command>
+program used for reading GNU hypertext documentation, including the
+documentation on Emacs itself.</para></listitem>
+
+<listitem><para>Friendly front-end to <command>gdb</command>,
+allowing you to look at the source code as you step through your
+program.</para></listitem>
+
+<listitem><para>You can read Usenet news and mail while your program
+is compiling.</para></listitem>
+
+</itemizedlist>And doubtless many more that I've overlooked.</para>
+
+<para>Emacs can be installed on FreeBSD using <ulink
+URL="http://www.freebsd.org/ports/editors">the Emacs
+port</ulink>.</para>
+
+<para>Once it's installed, start it up and do <userinput>C-h
+t</userinput> to read an Emacs tutorial&mdash;that means hold down
+the <keycap>control</keycap> key, press <keycap>h</keycap>, let go of
+the <keycap>control</keycap> key, and then press <keycap>t</keycap>.
+(Alternatively, you can you use the mouse to select <guimenuitem>Emacs
+Tutorial</guimenuitem> from the <guimenu>Help</guimenu> menu).</para>
+
+<para>Although Emacs does have menus, it's well worth learning the
+key bindings, as it's much quicker when you're editing something to
+press a couple of keys than to try and find the mouse and then click
+on the right place. And, when you're talking to seasoned Emacs users,
+you'll find they often casually throw around expressions like
+<quote><literal>M-x replace-s RET foo RET bar RET</literal></quote>
+so it's useful to know what they mean. And in any case, Emacs has far
+too many useful functions for them to all fit on the menu
+bars.</para>
+
+<para>Fortunately, it's quite easy to pick up the key-bindings, as
+they're displayed next to the menu item. My advice is to use the
+menu item for, say, opening a file until you understand how it works
+and feel confident with it, then try doing C-x C-f. When you're happy
+with that, move on to another menu command.</para>
+
+<para>If you can't remember what a particular combination of keys
+does, select <guimenuitem>Describe Key</guimenuitem> from the
+<guimenu>Help</guimenu> menu and type it in&mdash;Emacs will tell you
+what it does. You can also use the <guimenuitem>Command
+Apropos</guimenuitem> menu item to find out all the commands which
+contain a particular word in them, with the key binding next to
+it.</para>
+
+<para>By the way, the expression above means hold down the
+<keysym>Meta</keysym> key, press <keysym>x</keysym>, release the
+<keysym>Meta</keysym> key, type <userinput>replace-s</userinput>
+(short for <literal>replace-string</literal>&mdash;another feature of
+Emacs is that you can abbreviate commands), press the
+<keysym>return</keysym> key, type <userinput>foo</userinput> (the
+string you want replaced), press the <keysym>return</keysym> key,
+type bar (the string you want to replace <literal>foo</literal> with)
+and press <keysym>return</keysym> again. Emacs will then do the
+search-and-replace operation you've just requested.</para>
+
+<para>If you're wondering what on earth the <keysym>Meta</keysym> key
+is, it's a special key that many Unix workstations have.
+Unfortunately, PC's don't have one, so it's usually the
+<keycap>alt</keycap> key (or if you're unlucky, the <keysym>escape</keysym>
+key).</para>
+
+<para>Oh, and to get out of Emacs, do <command>C-c C-x</command>
+(that means hold down the <keysym>control</keysym> key, press
+<keysym>c</keysym>, press <keysym>x</keysym> and release the
+<keysym>control</keysym> key). If you have any unsaved files open,
+Emacs will ask you if you want to save them. (Ignore the bit in the
+documentation where it says <command>C-z</command> is the usual way
+to leave Emacs&mdash;that leaves Emacs hanging around in the
+background, and is only really useful if you're on a system which
+doesn't have virtual terminals).</para>
+
+</sect1>
+
+<sect1>
+<title>Configuring Emacs</title>
+
+<para>Emacs does many wonderful things; some of them are built in,
+some of them need to be configured.</para>
+
+<para>Instead of using a proprietary macro language for
+configuration, Emacs uses a version of Lisp specially adapted for
+editors, known as Emacs Lisp. This can be quite useful if you want to
+go on and learn something like Common Lisp, as it's considerably
+smaller than Common Lisp (although still quite big!).</para>
+
+<para>The best way to learn Emacs Lisp is to download the <ulink
+URL="ftp://prep.ai.mit.edu:pub/gnu/elisp-manual-19-2.4.tar.gz">Emacs
+Tutorial</ulink></para>
+
+<para>However, there's no need to actually know any Lisp to get
+started with configuring Emacs, as I've included a sample
+<filename>.emacs</filename> file, which should be enough to get you
+started. Just copy it into your home directory and restart Emacs if
+it's already running; it will read the commands from the file and
+(hopefully) give you a useful basic setup.</para>
+
+</sect1>
+
+<sect1>
+<title>A sample <filename>.emacs</filename> file</title>
+
+<para>Unfortunately, there's far too much here to explain it in detail;
+however there are one or two points worth mentioning.</para>
+  
+<para>
+<itemizedlist>
+
+<listitem><para>Everything beginning with a <literal>;</> is a
+comment and is ignored by Emacs.</para></listitem>
+
+<listitem><para>In the first line, the
+<literal>-*-&nbsp;Emacs-Lisp&nbsp;-*-</literal> is so that we can
+edit the <filename>.emacs</filename> file itself within Emacs and get
+all the fancy features for editing Emacs Lisp. Emacs usually tries to
+guess this based on the filename, and may not get it right for
+<filename>.emacs</filename>. </para></listitem>
+
+<listitem><para>The <keysym>tab</keysym> key is bound to an
+indentation function in some modes, so when you press the tab key, it
+will indent the current line of code. If you want to put a
+<token>tab</token> character in whatever you're writing, hold the
+<keysym>control</keysym> key down while you're pressing the
+<keysym>tab</keysym> key.</para></listitem>
+
+<listitem><para>This file supports syntax highlighting for C, C++,
+Perl, Lisp and Scheme, by guessing the language from the
+filename.</para></listitem>
+
+<listitem><para>Emacs already has a pre-defined function called
+<function>next-error</function>. In a compilation output window, this
+allows you to move from one compilation error to the next by doing
+<command>M-n</command>; we define a complementary function,
+<function>previous-error</function>, that allows you to go to a
+previous error by doing <command>M-p</command>. The nicest feature of
+all is that <command>C-c C-c</command> will open up the source file
+in which the error occurred and jump to the appropriate
+line.</para></listitem>
+
+<listitem><para> We enable Emacs's ability to act as a server, so
+that if you're doing something outside Emacs and you want to edit a
+file, you can just type in 
+<screen>$ <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
+and then you can edit the file in your Emacs!<footnote><para>Many
+Emacs users set their <systemitem
+class=environvar>EDITOR</systemitem> environment to
+<literal>emacsclient</literal> so this happens every time they need
+to edit a file.</para></footnote></para></listitem>
+
+</itemizedlist>
+</para>
+  
+<example>
+<title>A sample <filename>.emacs</filename> file</title>
+<screen>;; -*-Emacs-Lisp-*-
+
+;; This file is designed to be re-evaled; use the variable first-time
+;; to avoid any problems with this.
+(defvar first-time t 
+  "Flag signifying this is the first time that .emacs has been evaled")
+
+;; Meta
+(global-set-key "\M- " 'set-mark-command)
+(global-set-key "\M-\C-h" 'backward-kill-word)
+(global-set-key "\M-\C-r" 'query-replace)
+(global-set-key "\M-r" 'replace-string)
+(global-set-key "\M-g" 'goto-line)
+(global-set-key "\M-h" 'help-command)
+
+;; Function keys
+(global-set-key [f1] 'manual-entry)
+(global-set-key [f2] 'info)
+(global-set-key [f3] 'repeat-complex-command)
+(global-set-key [f4] 'advertised-undo)
+(global-set-key [f5] 'eval-current-buffer)
+(global-set-key [f6] 'buffer-menu)
+(global-set-key [f7] 'other-window)
+(global-set-key [f8] 'find-file)
+(global-set-key [f9] 'save-buffer)
+(global-set-key [f10] 'next-error)
+(global-set-key [f11] 'compile)
+(global-set-key [f12] 'grep)
+(global-set-key [C-f1] 'compile)
+(global-set-key [C-f2] 'grep)
+(global-set-key [C-f3] 'next-error)
+(global-set-key [C-f4] 'previous-error)
+(global-set-key [C-f5] 'display-faces)
+(global-set-key [C-f8] 'dired)
+(global-set-key [C-f10] 'kill-compilation)
+
+;; Keypad bindings
+(global-set-key [up] "\C-p")
+(global-set-key [down] "\C-n")
+(global-set-key [left] "\C-b")
+(global-set-key [right] "\C-f")
+(global-set-key [home] "\C-a")
+(global-set-key [end] "\C-e")
+(global-set-key [prior] "\M-v")
+(global-set-key [next] "\C-v")
+(global-set-key [C-up] "\M-\C-b")
+(global-set-key [C-down] "\M-\C-f")
+(global-set-key [C-left] "\M-b")
+(global-set-key [C-right] "\M-f")
+(global-set-key [C-home] "\M-&lt;")
+(global-set-key [C-end] "\M-&gt;")
+(global-set-key [C-prior] "\M-&lt;")
+(global-set-key [C-next] "\M-&gt;")
+
+;; Mouse
+(global-set-key [mouse-3] 'imenu)
+
+;; Misc
+(global-set-key [C-tab] "\C-q\t")	; Control tab quotes a tab.
+(setq backup-by-copying-when-mismatch t)
+
+;; Treat 'y' or &lt;CR&gt; as yes, 'n' as no.
+(fset 'yes-or-no-p 'y-or-n-p)
+    (define-key query-replace-map [return] 'act)
+    (define-key query-replace-map [?\C-m] 'act)
+
+;; Load packages
+(require 'desktop)
+(require 'tar-mode)
+
+;; Pretty diff mode
+(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files-remote "ediff"
+  "Intelligent Emacs interface to diff") </screen>
+
+<screen>(if first-time
+    (setq auto-mode-alist
+	  (append '(("\\.cpp$" . c++-mode)
+		    ("\\.hpp$" . c++-mode)
+                    ("\\.lsp$" . lisp-mode)
+		    ("\\.scm$" . scheme-mode)
+		    ("\\.pl$" . perl-mode)
+		    ) auto-mode-alist)))
+
+;; Auto font lock mode
+(defvar font-lock-auto-mode-list 
+  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
+  "List of modes to always start in font-lock-mode")
+
+(defvar font-lock-mode-keyword-alist
+  '((c++-c-mode . c-font-lock-keywords)
+    (perl-mode . perl-font-lock-keywords))
+  "Associations between modes and keywords")
+
+(defun font-lock-auto-mode-select ()
+  "Automatically select font-lock-mode if the current major mode is
+in font-lock-auto-mode-list"
+  (if (memq major-mode font-lock-auto-mode-list) 
+      (progn
+	(font-lock-mode t))
+    )
+  )
+
+(global-set-key [M-f1] 'font-lock-fontify-buffer)
+
+;; New dabbrev stuff
+;(require 'new-dabbrev)
+(setq dabbrev-always-check-other-buffers t)
+(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+(add-hook 'emacs-lisp-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
+	     (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'c-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) nil)
+	     (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'text-mode-hook
+	  '(lambda () 
+	     (set (make-local-variable 'dabbrev-case-fold-search) t)
+	     (set (make-local-variable 'dabbrev-case-replace) t)))
+
+;; C++ and C mode...
+(defun my-c++-mode-hook ()
+  (setq tab-width 4)
+  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key c++-mode-map "\C-ce" 'c-comment-edit)
+  (setq c++-auto-hungry-initial-state 'none)
+  (setq c++-delete-function 'backward-delete-char)
+  (setq c++-tab-always-indent t)
+  (setq c-indent-level 4)
+  (setq c-continued-statement-offset 4)
+  (setq c++-empty-arglist-indent 4))
+
+(defun my-c-mode-hook ()
+  (setq tab-width 4)
+  (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key c-mode-map "\C-ce" 'c-comment-edit)
+  (setq c-auto-hungry-initial-state 'none)
+  (setq c-delete-function 'backward-delete-char)
+  (setq c-tab-always-indent t)
+;; BSD-ish indentation style
+  (setq c-indent-level 4)
+  (setq c-continued-statement-offset 4)
+  (setq c-brace-offset -4)
+  (setq c-argdecl-indent 0)
+  (setq c-label-offset -4))
+
+;; Perl mode
+(defun my-perl-mode-hook ()
+  (setq tab-width 4)
+  (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (setq perl-indent-level 4)
+  (setq perl-continued-statement-offset 4))
+
+;; Scheme mode...
+(defun my-scheme-mode-hook ()
+  (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
+
+;; Emacs-Lisp mode...
+(defun my-lisp-mode-hook ()
+  (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
+  (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
+  (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
+
+;; Add all of the hooks...
+(add-hook 'c++-mode-hook 'my-c++-mode-hook)
+(add-hook 'c-mode-hook 'my-c-mode-hook)
+(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
+(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'perl-mode-hook 'my-perl-mode-hook)
+
+;; Complement to next-error
+(defun previous-error (n)
+  "Visit previous compilation error message and corresponding source code."
+  (interactive "p")
+  (next-error (- n)))</screen>
+
+<screen>;; Misc...
+(transient-mark-mode 1)
+(setq mark-even-if-inactive t)
+(setq visible-bell nil)
+(setq next-line-add-newlines nil)
+(setq compile-command "make")
+(setq suggest-key-bindings nil)
+(put 'eval-expression 'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+(put 'set-goal-column 'disabled nil)
+
+;; Elisp archive searching
+(autoload 'format-lisp-code-directory "lispdir" nil t)
+(autoload 'lisp-dir-apropos "lispdir" nil t)
+(autoload 'lisp-dir-retrieve "lispdir" nil t)
+(autoload 'lisp-dir-verify "lispdir" nil t)
+
+;; Font lock mode
+(defun my-make-face (face colour &amp;optional bold)
+  "Create a face from a colour and optionally make it bold"
+  (make-face face)
+  (copy-face 'default face)
+  (set-face-foreground face colour)
+  (if bold (make-face-bold face))
+  )
+
+(if (eq window-system 'x)
+    (progn
+      (my-make-face 'blue "blue")
+      (my-make-face 'red "red")
+      (my-make-face 'green "dark green")
+      (setq font-lock-comment-face 'blue)
+      (setq font-lock-string-face 'bold)
+      (setq font-lock-type-face 'bold)
+      (setq font-lock-keyword-face 'bold)
+      (setq font-lock-function-name-face 'red)
+      (setq font-lock-doc-string-face 'green)
+      (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
+
+      (setq baud-rate 1000000)
+      (global-set-key "\C-cmm" 'menu-bar-mode)
+      (global-set-key "\C-cms" 'scroll-bar-mode)
+      (global-set-key [backspace] 'backward-delete-char)
+					;      (global-set-key [delete] 'delete-char)
+      (standard-display-european t)
+      (load-library "iso-transl")))
+
+;; X11 or PC using direct screen writes
+(if window-system
+    (progn
+      ;;      (global-set-key [M-f1] 'hilit-repaint-command)
+      ;;      (global-set-key [M-f2] [?\C-u M-f1])
+      (setq hilit-mode-enable-list  
+	    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
+		  scheme-mode)
+	    hilit-auto-highlight nil
+	    hilit-auto-rehighlight 'visible
+	    hilit-inhibit-hooks nil
+	    hilit-inhibit-rebinding t)
+      (require 'hilit19)
+      (require 'paren))
+  (setq baud-rate 2400)			; For slow serial connections
+  )
+
+;; TTY type terminal
+(if (and (not window-system) 
+	 (not (equal system-type 'ms-dos)))
+    (progn
+      (if first-time
+	  (progn
+	    (keyboard-translate ?\C-h ?\C-?)
+	    (keyboard-translate ?\C-? ?\C-h)))))
+
+;; Under UNIX
+(if (not (equal system-type 'ms-dos))
+    (progn
+      (if first-time
+	  (server-start))))
+
+;; Add any face changes here
+(add-hook 'term-setup-hook 'my-term-setup-hook)
+(defun my-term-setup-hook ()
+  (if (eq window-system 'pc)
+      (progn
+;;	(set-face-background 'default "red")
+	)))
+
+;; Restore the "desktop" - do this as late as possible
+(if first-time
+    (progn
+      (desktop-load-default)
+      (desktop-read)))
+
+;; Indicate that this file has been read at least once
+(setq first-time nil)
+
+;; No need to debug anything now
+(setq debug-on-error nil)
+
+;; All done
+(message "All done, %s%s" (user-login-name) ".")
+</screen>
+</example>
+  
+</sect1>
+
+<sect1>
+<title>Extending the Range of Languages Emacs Understands</title>
+
+<para>Now, this is all very well if you only want to program in the
+languages already catered for in the <filename>.emacs</filename> file
+(C, C++, Perl, Lisp and Scheme), but what happens if a new language
+called <quote>whizbang</quote> comes out, full of exciting
+features?</para>
+
+<para>The first thing to do is find out if whizbang
+comes with any files that tell Emacs about the language. These
+usually end in <filename>.el</filename>, short for <quote>Emacs
+Lisp</quote>. For example, if whizbang is a FreeBSD
+port, we can locate these files by doing
+<screen>$ <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
+and install them by copying them into the Emacs site Lisp directory. On
+FreeBSD 2.1.0-RELEASE, this is
+<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
+
+<para>So for example, if the output from the find command was
+<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
+we would do
+<screen>$ <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
+</para>
+  
+<para>Next, we need to decide what extension whizbang source files
+have. Let's say for the sake of argument that they all end in
+<filename>.wiz</filename>. We need to add an entry to our
+<filename>.emacs</filename> file to make sure Emacs will be able to
+use the information in <filename>whizbang.el</filename>.</para>
+
+<para>Find the <symbol>auto-mode-alist entry</symbol> in
+<filename>.emacs</filename> and add a line for whizbang, such
+as:
+<programlisting><lineannotation>&hellip;</>
+("\\.lsp$" . lisp-mode)
+("\\.wiz$" . whizbang-mode)
+("\\.scm$" . scheme-mode)
+<lineannotation>&hellip;</></programlisting>  
+This means that Emacs will automatically go into
+<function>whizbang-mode</function> when you edit a file ending in
+<filename>.wiz</filename>.</para>
+
+<para>Just below this, you'll find the
+<symbol>font-lock-auto-mode-list</symbol> entry. Add
+<function>whizbang-mode</function> to it like so:
+<programlisting>;; Auto font lock mode
+(defvar font-lock-auto-mode-list 
+  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
+  "List of modes to always start in font-lock-mode")</programlisting>
+This means that Emacs will always enable
+<function>font-lock-mode</function> (ie syntax highlighting) when
+editing a <filename>.wiz</filename> file.</para>
+
+<para>And that's all that's needed. If there's anything else you want
+done automatically when you open up a <filename>.wiz</filename> file,
+you can add a <function>whizbang-mode hook</function> (see
+<function>my-scheme-mode-hook</function> for a simple example that
+adds <function>auto-indent</function>).</para>
+  
+</sect1>
+</chapter>
+
+<chapter>
+<title>Further Reading</title>
+
+<itemizedlist>
+<listitem><para>Brian Harvey and Matthew Wright
+<emphasis>Simply Scheme</emphasis>
+MIT 1994.<!-- <br> -->
+ISBN 0-262-08226-8</para></listitem>
+
+<listitem><para>Randall Schwartz
+<emphasis>Learning Perl</emphasis>
+O'Reilly 1993<!-- <br> -->
+ISBN 1-56592-042-2</para></listitem>
+
+<listitem><para>Patrick Henry Winston and Berthold Klaus Paul Horn
+<emphasis>Lisp (3rd Edition)</emphasis>
+Addison-Wesley 1989<!-- <br> -->
+ISBN 0-201-08319-1</para></listitem>
+
+<listitem><para>Brian W. Kernighan and Rob Pike
+<emphasis>The Unix Programming Environment</emphasis>
+Prentice-Hall 1984<!-- <br> -->
+ISBN 0-13-937681-X</para></listitem>
+
+<listitem><para>Brian W. Kernighan and Dennis M. Ritchie
+<emphasis>The C Programming Language (2nd Edition)</emphasis>
+Prentice-Hall 1988<!-- <br> -->
+ISBN 0-13-110362-8</para></listitem>
+
+<listitem><para>Bjarne Stroustrup
+<emphasis>The C++ Programming Language</emphasis>
+Addison-Wesley 1991<!-- <br> -->
+ISBN 0-201-53992-6</para></listitem>
+
+<listitem><para>W. Richard Stevens
+<emphasis>Advanced Programming in the Unix Environment</emphasis>
+Addison-Wesley 1992<!-- <br> -->
+ISBN 0-201-56317-7</para></listitem>
+
+<listitem><para>W. Richard Stevens
+<emphasis>Unix Network Programming</emphasis>
+Prentice-Hall 1990<!-- <br> -->
+ISBN 0-13-949876-1</para></listitem>
+
+</itemizedlist>
+
+</chapter>
+</book>
diff --git a/en_US.ISO_8859-1/tutorials/Makefile b/en_US.ISO_8859-1/tutorials/Makefile
index 40a10bc3f1..e414259fe1 100644
--- a/en_US.ISO_8859-1/tutorials/Makefile
+++ b/en_US.ISO_8859-1/tutorials/Makefile
@@ -1,5 +1,5 @@
 DOCS=		index.sgml
-SUBDIR=		disklessx newuser
-DOCSUBDIR=	ddwg devel fonts mh multios ppp
+SUBDIR=		devel disklessx newuser
+DOCSUBDIR=	ddwg fonts mh multios ppp
 
 .include "../web.mk"
diff --git a/en_US.ISO_8859-1/tutorials/index.sgml b/en_US.ISO_8859-1/tutorials/index.sgml
index ebbc838f65..0f785a2caf 100644
--- a/en_US.ISO_8859-1/tutorials/index.sgml
+++ b/en_US.ISO_8859-1/tutorials/index.sgml
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN" [
 <!ENTITY base CDATA "..">
-<!ENTITY date "$Date: 1997-01-18 02:24:07 $">
+<!ENTITY date "$Date: 1997-01-19 15:29:57 $">
 <!ENTITY title "FreeBSD Tutorials">
 <!ENTITY % includes SYSTEM "../includes.sgml"> %includes;
 ]>
@@ -19,9 +19,8 @@
       	    (<a href="mh/mh.ps">postscript</a>,
 		<a href="mh/mh-html.tar.gz">gzipd tar file</a>)</li>
 
-      <li><a href="devel/devel.html">A User's Guide to FreeBSD Programming Tools</a>
-      	    (<a href="devel/devel.ps">postscript</a>,
-		<a href="devel/devel-html.tar.gz">gzipd tar file</a>)</li>
+      <li><a href="devel/devel.html">A User's Guide to FreeBSD Programming
+	Tools</a></li>
 
       <li><a href="ddwg/ddwg.html">Writing device drivers for FreeBSD</a>
       	    (<a href="ddwg/ddwg.ps">postscript</a>,