home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / xvi / part01 < prev    next >
Encoding:
Text File  |  1992-10-22  |  55.8 KB  |  1,864 lines

  1. Newsgroups: comp.sources.misc
  2. From: jmd@cyclone.bt.co.uk (John Downey)
  3. Subject:  v33i010:  xvi - portable multi-window vi-like editor, Part01/18
  4. Message-ID: <csm-v33i010=xvi.130853@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: db12b2eefb14a48da0af9ee0bebc6ed3
  6. Date: Fri, 23 Oct 1992 18:10:03 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jmd@cyclone.bt.co.uk (John Downey)
  10. Posting-number: Volume 33, Issue 10
  11. Archive-name: xvi/part01
  12. Environment: Unix, MS-DOS, OS/2, QNX
  13.  
  14. This is a source release of the Xvi editor (derived from "STEVIE"), a
  15. clone of the UNIX editor `vi'. The program was originally developed
  16. for the Atari ST, but has been ported to UNIX, MS-DOS, OS/2 and QNX as
  17. well.
  18.  
  19. Xvi is a portable multi-window version of `vi'. In spite of its name,
  20. there is, as yet, no X-Windows-specific version of it, but work is
  21. still in progress. Existing versions use text windows separated by
  22. horizontal status lines on character mode displays.  The windows may
  23. represent different files being edited, or different views on to the
  24. same file.
  25.  
  26. Unix, MS-DOS and QNX versions have now been in regular use by the
  27. authors, and many of our colleagues, for about three and a half years,
  28. and the editor's behaviour seems fairly satisfactory.
  29.  
  30. This source code is not in the public domain, but is provided for free,
  31. subject to the license conditions set out in the COPYING file.
  32.  
  33. The files included in the `doc' directory are:
  34.  
  35. README
  36.     What you're reading.
  37.  
  38. COPYING
  39.     The license under which xvi is provided. Please read and
  40.     understand this license if you are going to re-distribute xvi.
  41.  
  42. help
  43.     The help file used by xvi.
  44.  
  45. source.ms
  46. source.lst
  47.     A guide to the Xvi source code, including information about
  48.     how to port Xvi to different systems. Provided in [nt]roff -ms
  49.     source & nroff output formats. A PostScript version may follow
  50.     later.
  51.  
  52. summary.ms
  53. summary.lst
  54.     A document describing the differences between vi and xvi.
  55.     Same formats.
  56.  
  57. xvi.1
  58. xvi.lst
  59.     A Unix-style manual page, in [nt]roff -man & nroff output
  60.     formats.
  61.  
  62. Chances are, if you're on UNIX, MS-DOS or QNX, you'll be able
  63. to compile xvi without changing anything. Change directory
  64. into `src', pick a makefile and go for it.
  65.  
  66. If that doesn't work, read doc/source.ms.
  67.  
  68. Chris & John Downey
  69. October 1992
  70.  
  71. #! /bin/sh
  72. # This is a shell archive.  Remove anything before this line, then feed it
  73. # into a shell via "sh file" or similar.  To overwrite existing files,
  74. # type "sh file -c".
  75. # Contents:  xvi xvi/doc xvi/doc/source.ms xvi/src xvi/src/tags.c
  76. # Wrapped by kent@sparky on Thu Oct 22 09:03:40 1992
  77. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  78. echo If this archive is complete, you will see the following message:
  79. echo '          "shar: End of archive 1 (of 18)."'
  80. if test ! -d 'xvi' ; then
  81.     echo shar: Creating directory \"'xvi'\"
  82.     mkdir 'xvi'
  83. fi
  84. if test ! -d 'xvi/doc' ; then
  85.     echo shar: Creating directory \"'xvi/doc'\"
  86.     mkdir 'xvi/doc'
  87. fi
  88. if test -f 'xvi/doc/source.ms' -a "${1}" != "-c" ; then 
  89.   echo shar: Will not clobber existing file \"'xvi/doc/source.ms'\"
  90. else
  91.   echo shar: Extracting \"'xvi/doc/source.ms'\" \(44132 characters\)
  92.   sed "s/^X//" >'xvi/doc/source.ms' <<'END_OF_FILE'
  93. X.\"========== Redefine NH to avoid widowing
  94. X.rn NH Nh
  95. X.nr nH 0
  96. X.de NH
  97. X.br
  98. X.if \\n(nH=\\$1 .sp 0.3i
  99. X.nr nH 1
  100. X.ne 1i
  101. X.Nh \\$1 \\$2
  102. X..
  103. X.\"========== Example macros
  104. X.de Ex
  105. X.br
  106. X.ne 0.75i
  107. X.IP "\fB\\$1\fP\ \ \ " \\$2
  108. X..
  109. X.de Ey
  110. X.sp -0.3v
  111. X.IP "\fB\\$1\fP\ \ \ " \\$2
  112. X..
  113. X.\"========== Put string in boldface & surround with quotes
  114. X.de qB
  115. X\%\*Q\fB\\$1\fP\*U\\$2
  116. X..
  117. X.\"========== 11 on 13 looks so much better than 10 on 12
  118. X.nr PS 11
  119. X.nr VS 13
  120. X.ps 11
  121. X.vs 13p
  122. X.nr PI 0.5i
  123. X.nr HM 0.9i
  124. X.nr FM 0.9i
  125. X.if n .nr PO 0.5i
  126. X.if n .nr LL 6.5i
  127. X.\"========== Turn hyphenation off, and make sure it stays off
  128. X.nh
  129. X.rm hy
  130. X.\"========== Headers in italics helps them to stand out from the text
  131. X.OH '\fIXvi Source Code Notes\fP''\fI%\fP'
  132. X.EH '\fI%\fP''\fIXvi Source Code Notes\fP'
  133. X.OF '\fI25th September 1992\fP''\fIPage %\fP'
  134. X.EF '\fIPage %\fP''\fI25th September 1992\fP'
  135. X.\"===========================================================================
  136. X.TL
  137. XNotes on the Xvi Source Code
  138. X.AU
  139. XChris Downey
  140. XJohn Downey
  141. X.AB no
  142. X\fBXvi\fP (pronounced \fIecks-vee-eye\fP)
  143. Xis a free, portable, multi-window implementation of the popular
  144. X.UX
  145. Xeditor \fBvi\fP.
  146. X.LP
  147. XThis document contains information on how
  148. Xto port \fBxvi\fP to systems not currently supported.
  149. XIt also explains
  150. Xhow the \fBxvi\fP source code is arranged into modules,
  151. Xand explains some of the data structures which are used,
  152. Xso that modifications may be made if and when necessary
  153. Xto the editor itself.
  154. X.AE
  155. X.\"===========================================================================
  156. X.NH 1
  157. XINTRODUCTION
  158. X.LP
  159. X\fBXvi\fP is intended to be portable to just about any system.
  160. XThis is one of the central reasons for its existence; the
  161. Xauthors wish to be able to use the same editor everywhere.
  162. X.LP
  163. XThe main body of the editor is (supposedly) fully portable,
  164. Xrelying only on standard facilities defined by the White
  165. XBook, and on a set of \fIprimitives\fP which are provided by a set
  166. Xof one or more modules for each operating system.
  167. XIf
  168. X.B __STDC__
  169. Xis defined, certain ANSI C facilities will be used,
  170. Xbut the editor will compile with non-ANSI compilers.
  171. X.LP
  172. XTherefore, in order to port \fBxvi\fP to a new system, all that is
  173. Xnecessary is to provide the defined set of \fIprimitives\fP, and
  174. Xthen build the editor.
  175. XOr at least, that's the idea; we have refined the set of primitives
  176. Xas we port the editor to new environments, and it's getting pretty easy now.
  177. X.LP
  178. XThe rest of this document is divided into sections as follows:
  179. X.IP "\fISection 2: System-Specific Modules\fP"
  180. XThis section deals with the layout of source files and makefiles
  181. Xwhich you will have to deal with when porting \fBxvi\fP.
  182. X.IP "\fISection 3: Primitives Provided by xvi\fP"
  183. XDiscusses what primitives are provided by the main body of the editor source
  184. Xcode for use by the system interface code.
  185. X.IP "\fISection 4: System Interface\fP"
  186. XExplains the primitives which need to be provided
  187. Xin order to make \fBxvi\fP work.
  188. X.IP "\fISection 5: Data Structures\fP"
  189. XDetails the internal data types used in the editor,
  190. Xand any functions available for operating on those types.
  191. X.IP "\fISection 6: Source Files\fP"
  192. XLists the source files comprising the editor,
  193. Xand explains what functionality is provided by each one.
  194. X.\"===========================================================================
  195. X.NH 1
  196. XSYSTEM-SPECIFIC MODULES
  197. X.LP
  198. XThe system-specific code normally consists of three (or more) files;
  199. Xa
  200. X.qB .c
  201. Xfile, a
  202. X.qB .h
  203. Xfile, and a makefile.
  204. XFor example:
  205. X.DS
  206. X.B
  207. Xqnx.c
  208. Xqnx.h
  209. Xmakefile.qnx
  210. X.R
  211. X.DE
  212. Xcomprise the system-specific module for the QNX operating system.
  213. X.LP
  214. XIn most cases, the system-specific code is divided into two
  215. Xor more modules, where one (called the \fIsystem interface module\fP)
  216. Xis concerned with general interactions with the operating system
  217. Xand the other (called the \fIterminal interface module\fP)
  218. Xis designed for a specific interface to a display and keyboard
  219. X(and possibly, a mouse).
  220. X.LP
  221. XFor example, the generic
  222. X.UX
  223. Ximplementation has
  224. X.B unix.c
  225. Xand
  226. X.B unix.h
  227. Xfor the system interface module, and
  228. X.B termcap.c
  229. Xand
  230. X.B termcap.h
  231. Xfor the terminal interface module; this should
  232. Xwork reasonably with any full-duplex terminal that can be
  233. Xdescribed in the
  234. X.B termcap
  235. Xdatabase.
  236. XOn consoles with memory-mapped displays, or systems with graphic user
  237. Xinterfaces, however, it may be possible to achieve faster
  238. Xdisplay updating, and perhaps other benefits, by replacing
  239. Xthe
  240. X.B termcap
  241. Xmodule with another one that makes better use of
  242. Xwhatever facilities are available.
  243. XFor instance, there is an experimental version for SunView,
  244. Xwhich allows mouse input on Sun workstations running the SunView window system.
  245. X.LP
  246. XOn the other hand, the
  247. X.B termcap -specific
  248. Xroutines might
  249. Xconceivably be useful on some other operating systems (such
  250. Xas VMS), so in general it seemed a good idea to make the
  251. X.B termcap -specific
  252. Xroutines a separate module.
  253. X.LP
  254. XThe current \%MS-DOS implementation has a separate terminal
  255. Xinterface module, which is designed specifically for IBM PC
  256. Xcompatible computers.
  257. XThis is in the files
  258. X.DS
  259. X.B
  260. Xibmpc_a.asm
  261. Xibmpc_c.c
  262. Xibmpc.h
  263. X.R
  264. X.DE
  265. XThe first of these is written in assembly language because
  266. Xthere are not enough routines common to the various \%MS-DOS
  267. XC compilers which reliably access the display and keyboard at
  268. Xa low enough level.
  269. X.LP
  270. XThe hardware-independent system interface module for \%MS-DOS is in
  271. X.DS
  272. X.B
  273. Xmsdos_a.asm
  274. Xmsdos_c.c
  275. Xmsdos.h
  276. X.R
  277. X.DE
  278. XThe first of these is written in assembly
  279. Xlanguage for the same reason as is
  280. X.B ibmpc_a.asm .
  281. X.LP
  282. XTheoretically, different terminal interface modules could be
  283. Xwritten for \%MS-DOS systems running on hardware which is not
  284. XIBM-compatible but, unfortunately, such systems seem to be
  285. Xvirtually extinct nowadays.
  286. X.LP
  287. XSometimes more than one makefile is provided, as in the case of
  288. X.UX ,
  289. Xwhere different versions work in slightly different ways.
  290. X.LP
  291. XIt is, of couse, not necessary to provide all \(em or any \(em
  292. Xof these files for a particular implementation; this is just a convention.
  293. XThe makefile(s) for each system determine what
  294. Xfiles are used in the compilation of the editor.
  295. X.LP
  296. XThe following porting modules are available at present:
  297. X.\" ----------------------------------------------------------
  298. X.\" Note: this table does not fit very well with nroff output,
  299. X.\" so please try to avoid widening it if you add anything.
  300. X.TS
  301. Xcenter, box;
  302. Xc|c|c
  303. Xl|l|l.
  304. XSystem    Makefile    Source Files
  305. X_
  306. X.sp 0.5v
  307. XUNIX
  308. X  BSD    \fBmakefile.bsd\fP    \fBunix.[ch] termcap.[ch]\fP
  309. X  System V \fB\(dg\fP    \fBmakefile.usg\fP    \fBunix.[ch] termcap.[ch]\fP
  310. X  AIX    \fBmakefile.aix\fP    \fBunix.[ch] termcap.[ch]\fP
  311. X  ULTRIX    \fBmakefile.ult\fP    \fBunix.[ch] termcap.[ch]\fP
  312. X  Xenix \fB\(dg\fP    \fBmakefile.xen\fP    \fBunix.[ch] termcap.[ch]\fP
  313. X  POSIX (e.g. BSDI)    \fBmakefile.pos\fP    \fBunix.[ch] termcap.[ch]\fP
  314. X  SunOS    \fBmakefile.sun\fP    \fBunix.[ch] termcap.[ch]\fP
  315. X  SunView    \fBmakefile.sv\fP    \fBunix.[ch] sunview.h\fP
  316. X        \fBsunfront.c sunback.c\fP
  317. X        \fBxvi.icn\fP
  318. X.sp 0.5v
  319. X_
  320. X.sp 0.5v
  321. X\%MS-DOS        \fBmsdos_c.c msdos.h\fP
  322. X        \fBibmpc_c.c ibmpc.h\fP
  323. X.sp 0.5v
  324. X  Microsoft C 5.*    \fBmakefile.msc\fP    \fB8086mm.inc ibmpc_a.asm\fP
  325. X  & MASM 5.*        \fBmsdos_a.asm\fP
  326. X.sp 0.5v
  327. X  Microsoft Quick C    \fBmakefile.qc\fP    \fB8086mm.inc ibmpc_a.asm\fP
  328. X  & MASM 5.*        \fBmsdos_a.asm\fP
  329. X.sp 0.5v
  330. X  Zortech C++ 2.*    \fBmakefile.zc2\fP    \fB8086mm.inc ibmpc_a.asm\fP
  331. X  & MASM 5.*        \fBmsdos_a.asm\fP
  332. X.sp 0.5v
  333. X  Zortech C++ 3.*    \fBmakefile.zc3\fP    \fB8086mm.inc ibmpc_a.asm\fP
  334. X  & MASM 5.*        \fBmsdos_a.asm\fP
  335. X.sp 0.5v
  336. X  Zortech C++ 3.*
  337. X  386 protected mode    \fBmakefile.386\fP    \fBpc386.[ch]\fP
  338. X.sp 0.5v
  339. X_
  340. X.sp 0.5v
  341. XOS/2 \fB\(dg\fP
  342. X  Version 1, text mode
  343. X  Microsoft C 5.1    \fBmakefile.os2\fP    \fBos2vio.[ch]\fP
  344. X  & MASM 5.1        \fBi286.asm\fP
  345. X.sp 0.5v
  346. X_
  347. X.sp 0.5v
  348. XQNX
  349. X  Version 2/3 (CII)    \fBmakefile.qnx\fP    \fBqnx.[ch]\fP
  350. X  Version 4 (Watcom C)    \fBmakefile.qn4\fP    \fBunix.[ch] termcap.[ch]\fP
  351. X.sp 0.5v
  352. X_
  353. X.sp 0.5v
  354. XTOS \fB\(dg\fP
  355. X  Lattice C    \fBmakefile.tos\fP    \fBtos.[ch] tos.lnk\fP
  356. X.sp 0.5v
  357. X.TE
  358. X.IP \fB\(dg\fP 2
  359. XVersions marked with
  360. X.B \(dg
  361. Xprobably do not work, as systems
  362. Xhave not been recently available to the authors for testing.
  363. X.\"===========================================================================
  364. X.NH 1
  365. XPRIMITIVES PROVIDED BY XVI
  366. X.NH 2
  367. XGeneral Definitions
  368. X.LP
  369. XThe file
  370. X.B xvi.h
  371. Xshould be included by all system-specific modules;
  372. Xthis file should also be edited
  373. Xso that a system-specific header
  374. Xfile (or files), as determined by a predefined keyword,
  375. Xwill be included.
  376. X.LP
  377. XFor instance, under
  378. X.UX ,
  379. Xthe word
  380. X.B UNIX
  381. Xis defined by passing the
  382. X.B -DUNIX
  383. Xflag to the C compiler
  384. Xfrom the makefile, and
  385. X.B xvi.h
  386. Xcontains the following lines:
  387. X.DS
  388. X.B
  389. X#ifdef UNIX
  390. X#   include "unix.h"
  391. X#endif
  392. X.R
  393. X.DE
  394. Xin order to obtain the
  395. X.UX -related
  396. Xdefinitions from that header file.
  397. X.LP
  398. XAmong the definitions in
  399. X.B xvi.h
  400. Xare the following:
  401. X.Ex bool_t
  402. XA Boolean type having values
  403. X.B TRUE
  404. Xor
  405. X.B FALSE .
  406. X.Ex const
  407. X.Ey volatile
  408. XThese are defined out when
  409. X.B __STDC__
  410. Xis not defined,
  411. Xso that it is always safe to use them.
  412. X.LP
  413. X.B xvi.h
  414. Xalso includes various other header files which are needed.
  415. XThe following system header files are always included:
  416. X.DS
  417. X.B
  418. Xstdio.h
  419. Xctype.h
  420. Xsignal.h
  421. Xstring.h
  422. X.R
  423. X.DE
  424. XThese files are included if
  425. X.B __STDC__
  426. Xis defined:
  427. X.DS
  428. X.B
  429. Xstddef.h
  430. Xstdlib.h
  431. Xlimits.h
  432. X.R
  433. X.DE
  434. Xand if
  435. X.B __STDC__
  436. Xis not defined,
  437. X.B xvi.h
  438. Xwill provide its own
  439. Xdefinitions for the following:
  440. X.DS
  441. X.B
  442. XINT_MAX
  443. XINT_MIN
  444. XULONG_MAX
  445. X
  446. XFILE    *fopen();
  447. Xchar    *malloc();
  448. Xchar    *getenv();
  449. X.R
  450. X.DE
  451. XFinally, one of the following header files will be included:
  452. X.DS
  453. X.B
  454. Xstdarg.h
  455. Xvarargs.h
  456. X.R
  457. X.DE
  458. Xdepending on whether
  459. X.B __STDC__
  460. Xis defined or not.
  461. XIn order to make coding of
  462. X.B varargs
  463. Xfunctions easier, a macro
  464. X.B VA_START ()
  465. Xis defined, which takes the same arguments as the
  466. XANSI-style
  467. X.B va_start (),
  468. Xbut which is also available in non-ANSI
  469. Xenvironments (e.g. BSD).
  470. X.LP
  471. XIn order to make it possible to use ANSI-style prototypes
  472. Xfor function declarations, but still allow compilation under
  473. Xnon-ANSI environments, the following macro is provided:
  474. X.DS
  475. X.B
  476. X#ifdef __STDC__
  477. X#   define  P(args) args
  478. X#else
  479. X#   define  P()     ()
  480. X#endif
  481. X.R
  482. X.DE
  483. Xso that function declarations may be specified thus:
  484. X.DS
  485. X.B
  486. Xextern FILE *fopen P((const char *, const char *));
  487. X.R
  488. X.DE
  489. XPlease use this facility when you provide declarations for
  490. Xyour system primitives, unless your system always uses an
  491. XANSI compiler.
  492. X.\"===========================================================================
  493. X.NH 2
  494. XParameters
  495. X.LP
  496. XAn important facility provided for use by system-specific
  497. Xmodules is access to the editor's parameter table.
  498. XThis is achieved by means of some apparent functions,
  499. Xand a set of
  500. X.B #define d
  501. Xtoken values.
  502. XThe functions are:
  503. X.Ex "void set_param(int n, val)"
  504. XThis function sets the indicated parameter to the
  505. Xpassed value, which must be of an appropriate type.
  506. XParameter values may be obtained by means of the following
  507. Xfunctions (actually macros):
  508. X.Ex "char *Ps(int n)"
  509. Xreturn value of string parameter
  510. X.Ex "int Pn(int n)"
  511. Xreturn value of numeric parameter
  512. X.Ex "bool_t Pb(int n)"
  513. Xreturn value of boolean parameter
  514. X.Ex "char **Pl(int n)"
  515. Xreturn value of list parameter (a
  516. X\fBNULL\fP-terminated array of character pointers)
  517. X.Ex "int Pen(int n)"
  518. Xreturn numeric value (index) of enumerated parameter
  519. X.Ex "char **Pes(int n)"
  520. Xreturn string value of enumerated parameter
  521. X.LP
  522. XIn all cases, the \fBint n\fP argument is the index of the parameter
  523. Xin the table; a set of
  524. X.B #define s
  525. Xis provided, of the form:
  526. X.DS
  527. X.B P_name
  528. X.DE
  529. Xwhich map the parameter names into integral values.
  530. XThus, for example, we might obtain the value of the
  531. X.B colour
  532. Xparameter:
  533. X.DS
  534. X.B
  535. Xcolour = Pn(P_colour);
  536. X.R
  537. X.DE
  538. Xor set the value of the
  539. X.B helpfile
  540. Xparameter:
  541. X.DS
  542. X.B
  543. Xset_param(P_helpfile, "/usr/lib/xvi/help");
  544. X.R
  545. X.DE
  546. X.\"===========================================================================
  547. X.NH 1
  548. XSYSTEM INTERFACE
  549. X.NH 2
  550. XIntroduction
  551. X.LP
  552. XThere follows a list of the primitives which must be provided
  553. Xeither by the system interface module or by the underlying OS.
  554. XNote that it is perfectly acceptable to implement functions or external
  555. Xvariables as
  556. Xmacros
  557. Xso long as they \*Qlook the same\*U as the definitions
  558. Xbelow.
  559. XAs a guideline, anything which is (a) in capitals, or (b) is a
  560. X\fBconst\fP variable, will be implemented as a
  561. X.B #define
  562. Xfor most
  563. Xsystems.
  564. X.LP
  565. XWhen you want to actually do the port, it is highly
  566. Xrecommended that you copy the system-specific files for the
  567. Xsystem which seems closest to your own, and modify those
  568. Xfiles, rather than starting from scratch.
  569. X.LP
  570. XAll the following symbols should be defined in the system
  571. Xinterface module, or by standard header files already included
  572. Xby
  573. X.B xvi.h ,
  574. Xor by other header files explicitly included by
  575. Xthe system-specific header file:
  576. X.\" ----- Standard items, not always available -----
  577. X.Ex "const unsigned int MAXPATHLEN"
  578. XThe maximum number of characters in a pathname.
  579. X.Ex "const unsigned int MAXNAMLEN"
  580. XThe maximum number of characters in a filename.
  581. X.Ex "int remove(char *filename)"
  582. XRemove the named file as per ANSI.
  583. X.Ex "int rename(char *old, char *new)"
  584. XRename the file \fBold\fP to \fBnew\fP as per ANSI.
  585. X.Ex "void sleep(unsigned int seconds)"
  586. XPut the process to sleep for the given number of seconds.
  587. X.\" ----- xvi specials -----
  588. X.Ex "const char * const DIRSEPS"
  589. XThe pathname separators supported for system calls (e.g.
  590. X\fB"\e\e\|/"\fP
  591. Xfor \%MS-DOS).
  592. X.Ex "FILE *fopenrb(char *file)"
  593. X.Ey "FILE *fopenwb(char *file)"
  594. XLike the standard
  595. X.B fopen()
  596. Xlibrary call,
  597. Xbut they both open files in \*Qbinary\*U mode
  598. X(i.e. no conversion of cr/lf/crlf is done),
  599. Xfor reading and writing respectively.
  600. X.Ex "bool_t exists(char *filename)"
  601. XReturns
  602. X.B TRUE
  603. Xif the named file exists.
  604. X.Ex "bool_t can_write(char *filename)"
  605. XReturns
  606. X.B TRUE
  607. Xif the named file can be written,
  608. Xi.e. if a \fBfopenwb(filename)\fP will succeed.
  609. X.Ex "char *fexpand(char *filename)"
  610. XReturns a filename-expanded version of the passed filename.
  611. X.Ex "#define SETVBUF_AVAIL"
  612. X.Ey "const unsigned int READBUFSIZ"
  613. X.Ey "const unsigned int WRTBUFSIZ"
  614. XIf
  615. X.B SETVBUF_AVAIL
  616. X(or
  617. X.B __STDC__ )
  618. Xis defined, these constant values
  619. Xare used to set I/O buffer sizes (using the \fBsetvbuf()\fP function)
  620. Xfor reading and writing files.
  621. XNote that if buffers of these sizes are unavailable at runtime,
  622. Xthe editor will try to allocate smaller buffers by iteratively
  623. Xhalving the buffer size until the allocation succeeds.
  624. XIt is therefore acceptable for these values to be quite large.
  625. X.Ex "char *tempfname(const char *filename)"
  626. XCreate a unique name for a temporary file,
  627. Xpossibly using \fBfilename\fP as a base
  628. X(this will be used by
  629. X.B do_preserve()
  630. Xto create a backup file
  631. Xfor the file named by
  632. X.B filename ).
  633. XThe string returned must have been allocated using
  634. X.B malloc() ;
  635. X.B NULL
  636. Xcan be returned if there is no more memory available.
  637. X.Ex "int call_system(char *command)"
  638. XInvoke the given command in a subshell.
  639. XThis is used for shell escapes from \fBxvi\fP.
  640. XThe command string may contain metacharacters
  641. Xwhich are expected to be expanded
  642. Xby a command interpreter, e.g.
  643. X.UX
  644. X.B /bin/sh ,
  645. X\%MS-DOS
  646. X.B command.com .
  647. XReturn value is 0 for success.
  648. XIn many environments, this call may safely be
  649. X.B #define d
  650. Xas
  651. X.B system(command) .
  652. X.Ex "int call_shell(char *shell)"
  653. XInvoke the named shell.
  654. XThis is used for the
  655. X.B :shell
  656. Xcommand.
  657. XIt may be mapped into
  658. X.B call_system() ,
  659. Xbut is separate on some systems for
  660. Xefficiency reasons (i.e. not invoking two shells to get one).
  661. XReturn value is 0 for success.
  662. X.Ex "bool_t"
  663. X.Ey "sys_pipe(char *cmd, int (*wf)(FILE *), long (*rf)(FILE *))"
  664. XUsed for the
  665. X.B !
  666. Xcommand.
  667. XThe first parameter is the command to invoke, while the second and third
  668. Xare functions which should be called with an open file pointer in order
  669. Xto
  670. Xwrite out old,
  671. Xor read in new
  672. Xlines (respectively).
  673. XNote that if \*Qreal\*U pipes are not available, it is acceptable
  674. Xto implement this function using temporary files, but the \fBwf\fP
  675. Xfunction must obviously be called before \fBrf\fP.
  676. X.Ex "void sys_exit(int code)"
  677. XExit with given exit status.
  678. XThis routine must not return.
  679. XThe editor is considered \*Qdead\*U once it has been called, and no
  680. Xfurther calls to editor functions should be made.
  681. X.Ex "void delay(void)"
  682. XDelay for a short time, about a fifth of a second.
  683. XThis is used for showing matching brackets when \fBshowmatch\fP is set.
  684. XIt is acceptable to just return if implementing this is not easy.
  685. X.\"===========================================================================
  686. X.NH 2
  687. XScreen Control
  688. X.LP
  689. XAn instance of the following structure must be defined
  690. Xin order to allow screen output to take place:
  691. X.DS L
  692. X.ta 1.3i 3i
  693. X.B
  694. X  typedef struct virtscr {
  695. X    genptr    *pv_window;
  696. X    int    pv_rows;
  697. X    int    pv_cols;
  698. X/* public: */
  699. X    VirtScr    *(*v_new)(VirtScr *);
  700. X    void    (*v_close)(VirtScr *);
  701. X
  702. X    int    (*v_rows)(VirtScr *);
  703. X    int    (*v_cols)(VirtScr *);
  704. X
  705. X    void    (*v_clear_all)(VirtScr *);
  706. X    void    (*v_clear_line)(VirtScr *);
  707. X
  708. X    void    (*v_goto)(VirtScr *, int row, int col);
  709. X    void    (*v_advise)(VirtScr *, int row, int col,
  710. X        int index, char *str);
  711. X
  712. X    void    (*v_write)(VirtScr *, int row, int col, char *str);
  713. X    void    (*v_putc)(VirtScr *, int row, int col, int ch);
  714. X
  715. X    void    (*v_set_colour)(VirtScr *, int colour);
  716. X    int    (*v_colour_cost)(VirtScr *);
  717. X
  718. X    void    (*v_flush)(VirtScr *);
  719. X
  720. X    void    (*v_beep)(VirtScr *);
  721. X
  722. X/* optional: not used if NULL */
  723. X    void    (*v_insert)(VirtScr *, int row, int col, char *str);
  724. X
  725. X    int    (*v_scroll)(VirtScr *, int start, int end, int nlines);
  726. X  } VirtScr;
  727. X.R
  728. X.DE
  729. X.LP
  730. XThe first three fields in this structure are \*Qprivate\*U, for use only
  731. Xwithin the implementation of the \*Qpublic\*U functions.
  732. XThe remaining fields are all function pointers, and are described below.
  733. XNote that all functions have at least one parameter, which is a pointer
  734. Xto the instance of the \fBVirtScr\fP in question.
  735. XThis is always referred to as \fBvs\fP below.
  736. XNote also that the top-left-hand corner of the window is taken to be (0,0).
  737. X.Ex "v_new(vs)"
  738. XObtain a new \fBVirtScr\fP, and return a pointer to it.
  739. XThis is not used at present, and should return
  740. X.B NULL .
  741. X.Ex "v_close(vs)"
  742. XClose the window to which \fBvs\fP refers.
  743. X.Ex "v_rows(vs)"
  744. XReturn the number of rows in \fBvs\fP.
  745. X.Ex "v_cols(vs)"
  746. XReturn the number of columns in \fBvs\fP.
  747. X.Ex "v_clear_all(vs)"
  748. XClear the window completely.
  749. X.Ex "v_clear_line(vs, int row, int col)"
  750. XClear the specified line, from the given column to the right hand edge
  751. Xof the window, inclusive.
  752. X.Ex "v_goto(vs, int row, int col)"
  753. XMove the cursor to the specified row and column.
  754. X.Ex "v_advise(vs, int row, int col, int index, char *str)"
  755. XThis function is called when the editor is about to produce some
  756. Xoutput on the same line as the last output, but separate from it
  757. Xby one or more characters.
  758. XThe destination position is the coordinate pair \fB(row, col + index)\fP,
  759. Xand \fBstr\fP contains the string of characters which are in the window
  760. Xstarting at position \fB(row, col)\fP.
  761. XWhere there is a cost incurred
  762. Xby moving the cursor to a specific screen position,
  763. Xthe terminal interface module may decide to write the intervening characters
  764. Xto the screen rather than using a specific \*Qmove cursor\*U sequence,
  765. Xin order to minimise the number of characters written to the terminal.
  766. X.Ex
  767. XNote that for many environments, the cost of re-positioning the cursor is
  768. Xnil, and under these circumstances this function need not do anything.
  769. X.Ex "v_write(vs, int row, int col, char *str)"
  770. XWrite the specified string of characters into the window, starting at
  771. Xthe specified row and column.
  772. XThe parameters will be such that the string will always fit into
  773. Xa single line of the window, i.e. no line-wrapping is necessary;
  774. Xhowever, it is quite possible for the string to end on the last character
  775. Xof a line, and some implementations will need to take special
  776. Xprecautions to handle this correctly.
  777. X.Ex "v_putc(vs, int row, int col, int ch)"
  778. XThis is like \fBv_write\fP but for a single character.
  779. X.Ex "v_set_colour(vs, int colour)"
  780. XSet the colour for all subsequent output (including clearing of
  781. Xlines or the whole window) to the specified colour.
  782. XThe meaning of the value is system-specific.
  783. X.Ex "v_colour_cost(vs)"
  784. XReturn the number of extra characters which are taken up in the window
  785. Xby a colour change.
  786. XThis is almost always 0,
  787. Xbut there exist some terminals for which it is not
  788. X(see the
  789. X.qB sg
  790. X.B termcap
  791. Xcapability).
  792. X.Ex "v_flush(vs)"
  793. XFlush all screen output, and move the cursor on the screen to the correct
  794. Xposition.
  795. XThe screen need not actually be updated until either this function is called,
  796. Xor \fBxvi_handle_event()\fP returns.
  797. X.Ex "v_beep(vs)"
  798. XBeep.
  799. XIt is acceptable to flash the screen or window if no audio facility
  800. Xis available.
  801. X.Ex "v_insert(vs, int row, int col, char *str)"
  802. XThis function inserts the given string at the given position,
  803. Xpushing any other characters on the same row to the right.
  804. XIf such a facility is not available,
  805. Xthe function pointer should be set to
  806. X.B NULL .
  807. X.Ex "v_scroll(vs, int start, int end, int nlines)"
  808. XThis function scrolls the set of lines between \fBstart\fP and \fBend\fP
  809. X(inclusive) by \fBnlines\fP lines.
  810. XIf \fBnlines\fP is positive, \fInormal\fP scrolling should be done,
  811. Xi.e. the lines should be moved upwards with respect to the window.
  812. XIf \fBnlines\fP is negative, scrolling should be in the reverse direction.
  813. XThe lines which are left by the scrolling should be cleared.
  814. XThe function should return non-zero if the scrolling was successful,
  815. Xotherwise 0.
  816. X.Ex
  817. XIf scrolling is not available, the function pointer should be set to
  818. X.B NULL .
  819. X.\"===========================================================================
  820. X.NH 2
  821. XParameters
  822. X.LP
  823. XDefault values should be
  824. X.B #define d
  825. Xfor certain parameters
  826. Xas follows:
  827. X.TS
  828. Xcenter, box;
  829. Xc|c|c
  830. Xl|c|l.
  831. XParameter Name    Type    \fB#define\fP name
  832. X_
  833. X\fBsyscolour\fP    numeric    \fBDEF_SYSCOLOUR\fP
  834. X\fBcolour\fP    numeric    \fBDEF_COLOUR\fP
  835. X\fBstatuscolour\fP    numeric    \fBDEF_STCOLOUR\fP
  836. X\fBroscolour\fP    numeric    \fBDEF_ROSCOLOUR\fP
  837. X\fBhelpfile\fP    string    \fBHELPFILE\fP
  838. X\fBformat\fP    string    \fBDEF_TFF\fP
  839. X.TE
  840. X.\===========================================================================
  841. X.NH 2
  842. XFile Formats
  843. X.LP
  844. XThe functions in \fBxvi\fP which read and write text
  845. Xfiles are aware of several different newline conventions
  846. X(for example,
  847. X\fB"\e\^n"\fP on
  848. X.UX ,
  849. X\fB"\e\^r\^\e\^n"\fP on \%MS-DOS, and so on), so
  850. Xthat any version of the editor can read and write any of the
  851. Xsupported formats.
  852. XThe value of the \fBformat\fP parameter
  853. X(which can be set to
  854. X.qB unix ,
  855. X.qB msdos ,
  856. X.qB macintosh ,
  857. Xetc.)
  858. Xdetermines which format is currently being used.
  859. XIf you are porting \fBxvi\fP to a system with a newline convention which
  860. Xisn't one of those currently supported (see the table called
  861. X.B tftable
  862. Xin
  863. X.B fileio.c )
  864. Xyou may have to add a new entry to the table.
  865. X.LP
  866. XUnfortunately, the current design is not as general as it ought to be.
  867. XIf you happen to be porting to VMS,
  868. Xor some other system which doesn't use either
  869. Xa single character
  870. Xor a consecutive pair of characters
  871. Xto represent a newline,
  872. Xyou will have quite a lot of work to do
  873. Xif you want to retain the facility for
  874. Xconverting between file formats within the editor.
  875. X.LP
  876. XIn any case, your system interface module should define
  877. X.B DEF_TFF
  878. Xto be the index of the entry in \fBtftable\fP
  879. Xwhich represents the default format for your system.
  880. XThis is the value for
  881. X.B Pen(P_format)
  882. Xwhich will be
  883. Xcompiled into the parameter table.
  884. X.\"===========================================================================
  885. X.NH 2
  886. XNotes on Termcap Implementation
  887. X.LP
  888. XThere exists a \fBtermcap\fP implementation of the terminal interface,
  889. Xcurrently only used for the
  890. X.UX
  891. Xport.
  892. XThis module could quite easily be re-used for other systems if desired;
  893. Xthe following routines would need to be defined by the system module:
  894. X.Ex "void foutch(int c)"
  895. XOutput a single character to the terminal.
  896. XThis must be implemented as a function, not a macro, because it is passed
  897. Xas a parameter into the
  898. X.B termcap
  899. Xlibrary.
  900. X.Ex "void moutch(int c)"
  901. XSame as
  902. X.B foutch()
  903. Xexcept that it can be implemented as a macro.
  904. XThis will be used by the
  905. X.B termcap
  906. Xinterface module to write characters to
  907. Xthe screen.
  908. X.Ex "void oflush(void)"
  909. XFlush buffered output to the terminal.
  910. X.\"===========================================================================
  911. X.NH 2
  912. XEntering/Leaving Visual Mode
  913. X.LP
  914. XSome facility is commonly necessary for the system interface module
  915. Xto be able to tell the terminal interface module to enter or exit
  916. X\fIvisual\fP mode.
  917. XThis might mean changing the terminal state between \*Qraw\*U and \*Qcooked\*U
  918. Xmodes, or switching display pages.
  919. XNo specific interface for this is defined,
  920. Xalthough the standard
  921. X.UX
  922. Xand \%MS-DOS implementations do use such a facility,
  923. Xand the interface functions for both systems are identically defined.
  924. X.\"===========================================================================
  925. X.NH 2
  926. XFunction Keys\|\|/\|\|Mouse Handling
  927. X.LP
  928. XFunction key values are coded into a set of
  929. X.B #define d
  930. Xconstants in the file
  931. X.B ascii.h ;
  932. Xe.g. the value
  933. X.B K_UARROW
  934. Xmight be given as input when the keyboard up-arrow key has been pressed.
  935. X.LP
  936. XIf the global variable
  937. X.B State
  938. Xis not equal to
  939. X.B NORMAL ,
  940. Xall
  941. Xfunction keys except for a backspace key are invalid input.
  942. XIf an invalid key is pressed, the safest strategy may be to
  943. Xbeep and wait for another key to be pressed.
  944. X.B NORMAL
  945. Xis defined in
  946. X.B xvi.h .
  947. X.LP
  948. XAnother facility which may be provided
  949. Xis handling mouse input on systems where it is available.
  950. XThe strategy for interpreting mouse input is controlled
  951. Xby the
  952. X.B mouseclick()
  953. Xfunction (in
  954. X.B mouse.c );
  955. Xthe idea is
  956. Xto make the strategy independent of any specific device interface.
  957. XIf a mouse button is pressed before a keyboard key is pressed,
  958. Xthe following routine should be called:
  959. X.DS
  960. X.B "mouseclick(int row, int column);"
  961. X.DE
  962. Xwhere row and column are the current co-ordinates, counted
  963. Xin character positions, of the mouse pointer within the
  964. Xscreen or editing window.
  965. XIf the mouse is moved while a button is held down, the routine
  966. X.DS
  967. X.B "mousedrag(int startrow, int endrow, int startcolumn, int endcolumn);"
  968. X.DE
  969. Xshould be called with co-ordinates describing the movement.
  970. XIf the global variable
  971. X.B State
  972. Xis not equal to
  973. X.B NORMAL ,
  974. Xmouse input can be ignored altogether.
  975. X.LP
  976. XAll this will be considerably tidied up at a later stage, when we have
  977. Xproper
  978. X.B xvEvent
  979. Xtypes for function keys and mouse actions.
  980. X.\"===========================================================================
  981. X.NH 2
  982. XMain
  983. X.LP
  984. XFinally, the system interface module must provide a \fBmain()\fP function.
  985. XThis function must call \fBxvi_startup(vs, argc, argv, env)\fP at startup,
  986. Xwith parameters as follows:
  987. X.Ex "VirstScr *vs;"
  988. XThis is a pointer to the \fBVirtScr\fP structure for the first window,
  989. Xor for the terminal screen.
  990. X.Ex "int argc, char **argv;"
  991. XThese are as for a \fBmain()\fP function.
  992. X.Ex "char *env;"
  993. XThis is an environment string, normally the return value from
  994. X\fBgetenv("XVINIT")\fP.
  995. XIf the concept of environment variables does not exist,
  996. Xa string of the form \fB"source\ \fIfilename\fB"\fR may be passed instead,
  997. Xso as to allow users to localise their usage of the editor.
  998. X.LP
  999. XThe return value from \fBxvi_startup()\fP is a pointer, which will
  1000. Xbe used in future to identify the window for input events.
  1001. XFor now, it should be stored in the \fBVirtScr\fP's \fBpv_window\fP field.
  1002. X.LP
  1003. XHaving called \fBxvi_startup()\fP, input events may then be passed
  1004. Xto the editor by calling \fBxvi_handle_event\fP with a pointer to
  1005. Xan \fBxvEvent\fP structure as the sole argument.
  1006. XThis structure is defined as follows:
  1007. X.DS
  1008. X.B
  1009. Xtypedef struct event {
  1010. X    enum {
  1011. X        Ev_char,
  1012. X        Ev_timeout
  1013. X    }                   ev_type;
  1014. X    union {
  1015. X        /* Ev_char: */
  1016. X        int evu_inchar;
  1017. X
  1018. X        /* Ev_timeout: */
  1019. X    }                   ev_u;
  1020. X} xvEvent;
  1021. X
  1022. X#define    ev_inchar    ev_u.evu_inchar
  1023. X.R
  1024. X.DE
  1025. X.LP
  1026. XThe \fBev_type\fP field is a tag which identifies the type of event
  1027. Xwhich has occurred.
  1028. XAt present, only two events are supported: an input character from
  1029. Xthe user, and a timeout.
  1030. XThe union which follows contains data associated with each event type;
  1031. Xcurrently only the type \fBEv_char\fP requires data, as may be seen.
  1032. XThe
  1033. X.B #define
  1034. Xfor \fBev_inchar\fP is provided purely for convenience.
  1035. X.LP
  1036. XThe return value from \fBxvi_handle_event()\fP is a long integer value
  1037. Xwhich is the time in milliseconds for which the editor is prepared
  1038. Xto wait for more input.
  1039. XIf no input arrives within that time, the function should be called
  1040. Xagain with an event of type \fBEv_timeout\fP.
  1041. XThe timeout value returned may be 0L, indicating that no timeout is necessary.
  1042. XIt is very important that timeouts should actually be implemented because
  1043. Xthey are needed for the
  1044. X.B preserve
  1045. Xfacility.
  1046. X.LP
  1047. XCurrently, if a keyboard interrupt is received,
  1048. X.B xvi_handle_event()
  1049. Xneed not be called
  1050. X(it should,
  1051. Xin any case,
  1052. Xnever be called from an asynchronous interrupt
  1053. Xor signal
  1054. Xhandler)
  1055. Xbut the global variable
  1056. X.B kbdintr
  1057. Xshould be set to a non-zero value.
  1058. X.\"===========================================================================
  1059. X.NH 1
  1060. XDATA STRUCTURES
  1061. X.LP
  1062. XStructures used in \fBxvi\fP are all typedef'd,
  1063. Xand all begin with a capital letter.
  1064. XThey are defined in
  1065. X.B xvi.h .
  1066. XThe following data structures are defined:
  1067. X.NH 2
  1068. XLine
  1069. X.LP
  1070. XThis structure is used to hold a single text line.
  1071. XIt contains forward and backward pointers which are connected together
  1072. Xto form a two-way linked list.
  1073. XIt also contains a pointer to an allocated text buffer,
  1074. Xan integer recording the number of bytes allocated for the text,
  1075. Xand the line number (an unsigned long).
  1076. XThe text is null-terminated, and the space allocated for it may be
  1077. Xgrown but is never shrunk.
  1078. XThe maximum size of this space is given by
  1079. X.B MAX_LINE_LENGTH .
  1080. X.LP
  1081. XThe line number is used when showing line numbers on screen, but this
  1082. Xis secondary to its main purpose of providing an ordering on lines;
  1083. Xthe ordering of two lines in a list may be established by simply
  1084. Xcomparing their line numbers
  1085. X(macros are available for this purpose; see later for details).
  1086. X.NH 2
  1087. XBuffer
  1088. X.LP
  1089. XThis structure holds the internal representation of a file.
  1090. XIt contains pointers to the
  1091. Xlinked list of lines which comprise the actual text.
  1092. XWe always allocate an extra line at the beginning and the end,
  1093. Xwith line numbers 0 and
  1094. X.B MAX_LINENO
  1095. Xrespectively,
  1096. Xin order to make the code which deals with this structure easier.
  1097. XThe line numbers of \fBLine\fP structures in a \fBBuffer\fP
  1098. Xare always maintained by code in \fBundo.c\fP,
  1099. Xwhich is the only module which ever changes the text of a \fBBuffer\fP.
  1100. X.LP
  1101. XThe \fBBuffer\fP structure also contains:
  1102. X.IP \(bu
  1103. Xflags, including readonly and modified
  1104. X.IP \(bu
  1105. Xcurrent filename associated with the buffer
  1106. X.IP \(bu
  1107. Xtemporary filename for buffer preservation
  1108. X.IP \(bu
  1109. Xspace for the
  1110. X.B mark
  1111. Xmodule to store information about marked lines
  1112. X.IP \(bu
  1113. Xspace for the
  1114. X.B undo
  1115. Xmodule to store information about the last change
  1116. X.IP \(bu
  1117. Xnumber of windows associated with the buffer
  1118. X.LP
  1119. XThe following macros are used to find out certain information
  1120. Xabout \fBLine\fPs within \fBBuffers\fP:
  1121. X.Ex "lineno(Buffer *b, Line *l)"
  1122. XReturns the line number of the specified \fBLine\fP,
  1123. Xwhich belongs to the specified \fBBuffer\fP.
  1124. X.Ex "earlier(Line *l1, Line *l2)"
  1125. XReturns
  1126. X.B TRUE
  1127. Xif \fBl1\fP is earlier in the buffer than \fBl2\fP.
  1128. X.Ex "later(Line *l1, Line *l2)"
  1129. XReturns
  1130. X.B TRUE
  1131. Xif \fBl1\fP is later in the buffer than \fBl2\fP.
  1132. X.Ex "is_lastline(Line *l1)"
  1133. XReturns
  1134. X.B TRUE
  1135. Xif \fBl1\fP is the last line (i.e. the extra line
  1136. Xat the end, not the last text line) of the buffer.
  1137. X.Ex "is_line0(Line *l1)"
  1138. XReturns
  1139. X.B TRUE
  1140. Xif \fBl1\fP is the 0th line (i.e. the extra line
  1141. Xat the start, not the first text line) of the buffer.
  1142. X.NH 2
  1143. XPosn
  1144. X.LP
  1145. XThis structure is very simple; it contains a \fBLine\fP pointer and an integer
  1146. Xindex into the line's text, and is used to record a position within a buffer,
  1147. Xe.g. the current cursor position.
  1148. X.LP
  1149. XThese functions are available for operating on \fBPosn\fP structures:
  1150. X.Ex "gchar(Posn *)"
  1151. XReturns the character which is at the given position.
  1152. X.Ex "inc(Posn *)"
  1153. XIncrements the given position, moving past
  1154. Xend-of-line to the next line if necessary.
  1155. XThe following type is returned:
  1156. X.DS L
  1157. X.B
  1158. X.ta 2i
  1159. X  enum mvtype {
  1160. X      mv_NOMOVE,    /* at beginning or end of buffer */
  1161. X      mv_SAMELINE,    /* still within same line */
  1162. X      mv_CHLINE,    /* changed to different line */
  1163. X      mv_EOL,    /* at terminating '\e0' */
  1164. X  };
  1165. X.R
  1166. X.DE
  1167. X.Ex "dec(Posn *)"
  1168. XAs for \fBinc()\fP but decrements the position.
  1169. X.Ex "lt(Posn *p1, Posn *p2)"
  1170. XReturns
  1171. X.B TRUE
  1172. Xif the position specified by \fBp1\fP is earlier in the buffer
  1173. Xthan that specified by \fBp2\fP.
  1174. X.NH 2
  1175. XXviwin
  1176. X.LP
  1177. XThis structure maps a screen window onto a \fBBuffer\fP.
  1178. XIt contains:
  1179. X.IP \(bu
  1180. Xa pointer to the \fBBuffer\fP structure which it is mapped onto
  1181. X.IP \(bu
  1182. Xthe cursor's \fIlogical\fP position in the buffer (a \fBPosn\fP structure)
  1183. X.IP \(bu
  1184. Xthe cursor's \fIphysical\fP position in the window (row and column)
  1185. X.IP \(bu
  1186. Xinformation about size and location of screen window
  1187. X.IP \(bu
  1188. Xcurrent text of status line
  1189. X.IP \(bu
  1190. Xforward and backward pointers to other windows
  1191. X.LP
  1192. XNote that there is at least one \fBXviwin\fP for every \fBBuffer\fP.
  1193. X.LP
  1194. XWhen the editor was modified to support buffer windows, many
  1195. Xglobal variables were moved into the \fBBuffer\fP and \fBXviwin\fP structures;
  1196. Xsome were left as globals.
  1197. XFor instance, the
  1198. X.I undo
  1199. Xand
  1200. X.I mark
  1201. Xfacilities are obviously buffer-related,
  1202. Xbut
  1203. X.I yank
  1204. Xis useful if it is global
  1205. X(actually static within its own module);
  1206. Xit was decided that
  1207. X.I search
  1208. Xand
  1209. X.I redo
  1210. Xshould also be global.
  1211. X.LP
  1212. XSome modules have their own internal static data structures;
  1213. Xfor instance, the
  1214. X.B search
  1215. Xmodule remembers the last pattern
  1216. Xsearched for.
  1217. XAlso, certain modules use data structures which are included
  1218. Xin more global ones; e.g. each \fBBuffer\fP structure contains some
  1219. Xdata used only within
  1220. X.B undo.c .
  1221. XThis is not very well structured, but in practice it's quite
  1222. Xclean because we simply ensure that references to such structures
  1223. Xare kept local to the module which \*Qowns\*U them.
  1224. X.NH 2
  1225. XMark
  1226. X.LP
  1227. XThis data structure records a mark (defined by the \fBm\fP command).
  1228. XIt contains a \fBPosn\fP and a character field to hold the letter
  1229. Xwhich defines the mark.
  1230. XEach \fBBuffer\fP contains an array of these structures for holding
  1231. Xalphabetic marks, plus one for the previous context mark
  1232. X(as used by the
  1233. X.B ''
  1234. Xand
  1235. X.B ``
  1236. Xcommands).
  1237. XThe file
  1238. X.B mark.c
  1239. Xdeals with marks.
  1240. X.NH 2
  1241. XChange
  1242. X.LP
  1243. XThis structure records a single change which has been made to a buffer.
  1244. XIt also contains a pointer, so that it may be formed into a list.
  1245. XSee the discussion of
  1246. X.B undo.c
  1247. Xbelow for further details.
  1248. X.NH 2
  1249. XFlexbuf
  1250. X.LP
  1251. XThis structure is used to store text strings for which the length is unknown.
  1252. XThe following operations are defined for this type.
  1253. XAll functions take a Flexbuf pointer as a parameter.
  1254. X.Ex "flexnew(f)"
  1255. XInitialise a Flexbuf; not needed for static Flexbufs.
  1256. X.Ex "flexclear(f)"
  1257. XTruncate a Flexbuf to zero length, but don't free its storage.
  1258. X.Ex "flexdelete(f)"
  1259. XFree all storage belonging to a Flexbuf.
  1260. X.Ex "flexempty(f)"
  1261. XReturn
  1262. X.B TRUE
  1263. Xif the Flexbuf is empty.
  1264. X.Ex "flexlen(f)"
  1265. XReturn the number of characters in the Flexbuf.
  1266. X.Ex "flexrmchar(f)"
  1267. XRemove the last character from a Flexbuf.
  1268. X.Ex "flexpopch(f)"
  1269. XRemove the first character from a Flexbuf and return it.
  1270. X.Ex "flexgetstr(f)"
  1271. XReturn a pointer to the string contained in the Flexbuf.
  1272. X.Ex "flexaddch(f, c)"
  1273. XAdd the character \fBc\fP to the end of the Flexbuf.
  1274. X.Ex "lformat(f, fmt, ...)"
  1275. XA subset of \fBsprintf()\fP but for Flexbufs.
  1276. X.Ex "vformat(f, fmt, va_list)"
  1277. XA subset of \fBvsprintf()\fP but for Flexbufs.
  1278. X.LP
  1279. XThe last two functions are especially useful, since they avoid
  1280. Xthe usual problems with the lack of bounds-checking in \fBsprintf()\fP.
  1281. XAll code in the editor itself now uses Flexbufs to avoid the possibility
  1282. Xof buffer overruns, and to reduce the size of the executable.
  1283. XSome OS-specific modules, however, may still use the \fBprintf()\fP family.
  1284. XThe subset of \fBprintf\fP-like format specifiers implemented includes
  1285. Xthose for integers and strings, but not for floating-point numbers.
  1286. X.NH 2
  1287. Xbool_t
  1288. X.LP
  1289. XA simple Boolean type; has values
  1290. X.B TRUE
  1291. Xand
  1292. X.B FALSE ,
  1293. Xwhich are defined as
  1294. X1 and 0 so as to be compatible with C comparison operators.
  1295. X.NH 2
  1296. XxvEvent
  1297. X.LP
  1298. XThis type is defined in the previous section,
  1299. Xsince it forms part of the porting interface.
  1300. X.NH 2
  1301. XVirtScr
  1302. X.LP
  1303. XThis type represents a virtual screen, and
  1304. Xis constructed in a similar way to a \fIclass\fP.
  1305. XIt contains some function pointers which may be used to manipulate the
  1306. Xscreen in various ways, and some private data which is used by the
  1307. Ximplementation of the class.
  1308. X.LP
  1309. XThe old terminal interface, which consisted of a set of disparate functions,
  1310. Xis being replaced by the \fBVirtScr\fP interface;
  1311. Xthe first step in this process has been accomplished
  1312. Xby the provision of a default \fBVirtScr\fP implementation
  1313. Xusing the old primitive functions.
  1314. XNew, native, \fBVirtScr\fP implementations may now be coded,
  1315. Xwhich will increase the efficiency of screen output.
  1316. X.LP
  1317. XAs the final stage, a windowing implementation of the \fBVirtScr\fP class
  1318. Xwill be provided, using the underlying \fBVirtScr\fP implementations,
  1319. Xand the window-handling code in the editor will be modified to
  1320. Xthat each occurrence of an \fBXviwin\fP references its own \fBVirtScr\fP.
  1321. XIt will then be possible to build a version of the editor which operates in a
  1322. Xtrue windowing environment by using a separate screen window for each buffer,
  1323. Xinstead of the current vertical-split method.
  1324. X.LP
  1325. XA full definition of the \fBVirtScr\fP type will be found
  1326. Xin the previous section.
  1327. X.\"===========================================================================
  1328. X.NH 2
  1329. XGlobal Variables
  1330. X.LP
  1331. XThere are only a few global variables in the editor.
  1332. XThese are the important ones:
  1333. X.Ex curbuf 0.7i
  1334. Xpointer to the current \fBBuffer\fP
  1335. X.Ex curwin 0.7i
  1336. Xpointer to the current \fBXviwin\fP
  1337. X.Ex State 0.7i
  1338. Xthe current \fIstate\fP of the editor;
  1339. Xcontrols what we do with input characters.
  1340. XThe value is one of the following:
  1341. X.RS
  1342. X.Ex NORMAL 1i
  1343. XThe default state; \fBvi\fP-mode commands may be executed
  1344. X.Ex INSERT 1i
  1345. XInsert mode, i.e. characters typed get inserted into the current buffer
  1346. X.Ex REPLACE 1i
  1347. XReplace mode, characters in the buffer get overwritten by what is typed
  1348. X.Ex CMDLINE 1i
  1349. XReading a colon-command, regular expression or pipe command
  1350. X.Ex DISPLAY 1i
  1351. XDisplaying text, i.e. \fB:p\fP command, or \fB:set\fP or \fB:map\fP with no argument
  1352. X.RE
  1353. X.Ex echo 0.7i
  1354. XThis variable controls what output is currently displayable.
  1355. XIt is used at various points within the editor to stop certain
  1356. Xoutput which is either undesirable or sub-optimal.
  1357. XIt must always
  1358. Xbe restored to its previous value after the code which changed it
  1359. Xhas finished what it is doing.
  1360. X.Ex kbdintr 0.7i
  1361. XThis can be set to a non-zero value to indicate that an asynchronous
  1362. Xuser-generated interrupt (such as a keyboard interrupt) has occurred.
  1363. XSee the discussion of event handling in the previous section.
  1364. X.\"===========================================================================
  1365. X.nr PI 1i    \" Extra indentation for filenames
  1366. X.NH 1
  1367. XSOURCE FILES
  1368. X.LP
  1369. XThe header file
  1370. X.B xvi.h
  1371. Xcontains all the type definitions
  1372. Xused within the editor, as well as function declarations etc.
  1373. X.LP
  1374. XThe following source files form the primary interface to the editor:
  1375. X.Ex startup.c
  1376. XEntry point for the editor.
  1377. XDeals with argument
  1378. Xand option parsing and initial setup, calling
  1379. Xmodule initialisation functions as necessary.
  1380. X.Ex events.c
  1381. XContains the routine \fBxvi_handle_event()\fP, which is
  1382. Xthe entry point for handling input to the editor;
  1383. Xinput is passed to different routines according to the
  1384. X\fBState\fP variable.
  1385. XTimeouts on input are also handled here, by calling appropriate
  1386. Xroutines in \fBmap.c\fP or \fBpreserve.c\fP.
  1387. X.Ex edit.c
  1388. XDeals with insert and replace modes.
  1389. X.Ex normal.c
  1390. XHandles normal-mode commands.
  1391. X.Ex map.c
  1392. XThis file is responsible for all input mapping (both set up by the
  1393. X\fB:map\fP command and internally for function-key mappings;
  1394. Xit also implements a stuff-characters-into-the-input-stream
  1395. Xfunction for use within the editor.
  1396. XThis is used, for example, to implement command redo
  1397. X(but \fInot\fP to implement \*Qundo\*U and \*Qput\*U as in STEVIE).
  1398. X.\"-----------------------------------------------------------------
  1399. X.sp
  1400. X.LP
  1401. XColon (\fBex\fP-type) commands are handled by this group:
  1402. X.Ex cmdline.c
  1403. XDecodes and executes colon commands.
  1404. X.Ex ex_cmds1.c
  1405. XFile-, \fBBuffer\fP- and \fBXviwin\fP-related colon commands.
  1406. X.Ex ex_cmds2.c
  1407. XOther colon commands (e.g. shell escape).
  1408. X.\"-----------------------------------------------------------------
  1409. X.sp
  1410. X.LP
  1411. XScreen updating is done within the following files:
  1412. X.Ex screen.c
  1413. XScreen updating code, including handling of line-based entry
  1414. X(for colon commands, searches etc) as they are typed in,
  1415. Xand display-mode stuff (for parameter displaying,
  1416. X.B :g/re/p
  1417. Xetc).
  1418. X.Ex cursor.c
  1419. XThis file contains the single function \fBcursupdate()\fP,
  1420. Xwhich is responsible for deciding where the physical screen cursor
  1421. Xshould be, according to the position of the logical cursor in the
  1422. Xbuffer and the position of the window onto that buffer.
  1423. XThis routine is not very optimal, and will probably disappear in due course.
  1424. X.Ex defscr.c
  1425. XThis file contains the default implementation of the \fBVirtScr\fP class,
  1426. Xon top of the old terminal/system interface.
  1427. X.Ex status.c
  1428. XFunctions to update the status line of a window; there are different
  1429. Xfunctions to display file information (name, position etc.)
  1430. Xand error/information messages.
  1431. X.\"-----------------------------------------------------------------
  1432. X.sp
  1433. X.LP
  1434. XThese files deal with specific areas of functionality:
  1435. X.Ex find.c
  1436. XSearch functions: all kinds of searches, including character-based
  1437. Xand word-based commands, sections, paragraphs, and the interface to
  1438. X\*Qreal\*U searching (which is actually done in
  1439. X.B search.c ).
  1440. X.Ex mark.c
  1441. XProvides primitives to record marks within a \fBBuffer\fP,
  1442. Xand to find the marks again.
  1443. X.Ex mouse.c
  1444. XCode to handle mice moving the cursor around and resizing windows.
  1445. X.Ex param.[ch]
  1446. XCode to handle setting of, and access to, parameters.
  1447. X(These are things like \fBtabstops\fP, \fBautoindent\fP, etc.)
  1448. X.Ex pipe.c
  1449. XHandles piping through system commands.
  1450. X.Ex preserve.c
  1451. XFile preservation routines.
  1452. X.Ex search.c
  1453. XCode for pattern-searching in a buffer, and for substitutions
  1454. Xand global execution.
  1455. XUses \fBregexp.[ch]\fP for the actual regular expression stuff.
  1456. X.Ex tags.c
  1457. XRoutines to handle tags \(em for \fB:tag\fP, \fB-t\fP and \fB^]\fP.
  1458. X.Ex undo.c
  1459. XCode to deal with doing and undoing; i.e. making and unmaking
  1460. Xchanges to a buffer.
  1461. XThis is one of the more complex and delicate files.
  1462. X.Ex yankput.c
  1463. XCode to deal with yanking and putting text, including named buffers.
  1464. X.\"-----------------------------------------------------------------
  1465. X.sp
  1466. X.LP
  1467. Xwhile these files provide lower-level functions:
  1468. X.Ex alloc.c
  1469. XMemory allocation routines.
  1470. X.Ex ascii.[ch]
  1471. XDeals with the visual representation of special
  1472. Xcharacters on the display (e.g. tabs, control chars).
  1473. X.Ex buffers.c
  1474. XRoutines dealing with the allocation and freeing of \fBBuffers\fP.
  1475. X.Ex fileio.c
  1476. XFile I/O routines; reading, writing, re-editing files.
  1477. XAlso handling of the \fBformat\fP parameter.
  1478. X.Ex flexbuf.c
  1479. XFlexible-length character-buffer routines.
  1480. X.Ex misccmds.c
  1481. XMiscellaneous functions.
  1482. X.Ex movement.c
  1483. XCode to deal with moving the cursor around in the buffer,
  1484. Xand scrolling the screen etc.
  1485. X.Ex ptrfunc.[ch]
  1486. XPrimitives to handle \fBPosn\fP structures; including various
  1487. Xoperators to compare positions in a text buffer.
  1488. X.Ex "regexp.[ch], regmagic.h"
  1489. XRegular-expression stuff, originally written by Henry Spencer
  1490. X(thanks Henry) and slightly hacked for use within \fBxvi\fP.
  1491. X.Ex signal.c
  1492. XHandling of terminal-generated signals in an ANSI environment.
  1493. X.Ex virtscr.h
  1494. XVirtual Screen interface definition.
  1495. XThis is a new part of \fBxvi\fP, and is not yet fully completed.
  1496. XWhen it is finished, it will provide the ability to implement
  1497. X\*Qnative\*U versions of \fBxvi\fP under various windowing systems,
  1498. Xin a clean and wholesome way.
  1499. XCurrently there is a single instance of the \fBVirtScr\fP class, which
  1500. Xis defined on top of the old system/terminal interface.
  1501. X.Ex windows.c
  1502. XCode to deal with creating, deleting, resizing windows.
  1503. X.Ex version.c
  1504. XContains only the version string.
  1505. X.\"-----------------------------------------------------------------
  1506. END_OF_FILE
  1507.   if test 44132 -ne `wc -c <'xvi/doc/source.ms'`; then
  1508.     echo shar: \"'xvi/doc/source.ms'\" unpacked with wrong size!
  1509.   fi
  1510.   # end of 'xvi/doc/source.ms'
  1511. fi
  1512. if test ! -d 'xvi/src' ; then
  1513.     echo shar: Creating directory \"'xvi/src'\"
  1514.     mkdir 'xvi/src'
  1515. fi
  1516. if test -f 'xvi/src/tags.c' -a "${1}" != "-c" ; then 
  1517.   echo shar: Will not clobber existing file \"'xvi/src/tags.c'\"
  1518. else
  1519.   echo shar: Extracting \"'xvi/src/tags.c'\" \(6968 characters\)
  1520.   sed "s/^X//" >'xvi/src/tags.c' <<'END_OF_FILE'
  1521. X/* Copyright (c) 1990,1991,1992 Chris and John Downey */
  1522. X#ifndef lint
  1523. Xstatic char *sccsid = "@(#)tags.c    2.1 (Chris & John Downey) 7/29/92";
  1524. X#endif
  1525. X
  1526. X/***
  1527. X
  1528. X* program name:
  1529. X    xvi
  1530. X* function:
  1531. X    PD version of UNIX "vi" editor, with extensions.
  1532. X* module name:
  1533. X    tags.c
  1534. X* module function:
  1535. X    Handle tags.
  1536. X* history:
  1537. X    STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  1538. X    Originally by Tim Thompson (twitch!tjt)
  1539. X    Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  1540. X    Heavily modified by Chris & John Downey
  1541. X
  1542. X***/
  1543. X
  1544. X#include "xvi.h"
  1545. X
  1546. X#define    LSIZE        512    /* max. size of a line in the tags file */
  1547. X
  1548. X/*
  1549. X * Macro evaluates true if char 'c' is a valid identifier character.
  1550. X * Used by tagword().
  1551. X */
  1552. X#define IDCHAR(c)    (is_alnum(c) || (c) == '_')
  1553. X
  1554. X/*
  1555. X * Return values for find_tag().
  1556. X */
  1557. X#define    FT_SUCCESS    0        /* found tag */
  1558. X#define    FT_CANT_OPEN    1        /* can't open given file */
  1559. X#define    FT_NO_MATCH    2        /* no such tag in file */
  1560. X#define    FT_ERROR    3        /* error in tags file */
  1561. X
  1562. Xstatic    int    find_tag P((char *, char *, char **, char **));
  1563. X
  1564. X/*
  1565. X * Tag to the word under the cursor.
  1566. X */
  1567. Xvoid
  1568. Xtagword()
  1569. X{
  1570. X    char    ch;
  1571. X    Posn    pos;
  1572. X    char    tagbuf[50];
  1573. X    char    *tp = tagbuf;
  1574. X
  1575. X    pos = *curwin->w_cursor;
  1576. X
  1577. X    ch = gchar(&pos);
  1578. X    if (!IDCHAR(ch))
  1579. X    return;
  1580. X
  1581. X    /*
  1582. X     * Now grab the chars in the identifier.
  1583. X     */
  1584. X    while (IDCHAR(ch) && tp < tagbuf + sizeof(tagbuf)) {
  1585. X    *tp++ = ch;
  1586. X    if (inc(&pos) != mv_SAMELINE)
  1587. X        break;
  1588. X    ch = gchar(&pos);
  1589. X    }
  1590. X
  1591. X    /*
  1592. X     * If the identifier is too long, just beep.
  1593. X     */
  1594. X    if (tp >= tagbuf + sizeof(tagbuf)) {
  1595. X    beep(curwin);
  1596. X    return;
  1597. X    }
  1598. X
  1599. X    *tp = '\0';
  1600. X
  1601. X    (void) do_tag(curwin, tagbuf, FALSE, TRUE, TRUE);
  1602. X}
  1603. X
  1604. X/*
  1605. X * do_tag(window, tag, force, interactive) - goto tag
  1606. X */
  1607. Xbool_t
  1608. Xdo_tag(window, tag, force, interactive, split)
  1609. XXviwin    *window;
  1610. Xchar    *tag;            /* function to search for */
  1611. Xbool_t    force;            /* if true, force re-edit */
  1612. Xbool_t    interactive;        /* true if reading from tty */
  1613. Xbool_t    split;            /* true if want to split */
  1614. X{
  1615. X    char    *fname;        /* file name to edit (2nd field) */
  1616. X    char    *field3;    /* 3rd field - pattern or line number */
  1617. X    bool_t    edited;        /* TRUE if we have edited the file */
  1618. X    Xviwin    *tagwindow;    /* tmp window pointer */
  1619. X    int        status;        /* return value from find_tag() */
  1620. X    int        count;
  1621. X    char    **tagfiles;
  1622. X
  1623. X    if (tag == NULL || tag[0] == '\0') {
  1624. X    if (interactive) {
  1625. X        show_error(window, "Usage: :tag <identifier>");
  1626. X    } else {
  1627. X        beep(window);
  1628. X    }
  1629. X    return(FALSE);
  1630. X    }
  1631. X
  1632. X    tagfiles = Pl(P_tags);
  1633. X    if (tagfiles == NULL || tagfiles[0] == NULL) {
  1634. X    if (interactive) {
  1635. X        show_error(window, "No tags parameter set!");
  1636. X        return(FALSE);
  1637. X    }
  1638. X    }
  1639. X
  1640. X    gotocmd(window, FALSE);
  1641. X
  1642. X    for (count = 0; tagfiles[count] != NULL; count++) {
  1643. X    status = find_tag(tag, tagfiles[count], &fname, &field3);
  1644. X    if (status == FT_SUCCESS) {
  1645. X        break;
  1646. X    }
  1647. X    }
  1648. X
  1649. X    /*
  1650. X     * Either:
  1651. X     *    we have found the tag in tagfiles[count]
  1652. X     * or:
  1653. X     *    we have failed to find it, and tagfiles[count - 1]
  1654. X     *    contains the name of the last tags file tried.
  1655. X     */
  1656. X
  1657. X    switch (status) {
  1658. X    case FT_CANT_OPEN:
  1659. X    if (interactive) {
  1660. X        show_error(window, "Can't open tags file \"%s\"",
  1661. X                tagfiles[count - 1]);
  1662. X    }
  1663. X    return(FALSE);
  1664. X
  1665. X    case FT_ERROR:
  1666. X    if (interactive) {
  1667. X        show_error(window, "Format error in tags file \"%s\"",
  1668. X                tagfiles[count - 1]);
  1669. X    }
  1670. X    return(FALSE);
  1671. X
  1672. X    case FT_NO_MATCH:
  1673. X    if (interactive) {
  1674. X        show_error(window, "Tag not found");
  1675. X    }
  1676. X    return(FALSE);
  1677. X    }
  1678. X
  1679. X    /*
  1680. X     * If we are already editing the file, just do the search.
  1681. X     *
  1682. X     * If "autosplit" is set, create a new buffer window and
  1683. X     * edit the file in it.
  1684. X     *
  1685. X     * Else just edit it in the current window.
  1686. X     */
  1687. X    tagwindow = find_window(window, fname);
  1688. X    if (tagwindow != NULL) {
  1689. X    curwin = tagwindow;
  1690. X    curbuf = curwin->w_buffer;
  1691. X    edited = TRUE;
  1692. X
  1693. X    } else if (split && can_split() && do_buffer(window, fname)) {
  1694. X    edited = TRUE;
  1695. X
  1696. X    } else if (do_edit(window, force, fname)) {
  1697. X    edited = TRUE;
  1698. X
  1699. X    } else {
  1700. X    /*
  1701. X     * If the re-edit failed, abort here.
  1702. X     */
  1703. X    edited = FALSE;
  1704. X    }
  1705. X
  1706. X    /*
  1707. X     * Finally, search for the given pattern in the file,
  1708. X     * but only if we successfully edited it. Note that we
  1709. X     * always use curwin at this stage because it is not
  1710. X     * necessarily the same as our "window" parameter.
  1711. X     */
  1712. X    if (edited) {
  1713. X    char    *cp;
  1714. X
  1715. X    /*
  1716. X     * Remove trailing newline if present.
  1717. X     */
  1718. X    cp = field3 + strlen(field3) - 1;
  1719. X    if (*cp == '\n') {
  1720. X        *cp-- = '\0';
  1721. X    }
  1722. X
  1723. X    if (*field3 == '/' || *field3 == '?') {
  1724. X        int    old_rxtype;
  1725. X
  1726. X        /*
  1727. X         * Remove leading and trailing '/'s or '?'s
  1728. X         * from the search pattern.
  1729. X         */
  1730. X        field3++;
  1731. X        if (*cp == '/' || *cp == '?') {
  1732. X        *cp = '\0';
  1733. X        }
  1734. X
  1735. X        /*
  1736. X         * Set the regular expression type to rt_TAGS
  1737. X         * so that only ^ and $ have a special meaning;
  1738. X         * this is like nomagic in "real" vi.
  1739. X         */
  1740. X        old_rxtype = Pn(P_regextype);
  1741. X        set_param(P_regextype, rt_TAGS, (char **) NULL);
  1742. X
  1743. X        if (dosearch(curwin, field3, '/')) {
  1744. X        show_file_info(curwin);
  1745. X        } else {
  1746. X        beep(curwin);
  1747. X        }
  1748. X        set_param(P_regextype, old_rxtype, (char **) NULL);
  1749. X    } else if (is_digit(*field3)) {
  1750. X        /*
  1751. X         * Not a search pattern; a line number.
  1752. X         */
  1753. X        do_goto(atol(field3));
  1754. X    } else {
  1755. X        show_error(curwin, "Ill-formed tag pattern \"%s\"", field3);
  1756. X    }
  1757. X    move_window_to_cursor(curwin);
  1758. X    update_all();
  1759. X    }
  1760. X
  1761. X    return(TRUE);
  1762. X}
  1763. X
  1764. Xstatic int
  1765. Xfind_tag(tag, file, fnamep, pattern)
  1766. Xchar    *tag;
  1767. Xchar    *file;
  1768. Xchar    **fnamep;
  1769. Xchar    **pattern;
  1770. X{
  1771. X    register char    *str;        /* used for scanning strings */
  1772. X    FILE        *tp;        /* file pointer for tags file */
  1773. X    static char        lbuf[LSIZE];    /* input line from tags file */
  1774. X    bool_t        found;
  1775. X    int            max_chars;
  1776. X
  1777. X    max_chars = Pn(P_taglength);
  1778. X    if (max_chars == 0) {
  1779. X    max_chars = INT_MAX;
  1780. X    }
  1781. X
  1782. X    tp = fopen(file, "r");
  1783. X    if (tp == NULL) {
  1784. X    return(FT_CANT_OPEN);
  1785. X    }
  1786. X
  1787. X    found = FALSE;
  1788. X    while (fgets(lbuf, LSIZE, tp) != NULL) {
  1789. X    register char    *tagptr;
  1790. X    register int    nchars;
  1791. X
  1792. X    for (str = lbuf, tagptr = tag, nchars = 0;
  1793. X        *str == *tagptr && nchars < max_chars;
  1794. X        str++, tagptr++, nchars++) {
  1795. X        ;
  1796. X    }
  1797. X    if ((*tagptr == '\0' && *str == '\t') || nchars == max_chars) {
  1798. X        found = TRUE;
  1799. X        break;
  1800. X    }
  1801. X
  1802. X    }
  1803. X
  1804. X    (void) fclose(tp);
  1805. X
  1806. X    if (!found) {
  1807. X    return(FT_NO_MATCH);
  1808. X    }
  1809. X
  1810. X    /*
  1811. X     * Okay, we have found the right line.
  1812. X     * Now extract the second and third fields.
  1813. X     *
  1814. X     * If we get here, str points at the tab after the first field,
  1815. X     * or at part of the tag if we have matched up to taglength.
  1816. X     * So first move to the start of the second field.
  1817. X     */
  1818. X    while (!is_space(*str)) {
  1819. X    str++;
  1820. X    }
  1821. X    while (is_space(*str)) {
  1822. X    str++;
  1823. X    }
  1824. X    *fnamep = str;
  1825. X
  1826. X    /*
  1827. X     * Find third field and null-terminate second field.
  1828. X     */
  1829. X    str = strchr(str, '\t');
  1830. X    if (str == NULL) {
  1831. X    (void) fclose(tp);
  1832. X    return(FT_ERROR);
  1833. X    }
  1834. X    while (is_space(*str)) {
  1835. X    *str++ = '\0';
  1836. X    }
  1837. X    *pattern = str;
  1838. X
  1839. X    return(FT_SUCCESS);
  1840. X}
  1841. END_OF_FILE
  1842.   if test 6968 -ne `wc -c <'xvi/src/tags.c'`; then
  1843.     echo shar: \"'xvi/src/tags.c'\" unpacked with wrong size!
  1844.   fi
  1845.   # end of 'xvi/src/tags.c'
  1846. fi
  1847. echo shar: End of archive 1 \(of 18\).
  1848. cp /dev/null ark1isdone
  1849. MISSING=""
  1850. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  1851.     if test ! -f ark${I}isdone ; then
  1852.     MISSING="${MISSING} ${I}"
  1853.     fi
  1854. done
  1855. if test "${MISSING}" = "" ; then
  1856.     echo You have unpacked all 18 archives.
  1857.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1858. else
  1859.     echo You still must unpack the following archives:
  1860.     echo "        " ${MISSING}
  1861. fi
  1862. exit 0
  1863. exit 0 # Just in case...
  1864.