home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-11-21 | 54.2 KB | 1,888 lines |
- Newsgroups: comp.sources.misc
- From: pvr@wang.com (Peter Reilley)
- Subject: v26i041: beav - Binary file editor and viewer, v1.32, Part05/09
- Message-ID: <1991Nov21.230249.1723@sparky.imd.sterling.com>
- X-Md4-Signature: 48398edd23ac6d7863fbcb523ed1a8be
- Date: Thu, 21 Nov 1991 23:02:49 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: pvr@wang.com (Peter Reilley)
- Posting-number: Volume 26, Issue 41
- Archive-name: beav/part05
- Environment: UNIX, AIX, MS-DOS, AMIGA
- Supersedes: beav: Volume 22, Issue 10-18
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: def.h fileio.c search.c
- # Wrapped by kent@sparky on Thu Nov 21 16:47:01 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 5 (of 9)."'
- if test -f 'def.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'def.h'\"
- else
- echo shar: Extracting \"'def.h'\" \(21214 characters\)
- sed "s/^X//" >'def.h' <<'END_OF_FILE'
- X/*
- X * Common header file.
- X *
- X * This file is the general header file for all parts
- X * of the display editor. It contains all of the
- X * general definitions and macros. It also contains some
- X * conditional compilation flags. All of the per-system and
- X * per-terminal definitions are in special header files.
- X * The most common reason to edit this file would be to zap
- X * the definition of CVMVAS or BACKUP.
- X */
- X#define LINT_ARGS 1 /* enable lint type checking */
- X#include "stdio.h"
- X
- X#ifndef NOPROTO
- X#ifdef UNIX
- X#include "sys/types.h"
- X#endif /* UNIX */
- X#include "prototyp.h"
- X#endif /* NOPROTO */
- X
- X#define BACKUP 1 /* Make backup file. */
- X#define RUNCHK 1 /* Do additional checking at run time */
- X
- X#ifndef uchar
- X#define uchar unsigned char
- X#endif
- X
- X#ifndef uint
- X#define uint unsigned int
- X#endif
- X
- X#ifndef ushort
- X#define ushort unsigned short
- X#endif
- X
- X#ifndef ulong
- X#define ulong unsigned long
- X#endif
- X
- X/* these defines are reserved for handling data values from the buffer */
- X#define D8 uchar /* this had better be a 8 bit quantity */
- X#define D16 ushort /* this had better be a 16 bit quantity */
- X#define D32 ulong /* this had better be a 32 bit quantity */
- X
- X/* this define is reserved for the address of a location in the buffer */
- X#define A32 ulong /* this is a 32 bit address into the buffer */
- X
- X#define bool char /* used for boolean values */
- X#define bits char /* used for boolean bit flags */
- X
- X/* this define is reserved for the byte location in the a LINE structure */
- X#define LPOS uint /* this is a 32 bit address into the buffer */
- X
- X/*
- X * MS-DOS system header file.
- X */
- X#if MSDOS
- X#define LARGE 1 /* Large model. */
- X#endif
- X#define PCC 1 /* "[]" won't work. */
- X#define GOOD 0 /* Indicate hunkydoryhood */
- X
- X/*
- X * Macros used by the buffer name making code.
- X * Start at the end of the file name, scan to the left
- X * until BDC1 (or BDC2, if defined) is reached. The buffer
- X * name starts just to the right of that location, and
- X * stops at end of string (or at the next BDC3 character,
- X * if defined). BDC2 and BDC3 are mainly for VMS.
- X */
- X#define BDC1 ':' /* Buffer names. */
- X#define BDC2 '/' /* Buffer names. jam */
- X
- X#ifdef UNIX
- X#define PATHCHR ':'
- X#define SEPCHAR '/'
- X#else
- X#define PATHCHR ';'
- X#define SEPCHAR 0x5c /* this is a \ char */
- X#endif
- X
- X/*
- X * Digital ANSI terminal header file
- X */
- X#ifdef MSDOS
- X#define ANSI 1 /* send ANSI escape codes */
- X#endif
- X
- X#ifdef UNIX
- X#define NROW 100
- X#define NCOL 80 /* Columns. */
- X#else
- X#define NROW 25 /* Rows.for boot */
- X#define NCOL 80 /* Columns. */
- X#endif
- X
- X#define CUSTOMIZE /* compile switch for extended key
- Xbinding in extend.c */
- X#define COSMETIC /* cosmetic screen stuff on
- Xinsert off screen */
- X#ifdef MSDOS
- X#define WANG_CHARACTER_SCREEN 0xf0000000L
- X#endif
- X/*
- X * Table sizes, etc.
- X */
- X#define NSHASH 31 /* Symbol table hash size. */
- X#define NFILEN 80 /* Length, file name. */
- X#define NBUFN 13 /* Length, buffer name. */
- X#define NFILE 12 /* Length, file name. */ /* krw */
- X#define NKBDM 256 /* Length, keyboard macro. */
- X#define NMSG 512 /* Length, message buffer. */
- X#define NPAT 80 /* Length, pattern. */
- X#define HUGE 1000 /* A rather large number. */
- X#define NSRCH 128 /* Undoable search commands. */
- X#define NXNAME 64 /* Length, extended command. */
- X#define MAXPOS 0x7FFFFFFF /* Maximum positive long value */
- X
- X/*
- X * This is the initial allocation for user data storage.
- X * It has should be in the range of 1 to less than half the size
- X * of an int. The define LPOS is used to index into an array of this size.
- X * This is main tunable parameter for the speed of beav.
- X * If it is too large inserts and deletes will be slow but
- X * file loads will be fast and memory will be efficiently used.
- X * If it is too small the reverse will be true.
- X * This seems like a good number, but I have not tested it for performance.
- X */
- X#define NLINE 0x1000 /* Length, line. pvr */
- X
- X/*
- X * When memory must be reallocated this is added to the allocation
- X * request to allow for a little slop on areas that are being worked on.
- X * This should reduce the number of allocations done.
- X */
- X#define NBLOCK 0x1000 /* Line block extra size */
- X
- X/*
- X * This is the number of bytes that are allocated for the kill buffer
- X * when data cannot be moved by changing the pointers.
- X */
- X#define KBLOCK 0x1000 /* Kill buffer block size. */
- X
- X/*
- X * Universal.
- X */
- X#define FALSE 0 /* False, no, bad, etc. */
- X#define TRUE 1 /* True, yes, good, etc. */
- X#define ABORT 2 /* Death, ^G, abort, etc. */
- X
- X/*
- X * These flag bits keep track of
- X * some aspects of the last command.
- X * The CFKILL flag controls the clearing versus appending
- X * of data in the kill buffer.
- X */
- X#define CFKILL 0x0002 /* Last command was a kill */
- X
- X/*
- X * File I/O.
- X */
- X#define FIOSUC 0 /* Success. */
- X#define FIOFNF 1 /* File not found. */
- X#define FIOEOF 2 /* End of file. */
- X#define FIOERR 3 /* Error. */
- X
- X/*
- X * Directory I/O.
- X */
- X#define DIOSUC 0 /* Success. */
- X#define DIOEOF 1 /* End of file. */
- X#define DIOERR 2 /* Error. */
- X
- X/*
- X * Display colors.
- X */
- X#define CNONE 0 /* Unknown color. */
- X#define CTEXT 1 /* Text color. */
- X#define CMODE 2 /* Mode line color. */
- X
- X/*
- X * Flags for "eread".
- X */
- X#define EFNEW 0x0001 /* New prompt. */
- X#define EFAUTO 0x0002 /* Autocompletion enabled. */
- X#define EFCR 0x0004 /* Echo CR at end; last read. */
- X
- X/*
- X * Keys are represented inside using an 11 bit
- X * keyboard code. The transformation between the keys on
- X * the keyboard and 11 bit code is done by terminal specific
- X * code in the "kbd.c" file. The actual character is stored
- X * in 8 bits (DEC multinationals work); there is also a control
- X * flag KCTRL, a meta flag KMETA, and a control-X flag KCTLX.
- X * ASCII control characters are always represented using the
- X * KCTRL form. Although the C0 control set is free, it is
- X * reserved for C0 controls because it makes the communication
- X * between "getkey" and "getkbd" easier. The funny keys get
- X * mapped into the C1 control area.
- X */
- X#define NKEYS 2048 /* 11 bit code. */
- X
- X#define METACH 0x1B /* M- prefix, Control-[, ESC */
- X#define CTMECH 0x1C /* C-M- prefix, Control-\ */
- X#define EXITCH 0x1D /* Exit level, Control-] */
- X#define CTRLCH 0x1E /* C- prefix, Control-^ */
- X#define HELPCH 0x1F /* Help key, Control-_ */
- X#define CTL_G 0x07 /* Abort command key */
- X
- X#define KCHAR 0x00FF /* The basic character code. */
- X#define KCTRL 0x0100 /* Control flag. */
- X#define KMETA 0x0200 /* Meta flag. */
- X#define KCTLX 0x0400 /* Control-X flag. */
- X
- X#define KFIRST 0x0080 /* First special. fitz */
- X#define KLAST 0x00F3 /* Last special. */
- X
- X#define KRANDOM 0x0080 /* A "no key" code. */
- X
- X/*
- X* This causes the key sequence ESC [ <key> to be delevered as
- X* KCTRL | KMETA | KCTLX | <key>. This allows VT100 function keys
- X* to be bound.
- X*/
- X#define VT100KEY
- X
- X/*
- X * These define the column used in the help (wallchart) function
- X */
- X#define HFUNCCOL 3
- X#define HKEY 32
- X#define HKEYCODE 50
- X#define HENDCOL 55
- X
- X/*
- X * These flags, and the macros below them,
- X * make up a do-it-yourself set of "ctype" macros that
- X * understand the DEC multinational set, and let me ask
- X * a slightly different set of questions.
- X */
- X#define _W 0x01 /* Word. */
- X#define _U 0x02 /* Upper case letter. */
- X#define _L 0x04 /* Lower case letter. */
- X#define _C 0x08 /* Control. */
- X
- X#define ISCTRL(c) ((cinfo[(c)]&_C)!=0)
- X#define ISUPPER(c) ((cinfo[(c)]&_U)!=0)
- X#define ISLOWER(c) ((cinfo[(c)]&_L)!=0)
- X#define TOUPPER(c) ((c)-0x20)
- X#define TOLOWER(c) ((c)+0x20)
- X
- X#define BUF_SIZE(wp) (wp -> w_bufp -> b_linep -> l_bp -> l_file_offset + \
- X wp -> w_bufp -> b_linep -> l_bp -> l_used)
- X#define BUF_START(wp) (wp -> w_bufp -> b_linep -> l_fp -> l_file_offset)
- X#define DOT_POS(wp) (wp -> w_dotp -> l_file_offset + wp -> w_doto)
- X#define MARK_POS(wp) (wp -> w_markp -> l_file_offset + wp -> w_marko)
- X#define DOT_CHAR(wp) (wp -> w_dotp -> l_text[wp -> w_doto])
- X#define WIND_POS(wp) (wp -> w_linep -> l_file_offset + wp -> w_loff)
- X#define R_TYPE(wp) (wp -> w_fmt_ptr -> r_type)
- X#define R_SIZE(wp) (wp -> w_fmt_ptr -> r_size)
- X#define R_UNITS(wp) (wp -> w_fmt_ptr -> r_units)
- X#define R_BYTES(wp) (wp -> w_fmt_ptr -> r_bytes)
- X#define R_ALIGN(wp) (wp -> w_fmt_ptr -> r_align)
- X#define R_B_PER_U(wp) (wp -> w_fmt_ptr -> r_b_per_u)
- X#define R_CHR_PER_U(wp) (wp -> w_fmt_ptr -> r_chr_per_u)
- X#define R_FLAGS(wp) (wp -> w_fmt_ptr -> r_flags)
- X#define R_UNIT_FMT(wp) (wp -> w_fmt_ptr -> r_unit_fmt)
- X#define R_POS_FMT(wp) (wp -> w_fmt_ptr -> r_pos_fmt)
- X#define R_BYTE_FMT(wp) (wp -> w_fmt_ptr -> r_byte_fmt)
- X#define R_POSITIONS(wp) (wp -> w_fmt_ptr -> r_positions)
- X
- X/*
- X * The symbol table links editing functions
- X * to names. Entries in the key map point at the symbol
- X * table entry. A reference count is kept, but it is
- X * probably next to useless right now. The old type code,
- X * which was not being used and probably not right
- X * anyway, is all gone.
- X */
- Xtypedef struct SYMBOL {
- X struct SYMBOL *s_symp; /* Hash chain. */
- X short s_nkey; /* Count of keys bound here. */
- X char *s_name; /* Name. */
- X bool (*s_funcp)(); /* Function. */
- X bits s_modify; /* modify bit */
- X} SYMBOL;
- X
- X/*
- X* These are the legal values for 's_modify' and 'k_modify'
- X*/
- X#define SMOD 0x01 /* command modifies the buffer */
- X#define SSIZE 0x02 /* command changes buffer size */
- X#define SSRCH 0x04 /* command valid in search */
- X#define SRPLC 0x08 /* command valid in replace */
- X#define SBOUND 0x10 /* key was bound bu user or rc file */
- X
- X/*
- X * There is a window structure allocated for
- X * every active display window. The windows are kept in a
- X * big list, in top to bottom screen order, with the listhead at
- X * "wheadp". Each window contains its own values of dot and mark.
- X * The flag field contains some bits that are set by commands
- X * to guide redisplay; although this is a bit of a compromise in
- X * terms of decoupling, the full blown redisplay is just too
- X * expensive to run for every input character.
- X */
- Xtypedef struct WINDOW {
- X struct WINDOW *w_wndp; /* Next window */
- X struct BUFFER *w_bufp; /* Buffer displayed in window */
- X struct LINE *w_linep; /* Top line in the window */
- X LPOS w_loff; /* Offset into line for start pvr */
- X A32 w_wind_temp; /* temp storage for window file pos */
- X struct LINE *w_dotp; /* Line containing "." */
- X LPOS w_doto; /* Offset into line for "." */
- X A32 w_dot_temp; /* temp storage for dot file pos */
- X struct LINE *w_markp; /* Line containing "mark" */
- X LPOS w_marko; /* Byte offset for "mark" */
- X A32 w_mark_temp; /* temp storage for mark file pos */
- X char w_unit_offset; /* Byte offset for "." into unit pvr */
- X char w_toprow; /* Origin 0 top row of window */
- X char w_ntrows; /* # of rows of text in window */
- X bits w_flag; /* Flags. */
- X char w_disp_shift; /* Display byte shift; 0-3 pvr */
- X bool w_intel_mode; /* Display byte swaped. pvr */
- X struct ROW_FMT *w_fmt_ptr; /* Pointer to display format pvr */
- X} WINDOW;
- X
- X/*
- X * Window flags are set by command processors to
- X * tell the display system what has happened to the buffer
- X * mapped by the window. Setting "WFHARD" is always a safe thing
- X * to do, but it may do more work than is necessary. Always try
- X * to set the simplest action that achieves the required update.
- X * Because commands set bits in the "w_flag", update will see
- X * all change flags, and do the most general one.
- X */
- X#define WFFORCE 0x01 /* Force reframe. */
- X#define WFMOVE 0x02 /* Movement from line to line. */
- X#define WFEDIT 0x04 /* Editing within a line. */
- X#define WFHARD 0x08 /* Better to a full display. */
- X#define WFMODE 0x10 /* Update mode line. */
- X/*
- X* This structure contains how a row is constructed. pvr
- X*/
- X
- Xtypedef struct ROW_FMT {
- X uchar r_type; /* format type nibbles */
- X uchar r_size; /* format size: must be 0,1,3,7,15, etc */
- X uchar r_units; /* number of units per window row: must be 1,2,4,8,16*/
- X uchar r_bytes; /* number of bytes per window row: must be 1,2,4,8,16*/
- X uchar r_align; /* number of bytes per align row: must be 1,2,4,8,16*/
- X uchar r_b_per_u; /* number of bytes per unit: must be 1,2,4,8,16 */
- X uchar r_chr_per_u; /* displayed chars per unit */
- X bits r_flags; /* flags controlling format */
- X char *r_unit_fmt; /* print format for unit */
- X char *r_pos_fmt; /* print format for buffer position, always a long */
- X char *r_byte_fmt; /* print format for bytes */
- X uchar *r_positions; /* list of unit positions */
- X struct ROW_FMT *r_srch_fmt; /* pointer to search display format */
- X} ROW_FMT;
- X
- X/* legal values for 'r_size' (values significant; used as bit mask) pvr */
- X
- X#define BYTES 0x00 /* Display as byte; 8 bits */
- X#define WORDS 0x01 /* Display as word; 16 bits */
- X#define DWORDS 0x03 /* Display as doubles; 32 bits */
- X
- X/* legal values for 'r_type' pvr */
- X#define ASCII 0x10 /* Display as ascii */
- X#define OCTAL 0x20 /* Display as octal values */
- X#define DECIMAL 0x30 /* Display as decimal values */
- X#define HEX 0x40 /* Display as hex values */
- X#define BINARY 0x50 /* Display as binary values */
- X#define EBCDIC 0x60 /* Display as ebcdic */
- X#define TEXT 0x70 /* Display as normal text */
- X
- X/*
- X * Text is kept in buffers. A buffer header, described
- X * below, exists for every buffer in the system. The buffers are
- X * kept in a big list, so that commands that search for a buffer by
- X * name can find the buffer header. There is a safe store for the
- X * dot and mark in the header, but this is only valid if the buffer
- X * is not being displayed (that is, if "b_nwnd" is 0). The text for
- X * the buffer is kept in a circularly linked list of lines, with
- X * a pointer to the header line in "b_linep".
- X */
- Xtypedef struct BUFFER {
- X bits b_type; /* Type of buffer */
- X struct BUFFER *b_bufp; /* Link to next BUFFER */
- X struct LINE *b_dotp; /* Link to "." LINE structure */
- X LPOS b_doto; /* Offset of "." in above LINE */
- X char b_unit_offset; /* Offset into unit for "." pvr */
- X struct LINE *b_markp; /* The same as the above two, */
- X LPOS b_marko; /* but for the "mark" */
- X struct LINE *b_linep; /* Link to the header LINE */
- X char b_nwnd; /* Count of windows on buffer */
- X bits b_flag; /* Flags */
- X A32 b_begin_addr; /* File address of begining of buffer */
- X A32 b_end_addr; /* File address of end of buffer */
- X A32 b_file_size; /* Size of file */
- X char b_fname[NFILEN]; /* File name */
- X char b_bname[NBUFN]; /* Buffer name */
- X} BUFFER;
- X
- X/* Values for 'buf_type' */
- X#define BTFILE 0x00 /* Buffer contains a file */
- X#define BTDISK 0x01 /* Buffer points to a disk */
- X#define BTMEMORY 0x02 /* Buffer points to memory */
- X#define BTSAVE 0x03 /* This is the save buffer */
- X#define BTLIST 0x04 /* This is the buffer list */
- X#define BTHELP 0x05 /* This is the help buffer */
- X
- X/* Values for 'b_flag' */
- X
- X#define BFCHG 0x01 /* Changed. */
- X#define BFBAK 0x02 /* Need to make a backup. */
- X#define BFBAD 0x04 /* may be trashed alloc error? */
- X#define BFINMEM 0x08 /* File is entirely in memory */
- X#define BFVIEW 0x10 /* read only (jam) */
- X#define BFLINK 0x20 /* Linked mode pvr */
- X#define BFSLOCK 0x40 /* Lock buffer size pvr */
- X/*
- X * This structure holds the starting position
- X * (as a line/offset pair) and the number of characters in a
- X * region of a buffer. This makes passing the specification
- X * of a region around a little bit easier.
- X * There have been some complaints that the short in this
- X * structure is wrong; that a long would be more appropriate.
- X * I'll await more comments from the folks with the little
- X * machines; I have a VAX, and everything fits.
- X */
- Xtypedef struct reg {
- X struct LINE *r_linep; /* Origin LINE address. */
- X LPOS r_offset; /* Origin LINE offset. */
- X A32 r_size; /* Length in characters. */
- X} REGION;
- X
- X/*
- X * All text is kept in circularly linked
- X * lists of "LINE" structures. These begin at the
- X * header line (which is the blank line beyond the
- X * end of the buffer). This line is pointed to by
- X * the "BUFFER". Each line contains a the number of
- X * bytes in the line (the "used" size), the size
- X * of the text array, and the text. The end of line
- X * is not stored as a byte; it's implied. Future
- X * additions will include update hints, and a
- X * list of marks into the line.
- X */
- Xtypedef struct LINE {
- X struct LINE *l_fp; /* Link to the next line */
- X struct LINE *l_bp; /* Link to the previous line */
- X A32 l_file_offset; /* Offset from begining of file pvr */
- X LPOS l_size; /* Allocated size */
- X LPOS l_used; /* Used size */
- X#if PCC
- X D8 l_text[1]; /* A bunch of characters. */
- X#else
- X D8 l_text[]; /* A bunch of characters. */
- X#endif
- X} LINE;
- X
- X/*
- X * The rationale behind these macros is that you
- X * could (with some editing, like changing the type of a line
- X * link from a "LINE *" to a "REFLINE", and fixing the commands
- X * like file reading that break the rules) change the actual
- X * storage representation of lines to use something fancy on
- X * machines with small address spaces.
- X */
- X#define lforw(lp) ((lp)->l_fp)
- X#define lback(lp) ((lp)->l_bp)
- X#define lgetc(lp, n) ((lp)->l_text[(n)]&0xFF)
- X#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c))
- X#define llength(lp) ((lp)->l_used)
- X
- X/*
- X * Externals.
- X */
- Xextern int thisflag;
- Xextern int lastflag;
- Xextern int curgoal;
- Xextern int epresf;
- Xextern int sgarbf;
- Xextern WINDOW *curwp;
- Xextern BUFFER *curbp;
- Xextern WINDOW *wheadp;
- Xextern BUFFER *bheadp;
- Xextern BUFFER *blistp;
- Xextern short kbdm[];
- Xextern short *kbdmip;
- Xextern short *kbdmop;
- Xextern SYMBOL *symbol[];
- Xextern SYMBOL *binding[];
- Xextern BUFFER *bfind();
- Xextern BUFFER *bcreate();
- Xextern WINDOW *wpopup();
- Xextern LINE *lalloc();
- Xextern int nrow;
- Xextern int ncol;
- Xextern char version[];
- Xextern int ttrow;
- Xextern int ttcol;
- Xextern int tceeol;
- Xextern int tcinsl;
- Xextern int tcdell;
- Xextern char cinfo[];
- Xextern SYMBOL *symlookup();
- Xextern int nmsg;
- Xextern int curmsgf;
- Xextern int newmsgf;
- Xextern char msg[];
- X
- X/* jam
- X */
- Xextern char *okmsg;
- Xextern int insert_mode;
- Xextern int extend_buf;
- Xextern int flush_num;
- Xextern int auto_update;
- Xextern int flush_count;
- Xextern int rowb;
- Xextern char file_off_bad;
- X
- X/*
- X * Standard I/O.
- X */
- Xextern char *malloc();
- Xextern char *strcpy();
- Xextern char *strcat();
- END_OF_FILE
- if test 21214 -ne `wc -c <'def.h'`; then
- echo shar: \"'def.h'\" unpacked with wrong size!
- fi
- # end of 'def.h'
- fi
- if test -f 'fileio.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fileio.c'\"
- else
- echo shar: Extracting \"'fileio.c'\" \(5255 characters\)
- sed "s/^X//" >'fileio.c' <<'END_OF_FILE'
- X/*
- X* file I/O.
- X*/
- X
- X#ifdef UNIX
- X#include <sys/types.h>
- X#include <fcntl.h>
- X#include <sys/stat.h>
- X#endif
- X#ifdef AMIGA
- X#include <sys/types.h>
- X#include <fcntl.h>
- X#include <sys/stat.h>
- X#endif
- X#include "def.h"
- X
- Xextern char MSG_cnt_wr[];
- Xextern char MSG_wr_io_er[];
- Xextern char MSG_rd_er[];
- Xextern char MSG_bak[];
- Xextern char MSG_backup[];
- Xextern char MSG_back_er[];
- Xextern char MSG_back_of[];
- X
- X#ifdef MSDOS
- Xstatic FILE * ffp;
- X#endif
- X
- X#ifdef UNIX
- Xstatic int ffp;
- X#endif
- X
- X#ifdef AMIGA
- Xstatic int ffp;
- X#endif
- X
- X/*
- X* Open a file for reading.
- X*/
- Xchar ffropen (fn)
- Xchar *fn;
- X{
- X#ifdef MSDOS
- X if ((ffp = fopen (fn, "rb")) == NULL)/* pvr */
- X return (FIOERR);
- X ;
- X return (FIOSUC);
- X#endif
- X#ifdef UNIX
- X if ((ffp = open (fn, O_RDONLY)) == -1)/* pvr */
- X return (FIOERR);
- X ;
- X return (FIOSUC);
- X#endif
- X#ifdef AMIGA
- X if ((ffp = open (fn, O_RDONLY)) == -1)/* pvr */
- X return (FIOERR);
- X ;
- X return (FIOSUC);
- X#endif
- X}
- X/*
- X* Get the file length
- X*/
- X#ifdef AMIGA
- XA32 file_len(char *fname)
- X{
- X struct stat st;
- X
- X if (stat (fname, &st) == -1)
- X return (-1);
- X return (st.st_size);
- X}
- X#else /* AMIGA */
- XA32 file_len ()
- X{
- X#ifdef MSDOS
- X return (filelength (fileno (ffp)));
- X#endif
- X#ifdef UNIX
- X struct stat st;
- X
- X if (fstat (ffp, &st) == -1)
- X return (-1);
- X return (st.st_size);
- X#endif
- X}
- X#endif /* AMIGA */
- X
- X/*
- X* Open a file for writing.
- X* Set file permissions as requested
- X* Return TRUE if all is well, and
- X* FALSE on error (cannot create).
- X*/
- Xchar ffwopen (fn, mode)
- Xchar *fn;
- Xushort mode;
- X{
- X#ifdef MSDOS
- X if ((ffp = fopen (fn, "wb")) == NULL)/* pvr */
- X {
- X err_echo (MSG_cnt_wr);
- X return (FIOERR);
- X }
- X return (FIOSUC);
- X#endif
- X#ifdef UNIX
- X /* set perms as in original file 1.31 */
- X if ((ffp = open (fn, O_WRONLY | O_CREAT, mode)) == -1)/* pvr */
- X return (FIOERR);
- X ;
- X return (FIOSUC);
- X#endif
- X#ifdef AMIGA
- X /* set perms as in original file 1.31 */
- X if ((ffp = open (fn, O_WRONLY | O_CREAT, mode)) == -1)/* pvr */
- X return (FIOERR);
- X ;
- X return (FIOSUC);
- X#endif
- X}
- X
- X/*
- X* Close a file.
- X* Should look at the status.
- X*/
- Xchar ffclose ()
- X{
- X#ifdef MSDOS
- X fclose (ffp);
- X#endif
- X#ifdef UNIX
- X close (ffp);
- X#endif
- X return (FIOSUC);
- X#ifdef AMIGA
- X close (ffp);
- X#endif
- X return (FIOSUC);
- X}
- X
- X/*
- X* Write a line to the already
- X* opened file. The "buf" points to the
- X* buffer, and the "nbuf" is its length. pvr
- X* Return the status.
- X*/
- Xchar ffputline (buf, nbuf)
- Xregister char buf[];
- Xint nbuf;
- X{
- X register int i;
- X
- X#ifdef MSDOS
- X i = fwrite (buf, 1, nbuf, ffp);
- X#endif
- X#ifdef UNIX
- X i = write (ffp, buf, nbuf);
- X#endif
- X#ifdef AMIGA
- X i = write (ffp, buf, nbuf);
- X#endif
- X
- X if ((i != nbuf)
- X#ifdef MSDOS
- X || (ferror (ffp) != FALSE))
- X#else
- X )
- X#endif
- X {
- X err_echo (MSG_wr_io_er);
- X return (FIOERR);
- X }
- X return (FIOSUC);
- X}
- X
- X/*
- X* Read a line from a file, and store the bytes
- X* in the supplied buffer. Stop on end of file or after 'nbuf' characters. pvr
- X* the first byte in the buffer is the length in bytes.
- X*/
- Xchar ffgetline (buf, nbuf, rbuf)
- Xregister char *buf;
- Xregister LPOS *rbuf, nbuf;
- X{
- X#ifdef MSDOS
- X *rbuf = fread (buf, 1, nbuf, ffp);
- X#endif
- X
- X#ifdef UNIX
- X *rbuf = read (ffp, buf, nbuf);
- X#endif
- X#ifdef AMIGA
- X *rbuf = read (ffp, buf, nbuf);
- X#endif
- X
- X /* End of file. */
- X#ifdef MSDOS
- X if (ferror (ffp) != FALSE)
- X {
- X err_echo (MSG_rd_er);
- X return (FIOERR);
- X }
- X#endif
- X if (*rbuf == 0)
- X return (FIOEOF);
- X
- X return (FIOSUC);
- X}
- X
- X/*
- X* Seek to specified position in file.
- X* Return the actual position in the file.
- X*/
- XA32 ffseek (posn)
- XA32 posn;
- X{
- X#ifdef MSDOS
- X fseek (ffp, posn, SEEK_SET);
- X return (ftell (ffp));
- X#endif
- X#ifdef UNIX
- X return (lseek (ffp, posn, 0));
- X#endif
- X#ifdef AMIGA
- X return (lseek (ffp, posn, 0));
- X#endif
- X}
- X
- X/*
- X* Some backup user on MS-DOS might want
- X* to determine some rule for doing backups on that
- X* system, and fix this. I don't use MS-DOS, so I don't
- X* know what the right rules would be. Return TRUE so
- X* the caller does not abort a write.
- X* Under UNIX just append the .bak postfix.
- X*/
- X#ifdef BACKUP
- Xbool fbackupfile (fname)
- Xchar *fname;
- X{
- X char backname[NFILEN];
- X char *source,
- X *backup;
- X char buf[NCOL];
- X
- X source = fname;
- X backup = backname;
- X while ((*source > 0)
- X#ifdef MSDOS
- X && (*source != '.'))
- X#else
- X )
- X#endif
- X {
- X *backup = *source;
- X backup++;
- X source++;
- X *backup = 0;
- X }
- X strcat (backname, MSG_bak);
- X sprintf (buf, MSG_backup, fname, backname);
- X writ_echo (buf);
- X unlink (backname);
- X#ifdef NORENAME
- X if ((link (fname, backname) != 0) || (unlink (fname) != 0))
- X#else
- X if (rename (fname, backname) > 0)
- X#endif
- X {
- X sprintf (buf, MSG_back_er, fname, backname);
- X err_echo (buf);
- X return (FALSE);
- X }
- X return (TRUE); /* Hack. */
- X}
- X
- X#endif
- X
- X/*
- X* The string "fn" is a file name.
- X* Perform any required case adjustments. All systems
- X* we deal with so far have case insensitive file systems.
- X* We zap everything to lower case. The problem we are trying
- X* to solve is getting 2 buffers holding the same file if
- X* you visit one of them with the "caps lock" key down.
- X* On UNIX and AMIGA file names are dual case, so we leave
- X* everything alone.
- X*/
- Xvoid adjustcase (fn)
- Xregister char *fn;
- X{
- X register int c;
- X
- X while ((c = *fn) != 0)
- X {
- X if (c >= 'A' && c <= 'Z')
- X *fn = c + 'a' - 'A';
- X ++fn;
- X }
- X}
- END_OF_FILE
- if test 5255 -ne `wc -c <'fileio.c'`; then
- echo shar: \"'fileio.c'\" unpacked with wrong size!
- fi
- # end of 'fileio.c'
- fi
- if test -f 'search.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'search.c'\"
- else
- echo shar: Extracting \"'search.c'\" \(24696 characters\)
- sed "s/^X//" >'search.c' <<'END_OF_FILE'
- X/*
- X* Search commands.
- X* The functions in this file implement the
- X* search commands (both plain and incremental searches
- X* are supported) and the query-replace command.
- X*/
- X#include "def.h"
- X
- Xchar replaceit ();
- Xchar forwsrch ();
- Xchar backsrch ();
- Xchar readpattern ();
- Xvoid next_pat ();
- X
- Xextern char MSG_sch_str[];
- Xextern char MSG_bsrc_str[];
- Xextern char MSG_rpl_str[];
- Xextern char MSG_pat_fnd[];
- Xextern char MSG_no_srch[];
- Xextern char MSG_fnd_at[];
- Xextern char MSG_no_rpl[];
- Xextern char MSG_1_rpl[];
- Xextern char MSG_n_rpl[];
- Xextern char MSG_srcing[];
- Xextern char MSG_curs[];
- Xextern char MSG_cmp_end[];
- Xextern char MSG_cmp_term[];
- Xextern char MSG_cmp_dif[];
- Xextern char MSG_only_2[];
- Xextern char MSG_cmping[];
- Xextern char MSG_not_fnd[];
- X#if RUNCHK
- Xextern char ERR_rdpat[];
- Xextern char ERR_mask[];
- Xextern char ERR_m_cl[];
- X#endif
- X
- X#define CCHR(x) ((x)-'@')
- X
- X#define SRCH_BEGIN (0) /* Search sub-codes. */
- X#define SRCH_FORW (-1)
- X#define SRCH_BACK (-2)
- X#define SRCH_PREV (-3)
- X#define SRCH_NEXT (-4)
- X#define SRCH_NOPR (-5)
- X#define SRCH_ACCM (-6)
- X
- Xtypedef struct
- X{
- X int s_code;
- X LINE * s_dotp;
- X short s_doto;
- X}SRCHCOM;
- X
- X#define MAX_PAT 260
- X
- Xextern ROW_FMT hex_s_8_fmt;
- Xextern ROW_FMT ascii_s_fmt;
- X
- Xbool recall_flag = FALSE;
- Xbool read_pat_mode = FALSE;
- Xbool srch_mode = FALSE;
- Xbool rplc_mode = FALSE;
- Xbool dont_repeat = FALSE; /* used to prevent toggling commands from */
- X/* failing in read_pattern */
- Xstatic char srch_patb[MAX_PAT];
- Xstatic char srch_maskb[MAX_PAT];
- Xstatic char rplc_patb[MAX_PAT];
- Xstatic char rplc_maskb[MAX_PAT];
- X
- Xstatic LINE *srch_pat = (LINE *)srch_patb;
- Xstatic LINE *srch_mask = (LINE *)srch_maskb;
- Xstatic LINE *cur_pat;
- Xstatic LINE *cur_mask;
- Xstatic LINE *rplc_pat = (LINE *)rplc_patb;
- Xstatic LINE *rplc_mask = (LINE *)rplc_maskb;
- X
- Xstatic int old_srch_pat_size = 0;/* for pattern recall */
- Xstatic int old_rplc_pat_size = 0;
- Xstatic ROW_FMT *old_fmt = &hex_s_8_fmt;
- X
- Xchar *cur_prompt;
- X
- Xint srch_lastdir = SRCH_NOPR;/* Last search flags. */
- X
- X/*
- X* Search forward.
- X* Get a search string from the user, and search for it,
- X* starting at ".". If found, "." gets moved to the
- X* first matched character, and display does all the hard stuff.
- X* If not found, it just prints a message.
- X*/
- Xchar forwsearch ()
- X{
- X register char s;
- X char buf[NCOL], buf1[NCOL];
- X
- X srch_mode = TRUE;
- X rplc_mode = FALSE;
- X cur_prompt = MSG_sch_str;
- X if ((s = readpattern ()) != TRUE)
- X {
- X srch_mode = FALSE;
- X eerase (); /* clear message line */
- X return (s);
- X }
- X if (forwsrch () == FALSE)
- X {
- X writ_echo (MSG_not_fnd);
- X srch_mode = FALSE;
- X return (FALSE);
- X }
- X srch_lastdir = SRCH_FORW;
- X curwp -> w_flag |= WFMODE; /* update mode line */
- X curwp -> w_unit_offset = 0;
- X /* build format */
- X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
- X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
- X curwp -> w_doto);
- X writ_echo (buf);
- X srch_mode = FALSE;
- X return (TRUE);
- X}
- X
- X
- X/*
- X* Reverse search.
- X* Get a search string from the user, and search, starting at "."
- X* and proceeding toward the front of the buffer. If found "." is left
- X* pointing at the first character of the pattern [the last character that
- X* was matched].
- X*/
- Xchar backsearch ()
- X{
- X register char s;
- X char buf[NCOL], buf1[NCOL];
- X
- X srch_mode = TRUE;
- X rplc_mode = FALSE;
- X cur_prompt = MSG_bsrc_str;
- X if ((s = readpattern ()) != TRUE)
- X {
- X srch_mode = FALSE;
- X eerase (); /* clear message line */
- X return (s);
- X }
- X if (backsrch () == FALSE)
- X {
- X writ_echo (MSG_not_fnd);
- X srch_mode = FALSE;
- X return (FALSE);
- X }
- X srch_lastdir = SRCH_BACK;
- X curwp -> w_flag |= WFMODE; /* update mode line */
- X curwp -> w_unit_offset = 0;
- X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
- X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
- X curwp -> w_doto);
- X writ_echo (buf);
- X srch_mode = FALSE;
- X return (TRUE);
- X}
- X
- X
- X/*
- X* Search again, using the same search string
- X* and direction as the last search command. The direction
- X* has been saved in "srch_lastdir", so you know which way
- X* to go.
- X*/
- Xchar searchagain ()
- X{
- X char buf[NCOL], buf1[NCOL];
- X long dot_pos;
- X srch_mode = TRUE;
- X rplc_mode = FALSE;
- X
- X dot_pos = DOT_POS(curwp);
- X if (srch_lastdir == SRCH_FORW)
- X {
- X /* advance one unit so we don't find the same thing again */
- X move_ptr (curwp, dot_pos + 1, TRUE, FALSE, FALSE);
- X if (forwsrch () == FALSE)
- X { /* go back to orig pt */
- X move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
- X writ_echo (MSG_not_fnd);
- X srch_mode = FALSE;
- X return (FALSE);
- X }
- X curwp -> w_flag |= WFMODE; /* update mode line */
- X curwp -> w_unit_offset = 0;
- X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
- X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
- X curwp -> w_doto);
- X writ_echo (buf);
- X srch_mode = FALSE;
- X return (TRUE);
- X }
- X if (srch_lastdir == SRCH_BACK)
- X {
- X /* step back one unit so we don't find the same thing again */
- X move_ptr (curwp, dot_pos - 1, TRUE, FALSE, FALSE);
- X if (backsrch () == FALSE)
- X { /* go back to orig pt */
- X move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
- X writ_echo (MSG_not_fnd);
- X srch_mode = FALSE;
- X return (FALSE);
- X }
- X curwp -> w_flag |= WFMODE; /* update mode line */
- X curwp -> w_unit_offset = 0;
- X sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
- X sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
- X curwp -> w_doto);
- X writ_echo (buf);
- X srch_mode = FALSE;
- X return (TRUE);
- X }
- X writ_echo (MSG_no_srch);
- X srch_mode = FALSE;
- X return (FALSE);
- X}
- X
- X
- X/*
- X* Query Replace.
- X* Replace strings selectively. Does a search and replace operation.
- X* A space or a comma replaces the string, a period replaces and quits,
- X* an n doesn't replace, a C-G quits.
- X* (note typical hack to add a function with minimal code)
- X*/
- Xchar queryrepl (f, n, k)
- X{
- X
- X register char s;
- X
- X srch_mode = FALSE;
- X rplc_mode = TRUE;
- X cur_prompt = MSG_sch_str;
- X if (s = readpattern ())
- X {
- X replaceit ();
- X }
- X srch_mode = FALSE;
- X rplc_mode = FALSE;
- X return (s);
- X}
- X
- X
- Xchar replaceit ()
- X{
- X int rcnt = 0; /* Replacements made so far */
- X int plen; /* length of found string */
- X int rlen; /* length of replace string */
- X long abs_dot_p; /* absolute dot position */
- X long abs_mark_p; /* absolute mark position */
- X char buf[NCOL], buf1[NCOL];
- X
- X /*
- X * Search forward repeatedly, checking each time whether to insert
- X * or not. The "!" case makes the check always true, so it gets put
- X * into a tighter loop for efficiency.
- X *
- X * If we change the line that is the remembered value of dot, then
- X * it is possible for the remembered value to move. This causes great
- X * pain when trying to return to the non-existant line.
- X *
- X * possible fixes:
- X * 1) put a single, relocated marker in the WINDOW structure, handled
- X * like mark. The problem now becomes a what if two are needed...
- X * 2) link markers into a list that gets updated (auto structures for
- X * the nodes)
- X * 3) Expand the mark into a stack of marks and add pushmark, popmark.
- X */
- X
- X plen = srch_pat -> l_used;
- X rlen = rplc_pat -> l_used;
- X
- X abs_dot_p = DOT_POS(curwp); /* save current dot position */
- X if (curwp->w_markp != NULL) /* mark may not be set */
- X abs_mark_p = MARK_POS(curwp);
- X
- X while (forwsrch () == TRUE)
- X {
- Xretry:
- X sprintf (buf1, MSG_fnd_at, R_POS_FMT(curwp));
- X sprintf (buf, buf1, DOT_POS(curwp));
- X writ_echo (buf);
- X curwp -> w_flag |= WFMODE; /* update mode line */
- X update ();
- X switch (ttgetc ())
- X {
- X case 'r':
- X case 'R':
- X case ' ':
- X case ',':
- X /* update has fixedup the dot position so move to found byte */
- X /* go and do the replace */
- X if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
- X return (FALSE);
- X /* begin searching after replace string */
- X move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
- X rcnt++;
- X break;
- X
- X case 'o':
- X case 'O':
- X case '.':
- X if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
- X return (FALSE);
- X /* begin searching after replace string */
- X move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
- X rcnt++;
- X goto stopsearch;
- X
- X case 'q':
- X case 'Q':
- X case CCHR ('G'):
- X ctrlg (FALSE, 0, KRANDOM);
- X goto stopsearch;
- X
- X case 'a':
- X case 'A':
- X case '!':
- X do
- X {
- X if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
- X return (FALSE);
- X /* begin searching after replace string */
- X move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
- X rcnt++;
- X } while (forwsrch () == TRUE);
- X goto stopsearch;
- X
- X case 's':
- X case 'S':
- X case 'n':
- X /* begin searching after this byte */
- X move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
- X break;
- X
- X default:
- X ttbeep ();
- X goto retry;
- X }
- X }
- X
- Xstopsearch:
- X move_ptr (curwp, abs_dot_p, TRUE, TRUE, FALSE);
- X if (curwp -> w_markp != NULL)
- X {
- X swapmark ();
- X /* insure that the mark points to the same byte as before */
- X if (abs_mark_p > abs_dot_p)
- X move_ptr (curwp, abs_mark_p + rlen - plen, TRUE, FALSE, FALSE);
- X else
- X move_ptr (curwp, abs_mark_p, TRUE, FALSE, FALSE);
- X swapmark ();
- X }
- X curwp -> w_flag |= WFHARD;
- X update ();
- X if (rcnt == 0)
- X {
- X writ_echo (MSG_no_rpl);
- X }
- X else if (rcnt == 1)
- X {
- X writ_echo (MSG_1_rpl);
- X }
- X else
- X {
- X sprintf (buf1, MSG_n_rpl, R_POS_FMT(curwp));
- X sprintf (buf, buf1, (ulong)rcnt);
- X writ_echo (buf);
- X }
- X flush_count += rcnt; /* jam for auto write buffers */
- X return (TRUE);
- X}
- X
- X
- X/*
- X* This routine does the real work of a
- X* forward search. The pattern is sitting in the external
- X* variable "srch_pat" the mask if in "srch_mask".
- X* If found, dot is updated, the window system
- X* is notified of the change, and TRUE is returned. If the
- X* string isn't found, FALSE is returned.
- X*/
- Xchar forwsrch ()
- X{
- X register LINE *save_dotp, *save2_dotp;
- X register int save_doto, save2_doto;
- X register D8 *pat_ptr, *mask_ptr;
- X register int i, j, pat_cnt;
- X register D8 first_pat, first_mask;
- X char buf[NCOL], buf1[NCOL];
- X
- X save_dotp = curwp -> w_dotp; /* save dot position for later */
- X save_doto = curwp -> w_doto;
- X pat_ptr = srch_pat -> l_text;
- X mask_ptr = srch_mask -> l_text;
- X pat_cnt = srch_pat -> l_used;
- X first_mask = mask_ptr[0];
- X first_pat = pat_ptr[0] | first_mask;
- X j = (int)DOT_POS(curwp) & 0xffff;
- X
- X do
- X {
- X if ((j++ & 0x2ff) == 0)
- X {
- X sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
- X sprintf (buf, buf1, DOT_POS(curwp));
- X writ_echo (buf);
- X /* check if we should quit */
- X if (ttkeyready ())
- X {
- X if (ttgetc () == CTL_G)
- X break;
- X }
- X }
- X if (first_pat ==
- X ((DOT_CHAR(curwp) | first_mask) & 0xff))
- X {
- X save2_dotp = curwp -> w_dotp; /* save dot position for later */
- X save2_doto = curwp -> w_doto;
- X for (i = 1; i < pat_cnt; i++)
- X {
- X if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
- X ((pat_ptr[i] & ~mask_ptr[i]) !=
- X (DOT_CHAR(curwp) & ~mask_ptr[i])))
- X { /* not found */
- X curwp -> w_dotp = save2_dotp; /* restore dot position */
- X curwp -> w_doto = save2_doto;
- X break;
- X }
- X }
- X if (i == pat_cnt) /* found */
- X { /* move back to the first matching unit */
- X move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
- X wind_on_dot (curwp);
- X return (TRUE);
- X }
- X }
- X } while (move_ptr (curwp, 1L, TRUE, FALSE, TRUE));
- X
- X curwp -> w_dotp = save_dotp; /* restore dot position */
- X curwp -> w_doto = save_doto;
- X return (FALSE);
- X}
- X
- X
- X/*
- X* This routine does the real work of a
- X* backward search. The pattern is sitting in the external
- X* variable "srch_pat". If found, dot is updated, the window system
- X* is notified of the change, and TRUE is returned. If the
- X* string isn't found, FALSE is returned.
- X*/
- Xchar backsrch ()
- X{
- X register LINE *save_dotp, *save_p;
- X register LPOS save_doto, save_o;
- X register D8 *pat_ptr, *mask_ptr;
- X register int i, j, pat_cnt;
- X register char first_pat, first_mask;
- X char buf[NCOL], buf1[NCOL];
- X
- X save_dotp = curwp -> w_dotp; /* save dot position for later */
- X save_doto = curwp -> w_doto;
- X pat_ptr = srch_pat -> l_text;
- X mask_ptr = srch_mask -> l_text;
- X pat_cnt = srch_pat -> l_used;
- X first_mask = mask_ptr[0];
- X first_pat = pat_ptr[0] | first_mask;
- X j = (int)DOT_POS(curwp) & 0xffff;
- X
- X do
- X {
- X /* check if we should quit */
- X if (ttkeyready ())
- X {
- X if (ttgetc () == CTL_G)
- X break;
- X }
- X if ((j-- & 0x2ff) == 0)
- X {
- X sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
- X sprintf (buf, buf1, DOT_POS(curwp));
- X writ_echo (buf);
- X }
- X if (first_pat ==
- X (curwp -> w_dotp -> l_text[curwp -> w_doto] | first_mask))
- X {
- X
- X save_p = curwp -> w_dotp;
- X save_o = curwp -> w_doto;
- X for (i = 1; i < pat_cnt; i++)
- X {
- X if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
- X ((pat_ptr[i] & ~mask_ptr[i]) !=
- X (DOT_CHAR(curwp) & ~mask_ptr[i])))
- X { /* not found */
- X curwp -> w_dotp = save_p; /* restore ptr to continue */
- X
- X curwp -> w_doto = save_o;
- X break;
- X }
- X }
- X if (i == pat_cnt) /* found */
- X { /* move back to the first matching unit */
- X move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
- X wind_on_dot (curwp);
- X return (TRUE);
- X }
- X }
- X } while (move_ptr (curwp, -1L, TRUE, FALSE, TRUE));
- X
- X curwp -> w_dotp = save_dotp; /* restore dot position */
- X curwp -> w_doto = save_doto;
- X return (FALSE);
- X}
- X
- X/*
- X* Read a pattern.
- X* Display and edit in the form of the current window.
- X* Slide the displayed line back and forth when the cursor hits a boundary.
- X* Manage the mask buffer. When a '*' (wild card) is entered mask all
- X* bits in that unit and display all '?'s.
- X*/
- Xchar readpattern ()
- X{
- X int cod, mask_cod, curs_pos, curs_pos1, prt_siz, i, doto, loff;
- X WINDOW srch_wind, *save_wind;
- X BUFFER srch_buf, *save_buf;
- X LINE head_line;
- X char disp_buf[120],
- X mask_buf[120],
- X buf1[NCOL],
- X siz_prompt2,
- X r_type,
- X first_time,
- X u_off,
- X stat;
- X
- X
- X save_wind = curwp; /* save current window for later */
- X save_buf = curbp; /* save current buffer for later */
- X
- X curwp = &srch_wind; /* search window is current window during
- X search */
- X curbp = &srch_buf;
- X cur_pat = srch_pat; /* set global variables for LINE finctions */
- X cur_mask = srch_mask;
- X
- X recall_flag = FALSE;
- X first_time = TRUE;
- X read_pat_mode = TRUE;
- X curwp -> w_wndp = NULL;
- X curwp -> w_bufp = curbp;
- X curwp -> w_linep = cur_pat;
- X curwp -> w_loff = 0;
- X curwp -> w_dotp = cur_pat;
- X curwp -> w_doto = 0;
- X curwp -> w_unit_offset = 0;
- X curwp -> w_toprow = 24;
- X curwp -> w_ntrows = 1;
- X curwp -> w_intel_mode = save_wind -> w_intel_mode;
- X curwp -> w_disp_shift = 0;
- X if (R_TYPE(save_wind) == TEXT)
- X curwp -> w_fmt_ptr = &ascii_s_fmt;
- X else
- X curwp -> w_fmt_ptr = save_wind -> w_fmt_ptr -> r_srch_fmt;
- X
- X srch_buf.b_bufp = NULL;
- X srch_buf.b_linep = &head_line;
- X srch_buf.b_unit_offset = 0; /* unit offset pvr */
- X srch_buf.b_markp = NULL;
- X srch_buf.b_marko = 0;
- X srch_buf.b_flag = 0;
- X srch_buf.b_nwnd = 1;
- X srch_buf.b_fname[0] = 0;
- X srch_buf.b_bname[0] = 0;
- X
- X head_line.l_fp = cur_pat;
- X head_line.l_bp = cur_pat;
- X head_line.l_file_offset = 0; /* pvr */
- X head_line.l_used = 0;
- X head_line.l_size = 0;
- X
- X cur_pat -> l_fp = &head_line;
- X cur_pat -> l_bp = &head_line;
- X cur_pat -> l_size = 266; /* leave some extra past 256 */
- X cur_pat -> l_used = 0;
- X cur_pat -> l_file_offset = 0;
- X
- X cur_mask -> l_fp = &head_line;
- X cur_mask -> l_bp = &head_line;
- X cur_mask -> l_size = 266; /* leave some extra past 256 */
- X cur_mask -> l_used = 0;
- X cur_mask -> l_file_offset = 0;
- X
- X rplc_pat -> l_fp = &head_line;
- X rplc_pat -> l_bp = &head_line;
- X rplc_pat -> l_size = 266; /* leave some extra past 256 */
- X rplc_pat -> l_used = 0;
- X rplc_pat -> l_file_offset = 0;
- X
- X rplc_mask -> l_fp = &head_line;
- X rplc_mask -> l_bp = &head_line;
- X rplc_mask -> l_size = 266; /* leave some extra past 256 */
- X rplc_mask -> l_used = 0;
- X rplc_mask -> l_file_offset = 0;
- X
- X sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
- X R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
- X sprintf (disp_buf, buf1, curwp -> w_doto,
- X curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
- X curwp -> w_dotp -> l_used);
- X
- X siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
- X
- X for (i = siz_prompt2; i < NCOL; i++) /* clear rest of buffer */
- X disp_buf [i] = ' ';
- X
- X writ_echo (disp_buf);
- X
- X r_type = R_TYPE(curwp);
- X
- X while (TRUE)
- X {
- X /* position cursor */
- X curs_pos = curwp -> w_doto - curwp -> w_loff;
- X if (curwp -> w_fmt_ptr -> r_size == 1)
- X {
- X curs_pos >>= 1;
- X }
- X else if (curwp -> w_fmt_ptr -> r_size == 3)
- X {
- X curs_pos >>= 2;
- X }
- X curs_pos1 = curwp -> w_fmt_ptr -> r_positions[curs_pos] +
- X curwp -> w_unit_offset + siz_prompt2;
- X ttmove (nrow - 1, curs_pos1);
- X ttflush ();
- X
- X cod = getkey ();
- X
- X if (cod == 0x014D) /* check for return */
- X {
- X if ((rplc_mode == TRUE) && (cur_prompt == MSG_sch_str))
- X {
- X next_pat ();
- X dont_repeat = FALSE; /* fix up */
- X goto next_loop;
- X }
- X else
- X {
- X old_srch_pat_size = srch_pat -> l_used; /* save for restore */
- X if (rplc_mode == TRUE)
- X old_rplc_pat_size = rplc_pat -> l_used;
- X
- X old_fmt = curwp -> w_fmt_ptr;
- X curwp = save_wind; /* restore current window */
- X curbp = save_buf; /* restore current buffer */
- X read_pat_mode = FALSE;
- X return (TRUE);
- X }
- X }
- X
- X if ((cod >= ' ') && (cod < 0x7f))
- X {
- X if ((r_type == ASCII) || (r_type == EBCDIC))
- X {
- X mask_cod = '9'; /* use 9 as dummy char that will get through */
- X }
- X else if (r_type == DECIMAL)
- X {
- X mask_cod = '0'; /* clear mask byte */
- X }
- X else if (cod == '?')
- X {
- X cod = '0';
- X switch (r_type)
- X {
- X case OCTAL:
- X if (curwp -> w_unit_offset == 0) /* if first char */
- X {
- X if (R_SIZE(curwp) == WORDS)
- X mask_cod = '1';
- X else
- X mask_cod = '3';
- X }
- X else
- X mask_cod = '7';
- X break;
- X
- X case HEX:
- X mask_cod = 'F';
- X break;
- X
- X case BINARY:
- X mask_cod = '1';
- X break;
- X#if RUNCHK
- X default:
- X printf (ERR_rdpat);
- X break;
- X#endif
- X }
- X }
- X else
- X {
- X mask_cod = '0';
- X }
- X }
- X else
- X mask_cod = cod; /* must be control; do the same to the mask */
- X
- X /* save current dot and window positions */
- X doto = curwp -> w_doto;
- X u_off = curwp -> w_unit_offset;
- X loff = curwp -> w_loff;
- X stat = execute (cod, FALSE, 1);
- X
- X if (stat == ABORT)
- X {
- X old_srch_pat_size = srch_pat -> l_used; /* save for restore */
- X if (rplc_mode == TRUE)
- X old_rplc_pat_size = rplc_pat -> l_used;
- X old_fmt = curwp -> w_fmt_ptr;
- X curwp = save_wind; /* restore current window */
- X curbp = save_buf; /* restore current buffer */
- X read_pat_mode = FALSE;
- X return (FALSE);
- X }
- X
- X /* If key is recall then reset the size variables */
- X if (first_time)
- X {
- X first_time = FALSE;
- X if (recall_flag)
- X {
- X srch_pat -> l_used = old_srch_pat_size;
- X srch_mask -> l_used = old_srch_pat_size;
- X rplc_pat -> l_used = old_rplc_pat_size;
- X rplc_mask -> l_used = old_rplc_pat_size;
- X curwp -> w_fmt_ptr = old_fmt;
- X recall_flag = FALSE;
- X }
- X }
- X
- X /* if it was a toggling command, don't do it again */
- X if (!dont_repeat &&
- X (stat == TRUE))
- X {
- X head_line.l_fp = cur_mask; /* point to mask */
- X head_line.l_bp = cur_mask;
- X curwp -> w_linep = cur_mask;
- X curwp -> w_dotp = cur_mask;
- X curwp -> w_loff = loff;
- X curwp -> w_doto = doto;
- X curwp -> w_unit_offset = u_off;
- X execute (mask_cod, FALSE, 1);
- X
- X head_line.l_fp = cur_pat; /* restore pointers */
- X head_line.l_bp = cur_pat;
- X curwp -> w_linep = cur_pat;
- X curwp -> w_dotp = cur_pat;
- X }
- X else
- X dont_repeat = FALSE;
- X
- X /* limit at 256 bytes */
- X if (cur_pat -> l_used >= 256)
- X {
- X cur_mask -> l_used = 255;
- X cur_pat -> l_used = 255;
- X if (curwp -> w_doto >= 256)
- X {
- X move_ptr (curwp, 255L, TRUE, TRUE, FALSE); /* last position */
- X }
- X }
- X
- X /* if buffer is size locked then replace pattern must be the */
- X /* same size as the search pattern */
- X if (rplc_mode && (save_buf -> b_flag & BFSLOCK))
- X {
- X rplc_pat -> l_used = srch_pat -> l_used;
- X rplc_mask -> l_used = srch_pat -> l_used;
- X }
- X
- X r_type = R_TYPE(curwp);
- X#if RUNCHK
- X /* check that the pattern and the mask are the same size */
- X if (cur_pat -> l_used != cur_mask -> l_used)
- X {
- X printf (ERR_mask, cur_pat -> l_used, cur_mask -> l_used);
- X }
- X
- X /* check that in ascii mode the byte that will be set to zero */
- X /* is the dummy char 9 */
- X /* if (((r_type == ASCII) &&
- X (cur_mask -> l_text[curwp -> w_doto - 1] != '9'))
- X ||
- X ((r_type == EBCDIC) &&
- X (cur_mask -> l_text[curwp -> w_doto - 1] != to_ebcdic('9'))))
- X printf (ERR_m_cl);
- X*/
- X#endif
- X if (((r_type == ASCII) ||
- X (r_type == EBCDIC)) &&
- X ((cod >= ' ') && (cod < 0x7f)))
- X cur_mask -> l_text[doto] = 0; /* clear mask byte */
- X
- Xnext_loop:
- X sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
- X R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
- X sprintf (disp_buf, buf1, curwp -> w_doto,
- X curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
- X curwp -> w_dotp -> l_used);
- X
- X siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
- X
- X for (i = siz_prompt2; i < NCOL; i++)
- X {
- X disp_buf [i] = ' ';
- X mask_buf [i] = ' ';
- X }
- X
- X if ((curbp -> b_flag & BFSLOCK) &&
- X (rplc_pat -> l_used != srch_pat -> l_used))
- X {
- X rplc_pat -> l_used = srch_pat -> l_used;
- X /* if dot is past the end then move it back, replace string only */
- X if (DOT_POS(curwp) > srch_pat -> l_used)
- X move_ptr (curwp, (long)srch_pat -> l_used, TRUE, TRUE, FALSE);
- X }
- X
- X wind_on_dot (curwp);
- X
- X /* figure number of bytes to convert to text */
- X if ((cur_pat -> l_used - curwp -> w_loff) <
- X (prt_siz = curwp -> w_fmt_ptr -> r_bytes))
- X prt_siz = cur_pat -> l_used - curwp -> w_loff;
- X
- X bin_to_text (&cur_pat -> l_text[curwp -> w_loff],
- X &disp_buf[siz_prompt2],
- X prt_siz, curwp -> w_fmt_ptr);
- X
- X /* change any char to a ? if any bit is set in the mask buffer */
- X if ((r_type != ASCII) && (r_type != EBCDIC))
- X {
- X /* print the contents of the mask to a invisible buffer */
- X bin_to_text (&cur_mask -> l_text[curwp -> w_loff],
- X &mask_buf[siz_prompt2],
- X prt_siz, curwp -> w_fmt_ptr);
- X
- X for (i = siz_prompt2; (disp_buf[i] != 0) && (i < NCOL); i++)
- X {
- X if ((mask_buf[i] != '0') &&
- X (mask_buf[i] != ' '))
- X disp_buf[i] = '?';
- X }
- X }
- X else
- X {
- X for (i = 0; i < prt_siz; i++)
- X {
- X if (cur_mask -> l_text[curwp -> w_loff + i] != 0)
- X disp_buf[i + siz_prompt2] = '?';
- X }
- X }
- X writ_echo (disp_buf);
- X }
- X return (TRUE);
- X}
- X
- X/*
- X* Recall the last contents of the search string
- X*/
- Xbool recall ()
- X{
- X recall_flag = TRUE;
- X return (TRUE);
- X}
- X
- X/*
- X* Switch between search pattern and replace pattern and their
- X* respective masks
- X*/
- Xvoid next_pat ()
- X{
- X if (cur_pat == srch_pat)
- X {
- X cur_prompt = MSG_rpl_str;
- X cur_pat = rplc_pat; /* point to replace pattern */
- X cur_mask = rplc_mask;
- X }
- X else
- X {
- X cur_prompt = MSG_sch_str;
- X cur_pat = srch_pat; /* point to search pattern */
- X cur_mask = srch_mask;
- X }
- X curwp -> w_dotp = cur_pat;
- X curwp -> w_linep = cur_pat;
- X curbp -> b_linep -> l_fp = cur_pat;
- X curbp -> b_linep -> l_bp = cur_pat;
- X
- X if (curwp -> w_doto > cur_pat -> l_used)
- X {
- X curwp -> w_doto = cur_pat -> l_used;
- X curwp -> w_unit_offset = 0;
- X }
- X if (curwp -> w_loff > cur_pat -> l_used)
- X curwp -> w_loff = cur_pat -> l_used;
- X dont_repeat = TRUE;
- X}
- X
- X/*
- X* Compare the contents of two windows.
- X* There must be exactly two windows displayed.
- X* The bytes under the cursor in each window are compared and if
- X* a difference is found then the loop is stopped with the dot
- X* position in each window pointing to the difference.
- X* The two windows can be pointing at the same or different buffers.
- X*/
- Xbool compare ()
- X
- X{
- X WINDOW *wp1, *wp2;
- X bool move1, move2;
- X int j;
- X char *term_str = MSG_cmp_dif;
- X char buf[NCOL], buf1[NCOL];
- X
- X if (wheadp -> w_wndp -> w_wndp != NULL)
- X {
- X writ_echo (MSG_only_2);
- X return (FALSE);
- X }
- X
- X wp1 = wheadp;
- X wp2 = wheadp -> w_wndp;
- X j = (int)DOT_POS(curwp) & 0xffff;
- X
- X wp1 -> w_flag |= WFMOVE;
- X wp2 -> w_flag |= WFMOVE;
- X
- X while (DOT_CHAR(wp1) == DOT_CHAR(wp2))
- X {
- X if ((j++ & 0xff) == 0)
- X {
- X sprintf (buf1, MSG_cmping, R_POS_FMT(curwp));
- X sprintf (buf, buf1, DOT_POS(curwp));
- X writ_echo (buf);
- X /* check if we should quit */
- X if (ttkeyready ())
- X {
- X if (ttgetc () == CTL_G)
- X {
- X term_str = MSG_cmp_term;
- X break;
- X }
- X }
- X }
- X move1 = move_ptr (wp1, 1L, TRUE, FALSE, TRUE);
- X move2 = move_ptr (wp2, 1L, TRUE, FALSE, TRUE);
- X
- X if (!(move1 && move2))
- X {
- X term_str = MSG_cmp_end;
- X break;
- X }
- X }
- X writ_echo (term_str);
- X wind_on_dot (wp1);
- X wind_on_dot (wp2);
- X return (TRUE);
- X}
- END_OF_FILE
- if test 24696 -ne `wc -c <'search.c'`; then
- echo shar: \"'search.c'\" unpacked with wrong size!
- fi
- # end of 'search.c'
- fi
- echo shar: End of archive 5 \(of 9\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-