Familiarity with the C language is essential; familiarity with se from the user's point of view is also very important. Knowledge of C compilers, operating systems and programming tools is assumed.
The VAX version is usually distributed on a TK50 tape cartridge. The Unix versions are often distributed on DC600 tape cartridges or via E-mail.
In order to rebuild the
se
documentation, you will need, in addition, all of the following:
A copy of the PD M4 program.
A copy of fmt, the Software Tools Text Formatter.
A copy of pg, the paginator.
An fmt post-processor
suitable for your printer.
fx for the Epson FX,
lj for the HP LaserJet Series II
or ps for PostScript.
If you have the LaTeX system, it is possible to post-process
the fmt documents into a form that LaTeX will accept.
The resulting document will look nicer than the fmt version,
but then not everyone can run LaTeX.
To do this you will also need a copy of the stream editor,
sed.
It's also possible to post-process the fmt documents into HTML, which nowadays nearly everybody can use. The resulting documents look OK in any browser and can be viewed at the same time as running se in another window. At present, however, there are no hyperlinks within the documents. This feature is high on the list of things to add.
Of course, you will also need an editor, such as se itself!
Unix users will know the vi screen editor. Although vi has a command line, it starts up in full-screen mode. Unfortunately, there is no way of knowing from looking at the screen whether one is in append mode or command mode. There is no status line and line numbers have to be invoked with an option.
Some favour the emacs approach: no command line, everything done with control keys and function keys. One of the great advantages of emacs is its ability to redefine almost any command key. However, emacs cannot do any of the tricks se can do with global on pattern or global on markname commands. This can result in laborious editing sessions doing repetitive changes throughout a file.
Se attempts to be friendlier than vi while retaining the power of a command-line driven editor. The screen layout includes a status line, so that the user can see what state se is in at a glance. Line numbers are displayed for reference against, say, a compiler error message. On machines with colour displays, se supports a fully configurable colour option. On machines with a mouse, it supports the mouse. But if you really want to do a substitute command on all lines that begin with a dot and don't contain the letter A, you can.
Better still, se is free and comes with full source code. It is portable between widely differing machines, so once you've learned to use it, you can take it with you to another system. It has full documentation, so users can't complain (but probably will).
OK, now for the bad news. On micros, se is best used with a hard disk although it will work on floppies if you're desperate. It needs at least half a meg of memory to run in (the more the better). It takes time to learn how to use se.
If a choice has to be made between easy to use and powerful, se usually goes for powerful.
The function main sets up all the internal state that the editor needs. Certain modules have private data that must be initialised and functions are called to do this. On some systems, the terminal must be switched into an unbuffered mode (cbreak on Unix, for instance) and this is done by a function called from main (). Once the terminal is set up, the text buffer is created with mkbuf () and then edit () is called. When the user decides to quit, edit () returns and the buffer is destroyed, the terminal is reset and se exits to the operating system.
getcmd.c contains just one major function getcmd (). A number of smaller functions deal with scanning the command line for tabs or for specific characters; they are declared static. An important static function here is stuff_string (). It is used to insert strings into the command line in response to certain function tokens such as curln, date and filename.
Most of the pattern-matching code is, in fact, a C translation of the original Software Tools Ratfor code. Virtually the only addition is the use of a global flag to control case-sensitive matching.
A cursor editing function is represented by a token, a negative code that triggers an editing function (such as cursor motion). The user sets up mappings with the ob option, which results in a call to dobind ().
Other, static, functions in this file deal with more complex options such as colour and tab settings.
It makes calls on other routines in the video driver to actually do the output. All the code to recognise reserved words is in this module, functions kwlookup (), addkw () and clearkws ().
The function watch (void), which displays the time on the status line, is also in this module but the code to read the OS clock is not that belongs elsewhere.
The function scroll_window is used by the code for command mode and overlay mode to handle vertical motion of the cursor. Cursor functions such as page_up and scroll_up are implemented here.
The minor function hwinsdel just deals with the hardware line insert/delete flag.
Two routines, shell_open () and shell_close (), deal with reading or writing to shell commands. On Unix, this is done via a pipe; on MS-DOS a temporary file is used. Another function, call_shell (const uchar *) handles shell escapes.
The function getflen () is used in just one place, to determine the size of the message file and therefore how much memory to allocate before reading it in.
The functions getreadonly () and setreadonly () are used to read and set a file's read-only flag, respectively.
If the symbol LOG_USAGE is defined, the function log_usage () is compiled in and called whenever se starts up. Its purpose is to write a line into a log file that identifies the date and time when the editor was used, the version that was used and the name of the user. This log is only really useful on multi-user systems.
The file ibmpc.c drives various IBM PC video displays via a small assembler routine in mvaddch.asm. Some of these displays are particularly obscure...
The file sirius.c deals with Bob Green's Sirius and also uses some assembler code, sirtty.asm. Anybody who still runs a Sirius is welcome to compile up the code and see if it still works.
The Atari ST driver currently drives the bit-mapped screen via the ROM-based VT-52 emulator; a more direct A-line driver might have been useful if A-line code hadn't been deprecated by Atari Corp. Well, the whole machine's deprecated now...
On a VAX running VMS, vaxtty.c drives the terminal via the SMG$ library.
On Unix systems, the driver file is uxterm.c. This driver uses either the termcap library or the terminfo library according to the flavour of Unix that you're running. Linux is just another flavour of Unix, as far as this driver is concerned. Minix V1.50 systems also have termcap, so this file suits them too.
An additional driver, hardterm.c, is provided for those rare systems that require control sequences for terminals but provide no terminal-handling library. A notable example is the ICL PERQ running certain versions of PNX.
Certain routines in the main part of se need to read back from the screen image and mvinch () is provided for this. Usually, it is simply implemented by a single line of code that returns a character from Screen_image.
The code that deals with the .RC file needs to know the name of the terminal and calls term_name () to get this from the video driver. The terminal name is passed in as an argument to set_term (), but this routine is provided for systems where the terminal type is fixed, such as the IBM PC, Atari ST and X windows. In such systems, the value passed into set_term () will be NULL and will be ignored.
When se operates on a terminal that cannot do hardware line insert and delete, the behaviour of append mode is altered. This involves special code to copy a row of the screen from the bottom to the top of the text window. The function cprow () performs this copying, since it needs access to the screen image.
Finally, the function restore_screen () is called in response to the fix_screen cursor function. Its job is to rebuild the display from se's internal copy in Screen_image. The most efficient way to do this is to clear the screen and then redraw all the characters that are either non-blank or have non-default colours.
The show_cursor () function is currently unused but reserved for future expansion.
The shape_cursor () function is used to change to appearance of the cursor when in insert mode. Not many terminals support this, but it is useful as a hook for future use.
If the terminal is capable of performing line insert and delete, as mentioned above, two functions will be called whenever this operation is required. inslines () is called to insert lines and dellines () to delete them.
There are several routines in se that need to make an audible alert signal. This is generally referred to as ringing the terminal's bell, but nowadays is unlikely to involve a large brass bell being struck inside a teletype! Some computers can control the volume, pitch or duration of the bleep that they produce and ringbell () accepts a parameter that can be used to distinguish various classes of bell sounds.
The obvious functions are fopen (), fclose (), fgets () and fputs (). Hopefully your C library contains these! Se will open a file during e, r and w commands and close it as soon as it has been read or written. The scratch file is opened when se is invoked and remains open until either a garbage collect is done, a new file is edited or the user quits. The file in the second window is opened when the window is opened and remains open until the window is closed. If message polling is enabled, se may attempt to open a file after each command; if this takes significant time, conditionally compile out the code.
Se also needs to read characters from the keyboard with no echo and no waiting for a carriage return. In Unix, this is done by setting cbreak mode. On the IBM PC and Atari ST, a BIOS call is available that does the job. Some machines assume all input is buffered until return is pressed, while others throw away certain control characters whether you like it or not. This type of system may be a problem.
Output to the screen is the most versatile part of se's links with the hardware. The interface is well-defined via a few function calls, all of which hide the implementation of the screen driver itself. See the next section for a description of the current video driver modules.
In os.c you will find a number of operating system routines which are conditionally compiled according to the target machine. The simpler functions do things like reading the system clock and polling for messages.
A function called sysname (void) returns a pointer to a string that gives the current machine name for the l command. Two functions, isreadonly (const uchar *) and setreadonly (const uchar *, bool), deal with reading and setting the file's read-only flag, respectively. Most of these are usually available but they can be faked if necessary.
call_shell () is the real problem. By no means all systems can invoke a new level of shell and even those that can may well not do it reliably. The Atari ST falls into the latter category, with a variety of shells available but little in the way of standardisation. The functions shell_open () and shell_close () allow se to read from or write into a pipe connected to another program. Again, not many systems can do this. The MS-DOS version fakes it by means of a temporary file.
If you cannot do shell escapes at all, arrange to conditionally compile out all references to the shell in the source code and in the documentation. If you can call the shell, but with limitations, make sure se gives a reasonable error message when something goes wrong and document the problem. Refer to the error codes ENOSHELL, ESHELLERR and ECANTFORK. If there is a strong chance of losing the buffer due to a problem with shell escapes, do not provide them.
ibmpc.c consists of the C routines required to drive a Monochrome Display and Printer Adaptor (MDPA), a Colour Graphics Adaptor (CGA), an Enhanced Graphics Adaptor (EGA) or a Video Graphics Array (VGA). Each of these adaptors is driven in 80 column text mode mode 7 on MDPAs, mode 3 otherwise. If the PC is found to be in a graphics mode when se is started, it is immediately put into mode 3; the graphics mode is restored on exit.
On the PC, either BIOS calls or direct memory access is used, depending on the setting of the boolean variable Use_bios. If the symbol ODDVID is defined, se knows about the Wyse 700 monochrome display and can drive it in 160 column, 50 row mode. In order to drive the Wyse, se has to use BIOS, so Use_bios is set to YES. BIOS is also useful when running under Microsoft Windows, so the environment variable SE_BIOS will set the Use_bios flag. Otherwise, all characters are placed directly into video memory by an assembler routine called mvaddch (). The reason, of course, is speed of screen updates; se is usable even on a slow 8088 system.
For certain VGAs, it is possible to set a video mode that gives a 132 column display. In this case, a call to setncols () sets the memory width to (132 * 2) bytes instead of (80 * 2). In this way, the low-level code is aware of the layout of the screen and we can still use the fast mvaddch ().
If anyone adds non-IBM video adaptors to the IBM PC version of se, please make the code conditional on ODDVID so that the size of the EXE file is not increased by unwanted display driver code. When distributing binary copies of se try to give both variants: ODDVID and standard IBM.
On the Atari ST, BIOS is used for all screen output at present, although it may be modified to use A-line instructions instead. The ST has a VT52 emulator built-in which is the only way to do cursor motion from BIOS. Therefore, the atari.c file bears a remarkable similarity to the parts of hardterm.c that drive a VT52.
The Sirius driver goes right ahead and reprograms the 6845 CRT controller. Cursor size and position are both controlled by 6845 registers on the Sirius. Like the IBM PC driver, an assembler routine is used for most of the speed-critical stuff. Code to perform line insert-delete is also coded in the assembler file sirtty.asm.
0 SNULL V2.08 /* Special null string (not in file) */ 1 EBACKWARD Line numbers in backward order