![]() |
Series: EMX, UnixOS/2 and Porting Author: Arnd H. Hanses Homepage: posix2.sourceforge |
+ Alexander Mai's porting guide + Unix to EMX porting guide + UNIXish environment |
[1]
"Good programmers know what to write.Informal introduction into aspects of porting from UNIX/POSIX to OS/2 that are closely related to the emx development tools. Teaching ANSI C is not intended, some familiarity with programming in C or C++ is assumed; pointers to tutorials for rank beginners are included.
Great ones know what to rewrite (and reuse)."
(ERIC S. RAYMOND, IN: "THE CATHEDRAL AND THE BAZAAR")
Alfieri: > E la fama? <
Gozzi: > E la fame? <
(COMMEDIA DELL'ARTE)
(Authorship is usually indicated. Please mail me any errors and
suggested additions. I am looking forward to adding new chapters written by
interested readers. If the author's name is omitted and not evident, I am citing
usually an excerpt from the emx documentation. Those hundreds of trademarks
are those of their respective owners.)
"I have found a cool X utility which I want to port. How should I proceed?
Normally, with X utilities, you get an Imakefile. Simply proceed as if you were under Unix. Run xmkmf -a to compile. Read the programming section on special issues."
("The XFree86/OS2 FAQ")
Since I am not a professional programmer, I am advocating user
friendly tools and user friendly documentation. I do not think such helpful
things should aim at becoming large or comprehensive, but simple and down-to-earth.
It should just enable the first simple steps and help to reduce the beginners
problems, thus providing the necessary basis and some pointers so that you learn
how to get access to the huge piles of helpful information on the Net and elsewhere.
Well, it is time now to make the first step towards a (still epigonous and rudimentary)
porting tutorial, compiling in the form of short articles some of the helpful
information that's scattered in small bits and pieces everywhere (while trying
to identify and name the author). Everybody may contribute such a small article
for inclusion.
The number of new compilers for OS/2, which provide all (now standardized or still experimental) features of bleeding edge STL versions is very limited. 'Workframe' solutions fail, when a huge codebase with hundreds of megabytes of source is involved and a reasonable make process (i.e. based on Unix' 20 years of scientific and industrial experience with complex projects for heterogenous platforms and distributed networking, using quality software engineering strategies for code reliability) is required for any serious development. A prominent example is XFree86/OS2, where all make utilities and development tools except the GNU make utility and the GNU compiler gcc failed. Both are based on the emx libraries:
[excerpt from emx 0.9d INTRODUCTION 21-Dec-1998]This may be the right moment now to carefully read emx/doc/INSTALL file, and to test if you can successfully compile, run and debug the programs mentioned there.``Introduction
Welcome to emx 0.9d, an environment for creating 32-bit programs for OS/2 and DOS. You can use the GNU C compiler to compile programs for emx. The main design goal of emx is to simplify porting Unix software to OS/2 and DOS. Moreover, you can create `native' OS/2 programs, including Presentation Manager applications.
The emx package includes:
Additionally, the following GNU programs are available compiled and with patches and sources:
- emx.dll, emxio.dll, emxwrap.dll and emxlibc.dll dynamic link libraries for OS/2
- emx.exe DOS extender for running 32-bit programs under DOS
- emxfpemu, W. Metzenthen's FPU (387) emulator
- emxbind.exe for creating .exe files which work both under OS/2 and DOS
- emxomf.exe for converting .o object files (a.out) to .obj object files (OMF). With emxomf and LINK386 you can create OS/2 programs that don't need emx.dll
- emximp.exe for creating import libraries
- emxexp.exe for creating a list of export definitions from object files
- C header files and a complete C library
- a simple graphics library for 320x200 (256 colors) mode
- a library for screen output in windows
- header files and a library for using sockets of IBM TCP/IP for OS/2
You can get the complete unpatched GNU sources by anonymous ftp from prep.ai.mit.edu and other archives such as ftp.leo.org.
- GCC 2.8.1, the GNU C compiler, supporting the C, C++, and Objective C languages
- GAS 2.6, the GNU assembler
- GDB 4.16, the GNU debugger
- ld, an ancient version of the GNU linker hacked for emx
- strip: a member of an ancient version of the GNU binary utilties
- ar, nm, size, objdump: a subset of the GNU binary utilities 2.6
- gprof, the BSD/GNU profiler
- texinfo, the GNU documentation system
- Patches for the GNU sources
- Patched source for GCC, GAS, GDB, ld, ar, nm, size, strip, objdump, info, makeinfo, texindex. You can compile all these programs with the files that come with emx (but you also need a make utility, such as dmake).
Additionally, the following libraries are provided:
After unpacking the emx runtime and development system packages, you'll find further information in the following files:
- some parts of the BSD C library
- the BSD data base library: dbopen()
- BSD curses library
- Henry Spencer's regexp library
- The GNU and BSD termcap libraries [...]
After unpacking the GNU and BSD packages, you'll find further information in the following files: [...]
- emxdocCOPYING.EMX emx & library license, license overview
- emxdocCOPYING GNU General Public License
- emxdocinstall.doc Installation guide
- emxdocemxrt.doc User's guide to the emx runtime package emxdocemxdev.doc Application developer's guide
- emxdocemxlib.doc C library reference
- emxdocfaq.doc Frequently asked questions (with answers)
- emxdocbuild.doc Compiling the sources
- emxdochistory.doc Change log [...]
emx is available for anonymous ftp on
- emxdocemxgnu.doc GNU development tools information
- emxdocemxbsd.doc BSD library information [...]
An emx-related mailing list has been created. The address for people to request to be added to or removed from the list is:
- ftp.leo.org: /pub/comp/os/os2/leo/gnu/emx+gcc/
- ftp-os2.cdrom.com: /pub/os2/emx09d/
- ftp-os2.nmsu.edu: /pub/os2/dev/emx/v0.9d/ [...]
majordomo@iaehv.nl
To subscribe, send a message containing
subscribe emx
to majordomo@iaehv.nl. [...]
Highly optimized and bleeding edge C++-code can be compiled with the most recent experimental GNU Pentium Compiler Group's pgcc, which also contains tools updates, interesting for assembler (MMX) programmers.
Although not completely POSIX compliant, emx for OS/2 is nearly as close as can be for the pre-POSIX operating system OS/2. This makes it an ideal platform for CODE REUSE and OPEN PORTABILITY.
" X - a portable network transparent window system", as the authors call it, enables the reuse of Unix software for OS/2 and in general gives you the chance to write extremely portable gui code, running on a PC as well as on a super-computer by simply recompiling it, provided you have a POSIX-like programming interface.
"Why is writing portable code (and therefore emx) so important?"
"As for non-existing API, I would recommend to stick to well-known things like POSIX, BSD networking, X11 and avoid system-specific calls like DosWrite() etc. completely. If you're doing really multiplatform project. Really 'standard' calls are the same everywhere and rarely require re-implementation. There's some oddity here and there (I heard Ultrix(?) does not have strdup()?) but you can add it in transparent way, namely linking on Ultrix with your own implementation of strdup()."Well, the tutorials motto is:(Dr. Sergey Ayukov, Sternberg Astronomical Institute Moscow, Russia http://www.ayukov.com, http://crydee.sai.msu.ru/index-asv.html)
"Good programmers know what to write. Great ones know what to rewrite (and reuse)."Paramount for reuse in the future is reusability through open standards (and - even more important - good comments ;-). Here the open Posix/BSD/MIT API 's distinguish XFree/emx/gcc/pgcc from other compilers and make it the 'future compatible' development platform. For this reason it is outstanding and may well be recommended.
A good tutorial to ANSI C (cf. e.g. "An Introduction to C Programming", by Carsten Whimster"Heelpp, I'm stuck! Where to begin?"
(anonymous)
"Use standard ANSI C (or C++) whereever possible!"Only, in this moment this will probably help you less than nothing. Moreover, the only viable solution often requires low-level functions. Remember that ' EMX/GCC' as well as 'x11make' of XFree86/OS2 (or 'gmake') is generally a superset of the Unix standard 'cc', 'cxx' and 'make'. So, if you like to read a basic tutorial for beginners with a strictly didactical approach, I recommend as a good starting point:
"ANSI C for Programmers on UNIX Systems",
by T. P. Love, CUED Cambridge University Engineering Department)
<tpl@eng.cam.ac.uk>,
In the following, to fill some gaps, I'll give a very short summary of porting-related concepts and specialties. For general information please refer to the online documentation that comes with recent Linux and FreeBSD distributions. It is also necessary that you have access to a good Unix/Linux tutorial, explaining those numerous concepts unfamiliar for OS/2, which cannot be covered here. For standards, try e.g.:
This tutorial will concentrate on emx-specific questions that recently were discussed on the respective lists. Further sources of information are indexed by Timur Tabi:
"Those who do not understand Unix are condemned to reinvent it, poorly."(Henry Spencer)
The following are some excerpts from a terse introduction into how to behave in a FreeBSD Unix development environment (``A User's Guide to FreeBSD Programming Tools``)
``Simply proceed as if you were under Unix!''I'm sure, you'll soon discover how little a programmer who is writing portable ('posixified') applications has to re-learn or re-do.
``This section deals only with the GNU compiler for C and C++, since that comes with the base FreeBSD [and the emx] system. It can be invoked by either cc [write a cc.cmd file] or gcc. ... Once you've written your masterpiece, the next step is to convert it into something that will (hopefully!) run on FreeBSD [as well as on OS/2 after compiling your portable Posix source with emx gcc]. This usually involves several steps, each of which is done by a separate program:
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.
% cc -O -o foobar foobar.c
Create an optimised version of the executable. The compiler performs various clevertricks to try and produce an executable that runs faster than normal. You can add a number after the -O to specify a higher level of optimisation, but this often exposes bugsin the compiler's optimiser. ... Optimisation is usually only turned on when compiling a release version. ...
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.
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?
The most common example of this is when compiling a program that uses some of the mathematical functions in C. Unlike most other platforms [emx included], 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 -lsomething. For example, the math library is libm.a, so you give cc the argument -lm. A common "gotcha" with the math library is that it has to be the last library on the command line. [Emx does not cut off the leading 'lib' part of library names and m.a or m.lib is just a dummy library which can be used for your own common extension modules.]
If you are compiling C++ code, you need to add -lg++, or -lstdc++ ... to the command line argument to link the C++ library functions. ...
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!
Q: I am trying to write a program which uses the sin() function and I get an error like this. What does it mean?
Q: All right, I wrote this simple program to practice using -lm. All it does is raise 2.1 to the power of 6.
int main()
{
float f = pow(2.1, 6);
printf("2.1 ^ 6 = %f", f);
return 0;
}
2.1 ^ 6 = 1023.000000
A: When the compiler sees you call a function, it checks if it has already seen a prototype for it. If it has not, it assumes the function returns an int, which is definitely not what you want here.
Q: So how do I fix this?
A: The prototypes for the mathematical functions are in math.h. If you include this file, the compiler will be able to find the prototype and it will stop doing strange things to your calculation!
#include <stdio.h>
int main() {
...
2.1 ^ 6 = 85.766121
Q: I compiled my program and it seemed to run all right at first, then there was an error and it said something about core dumped. What does that mean?
A: The name core dump dates back to the very early days of Unix, when the machines used core memory for storing data. Basically, if the program failed under certain conditions, the system would write the contents of core memory to disk in a file called core, which the programmer could then pore over to find out what went wrong.
Q: Fascinating stuff, but what I am supposed to do now?
A: Use gdb to analyse the core (see Section 5).
Q: When my program dumped core, it said something about a segmentation fault. What's that?
A: This basically means that your program tried to perform some sort of illegal operation on memory; Unix is designed to protect the operating system and other programs from rogue programs.
Common causes for this are [Read this carefully, well meant advice]:
Trying to write to a NULL pointer, eg
strcpy(foo, "bang!");
strcpy(foo, "bang!");
bar[27] = 6;
strcpy(foo, "bang!");
Doing naughty things with malloc() and free(), eg
free(bar);
free(foo);
free(foo);
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.
Here's a very simple make file:
cc -o foo foo.c
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:
cc -o foo.exe foo.c
install:
cp foo /home/me
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. ...
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 ... 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
The debugger that comes with FreeBSD [and emx] is called gdb (GNU debugger). You start it up by typing
front-end for it xxgdb in the ports collection. [Emx calls it pmgdb.} ...
You'll need to have compiled the program with the -g option to get the most out of using gdb. It will work without, but you'll only see the name of the function you're in, instead of the source code. If you see a line like:
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):
int bazz(int anint);
main() {
int i;
printf("This is my programn");
bazz(i);
return 0;
}
int bazz(int anint) {
printf("You gave me %dn", anint);
return anint;
}
When we compile and run the program we get
% ./temp
This is my program
anint = 4231
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. breakpoint at main()
(gdb) run Run as far as main()
Starting program: 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)
#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
main() {
int i;
i = 5;
printf("This is my programn");
...
in that area of memory when the program ran, which in this case happened to be 4231.
Note: 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).
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. [emx calls it just core.]
To examine a core file, start up gdb in the usual way. Instead of typing break or run, type
You should see something like this:
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)
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:
#0 0x164a in bazz (anint=0x5) at temp.c:17
#1 0xefbfd888 in end()
#2 0x162c in main() at temp.c:11
(gdb)
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
"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):
if ((pid = fork()) < 0) /* _Always_ check this */
error();
else if (pid == 0) { /* child */
int PauseMode = 1;
while (PauseMode)
sleep(10); /* Wait until someone attaches to us */
...
} else { /* parent */
...
Using Emacs as a Development Environment
Emacs
[...] 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. [I recommend also to test elvis, a vi clone.] It's impossible even to summarise everything Emacs can do here, but here are some of the features of interest to developers:
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).
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.
Unfortunately, there's far too much here to explain it in detail; however there are one or two points worth mentioning.
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
;; 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-qt") ; 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) ".")
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
So for example, if the output from the find command was
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)
...
ending in .wiz.
Just below this, you'll find the font-lock-auto-mode-list entry. Add whizbang-mode to it like so:
(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")
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).
"Too much X around, I'm confused!"(A novice to X )
Running 'man X' on Unix - and on your system if the necessary backends are installed ('man' or 'xman' is generally a good idea for terse descriptions of terms, apps and interfaces) - spits out something (cryptical) like:
X - a portable, network-transparent window system
SYNOPSIS
The X Window System is a network transparent window system which
runs on a wide range of computing and graphics machines. It should
be relatively straightforward to build the X Consortium software
distribution on most ANSI C and POSIX compliant systems. Commercial
implementations are also available for a wide range of platforms.
The X Consortium requests that the following names be used when
referring to this software:
X ; X Window System; X Version 11; X Window System, Version 11;
X 11
X Window System is a trademark of X Consortium, Inc.
DESCRIPTION
X Window System servers run on computers with bitmap displays. The
server distributes user input to and accepts output requests from
various client programs through a variety of different interprocess
communication channels. Although the most common case is for the
client programs to be running on the same machine as the server,
clients can be run transparently from other machines (including
machines with different architectures and operating systems) as well.
X supports overlapping hierarchical subwindows and text and graphics
operations, on both monochrome and color dis plays. For a full
explanation of the functions that are available, see the Xlib -
C Language X Interface manual, the X Window System Protocol
specification, the X Toolkit Intrinsics - C Language Interface
manual, and various toolkit documents.
The number of programs that use X is quite large. Programs provided
in the core X Consortium distribution include: a terminal emulator,
xterm; a window manager, twm; [...] access control programs, xauth,
xhost, and iceauth; user preference setting programs, xrdb, xcmsdb,
xset, xsetroot, xstdcmap, and xmodmap; [...]; utilities for listing
information about [...] displays, xdpyinfo, xlsatoms, and xprop;
[...]; a display server and related utilities, Xserver [...]; a
utility to terminate clients, xkill; [...]
Many other utilities, window managers, games, toolkits, etc. are
included as user-contributed software in the X Consortium distribution,
or are available using anonymous ftp on the Internet. See your site
administrator for details.
The newest OS/2-port is introduced in "The XFree86/OS2 FAQ" (by Holger Veit, Sebastien Marineau):
*1.1 What is X11, X11R6.3, XFree86, XFree86/OS2?X11, more precisely called "The X Window System" is a complete window system that usually runs as the de-facto standard in Unix environments. X11R6.3 is the name of the current release (precisely, the most recent one is X11R6.4, but this is not part of the 3.X server line. XFree86 is a port of the X Window System to x86-based systems. XFree86/OS2 is a particular port of XFree86 for OS/2 based systems.
1.2 Where can I find more information?
Books about X11 exist in any well-sorted CS bookstore.
Some URLs:
Newsgroups:
- http://www.x11.org/ (this has a rather large bibliography)
http://www.xfree86.org/
http://set.gmd.de/~veit/os2/xf86os2.html (XFree86/OS2)
Mailing list (for XFree86/OS2): see Q 1.7 [...]
- comp.windows.x.* (X11 specific things)
comp.os.os2.programmer.* (OS/2 specific things)
*1.7 Is there a mailing list for XFree86/OS2?
Yes, read
for details. [...] There is also a digest version available, read the above URL. [...]
- http://set.gmd.de/~veit/os2/xf86mail.html
1.16 Are there some X11 books?
Sure, ask in your book store. A user's guide is for instance:
Niall Mansfield, The X Window System - A User's Guide, Addison Wesley, or The Definite Guides to the X Windows System, Volume Three, X Window System User's Guide, O'Reilly&Associates
The latter one is part of an eight (nine,ten?) volume documentation set for the X11 programmer. From my biased point of view of a programmer, this is the most comprehensive must-have for the serious programmer (however, it does not belong to the cheaper booksets, unfortunately)."
XFree86 and most of it's ports stem from Unix/POSIX; it is advisable that you download the Posix' standard utilities like rm, grep, mkdir, cp etc.
The required shell for Rexx is CMD.EXE. While this is familiar, porting will require a shell that acts like AT&T 'sh', like the xksh. I recommend a recent version of ash/bsh, the Berkeley Unix standard shell; other ported shells often have too small command-line buffers.
"Adrian Gschwend" <ktk@netlabs.org> introduces it: "Today Brian Smith released the first beta of EverBlue, the XLib-PM implementation for OS/2 which allows you to compile Xlib (Unix/Linux) applications as native PM applications.
The beta is not really usable for endusers but developers can use it to compile PM versions of X-Applications. There is just a small demo included so maybe it does not make sense to download it now if you are not a developer.
Sourcecode of this betadrop is also included in the package, just install it. If you want to support this project you can subscribe to the EverBlue mailinglist at Egroups, we still need a lot of support because the project is not yet complete. I will set up a CVS server at Netlabs as soon as we decided how to organise the structure of the source. Informations about CVS will be posted to the EverBlue mailinglist.
Run e.g. on Linux
NAME
System calls are documented in /emx/doc/system.doc.The term ' POSIX' denotes in the following all (development) platforms "aiming at IEEE 1003.1/2 compatability" and is not restricted to those relatively few commercial platforms that passed the official tests and paid the license fee. Please note that there is e.g. an old Linux/POSIX distribution with an 'official' POSIX label. This means: We will neglect all old broken pre-Posix Unix-like systems and encourage to completely forget about them.All system calls are declared in <emx/syscalls.h>. Interface routines are in the emx.a and emx.lib libraries. System call emulation routines are in the sys.lib libraries. Please do not use system calls from application programs - always use C library functions. If you need a system call, put a function into the library which issues the system call. [...] The goal is to have Unix-like system calls.
Moreover if we go into details we should explain XPG, X/OPEN, Spec1170, etc. Please consult Unix tutorials here.
Specify the desired environment (cf. emx GNU gcc manual 2.12/2.8):
__EMX__. If the -Zmt, -Zmts, or -Zmtd option is given on the
GCC command line, the symbol __MT__ is defined."
"The following assertions are predefined in the emx port of
gcc:
#system(unix),
#system(emx),
#cpu(i386) and
#machine(i386)."
If more than one of these are defined, they accumulate. For example:
_POSIX_SOURCE IEEE Std 1003.1.
_POSIX_C_SOURCE
if >=2 add IEEE Std 1003.2;
if >=199309L, add IEEE Std 1003.1b-1993
[Note: No specific emx support! Also cf.
Now time has come to compile some simple demo code. Here I will not add another one to the pile of introduction to ANSI C, several excellent tutorials exist. All I can express here is a kind of compliment to Eberhard Mattes for his emx development tools and libraries: There is not much to say about compiling standard C (and C++; provided you use a recent compiler version) with emx. Just start.
This is just the right moment to re-read the README and INSTALL file of emx. Then compile the sample code provided by Eberhard Mattes and have a close look at the first chapters of the Emx Application Developers Guide, which introduce its philosophy. Doing both carefully might save you trouble later:
``There are three methods for creating executable files:The default stack size is 0x8000 bytes. 512 kbytes of local stack are sufficient for small tools, but too small for complex programs; pre-allocate 32 Mbytes local stack to be on the safer side. Note that all of the command line arguments and environment pointers are copied to the stack on startup!!! Small local stacksizes are the most prominent reason for seemingly arbitrary erroneous program behaviour. (Your program code is correct: The error will disappear when you perform the usual testing in a debugger ;-).(E1) using ld and emxbind
(E2) using emxomf, emxomfld and LINK386, the program will use the emx.dll dynamic link library for performing system calls
(E3) using emxomf, emxomfld and LINK386, the program will be linked with a system call library (creating a stand-alone application or DLL)
The assembler [GNU as] creates a Unix-style a.out object file (.o file). When using method (E1), .o files created by the assembler are linked by a Unix-style linker [GNU ld] with Unix-style libraries (.a files) to create a Unix-style a.out file. Then, emxbind is used to turn this file into an .exe file that can be executed under both OS/2 and DOS. Using method (E1) enables core dumps and fork(). Moreover, programs created with method (E1) can be debugged using GDB, the GNU debugger. Programs created using method (E1) use emx (emx.dll under OS/2, emx.exe under DOS) for system calls.
When using method (E2), the .o files created by the assembler are converted to Object Module Format files (.obj files). These files are linked with the OS/2 linker LINK386. The libraries are .lib files. emxomfld is a front end to LINK386 which converts the ld command line to a LINK386 command line. Programs created with method (E2) cannot create core dumps, cannot call fork() and cannot be debugged with GDB. Method (E2) works only under OS/2 and creates programs that work only under OS/2. You can use IBM's IPMD and SD386 debuggers to debug programs created with methods (E2) and (E3). Files created with method (E2) are usually smaller. The emx.dll dynamic link library is used for system calls. The -Zomf option of GCC selects method (E2).
When using method (E3), the program won't call the emx.dll dynamic link library. A system call library (emx emulator) is linked to the program. The system call library maps system calls to OS/2 API calls. Only a subset of the emx system calls is available with method (E3). For instance, the general terminal interface is not available. Functions which are not available or are limited with method (E3) are marked [*] in the library reference. Use a module definition file and the STACKSIZE statement to set the stack size. Alternatively, you can use the -Zstack option of GCC.''
Now a trivial example to illustrate some Posix compliant emx interfaces. Refer to the Emx C Library Reference for the details about open(), read(), write(), etc.
(For an example how to use the more efficient ANSI streams counterparts fopen(), fread()