aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--en_US.ISO8859-1/articles/programming-tools/article.sgml2227
1 files changed, 5 insertions, 2222 deletions
diff --git a/en_US.ISO8859-1/articles/programming-tools/article.sgml b/en_US.ISO8859-1/articles/programming-tools/article.sgml
index 12db95ba14..ae9d862e30 100644
--- a/en_US.ISO8859-1/articles/programming-tools/article.sgml
+++ b/en_US.ISO8859-1/articles/programming-tools/article.sgml
@@ -1,2234 +1,17 @@
-<!-- $FreeBSD: doc/en_US.ISO8859-1/articles/programming-tools/article.sgml,v 1.15 2001/04/17 15:53:39 nik Exp $ -->
+<!-- $FreeBSD: doc/en_US.ISO8859-1/articles/programming-tools/article.sgml,v 1.16 2001/07/06 13:02:51 dd Exp $ -->
<!-- The FreeBSD Documentation Project -->
<!DOCTYPE ARTICLE PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN">
<article>
<articleinfo>
<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>August 17, 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>
</articleinfo>
<sect1>
- <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</command> and <command>awk</command>. 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</acronym> and <acronym>ANSI</acronym> 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>
- </sect1>
-
- <sect1>
- <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</firstterm>, the other a
- <firstterm>compiler</firstterm>. 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>
-
- <sect2>
- <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>, <command>csh</command>) is itself an
- interpreter, and many people do in fact write shell
- <quote>scripts</quote> to help with various
- <quote>housekeeping</quote> 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>
- </sect2>
-
- <sect2>
- <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</para>
-
- <screen>&prompt.root; <userinput>pkg_add <replaceable>package name</></userinput></screen>
-
- <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>
-
- <variablelist>
- <varlistentry>
- <term><acronym>BASIC</acronym></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</acronym> has been the first programming
- language for many programmers. It's also the foundation
- for 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</acronym> scripts.</para>
-
- <para>The latest version (version 5) comes with FreeBSD.</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>
- </sect2>
-
- <sect2>
- <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</acronym> as such; however it is possible to use Emacs
- for this purpose. This is discussed in <xref
- linkend="emacs">.</para>
- </sect2>
- </sect1>
-
- <sect1>
- <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</command> or <command>gcc</command>. 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</command> converts the
- source code into its own, machine-independent
- <firstterm>p-code</firstterm> 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</firstterm> is often used to refer to
- just steps 1 to 4&mdash;the others are referred to as
- <firstterm>linking</firstterm>. Sometimes step 1 is referred to as
- <firstterm>pre-processing</firstterm> and steps 3-4 as
- <firstterm>assembling</firstterm>.</para>
-
- <para>Fortunately, almost all this detail is hidden from you, as
- <command>cc</command> is a front end that manages calling all these
- programs with the right arguments for you; simply typing</para>
-
- <screen>&prompt.user; <userinput>cc foobar.c</></screen>
-
- <para>will cause <filename>foobar.c</filename> to be compiled by all the
- steps above. If you have more than one file to compile, just do
- something like</para>
-
- <screen>&prompt.user; <userinput>cc foo.c bar.c</></screen>
-
- <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</command>, 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></option></term>
-
- <listitem>
- <para>The output name of the file. If you do not use this
- option, <command>cc</command> will produce an executable called
- <filename>a.out</filename>.
-
- <footnote>
- <para>The reasons for this are buried in the mists of
- history.</para>
- </footnote></para>
-
- <informalexample>
- <screen>&prompt.user; <userinput>cc foobar.c</> <lineannotation>executable is <filename>a.out</></>
-&prompt.user; <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>&prompt.user; <userinput>cc -c foobar.c</userinput>
- </screen>
- </informalexample>
-
- <para>This will produce an <firstterm>object file</firstterm> (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>&prompt.user; <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>&prompt.user; <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</acronym>&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</acronym>&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>&prompt.user; <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>&prompt.user; <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>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>For FreeBSD 2.1.6 and earlier</>
-&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>For FreeBSD 2.2 and later</>
-&prompt.user; <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
- MS-DOS 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>
-
- <sect2>
- <title>Common <command>cc</command> Queries and Problems</title>
-
- <qandaset>
- <qandaentry>
- <question>
- <para>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?</para>
-
- <informalexample>
- <screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment
- </screen>
- </informalexample>
- </question>
-
- <answer>
- <para>When using mathematical functions like
- <function>sin()</function>, you have to tell
- <command>cc</command> to link in the math library, like
- so:</para>
-
- <informalexample>
- <screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
- </screen>
- </informalexample>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>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.</para>
-
- <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>
-
- <para>and I compiled it as:</para>
-
- <informalexample>
- <screen>&prompt.user; <userinput>cc temp.c -lm</userinput>
- </screen>
- </informalexample>
-
- <para>like you said I should, but I get this when I run
- it:</para>
-
- <informalexample>
- <screen>&prompt.user; <userinput>./a.out</userinput>
-2.1 ^ 6 = 1023.000000
- </screen>
- </informalexample>
-
- <para>This is <emphasis>not</emphasis> the right answer!
- What is going on?</para>
- </question>
-
- <answer>
- <para>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>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>So how do I fix this?</para>
- </question>
-
- <answer>
- <para>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!</para>
-
- <informalexample>
- <programlisting>#include &lt;math.h&gt;
-#include &lt;stdio.h&gt;
-
-int main() {
-...
- </programlisting>
- </informalexample>
-
- <para>After recompiling it as you did before, run
- it:</para>
-
- <informalexample>
- <screen>&prompt.user; <userinput>./a.out</userinput>
-2.1 ^ 6 = 85.766121
- </screen>
- </informalexample>
-
- <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>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>I compiled a file called
- <filename>foobar.c</filename> and I cannot find an
- executable called <filename>foobar</filename>. Where's
- it gone?</para>
- </question>
-
- <answer>
- <para>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:</para>
-
- <informalexample>
- <screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput>
- </screen>
- </informalexample>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>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>
- </question>
-
- <answer>
- <para>Unlike MS-DOS, 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 <envar
- >PATH</envar> environment
- variable so that it looks something like</para>
-
- <informalexample>
- <screen>bin:/usr/bin:/usr/local/bin:.
- </screen>
- </informalexample>
-
- <para>The dot at the end means <quote>look in the current
- directory if it is not in any of the
- others</quote>.</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>I called my executable <filename>test</filename>,
- but nothing happens when I run it. What is going
- on?</para>
- </question>
-
- <answer>
- <para>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:</para>
-
- <informalexample>
- <screen>&prompt.user; <userinput>./test</userinput>
- </screen>
- </informalexample>
-
- <para>or choose a better name for your program!</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>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>
- </question>
-
- <answer>
- <para>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>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>Fascinating stuff, but what I am supposed to do
- now?</para>
- </question>
-
- <answer>
- <para>Use <command>gdb</command> to analyse the core (see
- <xref linkend="debugging">).</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>When my program dumped core, it said something about
- a <errorname>segmentation fault</errorname>. What's
- that?</para>
- </question>
-
- <answer>
- <para>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:</para>
-
- <itemizedlist>
- <listitem>
- <para>Trying to write to a <symbol>NULL</symbol>
- pointer, eg</para>
-
- <programlisting>char *foo = NULL;
-strcpy(foo, "bang!");
- </programlisting>
- </listitem>
-
- <listitem>
- <para>Using a pointer that hasn't been initialised,
- eg</para>
-
- <programlisting>char *foo;
-strcpy(foo, "bang!");
- </programlisting>
-
- <para>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</para>
-
- <programlisting>int bar[20];
-bar[27] = 6;
- </programlisting>
- </listitem>
-
- <listitem>
- <para>Trying to store something in read-only memory,
- eg</para>
-
- <programlisting>char *foo = "My string";
-strcpy(foo, "bang!");
- </programlisting>
-
- <para>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</para>
-
- <programlisting>char bar[80];
-free(bar);
- </programlisting>
-
- <para>or</para>
-
- <programlisting>char *foo = malloc(27);
-free(foo);
-free(foo);
- </programlisting>
- </listitem>
- </itemizedlist>
-
- <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>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>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>
- </question>
-
- <answer>
- <para>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>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question>
- <para>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>
- </question>
-
- <answer>
- <para>Yes, just go to another console or xterm, do</para>
-
- <screen>&prompt.user; <userinput>ps</userinput>
- </screen>
-
- <para>to find out the process ID of your program, and
- do</para>
-
- <screen>&prompt.user; <userinput>kill -ABRT <replaceable>pid</replaceable></userinput>
- </screen>
-
- <para>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>
- </answer>
- </qandaentry>
- </qandaset>
- </sect2>
- </sect1>
-
- <sect1>
- <title>Make</title>
-
- <sect2>
- <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</para>
-
- <screen>&prompt.user; <userinput>cc file1.c file2.c</userinput></screen>
-
- <para>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:</para>
-
- <screen>&prompt.user; <userinput>cc file1.o file2.o</userinput> &hellip; <userinput>file37.c</userinput> &hellip</screen>
-
- <para>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>
- </sect2>
-
- <sect2>
- <title>Example of using <command>make</command></title>
-
- <para>Here's a very simple make file:</para>
-
- <programlisting>foo: foo.c
- cc -o foo foo.c</programlisting>
-
- <para>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:</para>
-
- <programlisting>foo: foo.c
- cc -o foo foo.c
-
-install:
- cp foo /home/me</programlisting>
-
- <para>We can tell make which target we want to make by
- typing:</para>
-
- <screen>&prompt.user; <userinput>make <replaceable>target</replaceable></userinput></screen>
-
- <para><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>
- </sect2>
-
- <sect2>
- <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>:</para>
-
- <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>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>
- </sect2>
-
- <sect2>
- <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</para>
-
- <screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen>
-
- <para>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</para>
-
- <programlisting> * Make: (make). The GNU Make utility.</programlisting>
-
- <para>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>
- </sect2>
- </sect1>
-
- <sect1 id="debugging">
- <title>Debugging</title>
-
- <sect2>
- <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</para>
-
- <screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
-
- <para>although most people prefer to run it inside
- <application>Emacs</application>. You can do this by:</para>
-
- <screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen>
-
- <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="../../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>
- </sect2>
-
- <sect2>
- <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:</para>
-
- <screen>&hellip; (no debugging symbols found) &hellip;</screen>
-
- <para>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):</para>
-
- <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>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</para>
-
- <screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
-&prompt.user; <userinput>./temp</userinput>
-This is my program
-anint = 4231</screen>
-
- <para>That wasn't what we expected! Time to see what's going
- on!</para>
-
- <screen>&prompt.user; <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>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>
-
- <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>
-
- <para>Oh dear! Looking at the code, we forgot to initialise
- <symbol>i</symbol>. We meant to put</para>
-
- <programlisting><lineannotation>&hellip;</>
-main() {
- int i;
-
- i = 5;
- printf("This is my program\n");
-<lineannotation>&hellip</></programlisting>
-
- <para>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>
- </sect2>
-
- <sect2>
- <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</replaceable>.core</filename> 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</para>
-
- <screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
-
- <para>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:</para>
-
- <screen>&prompt.user; <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>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:</para>
-
- <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>
-
- <para>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>
- </sect2>
-
- <sect2>
- <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</para>
-
- <screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
-
- <para>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):</para>
-
- <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>
-
- <para>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>
- </sect2>
- </sect1>
-
- <sect1 id="emacs">
- <title>Using Emacs as a Development Environment</title>
-
- <sect2>
- <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:</para>
-
- <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>
-
- <para>And doubtless many more that I've overlooked.</para>
-
- <para>Emacs can be installed on FreeBSD using <ulink
- URL="../../ports/editors.html">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-x C-c</command>
- (that means hold down the <keysym>control</keysym> key, press
- <keysym>x</keysym>, press <keysym>c</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>
- </sect2>
-
- <sect2>
- <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>
- </sect2>
-
- <sect2>
- <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>
-
- <itemizedlist>
- <listitem>
- <para>Everything beginning with a <literal>;</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</para>
-
- <screen>&prompt.user; <userinput>emacsclient <replaceable>filename</replaceable></userinput>
- </screen>
-
- <para>and then you can edit the file in your
- Emacs!
-
- <footnote>
- <para>Many Emacs users set their <envar
- >EDITOR</envar> environment to
- <literal>emacsclient</literal> so this happens every
- time they need to edit a file.</para>
- </footnote></para>
- </listitem>
- </itemizedlist>
-
- <example>
- <title>A sample <filename>.emacs</filename> file</title>
-
- <programlisting>;; -*-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")
-
-(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)))
-
-;; 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) ".")
- </programlisting>
- </example>
- </sect2>
-
- <sect2>
- <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</para>
-
- <screen>&prompt.user; <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
-
- <para>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</para>
-
- <screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
-
- <para>we would do</para>
-
- <screen>&prompt.root; <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
-
- <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:</para>
-
- <programlisting><lineannotation>&hellip;</>
-("\\.lsp$" . lisp-mode)
-("\\.wiz$" . whizbang-mode)
-("\\.scm$" . scheme-mode)
-<lineannotation>&hellip;</></programlisting>
-
- <para>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:</para>
-
- <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>
-
- <para>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>
- </sect2>
- </sect1>
-
- <sect1>
- <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>
+ <title>This document has moved!</title>
- <listitem>
- <para>W. Richard Stevens
- <emphasis>Unix Network Programming</emphasis>
- Prentice-Hall 1990<!-- <br> -->
- ISBN 0-13-949876-1</para>
- </listitem>
- </itemizedlist>
+ <para>This document has been integrated into the <ulink
+ url="../../books/developers-handbook/">Developer's
+ Handbook</ulink>. Please update your bookmarks.</para>
</sect1>
</article>