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 @@ - +
A User's Guide to FreeBSD Programming Tools - - - - James - - Raynard - - -
- jraynard@FreeBSD.org -
-
-
-
- - August 17, 1997 - - - 1997 - James Raynard - - - - 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 - 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 -
- Introduction<anchor id=foo> - - 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 is - not 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. - - 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. - - 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! - - - - Introduction to Programming - - 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 are 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. - - - Interpreters - - 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. - - 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. - - 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 (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. - - - - Interpreters available with FreeBSD - - Here is a list of interpreters that are available as - FreeBSD - packages, with a brief discussion of some of the - more popular interpreted languages. - - To get one of these packages, all you need to do is to - click on the hotlink for the package, then run - - &prompt.root; pkg_add package name - - as root. Obviously, you will need to have a fully - functional FreeBSD 2.1.0 or later system for the package to - work! - - - - BASIC - - - 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 Bywater - Basic Interpreter and the Phil - Cockroft's Basic Interpreter (formerly Rabbit - Basic) are available as FreeBSD FreeBSD - packages - - - - - Lisp - - - 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 GNU - Common Lisp available as a package. - - - - - Perl - - - Very popular with system administrators for writing - scripts; also often used on World Wide Web servers for - writing CGI scripts. - - The latest version (version 5) comes with FreeBSD. - - - - - Scheme - - - 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. - - FreeBSD has packages of the Elk - Scheme Interpreter, the MIT - Scheme Interpreter and the SCM - Scheme Interpreter. - - - - - Icon - - - The - Icon Programming Language. - - - - - Logo - - - Brian - Harvey's LOGO Interpreter. - - - - - Python - - - The - Python Object-Oriented Programming - Language - - - - - - - Compilers - - 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. - - - If you run it in the shell, you may get a core - dump. - - - 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—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—you - can just give them a copy of the executable, assuming they - have the same operating system as you. - - 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. - - 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 does not have an - IDE as such; however it is possible to use Emacs - for this purpose. This is discussed in . - - - - - Compiling with <command>cc</command> - - 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. - - 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. - - - - Pre-process your source code to remove comments and do - other tricks like expanding macros in C. - - - - Check the syntax of your code to see if you have obeyed - the rules of the language. If you have not, it will - complain! - - - - Convert the source code into assembly - language—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 assembly language at - this stage. - - - - - Convert the assembly language into machine - code—yep, we are talking bits and bytes, ones and - zeros here. - - - - 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. - - - - If you are trying to produce an executable from several - source code files, work out how to fit them all - together. - - - - Work out how to produce something that the system's - run-time loader will be able to load into memory and - run. - - - - Finally, write the executable on the file system. - - - - 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. - - 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 - - &prompt.user; cc foobar.c - - 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 - - &prompt.user; cc foo.c bar.c - - Note that the syntax checking is just that—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. - - - In case you didn't know, a binary sort is an efficient - way of sorting things into order and a bubble sort - isn't. - - - 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. - - - - - - - The output name of the file. If you do not use this - option, cc will produce an executable called - a.out. - - - The reasons for this are buried in the mists of - history. - - - - &prompt.user; cc foobar.c executable is a.out -&prompt.user; cc -o foobar foobar.c executable is foobar - - - - - - - - - - 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 Makefile. - - - &prompt.user; cc -c foobar.c - - - - This will produce an object file (not an - executable) called foobar.o. This - can be linked together with other object files into an - executable. - - - - - - - - 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 - very useful; the disadvantage is that - all this extra information makes the program much bigger. - Normally, you compile with while you - are developing a program and then compile a release - version without when you're - satisfied it works properly. - - - &prompt.user; cc -g foobar.c - - - - This will produce a debug version of the - program. - - - Note, we didn't use the flag - to specify the executable name, so we will get an - executable called a.out. - Producing a debug version called - foobar is left as an exercise for - the reader! - - - - - - - - - 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 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 - option in some circumstances. - - Optimisation is usually only turned on when compiling - a release version. - - - &prompt.user; cc -O -o foobar foobar.c - - - - This will produce an optimised version of - foobar. - - - - - 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 is an - ISO standard. - - - - - - - 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. - - - - - - - - Turn off most, but not all, of the - non-ANSI C features provided by - cc. Despite the name, it does not - guarantee strictly that your code will comply to the - standard. - - - - - - - - Turn off all - cc's non-ANSI C - features. - - - - - 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. - - 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? - - - &prompt.user; cc -Wall -ansi -pedantic -o foobar foobar.c - - - This will produce an executable foobar - after checking foobar.c for standard - compliance. - - - - - - - Specify a function library to be used during when - linking. - - 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. - - The rule is that if the library is called - libsomething.a, - you give cc the argument - . - For example, the math library is - libm.a, so you give - cc the argument . - A common gotcha with the math library is - that it has to be the last library on the command - line. - - - &prompt.user; cc -o foobar foobar.c -lm - - - - This will link the math library functions into - foobar. - - If you are compiling C++ code, you need to add - , or if - you are using FreeBSD 2.2 or later, to the command line - argument to link the C++ library functions. - Alternatively, you can run c++ instead - of cc, which does this for you. - c++ can also be invoked as - g++ on FreeBSD. - - - &prompt.user; cc -o foobar foobar.cc -lg++ For FreeBSD 2.1.6 and earlier -&prompt.user; cc -o foobar foobar.cc -lstdc++ For FreeBSD 2.2 and later -&prompt.user; c++ -o foobar foobar.cc - - - - Each of these 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 - MS-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! - - - - - - Common <command>cc</command> Queries and Problems - - - - - I am trying to write a program which uses the - sin() function and I get an error - like this. What does it mean? - - - /var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment - - - - - - When using mathematical functions like - sin(), you have to tell - cc to link in the math library, like - so: - - - &prompt.user; cc -o foobar foobar.c -lm - - - - - - - - All right, I wrote this simple program to practice - using . All it does is raise 2.1 to - the power of 6. - - - #include <stdio.h> - -int main() { - float f; - - f = pow(2.1, 6); - printf("2.1 ^ 6 = %f\n", f); - return 0; -} - - - - and I compiled it as: - - - &prompt.user; cc temp.c -lm - - - - like you said I should, but I get this when I run - it: - - - &prompt.user; ./a.out -2.1 ^ 6 = 1023.000000 - - - - This is not the right answer! - What is going on? - - - - 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 - int, which is definitely not what you want - here. - - - - - - So how do I fix this? - - - - 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 - will stop doing strange things to your - calculation! - - - #include <math.h> -#include <stdio.h> - -int main() { -... - - - - After recompiling it as you did before, run - it: - - - &prompt.user; ./a.out -2.1 ^ 6 = 85.766121 - - - - If you are using any of the mathematical functions, - always include - math.h and remember to link in the - math library. - - - - - - I compiled a file called - foobar.c and I cannot find an - executable called foobar. Where's - it gone? - - - - Remember, cc will call the - executable a.out unless you tell it - differently. Use the - - option: - - - &prompt.user; cc -o foobar foobar.c - - - - - - - - OK, I have an executable called - foobar, I can see it when I run - ls, but when I type in - foobar at the command prompt it tells - me there is no such file. Why can it not find - it? - - - - 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 ./foobar, which - means run the file called - foobar in the current - directory, or change your PATH environment - variable so that it looks something like - - - bin:/usr/bin:/usr/local/bin:. - - - - The dot at the end means look in the current - directory if it is not in any of the - others. - - - - - - I called my executable test, - but nothing happens when I run it. What is going - on? - - - - Most Unix systems have a program called - test in /usr/bin - and the shell is picking that one up before it gets to - checking the current directory. Either type: - - - &prompt.user; ./test - - - - or choose a better name for your program! - - - - - - 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? - - - - 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. - - - - - - Fascinating stuff, but what I am supposed to do - now? - - - - Use gdb to analyse the core (see - ). - - - - - - When my program dumped core, it said something about - a segmentation fault. What's - that? - - - - 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. - - Common causes for this are: - - - - Trying to write to a NULL - pointer, eg - - char *foo = NULL; -strcpy(foo, "bang!"); - - - - - Using a pointer that hasn't been initialised, - eg - - char *foo; -strcpy(foo, "bang!"); - - - 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. - - - - Trying to access past the end of an array, - eg - - int bar[20]; -bar[27] = 6; - - - - - Trying to store something in read-only memory, - eg - - char *foo = "My string"; -strcpy(foo, "bang!"); - - - Unix compilers often put string literals like - "My string" into read-only areas - of memory. - - - - Doing naughty things with - malloc() and - free(), eg - - char bar[80]; -free(bar); - - - or - - char *foo = malloc(27); -free(foo); -free(foo); - - - - - 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. - - - - - - 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? - - - - 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. - - - - - - 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? - - - - Yes, just go to another console or xterm, do - - &prompt.user; ps - - - to find out the process ID of your program, and - do - - &prompt.user; kill -ABRT pid - - - where - pid is - the process ID you looked up. - - This is useful if your program has got stuck in an - infinite loop, for instance. If your program happens to - trap SIGABRT, there are several other - signals which have a similar effect. - - - - - - - - Make - - - What is <command>make</command>? - - When you're working on a simple program with only one or - two source files, typing in - - &prompt.user; cc file1.c file2.c - - is not too bad, but it quickly becomes very tedious when - there are several files—and it can take a while to - compile, too. - - 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: - - &prompt.user; cc file1.o file2.ofile37.c &hellip - - if we'd changed file37.c, 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. - - 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. - - 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? - - 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. - - This program is called make. It reads - in a file, called a makefile, 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 makefile also has rules telling - make how to re-compile the source file, - making it a much more powerful tool. - - Makefiles 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. - - - - - Example of using <command>make</command> - - Here's a very simple make file: - - foo: foo.c - cc -o foo foo.c - - It consists of two lines, a dependency line and a creation - line. - - The dependency line here consists of the name of the - program (known as the target), followed - by a colon, then whitespace, 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. - - 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. - - 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! - - 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: - - foo: foo.c - cc -o foo foo.c - -install: - cp foo /home/me - - We can tell make which target we want to make by - typing: - - &prompt.user; make target - - make will then only look at that target - and ignore any others. For example, if we type - make foo with the makefile above, make - will ignore the install target. - - 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. - - 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 makefiles, - so that the application can be installed in the correct - directory when it has been correctly compiled. - - 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. - - - - FreeBSD Makefiles - - 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 Makefile: - - MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/ -DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz - -.include <bsd.port.mk> - - Now, if we go to the directory for this port and type - make, the following happens: - - - - A check is made to see if the source code for this - port is already on the system. - - - - If it isn't, an FTP connection to the URL in - MASTER_SITES is set up to download the - source. - - - - 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. - - - - Any changes required to make the source work on - FreeBSD are applied—this is known as - patching. - - - - 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). - - - - 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. - - - - 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. - - - - Now I think you'll agree that's rather impressive for a - four line script! - - The secret lies in the last line, which tells - make to look in the system makefile 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 makefile that tells - make 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! - - If you want to have a look at these system makefiles, - they're in /usr/share/mk, 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!) - - - - More advanced uses of <command>make</command> - - 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. - - 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 - - &prompt.user; zmore paper.ascii.gz - - in that directory. - - 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 its own right. - - 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 - - * Make: (make). The GNU Make utility. - - 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). - - - - - Debugging - - - The Debugger - - The debugger that comes with FreeBSD is called - gdb (GNU - debugger). You start it up by typing - - &prompt.user; gdb progname - - although most people prefer to run it inside - Emacs. You can do this by: - - M-x gdb RET progname RET - - 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. - - 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. - - Finally, if you find its text-based command-prompt style - off-putting, there's a graphical front-end for it xxgdb in the ports - collection. - - This section is intended to be an introduction to using - gdb and does not cover specialised topics - such as debugging the kernel. - - - - Running a program in the debugger - - You'll need to have compiled the program with the - 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: - - … (no debugging symbols found) … - - when gdb starts up, you'll know that - the program wasn't compiled with the - option. - - 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!). - - 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. - - Here's a simple example of how to spot a mistake in a - program with gdb. This is our program - (with a deliberate mistake): - - #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; -} - - This program sets i to be - 5 and passes it to a function - bazz() which prints out the number we - gave it. - - When we compile and run the program we get - - &prompt.user; cc -g -o temp temp.c -&prompt.user; ./temp -This is my program -anint = 4231 - - That wasn't what we expected! Time to see what's going - on! - - &prompt.user; gdb temp -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 -(gdb) s step into bazz() -bazz (anint=4231) at temp.c:17 gdb displays stack frame -(gdb) - - 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. - - (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 - - Oh dear! Looking at the code, we forgot to initialise - i. We meant to put - - … -main() { - int i; - - i = 5; - printf("This is my program\n"); -&hellip - - but we left 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. - - - 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). - - - - - Examining a core file - - 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. - - To examine a core file, start up gdb in - the usual way. Instead of typing break or - run, type - - (gdb) core progname.core - - If you're not in the same directory as the core file, - you'll have to do dir - /path/to/core/file first. - - You should see something like this: - - &prompt.user; gdb a.out -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 bazz (anint=0x5) at temp.c:17 -(gdb) - - 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. - - 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: - - (gdb) bt -#0 0x164a in bazz (anint=0x5) at temp.c:17 -#1 0xefbfd888 in end () -#2 0x162c in main () at temp.c:11 -(gdb) - - The end() function is called when a - program crashes; in this case, the bazz() - function was called from main(). - - - - Attaching to a running program - - 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. - - What you do is start up another gdb, - use ps to find the process ID for the - child, and do - - (gdb) attach pid - - in gdb, and then debug as usual. - - 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): - - &hellip -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 */ - &hellip -} else { /* parent */ - &hellip - - Now all you have to do is attach to the child, set - PauseMode to 0, and wait - for the sleep() call to return! - - - - - Using Emacs as a Development Environment - - - Emacs - - 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. - - 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. - - 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. - - It's impossible even to summarise everything Emacs can do - here, but here are some of the features of interest to - developers: - - - - Very powerful editor, allowing search-and-replace on - both strings and regular expressions (patterns), jumping - to start/end of block expression, etc, etc. - - - - Pull-down menus and online help. - - - - Language-dependent syntax highlighting and - indentation. - - - - Completely customisable. - - - - You can compile and debug programs within - Emacs. - - - - On a compilation error, you can jump to the offending - line of source code. - - - - Friendly-ish front-end to the info - program used for reading GNU hypertext documentation, - including the documentation on Emacs itself. - - - - Friendly front-end to gdb, allowing - you to look at the source code as you step through your - program. - - - - You can read Usenet news and mail while your program - is compiling. - - - - And doubtless many more that I've overlooked. - - Emacs can be installed on FreeBSD using the Emacs - port. - - 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). - - 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 M-x - replace-s RET foo RET bar RET 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. - - 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. - - 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. - - 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. - - 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). - - Oh, and to get out of Emacs, do C-x C-c - (that means hold down the control key, press - x, press c 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). - - - - Configuring Emacs - - Emacs does many wonderful things; some of them are built - in, some of them need to be configured. - - 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!). - - The best way to learn Emacs Lisp is to download the Emacs - Tutorial - - 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. - - - - A sample <filename>.emacs</filename> file - - Unfortunately, there's far too much here to explain it in - detail; however there are one or two points worth - mentioning. - - - - Everything beginning with a ; is a comment - and is ignored by Emacs. - - - - 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. - - - - 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. - - - - This file supports syntax highlighting for C, C++, - Perl, Lisp and Scheme, by guessing the language from the - filename. - - - - 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. - - - - 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 - - &prompt.user; emacsclient filename - - - 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. - - - - - - A sample <filename>.emacs</filename> file - - ;; -*-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") - -(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 &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) ".") - - - - - - Extending the Range of Languages Emacs Understands - - 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? - - 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 - - &prompt.user; find /usr/ports/lang/whizbang -name "*.el" -print - - 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 - - /usr/ports/lang/whizbang/work/misc/whizbang.el - - we would do - - &prompt.root; cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp - - 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. - - Find the auto-mode-alist entry in - .emacs and add a line for whizbang, such - as: - - … -("\\.lsp$" . lisp-mode) -("\\.wiz$" . whizbang-mode) -("\\.scm$" . scheme-mode) - - - This means that Emacs will automatically go into - whizbang-mode when you edit a file ending - in .wiz. - - Just below this, you'll find the - font-lock-auto-mode-list entry. Add - whizbang-mode to it like so: - - ;; 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") - - This means that Emacs will always enable - font-lock-mode (ie syntax highlighting) - when editing a .wiz file. - - 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). - - - - - Further Reading - - - - Brian Harvey and Matthew Wright - Simply Scheme - MIT 1994. - ISBN 0-262-08226-8 - - - - Randall Schwartz - Learning Perl - O'Reilly 1993 - ISBN 1-56592-042-2 - - - - Patrick Henry Winston and Berthold Klaus Paul Horn - Lisp (3rd Edition) - Addison-Wesley 1989 - ISBN 0-201-08319-1 - - - - Brian W. Kernighan and Rob Pike - The Unix Programming Environment - Prentice-Hall 1984 - ISBN 0-13-937681-X - - - - Brian W. Kernighan and Dennis M. Ritchie - The C Programming Language (2nd Edition) - Prentice-Hall 1988 - ISBN 0-13-110362-8 - - - - Bjarne Stroustrup - The C++ Programming Language - Addison-Wesley 1991 - ISBN 0-201-53992-6 - - - - W. Richard Stevens - Advanced Programming in the Unix Environment - Addison-Wesley 1992 - ISBN 0-201-56317-7 - + This document has moved! - - W. Richard Stevens - Unix Network Programming - Prentice-Hall 1990 - ISBN 0-13-949876-1 - - + This document has been integrated into the Developer's + Handbook. Please update your bookmarks.