home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / x / xvidoc.zoo / source.lst < prev    next >
File List  |  1992-07-28  |  56KB  |  1,519 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.                Notes on the Xvi Source Code
  11.  
  12.  
  13.                    Chris Downey
  14.                 John Downey
  15.  
  16.  
  17.  
  18.            Xvi (pronounced _e_c_k_s-_v_e_e-_e_y_e) is a free, portable,
  19.       multi-window implementation of the popular UNIX|- editor
  20.       vi.
  21.  
  22.       This document contains information on how to  port  xvi
  23.       to  systems  not currently supported.  It also explains
  24.       how the xvi source code is arranged into  modules,  and
  25.       explains some of the data structures which are used, so
  26.       that modifications may be made if and when necessary to
  27.       the editor itself.
  28.  
  29.  
  30.  
  31.      _1.  _I_N_T_R_O_D_U_C_T_I_O_N
  32.  
  33.      Xvi is intended to be portable to just about any system.  This is
  34.      one of the central reasons for its existence; the authors wish to
  35.      be able to use the same editor everywhere.
  36.  
  37.      The main body of  the  editor  is  (supposedly)  fully  portable,
  38.      relying  only  on  standard facilities defined by the White Book,
  39.      and on a set of _p_r_i_m_i_t_i_v_e_s which are provided by a set of one  or
  40.      more  modules for each operating system.  If ___S_T_D_C__ is defined,
  41.      certain ANSI C facilities will  be  used,  but  the  editor  will
  42.      compile with non-ANSI compilers.
  43.  
  44.      Therefore, in order to port xvi to a  new  system,  all  that  is
  45.      necessary  is  to provide the defined set of _p_r_i_m_i_t_i_v_e_s, and then
  46.      build the editor.  Or at least, that's the idea; we have  refined
  47.      the  set of primitives as we port the editor to new environments,
  48.      and it's getting pretty easy now.
  49.  
  50.      The rest of this document is divided into sections as follows:
  51.  
  52.      _S_e_c_t_i_o_n _2: _S_y_s_t_e_m-_S_p_e_c_i_f_i_c _M_o_d_u_l_e_s
  53.       This section deals with  the  layout  of  source  files  and
  54.       makefiles which you will have to deal with when porting xvi.
  55.  
  56.      _S_e_c_t_i_o_n _3: _P_r_i_m_i_t_i_v_e_s _P_r_o_v_i_d_e_d _b_y _x_v_i
  57.       Discusses what primitives are provided by the main  body  of
  58.       the editor source code for use by the system interface code.
  59.      _________________________
  60.      |- UNIX is a trademark of Bell Laboratories.
  61.  
  62.  
  63.  
  64.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _1
  65.  
  66.  
  67.  
  68.  
  69.  
  70.      _2                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  71.  
  72.  
  73.      _S_e_c_t_i_o_n _4: _S_y_s_t_e_m _I_n_t_e_r_f_a_c_e
  74.       Explains the primitives which need to be provided  in  order
  75.       to make xvi work.
  76.  
  77.      _S_e_c_t_i_o_n _5: _D_a_t_a _S_t_r_u_c_t_u_r_e_s
  78.       Details the internal data types used in the editor, and  any
  79.       functions available for operating on those types.
  80.  
  81.      _S_e_c_t_i_o_n _6: _S_o_u_r_c_e _F_i_l_e_s
  82.       Lists the source files comprising the editor,  and  explains
  83.       what functionality is provided by each one.
  84.  
  85.  
  86.  
  87.      _2.  _S_Y_S_T_E_M-_S_P_E_C_I_F_I_C _M_O_D_U_L_E_S
  88.  
  89.      The system-specific code normally consists  of  three  (or  more)
  90.      files; a ".c" file, a ".h" file, and a makefile.  For example:
  91.  
  92.          _q_n_x._c
  93.          _q_n_x._h
  94.          _m_a_k_e_f_i_l_e._q_n_x
  95.  
  96.      comprise the system-specific module for the QNX operating system.
  97.  
  98.      In most cases, the system-specific code is divided  into  two  or
  99.      more  modules,  where one (called the _s_y_s_t_e_m _i_n_t_e_r_f_a_c_e _m_o_d_u_l_e) is
  100.      concerned with general interactions with the operating system and
  101.      the  other (called the _t_e_r_m_i_n_a_l _i_n_t_e_r_f_a_c_e _m_o_d_u_l_e) is designed for
  102.      a specific interface to a display and keyboard (and  possibly,  a
  103.      mouse).
  104.  
  105.      For example, the  generic  UNIX  implementation  has  _u_n_i_x._c  and
  106.      _u_n_i_x._h  for  the  system  interface  module,  and  _t_e_r_m_c_a_p._c  and
  107.      _t_e_r_m_c_a_p._h for the terminal interface  module;  this  should  work
  108.      reasonably with any full-duplex terminal that can be described in
  109.      the _t_e_r_m_c_a_p database.  On consoles with  memory-mapped  displays,
  110.      or  systems  with  graphic  user  interfaces,  however, it may be
  111.      possible to achieve faster display updating,  and  perhaps  other
  112.      benefits,  by  replacing the _t_e_r_m_c_a_p module with another one that
  113.      makes better use  of  whatever  facilities  are  available.   For
  114.      instance,  there  is  an  experimental version for SunView, which
  115.      allows mouse input on Sun workstations running the SunView window
  116.      system.
  117.  
  118.      On  the  other  hand,   the   _t_e_r_m_c_a_p-specific   routines   might
  119.      conceivably  be  useful  on some other operating systems (such as
  120.      VMS), so in general it seemed a good idea to  make  the  _t_e_r_m_c_a_p-
  121.      specific routines a separate module.
  122.  
  123.      The  current  MS-DOS  implementation  has  a  separate   terminal
  124.      interface  module,  which  is  designed  specifically  for IBM PC
  125.      compatible computers.  This is in the files
  126.  
  127.  
  128.  
  129.  
  130.      _P_a_g_e _2                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  131.  
  132.  
  133.  
  134.  
  135.  
  136.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _3
  137.  
  138.  
  139.  
  140.          _i_b_m_p_c__a._a_s_m
  141.          _i_b_m_p_c__c._c
  142.          _i_b_m_p_c._h
  143.  
  144.      The first of these is written in assembly language because  there
  145.      are  not enough routines common to the various MS-DOS C compilers
  146.      which reliably access the display and keyboard at  a  low  enough
  147.      level.
  148.  
  149.      The hardware-independent system interface module for MS-DOS is in
  150.  
  151.          _m_s_d_o_s__a._a_s_m
  152.          _m_s_d_o_s__c._c
  153.          _m_s_d_o_s._h
  154.  
  155.      The first of these is written in assembly language for  the  same
  156.      reason as is _i_b_m_p_c__a._a_s_m.
  157.  
  158.      Theoretically, different  terminal  interface  modules  could  be
  159.      written  for MS-DOS systems running on hardware which is not IBM-
  160.      compatible but, unfortunately, such systems seem to be  virtually
  161.      extinct nowadays.
  162.  
  163.      Sometimes more than one makefile is provided, as in the  case  of
  164.      UNIX, where different versions work in slightly different ways.
  165.  
  166.      It is, of couse, not necessary to provide all - or any - of these
  167.      files for a particular implementation; this is just a convention.
  168.      The makefile(s) for each system determine what files are used  in
  169.      the compilation of the editor.
  170.  
  171.      The following porting modules are available at present:
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _3
  197.  
  198.  
  199.  
  200.  
  201.  
  202.      _4                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  203.  
  204.      ________________________________________________________________
  205.     |         System        |    Makefile  |       Source Files     |
  206.     |________________________|_______________|_________________________|
  207.     | UNIX                  |              |                        |
  208.     |   BSD                 |  makefile.bsd|  unix.[ch] termcap.[ch]|
  209.     |   System V |-          |  makefile.usg|  unix.[ch] termcap.[ch]|
  210.     |   AIX                 |  makefile.aix|  unix.[ch] termcap.[ch]|
  211.     |   ULTRIX              |  makefile.ult|  unix.[ch] termcap.[ch]|
  212.     |   Xenix |-             |  makefile.xen|  unix.[ch] termcap.[ch]|
  213.     |   POSIX (e.g. BSDI)   |  makefile.pos|  unix.[ch] termcap.[ch]|
  214.     |   SunOS               |  makefile.sun|  unix.[ch] termcap.[ch]|
  215.     |   SunView             |  makefile.sv |  unix.[ch] sunview.h   |
  216.     |                       |              |  sunfront.c sunback.c  |
  217.     |                       |              |  xvi.icn               |
  218.     |________________________|_______________|_________________________|
  219.     |                       |              |                        |
  220.     | MS-DOS                |              |  msdos_c.c msdos.h     |
  221.     |                       |              |  ibmpc_c.c ibmpc.h     |
  222.     |   Microsoft C 5.*     |  makefile.msc|  8086mm.inc ibmpc_a.asm|
  223.     |   & MASM 5.*          |              |  msdos_a.asm           |
  224.     |                       |              |                        |
  225.     |   Microsoft Quick C   |  makefile.qc |  8086mm.inc ibmpc_a.asm|
  226.     |   & MASM 5.*          |              |  msdos_a.asm           |
  227.     |   Zortech C++ 2.*     |  makefile.zc2|  8086mm.inc ibmpc_a.asm|
  228.     |   & MASM 5.*          |              |  msdos_a.asm           |
  229.     |                       |              |                        |
  230.     |   Zortech C++ 3.*     |  makefile.zc3|  8086mm.inc ibmpc_a.asm|
  231.     |   & MASM 5.*          |              |  msdos_a.asm           |
  232.     |   Zortech C++ 3.*     |              |                        |
  233.     |   386 protected mode  |  makefile.386|  pc386.[ch]            |
  234.     |________________________|_______________|_________________________|
  235.     |                       |              |                        |
  236.     | OS/2 |-                |              |                        |
  237.     |   Version 1, text mode|              |                        |
  238.     |   Microsoft C 5.1     |  makefile.os2|  os2vio.[ch]           |
  239.     |   & MASM 5.1          |              |  i286.asm              |
  240.     |________________________|_______________|_________________________|
  241.     | QNX                   |              |                        |
  242.     |   Version 2/3 (CII)   |  makefile.qnx|  qnx.[ch]              |
  243.     |   Version 4 (Watcom C)|  makefile.qn4|  unix.[ch] termcap.[ch]|
  244.     |________________________|_______________|_________________________|
  245.     |                       |              |                        |
  246.     | TOS |-                 |              |                        |
  247.     |   Lattice C           |  makefile.tos|  tos.[ch] tos.lnk      |
  248.     |________________________|_______________|_________________________|
  249.  
  250.  
  251.      |- Versions marked with |- probably do not work,  as  systems  have
  252.        not been recently available to the authors for testing.
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.      _P_a_g_e _4                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  263.  
  264.  
  265.  
  266.  
  267.  
  268.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _5
  269.  
  270.  
  271.      _3.  _P_R_I_M_I_T_I_V_E_S _P_R_O_V_I_D_E_D _B_Y _X_V_I
  272.  
  273.      _3._1.  _G_e_n_e_r_a_l _D_e_f_i_n_i_t_i_o_n_s
  274.  
  275.      The file _x_v_i._h should be included by all system-specific modules;
  276.      this  file should also be edited so that a system-specific header
  277.      file (or files), as determined by a predefined keyword,  will  be
  278.      included.
  279.  
  280.      For instance, under UNIX, the word _U_N_I_X is defined by passing the
  281.      -_D_U_N_I_X  flag  to  the  C  compiler  from  the makefile, and _x_v_i._h
  282.      contains the following lines:
  283.  
  284.          #_i_f_d_e_f _U_N_I_X
  285.          #   _i_n_c_l_u_d_e "_u_n_i_x._h"
  286.          #_e_n_d_i_f
  287.  
  288.      in order to obtain the UNIX-related definitions from that  header
  289.      file.
  290.  
  291.      Among the definitions in _x_v_i._h are the following:
  292.  
  293.      bool_t
  294.       A Boolean type having values _T_R_U_E or _F_A_L_S_E.
  295.  
  296.      const
  297.      volatile
  298.       These are defined out when ___S_T_D_C__ is not defined, so  that
  299.       it is always safe to use them.
  300.  
  301.      _x_v_i._h also includes various other header files which are  needed.
  302.      The following system header files are always included:
  303.  
  304.          _s_t_d_i_o._h
  305.          _c_t_y_p_e._h
  306.          _s_i_g_n_a_l._h
  307.          _s_t_r_i_n_g._h
  308.  
  309.      These files are included if ___S_T_D_C__ is defined:
  310.  
  311.          _s_t_d_d_e_f._h
  312.          _s_t_d_l_i_b._h
  313.          _l_i_m_i_t_s._h
  314.  
  315.      and if ___S_T_D_C__ is  not  defined,  _x_v_i._h  will  provide  its  own
  316.      definitions for the following:
  317.  
  318.          _I_N_T__M_A_X
  319.          _I_N_T__M_I_N
  320.          _U_L_O_N_G__M_A_X
  321.  
  322.          _F_I_L_E    *_f_o_p_e_n();
  323.          _c_h_a_r    *_m_a_l_l_o_c();
  324.          _c_h_a_r    *_g_e_t_e_n_v();
  325.  
  326.  
  327.  
  328.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _5
  329.  
  330.  
  331.  
  332.  
  333.  
  334.      _6                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  335.  
  336.  
  337.      Finally, one of the following header files will be included:
  338.  
  339.          _s_t_d_a_r_g._h
  340.          _v_a_r_a_r_g_s._h
  341.  
  342.      depending on whether ___S_T_D_C__ is defined or  not.   In  order  to
  343.      make  coding  of  _v_a_r_a_r_g_s functions easier, a macro _V_A__S_T_A_R_T() is
  344.      defined,  which  takes  the  same  arguments  as  the  ANSI-style
  345.      _v_a__s_t_a_r_t(),  but which is also available in non-ANSI environments
  346.      (e.g. BSD).
  347.  
  348.      In order to make it possible to  use  ANSI-style  prototypes  for
  349.      function declarations, but still allow compilation under non-ANSI
  350.      environments, the following macro is provided:
  351.  
  352.          #_i_f_d_e_f ___S_T_D_C__
  353.          #   _d_e_f_i_n_e  _P(_a_r_g_s) _a_r_g_s
  354.          #_e_l_s_e
  355.          #   _d_e_f_i_n_e  _P()     ()
  356.          #_e_n_d_i_f
  357.  
  358.      so that function declarations may be specified thus:
  359.  
  360.          _e_x_t_e_r_n _F_I_L_E *_f_o_p_e_n _P((_c_o_n_s_t _c_h_a_r *, _c_o_n_s_t _c_h_a_r *));
  361.  
  362.      Please use this facility when you provide declarations  for  your
  363.      system  primitives,  unless  your  system  always  uses  an  ANSI
  364.      compiler.
  365.  
  366.      _3._2.  _P_a_r_a_m_e_t_e_r_s
  367.  
  368.      An important facility provided for use by system-specific modules
  369.      is  access  to the editor's parameter table.  This is achieved by
  370.      means of some apparent functions, and a  set  of  #_d_e_f_i_n_ed  token
  371.      values.  The functions are:
  372.  
  373.      void set_param(int n, val)
  374.       This function sets the indicated  parameter  to  the  passed
  375.       value,  which  must  be  of  an appropriate type.  Parameter
  376.       values may be obtained by means of the  following  functions
  377.       (actually macros):
  378.  
  379.      char *Ps(int n)
  380.       return value of string parameter
  381.  
  382.      int Pn(int n)
  383.       return value of numeric parameter
  384.  
  385.      bool_t Pb(int n)
  386.       return value of boolean parameter
  387.  
  388.      char **Pl(int n)
  389.       return value of list parameter (a NULL-terminated  array  of
  390.       character pointers)
  391.  
  392.  
  393.  
  394.      _P_a_g_e _6                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  395.  
  396.  
  397.  
  398.  
  399.  
  400.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _7
  401.  
  402.  
  403.      int Pen(int n)
  404.       return numeric value (index) of enumerated parameter
  405.  
  406.      char **Pes(int n)
  407.       return string value of enumerated parameter
  408.  
  409.      In all cases, the int n argument is the index of the parameter in
  410.      the table; a set of #_d_e_f_i_n_es is provided, of the form:
  411.  
  412.          _P__n_a_m_e
  413.  
  414.      which map the parameter names into integral  values.   Thus,  for
  415.      example, we might obtain the value of the _c_o_l_o_u_r parameter:
  416.  
  417.          _c_o_l_o_u_r = _P_n(_P__c_o_l_o_u_r);
  418.  
  419.      or set the value of the _h_e_l_p_f_i_l_e parameter:
  420.  
  421.          _s_e_t__p_a_r_a_m(_P__h_e_l_p_f_i_l_e, "/_u_s_r/_l_i_b/_x_v_i/_h_e_l_p");
  422.  
  423.  
  424.  
  425.  
  426.      _4.  _S_Y_S_T_E_M _I_N_T_E_R_F_A_C_E
  427.  
  428.      _4._1.  _I_n_t_r_o_d_u_c_t_i_o_n
  429.  
  430.      There follows a list of the primitives  which  must  be  provided
  431.      either  by  the  system interface module or by the underlying OS.
  432.      Note that it is perfectly acceptable to  implement  functions  or
  433.      external  variables  as macros so long as they "look the same" as
  434.      the definitions below.  As a guideline, anything which is (a)  in
  435.      capitals,  or  (b)  is a const variable, will be implemented as a
  436.      #_d_e_f_i_n_e for most systems.
  437.  
  438.      When you want to actually do the port, it is  highly  recommended
  439.      that  you  copy  the  system-specific  files for the system which
  440.      seems closest to your own, and modify those  files,  rather  than
  441.      starting from scratch.
  442.  
  443.      All the  following  symbols  should  be  defined  in  the  system
  444.      interface module, or by standard header files already included by
  445.      _x_v_i._h, or by  other  header  files  explicitly  included  by  the
  446.      system-specific header file:
  447.  
  448.      const unsigned int MAXPATHLEN
  449.       The maximum number of characters in a pathname.
  450.  
  451.      const unsigned int MAXNAMLEN
  452.       The maximum number of characters in a filename.
  453.  
  454.      int remove(char *filename)
  455.       Remove the named file as per ANSI.
  456.  
  457.  
  458.  
  459.  
  460.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _7
  461.  
  462.  
  463.  
  464.  
  465.  
  466.      _8                                           _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  467.  
  468.  
  469.      int rename(char *old, char *new)
  470.       Rename the file old to new as per ANSI.
  471.  
  472.      void sleep(unsigned int seconds)
  473.       Put the process to sleep for the given number of seconds.
  474.  
  475.      const char * const DIRSEPS
  476.       The pathname separators supported  for  system  calls  (e.g.
  477.       "\\/" for MS-DOS).
  478.  
  479.      FILE *fopenrb(char *file)
  480.      FILE *fopenwb(char *file)
  481.       Like the standard _f_o_p_e_n() library call, but they  both  open
  482.       files  in "binary" mode (i.e. no conversion of cr/lf/crlf is
  483.       done), for reading and writing respectively.
  484.  
  485.      bool_t exists(char *filename)
  486.       Returns _T_R_U_E if the named file exists.
  487.  
  488.      bool_t can_write(char *filename)
  489.       Returns _T_R_U_E if the named file can be  written,  i.e.  if  a
  490.       fopenwb(filename) will succeed.
  491.  
  492.      char *fexpand(char *filename)
  493.       Returns a filename-expanded version of the passed filename.
  494.  
  495.      #define SETVBUF_AVAIL
  496.  
  497.      const unsigned int READBUFSIZ
  498.      const unsigned int WRTBUFSIZ
  499.       If _S_E_T_V_B_U_F__A_V_A_I_L (or ___S_T_D_C__) is  defined,  these  constant
  500.       values are used to set I/O buffer sizes (using the setvbuf()
  501.       function) for reading  and  writing  files.   Note  that  if
  502.       buffers  of  these  sizes  are  unavailable  at runtime, the
  503.       editor will try to allocate smaller buffers  by  iteratively
  504.       halving  the  buffer size until the allocation succeeds.  It
  505.       is therefore acceptable for these values to be quite large.
  506.  
  507.      char *tempfname(const char *filename)
  508.       Create a unique name for a temporary  file,  possibly  using
  509.       filename  as  a  base (this will be used by _d_o__p_r_e_s_e_r_v_e() to
  510.       create a backup file for the file named by  _f_i_l_e_n_a_m_e).   The
  511.       string  returned  must  have  been allocated using _m_a_l_l_o_c();
  512.       _N_U_L_L can be returned if there is no more memory available.
  513.  
  514.      int call_system(char *command)
  515.       Invoke the given command in a subshell.  This  is  used  for
  516.       shell  escapes  from  xvi.   The  command string may contain
  517.       metacharacters which  are  expected  to  be  expanded  by  a
  518.       command interpreter, e.g.  UNIX /_b_i_n/_s_h, MS-DOS _c_o_m_m_a_n_d._c_o_m.
  519.       Return value is 0 for success.  In many  environments,  this
  520.       call may safely be #_d_e_f_i_n_ed as _s_y_s_t_e_m(_c_o_m_m_a_n_d).
  521.  
  522.  
  523.  
  524.  
  525.  
  526.      _P_a_g_e _8                                        _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  527.  
  528.  
  529.  
  530.  
  531.  
  532.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                           _9
  533.  
  534.  
  535.      int call_shell(char *shell)
  536.       Invoke the  named  shell.   This  is  used  for  the  :_s_h_e_l_l
  537.       command.   It  may  be  mapped  into  _c_a_l_l__s_y_s_t_e_m(),  but is
  538.       separate on some systems for efficiency  reasons  (i.e.  not
  539.       invoking  two  shells  to  get  one).  Return value is 0 for
  540.       success.
  541.  
  542.      bool_t
  543.      sys_pipe(char *cmd, int (*wf)(FILE *), long (*rf)(FILE *))
  544.       Used for the !  command.  The first parameter is the command
  545.       to  invoke,  while  the second and third are functions which
  546.       should be called with an open file pointer in order to write
  547.       out  old, or read in new lines (respectively).  Note that if
  548.       "real"  pipes  are  not  available,  it  is  acceptable   to
  549.       implement  this  function  using temporary files, but the wf
  550.       function must obviously be called before rf.
  551.  
  552.      void sys_exit(int code)
  553.       Exit with given exit status.  This routine must not  return.
  554.       The editor is considered "dead" once it has been called, and
  555.       no further calls to editor functions should be made.
  556.  
  557.      void delay(void)
  558.       Delay for a short time, about a fifth of a second.  This  is
  559.       used  for  showing  matching brackets when showmatch is set.
  560.       It is acceptable to just return if implementing this is  not
  561.       easy.
  562.  
  563.      _4._2.  _S_c_r_e_e_n _C_o_n_t_r_o_l
  564.  
  565.      An instance of the following structure must be defined  in  order
  566.      to allow screen output to take place:
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                        _P_a_g_e _9
  593.  
  594.  
  595.  
  596.  
  597.  
  598.      _1_0                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  599.  
  600.  
  601.  
  602.        _t_y_p_e_d_e_f _s_t_r_u_c_t _v_i_r_t_s_c_r {
  603.      _g_e_n_p_t_r   *_p_v__w_i_n_d_o_w;
  604.      _i_n_t      _p_v__r_o_w_s;
  605.      _i_n_t      _p_v__c_o_l_s;
  606.      /* _p_u_b_l_i_c: */
  607.      _V_i_r_t_S_c_r  *(*_v__n_e_w)(_V_i_r_t_S_c_r *);
  608.      _v_o_i_d     (*_v__c_l_o_s_e)(_V_i_r_t_S_c_r *);
  609.  
  610.      _i_n_t      (*_v__r_o_w_s)(_V_i_r_t_S_c_r *);
  611.      _i_n_t      (*_v__c_o_l_s)(_V_i_r_t_S_c_r *);
  612.  
  613.      _v_o_i_d     (*_v__c_l_e_a_r__a_l_l)(_V_i_r_t_S_c_r *);
  614.      _v_o_i_d     (*_v__c_l_e_a_r__l_i_n_e)(_V_i_r_t_S_c_r *);
  615.  
  616.      _v_o_i_d     (*_v__g_o_t_o)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l);
  617.      _v_o_i_d     (*_v__a_d_v_i_s_e)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l,
  618.                    _i_n_t _i_n_d_e_x, _c_h_a_r *_s_t_r);
  619.  
  620.      _v_o_i_d     (*_v__w_r_i_t_e)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l, _c_h_a_r *_s_t_r);
  621.      _v_o_i_d     (*_v__p_u_t_c)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l, _i_n_t _c_h);
  622.  
  623.      _v_o_i_d     (*_v__s_e_t__c_o_l_o_u_r)(_V_i_r_t_S_c_r *, _i_n_t _c_o_l_o_u_r);
  624.      _i_n_t      (*_v__c_o_l_o_u_r__c_o_s_t)(_V_i_r_t_S_c_r *);
  625.  
  626.      _v_o_i_d     (*_v__f_l_u_s_h)(_V_i_r_t_S_c_r *);
  627.  
  628.      _v_o_i_d     (*_v__b_e_e_p)(_V_i_r_t_S_c_r *);
  629.  
  630.      /* _o_p_t_i_o_n_a_l: _n_o_t _u_s_e_d _i_f _N_U_L_L */
  631.      _v_o_i_d     (*_v__i_n_s_e_r_t)(_V_i_r_t_S_c_r *, _i_n_t _r_o_w, _i_n_t _c_o_l, _c_h_a_r *_s_t_r);
  632.  
  633.      _i_n_t      (*_v__s_c_r_o_l_l)(_V_i_r_t_S_c_r *, _i_n_t _s_t_a_r_t, _i_n_t _e_n_d, _i_n_t _n_l_i_n_e_s);
  634.        } _V_i_r_t_S_c_r;
  635.  
  636.  
  637.      The first three fields in this structure are "private",  for  use
  638.      only  within  the  implementation of the "public" functions.  The
  639.      remaining fields are all function  pointers,  and  are  described
  640.      below.   Note  that  all  functions  have at least one parameter,
  641.      which is a pointer to the instance of the  VirtScr  in  question.
  642.      This  is always referred to as vs below.  Note also that the top-
  643.      left-hand corner of the window is taken to be (0,0).
  644.  
  645.      v_new(vs)
  646.       Obtain a new VirtScr, and return a pointer to it.   This  is
  647.       not used at present, and should return _N_U_L_L.
  648.  
  649.      v_close(vs)
  650.       Close the window to which vs refers.
  651.  
  652.      v_rows(vs)
  653.       Return the number of rows in vs.
  654.  
  655.  
  656.  
  657.  
  658.      _P_a_g_e _1_0                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  659.  
  660.  
  661.  
  662.  
  663.  
  664.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_1
  665.  
  666.  
  667.      v_cols(vs)
  668.       Return the number of columns in vs.
  669.  
  670.      v_clear_all(vs)
  671.       Clear the window completely.
  672.  
  673.      v_clear_line(vs, int row, int col)
  674.       Clear the specified line, from the given column to the right
  675.       hand edge of the window, inclusive.
  676.  
  677.      v_goto(vs, int row, int col)
  678.       Move the cursor to the specified row and column.
  679.  
  680.      v_advise(vs, int row, int col, int index, char *str)
  681.       This function is called when the editor is about to  produce
  682.       some  output  on  the  same  line  as  the  last output, but
  683.       separate from it by one or more characters.  The destination
  684.       position  is the coordinate pair (row, col + index), and str
  685.       contains the string of characters which are  in  the  window
  686.       starting  at  position  (row,  col).   Where there is a cost
  687.       incurred by moving the cursor to a specific screen position,
  688.       the  terminal  interface  module  may  decide  to  write the
  689.       intervening characters to the screen  rather  than  using  a
  690.       specific  "move  cursor"  sequence, in order to minimise the
  691.       number of characters written to the terminal.
  692.  
  693.       Note that for many environments, the cost of  re-positioning
  694.       the  cursor  is  nil,  and  under  these  circumstances this
  695.       function need not do anything.
  696.  
  697.      v_write(vs, int row, int col, char *str)
  698.       Write the specified string of characters  into  the  window,
  699.       starting  at  the  specified row and column.  The parameters
  700.       will be such that the string will always fit into  a  single
  701.       line  of  the  window,  i.e.  no line-wrapping is necessary;
  702.       however, it is quite possible for the string to end  on  the
  703.       last character of a line, and some implementations will need
  704.       to take special precautions to handle this correctly.
  705.  
  706.      v_putc(vs, int row, int col, int ch)
  707.       This is like v_write but for a single character.
  708.  
  709.      v_set_colour(vs, int colour)
  710.       Set the colour for all subsequent output (including clearing
  711.       of  lines or the whole window) to the specified colour.  The
  712.       meaning of the value is system-specific.
  713.  
  714.      v_colour_cost(vs)
  715.       Return the number of extra characters which are taken up  in
  716.       the window by a colour change.  This is almost always 0, but
  717.       there exist some terminals for which it is not (see the "sg"
  718.       _t_e_r_m_c_a_p capability).
  719.  
  720.  
  721.  
  722.  
  723.  
  724.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_1
  725.  
  726.  
  727.  
  728.  
  729.  
  730.      _1_2                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  731.  
  732.  
  733.      v_flush(vs)
  734.       Flush all screen output, and move the cursor on  the  screen
  735.       to  the  correct  position.  The screen need not actually be
  736.       updated  until  either   this   function   is   called,   or
  737.       xvi_handle_event() returns.
  738.  
  739.      v_beep(vs)
  740.       Beep.  It is acceptable to flash the screen or window if  no
  741.       audio facility is available.
  742.  
  743.      v_insert(vs, int row, int col, char *str)
  744.       This  function  inserts  the  given  string  at  the   given
  745.       position,  pushing  any  other characters on the same row to
  746.       the right.   If  such  a  facility  is  not  available,  the
  747.       function pointer should be set to _N_U_L_L.
  748.  
  749.      v_scroll(vs, int start, int end, int nlines)
  750.       This function scrolls the set of lines between start and end
  751.       (inclusive)  by nlines lines.  If nlines is positive, _n_o_r_m_a_l
  752.       scrolling should be done, i.e. the  lines  should  be  moved
  753.       upwards  with respect to the window.  If nlines is negative,
  754.       scrolling should be in the  reverse  direction.   The  lines
  755.       which  are  left  by  the  scrolling should be cleared.  The
  756.       function  should  return  non-zero  if  the  scrolling   was
  757.       successful, otherwise 0.
  758.  
  759.       If scrolling is not available, the function  pointer  should
  760.       be set to _N_U_L_L.
  761.  
  762.      _4._3.  _P_a_r_a_m_e_t_e_r_s
  763.  
  764.      Default values should  be  #_d_e_f_i_n_ed  for  certain  parameters  as
  765.      follows:
  766.         __________________________________________
  767.            | Parameter Name|   Type  |  #define name |
  768.            |________________|__________|________________|
  769.            | syscolour     |  numeric|  DEF_SYSCOLOUR|
  770.            | colour        |  numeric|  DEF_COLOUR   |
  771.            | statuscolour  |  numeric|  DEF_STCOLOUR |
  772.            | roscolour     |  numeric|  DEF_ROSCOLOUR|
  773.            | helpfile      |  string |  HELPFILE     |
  774.            |_f_o_r_m_a_t__________|__s_t_r_i_n_g___|__D_E_F___T_F_F________|
  775.  
  776.  
  777.      _4._4.  _F_i_l_e _F_o_r_m_a_t_s
  778.  
  779.      The functions in xvi which read and write text files are aware of
  780.      several different newline conventions (for example, "\n" on UNIX,
  781.      "\r\n" on MS-DOS, and so on), so that any version of  the  editor
  782.      can  read  and  write any of the supported formats.  The value of
  783.      the format parameter  (which  can  be  set  to  "unix",  "msdos",
  784.      "macintosh",  etc.)  determines  which  format is currently being
  785.      used.  If you  are  porting  xvi  to  a  system  with  a  newline
  786.      convention  which isn't one of those currently supported (see the
  787.      table called _t_f_t_a_b_l_e in _f_i_l_e_i_o._c) you may have to add a new entry
  788.  
  789.  
  790.      _P_a_g_e _1_2                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  791.  
  792.  
  793.  
  794.  
  795.  
  796.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_3
  797.  
  798.  
  799.      to the table.
  800.  
  801.      Unfortunately, the current design is not as general as  it  ought
  802.      to  be.  If you happen to be porting to VMS, or some other system
  803.      which doesn't use either a single character or a consecutive pair
  804.      of  characters  to represent a newline, you will have quite a lot
  805.      of work to do if you want to retain the facility  for  converting
  806.      between file formats within the editor.
  807.  
  808.      In any case, your system interface module should  define  _D_E_F__T_F_F
  809.      to  be  the  index  of  the entry in tftable which represents the
  810.      default  format  for  your  system.   This  is  the   value   for
  811.      _P_e_n(_P__f_o_r_m_a_t) which will be compiled into the parameter table.
  812.  
  813.      _4._5.  _N_o_t_e_s _o_n _T_e_r_m_c_a_p _I_m_p_l_e_m_e_n_t_a_t_i_o_n
  814.  
  815.      There exists a termcap implementation of the terminal  interface,
  816.      currently  only  used for the UNIX port.  This module could quite
  817.      easily be re-used for other systems  if  desired;  the  following
  818.      routines would need to be defined by the system module:
  819.  
  820.      void foutch(int c)
  821.       Output a single character to the  terminal.   This  must  be
  822.       implemented as a function, not a macro, because it is passed
  823.       as a parameter into the _t_e_r_m_c_a_p library.
  824.  
  825.      void moutch(int c)
  826.       Same as _f_o_u_t_c_h() except that it  can  be  implemented  as  a
  827.       macro.  This will be used by the _t_e_r_m_c_a_p interface module to
  828.       write characters to the screen.
  829.  
  830.      void oflush(void)
  831.       Flush buffered output to the terminal.
  832.  
  833.      _4._6.  _E_n_t_e_r_i_n_g/_L_e_a_v_i_n_g _V_i_s_u_a_l _M_o_d_e
  834.  
  835.      Some facility is commonly  necessary  for  the  system  interface
  836.      module  to be able to tell the terminal interface module to enter
  837.      or exit _v_i_s_u_a_l mode.  This might mean changing the terminal state
  838.      between "raw" and "cooked" modes, or switching display pages.  No
  839.      specific interface for this is  defined,  although  the  standard
  840.      UNIX  and  MS-DOS implementations do use such a facility, and the
  841.      interface functions for both systems are identically defined.
  842.  
  843.      _4._7.  _F_u_n_c_t_i_o_n _K_e_y_s/_M_o_u_s_e _H_a_n_d_l_i_n_g
  844.  
  845.      Function key values are coded into a set of #_d_e_f_i_n_ed constants in
  846.      the file _a_s_c_i_i._h; e.g. the value _K__U_A_R_R_O_W might be given as input
  847.      when the keyboard up-arrow key has been pressed.
  848.  
  849.      If the global variable _S_t_a_t_e is not equal to _N_O_R_M_A_L, all function
  850.      keys except for a backspace key are invalid input.  If an invalid
  851.      key is pressed, the safest strategy may be to beep and  wait  for
  852.      another key to be pressed.  _N_O_R_M_A_L is defined in _x_v_i._h.
  853.  
  854.  
  855.  
  856.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_3
  857.  
  858.  
  859.  
  860.  
  861.  
  862.      _1_4                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  863.  
  864.  
  865.      Another facility which may be provided is handling mouse input on
  866.      systems  where  it  is  available.  The strategy for interpreting
  867.      mouse input  is  controlled  by  the  _m_o_u_s_e_c_l_i_c_k()  function  (in
  868.      _m_o_u_s_e._c);  the  idea  is  to make the strategy independent of any
  869.      specific device interface.  If a mouse button is pressed before a
  870.      keyboard key is pressed, the following routine should be called:
  871.  
  872.          _m_o_u_s_e_c_l_i_c_k(_i_n_t _r_o_w, _i_n_t _c_o_l_u_m_n);
  873.  
  874.      where row and column are the  current  co-ordinates,  counted  in
  875.      character  positions,  of  the mouse pointer within the screen or
  876.      editing window.  If the mouse is moved while  a  button  is  held
  877.      down, the routine
  878.  
  879.          _m_o_u_s_e_d_r_a_g(_i_n_t _s_t_a_r_t_r_o_w, _i_n_t _e_n_d_r_o_w, _i_n_t _s_t_a_r_t_c_o_l_u_m_n, _i_n_t _e_n_d_c_o_l_u_m_n);
  880.  
  881.      should be called with co-ordinates describing the  movement.   If
  882.      the global variable _S_t_a_t_e is not equal to _N_O_R_M_A_L, mouse input can
  883.      be ignored altogether.
  884.  
  885.      All this will be considerably tidied up at a later stage, when we
  886.      have proper _x_v_E_v_e_n_t types for function keys and mouse actions.
  887.  
  888.      _4._8.  _M_a_i_n
  889.  
  890.      Finally, the  system  interface  module  must  provide  a  main()
  891.      function.   This  function  must call xvi_startup(vs, argc, argv,
  892.      env) at startup, with parameters as follows:
  893.  
  894.      VirstScr *vs;
  895.       This is a pointer to the VirtScr  structure  for  the  first
  896.       window, or for the terminal screen.
  897.  
  898.      int argc, char **argv;
  899.       These are as for a main() function.
  900.  
  901.      char *env;
  902.       This is an environment string,  normally  the  return  value
  903.       from   getenv("XVINIT").   If  the  concept  of  environment
  904.       variables  does  not   exist,   a   string   of   the   form
  905.       "source _f_i_l_e_n_a_m_e"  may  be  passed  instead,  so as to allow
  906.       users to localise their usage of the editor.
  907.  
  908.      The return value from xvi_startup() is a pointer, which  will  be
  909.      used in future to identify the window for input events.  For now,
  910.      it should be stored in the VirtScr's pv_window field.
  911.  
  912.      Having called xvi_startup(), input events may then be  passed  to
  913.      the  editor  by  calling  xvi_handle_event  with  a pointer to an
  914.      xvEvent structure  as  the  sole  argument.   This  structure  is
  915.      defined as follows:
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.      _P_a_g_e _1_4                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  923.  
  924.  
  925.  
  926.  
  927.  
  928.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_5
  929.  
  930.  
  931.  
  932.          _t_y_p_e_d_e_f _s_t_r_u_c_t _e_v_e_n_t {
  933.          _e_n_u_m {
  934.              _E_v__c_h_a_r,
  935.              _E_v__t_i_m_e_o_u_t
  936.          }                   _e_v__t_y_p_e;
  937.          _u_n_i_o_n {
  938.              /* _E_v__c_h_a_r: */
  939.              _i_n_t _e_v_u__i_n_c_h_a_r;
  940.  
  941.              /* _E_v__t_i_m_e_o_u_t: */
  942.          }                   _e_v__u;
  943.          } _x_v_E_v_e_n_t;
  944.  
  945.          #_d_e_f_i_n_e _e_v__i_n_c_h_a_r       _e_v__u._e_v_u__i_n_c_h_a_r
  946.  
  947.  
  948.      The ev_type field is a tag which identifies  the  type  of  event
  949.      which  has  occurred.  At present, only two events are supported:
  950.      an input character from the user, and a timeout.  The union which
  951.      follows  contains data associated with each event type; currently
  952.      only the type Ev_char requires data, as may be seen.  The #_d_e_f_i_n_e
  953.      for ev_inchar is provided purely for convenience.
  954.  
  955.      The return value from xvi_handle_event() is a long integer  value
  956.      which  is  the  time  in  milliseconds  for  which  the editor is
  957.      prepared to wait for more input.  If no input arrives within that
  958.      time,  the  function should be called again with an event of type
  959.      Ev_timeout.  The timeout value returned  may  be  0L,  indicating
  960.      that no timeout is necessary.  It is very important that timeouts
  961.      should actually be implemented because they are  needed  for  the
  962.      _p_r_e_s_e_r_v_e facility.
  963.  
  964.      Currently,    if    a    keyboard    interrupt    is    received,
  965.      _x_v_i__h_a_n_d_l_e__e_v_e_n_t()  need  not  be called (it should, in any case,
  966.      never be called from an asynchronous interrupt or signal handler)
  967.      but  the  global  variable  _k_b_d_i_n_t_r  should  be set to a non-zero
  968.      value.
  969.  
  970.  
  971.  
  972.      _5.  _D_A_T_A _S_T_R_U_C_T_U_R_E_S
  973.  
  974.      Structures used in xvi are all typedef'd, and all  begin  with  a
  975.      capital  letter.   They are defined in _x_v_i._h.  The following data
  976.      structures are defined:
  977.  
  978.      _5._1.  _L_i_n_e
  979.  
  980.      This structure is used to hold a single text line.   It  contains
  981.      forward  and  backward  pointers  which are connected together to
  982.      form a two-way linked list.  It also contains  a  pointer  to  an
  983.      allocated  text  buffer, an integer recording the number of bytes
  984.      allocated for the text, and the line number (an  unsigned  long).
  985.      The  text  is null-terminated, and the space allocated for it may
  986.  
  987.  
  988.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_5
  989.  
  990.  
  991.  
  992.  
  993.  
  994.      _1_6                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  995.  
  996.  
  997.      be grown but is never shrunk.  The maximum size of this space  is
  998.      given by _M_A_X__L_I_N_E__L_E_N_G_T_H.
  999.  
  1000.      The line number is used when showing line numbers on screen,  but
  1001.      this is secondary to its main purpose of providing an ordering on
  1002.      lines; the ordering of two lines in a list may be established  by
  1003.      simply  comparing  their  line  numbers (macros are available for
  1004.      this purpose; see later for details).
  1005.  
  1006.      _5._2.  _B_u_f_f_e_r
  1007.  
  1008.      This structure holds the internal representation of a  file.   It
  1009.      contains  pointers to the linked list of lines which comprise the
  1010.      actual text.  We always allocate an extra line at  the  beginning
  1011.      and  the end, with line numbers 0 and _M_A_X__L_I_N_E_N_O respectively, in
  1012.      order to make the code which deals with  this  structure  easier.
  1013.      The  line  numbers  of  Line  structures  in  a Buffer are always
  1014.      maintained by code in undo.c, which is the only module which ever
  1015.      changes the text of a Buffer.
  1016.  
  1017.      The Buffer structure also contains:
  1018.  
  1019.      o+    flags, including readonly and modified
  1020.  
  1021.      o+    current filename associated with the buffer
  1022.  
  1023.      o+    temporary filename for buffer preservation
  1024.  
  1025.      o+    space for the _m_a_r_k module to store information about  marked
  1026.       lines
  1027.  
  1028.      o+    space for the _u_n_d_o module to  store  information  about  the
  1029.       last change
  1030.  
  1031.      o+    number of windows associated with the buffer
  1032.  
  1033.      The following macros are used to  find  out  certain  information
  1034.      about Lines within Buffers:
  1035.  
  1036.      lineno(Buffer *b, Line *l)
  1037.       Returns the line number of the specified Line, which belongs
  1038.       to the specified Buffer.
  1039.  
  1040.      earlier(Line *l1, Line *l2)
  1041.       Returns _T_R_U_E if l1 is earlier in the buffer than l2.
  1042.  
  1043.      later(Line *l1, Line *l2)
  1044.       Returns _T_R_U_E if l1 is later in the buffer than l2.
  1045.  
  1046.      is_lastline(Line *l1)
  1047.       Returns _T_R_U_E if l1 is the last line (i.e. the extra line  at
  1048.       the end, not the last text line) of the buffer.
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.      _P_a_g_e _1_6                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_7
  1061.  
  1062.  
  1063.      is_line0(Line *l1)
  1064.       Returns _T_R_U_E if l1 is the 0th line (i.e. the extra  line  at
  1065.       the start, not the first text line) of the buffer.
  1066.  
  1067.      _5._3.  _P_o_s_n
  1068.  
  1069.      This structure is very simple; it contains a Line pointer and  an
  1070.      integer  index  into  the  line's  text,  and is used to record a
  1071.      position within a buffer, e.g. the current cursor position.
  1072.  
  1073.      These functions are available for operating on Posn structures:
  1074.  
  1075.      gchar(Posn *)
  1076.       Returns the character which is at the given position.
  1077.  
  1078.      inc(Posn *)
  1079.       Increments the given position, moving  past  end-of-line  to
  1080.       the next line if necessary.  The following type is returned:
  1081.  
  1082.         _e_n_u_m _m_v_t_y_p_e {
  1083.         _m_v__N_O_M_O_V_E,    /* _a_t _b_e_g_i_n_n_i_n_g _o_r _e_n_d _o_f _b_u_f_f_e_r */
  1084.         _m_v__S_A_M_E_L_I_N_E,  /* _s_t_i_l_l _w_i_t_h_i_n _s_a_m_e _l_i_n_e */
  1085.         _m_v__C_H_L_I_N_E,    /* _c_h_a_n_g_e_d _t_o _d_i_f_f_e_r_e_n_t _l_i_n_e */
  1086.         _m_v__E_O_L,       /* _a_t _t_e_r_m_i_n_a_t_i_n_g '_\_0' */
  1087.         };
  1088.  
  1089.  
  1090.      dec(Posn *)
  1091.       As for inc() but decrements the position.
  1092.  
  1093.      lt(Posn *p1, Posn *p2)
  1094.       Returns _T_R_U_E if the position specified by p1 is  earlier  in
  1095.       the buffer than that specified by p2.
  1096.  
  1097.      _5._4.  _X_v_i_w_i_n
  1098.  
  1099.      This structure maps a screen window onto a Buffer.  It contains:
  1100.  
  1101.      o+    a pointer to the Buffer structure which it is mapped onto
  1102.  
  1103.      o+    the  cursor's  _l_o_g_i_c_a_l  position  in  the  buffer  (a   Posn
  1104.       structure)
  1105.  
  1106.      o+    the cursor's  _p_h_y_s_i_c_a_l  position  in  the  window  (row  and
  1107.       column)
  1108.  
  1109.      o+    information about size and location of screen window
  1110.  
  1111.      o+    current text of status line
  1112.  
  1113.      o+    forward and backward pointers to other windows
  1114.  
  1115.      Note that there is at least one Xviwin for every Buffer.
  1116.  
  1117.      When the editor was modified  to  support  buffer  windows,  many
  1118.  
  1119.  
  1120.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_7
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.      _1_8                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  1127.  
  1128.  
  1129.      global   variables   were   moved  into  the  Buffer  and  Xviwin
  1130.      structures; some were left as globals.  For  instance,  the  _u_n_d_o
  1131.      and  _m_a_r_k  facilities  are  obviously buffer-related, but _y_a_n_k is
  1132.      useful if it is global (actually static within its  own  module);
  1133.      it was decided that _s_e_a_r_c_h and _r_e_d_o should also be global.
  1134.  
  1135.      Some modules have their own internal static data structures;  for
  1136.      instance,  the  _s_e_a_r_c_h module remembers the last pattern searched
  1137.      for.   Also,  certain  modules  use  data  structures  which  are
  1138.      included in more global ones; e.g. each Buffer structure contains
  1139.      some data used  only  within  _u_n_d_o._c.   This  is  not  very  well
  1140.      structured,  but  in  practice it's quite clean because we simply
  1141.      ensure that references to such structures are kept local  to  the
  1142.      module which "owns" them.
  1143.  
  1144.      _5._5.  _M_a_r_k
  1145.  
  1146.      This data structure records a mark (defined by  the  m  command).
  1147.      It contains a Posn and a character field to hold the letter which
  1148.      defines the  mark.   Each  Buffer  contains  an  array  of  these
  1149.      structures  for  holding  alphabetic  marks,  plus  one  for  the
  1150.      previous context mark (as used by the '' and ``  commands).   The
  1151.      file _m_a_r_k._c deals with marks.
  1152.  
  1153.      _5._6.  _C_h_a_n_g_e
  1154.  
  1155.      This structure records a single change which has been made  to  a
  1156.      buffer.   It  also  contains  a pointer, so that it may be formed
  1157.      into a list.  See the discussion  of  _u_n_d_o._c  below  for  further
  1158.      details.
  1159.  
  1160.      _5._7.  _F_l_e_x_b_u_f
  1161.  
  1162.      This structure is used to store text strings for which the length
  1163.      is  unknown.  The following operations are defined for this type.
  1164.      All functions take a Flexbuf pointer as a parameter.
  1165.  
  1166.      flexnew(f)
  1167.       Initialise a Flexbuf; not needed for static Flexbufs.
  1168.  
  1169.      flexclear(f)
  1170.       Truncate a Flexbuf  to  zero  length,  but  don't  free  its
  1171.       storage.
  1172.  
  1173.      flexdelete(f)
  1174.       Free all storage belonging to a Flexbuf.
  1175.  
  1176.      flexempty(f)
  1177.       Return _T_R_U_E if the Flexbuf is empty.
  1178.  
  1179.      flexlen(f)
  1180.       Return the number of characters in the Flexbuf.
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.      _P_a_g_e _1_8                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _1_9
  1193.  
  1194.  
  1195.      flexrmchar(f)
  1196.       Remove the last character from a Flexbuf.
  1197.  
  1198.      flexpopch(f)
  1199.       Remove the first character from a Flexbuf and return it.
  1200.  
  1201.      flexgetstr(f)
  1202.       Return a pointer to the string contained in the Flexbuf.
  1203.  
  1204.      flexaddch(f, c)
  1205.       Add the character c to the end of the Flexbuf.
  1206.  
  1207.      lformat(f, fmt, ...)
  1208.       A subset of sprintf() but for Flexbufs.
  1209.  
  1210.      vformat(f, fmt, va_list)
  1211.       A subset of vsprintf() but for Flexbufs.
  1212.  
  1213.      The last two functions are especially useful,  since  they  avoid
  1214.      the usual problems with the lack of bounds-checking in sprintf().
  1215.      All code in the editor itself now  uses  Flexbufs  to  avoid  the
  1216.      possibility  of  buffer  overruns,  and to reduce the size of the
  1217.      executable.  Some OS-specific modules, however, may still use the
  1218.      printf()  family.   The  subset  of printf-like format specifiers
  1219.      implemented includes those for integers and strings, but not  for
  1220.      floating-point numbers.
  1221.  
  1222.      _5._8.  _b_o_o_l__t
  1223.  
  1224.      A simple Boolean type; has  values  _T_R_U_E  and  _F_A_L_S_E,  which  are
  1225.      defined  as  1  and  0  so  as to be compatible with C comparison
  1226.      operators.
  1227.  
  1228.      _5._9.  _x_v_E_v_e_n_t
  1229.  
  1230.      This type is defined in the previous section, since it forms part
  1231.      of the porting interface.
  1232.  
  1233.      _5._1_0.  _V_i_r_t_S_c_r
  1234.  
  1235.      This type represents a virtual screen, and is  constructed  in  a
  1236.      similar way to a _c_l_a_s_s.  It contains some function pointers which
  1237.      may be used to manipulate the screen in various  ways,  and  some
  1238.      private data which is used by the implementation of the class.
  1239.  
  1240.      The old terminal interface, which consisted of a set of disparate
  1241.      functions,  is being replaced by the VirtScr interface; the first
  1242.      step in this process has been accomplished by the provision of  a
  1243.      default VirtScr implementation using the old primitive functions.
  1244.      New, native, VirtScr implementations may now be coded, which will
  1245.      increase the efficiency of screen output.
  1246.  
  1247.      As the final stage, a windowing  implementation  of  the  VirtScr
  1248.      class   will   be   provided,   using   the   underlying  VirtScr
  1249.      implementations, and the window-handling code in the editor  will
  1250.  
  1251.  
  1252.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _1_9
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.      _2_0                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  1259.  
  1260.  
  1261.      be  modified  to that each occurrence of an Xviwin references its
  1262.      own VirtScr.  It will then be possible to build a version of  the
  1263.      editor  which operates in a true windowing environment by using a
  1264.      separate screen window for each buffer, instead  of  the  current
  1265.      vertical-split method.
  1266.  
  1267.      A full definition of the  VirtScr  type  will  be  found  in  the
  1268.      previous section.
  1269.  
  1270.      _5._1_1.  _G_l_o_b_a_l _V_a_r_i_a_b_l_e_s
  1271.  
  1272.      There are only a few global variables in the editor.   These  are
  1273.      the important ones:
  1274.  
  1275.      curbuf
  1276.         pointer to the current Buffer
  1277.  
  1278.      curwin
  1279.         pointer to the current Xviwin
  1280.  
  1281.      State   the current _s_t_a_t_e of the editor; controls what we do with
  1282.         input characters.  The value is one of the following:
  1283.  
  1284.         NORMAL    The  default  state;  vi-mode  commands  may  be
  1285.               executed
  1286.  
  1287.         INSERT    Insert mode, i.e. characters typed get  inserted
  1288.               into the current buffer
  1289.  
  1290.         REPLACE   Replace  mode,  characters  in  the  buffer  get
  1291.               overwritten by what is typed
  1292.  
  1293.         CMDLINE   Reading a colon-command, regular  expression  or
  1294.               pipe command
  1295.  
  1296.         DISPLAY   Displaying text, i.e. :p  command,  or  :set  or
  1297.               :map with no argument
  1298.  
  1299.      echo   This  variable   controls   what   output   is   currently
  1300.         displayable.   It  is  used  at  various points within the
  1301.         editor to stop certain output which is either  undesirable
  1302.         or  sub-optimal.   It  must  always  be  restored  to  its
  1303.         previous  value  after  the  code  which  changed  it  has
  1304.         finished what it is doing.
  1305.  
  1306.      kbdintr
  1307.         This can be set to a non-zero value to  indicate  that  an
  1308.         asynchronous  user-generated interrupt (such as a keyboard
  1309.         interrupt) has occurred.   See  the  discussion  of  event
  1310.         handling in the previous section.
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.      _P_a_g_e _2_0                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  1319.  
  1320.  
  1321.  
  1322.  
  1323.  
  1324.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _2_1
  1325.  
  1326.  
  1327.      _6.  _S_O_U_R_C_E _F_I_L_E_S
  1328.  
  1329.      The header file _x_v_i._h contains  all  the  type  definitions  used
  1330.      within the editor, as well as function declarations etc.
  1331.  
  1332.      The following source files form  the  primary  interface  to  the
  1333.      editor:
  1334.  
  1335.      startup.c
  1336.            Entry point for the editor.  Deals  with  argument  and
  1337.            option   parsing  and  initial  setup,  calling  module
  1338.            initialisation functions as necessary.
  1339.  
  1340.      events.c   Contains the routine xvi_handle_event(), which is  the
  1341.            entry  point for handling input to the editor; input is
  1342.            passed to different routines  according  to  the  State
  1343.            variable.   Timeouts on input are also handled here, by
  1344.            calling appropriate routines in map.c or preserve.c.
  1345.  
  1346.      edit.c    Deals with insert and replace modes.
  1347.  
  1348.      normal.c   Handles normal-mode commands.
  1349.  
  1350.      map.c     This file is responsible for all  input  mapping  (both
  1351.            set   up   by  the  :map  command  and  internally  for
  1352.            function-key mappings;  it  also  implements  a  stuff-
  1353.            characters-into-the-input-stream   function   for   use
  1354.            within the editor.   This  is  used,  for  example,  to
  1355.            implement command redo (but _n_o_t to implement "undo" and
  1356.            "put" as in STEVIE).
  1357.  
  1358.  
  1359.      Colon (ex-type) commands are handled by this group:
  1360.  
  1361.      cmdline.c
  1362.            Decodes and executes colon commands.
  1363.  
  1364.      ex_cmds1.c
  1365.            File-, Buffer- and Xviwin-related colon commands.
  1366.  
  1367.      ex_cmds2.c
  1368.            Other colon commands (e.g. shell escape).
  1369.  
  1370.  
  1371.      Screen updating is done within the following files:
  1372.  
  1373.      screen.c   Screen updating code, including handling of line-based
  1374.            entry  (for  colon  commands, searches etc) as they are
  1375.            typed  in,  and  display-mode  stuff   (for   parameter
  1376.            displaying, :_g/_r_e/_p etc).
  1377.  
  1378.      cursor.c   This file contains the single  function  cursupdate(),
  1379.            which  is  responsible  for deciding where the physical
  1380.            screen cursor should be, according to the  position  of
  1381.            the  logical  cursor  in the buffer and the position of
  1382.  
  1383.  
  1384.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _2_1
  1385.  
  1386.  
  1387.  
  1388.  
  1389.  
  1390.      _2_2                                          _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s
  1391.  
  1392.  
  1393.            the window onto that buffer.  This routine is not  very
  1394.            optimal, and will probably disappear in due course.
  1395.  
  1396.      defscr.c   This file contains the default implementation  of  the
  1397.            VirtScr  class,  on  top  of  the  old  terminal/system
  1398.            interface.
  1399.  
  1400.      status.c   Functions to update the status line of a window; there
  1401.            are  different  functions  to  display file information
  1402.            (name, position etc.) and error/information messages.
  1403.  
  1404.  
  1405.      These files deal with specific areas of functionality:
  1406.  
  1407.      find.c    Search functions:  all  kinds  of  searches,  including
  1408.            character-based   and  word-based  commands,  sections,
  1409.            paragraphs,  and  the  interface  to  "real"  searching
  1410.            (which is actually done in _s_e_a_r_c_h._c).
  1411.  
  1412.      mark.c    Provides primitives to record marks  within  a  Buffer,
  1413.            and to find the marks again.
  1414.  
  1415.      mouse.c   Code to  handle  mice  moving  the  cursor  around  and
  1416.            resizing windows.
  1417.  
  1418.      param.[ch]
  1419.            Code to handle setting of, and access  to,  parameters.
  1420.            (These are things like tabstops, autoindent, etc.)
  1421.  
  1422.      pipe.c    Handles piping through system commands.
  1423.  
  1424.      preserve.c
  1425.            File preservation routines.
  1426.  
  1427.      search.c   Code  for  pattern-searching  in  a  buffer,  and  for
  1428.            substitutions  and  global execution.  Uses regexp.[ch]
  1429.            for the actual regular expression stuff.
  1430.  
  1431.      tags.c    Routines to handle tags - for :tag, -t and ^].
  1432.  
  1433.      undo.c    Code to deal with doing and undoing;  i.e.  making  and
  1434.            unmaking  changes to a buffer.  This is one of the more
  1435.            complex and delicate files.
  1436.  
  1437.      yankput.c
  1438.            Code to deal with yanking and putting  text,  including
  1439.            named buffers.
  1440.  
  1441.  
  1442.      while these files provide lower-level functions:
  1443.  
  1444.      alloc.c   Memory allocation routines.
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.      _P_a_g_e _2_2                                       _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2
  1451.  
  1452.  
  1453.  
  1454.  
  1455.  
  1456.      _X_v_i _S_o_u_r_c_e _C_o_d_e _N_o_t_e_s                                          _2_3
  1457.  
  1458.  
  1459.      ascii.[ch]
  1460.            Deals  with  the  visual  representation   of   special
  1461.            characters on the display (e.g. tabs, control chars).
  1462.  
  1463.      buffers.c
  1464.            Routines dealing with the  allocation  and  freeing  of
  1465.            Buffers.
  1466.  
  1467.      fileio.c   File I/O routines; reading, writing, re-editing files.
  1468.            Also handling of the format parameter.
  1469.  
  1470.      flexbuf.c
  1471.            Flexible-length character-buffer routines.
  1472.  
  1473.      misccmds.c
  1474.            Miscellaneous functions.
  1475.  
  1476.      movement.c
  1477.            Code to deal with  moving  the  cursor  around  in  the
  1478.            buffer, and scrolling the screen etc.
  1479.  
  1480.      ptrfunc.[ch]
  1481.            Primitives to handle Posn structures; including various
  1482.            operators to compare positions in a text buffer.
  1483.  
  1484.      regexp.[ch], regmagic.h
  1485.            Regular-expression stuff, originally written  by  Henry
  1486.            Spencer  (thanks  Henry)  and  slightly  hacked for use
  1487.            within xvi.
  1488.  
  1489.      signal.c   Handling of  terminal-generated  signals  in  an  ANSI
  1490.            environment.
  1491.  
  1492.      virtscr.h
  1493.            Virtual Screen interface definition.   This  is  a  new
  1494.            part  of  xvi, and is not yet fully completed.  When it
  1495.            is finished, it will provide the ability  to  implement
  1496.            "native"   versions  of  xvi  under  various  windowing
  1497.            systems, in a clean and wholesome way.  Currently there
  1498.            is  a  single  instance  of the VirtScr class, which is
  1499.            defined on top of the old system/terminal interface.
  1500.  
  1501.      windows.c
  1502.            Code to deal with creating, deleting, resizing windows.
  1503.  
  1504.      version.c
  1505.            Contains only the version string.
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.      _2_5_t_h _S_e_p_t_e_m_b_e_r _1_9_9_2                                       _P_a_g_e _2_3
  1517.  
  1518.  
  1519.