home *** CD-ROM | disk | FTP | other *** search
- From: pgf@cayman.COM (Paul Fox)
- Newsgroups: alt.sources
- Subject: Vile 16/17 - vi feel-alike (multi-window)
- Message-ID: <4535@cayman.COM>
- Date: 7 Jun 91 22:10:23 GMT
-
- #!/bin/sh
- # this is vileshar.16 (part 16 of Vile)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file vile.hlp continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 16; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- echo 'x - continuing file vile.hlp'
- sed 's/^X//' << 'SHAR_EOF' >> 'vile.hlp' &&
- X single following digit.) Note that since the buffer names
- X are displayed in order of use, the list can quickly grow
- X "stale" -- the numbers may be meaningless if buffer
- X switching has been done since the last display of the list.
- X
- X The program version is also displayed with this command.
- X
- X ^A-* Always display a list of all buffers. Useful for updating the
- X list if it's already on the screen but may be out of date.
- X Any argument will cause the list to include _all_ buffers,
- X even those normally considered "invisible". (For example,
- X macros are stored in "invisible" buffers.)
- X
- Window manipulation commands:
- -----------------------------
- X ^T Make Two windows. Splits the current window in half. This
- X is the usual way to create a new window.
- X ^K Get rid of (Kill) this window.
- X ^O Make this the Only window on the screen.
- X
- X The emacs-style commands ^X-2, ^X-0, and ^X-1 are also
- X included, and are synonymous with ^T, ^K, and ^O.
- X
- X ^N Go to the next window on the screen.
- X ^P Go to the previous window on the screen.
- X
- X These two commands may be disturbing to vi users who use
- X ^N and ^P to move between lines. See the examples under
- X Key Rebinding for how to fix this.
- X
- X v Make the current window smaller.
- X V Make the current window larger.
- X
- X ^A-^D Scroll the next window down half a screen.
- X ^A-^U Scroll the next window up half a screen.
- X ^A-^E Scroll the next window up one line.
- X ^A-^Y Scroll the next window down one line.
- X (The previous four commands are useful when comparing two buffers.
- X Mnemonic -- think of them as affecting the "A"lternate window.)
- X
- X zH zM zL These are synonyms for vi's 'z+', 'z.', and 'z-', which
- X position the line holding the cursor at the top, middle, or
- X bottom of the screen, respectively.
- X
- X ^X-^R Scroll the window right by 1/3 of a screen, or by the
- X number of lines specifed.
- X ^X-^L Scroll the window left by 1/3 of a screen, or by the
- X number of lines specifed.
- X
- X If for some reason you can't get your screen set right via a
- X TERM variable, try the ":screen-rows" or ":screen-columns"
- X commands (which take their args (number of rows or columns
- X respectively) before you type the ":").
- X
- File manipulation commands:
- ---------------------------
- X The usual :e, :r, :f, :w commands are available, though only
- X ":e!" is available of the "!" options. The :r command reads the
- X named file in after the current line. To read a file before the
- X first line, use ":0r".
- X
- X As in vi, ranges of lines specified by line numbers (including '.',
- X '$', and '%' shorthands) or marks may precede these commands.
- X Unlike vi, search patterns cannot be used as line specifiers.
- X
- X In addition, two non-"colon" commands have been added:
- X
- X ^R Prompts for a filename, and then reads it in _above_ the
- X current line. If a register is specified (e.g. "a^R ),
- X the file is read into that named register, but not inserted
- X into the current buffer.
- X
- X ^W is a writing operator, which prompts for a filename, and
- X writes the specified region to that file. Like all operators,
- X it the command is repeated, as in ^W^W, then lines are
- X affected. Use 10^W^W to write 10 lines.
- X
- X If a register is specified (e.g. "a^W ) then the command
- X is _not_ an operator, but writes the specified register to
- X the named file.
- X
- Shell Access
- ------------
- X Anywhere a filename is valid, a command name is also
- X valid, entered in the form "!shell-command". The whole line is
- X handed to the shell, and the read or write operation is done on
- X the commands standard input or output, as appropriate. Thus
- X you can type ":e !date" to edit a copy of today's date.
- X
- X The ": !cmd" shell escape works pretty much as it does in vi.
- X The command ":!!" will rerun the previous such shell command.
- X
- X The '!' operator works as expected.
- X
- X In addition, the ^X-! command runs a shell command and captures
- X its output in a specific buffer, called "[Output]". This is
- X almost identical to ":e !cmd", except that in that case the buffer
- X is named according to the command name.
- X
- X These output capture commands are most useful in conjunction with
- X the "error finder", described below.
- X
- X On systems supporting job control, ^Z will suspend vile.
- X
- Text manipulation command:
- --------------------------
- X Remember, these are only the new or different commands. The
- X standard vi set should still work.
- X
- X Undo ("u") and line-undo ("U") are available for all commands.
- X They should be a little less capricious than their
- X vi counterparts, since they do not share the default yank register
- X for their operation. Also, line-undo ("U") is available until
- X the next change anywhere in the file, rather than until you leave
- X the line. Unfortunately, the cursor position after an undo may not
- X always be the same as it would be in vi.
- X
- X The vi "global" command is present, in its non-interactive form
- X only. So is the "substitute" command. These both look pretty
- X different while they're being used than they do in vi, and since
- X the searching is done right after the pattern is entered, there
- X can be a long delay while you're trying to finish typing your
- X complete command. You can type commands just as you would have
- X in vi, i.e. ":g/oldpat/s//newstring/" will work. But you won't
- X see any of the '/' characters. Try it-- you'll get the idea.
- X Line ranges are not possible on ":g", but they are on ":s".
- X
- X The ":v" counterpart to ":g" is not implemented.
- X
- X The ":g" command can be followed by any of l (list), p (print),
- X < (left shift), > (right shift), r (read file), d (delete),
- X L (lower case), U (upper case), ~ (flip case), put (append
- X yanked text), Put (prepend yanked text), s (substitute),
- X t (trim trailing whitespace). For example, ":g/pattern/Put"
- X will insert the contents of the default yank register just
- X above every line containing "pattern".
- X
- X Operators
- X ---------
- X Vi has a class of commands known as "operators". Operator
- X commands are always immediately followed by a motion command.
- X The text affected by an operator is bounded by the initial
- X position, and the cursor position after the motion is
- X completed. Thus the delete operator ('d') can be followed by
- X the word motion command ('w'), causing the next word to be
- X deleted. The sequence "dG" will delete through the end of the
- X file, and "d/junk" will delete to the next occurence of the
- X string "junk". Operators can all be "stuttered" to affect
- X lines. Thus "dd" deletes one line, "4dd" affects 4 lines,
- X etc.
- X
- X Some operators in vile can be forced to affect whole lines,
- X though the motion wouldn't normally imply it, by using the ^X
- X form of the command. For example, "d%" (assuming you are on a
- X curly brace) will delete a C-style block of code. "^X-d%"
- X will delete that same area, plus anything else on the lines
- X containing the curly- brace endpoints.
- X
- X Note that some operators always affect whole lines, no matter
- X how the motion is specified. For instance, "!w" will always
- X filter an entire line, and not just a single word.
- X
- X There are several new operator commands:
- X
- X ^A-~ Is the operator form of the '~' command, so "^A-~~"
- X changes the case of all characters on the current
- X line, "^A-~w" does it to a word, "3^A-~}" does it for
- X 3 paragraphs, etc.
- X ^A-u Like ^A-~, but converts the region to upper case.
- X ^A-l Like ^A-~, but converts the region to lower case.
- X
- X ^A-f Format the region based on the current fill column. The
- X initial indentation of both the first and second lines
- X of the region are preserved, and all subsequent lines
- X get the second line's indentation. This makes indented/
- X outdented paragraphs work correctly. The usual use of
- X this command is "^A-f}", which does it to the current
- X paragraph. (This is intentionally _not_ the same bevavior
- X obtained by "!fmt", since that behavior is obviously
- X available elsewhere.)
- X
- X ^X-d Delete the region, including the lines it starts and ends on.
- X ^X-c Change the region, including the lines it starts and ends on.
- X ^X-y Yank the region, including the lines it starts and ends on.
- X
- X Text insertion
- X --------------
- X ^X-p Causes the previously yanked or deleted text, no matter
- X how it was obtained, to be inserted after the current line.
- X Usually text that did not consist of whole lines where it
- X came from is inserted immediately following the cursor.
- X ^X-P As above, but the text is put before the current line.
- X Thus "dw" followed by a "p" command does a normal insertion
- X of the deleted word, whereas "^X-p" results in the word
- X being inserted on a line by itself.
- X
- X Searching
- X ---------
- X ^X-/ Does a forward search for the "word" located under the
- X cursor.
- X ^X-? Does a reverse search for the "word" located under the
- X cursor.
- X ^A-/ Does not do a search, but sets the search pattern to the
- X "word" under the cursor. Useful for "picking up" a word
- X from one buffer, and searching for it in another.
- X
- X The following two commands may not always be present in vile,
- X depeinding on how it was built:
- X ^X-S Incremental forward searching. As you enter the search
- X string, the cursor is advanced to the next match with
- X what you've typed so far. Use ^F and ^R to continue the
- X search forward or in reverse, using the current pattern.
- X ^X-R As above, but in reverse.
- X
- X Tags
- X ----
- X Vile supports vi-style "tags" files.
- X
- X ":ta" or ":tag" allows you to enter a tagname to locate. Changes
- X to that file and location.
- X ^] Uses the identifier currently under the cursor as the
- X tagname.
- X ^X-^] "Un-tag" - pops to the file and location just previous to
- X the last tag command. (Some versions of vi have this command
- X attached to ^T)
- X
- X When one of these commands is used, vile will look for a file named
- X "tags" in the current directory, and load it into a hidden buffer
- X for use during tag searches. This buffer is editable if you wish
- X (":e tags"), but will not appear in the buffer lists. If a buffer
- X named "tags" is already available when a tag is first requested, it
- X will be used instead of a file called "tags", and of course will
- X remain visible.
- X
- X "Advanced" editing
- X ------------------
- X [ Eventually, these will be rewritten to become "operators", similar to
- X those described above. ]
- X ^A-<SPACE> Convert tabs to spaces on the current line. An argument
- X tells how many lines.
- X ^A-<TAB> Convert as many spaces to tabs as possible on the
- X current line. Argument tells how many lines.
- X ^A-o Remove all but one blank line at the current spot.
- X
- Miscellaneous commands
- ----------------------
- X ^X-^X The "error finder". Goes to the next file/line error pair
- X specified in the last buffer captured from a command's
- X output. This buffer is usually created with the ^X-! command.
- X For example, "-!cc -c junk.c" puts all of the compiler output
- X into the buffer named "[Output]". Repeatedly hitting ^X-^X
- X will position the editor at each error in turn, and will
- X eventually start over again at the top..
- X ^X-t Set or report on the tab-stop width. Tab-stops may only be
- X set to 2, 4, 8, or 16 column spacings. To set, the spacing
- X must precede the command, as in "4^X-t". The "set tabstop"
- X command described below does the same thing.
- X ^X-f Set the fill-column to be used with ^A-f and auto-wrap mode on
- X insert. The default value is 7/8's of the screen size, with
- X a maximum of 70. Since arguments come before commands, you
- X type: 65^X-f. The "set fillcol" command does the same thing.
- X ^X-x Set encryption key. (not well tested, but hopefully not broken)
- X The CRYPT mode must be set for this to do anything.
- X K Count prefix. The first time you type it, it is equivalent
- X to an argument of 4 to the following command. If you repeat
- X it, it becomes worth 16, the next time 64, etc...
- X
- Editor modes
- ------------
- X Modes are associated with buffers, and are inherited from a set of
- X global modes. To set a mode on a buffer, use ":set", to remove the
- X mode, use ":unset", ":setno", or ":set" with the modename prefixed
- X with "no". To set and reset global modes, use ":setg", ":unsetg",
- X ":setgno". To display modes, use ":setall", ":modes", or
- X ":setgall", ":gmodes". (The modename "all" is also accepted as a
- X dummy mode, which sets nothing, but display instead. So vi's "set all"
- X works as well.) The possible modes are:
- X
- X wrap similar to vi's auto-wrap mode. While inserting, words are
- X moved to the next line if the current line gets too long.
- X Unlike vi, wrapping is only attempted when a space is typed.
- X
- X cmode C-code mode.. Maintains current indentation level
- X automatically during insert. If a line ends with a '{',
- X then the next line tabs in further. If a line begins with
- X a '}', it is lined up with its matching paired brace. If a
- X line starts with '#' it is started at the beginning of
- X line. If the global CMODE is set, then the buffer's mode
- X is turned on automatically only for files ending in ".c" or
- X ".h". A common mistake is to put "set cmode" in a .vilerc
- X file. One almost always wants "setg cmode".
- X
- X swrap Scanwrap mode. Text searches will continue from past the
- X bottom of the file to the top, and vice-versa.
- X
- X exact Text searches must match the pattern exactly. Otherwise,
- X searches are case-insensitive.
- X
- X view View the file only. No changes are permitted. This is set
- X automatically for the output of shell commands.
- X
- X magic Allow meta-characters in search strings. Otherwise,
- X strings are taken literally. Meta characters available are:
- X ^ - matches beginning of line
- X $ - matches end of line
- X . - matches any single character
- X * - matches any number of the previous character
- X [...] - matches a character class
- X \ - take the next character literally
- X
- X asave Automatic file saving. Writes the file after every 256
- X characters of inserted text. Other file changes are not
- X counted.
- X
- X crypt Causes files to be encrypted. This is NOT compatible
- X with the UNIX crypt(1) routines.
- X
- X list The buffer will be displayed with tabs and newlines made
- X visible, instead of as whitespace.
- X
- X dos When writing the buffer, terminate lines with CR/LF pairs,
- X rather than the usual single LF. On input, if the global
- X DOS mode is set, then incoming CR/LF pairs are taken as
- X line terminators, and the local DOS mode is set on the
- X buffer if the majority of lines ended that way. If global
- X DOS mode is _not_ set, then incoming CR characters will be
- X visible on the screen.
- X
- X aindent Similar to C mode, above, but works for any buffer, and is
- X not sensitive to {, }, or #. Attempts to align new lines
- X of text with previous lines.
- X
- X lazy If an attempt is made to edit a file (with ":e filename")
- X which does not exist in the current directory, vile will
- X try looking for a file of the same name (but in a different
- X directory) which has been referenced in the tags file.
- X This mode is global to the editor, and is not "inherited"
- X by buffers. It's not very fast, either.
- X
- X tabstop Will prompt for a new value for spacing of tabstops. The
- X only supported values are 2, 4, 8, and 16. This value is,
- X unfortunately, not settable on a per-buffer basis.
- X
- X fillcol Will prompt for a new value for the fill column, where
- X auto-wrapping and region formatting will break lines. This
- X value is, unfortunately, not settable on a per-buffer
- X basis.
- X
- Special Character Expansion
- ---------------------------
- X
- X As in vi, the % and # characters typed while responding to a prompt
- X will expand to the current or "alternate" filename. In addition,
- X the colon character (":") expands to the identifier name under the
- X cursor. Expansion of ! to the last command run is not implemented.
- X
- Key Rebinding
- -------------
- X
- X The vi "map", "map!", and "abbr" commands are not currently supported.
- X
- X There is a key rebinding facility (if vile is built to include it),
- X which is invoked as follows. One must know the "english" name for the
- X command being rebound. Use ":describe-bindings" or ":apropos string"
- X to find englishnames containing "string". Then use the command:
- X ":bind-key englishname keyseq"
- X where keyseq is the exact keyboard sequence (i.e. single character,
- X or ^X or ^A followed by a single character) to which the
- X command should be bound. In a ".vilerc" file, keyseq should be the
- X printable representation of the sequence, e.g. M-a or ^X-S.
- X
- X Examples:
- X To cause the / and ? commands to perform incremental
- X searches, use:
- X bind-key incremental-search /
- X bind-key reverse-incremental-search ?
- X To change the default window-switching behavior of ^N and ^P, try
- X bind-key next-line ^N
- X bind-key previous-line ^P
- X To cause the space bar to move forward by pages, as in them "more"
- X command, use:
- X bind-key next-page <sp>
- X
- X (Space and tab can be represented with the strings: "<sp>" and
- X "<tab>".) The englishname "rebind-key" is synonymous with "bind-key".
- X
- X Note that even the ^A and ^X prefix characters can be rebound, using
- X the dummy functions "cntl_a-prefix" and "cntl_x-prefix". Even
- X if they are rebound, however, the binding list and bind-key
- X commands will refer to them as ^A and ^X.
- X
- Macros
- ------
- X
- X The first type of macro in vile, is for temporary, quick macro
- X usage, and lets you record a macro as you execute vile commands.
- X You can then replay those keystrokes with a single key.
- X
- X ^X-( Begin recording a keyboard macro. The keystrokes you type
- X are recorded, until you use ^X-).
- X ^X-) Finish recording a keyboard macro.
- X ^X-& Execute the keyboard macro.
- X
- X Vile can also be extended (though I confess this has only been
- X lightly used or tested) by defining macros and then binding
- X execution of those macros to key sequences. For example, if
- X the following lines appear in a .vilerc file:
- X
- X 1 store-macro
- X 5 delete-til next-word
- X endm
- X
- X bind-key execute-macro-1 M-1
- X
- X then when M-1 is executed, 5 words will be deleted. The "-til"
- X suffix on an englishname denotes that it is a vi operator style
- X command, and expects to be followed by a motion command.
- X
- Differences
- ------------
- X Of course, this really isn't vi. Some of the following differences
- X deserve changing, others do not.
- X
- X The parser for the ':' commands is not very vi-like. For instance,
- X ":e" will prompt you for a file name. Most commands remember their
- X last argument, and will present it as the default reply to their
- X prompt.
- X
- X The backspace, line kill, job control, etc. characters are not
- X taken from the terminal settings on startup, but are hard-coded.
- X The insert-mode command characters cannot even be rebound.
- X
- X In insert mode there is no word kill (^W) or line kill (^U or @).
- X
- X Repeated backspacing while in insert mode will move past the point
- X where the insert began, until the beginning of line is reached.
- X
- X There is no expansion of ! in filenames or shell escapes. The
- X command ":!!" does rerun the previous shell command. Occurences of
- X '#' and '%' are recognized and expanded to the previous or current
- X filename. Other punctuation (e.g. '~') may be expanded by your
- X shell (sh, csh), since it is handed filenames for expansion if they
- X contain any of these characters: * ? ~ [ ] $ { }
- X
- X Paragraph and section boundaries, for the {, }, [, and ] commands
- X are not configurable, and do not exactly match those in vi. The
- X current set is:
- X Paragraphs: blank lines, or lines beginning in .I .L .P .Q or .b
- X Sections: lines beginning in {, formfeeds, or .S .H .N
- X I think these will find more boundaries than vi, rather than fewer.
- X
- X There is no special lisp support. But then, when was the last time
- X you heard of a lisp programmer that used vi?
- X
- X Of course, ex and open mode aren't there.
- X
- X There is no concept of shiftwidth. ^D and ^T are aliased to backspace
- X and tab for those whose fingers are too old for new tricks.
- X
- X There are no "sentence" oriented motions. That is, "(" and ")" are
- X missing.
- X
- X Most, but not all, of the word-motion-with-operator and end-of-line
- X anomalies have been recreated. One missing anomaly: In vile, "dw"
- X on the last word of a line ending in whitespace deletes the
- X trailing whitespace. Vi does not delete the whitespace.
- X
- Credits
- -------
- X This code has been written by a _lot_ of people. Names appearing
- X within comments in the micro-Emacs source code are: Dave
- X Conroy, Daniel Lawrence, John Gamble, Roger Ove, Dana Hoggatt,
- X Jon Reid, Steve Wilhite, George Jones, Adam Fritz, D.R.Banks,
- X Bob McNamara. In addition, some of the "ex" code is by Steve
- X Kirkendall, author of the vi clone called "elvis". The
- X changes to create vile from micro-Emacs were all done by Paul
- X Fox, who can be reached at pgf@cayman.com. (By the way, this is
- X not the same Paul Fox who did the Crisp editor.)
- X
- X
- SHAR_EOF
- echo 'File vile.hlp is complete' &&
- chmod 0444 vile.hlp ||
- echo 'restore of vile.hlp failed'
- Wc_c="`wc -c < 'vile.hlp'`"
- test 24385 -eq "$Wc_c" ||
- echo 'vile.hlp: original size 24385, current size' "$Wc_c"
- # ============= vmalloc.c ==============
- echo 'x - extracting vmalloc.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'vmalloc.c' &&
- #include "estruct.h"
- #include "edef.h"
- X
- /* these routines copied without permission from "The C User's Journal",
- X issue of Feb. 1989. I assume they are Copyright 1989 by them.
- X They and the accompanying article were written by Eric White */
- X
- #if VMALLOC
- X
- #undef malloc
- #undef free
- #undef realloc
- #undef calloc
- #undef vverify
- X
- #include "stdio.h"
- #include "string.h"
- X
- char *malloc(), *calloc(), *realloc();
- X
- char *vmalloc();
- void vfree();
- void rvverify();
- char *vrealloc();
- char *vcalloc();
- void vdump();
- X
- typedef unsigned long ulong;
- X
- /* max buffers alloced but not yet freed */
- #define MAXMALLOCS 20000
- X
- /* known pattern, and how many of them */
- #define KP 0xaaaaaaaaL
- #define KPW (2*sizeof(unsigned long))
- X
- X
- static void trace();
- static void errout();
- X
- static int nummallocs = 0;
- struct mtype {
- X unsigned char *addr;
- X int size;
- };
- X
- static struct mtype m[MAXMALLOCS];
- X
- #define VMAL 1
- #define VFRE 2
- #define VREA 4
- int doverifys = VMAL|VREA; /* |VFRE */
- X
- static void
- dumpbuf(x)
- int x;
- {
- X unsigned char *c;
- X char s [80];
- X c = (unsigned char *)m[x].addr - 2;
- X /* dump malloc buffer to the vmalloc file */
- X while (c <= m[x].addr + m[x].size + KPW + KPW + 1) {
- X sprintf(s, "%04.4lx : %02x ", (long)c, *c);
- X if (c == m[x].addr)
- X strcat(s," <= leading known pattern");
- X if (c == m[x].addr + KPW)
- X strcat(s," <= addr of malloc buffer");
- X if (c == m[x].addr + m[x].size + KPW)
- X strcat(s," <= trailing known pattern");
- X strcat(s,"\n");
- X trace(s);
- X ++c;
- X }
- }
- X
- void
- rvverify(id,f,l)
- char *id;
- char *f;
- {
- X char s[80];
- X register int c;
- X register struct mtype *mp;
- X
- X
- X /* verify entire malloc heap */
- X for (mp = &m[nummallocs-1]; mp >= m; mp--) {
- X if (mp->addr != NULL) {
- X if (*(ulong *)mp->addr != KP ||
- X *(ulong *)(mp->addr + sizeof (ulong)) != KP)
- X {
- X sprintf(s,
- X "ERROR: Malloc area corrupted (%s). %s %d\n",
- X id,f,l);
- X fputs(s,stderr);
- X trace(s);
- X dumpbuf(mp - m);
- X errout();
- X }
- X }
- X }
- }
- X
- char *
- vmalloc(size,f,l)
- char *f;
- {
- X unsigned char *buffer;
- X char *sp, s[80];
- X register int c;
- X register struct mtype *mp;
- X
- X if (doverifys & VMAL)
- X rvverify("vmalloc",f,l);
- X if (( buffer = (unsigned char *)malloc(size + KPW + KPW)) == NULL) {
- X sp = "ERROR: real malloc returned NULL\n";
- X fprintf(stderr,sp);
- X trace(sp);
- X errout();
- X }
- #ifdef VERBOSE
- X sprintf(s,"%04.4lx:vmalloc size = %ld, %s %d\n",
- X (long)buffer,(long)size,f,l);
- X trace(s);
- #endif
- X /* find a place for an entry in m */
- X for (mp = m; mp < &m[MAXMALLOCS] && mp->addr != NULL; ++mp)
- X ;
- X if (mp == &m[MAXMALLOCS]) {
- X sp = "ERROR: too many mallocs\n";
- X fprintf(stderr,sp);
- X trace(sp);
- X errout();
- X }
- X mp->addr = buffer;
- X mp->size = size;
- X if (mp == &m[nummallocs])
- X ++nummallocs;
- X *(ulong *)(mp->addr) = KP;
- X *(ulong *)(mp->addr + sizeof(ulong)) = KP;
- X return (char *)(buffer + KPW);
- }
- X
- char *
- vcalloc(n,size,f,l)
- int n, size;
- char *f;
- {
- X return vmalloc(n * size,f,l);
- }
- X
- void
- vfree(buffer,f,l)
- unsigned char *buffer;
- char *f;
- {
- X unsigned char *b;
- X char s[80], *sp;
- X register struct mtype *mp;
- X
- X b = buffer - KPW;
- X if (doverifys & VFRE)
- X rvverify("vfree",f,l);
- X for (mp = &m[nummallocs-1]; mp >= m && mp->addr != b; mp--)
- X ;
- X if (mp < m) {
- X sprintf(s,"ERROR: location to free is not in list. %s %d\n",
- X f,l);
- X fprintf(stderr,s);
- X trace(s);
- X errout();
- X }
- #ifdef VERBOSE
- X sprintf(s,"%04.4lx:vfree %s %d\n",(long)b,f,l);
- X trace(s);
- #endif
- X if (*(ulong *)mp->addr != KP ||
- X *(ulong *)(mp->addr + sizeof (ulong)) != KP)
- X {
- X sprintf(s,"ERROR: corrupted freed block. %s %d\n", f,l);
- X fprintf(stderr,s);
- X trace(s);
- X errout();
- X }
- X free(b);
- X mp->addr = NULL;
- X if (mp == &m[nummallocs-1])
- X --nummallocs;
- }
- X
- char *
- vrealloc(buffer,size,f,l)
- unsigned char *buffer;
- int size;
- char *f;
- {
- X unsigned char *b, *b2;
- X char *sp, s[80];
- X register int c;
- X register struct mtype *mp;
- X
- X b = buffer - KPW;
- X if (doverifys & VREA)
- X rvverify("vrealloc",f,l);
- X
- X for (mp = &m[nummallocs-1]; mp >= m && mp->addr != b; mp--)
- X ;
- X if (mp < m) {
- X sprintf(s,"ERROR: location to realloc is not in list. %s %d\n",
- X sp,f,l);
- X fprintf(stderr,s);
- X trace(s);
- X errout();
- X }
- X
- #ifdef VERBOSE
- X sprintf(s,"%04.4lx:vrealloc size = %ld, %s %d\n",
- X (long)b,(long)size,f,l);
- X trace(s);
- #endif
- X *(ulong *)(mp->addr) = KP;
- X *(ulong *)(mp->addr + sizeof (ulong)) = KP;
- X b2 = (unsigned char *)realloc(b,size+KPW+KPW);
- X *(ulong *)(mp->addr + mp->size + KPW) = KP;
- X *(ulong *)(mp->addr + mp->size + KPW + sizeof (ulong)) = KP;
- X return (char *)(b2 + KPW);
- }
- X
- void
- vdump(id)
- char *id;
- {
- X char s[80];
- X int x;
- X sprintf(s,"=============Dump of malloc heap==========%s\n",id);
- X trace(s);
- X for (x = 0; x < nummallocs; ++x) {
- X if (m[x].addr != NULL) {
- X sprintf(s,"=========malloc buffer addr: %04.4lx\n",
- X (long)m[x].addr);
- X trace(s);
- X sprintf(s,"=========malloc buffer size: %04x\n",
- X (long)m[x].size + KPW + KPW);
- X trace(s);
- X dumpbuf(x);
- X }
- X }
- }
- X
- static void
- trace(s)
- char *s;
- {
- X static FILE *out = NULL;
- X if (out == NULL) {
- X unlink("vmalloc.log");
- X out = fopen("vmalloc.log", "w");
- X setbuf(out,NULL);
- X }
- X fputs(s,out);
- }
- X
- static void
- errout()
- {
- X sleep(1);
- X kill(getpid(),3);
- X pause();
- }
- X
- setvmalloc(f,n)
- {
- X register struct mtype *mp;
- X int i,num,found;
- X
- X if (f)
- X doverifys = n;
- X rvverify("requested",__FILE__,__LINE__);
- X for (mp = m, num = 0; mp < &m[MAXMALLOCS]; ++mp) {
- X if (mp->addr != NULL)
- X num++;
- X }
- X found = 0;
- X { /* windows */
- X register WINDOW *wp;
- X for (wp=wheadp; wp != NULL; wp = wp->w_wndp)
- X found++;
- X }
- X { /* buffers */
- X register BUFFER *bp;
- X for (bp=bheadp; bp != NULL; bp = bp->b_bufp) {
- X LINE *lp;
- X found++; /* for b_linep */
- X for(lp = bp->b_linep; lp->l_fp != bp->b_linep;
- X lp = lp->l_fp)
- X found++;
- X if (bp->b_nmmarks)
- X found++;
- X if (bp->b_ulinep)
- X found++;
- X found++; /* for the buffer itself */
- X for (i = 0; i < 2; i++) {
- X for (lp = bp->b_udstks[i]; lp != NULL;
- X lp = lp->l_nxtundo)
- X found++;
- X }
- X }
- X }
- X found += term.t_mrow+1; /* vscreen and the rows */
- #if ! MEMMAP
- X found += term.t_mrow+1; /* pscreen and the rows */
- #endif
- X if (fline)
- X found++;
- #if ! SMALLER
- X { /* user vars */
- X extern UVAR uv[MAXVARS];
- X for (i=0; i < MAXVARS; i++)
- X if (uv[i].u_value) found++;
- X }
- #endif
- #if FILOCK
- X need to count lock mallocs...
- #endif
- X { /* searching */
- X register MC *mcptr;
- X
- X if (patmatch)
- X found++;
- X
- X mcptr = &mcpat[0];
- X while (mcptr->mc_type != MCNIL)
- X {
- X if ((mcptr->mc_type & MASKCL) == CCL ||
- X (mcptr->mc_type & MASKCL) == NCCL)
- X if (mcptr->u.cclmap) found++;
- X mcptr++;
- X }
- X }
- X { /* kill registers */
- X for (i = 0; i < NKREGS; i++) {
- X KILL *kb;
- X if ((kb = kbs[i].kbufh) != NULL) {
- X while (kb) {
- X found++;
- X kb = kb->d_next;
- X }
- X }
- X }
- X }
- X mlwrite("doverifys %s %d, outstanding mallocs: %d, %d accounted for.",
- X f ? "set to":"is still", doverifys, num, found);
- X return TRUE;
- }
- X
- #endif
- SHAR_EOF
- chmod 0444 vmalloc.c ||
- echo 'restore of vmalloc.c failed'
- Wc_c="`wc -c < 'vmalloc.c'`"
- test 6798 -eq "$Wc_c" ||
- echo 'vmalloc.c: original size 6798, current size' "$Wc_c"
- # ============= vmsvt.c ==============
- echo 'x - extracting vmsvt.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'vmsvt.c' &&
- /*
- X * Advanced VMS terminal driver
- X *
- X * Knows about any terminal defined in SMGTERMS.TXT and TERMTABLE.TXT
- X * located in SYS$SYSTEM.
- X *
- X * Author: Curtis Smith
- X * Last Updated: 07/14/87
- X */
- X
- #include <stdio.h> /* Standard I/O package */
- #include "estruct.h" /* Emacs' structures */
- #include "edef.h" /* Emacs' definitions */
- X
- #if VMSVT
- X
- #include <descrip.h> /* Descriptor definitions */
- X
- /* These would normally come from iodef.h and ttdef.h */
- #define IO$_SENSEMODE 0x27 /* Sense mode of terminal */
- #define TT$_UNKNOWN 0x00 /* Unknown terminal */
- X
- /** Forward references **/
- int vmsopen(), ttclose(), vmskopen(), vmskclose(), ttgetc(), ttputc();
- int ttflush(), vmsmove(), vmseeol(), vmseeop(), vmsbeep(), vmsrev();
- int vmscres();
- extern int eolexist, revexist;
- extern char sres[];
- X
- #if COLOR
- int vmsfcol(), vmsbcol();
- #endif
- X
- /** SMG stuff **/
- static char * begin_reverse, * end_reverse, * erase_to_end_line;
- static char * erase_whole_display;
- static int termtype;
- X
- #define SMG$K_BEGIN_REVERSE 0x1bf
- #define SMG$K_END_REVERSE 0x1d6
- #define SMG$K_SET_CURSOR_ABS 0x23a
- #define SMG$K_ERASE_WHOLE_DISPLAY 0x1da
- #define SMG$K_ERASE_TO_END_LINE 0x1d9
- X
- X
- /* Dispatch table. All hard fields just point into the terminal I/O code. */
- TERM term = {
- X 24 - 1, /* Max number of rows allowable */
- X /* Filled in */ - 1, /* Current number of rows used */
- X 132, /* Max number of columns */
- X /* Filled in */ 0, /* Current number of columns */
- X 64, /* Min margin for extended lines*/
- X 8, /* Size of scroll region */
- X 100, /* # times thru update to pause */
- X vmsopen, /* Open terminal at the start */
- X ttclose, /* Close terminal at end */
- X vmskopen, /* Open keyboard */
- X vmskclose, /* Close keyboard */
- X ttgetc, /* Get character from keyboard */
- X ttputc, /* Put character to display */
- X ttflush, /* Flush output buffers */
- X vmsmove, /* Move cursor, origin 0 */
- X vmseeol, /* Erase to end of line */
- X vmseeop, /* Erase to end of page */
- X vmsbeep, /* Beep */
- X vmsrev, /* Set reverse video state */
- X vmscres /* Change screen resolution */
- #if COLOR
- X , vmsfcol, /* Set forground color */
- X vmsbcol /* Set background color */
- #endif
- };
- X
- /***
- X * ttputs - Send a string to ttputc
- X *
- X * Nothing returned
- X ***/
- ttputs(string)
- char * string; /* String to write */
- {
- X if (string)
- X while (*string != '\0')
- X ttputc(*string++);
- }
- X
- X
- /***
- X * vmsmove - Move the cursor (0 origin)
- X *
- X * Nothing returned
- X ***/
- vmsmove(row, col)
- int row; /* Row position */
- int col; /* Column position */
- {
- X char buffer[32];
- X int ret_length;
- X static int request_code = SMG$K_SET_CURSOR_ABS;
- X static int max_buffer_length = sizeof(buffer);
- X static int arg_list[3] = { 2 };
- X register char * cp;
- X
- X register int i;
- X
- X /* Set the arguments into the arg_list array
- X * SMG assumes the row/column positions are 1 based (boo!)
- X */
- X arg_list[1] = row + 1;
- X arg_list[2] = col + 1;
- X
- X if ((smg$get_term_data( /* Get terminal data */
- X &termtype, /* Terminal table address */
- X &request_code, /* Request code */
- X &max_buffer_length, /* Maximum buffer length */
- X &ret_length, /* Return length */
- X buffer, /* Capability data buffer */
- X arg_list) /* Argument list array */
- X
- X /* We'll know soon enough if this doesn't work */
- X & 1) == 0) {
- X ttputs("OOPS");
- X return;
- X }
- X
- X /* Send out resulting sequence */
- X i = ret_length;
- X cp = buffer;
- X while (i-- > 0)
- X ttputc(*cp++);
- }
- X
- X
- /***
- X * vmsrev - Set the reverse video status
- X *
- X * Nothing returned
- X ***/
- vmsrev(status)
- int status; /* TRUE if setting reverse */
- {
- X if (status)
- X ttputs(begin_reverse);
- X else
- X ttputs(end_reverse);
- }
- X
- /***
- X * vmscres - Change screen resolution (which it doesn't)
- X *
- X * Nothing returned
- X ***/
- vmscres()
- {
- X /* But it could. For vt100/vt200s, one could switch from
- X 80 and 132 columns modes */
- }
- X
- X
- #if COLOR
- /***
- X * vmsfcol - Set the forground color (not implimented)
- X *
- X * Nothing returned
- X ***/
- vmsfcol()
- {
- }
- X
- /***
- X * vmsbcol - Set the background color (not implimented)
- X *
- X * Nothing returned
- X ***/
- vmsbcol()
- {
- }
- #endif
- X
- /***
- X * vmseeol - Erase to end of line
- X *
- X * Nothing returned
- X ***/
- vmseeol()
- {
- X ttputs(erase_to_end_line);
- }
- X
- X
- /***
- X * vmseeop - Erase to end of page (clear screen)
- X *
- X * Nothing returned
- X ***/
- vmseeop()
- {
- X ttputs(erase_whole_display);
- }
- X
- X
- /***
- X * vmsbeep - Ring the bell
- X *
- X * Nothing returned
- X ***/
- vmsbeep()
- {
- X ttputc('\007');
- }
- X
- X
- /***
- X * vmsgetstr - Get an SMG string capability by name
- X *
- X * Returns: Escape sequence
- X * NULL No escape sequence available
- X ***/
- char * vmsgetstr(request_code)
- int request_code; /* Request code */
- {
- X register char * result;
- X static char seq_storage[1024];
- X static char * buffer = seq_storage;
- X static int arg_list[2] = { 1, 1 };
- X int max_buffer_length, ret_length;
- X
- X /* Precompute buffer length */
- X
- X max_buffer_length = (seq_storage + sizeof(seq_storage)) - buffer;
- X
- X /* Get terminal commands sequence from master table */
- X
- X if ((smg$get_term_data( /* Get terminal data */
- X &termtype, /* Terminal table address */
- X &request_code, /* Request code */
- X &max_buffer_length,/* Maximum buffer length */
- X &ret_length, /* Return length */
- X buffer, /* Capability data buffer */
- X arg_list) /* Argument list array */
- X
- X /* If this doesn't work, try again with no arguments */
- X
- X & 1) == 0 &&
- X
- X (smg$get_term_data( /* Get terminal data */
- X &termtype, /* Terminal table address */
- X &request_code, /* Request code */
- X &max_buffer_length,/* Maximum buffer length */
- X &ret_length, /* Return length */
- X buffer) /* Capability data buffer */
- X
- X /* Return NULL pointer if capability is not available */
- X
- X & 1) == 0)
- X return NULL;
- X
- X /* Check for empty result */
- X if (ret_length == 0)
- X return NULL;
- X
- X /* Save current position so we can return it to caller */
- X
- X result = buffer;
- X
- X /* NIL terminate the sequence for return */
- X
- X buffer[ret_length] = 0;
- X
- X /* Advance buffer */
- X
- X buffer += ret_length + 1;
- X
- X /* Return capability to user */
- X return result;
- }
- X
- X
- /** I/O information block definitions **/
- struct iosb { /* I/O status block */
- X short i_cond; /* Condition value */
- X short i_xfer; /* Transfer count */
- X long i_info; /* Device information */
- };
- struct termchar { /* Terminal characteristics */
- X char t_class; /* Terminal class */
- X char t_type; /* Terminal type */
- X short t_width; /* Terminal width in characters */
- X long t_mandl; /* Terminal's mode and length */
- X long t_extend; /* Extended terminal characteristics */
- };
- static struct termchar tc; /* Terminal characteristics */
- X
- /***
- X * vmsgtty - Get terminal type from system control block
- X *
- X * Nothing returned
- X ***/
- vmsgtty()
- {
- X short fd;
- X int status;
- X struct iosb iostatus;
- X $DESCRIPTOR(devnam, "SYS$INPUT");
- X
- X /* Assign input to a channel */
- X status = sys$assign(&devnam, &fd, 0, 0);
- X if ((status & 1) == 0)
- X exit (status);
- X
- X /* Get terminal characteristics */
- X status = sys$qiow( /* Queue and wait */
- X 0, /* Wait on event flag zero */
- X fd, /* Channel to input terminal */
- X IO$_SENSEMODE, /* Get current characteristic */
- X &iostatus, /* Status after operation */
- X 0, 0, /* No AST service */
- X &tc, /* Terminal characteristics buf */
- X sizeof(tc), /* Size of the buffer */
- X 0, 0, 0, 0); /* P3-P6 unused */
- X
- X /* De-assign the input device */
- X if ((sys$dassgn(fd) & 1) == 0)
- X exit(status);
- X
- X /* Jump out if bad status */
- X if ((status & 1) == 0)
- X exit(status);
- X if ((iostatus.i_cond & 1) == 0)
- X exit(iostatus.i_cond);
- }
- X
- X
- /***
- X * vmsopen - Get terminal type and open terminal
- X *
- X * Nothing returned
- X ***/
- vmsopen()
- {
- X /* Get terminal type */
- X vmsgtty();
- X if (tc.t_type == TT$_UNKNOWN) {
- X printf("Terminal type is unknown!\n");
- X printf("Try set your terminal type with SET TERMINAL/INQUIRE\n");
- X printf("Or get help on SET TERMINAL/DEVICE_TYPE\n");
- X exit(3);
- X }
- X
- X /* Access the system terminal definition table for the */
- X /* information of the terminal type returned by IO$_SENSEMODE */
- X if ((smg$init_term_table_by_type(&tc.t_type, &termtype) & 1) == 0)
- X return -1;
- X
- X /* Set sizes */
- X term.t_nrow = ((unsigned int) tc.t_mandl >> 24) - 1;
- X term.t_ncol = tc.t_width;
- X
- X /* Get some capabilities */
- X begin_reverse = vmsgetstr(SMG$K_BEGIN_REVERSE);
- X end_reverse = vmsgetstr(SMG$K_END_REVERSE);
- X revexist = begin_reverse != NULL && end_reverse != NULL;
- X erase_to_end_line = vmsgetstr(SMG$K_ERASE_TO_END_LINE);
- X eolexist = erase_whole_display != NULL;
- X erase_whole_display = vmsgetstr(SMG$K_ERASE_WHOLE_DISPLAY);
- X
- X /* Set resolution */
- X strcpy(sres, "NORMAL");
- X
- X /* Open terminal I/O drivers */
- X ttopen();
- }
- X
- X
- /***
- X * vmskopen - Open keyboard (not used)
- X *
- X * Nothing returned
- X ***/
- vmskopen()
- {
- }
- X
- X
- /***
- X * vmskclose - Close keyboard (not used)
- X *
- X * Nothing returned
- X ***/
- vmskclose()
- {
- }
- X
- X
- /***
- X * fnclabel - Label function keys (not used)
- X *
- X * Nothing returned
- X ***/
- #if FLABEL
- fnclabel(f, n) /* label a function key */
- int f,n; /* default flag, numeric argument [unused] */
- {
- X /* on machines with no function keys...don't bother */
- X return(TRUE);
- }
- #endif
- X
- X
- /***
- X * spal - Set palette type (Are you kidding?)
- X *
- X * Nothing returned
- X ***/
- spal()
- {
- }
- X
- #else
- X
- /***
- X * hellovms - Avoid error because of empty module
- X *
- X * Nothing returned
- X ***/
- hellovms()
- {
- }
- X
- #endif
- SHAR_EOF
- chmod 0444 vmsvt.c ||
- echo 'restore of vmsvt.c failed'
- Wc_c="`wc -c < 'vmsvt.c'`"
- test 9271 -eq "$Wc_c" ||
- echo 'vmsvt.c: original size 9271, current size' "$Wc_c"
- # ============= vt52.c ==============
- echo 'x - extracting vt52.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'vt52.c' &&
- /*
- X * The routines in this file
- X * provide support for VT52 style terminals
- X * over a serial line. The serial I/O services are
- X * provided by routines in "termio.c". It compiles
- X * into nothing if not a VT52 style device. The
- X * bell on the VT52 is terrible, so the "beep"
- X * routine is conditionalized on defining BEL.
- X */
- #define termdef 1 /* don't define "term" external */
- X
- #include <stdio.h>
- #include "estruct.h"
- #include "edef.h"
- X
- #if VT52
- X
- #define NROW 24 /* Screen size. */
- #define NCOL 80 /* Edit if you want to. */
- #define MARGIN 8 /* size of minimim margin and */
- #define SCRSIZ 64 /* scroll size for extended lines */
- #define NPAUSE 100 /* # times thru update to pause */
- #define BIAS 0x20 /* Origin 0 coordinate bias. */
- #define ESC 0x1B /* ESC character. */
- #define BEL 0x07 /* ascii bell character */
- X
- extern int ttopen(); /* Forward references. */
- extern int ttgetc();
- extern int ttputc();
- extern int ttflush();
- extern int ttclose();
- extern int vt52move();
- extern int vt52eeol();
- extern int vt52eeop();
- extern int vt52beep();
- extern int vt52open();
- extern int vt52rev();
- extern int vt52cres();
- extern int vt52kopen();
- extern int vt52kclose();
- X
- #if COLOR
- extern int vt52fcol();
- extern int vt52bcol();
- #endif
- X
- /*
- X * Dispatch table. All the
- X * hard fields just point into the
- X * terminal I/O code.
- X */
- TERM term = {
- X NROW-1,
- X NROW-1,
- X NCOL,
- X NCOL,
- X MARGIN,
- X SCRSIZ,
- X NPAUSE,
- X &vt52open,
- X &ttclose,
- X &vt52kopen,
- X &vt52kclose,
- X &ttgetc,
- X &ttputc,
- X &ttflush,
- X &vt52move,
- X &vt52eeol,
- X &vt52eeop,
- X &vt52beep,
- X &vt52rev,
- X &vt52cres
- #if COLOR
- X , &vt52fcol,
- X &vt52bcol
- #endif
- };
- X
- vt52move(row, col)
- {
- X ttputc(ESC);
- X ttputc('Y');
- X ttputc(row+BIAS);
- X ttputc(col+BIAS);
- }
- X
- vt52eeol()
- {
- X ttputc(ESC);
- X ttputc('K');
- }
- X
- vt52eeop()
- {
- X ttputc(ESC);
- X ttputc('J');
- }
- X
- vt52rev(status) /* set the reverse video state */
- X
- int status; /* TRUE = reverse video, FALSE = normal video */
- X
- {
- X /* can't do this here, so we won't */
- }
- X
- vt52cres() /* change screen resolution - (not here though) */
- X
- {
- X return(TRUE);
- }
- X
- spal() /* change palette string */
- X
- {
- X /* Does nothing here */
- }
- X
- #if COLOR
- vt52fcol() /* set the forground color [NOT IMPLIMENTED] */
- {
- }
- X
- vt52bcol() /* set the background color [NOT IMPLIMENTED] */
- {
- }
- #endif
- X
- vt52beep()
- {
- #ifdef BEL
- X ttputc(BEL);
- X ttflush();
- #endif
- }
- X
- vt52open()
- {
- #if V7 | BSD
- X register char *cp;
- X char *getenv();
- X
- X if ((cp = getenv("TERM")) == NULL) {
- X puts("Shell variable TERM not defined!");
- X exit(1);
- X }
- X if (strcmp(cp, "vt52") != 0 && strcmp(cp, "z19") != 0) {
- X puts("Terminal type not 'vt52'or 'z19' !");
- X exit(1);
- X }
- #endif
- X ttopen();
- }
- X
- vt52kopen()
- X
- {
- }
- X
- vt52kclose()
- X
- {
- }
- X
- X
- #if FLABEL
- fnclabel(f, n) /* label a function key */
- X
- int f,n; /* default flag, numeric argument [unused] */
- X
- {
- X /* on machines with no function keys...don't bother */
- X return(TRUE);
- }
- #endif
- #else
- X
- vt52hello()
- X
- {
- }
- X
- #endif
- SHAR_EOF
- chmod 0444 vt52.c ||
- echo 'restore of vt52.c failed'
- Wc_c="`wc -c < 'vt52.c'`"
- test 3386 -eq "$Wc_c" ||
- echo 'vt52.c: original size 3386, current size' "$Wc_c"
- # ============= window.c ==============
- echo 'x - extracting window.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'window.c' &&
- /*
- X * Window management. Some of the functions are internal, and some are
- X * attached to keys that the user actually types.
- X */
- X
- #include <stdio.h>
- #include "estruct.h"
- #include "edef.h"
- X
- #if MEGAMAX & ST520
- overlay "window"
- #endif
- X
- /*
- X * Reposition dot's line to line "n" of the window. If the argument is
- X * positive, it is that line. If it is negative it is that line from the
- X * bottom. If it is 0 the window is centered around dot (this is what
- X * the standard redisplay code does). Defaults to 0.
- X */
- reposition(f, n)
- {
- X if (f == FALSE) /* default to 0 to center screen */
- X n = 0;
- X curwp->w_force = n;
- X curwp->w_flag |= WFFORCE;
- X return (TRUE);
- }
- X
- /*
- X * Refresh the screen. With no argument, it just does the refresh. With an
- X * argument it recenters "." in the current window.
- X */
- refresh(f, n)
- {
- #if NeWS /* see if the window has changed size */
- X newsrefresh() ;
- #endif
- X
- X if (f == FALSE) {
- X sgarbf = TRUE;
- X } else {
- X curwp->w_force = 0; /* Center dot. */
- X curwp->w_flag |= WFFORCE;
- X }
- X
- #if NeWS
- X newsreportmodes() ;
- #endif
- X return (TRUE);
- }
- X
- /*
- X * The command make the next window (next => down the screen) the current
- X * window. There are no real errors, although the command does nothing if
- X * there is only 1 window on the screen.
- X *
- X * with an argument this command finds the <n>th window from the top
- X *
- X */
- nextwind(f, n)
- int f, n; /* default flag and numeric argument */
- {
- X register WINDOW *wp;
- X register int nwindows; /* total number of windows */
- X
- X if (f) {
- X
- X /* first count the # of windows */
- X wp = wheadp;
- X nwindows = 1;
- X while (wp->w_wndp != NULL) {
- X nwindows++;
- X wp = wp->w_wndp;
- X }
- X
- X /* if the argument is negative, it is the nth window
- X from the bottom of the screen */
- X if (n < 0)
- X n = nwindows + n + 1;
- X
- X /* if an argument, give them that window from the top */
- X if (n > 0 && n <= nwindows) {
- X wp = wheadp;
- X while (--n)
- X wp = wp->w_wndp;
- X } else {
- X mlwrite("Window number out of range");
- X return(FALSE);
- X }
- X } else {
- X if ((wp = curwp->w_wndp) == NULL)
- X wp = wheadp;
- X }
- X curwp = wp;
- X make_current(curwp->w_bufp);
- X upmode();
- X return (TRUE);
- }
- X
- poswind(f,n)
- {
- X register int c;
- X register int rows;
- X int s;
- X
- X c = kbd_key();
- X if (c == abortc)
- X return FALSE;
- X
- X if (c == '+' || c == '\r' || c == 'H') {
- X rows = 1;
- X } else if (c == '.' || c == 'M') {
- X rows = 0;
- X } else if (c == '-' || c == 'L') {
- X rows = -1;
- X } else {
- X TTbeep();
- X return FALSE;
- X }
- X
- X if (f == TRUE) {
- X s = gotoline(f,n);
- X if (s != TRUE)
- X return(s);
- X }
- X return(reposition(TRUE,rows));
- }
- X
- /*
- X * This command makes the previous window (previous => up the screen) the
- X * current window. There arn't any errors, although the command does not do a
- X * lot if there is 1 window.
- X */
- prevwind(f, n)
- {
- X register WINDOW *wp1;
- X register WINDOW *wp2;
- X
- X /* if we have an argument, we mean the nth window from the bottom */
- X if (f)
- X return(nextwind(f, -n));
- X
- X wp1 = wheadp;
- X wp2 = curwp;
- X
- X if (wp1 == wp2)
- X wp2 = NULL;
- X
- X while (wp1->w_wndp != wp2)
- X wp1 = wp1->w_wndp;
- X
- X curwp = wp1;
- X make_current(curwp->w_bufp);
- X upmode();
- X return (TRUE);
- }
- X
- /*
- X * This command moves the current window down by "arg" lines. Recompute the
- X * top line in the window. The move up and move down code is almost completely
- X * the same; most of the work has to do with reframing the window, and picking
- X * a new dot. We share the code by having "move down" just be an interface to
- X * "move up". Magic.
- X */
- mvdnwind(f, n)
- int n;
- {
- X return (mvupwind(f, -n));
- }
- X
- /*
- X * Move the current window up by "arg" lines. Recompute the new top line of
- X * the window. Look to see if "." is still on the screen. If it is, you win.
- X * If it isn't, then move "." to center it in the new framing of the window
- X * (this command does not really move "." (except as above); it moves the
- X * frame).
- X */
- mvupwind(f, n)
- int n;
- {
- X register LINE *lp;
- X register int i;
- X int was_n = n;
- X
- X lp = curwp->w_linep;
- X
- X if (n < 0) {
- X while (n++ && lforw(lp) != curbp->b_linep)
- X lp = lforw(lp);
- X } else {
- X while (n-- && lback(lp)!=curbp->b_linep)
- X lp = lback(lp);
- X }
- X
- X curwp->w_linep = lp;
- X curwp->w_flag |= WFHARD|WFMODE;
- X
- X /* is it still in the window */
- X for (i = 0; i < curwp->w_ntrows; ++i) {
- X if (lp == curwp->w_dotp)
- X return (TRUE);
- X if (lforw(lp) == curbp->b_linep)
- X break;
- X lp = lforw(lp);
- X }
- X /* now lp is either just past the window bottom, or
- X it's the last line of the file */
- X
- X /* preserve the current column */
- X if (curgoal < 0)
- X curgoal = getccol(FALSE);
- X
- X if (was_n < 0)
- X curwp->w_dotp = curwp->w_linep;
- X else
- X curwp->w_dotp = lback(lp);
- X curwp->w_doto = getgoal(curwp->w_dotp);
- X return (TRUE);
- }
- X
- mvdnnxtwind(f, n)
- {
- X nextwind(FALSE, 1);
- X mvdnwind(f, n);
- X prevwind(FALSE, 1);
- }
- X
- mvupnxtwind(f, n)
- {
- X nextwind(FALSE, 1);
- X mvupwind(f, n);
- X prevwind(FALSE, 1);
- }
- X
- mvrightwind(f,n)
- {
- X int move, col;
- X
- X if (f)
- X move = n;
- X else
- X move = term.t_ncol/3;
- X
- X if (curwp->w_sideways + move > (col = getccol(FALSE)) - 1) {
- X TTbeep();
- X return FALSE;
- X }
- X
- X curwp->w_sideways += move;
- X
- X curwp->w_flag |= WFHARD|WFMOVE;
- X
- X return TRUE;
- }
- X
- mvleftwind(f,n)
- {
- X if (f)
- X curwp->w_sideways -= n;
- X else
- X curwp->w_sideways -= term.t_ncol/3;
- X
- X if (curwp->w_sideways < 0)
- X curwp->w_sideways = 0;
- X
- X curwp->w_flag |= WFHARD|WFMOVE;
- X
- X return TRUE;
- }
- X
- /*
- X * This command makes the current window the only window on the screen.
- X * Try to set the framing so that "." does not have to move on the
- X * display. Some care has to be taken to keep the values of dot and mark in
- X * the buffer structures right if the distruction of a window makes a buffer
- X * become undisplayed.
- X */
- onlywind(f, n)
- {
- X register WINDOW *wp;
- X register LINE *lp;
- X register int i;
- X
- X wp = wheadp;
- X while (wp != NULL) {
- X register WINDOW *nwp;
- X nwp = wp->w_wndp;
- X if (wp != curwp) {
- X if (--wp->w_bufp->b_nwnd == 0)
- X undispbuff(wp->w_bufp,wp);
- X free((char *) wp);
- X }
- X wp = nwp;
- X }
- X wheadp = curwp;
- X wheadp->w_wndp = NULL;
- X lp = curwp->w_linep;
- X i = curwp->w_toprow;
- X while (i!=0 && lback(lp)!=curbp->b_linep) {
- X --i;
- X lp = lback(lp);
- X }
- X curwp->w_toprow = 0;
- X curwp->w_ntrows = term.t_nrow-1;
- X curwp->w_linep = lp;
- X curwp->w_flag |= WFMODE|WFHARD;
- X return (TRUE);
- }
- X
- /*
- X * Delete the current window, placing its space in the window above,
- X * or, if it is the top window, the window below.
- X */
- X
- delwind(f,n)
- int f, n; /* arguments are ignored for this command */
- {
- X return delwp(curwp);
- }
- X
- delwp(thewp)
- WINDOW *thewp;
- {
- X register WINDOW *wp; /* window to recieve deleted space */
- X register LINE *lp; /* line pointer */
- X register int i;
- X
- X /* if there is only one window, don't delete it */
- X if (wheadp->w_wndp == NULL) {
- X mlwrite("Cannot delete the only window");
- X return(FALSE);
- X }
- X
- X /* find recieving window and give up our space */
- X if (thewp == wheadp) { /* there's nothing before */
- X /* find the next window down */
- X wp = thewp->w_wndp;
- X lp = wp->w_linep;
- X /* the prev. window (thewp) has wp->w_toprow rows in it */
- X for (i = wp->w_toprow;
- X i > 0 && lback(lp) != wp->w_bufp->b_linep; --i)
- X lp = lback(lp);
- X wp->w_linep = lp;
- X wp->w_ntrows += wp->w_toprow; /* add in the new rows */
- X wp->w_toprow = 0; /* and we're at the top of the screen */
- X wheadp = wp; /* and at the top of the list as well */
- X } else {
- X /* find window before thewp in linked list */
- X for (wp = wheadp; wp->w_wndp != thewp; wp = wp->w_wndp)
- X ;
- X /* add thewp's rows to the next window up */
- X wp->w_ntrows += thewp->w_ntrows+1;
- X
- X wp->w_wndp = thewp->w_wndp; /* make their next window ours */
- X }
- X
- X /* get rid of the current window */
- X if (--thewp->w_bufp->b_nwnd == 0)
- X undispbuff(thewp->w_bufp,thewp);
- X free((char *)thewp);
- X if (thewp == curwp) {
- X curwp = wp;
- X curwp->w_flag |= WFHARD;
- X make_current(curwp->w_bufp);
- X }
- X upmode();
- X return(TRUE);
- }
- X
- /*
- X Split the current window. A window smaller than 3 lines cannot be
- X split. An argument of 1 forces the cursor into the upper window, an
- X argument of two forces the cursor to the lower window. The only other
- X error that is possible is a "malloc" failure allocating the structure
- X for the new window.
- X */
- splitwind(f, n)
- {
- X register WINDOW *wp;
- X register LINE *lp;
- X register int ntru;
- X register int ntrl;
- X register int ntrd;
- X register WINDOW *wp1;
- X register WINDOW *wp2;
- X register int i;
- X
- X if (curwp->w_ntrows < 3) {
- X mlwrite("Cannot split a %d line window", curwp->w_ntrows);
- X return (FALSE);
- X }
- X if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL) {
- X mlwrite("[OUT OF MEMORY]");
- X return (FALSE);
- X }
- X ++curbp->b_nwnd; /* Displayed twice. */
- X wp->w_bufp = curbp;
- X wp->w_dotp = curwp->w_dotp;
- X wp->w_doto = curwp->w_doto;
- X wp->w_mkp = curwp->w_mkp;
- X wp->w_mko = curwp->w_mko;
- X wp->w_linep = curwp->w_linep;
- X wp->w_ldmkp = curwp->w_ldmkp;
- X wp->w_ldmko = curwp->w_ldmko;
- X wp->w_sideways = curwp->w_sideways;
- X wp->w_flag = 0;
- X wp->w_force = 0;
- #if COLOR
- X /* set the colors of the new window */
- X wp->w_fcolor = gfcolor;
- X wp->w_bcolor = gbcolor;
- #endif
- X ntru = (curwp->w_ntrows-1) / 2; /* Upper size */
- X ntrl = (curwp->w_ntrows-1) - ntru; /* Lower size */
- X lp = curwp->w_linep;
- X ntrd = 0;
- X while (lp != curwp->w_dotp) {
- X ++ntrd;
- X lp = lforw(lp);
- X }
- X /* ntrd is now the row containing dot */
- X if (((f == FALSE) && (ntrd <= ntru)) || ((f == TRUE) && (n == 1))) {
- X /* Old is upper window. */
- X /* Adjust the top line if necessary */
- X if (ntrd == ntru) /* Hit mode line. */
- X if (ntrl > 1) {
- X ntru++;
- X ntrl--;
- X } else
- X curwp->w_linep = lforw(curwp->w_linep);
- X curwp->w_ntrows = ntru; /* new size */
- X /* insert new window after curwp in window list */
- X wp->w_wndp = curwp->w_wndp;
- X curwp->w_wndp = wp;
- X /* set new window's position and size */
- X wp->w_toprow = curwp->w_toprow+ntru+1;
- X wp->w_ntrows = ntrl;
- X /* try to keep lower from reframing */
- X for (i = ntru+1; i > 0 &&
- X wp->w_linep != wp->w_bufp->b_linep; i--) {
- X wp->w_linep = lforw(wp->w_linep);
- X }
- X wp->w_dotp = wp->w_linep;
- X wp->w_doto = 0;
- X } else {
- X /* Old is lower window */
- X wp1 = NULL;
- X wp2 = wheadp;
- X while (wp2 != curwp) {
- X wp1 = wp2;
- X wp2 = wp2->w_wndp;
- X }
- X if (wp1 == NULL)
- X wheadp = wp;
- X else
- X wp1->w_wndp = wp;
- X wp->w_wndp = curwp;
- X wp->w_toprow = curwp->w_toprow;
- X wp->w_ntrows = ntru;
- X ++ntru; /* Mode line. */
- X curwp->w_toprow += ntru;
- X curwp->w_ntrows = ntrl;
- X wp->w_dotp = wp->w_linep;
- X /* move upper window dot to bottom line of upper */
- X for (i = ntru-2; i > 0 && wp->w_dotp!=wp->w_bufp->b_linep; i--)
- X wp->w_dotp = lforw(wp->w_dotp);
- X wp->w_doto = 0;
- X /* adjust lower window topline */
- X while (ntru--)
- X curwp->w_linep = lforw(curwp->w_linep);
- X }
- X curwp->w_flag |= WFMODE|WFHARD;
- X wp->w_flag |= WFMODE|WFHARD;
- X return (TRUE);
- }
- X
- /*
- X * Enlarge the current window. Find the window that loses space. Make sure it
- X * is big enough. If so, hack the window descriptions, and ask redisplay to do
- SHAR_EOF
- true || echo 'restore of window.c failed'
- echo 'End of Vile part 16'
- echo 'File window.c is continued in part 17'
- echo 17 > _shar_seq_.tmp
- exit 0
- --
- paul fox, pgf@cayman.com, (617)494-1999
- Cayman Systems, 26 Landsdowne St., Cambridge, MA 02139
-