home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume1 / pcurses / part07 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  54.4 KB

  1. Subject:  Terminfo/Curses Part 7 of 11
  2.  
  3. : Run this shell script with "sh" not "csh"
  4. PATH=:/bin:/usr/bin:/usr/ucb
  5. export PATH
  6. if test ! -d =src
  7. then
  8.     echo 'Making directory "=src"'
  9.     mkdir =src
  10. fi
  11. echo 'x - =src/lib_getch.c'
  12. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getch.c
  13. X/*********************************************************************
  14. *                         COPYRIGHT NOTICE                           *
  15. **********************************************************************
  16. *        This software is copyright (C) 1982 by Pavel Curtis         *
  17. *                                                                    *
  18. *        Permission is granted to reproduce and distribute           *
  19. *        this file by any means so long as no fee is charged         *
  20. *        above a nominal handling fee and so long as this            *
  21. *        notice is always included in the copies.                    *
  22. *                                                                    *
  23. *        Other rights are reserved except as explicitly granted      *
  24. *        by written permission of the author.                        *
  25. *                Pavel Curtis                                        *
  26. *                Computer Science Dept.                              *
  27. *                405 Upson Hall                                      *
  28. *                Cornell University                                  *
  29. *                Ithaca, NY 14853                                    *
  30. *                                                                    *
  31. *                Ph- (607) 256-4934                                  *
  32. *                                                                    *
  33. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  34. *                decvax!cornell!pavel       (UUCPnet)                *
  35. *********************************************************************/
  36.  
  37. X/*
  38. **    lib_getch.c
  39. **
  40. **    The routine getch().
  41. **
  42. ** $Log:    RCS/lib_getch.v $
  43.  * Revision 2.1  82/10/25  14:47:29  pavel
  44.  * Added Copyright Notice
  45.  * 
  46.  * Revision 2.0  82/10/25  13:45:19  pavel
  47.  * Beta-one Test Release
  48.  * 
  49. **
  50. */
  51.  
  52. static char RCSid[] =
  53.     "$Header:   RCS/lib_getch.v  Revision 2.1  82/10/25  14:47:29  pavel  Exp$";
  54.  
  55. #include <signal.h>
  56. #include "curses.h"
  57. #include "curses.priv.h"
  58.  
  59. #define nextc()       (SP->_backcnt > 0  ?  SP->_backbuf[--SP->_backcnt] \
  60.                                          :  getc(SP->_ifp))
  61.                        
  62. #define putback(ch)   SP->_backbuf[SP->_backcnt++] = ch
  63.  
  64.  
  65. wgetch(win)
  66. WINDOW    *win;
  67. {
  68.     bool    setHere = FALSE;    /* cbreak mode was set here         */
  69.     short    ch;                     /* 'short' because of keypad codes  */
  70.         short   kgetch();
  71.  
  72. #ifdef TRACE
  73.     if (_tracing)
  74.         _tracef("wgetch(%o) called", win);
  75. #endif
  76.  
  77.     if (! win->_scroll  &&  (win->_flags & _FULLWIN)
  78.                         &&  win->_curx == win->_maxx
  79.                         &&  win->_cury == win->_maxy)
  80.         return(ERR);
  81.  
  82. #ifdef FIONREAD
  83.     if (win->_nodelay)
  84.     {
  85.         long    count;
  86.  
  87.         ioctl(fileno(SP->_ifp), FIONREAD, &count);
  88.  
  89.         if (! count)
  90.         return(-1);
  91.     }
  92. #endif
  93.  
  94.     if (SP->_echo  &&  ! (SP->_raw  ||  SP->_cbreak))
  95.     {
  96.         cbreak();
  97.         setHere = TRUE;
  98.     }
  99.  
  100.         if (win->_use_keypad)
  101.             ch = kgetch();
  102.         else
  103.         ch = nextc();
  104.  
  105.     if (SP->_echo  &&  ch < 0400)    /* ch < 0400 => not a keypad key */
  106.     {
  107.         mvwaddch(curscr, win->_begy + win->_cury,
  108.                              win->_begx + win->_curx, ch | win->_attrs);
  109.         waddch(win, ch | win->_attrs);
  110.     }
  111.  
  112.     if (setHere)
  113.         nocbreak();
  114.  
  115.     return(ch);
  116. }
  117.  
  118.  
  119.  
  120. X/*
  121. **      short
  122. **      kgetch()
  123. **
  124. **      Get an input character, but take care of keypad sequences, returning
  125. **      an appropriate code when one matches the input.  After each character
  126. **      is received, set a one-second alarm call.  If no more of the sequence
  127. **      is received by the time the alarm goes off, pass through the sequence
  128. **      gotten so far.
  129. **
  130. */
  131.  
  132. static  bool    alarmed;
  133.  
  134. static
  135. short
  136. kgetch()
  137. {
  138.         struct try  *ptr;
  139.     char        ch;
  140.     char        buffer[10];     /* Assume no sequences longer than 10 */
  141.     char        *bufp = buffer;
  142.     int         (*oldsig)();
  143.     int         sigalrm();
  144.  
  145.     ptr = SP->_keytry;
  146.     
  147.     oldsig = signal(SIGALRM, sigalrm);
  148.     alarmed = FALSE;
  149.     
  150.     do
  151.     {
  152.         ch = nextc();
  153.         if (ch != EOF)              /* getc() returns EOF on error, too */
  154.             *(bufp++) = ch;
  155.         if (alarmed)
  156.             break;
  157.         
  158.         while (ptr != NULL  &&  ptr->ch != ch)
  159.             ptr = ptr->sibling;
  160.         
  161.         if (ptr != NULL)
  162.         {
  163.             if (ptr->value != NULL)
  164.         {
  165.             alarm(0);
  166.             signal(SIGALRM, oldsig);
  167.             return(ptr->value);
  168.         }
  169.         else
  170.         {
  171.             ptr = ptr->child;
  172.             alarm(1);
  173.             }
  174.         }
  175.         
  176.     } while (ptr != NULL);
  177.     
  178.     alarm(0);
  179.     signal(SIGALRM, oldsig);
  180.     
  181.     while (--bufp > buffer)
  182.         putback(*bufp);
  183.         
  184.     return(*bufp);
  185. }
  186.  
  187.  
  188. static
  189. sigalrm()
  190. {
  191.         alarmed = TRUE;
  192.     signal(SIGALRM, sigalrm);
  193. }
  194. //go.sysin dd *
  195. echo 'x - =src/lib_getstr.c'
  196. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_getstr.c
  197. X/*********************************************************************
  198. *                         COPYRIGHT NOTICE                           *
  199. **********************************************************************
  200. *        This software is copyright (C) 1982 by Pavel Curtis         *
  201. *                                                                    *
  202. *        Permission is granted to reproduce and distribute           *
  203. *        this file by any means so long as no fee is charged         *
  204. *        above a nominal handling fee and so long as this            *
  205. *        notice is always included in the copies.                    *
  206. *                                                                    *
  207. *        Other rights are reserved except as explicitly granted      *
  208. *        by written permission of the author.                        *
  209. *                Pavel Curtis                                        *
  210. *                Computer Science Dept.                              *
  211. *                405 Upson Hall                                      *
  212. *                Cornell University                                  *
  213. *                Ithaca, NY 14853                                    *
  214. *                                                                    *
  215. *                Ph- (607) 256-4934                                  *
  216. *                                                                    *
  217. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  218. *                decvax!cornell!pavel       (UUCPnet)                *
  219. *********************************************************************/
  220.  
  221. X/*
  222. **    lib_getstr.c
  223. **
  224. **    The routine wgetstr().
  225. **
  226. ** $Log:    RCS/lib_getstr.v $
  227.  * Revision 2.1  82/10/25  14:47:33  pavel
  228.  * Added Copyright Notice
  229.  * 
  230.  * Revision 2.0  82/10/25  13:45:39  pavel
  231.  * Beta-one Test Release
  232.  * 
  233. **
  234. */
  235.  
  236. static char RCSid[] =
  237.     "$Header:   RCS/lib_getstr.v  Revision 2.1  82/10/25  14:47:33  pavel  Exp$";
  238.  
  239. #include "curses.h"
  240. #include "curses.priv.h"
  241. #include "unctrl.h"
  242.  
  243. #define backspace() {                            \
  244.             mvwaddstr(curscr, win->_begy + win->_cury,        \
  245.                       win->_begx + win->_curx, "\b \b");\
  246.             waddstr(win, "\b \b");                \
  247.             fputs("\b \b", SP->_ofp);                \
  248.             fflush(SP->_ofp);                    \
  249.             }
  250.  
  251.  
  252. wgetstr(win,str)
  253. WINDOW    *win; 
  254. char    *str;
  255. {
  256.     bool    oldnl, oldecho, oldraw, oldcbreak;
  257.     char    erasec;
  258.     char    killc;
  259.     char    *oldstr;
  260.  
  261. #ifdef TRACE
  262.     if (_tracing)
  263.         _tracef("wgetstr(%o,%o) called", win, str);
  264. #endif
  265.  
  266.     oldnl = SP->_nl;
  267.     oldecho = SP->_echo;
  268.     oldraw = SP->_raw;
  269.     oldcbreak = SP->_cbreak;
  270.     nl();
  271.     noecho();
  272.     noraw();
  273.     cbreak();
  274.  
  275.     erasec = erasechar();
  276.     killc = killchar();
  277.  
  278.     oldstr = str;
  279.  
  280.     while ((*str = getc(SP->_ifp)) != ERR  &&  *str != '\n')
  281.     {
  282.         if (*str == erasec)
  283.         {
  284.         if (str > oldstr)
  285.         {
  286.             str--;
  287.             backspace();
  288.             if (*str < ' ' ||  *str == '\177')
  289.             backspace();
  290.         }
  291.         }
  292.         else if (*str == killc)
  293.         {
  294.         while (str > oldstr)
  295.         {
  296.             str--;
  297.             backspace();
  298.             if (*str < ' ' ||  *str == '\177')
  299.             backspace();
  300.         }
  301.         }
  302.         else
  303.         {
  304.         mvwaddstr(curscr, win->_begy + win->_cury,
  305.                   win->_begx + win->_curx, unctrl(*str));
  306.         waddstr(win, unctrl(*str));
  307.         fputs(unctrl(*str), SP->_ofp);
  308.         fflush(SP->_ofp);
  309.         str++;
  310.         }
  311.     }
  312.  
  313.     if (! oldnl)
  314.         nonl();
  315.  
  316.     if (oldecho)
  317.         echo();
  318.  
  319.     if (oldraw)
  320.         raw();
  321.  
  322.     if (! oldcbreak)
  323.         nocbreak();
  324.  
  325.     if (*str == ERR)
  326.         {
  327.         *str = '\0';
  328.         return(ERR);
  329.     }
  330.  
  331.     *str = '\0';
  332.  
  333. #ifdef TRACE
  334.     if (_tracing)
  335.         _tracef("\twgetstr returns %s", oldstr);
  336. #endif
  337.  
  338.     return(OK);
  339. }
  340. //go.sysin dd *
  341. echo 'x - =src/lib_initscr.c'
  342. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_initscr.c
  343. X/*********************************************************************
  344. *                         COPYRIGHT NOTICE                           *
  345. **********************************************************************
  346. *        This software is copyright (C) 1982 by Pavel Curtis         *
  347. *                                                                    *
  348. *        Permission is granted to reproduce and distribute           *
  349. *        this file by any means so long as no fee is charged         *
  350. *        above a nominal handling fee and so long as this            *
  351. *        notice is always included in the copies.                    *
  352. *                                                                    *
  353. *        Other rights are reserved except as explicitly granted      *
  354. *        by written permission of the author.                        *
  355. *                Pavel Curtis                                        *
  356. *                Computer Science Dept.                              *
  357. *                405 Upson Hall                                      *
  358. *                Cornell University                                  *
  359. *                Ithaca, NY 14853                                    *
  360. *                                                                    *
  361. *                Ph- (607) 256-4934                                  *
  362. *                                                                    *
  363. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  364. *                decvax!cornell!pavel       (UUCPnet)                *
  365. *********************************************************************/
  366.  
  367. X/*
  368. **    lib_initscr.c
  369. **
  370. **    The routine initscr().
  371. **
  372. ** $Log:    RCS/lib_initscr.v $
  373.  * Revision 2.1  82/10/25  14:47:36  pavel
  374.  * Added Copyright Notice
  375.  * 
  376.  * Revision 2.0  82/10/25  13:45:54  pavel
  377.  * Beta-one Test Release
  378.  * 
  379. **
  380. */
  381.  
  382. static char RCSid[] =
  383.     "$Header:   RCS/lib_initscr.v  Revision 2.1  82/10/25  14:47:36  pavel  Exp$";
  384.  
  385. #include "curses.h"
  386. #include "curses.priv.h"
  387.  
  388.  
  389. WINDOW *
  390. initscr()
  391. {
  392. #ifdef TRACE
  393.     _init_trace();
  394.  
  395.     if (_tracing)
  396.         _tracef("initscr() called");
  397. #endif
  398.  
  399.         if (newterm(getenv("TERM"), stdout) == ERR)
  400.         return(ERR);
  401.     else
  402.         return(stdscr);
  403. }
  404. //go.sysin dd *
  405. echo 'x - =src/lib_insch.c'
  406. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insch.c
  407. X/*********************************************************************
  408. *                         COPYRIGHT NOTICE                           *
  409. **********************************************************************
  410. *        This software is copyright (C) 1982 by Pavel Curtis         *
  411. *                                                                    *
  412. *        Permission is granted to reproduce and distribute           *
  413. *        this file by any means so long as no fee is charged         *
  414. *        above a nominal handling fee and so long as this            *
  415. *        notice is always included in the copies.                    *
  416. *                                                                    *
  417. *        Other rights are reserved except as explicitly granted      *
  418. *        by written permission of the author.                        *
  419. *                Pavel Curtis                                        *
  420. *                Computer Science Dept.                              *
  421. *                405 Upson Hall                                      *
  422. *                Cornell University                                  *
  423. *                Ithaca, NY 14853                                    *
  424. *                                                                    *
  425. *                Ph- (607) 256-4934                                  *
  426. *                                                                    *
  427. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  428. *                decvax!cornell!pavel       (UUCPnet)                *
  429. *********************************************************************/
  430.  
  431. X/*
  432. **    lib_insch.c
  433. **
  434. **    The routine winsch().
  435. **
  436. ** $Log:    RCS/lib_insch.v $
  437.  * Revision 2.1  82/10/25  14:47:39  pavel
  438.  * Added Copyright Notice
  439.  * 
  440.  * Revision 2.0  82/10/25  13:46:02  pavel
  441.  * Beta-one Test Release
  442.  * 
  443. **
  444. */
  445.  
  446. static char RCSid[] =
  447.     "$Header:   RCS/lib_insch.v  Revision 2.1  82/10/25  14:47:39  pavel  Exp$";
  448.  
  449. #include "curses.h"
  450. #include "curses.priv.h"
  451.  
  452.  
  453. winsch(win, c)
  454. WINDOW    *win;
  455. char    c;
  456. {
  457.     chtype    *temp1, *temp2;
  458.     chtype    *end;
  459.  
  460. #ifdef TRACE
  461.     if (_tracing)
  462.         _tracef("winsch(%o,'%c') called", win, c);
  463. #endif
  464.  
  465.     end = &win->_line[win->_cury][win->_curx];
  466.     temp1 = &win->_line[win->_cury][win->_maxx];
  467.     temp2 = temp1 - 1;
  468.  
  469.     while (temp1 > end)
  470.         *temp1-- = *temp2--;
  471.  
  472.     *temp1 = c | win->_attrs;
  473.  
  474.     win->_lastchar[win->_cury] = win->_maxx;
  475.     if (win->_firstchar[win->_cury] == _NOCHANGE
  476.                     ||  win->_firstchar[win->_cury] > win->_curx)
  477.         win->_firstchar[win->_cury] = win->_curx;
  478. }
  479. //go.sysin dd *
  480. echo 'x - =src/lib_insertln.c'
  481. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_insertln.c
  482. X/*********************************************************************
  483. *                         COPYRIGHT NOTICE                           *
  484. **********************************************************************
  485. *        This software is copyright (C) 1982 by Pavel Curtis         *
  486. *                                                                    *
  487. *        Permission is granted to reproduce and distribute           *
  488. *        this file by any means so long as no fee is charged         *
  489. *        above a nominal handling fee and so long as this            *
  490. *        notice is always included in the copies.                    *
  491. *                                                                    *
  492. *        Other rights are reserved except as explicitly granted      *
  493. *        by written permission of the author.                        *
  494. *                Pavel Curtis                                        *
  495. *                Computer Science Dept.                              *
  496. *                405 Upson Hall                                      *
  497. *                Cornell University                                  *
  498. *                Ithaca, NY 14853                                    *
  499. *                                                                    *
  500. *                Ph- (607) 256-4934                                  *
  501. *                                                                    *
  502. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  503. *                decvax!cornell!pavel       (UUCPnet)                *
  504. *********************************************************************/
  505.  
  506. X/*
  507. **    lib_insertln.c
  508. **
  509. **    The routine winsertln().
  510. **
  511. ** $Log:    RCS/lib_insertln.v $
  512.  * Revision 2.1  82/10/25  14:47:44  pavel
  513.  * Added Copyright Notice
  514.  * 
  515.  * Revision 2.0  82/10/25  13:46:12  pavel
  516.  * Beta-one Test Release
  517.  * 
  518. **
  519. */
  520.  
  521. static char RCSid[] =
  522.     "$Header:   RCS/lib_insertln.v  Revision 2.1  82/10/25  14:47:44  pavel  Exp$";
  523.  
  524. #include "curses.h"
  525. #include "curses.priv.h"
  526.  
  527.  
  528. winsertln(win)
  529. WINDOW    *win;
  530. {
  531.     chtype    *temp, *end;
  532.     int    y;
  533.  
  534. #ifdef TRACE
  535.     if (_tracing)
  536.         _tracef("winsertln(%o) called", win);
  537. #endif
  538.  
  539.     temp = win->_line[win->_regbottom];
  540.  
  541.     win->_firstchar[win->_cury] = 0;
  542.     win->_lastchar[win->_cury] = win->_maxx;
  543.  
  544.     for (y = win->_regbottom;  y > win->_cury;  y--)
  545.     {
  546.         win->_line[y] = win->_line[y-1];
  547.  
  548.         win->_firstchar[y] = 0;
  549.         win->_lastchar[y] = win->_maxx;
  550.     }
  551.  
  552.     win->_line[win->_cury] = temp;
  553.  
  554.     for (end = &temp[win->_maxx];  temp <= end;  temp++)
  555.         *temp = ' ' | win->_attrs;
  556. }
  557. //go.sysin dd *
  558. echo 'x - =src/lib_longname.c'
  559. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_longname.c
  560. X/*********************************************************************
  561. *                         COPYRIGHT NOTICE                           *
  562. **********************************************************************
  563. *        This software is copyright (C) 1982 by Pavel Curtis         *
  564. *                                                                    *
  565. *        Permission is granted to reproduce and distribute           *
  566. *        this file by any means so long as no fee is charged         *
  567. *        above a nominal handling fee and so long as this            *
  568. *        notice is always included in the copies.                    *
  569. *                                                                    *
  570. *        Other rights are reserved except as explicitly granted      *
  571. *        by written permission of the author.                        *
  572. *                Pavel Curtis                                        *
  573. *                Computer Science Dept.                              *
  574. *                405 Upson Hall                                      *
  575. *                Cornell University                                  *
  576. *                Ithaca, NY 14853                                    *
  577. *                                                                    *
  578. *                Ph- (607) 256-4934                                  *
  579. *                                                                    *
  580. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  581. *                decvax!cornell!pavel       (UUCPnet)                *
  582. *********************************************************************/
  583.  
  584. X/*
  585. **    lib_longname.c
  586. **
  587. **    The routine longname().
  588. **
  589. ** $Log:    RCS/lib_longname.v $
  590.  * Revision 2.1  82/10/25  14:47:49  pavel
  591.  * Added Copyright Notice
  592.  * 
  593.  * Revision 2.0  82/10/25  13:46:21  pavel
  594.  * Beta-one Test Release
  595.  * 
  596. **
  597. */
  598.  
  599. static char RCSid[] =
  600.     "$Header:   RCS/lib_longname.v  Revision 2.1  82/10/25  14:47:49  pavel  Exp$";
  601.  
  602. #include "curses.h"
  603. #include "curses.priv.h"
  604.  
  605.  
  606. char *
  607. longname()
  608. {
  609.         char    *ptr;
  610.  
  611. #ifdef TRACE
  612.     if (_tracing)
  613.         _tracef("longname() called");
  614. #endif
  615.  
  616.     for (ptr = ttytype + strlen(ttytype); ptr > ttytype; ptr--)
  617.         if (*ptr == '|')
  618.         return(ptr + 1);
  619.  
  620.         return(ttytype);
  621. }
  622. //go.sysin dd *
  623. echo 'x - =src/lib_move.c'
  624. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_move.c
  625. X/*********************************************************************
  626. *                         COPYRIGHT NOTICE                           *
  627. **********************************************************************
  628. *        This software is copyright (C) 1982 by Pavel Curtis         *
  629. *                                                                    *
  630. *        Permission is granted to reproduce and distribute           *
  631. *        this file by any means so long as no fee is charged         *
  632. *        above a nominal handling fee and so long as this            *
  633. *        notice is always included in the copies.                    *
  634. *                                                                    *
  635. *        Other rights are reserved except as explicitly granted      *
  636. *        by written permission of the author.                        *
  637. *                Pavel Curtis                                        *
  638. *                Computer Science Dept.                              *
  639. *                405 Upson Hall                                      *
  640. *                Cornell University                                  *
  641. *                Ithaca, NY 14853                                    *
  642. *                                                                    *
  643. *                Ph- (607) 256-4934                                  *
  644. *                                                                    *
  645. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  646. *                decvax!cornell!pavel       (UUCPnet)                *
  647. *********************************************************************/
  648.  
  649. X/*
  650. **    lib_move.c
  651. **
  652. **    The routine wmove().
  653. **
  654. ** $Log:    RCS/lib_move.v $
  655.  * Revision 2.1  82/10/25  14:47:51  pavel
  656.  * Added Copyright Notice
  657.  * 
  658.  * Revision 2.0  82/10/25  13:46:31  pavel
  659.  * Beta-one Test Release
  660.  * 
  661. **
  662. */
  663.  
  664. static char RCSid[] =
  665.     "$Header:   RCS/lib_move.v  Revision 2.1  82/10/25  14:47:51  pavel  Exp$";
  666.  
  667. #include "curses.h"
  668. #include "curses.priv.h"
  669.  
  670.  
  671. wmove(win, y, x)
  672. WINDOW    *win;
  673. int    y, x;
  674. {
  675. #ifdef TRACE
  676.     if (_tracing)
  677.         _tracef("wmove(%o,%d,%d) called", win, y, x);
  678. #endif
  679.  
  680.     if (0 <= x  &&  x <= win->_maxx  &&
  681.         win->_regtop <= y  &&  y <= win->_regbottom)
  682.     {
  683.         win->_curx = x;
  684.         win->_cury = y;
  685.  
  686.         return(OK);
  687.     }
  688.     else
  689.         return(ERR);
  690. }
  691. //go.sysin dd *
  692. echo 'x - =src/lib_mvcur.c'
  693. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvcur.c
  694. X/*********************************************************************
  695. *                         COPYRIGHT NOTICE                           *
  696. **********************************************************************
  697. *        This software is copyright (C) 1982 by Pavel Curtis         *
  698. *                                                                    *
  699. *        Permission is granted to reproduce and distribute           *
  700. *        this file by any means so long as no fee is charged         *
  701. *        above a nominal handling fee and so long as this            *
  702. *        notice is always included in the copies.                    *
  703. *                                                                    *
  704. *        Other rights are reserved except as explicitly granted      *
  705. *        by written permission of the author.                        *
  706. *                Pavel Curtis                                        *
  707. *                Computer Science Dept.                              *
  708. *                405 Upson Hall                                      *
  709. *                Cornell University                                  *
  710. *                Ithaca, NY 14853                                    *
  711. *                                                                    *
  712. *                Ph- (607) 256-4934                                  *
  713. *                                                                    *
  714. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  715. *                decvax!cornell!pavel       (UUCPnet)                *
  716. *********************************************************************/
  717.  
  718. X/*
  719. **
  720. **    lib_mvcur.c
  721. **
  722. **    mvcur() and its subroutines
  723. **
  724. ** $Log:    RCS/lib_mvcur.v $
  725.  * Revision 2.1  82/10/25  14:47:54  pavel
  726.  * Added Copyright Notice
  727.  * 
  728.  * Revision 2.0  82/10/25  13:46:40  pavel
  729.  * Beta-one Test Release
  730.  * 
  731. **
  732. **    Revisions needed:
  733. **        implement c_save instead of multiple tputs() calls
  734. **        routine revisions
  735. */
  736.  
  737. static char RCSid[] =
  738.     "$Header:   RCS/lib_mvcur.v  Revision 2.1  82/10/25  14:47:54  pavel  Exp$";
  739.  
  740. #include "term.h"
  741. #include "curses.h"
  742. #include "curses.priv.h"
  743.  
  744.  
  745. #define BUFSIZE    128            /* size of strategy buffer */
  746.  
  747. struct Sequence
  748. {
  749.     int    vec[BUFSIZE],    /* vector of operations */
  750.         *end,        /* end of vector */
  751.         cost;        /* cost of vector */
  752. };
  753.  
  754. X/*
  755. **    #define
  756. **    Make_seq_best(s1, s2)
  757. **    
  758. **    Make_seq_best() swaps the values
  759. **  of the pointers if s1->cost > s2->cost.
  760. */
  761.  
  762. #define Make_seq_best(s1, s2)        \
  763.     if (s1->cost > s2->cost)    \
  764.     {                \
  765.         struct Sequence    *temp;    \
  766.                     \
  767.         temp = s1;            \
  768.         s1 = s2;            \
  769.         s2 = temp;            \
  770.     }                
  771.  
  772.  
  773. XFILE    *out_file;                /* pointer to output file */
  774.  
  775. static int    c_count;        /* used for counting tputs output */
  776.  
  777. X/*rev c_save not yet used
  778. static char    *c_save;        /* used for saving tputs output */
  779.  
  780. #define    INFINITY    1000        /* biggest, impossible sequence cost */
  781.  
  782.  
  783. #define NUM_OPS        16        /* num. term. control sequences */
  784. #define NUM_NPARM    9        /* num. ops wo/ parameters */
  785.  
  786.     /* operator indexes into op_info */
  787.  
  788. #define    CARRIAGE_RETURN    0        /* watch out for nl mapping */
  789. #define    CURS_DOWN    1
  790. #define    CURS_HOME    2
  791. #define    CURS_LEFT    3
  792. #define    CURS_RIGHT    4
  793. #define    CURS_TO_LL    5
  794. #define    CURS_UP        6
  795. #define    TAB        7
  796. #define    BACK_TAB    8
  797. #define    ROW_ADDR    9
  798. #define    COL_ADDR    10
  799. #define    P_DOWN_CURS    11
  800. #define    P_LEFT_CURS    12
  801. #define    P_RIGHT_CURS    13
  802. #define    P_UP_CURS    14
  803. #define    CURS_ADDR    15
  804.  
  805. static bool    loc_init = FALSE;    /* set if op_info is init'ed */
  806.  
  807. static bool    rel_ok;            /* set if we really know where we are */
  808.  
  809.  
  810. X/*
  811.  *    op_info[NUM_OPS]
  812.  *
  813.  *    op_info[] contains for operations with no parameters
  814.  *  the cost of the operation.  These ops should be first in the array.
  815.  *    For operations with parameters, op_info[] contains
  816.  *  the negative of the number of parameters.
  817.  */
  818.  
  819. static int    op_info[NUM_OPS] =
  820. {
  821.     0,        /* carriage_return */
  822.     0,        /* cursor_down */
  823.     0,        /* cursor_home */
  824.     0,        /* cursor_left */
  825.     0,        /* cursor_right */
  826.     0,        /* cursor_to_ll */
  827.     0,        /* cursor_up */
  828.     0,        /* tab */
  829.     0,        /* back_tab */
  830.     -1,        /* row_address */
  831.     -1,        /* column_address */
  832.     -1,        /* parm_down_cursor */
  833.     -1,        /* parm_left_cursor */
  834.     -1,        /* parm_right_cursor */
  835.     -1,        /* parm_up_cursor */
  836.     -2        /* cursor_address */
  837. };
  838.  
  839.  
  840. X/*
  841. **
  842. **    mvcur(oldrow, oldcol, newrow, newcol)
  843. **
  844. **    mvcur() optimally moves the cursor from the position
  845. **  specified by (oldrow, oldcol) to (newrow, newcol).  If
  846. **  (oldrow, oldcol) == (-1, -1), mvcur() does not use relative
  847. **  cursor motions.  If the coordinates are otherwise
  848. **  out of bounds, it mods them into range.
  849. **
  850. **    Revisions needed:
  851. **        eat_newline_glitch, auto_right_margin
  852. */
  853.  
  854. mvcur(oldrow, oldcol, newrow, newcol)
  855. int    oldrow, oldcol,
  856.     newrow, newcol;
  857. {
  858.     struct Sequence    seqA, seqB,    /* allocate work structures */
  859.             col0seq,    /* sequence to get from col0 to nc */
  860.             *best,        /* best sequence so far */
  861.             *try;        /* next try */
  862.  
  863. #ifdef TRACE
  864.     if (_tracing)
  865.         _tracef("mvcur(%d,%d,%d,%d) called",
  866.                         oldrow, oldcol, newrow, newcol);
  867. #endif
  868.  
  869.     update_ops();            /* make sure op_info[] is current */
  870.  
  871.     if (oldrow < 0  ||  oldcol < 0)
  872.         rel_ok = FALSE;        /* relative ops ok? */
  873.     else
  874.     {
  875.         rel_ok = TRUE;
  876.  
  877.         oldrow %= lines;        /* mod values into range */
  878.         oldcol %= columns;
  879.     }
  880.     newrow %= lines;
  881.     newcol %= columns;
  882.  
  883.     best = &seqA;
  884.     try = &seqB;
  885.  
  886.         /* try out direct cursor addressing */
  887.  
  888.     zero_seq(best);
  889.     add_op(best, CURS_ADDR, newrow, newcol);
  890.  
  891.         /* try out independent row/column addressing */
  892.  
  893.     if (rel_ok)
  894.     {
  895.         zero_seq(try);
  896.         row(try, oldrow, newrow);
  897.         column(try, oldcol, newcol);
  898.         Make_seq_best(best, try);
  899.     }
  900.  
  901.     zero_seq(&col0seq);        /* store seq. to get from c0 to nc */
  902.     column(&col0seq, 0, newcol);
  903.  
  904.     if(col0seq.cost < INFINITY)    /* can get from col0 to newcol */
  905.     {
  906.             /* try out homing and then row/column */
  907.  
  908.         if (! rel_ok  ||  newcol < oldcol  ||  newrow < oldrow)
  909.         {
  910.         zero_seq(try);
  911.         add_op(try, CURS_HOME, 1);
  912.         row(try, 0, newrow);
  913.         add_seq(try, &col0seq);
  914.         Make_seq_best(best, try);
  915.         }
  916.  
  917.             /* try out homing to last line  and then row/column */
  918.  
  919.         if (! rel_ok  ||  newcol < oldcol  ||  newrow > oldrow)
  920.         {
  921.         zero_seq(try);
  922.         add_op(try, CURS_TO_LL, 1);
  923.         row(try, lines - 1, newrow);
  924.         add_seq(try, &col0seq);
  925.         Make_seq_best(best, try);
  926.         }
  927.     }
  928.  
  929. #ifdef TRACE
  930.     if (_tracing)
  931.         _tracef("\tmvcur: result follows");
  932. #endif
  933.  
  934.     out_seq(best);
  935.  
  936. #ifdef TRACE
  937.     if (_tracing)
  938.         _tracef("\tmvcur: end of result");
  939. #endif
  940. }
  941.  
  942.  
  943. X/*
  944. **    row(outseq, oldrow, newrow)
  945. **
  946. **    row() adds the best sequence for moving
  947. **  the cursor from oldrow to newrow to seq.
  948. **    row() considers row_address, parm_up/down_cursor
  949. **  and cursor_up/down.
  950. */
  951.  
  952. static
  953. row(outseq, orow, nrow)
  954. int        orow, nrow;        /* old, new cursor locations */
  955. struct Sequence    *outseq;        /* where to put the output */
  956. {
  957.     struct Sequence    seqA, seqB,
  958.             *best,        /* best sequence so far */
  959.             *try;        /* next try */
  960.     int    parm_cursor, one_step;
  961.  
  962.     best = &seqA;
  963.     try = &seqB;
  964.  
  965.     if (nrow == orow)
  966.         return;
  967.  
  968.     if (nrow < orow)
  969.     {
  970.         parm_cursor = P_UP_CURS;
  971.         one_step = CURS_UP;
  972.     }
  973.     else
  974.     {
  975.         parm_cursor = P_DOWN_CURS;
  976.         one_step = CURS_DOWN;
  977.     }
  978.  
  979.         /* try out direct row addressing */
  980.  
  981.     zero_seq(best);
  982.     add_op(best, ROW_ADDR, nrow);
  983.  
  984.         /* try out paramaterized up or down motion */
  985.  
  986.     if (rel_ok)
  987.     {
  988.         zero_seq(try);
  989.         add_op(try, parm_cursor, abs(orow - nrow));
  990.         Make_seq_best(best, try);
  991.     }
  992.         /* try getting there one step at a time... */
  993.  
  994.     if (rel_ok)
  995.     {
  996.         zero_seq(try);
  997.         add_op(try, one_step, abs(orow-nrow));
  998.         Make_seq_best(best, try);
  999.     }
  1000.  
  1001.     add_seq(outseq, best);
  1002. }
  1003.  
  1004.  
  1005. X/*
  1006. **    column(outseq, oldcol, newcol)
  1007. **
  1008. **    column() adds the best sequence for moving
  1009. **  the cursor from oldcol to newcol to outseq.
  1010. **    column() considers column_address, parm_left/right_cursor,
  1011. **  simp_col(), and carriage_return followed by simp_col().
  1012. */
  1013.  
  1014. static
  1015. column(outseq, ocol, ncol)
  1016. struct Sequence    *outseq;            /* where to put the output */
  1017. int        ocol, ncol;            /* old, new cursor  column */
  1018. {
  1019.     struct Sequence    seqA, seqB,
  1020.             *best, *try;
  1021.     int        parm_cursor;    /* set to either parm_up/down_cursor */
  1022.  
  1023.     best = &seqA;
  1024.     try = &seqB;
  1025.  
  1026.     if (ncol == ocol)
  1027.         return;
  1028.  
  1029.     if (ncol < ocol)
  1030.         parm_cursor = P_LEFT_CURS;
  1031.     else
  1032.         parm_cursor = P_RIGHT_CURS;
  1033.  
  1034.         /* try out direct column addressing */
  1035.  
  1036.     zero_seq(best);
  1037.     add_op(best, COL_ADDR, ncol);
  1038.  
  1039.         /* try carriage_return then simp_col() */
  1040.  
  1041.     if (! rel_ok  ||  (ncol < ocol))
  1042.     {
  1043.         zero_seq(try);
  1044.         add_op(try, CARRIAGE_RETURN, 1);
  1045.         simp_col(try, 0, ncol);
  1046.         Make_seq_best(best, try);
  1047.     }
  1048.     if (rel_ok)
  1049.     {
  1050.         /* try out paramaterized left or right motion */
  1051.  
  1052.         zero_seq(try);
  1053.         add_op(try, parm_cursor, abs(ocol - ncol));
  1054.         Make_seq_best(best, try);
  1055.  
  1056.         /* try getting there with simp_col() */
  1057.  
  1058.         zero_seq(try);
  1059.         simp_col(try, ocol, ncol);
  1060.         Make_seq_best(best, try);
  1061.     }
  1062.  
  1063.     add_seq(outseq, best);
  1064. }
  1065.  
  1066.  
  1067. X/*
  1068. **     simp_col(outseq, oldcol, newcol)
  1069. **
  1070. **    simp_col() adds the best simple sequence for getting
  1071. **  from oldcol to newcol to outseq.
  1072. **    simp_col() considers (back_)tab and cursor_left/right.
  1073. **
  1074. **  Revisions needed:
  1075. **    Simp_col asssumes that the cost of a (back_)tab
  1076. **  is less then the cost of one-stepping to get to the same column.
  1077. **    Should sometimes use overprinting instead of cursor_right.
  1078. */
  1079.  
  1080. static
  1081. simp_col(outseq, oc, nc)
  1082. struct Sequence    *outseq;        /* place to put sequence */
  1083. int        oc, nc;            /* old column, new column */
  1084. {
  1085.     struct Sequence    seqA, seqB, tabseq,
  1086.             *best, *try;
  1087.     int        mytab, tabs, onepast,
  1088.             one_step, opp_step; 
  1089.  
  1090.     if (! rel_ok)
  1091.     {
  1092.         outseq->cost = INFINITY;
  1093.         return;
  1094.     }
  1095.  
  1096.     if (oc == nc)
  1097.         return;
  1098.  
  1099.     best = &seqA;
  1100.     try  = &seqB;
  1101.  
  1102.     if (oc < nc)
  1103.     {
  1104.         mytab = TAB;
  1105.         if (init_tabs > 0  &&  op_info[TAB] < INFINITY)
  1106.         {
  1107.         tabs = nc / init_tabs - oc / init_tabs;
  1108.         onepast = ((nc / init_tabs) + 1) * init_tabs;
  1109.         if (tabs)
  1110.             oc = onepast - init_tabs;    /* consider it done */
  1111.         }
  1112.         else
  1113.         tabs = 0;
  1114.  
  1115.         one_step = CURS_RIGHT;
  1116.         opp_step = CURS_LEFT;
  1117.     }
  1118.     else
  1119.     {
  1120.         mytab = BACK_TAB;
  1121.         if (init_tabs > 0  &&  op_info[BACK_TAB] < INFINITY)
  1122.         {
  1123.         tabs = oc / init_tabs - nc / init_tabs;
  1124.         onepast = ((nc - 1) / init_tabs) * init_tabs;
  1125.         if (tabs)
  1126.             oc = onepast + init_tabs;    /* consider it done */
  1127.         }
  1128.         else
  1129.         tabs = 0;
  1130.  
  1131.         one_step = CURS_LEFT;
  1132.         opp_step = CURS_RIGHT;
  1133.     }
  1134.  
  1135.         /* tab as close as possible to nc */
  1136.  
  1137.     zero_seq(&tabseq);
  1138.     add_op(&tabseq, mytab, tabs);
  1139.  
  1140.         /* try extra tab and backing up */
  1141.  
  1142.     zero_seq(best);
  1143.  
  1144.     if (onepast >= 0  &&  onepast < columns)
  1145.     {
  1146.         add_op(best, mytab, 1);
  1147.         add_op(best, opp_step, abs(onepast - nc));
  1148.     }
  1149.     else
  1150.         best->cost = INFINITY;    /* make sure of next swap */
  1151.  
  1152.         /* try stepping to nc */
  1153.  
  1154.     zero_seq(try);
  1155.     add_op(try, one_step, abs(nc - oc));
  1156.     Make_seq_best(best, try);
  1157.     
  1158.     if (tabseq.cost < INFINITY)
  1159.         add_seq(outseq, &tabseq);
  1160.     add_seq(outseq, best);
  1161. }
  1162.  
  1163.  
  1164. X/*
  1165. **    zero_seq(seq)
  1166. **    add_seq(seq1, seq2)
  1167. **    out_seq(seq)
  1168. **
  1169. **    zero_seq() empties seq.
  1170. **    add_seq() adds seq1 to seq2.
  1171. **    out_seq() outputs a sequence.
  1172. */
  1173.  
  1174. static
  1175. zero_seq(seq)
  1176. struct Sequence    *seq;
  1177. {
  1178.     seq->end = seq->vec;
  1179.     seq->cost = 0;
  1180. }
  1181.  
  1182. static
  1183. add_seq(seq1, seq2)
  1184. struct Sequence    *seq1, *seq2;
  1185. {
  1186.     int    *vptr;
  1187.  
  1188.     if(seq1->cost >= INFINITY  ||  seq2->cost >= INFINITY)
  1189.         seq1->cost = INFINITY;
  1190.     else
  1191.     {
  1192.         vptr = seq2->vec;
  1193.         while (vptr != seq2->end)
  1194.         *(seq1->end++) = *(vptr++);
  1195.         seq1->cost += seq2->cost;
  1196.     }
  1197. }
  1198.  
  1199.  
  1200. static
  1201. out_seq(seq)
  1202. struct Sequence    *seq;
  1203. {
  1204.     int    *opptr, prm[9], ps, p, op, outc();
  1205.     int    count;
  1206.     char    *sequence();
  1207.  
  1208.     if (seq->cost >= INFINITY)
  1209.         return;
  1210.  
  1211.     for (opptr = seq->vec;  opptr < seq->end;  opptr++)
  1212.     {
  1213.         op = *opptr;            /* grab operator */
  1214.         ps = -op_info[op];
  1215.         if(ps > 0)                /* parameterized */
  1216.         {
  1217.         for (p = 0;  p < ps;  p++)    /* fill in needed parms */
  1218.             prm[p] = *(++opptr);
  1219.  
  1220.         tputs(tparm(sequence(op),
  1221.                     prm[0], prm[1], prm[2], prm[3], prm[4],
  1222.                 prm[5], prm[6], prm[7], prm[8]), 1, outc);
  1223.         }
  1224.         else
  1225.         {
  1226.         count = *(++opptr);
  1227.             /*rev should save tputs output instead of mult calls */
  1228.         while (count--)            /* do count times */
  1229.             tputs(sequence(op), 1, outc);
  1230.         }
  1231.     }
  1232. }
  1233.  
  1234.  
  1235. X/*
  1236. **    update_ops()
  1237. **
  1238. **    update_ops() makes sure that
  1239. ** the op_info[] array is updated and initializes
  1240. ** the cost array for SP if needed.
  1241. */
  1242.  
  1243. static
  1244. update_ops()
  1245. {
  1246.     if (SP)                /* SP structure exists */
  1247.     {
  1248.         int    op; 
  1249.  
  1250.         out_file = SP->_ofp;    /* set output file pointer */
  1251.  
  1252.         if (! SP->_costinit)    /* this term not yet assigned costs */
  1253.         {
  1254.         loc_init = FALSE;    /* if !SP in the future, new term */
  1255.         init_costs(SP->_costs);    /* fill term costs */
  1256.         SP->_costinit = TRUE;
  1257.         }
  1258.  
  1259.         for (op = 0;  op < NUM_NPARM;  op++)
  1260.         op_info[op] = SP->_costs[op];    /* set up op_info */
  1261.         
  1262.         /* check for newline that might be mapped... */
  1263.         if (SP->_nlmapping  &&  index(sequence(CURS_DOWN), '\n'))
  1264.         op_info[CURS_DOWN] = INFINITY;
  1265.     }
  1266.     else
  1267.     {
  1268.         out_file = stdout;
  1269.  
  1270.         if (! loc_init)            /* using local costs */
  1271.         {
  1272.         loc_init = TRUE;
  1273.         init_costs(op_info);        /* set up op_info */
  1274.         }
  1275.         /* check for newline that might be mapped... */
  1276.         if (index(sequence(CURS_DOWN), '\n'))
  1277.         op_info[CURS_DOWN] = INFINITY;
  1278.     }
  1279. }
  1280.  
  1281.  
  1282. X/*
  1283. **    init_costs(costs)
  1284. **
  1285. **    init_costs() fills the array costs[NUM_NPARM]
  1286. ** with costs calculated by doing tputs() calls.
  1287. */
  1288.  
  1289. static
  1290. init_costs(costs)
  1291. int    costs[];
  1292. {
  1293.     int    i, countc();
  1294.  
  1295.     for (i = 0;  i < NUM_NPARM;  i++)
  1296.         if(sequence(i) != (char *) 0)
  1297.         {
  1298. #ifdef UNDEFINED
  1299.     if (_tracing)
  1300.         _tracef("\tinit_costs: pricing %d: '%s'", i, sequence(i));
  1301. #endif
  1302.  
  1303.         c_count = 0;
  1304.         tputs(sequence(i), 1, countc);
  1305.         costs[i] = c_count;
  1306.         }
  1307.         else
  1308.         costs[i] = INFINITY;
  1309. }
  1310.  
  1311.  
  1312. X/*
  1313. **    countc()
  1314. **    outc(c)
  1315. **    savec(c)
  1316. **    
  1317. **    countc() increments global var c_count.
  1318. **    outc() outputs a single character.
  1319. **    savec() saves c in *c_save and increments c_save and c_count.
  1320. */
  1321.  
  1322. static
  1323. countc()
  1324. {
  1325.     c_count++;
  1326. }
  1327.  
  1328. static
  1329. outc(c)
  1330. char c;
  1331. {
  1332.     fputc(c, out_file);
  1333. }
  1334.  
  1335. X/*rev not yet needed 
  1336. static
  1337. savec(c)
  1338. char c;
  1339. {
  1340.     *(c_save++) = c;
  1341.     c_count++;
  1342. }
  1343. */
  1344.  
  1345.  
  1346. X/*
  1347. **    add_op(seq, op, p0, p1, ... , p8)
  1348. **
  1349. **    add_op() adds the operator op and the appropriate
  1350. **  number of paramaters to seq.  It also increases the 
  1351. **  cost appropriately.
  1352. **    if op has no parameters, p0 is taken to be a count.
  1353. */
  1354.  
  1355. static
  1356. add_op(seq, op, p0, p1, p2, p3, p4, p5, p6, p7, p8)
  1357. struct Sequence    *seq;
  1358. int        op, p0, p1, p2, p3, p4, p5, p6, p7, p8;
  1359. {
  1360.     int    num_ps, p;
  1361.  
  1362. #ifdef UNDEFINED
  1363.     if (_tracing)
  1364.         _tracef("\tadd_op(%o,%d,%d,%d) called", seq, op, p0, p1);
  1365. #endif
  1366.  
  1367.     num_ps = - op_info[op];        /* get parms or -cost */
  1368.     *(seq->end++) = op;
  1369.  
  1370.     if (num_ps == (- INFINITY)  ||  sequence(op) == (char *) 0)
  1371.         seq->cost = INFINITY;
  1372.     else
  1373.         if (num_ps <= 0)        /* no parms, -cost */
  1374.     {
  1375.         seq->cost -= p0 * num_ps;    /* ADD count * cost */
  1376.         *(seq->end++) = p0;
  1377.     }
  1378.     else
  1379.     {
  1380.         int    pms[9];
  1381.  
  1382.         pms[0] = p0;  pms[1] = p1;  pms[2] = p2;
  1383.         pms[3] = p3;  pms[4] = p4;  pms[5] = p5;
  1384.         pms[6] = p6;  pms[7] = p7;  pms[8] = p8;  
  1385.         for(p = 0;  p < num_ps;  p++)
  1386.         *(seq->end++) = pms[p];
  1387.         c_count = 0;
  1388.         tputs(tparm(sequence(op), p0, p1, p2, p3, p4, p5, p6, p7, p8),
  1389.                                  1, countc);
  1390.         seq->cost += c_count;
  1391.     }
  1392. }
  1393.  
  1394.  
  1395. X/*
  1396. **    char    *
  1397. **    sequence(op)
  1398. **
  1399. **    sequence() returns a pointer to the op's
  1400. **  terminal control sequence.
  1401. */
  1402.  
  1403. static char    *
  1404. sequence(op)
  1405. int    op;
  1406. {
  1407.     
  1408.     switch(op)
  1409.     {
  1410.         case CARRIAGE_RETURN:
  1411.         return (carriage_return);
  1412.         case CURS_DOWN:
  1413.         return (cursor_down);
  1414.         case CURS_HOME:
  1415.         return (cursor_home);
  1416.         case CURS_LEFT:
  1417.         return (cursor_left);
  1418.         case CURS_RIGHT:
  1419.         return (cursor_right);
  1420.         case CURS_TO_LL:
  1421.         return (cursor_to_ll);
  1422.         case CURS_UP:
  1423.         return (cursor_up);
  1424.         case TAB:
  1425.         return (tab);
  1426.         case BACK_TAB:
  1427.         return (back_tab);
  1428.         case ROW_ADDR:
  1429.         return (row_address);
  1430.         case COL_ADDR:
  1431.         return (column_address);
  1432.         case P_DOWN_CURS:
  1433.         return (parm_down_cursor);
  1434.         case P_LEFT_CURS:
  1435.         return (parm_left_cursor);
  1436.         case P_RIGHT_CURS:
  1437.         return (parm_right_cursor);
  1438.         case P_UP_CURS:
  1439.         return (parm_up_cursor);
  1440.         case CURS_ADDR:
  1441.         return (cursor_address);
  1442.         default:
  1443.         return ((char *) 0);
  1444.     }
  1445. }
  1446.  
  1447. //go.sysin dd *
  1448. echo 'x - =src/lib_mvwin.c'
  1449. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_mvwin.c
  1450. X/*********************************************************************
  1451. *                         COPYRIGHT NOTICE                           *
  1452. **********************************************************************
  1453. *        This software is copyright (C) 1982 by Pavel Curtis         *
  1454. *                                                                    *
  1455. *        Permission is granted to reproduce and distribute           *
  1456. *        this file by any means so long as no fee is charged         *
  1457. *        above a nominal handling fee and so long as this            *
  1458. *        notice is always included in the copies.                    *
  1459. *                                                                    *
  1460. *        Other rights are reserved except as explicitly granted      *
  1461. *        by written permission of the author.                        *
  1462. *                Pavel Curtis                                        *
  1463. *                Computer Science Dept.                              *
  1464. *                405 Upson Hall                                      *
  1465. *                Cornell University                                  *
  1466. *                Ithaca, NY 14853                                    *
  1467. *                                                                    *
  1468. *                Ph- (607) 256-4934                                  *
  1469. *                                                                    *
  1470. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  1471. *                decvax!cornell!pavel       (UUCPnet)                *
  1472. *********************************************************************/
  1473.  
  1474. X/*
  1475. **    lib_mvwin.c
  1476. **
  1477. **    The routine mvwin().
  1478. **
  1479. ** $Log:    RCS/lib_mvwin.v $
  1480.  * Revision 2.1  82/10/25  14:48:10  pavel
  1481.  * Added Copyright Notice
  1482.  * 
  1483.  * Revision 2.0  82/10/25  13:47:03  pavel
  1484.  * Beta-one Test Release
  1485.  * 
  1486. **
  1487. */
  1488.  
  1489. static char RCSid[] =
  1490.     "$Header:   RCS/lib_mvwin.v  Revision 2.1  82/10/25  14:48:10  pavel  Exp$";
  1491.  
  1492. #include "curses.h"
  1493. #include "curses.priv.h"
  1494.  
  1495.  
  1496. mvwin(win, by, bx)
  1497. WINDOW    *win;
  1498. int    by, bx;
  1499. {
  1500. #ifdef TRACE
  1501.     if (_tracing)
  1502.         _tracef("mvwin(%o,%d,%d) called", win, by, bx);
  1503. #endif
  1504.  
  1505.     if (by + win->_maxy > LINES -1  ||  bx + win->_maxx > COLS - 1)
  1506.         return(ERR);
  1507.  
  1508.     win->_begy = by;
  1509.     win->_begx = bx;
  1510.  
  1511.     touchwin(win);
  1512.  
  1513.     return(OK);
  1514. }
  1515. //go.sysin dd *
  1516. echo 'x - =src/lib_newterm.c'
  1517. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newterm.c
  1518. X/*********************************************************************
  1519. *                         COPYRIGHT NOTICE                           *
  1520. **********************************************************************
  1521. *        This software is copyright (C) 1982 by Pavel Curtis         *
  1522. *                                                                    *
  1523. *        Permission is granted to reproduce and distribute           *
  1524. *        this file by any means so long as no fee is charged         *
  1525. *        above a nominal handling fee and so long as this            *
  1526. *        notice is always included in the copies.                    *
  1527. *                                                                    *
  1528. *        Other rights are reserved except as explicitly granted      *
  1529. *        by written permission of the author.                        *
  1530. *                Pavel Curtis                                        *
  1531. *                Computer Science Dept.                              *
  1532. *                405 Upson Hall                                      *
  1533. *                Cornell University                                  *
  1534. *                Ithaca, NY 14853                                    *
  1535. *                                                                    *
  1536. *                Ph- (607) 256-4934                                  *
  1537. *                                                                    *
  1538. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  1539. *                decvax!cornell!pavel       (UUCPnet)                *
  1540. *********************************************************************/
  1541.  
  1542. X/*
  1543. **    lib_newterm.c
  1544. **
  1545. **     The newterm() function.
  1546. **
  1547. ** $Log:    RCS/lib_newterm.v $
  1548.  * Revision 2.1  82/10/25  14:48:14  pavel
  1549.  * Added Copyright Notice
  1550.  * 
  1551.  * Revision 2.0  82/10/25  13:47:11  pavel
  1552.  * Beta-one Test Release
  1553.  * 
  1554. **
  1555. */
  1556.  
  1557. static char RCSid[] =
  1558.     "$Header:   RCS/lib_newterm.v  Revision 2.1  82/10/25  14:48:14  pavel  Exp$";
  1559.  
  1560. #include <signal.h>
  1561. #include <stdio.h>
  1562. #include "curses.h"
  1563. #include "term.h"
  1564. #include "curses.priv.h"
  1565.  
  1566.  
  1567.  
  1568. struct screen *
  1569. newterm(term, fp)
  1570. char    *term;
  1571. XFILE    *fp;
  1572. {
  1573.     int    errret;
  1574.     int    tstp();
  1575.  
  1576. #ifdef TRACE
  1577.     _init_trace();
  1578.  
  1579.     if (_tracing)
  1580.         _tracef("newterm(%s,%o) called", term, fp);
  1581. #endif
  1582.  
  1583.     if (setupterm(term, fileno(fp), &errret) != 1)
  1584.         return(ERR);
  1585.  
  1586.     if ((SP = (struct screen *) malloc(sizeof *SP)) == NULL)
  1587.         return(ERR);
  1588.  
  1589.     if (fp == stdout)
  1590.     {
  1591.         SP->_ofp       = stdout;
  1592.         SP->_ifp       = stdin;
  1593.     }
  1594.     else
  1595.     {
  1596.         SP->_ofp       = fp;
  1597.         SP->_ifp       = fp;
  1598.     }
  1599.     SP->_term      = cur_term;
  1600.     SP->_cursrow   = -1;
  1601.     SP->_curscol   = -1;
  1602.         SP->_keytry    = UNINITIALISED;
  1603.     SP->_nl        = TRUE;
  1604.     SP->_raw       = FALSE;
  1605.     SP->_cbreak    = FALSE;
  1606.     SP->_echo      = TRUE;
  1607.     SP->_nlmapping = TRUE;
  1608.     SP->_costinit  = FALSE;
  1609.  
  1610.     LINES = lines;
  1611.     COLS = columns;
  1612.  
  1613.     if (enter_ca_mode)
  1614.         putp(enter_ca_mode);
  1615.  
  1616.     if ((newscr = newwin(lines, columns, 0, 0)) == ERR)
  1617.         return(ERR);
  1618.  
  1619.     if ((curscr = newwin(lines, columns, 0, 0)) == ERR)
  1620.         return(ERR);
  1621.  
  1622.     SP->_newscr = newscr;
  1623.     SP->_curscr = curscr;
  1624.  
  1625.     newscr->_clear = TRUE;
  1626.     curscr->_clear = FALSE;
  1627.  
  1628.     signal(SIGTSTP, tstp);
  1629.  
  1630.     if (stdscr == NULL)
  1631.         if ((stdscr = newwin(lines, columns, 0, 0)) == ERR)
  1632.         return(ERR);
  1633.  
  1634. #ifdef TRACE
  1635.     if (_tracing)
  1636.         _tracef("\tnewterm returns %o", SP);
  1637. #endif
  1638.  
  1639.     return(SP);
  1640. }
  1641. //go.sysin dd *
  1642. echo 'x - =src/lib_newwin.c'
  1643. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_newwin.c
  1644. X/*********************************************************************
  1645. *                         COPYRIGHT NOTICE                           *
  1646. **********************************************************************
  1647. *        This software is copyright (C) 1982 by Pavel Curtis         *
  1648. *                                                                    *
  1649. *        Permission is granted to reproduce and distribute           *
  1650. *        this file by any means so long as no fee is charged         *
  1651. *        above a nominal handling fee and so long as this            *
  1652. *        notice is always included in the copies.                    *
  1653. *                                                                    *
  1654. *        Other rights are reserved except as explicitly granted      *
  1655. *        by written permission of the author.                        *
  1656. *                Pavel Curtis                                        *
  1657. *                Computer Science Dept.                              *
  1658. *                405 Upson Hall                                      *
  1659. *                Cornell University                                  *
  1660. *                Ithaca, NY 14853                                    *
  1661. *                                                                    *
  1662. *                Ph- (607) 256-4934                                  *
  1663. *                                                                    *
  1664. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  1665. *                decvax!cornell!pavel       (UUCPnet)                *
  1666. *********************************************************************/
  1667.  
  1668. X/*
  1669. **    lib_newwin.c
  1670. **
  1671. **    The routines newwin(), subwin() and their dependent
  1672. **
  1673. ** $Log:    RCS/lib_newwin.v $
  1674.  * Revision 2.1  82/10/25  14:48:18  pavel
  1675.  * Added Copyright Notice
  1676.  * 
  1677.  * Revision 2.0  82/10/25  13:47:18  pavel
  1678.  * Beta-one Test Release
  1679.  * 
  1680. **
  1681. */
  1682.  
  1683. #include "term.h"
  1684. #include "curses.h"
  1685. #include "curses.priv.h"
  1686.  
  1687. short    *calloc();
  1688. WINDOW    *malloc();
  1689.  
  1690. static WINDOW    *makenew();
  1691.  
  1692.  
  1693. WINDOW *
  1694. newwin(num_lines, num_columns, begy, begx)
  1695. int    num_lines, num_columns, begy, begx;
  1696. {
  1697.     WINDOW    *win;
  1698.     chtype    *ptr;
  1699.     int    i, j;
  1700.  
  1701. #ifdef TRACE
  1702.     if (_tracing)
  1703.         _tracef("newwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx);
  1704. #endif
  1705.  
  1706.     if (num_lines == 0)
  1707.         num_lines = lines - begy;
  1708.  
  1709.     if (num_columns == 0)
  1710.         num_columns = columns - begx;
  1711.  
  1712.     if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR)
  1713.         return(ERR);
  1714.  
  1715.     for (i = 0; i < num_lines; i++)
  1716.     {
  1717.         if ((win->_line[i] = (chtype *) calloc(num_columns, sizeof(chtype)))
  1718.                                       == NULL)
  1719.         {
  1720.         for (j = 0; j < i; j++)
  1721.             cfree(win->_line[j]);
  1722.  
  1723.         cfree(win->_firstchar);
  1724.         cfree(win->_lastchar);
  1725.         cfree(win->_line);
  1726.         cfree(win);
  1727.  
  1728.         return(ERR);
  1729.         }
  1730.         else
  1731.         for (ptr = win->_line[i]; ptr < win->_line[i] + num_columns; )
  1732.             *ptr++ = ' ';
  1733.     }
  1734.  
  1735. #ifdef TRACE
  1736.     if (_tracing)
  1737.         _tracef("\tnewwin: returned window is %o", win);
  1738. #endif
  1739.  
  1740.     return(win);
  1741. }
  1742.  
  1743.  
  1744.  
  1745. WINDOW *
  1746. subwin(orig, num_lines, num_columns, begy, begx)
  1747. WINDOW    *orig;
  1748. int    num_lines, num_columns, begy, begx;
  1749. {
  1750.     WINDOW    *win;
  1751.     int    i, j, k;
  1752.  
  1753. #ifdef TRACE
  1754.     if (_tracing)
  1755.         _tracef("subwin(%d,%d,%d,%d) called", num_lines, num_columns, begy, begx);
  1756. #endif
  1757.  
  1758.     /*
  1759.     ** make sure window fits inside the original one
  1760.     */
  1761.  
  1762.     if (begy < orig->_begy || begx < orig->_begx
  1763.             || begy + num_lines > orig->_maxy
  1764.             || begx + num_columns > orig->_maxx)
  1765.         return(ERR);
  1766.  
  1767.     if (num_lines == 0)
  1768.         num_lines = orig->_maxy - orig->_begy - begy;
  1769.  
  1770.     if (num_columns == 0)
  1771.         num_columns = orig->_maxx - orig->_begx - begx;
  1772.  
  1773.     if ((win = makenew(num_lines, num_columns, begy, begx)) == ERR)
  1774.         return(ERR);
  1775.  
  1776.     j = orig->_begy + begy;
  1777.     k = orig->_begx + begx;
  1778.  
  1779.     for (i = 0; i < num_lines; i++)
  1780.         win->_line[i] = &orig->_line[j++][k];
  1781.  
  1782.     win->_flags = _SUBWIN;
  1783.  
  1784. #ifdef TRACE
  1785.     if (_tracing)
  1786.         _tracef("\tsubwin: returned window is %o", win);
  1787. #endif
  1788.  
  1789.     return(win);
  1790. }
  1791.  
  1792.  
  1793.  
  1794. static WINDOW *
  1795. makenew(num_lines, num_columns, begy, begx)
  1796. int    num_lines, num_columns, begy, begx;
  1797. {
  1798.     int    i;
  1799.     WINDOW    *win;
  1800.  
  1801.     if ((win = (WINDOW *) malloc(sizeof(WINDOW))) == NULL)
  1802.         return ERR;
  1803.  
  1804.     if ((win->_line = (chtype **) calloc(num_lines, sizeof (chtype *)))
  1805.                                        == NULL)
  1806.     {
  1807.         cfree(win);
  1808.  
  1809.         return(ERR);
  1810.     }
  1811.  
  1812.     if ((win->_firstchar = calloc(num_lines, sizeof(short))) == NULL)
  1813.     {
  1814.         cfree(win);
  1815.         cfree(win->_line);
  1816.  
  1817.         return(ERR);
  1818.     }
  1819.  
  1820.     if ((win->_lastchar = calloc(num_lines, sizeof(short))) == NULL)
  1821.     {
  1822.         cfree(win);
  1823.         cfree(win->_line);
  1824.         cfree(win->_firstchar);
  1825.  
  1826.         return(ERR);
  1827.     }
  1828.  
  1829.     if ((win->_numchngd = calloc(num_lines, sizeof(short))) == NULL)
  1830.     {
  1831.         cfree(win);
  1832.         cfree(win->_line);
  1833.         cfree(win->_firstchar);
  1834.         cfree(win->_lastchar);
  1835.  
  1836.         return(ERR);
  1837.     }
  1838.  
  1839.     win->_curx       = 0;
  1840.     win->_cury       = 0;
  1841.     win->_maxy       = num_lines - 1;
  1842.     win->_maxx       = num_columns - 1;
  1843.     win->_begy       = begy;
  1844.     win->_begx       = begx;
  1845.  
  1846.     win->_flags      = 0;
  1847.     win->_attrs      = A_NORMAL;
  1848.  
  1849.     win->_clear      = (num_lines == lines  &&  num_columns == columns);
  1850.     win->_scroll     = FALSE;
  1851.     win->_leave      = FALSE;
  1852.     win->_use_keypad = FALSE;
  1853.     win->_use_meta   = FALSE;
  1854.     win->_nodelay    = FALSE;
  1855.  
  1856.     win->_regtop     = 0;
  1857.     win->_regbottom  = num_lines - 1;
  1858.  
  1859.     for (i = 0; i < num_lines; i++)
  1860.     {
  1861.         win->_firstchar[i] = win->_lastchar[i] = _NOCHANGE;
  1862.         win->_numchngd[i] = 0;
  1863.     }
  1864.  
  1865.     if (begx + num_columns == columns)
  1866.     {
  1867.         win->_flags |= _ENDLINE;
  1868.  
  1869.         if (begx == 0  &&  num_lines == lines  &&  begy == 0)
  1870.             win->_flags |= _FULLWIN;
  1871.  
  1872.         if (begy + num_lines == lines)
  1873.             win->_flags |= _SCROLLWIN;
  1874.     }
  1875.  
  1876.     return(win);
  1877. }
  1878. //go.sysin dd *
  1879. echo 'x - =src/lib_options.c'
  1880. sed 's/^X//' <<'//go.sysin dd *' >=src/lib_options.c
  1881. X/*********************************************************************
  1882. *                         COPYRIGHT NOTICE                           *
  1883. **********************************************************************
  1884. *        This software is copyright (C) 1982 by Pavel Curtis         *
  1885. *                                                                    *
  1886. *        Permission is granted to reproduce and distribute           *
  1887. *        this file by any means so long as no fee is charged         *
  1888. *        above a nominal handling fee and so long as this            *
  1889. *        notice is always included in the copies.                    *
  1890. *                                                                    *
  1891. *        Other rights are reserved except as explicitly granted      *
  1892. *        by written permission of the author.                        *
  1893. *                Pavel Curtis                                        *
  1894. *                Computer Science Dept.                              *
  1895. *                405 Upson Hall                                      *
  1896. *                Cornell University                                  *
  1897. *                Ithaca, NY 14853                                    *
  1898. *                                                                    *
  1899. *                Ph- (607) 256-4934                                  *
  1900. *                                                                    *
  1901. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  1902. *                decvax!cornell!pavel       (UUCPnet)                *
  1903. *********************************************************************/
  1904.  
  1905. X/*
  1906. **    lib_options.c
  1907. **
  1908. **    The routines to handle option setting.
  1909. **
  1910. ** $Log:    RCS/lib_options.v $
  1911.  * Revision 2.1  82/10/25  14:48:24  pavel
  1912.  * Added Copyright Notice
  1913.  * 
  1914.  * Revision 2.0  82/10/25  13:47:45  pavel
  1915.  * Beta-one Test Release
  1916.  * 
  1917. **
  1918. */
  1919.  
  1920. static char RCSid[] =
  1921.     "$Header:   RCS/lib_options.v  Revision 2.1  82/10/25  14:48:24  pavel  Exp$";
  1922.  
  1923. #include "term.h"
  1924. #include "curses.h"
  1925. #include "curses.priv.h"
  1926.  
  1927.  
  1928. static
  1929. outc(ch)
  1930. char    ch;
  1931. {
  1932.         putc(ch, SP->_ofp);
  1933. }
  1934.  
  1935.  
  1936. idlok(win, flag)
  1937. WINDOW    *win;
  1938. int    flag;
  1939. {
  1940. #ifdef TRACE
  1941.     if (_tracing)
  1942.         _tracef("idlok(%o,%d) called", win, flag);
  1943. #endif
  1944.  
  1945.         if ((insert_line  &&  delete_line)
  1946. #ifdef UNIMPLEMENTED
  1947.          ||  (change_scroll_region)
  1948. #endif
  1949.        )
  1950.         curscr->_idlok = flag;
  1951. }
  1952.  
  1953.  
  1954. clearok(win, flag)
  1955. WINDOW    *win;
  1956. int    flag;
  1957. {
  1958. #ifdef TRACE
  1959.     if (_tracing)
  1960.         _tracef("clearok(%o,%d) called", win, flag);
  1961. #endif
  1962.  
  1963.         if (win == curscr)
  1964.         newscr->_clear = flag;
  1965.     else
  1966.         win->_clear = flag;
  1967. }
  1968.  
  1969.  
  1970. leaveok(win, flag)
  1971. WINDOW    *win;
  1972. int    flag;
  1973. {
  1974. #ifdef TRACE
  1975.     if (_tracing)
  1976.         _tracef("leaveok(%o,%d) called", win, flag);
  1977. #endif
  1978.  
  1979.         win->_leave = flag;
  1980. }
  1981.  
  1982.  
  1983. scrollok(win, flag)
  1984. WINDOW    *win;
  1985. int    flag;
  1986. {
  1987. #ifdef TRACE
  1988.     if (_tracing)
  1989.         _tracef("scrollok(%o,%d) called", win, flag);
  1990. #endif
  1991.  
  1992.         win->_scroll = flag;
  1993. }
  1994.  
  1995.  
  1996. nodelay(win, flag)
  1997. WINDOW    *win;
  1998. int    flag;
  1999. {
  2000. #ifdef TRACE
  2001.     if (_tracing)
  2002.         _tracef("nodelay(%o,%d) called", win, flag);
  2003. #endif
  2004.  
  2005.         win->_nodelay = flag;
  2006. }
  2007.  
  2008.  
  2009. keypad(win, flag)
  2010. WINDOW    *win;
  2011. int    flag;
  2012. {
  2013. #ifdef TRACE
  2014.     if (_tracing)
  2015.         _tracef("keypad(%o,%d) called", win, flag);
  2016. #endif
  2017.  
  2018.         win->_use_keypad = flag;
  2019.  
  2020.     if (flag  &&  keypad_xmit)
  2021.         tputs(keypad_xmit, 1, outc);
  2022.     else if (! flag  &&  keypad_local)
  2023.         tputs(keypad_local, 1, outc);
  2024.         
  2025.         if (SP->_keytry == UNINITIALISED)
  2026.         init_keytry();
  2027. }
  2028.  
  2029.  
  2030.  
  2031. meta(win, flag)
  2032. WINDOW    *win;
  2033. int    flag;
  2034. {
  2035. #ifdef TRACE
  2036.     if (_tracing)
  2037.         _tracef("meta(%o,%d) called", win, flag);
  2038. #endif
  2039.  
  2040.     win->_use_meta = flag;
  2041.  
  2042.     if (flag  &&  meta_on)
  2043.         tputs(meta_on, 1, outc);
  2044.     else if (! flag  &&  meta_off)
  2045.         tputs(meta_off, 1, outc);
  2046. }
  2047.  
  2048.  
  2049.  
  2050. X/*
  2051. **      init_keytry()
  2052. **
  2053. **      Construct the try for the current terminal's keypad keys.
  2054. **
  2055. */
  2056.  
  2057.  
  2058. static struct  try *newtry;
  2059.  
  2060. static
  2061. init_keytry()
  2062. {
  2063.         newtry = NULL;
  2064.     
  2065.         add_to_try(key_backspace, KEY_BACKSPACE);
  2066.         add_to_try(key_catab, KEY_CATAB);
  2067.         add_to_try(key_clear, KEY_CLEAR);
  2068.         add_to_try(key_ctab, KEY_CTAB);
  2069.         add_to_try(key_dc, KEY_DC);
  2070.         add_to_try(key_dl, KEY_DL);
  2071.         add_to_try(key_down, KEY_DOWN);
  2072.         add_to_try(key_eic, KEY_EIC);
  2073.         add_to_try(key_eol, KEY_EOL);
  2074.         add_to_try(key_eos, KEY_EOS);
  2075.         add_to_try(key_f0, KEY_F(0));
  2076.         add_to_try(key_f1, KEY_F(1));
  2077.         add_to_try(key_f2, KEY_F(2));
  2078.         add_to_try(key_f3, KEY_F(3));
  2079.         add_to_try(key_f4, KEY_F(4));
  2080.         add_to_try(key_f5, KEY_F(5));
  2081.         add_to_try(key_f6, KEY_F(6));
  2082.         add_to_try(key_f7, KEY_F(7));
  2083.         add_to_try(key_f8, KEY_F(8));
  2084.         add_to_try(key_f9, KEY_F(9));
  2085.         add_to_try(key_f10, KEY_F(10));
  2086.         add_to_try(key_home, KEY_HOME);
  2087.         add_to_try(key_ic, KEY_IC);
  2088.         add_to_try(key_il, KEY_IL);
  2089.         add_to_try(key_left, KEY_LEFT);
  2090.         add_to_try(key_npage, KEY_NPAGE);
  2091.         add_to_try(key_ppage, KEY_PPAGE);
  2092.         add_to_try(key_right, KEY_RIGHT);
  2093.         add_to_try(key_sf, KEY_SF);
  2094.         add_to_try(key_sr, KEY_SR);
  2095.         add_to_try(key_stab, KEY_STAB);
  2096.         add_to_try(key_up, KEY_UP);
  2097.     
  2098.     SP->_keytry = newtry;
  2099. }
  2100.  
  2101.  
  2102. add_to_try(str, code)
  2103. char    *str;
  2104. short   code;
  2105. {
  2106.         static bool     out_of_memory = FALSE;
  2107.         struct try      *ptr, *savedptr;
  2108.     struct try      *malloc();
  2109.  
  2110.     if (! str  ||  out_of_memory)
  2111.         return;
  2112.     
  2113.     if (newtry != NULL)    
  2114.     {
  2115.         ptr = newtry;
  2116.         
  2117.                for (;;)
  2118.         {
  2119.             while (ptr->ch != *str  &&  ptr->sibling != NULL)
  2120.                 ptr = ptr->sibling;
  2121.         
  2122.             if (ptr->ch == *str)
  2123.         {
  2124.             if (*(++str))
  2125.             {
  2126.                     if (ptr->child != NULL)
  2127.                     ptr = ptr->child;
  2128.                         else
  2129.                     break;
  2130.             }
  2131.             else
  2132.             {
  2133.                 ptr->value = code;
  2134.             return;
  2135.             }
  2136.         }
  2137.         else
  2138.             {
  2139.             if ((ptr->sibling = malloc(sizeof *ptr)) == NULL)
  2140.             {
  2141.                 out_of_memory = TRUE;
  2142.             return;
  2143.             }
  2144.             
  2145.             savedptr = ptr = ptr->sibling;
  2146.             ptr->child = ptr->sibling = NULL;
  2147.             ptr->ch = *str++;
  2148.             ptr->value = NULL;
  2149.             
  2150.                     break;
  2151.             }
  2152.         } /* end for (;;) */  
  2153.     }
  2154.     else    /* newtry == NULL :: First sequence to be added */
  2155.     {
  2156.         savedptr = ptr = newtry = malloc(sizeof *ptr);
  2157.         
  2158.         if (ptr == NULL)
  2159.         {
  2160.             out_of_memory = TRUE;
  2161.         return;
  2162.         }
  2163.         
  2164.         ptr->child = ptr->sibling = NULL;
  2165.         ptr->ch = *(str++);
  2166.         ptr->value = NULL;
  2167.     }
  2168.     
  2169.         /* at this point, we are adding to the try.  ptr->child == NULL */
  2170.         
  2171.     while (*str)
  2172.     {
  2173.         ptr->child = malloc(sizeof *ptr);
  2174.         
  2175.         ptr = ptr->child;
  2176.         
  2177.         if (ptr == NULL)
  2178.         {
  2179.             out_of_memory = TRUE;
  2180.         
  2181.         ptr = savedptr;
  2182.         while (ptr != NULL) 
  2183.         {
  2184.             savedptr = ptr->child;
  2185.             free(ptr);
  2186.             ptr = savedptr;
  2187.         }
  2188.         
  2189.         return;
  2190.         }
  2191.         
  2192.         ptr->child = ptr->sibling = NULL;
  2193.         ptr->ch = *(str++);
  2194.         ptr->value = NULL;
  2195.     }
  2196.     
  2197.     ptr->value = code;
  2198.     return;
  2199. }
  2200. //go.sysin dd *
  2201. exit
  2202.