home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume26 / beav / part05 < prev    next >
Encoding:
Text File  |  1991-11-21  |  54.2 KB  |  1,888 lines

  1. Newsgroups: comp.sources.misc
  2. From: pvr@wang.com (Peter Reilley)
  3. Subject:  v26i041:  beav - Binary file editor and viewer, v1.32, Part05/09
  4. Message-ID: <1991Nov21.230249.1723@sparky.imd.sterling.com>
  5. X-Md4-Signature: 48398edd23ac6d7863fbcb523ed1a8be
  6. Date: Thu, 21 Nov 1991 23:02:49 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pvr@wang.com (Peter Reilley)
  10. Posting-number: Volume 26, Issue 41
  11. Archive-name: beav/part05
  12. Environment: UNIX, AIX, MS-DOS, AMIGA
  13. Supersedes: beav: Volume 22, Issue 10-18
  14.  
  15. #! /bin/sh
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  19. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  20. # Contents:  def.h fileio.c search.c
  21. # Wrapped by kent@sparky on Thu Nov 21 16:47:01 1991
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 5 (of 9)."'
  25. if test -f 'def.h' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'def.h'\"
  27. else
  28.   echo shar: Extracting \"'def.h'\" \(21214 characters\)
  29.   sed "s/^X//" >'def.h' <<'END_OF_FILE'
  30. X/*
  31. X *     Common header file.
  32. X *
  33. X * This file is the general header file for all parts
  34. X * of the display editor. It contains all of the
  35. X * general definitions and macros. It also contains some
  36. X * conditional compilation flags. All of the per-system and
  37. X * per-terminal definitions are in special header files.
  38. X * The most common reason to edit this file would be to zap
  39. X * the definition of CVMVAS or BACKUP.
  40. X */
  41. X#define LINT_ARGS   1           /* enable lint type checking */
  42. X#include        "stdio.h"
  43. X
  44. X#ifndef NOPROTO
  45. X#ifdef UNIX
  46. X#include        "sys/types.h"
  47. X#endif /* UNIX */
  48. X#include        "prototyp.h"
  49. X#endif  /* NOPROTO */
  50. X
  51. X#define BACKUP  1           /* Make backup file.            */
  52. X#define RUNCHK  1           /* Do additional checking at run time */
  53. X
  54. X#ifndef    uchar
  55. X#define uchar   unsigned    char
  56. X#endif
  57. X
  58. X#ifndef    uint
  59. X#define uint    unsigned    int 
  60. X#endif
  61. X
  62. X#ifndef    ushort
  63. X#define ushort  unsigned    short
  64. X#endif
  65. X
  66. X#ifndef    ulong
  67. X#define ulong   unsigned    long
  68. X#endif
  69. X
  70. X/* these defines are reserved for handling data values from the buffer */
  71. X#define     D8  uchar       /* this had better be a 8 bit quantity */
  72. X#define     D16 ushort      /* this had better be a 16 bit quantity */
  73. X#define     D32 ulong       /* this had better be a 32 bit quantity */
  74. X
  75. X/* this define is reserved for the address of a location in the buffer */
  76. X#define     A32 ulong        /* this is a 32 bit address into the buffer */
  77. X
  78. X#define     bool char       /* used for boolean values      */
  79. X#define     bits char       /* used for boolean bit flags   */
  80. X
  81. X/* this define is reserved for the byte location in the a LINE structure */
  82. X#define     LPOS uint       /* this is a 32 bit address into the buffer */
  83. X
  84. X/*
  85. X *      MS-DOS system header file.
  86. X */
  87. X#if    MSDOS
  88. X#define LARGE   1           /* Large model.         */
  89. X#endif
  90. X#define PCC 1               /* "[]" won't work.     */
  91. X#define GOOD    0           /* Indicate hunkydoryhood   */
  92. X
  93. X/*
  94. X * Macros used by the buffer name making code.
  95. X * Start at the end of the file name, scan to the left
  96. X * until BDC1 (or BDC2, if defined) is reached. The buffer
  97. X * name starts just to the right of that location, and
  98. X * stops at end of string (or at the next BDC3 character,
  99. X * if defined). BDC2 and BDC3 are mainly for VMS.
  100. X */
  101. X#define BDC1    ':'         /* Buffer names.        */
  102. X#define BDC2    '/'         /* Buffer names. jam    */
  103. X
  104. X#ifdef UNIX
  105. X#define PATHCHR ':'
  106. X#define    SEPCHAR '/'
  107. X#else
  108. X#define PATHCHR ';'
  109. X#define    SEPCHAR 0x5c    /* this is a \ char */
  110. X#endif
  111. X
  112. X/*
  113. X *      Digital ANSI terminal header file
  114. X */
  115. X#ifdef MSDOS
  116. X#define    ANSI    1            /* send ANSI escape codes */
  117. X#endif
  118. X
  119. X#ifdef UNIX
  120. X#define NROW    100
  121. X#define NCOL    80          /* Columns.         */
  122. X#else
  123. X#define NROW    25          /* Rows.for boot    */
  124. X#define NCOL    80          /* Columns.         */
  125. X#endif
  126. X
  127. X#define CUSTOMIZE                       /* compile switch for extended key
  128. Xbinding in extend.c           */
  129. X#define COSMETIC                        /* cosmetic screen stuff on 
  130. Xinsert off screen             */
  131. X#ifdef MSDOS
  132. X#define WANG_CHARACTER_SCREEN 0xf0000000L
  133. X#endif
  134. X/*
  135. X * Table sizes, etc.
  136. X */
  137. X#define NSHASH  31          /* Symbol table hash size.      */
  138. X#define NFILEN  80          /* Length, file name.           */
  139. X#define NBUFN   13          /* Length, buffer name.     */
  140. X#define NFILE   12          /* Length, file name.  */ /* krw */
  141. X#define NKBDM   256         /* Length, keyboard macro.      */
  142. X#define NMSG    512         /* Length, message buffer.      */
  143. X#define NPAT    80          /* Length, pattern.             */
  144. X#define HUGE    1000        /* A rather large number.       */
  145. X#define NSRCH   128         /* Undoable search commands.    */
  146. X#define NXNAME  64          /* Length, extended command.    */
  147. X#define MAXPOS  0x7FFFFFFF  /* Maximum positive long value  */
  148. X
  149. X/*
  150. X * This is the initial allocation for user data storage.
  151. X * It has should be in the range of 1 to less than half the size 
  152. X * of an int.   The define LPOS is used to index into an array of this size.
  153. X * This is main tunable parameter for the speed of beav.
  154. X * If it is too large inserts and deletes will be slow but
  155. X * file loads will be fast and memory will be efficiently used.
  156. X * If it is too small the reverse will be true.
  157. X * This seems like a good number, but I have not tested it for performance.
  158. X */
  159. X#define NLINE   0x1000      /* Length, line.      pvr  */
  160. X
  161. X/*
  162. X * When memory must be reallocated this is added to the allocation
  163. X * request to allow for a little slop on areas that are being worked on.
  164. X * This should reduce the number of allocations done.
  165. X */
  166. X#define NBLOCK  0x1000      /* Line block extra size        */
  167. X
  168. X/*
  169. X * This is the number of bytes that are allocated for the kill buffer 
  170. X * when data cannot be moved by changing the pointers.
  171. X */
  172. X#define KBLOCK  0x1000      /* Kill buffer block size.  */
  173. X
  174. X/*
  175. X * Universal.
  176. X */
  177. X#define FALSE   0                       /* False, no, bad, etc.         */
  178. X#define TRUE    1                       /* True, yes, good, etc.        */
  179. X#define ABORT   2                       /* Death, ^G, abort, etc.       */
  180. X
  181. X/*
  182. X * These flag bits keep track of
  183. X * some aspects of the last command.
  184. X * The CFKILL flag controls the clearing versus appending
  185. X * of data in the kill buffer.
  186. X */
  187. X#define CFKILL  0x0002                  /* Last command was a kill      */
  188. X
  189. X/*
  190. X * File I/O.
  191. X */
  192. X#define FIOSUC  0                       /* Success.                     */
  193. X#define FIOFNF  1                       /* File not found.              */
  194. X#define FIOEOF  2                       /* End of file.                 */
  195. X#define FIOERR  3                       /* Error.                       */
  196. X
  197. X/*
  198. X * Directory I/O.
  199. X */
  200. X#define DIOSUC  0                       /* Success.                     */
  201. X#define DIOEOF  1                       /* End of file.                 */
  202. X#define DIOERR  2                       /* Error.                       */
  203. X
  204. X/*
  205. X * Display colors.
  206. X */
  207. X#define CNONE   0                       /* Unknown color.               */
  208. X#define CTEXT   1                       /* Text color.                  */
  209. X#define CMODE   2                       /* Mode line color.             */
  210. X
  211. X/*
  212. X * Flags for "eread".
  213. X */
  214. X#define EFNEW   0x0001                  /* New prompt.                  */
  215. X#define EFAUTO  0x0002                  /* Autocompletion enabled.      */
  216. X#define EFCR    0x0004                  /* Echo CR at end; last read.   */
  217. X
  218. X/*
  219. X * Keys are represented inside using an 11 bit
  220. X * keyboard code. The transformation between the keys on
  221. X * the keyboard and 11 bit code is done by terminal specific
  222. X * code in the "kbd.c" file. The actual character is stored
  223. X * in 8 bits (DEC multinationals work); there is also a control
  224. X * flag KCTRL, a meta flag KMETA, and a control-X flag KCTLX.
  225. X * ASCII control characters are always represented using the
  226. X * KCTRL form. Although the C0 control set is free, it is
  227. X * reserved for C0 controls because it makes the communication
  228. X * between "getkey" and "getkbd" easier. The funny keys get
  229. X * mapped into the C1 control area.
  230. X */
  231. X#define NKEYS   2048                    /* 11 bit code.                 */
  232. X
  233. X#define METACH  0x1B                    /* M- prefix,   Control-[, ESC  */
  234. X#define CTMECH  0x1C                    /* C-M- prefix, Control-\       */
  235. X#define EXITCH  0x1D                    /* Exit level,  Control-]       */
  236. X#define CTRLCH  0x1E                    /* C- prefix,   Control-^       */
  237. X#define HELPCH  0x1F                    /* Help key,    Control-_       */
  238. X#define CTL_G   0x07                    /* Abort command key            */
  239. X
  240. X#define KCHAR   0x00FF                  /* The basic character code.    */
  241. X#define KCTRL   0x0100                  /* Control flag.                */
  242. X#define KMETA   0x0200                  /* Meta flag.                   */
  243. X#define KCTLX   0x0400                  /* Control-X flag.              */
  244. X
  245. X#define KFIRST  0x0080                  /* First special.       fitz    */
  246. X#define KLAST   0x00F3                  /* Last special.                */
  247. X
  248. X#define KRANDOM 0x0080                  /* A "no key" code.             */
  249. X
  250. X/*
  251. X*    This causes the key sequence ESC [ <key> to be delevered as
  252. X*    KCTRL | KMETA | KCTLX | <key>.   This allows VT100 function keys
  253. X*    to be bound. 
  254. X*/
  255. X#define    VT100KEY
  256. X
  257. X/*
  258. X *    These define the column used in the help (wallchart) function 
  259. X */
  260. X#define    HFUNCCOL    3
  261. X#define    HKEY        32
  262. X#define    HKEYCODE    50
  263. X#define    HENDCOL     55
  264. X
  265. X/*
  266. X * These flags, and the macros below them,
  267. X * make up a do-it-yourself set of "ctype" macros that
  268. X * understand the DEC multinational set, and let me ask
  269. X * a slightly different set of questions.
  270. X */
  271. X#define _W      0x01                    /* Word.                        */
  272. X#define _U      0x02                    /* Upper case letter.           */
  273. X#define _L      0x04                    /* Lower case letter.           */
  274. X#define _C      0x08                    /* Control.                     */
  275. X
  276. X#define ISCTRL(c)       ((cinfo[(c)]&_C)!=0)
  277. X#define ISUPPER(c)      ((cinfo[(c)]&_U)!=0)
  278. X#define ISLOWER(c)      ((cinfo[(c)]&_L)!=0)
  279. X#define TOUPPER(c)      ((c)-0x20)
  280. X#define TOLOWER(c)      ((c)+0x20)
  281. X
  282. X#define BUF_SIZE(wp)    (wp -> w_bufp -> b_linep -> l_bp -> l_file_offset + \
  283. X                        wp -> w_bufp -> b_linep -> l_bp -> l_used)
  284. X#define BUF_START(wp)   (wp -> w_bufp -> b_linep -> l_fp -> l_file_offset)
  285. X#define DOT_POS(wp)     (wp -> w_dotp -> l_file_offset + wp -> w_doto)
  286. X#define MARK_POS(wp)    (wp -> w_markp -> l_file_offset + wp -> w_marko)
  287. X#define DOT_CHAR(wp)    (wp -> w_dotp -> l_text[wp -> w_doto])
  288. X#define WIND_POS(wp)    (wp -> w_linep -> l_file_offset + wp -> w_loff)
  289. X#define R_TYPE(wp)      (wp -> w_fmt_ptr -> r_type)
  290. X#define R_SIZE(wp)      (wp -> w_fmt_ptr -> r_size)
  291. X#define R_UNITS(wp)     (wp -> w_fmt_ptr -> r_units)
  292. X#define R_BYTES(wp)     (wp -> w_fmt_ptr -> r_bytes)
  293. X#define R_ALIGN(wp)     (wp -> w_fmt_ptr -> r_align)
  294. X#define R_B_PER_U(wp)   (wp -> w_fmt_ptr -> r_b_per_u)
  295. X#define R_CHR_PER_U(wp) (wp -> w_fmt_ptr -> r_chr_per_u)
  296. X#define R_FLAGS(wp)     (wp -> w_fmt_ptr -> r_flags)
  297. X#define R_UNIT_FMT(wp)  (wp -> w_fmt_ptr -> r_unit_fmt)
  298. X#define R_POS_FMT(wp)   (wp -> w_fmt_ptr -> r_pos_fmt)
  299. X#define R_BYTE_FMT(wp)   (wp -> w_fmt_ptr -> r_byte_fmt)
  300. X#define R_POSITIONS(wp) (wp -> w_fmt_ptr -> r_positions)
  301. X
  302. X/*
  303. X * The symbol table links editing functions
  304. X * to names. Entries in the key map point at the symbol
  305. X * table entry. A reference count is kept, but it is
  306. X * probably next to useless right now. The old type code,
  307. X * which was not being used and probably not right
  308. X * anyway, is all gone.
  309. X */
  310. Xtypedef struct  SYMBOL {
  311. X    struct  SYMBOL *s_symp;         /* Hash chain.                  */
  312. X    short   s_nkey;                 /* Count of keys bound here.    */
  313. X    char    *s_name;                /* Name.            */
  314. X    bool    (*s_funcp)();           /* Function.                    */
  315. X    bits    s_modify;               /* modify bit */
  316. X}       SYMBOL;
  317. X
  318. X/*
  319. X*   These are the legal values for 's_modify' and 'k_modify'
  320. X*/
  321. X#define SMOD    0x01            /* command modifies the buffer  */
  322. X#define SSIZE   0x02            /* command changes buffer size  */
  323. X#define SSRCH   0x04            /* command valid in search  */
  324. X#define SRPLC   0x08            /* command valid in replace */
  325. X#define SBOUND  0x10            /* key was bound bu user or rc file */
  326. X
  327. X/*
  328. X * There is a window structure allocated for
  329. X * every active display window. The windows are kept in a
  330. X * big list, in top to bottom screen order, with the listhead at
  331. X * "wheadp". Each window contains its own values of dot and mark.
  332. X * The flag field contains some bits that are set by commands
  333. X * to guide redisplay; although this is a bit of a compromise in
  334. X * terms of decoupling, the full blown redisplay is just too
  335. X * expensive to run for every input character.
  336. X */
  337. Xtypedef struct  WINDOW {
  338. X    struct  WINDOW *w_wndp;         /* Next window                  */
  339. X    struct  BUFFER *w_bufp;         /* Buffer displayed in window   */
  340. X    struct  LINE *w_linep;          /* Top line in the window       */
  341. X    LPOS    w_loff;                 /* Offset into line for start pvr  */
  342. X    A32     w_wind_temp;            /* temp storage for window file pos */
  343. X    struct  LINE *w_dotp;           /* Line containing "."          */
  344. X    LPOS    w_doto;                 /* Offset into line for "." */
  345. X    A32     w_dot_temp;             /* temp storage for dot file pos */
  346. X    struct  LINE *w_markp;          /* Line containing "mark"       */
  347. X    LPOS    w_marko;                /* Byte offset for "mark"       */
  348. X    A32     w_mark_temp;            /* temp storage for mark file pos */
  349. X    char    w_unit_offset;          /* Byte offset for "." into unit pvr */
  350. X    char    w_toprow;               /* Origin 0 top row of window   */
  351. X    char    w_ntrows;               /* # of rows of text in window  */
  352. X    bits    w_flag;                 /* Flags.                       */
  353. X    char    w_disp_shift;           /* Display byte shift; 0-3  pvr */
  354. X    bool    w_intel_mode;           /* Display byte swaped.     pvr */
  355. X    struct  ROW_FMT *w_fmt_ptr;     /* Pointer to display format pvr */
  356. X}       WINDOW;
  357. X
  358. X/*
  359. X * Window flags are set by command processors to
  360. X * tell the display system what has happened to the buffer
  361. X * mapped by the window. Setting "WFHARD" is always a safe thing
  362. X * to do, but it may do more work than is necessary. Always try
  363. X * to set the simplest action that achieves the required update.
  364. X * Because commands set bits in the "w_flag", update will see
  365. X * all change flags, and do the most general one.
  366. X */
  367. X#define WFFORCE 0x01                    /* Force reframe.               */
  368. X#define WFMOVE  0x02                    /* Movement from line to line.  */
  369. X#define WFEDIT  0x04                    /* Editing within a line.       */
  370. X#define WFHARD  0x08                    /* Better to a full display.    */
  371. X#define WFMODE  0x10                    /* Update mode line.        */
  372. X/*
  373. X*   This structure contains how a row is constructed.   pvr
  374. X*/
  375. X
  376. Xtypedef struct  ROW_FMT {
  377. X    uchar   r_type;     /* format type nibbles          */
  378. X    uchar   r_size;     /* format size: must be 0,1,3,7,15, etc */
  379. X    uchar   r_units;    /* number of units per window row: must be 1,2,4,8,16*/
  380. X    uchar   r_bytes;    /* number of bytes per window row: must be 1,2,4,8,16*/
  381. X    uchar   r_align;    /* number of bytes per align row: must be 1,2,4,8,16*/
  382. X    uchar   r_b_per_u;  /* number of bytes per unit: must be 1,2,4,8,16 */
  383. X    uchar   r_chr_per_u; /* displayed chars per unit     */
  384. X    bits    r_flags;    /* flags controlling format     */
  385. X    char    *r_unit_fmt; /* print format for unit */
  386. X    char    *r_pos_fmt; /* print format for buffer position, always a long */
  387. X    char    *r_byte_fmt; /* print format for bytes */
  388. X    uchar   *r_positions; /* list of unit positions   */
  389. X    struct ROW_FMT *r_srch_fmt; /* pointer to search display format */
  390. X} ROW_FMT;
  391. X
  392. X/* legal values for 'r_size'  (values significant; used as bit mask) pvr */
  393. X
  394. X#define BYTES   0x00        /* Display as byte; 8 bits  */
  395. X#define WORDS   0x01        /* Display as word;    16 bits  */
  396. X#define DWORDS  0x03        /* Display as doubles; 32 bits  */
  397. X
  398. X/* legal values for 'r_type'   pvr */
  399. X#define ASCII   0x10        /* Display as ascii     */
  400. X#define OCTAL   0x20        /* Display as octal values  */
  401. X#define DECIMAL 0x30        /* Display as decimal values    */
  402. X#define HEX     0x40        /* Display as hex values    */
  403. X#define BINARY  0x50        /* Display as binary values */
  404. X#define EBCDIC  0x60        /* Display as ebcdic        */
  405. X#define TEXT    0x70        /* Display as normal text   */
  406. X
  407. X/*
  408. X * Text is kept in buffers. A buffer header, described
  409. X * below, exists for every buffer in the system. The buffers are
  410. X * kept in a big list, so that commands that search for a buffer by
  411. X * name can find the buffer header. There is a safe store for the
  412. X * dot and mark in the header, but this is only valid if the buffer
  413. X * is not being displayed (that is, if "b_nwnd" is 0). The text for
  414. X * the buffer is kept in a circularly linked list of lines, with
  415. X * a pointer to the header line in "b_linep".
  416. X */
  417. Xtypedef struct  BUFFER {
  418. X    bits    b_type;         /* Type of buffer       */
  419. X    struct  BUFFER *b_bufp; /* Link to next BUFFER          */
  420. X    struct  LINE *b_dotp;   /* Link to "." LINE structure   */
  421. X    LPOS    b_doto;         /* Offset of "." in above LINE  */
  422. X    char    b_unit_offset;  /* Offset into unit for "." pvr */
  423. X    struct  LINE *b_markp;  /* The same as the above two,   */
  424. X    LPOS    b_marko;        /* but for the "mark"       */
  425. X    struct  LINE *b_linep;  /* Link to the header LINE      */
  426. X    char    b_nwnd;         /* Count of windows on buffer   */
  427. X    bits    b_flag;         /* Flags            */
  428. X    A32     b_begin_addr;   /* File address of begining of buffer */
  429. X    A32     b_end_addr;     /* File address of end of buffer */
  430. X    A32     b_file_size;    /* Size of file */
  431. X    char    b_fname[NFILEN]; /* File name                    */
  432. X    char    b_bname[NBUFN];  /* Buffer name                  */
  433. X}   BUFFER;
  434. X
  435. X/* Values for 'buf_type' */
  436. X#define BTFILE   0x00            /* Buffer contains a file   */
  437. X#define BTDISK   0x01            /* Buffer points to a disk  */
  438. X#define BTMEMORY 0x02            /* Buffer points to memory  */
  439. X#define BTSAVE   0x03            /* This is the save buffer */
  440. X#define BTLIST   0x04            /* This is the buffer list */
  441. X#define BTHELP   0x05            /* This is the help buffer */
  442. X
  443. X/* Values for 'b_flag' */
  444. X
  445. X#define BFCHG   0x01            /* Changed.         */
  446. X#define BFBAK   0x02            /* Need to make a backup.       */
  447. X#define BFBAD   0x04            /* may be trashed alloc error?  */
  448. X#define BFINMEM 0x08            /* File is entirely in memory */
  449. X#define BFVIEW  0x10            /* read only (jam)               */
  450. X#define BFLINK  0x20            /* Linked mode    pvr        */
  451. X#define BFSLOCK 0x40            /* Lock buffer size   pvr    */
  452. X/*
  453. X * This structure holds the starting position
  454. X * (as a line/offset pair) and the number of characters in a
  455. X * region of a buffer. This makes passing the specification
  456. X * of a region around a little bit easier.
  457. X * There have been some complaints that the short in this
  458. X * structure is wrong; that a long would be more appropriate.
  459. X * I'll await more comments from the folks with the little
  460. X * machines; I have a VAX, and everything fits.
  461. X */
  462. Xtypedef struct  reg {
  463. X    struct  LINE *r_linep;          /* Origin LINE address.         */
  464. X    LPOS    r_offset;               /* Origin LINE offset.          */
  465. X    A32     r_size;                 /* Length in characters.        */
  466. X}       REGION;
  467. X
  468. X/*
  469. X * All text is kept in circularly linked
  470. X * lists of "LINE" structures. These begin at the
  471. X * header line (which is the blank line beyond the
  472. X * end of the buffer). This line is pointed to by
  473. X * the "BUFFER". Each line contains a the number of
  474. X * bytes in the line (the "used" size), the size
  475. X * of the text array, and the text. The end of line
  476. X * is not stored as a byte; it's implied. Future
  477. X * additions will include update hints, and a
  478. X * list of marks into the line.
  479. X */
  480. Xtypedef struct  LINE {
  481. X    struct  LINE *l_fp;       /* Link to the next line        */
  482. X    struct  LINE *l_bp;       /* Link to the previous line    */
  483. X    A32     l_file_offset;        /* Offset from begining of file pvr */
  484. X    LPOS    l_size;           /* Allocated size           */
  485. X    LPOS    l_used;           /* Used size            */
  486. X#if     PCC
  487. X    D8      l_text[1];        /* A bunch of characters.       */
  488. X#else
  489. X    D8      l_text[];         /* A bunch of characters.       */
  490. X#endif
  491. X}      LINE;
  492. X
  493. X/*
  494. X * The rationale behind these macros is that you
  495. X * could (with some editing, like changing the type of a line
  496. X * link from a "LINE *" to a "REFLINE", and fixing the commands
  497. X * like file reading that break the rules) change the actual
  498. X * storage representation of lines to use something fancy on
  499. X * machines with small address spaces.
  500. X */
  501. X#define lforw(lp)       ((lp)->l_fp)
  502. X#define lback(lp)       ((lp)->l_bp)
  503. X#define lgetc(lp, n)    ((lp)->l_text[(n)]&0xFF)
  504. X#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c))
  505. X#define llength(lp)     ((lp)->l_used)
  506. X
  507. X/*
  508. X * Externals.
  509. X */
  510. Xextern  int     thisflag;
  511. Xextern  int     lastflag;
  512. Xextern  int     curgoal;
  513. Xextern  int     epresf;
  514. Xextern  int     sgarbf;
  515. Xextern  WINDOW  *curwp;
  516. Xextern  BUFFER  *curbp;
  517. Xextern  WINDOW  *wheadp;
  518. Xextern  BUFFER  *bheadp;
  519. Xextern  BUFFER  *blistp;
  520. Xextern  short   kbdm[];
  521. Xextern  short   *kbdmip;
  522. Xextern  short   *kbdmop;
  523. Xextern  SYMBOL  *symbol[];
  524. Xextern  SYMBOL  *binding[];
  525. Xextern  BUFFER  *bfind();
  526. Xextern  BUFFER  *bcreate();
  527. Xextern  WINDOW  *wpopup();
  528. Xextern  LINE    *lalloc();
  529. Xextern  int     nrow;
  530. Xextern  int     ncol;
  531. Xextern  char    version[];
  532. Xextern  int     ttrow;
  533. Xextern  int     ttcol;
  534. Xextern  int     tceeol;
  535. Xextern  int     tcinsl;
  536. Xextern  int     tcdell;
  537. Xextern  char    cinfo[];
  538. Xextern  SYMBOL  *symlookup();
  539. Xextern  int     nmsg;
  540. Xextern  int     curmsgf;
  541. Xextern  int     newmsgf;
  542. Xextern  char    msg[];
  543. X
  544. X/* jam
  545. X */
  546. Xextern  char    *okmsg;
  547. Xextern  int     insert_mode;
  548. Xextern  int     extend_buf;
  549. Xextern  int     flush_num;
  550. Xextern  int     auto_update;
  551. Xextern  int     flush_count;
  552. Xextern  int     rowb;
  553. Xextern  char    file_off_bad;
  554. X
  555. X/*
  556. X * Standard I/O.
  557. X */
  558. Xextern  char    *malloc();
  559. Xextern  char    *strcpy();
  560. Xextern  char    *strcat();
  561. END_OF_FILE
  562.   if test 21214 -ne `wc -c <'def.h'`; then
  563.     echo shar: \"'def.h'\" unpacked with wrong size!
  564.   fi
  565.   # end of 'def.h'
  566. fi
  567. if test -f 'fileio.c' -a "${1}" != "-c" ; then 
  568.   echo shar: Will not clobber existing file \"'fileio.c'\"
  569. else
  570.   echo shar: Extracting \"'fileio.c'\" \(5255 characters\)
  571.   sed "s/^X//" >'fileio.c' <<'END_OF_FILE'
  572. X/*
  573. X*    file I/O.
  574. X*/
  575. X
  576. X#ifdef UNIX
  577. X#include    <sys/types.h> 
  578. X#include    <fcntl.h> 
  579. X#include    <sys/stat.h> 
  580. X#endif
  581. X#ifdef AMIGA
  582. X#include    <sys/types.h> 
  583. X#include    <fcntl.h> 
  584. X#include    <sys/stat.h> 
  585. X#endif
  586. X#include        "def.h"
  587. X
  588. Xextern    char    MSG_cnt_wr[];
  589. Xextern    char    MSG_wr_io_er[];
  590. Xextern    char    MSG_rd_er[];
  591. Xextern    char    MSG_bak[];
  592. Xextern    char    MSG_backup[];
  593. Xextern    char    MSG_back_er[];
  594. Xextern    char    MSG_back_of[];
  595. X
  596. X#ifdef MSDOS
  597. Xstatic  FILE * ffp;
  598. X#endif
  599. X
  600. X#ifdef UNIX
  601. Xstatic  int ffp;
  602. X#endif
  603. X
  604. X#ifdef AMIGA
  605. Xstatic  int ffp;
  606. X#endif
  607. X
  608. X/*
  609. X* Open a file for reading.
  610. X*/
  611. Xchar    ffropen (fn)
  612. Xchar   *fn;
  613. X{
  614. X#ifdef MSDOS
  615. X    if ((ffp = fopen (fn, "rb")) == NULL)/* pvr */
  616. X        return (FIOERR);
  617. X    ;
  618. X    return (FIOSUC);
  619. X#endif
  620. X#ifdef UNIX
  621. X    if ((ffp = open (fn, O_RDONLY)) == -1)/* pvr */
  622. X        return (FIOERR);
  623. X    ;
  624. X    return (FIOSUC);
  625. X#endif
  626. X#ifdef AMIGA
  627. X    if ((ffp = open (fn, O_RDONLY)) == -1)/* pvr */
  628. X        return (FIOERR);
  629. X    ;
  630. X    return (FIOSUC);
  631. X#endif
  632. X}
  633. X/*
  634. X*   Get the file length
  635. X*/
  636. X#ifdef AMIGA
  637. XA32 file_len(char *fname)
  638. X{
  639. X    struct stat st;
  640. X
  641. X    if (stat (fname, &st) == -1)
  642. X        return (-1);
  643. X    return (st.st_size);
  644. X}
  645. X#else /* AMIGA */
  646. XA32 file_len ()
  647. X{
  648. X#ifdef MSDOS
  649. X    return (filelength (fileno (ffp)));
  650. X#endif
  651. X#ifdef UNIX
  652. X    struct    stat    st;
  653. X
  654. X    if (fstat (ffp, &st) == -1)
  655. X        return (-1);
  656. X    return (st.st_size);
  657. X#endif
  658. X}
  659. X#endif    /* AMIGA */
  660. X
  661. X/*
  662. X* Open a file for writing.
  663. X* Set file permissions as requested 
  664. X* Return TRUE if all is well, and
  665. X* FALSE on error (cannot create).
  666. X*/
  667. Xchar    ffwopen (fn, mode)
  668. Xchar   *fn;
  669. Xushort    mode;
  670. X{
  671. X#ifdef MSDOS
  672. X    if ((ffp = fopen (fn, "wb")) == NULL)/* pvr */
  673. X    {
  674. X        err_echo (MSG_cnt_wr);
  675. X        return (FIOERR);
  676. X    }
  677. X    return (FIOSUC);
  678. X#endif
  679. X#ifdef UNIX
  680. X    /* set perms as in original file 1.31 */
  681. X    if ((ffp = open (fn, O_WRONLY | O_CREAT, mode)) == -1)/* pvr */
  682. X        return (FIOERR);
  683. X    ;
  684. X    return (FIOSUC);
  685. X#endif
  686. X#ifdef AMIGA
  687. X    /* set perms as in original file 1.31 */
  688. X    if ((ffp = open (fn, O_WRONLY | O_CREAT, mode)) == -1)/* pvr */
  689. X        return (FIOERR);
  690. X    ;
  691. X    return (FIOSUC);
  692. X#endif
  693. X}
  694. X
  695. X/*
  696. X* Close a file.
  697. X* Should look at the status.
  698. X*/
  699. Xchar    ffclose ()
  700. X{
  701. X#ifdef MSDOS
  702. X    fclose (ffp);
  703. X#endif
  704. X#ifdef UNIX
  705. X    close (ffp);
  706. X#endif
  707. X    return (FIOSUC);
  708. X#ifdef AMIGA
  709. X    close (ffp);
  710. X#endif
  711. X    return (FIOSUC);
  712. X}
  713. X
  714. X/*
  715. X* Write a line to the already
  716. X* opened file. The "buf" points to the
  717. X* buffer, and the "nbuf" is its length.   pvr
  718. X* Return the status.
  719. X*/
  720. Xchar    ffputline (buf, nbuf)
  721. Xregister char   buf[];
  722. Xint     nbuf;
  723. X{
  724. X    register int    i;
  725. X
  726. X#ifdef MSDOS
  727. X    i = fwrite (buf, 1, nbuf, ffp);
  728. X#endif
  729. X#ifdef UNIX
  730. X    i = write (ffp, buf, nbuf);
  731. X#endif
  732. X#ifdef AMIGA
  733. X    i = write (ffp, buf, nbuf);
  734. X#endif
  735. X
  736. X    if ((i != nbuf)
  737. X#ifdef MSDOS    
  738. X        || (ferror (ffp) != FALSE))
  739. X#else
  740. X        )
  741. X#endif     
  742. X            {
  743. X            err_echo (MSG_wr_io_er);
  744. X            return (FIOERR);
  745. X        }
  746. X    return (FIOSUC);
  747. X}
  748. X
  749. X/*
  750. X* Read a line from a file, and store the bytes
  751. X* in the supplied buffer. Stop on end of file or after 'nbuf' characters. pvr
  752. X* the first byte in the buffer is the length in bytes.
  753. X*/
  754. Xchar    ffgetline (buf, nbuf, rbuf)
  755. Xregister char   *buf;
  756. Xregister LPOS   *rbuf, nbuf;
  757. X{
  758. X#ifdef MSDOS
  759. X    *rbuf = fread (buf, 1, nbuf, ffp);
  760. X#endif
  761. X
  762. X#ifdef UNIX
  763. X    *rbuf = read (ffp, buf, nbuf);
  764. X#endif
  765. X#ifdef AMIGA
  766. X    *rbuf = read (ffp, buf, nbuf);
  767. X#endif
  768. X
  769. X    /* End of file.         */
  770. X#ifdef MSDOS
  771. X    if (ferror (ffp) != FALSE)
  772. X    {
  773. X        err_echo (MSG_rd_er);
  774. X        return (FIOERR);
  775. X    }
  776. X#endif
  777. X    if (*rbuf == 0)
  778. X        return (FIOEOF);
  779. X
  780. X    return (FIOSUC);
  781. X}
  782. X
  783. X/*
  784. X*   Seek to specified position in file.
  785. X*   Return the actual position in the file.
  786. X*/
  787. XA32     ffseek (posn)
  788. XA32     posn;
  789. X{
  790. X#ifdef MSDOS
  791. X    fseek (ffp, posn, SEEK_SET);
  792. X    return (ftell (ffp));
  793. X#endif
  794. X#ifdef UNIX
  795. X    return (lseek (ffp, posn, 0));
  796. X#endif
  797. X#ifdef AMIGA
  798. X    return (lseek (ffp, posn, 0));
  799. X#endif
  800. X}
  801. X
  802. X/*
  803. X* Some backup user on MS-DOS might want
  804. X* to determine some rule for doing backups on that
  805. X* system, and fix this. I don't use MS-DOS, so I don't
  806. X* know what the right rules would be. Return TRUE so
  807. X* the caller does not abort a write.
  808. X* Under UNIX just append the .bak postfix.
  809. X*/
  810. X#ifdef BACKUP
  811. Xbool    fbackupfile (fname)
  812. Xchar   *fname;
  813. X{
  814. X    char    backname[NFILEN];
  815. X    char   *source,
  816. X    *backup;
  817. X    char    buf[NCOL];
  818. X
  819. X    source = fname;
  820. X    backup = backname;
  821. X    while ((*source > 0)
  822. X#ifdef MSDOS
  823. X        && (*source != '.'))
  824. X#else
  825. X        )
  826. X#endif
  827. X            {
  828. X            *backup = *source;
  829. X            backup++;
  830. X            source++;
  831. X            *backup = 0;
  832. X        }
  833. X    strcat (backname, MSG_bak);
  834. X    sprintf (buf, MSG_backup, fname, backname);
  835. X    writ_echo (buf);
  836. X    unlink (backname);
  837. X#ifdef NORENAME
  838. X    if ((link (fname, backname) != 0) || (unlink (fname) != 0))
  839. X#else
  840. X        if (rename (fname, backname) > 0)
  841. X#endif
  842. X        {
  843. X            sprintf (buf, MSG_back_er, fname, backname);
  844. X            err_echo (buf);
  845. X            return (FALSE);
  846. X        }
  847. X    return (TRUE);              /* Hack.                */
  848. X}
  849. X
  850. X#endif
  851. X
  852. X/*
  853. X* The string "fn" is a file name.
  854. X* Perform any required case adjustments. All systems
  855. X* we deal with so far have case insensitive file systems.
  856. X* We zap everything to lower case. The problem we are trying
  857. X* to solve is getting 2 buffers holding the same file if
  858. X* you visit one of them with the "caps lock" key down.
  859. X* On UNIX and AMIGA file names are dual case, so we leave
  860. X* everything alone.
  861. X*/
  862. Xvoid    adjustcase (fn)
  863. Xregister char  *fn;
  864. X{
  865. X    register int    c;
  866. X
  867. X    while ((c = *fn) != 0)
  868. X    {
  869. X        if (c >= 'A' && c <= 'Z')
  870. X            *fn = c + 'a' - 'A';
  871. X        ++fn;
  872. X    }
  873. X}
  874. END_OF_FILE
  875.   if test 5255 -ne `wc -c <'fileio.c'`; then
  876.     echo shar: \"'fileio.c'\" unpacked with wrong size!
  877.   fi
  878.   # end of 'fileio.c'
  879. fi
  880. if test -f 'search.c' -a "${1}" != "-c" ; then 
  881.   echo shar: Will not clobber existing file \"'search.c'\"
  882. else
  883.   echo shar: Extracting \"'search.c'\" \(24696 characters\)
  884.   sed "s/^X//" >'search.c' <<'END_OF_FILE'
  885. X/*
  886. X*       Search commands.
  887. X* The functions in this file implement the
  888. X* search commands (both plain and incremental searches
  889. X* are supported) and the query-replace command.
  890. X*/
  891. X#include    "def.h"
  892. X
  893. Xchar    replaceit ();
  894. Xchar    forwsrch ();
  895. Xchar    backsrch ();
  896. Xchar    readpattern ();
  897. Xvoid    next_pat ();
  898. X
  899. Xextern    char    MSG_sch_str[];
  900. Xextern    char    MSG_bsrc_str[];
  901. Xextern    char    MSG_rpl_str[];
  902. Xextern    char    MSG_pat_fnd[];
  903. Xextern    char    MSG_no_srch[];
  904. Xextern    char    MSG_fnd_at[];
  905. Xextern    char    MSG_no_rpl[];
  906. Xextern    char    MSG_1_rpl[];
  907. Xextern    char    MSG_n_rpl[];
  908. Xextern    char    MSG_srcing[];
  909. Xextern    char    MSG_curs[];
  910. Xextern    char    MSG_cmp_end[];
  911. Xextern    char    MSG_cmp_term[];
  912. Xextern    char    MSG_cmp_dif[];
  913. Xextern    char    MSG_only_2[];
  914. Xextern    char    MSG_cmping[];
  915. Xextern    char    MSG_not_fnd[];
  916. X#if RUNCHK
  917. Xextern    char    ERR_rdpat[];
  918. Xextern    char    ERR_mask[];
  919. Xextern    char    ERR_m_cl[];
  920. X#endif
  921. X
  922. X#define CCHR(x)     ((x)-'@')
  923. X
  924. X#define SRCH_BEGIN  (0)         /* Search sub-codes.    */
  925. X#define SRCH_FORW   (-1)
  926. X#define SRCH_BACK   (-2)
  927. X#define SRCH_PREV   (-3)
  928. X#define SRCH_NEXT   (-4)
  929. X#define SRCH_NOPR   (-5)
  930. X#define SRCH_ACCM   (-6)
  931. X
  932. Xtypedef struct
  933. X{
  934. X    int     s_code;
  935. X    LINE * s_dotp;
  936. X    short   s_doto;
  937. X}SRCHCOM;
  938. X
  939. X#define MAX_PAT 260
  940. X
  941. Xextern  ROW_FMT hex_s_8_fmt;
  942. Xextern  ROW_FMT ascii_s_fmt;
  943. X
  944. Xbool    recall_flag = FALSE;
  945. Xbool    read_pat_mode = FALSE;
  946. Xbool    srch_mode = FALSE;
  947. Xbool    rplc_mode = FALSE;
  948. Xbool    dont_repeat = FALSE;    /* used to prevent toggling commands from */
  949. X/* failing in read_pattern */
  950. Xstatic  char    srch_patb[MAX_PAT];
  951. Xstatic  char    srch_maskb[MAX_PAT];
  952. Xstatic  char    rplc_patb[MAX_PAT];
  953. Xstatic  char    rplc_maskb[MAX_PAT];
  954. X
  955. Xstatic  LINE    *srch_pat = (LINE *)srch_patb;
  956. Xstatic  LINE    *srch_mask = (LINE *)srch_maskb;
  957. Xstatic  LINE    *cur_pat;
  958. Xstatic  LINE    *cur_mask;
  959. Xstatic  LINE    *rplc_pat = (LINE *)rplc_patb;
  960. Xstatic  LINE    *rplc_mask = (LINE *)rplc_maskb;
  961. X
  962. Xstatic  int     old_srch_pat_size = 0;/* for pattern recall */
  963. Xstatic  int     old_rplc_pat_size = 0;
  964. Xstatic  ROW_FMT *old_fmt = &hex_s_8_fmt;
  965. X
  966. Xchar    *cur_prompt;
  967. X
  968. Xint     srch_lastdir = SRCH_NOPR;/* Last search flags.   */
  969. X
  970. X/*
  971. X* Search forward.
  972. X* Get a search string from the user, and search for it,
  973. X* starting at ".". If found, "." gets moved to the
  974. X* first matched character, and display does all the hard stuff.
  975. X* If not found, it just prints a message.
  976. X*/
  977. Xchar    forwsearch ()
  978. X{
  979. X    register char   s;
  980. X    char    buf[NCOL], buf1[NCOL];
  981. X
  982. X    srch_mode = TRUE;
  983. X    rplc_mode = FALSE;
  984. X    cur_prompt = MSG_sch_str;
  985. X    if ((s = readpattern ()) != TRUE)
  986. X    {
  987. X        srch_mode = FALSE;
  988. X        eerase ();  /* clear message line */
  989. X        return (s);
  990. X    }
  991. X    if (forwsrch () == FALSE)
  992. X    {
  993. X        writ_echo (MSG_not_fnd);
  994. X        srch_mode = FALSE;
  995. X        return (FALSE);
  996. X    }
  997. X    srch_lastdir = SRCH_FORW;
  998. X    curwp -> w_flag |= WFMODE;  /* update mode line */
  999. X    curwp -> w_unit_offset = 0;
  1000. X    /* build format */
  1001. X    sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
  1002. X    sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
  1003. X        curwp -> w_doto);
  1004. X    writ_echo (buf);
  1005. X    srch_mode = FALSE;
  1006. X    return (TRUE);
  1007. X}
  1008. X
  1009. X
  1010. X/*
  1011. X* Reverse search.
  1012. X* Get a search string from the  user, and search, starting at "."
  1013. X* and proceeding toward the front of the buffer. If found "." is left
  1014. X* pointing at the first character of the pattern [the last character that
  1015. X* was matched].
  1016. X*/
  1017. Xchar    backsearch ()
  1018. X{
  1019. X    register char   s;
  1020. X    char    buf[NCOL], buf1[NCOL];
  1021. X
  1022. X    srch_mode = TRUE;
  1023. X    rplc_mode = FALSE;
  1024. X    cur_prompt = MSG_bsrc_str;
  1025. X    if ((s = readpattern ()) != TRUE)
  1026. X    {
  1027. X        srch_mode = FALSE;
  1028. X        eerase ();  /* clear message line */
  1029. X        return (s);
  1030. X    }
  1031. X    if (backsrch () == FALSE)
  1032. X    {
  1033. X        writ_echo (MSG_not_fnd);
  1034. X        srch_mode = FALSE;
  1035. X        return (FALSE);
  1036. X    }
  1037. X    srch_lastdir = SRCH_BACK;
  1038. X    curwp -> w_flag |= WFMODE;  /* update mode line */
  1039. X    curwp -> w_unit_offset = 0;
  1040. X    sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
  1041. X    sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
  1042. X        curwp -> w_doto);
  1043. X    writ_echo (buf);
  1044. X    srch_mode = FALSE;
  1045. X    return (TRUE);
  1046. X}
  1047. X
  1048. X
  1049. X/* 
  1050. X* Search again, using the same search string
  1051. X* and direction as the last search command. The direction
  1052. X* has been saved in "srch_lastdir", so you know which way
  1053. X* to go.
  1054. X*/
  1055. Xchar    searchagain ()
  1056. X{
  1057. X    char    buf[NCOL], buf1[NCOL];
  1058. X    long    dot_pos;
  1059. X    srch_mode = TRUE;
  1060. X    rplc_mode = FALSE;
  1061. X
  1062. X    dot_pos = DOT_POS(curwp);
  1063. X    if (srch_lastdir == SRCH_FORW)
  1064. X    {
  1065. X        /* advance one unit so we don't find the same thing again */
  1066. X        move_ptr (curwp, dot_pos + 1, TRUE, FALSE, FALSE);
  1067. X        if (forwsrch () == FALSE)
  1068. X        {    /* go back to orig pt */
  1069. X            move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
  1070. X            writ_echo (MSG_not_fnd);
  1071. X            srch_mode = FALSE;
  1072. X            return (FALSE);
  1073. X        }
  1074. X        curwp -> w_flag |= WFMODE;  /* update mode line */
  1075. X        curwp -> w_unit_offset = 0;
  1076. X        sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
  1077. X        sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
  1078. X            curwp -> w_doto);
  1079. X        writ_echo (buf);
  1080. X        srch_mode = FALSE;
  1081. X        return (TRUE);
  1082. X    }
  1083. X    if (srch_lastdir == SRCH_BACK)
  1084. X    {
  1085. X        /* step back one unit so we don't find the same thing again */
  1086. X        move_ptr (curwp, dot_pos - 1, TRUE, FALSE, FALSE);
  1087. X        if (backsrch () == FALSE)
  1088. X        {    /* go back to orig pt */
  1089. X            move_ptr (curwp, dot_pos, TRUE, FALSE, FALSE);
  1090. X            writ_echo (MSG_not_fnd);
  1091. X            srch_mode = FALSE;
  1092. X            return (FALSE);
  1093. X        }
  1094. X        curwp -> w_flag |= WFMODE;  /* update mode line */
  1095. X        curwp -> w_unit_offset = 0;
  1096. X        sprintf (buf1, MSG_pat_fnd, R_POS_FMT(curwp));
  1097. X        sprintf (buf, buf1, curwp -> w_dotp -> l_file_offset +
  1098. X            curwp -> w_doto);
  1099. X        writ_echo (buf);
  1100. X        srch_mode = FALSE;
  1101. X        return (TRUE);
  1102. X    }
  1103. X    writ_echo (MSG_no_srch);
  1104. X    srch_mode = FALSE;
  1105. X    return (FALSE);
  1106. X}
  1107. X
  1108. X
  1109. X/*
  1110. X* Query Replace.
  1111. X*   Replace strings selectively.  Does a search and replace operation.
  1112. X*   A space or a comma replaces the string, a period replaces and quits,
  1113. X*   an n doesn't replace, a C-G quits.
  1114. X* (note typical hack to add a function with minimal code) 
  1115. X*/
  1116. Xchar    queryrepl (f, n, k)
  1117. X{
  1118. X
  1119. X    register char   s;
  1120. X
  1121. X    srch_mode = FALSE;
  1122. X    rplc_mode = TRUE;
  1123. X    cur_prompt = MSG_sch_str;
  1124. X    if (s = readpattern ())
  1125. X    {
  1126. X        replaceit ();
  1127. X    }
  1128. X    srch_mode = FALSE;
  1129. X    rplc_mode = FALSE;
  1130. X    return (s);
  1131. X}
  1132. X
  1133. X
  1134. Xchar    replaceit ()
  1135. X{
  1136. X    int     rcnt = 0;           /* Replacements made so far */
  1137. X    int     plen;               /* length of found string   */
  1138. X    int     rlen;               /* length of replace string   */
  1139. X    long    abs_dot_p;          /* absolute dot position */
  1140. X    long    abs_mark_p;         /* absolute mark position */
  1141. X    char    buf[NCOL], buf1[NCOL];
  1142. X
  1143. X    /* 
  1144. X  * Search forward repeatedly, checking each time whether to insert
  1145. X  * or not.  The "!" case makes the check always true, so it gets put
  1146. X  * into a tighter loop for efficiency.
  1147. X  *
  1148. X  * If we change the line that is the remembered value of dot, then
  1149. X  * it is possible for the remembered value to move.  This causes great
  1150. X  * pain when trying to return to the non-existant line.
  1151. X  *
  1152. X  * possible fixes:
  1153. X  * 1) put a single, relocated marker in the WINDOW structure, handled
  1154. X  *    like mark.  The problem now becomes a what if two are needed...
  1155. X  * 2) link markers into a list that gets updated (auto structures for
  1156. X  *    the nodes)
  1157. X  * 3) Expand the mark into a stack of marks and add pushmark, popmark.
  1158. X  */
  1159. X
  1160. X    plen = srch_pat -> l_used;
  1161. X    rlen = rplc_pat -> l_used;
  1162. X
  1163. X    abs_dot_p = DOT_POS(curwp); /* save current dot position */
  1164. X    if (curwp->w_markp != NULL)    /* mark may not be set */
  1165. X        abs_mark_p = MARK_POS(curwp);
  1166. X
  1167. X    while (forwsrch () == TRUE)
  1168. X    {
  1169. Xretry:
  1170. X        sprintf (buf1, MSG_fnd_at, R_POS_FMT(curwp));
  1171. X        sprintf (buf, buf1, DOT_POS(curwp));
  1172. X        writ_echo (buf);
  1173. X        curwp -> w_flag |= WFMODE;  /* update mode line */
  1174. X        update ();
  1175. X        switch (ttgetc ())
  1176. X        {
  1177. X        case 'r':
  1178. X        case 'R':
  1179. X        case ' ':
  1180. X        case ',':
  1181. X            /* update has fixedup the dot position so move to found byte */
  1182. X            /* go and do the replace */
  1183. X            if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
  1184. X                return (FALSE);
  1185. X            /* begin searching after replace string */
  1186. X            move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
  1187. X            rcnt++;
  1188. X            break;
  1189. X
  1190. X        case 'o':
  1191. X        case 'O':
  1192. X        case '.':
  1193. X            if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
  1194. X                return (FALSE);
  1195. X            /* begin searching after replace string */
  1196. X            move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
  1197. X            rcnt++;
  1198. X            goto stopsearch;
  1199. X
  1200. X        case 'q':
  1201. X        case 'Q':
  1202. X        case CCHR ('G'):
  1203. X            ctrlg (FALSE, 0, KRANDOM);
  1204. X            goto stopsearch;
  1205. X
  1206. X        case 'a':
  1207. X        case 'A':
  1208. X        case '!':
  1209. X            do
  1210. X            {
  1211. X                if (lrepl_str (plen, rplc_pat, rplc_mask) == FALSE)
  1212. X                    return (FALSE);
  1213. X                /* begin searching after replace string */
  1214. X                move_ptr (curwp, (long)rlen, TRUE, FALSE, TRUE);
  1215. X                rcnt++;
  1216. X            }                while (forwsrch () == TRUE);
  1217. X            goto stopsearch;
  1218. X
  1219. X        case 's':
  1220. X        case 'S':
  1221. X        case 'n':
  1222. X            /* begin searching after this byte */
  1223. X            move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  1224. X            break;
  1225. X
  1226. X        default:
  1227. X            ttbeep ();
  1228. X            goto retry;
  1229. X        }
  1230. X    }
  1231. X
  1232. Xstopsearch:
  1233. X    move_ptr (curwp, abs_dot_p, TRUE, TRUE, FALSE);
  1234. X    if (curwp -> w_markp != NULL)
  1235. X    {
  1236. X        swapmark ();
  1237. X        /* insure that the mark points to the same byte as before */
  1238. X        if (abs_mark_p > abs_dot_p)
  1239. X            move_ptr (curwp, abs_mark_p + rlen - plen, TRUE, FALSE, FALSE);
  1240. X        else
  1241. X            move_ptr (curwp, abs_mark_p, TRUE, FALSE, FALSE);
  1242. X        swapmark ();
  1243. X    }
  1244. X    curwp -> w_flag |= WFHARD;
  1245. X    update ();
  1246. X    if (rcnt == 0)
  1247. X    {
  1248. X        writ_echo (MSG_no_rpl);
  1249. X    }
  1250. X    else if (rcnt == 1)
  1251. X    {
  1252. X        writ_echo (MSG_1_rpl);
  1253. X    }
  1254. X    else
  1255. X    {
  1256. X        sprintf (buf1, MSG_n_rpl, R_POS_FMT(curwp));
  1257. X        sprintf (buf, buf1, (ulong)rcnt);
  1258. X        writ_echo (buf);
  1259. X    }
  1260. X    flush_count += rcnt;        /* jam for auto write buffers */
  1261. X    return (TRUE);
  1262. X}
  1263. X
  1264. X
  1265. X/*
  1266. X* This routine does the real work of a
  1267. X* forward search. The pattern is sitting in the external
  1268. X* variable "srch_pat" the mask if in "srch_mask".
  1269. X* If found, dot is updated, the window system
  1270. X* is notified of the change, and TRUE is returned. If the
  1271. X* string isn't found, FALSE is returned.
  1272. X*/
  1273. Xchar    forwsrch ()
  1274. X{
  1275. X    register    LINE    *save_dotp, *save2_dotp;
  1276. X    register    int     save_doto, save2_doto;
  1277. X    register    D8      *pat_ptr, *mask_ptr;
  1278. X    register    int     i, j, pat_cnt;
  1279. X    register    D8      first_pat, first_mask;
  1280. X    char        buf[NCOL], buf1[NCOL];
  1281. X
  1282. X    save_dotp = curwp -> w_dotp;    /* save dot position for later */
  1283. X    save_doto = curwp -> w_doto;
  1284. X    pat_ptr = srch_pat -> l_text;
  1285. X    mask_ptr = srch_mask -> l_text;
  1286. X    pat_cnt = srch_pat -> l_used;
  1287. X    first_mask = mask_ptr[0];
  1288. X    first_pat = pat_ptr[0] | first_mask;
  1289. X    j =  (int)DOT_POS(curwp) & 0xffff;
  1290. X
  1291. X    do 
  1292. X    {
  1293. X        if ((j++ & 0x2ff) == 0)
  1294. X        {
  1295. X            sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
  1296. X            sprintf (buf, buf1, DOT_POS(curwp));
  1297. X            writ_echo (buf);
  1298. X            /* check if we should quit */
  1299. X            if (ttkeyready ())
  1300. X            {
  1301. X                if (ttgetc () == CTL_G)
  1302. X                    break;
  1303. X            }
  1304. X        }
  1305. X        if (first_pat == 
  1306. X            ((DOT_CHAR(curwp) | first_mask) & 0xff))
  1307. X        {
  1308. X            save2_dotp = curwp -> w_dotp;    /* save dot position for later */
  1309. X            save2_doto = curwp -> w_doto;
  1310. X            for (i = 1; i < pat_cnt; i++)
  1311. X            {
  1312. X                if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
  1313. X                    ((pat_ptr[i] & ~mask_ptr[i]) != 
  1314. X                    (DOT_CHAR(curwp) & ~mask_ptr[i])))
  1315. X                {   /* not found */
  1316. X                    curwp -> w_dotp = save2_dotp;  /* restore dot position */
  1317. X                    curwp -> w_doto = save2_doto;
  1318. X                    break;
  1319. X                }
  1320. X            }
  1321. X            if (i == pat_cnt)   /* found */
  1322. X            {   /* move back to the first matching unit */
  1323. X                move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
  1324. X                wind_on_dot (curwp);
  1325. X                return (TRUE);
  1326. X            }
  1327. X        }
  1328. X    }    while (move_ptr (curwp, 1L, TRUE, FALSE, TRUE));
  1329. X
  1330. X    curwp -> w_dotp = save_dotp;  /* restore dot position */
  1331. X    curwp -> w_doto = save_doto;
  1332. X    return (FALSE);
  1333. X}
  1334. X
  1335. X
  1336. X/*
  1337. X* This routine does the real work of a
  1338. X* backward search. The pattern is sitting in the external
  1339. X* variable "srch_pat". If found, dot is updated, the window system
  1340. X* is notified of the change, and TRUE is returned. If the
  1341. X* string isn't found, FALSE is returned.
  1342. X*/
  1343. Xchar    backsrch ()
  1344. X{
  1345. X    register    LINE    *save_dotp, *save_p;
  1346. X    register    LPOS    save_doto, save_o;
  1347. X    register    D8      *pat_ptr, *mask_ptr;
  1348. X    register    int     i, j, pat_cnt;
  1349. X    register    char    first_pat, first_mask;
  1350. X    char        buf[NCOL], buf1[NCOL];
  1351. X
  1352. X    save_dotp = curwp -> w_dotp;    /* save dot position for later */
  1353. X    save_doto = curwp -> w_doto;
  1354. X    pat_ptr = srch_pat -> l_text;
  1355. X    mask_ptr = srch_mask -> l_text;
  1356. X    pat_cnt = srch_pat -> l_used;
  1357. X    first_mask = mask_ptr[0];
  1358. X    first_pat = pat_ptr[0] | first_mask;
  1359. X    j =  (int)DOT_POS(curwp) & 0xffff;
  1360. X
  1361. X    do 
  1362. X    {
  1363. X        /* check if we should quit */
  1364. X        if (ttkeyready ())
  1365. X        {
  1366. X            if (ttgetc () == CTL_G)
  1367. X                break;
  1368. X        }
  1369. X        if ((j-- & 0x2ff) == 0)
  1370. X        {
  1371. X            sprintf (buf1, MSG_srcing, R_POS_FMT(curwp));
  1372. X            sprintf (buf, buf1, DOT_POS(curwp));
  1373. X            writ_echo (buf);
  1374. X        }
  1375. X        if (first_pat == 
  1376. X            (curwp -> w_dotp -> l_text[curwp -> w_doto] | first_mask))
  1377. X        {
  1378. X
  1379. X            save_p = curwp -> w_dotp;
  1380. X            save_o = curwp -> w_doto;
  1381. X            for (i = 1; i < pat_cnt; i++)
  1382. X            {
  1383. X                if (!move_ptr (curwp, 1L, TRUE, FALSE, TRUE) ||
  1384. X                    ((pat_ptr[i] & ~mask_ptr[i]) != 
  1385. X                    (DOT_CHAR(curwp) & ~mask_ptr[i])))
  1386. X                {   /* not found */
  1387. X                    curwp -> w_dotp = save_p;   /* restore ptr to continue */
  1388. X
  1389. X                    curwp -> w_doto = save_o;
  1390. X                    break;
  1391. X                }
  1392. X            }
  1393. X            if (i == pat_cnt)   /* found */
  1394. X            {   /* move back to the first matching unit */
  1395. X                move_ptr (curwp, -(long)pat_cnt + 1, TRUE, FALSE, TRUE);
  1396. X                wind_on_dot (curwp);
  1397. X                return (TRUE);
  1398. X            }
  1399. X        }
  1400. X    }    while (move_ptr (curwp, -1L, TRUE, FALSE, TRUE));
  1401. X
  1402. X    curwp -> w_dotp = save_dotp;  /* restore dot position */
  1403. X    curwp -> w_doto = save_doto;
  1404. X    return (FALSE);
  1405. X}
  1406. X
  1407. X/*
  1408. X* Read a pattern.
  1409. X* Display and edit in the form of the current window.
  1410. X* Slide the displayed line back and forth when the cursor hits a boundary.
  1411. X* Manage the mask buffer. When a '*' (wild card) is entered mask all
  1412. X* bits in that unit and display all '?'s.
  1413. X*/
  1414. Xchar    readpattern ()
  1415. X{
  1416. X    int     cod, mask_cod, curs_pos, curs_pos1, prt_siz, i, doto, loff;
  1417. X    WINDOW  srch_wind, *save_wind;
  1418. X    BUFFER  srch_buf, *save_buf;
  1419. X    LINE    head_line;
  1420. X    char    disp_buf[120],
  1421. X    mask_buf[120],
  1422. X    buf1[NCOL],
  1423. X    siz_prompt2,
  1424. X    r_type,
  1425. X    first_time,
  1426. X    u_off,
  1427. X    stat;
  1428. X
  1429. X
  1430. X    save_wind = curwp;          /* save current window for later */
  1431. X    save_buf = curbp;       /* save current buffer for later */
  1432. X
  1433. X    curwp = &srch_wind;         /* search window is current window during
  1434. X                                                           search */
  1435. X    curbp = &srch_buf;
  1436. X    cur_pat = srch_pat;         /* set global variables for LINE finctions */
  1437. X    cur_mask = srch_mask;
  1438. X
  1439. X    recall_flag = FALSE;
  1440. X    first_time = TRUE;
  1441. X    read_pat_mode = TRUE;
  1442. X    curwp -> w_wndp = NULL;
  1443. X    curwp -> w_bufp = curbp;
  1444. X    curwp -> w_linep = cur_pat;
  1445. X    curwp -> w_loff = 0;
  1446. X    curwp -> w_dotp = cur_pat;
  1447. X    curwp -> w_doto = 0;
  1448. X    curwp -> w_unit_offset = 0;
  1449. X    curwp -> w_toprow = 24;
  1450. X    curwp -> w_ntrows = 1;
  1451. X    curwp -> w_intel_mode = save_wind -> w_intel_mode;
  1452. X    curwp -> w_disp_shift = 0;
  1453. X    if (R_TYPE(save_wind) == TEXT)
  1454. X        curwp -> w_fmt_ptr = &ascii_s_fmt;
  1455. X    else
  1456. X        curwp -> w_fmt_ptr = save_wind -> w_fmt_ptr -> r_srch_fmt;
  1457. X
  1458. X    srch_buf.b_bufp = NULL;
  1459. X    srch_buf.b_linep = &head_line;
  1460. X    srch_buf.b_unit_offset = 0;    /* unit offset   pvr */
  1461. X    srch_buf.b_markp = NULL;
  1462. X    srch_buf.b_marko = 0;
  1463. X    srch_buf.b_flag = 0;
  1464. X    srch_buf.b_nwnd = 1;
  1465. X    srch_buf.b_fname[0] = 0;
  1466. X    srch_buf.b_bname[0] = 0;
  1467. X
  1468. X    head_line.l_fp = cur_pat;
  1469. X    head_line.l_bp = cur_pat;
  1470. X    head_line.l_file_offset = 0;    /* pvr */
  1471. X    head_line.l_used = 0;
  1472. X    head_line.l_size = 0;
  1473. X
  1474. X    cur_pat -> l_fp = &head_line;
  1475. X    cur_pat -> l_bp = &head_line;
  1476. X    cur_pat -> l_size = 266;    /* leave some extra past 256 */
  1477. X    cur_pat -> l_used = 0;
  1478. X    cur_pat -> l_file_offset = 0;
  1479. X
  1480. X    cur_mask -> l_fp = &head_line;
  1481. X    cur_mask -> l_bp = &head_line;
  1482. X    cur_mask -> l_size = 266;   /* leave some extra past 256 */
  1483. X    cur_mask -> l_used = 0;
  1484. X    cur_mask -> l_file_offset = 0;
  1485. X
  1486. X    rplc_pat -> l_fp = &head_line;
  1487. X    rplc_pat -> l_bp = &head_line;
  1488. X    rplc_pat -> l_size = 266;    /* leave some extra past 256 */
  1489. X    rplc_pat -> l_used = 0;
  1490. X    rplc_pat -> l_file_offset = 0;
  1491. X
  1492. X    rplc_mask -> l_fp = &head_line;
  1493. X    rplc_mask -> l_bp = &head_line;
  1494. X    rplc_mask -> l_size = 266;   /* leave some extra past 256 */
  1495. X    rplc_mask -> l_used = 0;
  1496. X    rplc_mask -> l_file_offset = 0;
  1497. X
  1498. X    sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
  1499. X        R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
  1500. X    sprintf (disp_buf, buf1, curwp -> w_doto,
  1501. X        curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
  1502. X        curwp -> w_dotp -> l_used);
  1503. X
  1504. X    siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
  1505. X
  1506. X    for (i = siz_prompt2; i < NCOL; i++)    /* clear rest of buffer */
  1507. X        disp_buf [i] = ' ';
  1508. X
  1509. X    writ_echo (disp_buf);
  1510. X
  1511. X    r_type = R_TYPE(curwp);
  1512. X
  1513. X    while (TRUE)
  1514. X    {
  1515. X        /* position cursor */
  1516. X        curs_pos = curwp -> w_doto - curwp -> w_loff;
  1517. X        if (curwp -> w_fmt_ptr -> r_size == 1)
  1518. X        {
  1519. X            curs_pos >>= 1;
  1520. X        }
  1521. X        else if (curwp -> w_fmt_ptr -> r_size == 3)
  1522. X        {
  1523. X            curs_pos >>= 2;
  1524. X        }
  1525. X        curs_pos1 = curwp -> w_fmt_ptr -> r_positions[curs_pos] + 
  1526. X            curwp -> w_unit_offset + siz_prompt2;
  1527. X        ttmove (nrow - 1, curs_pos1);
  1528. X        ttflush ();
  1529. X
  1530. X        cod = getkey ();
  1531. X
  1532. X        if (cod == 0x014D)  /* check for return */
  1533. X        {
  1534. X            if ((rplc_mode == TRUE) && (cur_prompt == MSG_sch_str))
  1535. X            {
  1536. X                next_pat ();
  1537. X                dont_repeat = FALSE;    /* fix up */
  1538. X                goto next_loop;
  1539. X            }
  1540. X            else
  1541. X            {
  1542. X                old_srch_pat_size = srch_pat -> l_used; /* save for restore */
  1543. X                if (rplc_mode == TRUE)
  1544. X                    old_rplc_pat_size = rplc_pat -> l_used;
  1545. X
  1546. X                old_fmt = curwp -> w_fmt_ptr;
  1547. X                curwp = save_wind;  /* restore current window */
  1548. X                curbp = save_buf;  /* restore current buffer */
  1549. X                read_pat_mode = FALSE;
  1550. X                return (TRUE);
  1551. X            }
  1552. X        }
  1553. X
  1554. X        if ((cod >= ' ') && (cod < 0x7f))
  1555. X        {
  1556. X            if ((r_type == ASCII) || (r_type == EBCDIC))
  1557. X            {
  1558. X                mask_cod = '9'; /* use 9 as dummy char that will get through */
  1559. X            }
  1560. X            else if (r_type == DECIMAL)
  1561. X            {
  1562. X                mask_cod = '0'; /* clear mask byte */
  1563. X            }
  1564. X            else if (cod == '?')
  1565. X            {
  1566. X                cod = '0';
  1567. X                switch (r_type)
  1568. X                {
  1569. X                case OCTAL:
  1570. X                    if (curwp -> w_unit_offset == 0)    /* if first char */
  1571. X                    {
  1572. X                        if (R_SIZE(curwp) == WORDS)
  1573. X                            mask_cod = '1';
  1574. X                        else
  1575. X                            mask_cod = '3';
  1576. X                    }
  1577. X                    else
  1578. X                        mask_cod = '7';
  1579. X                    break;
  1580. X
  1581. X                case HEX:
  1582. X                    mask_cod = 'F';
  1583. X                    break;
  1584. X
  1585. X                case BINARY:
  1586. X                    mask_cod = '1';
  1587. X                    break;
  1588. X#if RUNCHK
  1589. X                default:
  1590. X                    printf (ERR_rdpat);
  1591. X                    break;
  1592. X#endif
  1593. X                }
  1594. X            }
  1595. X            else
  1596. X            {
  1597. X                mask_cod = '0';
  1598. X            }
  1599. X        }
  1600. X        else
  1601. X            mask_cod = cod;     /* must be control; do the same to the mask */
  1602. X
  1603. X        /* save current dot and window positions */
  1604. X        doto = curwp -> w_doto;
  1605. X        u_off = curwp -> w_unit_offset;
  1606. X        loff = curwp -> w_loff;
  1607. X        stat = execute (cod, FALSE, 1);
  1608. X
  1609. X        if (stat == ABORT)
  1610. X        {
  1611. X            old_srch_pat_size = srch_pat -> l_used; /* save for restore */
  1612. X            if (rplc_mode == TRUE)
  1613. X                old_rplc_pat_size = rplc_pat -> l_used;
  1614. X            old_fmt = curwp -> w_fmt_ptr;
  1615. X            curwp = save_wind;  /* restore current window */
  1616. X            curbp = save_buf;  /* restore current buffer */
  1617. X            read_pat_mode = FALSE;
  1618. X            return (FALSE);
  1619. X        }
  1620. X
  1621. X        /* If key is recall then reset the size variables */
  1622. X        if (first_time)
  1623. X        {
  1624. X            first_time = FALSE;
  1625. X            if (recall_flag)
  1626. X            {
  1627. X                srch_pat -> l_used = old_srch_pat_size;
  1628. X                srch_mask -> l_used = old_srch_pat_size;
  1629. X                rplc_pat -> l_used = old_rplc_pat_size;
  1630. X                rplc_mask -> l_used = old_rplc_pat_size;
  1631. X                curwp -> w_fmt_ptr = old_fmt;
  1632. X                recall_flag = FALSE;
  1633. X            }
  1634. X        }
  1635. X
  1636. X        /* if it was a toggling command, don't do it again */
  1637. X        if (!dont_repeat &&
  1638. X            (stat == TRUE))
  1639. X        {
  1640. X            head_line.l_fp = cur_mask;   /* point to mask */
  1641. X            head_line.l_bp = cur_mask;
  1642. X            curwp -> w_linep = cur_mask;
  1643. X            curwp -> w_dotp = cur_mask;
  1644. X            curwp -> w_loff = loff;
  1645. X            curwp -> w_doto = doto;
  1646. X            curwp -> w_unit_offset = u_off;
  1647. X            execute (mask_cod, FALSE, 1);
  1648. X
  1649. X            head_line.l_fp = cur_pat;    /* restore pointers */
  1650. X            head_line.l_bp = cur_pat;
  1651. X            curwp -> w_linep = cur_pat;
  1652. X            curwp -> w_dotp = cur_pat;
  1653. X        }
  1654. X        else
  1655. X            dont_repeat = FALSE;
  1656. X
  1657. X        /* limit at 256 bytes */
  1658. X        if (cur_pat -> l_used >= 256)
  1659. X        {
  1660. X            cur_mask -> l_used = 255;
  1661. X            cur_pat -> l_used = 255;
  1662. X            if (curwp -> w_doto >= 256)
  1663. X            {
  1664. X                move_ptr (curwp, 255L, TRUE, TRUE, FALSE);  /* last position */
  1665. X            }
  1666. X        }
  1667. X
  1668. X        /* if buffer is size locked then replace pattern must be the */
  1669. X        /* same size as the search pattern */
  1670. X        if (rplc_mode && (save_buf -> b_flag & BFSLOCK))
  1671. X        {
  1672. X            rplc_pat -> l_used = srch_pat -> l_used;
  1673. X            rplc_mask -> l_used = srch_pat -> l_used;
  1674. X        }
  1675. X
  1676. X        r_type = R_TYPE(curwp);
  1677. X#if RUNCHK
  1678. X        /* check that the pattern and the mask are the same size */
  1679. X        if (cur_pat -> l_used != cur_mask -> l_used)
  1680. X        {
  1681. X            printf (ERR_mask, cur_pat -> l_used, cur_mask -> l_used);
  1682. X        }
  1683. X
  1684. X        /* check that in ascii mode the byte that will be set to zero */
  1685. X        /* is the dummy char 9 */
  1686. X        /*        if (((r_type == ASCII) &&
  1687. X            (cur_mask -> l_text[curwp -> w_doto - 1] != '9'))
  1688. X            ||
  1689. X            ((r_type == EBCDIC) &&
  1690. X            (cur_mask -> l_text[curwp -> w_doto - 1] != to_ebcdic('9'))))
  1691. X            printf (ERR_m_cl);
  1692. X*/
  1693. X#endif
  1694. X        if (((r_type == ASCII) ||
  1695. X            (r_type == EBCDIC)) &&
  1696. X            ((cod >= ' ') && (cod < 0x7f)))
  1697. X            cur_mask -> l_text[doto] = 0; /* clear mask byte */
  1698. X
  1699. Xnext_loop:
  1700. X        sprintf (buf1, MSG_curs, cur_prompt, R_BYTE_FMT(curwp),
  1701. X            R_BYTE_FMT(curwp), R_BYTE_FMT(curwp));
  1702. X        sprintf (disp_buf, buf1, curwp -> w_doto,
  1703. X            curwp -> w_fmt_ptr -> r_chr_per_u - curwp -> w_unit_offset - 1,
  1704. X            curwp -> w_dotp -> l_used);
  1705. X
  1706. X        siz_prompt2 = strlen (disp_buf); /* save prompt length for later */
  1707. X
  1708. X        for (i = siz_prompt2; i < NCOL; i++)
  1709. X        {
  1710. X            disp_buf [i] = ' ';
  1711. X            mask_buf [i] = ' ';
  1712. X        }
  1713. X
  1714. X        if ((curbp -> b_flag & BFSLOCK) &&
  1715. X            (rplc_pat -> l_used != srch_pat -> l_used))
  1716. X        {
  1717. X            rplc_pat -> l_used = srch_pat -> l_used;
  1718. X            /* if dot is past the end then move it back, replace string only */
  1719. X            if (DOT_POS(curwp) > srch_pat -> l_used)
  1720. X                move_ptr (curwp, (long)srch_pat -> l_used, TRUE, TRUE, FALSE);
  1721. X        }
  1722. X
  1723. X        wind_on_dot (curwp);
  1724. X
  1725. X        /* figure number of bytes to convert to text */
  1726. X        if ((cur_pat -> l_used - curwp -> w_loff) <
  1727. X            (prt_siz = curwp -> w_fmt_ptr -> r_bytes))
  1728. X            prt_siz = cur_pat -> l_used - curwp -> w_loff;
  1729. X
  1730. X        bin_to_text (&cur_pat -> l_text[curwp -> w_loff],
  1731. X            &disp_buf[siz_prompt2],
  1732. X            prt_siz, curwp -> w_fmt_ptr);
  1733. X
  1734. X        /* change any char to a ? if any bit is set in the mask buffer */
  1735. X        if ((r_type != ASCII) && (r_type != EBCDIC))
  1736. X        {
  1737. X            /* print the contents of the mask to a invisible buffer */
  1738. X            bin_to_text (&cur_mask -> l_text[curwp -> w_loff],
  1739. X                &mask_buf[siz_prompt2],
  1740. X                prt_siz, curwp -> w_fmt_ptr);
  1741. X
  1742. X            for (i = siz_prompt2; (disp_buf[i] != 0) && (i < NCOL); i++)
  1743. X            {
  1744. X                if ((mask_buf[i] != '0') &&
  1745. X                    (mask_buf[i] != ' '))
  1746. X                    disp_buf[i] = '?';
  1747. X            }
  1748. X        }
  1749. X        else
  1750. X        {
  1751. X            for (i = 0; i < prt_siz; i++)
  1752. X            {
  1753. X                if (cur_mask -> l_text[curwp -> w_loff + i] != 0)
  1754. X                    disp_buf[i + siz_prompt2] = '?';
  1755. X            }
  1756. X        }
  1757. X        writ_echo (disp_buf);
  1758. X    }
  1759. X    return (TRUE);
  1760. X}
  1761. X
  1762. X/*
  1763. X*   Recall the last contents of the search string
  1764. X*/
  1765. Xbool    recall ()
  1766. X{
  1767. X    recall_flag = TRUE;
  1768. X    return (TRUE);
  1769. X}
  1770. X
  1771. X/*
  1772. X*   Switch between search pattern and replace pattern and their 
  1773. X*   respective masks 
  1774. X*/
  1775. Xvoid    next_pat ()
  1776. X{
  1777. X    if (cur_pat == srch_pat)
  1778. X    {
  1779. X        cur_prompt = MSG_rpl_str;
  1780. X        cur_pat = rplc_pat; /* point to replace pattern */
  1781. X        cur_mask = rplc_mask;
  1782. X    }
  1783. X    else
  1784. X    {
  1785. X        cur_prompt = MSG_sch_str;
  1786. X        cur_pat = srch_pat;     /* point to search pattern */
  1787. X        cur_mask = srch_mask;
  1788. X    }
  1789. X    curwp -> w_dotp = cur_pat;
  1790. X    curwp -> w_linep = cur_pat;
  1791. X    curbp -> b_linep -> l_fp = cur_pat;
  1792. X    curbp -> b_linep -> l_bp = cur_pat;
  1793. X
  1794. X    if (curwp -> w_doto > cur_pat -> l_used)
  1795. X    {
  1796. X        curwp -> w_doto = cur_pat -> l_used;
  1797. X        curwp -> w_unit_offset = 0;
  1798. X    }
  1799. X    if (curwp -> w_loff > cur_pat -> l_used)
  1800. X        curwp -> w_loff = cur_pat -> l_used;
  1801. X    dont_repeat = TRUE;
  1802. X}
  1803. X
  1804. X/*
  1805. X* Compare the contents of two windows.
  1806. X* There must be exactly two windows displayed.
  1807. X* The bytes under the cursor in each window are compared and if 
  1808. X* a difference is found then the loop is stopped with the dot
  1809. X* position in each window pointing to the difference.
  1810. X* The two windows can be pointing at the same or different buffers.
  1811. X*/
  1812. Xbool    compare ()
  1813. X
  1814. X{
  1815. X    WINDOW  *wp1, *wp2;
  1816. X    bool    move1, move2;
  1817. X    int     j;
  1818. X    char    *term_str = MSG_cmp_dif;
  1819. X    char    buf[NCOL], buf1[NCOL];
  1820. X
  1821. X    if (wheadp -> w_wndp -> w_wndp != NULL)
  1822. X    {
  1823. X        writ_echo (MSG_only_2);
  1824. X        return (FALSE);
  1825. X    }
  1826. X
  1827. X    wp1 = wheadp;
  1828. X    wp2 = wheadp -> w_wndp;
  1829. X    j =  (int)DOT_POS(curwp) & 0xffff;
  1830. X
  1831. X    wp1 -> w_flag |= WFMOVE;
  1832. X    wp2 -> w_flag |= WFMOVE;
  1833. X
  1834. X    while (DOT_CHAR(wp1) == DOT_CHAR(wp2))
  1835. X    {
  1836. X        if ((j++ & 0xff) == 0)
  1837. X        {
  1838. X            sprintf (buf1, MSG_cmping, R_POS_FMT(curwp));
  1839. X            sprintf (buf, buf1, DOT_POS(curwp));
  1840. X            writ_echo (buf);
  1841. X            /* check if we should quit */
  1842. X            if (ttkeyready ())
  1843. X            {
  1844. X                if (ttgetc () == CTL_G)
  1845. X                {
  1846. X                    term_str = MSG_cmp_term;
  1847. X                    break;
  1848. X                }
  1849. X            }
  1850. X        }
  1851. X        move1 = move_ptr (wp1, 1L, TRUE, FALSE, TRUE);
  1852. X        move2 = move_ptr (wp2, 1L, TRUE, FALSE, TRUE);
  1853. X
  1854. X        if (!(move1 && move2))
  1855. X        {
  1856. X            term_str = MSG_cmp_end;
  1857. X            break;
  1858. X        }
  1859. X    }
  1860. X    writ_echo (term_str);
  1861. X    wind_on_dot (wp1);
  1862. X    wind_on_dot (wp2);
  1863. X    return (TRUE);
  1864. X}
  1865. END_OF_FILE
  1866.   if test 24696 -ne `wc -c <'search.c'`; then
  1867.     echo shar: \"'search.c'\" unpacked with wrong size!
  1868.   fi
  1869.   # end of 'search.c'
  1870. fi
  1871. echo shar: End of archive 5 \(of 9\).
  1872. cp /dev/null ark5isdone
  1873. MISSING=""
  1874. for I in 1 2 3 4 5 6 7 8 9 ; do
  1875.     if test ! -f ark${I}isdone ; then
  1876.     MISSING="${MISSING} ${I}"
  1877.     fi
  1878. done
  1879. if test "${MISSING}" = "" ; then
  1880.     echo You have unpacked all 9 archives.
  1881.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1882. else
  1883.     echo You still must unpack the following archives:
  1884.     echo "        " ${MISSING}
  1885. fi
  1886. exit 0
  1887. exit 0 # Just in case...
  1888.