]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - doc/hackguide.doc
ncurses 5.6 - patch 20080804
[ncurses.git] / doc / hackguide.doc
index e9828d2919fab62f53a0e0f7efbf00c482dbdd6c..8e0ba5c0f85b3c048f04ee224e759ac10a88d77c 100644 (file)
@@ -1,8 +1,7 @@
-
                           A Hacker's Guide to NCURSES
-                                       
+
                                    Contents
-                                       
+
      * Abstract
      * Objective of the Package
           + Why System V Curses?
      * Other Utilities
      * Style Tips for Developers
      * Porting Hints
-       
+
                                    Abstract
-                                       
+
    This document is a hacker's tour of the ncurses library and utilities.
-   It discusses design philosophy, implementation methods, and the
-   conventions used for coding and documentation. It is recommended
-   reading for anyone who is interested in porting, extending or
+   It  discusses  design  philosophy,  implementation  methods,  and  the
+   conventions  used  for  coding  and  documentation.  It is recommended
+   reading  for  anyone  who  is  interested  in  porting,  extending  or
    improving the package.
-   
+
                            Objective of the Package
-                                       
+
    The objective of the ncurses package is to provide a free software API
    for character-cell terminals and terminal emulators with the following
    characteristics:
-     * Source-compatible with historical curses implementations
+     * Source-compatible    with    historical   curses   implementations
        (including the original BSD curses and System V curses.
-     * Conformant with the XSI Curses standard issued as part of XPG4 by
+     * Conformant  with the XSI Curses standard issued as part of XPG4 by
        X/Open.
-     * High-quality -- stable and reliable code, wide portability, good
+     * High-quality  --  stable and reliable code, wide portability, good
        packaging, superior documentation.
-     * Featureful -- should eliminate as much of the drudgery of C
+     * Featureful  --  should  eliminate  as  much  of  the drudgery of C
        interface programming as possible, freeing programmers to think at
        a higher level of design.
-       
-   These objectives are in priority order. So, for example, source
-   compatibility with older version must trump featurefulness -- we
-   cannot add features if it means breaking the portion of the API
+
+   These  objectives  are  in  priority  order.  So,  for example, source
+   compatibility  with  older  version  must  trump  featurefulness -- we
+   cannot  add  features  if  it  means  breaking  the portion of the API
    corresponding to historical curses versions.
-   
+
 Why System V Curses?
 
-   We used System V curses as a model, reverse-engineering their API, in
+   We  used System V curses as a model, reverse-engineering their API, in
    order to fulfill the first two objectives.
-   
-   System V curses implementations can support BSD curses programs with
+
+   System  V  curses implementations can support BSD curses programs with
    just a recompilation, so by capturing the System V API we also capture
    BSD's.
-   
-   More importantly for the future, the XSI Curses standard issued by
-   X/Open is explicitly and closely modeled on System V. So conformance
+
+   More  importantly  for  the  future, the XSI Curses standard issued by
+   X/Open  is  explicitly and closely modeled on System V. So conformance
    with System V took us most of the way to base-level XSI conformance.
-   
+
 How to Design Extensions
 
-   The third objective (standards conformance) requires that it be easy
-   to condition source code using ncurses so that the absence of
+   The  third  objective (standards conformance) requires that it be easy
+   to  condition  source  code  using  ncurses  so  that  the  absence of
    nonstandard extensions does not break the code.
-   
-   Accordingly, we have a policy of associating with each nonstandard
-   extension a feature macro, so that ncurses client code can use this
-   macro to condition in or out the code that requires the ncurses
+
+   Accordingly,  we  have  a  policy of associating with each nonstandard
+   extension  a  feature  macro, so that ncurses client code can use this
+   macro  to  condition  in  or  out  the  code that requires the ncurses
    extension.
-   
-   For example, there is a macro NCURSES_MOUSE_VERSION which XSI Curses
-   does not define, but which is defined in the ncurses library header.
+
+   For  example,  there is a macro NCURSES_MOUSE_VERSION which XSI Curses
+   does  not  define, but which is defined in the ncurses library header.
    You can use this to condition the calls to the mouse API calls.
-   
+
                          Portability and Configuration
-                                       
-   Code written for ncurses may assume an ANSI-standard C compiler and
-   POSIX-compatible OS interface. It may also assume the presence of a
+
+   Code  written  for  ncurses may assume an ANSI-standard C compiler and
+   POSIX-compatible  OS  interface.  It may also assume the presence of a
    System-V-compatible select(2) call.
-   
+
    We encourage (but do not require) developers to make the code friendly
    to less-capable UNIX environments wherever possible.
-   
-   We encourage developers to support OS-specific optimizations and
+
+   We  encourage  developers  to  support  OS-specific  optimizations and
    methods not available under POSIX/ANSI, provided only that:
-     * All such code is properly conditioned so the build process does
+     * All  such  code  is properly conditioned so the build process does
        not attempt to compile it under a plain ANSI/POSIX environment.
-     * Adding such implementation methods does not introduce
+     * Adding    such   implementation   methods   does   not   introduce
        incompatibilities in the ncurses API between platforms.
-       
-   We use GNU autoconf(1) as a tool to deal with portability issues. The
+
+   We  use GNU autoconf(1) as a tool to deal with portability issues. The
    right way to leverage an OS-specific feature is to modify the autoconf
-   specification files (configure.in and aclocal.m4) to set up a new
+   specification  files  (configure.in  and  aclocal.m4)  to set up a new
    feature macro, which you then use to condition your code.
-   
+
                            Documentation Conventions
-                                       
-   There are three kinds of documentation associated with this package.
+
+   There  are  three kinds of documentation associated with this package.
    Each has a different preferred format:
      * Package-internal files (README, INSTALL, TO-DO etc.)
      * Manual pages.
      * Everything else (i.e., narrative documentation).
-       
+
    Our conventions are simple:
     1. Maintain package-internal files in plain text. The expected viewer
-       for them more(1) or an editor window; there's no point in
+       for  them  more(1)  or  an  editor  window;  there's  no  point in
        elaborate mark-up.
-    2. Mark up manual pages in the man macros. These have to be viewable
+    2. Mark  up manual pages in the man macros. These have to be viewable
        through traditional man(1) programs.
     3. Write everything else in HTML.
-       
-   When in doubt, HTMLize a master and use lynx(1) to generate plain
+
+   When  in  doubt,  HTMLize  a  master and use lynx(1) to generate plain
    ASCII (as we do for the announcement document).
-   
+
    The reason for choosing HTML is that it's (a) well-adapted for on-line
    browsing through viewers that are everywhere; (b) more easily readable
-   as plain text than most other mark-ups, if you don't have a viewer;
-   and (c) carries enough information that you can generate a
-   nice-looking printed version from it. Also, of course, it make
+   as  plain  text  than most other mark-ups, if you don't have a viewer;
+   and   (c)   carries   enough  information  that  you  can  generate  a
+   nice-looking  printed  version  from  it.  Also,  of  course,  it make
    exporting things like the announcement document to WWW pretty trivial.
-   
+
                               How to Report Bugs
-                                       
-   The reporting address for bugs is bug-ncurses@gnu.org. This is a
-   majordomo list; to join, write to bug-ncurses-request@gnu.org with a
+
+   The  reporting  address  for  bugs  is  bug-ncurses@gnu.org. This is a
+   majordomo  list;  to join, write to bug-ncurses-request@gnu.org with a
    message containing the line:
              subscribe <name>@<host.domain>
 
-   The ncurses code is maintained by a small group of volunteers. While
-   we try our best to fix bugs promptly, we simply don't have a lot of
-   hours to spend on elementary hand-holding. We rely on intelligent
-   cooperation from our users. If you think you have found a bug in
-   ncurses, there are some steps you can take before contacting us that
+   The  ncurses  code is maintained by a small group of volunteers. While
+   we  try  our  best to fix bugs promptly, we simply don't have a lot of
+   hours  to  spend  on  elementary  hand-holding. We rely on intelligent
+   cooperation  from  our  users.  If  you  think you have found a bug in
+   ncurses,  there  are some steps you can take before contacting us that
    will help get the bug fixed quickly.
-   
-   In order to use our bug-fixing time efficiently, we put people who
+
+   In  order  to  use  our bug-fixing time efficiently, we put people who
    show us they've taken these steps at the head of our queue. This means
-   that if you don't, you'll probably end up at the tail end and have to
+   that  if you don't, you'll probably end up at the tail end and have to
    wait a while.
     1. Develop a recipe to reproduce the bug.
-       Bugs we can reproduce are likely to be fixed very quickly, often
-       within days. The most effective single thing you can do to get a
-       quick fix is develop a way we can duplicate the bad behavior --
-       ideally, by giving us source for a small, portable test program
-       that breaks the library. (Even better is a keystroke recipe using
+       Bugs  we  can reproduce are likely to be fixed very quickly, often
+       within  days.  The most effective single thing you can do to get a
+       quick  fix  is  develop a way we can duplicate the bad behavior --
+       ideally,  by  giving  us source for a small, portable test program
+       that  breaks the library. (Even better is a keystroke recipe using
        one of the test programs provided with the distribution.)
     2. Try to reproduce the bug on a different terminal type.
-       In our experience, most of the behaviors people report as library
+       In  our experience, most of the behaviors people report as library
        bugs are actually due to subtle problems in terminal descriptions.
        This is especially likely to be true if you're using a traditional
-       asynchronous terminal or PC-based terminal emulator, rather than
+       asynchronous  terminal  or PC-based terminal emulator, rather than
        xterm or a UNIX console entry.
        It's therefore extremely helpful if you can tell us whether or not
-       your problem reproduces on other terminal types. Usually you'll
-       have both a console type and xterm available; please tell us
+       your  problem  reproduces  on other terminal types. Usually you'll
+       have  both  a  console  type  and  xterm available; please tell us
        whether or not your bug reproduces on both.
-       If you have xterm available, it is also good to collect xterm
+       If  you  have  xterm  available,  it is also good to collect xterm
        reports for different window sizes. This is especially true if you
-       normally use an unusual xterm window size -- a surprising number
+       normally  use  an unusual xterm window size -- a surprising number
        of the bugs we've seen are either triggered or masked by these.
     3. Generate and examine a trace file for the broken behavior.
-       Recompile your program with the debugging versions of the
-       libraries. Insert a trace() call with the argument set to
-       TRACE_UPDATE. (See "Writing Programs with NCURSES" for details on
-       trace levels.) Reproduce your bug, then look at the trace file to
+       Recompile   your  program  with  the  debugging  versions  of  the
+       libraries.  Insert  a  trace()  call  with  the  argument  set  to
+       TRACE_UPDATE.  (See "Writing Programs with NCURSES" for details on
+       trace  levels.) Reproduce your bug, then look at the trace file to
        see what the library was actually doing.
-       Another frequent cause of apparent bugs is application coding
-       errors that cause the wrong things to be put on the virtual
+       Another  frequent  cause  of  apparent  bugs is application coding
+       errors  that  cause  the  wrong  things  to  be put on the virtual
        screen. Looking at the virtual-screen dumps in the trace file will
-       tell you immediately if this is happening, and save you from the
-       possible embarrassment of being told that the bug is in your code
+       tell  you  immediately if this is happening, and save you from the
+       possible  embarrassment of being told that the bug is in your code
        and is your problem rather than ours.
-       If the virtual-screen dumps look correct but the bug persists,
-       it's possible to crank up the trace level to give more and more
-       information about the library's update actions and the control
-       sequences it issues to perform them. The test directory of the
+       If  the  virtual-screen  dumps  look correct but the bug persists,
+       it's  possible  to  crank up the trace level to give more and more
+       information  about  the  library's  update actions and the control
+       sequences  it  issues  to  perform them. The test directory of the
        distribution contains a tool for digesting these logs to make them
        less tedious to wade through.
        Often you'll find terminfo problems at this stage by noticing that
-       the escape sequences put out for various capabilities are wrong.
-       If not, you're likely to learn enough to be able to characterize
+       the  escape  sequences put out for various capabilities are wrong.
+       If  not,  you're likely to learn enough to be able to characterize
        any bug in the screen-update logic quite exactly.
     4. Report details and symptoms, not just interpretations.
-       If you do the preceding two steps, it is very likely that you'll
+       If  you  do the preceding two steps, it is very likely that you'll
        discover the nature of the problem yourself and be able to send us
-       a fix. This will create happy feelings all around and earn you
-       good karma for the first time you run into a bug you really can't
+       a  fix.  This  will  create happy feelings all around and earn you
+       good  karma for the first time you run into a bug you really can't
        characterize and fix yourself.
-       If you're still stuck, at least you'll know what to tell us.
-       Remember, we need details. If you guess about what is safe to
+       If  you're  still  stuck,  at  least  you'll know what to tell us.
+       Remember,  we  need  details.  If  you guess about what is safe to
        leave out, you are too likely to be wrong.
-       If your bug produces a bad update, include a trace file. Try to
-       make the trace at the least voluminous level that pins down the
-       bug. Logs that have been through tracemunch are OK, it doesn't
-       throw away any information (actually they're better than
+       If  your  bug  produces a bad update, include a trace file. Try to
+       make  the  trace  at the least voluminous level that pins down the
+       bug.  Logs  that  have  been through tracemunch are OK, it doesn't
+       throw   away   any   information  (actually  they're  better  than
        un-munched ones because they're easier to read).
-       If your bug produces a core-dump, please include a symbolic stack
+       If  your bug produces a core-dump, please include a symbolic stack
        trace generated by gdb(1) or your local equivalent.
        Tell us about every terminal on which you've reproduced the bug --
-       and every terminal on which you can't. Ideally, sent us terminfo
+       and  every  terminal on which you can't. Ideally, sent us terminfo
        sources for all of these (yours might differ from ours).
-       Include your ncurses version and your OS/machine type, of course!
+       Include  your ncurses version and your OS/machine type, of course!
        You can find your ncurses version in the curses.h file.
-       
-   If your problem smells like a logic error or in cursor movement or
-   scrolling or a bad capability, there are a couple of tiny test frames
-   for the library algorithms in the progs directory that may help you
-   isolate it. These are not part of the normal build, but do have their
+
+   If  your  problem  smells  like a logic error or in cursor movement or
+   scrolling  or a bad capability, there are a couple of tiny test frames
+   for  the  library  algorithms in the progs directory that may help you
+   isolate  it. These are not part of the normal build, but do have their
    own make productions.
-   
-   The most important of these is mvcur, a test frame for the
-   cursor-movement optimization code. With this program, you can see
-   directly what control sequences will be emitted for any given cursor
+
+   The   most  important  of  these  is  mvcur,  a  test  frame  for  the
+   cursor-movement  optimization  code.  With  this  program, you can see
+   directly  what  control sequences will be emitted for any given cursor
    movement or scroll/insert/delete operations. If you think you've got a
-   bad capability identified, you can disable it and test again. The
+   bad  capability  identified,  you  can  disable it and test again. The
    program is command-driven and has on-line help.
-   
-   If you think the vertical-scroll optimization is broken, or just want
-   to understand how it works better, build hashmap and read the header
-   comments of hardscroll.c and hashmap.c; then try it out. You can also
+
+   If  you think the vertical-scroll optimization is broken, or just want
+   to  understand  how it works better, build hashmap and read the header
+   comments  of hardscroll.c and hashmap.c; then try it out. You can also
    test the hardware-scrolling optimization separately with hardscroll.
-   
-   There's one other interactive tester, tctest, that exercises
-   translation between termcap and terminfo formats. If you have a
-   serious need to run this, you probably belong on our development team!
-   
+
                          A Tour of the Ncurses Library
-                                       
+
 Library Overview
 
-   Most of the library is superstructure -- fairly trivial convenience
-   interfaces to a small set of basic functions and data structures used
-   to manipulate the virtual screen (in particular, none of this code
-   does any I/O except through calls to more fundamental modules
+   Most  of  the  library is superstructure -- fairly trivial convenience
+   interfaces  to a small set of basic functions and data structures used
+   to  manipulate  the  virtual  screen (in particular, none of this code
+   does  any  I/O  except  through  calls  to  more  fundamental  modules
    described below). The files
-   
-     lib_addch.c lib_bkgd.c lib_box.c lib_chgat.c lib_clear.c
-     lib_clearok.c lib_clrbot.c lib_clreol.c lib_colorset.c lib_data.c
-     lib_delch.c lib_delwin.c lib_echo.c lib_erase.c lib_gen.c
-     lib_getstr.c lib_hline.c lib_immedok.c lib_inchstr.c lib_insch.c
-     lib_insdel.c lib_insstr.c lib_instr.c lib_isendwin.c lib_keyname.c
-     lib_leaveok.c lib_move.c lib_mvwin.c lib_overlay.c lib_pad.c
-     lib_printw.c lib_redrawln.c lib_scanw.c lib_screen.c lib_scroll.c
-     lib_scrollok.c lib_scrreg.c lib_set_term.c lib_slk.c
-     lib_slkatr_set.c lib_slkatrof.c lib_slkatron.c lib_slkatrset.c
-     lib_slkattr.c lib_slkclear.c lib_slkcolor.c lib_slkinit.c
-     lib_slklab.c lib_slkrefr.c lib_slkset.c lib_slktouch.c lib_touch.c
+
+     lib_addch.c    lib_bkgd.c    lib_box.c    lib_chgat.c   lib_clear.c
+     lib_clearok.c  lib_clrbot.c  lib_clreol.c lib_colorset.c lib_data.c
+     lib_delch.c    lib_delwin.c    lib_echo.c   lib_erase.c   lib_gen.c
+     lib_getstr.c  lib_hline.c  lib_immedok.c  lib_inchstr.c lib_insch.c
+     lib_insdel.c  lib_insstr.c lib_instr.c lib_isendwin.c lib_keyname.c
+     lib_leaveok.c   lib_move.c   lib_mvwin.c   lib_overlay.c  lib_pad.c
+     lib_printw.c  lib_redrawln.c  lib_scanw.c lib_screen.c lib_scroll.c
+     lib_scrollok.c      lib_scrreg.c      lib_set_term.c      lib_slk.c
+     lib_slkatr_set.c   lib_slkatrof.c   lib_slkatron.c  lib_slkatrset.c
+     lib_slkattr.c     lib_slkclear.c    lib_slkcolor.c    lib_slkinit.c
+     lib_slklab.c  lib_slkrefr.c lib_slkset.c lib_slktouch.c lib_touch.c
      lib_unctrl.c lib_vline.c lib_wattroff.c lib_wattron.c lib_window.c
-     
-   are all in this category. They are very unlikely to need change,
+
+   are  all  in  this  category.  They  are very unlikely to need change,
    barring bugs or some fundamental reorganization in the underlying data
    structures.
-   
+
    These files are used only for debugging support:
-   
-     lib_trace.c lib_traceatr.c lib_tracebits.c lib_tracechr.c
+
+     lib_trace.c     lib_traceatr.c    lib_tracebits.c    lib_tracechr.c
      lib_tracedmp.c lib_tracemse.c trace_buf.c
-     
-   It is rather unlikely you will ever need to change these, unless you
-   want to introduce a new debug trace level for some reasoon.
-   
-   There is another group of files that do direct I/O via tputs(),
-   computations on the terminal capabilities, or queries to the OS
-   environment, but nevertheless have only fairly low complexity. These
+
+   It  is  rather unlikely you will ever need to change these, unless you
+   want to introduce a new debug trace level for some reason.
+
+   There  is  another  group  of  files  that  do direct I/O via tputs(),
+   computations  on  the  terminal  capabilities,  or  queries  to the OS
+   environment,  but  nevertheless have only fairly low complexity. These
    include:
-   
-     lib_acs.c lib_beep.c lib_color.c lib_endwin.c lib_initscr.c
-     lib_longname.c lib_newterm.c lib_options.c lib_termcap.c lib_ti.c
+
+     lib_acs.c   lib_beep.c   lib_color.c   lib_endwin.c   lib_initscr.c
+     lib_longname.c  lib_newterm.c  lib_options.c lib_termcap.c lib_ti.c
      lib_tparm.c lib_tputs.c lib_vidattr.c read_entry.c.
-     
+
    They are likely to need revision only if ncurses is being ported to an
    environment without an underlying terminfo capability representation.
-   
-   These files have serious hooks into the tty driver and signal
+
+   These  files  have  serious  hooks  into  the  tty  driver  and signal
    facilities:
-   
+
      lib_kernel.c lib_baudrate.c lib_raw.c lib_tstp.c lib_twait.c
-     
+
    If you run into porting snafus moving the package to another UNIX, the
-   problem is likely to be in one of these files. The file lib_print.c
+   problem  is  likely  to be in one of these files. The file lib_print.c
    uses sleep(2) and also falls in this category.
-   
+
    Almost all of the real work is done in the files
-   
-     hardscroll.c hashmap.c lib_addch.c lib_doupdate.c lib_getch.c
+
+     hardscroll.c   hashmap.c   lib_addch.c  lib_doupdate.c  lib_getch.c
      lib_mouse.c lib_mvcur.c lib_refresh.c lib_setup.c lib_vidattr.c
-     
-   Most of the algorithmic complexity in the library lives in these
-   files. If there is a real bug in ncurses itself, it's probably here.
+
+   Most  of  the  algorithmic  complexity  in  the library lives in these
+   files.  If  there is a real bug in ncurses itself, it's probably here.
    We'll tour some of these files in detail below (see The Engine Room).
-   
-   Finally, there is a group of files that is actually most of the
-   terminfo compiler. The reason this code lives in the ncurses library
+
+   Finally,  there  is  a  group  of  files  that is actually most of the
+   terminfo  compiler.  The reason this code lives in the ncurses library
    is to support fallback to /etc/termcap. These files include
-   
-     alloc_entry.c captoinfo.c comp_captab.c comp_error.c comp_hash.c
+
+     alloc_entry.c  captoinfo.c  comp_captab.c  comp_error.c comp_hash.c
      comp_parse.c comp_scan.c parse_entry.c read_termcap.c write_entry.c
-     
+
    We'll discuss these in the compiler tour.
-   
+
 The Engine Room
 
   Keyboard Input
-  
-   All ncurses input funnels through the function wgetch(), defined in
-   lib_getch.c. This function is tricky; it has to poll for keyboard and
-   mouse events and do a running match of incoming input against the set
+
+   All  ncurses  input  funnels through the function wgetch(), defined in
+   lib_getch.c.  This function is tricky; it has to poll for keyboard and
+   mouse  events and do a running match of incoming input against the set
    of defined special keys.
-   
-   The central data structure in this module is a FIFO queue, used to
-   match multiple-character input sequences against special-key
+
+   The  central  data  structure  in this module is a FIFO queue, used to
+   match   multiple-character   input   sequences   against   special-key
    capabilities; also to implement pushback via ungetch().
-   
+
    The wgetch() code distinguishes between function key sequences and the
-   same sequences typed manually by doing a timed wait after each input
-   character that could lead a function key sequence. If the entire
-   sequence takes less than 1 second, it is assumed to have been
+   same  sequences  typed manually by doing a timed wait after each input
+   character  that  could  lead  a  function  key sequence. If the entire
+   sequence  takes  less  than  1  second,  it  is  assumed  to have been
    generated by a function key press.
-   
-   Hackers bruised by previous encounters with variant select(2) calls
-   may find the code in lib_twait.c interesting. It deals with the
+
+   Hackers  bruised  by  previous encounters with variant select(2) calls
+   may  find  the  code  in  lib_twait.c  interesting.  It deals with the
    problem that some BSD selects don't return a reliable time-left value.
    The function timed_wait() effectively simulates a System V select.
-   
+
   Mouse Events
-  
+
    If the mouse interface is active, wgetch() polls for mouse events each
-   call, before it goes to the keyboard for input. It is up to
+   call,  before  it  goes  to  the  keyboard  for  input.  It  is  up to
    lib_mouse.c how the polling is accomplished; it may vary for different
    devices.
-   
-   Under xterm, however, mouse event notifications come in via the
-   keyboard input stream. They are recognized by having the kmous
-   capability as a prefix. This is kind of klugey, but trying to wire in
-   recognition of a mouse key prefix without going through the
-   function-key machinery would be just too painful, and this turns out
-   to imply having the prefix somewhere in the function-key capabilities
+
+   Under  xterm,  however,  mouse  event  notifications  come  in via the
+   keyboard  input  stream.  They  are  recognized  by  having  the kmous
+   capability  as a prefix. This is kind of klugey, but trying to wire in
+   recognition   of   a  mouse  key  prefix  without  going  through  the
+   function-key  machinery  would be just too painful, and this turns out
+   to  imply having the prefix somewhere in the function-key capabilities
    at terminal-type initialization.
-   
-   This kluge only works because kmous isn't actually used by any
+
+   This  kluge  only  works  because  kmous  isn't  actually  used by any
    historic terminal type or curses implementation we know of. Best guess
-   is it's a relic of some forgotten experiment in-house at Bell Labs
-   that didn't leave any traces in the publicly-distributed System V
-   terminfo files. If System V or XPG4 ever gets serious about using it
+   is  it's  a  relic  of some forgotten experiment in-house at Bell Labs
+   that  didn't  leave  any  traces  in the publicly-distributed System V
+   terminfo  files.  If System V or XPG4 ever gets serious about using it
    again, this kluge may have to change.
-   
+
    Here are some more details about mouse event handling:
-   
+
    The lib_mouse()code is logically split into a lower level that accepts
-   event reports in a device-dependent format and an upper level that
+   event  reports  in  a  device-dependent format and an upper level that
    parses mouse gestures and filters events. The mediating data structure
    is a circular queue of event structures.
-   
+
    Functionally, the lower level's job is to pick up primitive events and
-   put them on the circular queue. This can happen in one of two ways:
-   either (a) _nc_mouse_event() detects a series of incoming mouse
-   reports and queues them, or (b) code in lib_getch.c detects the kmous
-   prefix in the keyboard input stream and calls _nc_mouse_inline to
+   put  them  on  the circular queue. This can happen in one of two ways:
+   either  (a)  _nc_mouse_event()  detects  a  series  of  incoming mouse
+   reports  and queues them, or (b) code in lib_getch.c detects the kmous
+   prefix  in  the  keyboard  input  stream and calls _nc_mouse_inline to
    queue up a series of adjacent mouse reports.
-   
+
    In either case, _nc_mouse_parse() should be called after the series is
    accepted to parse the digested mouse reports (low-level events) into a
    gesture (a high-level or composite event).
-   
+
   Output and Screen Updating
-  
+
    With the single exception of character echoes during a wgetnstr() call
-   (which simulates cooked-mode line editing in an ncurses window), the
+   (which  simulates  cooked-mode line editing in an ncurses window), the
    library normally does all its output at refresh time.
-   
-   The main job is to go from the current state of the screen (as
-   represented in the curscr window structure) to the desired new state
+
+   The  main  job  is  to  go  from  the  current state of the screen (as
+   represented  in  the curscr window structure) to the desired new state
    (as represented in the newscr window structure), while doing as little
    I/O as possible.
-   
-   The brains of this operation are the modules hashmap.c, hardscroll.c
-   and lib_doupdate.c; the latter two use lib_mvcur.c. Essentially, what
+
+   The  brains  of this operation are the modules hashmap.c, hardscroll.c
+   and  lib_doupdate.c; the latter two use lib_mvcur.c. Essentially, what
    happens looks like this:
-   
-   The hashmap.c module tries to detect vertical motion changes between
-   the real and virtual screens. This information is represented by the
-   oldindex members in the newscr structure. These are modified by
-   vertical-motion and clear operations, and both are re-initialized
+
+   The  hashmap.c  module tries to detect vertical motion changes between
+   the  real  and virtual screens. This information is represented by the
+   oldindex  members  in  the  newscr  structure.  These  are modified by
+   vertical-motion  and  clear  operations,  and  both are re-initialized
    after each update. To this change-journalling information, the hashmap
-   code adds deductions made using a modified Heckel algorithm on hash
+   code  adds  deductions  made using a modified Heckel algorithm on hash
    values generated from the line contents.
-   
-   The hardscroll.c module computes an optimum set of scroll, insertion,
-   and deletion operations to make the indices match. It calls
+
+   The  hardscroll.c module computes an optimum set of scroll, insertion,
+   and   deletion   operations  to  make  the  indices  match.  It  calls
    _nc_mvcur_scrolln() in lib_mvcur.c to do those motions.
-   
-   Then lib_doupdate.c goes to work. Its job is to do line-by-line
-   transformations of curscr lines to newscr lines. Its main tool is the
-   routine mvcur() in lib_mvcur.c. This routine does cursor-movement
-   optimization, attempting to get from given screen location A to given
-   location B in the fewest output characters posible.
-   
-   If you want to work on screen optimizations, you should use the fact
-   that (in the trace-enabled version of the library) enabling the
-   TRACE_TIMES trace level causes a report to be emitted after each
-   screen update giving the elapsed time and a count of characters
-   emitted during the update. You can use this to tell when an update
+
+   Then  lib_doupdate.c  goes  to  work.  Its  job  is to do line-by-line
+   transformations  of curscr lines to newscr lines. Its main tool is the
+   routine  mvcur()  in  lib_mvcur.c.  This  routine does cursor-movement
+   optimization,  attempting to get from given screen location A to given
+   location B in the fewest output characters possible.
+
+   If  you  want to work on screen optimizations, you should use the fact
+   that  (in  the  trace-enabled  version  of  the  library) enabling the
+   TRACE_TIMES  trace  level  causes  a  report  to be emitted after each
+   screen  update  giving  the  elapsed  time  and  a count of characters
+   emitted  during  the  update.  You can use this to tell when an update
    optimization improves efficiency.
-   
-   In the trace-enabled version of the library, it is also possible to
+
+   In  the  trace-enabled  version of the library, it is also possible to
    disable and re-enable various optimizations at runtime by tweaking the
-   variable _nc_optimize_enable. See the file include/curses.h.in for
+   variable  _nc_optimize_enable.  See  the  file include/curses.h.in for
    mask values, near the end.
-   
+
                          The Forms and Menu Libraries
-                                       
-   The forms and menu libraries should work reliably in any environment
-   you can port ncurses to. The only portability issue anywhere in them
-   is what flavor of regular expressions the built-in form field type
+
+   The  forms  and menu libraries should work reliably in any environment
+   you  can  port ncurses to. The only portability issue anywhere in them
+   is  what  flavor  of  regular expressions the built-in form field type
    TYPE_REGEXP will recognize.
-   
-   The configuration code prefers the POSIX regex facility, modeled on
-   System V's, but will settle for BSD regexps if the former isn't
+
+   The  configuration  code  prefers the POSIX regex facility, modeled on
+   System  V's,  but  will  settle  for  BSD  regexps if the former isn't
    available.
-   
-   Historical note: the panels code was written primarily to assist in
-   porting u386mon 2.0 (comp.sources.misc v14i001-4) to systems lacking
-   panels support; u386mon 2.10 and beyond use it. This version has been
+
+   Historical  note:  the  panels code was written primarily to assist in
+   porting  u386mon  2.0 (comp.sources.misc v14i001-4) to systems lacking
+   panels  support; u386mon 2.10 and beyond use it. This version has been
    slightly cleaned up for ncurses.
-   
+
                         A Tour of the Terminfo Compiler
-                                       
+
    The ncurses implementation of tic is rather complex internally; it has
-   to do a trying combination of missions. This starts with the fact
-   that, in addition to its normal duty of compiling terminfo sources
-   into loadable terminfo binaries, it has to be able to handle termcap
+   to  do  a  trying  combination  of missions. This starts with the fact
+   that,  in  addition  to  its normal duty of compiling terminfo sources
+   into  loadable  terminfo binaries, it has to be able to handle termcap
    syntax and compile that too into terminfo entries.
-   
-   The implementation therefore starts with a table-driven, dual-mode
+
+   The  implementation  therefore  starts  with a table-driven, dual-mode
    lexical analyzer (in comp_scan.c). The lexer chooses its mode (termcap
    or terminfo) based on the first `,' or `:' it finds in each entry. The
-   lexer does all the work of recognizing capability names and values;
-   the grammar above it is trivial, just "parse entries till you run out
+   lexer  does  all  the work of recognizing capability names and values;
+   the  grammar above it is trivial, just "parse entries till you run out
    of file".
-   
+
 Translation of Non-use Capabilities
 
-   Translation of most things besides use capabilities is pretty
-   straightforward. The lexical analyzer's tokenizer hands each
-   capability name to a hash function, which drives a table lookup. The
+   Translation   of  most  things  besides  use  capabilities  is  pretty
+   straightforward.   The   lexical   analyzer's   tokenizer  hands  each
+   capability  name  to a hash function, which drives a table lookup. The
    table entry yields an index which is used to look up the token type in
    another table, and controls interpretation of the value.
-   
-   One possibly interesting aspect of the implementation is the way the
-   compiler tables are initialized. All the tables are generated by
-   various awk/sed/sh scripts from a master table include/Caps; these
-   scripts actually write C initializers which are linked to the
+
+   One  possibly  interesting aspect of the implementation is the way the
+   compiler  tables  are  initialized.  All  the  tables are generated by
+   various  awk/sed/sh  scripts  from  a master table include/Caps; these
+   scripts  actually  write  C  initializers  which  are  linked  to  the
    compiler. Furthermore, the hash table is generated in the same way, so
-   it doesn't have to be generated at compiler startup time (another
-   benefit of this organization is that the hash table can be in
+   it  doesn't  have  to  be  generated at compiler startup time (another
+   benefit  of  this  organization  is  that  the  hash  table  can be in
    shareable text space).
-   
+
    Thus, adding a new capability is usually pretty trivial, just a matter
-   of adding one line to the include/Caps file. We'll have more to say
+   of  adding  one  line to the include/Caps file. We'll have more to say
    about this in the section on Source-Form Translation.
-   
+
 Use Capability Resolution
 
-   The background problem that makes tic tricky isn't the capability
-   translation itself, it's the resolution of use capabilities. Older
+   The  background  problem  that  makes  tic tricky isn't the capability
+   translation  itself,  it's  the  resolution of use capabilities. Older
    versions would not handle forward use references for this reason (that
    is, a using terminal always had to follow its use target in the source
-   file). By doing this, they got away with a simple implementation
-   tactic; compile everything as it blows by, then resolve uses from
+   file).  By  doing  this,  they  got  away with a simple implementation
+   tactic;  compile  everything  as  it  blows by, then resolve uses from
    compiled entries.
-   
-   This won't do for ncurses. The problem is that that the whole
-   compilation process has to be embeddable in the ncurses library so
+
+   This  won't  do  for  ncurses.  The  problem  is  that  that the whole
+   compilation  process  has  to  be embeddable in the ncurses library so
    that it can be called by the startup code to translate termcap entries
-   on the fly. The embedded version can't go promiscuously writing
-   everything it translates out to disk -- for one thing, it will
+   on  the  fly.  The  embedded  version  can't  go promiscuously writing
+   everything  it  translates  out  to  disk  --  for  one thing, it will
    typically be running with non-root permissions.
-   
-   So our tic is designed to parse an entire terminfo file into a
-   doubly-linked circular list of entry structures in-core, and then do
-   use resolution in-memory before writing everything out. This design
+
+   So  our  tic  is  designed  to  parse  an  entire terminfo file into a
+   doubly-linked  circular  list of entry structures in-core, and then do
+   use  resolution  in-memory  before writing everything out. This design
    has other advantages: it makes forward and back use-references equally
-   easy (so we get the latter for free), and it makes checking for name
+   easy  (so  we get the latter for free), and it makes checking for name
    collisions before they're written out easy to do.
-   
-   And this is exactly how the embedded version works. But the
-   stand-alone user-accessible version of tic partly reverts to the
+
+   And   this  is  exactly  how  the  embedded  version  works.  But  the
+   stand-alone  user-accessible  version  of  tic  partly  reverts to the
    historical strategy; it writes to disk (not keeping in core) any entry
    with no use references.
-   
-   This is strictly a core-economy kluge, implemented because the
-   terminfo master file is large enough that some core-poor systems swap
+
+   This  is  strictly  a  core-economy  kluge,  implemented  because  the
+   terminfo  master file is large enough that some core-poor systems swap
    like crazy when you compile it all in memory...there have been reports
-   of this process taking three hours, rather than the twenty seconds or
+   of  this process taking three hours, rather than the twenty seconds or
    less typical on the author's development box.
-   
+
    So. The executable tic passes the entry-parser a hook that immediately
-   writes out the referenced entry if it has no use capabilities. The
-   compiler main loop refrains from adding the entry to the in-core list
-   when this hook fires. If some other entry later needs to reference an
-   entry that got written immediately, that's OK; the resolution code
+   writes  out  the  referenced  entry if it has no use capabilities. The
+   compiler  main loop refrains from adding the entry to the in-core list
+   when  this hook fires. If some other entry later needs to reference an
+   entry  that  got  written  immediately, that's OK; the resolution code
    will fetch it off disk when it can't find it in core.
-   
-   Name collisions will still be detected, just not as cleanly. The
-   write_entry() code complains before overwriting an entry that
-   postdates the time of tic's first call to write_entry(), Thus it will
-   complain about overwriting entries newly made during the tic run, but
+
+   Name  collisions  will  still  be  detected,  just not as cleanly. The
+   write_entry()   code   complains  before  overwriting  an  entry  that
+   postdates  the time of tic's first call to write_entry(), Thus it will
+   complain  about overwriting entries newly made during the tic run, but
    not about overwriting ones that predate it.
-   
+
 Source-Form Translation
 
    Another use of tic is to do source translation between various termcap
    and terminfo formats. There are more variants out there than you might
    think; the ones we know about are described in the captoinfo(1) manual
    page.
-   
-   The translation output code (dump_entry() in ncurses/dump_entry.c) is
-   shared with the infocmp(1) utility. It takes the same internal
-   representation used to generate the binary form and dumps it to
+
+   The  translation output code (dump_entry() in ncurses/dump_entry.c) is
+   shared  with  the  infocmp(1)  utility.  It  takes  the  same internal
+   representation  used  to  generate  the  binary  form  and dumps it to
    standard output in a specified format.
-   
-   The include/Caps file has a header comment describing ways you can
-   specify source translations for nonstandard capabilities just by
+
+   The  include/Caps  file  has  a header comment describing ways you can
+   specify  source  translations  for  nonstandard  capabilities  just by
    altering the master table. It's possible to set up capability aliasing
-   or tell the compiler to plain ignore a given capability without
+   or  tell  the  compiler  to  plain  ignore  a given capability without
    writing any C code at all.
-   
-   For circumstances where you need to do algorithmic translation, there
-   are functions in parse_entry.c called after the parse of each entry
+
+   For  circumstances where you need to do algorithmic translation, there
+   are  functions  in  parse_entry.c called after the parse of each entry
    that are specifically intended to encapsulate such translations. This,
-   for example, is where the AIX box1 capability get translated to an
+   for  example,  is  where  the AIX box1 capability get translated to an
    acsc string.
-   
+
                                 Other Utilities
-                                       
-   The infocmp utility is just a wrapper around the same entry-dumping
-   code used by tic for source translation. Perhaps the one interesting
-   aspect of the code is the use of a predicate function passed in to
-   dump_entry() to control which capabilities are dumped. This is
+
+   The  infocmp  utility  is just a wrapper around the same entry-dumping
+   code  used  by tic for source translation. Perhaps the one interesting
+   aspect  of  the  code  is the use of a predicate function passed in to
+   dump_entry()  to  control  which  capabilities  are  dumped.  This  is
    necessary in order to handle both the ordinary De-compilation case and
    entry difference reporting.
-   
-   The tput and clear utilities just do an entry load followed by a
+
+   The  tput  and  clear  utilities  just  do an entry load followed by a
    tputs() of a selected capability.
-   
+
                            Style Tips for Developers
-                                       
-   See the TO-DO file in the top-level directory of the source
+
+   See   the  TO-DO  file  in  the  top-level  directory  of  the  source
    distribution for additions that would be particularly useful.
-   
-   The prefix _nc_ should be used on library public functions that are
-   not part of the curses API in order to prevent pollution of the
-   application namespace. If you have to add to or modify the function
-   prototypes in curses.h.in, read ncurses/MKlib_gen.sh first so you can
-   avoid breaking XSI conformance. Please join the ncurses mailing list.
-   See the INSTALL file in the top level of the distribution for details
+
+   The  prefix  _nc_  should be used on library public functions that are
+   not  part  of  the  curses  API  in  order to prevent pollution of the
+   application  namespace.  If  you have to add to or modify the function
+   prototypes  in curses.h.in, read ncurses/MKlib_gen.sh first so you can
+   avoid  breaking XSI conformance. Please join the ncurses mailing list.
+   See  the INSTALL file in the top level of the distribution for details
    on the list.
-   
-   Look for the string FIXME in source files to tag minor bugs and
+
+   Look  for  the  string  FIXME  in  source  files to tag minor bugs and
    potential problems that could use fixing.
-   
-   Don't try to auto-detect OS features in the main body of the C code.
+
+   Don't  try  to auto-detect OS features in the main body of the C code.
    That's the job of the configuration system.
-   
+
    To hold down complexity, do make your code data-driven. Especially, if
-   you can drive logic from a table filtered out of include/Caps, do it.
-   If you find you need to augment the data in that file in order to
-   generate the proper table, that's still preferable to ad-hoc code --
+   you  can drive logic from a table filtered out of include/Caps, do it.
+   If  you  find  you  need  to augment the data in that file in order to
+   generate  the  proper table, that's still preferable to ad-hoc code --
    that's why the fifth field (flags) is there.
-   
+
    Have fun!
-   
+
                                  Porting Hints
-                                       
-   The following notes are intended to be a first step towards DOS and
+
+   The  following  notes  are intended to be a first step towards DOS and
    Macintosh ports of the ncurses libraries.
-   
-   The following library modules are `pure curses'; they operate only on
-   the curses internal structures, do all output through other curses
-   calls (not including tputs() and putp()) and do not call any other
-   UNIX routines such as signal(2) or the stdio library. Thus, they
+
+   The  following library modules are `pure curses'; they operate only on
+   the  curses  internal  structures,  do all output through other curses
+   calls  (not  including  tputs()  and putp()) and do not call any other
+   UNIX  routines  such  as  signal(2)  or  the stdio library. Thus, they
    should not need to be modified for single-terminal ports.
-   
-     lib_addch.c lib_addstr.c lib_bkgd.c lib_box.c lib_clear.c
-     lib_clrbot.c lib_clreol.c lib_delch.c lib_delwin.c lib_erase.c
-     lib_inchstr.c lib_insch.c lib_insdel.c lib_insstr.c lib_keyname.c
-     lib_move.c lib_mvwin.c lib_newwin.c lib_overlay.c lib_pad.c
-     lib_printw.c lib_refresh.c lib_scanw.c lib_scroll.c lib_scrreg.c
-     lib_set_term.c lib_touch.c lib_tparm.c lib_tputs.c lib_unctrl.c
+
+     lib_addch.c    lib_addstr.c    lib_bkgd.c   lib_box.c   lib_clear.c
+     lib_clrbot.c   lib_clreol.c  lib_delch.c  lib_delwin.c  lib_erase.c
+     lib_inchstr.c  lib_insch.c  lib_insdel.c lib_insstr.c lib_keyname.c
+     lib_move.c   lib_mvwin.c   lib_newwin.c   lib_overlay.c   lib_pad.c
+     lib_printw.c  lib_refresh.c  lib_scanw.c  lib_scroll.c lib_scrreg.c
+     lib_set_term.c  lib_touch.c  lib_tparm.c  lib_tputs.c  lib_unctrl.c
      lib_window.c panel.c
-     
+
    This module is pure curses, but calls outstr():
-   
+
      lib_getstr.c
-     
-   These modules are pure curses, except that they use tputs() and
+
+   These  modules  are  pure  curses,  except  that  they use tputs() and
    putp():
-   
-     lib_beep.c lib_color.c lib_endwin.c lib_options.c lib_slk.c
+
+     lib_beep.c   lib_color.c   lib_endwin.c   lib_options.c   lib_slk.c
      lib_vidattr.c
-     
+
    This modules assist in POSIX emulation on non-POSIX systems:
-   
+
    sigaction.c
           signal calls
-          
-   The following source files will not be needed for a
+
+   The    following   source   files   will   not   be   needed   for   a
    single-terminal-type port.
-   
-     alloc_entry.c captoinfo.c clear.c comp_captab.c comp_error.c
-     comp_hash.c comp_main.c comp_parse.c comp_scan.c dump_entry.c
+
+     alloc_entry.c   captoinfo.c   clear.c   comp_captab.c  comp_error.c
+     comp_hash.c   comp_main.c   comp_parse.c  comp_scan.c  dump_entry.c
      infocmp.c parse_entry.c read_entry.c tput.c write_entry.c
-     
-   The following modules will use open()/read()/write()/close()/lseek()
+
+   The  following  modules will use open()/read()/write()/close()/lseek()
    on files, but no other OS calls.
-   
+
    lib_screen.c
           used to read/write screen dumps
-          
+
    lib_trace.c
           used to write trace data to the logfile
-          
+
    Modules that would have to be modified for a port start here:
-   
-   The following modules are `pure curses' but contain assumptions
+
+   The  following  modules  are  `pure  curses'  but  contain assumptions
    inappropriate for a memory-mapped port.
-   
+
    lib_longname.c
           assumes there may be multiple terminals
-          
+
    lib_acs.c
           assumes acs_map as a double indirection
-          
+
    lib_mvcur.c
           assumes cursor moves have variable cost
-          
+
    lib_termcap.c
           assumes there may be multiple terminals
-          
+
    lib_ti.c
           assumes there may be multiple terminals
-          
+
    The following modules use UNIX-specific calls:
-   
+
    lib_doupdate.c
           input checking
-          
+
    lib_getch.c
           read()
-          
+
    lib_initscr.c
           getenv()
-          
+
    lib_newterm.c
    lib_baudrate.c
    lib_kernel.c
           various tty-manipulation and system calls
-          
+
    lib_raw.c
           various tty-manipulation calls
-          
+
    lib_setup.c
           various tty-manipulation calls
-          
+
    lib_restart.c
           various tty-manipulation calls
-          
+
    lib_tstp.c
           signal-manipulation calls
-          
+
    lib_twait.c
           gettimeofday(), select().
      _________________________________________________________________
-   
-   
+
+
     Eric S. Raymond <esr@snark.thyrsus.com>
-    
+
    (Note: This is not the bug address!)