home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / doc / config / usenixws / paper.ms < prev    next >
Encoding:
Text File  |  1989-03-02  |  22.4 KB  |  624 lines

  1. .\" macros ripped off from Rosenthal and Lemke's paper
  2. .\"    refer -e -n -p vis.refs -s vis.nr | eqn | pic | psroff -ms
  3. .\.EQ
  4. .\delim $$
  5. .\.EN
  6. .ds CH
  7. .de Ip
  8. .IP \(bu 3
  9. ..
  10. .de Qp
  11. .nr PS -2
  12. .nr VS -2
  13. .QP
  14. ..
  15. .de Qe
  16. .nr PS +2
  17. .nr VS +2
  18. ..
  19. .de RQ
  20. .br
  21. .di
  22. .nr NF 0
  23. .if \\n(dn-\\n(.t .nr NF 1
  24. .if \\n(TC .nr NF 1
  25. .if !\\n(NF .if \\n(TB .nr TB 0
  26. .nf
  27. .rs
  28. .nr TC 5
  29. .in 0
  30. .ls 1
  31. .if !\\n(TB \{\
  32. .    ev
  33. .    br
  34. .    ev 2
  35. .    KK
  36. .\}
  37. .ls
  38. .ce 0
  39. .if !\\n(TB .rm KK
  40. .if \\n(TB .da KJ
  41. .if \\n(TB \!.KD \\n(dn
  42. .if \\n(TB .KK
  43. .if \\n(TB .di
  44. .nr TC \\n(TB
  45. .if \\n(KN .fi
  46. .in
  47. .ev
  48. ..
  49. .\"    These macros should select a typewriter font if you have one.
  50. .de LS
  51. .LP
  52. .KS
  53. .LD
  54. .ft L
  55. .ta .6i 1.2i 1.8i 2.4i 3i 3.6i 4.2i
  56. ..
  57. .de LE
  58. .ft P
  59. .DE
  60. .KE
  61. ..
  62. .de Ls
  63. .nr PS -4
  64. .nr VS -6
  65. .LS
  66. ..
  67. .de Le
  68. .LE
  69. .nr PS +4
  70. .nr VS +6
  71. .LP
  72. ..
  73. .nr PO 1.25i
  74. .TL
  75. Configuration Management in the X Window System
  76. .AU
  77. Jim Fulton
  78. .AI
  79. X Consortium
  80. MIT Laboratory for Computer Science
  81. 545 Technology Square
  82. Cambridge, MA  02139
  83. .AB
  84. The X Window System\(dg has become an industry standard for network window
  85. technology in part because of the
  86. portability of the sample implementation from MIT.  Although many systems are
  87. designed to reuse source code across different platforms, X is 
  88. unusual in its
  89. portability across software build environments.  This paper describes several
  90. mechanisms used in the MIT release of the X Window System to obtain such
  91. flexibility, and summarizes some of the lessons learned in trying to support
  92. X on a number of different platforms.
  93. .AE
  94. .NH 1
  95. Introduction
  96. .LP
  97. The X Window System\f(d is a portable, network transparent window system 
  98. originally developed at MIT.  It is intended for use on raster display
  99. devices ranging from simple monochrome frame buffers to deep,
  100. true color graphics processors.  Because of its client/server architecture,
  101. the non-proprietary nature of its background, and the portability of the
  102. sample implementation from MIT, the X Window System has rapidly grown to 
  103. become an industry standard.  This portability is the result of several
  104. factors: a system architecture that isolates operating system and
  105. device-specifics at several levels; a slow, but machine-independent, graphics
  106. package that may be used for an initial port and to handle cases that
  107. the underlying graphics hardware does not support; and the use of a few,
  108. higher-level tools for managing the build process itself.
  109. .FS
  110. \(dg X Window System is a trademark of MIT; DECnet is a trademark of 
  111. Digital Equipment Corporation; UNIX is a registered trademark of AT&T.
  112. .sp
  113. Copyright \(co\ 1989 by the Massachusetts Institute of Technology.
  114. .sp
  115. Permission to use, copy, modify, and distribute this
  116. document for any purpose and without
  117. fee is hereby granted, provided that the above copyright
  118. notice appear in all copies and that both that copyright
  119. notice and this permission notice appear in supporting
  120. documentation, and that the name of M.I.T. not be used in
  121. advertising or publicity pertaining to distribution of the
  122. software without specific, written prior permission.
  123. M.I.T. makes no representations about the suitability of
  124. the software described herein for any purpose.  It is provided "as is"
  125. without express or implied warranty.
  126. .FE
  127. .NH 2
  128. Summary of X Window System Architecture
  129. .LP
  130. The X Window System is the result of a combined effort between MIT Project 
  131. Athena and the MIT Laboratory for Computer Science.  Since its inception 
  132. in 1984, X has been redesigned three times, culminating in Version 11 which
  133. has since become an industry standard (see [Scheifler 88] for a more detailed
  134. history).  X uses the client/server model of 
  135. limiting interactions with the physical display hardware to a single program
  136. (the \fIserver\fP) and providing a way for applications (the \fIclients\fP)
  137. to send messages (known as \fIrequests\fP) to the server to ask it to perform
  138. graphics operations on the client's behalf.  These messages are sent along
  139. a reliable, sequenced, duplex byte stream using whatever underlying transport
  140. mechanisms the operating system provides.  If connections 
  141. using network virtual circuits (such as TCP/IP or DECnet) are supported,
  142. clients may be run
  143. on any remote machine (including ones of differing architectures) while still
  144. displaying on the local server.
  145. .LP
  146. The details of how the client establishes and maintains connections with the
  147. server are typically hidden in a subroutine package (known as a \fIlanguage
  148. binding\fP) which provides a function call interface to the X protocol.  Higher
  149. level toolkits and user interface management systems are then built on top of 
  150. the binding library, as shown in Figure 1 for the C programming language.
  151. Since only the underlying
  152. operating system networking interface of the binding (shown in \fIitalics\fP)
  153. need be changed when 
  154. porting to a new platform, well-written applications can simply be recompiled.
  155. .sp 1
  156. .DS C
  157. .TS
  158. box tab (/) ;
  159. cB    s    s    s 
  160. _     lB   lB   lB 
  161. cBe | le   le   le
  162. _     s    lB   lB
  163. cB    s |  lB   lB
  164. _     s    s    lB
  165. cB    s    s |  lB
  166. _     s    s    s
  167. cB    s    s    s
  168. _     lB   lB   _
  169. cI    s    s    s .
  170. application///
  171. ///
  172. UIMS///
  173. ///
  174. widgets///
  175. ///
  176. toolkit///
  177. ///
  178. Xlib///
  179. ///
  180. os
  181. .TE
  182. .sp 1
  183. \fBFigure 1:\fP  architecture of a typical C language client program
  184. .DE
  185. .sp 1
  186. .LP
  187. The server takes care of clipping of graphics output and routing keyboard and
  188. pointer input
  189. to the appropriate applications.  Unlike many previous window systems, 
  190. moving and resizing of windows are handled outside the server
  191. by special X applications called
  192. \fIwindow managers\fP.  Different user interface policies can be selected 
  193. simply by running a different window manager.
  194. .LP
  195. The MIT sample server can be divided into three sections: a device-independent
  196. layer called \fIdiX\fP for managing the various shared resources (windows, 
  197. pixmaps, colormaps, fonts, cursors, etc.), an operating system layer called
  198. \fIos\fP for performing machine-specific operations (managing
  199. connections to clients, dealing with timers, reading color and font name 
  200. databases, and memory allocation), and a device-specific
  201. layer called \fIddX\fP for drawing on the display and getting input from the 
  202. keyboard and pointer.  Only the \fIos\fP and \fIddX\fP portions of the server
  203. need to be changed when porting X to a new device.
  204. .LP
  205. Although this is still
  206. a substantial amount of work, a collection of pixel-oriented drawing packages
  207. that only require device-specific routines (refered to as \fIspans\fP) 
  208. to read and write rows of pixels are provided
  209. to allow initial ports of X to be done in a very short time.  A server
  210. developer can then concentrate on replacing those operations that can be
  211. implemented more efficiently by the hardware.  Figure 2 shows the relative
  212. layering of the various packages within the sample server from MIT.  The
  213. \fImi\fP library provides highly portable, machine-independent routines that
  214. may be used on a wide variety of displays.  The \fImfb\fP and \fIcfb\fP 
  215. libraries contain versions of the graphics routines for monochrome and
  216. color frame buffers, respectively.  Finally, the \fIsnf\fP library can be
  217. used to read fonts stored in Server Natural Format.  Typically, only the 
  218. sections printed in \fIitalics\fP need be changed when moving to a new 
  219. platform.
  220. .sp 1
  221. .DS C
  222. .TS
  223. allbox tab (/) ;
  224. cB s s s s
  225. cI s s s cI
  226. cB cB cB cB cB
  227. cI s s s cB .
  228. diX
  229. ddX/os
  230. mi/mfb/cfb/snf/\^
  231. spans/\^
  232. .TE
  233. .sp 1
  234. \fBFigure 2:\fP  architecture of the MIT sample server
  235. .DE
  236. .sp 1
  237. .LP
  238. By splitting out the device-specific code (by separating clients from servers
  239. and \fIdiX\fP from \fIddX\fP) and then providing portable utility libraries 
  240. (\fImi\fP, \fImfb\fP, \fIcfb\fP, and \fIcfb\fP) that may be used to 
  241. implement the non-portable portions
  242. of the system, much of the code can be reused across many platforms, ranging
  243. from personal computers to supercomputers.
  244. .NH 1
  245. Configuring the Software Build Process
  246. .LP
  247. In practice, porting X to a new platform typically requires adding support 
  248. in the operating system-specific networking routines and mixing together
  249. pieces of machine-independent and device-specific code to access the
  250. input and output hardware.  Although this approach is very portable, it
  251. increases the complexity of the build process as different implementations 
  252. require different subsets.  One solution is to litter the 
  253. source code with machine-specific compiler directives controlling which 
  254. modules areas get built on a given platform.  However, this rapidly leads to 
  255. sources that are hard to understand and even harder to maintain.
  256. .LP
  257. A more serious problem with this approach is that it requires 
  258. configuration information to be replicated in almost every module.  In
  259. addition to being highly prone to error, modifying or adding a new 
  260. configuration becomes extremely difficult.  In contrast, collecting the 
  261. various options and parameters in a single location makes it possible for
  262. someone to reconfigure the system without having to 
  263. understand how all of the modules fit together.
  264. .LP
  265. Although sophisticated software management systems are very useful, they 
  266. tend to be found only on specific platforms.  Since the configuration system 
  267. must be working before a build can begin, the MIT releases try to adhere to
  268. the following principles:
  269. .RS .5in
  270. .Ip
  271. Use existing tools to do the build (e.g. \fImake\fP) where possible; writing
  272. complicated new tools simply adds to the amount of software that has to be
  273. bootstrapped.
  274. .Ip
  275. Keep it simple.  Every platform has a different set of extensions and bugs.
  276. Plan for the least common denominator by only using 
  277. the core features of known tools; don't rely on vendor-specific features.
  278. .Ip
  279. Providing sample implementations of simple tools that are not available on
  280. all platforms (e.g. a BSD-compatible \fIinstall\fP script for System V) is
  281. very useful.
  282. .Ip
  283. Machine-dependencies should be centralized to make reconfiguration easy.
  284. .Ip
  285. Site-wide options (e.g. default parameters such as directory names, 
  286. file permissions, and enabling particular features) should be stored in
  287. only one location.
  288. .Ip
  289. Rebuilding within the source tree without losing any of the configuration
  290. information must be simple.
  291. .Ip
  292. It should be possible to configure external software without requiring 
  293. access to the source tree.
  294. .RE
  295. .LP
  296. One approach is to add certain programming constructs (particularly 
  297. conditionals and iterators) to the utility used to actually build the 
  298. software (usually \fImake\fP; see [Lord 88]).  Although this an attractive
  299. solution, limits on time and personnel made implementing and maintaining
  300. such a system impractical for X.
  301. .LP
  302. The MIT releases of X employ a less ambitious approach that uses existing tools
  303. (particularly \fImake\fP and \fIcpp\fP).  \fIMakefiles\fP
  304. are generated automatically by a small,
  305. very simple program named \fIimake\fP (written by Todd Brunhoff of Tektronix)
  306. that combines a template listing variables and rules
  307. that are common to all 
  308. \fIMakefiles\fP, a machine- and a site-specific configuration file,
  309. a set of rule functions written as \fIcpp\fP macros,
  310. and simple specifications of targets and sources called \fIImakefiles\fP.
  311. Since the descriptions of the inputs and outputs of the build are separated
  312. from the commands that implement them, machine dependencies such as the
  313. following can be controlled from a single location:
  314. .RS .5in
  315. .Ip
  316. Some versions of \fImake\fP require that the variable SHELL to be set to the
  317. name of the shell that should be used to execute \fImake\fP commands.
  318. .Ip
  319. The names of various special \fImake\fP variables (e.g. MFLAGS vs. MAKEFLAGS) 
  320. differ between versions.
  321. .Ip
  322. Special directives to control interaction with source code maintenance systems
  323. are required by some versions of \fImake\fP.
  324. .Ip
  325. Rules for building targets (e.g. \fIranlib\fP,
  326. lint options, executable shell scripts, selecting alternate compilers)
  327. differ among platforms.
  328. .Ip
  329. Some systems require special compiler options (e.g. increased internal
  330. table sizes, floating point options) for even simple programs.
  331. .Ip
  332. Some systems require extra libraries when linking programs.
  333. .Ip
  334. Not all systems need to compile all sources.
  335. .Ip
  336. Configuration parameters may need to be passed to some (such as -DDNETCONN
  337. to compile in DECnet support) or all (such as -DSYSV to select System V code)
  338. programs as preprocessor symbols.
  339. .Ip
  340. Almost all systems organize header files differently, making
  341. static dependencies in \fIMakefiles\fP impossible to generate.
  342. .RE
  343. .LP
  344. By using the C preprocessor, \fIimake\fP provides a familiar set of interfaces
  345. to conditionals, macros, and symbolic constants.  Common operations, such as
  346. compiling programs, creating libraries,    creating shell scripts, and
  347. managing subdirectories, can be described in a concise, simple way.  
  348. Figure 3 shows the \fIImakefile\fP used to build a manual page browser
  349. named \fIxman\fP (written by Chris Peterson program of the MIT X Consortium,
  350. based on an implementation for X10 by Barry Shein):
  351. .sp 1
  352. .KF
  353. .RS 1in
  354. .nf
  355. .ft L
  356. DEFINES =  -DHELPFILE=\e"$(LIBDIR)$(PATHSEP)xman.help\e"
  357. LOCAL_LIBRARIES =  $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
  358. SRCS =  ScrollByL.c handler.c man.c pages.c buttons.c help.c menu.c search.c \e
  359.         globals.c main.c misc.c tkfuncs.c
  360. OBJS =  ScrollByL.o handler.o man.o pages.o buttons.o help.o menu.o search.o \e
  361.         globals.o main.o misc.o tkfuncs.o
  362. INCLUDES =  -I$(TOOLKITSRC) -I$(TOP)
  363.  
  364. ComplexProgramTarget (xman)
  365. InstallNonExec (xman.help, $(LIBDIR))
  366.  
  367. .ft P
  368. .fi
  369. .RE
  370. .DS C
  371. .sp 1
  372. \fBFigure 3:\fP  \fIImakefile\fP used by a typical client program
  373. .DE
  374. .KE
  375. .sp 1
  376. .LP
  377. This application requires the name of the directory in which its help file is
  378. installed (which is a configuration parameter), several libraries, and 
  379. various X header files.  The macro
  380. \fIComplexProgramTarget\fP generates the appropriate rules to build
  381. the program, install it, compute dependencies, and remove old versions of
  382. the program and its object files.  The \fIInstallNonExec\fP macro generates
  383. rules to install \fIxman\fP's help file with appropriate permissions.
  384. .NH 1
  385. Generating Makefiles
  386. .LP
  387. Although \fIimake\fP is a fairly powerful tool, it is a very simple program.
  388. All of the real work is performed by the template, rule, and configuration
  389. files.  The version currently used at MIT (which differs somewhat from the 
  390. version supplied in the last release of X)
  391. uses symbolic constants for all configuration 
  392. parameters so that they may be overridden or used by other parameters.
  393. General build issues (such as the command to execute to run the compiler) 
  394. are isolated from X issues (such as where should application default files be
  395. installed) by splitting the template as shown in Figure 4.
  396. .KF
  397. .sp 1
  398. .DS C
  399. .TS
  400. box tab (%) ;
  401. l s s
  402. l   _   l
  403. l | l | l
  404. l   _   l
  405. l   _   l
  406. l | l | l
  407. l   _   l
  408. l   _   l
  409. l | l | l
  410. l   _   l
  411. l   _   l
  412. l | l | l
  413. l   _   l
  414. l   _   l
  415. l | l | l
  416. l   _   l .
  417. Imake.tmpl
  418.  %
  419. %#include "\fImachine\fP.cf"%
  420.  %
  421.  %
  422. %#include "site.def"%
  423.  %
  424.  %
  425. %#include "Project.tmpl"%
  426.  %
  427.  %
  428. %#include "Imake.rules"%
  429.  %
  430.  %
  431. %#include "./Imakefile"%
  432.  %
  433. .TE
  434. .sp 1
  435. \fBFigure 4:\fP  structure of \fIimake\fP template used by X
  436. .DE
  437. .sp 1
  438. .KE
  439. .LP
  440. This template instructs \fIimake\fP to perform the following steps when
  441. creating a \fIMakefile\fP:
  442. .RS .5in
  443. .IP 1.
  444. Using conditionals, \fIImake.tmpl\fP determines the machine for which the
  445. build is being configured and includes a machine-specific configuration file 
  446. (usually named \fImachine\fP.cf).  Using the C preprocessor to define various
  447. symbols, this configuration file sets the major and minor version 
  448. numbers of the operating system, the names of any servers 
  449. to build, and any special programs (such as alternate compilers)
  450. or options (usually to increase internal table sizes) that
  451. need to be used during the build.  Defaults are provided for
  452. all parameters, so .cf files need only describe how this particular
  453. platform differs from ``generic'' UNIX System V or BSD UNIX.
  454. Unlike previous versions of the \fIimake\fP configuration files,
  455. when new parameters are added, only the systems which are
  456. effected by them need to be updated.
  457. .IP 2.
  458. Next, a site-specific file (named \fIsite.def\fP) is included so
  459. that parameters from the .cf files may be overridden or
  460. defaults for other options provided.  This is typically used
  461. by a site administrator to set the names of the various
  462. directories into which the software should be installed.
  463. Again, all of the standard \fIcpp\fP constructs may be used.
  464. .IP 3.
  465. A project-specific file (named \fIProject.tmpl\fP) is 
  466. included to set various parameters used by the particular
  467. software package being configured.  By separating the 
  468. project parameters (such as directories, options, etc.)
  469. from build parameters (such as compilers, utilities, etc.),
  470. the master template and the .cf files can be shared among various development
  471. efforts.  
  472. .IP 4.
  473. A file containing the set of \fIcpp\fP rules (named \fIImake.rules\fP)
  474. is included.  This is where the various macro functions used
  475. in the master template and the per-directory description
  476. files (named \fIImakefile\fP) are defined.  These rules typically
  477. make very heavy use of the \fImake\fP variables defined in
  478. \fIImake.tmpl\fP so that a build's configuration may be changed without
  479. having to edit this file.
  480. .IP 5.
  481. The \fIImakefile\fP describing the input files and output targets 
  482. for the current directory is included.  This file is supplied
  483. by the programmer instead of a \fIMakefile\fP.  The functions that
  484. it invokes are translated by \fIcpp\fP into series of \fImake\fP 
  485. rules and targets.
  486. .IP 6.
  487. Finally, \fImake\fP rules for recreating the \fIMakefile\fP and managing
  488. subdirectories are appended, and the result is written out as the
  489. new \fIMakefile\fP.
  490. .RE
  491. .LP
  492. \fIImake\fP, along with a separate tool (named \fImakedepend\fP, also 
  493. written by
  494. Brunhoff) that generates \fIMakefile\fP dependencies
  495. between object files and the source files used to build them, allows
  496. properly configured \fIMakefiles\fP to be regenerated quickly and correctly.  
  497. By isolating the machine- and site-specifics from the programmer,
  498. \fIimake\fP is much like a well-developed text formatter: both allow 
  499. the writer to concentrate on the content, rather than the production, of a 
  500. document.
  501. .NH 1
  502. How X uses \fIimake\fP
  503. .LP
  504. Development of X at MIT is currently done on more than half a dozen 
  505. different platforms, each of which is running a different operating system.
  506. A common source pool is shared across those machines that support
  507. symbolic links and NFS by creating trees of links pointing
  508. back to the master sources (similar to the object trees of [Harrison 88]).
  509. Editing and source code control is done in the master sources and builds are 
  510. done in the link trees.  
  511. .LP
  512. .ne 4
  513. A full build is done by creating a fresh link tree and invoking a
  514. simple, stub top-level \fIMakefile\fP which:
  515. .RS .5in
  516. .IP 1.
  517. compiles \fIimake\fP.
  518. .IP 2.
  519. builds the real top-level \fIMakefile\fP.
  520. .IP 3.
  521. builds the rest of the \fIMakefiles\fP using the new top-level \fIMakefile\fP.
  522. .IP 4.
  523. removes any object files left over from the previous build.
  524. .IP 5.
  525. builds the header file tree, and
  526. computes and appends the list of dependencies between object files and sources
  527. to the appropriate \fIMakefiles\fP.
  528. .IP 6.
  529. and finally, compiles all of the sources.
  530. .RE
  531. .LP
  532. If the build completes successfully, programs, libraries, data files, and
  533. manual pages may then be installed.  By keeping object files out of the master
  534. source tree, backups and releases can be done easily and efficiently.  By
  535. substituting local copies of particular files for the appropriate links, 
  536. developers can work without disturbing others.
  537. .NH 1
  538. Limitations
  539. .LP
  540. Although the system described here is very useful, it isn't perfect.  
  541. Differences
  542. between utilities on various systems places a restriction on how well
  543. existing tools can be used.  One of the reasons why \fIimake\fP is a program
  544. instead of a trivial invocation of the C preprocessor is that some \fIcpp\fP's
  545. collapse tabs into spaces while others do not.  Since \fImake\fP uses
  546. tabs to separate commands from targets, \fIimake\fP must sometimes reformat
  547. the output from \fIcpp\fP so that a valid \fIMakefile\fP is generated.
  548. .LP
  549. Since \fIcpp\fP only provides global 
  550. scoping of symbolic constants, parameters
  551. are visible to the whole configuration system.  For larger projects, this
  552. approach will probably prove unwieldy both to the people trying to maintain 
  553. them and to the preprocessors that keep the entire symbol table in memory.
  554. .LP
  555. The macro facility provided by \fIcpp\fP is convenient because it is available
  556. on every platform and it is familar to most people.  However, a better
  557. language with real programming constructs might provide a better interface.
  558. The notions of describing one platform in terms of another and providing
  559. private configuration parameters map intriguingly well into the models used
  560. in object management systems.
  561. .NH 1
  562. Summary and Observations
  563. .LP
  564. The sample implementation of the X Window System from MIT takes advantage
  565. of a system architecture that goes to great lengths to isolate
  566. device-dependencies.  By selectively using portable versions of
  567. the device-specific functions, a developer moving X to a new platform can
  568. quickly get an initial port up and running very quickly.
  569. .LP
  570. To manage the various combinations of modules and to cope with the 
  571. differing requirements of every platform and site, X uses a
  572. utility named \fIimake\fP
  573. to separate the description of sources and targets from the
  574. details of how the software is actually built.  Using as few external
  575. tools as possible, this mechanism allows support for new platforms to be
  576. added with relatively little effort.
  577. .LP
  578. Although the approaches taken by MIT will not work for everyone, several of
  579. its experiences may be useful in other projects:
  580. .RS .5in
  581. .Ip
  582. Even if portability isn't a goal now, it probably will become one sooner
  583. than expected.
  584. .Ip
  585. Just as in other areas, it frequently pays to periodically stand back 
  586. from a problem and see whether or not a simple tool will help.  With
  587. luck and the right amount of abstracting it may even solve several
  588. problems at once.  
  589. .Ip
  590. Be wary of anything that requires manual intervention.
  591. .Ip
  592. And finally, there is no such thing as portable software, only software that
  593. has been ported.
  594. .RE
  595. .NH 1
  596. References
  597. .LP
  598. .IP "\[Harrison 88\]"
  599. .br
  600. ``Rtools: Tools for Software Management in a Distributed Computing
  601. Environment,'' Helen E. Harrison, Stephen P. Schaefer, Terry S. Yoo,
  602. \fIProceedings of the Usenix Association Summer Conference\fP, 
  603. June 1988, 85-94.
  604. .IP "\[Lord 88\]"
  605. .br
  606. ``Tools and Policies for the Hierarchical Management of Source Code 
  607. Development,'' Thomas Lord, \fIProceedings of the Usenix Association
  608. Summer Conference\fP, June 1988, 95-106.
  609. .IP "\[Scheifler 88\]"
  610. .br
  611. \fIX Window System: C Library and Protocol Reference\fP, Robert Scheifler, 
  612. James Gettys, and Ron Newman, Digital Press, Bedford, MA, 1988.
  613.  
  614.  
  615. .\
  616. .\XXX - Xos.h:
  617. .\    o  12 character file names
  618. .\    o  isolate system calls
  619. .\    o  avoid tricky coding
  620. .\    o  index vs. strchr
  621. .\    o  bcopy
  622. .\    o  test on as wide a range of systems as possible
  623. .\
  624.