home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-28 | 61.7 KB | 2,560 lines |
- Newsgroups: comp.editors
- Path: sparky!uunet!paladin.american.edu!darwin.sura.net!Sirius.dfn.de!math.fu-berlin.de!wolff
- From: wolff@inf.fu-berlin.de (Thomas Wolff)
- Subject: Editor mined (2/4)
- Message-ID: <52I57ND@math.fu-berlin.de>
- Sender: news@math.fu-berlin.de (Math Department)
- Organization: Free University of Berlin, Germany
- Date: Tue, 28 Jul 1992 15:03:16 GMT
- Lines: 2549
-
- #! /bin/sh
- : This is a sharchive -- extract the files by running through sh
-
- echo ---------------------- extracting mined1.c -----------------
- sed 's/^,//' << \EOSED > mined1.c
- ,/* ================================================================== *
- , * Editor mined *
- , * Part 1 *
- , * for documentation see mined.doc *
- , * ================================================================== */
- ,
- ,#include "mined.h"
- ,
- ,/* #define DEBUG */
- ,
- ,/* ================================================================== *
- , * Definitions specific for mined1.c *
- , * ================================================================== */
- ,
- ,#ifdef unix
- ,#define helpcommand "man mined"
- ,#define printcommand "lpr %s"
- ,#endif
- ,#ifdef vms
- ,#define helpcommand "help mined"
- ,#define printcommand "print %s"
- ,#endif
- ,#ifdef msdos
- ,#define helpcommand "more < \\mined\\mined.hlp"
- ,/* #define helpcommand "list \\Dienste\\mined\\mined.hlp" */
- ,#define printcommand "copy %s prn:"
- ,#endif
- ,
- ,/* ================================================================== *
- , * Data section *
- , * ================================================================== */
- ,
- ,extern int (* key_map [256]) ();
- ,extern int (* pc_key_map [256]) ();
- ,
- ,LINE * header; /* Head of line list */
- ,LINE * tail; /* Last line in line list */
- ,LINE * cur_line; /* Current line in use */
- ,LINE * top_line; /* First line of screen */
- ,LINE * bot_line; /* Last line of screen */
- ,char * cur_text; /* Current char on current line in use */
- ,int last_y; /* Last y of screen. Usually SCREENMAX */
- ,int x = 0, y = 0; /* x, y coordinates on screen */
- ,
- ,short YMAX, XMAX;
- ,char screen [screen_BUFL]; /* I/O buffer for "writes" and "reads" */
- ,int nlines; /* Number of lines in file */
- ,FLAG modified = FALSE; /* Set when file is modified */
- ,FLAG viewonly = FALSE; /* Set when view only mode is selected */
- ,FLAG overwriteOK = FALSE; /* Set if current file is OK for overwrite */
- ,FLAG writable; /* Set if file cannot be written */
- ,FLAG loading = TRUE; /* Loading a file? Init TRUE for error handling */
- ,FLAG quit = FALSE; /* Set when quit character is typed */
- ,FLAG intr = FALSE; /* Set when intr character is typed */
- ,FLAG winchg = FALSE; /* Set when window size has changed */
- ,FLAG isscreenmode = FALSE; /* Set when screen mode is on */
- ,FLAG stat_visible; /* Set if status_line is visible */
- ,FLAG pagewrapped = FALSE; /* Did output on the bottom line wrap and scroll? */
- ,FLAG waitingforinput = FALSE; /* Set while waiting for the next command key */
- ,FLAG rpipe = FALSE; /* Set if file should be read from stdin */
- ,FLAG wpipe = FALSE; /* Set if file should be written to stdout */
- ,FLAG multiexit = FALSE; /* Should exit command go to next file? */
- ,long chars_saved; /* Nr of chars in buffer */
- ,int input_fd = STD_IN; /* File descriptors for terminal dialog */
- ,int output_fd = STD_ERR;
- ,int out_count = 0; /* Index in output buffer */
- ,char file_name [maxLINE_LEN]; /* Name of file in use */
- ,char text_buffer [MAX_CHARS]; /* for get_line, modifications, build_string */
- ,char blank_line [maxLINE_LEN]; /* Line filled with spaces, in case terminal cannot clear line */
- ,int hop_flag = 0; /* Counter for the HOP function */
- ,#ifdef msdos
- ,char SHIFT_MARK = 175; /* Char indicating that line continues */
- ,#else
- ,char SHIFT_MARK = '╗'; /* Char indicating that line continues */
- ,#endif
- ,char SHIFT_BEG = '\0'; /* Char indicating that line continues left */
- ,char TABchar = ' '; /* Char to be shown in place of tab chars */
- ,char RET_MARK = '\0'; /* Char indicating end of line */
- ,char RET_BLANK = '\0'; /* Char to fill the end of line with */
- ,char RET_BLANK2 = '\0'; /* Char to fill last position of line with */
- ,#ifdef vms
- ,int fprot = 0; /* To be used for all file creatings */
- ,#else
- ,int fprot = 0644; /* To be used for all file creatings */
- ,#endif
- ,int panic_level = 0; /* To adjust error handling to situation */
- ,int fnami; /* Parameter index of current file name */
- ,int fnami_min, fnami_max, fnami_cnt;
- ,char * (* fnamv) [];
- ,/*
- , * Yank variables.
- , */
- ,FLAG yank_status = NOT_VALID; /* Status of yank_file */
- ,char * temp_dir;
- ,char yank_file [maxLINE_LEN];
- ,char yankie_file [maxLINE_LEN];
- ,char panic_file [maxLINE_LEN];
- ,
- ,/* ================================================================== *
- , * Output *
- , * ================================================================== */
- ,
- ,#ifdef msdos
- ,#define iscontrol(c) (((c) == '\177') || ((u_char) c < (u_char) ' '))
- ,#else
- ,#define iscontrol(c) (((c) == '\177') || ((u_char) ((c) & '\177') < (u_char) ' '))
- ,#endif
- ,#define controlchar(c) (((c) == '\177') ? '?' : (c) + '@')
- ,
- ,/*
- , * Flush the I/O buffer on filedescriptor fd.
- ,flush () is flush_buffer (output_fd)
- , */
- ,flush_buffer (fd)
- , int fd;
- ,{
- , if (out_count <= 0) /* There is nothing to flush */
- , return FINE;
- ,#ifdef conio
- , if (fd == output_fd) {
- , cputs (screen);
- , }
- , else
- ,#endif
- , if (write (fd, screen, out_count) != out_count) {
- , bad_write (fd);
- , return ERRORS;
- , }
- , clear_buffer (); /* Empty buffer: out_count = 0; */
- , return FINE;
- ,}
- ,
- ,/*
- , * Bad_write () is called when a write failed. Notify the user.
- , */
- ,bad_write (fd)
- , int fd;
- ,{
- , if (fd == output_fd) { /* Cannot write to terminal? */
- , raw_mode (OFF);
- , panicio ("Write error on terminal", NIL_PTR);
- , }
- ,
- , clear_buffer (); /* out_count = 0; */
- , ring_bell ();
- , error ("Write aborted (File incomplete): ", serror ());
- ,}
- ,
- ,/*
- , * Write_char does a buffered output.
- ,putchar (c) is writechar (output_fd, (c))
- , */
- ,writechar (fd, c)
- , int fd;
- , char c;
- ,{
- , if (c == '\n') if (fd == output_fd) {
- , writechar (fd, '\015');
- , }
- , screen [out_count ++] = c;
- , if (out_count == screen_BUFL) /* Flush on screen_BUFL chars */
- , return flush_buffer (fd);
- ,#ifdef DEBUG
- , if (fd == output_fd) flush ();
- ,#endif
- , return FINE;
- ,}
- ,
- ,/*
- , * Writestring writes the given string on the given filedescriptor.
- , * (buffered via writechar via screen !)
- ,putstring (str) is writestring (output_fd, (str))
- , */
- ,writestring (fd, text)
- , register int fd;
- , register char * text;
- ,{
- , while (* text)
- , if (writechar (fd, * text ++) == ERRORS)
- , return ERRORS;
- , return FINE;
- ,}
- ,
- ,/*
- , * Print string on terminal, printing controls with ^.
- , */
- ,int lpos = 0;
- ,print_char (c, limit)
- , register u_char c;
- , register int limit;
- ,{
- , if (lpos == limit) {putchar (SHIFT_MARK); return ERRORS;}
- , lpos ++;
- , if (iscontrol (c)) {
- , if (putchar ('^') == ERRORS) return ERRORS;
- , if (lpos == limit) {putchar (SHIFT_MARK); return ERRORS;}
- , lpos ++;
- , return putchar (controlchar (c));
- , }
- , else return putchar (c);
- ,}
- ,print_string (text, limit)
- , register char * text;
- , register int limit;
- ,{
- , lpos = 0;
- , while (* text != '\0')
- , if (print_char (* text ++, limit) == ERRORS)
- , return ERRORS;
- , return FINE;
- ,}
- ,
- ,/* ================================================================== *
- , * Buffer oriented output *
- , * ================================================================== */
- ,/*
- , * Convert cnt to nearest tab position
- , */
- ,#define tab(cnt) (((cnt) + 8) & ~07)
- ,#define is_tab(c) ((c) == '\t')
- ,
- ,/*
- , * Put_line prints the given line on the standard output.
- , * If offset is not zero, printing will start at that x-coordinate.
- , * If the FLAG clear_line is TRUE, then the screen line will be cleared
- , * when the end of the line has been reached.
- ,line_print (line) is put_line (line, 0, TRUE)
- , * put_line is directly called only by S () and delete_text ()
- , */
- ,put_line (line, offset, clear_line)
- , LINE * line; /* Line to print */
- , int offset; /* Offset to start */
- , FLAG clear_line; /* Clear to eoln if TRUE */
- ,{
- , register char * textp = line->text;
- , register int count = get_shift (line->shift_count) * - SHIFT_SIZE;
- , int count_ini = count;
- , int tab_count; /* Used in tab expansion */
- ,
- ,/* Skip all chars as indicated by the offset and the shift_count field */
- , while (count < offset) {
- , if (is_tab (* textp ++))
- , count = tab (count);
- , else
- , count ++;
- , }
- ,
- , if (count == 0 && count_ini < 0 && SHIFT_BEG != '\0') {
- , putchar (SHIFT_BEG);
- , count ++;
- , if (! is_tab (* textp)) textp ++;
- , }
- ,
- , while (* textp != '\n' && count < XBREAK) {
- , if (is_tab (* textp)) { /* Expand tabs to spaces */
- , tab_count = tab (count);
- , while (count < XBREAK && count < tab_count) {
- , count ++;
- , putchar (TABchar);
- , }
- , textp ++;
- , }
- , else {
- , if (iscontrol (* textp)) {
- , reverse_on ();
- , putchar (controlchar (* textp));
- , reverse_off ();
- , textp ++;
- , }
- , else
- , putchar (* textp ++);
- , count ++;
- , }
- , }
- ,
- ,/* If line is longer than XBREAK chars, print the shift_mark */
- , if (count == XBREAK && * textp != '\n')
- , putchar (SHIFT_MARK);
- ,
- ,/* Mark end of line if so desired */
- , if (* textp == '\n' && RET_MARK != '\0') {
- , putchar (RET_MARK);
- , count ++;
- , if (RET_BLANK) {
- , while (count < XBREAK) {
- , putchar (RET_BLANK);
- , count ++;
- , }
- , if (RET_BLANK2) putchar (RET_BLANK2);
- , }
- , }
- ,
- ,/* Clear the rest of the line if clear_line is TRUE */
- , if (clear_line == TRUE) {
- , if (can_clear_eol == TRUE)
- , clear_eol ();
- , else {
- , while (count ++ <= XBREAK)
- , putchar (' ');
- , }
- , putchar ('\n');
- , }
- ,}
- ,
- ,/*
- , * Proceed returns the count'th line after `line'. When count is negative
- , * it returns the count'th line before `line'. When the next (previous)
- , * line is the tail (header) indicating EOF (tof) it stops.
- , */
- ,LINE *
- ,proceed (line, count)
- , register LINE * line;
- , register int count;
- ,{
- , if (count < 0)
- , while (count ++ < 0 && line != header)
- , line = line->prev;
- , else
- , while (count -- > 0 && line != tail)
- , line = line->next;
- , return line;
- ,}
- ,
- ,/*
- , * Reset assigns bot_line, top_line and cur_line according to `head_line'
- , * which must be the first line of the screen, and a y-coordinate,
- , * which will be the current y-coordinate (if it isn't larger than last_y)
- , */
- ,reset (head_line, screen_y)
- , LINE * head_line;
- , int screen_y;
- ,{
- , register LINE * line;
- ,
- , top_line = line = head_line;
- ,
- ,/* Search for bot_line (might be last line in file) */
- , for (last_y = 0; last_y < nlines - 1 && last_y < SCREENMAX
- , && line->next != tail; last_y ++)
- , line = line->next;
- ,
- , bot_line = line;
- , y = (screen_y > last_y) ? last_y : screen_y;
- ,
- ,/* Set cur_line according to the new y value */
- , cur_line = proceed (top_line, y);
- ,}
- ,
- ,/*
- , * Display () shows count + 1 lines on the terminal starting at the given
- , * coordinates. When the tail of the list is encountered it will fill the
- , * rest of the screen with blank_line's.
- , * When count is negative, a backwards print from `line' will be done.
- , */
- ,display (x_coord, y_coord, line, count)
- , int x_coord, y_coord;
- , register LINE * line;
- , register int count;
- ,{
- , set_cursor (x_coord, y_coord);
- ,
- ,/* Find new startline if count is negative */
- , if (count < 0) {
- , line = proceed (line, count);
- , count = - count;
- , }
- ,
- ,/* Print the lines */
- , while (line != tail && count -- >= 0) {
- , line_print (line);
- , line = line->next;
- , }
- ,
- ,/* Print the blank lines (if any) */
- , if (loading == FALSE) {
- , while (count -- >= 0) {
- , clear_eol ();
- , putchar ('\n');
- , }
- , }
- ,}
- ,
- ,/*
- , * Redraw the screen
- , */
- ,RD ()
- ,{
- , reverse_off ();
- , clear_screen ();
- ,
- ,/* Print first page */
- , display (0, 0, top_line, last_y);
- ,
- ,/* Clear last line */
- , set_cursor (0, YMAX);
- , clear_eol ();
- , move_y (y);
- , if (stat_visible == TRUE) rd_bottom_line ();
- ,}
- ,
- ,/* ================================================================== *
- , * Terminal Dialog *
- , * ================================================================== */
- ,
- ,/*
- , * promptyn reads in a 'y' or 'n' character.
- , */
- ,u_char
- ,promptyn ()
- ,{
- , register u_char c;
- , while ((c = readchar ()) != 'y' && c != 'n' && c != '\033' && quit == FALSE) {
- , ring_bell ();
- , flush ();
- , }
- , if (c == '\033') quit = TRUE;
- , return c;
- ,}
- ,
- ,/*
- , * Adjust current window size after WINCH signal
- , */
- ,RDwin ()
- ,{
- , register LINE * current_line;
- ,
- , winchg = FALSE;
- , getwinsize ();
- ,
- , current_line = cur_line;
- , reset (top_line, y);
- ,/* move_y (find_y_w_o_RD (current_line)); */
- , move_address (cur_text, find_y_w_o_RD (current_line));
- , RD ();
- , flush ();
- ,}
- ,
- ,/*
- , * In case of a QUIT signal, swallow the dummy char generated by catchquit ()
- , * called by re_search () and change ()
- , */
- ,swallow_dummy_quit_char ()
- ,{
- ,#ifdef UNUSED
- , readchar (); /* Swallow away a quit character delivered by QUIT */
- ,/* Not needed because this character is ignored by being the CANCEL command */
- ,#endif UNUSED
- ,}
- ,
- ,/*
- , * Readchar () reads one character from the terminal.
- , * There are problems due to interruption of the read operation by signals
- , * (QUIT, WINCH). The waitingforinput flag is only a partial solution.
- , * Unix doesn't provide sufficient facilities to handle these situations
- , * neatly and properly. Moreover, different Unix versions yield different
- , * surprising effects. However, the use of select () could still be
- , * an improvement.
- , */
- ,readchar ()
- ,{
- , register u_char c;
- ,
- , waitingforinput = TRUE;
- ,/* if (winchg == TRUE) RDwin (); /* This is now done in __readchar () */
- , c = _readchar ();
- , waitingforinput = FALSE;
- , /* the modification if (quit == TRUE) c = QUITCHAR; (now in __readchar)
- , must not be placed after resetting the flag waitingforinput = FALSE; .
- , Otherwise a QUIT signal coming in just between these two would
- , discard the last valid character just taken up. */
- , return c;
- ,}
- ,
- ,/*-------------------------------------------------------------------------*/
- ,
- ,#ifndef msdos
- ,
- ,#ifdef msdos
- ,#ifndef single_pass_compilation
- ,/* This seems to conflict with the same declaration in minedmp.c when
- , compiled with Turbo-C. C is just too stupid a language.
- , Luckily, we don't need this part at all on MSDOS */
- ,extern struct {char * fk; int (* fp) ();} keycode [];
- ,#endif
- ,#else
- ,extern struct {char * fk; int (* fp) ();} keycode [];
- ,#endif
- ,#define MAXCODELEN 7 /* max. length of function key sequence to be detected,
- , depending on the keycode table */
- ,
- ,/*
- , * queue collects the keys of an Escape sequence typed in until the
- , * sequence can be detected or rejected.
- , * If the queue is not empty, queue [0] contains the character next
- , * to be delivered by _readchar () (it's not a ring buffer).
- , * The queue contents is always terminated by a '\0', so queue can also
- , * be taken as a character string.
- , */
- ,static u_char queue [MAXCODELEN + 1], * endp = queue;
- ,
- ,int
- ,q_empty ()
- ,{
- , return (endp == queue ? 1 : 0);
- ,}
- ,
- ,int
- ,q_notfull ()
- ,{
- , return (endp - queue == MAXCODELEN ? 0 : 1);
- ,}
- ,
- ,q_clear ()
- ,{
- , endp = queue;
- ,}
- ,
- ,int
- ,q_len ()
- ,{
- , return endp - queue;
- ,}
- ,
- ,q_put (c)
- , u_char c;
- ,/* queue must not be full prior to this call! */
- ,{
- , * endp = c;
- , * ++ endp = '\0';
- ,}
- ,
- ,u_char
- ,q_get ()
- ,{
- , u_char c;
- , register u_char * pd, * ps;
- ,
- , c = * queue; pd = queue; ps = pd + 1;
- , while (ps <= endp) * pd ++ = * ps ++;
- , if (endp > queue) endp --;
- , return c;
- ,}
- ,
- ,/*
- , * Look up key sequence in keycode table.
- , * findkey (str) >= 0: str == keycode [findkey (str)].fk
- , * == -1: str is prefix of some entry in keycode
- , * == -2: str is not contained in keycode
- , */
- ,int
- ,findkey (str)
- , char * str;
- ,{
- , static int lastmatch = 0; /* last index with string matching prefix */
- , register int i;
- ,
- , if (keycode [0].fk == NIL_PTR) return -2;
- , i = lastmatch;
- , do {
- , if (strncmp (str, keycode [i].fk, strlen (str)) == 0) {
- , lastmatch = i;
- , return (strlen (str) == strlen (keycode [i].fk) ? i : -1);
- , }
- , ++ i;
- , if (keycode [i].fk == NIL_PTR) i = 0;
- , } while (i != lastmatch);
- , return -2;
- ,}
- ,
- ,/*
- , * Is a character available within a specified number of milliseconds ?
- , */
- ,char_ready_within (msec)
- , int msec;
- ,{
- , return (q_len () > 0) || inputreadyafter (input_fd, msec);
- ,}
- ,
- ,#else ndef msdos
- ,
- ,char_ready_within (msec)
- , int msec;
- ,{
- , return 0;
- ,}
- ,
- ,#endif def msdos
- ,
- ,extern I ();
- ,int (* keyproc) () = I;
- ,
- ,extern grave ();
- ,extern circumflex ();
- ,extern acute ();
- ,extern diaeresis ();
- ,extern tilde ();
- ,extern angstrom ();
- ,
- ,/*
- , * Read a character from terminal, considering function keys and
- , * composing special character of an 8 bit character set.
- , * _readchar () takes the following actions:
- , * - function key sequences according to the table 'keycode' are
- , * transformed into a special controlling character which is
- , * assigned the function FUNKEY. Also the intended editor function,
- , * as taken from the table 'keycode', is saved in a variable for
- , * use by FUNKEY.
- , * - the prefix keys for diacritic and special characters are
- , * combined with the following key to make up the character.
- , */
- ,_readchar ()
- ,{
- , register u_char ch;
- , int res;
- ,
- ,#ifndef msdos
- , if (q_len () > 0) return q_get ();
- ,#endif
- , ch = __readchar ();
- ,#ifdef msdos
- , if (ch == '\000') {
- , ch = __readchar ();
- , keyproc = pc_key_map [ch];
- ,#ifdef DEBUG
- , if (keyproc == I) return ch;
- ,#endif
- , if ((keyproc == grave) || (keyproc == circumflex)
- , || (keyproc == acute) || (keyproc == diaeresis)
- , || (keyproc == tilde) || (keyproc == angstrom))
- , {ch = (* keyproc) (readchar ());
- , keyproc = I;
- , return ch;
- , }
- , else return FUNcmd /* index of FUNKEY */;
- , }
- ,#else
- , if (ch == '\033') {
- , /* q_clear (); */
- , q_put (ch);
- , while ((res = findkey (queue)) == -1 /* prefix of table entry */
- , && q_notfull ()
- , && inputreadyafter (input_fd, 300)
- , )
- , q_put (__readchar ());
- , if (quit == TRUE) return '\0';
- , else if (res < 0) /* key pattern not detected in keycode table */
- , /* {if (q_len () > 1) return 0;
- , else return ch;} */
- , return q_get () /* just deliver the typed characters */;
- , else {
- , q_clear ();
- , keyproc = keycode [res].fp;
- , if ((keyproc == grave) || (keyproc == circumflex)
- , || (keyproc == acute) || (keyproc == diaeresis)
- , || (keyproc == tilde) || (keyproc == angstrom))
- , {ch = (* keyproc) (readchar ());
- , keyproc = I;
- , return ch;
- , }
- , else return FUNcmd /* index of FUNKEY */;
- , }
- , }
- ,#endif
- , else
- , return ch;
- ,}
- ,
- ,/* ================================================================== *
- , * Status Line Dialog *
- , * ================================================================== */
- ,
- ,/*
- , * Show concatenation of s1 and s2 on the status line (bottom of screen)
- , * If revfl is TRUE, turn on reverse video on both strings. Set stat_visible
- , * only if bottom_line is visible.
- , * The return value is FINE except for get_string, where it is taken
- , * from the call to input ().
- ,status_line (str1, str2) is bottom_line (ON, (str1), (str2), NIL_PTR, FALSE)
- ,error (str1, str2) is bottom_line (ON, (str1), (str2), NIL_PTR, FALSE)
- ,get_string (str1, str2, fl) is bottom_line (ON, (str1), NIL_PTR, (str2), fl)
- ,clear_status () is bottom_line (OFF, NIL_PTR, NIL_PTR, NIL_PTR, FALSE)
- ,status_msg (str) is status_line (str, NIL_PTR)
- ,status_beg (str) is bottom_line (ON, (str), NIL_PTR, NIL_PTR, TRUE)
- , */
- ,FLAG lastrevfl;
- ,char * lastinbuf;
- ,FLAG input_active = FALSE;
- ,char status_buf [maxLINE_LEN];
- ,
- ,rd_bottom_line ()
- ,{
- , set_cursor (0, YMAX);
- , reverse_on ();
- , if (lastinbuf == NIL_PTR)
- , print_string (status_buf, XBREAK);
- , else {
- , print_string (status_buf, -1);
- , print_string (lastinbuf, -1);
- , }
- , if (! input_active) {
- , reverse_off ();
- , set_cursor (x, y); /* Set cursor back to old position */
- , }
- , flush (); /* Perform the actual screen output */
- ,}
- ,
- ,int
- ,bottom_line (revfl, s1, s2, inbuf, statfl)
- , FLAG revfl;
- , char * s1, * s2;
- , char * inbuf;
- , FLAG statfl;
- ,{
- , int ret = FINE;
- ,
- , if (inbuf != NIL_PTR) * inbuf = '\0';
- , lastrevfl = revfl;
- , lastinbuf = inbuf;
- ,
- , if (pagewrapped == TRUE) {
- , status_buf [0] = '\0';
- , RD ();
- , pagewrapped = FALSE;
- , }
- ,
- , build_string (status_buf, " %s%s ", unnull (s1), unnull (s2));
- , /* (s1 == NIL_PTR) ? "" : s1, (s2 == NIL_PTR) ? "" : s2); */
- ,
- , if (revfl == ON && stat_visible == TRUE) {
- , set_cursor (0, YMAX);
- , clear_eol ();
- , }
- , set_cursor (0, YMAX);
- , if (revfl == ON) { /* Print rev. start sequence */
- , reverse_on ();
- , stat_visible = TRUE;
- , }
- , else /* Used as clear_status () */
- , stat_visible = FALSE;
- ,
- , if (inbuf == NIL_PTR)
- , print_string (status_buf, XBREAK);
- , else {
- , print_string (status_buf, -1);
- , input_active = TRUE;
- , ret = input (inbuf, statfl);
- , input_active = FALSE;
- , }
- ,
- , /* Print normal video */
- , reverse_off ();
- , clear_eol ();
- ,
- , if (inbuf != NIL_PTR) {
- , set_cursor (0, YMAX);
- , }
- , else if (statfl == TRUE)
- , reverse_on ();
- , else
- , set_cursor (x, y); /* Set cursor back to old position */
- ,
- , flush (); /* Perform the actual screen output */
- , if (ret != FINE) clear_status ();
- , return ret;
- ,}
- ,
- ,/*
- , * Input () reads a string from the terminal.
- , * Return values:
- , * when QUIT character typed => ERRORS
- , * when empty input and clearfl == TRUE: NO_INPUT
- , * else: FINE
- , */
- ,input (inbuf, clearfl)
- , u_char * inbuf;
- , FLAG clearfl;
- ,{
- , register u_char * ptr;
- , register u_char c;
- ,
- , ptr = inbuf;
- , * ptr = '\0';
- , while (quit == FALSE) {
- , flush ();
- , if (lpos >= XBREAK) pagewrapped = TRUE;
- , switch (c = readchar ()) {
- , case '\b' : /* Erase previous char */
- , case '\177' /* DEL */ :
- , if (ptr > inbuf) {
- , ptr --;
- , reverse_off ();
- , if (iscontrol (* ptr)) {
- , putstring (" \b\b\b \b\b");
- , lpos = lpos - 2;
- , }
- , else {
- , putstring (" \b\b \b");
- , lpos = lpos - 1;
- , }
- , reverse_on ();
- , putstring (" \b");
- , * ptr = '\0';
- , }
- , else
- , ring_bell ();
- , break;
- , case QUITCHAR :
- , case '\033' :
- , quit = TRUE;
- , break;
- , case '\n' : /* End of input */
- , case '\015' :
- , /* If inbuf is empty clear status_line */
- , return (ptr == inbuf && clearfl == TRUE) ?
- , NO_INPUT : FINE;
- , default :
- , if (c == '\026' /* ^V */) c = readchar ();
- , if ((ptr - inbuf) < maxLINE_LEN) {
- , if ((c > '\0')) {
- , * ptr ++ = c;
- , * ptr = '\0';
- , print_char (c, -1);
- , putstring (" \b");
- , }
- , else
- , ring_bell ();
- , }
- , else
- , ring_bell ();
- , }
- , }
- , quit = FALSE;
- , return ERRORS;
- ,}
- ,
- ,/*
- , * Get_number () reads a number from the terminal.
- , * The last character typed in is returned.
- , * ERRORS is returned on a bad number or on interrupted input.
- , * The resulting number is put into the integer the arguments points to.
- , */
- ,get_number (message, firstdigit, result)
- , char * message;
- , char firstdigit;
- , int * result;
- ,{
- , register int index;
- , register int count;
- ,
- , status_beg (message);
- ,
- , if (firstdigit > '\0')
- , index = firstdigit;
- , else
- , index = readchar ();
- ,
- , if (index == QUITCHAR) quit = TRUE;
- , if (index == '\033') quit = TRUE;
- , if (quit == FALSE && (index < '0' || index > '9')) {
- , error ("Bad number", NIL_PTR);
- , return ERRORS;
- , }
- ,
- ,/* Convert input to a decimal number */
- , count = 0;
- , while (index >= '0' && index <= '9' && quit == FALSE) {
- , print_char (index, -1); flush ();
- , if (lpos >= XBREAK) pagewrapped = TRUE;
- , count *= 10;
- , count += index - '0';
- , index = readchar ();
- , if (index == QUITCHAR) quit = TRUE;
- , if (index == '\033') quit = TRUE;
- , }
- ,
- , clear_status ();
- , if (quit == TRUE) {
- , clear_status ();
- , return ERRORS;
- , }
- , * result = count;
- , return index;
- ,}
- ,
- ,/*
- , * get_digits () reads in a number. In contrast to get_number, it does no
- , * echoing, no messaging, and it does not require any digits at all.
- , * The last character typed in is returned.
- , * The resulting number is put into the integer the arguments points to.
- , */
- ,get_digits (result)
- , int * result;
- ,{
- , register int index;
- , register int count;
- ,
- , index = readchar ();
- , if (index == QUITCHAR) quit = TRUE;
- , * result = -1;
- ,/* Convert input to a decimal number */
- , count = 0;
- , while (index >= '0' && index <= '9' && quit == FALSE) {
- , count *= 10;
- , count += index - '0';
- , * result = count;
- , index = readchar ();
- , if (index == QUITCHAR) quit = TRUE;
- , }
- ,
- , if (quit == TRUE) {
- , return QUITCHAR;
- , }
- , return index;
- ,}
- ,
- ,/*
- , * Get_file () reads a filename from the terminal.
- , */
- ,int
- ,get_file (message, file)
- , char * message, * file;
- ,{
- , int ret = get_string (message, file, TRUE);
- ,#ifndef msdos
- , char * filei;
- , char file1 [maxLINE_LEN];
- ,
- , if (file [0] == '~' && file [1] == '/') {
- , filei = file; filei ++;
- , build_string (file1, "%s%s", unnull (getenv ("HOME")), filei);
- , build_string (file, file1);
- , }
- ,#endif
- , return ret;
- ,}
- ,
- ,/* ================================================================== *
- , * Text buffer routines *
- , * ================================================================== */
- ,
- ,/*
- , * Ask the user if he wants to save the file or not.
- , */
- ,ask_save ()
- ,{
- , register u_char c;
- ,
- , status_line (file_name [0] ? file_name : "[buffer]" ,
- , " has been modified. Save? (y/n)");
- , /* previously only basename (file_name) was printed */
- , c = promptyn ();
- , clear_status ();
- , if (c == 'y')
- , return WT ();
- , else if (c == 'n')
- , return FINE;
- , else {
- , quit = FALSE; /* abort character has been given */
- , return ERRORS;
- , }
- ,}
- ,
- ,/*
- , * Ask user if named file should be overwritten.
- , */
- ,FLAG
- ,checkoverwrite (name)
- ,char * name;
- ,{
- , u_char c;
- ,
- , if (access (name, 0 /* F_OK */) < 0) /* Cannot access file */
- , return TRUE; /* thus no danger of unwanted damage */
- ,
- , status_line (name [0] ? name : "[buffer]" ,
- , ": OK to overwrite? (y/n)");
- , /* previously only basename (name) was printed */
- , c = promptyn ();
- , clear_status ();
- , if (c == 'y')
- , return TRUE;
- , else if (c == 'n')
- , return FALSE;
- , else {
- ,/* quit = FALSE; /* abort character has been given */
- , return FALSE;
- , }
- ,}
- ,
- ,/*
- , * Attach new file name to buffer
- , */
- ,NN ()
- ,{
- , char file [maxLINE_LEN]; /* Buffer for new file name */
- , if (get_file ("Enter new file name:", file) == ERRORS)
- , return ERRORS;
- , overwriteOK = FALSE;
- , writable = TRUE;
- , modified = TRUE; /* cf. CHDI command */
- , copy_string (file_name, file); /* Save new file name */
- ,/* set_cursor (x, y); /* Set cursor back to old position */
- , clear_status ();
- ,}
- ,
- ,/*
- , * Write file in core to disc.
- , */
- ,/* Call graph for writing functions:
- , panic --\
- , > QUED --\
- , ESC q --/ > ask_save --\
- , ESC e ---> EDIT --/ \
- , ESC v ---> VIEW -/ \
- , ESC w -----------------------------> WT
- , ESC z -----------> SUSP ----------/
- , ESC ESC ---------> EXED ---------/
- ,*/
- ,long write_count /* number of chars written */;
- ,write_file (fd)
- , int fd;
- ,{
- , register LINE * line;
- ,
- , write_count = 0L;
- , clear_buffer (); /* out_count = 0; */
- , for (line = header->next; line != tail; line = line->next) {
- , if (line->shift_count & DUMMY) {
- , if (line->next == tail && line->text [0] == '\n')
- , continue;
- , }
- , if (writestring (fd, line->text) == ERRORS) {
- , write_count = -1L;
- , break;
- , }
- , write_count += (long) length_of (line->text);
- , }
- ,
- , if (write_count > 0L && flush_buffer (fd) == ERRORS)
- , write_count = -1L;
- ,
- , (void) close (fd);
- ,}
- ,
- ,WT ()
- ,{
- , char file [maxLINE_LEN]; /* Buffer for new file name */
- , int fd; /* Filedescriptor of file */
- , int ret;
- ,
- , if (wpipe) {
- , fd = STD_OUT;
- , status_line ("Writing ", "to standard output");
- , wpipe = FALSE; /* no further write to same stream possible */
- , }
- , else {
- , if (modified == FALSE) {
- , status_msg ("Write not necessary.");
- , return FINE;
- , }
- ,
- , /* Check if file_name is valid and if file can be written */
- , if (file_name [0] == '\0' || writable == FALSE) {
- , overwriteOK = FALSE;
- , if ((ret = get_file ("Enter file name:", file)) != FINE)
- , return ret;
- , copy_string (file_name, file); /* Save file name */
- , }
- , if (overwriteOK == FALSE) {
- , if (checkoverwrite (file_name) == TRUE)
- , overwriteOK = TRUE;
- , else { if (quit == FALSE)
- , writable = FALSE;
- , return ERRORS;
- , }
- , }
- , if ((fd = creat (file_name, fprot)) < 0) { /* Empty file */
- , error ("Cannot create or write: " /*, file_name */, serror ());
- , writable = FALSE;
- , return ERRORS;
- , }
- , else
- , writable = TRUE;
- ,
- , status_line ("Writing ", file_name);
- , }
- ,
- , write_file (fd);
- ,
- , if (write_count == -1L)
- , return ERRORS;
- ,
- , modified = FALSE;
- , rpipe = FALSE; /* File name is now assigned */
- ,
- ,/* Display how many chars (and lines) were written */
- , fstatus ("Wrote", write_count);
- , return FINE;
- ,}
- ,
- ,panic_write ()
- ,{
- , int fd;
- , fd = creat (panic_file, fprot);
- , write_file (fd);
- , if (write_count == -1L)
- , return ERRORS;
- , else return FINE;
- ,}
- ,
- ,/*
- , * Edit/view another file. If the current file has been modified,
- , * ask whether the user wants to save it.
- , * (We could allow to switch between edit and view mode without changing
- , * the file, but we would have to consider carefully the relationship
- , * between viewonly and modified.)
- , */
- ,edit_file (prompt, vomode)
- , char * prompt;
- , FLAG vomode;
- ,{
- , char new_file [maxLINE_LEN]; /* Buffer to hold new file name */
- ,
- , if (modified == TRUE && ask_save () != FINE)
- , return;
- ,
- , viewonly = vomode;
- ,
- ,/* Get new file name */
- , if (get_file (prompt, new_file) == ERRORS)
- , return;
- ,
- ,/* Free old linked list, initialize global variables and load new file */
- , initialize ();
- , clear_screen ();
- , load_file (new_file [0] == '\0' ? NIL_PTR : new_file);
- ,}
- ,
- ,EDIT ()
- ,{
- , edit_file ("Edit file:", FALSE);
- ,}
- ,
- ,VIEW ()
- ,{
- , edit_file ("View file:", TRUE);
- ,}
- ,
- ,edit_nth_file (n)
- , int n;
- ,{
- , int number, index;
- ,
- , if (modified == TRUE && ask_save () != FINE)
- , return;
- ,
- , if (n == -1) {
- , index = get_number ("Edit which file (enter number) ...", '\0', & number);
- , if (index == ERRORS) return;
- , n = number - 1 + fnami_min;
- , }
- , if (n < fnami_min) n = fnami_min;
- , if (n > fnami_max) n = fnami_max;
- ,
- ,/* Free old linked list, initialize global variables and load new file */
- , initialize ();
- , clear_screen ();
- ,
- , fnami = n;
- , if (fnami < fnami_min) load_file (NIL_PTR);
- , else load_file ((* fnamv) [fnami]);
- ,}
- ,
- ,NXTFILE ()
- ,{
- , if (hop_flag > 0) edit_nth_file (fnami_max);
- , else edit_nth_file (fnami + 1);
- ,}
- ,
- ,PRVFILE ()
- ,{
- , if (hop_flag > 0) edit_nth_file (fnami_min);
- , else edit_nth_file (fnami - 1);
- ,}
- ,
- ,NTHFILE ()
- ,{
- , edit_nth_file (-1);
- ,}
- ,
- ,/*
- , * Leave editor. If the file has changed, ask if the user wants to save it.
- , */
- ,QUED ()
- ,{
- , if (modified == TRUE && ask_save () != FINE)
- , return ERRORS;
- ,
- , delete_yank_file ();
- , set_cursor (0, YMAX);
- , putchar ('\n');
- , raw_mode (OFF);
- , exit (0);
- ,}
- ,
- ,/*
- , * Exit editor. If the file has changed, save it.
- , */
- ,EXED ()
- ,{
- , if (multiexit == TRUE) EXFILE ();
- , else {
- , if (modified == TRUE)
- , if (WT () != FINE) return;
- ,
- , delete_yank_file ();
- , set_cursor (0, YMAX);
- , putchar ('\n');
- , raw_mode (OFF);
- , exit (0);
- , }
- ,}
- ,
- ,/*
- , * Exit editing current file. If the file has changed, save it.
- , * Edit next file if there is one.
- , */
- ,EXFILE ()
- ,{
- , if (modified == TRUE)
- , if (WT () != FINE) return;
- ,
- , if (fnami < fnami_max) NXTFILE ();
- , else {
- , delete_yank_file ();
- , set_cursor (0, YMAX);
- , putchar ('\n');
- , raw_mode (OFF);
- , exit (0);
- , }
- ,}
- ,
- ,/*
- , * Count_chars () count the number of chars that the line would occupy on the
- , * screen. Counting starts at the real x-coordinate of the line.
- , * Was only called by delete_text ().
- , */
- ,#ifdef UNUSED
- ,count_chars (line)
- , LINE * line;
- ,{
- , register int cnt = get_shift (line->shift_count) * - SHIFT_SIZE;
- , register char * textp = line->text;
- ,
- ,/* Find begin of line on screen */
- , while (cnt < 0) {
- , if (is_tab (* textp ++))
- , cnt = tab (cnt);
- , else
- , cnt ++;
- , }
- ,
- ,/* Count number of chars left */
- , cnt = 0;
- , while (* textp != '\n') {
- , if (is_tab (* textp ++))
- , cnt = tab (cnt);
- , else
- , cnt ++;
- , }
- , return cnt;
- ,}
- ,#endif UNUSED
- ,
- ,/*-------------------------------------------------------------------------*/
- ,
- ,/*
- , * move_to: move to given coordinates on screen.
- , * move_y: move to given line on screen, staying in last explicit column.
- , * move_address: move to given line at given text position.
- , * The caller must check that scrolling is not needed.
- , * If new x-position is < 0 or > XBREAK, move_it () will check if
- , * the line can be shifted. If it can it sets (or resets) the shift_count
- , * field of the current line accordingly. By this mechanism, the
- , * pseudo-x-positions LINE_START / LINE_END (a very small / big value)
- , * perform the appropriate positioning actions.
- , * Move also sets cur_text to the right char.
- , * "If we're moving to the same x coordinate, try to move the the x-coordinate
- , * used on the other previous call." -- This worked erroneously and was
- , * replaced by an explicit old_x variable and move_y call.
- , * move_address is directly called by move_next/previous_word(), re_search(), RDwin()
- , */
- ,int old_x = 0;
- ,move_y (ny)
- , register int ny;
- ,{
- , move_it (old_x, NIL_PTR, ny);
- ,}
- ,move_to (nx, ny)
- , register int nx;
- , register int ny;
- ,{
- , old_x = x;
- , move_it (nx, NIL_PTR, ny);
- , old_x = x;
- ,}
- ,move_address (nadd, ny)
- , register char * nadd;
- , register int ny;
- ,{
- , old_x = x;
- , move_it (0, nadd, ny);
- , old_x = x;
- ,}
- ,move_it (new_x, new_address, new_y)
- , register int new_x;
- , int new_y;
- , char * new_address;
- ,{
- , register LINE * line = cur_line; /* For building new cur_line */
- , int shift = 0; /* How many shifts to make */
- ,/* static int rel_x = 0; /* Remember relative x position */
- ,/* This was used as a trick to stay virtually in the previous column
- , even when moving across shorter lines; but it had >= 2 errors.
- , Renamed to old_x, made globally accessible and explicitly used
- , by appropriate calls to avoid these problems. TW */
- , int tx = x;
- , char * find_address ();
- ,
- ,/* Check for illegal values */
- , if (new_y < 0 || new_y > last_y)
- , return;
- ,
- ,/* Adjust y-coordinate and cur_line */
- , if (new_y < y)
- , while (y != new_y) {
- , y --;
- , line = line->prev;
- , }
- , else
- , while (y != new_y) {
- , y ++;
- , line = line->next;
- , }
- ,
- ,/* Set or unset relative x-coordinate */
- , if (new_address == NIL_PTR) {
- ,/* new_address = find_address (line, (new_x == x) ? rel_x : new_x , & tx);
- ,/* if (new_x != x)
- ,/* rel_x = tx; */
- , new_address = find_address (line, new_x , & tx);
- , new_x = tx;
- , }
- , else
- , /* rel_x = */ new_x = find_x (line, new_address);
- ,
- ,/* Adjust shift_count if new_x lower than 0 or higher than XBREAK */
- , if (new_x < 0 || new_x >= XBREAK) {
- , if (new_x > XBREAK || (new_x == XBREAK && * new_address != '\n'))
- , shift = (new_x - XBREAK) / SHIFT_SIZE + 1;
- , else {
- , shift = new_x / SHIFT_SIZE;
- , if (new_x % SHIFT_SIZE)
- , shift --;
- , }
- ,
- , if (shift != 0) {
- , line->shift_count += shift;
- , new_x = find_x (line, new_address);
- , set_cursor (0, y);
- , line_print (line);
- , /* rel_x = new_x; */
- , }
- , }
- ,
- ,/* Assign and position cursor */
- , x = new_x;
- , cur_text = new_address;
- , cur_line = line;
- , set_cursor (x, y);
- ,}
- ,
- ,/*
- , * Find_x () returns the x coordinate belonging to address.
- , * (Tabs are expanded).
- , */
- ,find_x (line, address)
- , LINE * line;
- , char * address;
- ,{
- , register char * textp = line->text;
- , register int nx = get_shift (line->shift_count) * - SHIFT_SIZE;
- ,
- , while (textp != address && * textp != '\0') {
- , if (is_tab (* textp ++)) /* Expand tabs */
- , nx = tab (nx);
- , else
- , nx ++;
- , }
- , return nx;
- ,}
- ,
- ,/*
- , * Find_address () returns the pointer in the line with offset x_coord.
- , * (Tabs are expanded).
- , * find_address is only called by move_it ()
- ,get_shift (cnt) is ((cnt) & DUMMY_MASK) ; DUMMY_MASK is 0x7F
- ,tab (cnt) is (((cnt) + 8) & ~07)
- ,is_tab (c) is ((c) == '\t')
- , */
- ,char *
- ,find_address (line, new_x, cur_x)
- , LINE * line;
- , int new_x;
- , int * cur_x;
- ,{
- , register char * textp = line->text;
- , register int tx = get_shift (line->shift_count) * - SHIFT_SIZE;
- ,
- , while (tx < new_x && * textp != '\n') {
- , if (is_tab (* textp)) {
- , if (new_x == old_x /* (* cur_x) */ - 1 && tab (tx) > new_x)
- , break; /* Moving left over tab */
- , else
- , tx = tab (tx);
- , }
- , else tx ++;
- , textp ++;
- , }
- , * cur_x = tx;
- , return textp;
- ,}
- ,
- ,/*-------------------------------------------------------------------------*/
- ,
- ,/*
- , * Initialize is called when a another file is edited. It free's the allocated
- , * space and sets modified back to FALSE and fixes the header/tail pointer.
- , */
- ,initialize ()
- ,{
- , register LINE * line, * next_line;
- ,
- ,/* Delete the whole list */
- , for (line = header->next; line != tail; line = next_line) {
- , next_line = line->next;
- , free_space (line->text);
- , free_space (line);
- , }
- ,
- ,/* header and tail should point to itself */
- , line->next = line->prev = line;
- , x = y = 0;
- , rpipe = modified = FALSE;
- ,}
- ,
- ,/*
- , * Load_file loads the file with given name or the input pipe into memory.
- , * If the file couldn't be opened, just an empty line is installed.
- , * Buffer pointers are initialized.
- , */
- ,load_file (file)
- , char * file;
- ,{
- , load_file_w_o_display (file);
- ,/* Print screen */
- , display (0, 0, header->next, last_y);
- , move_to (0, 0);
- ,/* fstatus ("Read", -1L); */
- ,}
- ,
- ,load_file_w_o_display (file)
- , char * file;
- ,{
- , register LINE * line = header;
- , register int len;
- , long nr_of_chars = 0L;
- , int fd = -1; /* Filedescriptor for file */
- ,
- , nlines = 0; /* Zero lines to start with */
- ,
- , overwriteOK = FALSE;
- ,/* Open file */
- , writable = TRUE; /* Benefit of the doubt */
- , if (file == NIL_PTR) {
- , if (rpipe == FALSE)
- , status_msg ("No file");
- , else {
- , fd = 0;
- , file = "standard input";
- , }
- , file_name [0] = '\0';
- , }
- , else {
- , copy_string (file_name, file); /* Save file name */
- , if (access (file, 0 /* F_OK */) < 0) { /* Cannot access file */
- , status_line ("New file ", file);
- , overwriteOK = TRUE;
- , }
- , else if ((fd = open (file, O_RDWR, 0)) >= 0) {
- , overwriteOK = TRUE;
- , writable = TRUE;
- , }
- , else if ((fd = open (file, O_RDONLY, 0)) < 0)
- , error ("Cannot open: " /*, file */, serror ());
- , else { overwriteOK = TRUE;
- , writable = FALSE;
- , }
- , }
- ,
- ,/* Read file */
- , loading = TRUE; /* Loading file, so set flag */
- , get_line_err1 = NIL_PTR;
- , get_line_err2 = NIL_PTR;
- ,
- , if (fd >= 0) {
- , status_line ("Reading ", file);
- , while ((len = get_line (fd, text_buffer)) != ERRORS) {
- , line = line_insert (line, text_buffer, len);
- , nr_of_chars += (long) len;
- , }
- , if (nlines == 0) /* The file was empty! */
- , line = line_insert (line, "\n", 1);
- , clear_buffer (); /* Clear output buffer: out_count = 0; */
- , cur_line = header->next;
- , (void) close (fd); /* Close file */
- , if ((get_line_err1 != NIL_PTR) || (get_line_err2 != NIL_PTR)) {
- , ring_bell ();
- , error (get_line_err1, get_line_err2);
- , sleep (1);
- , }
- , fstatus ("Read", nr_of_chars);
- , }
- , else /* Just install a "\n" */
- , (void) line_insert (line, "\n", 1);
- ,
- , reset (header->next, 0); /* Initialize pointers */
- , move_to (0, 0);
- , loading = FALSE; /* Stop loading, reset flag */
- ,}
- ,
- ,/*
- , * Get_line reads one line from filedescriptor fd. If EOF is reached on fd,
- , * get_line () returns ERRORS, else it returns the length of the string.
- , */
- ,char * get_line_err1;
- ,char * get_line_err2;
- ,
- ,get_line (fd, buffer)
- , int fd;
- , register char buffer [MAX_CHARS];
- ,{
- , static char * last = NIL_PTR;
- , static char * current = NIL_PTR;
- , static int read_chars;
- , register char * cur_pos = current;
- , char * begin = buffer;
- , char * fini = buffer + MAX_CHARS - 2 /* leave space for '\n\0' */;
- ,
- , do {
- , if (cur_pos == last) {
- , if ((read_chars = read (fd, screen, screen_BUFL)) <= 0)
- , break;
- , last = & screen [read_chars];
- , cur_pos = screen;
- , }
- , if (* cur_pos == '\0' ) {
- , get_line_err1 = "File contains NULL char's - changed to DEL's - ";
- , * cur_pos = '\177';
- , }
- ,#ifdef DEBUG
- , if (* cur_pos == '\r' ) {
- , get_line_err1 = "File contains RET char's - changed to DEL's - ";
- , * cur_pos = '\177';
- , }
- ,#endif
- , if (buffer == fini) {
- , get_line_err2 = "Line too long - split";
- , * buffer ++ = '\n';
- , break;
- , }
- , } while ((* buffer ++ = * cur_pos ++) != '\n');
- ,
- , current = cur_pos;
- , if (read_chars <= 0) {
- , if (buffer == begin)
- , return ERRORS;
- , if (* (buffer - 1) != '\n')
- , if (loading == TRUE) /* Add '\n' to last line of file */
- , * buffer ++ = '\n';
- , else {
- , * buffer = '\0';
- , return NO_LINE;
- , }
- , }
- ,
- , * buffer = '\0';
- , return buffer - begin;
- ,}
- ,
- ,/* ================================================================== *
- , * Auxiliary routines *
- , * ================================================================== */
- ,
- ,/*
- , * Unnull () changes a NULL string pointer into an empty string pointer
- , * to allow easy feading of string results into build_string / sprintf
- , */
- ,char *
- ,unnull (s)
- , char * s;
- ,{
- , if (s == NIL_PTR) return "";
- , else return s;
- ,}
- ,
- ,/*
- , * Build_string () prints the arguments as described in fmt, into the buffer.
- , * %s indicates a string argument, %d indicates an integer argument.
- , */
- ,#ifndef build_string /* otherwise build_string is sprintf */
- ,/* VARARGS */
- ,build_string (buf, fmt, args)
- , register char * buf, * fmt;
- , int args;
- ,{
- , int * argptr = & args;
- , char * scanp;
- , FLAG islong;
- ,
- , while (* fmt) {
- , if (* fmt == '%') {
- , fmt ++;
- , if (* fmt == 'l') {islong = TRUE; fmt ++;}
- , else islong = FALSE;
- , switch (* fmt ++) {
- , case 's' :
- , scanp = (char *) * argptr;
- , break;
- , case 'd' :
- , if (islong == TRUE) {
- , scanp = num_out ((long) * ((long *) argptr));
- , if (sizeof (long) > sizeof (int)) argptr ++;
- , break;
- , }
- , else {
- , scanp = num_out ((long) * argptr);
- , break;
- , }
- , case 'D' :
- , scanp = num_out ((long) * ((long *) argptr));
- , if (sizeof (long) > sizeof (int)) argptr ++;
- , break;
- , default :
- , scanp = "";
- , }
- , while (* buf ++ = * scanp ++)
- , ;
- , buf --;
- , argptr ++;
- , }
- , else
- , * buf ++ = * fmt ++;
- , }
- , * buf = '\0';
- ,}
- ,#endif not build_string
- ,
- ,/*
- , * Output an (unsigned) long in a 10 digit field without leading zeros.
- , * It returns a pointer to the first digit in the buffer.
- , */
- ,char *
- ,num_out (number)
- , long number;
- ,{
- , static char num_buf [11]; /* Buffer to build number */
- , register long digit; /* Next digit of number */
- , register long pow = 1000000000L; /* Highest ten power of long */
- , FLAG digit_seen = FALSE;
- , int i;
- ,
- , for (i = 0; i < 10; i ++) {
- , digit = number / pow; /* Get next digit */
- , if (digit == 0L && digit_seen == FALSE && i != 9)
- , num_buf [i] = ' ';
- , else {
- , num_buf [i] = '0' + (char) digit;
- , number -= digit * pow; /* Erase digit */
- , digit_seen = TRUE;
- , }
- , pow /= 10L; /* Get next digit */
- , }
- , num_buf [11] = '\0';
- , for (i = 0; num_buf [i] == ' '; i ++) /* Skip leading spaces */
- , ;
- , return (& num_buf [i]);
- ,}
- ,
- ,/*
- , * make_number () converts a string into a natural number
- , * returns the character after the last digit
- , */
- ,make_number (num, str)
- , int * num;
- , char * str;
- ,{
- , register char * chpoi = str;
- ,
- , * num = 0;
- , while (* chpoi >= '0' && * chpoi <= '9' && quit == FALSE) {
- , * num *= 10;
- , * num += * chpoi - '0';
- , chpoi ++;
- , }
- , return * chpoi;
- ,}
- ,
- ,/*
- , * Length_of () returns the number of characters in the string `string'
- , * excluding the '\0'.
- , */
- ,int
- ,length_of (string)
- , register char * string;
- ,{
- , register int count = 0;
- ,
- , if (string != NIL_PTR) {
- , while (* string ++ != '\0')
- , count ++;
- , }
- , return count;
- ,}
- ,
- ,/*
- , * Copy_string () copies the string `from' into the string `to'. `To' must be
- , * long enough to hold `from'.
- , */
- ,copy_string (to, from)
- , register char * to;
- , register char * from;
- ,{
- , while ((* to ++ = * from ++))
- , ;
- ,}
- ,
- ,/*-------------------------------------------------------------------------*/
- ,
- ,/*
- , * serrorof delivers the error message of the given errno value.
- , * serror delivers the error message of the current errno value.
- , * geterrno just returns the current errno value.
- , */
- ,#ifdef vms
- ,/* #define includeerrno */
- ,# ifdef includeerrno
- ,# include <errno.h>
- ,# else
- , extern volatile int noshare errno;
- , extern volatile int noshare vaxc$errno; /* VMS error code when errno = EVMSERR */
- ,# define EVMSERR 65535
- , extern volatile int noshare sys_nerr;
- , extern volatile char noshare * sys_errlist [];
- ,# endif
- ,#else
- , extern int errno;
- , extern int sys_nerr;
- , extern char * sys_errlist [];
- ,#endif
- ,
- ,char *
- ,serrorof (errno)
- , int errno;
- ,{
- , if ((errno < 0) || (errno >= sys_nerr))
- , { static char s [20];
- ,#ifdef vms
- , if (errno == EVMSERR)
- , build_string (s, "VMS error %d", vaxc$errno);
- , else
- ,#endif
- , build_string (s, "Unknown error %d", errno);
- , return s;
- , }
- , else return sys_errlist [errno];
- ,}
- ,char *
- ,serror ()
- ,{ return serrorof (errno); }
- ,int
- ,geterrno ()
- ,{ return errno; }
- ,
- ,/*
- , * Panic () is called with a mined error msg and an optional system error msg.
- , * It is called when something unrecoverable has happened.
- , * It writes the message to the terminal, resets the tty and exits.
- , * Ask the user if he wants to save his file.
- , */
- ,#define panic_msg(msg) if (isscreenmode == TRUE) {status_msg (msg); sleep (2);} else printf ("%s\n", msg);
- ,panic (message, err)
- , register char * message;
- , register char * err;
- ,{
- , int panic_written;
- ,
- , panic_level ++;
- ,
- , if (panic_level < 2) {
- , if (loading == FALSE && modified == TRUE) {
- , if ((panic_written = panic_write ()) == ERRORS) {
- , build_string (text_buffer, "Error writing panic file %s", panic_file);
- , sleep (2);
- , }
- , else
- , build_string (text_buffer, "Panic file %s written", panic_file);
- , ring_bell ();
- , panic_msg (text_buffer);
- , }
- , if (err == NIL_PTR)
- , build_string (text_buffer, "%s", message);
- , else
- , build_string (text_buffer, "%s (Error: %s)", message, err);
- , panic_msg (text_buffer);
- ,
- , /* "normal" panic handling: */
- , if (loading == FALSE) {
- , if (QUED () == ERRORS) /* Try to save the file */ {
- , sleep (2);
- , panic_msg ("Error writing file in panic mode - trying to continue");
- , panic_level --;
- , return;
- , }
- , }
- , }
- ,
- , if (panic_level < 3) {
- , if (isscreenmode == TRUE) {
- , set_cursor (0, YMAX);
- , putchar ('\n');
- , raw_mode (OFF);
- , }
- , delete_yank_file ();
- , }
- , exit (1) /* abort () sends IOT which would again be caught */;
- ,}
- ,panicio (message, err)
- , register char * message;
- , register char * err;
- ,{
- ,/* Should panic_level already be increased here ? */
- , panic (message, err);
- ,}
- ,
- ,catch_interrupt ()
- ,{
- , panic ("External signal caught - terminating", NIL_PTR);
- ,}
- ,
- ,/*
- , * Memory allocation
- , */
- ,#ifdef msdos
- ,#include <alloc.h>
- ,#define allocate farmalloc
- ,#define freemem farfree
- ,#else
- ,extern char * malloc ();
- ,#define allocate malloc
- ,#define freemem free
- ,#endif
- ,char *
- ,alloc (bytes)
- , int bytes;
- ,{
- , char * p;
- ,
- , if ((p = allocate ((unsigned) bytes)) == NIL_PTR)
- , panic ("Out of memory", NIL_PTR);
- , return p;
- ,}
- ,
- ,free_space (p)
- , char * p;
- ,{
- , freemem (p);
- ,}
- ,
- ,/*
- , * Basename () finds the absolute name of the file out of a given path_name.
- , */
- ,#ifdef UNUSED
- ,char *
- ,basename (path)
- , char * path;
- ,{
- , register char * ptr = path;
- , register char * last = NIL_PTR;
- ,
- , while (* ptr != '\0') {
- , if (* ptr == '/')
- , last = ptr;
- , ptr ++;
- , }
- , if (last == NIL_PTR)
- , return path;
- , if (* (last + 1) == '\0') { /* E.g. /usr/tmp/pipo/ */
- , * last = '\0';
- , return basename (path); /* Try again */
- , }
- , return last + 1;
- ,}
- ,#endif
- ,
- ,/*
- , * Delete file.
- , */
- ,delete_file (file)
- , char * file;
- ,{
- ,#ifdef unix
- , unlink (file);
- ,#endif
- ,#ifdef msdos
- , unlink (file);
- ,#endif
- ,#ifdef vms
- , delete (file);
- ,#endif
- ,}
- ,
- ,/*
- , * Delete yank file if there is one.
- , */
- ,delete_yank_file ()
- ,{
- , if (yank_status == VALID) delete_file (yank_file);
- ,}
- ,
- ,/* ================================================================== *
- , * Miscellaneous *
- , * ================================================================== */
- ,
- ,/*
- , * Ignore this keystroke.
- , */
- ,I ()
- ,{
- ,}
- ,
- ,/*
- , * Fortifying 'HOP' key.
- , */
- ,HOP ()
- ,{
- , hop_flag = 2;
- , if (! char_ready_within (500))
- , status_msg ("Continue HOP command (next command fortified) ...");
- ,}
- ,
- ,/*
- , * Cancel prefix function.
- , */
- ,CANCEL ()
- ,{
- , hop_flag = 0;
- , clear_status ();
- ,}
- ,
- ,/*
- , * Call proc associated with function key.
- , */
- ,FUNKEY ()
- ,{
- , (* keyproc) ('\0');
- , keyproc = I;
- ,}
- ,
- ,/*
- , * Combined command.
- , */
- ,extern MRT(), MLF();
- ,
- ,ESCAPE ()
- ,{
- , u_char c;
- , int (* func) ();
- ,
- , if (! char_ready_within (500))
- ,/* status_msg ("Continue ESCape command (for help use h) ..."); */
- , status_msg ("ESC(exit) q(uit w(rite e(dit /\\(search) r(eplace d(irectory h(elp ...");
- , if (quit == TRUE) return I ();
- , c = readchar ();
- , if (quit == TRUE) return I ();
- , clear_status ();
- , if ('0' <= c && c <= '9') return REPT (c);
- , switch (c) {
- , case '\033' : return EXED (); /* alternatively EXFILE () ? */
- , case 'q' : return QUED ();
- , case '/' : return SFW ();
- , case '\\' : return SRV ();
- , case 's' : return GR ();
- , case 'l' : return LR ();
- , case 'r' : return REPL ();
- , case 'w' : return WT ();
- , case 'e' : return EDIT ();
- , case 'v' : return VIEW ();
- , case 'h' : return HELP ();
- , case '?' : return FS ();
- , case '.' : return RD ();
- , case 'i' : return INF ();
- , case 'b' : return WB ();
- , case '=' : return REPT (' ');
- , case 'z' : return SUSP ();
- , case 'd' : return CHDI ();
- , case '!' : return SH ();
- , case ']' : return GOMA ();
- , case 'n' : return NN ();
- , case 'p' : return PBUF ();
- , case 'c' : return CMD ();
- , case ' ' : return I ();
- , case '+' : return NXTFILE ();
- , case '-' : return PRVFILE ();
- , case '#' : return NTHFILE ();
- , case QUITCHAR : return CANCEL ();
- , default : {
- , /* func = key_map [c];
- , if ((c < ' ') || (func == FUNKEY)) {
- , hop_flag = 1;
- , return (* func) (c);
- , }
- , else
- , */
- , return BAD (c);
- , }
- , }
- ,}
- ,
- ,/*
- , * DIRECT () reads in a direct cursor movement input sequence and moves.
- , */
- ,DIRECT ()
- ,{
- , u_char c;
- , int xpos, ypos;
- ,
- , c = get_digits (& ypos); /* c should be ';' */
- , c = get_digits (& xpos);
- , ypos = ypos - 1;
- , xpos = xpos - 1;
- , if (ypos > last_y) ypos = last_y;
- , move_to (xpos, ypos);
- , if (c == 'm') MARK (); /* middle mouse button */
- , if (c == 'r') YA (); /* right mouse button */
- ,}
- ,
- ,/*
- , * REPT () prompts for a count and wants a command after that. It repeats the
- , * command count times. If a ^\ is given during repeating, stop looping and
- , * return to main loop.
- , */
- ,REPT (firstdigit)
- , char firstdigit;
- ,{
- , register int count;
- , register int (* func) ();
- , int index, number;
- ,
- , hop_flag = 0;
- , if (firstdigit >= '0' && firstdigit <= '9')
- , index = get_number ("Please continue repeat count...", firstdigit, & number);
- , else
- , index = get_number ("Please enter repeat count...", '\0', & number);
- , if (index == ERRORS) return;
- ,
- , func = key_map [index];
- , if (func == I) { /* Function assigned? */
- , clear_status ();
- , return;
- , }
- , if (func == FUNKEY) {
- , func = * keyproc;
- , keyproc = I;
- , index = '\0';
- , }
- ,
- , count = number;
- , while (count -- > 0 && quit == FALSE) {
- , if (stat_visible == TRUE)
- , clear_status ();
- , (* func) (index);
- , flush ();
- , }
- ,
- , if (quit == TRUE) /* Abort has been given */
- , error ("Repeat aborted", NIL_PTR);
- , else
- , clear_status ();
- ,}
- ,
- ,/*
- , * Complains to illegal commands and eats up illegal escape sequences.
- , */
- ,BAD (c)
- , u_char c;
- ,{
- , static char message2 [] = "'**' - type a blank";
- ,
- , if (c < ' ') { message2 [1] = '^'; message2 [2] = c + '@'; }
- , else { message2 [1] = ' '; message2 [2] = c; }
- , error ("Unknown command ", message2);
- , while (readchar () != ' ' && quit == FALSE) {
- , ring_bell ();
- , flush ();
- , }
- , clear_status ();
- ,}
- ,
- ,/*
- , * Change working directory.
- , */
- ,CHDI ()
- ,{
- , char new_dir [maxLINE_LEN]; /* Buffer to hold new dir. name */
- ,
- ,#ifdef vms
- ,# define _getcwd_
- ,#endif
- ,#ifdef msdos
- ,# define _getcwd_
- ,#endif
- ,#ifdef _getcwd_
- , build_string (text_buffer, "Directory: %s, change to:", unnull (getcwd (new_dir, maxLINE_LEN)));
- ,#else
- , build_string (text_buffer, "Directory: %s, change to:", unnull (getwd (new_dir)));
- ,#endif
- , if (get_file (text_buffer, new_dir) != FINE)
- , return;
- , if (chdir (new_dir) == 0) {
- ,/* set_cursor (x, y); /* Set cursor back to old position */
- , clear_status ();
- , overwriteOK = FALSE; /* Same file base name ... */
- , writable = TRUE;
- ,/* if (viewmode == FALSE) */
- , modified = TRUE; /* would mean different file now */
- , }
- , else error ("Could not change work dir: ", serror ());
- ,}
- ,
- ,/*
- , * Print file status.
- , */
- ,FS ()
- ,{
- , fstatus (file_name [0] ? "" : "[buffer]", -1L);
- ,}
- ,
- ,/*
- , * Line_number () finds the line number we're on.
- , */
- ,line_number ()
- ,{
- , register LINE * line = header->next;
- , register int count = 1;
- ,
- , while (line != cur_line) {
- , count ++;
- , line = line->next;
- , }
- ,
- , return count;
- ,}
- ,
- ,/*
- , * Display a line telling how many chars and lines the file contains. Also tell
- , * whether the file is readonly and/or modified.
- ,fstatus (mess, cnt) is file_status ((mess), (cnt), file_name, \
- , nlines, writable, modified, viewonly)
- , */
- ,file_status (message, count, file, lines, writefl, changed, viewing)
- , char * message;
- , register long count; /* Contains number of characters in file */
- , char * file;
- , int lines;
- , FLAG writefl, changed, viewing;
- ,{
- , register LINE * line;
- , static char msg [maxLINE_LEN + 40]; /* Buffer to hold line */
- , char yank_msg [maxLINE_LEN]; /* Buffer for msg of yank_file */
- ,
- , if (count < 0) /* Not valid. Count chars in file */
- , for (line = header->next; line != tail; line = line->next)
- , count += length_of (line->text);
- ,
- , if (yank_status == VALID) /* Append buffer info */
- , build_string (yank_msg, " Buffer: %ld char%s.", chars_saved,
- , (chars_saved == 1L) ? "" : "s");
- , else
- , yank_msg [0] = '\0';
- ,
- , build_string (msg,
- , "%s %s%s%s%s, %d line%s, %ld char%s. Line %d.%s",
- , message,
- , (rpipe == TRUE && * message != '[') ?
- , "standard input" : file,
- , /* previously only basename (file) was printed */
- , (viewing == TRUE) ? " (View only)" : "",
- , (changed == TRUE) ? " (modified)" : "",
- , (writefl == FALSE) ? " (Readonly)" : "",
- , lines, (lines == 1) ? "" : "s",
- , count, (count == 1L) ? "" : "s",
- , line_number (),
- , yank_msg);
- ,
- , status_msg (msg); /* Print the information */
- ,}
- ,
- ,/*
- , * Show Help information on screen
- , */
- ,HELP ()
- ,{
- , clear_screen ();
- , status_msg ("Wait for help...");
- , flush ();
- , raw_mode (OFF);
- , if (getenv ("MINEDHELP"))
- , system ((char *) getenv ("MINEDHELP"));
- , else system (helpcommand);
- , sleep (1);
- , raw_mode (ON);
- , clear_status ();
- , RDwin ();
- ,}
- ,
- ,/*
- , * Print buffer
- , */
- ,PBUF ()
- ,{
- , int fd;
- , char cmd [maxLINE_LEN]; /* Buffer for print command */
- ,
- , if ((fd = scratch_file (READ, FALSE)) == ERRORS) {
- , error ("Buffer is empty.", NIL_PTR);
- , return;
- , }
- , close (fd);
- , build_string (cmd, getenv ("MINEDPRINT") ?
- , (char *) getenv ("MINEDPRINT") : printcommand, yank_file);
- , clear_status ();
- , set_cursor (0, YMAX);
- , flush ();
- , system (cmd);
- , sleep (1);
- , RDwin ();
- ,}
- ,
- ,/*
- , * Pipe buffer
- , */
- ,CMD ()
- ,{
- , int fd;
- , char cmd [maxLINE_LEN]; /* Buffer for command */
- , char command [maxLINE_LEN]; /* Buffer for full command */
- ,
- , if ((fd = scratch_file (READ, FALSE)) == ERRORS) {
- , error ("Buffer is empty.", NIL_PTR);
- , return;
- , }
- , close (fd);
- , if (get_string ("Command with buffer as input:", cmd, TRUE) != FINE)
- , return;
- , build_string (command, "%s < %s", cmd, yank_file);
- , clear_status ();
- , set_cursor (0, YMAX);
- , flush ();
- , raw_mode (OFF);
- , system (command);
- , sleep (1);
- , raw_mode (ON);
- , RDwin ();
- ,}
- ,
- ,/*
- , * Called if an operation is not implemented
- , */
- ,notimpl ()
- ,{
- , error ("Command not implemented", NIL_PTR);
- ,}
- ,
- ,/*
- , * Suspend editor after writing back the file.
- , */
- ,SUSP ()
- ,{
- , if (cansuspendmyself == TRUE) {
- , if (hop_flag == 0 && modified == TRUE)
- , if (WT () == ERRORS) return ERRORS;
- , set_cursor (0, YMAX);
- , raw_mode (OFF);
- , suspendmyself ();
- , raw_mode (ON);
- , clear_status ();
- , RDwin ();
- , }
- , else notimpl ();
- ,}
- ,
- ,/*
- , * Call an interactive shell.
- , */
- ,SH ()
- ,{
- ,#ifdef unix
- , register int w;
- , int pid, status, waiterr;
- ,
- , switch (pid = vfork ()) {
- , case -1: /* Error */
- , error ("Cannot fork: ", serror ());
- , return;
- , case 0: /* This is the child */
- , set_cursor (0, YMAX);
- , putchar ('\n');
- , raw_mode (OFF);
- , if (rpipe) { /* Fix stdin */
- , close (STD_IN);
- , if (open ("/dev/tty", O_RDONLY, 0) < 0)
- , exit (126);
- , }
- , execl (getenv ("SHELL"), getenv ("SHELL"), 0);
- , _exit (127); /* Exit with 127 */
- , default: /* This is the parent */
- , do {
- , w = wait (& status);
- , } while (w != -1 && w != pid);
- , waiterr = geterrno ();
- , }
- ,
- , raw_mode (ON);
- , RDwin ();
- ,
- , if (w == -1) {
- , error ("Wait error: ", serrorof (waiterr));
- , if (((status >> 8) == 127) || ((status >> 8) == 126)) sleep (2);
- , }
- , if ((status >> 8) == 127) /* Child died with 127 */
- , error (getenv ("SHELL"), ": cannot exec this ${SHELL} (not found / not enough memory ?)");
- , else if ((status >> 8) == 126)
- , error ("Cannot open /dev/tty as fd #0", NIL_PTR);
- ,#else
- , notimpl ();
- ,#endif
- ,}
- ,
- ,/* ================================================================== *
- , * Main *
- , * ================================================================== */
- ,
- ,main (argc, argv)
- , int argc;
- , char * argv [];
- ,{
- , register int index; /* index in key table */
- , int initlinenum;
- , int initlinenumi = 0;
- , LINE * initlinenumline;
- , char * Mark;
- , FLAG goon;
- ,
- ,/* fprot = umask (0); */
- ,
- , if (getenv ("NoCtrlSQ") || getenv ("NoControlSQ")) {
- , /* ^S and ^Q may come arbitrarily from terminal, so don't use them */
- , key_map ['\021'] = I;
- , key_map ['\023'] = I;
- , }
- , if (getenv ("MINEDMULT")) multiexit = TRUE;
- , Mark = (char *) getenv ("MINEDSHIFT");
- , if (Mark != NIL_PTR) {
- , SHIFT_MARK = Mark [0];
- , if (Mark [0] != '\0') SHIFT_BEG = Mark [1];
- , }
- , Mark = (char *) getenv ("MINEDTAB");
- , if (Mark != NIL_PTR) TABchar = (Mark [0] == '\0' ? '╖' : Mark [0]);
- , Mark = (char *) getenv ("MINEDRET");
- , if (Mark != NIL_PTR) {
- , RET_MARK = Mark [0];
- , if (RET_MARK) RET_BLANK = Mark [1];
- , if (RET_BLANK) RET_BLANK2 = Mark [2];
- , }
- ,
- , get_term ();
- ,
- , if (! can_clear_eol) {
- , for (index = 0; index < XMAX; index ++) /* Fill blank_line with spaces*/
- , blank_line [index] = ' ';
- , blank_line [XMAX] = '\0';
- , }
- ,
- , fnami = 1;
- , goon = TRUE;
- , do {
- , if (fnami < argc) {
- , if (* argv [fnami] == '+') {
- , initlinenumi = fnami;
- , fnami += 1;
- , }
- , else if (streq (argv [fnami], "-v")) {
- , viewonly = TRUE;
- , fnami += 1;
- , }
- , else goon = FALSE;
- , } else goon = FALSE;
- , } while (goon == TRUE);
- ,
- , fnami_min = fnami;
- , fnami_max = argc - 1;
- , fnami_cnt = argc - fnami_min;
- , fnamv = argv; /* Why does this produce a warning? C is such a stupid language! */
- , if (! (fnami < argc))
- , fnami = 0;
- ,
- , if (! isatty (STD_IN)) { /* Reading from pipe */
- , if (fnami != 0) {
- , panic ("Cannot read both pipe and file", NIL_PTR);
- , }
- , rpipe = TRUE;
- , modified = TRUE; /* Set modified flag not to loose buffer */
- , if ((input_fd = open ("/dev/tty", O_RDONLY, 0)) < 0)
- , panic ("Cannot open /dev/tty for read", serror ());
- , }
- , if (! isatty (STD_OUT)) {
- , wpipe = TRUE;
- , modified = TRUE; /* Set modified flag not to ignore buffer on exit */
- , /* if ((output_fd = open ("/dev/tty", O_WRONLY, 0)) < 0)
- , panic ("Cannot open /dev/tty for write", serror ()); */
- , }
- ,
- , raw_mode (ON); /* Set tty to appropriate mode */
- , clear_screen ();
- ,
- ,/*
- , * Generate names of paste files and of panic-file
- , */
- ,#ifdef unix
- , temp_dir = (char *) getenv ("TMPDIR");
- , if (temp_dir == NIL_PTR || temp_dir [0] == '\0') temp_dir = "/tmp";
- , if (getenv ("USER")) {
- , build_string (yankie_file, "%s/minedbuf.%s", temp_dir, getenv ("USER"));
- , build_string (panic_file, "%s/minedpanic.%s.%d", temp_dir, getenv ("USER"), getpid ());
- , }
- , else {
- , build_string (yankie_file, "%s/minedbuf.%d", temp_dir, geteuid ());
- , build_string (panic_file, "%s/minedpanic.%d.%d", temp_dir, geteuid (), getpid ());
- , }
- ,#endif
- ,#ifdef vms
- , if (getenv ("SYS$SCRATCH"))
- , temp_dir = "SYS$SCRATCH";
- , else temp_dir = "SYS$LOGIN";
- , if (getenv ("USER")) {
- , build_string (yankie_file, "%s:$MINEDBUF.%s", temp_dir, getenv ("USER"));
- , build_string (panic_file, "%s:$MINEDPANIC.%s.%d", temp_dir, getenv ("USER"), getpid ());
- , }
- , else {
- , build_string (yankie_file, "%s:$MINEDBUF.%d", temp_dir, geteuid ());
- , build_string (panic_file, "%s:$MINEDPANIC.%d.%d", temp_dir, geteuid (), getpid ());
- , }
- ,#endif
- ,#ifdef msdos
- , temp_dir = (char *) getenv ("TEMP");
- , if (temp_dir == NIL_PTR || temp_dir [0] == '\0') temp_dir = (char *) getenv ("TMP");
- , if (temp_dir == NIL_PTR || temp_dir [0] == '\0') temp_dir = "\\";
- , build_string (yankie_file, "%s\\minedbuf", temp_dir);
- , build_string (panic_file, "%s\\mined-pa.nic", temp_dir);
- ,#endif
- ,
- , header = tail = (LINE *) alloc (sizeof (LINE)); /* Make header of list*/
- , header->text = NIL_PTR;
- , header->next = tail->prev = header;
- ,
- ,/* Load the file (if any) */
- , if (fnami == 0)
- , load_file_w_o_display (NIL_PTR);
- , else {
- , /* This should be applied to all file names, or better, not at all:
- , if (length_of (argv [fnami]) > maxLINE_LEN) {
- , argv [fnami] [maxLINE_LEN] = '\0';
- , }
- , */
- , load_file_w_o_display (argv [fnami]);
- , }
- , loading = TRUE; /* keep loading flag TRUE until entering main loop */
- ,
- , if (initlinenumi != 0) {
- , make_number (& initlinenum, argv [initlinenumi] + 1);
- , if (initlinenum > 0) {
- , if (initlinenum <= 0 || (initlinenumline = proceed (header->next, initlinenum - 1)) == tail)
- , error ("Illegal line number: ", num_out ((long) initlinenum));
- , else {
- , move_to (x, find_y_w_o_RD (initlinenumline));
- , fstatus ("Read", -1L);
- , }
- , }
- , }
- , if (wpipe) {
- , file_name [0] = '\0'; /* don't let user believe he's editing a file */
- , fstatus ("Editing for standard output", -1L);
- , }
- , RD ();
- , flush ();
- , catch_signals (catch_interrupt);
- , loading = FALSE;
- ,
- ,/* Main loop of the editor */
- , for (;;) {
- , index = readchar ();
- , if (stat_visible == TRUE)
- , clear_status ();
- , if (quit == FALSE) { /* Call the function for the typed key */
- , (* key_map [index]) (index);
- , if (hop_flag > 0) hop_flag --;
- , flush (); /* Flush output (if any) */
- , }
- , if (quit == TRUE) {
- , CANCEL ();
- , quit = FALSE;
- , }
- , }
- , /* NOTREACHED */
- ,}
- ,
- ,/* ================================================================== *
- , * End *
- , * ================================================================== */
- EOSED
-
- exit 0
-
-