home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-02-03 | 58.3 KB | 2,242 lines |
- Path: xanth!mcnc!gatech!mandrill!hal!ncoast!allbery
- From: BLARSON@ECLA.USC.EDU (Bob Larson)
- Newsgroups: comp.sources.misc
- Subject: v03i032: mg 2a part 8 of 15
- Message-ID: <12401300459.47.BLARSON@ECLA.USC.EDU>
- Date: 26 May 88 04:58:01 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: BLARSON@ECLA.USC.EDU (Bob Larson)
- Lines: 2230
- Approved: allbery@ncoast.UUCP
-
- comp.sources.misc: Volume 3, Issue 32
- Submitted-By: "Bob Larson" <BLARSON@ECLA.USC.EDU>
- Archive-Name: mg2a/Part08
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- #----cut here-----cut here-----cut here-----cut here----#
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # sys/default/README
- # sys/default/alloca.c
- # sys/default/chrdef.h
- # sys/default/cinfo.c
- # sys/default/tty.c
- # sys/default/ttydef.h
- # sys/default/ttykbd.c
- # sys/default/varargs.h
- # sys/prime/cinfo.c
- # sys/prime/fileio.c
- # sys/prime/make.cpl
- # sys/prime/mg.64v.options.c
- # sys/prime/mg.options.c
- # sys/prime/readme
- # sys/prime/spawn.c
- # sys/prime/stackptr$.pma
- # sys/prime/sysdef.h
- # sys/prime/ttyio.c
- # sys/prime/varargs.h.ins.cc
- # This archive created: Sun May 22 02:24:06 1988
- # By: blarson
- if test -d sys
- then true
- else mkdir sys
- fi
- if test -d sys/default
- then true
- else mkdir sys/default
- fi
- if test -d sys/prime
- then true
- else mkdir sys/prime
- fi
- cat << \SHAR_EOF > sys/default/README
- MG Termcap Terminal Driver
-
- The termcap library needs to know where to get the terminal type and
- termcap capibilities file from. UNIX and Os9/68k users should
-
- setenv TERM term-type
-
- to their terminal type, and
-
- setenv TERMCAP termcap-file
-
- if they are using a non-standard termcap file. VMS users should see
- [.SYS.VMS]AAAREADME.1ST for information on how to define the logical
- names TERM and ETC to point to the termcap definition file. Users of
- other operating systems should do the aproprate thing. For an example
- of a termcap file, UNIX users may look in /etc/termcap, Os9/68k users
- may look at /dd/sys/termcap (if present), and VMS users should see the
- file [.SYS.VMS.TERMCAP]TERMCAP.
-
- MG requires that certain terminal capabilities exist in the specified
- termcap entry. The "cm" (cursor motion) capability *must* be
- available to use MG. (Yes, it is possible to fake cm with some other
- capibilities, but MG doesn't try.) If your terminal is one that uses
- control characters in the paramater portion of the "cm" string, the
- "up" and "bc" capabilites may also be needed. (See your termlib
- documentation for when this is so.)
-
- If the following capabilities are available, they are used. The AL
- and DL sequences are not totally standard, but having them improves
- the performance of the editor, since it doesn't have to redraw the
- screen to delete a line. They should not be used if they need control
- characters as paramaters.
-
- cd -- clear display
- ce -- clear to end of line
-
- al -- insert 1 line
- dl -- delete 1 line
-
- AL -- insert multiple lines (note capitalization)
- DL -- delete multiple lines (note capitalization)
-
- ti -- cursor movement initialization string
- te -- cursor movement end string
-
- The cs capability is not as standard as some of the other
- capibilities, but is used by MG when available. It is used to define
- a "scrolling region", which defines a window within the screen where
- all the action takes place. A newline character at the bottom of this
- area scrolls the rest of the text in the area up one line, just like
- the normal screen; a reverse linefeed (sr) at the top of the window
- moves all the text in the area down a line. MG does not properly
- handle "cs" if your terminal needs control characters as paramaters,
- and in this case "cs" should not be defined.
-
- If the cs and sr capabilities are available, the termcap driver uses
- these to make the insert/delete line functions work more smoothly. If
- only the cs capability is present, it is still used for the delete
- line function, but not for inserting lines.
-
- Use of the cs capability is often desirable, but is not a win on
- bit-mapped screens such as Sun workstation console windows. This is
- because it takes longer to scroll the window than to redraw it. If
- you are using a workstation window, you might consider using a termcap
- entry that doesn't have the cs capability.
-
- The definition of the cs capability is: the first parameter in the
- sequence defines the first row (origin 0) that is in the scrolling
- region, and the second argument defines the last row to include in the
- scrolling region.
-
- cs -- set scrolling region (arg1 = top, arg2 = bottom)
- sr -- reverse index
-
- The following capabilities provide for an enhanced (reverse-video or
- otherwise rendered) mode line. The sg entry should not be present on
- terminals that do this to characters as they are placed on the screen.
- Terminals that put a region of the screen in the standout mode should
- have sg defined as numeric: :sg#0: for terminals that do this on
- regions but don't take any character positions to do this, (this may
- be a non-standard interprition of the meaning of sg) and the number of
- character positions taken by any other terminal.
-
- so -- enter standout mode
- se -- leave standout mode
- sg -- number of character positions used by standout
-
- Terminal-specific initialization file
-
- If the MG termcap terminal driver is compiled with XKEYS defined, and
- the startup file option is enabled as well, MG will look for a
- terminal-specific initialization file. The name of the terminal
- initialization file varies between operating systems, but will usually
- look like .mg-TERM, where TERM represents your terminal type. For
- example, a terminal initialization file under Unix and VMS for the DEC
- VT100 terminal (termcap type vt100) would have the name ".mg-vt100".
-
- The terminal-specific startup file has the same format as the mg
- startup file, and is executed immediately after the startup file
- during mg's startup phase. An example vt100 initialization file
- follows, which globally binds the key sequences sent by the VT100
- terminal (in keypad mode) to the appropriate functions.
-
- ----------------------------------CUT HERE-----------------------------------
- ;
- ; Small key definition file for VT100 terminals using the termcap
- ; driver. This only works if XKEYS is defined during compilation.
- ;
- (global-set-key "\eOA" 'previous-line) ; up arrow
- (global-set-key "\eOB" 'next-line) ; down arrow
- (global-set-key "\eOC" 'forward-char) ; right arrow
- (global-set-key "\eOD" 'backward-char) ; left arrow
- SHAR_EOF
- cat << \SHAR_EOF > sys/default/alloca.c
- /*
- alloca -- (mostly) portable public-domain implementation
-
- last edit: 86/01/26 D A Gwyn
-
- This implementation of the PWB library alloca() function,
- which is used to allocate space off the run-time stack so
- that it is automatically reclaimed upon procedure exit,
- was inspired by discussions with J. Q. Johnson of Cornell.
-
- It should work under any C implementation that uses an
- actual procedure stack (as opposed to a linked list of
- frames). There are some preprocessor constants that can
- be defined when compiling for your specific system, for
- improved efficiency; however, the defaults should be okay.
-
- The general concept of this implementation is to keep
- track of all alloca()-allocated blocks, and reclaim any
- that are found to be deeper in the stack than the current
- invocation. This heuristic does not reclaim storage as
- soon as it becomes invalid, but it will do so eventually.
-
- As a special case, alloca(0) reclaims storage without
- allocating any. It is a good idea to use alloca(0) in
- your main control loop, etc. to force garbage collection.
- */
- #ifndef lint
- static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
- #endif
-
- #ifdef X3J11
- typedef void *pointer; /* generic pointer type */
- #else
- typedef char *pointer; /* generic pointer type */
- #endif
-
- #define NULL 0 /* null pointer constant */
-
- extern void free();
- extern pointer malloc();
-
- /*
- Define STACK_DIRECTION if you know the direction of stack
- growth for your system; otherwise it will be automatically
- deduced at run-time.
-
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown
- */
-
- #ifndef STACK_DIRECTION
- #define STACK_DIRECTION 0 /* direction unknown */
- #endif
-
- #if STACK_DIRECTION != 0
-
- #define STACK_DIR STACK_DIRECTION /* known at compile-time */
-
- #else /* STACK_DIRECTION == 0; need run-time code */
-
- static int stack_dir = 0; /* 1 or -1 once known */
- #define STACK_DIR stack_dir
-
- static void
- find_stack_direction( /* void */ )
- {
- static char *addr = NULL; /* address of first
- `dummy', once known */
- auto char dummy; /* to get stack address */
-
- if ( addr == NULL )
- { /* initial entry */
- addr = &dummy;
-
- find_stack_direction(); /* recurse once */
- }
- else /* second entry */
- if ( &dummy > addr )
- stack_dir = 1; /* stack grew upward */
- else
- stack_dir = -1; /* stack grew downward */
- }
-
- #endif /* STACK_DIRECTION == 0 */
-
- /*
- An "alloca header" is used to:
- (a) chain together all alloca()ed blocks;
- (b) keep track of stack depth.
-
- It is very important that sizeof(header) agree with malloc()
- alignment chunk size. The following default should work okay.
- */
-
- #ifndef ALIGN_SIZE
- #define ALIGN_SIZE sizeof(double)
- #endif
-
- typedef union hdr
- {
- char align[ALIGN_SIZE]; /* to force sizeof(header) */
- struct {
- union hdr *next; /* for chaining headers */
- char *deep; /* for stack depth measure */
- } h;
- } header;
-
- /*
- alloca( size ) returns a pointer to at least `size' bytes of
- storage which will be automatically reclaimed upon exit from
- the procedure that called alloca(). Originally, this space
- was supposed to be taken from the current stack frame of the
- caller, but that method cannot be made to work for some
- implementations of C, for example under Gould's UTX/32.
- */
-
- pointer
- alloca( size ) /* returns pointer to storage */
- unsigned size; /* # bytes to allocate */
- {
- static header *last = NULL; /* -> last alloca header */
- auto char probe; /* probes stack depth: */
- register char *depth = &probe;
-
- #if STACK_DIRECTION == 0
- if ( STACK_DIR == 0 ) /* unknown growth direction */
- find_stack_direction();
- #endif
-
- /* Reclaim garbage, defined as all alloca()ed storage that
- was allocated from deeper in the stack than currently. */
-
- {
- register header *hp; /* traverses linked list */
-
- for ( hp = last; hp != NULL; )
- if ( STACK_DIR > 0 && hp->h.deep > depth
- || STACK_DIR < 0 && hp->h.deep < depth
- ) {
- register header *np = hp->h.next;
-
- free( (pointer)hp ); /* collect garbage */
-
- hp = np; /* -> next header */
- }
- else
- break; /* rest are not deeper */
-
- last = hp; /* -> last valid storage */
- }
-
- if ( size == 0 )
- return NULL; /* no allocation required */
-
- /* Allocate combined header + user data storage. */
-
- {
- register pointer new = malloc( sizeof(header) + size );
- /* address of header */
-
- if ( new == NULL )
- return NULL; /* abort() is traditional */
-
- ((header *)new)->h.next = last;
- ((header *)new)->h.deep = depth;
-
- last = (header *)new;
-
- /* User storage begins just after header. */
-
- return (pointer)((char *)new + sizeof(header));
- }
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/default/chrdef.h
- /*
- * sys/default/chardef.h: character set specific #defines for mg 2a
- * Warning: System specific ones exist
- */
-
- #ifndef CHARMASK
- /*
- * casting should be at least as efficent as anding with 0xff,
- * and won't have the size problems. Override in sysdef.h if no
- * unsigned char type.
- */
- #define CHARMASK(c) ((unsigned char) (c))
- #endif
-
- /*
- * These flags, and the macros below them,
- * make up a do-it-yourself set of "ctype" macros that
- * understand the DEC multinational set, and let me ask
- * a slightly different set of questions.
- */
- #define _W 0x01 /* Word. */
- #define _U 0x02 /* Upper case letter. */
- #define _L 0x04 /* Lower case letter. */
- #define _C 0x08 /* Control. */
- #define _P 0x10 /* end of sentence punctuation */
- #define _D 0x20 /* is decimal digit */
-
- #define ISWORD(c) ((cinfo[CHARMASK(c)]&_W)!=0)
- #define ISCTRL(c) ((cinfo[CHARMASK(c)]&_C)!=0)
- #define ISUPPER(c) ((cinfo[CHARMASK(c)]&_U)!=0)
- #define ISLOWER(c) ((cinfo[CHARMASK(c)]&_L)!=0)
- #define ISEOSP(c) ((cinfo[CHARMASK(c)]&_P)!=0)
- #define ISDIGIT(c) ((cinfo[CHARMASK(c)]&_D)!=0)
- #define TOUPPER(c) ((c)-0x20)
- #define TOLOWER(c) ((c)+0x20)
-
- /*
- * generally useful thing for chars
- */
- #define CCHR(x) ((x) ^ 0x40) /* CCHR('?') == DEL */
-
- #ifndef METACH
- #define METACH CCHR('[')
- #endif
-
- #ifdef XKEYS
- #define K00 256
- #define K01 257
- #define K02 258
- #define K03 259
- #define K04 260
- #define K05 261
- #define K06 262
- #define K07 263
- #define K08 264
- #define K09 265
- #define K0A 266
- #define K0B 267
- #define K0C 268
- #define K0D 269
- #define K0E 270
- #define K0F 271
- #define K10 272
- #define K11 273
- #define K12 274
- #define K13 275
- #define K14 276
- #define K15 277
- #define K16 278
- #define K17 279
- #define K18 280
- #define K19 281
- #define K1A 282
- #define K1B 283
- #define K1C 284
- #define K1D 285
- #define K1E 286
- #define K1F 287
- #endif
- SHAR_EOF
- cat << \SHAR_EOF > sys/default/cinfo.c
- /*
- * Character class tables.
- * Do it yourself character classification
- * macros, that understand the multinational character set,
- * and let me ask some questions the standard macros (in
- * ctype.h) don't let you ask.
- */
- #include "def.h"
-
- /*
- * This table, indexed by a character drawn
- * from the 256 member character set, is used by my
- * own character type macros to answer questions about the
- * type of a character. It handles the full multinational
- * character set, and lets me ask some questions that the
- * standard "ctype" macros cannot ask.
- */
- char cinfo[256] = {
- _C, _C, _C, _C, /* 0x0X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C, /* 0x1X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- 0, _P, 0, 0, /* 0x2X */
- _W, _W, 0, _W,
- 0, 0, 0, 0,
- 0, 0, _P, 0,
- _D|_W, _D|_W, _D|_W, _D|_W, /* 0x3X */
- _D|_W, _D|_W, _D|_W, _D|_W,
- _D|_W, _D|_W, 0, 0,
- 0, 0, 0, _P,
- 0, _U|_W, _U|_W, _U|_W, /* 0x4X */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W, /* 0x5X */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, 0,
- 0, 0, 0, 0,
- 0, _L|_W, _L|_W, _L|_W, /* 0x6X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W, /* 0x7X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, 0,
- 0, 0, 0, _C,
- 0, 0, 0, 0, /* 0x8X */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, /* 0x9X */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, /* 0xAX */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0, /* 0xBX */
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0,
- _U|_W, _U|_W, _U|_W, _U|_W, /* 0xCX */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- 0, _U|_W, _U|_W, _U|_W, /* 0xDX */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, 0, _W,
- _L|_W, _L|_W, _L|_W, _L|_W, /* 0xEX */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- 0, _L|_W, _L|_W, _L|_W, /* 0xFX */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, 0, 0
- };
-
- /*
- * Find the name of a keystroke. Needs to be changed to handle 8-bit printing
- * characters and function keys better. Returns a pointer to the terminating
- * '\0'.
- */
-
- char *keyname(cp, k)
- register char *cp;
- register int k;
- {
- register char *np;
- #ifdef FKEYS
- extern char *keystrings[];
- #endif
-
- if(k < 0) k = CHARMASK(k); /* sign extended char */
- switch(k) {
- case CCHR('@'): np = "NUL"; break;
- case CCHR('I'): np = "TAB"; break;
- case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */
- case CCHR('M'): np = "RET"; break;
- case CCHR('['): np = "ESC"; break;
- case ' ': np = "SPC"; break; /* yuck again */
- case CCHR('?'): np = "DEL"; break;
- default:
- #ifdef FKEYS
- if(k >= KFIRST && k <= KLAST &&
- (np = keystrings[k - KFIRST]) != NULL)
- break;
- #endif
- if(k > CCHR('?')) {
- *cp++ = '0';
- *cp++ = ((k>>6)&7) + '0';
- *cp++ = ((k>>3)&7) + '0';
- *cp++ = (k&7) + '0';
- *cp = '\0';
- return cp;
- }
- if(k < ' ') {
- *cp++ = 'C';
- *cp++ = '-';
- k = CCHR(k);
- if(ISUPPER(k)) k = TOLOWER(k);
- }
- *cp++ = k;
- *cp = '\0';
- return cp;
- }
- (VOID) strcpy(cp, np);
- return cp + strlen(cp);
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/default/tty.c
- /*
- * Termcap/terminfo display driver
- *
- * Termcap is a terminal information database and routines to describe
- * terminals on most UNIX systems. Many other systems have adopted
- * this as a reasonable way to allow for widly varying and ever changing
- * varieties of terminal types. This should be used where practical.
- */
- /* Known problems:
- * If you have a terminal with no clear to end of screen and
- * memory of lines below the ones visible on the screen, display
- * will be wrong in some cases. I doubt that any such terminal
- * was ever made, but I thought everyone with delete line would
- * have clear to end of screen too...
- *
- * Code for terminals without clear to end of screen and/or clear
- * to end of line has not been extensivly tested.
- *
- * Cost calculations are very rough. Costs of insert/delete line
- * may be far from the truth. This is accentuated by display.c
- * not knowing about multi-line insert/delete.
- *
- * Using scrolling region vs insert/delete line should probably
- * be based on cost rather than the assuption that scrolling
- * region operations look better.
- */
- #include "def.h"
-
- #define BEL 0x07 /* BEL character. */
-
- extern int ttrow;
- extern int ttcol;
- extern int tttop;
- extern int ttbot;
- extern int tthue;
-
- int tceeol; /* Costs are set later */
- int tcinsl;
- int tcdell;
-
- static int insdel; /* Do we have both insert & delete line? */
-
- #ifdef NO_RESIZE
- static setttysize();
- #endif
-
- char *tgetstr();
- char *tgoto();
- int ttputc();
-
- #define TCAPSLEN 1024
-
- char tcapbuf[TCAPSLEN];
-
- /* PC, UP, and BC are used by termlib, so must be extern and have these
- * names unless you have a non-standard termlib.
- */
-
- int LI; /* standard # lines */
- char PC,
- *CM,
- *CE,
- *UP,
- *BC,
- *IM, /* insert mode */
- *IC, /* insert a single space */
- *EI, /* end insert mode */
- *DC,
- *AL, /* add line */
- *DL, /* del line */
- *pAL, /* parameterized add line */
- *pDL, /* parameterized delete line */
- *TI, /* term init -- start using cursor motion */
- *TE, /* term end --- end using cursor motion */
- *SO,
- *SE,
- *CD,
- *CS, /* set scroll region */
- *SF, /* forw index (used with scroll region) */
- *SR; /* back index (used with scroll region) */
- #ifdef XKEYS
- char *KS, *KE; /* enter keypad mode, exit keypad mode */
- #endif
- int SG; /* number of glitches, 0 for invisible, -1 for none */
- /* (yes virginia, there are terminals with invisible glitches) */
-
- /*
- * Initialize the terminal when the editor
- * gets started up.
- */
- static char tcbuf[1024];
-
- ttinit() {
- char *tv_stype;
- char *t, *p, *tgetstr();
- #ifndef gettermtype /* (avoid declaration if #define) */
- char *gettermtype(); /* system dependent function to determin terminal type */
- #endif
-
- if((tv_stype = gettermtype()) == NULL)
- panic("Could not determine terminal type");
- if((tgetent(tcbuf, tv_stype)) != 1) {
- (VOID) strcpy(tcbuf, "Unknown terminal type ");
- (VOID) strcat(tcbuf, tv_stype);
- panic(tcbuf);
- }
-
- p = tcapbuf;
- t = tgetstr("pc", &p);
- if(t) PC = *t;
-
- LI = tgetnum("li");
- CD = tgetstr("cd", &p);
- CM = tgetstr("cm", &p);
- CE = tgetstr("ce", &p);
- UP = tgetstr("up", &p);
- BC = tgetstr("bc", &p);
- IM = tgetstr("im", &p);
- IC = tgetstr("ic", &p);
- EI = tgetstr("ei", &p);
- DC = tgetstr("dc", &p);
- AL = tgetstr("al", &p);
- DL = tgetstr("dl", &p);
- pAL= tgetstr("AL", &p); /* parameterized insert and del. line */
- pDL= tgetstr("DL", &p);
- TI = tgetstr("ti", &p);
- TE = tgetstr("te", &p);
- SO = tgetstr("so", &p);
- SE = tgetstr("se", &p);
- CS = tgetstr("cs", &p); /* set scrolling region */
- SF = tgetstr("sf", &p);
- if(!SF || !*SF) { /* this is what GNU Emacs does */
- SF = tgetstr("do", &p);
- if(!SF || !*SF) {
- SF = tgetstr("nl", &p);
- if(!SF || !*SF) SF = "\n";
- }
- }
- SR = tgetstr("sr", &p);
- SG = tgetnum("sg"); /* standout glitch */
- #ifdef XKEYS
- KS = tgetstr("ks", &p); /* keypad start, keypad end */
- KE = tgetstr("ke", &p);
- #endif
-
- if(CM == NULL || UP == NULL)
- panic("This terminal is to stupid to run MicroGnuEmacs\n");
- ttresize(); /* set nrow & ncol */
-
- /* watch out for empty capabilities (sure to be wrong) */
- if (CE && !*CE) CE = NULL;
- if (CS && !*CS) CS = NULL;
- if (SR && !*SR) SR = NULL;
- if (AL && !*AL) AL = NULL;
- if (DL && !*DL) DL = NULL;
- if (pAL && !*pAL) pAL = NULL;
- if (pDL && !*pDL) pDL = NULL;
- if (CD && !*CD) CD = NULL;
-
- if(!CE) tceeol = ncol;
- else tceeol = charcost(CE);
-
- /* Estimate cost of inserting a line */
- if (CS && SR) tcinsl = charcost(CS)*2 + charcost(SR);
- else if (pAL) tcinsl = charcost(pAL);
- else if (AL) tcinsl = charcost(AL);
- else tcinsl = NROW * NCOL; /* make this cost high enough */
-
- /* Estimate cost of deleting a line */
- if (CS) tcdell = charcost(CS)*2 + charcost(SF);
- else if (pDL) tcdell = charcost(pDL);
- else if (DL) tcdell = charcost(DL);
- else tcdell = NROW * NCOL; /* make this cost high enough */
-
- /* Flag to indicate that we can both insert and delete lines */
- insdel = (AL || pAL) && (DL || pDL);
-
- if (p >= &tcapbuf[TCAPSLEN])
- panic("Terminal description too big!\n");
- if (TI && *TI) putpad(TI, 1); /* init the term */
- }
-
- /*
- * Clean up the terminal, in anticipation of
- * a return to the command interpreter. This is a no-op
- * on the ANSI display. On the SCALD display, it sets the
- * window back to half screen scrolling. Perhaps it should
- * query the display for the increment, and put it
- * back to what it was.
- */
- tttidy() {
- if (TE && *TE) putpad(TE, 1); /* set the term back to normal mode */
- #ifdef XKEYS
- ttykeymaptidy();
- #endif
- }
-
- /*
- * Move the cursor to the specified
- * origin 0 row and column position. Try to
- * optimize out extra moves; redisplay may
- * have left the cursor in the right
- * location last time!
- */
- ttmove(row, col) {
- char *tgoto();
-
- if (ttrow!=row || ttcol!=col) {
- putpad(tgoto(CM, col, row), 1);
- ttrow = row;
- ttcol = col;
- }
- }
-
- /*
- * Erase to end of line.
- */
- tteeol() {
- if(CE) putpad(CE, 1);
- else {
- register int i=ncol-ttcol;
- while(i--) ttputc(' ');
- ttrow = ttcol = HUGE;
- }
- }
-
- /*
- * Erase to end of page.
- */
- tteeop() {
- if(CD) putpad(CD, nrow - ttrow);
- else {
- putpad(CE, 1);
- if (insdel) ttdell(ttrow + 1, LI, LI - ttrow - 1);
- else { /* do it by hand */
- register int line;
- for (line = ttrow + 1; line <= LI; ++line) {
- ttmove(line, 0);
- tteeol();
- }
- }
- ttrow = ttcol = HUGE;
- }
- }
-
- /*
- * Make a noise.
- */
- ttbeep() {
- ttputc(BEL);
- ttflush();
- }
-
- /*
- * Insert nchunk blank line(s) onto the
- * screen, scrolling the last line on the
- * screen off the bottom. Use the scrolling
- * region if possible for a smoother display.
- * If no scrolling region, use a set
- * of insert and delete line sequences
- */
- ttinsl(row, bot, nchunk) {
- register int i, nl;
-
- if (row == bot) { /* Case of one line insert is */
- ttmove(row, 0); /* special */
- tteeol();
- return;
- }
- if (CS && SR) { /* Use scroll region and back index */
- nl = bot - row;
- ttwindow(row,bot);
- ttmove(row, 0);
- while (nchunk--) putpad(SR, nl);
- ttnowindow();
- return;
- } else if (insdel) {
- ttmove(1+bot-nchunk, 0);
- nl = nrow - ttrow;
- if (pDL) putpad(tgoto(pDL, 0, nchunk), nl);
- else for (i=0; i<nchunk; i++) /* For all lines in the chunk */
- putpad(DL, nl);
- ttmove(row, 0);
- nl = nrow - ttrow; /* ttmove() changes ttrow */
- if (pAL) putpad(tgoto(pAL, 0, nchunk), nl);
- else for (i=0; i<nchunk; i++) /* For all lines in the chunk */
- putpad(AL, nl);
- ttrow = HUGE;
- ttcol = HUGE;
- } else panic("ttinsl: Can't insert/delete line");
- }
-
- /*
- * Delete nchunk line(s) from "row", replacing the
- * bottom line on the screen with a blank line.
- * Unless we're using the scrolling region, this is
- * done with a crafty sequences of insert and delete
- * lines. The presence of the echo area makes a
- * boundry condition go away.
- */
- ttdell(row, bot, nchunk)
- {
- register int i, nl;
-
- if (row == bot) { /* One line special case */
- ttmove(row, 0);
- tteeol();
- return;
- }
- if (CS) { /* scrolling region */
- nl = bot - row;
- ttwindow(row, bot);
- ttmove(bot, 0);
- while (nchunk--) putpad(SF, nl);
- ttnowindow();
- }
- else if(insdel) {
- ttmove(row, 0); /* Else use insert/delete line */
- nl = nrow - ttrow;
- if (pDL) putpad(tgoto(pDL, 0, nchunk), nl);
- else for (i=0; i<nchunk; i++) /* For all lines in the chunk */
- putpad(DL, nl);
- ttmove(1+bot-nchunk,0);
- nl = nrow - ttrow; /* ttmove() changes ttrow */
- if (pAL) putpad(tgoto(pAL, 0, nchunk), nl);
- else for (i=0; i<nchunk; i++) /* For all lines in the chunk */
- putpad(AL, nl);
- ttrow = HUGE;
- ttcol = HUGE;
- } else panic("ttdell: Can't insert/delete line");
- }
-
- /*
- * This routine sets the scrolling window
- * on the display to go from line "top" to line
- * "bot" (origin 0, inclusive). The caller checks
- * for the pathalogical 1 line scroll window that
- * doesn't work right, and avoids it. The "ttrow"
- * and "ttcol" variables are set to a crazy value
- * to ensure that the next call to "ttmove" does
- * not turn into a no-op (the window adjustment
- * moves the cursor).
- *
- */
- ttwindow(top, bot)
- {
- if (CS && (tttop!=top || ttbot!=bot)) {
- putpad(tgoto(CS, bot, top), nrow - ttrow);
- ttrow = HUGE; /* Unknown. */
- ttcol = HUGE;
- tttop = top; /* Remember region. */
- ttbot = bot;
- }
- }
-
- /*
- * Switch to full screen scroll. This is
- * used by "spawn.c" just before is suspends the
- * editor, and by "display.c" when it is getting ready
- * to exit. This function gets to full screen scroll
- * by telling the terminal to set a scrolling regin
- * that is LI or nrow rows high, whichever is larger.
- * This behavior seems to work right on systems
- * where you can set your terminal size.
- */
- ttnowindow()
- {
- if (CS) {
- putpad(tgoto(CS, (nrow > LI ? nrow : LI) - 1, 0), nrow - ttrow);
- ttrow = HUGE; /* Unknown. */
- ttcol = HUGE;
- tttop = HUGE; /* No scroll region. */
- ttbot = HUGE;
- }
- }
-
- /*
- * Set the current writing color to the
- * specified color. Watch for color changes that are
- * not going to do anything (the color is already right)
- * and don't send anything to the display.
- * The rainbow version does this in putline.s on a
- * line by line basis, so don't bother sending
- * out the color shift.
- */
- ttcolor(color) register int color; {
- if (color != tthue) {
- if (color == CTEXT) { /* Normal video. */
- putpad(SE, 1);
- } else if (color == CMODE) { /* Reverse video. */
- putpad(SO, 1);
- }
- tthue = color; /* Save the color. */
- }
- }
-
- /*
- * This routine is called by the
- * "refresh the screen" command to try and resize
- * the display. The new size, which must be deadstopped
- * to not exceed the NROW and NCOL limits, it stored
- * back into "nrow" and "ncol". Display can always deal
- * with a screen NROW by NCOL. Look in "window.c" to
- * see how the caller deals with a change.
- */
- ttresize() {
- setttysize(); /* found in "ttyio.c", */
- /* ask OS for tty size */
- if (nrow < 1) /* Check limits. */
- nrow = 1;
- else if (nrow > NROW)
- nrow = NROW;
- if (ncol < 1)
- ncol = 1;
- else if (ncol > NCOL)
- ncol = NCOL;
- }
-
- #ifdef NO_RESIZE
- static setttysize() {
- nrow = tgetnum("li");
- ncol = tgetnum("co");
- }
- #endif
-
- static int cci;
-
- /*ARGSUSED*/
- static int /* fake char output for charcost() */
- fakec(c)
- char c;
- {
- cci++;
- }
-
- /* calculate the cost of doing string s */
- charcost (s) char *s; {
- cci = 0;
-
- tputs(s, nrow, fakec);
- return cci;
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/default/ttydef.h
- /*
- * Termcap terminal file, nothing special, just make it big
- * enough for windowing systems.
- */
-
- #define GOSLING /* Compile in fancy display. */
- /* #define MEMMAP */ /* Not memory mapped video. */
-
- #define NROW 66 /* (maximum) Rows. */
- #define NCOL 132 /* (maximum) Columns. */
- /* #define MOVE_STANDOUT /* don't move in standout mode */
- #define STANDOUT_GLITCH /* possible standout glitch */
- #define TERMCAP /* for possible use in ttyio.c */
-
- #define getkbd() (ttgetc())
-
- #ifndef XKEYS
- #define ttykeymapinit() {}
- #endif
-
- extern int tputs();
- #define putpad(str, num) tputs(str, num, ttputc)
-
- #define KFIRST K00
- #define KLAST K00
- SHAR_EOF
- cat << \SHAR_EOF > sys/default/ttykbd.c
- /*
- * Name: MG 2a
- * Termcap keyboard driver using key files
- * Created: 22-Nov-1987 Mic Kaczmarczik (mic@emx.cc.utexas.edu)
- */
-
- #include "def.h"
- #ifdef XKEYS
-
- /*
- * Get keyboard character. Very simple if you use keymaps and keys files.
- * Bob was right -- the old XKEYS code is not the right solution.
- * FKEYS code is not usefull other than to help debug FKEYS code in
- * extend.c.
- */
-
- #ifdef FKEYS
- char *keystrings[] = { NULL } ;
- #endif
-
- /*
- * Turn on function keys using KS, then load a keys file, if available.
- * The keys file is located in the same manner as the startup file is,
- * depending on what startupfile() does on your system.
- */
- extern int ttputc();
-
- ttykeymapinit()
- {
- extern char *KS;
- #ifndef NO_STARTUP
- char *cp, *startupfile();
-
- if (cp = gettermtype()) {
- if (((cp = startupfile(cp)) != NULL)
- && (load(cp) != TRUE))
- ewprintf("Error reading key initialization file");
- }
- #endif
- if (KS && *KS) /* turn on keypad */
- putpad(KS, 1);
- }
-
- /*
- * Clean up the keyboard -- called by tttidy()
- */
- ttykeymaptidy()
- {
- extern char *KE;
-
- if (KE && *KE)
- putpad(KE, 1); /* turn off keypad */
- }
-
- #endif
- SHAR_EOF
- cat << \SHAR_EOF > sys/default/varargs.h
- /* varargs.h for MicroGnuEmacs 2a. This one will work on systems that */
- /* the non-varargs version of mg 1 did. */
- /* based on the one I wrote for os9/68k . I did not look at the bsd code. */
-
- /* by Robert A. Larson */
-
- /* assumptions made about how arguments are passed: */
- /* arguments are stored in a block of memory with no padding between. */
- /* The first argument will have the lowest address */
-
- /* varargs is a "portable" way to write a routine that takes a variable */
- /* number of arguements. This implemination agrees with both the 4.2bsd*/
- /* and Sys V documentation of varargs. Note that just because varargs.h*/
- /* is used does not mean that it is used properly. */
-
- #define va_dcl unsigned va_alist;
-
- typedef char *va_list;
-
- #define va_start(pvar) ((pvar) = (char *)&va_alist)
-
- #define va_arg(pvar,type) (((pvar)+=sizeof(type)),*(((type *)(pvar)) - 1))
-
- #define va_end(pvar) /* va_end is simple */
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/cinfo.c
- /*
- * Character class tables.
- * Do it yourself character classification
- * macros, that understand the multinational character set,
- * and let me ask some questions the standard macros (in
- * ctype.h) don't let you ask.
- *
- * primos specific version
- */
- #include "def.h"
-
- /*
- * This table, indexed by a character drawn
- * from the 256 member character set, is used by my
- * own character type macros to answer questions about the
- * type of a character. It handles the full multinational
- * character set, and lets me ask some questions that the
- * standard "ctype" macros cannot ask.
- */
- char cinfo[256] = {
- _C, _C, _C, _C, /* 0x0X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C, /* 0x1X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- 0, _P, 0, 0, /* 0x2X */
- _W, _W, 0, _W,
- 0, 0, 0, 0,
- 0, 0, _P, 0,
- _D|_W, _D|_W, _D|_W, _D|_W, /* 0x3X */
- _D|_W, _D|_W, _D|_W, _D|_W,
- _D|_W, _D|_W, 0, 0,
- 0, 0, 0, _P,
- 0, _U|_W, _U|_W, _U|_W, /* 0x4X */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W, /* 0x5X */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, 0,
- 0, 0, 0, 0,
- 0, _L|_W, _L|_W, _L|_W, /* 0x6X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W, /* 0x7X */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, 0,
- 0, 0, 0, _C,
- _C, _C, _C, _C, /* 0x8X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C, /* 0x9X */
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- _C, _C, _C, _C,
- 0, _P, 0, 0, /* 0xAX */
- _W, _W, 0, _W,
- 0, 0, 0, 0,
- 0, 0, _P, 0,
- _D|_W, _D|_W, _D|_W, _D|_W, /* 0xbX */
- _D|_W, _D|_W, _D|_W, _D|_W,
- _D|_W, _D|_W, 0, 0,
- 0, 0, 0, _P,
- 0, _U|_W, _U|_W, _U|_W, /* 0xCX */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, _U|_W, /* 0xDX */
- _U|_W, _U|_W, _U|_W, _U|_W,
- _U|_W, _U|_W, _U|_W, 0,
- 0, 0, 0, 0,
- 0, _L|_W, _L|_W, _L|_W, /* 0xEX */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, _L|_W, /* 0xFX */
- _L|_W, _L|_W, _L|_W, _L|_W,
- _L|_W, _L|_W, _L|_W, 0,
- 0, 0, 0, _C,
- };
-
- /*
- * Find the name of a keystroke. Needs to be changed to handle 8-bit printing
- * characters and function keys better. Returns a pointer to the terminating
- * '\0'.
- */
-
- char *keyname(cp, k)
- register char *cp;
- register int k;
- {
- register char *np;
- #ifdef FKEYS
- extern char *keystrings[];
- #endif
-
- if(k < 0) k = CHARMASK(k); /* sign extended char */
- switch(k) {
- case CCHR('@'): np = "NUL"; break;
- case CCHR('I'): np = "TAB"; break;
- case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */
- case CCHR('M'): np = "RET"; break;
- case CCHR('['): np = "ESC"; break;
- case ' ': np = "SPC"; break; /* yuck again */
- case CCHR('?'): np = "DEL"; break;
- default:
- #ifdef FKEYS
- if(k >= KFIRST && k <= KLAST &&
- (np = keystrings[k - KFIRST]) != NULL)
- break;
- #endif
- if(k < CCHR('@')) {
- *cp++ = '0';
- *cp++ = ((k>>6)&7) + '0';
- *cp++ = ((k>>3)&7) + '0';
- *cp++ = (k&7) + '0';
- *cp = '\0';
- return cp;
- }
- if(k < ' ') {
- *cp++ = 'C';
- *cp++ = '-';
- k = CCHR(k);
- if(ISUPPER(k)) k = TOLOWER(k);
- }
- *cp++ = k;
- *cp = '\0';
- return cp;
- }
- (VOID) strcpy(cp, np);
- return cp + strlen(cp);
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/fileio.c
- /*
- * Prime fileio.c for MicroGnuEmacs by Robert A. Larson
- * system dependent file io routines
- *
- * Prime keeps the parity bit of every character set, as does mg 2a for primos.
- */
- #include <errd.ins.cc>
- #include <keys.ins.cc>
- #include "def.h"
-
- static FILE *ffp;
- char *index(), *rindex();
- fortran void cnam$$(), at$(), at$abs(), at$any(), at$hom(), clo$fu();
- fortran void gpath$(), dir$se(), cv$fdv();
- fortran long srsfx$();
-
- /*
- * Open a file for reading.
- */
- ffropen(fn)
- char *fn;
- {
- if ((ffp=fopen(fn, "r")) == NULL)
- return (FIOFNF);
- return (FIOSUC);
- }
-
- /*
- * Open a file for writing.
- * Return TRUE if all is well, and
- * FALSE on error (cannot create).
- */
- ffwopen(fn)
- char *fn;
- {
- short unit, type, sfu, code;
- struct {short len; char data[128];} fnb;
- register char *cp = &fnb.data[0];
- struct {short len; char data[32];} basename;
-
- /* most of this is to get a SAM rather than DAM file ... */
- (void) strcpy(fnb.data, fn);
- fnb.len = strlen(fnb.data);
- (void) srsfx$((short)(k$writ+k$getu+k$nsam), fnb, unit, type,
- (short)0, (short)0, basename, sfu, code);
- #ifdef OPEN_BUG
- if(code==0) {
- clo$fu(unit, code);
- fnb.data[fnb.len] = '\0';
- if((ffp=fopen(fnb.data, "w"))!=NULL) return FIOSUC;
- }
- ewprintf("Cannot open file for writing");
- return FIOERR;
- #else
- if (code != 0 || (ffp=fdopen(open("", -2, unit), "w")) == NULL) {
- ewprintf("Cannot open file for writing");
- if(code==0) clo$fu(unit, code);
- return (FIOERR);
- }
- return (FIOSUC);
- #endif
- }
-
- /*
- * Close a file.
- * Should look at the status.
- */
- ffclose()
- {
- fclose(ffp);
- return (FIOSUC);
- }
-
- /*
- * Write a buffer to the already
- * opened file. bp points to the
- * buffer. Return the status.
- * Check only at the newline and
- * end of buffer.
- */
- ffputbuf(bp)
- BUFFER *bp;
- {
- register char *cp;
- register char *cpend;
- register LINE *lp;
- register LINE *lpend;
-
- lpend = bp->b_linep;
- lp = lforw(lpend);
- do {
- cp = <ext(lp)[0]; /* begining of line */
- cpend = &cp[llength(lp)]; /* end of line */
- while(cp != cpend) {
- putc(*cp, ffp);
- cp++; /* putc may evalualte arguments more than once */
- }
- lp = lforw(lp);
- if(lp == lpend) break; /* no implied newline on last line */
- putc('\n', ffp);
- } while(!ferror(ffp));
- if(ferror(ffp)) {
- ewprintf("Write I/O error");
- return FIOERR;
- }
- return FIOSUC;
- }
-
- /*
- * Read a line from a file, and store the bytes
- * in the supplied buffer. Stop on end of file or end of
- * line. When FIOEOF is returned, there is a valid line
- * of data without the normally implied \n.
- */
- ffgetline(buf, nbuf, nbytes)
- register char *buf;
- register int nbuf;
- register int *nbytes;
- {
- register int c;
- register int i;
-
- i = 0;
- while((c = getc(ffp))!=EOF && c!='\n') {
- buf[i++] = c;
- if (i >= nbuf) return FIOLONG;
- }
- if (c == EOF && ferror(ffp) != FALSE) {
- ewprintf("File read error");
- return FIOERR;
- }
- *nbytes = i;
- return c==EOF ? FIOEOF : FIOSUC;
- }
-
- #ifndef NO_BACKUP
- /*
- * Rename the file "fname" into a backup copy.
- */
- fbackupfile(fname)
- char *fname;
- {
- struct {short len; char data[128];} back;
- struct {short len; char data[32];} ent;
- register char *cp;
- short code = 0, i;
-
- strcpy(back.data, fname);
- strcat(back.data, ".BAK");
- (void) delete(back.data);
- if((cp = rindex(back.data, '>'))!=NULL) {
- if(back.data[0]==('<') && index(back.data, '>')==cp) {
- strncpy(ent.data, back.data+1, ent.len = (cp - back.data) - 1);
- at$abs((short)k$setc, ent, (short)0, code);
- } else {
- back.len = (cp - back.data);
- if(index(back.data, '>') == cp)
- at$any((short)k$setc, back, code);
- else at$((short)k$setc, back, code);
- }
- if(code) return FALSE;
- cp++;
- /* cnam$$ needs word aligned strings */
- strncpy(ent.data, cp, back.len = strlen(cp));
- cp = ent.data;
- } else back.len = strlen(cp = back.data);
- cnam$$((char [])cp, (short)(back.len - 4), (char [])cp, back.len, code);
- at$hom(i);
- return code == 0;
- }
- #endif
-
- /*
- * The string "fn" is a file name. Prepend the directory name if
- * it's relative to the current directory.
- */
- #ifndef NO_DIR
- extern char *wdir;
- #endif
-
- char *adjustname(fn)
- register char *fn;
- {
- static char fnb[NFILEN];
- register char *cp = fnb;
- register char *cp2;
-
- #ifndef NO_DIR
- if((fn[0] == '*' && fn[1] == '>') || index(fn, '>')==NULL) {
- cp2 = wdir;
- while(*cp2) {
- *cp = *cp2;
- cp++;
- cp2++;
- }
- *cp++ = '>';
- if(fn[1]=='>') fn+=2;
- }
- #endif
- while(*fn) {
- *cp = ISUPPER(*fn) ? TOLOWER(*fn) : *fn;
- cp++;
- fn++;
- }
- *cp = '\0';
- return fnb;
- }
-
- #ifndef NO_STARTUP
- char *startupfile(suffix)
- char *suffix;
- {
- short code, len;
- static char startname[128];
- register char *cp;
-
- gpath$((short)k$inia, (short)-3, (char [])startname,
- (short)(128 - 5), len, code);
- if (code==0) {
- strcpy(startname + len, ">.MG");
- if(suffix) {
- startname[len+4] = '.';
- strcpy(startname + len + 5, suffix);
- }
- if(access(startname, 4)==0)
- return startname;
- }
- strcpy(startname, "MG*>.MG");
- if(suffix) {
- startname[7] = '.';
- strcpy(startname+8, suffix);
- }
- if(access(startname, 4)==0)
- return startname;
- return (char *)NULL;
- }
- #endif
-
- /* compare file names */
- fncmp(fn1, fn2)
- register char *fn1, *fn2;
- {
- /* ignore disk name if on one but not the other */
- if(*fn1 != *fn2) {
- if(*fn1 == '<') {
- fn1 = index(fn1, '>');
- if(fn1 == NULL) return -1;
- fn1++;
- } else if(*fn2 == '<') {
- fn2 = index(fn2, '>');
- if(fn2 == NULL) return -1;
- fn2++;
- } else return -1;
- } else fn1++, fn2++;
- /* compare ignoring case */
- while(*fn1) {
- if((*fn1 != *fn2) && (!ISUPPER(*fn1) || (TOLOWER(*fn1) == *fn2))
- && (!ISUPPER(*fn2) || (TOLOWER(*fn2) == *fn1)))
- return -1;
- fn1++;
- fn2++;
- }
- return *fn2;
- }
-
- #ifndef NO_DIRED
- #include "kbd.h"
-
- BUFFER *dired_(dirname)
- char *dirname;
- {
- register BUFFER *bp;
- LINE *lp, *blp;
- BUFFER *findbuffer();
- short dirunit, j, code, type, init, counts[4], i, nent;
- struct {short len; char dat[128];} dir;
- struct ent {short len; char dat[32];} base;
- static struct ent wild[1] = {{2, {'@','@'}}};
- static struct {
- short vers;
- struct ent *wp;
- short count;
- struct {unsigned dirs:1, seg_dirs:1, files:1, acats:1, rbf:1, spare:11;} desired;
- long mb, ma, bb, ba, cb, ca, ab, aa;
- } sel = {
- 1,
- &wild[0],
- 1,
- {1, 1, 1, 0, 0, 0},
- 0, 0, 0, 0, 0, 0, 0, 0,
- }, *s = &sel;
- #define MAXSE 16
- struct {
- struct {unsigned type:8, length:8;} ecw;
- struct ent name;
- struct {unsigned spare:5, odel:1, owrite:1, oread:1, delp:1,
- spare2:4, nodel:1, nowrite:1, noread:1;} prot;
- struct {unsigned lrat:1, dumped:1, dos:1, spec:1, rwl: 2,
- spare:2, type:8;} info;
- long dtm;
- short nondefault, logical_type, trunc;
- long dtb, dtc, dta;
- } ret[MAXSE], *r = &ret[0];
- static char *types[] = {"SAM", "DAM", "SEGSAM", "SEGDAM", "UFD",
- "ACAT", "CAM"};
- static char *rwlock[] = {"sys", "excl", "updt", "none"};
-
- if((dirname = adjustname(dirname)) == NULL) {
- ewprintf("Bad directory name");
- return NULL;
- }
- (void) strncpy(dir.dat, dirname, dir.len = strlen(dirname));
- if(dir.dat[dir.len-1]=='>') dir.len--;
- else strcat(dirname, ">");
- if((bp = findbuffer(dirname)) == NULL) {
- ewprintf("Could not create directory buffer");
- return NULL;
- }
- if(bclear(bp) != TRUE) return NULL;
- (void) srsfx$((short)(k$read+k$getu), dir, dirunit, type,
- (short)0, (short)0, base, j, code);
- if(code!=0) {
- ewprintf("Could not open directory '%s'", dirname);
- return NULL;
- }
- if(type<2 || type > 4) {
- clo$fu(dirunit, code);
- ewprintf("Not a directory '%s'", dirname);
- return NULL;
- }
- for(init = 0x8000; ; init = 0) {
- dir$se(dirunit, type, init, s, r, (short)MAXSE,
- (short)((sizeof ret[0])/2), nent, (short [])counts, (short)4, code);
- if(code!=0 && (code!=e$eof || nent==0)) break;
- for(i=0; i < nent; i++) {
- cv$fdv(ret[i].dtm, j, base);
- for(j=0; j<ret[i].name.len; j++)
- if(ISUPPER(ret[i].name.dat[j]))
- ret[i].name.dat[j] = TOLOWER(ret[i].name.dat[j]);
- #define D_FILEPOS 36
- if((lp = lalloc(D_FILEPOS + 1 + ret[i].name.len)) != NULL) {
- sprintf(lp->l_text, " %-6s %-4s %.18s %.*s",
- types[ret[i].info.type], rwlock[ret[i].info.rwl],
- base.dat, ret[i].name.len, ret[i].name.dat);
- llength(lp)--;
- for(blp=bp->b_linep->l_fp; blp!=bp->b_linep; blp=blp->l_fp) {
- j = strncmp(ret[i].name.dat, &blp->l_text[D_FILEPOS],
- ret[i].name.len);
- if(j < 0 || (j==0 && ret[i].name.len <=
- llength(blp)-D_FILEPOS)) break;
- }
- lp->l_fp = blp;
- lp->l_bp = blp->l_bp;
- blp->l_bp = lp;
- lp->l_bp->l_fp = lp;
- } else {
- clo$fu(dirunit, code);
- return NULL;
- }
- }
- }
- if(code!=e$eof) ewprintf("Directory read error %d", code);
- clo$fu(dirunit, code);
- bp->b_dotp = lforw(bp->b_linep);
- bp->b_doto = 0;
- bp->b_markp = NULL;
- strncpy(bp->b_fname, dirname, NFILEN);
- if((bp->b_modes[0] = name_mode("dired")) == NULL) {
- bp->b_modes[0] = &map_table[0];
- ewprintf("Could not find mode dired");
- return NULL;
- }
- bp->b_nmodes = 0;
- return bp;
- }
-
- d_makename(lp, fn)
- register LINE *lp;
- register char *fn;
- {
- register char *cp;
-
- if(llength(lp) <= D_FILEPOS) return ABORT;
- (VOID) strcpy(fn, curbp->b_fname);
- cp = fn + strlen(fn);
- bcopy(&lp->l_text[D_FILEPOS], cp, llength(lp) - D_FILEPOS);
- cp[llength(lp) - D_FILEPOS] = '\0';
- return strncmp(&lp->l_text[2], "UFD", 3)==0 ||
- strncmp(&lp->l_text[2], "SEG", 3)==0;
- }
-
- rename(old, new)
- char *old, *new;
- {
- struct {short len; char dat[128];} f;
- struct {short len; char dat[32];} oldent;
- char *cp;
- short code;
-
- old = adjustname(old);
- cp = rindex(old, '>');
- strncpy(f.dat, old, f.len = cp - old);
- at$((short)k$setc, f, code);
- if(code!=0) return -1;
- cp++;
- strncpy(oldent.dat, cp, oldent.len = strlen(cp));
- strncpy(f.dat, new, f.len = strlen(new));
- cnam$$((char [])oldent.dat, oldent.len, (char [])f.dat, f.len, code);
- if(code!=0) {
- at$hom(code);
- return -1;
- }
- at$hom(code);
- return 0;
- }
- #endif
-
- #ifndef NO_DIR
- char *getwd(cwd)
- char *cwd;
- {
- char homedir[128]; /* cwd may not be word alligned */
- short len, code;
- register char *cp1, *cp2;
-
- gpath$((short)k$homa, (short)-2, (char [])homedir, (short)128, len, code);
- if(code!=0) return NULL;
- cp1 = cwd;
- cp2 = homedir;
- while(len--) {
- *cp1 = ISUPPER(*cp2) ? TOLOWER(*cp2) : *cp2;
- cp1++;
- cp2++;
- }
- *cp1 = '\0';
- return cwd;
- }
- #endif
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/make.cpl
- /* make for micrognuemacs on primos
- /* by Robert A. Larson
- &args como:-como; ph:-ph; v64v: -64v;
- &if ^ [null %como%] &then como make.como
- &if ^ [null %ph%] &then &do
- chap idle
- &end
- &do f &list *>sys>prime>sysdef.h *>sys>default>ttydef.h *>sys>default>chrdef.h
- &if ^ [exists [entryname %f%]] &then copy %f% -rpt
- &else &if [attrib [entryname %f%] -dtm] < [attrib %f% -dtm] ~
- &then copy %f% -nq -rpt
- &end
- &set_var w := [attrib def.h -dtm]
- &if %w% < [attrib sysdef.h -dtm] &then &set_var w := [attrib sysdef.h -dtm]
- &if %w% < [attrib ttydef.h -dtm] &then &set_var w := [attrib ttydef.h -dtm]
- &if %w% < [attrib chrdef.h -dtm] &then &set_var w := [attrib chrdef.h -dtm]
- &if [null %v64v%] &then &do
- &if %w% < [attrib *>sys>prime>mg.options.c -dtm] ~
- &then &set_var w := [attrib *>sys>prime>mg.options.c -dtm]
- &set_var binext := .bin
- &end
- &else &do
- &if %w% < [attrib *>sys>prime>mg.64v.options.c -dtm] ~
- &then &set_var w := [attrib *>sys>prime>mg.64v.options.c -dtm]
- &set_var binext := .64v.bin
- &set_var m := ^ [exists stackptr$.64v.bin]
- &if ^ %m% &then &do
- &set_var bw := [attrib stackptr$.64v.bin -dtm]
- &set_var m := [attrib *>sys>prime>stackptr$.pma -dtm] > %bw% | %w% > %bw%
- &end
- &if %m% &then pma *>sys>prime>stackptr$.pma -list no -bin stackptr$.64v.bin
- &end
- &s dir := *
- &do f &list basic.c buffer.c dir.c dired.c display.c echo.c extend.c file.c ~
- help.c kbd.c keymap.c line.c macro.c main.c match.c modes.c paragraph.c ~
- random.c region.c search.c version.c window.c word.c
- &call compile
- &end
- &s dir := *>sys>prime
- &do f &list cinfo.c fileio.c spawn.c ttyio.c
- &call compile
- &end
- &s dir := *>sys>default
- &do f &list tty.c
- &call compile
- &end
- &s dir := *>termlib
- &do f &list fgetlr.c tgetent.c tgetflag.c tgetnum.c tgetstr.c tgoto.c tputs.c
- &call compile
- &end
- date
- time
- &set_var u := 0
- &data bind
- version mg 2a
- no_wildcard
- no_iteration
- li ccmain
- &do f &items [wild @%binext% -single u]
- lo %f%
- &end
- li c_lib
- li
- dynt -all
- rdc
- &if [null %v64v%] &then &do
- map mg.map
- file mg.run
- &end
- &else &do
- map mg.64v.map
- file mg.64v.run
- &end
- &end
- date
- time
- &if ^ [null %como%] &then como -end
- &return
-
- &routine compile
- &set_var b := [before %f% '.']%binext%
- &set_var f := %dir%>%f%
- &set_var m := ^ [exists %b%]
- &if ^ %m% &then &do /* avoid attrib on non-existant file
- &set_var bw := [attrib %b% -dtm]
- &set_var m := [attrib %f% -dtm] > %bw% | %w% > %bw%
- &end
- &if %m% &then &do
- type %f%
- date
- &if [null %v64v%] &then &do
- ci %f% -optionsfile *>sys>prime>mg.options.c -bin %b%
- &end
- &else &do
- cc %f% -optionsfile *>sys>prime>mg.64v.options.c -bin %b%
- &end
- &end
- &return
-
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/mg.64v.options.c
- /* options for Primos Mg by Robert A. Larson
-
- /* 64v mode version
- -64v
- -newfortran
- /* define to indicate primos
- -define __50SERIES
- /* get routine names in stack dump
- -store_owner_field
- /* tell it to run fast
- -standardintrinsics
- -optimize
- /* find varargs.h in *>sys>prime
- -include *>sys>prime
-
- /* real options
- -define NO_DIRED /* no 64v mode support in dired code
- -define PREFIXREGION
- -define NOTAB
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/mg.options.c
- /* options for Prime MicroGnuEmacs by Robert A. Larson
-
- -32ix
- /* get routine names in stack dump
- -store_owner_field
- /* tell it to run fast
- -standardintrinsics
- -optimize 1
- /* -pbstring was broken, and either got fixed or the other changes...
- -pbstring
- /* find varargs.h in *>sys>prime
- -include *>sys>prime
-
- /* real options
- -define PREFIXREGION
- -define NOTAB
-
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/readme
-
- MicroGnuEmacs 2a for primos
-
- This version has only been tested under primos 21.0 (.0, .1, .2s) in
- 32ix mode. The dired code does not run in 64v mode. (pl1 type ptr
- options(short) is a pain to simulate in 64v mode C.) The pre-rev 21
- code should work, but ^p, ^j, and a true meta key will be unusable.
-
- One major problem has been descovered: mg will always fail if it is
- already in memory. (access violations, illegal segno, etc.) This is a
- bug that has been reported to prime. I recomend aliasing mg to remepf
- mg;mg . (Further oddity: sometime remepf gets access violations!) To
- get your line back to a normal mode after this has happended, set your
- terminal's parity to mark and type "set_async -pro tty -echo -xoff"
- followed by a linefeed.
-
- Some pre-21 verisons of the C library had a bug in open(), there is
- code that can be included with a #define in fileio.c to avoid this
- problem. The -pbstring option is broken in some Prime C compiler
- versions, if you notice strange problems try recompiling with
- -lbstring.
-
- The rev 21 version will not run over primenet since the terminal line
- cannot be conditioned properly.
-
- Support for Prime's extended character set rather than a meta key
- should not be hard to add. (chrdef.h, cinfo.c, and ttyio.c are what
- would need changes.)
-
- Installation:
- copy *>sys>prime>make.cpl
- ph make -ph -como [add -64v if 64v mode is needed.]
- When phantom is finished:
- copy mg.run cmdnc0>== [32ix mode]
- or
- copy mg.64v.run cmdnc0>=.run [64v mode]
-
- Global variable .termcap (or .termcap$) should be set to the pathname
- of the termcap file if the default of mg*>termcap is inappropraite,
- and .terminal_type$ (or .term) should be set to your terminal type.
- (Global variables are manipulated with the primos commands
- define_gvar, set_var, and list_var.) The C library must be in your
- search rules. Your .mg initalization file should be located in your
- inital attach point, if you don't have one the one in mg* will be used
- if available. (Terminal specific files may also be used.) Prime
- emacs's termcap file does not work well with mg.
-
- On pre-rev 21 systems, due to primos limitations, neither ^P or ^J are
- usable input, and true meta keys are not supported. If ^P is
- accidentaly typed and you have break enabled, mg may be resumed with
- the start command (and the screen should be refreshed with the
- recenter command ^L).
-
- Primos programs other than mg and the C compiler do not understand tab
- characters, so use of notab mode is recomended.
-
- The options to make.cpl are:
-
- -ph chap -idle
- -como create como file make.como
- -64v create 64v rather than 32ix mode version
-
- Compilation options are in the files mg.options.c and
- mg.64v.options.c.
-
- Warnings to potential modifiers:
-
- The source to mg contains tab characters. These should be
- converted to spaces before printing or editing with an editor that
- does not cope with tabs.
-
- Make.cpl does not have all dependencies, if one of the new .h
- files is changed, delete all applicable .bin files.
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/spawn.c
- /*
- * prime spawn.c for micrognuemacs
- */
- #include "def.h"
-
- spawncli(f, n)
- {
- fortran void comlv$();
- ttcolor(CTEXT);
- ttnowindow();
- ttmove(nrow-1, 0);
- if (epresf != FALSE) {
- tteeol();
- epresf = FALSE;
- }
- ttclose();
- comlv$();
- sgarbf = TRUE; /* Force repaint. */
- ttopen();
- #ifndef NO_DIR
- (void) dirinit(); /* current directory may have changed */
- #endif
- return (TRUE);
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/stackptr$.pma
- * stackptr$.pma -- used by 64v varargs.h.ins.cc
- * 02/22/87 Robert Larson Name chagned to avoid potention conflict
-
- SEG
- SYML
- RLIT
- ENT STACKPTR$
-
- START EAXB SB%+4,*
- PRTN
-
- LINK
- STACKPTR$ ECB START
- END
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/sysdef.h
- /*
- * Prime specific definitions for MicroGnuEmacs 2a
- */
- #include <stdio.h>
-
- #define PCC /* "[]" gets an error. */
- #define KBLOCK 1024 /* Kill grow. */
- #define GOOD 0 /* Good exit status. */
- #define NO_RESIZE /* screen size is constant */
- #define MAXPATH 256
-
- /* typedefs for gnu version */
- typedef int RSIZE; /* Type for file/region sizes */
- typedef short KCHAR; /* Type for internal keystrokes */
-
- /*
- * Macros used by the buffer name making code.
- * Start at the end of the file name, scan to the left
- * until BDC1 (or BDC2, if defined) is reached. The buffer
- * name starts just to the right of that location, and
- * stops at end of string (or at the next BDC3 character,
- * if defined). BDC2 and BDC3 are mainly for VMS.
- */
- #define BDC1 '>'
-
- #define bcopy(from,to,len) if(1) {\
- register char *from_=from, *to_=to; register int len_=len;\
- while(len_--) *to_++ = *from_++;} else
-
- #define MALLOCROUND(m) (m+=7, m&=~7) /* round to 8 byte boundary */
-
- char *gettermtype(); /* #define fails because of static storage */
-
- #define unlink(f) delete(f)
- #define unlinkdir(f) delete(f)
-
- #ifdef DO_METAKEY
- #define METABIT 0400
- #endif
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/ttyio.c
- /*
- * sys>prime>ttyio.c by Robert A. Larson
- *
- * The functions in this file
- * negotiate with the operating system for
- * keyboard characters, and write characters to
- * the display in a barely buffered fashion.
- */
- #include "def.h"
-
- #define NOBUF 512 /* Output buffer size. */
-
- char obuf[NOBUF]; /* Output buffer. */
- short nobuf; /* characters in obuf */
- int nrow; /* Terminal size, rows. */
- int ncol; /* Terminal size, columns. */
- short ospeed; /* Terminal speed, for termlib.l */
-
- #ifndef PRE21
- /* use undocumented calls to set terminal modes */
- #define NSETTINGS 6
- fortran void as$lin(), as$get(), as$set();
- static short myline = 0;
- static short reset[NSETTINGS][2];
- #else
- /* do the best we can without undocumented calls */
- fortran short duplx$();
- fortran void break$();
- short duplx;
- #endif
-
- /*
- * This function gets called once, to set up
- * the terminal channel.
- */
-
- ttopen()
- {
- #ifndef PRE21
- short code, vers, len, bad;
- static short settings[NSETTINGS][2] = {
- {1, 0}, /* no echo */
- {2, 0}, /* don't echo line feed for cr */
- {3, 0}, /* disable ^S/^Q processing */
- {11, 0}, /* parity: none */
- {12, 3}, /* character length: 8 */
- {15, 1}, /* tran protocol */
- };
- short plist[38][2];
- short *p;
- register int i;
-
- if(myline==0) {
- as$lin(myline, code);
- if(code!=0) panic("Can't get terminal line");
- /* do io to get terminal type before setting modes */
- (void) gettermtype();
- }
- p = &plist[0][0];
- as$get(myline, vers, p, len, code);
- if(code!=0) panic("Can't determine current settings");
- ospeed = plist[9-1][1];
- for(i=0; i < NSETTINGS; i++) {
- reset[i][0] = settings[i][0];
- reset[i][1] = plist[settings[i][0]-1][1];
- }
- p = &settings[0][0];
- as$set(myline, (short)0, p, (short)NSETTINGS, code, bad);
- if(code!=0) panic("Can't set terminal modes");
- #else
- (void) gettermtype();
- duplx = duplx$((short)-1);
- (void) duplx$((unsigned short)0140000);
- ospeed = 4; /* assume 9600 for debugging */
- #endif
- nobuf = 0;
- }
-
- /*
- * This function gets called just
- * before we go back home to the shell. Put all of
- * the terminal parameters back.
- */
- ttclose()
- {
- #ifndef PRE21
- short code, bad;
- short *p;
- #endif
-
- ttflush();
- #ifndef PRE21
- p = &reset[0][0];
- as$set(myline, (short)0, p, (short)NSETTINGS, code, bad);
- if(code!=0) {
- printf("Can't reset terminal modes: code: %d bad: %d\n",
- code, bad);
- exit(1);
- }
- #else
- (void) duplx$(duplx);
- #endif
- }
-
- /*
- * Write character to the display.
- * Characters are buffered up, to make things
- * a little bit more efficient.
- */
- ttputc(c)
- {
- if (nobuf >= NOBUF)
- ttflush();
- obuf[nobuf++] = c;
- }
-
- /*
- * Flush output.
- */
- ttflush()
- {
- fortran void tnoua();
-
- if (nobuf != 0) {
- tnoua((char [])obuf, nobuf);
- nobuf = 0;
- }
- }
-
- /*
- * Read character from terminal.
- * Parity bit is stripped, to be normal
- */
- ttgetc()
- {
- fortran void t1in();
- short c;
-
- t1in(c);
- #ifdef DO_METAKEY
- if(c&0200) c |= METABIT;
- #endif
- c |= 0200;
- #ifdef PRE21
- if(c=='\n') return '\r'; /* fix repping done by primos */
- #ifdef DO_METAKEY
- if(c==('\n'|METABIT)) return '\r'|METABIT;
- #endif
- #endif
- return c;
- }
-
- int typeahead()
- {
- fortran short tty$in();
-
- return tty$in() < 0;
- }
-
- panic(s) char *s; {
- fortran void tnoua(), tnou();
-
- ttclose();
- tnoua((char [])"Panic: ", (short)7);
- tnou((char [])s, (short)strlen(s));
- exit(1);
- }
-
- #ifndef NO_DPROMPT
- ttwait() {
- register short i = 20;
- fortran short tty$in();
- fortran void sleep$();
-
- while(i--) {
- if(tty$in()<0) return FALSE;
- sleep$((long)100);
- }
- return tty$in() >= 0;
- }
- #endif
-
- char *gettermtype()
- {
- register char *cp;
- char *gvget();
- static char termtype[64] = "";
-
- if(termtype[0]!='\0') return termtype;
- cp = gvget(".TERMINAL_TYPE$"); /* get terminal type */
- if(cp==NULL) cp = gvget(".TERM");
- if(cp != NULL) {
- strncpy(termtype, cp, 64);
- return termtype;
- }
- fputs("Terminal type? ", stdout);
- fgets(termtype, 64, stdin);
- putchar('\n');
- termtype[strlen(termtype)-1] = '\0'; /* chop off \n */
- return termtype;
- }
- SHAR_EOF
- cat << \SHAR_EOF > sys/prime/varargs.h.ins.cc
- /* varargs.h.ins.cc -- varargs for both 32ix and 64v mode C unser primos */
- /* 02/22/87 Robert Larson Cleanup (Variable name changes to avoid conflicts) */
-
- #ifdef __CI
- /* varargs.h for 32ix mode on a Prime 9955 */
- /* Modified from the Primix varargs.h by James M Synge. */
- typedef char *va_list;
-
- #define va_alist _va_arg1
- #define va_dcl char va_alist;
- #define va_start(list) list = ((va_list)(&_va_arg1))
- #define va_end(list)
-
- #define va_arg(list,mode) ((mode *)((list) += sizeof(mode)))[-1]
-
- #else
-
- typedef int **va_list;
- extern short *stackptr$();
-
- #define va_alist \
- /* first argument at SB%+45 */ \
- _v0,_v1,_v2,_v3,_v4,_v5,_v6,_v7,_v8,_v9,_v10, \
- _v11,_v12,_v13,_v14,_v15,_v16,_v17,_v18,_v19,_v20, \
- _v21,_v22,_v23,_v24,_v25,_v26,_v27,_v28,_v29,_v30, \
- _v31,_v32,_v33,_v34,_v35,_v36,_v37,_v38,_v39,_v40, \
- _v41,_v42,_v43,_v44,_v45,_v46,_v47,_v48,_v49,_v50, \
- _v51,_v52,_v53,_v54,_v55,_v56,_v57,_v58,_v59,_v60, \
- _v61,_v62,_v63,_v64,_v65,_v66,_v67,_v68,_v69
-
- #define va_dcl int *_v0;
- #define va_start(list) list = ((va_list)(stackptr$() + 042))
- #define va_end(list)
- #define va_arg(list, mode) ( (sizeof(mode) == sizeof(char *)) ? \
- ((**(mode **)((list)++))) : \
- ((mode) (**((list)++))) )
- #endif
- SHAR_EOF
- # End of shell archive
- exit 0
- -------
-