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

  1. Newsgroups: comp.sources.misc
  2. From: pvr@wang.com (Peter Reilley)
  3. Subject:  v26i042:  beav - Binary file editor and viewer, v1.32, Part06/09
  4. Message-ID: <1991Nov21.230311.1795@sparky.imd.sterling.com>
  5. X-Md4-Signature: bcdbfdfae60a165cb15130d717e26304
  6. Date: Thu, 21 Nov 1991 23:03:11 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pvr@wang.com (Peter Reilley)
  10. Posting-number: Volume 26, Issue 42
  11. Archive-name: beav/part06
  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:  amibeav.lnk amiga.c line.c symbol.c ttyio.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 6 (of 9)."'
  25. if test -f 'amibeav.lnk' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'amibeav.lnk'\"
  27. else
  28.   echo shar: Extracting \"'amibeav.lnk'\" \(281 characters\)
  29.   sed "s/^X//" >'amibeav.lnk' <<'END_OF_FILE'
  30. XFROM LIB:c.o+
  31. Xamiga.o basic.o ebcdic.o fileio.o region.o text.o wangpc.o
  32. Xbuffer.o echo.o main.o search.o tty.o window.o
  33. Xcinfo.o extend.o kbd.o spawn.o ttyio.o termio.o tcap.o word.o
  34. Xdisplay.o file.o line.o random.o symbol.o ttykbd.o format.o
  35. XTO "beav"
  36. XLIB LIB:lc.lib LIB:amiga.lib
  37. END_OF_FILE
  38.   if test 281 -ne `wc -c <'amibeav.lnk'`; then
  39.     echo shar: \"'amibeav.lnk'\" unpacked with wrong size!
  40.   fi
  41.   # end of 'amibeav.lnk'
  42. fi
  43. if test -f 'amiga.c' -a "${1}" != "-c" ; then 
  44.   echo shar: Will not clobber existing file \"'amiga.c'\"
  45. else
  46.   echo shar: Extracting \"'amiga.c'\" \(13875 characters\)
  47.   sed "s/^X//" >'amiga.c' <<'END_OF_FILE'
  48. X/* -*-C-*-
  49. X *
  50. X * Module : amiga.c
  51. X *
  52. X * Author : Simon J Raybould.    (sie@fulcrum.bt.co.uk).
  53. X *
  54. X * Date   : Tuesday 11th June 1991.
  55. X *
  56. X * Desc   : amiga specifics for beav binary editor.
  57. X *
  58. X *
  59. X * This file is public domain and you can do what you want with it, even roll
  60. X * it up into a ball and toss it for your cat to chase. I accept no
  61. X * resposibility for it being unfit for any purpose (including a feline toy).
  62. X * Any bugs you can either fix them yourself or tell me and I'll do it.
  63. X * Any major fixes should be reported to me and I will inform the main keeper
  64. X * of beav to be sure they are fixed in the next release. This only applies to
  65. X * bugs in THIS FILE or in AMIGA sections of other files. Any other bugs to the
  66. X * original author.
  67. X *
  68. X * SJR - 25.Aug.91
  69. X *
  70. X *
  71. X */
  72. X
  73. X#ifdef AMIGA
  74. X
  75. X#include <stdio.h>
  76. X#include <fcntl.h>
  77. X#include <errno.h>
  78. X#include <signal.h>
  79. X#include <libraries/dosextens.h>
  80. X#include <exec/memory.h>
  81. X#include <intuition/intuition.h>
  82. X
  83. X#include "def.h"
  84. X
  85. X#define SCRBUFSIZ        1024    /* buffered screen io */
  86. X
  87. Xstruct NewWindow nw = {
  88. X    0, 0, 640,256, -1,-1, NULL,
  89. X    WINDOWDEPTH|WINDOWDRAG|SMART_REFRESH|ACTIVATE|BORDERLESS,
  90. X    NULL, NULL,
  91. X    "BEAV V1.32 Amiga Port by S.J.Raybould (sie@fulcrum.bt.co.uk)  Sep 1991",
  92. X    NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN
  93. X};
  94. X
  95. X/* Opens/allocations we'll need to clean up */
  96. Xstruct Library  *IntuitionBase = NULL;
  97. Xstruct Window   *win = NULL, *OpenWindow();
  98. Xstruct IOStdReq *writeReq = NULL;    /* I/O request block pointer */
  99. Xstruct MsgPort  *writePort = NULL;   /* replyport for writes      */
  100. X
  101. Xstruct IOStdReq *readReq = NULL;     /* I/O request block pointer */
  102. Xstruct MsgPort  *readPort = NULL;    /* replyport for reads       */
  103. X
  104. Xstruct MsgPort  *CreatePort();
  105. XBOOL OpenedConsole = FALSE;
  106. XUBYTE ibuf;
  107. XBYTE OpenConsole();
  108. Xvoid CloseConsole(), QueueRead(), ConWrite();
  109. X
  110. X
  111. Xint     nrow;                   /* Terminal size, rows.         */
  112. Xint     ncol;                   /* Terminal size, columns.      */
  113. X#ifdef CRAP
  114. Xint tceeol = 3;            /* Costs.                       */
  115. X#endif CRAP
  116. X
  117. Xint kbdpoll;            /* in O_NDELAY mode         */
  118. Xint kbdqp;            /* there is a char in kbdq  */
  119. X
  120. Xchar scrbuf[SCRBUFSIZ];        /* buffered screen io */
  121. Xshort scrbufpos = 0;        /* current write position */
  122. X
  123. X/* CODE TO REPLACE STUFF IN termio.c */
  124. X
  125. X/*
  126. X * This function gets called just before we go back home to the command
  127. X * interpreter. On VMS it puts the terminal back in a reasonable state.
  128. X * Another no-operation on CPM.
  129. X */
  130. Xvoid
  131. Xttclose()
  132. X{
  133. X    /* Put TTY back in sesible state */
  134. X    if(!(CheckIO(readReq))) AbortIO(readReq);
  135. X    WaitIO(readReq);
  136. X    if(OpenedConsole) CloseConsole(writeReq);
  137. X    if(readReq)       DeleteExtIO(readReq);
  138. X    if(readPort)      DeletePort(readPort);
  139. X    if(writeReq)      DeleteExtIO(writeReq);
  140. X    if(writePort)     DeletePort(writePort);
  141. X    if(win)           CloseWindow(win);
  142. X    if(IntuitionBase) CloseLibrary(IntuitionBase);
  143. X}
  144. X
  145. X/*
  146. X * Flush terminal buffer. Does real work where the terminal output is buffered
  147. X * up. A no-operation on systems where byte at a time terminal I/O is done.
  148. X */
  149. Xvoid
  150. Xttflush()
  151. X{
  152. X    if(scrbufpos>0) {
  153. X        ConWrite(writeReq, scrbuf, scrbufpos);
  154. X        scrbufpos = 0;
  155. X    }
  156. X}
  157. X
  158. X/*
  159. X * Write a character to the display. On VMS, terminal output is buffered, and
  160. X * we just put the characters in the big array, after checking for overflow.
  161. X * On CPM terminal I/O unbuffered, so we just write the byte out. Ditto on
  162. X * MS-DOS (use the very very raw console output routine).
  163. X */
  164. Xvoid ttputc(c)
  165. X{
  166. X    if(scrbufpos < SCRBUFSIZ)
  167. X        scrbuf[scrbufpos++] = c;
  168. X    else {
  169. X        ConWrite(writeReq, scrbuf, scrbufpos);
  170. X        scrbufpos = 0;
  171. X        scrbuf[scrbufpos++] = c;
  172. X    }
  173. X}
  174. X
  175. Xvoid
  176. Xttputs(char *str)
  177. X{
  178. X    while(*str)
  179. X        ttputc(*str++);
  180. X}
  181. X
  182. X/*
  183. X * Read a character from the terminal, performing no editing and doing no echo
  184. X * at all. More complex in VMS that almost anyplace else, which figures. Very
  185. X * simple on CPM, because the system can do exactly what you want.
  186. X */
  187. Xttgetc()
  188. X{
  189. X    char c, ConGetChar();
  190. X    static char Buffer[8], ri=0, wi=0;
  191. X
  192. X    if(kbdqp)
  193. X        kbdqp = FALSE;
  194. X    /* If we stil have chars from last time, return them */
  195. X    if(ri<wi)
  196. X        return Buffer[ri++]&0x7f;
  197. X
  198. X    /* Else empty the buffer and start a new read */
  199. X    ri=wi=0;
  200. X    c = ConGetChar(readPort, &ibuf);
  201. X    /*
  202. X   * Attempt some translations !
  203. X   * This is the place to extend, if you wish to add some more.
  204. X   * SEE RKM L&D 1.3 pg 654 for more info.
  205. X   */
  206. X    if((unsigned char)c == (unsigned char)0x9b) {    /* ANSI esc start */
  207. X        c = ConGetChar(readPort, &ibuf);
  208. X        switch(c) {
  209. X        case 'A':            /* UP */
  210. X            Buffer[wi++] = 0x10;    /* ^P */
  211. X            break;
  212. X        case 'B':            /* DOWN */
  213. X            Buffer[wi++] = 0x0e;    /* ^N */
  214. X            break;
  215. X        case 'C':            /* RIGHT */
  216. X            Buffer[wi++] = 0x06;    /* ^F */
  217. X            break;
  218. X        case 'D':            /* LEFT */
  219. X            Buffer[wi++] = 0x02;    /* ^B */
  220. X            break;
  221. X        case '0':            /* F1 */
  222. X            ConGetChar(readPort, &ibuf); /* discard tilde */
  223. X            Buffer[wi++] = 0x1b;    /* HELP = "ESC ?" */
  224. X            Buffer[wi++] = '?';
  225. X            break;
  226. X        case '1':            /* F2 or SHIFTED function key */
  227. X            c = ConGetChar(readPort, &ibuf); /* Get next char to see if it's a tilde */
  228. X            switch(c) {
  229. X            case '~':            /* was definately F2 */
  230. X                Buffer[wi++] = 0x1b;    /* mark-set = "ESC ." */
  231. X                Buffer[wi++] = '.';
  232. X                break;
  233. X            case '0':            /* SHIFTED F1 */
  234. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  235. X                Buffer[wi++] = 0x18;    /* binding-for-key = "Ctl-X ?" */
  236. X                Buffer[wi++] = '?';
  237. X                break;
  238. X            case '1':            /* SHIFTED F2 */
  239. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  240. X                Buffer[wi++] = 0x18;    /* file-read = "Ctl-X Ctl-R" */
  241. X                Buffer[wi++] = 0x12;
  242. X                break;
  243. X            case '2':            /* SHIFTED F3 */
  244. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  245. X                Buffer[wi++] = 0x18;    /* file-save = "Ctl-X Ctl-S" */
  246. X                Buffer[wi++] = 0x13;
  247. X                break;
  248. X            case '3':            /* SHIFTED F4 */
  249. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  250. X                Buffer[wi++] = 0x18;    /* file-visit = "Ctl-X Ctl-V" */
  251. X                Buffer[wi++] = 0x16;
  252. X                break;
  253. X            case '4':            /* SHIFTED F5 */
  254. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  255. X                Buffer[wi++] = 0x18;    /* file-write = "Ctl-X Ctl-W" */
  256. X                Buffer[wi++] = 0x17;
  257. X                break;
  258. X            case '5':            /* SHIFTED F6 */
  259. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  260. X                Buffer[wi++] = 0x18;    /* save-all-buffers = "Ctl-X return" */
  261. X                Buffer[wi++] = '\r';
  262. X                break;
  263. X            case '6':            /* SHIFTED F7 */
  264. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  265. X                Buffer[wi++] = 0x18;    /* buffer-set-file-name = "Ctl-X Ctl-F" */
  266. X                Buffer[wi++] = 0x06;
  267. X                break;
  268. X            case '7':            /* SHIFTED F8 */
  269. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  270. X                Buffer[wi++] = 0x18;    /* insert-file = "Ctl-X TAB" */
  271. X                Buffer[wi++] = '\t';
  272. X                break;
  273. X            case '8':            /* SHIFTED F9 */
  274. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  275. X                Buffer[wi++] = 0x18;    /* quit-save-all = "Ctl-X Ctl-E" */
  276. X                Buffer[wi++] = 0x05;
  277. X                break;
  278. X            case '9':            /* SHIFTED F10 */
  279. X                ConGetChar(readPort, &ibuf);    /* Discard the tilde */
  280. X                Buffer[wi++] = 0x03;    /* quit-no-save = "Ctl-C" */
  281. X                break;
  282. X            }
  283. X            break;
  284. X        case '2':            /* F3 */
  285. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  286. X            Buffer[wi++] = 0x1b;      /* search-forv = "ESC s" */
  287. X            Buffer[wi++] = 's';
  288. X            break;
  289. X        case '3':            /* F4 */
  290. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  291. X            Buffer[wi++] = 0x1b;    /* search-again = "ESC t" */
  292. X            Buffer[wi++] = 't';
  293. X            break;
  294. X        case '4':            /* F5 */
  295. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  296. X            Buffer[wi++] = 0x1b;    /* replace = "ESC %" */
  297. X            Buffer[wi++] = '%';
  298. X            break;
  299. X        case '5':            /* F6 */
  300. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  301. X            Buffer[wi++] = 0x19;    /* yank = "Ctl-Y" */
  302. X            break;
  303. X        case '6':            /* F7 */
  304. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  305. X            Buffer[wi++] = 0x1b;    /* copy-mark-to-cursor = "ESC w" */
  306. X            Buffer[wi++] = 'w';
  307. X            break;
  308. X        case '7':            /* F8 */
  309. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  310. X            Buffer[wi++] = 0x17;    /* delete-mark-to-cursor = "Ctl-W" */
  311. X            break;
  312. X        case '8':            /* F9 */
  313. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  314. X            Buffer[wi++] = 0x18;    /* move-to-byte = "Ctl-X G" */
  315. X            Buffer[wi++] = 'G';
  316. X            break;
  317. X        case '9':            /* F10 */
  318. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  319. X            Buffer[wi++] = 0x07;    /* abort-cmd = "Ctl-G" */
  320. X            break;
  321. X        case '?':            /* HELP */
  322. X            ConGetChar(readPort, &ibuf);        /* Discard the tilde */
  323. X            Buffer[wi++] = 0x1b;    /* help = "ESC ?" */
  324. X            Buffer[wi++] = '?';
  325. X            break;
  326. X        }
  327. X        return Buffer[ri++]&0x7f;
  328. X    } else    /* not an ANSI sequence */
  329. X        return c&0x7f;
  330. X}
  331. X
  332. X/*
  333. X * This function is called once to set up the terminal device streams.
  334. X * On VMS, it translates TT until it finds the terminal, then assigns
  335. X * a channel to it and sets it raw. On CPM it is a no-op.
  336. X */
  337. X
  338. Xvoid ttopen()
  339. X{
  340. X    int Sig;
  341. X    ULONG conreadsig, windowsig;
  342. X    BYTE error;
  343. X    struct Screen Screen;        /* get a copy of WBENCHSCREEN in here */
  344. X
  345. X
  346. X    if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0))) {
  347. X        printf("Can't open intuition\n");
  348. X        ttclose();
  349. X        exit(10);
  350. X    }
  351. X    /* Create reply port and io block for writing to console */
  352. X    if(!(writePort = CreatePort("LARN.console.write",0))) {
  353. X        printf("Can't create write port\n");
  354. X        ttclose();
  355. X        exit(10);
  356. X    }
  357. X    if(!(writeReq = (struct IOStdReq *)
  358. X        CreateExtIO(writePort,(LONG)sizeof(struct IOStdReq)))) {
  359. X        printf("Can't create write request\n");
  360. X        ttclose();
  361. X        exit(10);
  362. X    }
  363. X    /* Create reply port and io block for reading from console */
  364. X    if(!(readPort = CreatePort("LARN.console.read",0))) {
  365. X        printf("Can't create read port\n");
  366. X        ttclose();
  367. X        exit(10);
  368. X    }
  369. X    if(!(readReq = (struct IOStdReq *)
  370. X        CreateExtIO(readPort,(LONG)sizeof(struct IOStdReq)))) {
  371. X        printf("Can't create read request\n");
  372. X        ttclose();
  373. X        exit(10);
  374. X    }
  375. X    if(!GetScreenData(&Screen, sizeof(struct Screen), WBENCHSCREEN, NULL)) {
  376. X        printf("Can't get screen size\n");
  377. X        ttclose();
  378. X        exit(10);
  379. X    }
  380. X    nrow = Screen.Height/8-3;
  381. X    ncol = Screen.Width/8;
  382. X    nw.Height = Screen.Height;
  383. X    nw.Width = Screen.Width;
  384. X
  385. X    /* don't allow a larger number of rows than we can handle */
  386. X    if (nrow > NROW)
  387. X        nrow = NROW;
  388. X    /* don't allow a larger number of cols than we can handle */
  389. X    if (ncol > NCOL)
  390. X        ncol = NCOL;
  391. X
  392. X    /* Open a window */
  393. X    if(!(win = OpenWindow(&nw))) {
  394. X        printf("Can't open window\n");
  395. X        ttclose();
  396. X        exit(10);
  397. X    }
  398. X    /* Now, attach a console to the window */
  399. X    if(error = OpenConsole(writeReq,readReq,win)) {
  400. X        printf("Can't open console.device\n");
  401. X        ttclose();
  402. X        exit(10);
  403. X    } else
  404. X        OpenedConsole = TRUE;
  405. X
  406. X    QueueRead(readReq,&ibuf); /* send the first console read request */
  407. X    conreadsig = 1 << readPort->mp_SigBit;
  408. X    windowsig = 1 << win->UserPort->mp_SigBit;
  409. X    for(Sig=0; Sig<NSIG; Sig++)
  410. X        signal(Sig, SIG_IGN);
  411. X
  412. X    kbdpoll = FALSE;
  413. X    /* on all screens we are not sure of the initial position of the cursor */
  414. X    ttrow = 999;
  415. X    ttcol = 999;
  416. X}
  417. X
  418. X/* END OF TERMIO REPLACEMENT CODE */
  419. X
  420. X/* Attach console device to an open Intuition window.
  421. X * This function returns a value of 0 if the console 
  422. X * device opened correctly and a nonzero value (the error
  423. X * returned from OpenDevice) if there was an error.
  424. X */
  425. XBYTE OpenConsole(writereq, readreq, window)
  426. Xstruct IOStdReq *writereq;
  427. Xstruct IOStdReq *readreq;
  428. Xstruct Window *window;
  429. X{
  430. X    BYTE error;
  431. X
  432. X    writereq->io_Data = (APTR) window;
  433. X    writereq->io_Length = sizeof(struct Window);
  434. X    error = OpenDevice("console.device", 0, writereq, 0);
  435. X    readreq->io_Device = writereq->io_Device; /* clone required parts */
  436. X    readreq->io_Unit   = writereq->io_Unit;
  437. X    return(error);
  438. X}
  439. X
  440. Xvoid CloseConsole(struct IOStdReq *writereq)
  441. X{
  442. X    CloseDevice(writereq);
  443. X}
  444. X
  445. X/* Output a single character to a specified console 
  446. X */
  447. Xvoid ConPutChar(struct IOStdReq *writereq, UBYTE character)
  448. X{
  449. X    writereq->io_Command = CMD_WRITE;
  450. X    writereq->io_Data = (APTR)&character;
  451. X    writereq->io_Length = 1;
  452. X    DoIO(writereq);
  453. X    /* command works because DoIO blocks until command is done
  454. X   * (otherwise ptr to the character could become invalid)
  455. X   */
  456. X}
  457. X
  458. X
  459. X/* Output a stream of known length to a console 
  460. X */
  461. Xvoid ConWrite(struct IOStdReq *writereq, UBYTE *string, LONG length)
  462. X{
  463. X    writereq->io_Command = CMD_WRITE;
  464. X    writereq->io_Data = (APTR)string;
  465. X    writereq->io_Length = length;
  466. X    DoIO(writereq);
  467. X    /* command works because DoIO blocks until command is done
  468. X   * (otherwise ptr to string could become invalid in the meantime)
  469. X   */
  470. X}
  471. X
  472. X
  473. X/* Output a NULL-terminated string of characters to a console 
  474. X */
  475. Xvoid ConPuts(struct IOStdReq *writereq,UBYTE *string)
  476. X{
  477. X    writereq->io_Command = CMD_WRITE;
  478. X    writereq->io_Data = (APTR)string;
  479. X    writereq->io_Length = -1;  /* means print till terminating null */
  480. X    DoIO(writereq);
  481. X}
  482. X
  483. X/* Queue up a read request to console, passing it pointer
  484. X * to a buffer into which it can read the character
  485. X */
  486. Xvoid QueueRead(struct IOStdReq *readreq, UBYTE *whereto)
  487. X{
  488. X    readreq->io_Command = CMD_READ;
  489. X    readreq->io_Data = (APTR)whereto;
  490. X    readreq->io_Length = 1;
  491. X    SendIO(readreq);
  492. X}
  493. X
  494. Xstruct IOStdReq *readreq; /* ttkeyready() needs to be able to see this */
  495. X
  496. X/* Wait for a character
  497. X */
  498. Xchar ConGetChar(struct MsgPort *msgport, UBYTE *whereto)
  499. X{
  500. X    register temp;
  501. X
  502. X    WaitPort(msgport);
  503. X    readreq = (struct IOStdReq *)GetMsg(msgport);
  504. X    temp = *whereto;               /* get the character */
  505. X    QueueRead(readreq,whereto);    /* then re-use the request block*/
  506. X    return((char)temp);
  507. X}
  508. X
  509. X/* typahead():    Check to see if any characters are already in the
  510. X        keyboard buffer
  511. X   On the amiga, we do this by checking if the outstanding read request
  512. X   has been satisfied yet by calling CheckIO().
  513. X*/
  514. Xttkeyready ()
  515. X{
  516. X    if(!kbdqp)
  517. X        kbdqp = CheckIO(readreq)?1:0;
  518. X    return kbdqp;
  519. X}
  520. X
  521. X/* UNIX support stuff */
  522. X
  523. X#define BLOCKSIZE  4096
  524. X
  525. Xlink(char *SPath, char *DPath)
  526. X{
  527. X    int sfd, dfd, Bytes;
  528. X    char BlkBuf[BLOCKSIZE];
  529. X
  530. X    if((sfd = open(SPath, O_RDONLY)) == -1)
  531. X        return -1;
  532. X    if((dfd = open(DPath, O_WRONLY|O_CREAT|O_TRUNC)) == -1)
  533. X        return -1;
  534. X    while((Bytes = read(sfd, BlkBuf, BLOCKSIZE)) > 0)
  535. X        write(dfd, BlkBuf, Bytes);
  536. X    close(sfd);
  537. X    close(dfd);
  538. X    return 0;
  539. X}
  540. X
  541. X#endif /* AMIGA */
  542. END_OF_FILE
  543.   if test 13875 -ne `wc -c <'amiga.c'`; then
  544.     echo shar: \"'amiga.c'\" unpacked with wrong size!
  545.   fi
  546.   # end of 'amiga.c'
  547. fi
  548. if test -f 'line.c' -a "${1}" != "-c" ; then 
  549.   echo shar: Will not clobber existing file \"'line.c'\"
  550. else
  551.   echo shar: Extracting \"'line.c'\" \(14071 characters\)
  552.   sed "s/^X//" >'line.c' <<'END_OF_FILE'
  553. X/*
  554. X*       Text line handling.
  555. X* The functions in this file
  556. X* are a general set of line management
  557. X* utilities. They are the only routines that
  558. X* touch the text. They also touch the buffer
  559. X* and window structures, to make sure that the
  560. X* necessary updating gets done. There are routines
  561. X* in this file that handle the kill buffer too.
  562. X* It isn't here for any good reason.
  563. X*
  564. X* Note that this code only updates the dot and
  565. X* mark values in the window list. Since all the code
  566. X* acts on the current window, the buffer that we
  567. X* are editing must be being displayed, which means
  568. X* that "b_nwnd" is non zero, which means that the
  569. X* dot and mark values in the buffer headers are
  570. X* nonsense.
  571. X*/
  572. X
  573. X#include    "def.h"
  574. X
  575. Xvoid l_fix_up ();
  576. X
  577. Xextern    char    MSG_cnt_alloc[];
  578. X#if RUNCHK
  579. Xextern    char    ERR_no_alloc[];
  580. Xextern    char    ERR_db_dalloc[];
  581. Xextern    char    ERR_lock[];
  582. Xextern    char    ERR_lock_del[];
  583. X#endif
  584. X
  585. Xextern  LINE    *cur_pat;
  586. Xextern  LINE    *cur_mask;
  587. Xextern  bool    read_pat_mode;
  588. Xextern  BUFFER  sav_buf;
  589. X
  590. X/*
  591. X* This routine allocates a block
  592. X* of memory large enough to hold a LINE
  593. X* containing "size" characters. Return a pointer
  594. X* to the new block, or NULL if there isn't
  595. X* any memory left. Print a message in the
  596. X* message line if no space.
  597. X*/
  598. XLINE * lalloc (size)
  599. Xregister int    size;
  600. X{
  601. X    register    LINE * lp;
  602. X    char    buf[NCOL], buf1[NCOL];
  603. X#if RUNCHK
  604. X    if (read_pat_mode)
  605. X        printf (ERR_no_alloc);
  606. X#endif
  607. X
  608. X    if ((lp = (LINE *) malloc (sizeof (LINE) + size)) == NULL)
  609. X    {
  610. X        sprintf (buf1, MSG_cnt_alloc, R_POS_FMT(curwp));
  611. X        sprintf (buf, buf1, (A32)size);
  612. X        err_echo (buf);
  613. X        curbp -> b_flag |= BFBAD;/* may be trashed */
  614. X        curwp -> w_flag |= WFMODE;
  615. X        update ();
  616. X        return (NULL);
  617. X    }
  618. X    lp -> l_size = size;
  619. X    lp -> l_used = 0;
  620. X    lp -> l_file_offset = 0;    /* set resonable initial value */
  621. X    return (lp);
  622. X}
  623. X
  624. X
  625. X/*
  626. X* Delete line "lp". Fix all of the
  627. X* links that might point at it (they are
  628. X* moved to offset 0 of the next line.
  629. X* Unlink the line from whatever buffer it
  630. X* might be in. Release the memory. The
  631. X* buffers are updated too; the magic conditions
  632. X* described in the above comments don't hold
  633. X* here.
  634. X*/
  635. X
  636. Xvoid lfree (lp)
  637. Xregister    LINE * lp;
  638. X{
  639. X    register    BUFFER * bp;
  640. X    register    WINDOW * wp;
  641. X
  642. X#if RUNCHK
  643. X    if (read_pat_mode)
  644. X        printf (ERR_db_dalloc);
  645. X#endif
  646. X
  647. X    wp = wheadp;
  648. X    while (wp != NULL)
  649. X    {
  650. X        if (wp -> w_linep == lp)
  651. X        {
  652. X            wp -> w_linep = lp -> l_fp;
  653. X            wp -> w_loff = 0;
  654. X        }
  655. X
  656. X        if (wp -> w_dotp == lp)
  657. X        {
  658. X            wp -> w_dotp = lp -> l_fp;
  659. X            wp -> w_doto = 0;
  660. X        }
  661. X
  662. X        if (wp -> w_markp == lp)
  663. X        {
  664. X            wp -> w_markp = lp -> l_fp;
  665. X            wp -> w_marko = 0;
  666. X        }
  667. X
  668. X        wp = wp -> w_wndp;
  669. X    }
  670. X
  671. X    bp = bheadp;
  672. X    while (bp != NULL)
  673. X    {
  674. X        if (bp -> b_nwnd == 0)
  675. X        {
  676. X            if (bp -> b_dotp == lp)
  677. X            {
  678. X                bp -> b_dotp = lp -> l_fp;
  679. X                bp -> b_doto = 0;
  680. X            }
  681. X
  682. X            if (bp -> b_markp == lp)
  683. X            {
  684. X                bp -> b_markp = lp -> l_fp;
  685. X                bp -> b_marko = 0;
  686. X            }
  687. X        }
  688. X        bp = bp -> b_bufp;
  689. X    }
  690. X
  691. X    lp -> l_bp -> l_fp = lp -> l_fp;
  692. X    lp -> l_fp -> l_bp = lp -> l_bp;
  693. X    free ((char *) lp);
  694. X}
  695. X
  696. X
  697. X/*
  698. X* This routine gets called when
  699. X* a character is changed in place in the
  700. X* current buffer. It updates all of the required
  701. X* flags in the buffer and window system. The flag
  702. X* used is passed as an argument; if the buffer is being
  703. X* displayed in more than 1 window we change EDIT to
  704. X* HARD. Set MODE if the mode line needs to be
  705. X* updated (the "*" has to be set).
  706. X*/
  707. Xvoid lchange (flag)
  708. Xregister int    flag;
  709. X{
  710. X    register    WINDOW * wp;
  711. X
  712. X    if (curbp -> b_nwnd != 1)   /* Ensure hard.     */
  713. X        flag = WFHARD;
  714. X    if ((curbp -> b_flag & BFCHG) == 0)
  715. X    {
  716. X        /* First change, so     */
  717. X        flag |= WFMODE;         /* update mode lines.   */
  718. X        curbp -> b_flag |= BFCHG;
  719. X    }
  720. X
  721. X    wp = wheadp;
  722. X    while (wp != NULL)
  723. X    {
  724. X        if (wp -> w_bufp == curbp)
  725. X            wp -> w_flag |= flag;
  726. X        wp = wp -> w_wndp;
  727. X    }
  728. X}
  729. X
  730. X
  731. X/*
  732. X *  Break the line "dotp" in two at the position "doto."
  733. X */
  734. X
  735. XLINE *l_break_in_two (lp, lo, extra)
  736. Xregister LINE  *lp;
  737. Xregister LPOS  lo, extra;
  738. X{
  739. X    register LINE  *new_lp;
  740. X    register D8    *cp1;
  741. X    register D8    *cp2;
  742. X    LPOS    cnt, i;
  743. X
  744. X    i = 0;
  745. X    cnt = lp -> l_used - lo;
  746. X    if ((new_lp = lalloc (cnt + extra)) == NULL)
  747. X        return (NULL);
  748. X
  749. X    cp1 = &lp -> l_text[lo];  /* starting location, source */
  750. X    cp2 = &new_lp -> l_text[0];  /* starting location, destination */
  751. X
  752. X    /* kill bytes in the current line */
  753. X    while (i++ < cnt)
  754. X    {
  755. X        *cp2++ = *cp1++;
  756. X    }
  757. X    lp -> l_used -= cnt;
  758. X    new_lp -> l_used = cnt;
  759. X    new_lp -> l_file_offset = new_lp -> l_file_offset + lo;
  760. X
  761. X    /* insert into chain */
  762. X    new_lp -> l_fp = lp -> l_fp;
  763. X    lp -> l_fp = new_lp;
  764. X    new_lp -> l_bp = lp;
  765. X    new_lp -> l_fp -> l_bp = new_lp;
  766. X    return (new_lp);
  767. X}
  768. X
  769. X/*
  770. X* Insert "n" copies of the character "c"
  771. X* at the current location of dot. In the easy case
  772. X* all that happens is the text is stored in the line.
  773. X* Always allocate some extra space in line so that edit 
  774. X* will be faster next time but will save space in the general case.
  775. X* In the hard case, the line has to be reallocated.
  776. X* When the window list is updated, take special
  777. X* care; I screwed it up once. You always update dot
  778. X* in the current window. You update mark, and a
  779. X* dot in another window, if it is greater than
  780. X* the place where you did the insert. Return TRUE
  781. X* if all is well, and FALSE on errors.
  782. X*/
  783. Xbool linsert (n, c)
  784. Xuchar   c;
  785. X{
  786. X    register D8    *cp1;
  787. X    register D8    *cp2;
  788. X    register    LINE * lp1;
  789. X    register    LINE * lp2;
  790. X    register short  doto;
  791. X    register int    i;
  792. X    register    WINDOW * wp;
  793. X
  794. X#if RUNCHK
  795. X    /* check that buffer size can be changed */
  796. X    if (curbp -> b_flag & BFSLOCK)
  797. X    {
  798. X        writ_echo (ERR_lock);
  799. X        return (FALSE);
  800. X    }
  801. X#endif
  802. X
  803. X    lchange (WFMOVE);
  804. X    lp1 = curwp -> w_dotp;      /* Current line     */
  805. X    if (lp1 == curbp -> b_linep)
  806. X    {
  807. X        /* At the end: special  */
  808. X        /* break the current line at the end */
  809. X        if ((lp2 = l_break_in_two (lp1, lp1 -> l_used, (LPOS)n + NBLOCK)) == NULL)
  810. X            return (FALSE);
  811. X        for (i = 0; i < n; ++i)     /* Add the characters   */
  812. X            lp2 -> l_text[i] = c;
  813. X        lp2 -> l_used = n;
  814. X        curwp -> w_dotp = lp2;
  815. X        curwp -> w_doto = n;
  816. X        return (TRUE);
  817. X    }
  818. X
  819. X    doto = curwp -> w_doto;     /* Save for later.  */
  820. X    if (lp1 -> l_used + n > lp1 -> l_size)
  821. X    {
  822. X        /* break the current line and let the normal insert do it */
  823. X        if ((lp2 = l_break_in_two (lp1, doto, (LPOS)n + NBLOCK)) == NULL)
  824. X            return (FALSE);
  825. X        lp1 -> l_text[doto] = c;
  826. X        lp1 -> l_used++;
  827. X        curwp -> w_doto++;
  828. X        if (curwp -> w_doto >= lp1 -> l_used)
  829. X        {
  830. X            curwp -> w_dotp = lp2;
  831. X            curwp -> w_doto = 0;
  832. X        }
  833. X        if (n > 1)
  834. X            return (linsert (n - 1, c));    /* handle the rest in normal maner */
  835. X    }
  836. X    else
  837. X    {
  838. X        /* Easy: in place   */
  839. X        lp2 = lp1;              /* Pretend new line */
  840. X        lp2 -> l_used += n;
  841. X        cp2 = &lp1 -> l_text[lp1 -> l_used];
  842. X        cp1 = cp2 - n;
  843. X        while (cp1 != &lp1 -> l_text[doto])
  844. X            *--cp2 = *--cp1;
  845. X        for (i = 0; i < n; ++i)     /* Add the characters   */
  846. X            lp2 -> l_text[doto + i] = c;
  847. X        move_ptr (curwp, (A32)n, TRUE, TRUE, TRUE);
  848. X    }
  849. X
  850. X    wp = wheadp;                /* Update windows   */
  851. X    while (wp != NULL)
  852. X    {
  853. X        if ((wp -> w_linep == lp1) && (wp -> w_loff >= lp1 -> l_used))
  854. X        {
  855. X            wp -> w_linep = lp2;
  856. X            wp -> w_loff -= lp1 -> l_used;
  857. X        }
  858. X
  859. X        /* move dot to next line but not to head line */
  860. X        if ((wp -> w_dotp == lp1) && (wp -> w_doto >= lp1 -> l_used) &&
  861. X            (wp -> w_dotp -> l_fp -> l_size != 0))
  862. X        {
  863. X            wp -> w_dotp = lp2;
  864. X            wp -> w_doto -= (lp1 -> l_used - 1);
  865. X        }
  866. X
  867. X        if ((wp -> w_markp == lp1) && (wp -> w_marko >= lp1 -> l_used))
  868. X        {
  869. X            wp -> w_markp = lp2;
  870. X            wp -> w_marko -= (lp1 -> l_used - 1);
  871. X        }
  872. X
  873. X        wp = wp -> w_wndp;
  874. X    }
  875. X    l_fix_up (lp1);   /* re-adjust file offsets */
  876. X    return (TRUE);
  877. X}
  878. X
  879. X/*
  880. X* This function deletes n_bytes,
  881. X* starting at dot. It understands how to deal
  882. X* with end of lines, etc. It returns TRUE if all
  883. X* of the characters were deleted, and FALSE if
  884. X* they were not (because dot ran into the end of
  885. X* the buffer). The "kflag" is TRUE if the text
  886. X* should be put in the kill buffer.
  887. X*/
  888. Xbool ldelete (n_bytes, kflag)
  889. XA32    n_bytes;
  890. X{
  891. X    register LINE  *dotp, *lp, *lp_prev, *lp_next;
  892. X    register LPOS  doto, l_cnt;
  893. X    register WINDOW *wp;
  894. X    D8       *cp1, *cp2;
  895. X    D32      n_byt, dot_pos;
  896. X
  897. X#if RUNCHK
  898. X    /* check that buffer size can be changed */
  899. X    if (curbp -> b_flag & BFSLOCK)
  900. X    {
  901. X        writ_echo (ERR_lock_del);
  902. X        return (FALSE);
  903. X    }
  904. X#endif
  905. X    lchange (WFMOVE);
  906. X    doto = curwp -> w_doto;
  907. X    dotp = curwp -> w_dotp;
  908. X    lp_prev = dotp -> l_bp;
  909. X    dot_pos = DOT_POS(curwp);
  910. X
  911. X    /* if at the end of the buffer then delete nothing */
  912. X    if (dot_pos >= BUF_SIZE(curwp))
  913. X    {
  914. X        l_fix_up (dotp);    /* re-adjust file offsets */
  915. X        return (TRUE);
  916. X    }
  917. X
  918. X    /* save dot and mark positions for later restore */
  919. X    wp = wheadp;
  920. X    while (wp != NULL)
  921. X    {
  922. X        wp->w_dot_temp = DOT_POS (wp);
  923. X        if (wp->w_markp != NULL)  /* mark may not be set */
  924. X            wp->w_mark_temp = MARK_POS (wp);
  925. X        wp->w_wind_temp = WIND_POS (wp);
  926. X        wp = wp -> w_wndp;
  927. X    }
  928. X
  929. X    /* is delete wholy within one line? */
  930. X    if ((doto + n_bytes) < dotp -> l_used)
  931. X    {
  932. X        cp1 = &dotp -> l_text[doto];/* Scrunch text.    */
  933. X        cp2 = cp1 + n_bytes;
  934. X
  935. X        /* put stuff to delete into the kill buffer */
  936. X        if (kflag != FALSE)
  937. X        {
  938. X            /* Kill?        */
  939. X            while (cp1 != cp2)
  940. X            {
  941. X                if (b_append_c (&sav_buf, *cp1) == FALSE)
  942. X                    return (FALSE);
  943. X                ++cp1;
  944. X            }
  945. X            cp1 = &dotp -> l_text[doto];
  946. X        }
  947. X        /* kill bytes in the current line */
  948. X        while (cp2 < &dotp -> l_text[dotp -> l_used])
  949. X            *cp1++ = *cp2++;
  950. X
  951. X        dotp -> l_used -= n_bytes;
  952. X    }
  953. X    else
  954. X    {   /* wholesale delete by moving lines to save buffer */
  955. X        if (doto != 0)
  956. X        {
  957. X            if ((lp = l_break_in_two (dotp, doto, 0l)) == NULL)
  958. X                return (FALSE);
  959. X        }
  960. X        else
  961. X            lp = dotp;
  962. X
  963. X        n_byt = n_bytes;
  964. X        /* now handle whole lines if necessary */
  965. X        while (n_byt > 0)
  966. X        {
  967. X            lp_next = lp -> l_fp;
  968. X
  969. X            if (n_byt < lp -> l_used)
  970. X            {
  971. X                /* get last piece of a line */
  972. X                lp_next = l_break_in_two (lp, n_byt, 0l);
  973. X            }
  974. X            n_byt -= lp -> l_used;
  975. X            if (kflag)
  976. X            {
  977. X                /* remove form linked list */
  978. X                lp -> l_bp -> l_fp = lp -> l_fp;
  979. X                lp -> l_fp -> l_bp = lp -> l_bp;
  980. X                /* append it to the save buffer */
  981. X                b_append_l (&sav_buf, lp);
  982. X            }
  983. X            else
  984. X                /* if we don't want it, free it */
  985. X                lfree (lp);
  986. X            lp = lp_next;
  987. X        }
  988. X    }
  989. X    l_fix_up (lp_prev);    /* re-adjust file offsets */
  990. X
  991. X    /* adjust dot and marks in other windows */
  992. X    /* this should be ok because the save buffer dosn't disturb l_file_offset */
  993. X    wp = wheadp;            /* Fix windows      */
  994. X    while (wp != NULL)
  995. X    {
  996. X        if (curbp == wp -> w_bufp)
  997. X        {
  998. X            A32    temp;
  999. X
  1000. X            /* if dot is before delete position, do nothing */
  1001. X            if (dot_pos <= (temp = wp -> w_dot_temp))
  1002. X            {
  1003. X                /* step back to the previous line */
  1004. X                wp -> w_doto = 0;
  1005. X                wp -> w_dotp = lp_prev;
  1006. X
  1007. X                /* if dot is in deleted range, set to dot position */
  1008. X                if (temp > dot_pos + n_bytes)
  1009. X                    /* if after deleted range, move back deleted ammount */
  1010. X                    move_ptr (wp, temp - n_bytes, TRUE, TRUE, FALSE);
  1011. X                else
  1012. X                    /* if in the deleted range, move to curwp dot position */
  1013. X                    move_ptr (wp, dot_pos, TRUE, TRUE, FALSE);
  1014. X            }
  1015. X            /* mark may not be set in some windows */
  1016. X            if (wp -> w_markp != NULL)
  1017. X            {
  1018. X                /* do the same for mark */
  1019. X                if (dot_pos <= (temp = wp->w_mark_temp))
  1020. X                {
  1021. X                    /* if in or after the deleted range, move to curwp dot position */
  1022. X                    wp -> w_marko = curwp -> w_doto;
  1023. X                    wp -> w_markp = curwp -> w_dotp;
  1024. X
  1025. X                    /* if mark after deleted range */
  1026. X                    if (temp > dot_pos + n_bytes)
  1027. X                    {
  1028. X                        /* if after deleted range, move back deleted ammount */
  1029. X                        /* move dot then swap with mark to produce result */
  1030. X                        move_ptr (wp, temp - n_bytes, TRUE, TRUE, FALSE);
  1031. X                        lp_next = wp -> w_dotp;
  1032. X                        wp -> w_dotp = wp -> w_markp;
  1033. X                        wp -> w_markp = lp_next;
  1034. X                        l_cnt = wp -> w_doto;
  1035. X                        wp -> w_doto = wp -> w_marko;
  1036. X                        wp -> w_marko = l_cnt;
  1037. X                    }
  1038. X                }
  1039. X            }
  1040. X            /* if window position is before delete position, do nothing */
  1041. X            if (dot_pos <= (temp = wp -> w_wind_temp))
  1042. X            {
  1043. X                /* set window position to dot position */
  1044. X                wp -> w_loff = 0;
  1045. X                wp -> w_linep = wp -> w_dotp;
  1046. X                wind_on_dot (wp);
  1047. X            }
  1048. X        }
  1049. X        wp = wp -> w_wndp;
  1050. X    }
  1051. X    /* update buffer display */
  1052. X    if ((blistp -> b_nwnd != 0) &&
  1053. X        (blistp -> b_type == BTLIST))
  1054. X        listbuffers ();
  1055. X    return (TRUE);
  1056. X}
  1057. X/*
  1058. X*   Replace character at dot position.
  1059. X*/
  1060. Xvoid    lreplace (n, c)
  1061. Xint     n;
  1062. Xchar    c;
  1063. X{
  1064. X    lchange (WFEDIT);
  1065. X    while (n--)
  1066. X    {
  1067. X        DOT_CHAR(curwp) = c & 0xff;
  1068. X        move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  1069. X    }
  1070. X}
  1071. X
  1072. X/*
  1073. X* Replace plen characters before dot with argument string.
  1074. X*/
  1075. Xbool lrepl_str (plen, rstr, mstr)
  1076. X
  1077. Xregister int    plen;           /* length to remove     */
  1078. Xregister LINE   *rstr;          /* replace string       */
  1079. Xregister LINE   *mstr;          /* mask string       */
  1080. X{
  1081. X    register    int    i;       /* used for random characters   */
  1082. X    register    LINE   *dotp;   /* pointer to line structure */
  1083. X    register    int    doto;    /* offset into line     */
  1084. X    register    int     rlen;   /* rplace string length */
  1085. X    register    char    c;      /* temp storage for char */
  1086. X    register    char    mask;   /* temp storage for mask */
  1087. X
  1088. X    /* 
  1089. X  * make the string lengths match (either pad the line
  1090. X  * so that it will fit, or scrunch out the excess).
  1091. X  * be careful with dot's offset.
  1092. X  */
  1093. X    doto = curwp -> w_doto;
  1094. X    rlen = rstr -> l_used;
  1095. X    if (plen > rlen)
  1096. X    {
  1097. X        ldelete ((A32)(plen - rlen), FALSE);
  1098. X    }
  1099. X    else if (plen < rlen)
  1100. X    {
  1101. X        if (linsert (rlen - plen, ' ') == FALSE)
  1102. X            return (FALSE);
  1103. X    }
  1104. X    curwp -> w_doto = doto;
  1105. X    dotp = curwp -> w_dotp;     /* save dot line for later */
  1106. X
  1107. X    /* do the replacement. */
  1108. X    for (i = 0; i < rlen; i++)
  1109. X    {
  1110. X        c = DOT_CHAR(curwp);
  1111. X        mask = mstr -> l_text[i];
  1112. X        DOT_CHAR(curwp) = (c & mask) | (rstr -> l_text[i] & ~mask);
  1113. X        move_ptr (curwp, 1L, TRUE, FALSE, TRUE);
  1114. X    }
  1115. X    curwp -> w_doto = doto;
  1116. X    curwp -> w_dotp = dotp;
  1117. X    lchange (WFHARD);
  1118. X    return (TRUE);
  1119. X}
  1120. X
  1121. X/*
  1122. X*   Line fixup.
  1123. X*   This fixes the 'l_file_offset' variable in
  1124. X*   each line structure.
  1125. X*   This is necessary after every change in the size
  1126. X*   of the buffer.
  1127. X*/
  1128. Xvoid l_fix_up (line)
  1129. X
  1130. XLINE * line;                    /* points to buffer header line */
  1131. X
  1132. X{
  1133. X    long    offset;
  1134. X
  1135. X    offset = line -> l_file_offset;/* starting offset */
  1136. X    offset += line -> l_used;
  1137. X    for (;;)
  1138. X    {
  1139. X        line = line -> l_fp;
  1140. X        if (line -> l_size == 0)
  1141. X            return;
  1142. X        line -> l_file_offset = offset;
  1143. X        offset += line -> l_used;
  1144. X    }
  1145. X}
  1146. END_OF_FILE
  1147.   if test 14071 -ne `wc -c <'line.c'`; then
  1148.     echo shar: \"'line.c'\" unpacked with wrong size!
  1149.   fi
  1150.   # end of 'line.c'
  1151. fi
  1152. if test -f 'symbol.c' -a "${1}" != "-c" ; then 
  1153.   echo shar: Will not clobber existing file \"'symbol.c'\"
  1154. else
  1155.   echo shar: Extracting \"'symbol.c'\" \(18744 characters\)
  1156.   sed "s/^X//" >'symbol.c' <<'END_OF_FILE'
  1157. X/*
  1158. X*              Symbol table stuff.
  1159. X* Symbol tables, and keymap setup.
  1160. X* The terminal specific parts of building the
  1161. X* keymap has been moved to a better place.
  1162. X*/
  1163. X#include        "def.h"
  1164. X
  1165. Xvoid keyadd ();
  1166. Xvoid keydup ();
  1167. X
  1168. X
  1169. Xextern    char    MSG_byte_shift[];
  1170. Xextern    char    MSG_back_char[];
  1171. Xextern    char    MSG_quit[];
  1172. Xextern    char    MSG_forw_del_char[];
  1173. Xextern    char    MSG_toggle_swap[];
  1174. Xextern    char    MSG_forw_char[];
  1175. Xextern    char    MSG_abort[];
  1176. Xextern    char    MSG_ins_self[];
  1177. Xextern    char    MSG_back_del_char[];
  1178. Xextern    char    MSG_refresh[];
  1179. Xextern    char    MSG_forw_line[];
  1180. Xextern    char    MSG_back_line[];
  1181. Xextern    char    MSG_quote[];
  1182. Xextern    char    MSG_recall[];
  1183. Xextern    char    MSG_twiddle[];
  1184. Xextern    char    MSG_forw_page[];
  1185. Xextern    char    MSG_kill_region[];
  1186. Xextern    char    MSG_yank[];
  1187. Xextern    char    MSG_down_window[];
  1188. Xextern    char    MSG_ins_toggle[];
  1189. Xextern    char    MSG_display_buffers[];
  1190. Xextern    char    MSG_quit[];
  1191. Xextern    char    MSG_exit_flush_all[];
  1192. Xextern    char    MSG_set_file_name[];
  1193. Xextern    char    MSG_file_insert[];
  1194. Xextern    char    MSG_buf_size_lock[];
  1195. Xextern    char    MSG_flush_all[];
  1196. Xextern    char    MSG_down_window[];
  1197. Xextern    char    MSG_up_window[];
  1198. Xextern    char    MSG_file_read[];
  1199. Xextern    char    MSG_file_save[];
  1200. Xextern    char    MSG_file_visit[];
  1201. Xextern    char    MSG_file_write[];
  1202. Xextern    char    MSG_swap_dot_and_mark[];
  1203. Xextern    char    MSG_shrink_window[];
  1204. Xextern    char    MSG_display_position[];
  1205. Xextern    char    MSG_start_macro[];
  1206. Xextern    char    MSG_end_macro[];
  1207. Xextern    char    MSG_help[];
  1208. Xextern    char    MSG_only_window[];
  1209. Xextern    char    MSG_del_window[];
  1210. Xextern    char    MSG_split_window[];
  1211. Xextern    char    MSG_use_buffer[];
  1212. Xextern    char    MSG_spawn_cli[];
  1213. Xextern    char    MSG_execute_macro[];
  1214. Xextern    char    MSG_goto_line[];
  1215. Xextern    char    MSG_ins_unit[];
  1216. Xextern    char    MSG_kill_buffer[];
  1217. Xextern    char    MSG_load_bindings[];
  1218. Xextern    char    MSG_forw_window[];
  1219. Xextern    char    MSG_back_window[];
  1220. Xextern    char    MSG_view_file[];
  1221. Xextern    char    MSG_enlarge_window[];
  1222. Xextern    char    MSG_ascii_mode[];
  1223. Xextern    char    MSG_binary_mode[];
  1224. Xextern    char    MSG_buffer_name[];
  1225. Xextern    char    MSG_decimal_mode[];
  1226. Xextern    char    MSG_ebcdic_mode[];
  1227. Xextern    char    MSG_hex_mode[];
  1228. Xextern    char    MSG_back_del_unit[];
  1229. Xextern    char    MSG_octal_mode[];
  1230. Xextern    char    MSG_display_version[];
  1231. Xextern    char    MSG_unit_size1[];
  1232. Xextern    char    MSG_unit_size2[];
  1233. Xextern    char    MSG_unit_size4[];
  1234. Xextern    char    MSG_reposition_window[];
  1235. Xextern    char    MSG_set_mark[];
  1236. Xextern    char    MSG_goto_eob[];
  1237. Xextern    char    MSG_goto_bob[];
  1238. Xextern    char    MSG_next_buff[];
  1239. Xextern    char    MSG_prev_buff[];
  1240. Xextern    char    MSG_query_replace[];
  1241. Xextern    char    MSG_display_bindings[];
  1242. Xextern    char    MSG_auto_save[];
  1243. Xextern    char    MSG_back_unit[];
  1244. Xextern    char    MSG_compare[];
  1245. Xextern    char    MSG_forw_del_unit[];
  1246. Xextern    char    MSG_forw_unit[];
  1247. Xextern    char    MSG_link_windows[];
  1248. Xextern    char    MSG_print[];
  1249. Xextern    char    MSG_back_search[];
  1250. Xextern    char    MSG_forw_search[];
  1251. Xextern    char    MSG_back_page[];
  1252. Xextern    char    MSG_copy_region[];
  1253. Xextern    char    MSG_extended_command[];
  1254. Xextern    char    MSG_up_window[];
  1255. Xextern    char    MSG_search_again[];
  1256. Xextern    char    MSG_bind_to_key[];
  1257. Xextern    char    MSG_file_visit_split[];
  1258. Xextern    char    MSG_yank_buffer[];
  1259. Xextern    char    MSG_save_region[];
  1260. Xextern    char    MSG_use_buffer_split[];
  1261. Xextern    char    MSG_no_f_tb[];
  1262. Xextern    char    MSG_n_split[];
  1263. Xextern    char    MSG_n_combine[];
  1264. Xextern    char    MSG_show_save_buf[];
  1265. X
  1266. X/*
  1267. X* Defined by "main.c".
  1268. X*/
  1269. Xextern char ctrlg ();           /* Abort out of things      */
  1270. Xextern char quit ();            /* Quit             */
  1271. Xextern char ctlxlp ();          /* Begin macro          */
  1272. Xextern char ctlxrp ();          /* End macro            */
  1273. Xextern char ctlxe ();           /* Execute macro        */
  1274. Xextern char showversion ();     /* Show version numbers, etc.   */
  1275. Xextern char flushnquit ();      /* Flush buffers & exit (fitz)  */
  1276. Xextern char flush_all ();       /* Flush buffers (jam)      */
  1277. Xextern char autosave ();        /* autosave function (jam)  */
  1278. X
  1279. X/*
  1280. X* Defined by "search.c".
  1281. X*/
  1282. Xextern char forwsearch ();      /* Search forward       */
  1283. Xextern char backsearch ();      /* Search backwards     */
  1284. Xextern char searchagain ();     /* Repeat last search command   */
  1285. Xextern char queryrepl ();       /* Query replace        */
  1286. Xextern char compare ();         /* Compare two windows  */
  1287. Xextern char recall ();          /* Recall last search string  */
  1288. X
  1289. X/*
  1290. X* Defined by "basic.c".
  1291. X*/
  1292. Xextern char backchar ();        /* Move backward by characters  */
  1293. Xextern char forwchar ();        /* Move forward by characters   */
  1294. Xextern char gotobob ();         /* Move to start of buffer  */
  1295. Xextern char gotoeob ();         /* Move to end of buffer    */
  1296. Xextern char forwline ();        /* Move forward by lines    */
  1297. Xextern char backline ();        /* Move backward by lines   */
  1298. Xextern char forwpage ();        /* Move forward by pages    */
  1299. Xextern char backpage ();        /* Move backward by pages   */
  1300. Xextern char setmark ();         /* Set mark         */
  1301. Xextern char swapmark ();        /* Swap "." and mark        */
  1302. Xextern char gotoline ();        /* Go to a specified line.  */
  1303. X
  1304. X/*
  1305. X* Defined by "buffer.c".
  1306. X*/
  1307. Xextern char listbuffers ();     /* Display list of buffers  */
  1308. Xextern char showsavebuf ();     /* Show the save buffer contents */
  1309. Xextern char usebuffer ();       /* Switch a window to a buffer  */
  1310. Xextern char use_buffer ();      /* ditto, plus window split */
  1311. Xextern char killbuffer ();      /* Make a buffer go away.   */
  1312. Xextern char next_buf ();        /* goto next buffer     */
  1313. Xextern char prev_buf ();        /* goto prev buffer     */
  1314. Xextern char yank_buffer ();     /* yank buffer by name      */
  1315. Xextern char buffername ();      /* change buffer name       */
  1316. Xextern char bufsizlock ();      /* lock buffer size         */
  1317. X
  1318. X/*
  1319. X* Defined by "file."
  1320. X*/
  1321. Xextern char fileread ();        /* Get a file, read only    */
  1322. Xextern char filevisit ();       /* Get a file, read write   */
  1323. Xextern char file_visit ();      /* ditto , plus window split    */
  1324. Xextern char filewrite ();       /* Write a file         */
  1325. Xextern char filesave ();        /* Save current file        */
  1326. Xextern char filename ();        /* Adjust file name     */
  1327. Xextern char fileinsert ();      /* insert file to cursor (jam ) */
  1328. Xextern char viewfile ();        /* readonly file visit (jam)    */
  1329. X
  1330. X/*
  1331. X* Defined by "random.c".
  1332. X*/
  1333. X
  1334. Xextern char dispshift ();       /* Increment display shift   */
  1335. Xextern char selfinsert ();      /* Insert character  */
  1336. Xextern char insert_toggle ();   /* toggle insert mode  (jam)    */
  1337. Xextern char insertunit ();      /* insert unit  (pvr)    */
  1338. Xextern char showcpos ();        /* Show the cursor position */
  1339. Xextern char twiddle ();         /* Twiddle units        */
  1340. Xextern char forwdel ();         /* Forward delete       */
  1341. Xextern char backdel ();         /* Backward delete      */
  1342. Xextern char quote ();           /* Insert literal       */
  1343. Xextern char asciimode ();       /* display ASCII data   */
  1344. Xextern char ebcdicmode ();      /* display EBCDIC data   */
  1345. Xextern char decimalmode ();     /* display DECIMAL data   */
  1346. Xextern char hexmode ();         /* display HEX data   */
  1347. Xextern char octalmode ();       /* display OCTAL data   */
  1348. Xextern char binarymode ();      /* display BINARY data   */
  1349. Xextern char dispsize1 ();       /* display in BYTE format */
  1350. Xextern char dispsize2 ();       /* display in WORD format */
  1351. Xextern char dispsize4 ();       /* display in DWORD format*/
  1352. Xextern char dispswapbyte ();    /* Display swaped bytes    pvr   */
  1353. Xextern char yank ();            /* Yank back from killbuffer.   */
  1354. Xextern char linkwind ();        /* Link all windows on one buffer. */
  1355. Xextern char n_way_split ();     /* Split buffer into n buffers. */
  1356. Xextern char n_way_combine ();   /* Combine n buffers into one. */
  1357. X
  1358. X/*
  1359. X* Defined by "region.c".
  1360. X*/
  1361. Xextern char killregion ();      /* Kill region.         */
  1362. Xextern char copyregion ();      /* Copy region to kill buffer.  */
  1363. Xextern char save_region ();     /* Save region in named buffer. */
  1364. X
  1365. X/*
  1366. X* Defined by "spawn.c".
  1367. X*/
  1368. Xextern char spawncli ();        /* Run CLI in a subjob.     */
  1369. Xextern char clock ();           /* display time in modeline */
  1370. X
  1371. X/*
  1372. X* Defined by "window.c".
  1373. X*/
  1374. Xextern char reposition ();      /* Reposition window        */
  1375. Xextern char refresh ();         /* Refresh the screen       */
  1376. Xextern char nextwind ();        /* Move to the next window  */
  1377. Xextern char prevwind ();        /* Move to the previous window  */
  1378. Xextern char mvdnwind ();        /* Move window down     */
  1379. Xextern char mvupwind ();        /* Move window up       */
  1380. Xextern char onlywind ();        /* Make current window only one */
  1381. Xextern char delwind ();         /* Delete current window */
  1382. Xextern char splitwind ();       /* Split current window     */
  1383. Xextern char enlargewind ();     /* Enlarge display window.  */
  1384. Xextern char shrinkwind ();      /* Shrink window.       */
  1385. X
  1386. X/*
  1387. X* Defined by "word.c".
  1388. X*/
  1389. Xextern char backunit ();        /* Backup by units      */
  1390. Xextern char forwunit ();        /* Advance by units     */
  1391. Xextern char delfunit ();        /* Delete forward unit. */
  1392. Xextern char delbunit ();        /* Delete backward unit.    */
  1393. X
  1394. X/*
  1395. X* Defined by "extend.c".
  1396. X*/
  1397. Xextern char extend ();          /* Extended commands.       */
  1398. Xextern char help ();            /* Help key.            */
  1399. Xextern char bindtokey ();       /* Modify key bindings.     */
  1400. Xextern char wallchart ();       /* Make wall chart.     */
  1401. Xextern void check_extend ();    /* load extended key file   */
  1402. Xextern char load_extend ();     /* load extended file by name   */
  1403. X
  1404. X/*
  1405. X* Defined by "display.c
  1406. X*/
  1407. Xextern char print ();           /* print window from mark to dot */
  1408. X
  1409. Xtypedef struct
  1410. X{
  1411. X
  1412. X    short   k_key;              /* Key to bind.                 */
  1413. X    char    (*k_funcp) ();      /* Function.            */
  1414. X    char   *k_name;             /* Function name string.        */
  1415. X    char    k_modify;           /* modify bit */
  1416. X}                KEY;
  1417. X
  1418. X/*
  1419. X* Default key binding table. This contains
  1420. X* the function names, the symbol table name, and (possibly)
  1421. X* a key binding for the builtin functions. There are no
  1422. X* bindings for C-U or C-X. These are done with special
  1423. X* code, but should be done normally.
  1424. X*/
  1425. XKEY key[] =
  1426. X{
  1427. X    KCTRL | 'A', dispshift, MSG_byte_shift, 0,
  1428. X        KCTRL | 'B', backchar, MSG_back_char, SSRCH | SRPLC,
  1429. X        KCTRL | 'C', quit, MSG_quit, 0,/* pvr */
  1430. X    KCTRL | 'D', forwdel, MSG_forw_del_char, SMOD | SSIZE | SSRCH | SRPLC,
  1431. X        KCTRL | 'E', dispswapbyte, MSG_toggle_swap, SSRCH | SRPLC,/* pvr */
  1432. X    KCTRL | 'F', forwchar, MSG_forw_char, SSRCH | SRPLC,
  1433. X        KCTRL | 'G', ctrlg, MSG_abort, SSRCH | SRPLC,
  1434. X        KCTRL | 'I', selfinsert, MSG_ins_self, SMOD | SSRCH | SRPLC,
  1435. X        KCTRL | 'H', backdel, MSG_back_del_char, SMOD | SSIZE | SSRCH | SRPLC,
  1436. X        KCTRL | 'L', refresh, MSG_refresh, SSRCH | SRPLC,
  1437. X        KCTRL | 'N', forwline, MSG_forw_line, SSRCH | SRPLC,
  1438. X        KCTRL | 'P', backline, MSG_back_line, SSRCH | SRPLC,
  1439. X        KCTRL | 'Q', quote, MSG_quote, 0,
  1440. X        KCTRL | 'R', recall, MSG_recall, SSRCH | SRPLC,
  1441. X        KCTRL | 'T', twiddle, MSG_twiddle, SMOD | SSRCH | SRPLC,
  1442. X        KCTRL | 'V', forwpage, MSG_forw_page, SRPLC,
  1443. X        KCTRL | 'W', killregion, MSG_kill_region, SMOD | SSIZE,
  1444. X        KCTRL | 'Y', yank, MSG_yank, SMOD | SSIZE,
  1445. X        KCTRL | 'Z', mvdnwind, MSG_down_window, 0,/* fitz */
  1446. X    KCTLX | KCTRL | 'A', insert_toggle, MSG_ins_toggle, SSRCH | SRPLC,
  1447. X        KCTLX | KCTRL | 'B', listbuffers, MSG_display_buffers, 0,
  1448. X        KCTLX | KCTRL | 'C', quit, MSG_quit, 0,
  1449. X        KCTLX | KCTRL | 'E', flushnquit, MSG_exit_flush_all, 0,/* fitz */
  1450. X    KCTLX | KCTRL | 'F', filename, MSG_set_file_name, SMOD,/* jam */
  1451. X    KCTLX | KCTRL | 'I', fileinsert, MSG_file_insert, SMOD | SSIZE,
  1452. X        KCTLX | KCTRL | 'L', bufsizlock, MSG_buf_size_lock, 0,
  1453. X        KCTLX | KCTRL | 'M', flush_all, MSG_flush_all, 0,
  1454. X        KCTLX | KCTRL | 'N', mvdnwind, MSG_down_window, 0,
  1455. X        KCTLX | KCTRL | 'P', mvupwind, MSG_up_window, 0,
  1456. X        KCTLX | KCTRL | 'R', fileread, MSG_file_read, 0,
  1457. X        KCTLX | KCTRL | 'S', filesave, MSG_file_save, 0,
  1458. X        KCTLX | KCTRL | 'V', filevisit, MSG_file_visit, 0,
  1459. X        KCTLX | KCTRL | 'W', filewrite, MSG_file_write, 0,
  1460. X        KCTLX | KCTRL | 'X', swapmark, MSG_swap_dot_and_mark, 0,
  1461. X        KCTLX | KCTRL | 'Z', shrinkwind, MSG_shrink_window, 0,
  1462. X        KCTLX | '=', showcpos, MSG_display_position, 0,
  1463. X        KCTLX | '(', ctlxlp, MSG_start_macro, 0,
  1464. X        KCTLX | ')', ctlxrp, MSG_end_macro, 0,
  1465. X        KCTLX | '?', help, MSG_help, 0,
  1466. X        KCTLX | '0', delwind, MSG_del_window, 0,
  1467. X        KCTLX | '1', onlywind, MSG_only_window, 0,
  1468. X        KCTLX | '2', splitwind, MSG_split_window, 0,
  1469. X        KCTLX | 'B', usebuffer, MSG_use_buffer, 0,
  1470. X        KCTLX | 'C', spawncli, MSG_spawn_cli, 0,/* fitz */
  1471. X    KCTLX | 'E', ctlxe, MSG_execute_macro, 0,
  1472. X        KCTLX | 'G', gotoline, MSG_goto_line, 0,
  1473. X        KCTLX | 'I', insertunit, MSG_ins_unit, SMOD | SSIZE | SSRCH | SRPLC,
  1474. X        KCTLX | 'K', killbuffer, MSG_kill_buffer, 0,
  1475. X        KCTLX | 'L', load_extend, MSG_load_bindings, 0,
  1476. X        KCTLX | 'N', nextwind, MSG_forw_window, 0,
  1477. X        KCTLX | 'P', prevwind, MSG_back_window, 0,
  1478. X        KCTLX | 'V', viewfile, MSG_view_file, 0,/* jam */
  1479. X    KCTLX | 'Z', enlargewind, MSG_enlarge_window, 0,
  1480. X        KMETA | KCTRL | 'A', asciimode, MSG_ascii_mode, SSRCH | SRPLC, /* pvr */
  1481. X    KMETA | KCTRL | 'B', binarymode, MSG_binary_mode, SSRCH | SRPLC, /* pvr */
  1482. X    KMETA | KCTRL | 'F', n_way_combine, MSG_n_combine, SSIZE | SMOD, /* pvr */
  1483. X    KMETA | KCTRL | 'N', buffername, MSG_buffer_name, 0,
  1484. X        KMETA | KCTRL | 'D', decimalmode, MSG_decimal_mode, SSRCH | SRPLC, /* pvr */
  1485. X    KMETA | KCTRL | 'E', ebcdicmode, MSG_ebcdic_mode, SSRCH | SRPLC, /* pvr */
  1486. X    KMETA | KCTRL | 'H', hexmode, MSG_hex_mode, SSRCH | SRPLC, /* pvr */
  1487. X    KMETA | KCTRL | 'K', delbunit, MSG_back_del_unit, SMOD | SSIZE | SSRCH | SRPLC,
  1488. X        KMETA | KCTRL | 'O', octalmode, MSG_octal_mode, SSRCH | SRPLC, /* pvr */
  1489. X    KMETA | KCTRL | 'S', n_way_split, MSG_n_split, 0, /* pvr */
  1490. X    KMETA | KCTRL | 'V', showversion, MSG_display_version, 0,
  1491. X        KMETA | KCTRL | 'W', showsavebuf, MSG_show_save_buf, 0,
  1492. X        KMETA | '1', dispsize1, MSG_unit_size1, SSRCH | SRPLC,/* pvr */
  1493. X    KMETA | '2', dispsize2, MSG_unit_size2, SSRCH | SRPLC,/* pvr */
  1494. X    KMETA | '4', dispsize4, MSG_unit_size4, SSRCH | SRPLC,/* pvr */
  1495. X    KMETA | '!', reposition, MSG_reposition_window, 0,
  1496. X        KMETA | '.', setmark, MSG_set_mark, 0,
  1497. X        KMETA | '>', gotoeob, MSG_goto_eob, SSRCH | SRPLC,
  1498. X        KMETA | '<', gotobob, MSG_goto_bob, SSRCH | SRPLC,
  1499. X        KMETA | '+', next_buf, MSG_next_buff, 0,
  1500. X        KMETA | '-', prev_buf, MSG_prev_buff, 0,
  1501. X        KMETA | '%', queryrepl, MSG_query_replace, SMOD,
  1502. X        KMETA | '?', wallchart, MSG_display_bindings, 0,
  1503. X        KMETA | 'A', autosave, MSG_auto_save, 0,
  1504. X        KMETA | 'B', backunit, MSG_back_unit, SSRCH | SRPLC,
  1505. X        KMETA | 'C', compare, MSG_compare, 0,
  1506. X        KMETA | 'D', delfunit, MSG_forw_del_unit, SMOD | SSIZE | SSRCH | SRPLC,
  1507. X        KMETA | 'F', forwunit, MSG_forw_unit, SSRCH | SRPLC,
  1508. X        KMETA | 'G', use_buffer, MSG_use_buffer_split, 0,
  1509. X        KMETA | 'K', bindtokey, MSG_bind_to_key, 0,
  1510. X        KMETA | 'L', linkwind, MSG_link_windows, 0,
  1511. X        KMETA | 'O', save_region, MSG_save_region, 0,
  1512. X        KMETA | 'P', print, MSG_print, 0,
  1513. X        KMETA | 'R', backsearch, MSG_back_search, 0,
  1514. X        KMETA | 'S', forwsearch, MSG_forw_search, 0,
  1515. X        KMETA | 'T', searchagain, MSG_search_again, 0,
  1516. X        KMETA | 'U', file_visit, MSG_file_visit_split, 0,
  1517. X        KMETA | 'V', backpage, MSG_back_page, SRPLC,
  1518. X        KMETA | 'W', copyregion, MSG_copy_region, 0,
  1519. X        KMETA | 'X', extend, MSG_extended_command, 0,
  1520. X        KMETA | 'Y', yank_buffer, MSG_yank_buffer, SMOD | SSIZE,
  1521. X        KMETA | 'Z', mvupwind, MSG_up_window, 0
  1522. X};
  1523. X
  1524. X#define NKEY    (sizeof(key) / sizeof(key[0]))
  1525. X
  1526. X/*
  1527. X* Symbol table lookup.
  1528. X* Return a pointer to the SYMBOL node, or NULL if
  1529. X* the symbol is not found.
  1530. X*/
  1531. XSYMBOL * symlookup (cp)
  1532. Xregister char  *cp;
  1533. X{
  1534. X    register    SYMBOL * sp;
  1535. X
  1536. X    sp = symbol[symhash (cp)];
  1537. X    while (sp != NULL)
  1538. X    {
  1539. X        if (strcmp (cp, sp -> s_name) == 0)
  1540. X            return (sp);
  1541. X        sp = sp -> s_symp;
  1542. X    }
  1543. X    return (NULL);
  1544. X}
  1545. X
  1546. X
  1547. X/*
  1548. X* Take a string, and compute the symbol table
  1549. X* bucket number. This is done by adding all of the characters
  1550. X* together, and taking the sum mod NSHASH. The string probably
  1551. X* should not contain any GR characters; if it does the "*cp"
  1552. X* may get a nagative number on some machines, and the "%"
  1553. X* will return a negative number!
  1554. X*/
  1555. Xint     symhash (cp)
  1556. Xregister char  *cp;
  1557. X{
  1558. X    register int    c;
  1559. X    register int    n;
  1560. X
  1561. X    n = 0;
  1562. X    while ((c = *cp++) != 0)
  1563. X        n += c;
  1564. X    return (n % NSHASH);
  1565. X}
  1566. X
  1567. X
  1568. X/*
  1569. X* Build initial keymap. The funny keys
  1570. X* (commands, odd control characters) are mapped using
  1571. X* a big table and calls to "keyadd". The printing characters
  1572. X* are done with some do-it-yourself handwaving. The terminal
  1573. X* specific keymap initialization code is called at the
  1574. X* very end to finish up. All errors are fatal.
  1575. X*/
  1576. Xvoid keymapinit ()
  1577. X{
  1578. X    register    SYMBOL * sp;
  1579. X    register    KEY * kp;
  1580. X    register int    i;
  1581. X
  1582. X    for (i = 0; i < NKEYS; ++i)
  1583. X        binding[i] = NULL;
  1584. X    for (kp = &key[0]; kp < &key[NKEY]; ++kp)
  1585. X        keyadd (kp -> k_key, kp -> k_funcp, kp -> k_name, kp -> k_modify);
  1586. X    keydup (KCTLX | KCTRL | 'G', MSG_abort);
  1587. X    keydup (KMETA | KCTRL | 'G', MSG_abort);
  1588. X    keydup (0x7F, MSG_back_del_char);
  1589. X    keydup (KMETA | 'Q', MSG_quote);
  1590. X    keydup (KMETA | 0x7F, MSG_back_del_unit);
  1591. X    /* 
  1592. X  * Should be bound by "tab" already.
  1593. X  */
  1594. X    if ((sp = symlookup (MSG_ins_self)) == NULL)
  1595. X        abort ();
  1596. X    for (i = 0x20; i < 0x7F; ++i)
  1597. X    {
  1598. X        if (binding[i] != NULL)
  1599. X            abort ();
  1600. X        binding[i] = sp;
  1601. X        ++sp -> s_nkey;
  1602. X    }
  1603. X    ttykeymapinit ();
  1604. X}
  1605. X
  1606. X
  1607. X/*
  1608. X* Create a new builtin function "name"
  1609. X* with function "funcp". If the "new" is a real
  1610. X* key, bind it as a side effect. All errors
  1611. X* are fatal.
  1612. X*/
  1613. Xvoid keyadd (new, funcp, name, modify)
  1614. Xbool   (*funcp) ();
  1615. Xchar   *name;
  1616. X{
  1617. X    register    SYMBOL * sp;
  1618. X    register int    hash;
  1619. X
  1620. X    if ((sp = (SYMBOL *) malloc (sizeof (SYMBOL))) == NULL)
  1621. X        abort ();
  1622. X    hash = symhash (name);
  1623. X    sp -> s_symp = symbol[hash];
  1624. X    symbol[hash] = sp;
  1625. X    sp -> s_nkey = 0;
  1626. X    sp -> s_name = name;
  1627. X    sp -> s_funcp = funcp;
  1628. X    sp -> s_modify = modify;
  1629. X    if (new >= 0)
  1630. X    {
  1631. X        /* Bind this key.       */
  1632. X        if (binding[new] != NULL)
  1633. X            abort ();
  1634. X        binding[new] = sp;
  1635. X        ++sp -> s_nkey;
  1636. X    }
  1637. X}
  1638. X
  1639. X/*
  1640. X* Bind key "new" to the existing
  1641. X* routine "name". If the name cannot be found,
  1642. X* or the key is already bound, abort.
  1643. X*/
  1644. Xvoid keydup (new, name)
  1645. Xregister int    new;
  1646. Xchar   *name;
  1647. X{
  1648. X    register    SYMBOL * sp;
  1649. X
  1650. X    if (binding[new] != NULL || (sp = symlookup (name)) == NULL)
  1651. X    {
  1652. X        printf (MSG_no_f_tb, name);
  1653. X        abort ();
  1654. X    }
  1655. X    binding[new] = sp;
  1656. X    ++sp -> s_nkey;
  1657. X}
  1658. END_OF_FILE
  1659.   if test 18744 -ne `wc -c <'symbol.c'`; then
  1660.     echo shar: \"'symbol.c'\" unpacked with wrong size!
  1661.   fi
  1662.   # end of 'symbol.c'
  1663. fi
  1664. if test -f 'ttyio.c' -a "${1}" != "-c" ; then 
  1665.   echo shar: Will not clobber existing file \"'ttyio.c'\"
  1666. else
  1667.   echo shar: Extracting \"'ttyio.c'\" \(3055 characters\)
  1668.   sed "s/^X//" >'ttyio.c' <<'END_OF_FILE'
  1669. X/*
  1670. X*
  1671. X*   MS-DOS terminal I/O.               TTYIO.C
  1672. X*/
  1673. X
  1674. X#include        "def.h"
  1675. X#ifdef    MSDOS
  1676. X
  1677. X
  1678. Xvoid    ttopen ();
  1679. Xvoid    ttclose (); /* stub */
  1680. Xvoid    ttputc ();
  1681. Xvoid    putline ();
  1682. Xvoid    ttflush (); /* stub */
  1683. Xint     ttkeyready ();
  1684. Xint     ttgetc ();
  1685. Xvoid    ttraw ();
  1686. Xvoid    ttcooked ();
  1687. Xvoid    set_crt_type ();
  1688. X
  1689. X#include    "dos.h"
  1690. X
  1691. Xint     slot;
  1692. Xint     scr_type;
  1693. X#define SCREEN_PORT (video_port)
  1694. Xstatic int  video_port =
  1695. X{
  1696. X    0x1010
  1697. X};
  1698. X
  1699. Xextern  bool    wang_pc;
  1700. Xextern  bool    ibm_pc;
  1701. Xint     nrow;                   /* Terminal size, rows.         */
  1702. Xint     ncol;                   /* Terminal size, columns.      */
  1703. Xint     last_key;
  1704. X
  1705. X/*
  1706. X* Initialization.
  1707. X* Almost no operation in MS-DOS.
  1708. X*/
  1709. Xvoid ttopen ()
  1710. X{
  1711. X    if (wang_pc && !ibm_pc)
  1712. X        set_crt_type ();
  1713. X    nrow = NROW;
  1714. X    ncol = NCOL;
  1715. X}
  1716. X
  1717. Xvoid ttclose ()
  1718. X{
  1719. X}
  1720. Xvoid ttflush ()
  1721. X{
  1722. X}
  1723. X/*
  1724. X* Write character.
  1725. X*/
  1726. Xvoid ttputc (c)
  1727. X{
  1728. X    bdos (6, c, 0);
  1729. X}
  1730. X
  1731. Xvoid putline (row, startcol, stringsize, string)
  1732. Xint     row,
  1733. Xstartcol,
  1734. Xstringsize;
  1735. Xchar   *string;
  1736. X{
  1737. X    extern int  tthue;
  1738. X    unsigned short *screen;
  1739. X    int     x,
  1740. X    attribute;
  1741. X    char    c_row, c_col, i;
  1742. X    union   REGS    regs;
  1743. X
  1744. X    if (ibm_pc)
  1745. X    {
  1746. X        c_row = row - 1;
  1747. X        c_col = startcol - 1;
  1748. X        for (i = 0; i < stringsize; i++)
  1749. X        {
  1750. X            regs.h.ah = 2;
  1751. X            regs.h.dh = c_row;
  1752. X            regs.h.dl= c_col;
  1753. X            regs.h.bh = 0;
  1754. X            int86 (0x10, ®s, ®s); /* set cursor position */
  1755. X
  1756. X            if (tthue == CTEXT)
  1757. X                regs.h.bl = 0x07;
  1758. X            if (tthue == CMODE)
  1759. X                regs.h.bl = 0x70;
  1760. X            regs.h.ah = 9;
  1761. X            regs.h.bh = 0;
  1762. X            regs.h.al = string[i];
  1763. X            regs.x.cx= 1;
  1764. X            int86 (0x10, ®s, ®s); /* set cursor position */
  1765. X            c_col++;
  1766. X        }
  1767. X    }
  1768. X    else if (wang_pc)
  1769. X    {
  1770. X        if (tthue == CTEXT)
  1771. X            attribute = 0x00;
  1772. X        else
  1773. X            attribute = 0x02;
  1774. X
  1775. X        x = stringsize;
  1776. X        screen = (unsigned short *) WANG_CHARACTER_SCREEN;
  1777. X        screen += ((row - 1) * 80) + startcol - 1;
  1778. X        outp (SCREEN_PORT, 01);
  1779. X        while (x--)
  1780. X        {
  1781. X            *screen = (*string++ << 8) | attribute;
  1782. X            screen++;
  1783. X        }
  1784. X        outp (SCREEN_PORT, 00);
  1785. X    }
  1786. X}
  1787. X
  1788. X/* 
  1789. X*   return with a TRUE if key was struck.
  1790. X*/
  1791. Xint     ttkeyready ()
  1792. X{
  1793. X    int    cnt;
  1794. X
  1795. X    if (last_key != 0)
  1796. X        return (1);
  1797. X
  1798. X    last_key = bdos (6, 0xff, 0);
  1799. X    last_key &= 0xff;
  1800. X    if (last_key == 0)
  1801. X        return (0);
  1802. X    else
  1803. X        return (1);
  1804. X}
  1805. X
  1806. X/*
  1807. X* Read character.
  1808. X*/
  1809. Xint     ttgetc ()
  1810. X{
  1811. X    int     c;
  1812. X    if (last_key != 0)
  1813. X    {
  1814. X        c = last_key;
  1815. X        last_key = 0;
  1816. X        return (c);
  1817. X    }
  1818. X    ttcooked ();
  1819. X    c = (bdos (7, 0, 0) & 0xFF);
  1820. X    ttraw ();
  1821. X    return (c);
  1822. X}
  1823. X
  1824. X/* disable nasty cntrl-c during disk io!
  1825. X*/
  1826. Xvoid ttraw ()
  1827. X{
  1828. X    union REGS inregs, outregs;
  1829. X
  1830. X    inregs.h.al = 1;
  1831. X    inregs.h.ah = 0x33;
  1832. X    inregs.h.dl = 0;
  1833. X    intdos (&inregs, &outregs);
  1834. X    /*
  1835. X    cntrlcoff();
  1836. X*/
  1837. X}
  1838. X
  1839. X/* re enable cntrl-c for keyboard 
  1840. X*/
  1841. Xvoid ttcooked ()
  1842. X{
  1843. X    union REGS inregs, outregs;
  1844. X
  1845. X    inregs.h.al = 1;
  1846. X    inregs.h.ah = 0x33;
  1847. X    intdos (&inregs, &outregs);
  1848. X    inregs.h.dl = 1;
  1849. X    /*
  1850. X    cntrlcon();
  1851. X*/
  1852. X}
  1853. X
  1854. X/* switch physical monitors
  1855. X*/
  1856. Xstatic char str[] =
  1857. X{
  1858. X    0x1b, '/', 1, 's'
  1859. X};
  1860. X
  1861. Xvoid     set_crt_type ()
  1862. X{
  1863. X    char    active_screen;
  1864. X
  1865. X    active_screen = getscreenstate ();
  1866. X    slot = active_screen & 0x0f;
  1867. X    scr_type = (active_screen & 0x70) >> 4;
  1868. X    video_port = 0x1010 | (slot << 8);
  1869. X}
  1870. X#endif
  1871. END_OF_FILE
  1872.   if test 3055 -ne `wc -c <'ttyio.c'`; then
  1873.     echo shar: \"'ttyio.c'\" unpacked with wrong size!
  1874.   fi
  1875.   # end of 'ttyio.c'
  1876. fi
  1877. echo shar: End of archive 6 \(of 9\).
  1878. cp /dev/null ark6isdone
  1879. MISSING=""
  1880. for I in 1 2 3 4 5 6 7 8 9 ; do
  1881.     if test ! -f ark${I}isdone ; then
  1882.     MISSING="${MISSING} ${I}"
  1883.     fi
  1884. done
  1885. if test "${MISSING}" = "" ; then
  1886.     echo You have unpacked all 9 archives.
  1887.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1888. else
  1889.     echo You still must unpack the following archives:
  1890.     echo "        " ${MISSING}
  1891. fi
  1892. exit 0
  1893. exit 0 # Just in case...
  1894.