home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / xvi / part10 < prev    next >
Encoding:
Text File  |  1992-11-01  |  55.9 KB  |  1,765 lines

  1. Newsgroups: comp.sources.misc
  2. From: jmd@cyclone.bt.co.uk (John Downey)
  3. Subject:  v33i019:  xvi - portable multi-window vi-like editor, Part10/18
  4. Message-ID: <1992Oct24.172239.2004@sparky.imd.sterling.com>
  5. X-Md4-Signature: 504814a0f682503af7299b1e63aad003
  6. Date: Sat, 24 Oct 1992 17:22:39 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 19
  11. Archive-name: xvi/part10
  12. Environment: Unix, MS-DOS, OS/2, QNX
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  xvi/doc/xvi.lst.UU xvi/src/makefile.aix xvi/src/search.c
  19. # Wrapped by kent@sparky on Thu Oct 22 09:03:43 1992
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 10 (of 18)."'
  23. if test -f 'xvi/doc/xvi.lst.UU' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'xvi/doc/xvi.lst.UU'\"
  25. else
  26.   echo shar: Extracting \"'xvi/doc/xvi.lst.UU'\" \(23200 characters\)
  27.   sed "s/^X//" >'xvi/doc/xvi.lst.UU' <<'END_OF_FILE'
  28. Xbegin 664 xvi/doc/xvi.lst
  29. XM"@H*6%9)*#$I(" @(" @(" @(" @(" @(" @(%5315(@0T]-34%.1%,@(" @
  30. XM(" @(" @(" @(" @(" @("!85DDH,2D*"@H*3D%-10H@(" @('AV:2 M(&UU
  31. XM;'1I+69I;&4@=&5X="!E9&ET;W(*"E-93D]04TE3"B @(" @>'9I('L@+7,@
  32. XM(%\(<%\(85\(<E\(85\(;5\(95\(=%\(95\(<BU?"&%?"'-?"'-?"&E?"&=?
  33. XM"&Y?"&U?"&5?"&Y?"'0@('T@(%L@("UT("!?"'1?"&%?"&<@('P@("M?"&Y?
  34. XM"'5?"&U?"&)?"&5?"'(@('P*(" @(" K+U\(<%\(85\(=%\(=%\(95\(<E\(
  35. XM;B!=('L@7PAF7PAI7PAL7PAE7PAN7PAA7PAM7PAE("XN+B @?0H*1$530U))
  36. XM4%1)3TX*(" @("!8=FD@*'!R;VYO=6YC960@7PAE7PAC7PAK7PAS+5\(=E\(
  37. XM95\(92U?"&5?"'E?"&4I(&ES(&$@(&9R964L("!P;W)T86)L92P@(&UU;'1I
  38. XM+0H@(" @('=I;F1O=R @:6UP;&5M96YT871I;VX@(&]F('1H92!P;W!U;&%R
  39. XM('9I*#$I(&5D:71O<BX@($ET(&AA<PH@(" @('-O;64@=7-E9G5L(&5N:&%N
  40. XM8V5M96YT<RP@86QT:&]U9V@L(&%S(&1E<V-R:6)E9"!B96QO=RP@(&YO= H@
  41. XM(" @(&%L;" @;V8@('9I)W,@(&9E871U<F5S("!H879E(&)E96X@:6UP;&5M
  42. XM96YT960@>65T+"!A;F0@<V]M90H@(" @('1H:6YG<R!W;W)K(&1I9F9E<F5N
  43. XM=&QY(&9R;VT@=FDN"@I/4%1)3TY3"B @(" @5&AE(&9O;&QO=VEN9R!C;VUM
  44. XM86YD+6QI;F4@;W!T:6]N<R!A<F4@879A:6QA8FQE.@H*(" @(" M<R!?"'!?
  45. XM"&%?"')?"&%?"&U?"&5?"'1?"&5?"'(M7PAA7PAS7PAS7PAI7PAG7PAN7PAM
  46. XM7PAE7PAN7PAT"@D@(%-E="!T:&4@=F%L=64@;V8@=&AE('-P96-I9FEE9" @
  47. XM<&%R86UE=&5R("!A=" @<W1A<G1U<"X*"2 @5&AE("!A<W-I9VYM96YT("!H
  48. XM87,@('1H92!S86UE(&9O<FT@87,@=VAE;B!G:79E;B!A<R!A;@H)("!E9&ET
  49. XM;W(@8V]M;6%N9"P@:2YE.@H*"2 @7PAN7PAA7PAM7PAE/5\(<U\(=%\(<E\(
  50. XM:5\(;E\(9PH)(" @(" @(&9O<B!S=')I;F<@<&%R86UE=&5R<PH*"2 @7PAN
  51. XM7PAA7PAM7PAE/5\(;E\(=5\(;5\(8E\(95\(<@H)(" @(" @(&9O<B!N=6UE
  52. XM<FEC('!A<F%M971E<G,*"@D@(%\(;E\(85\(;5\(92!T;R!T=7)N(&$@0F]O
  53. XM;&5A;B!P87)A;65T97(@;VX*"@D@(&YO7PAN7PAA7PAM7PAE"@D@(" @(" @
  54. XM=&\@='5R;B!A($)O;VQE86X@<&%R86UE=&5R(&]F9@H*(" @(" M="!?"'1?
  55. XM"&%?"&<*"2 @161I="!T:&4@9FEL92!C;VYT86EN:6YG('1H92 @9&5F:6YI
  56. XM=&EO;B @<W!E8VEF:65D("!A<PH)("!?"'1?"&%?"&<L(&%T('1H92!S=&%R
  57. XM="!O9B!T:&4@9&5F:6YI=&EO;B H87,@<&5R('9I*2X*"B @(" @*U\(;E\(
  58. XM=5\(;5\(8E\(95\(<@H)("!';R!T;R!T:&4@<W!E8VEF:65D("!L:6YE("!N
  59. XM=6UB97(@(&]F("!T:&4@(&9I;&4@(&)E:6YG"@D@(&5D:71E9"X*"B @(" @
  60. XM*R]?"'!?"&%?"'1?"'1?"&5?"')?"&X*"2 @1V\@=&\@=&AE(&9I<G-T(&]C
  61. XM8W5R<F5N8V4@(&]F("!T:&4@('-P96-I9FEE9" @7PAP7PAA7PAT7PAT7PAE
  62. XM7PAR7PAN"@D@('=I=&AI;B!T:&4@9FEL92!B96EN9R!E9&ET960N"@H@(" @
  63. XM(%1H92 M<B!C;VUM86YD(&QI;F4@;W!T:6]N(&ES(&YO="!S=7!P;W)T960N
  64. XM"@I%3DA!3D-%345.5%,*("!-=6QT:7!L92!B=69F97)S(&%N9"!W:6YD;W=S
  65. XM"B @(" @02!?"&)?"'5?"&9?"&9?"&5?"'(@:7,@=&AE("!I;G1E<FYA;" @
  66. XM;V)J96-T("!W:&EC:" @:&]L9',@(&$@(&9I;&4@(&EN"B @(" @;65M;W)Y
  67. XM+" @=VAI;&4@82!?"'=?"&E?"&Y?"&1?"&]?"'<@:7,@86X@87)E82!O9B!T
  68. XM:&4@<V-R965N('=H:6-H('-H;W=S"B @(" @<&%R="!O9B!A(&)U9F9E<BX@
  69. XM($5V97)Y('=I;F1O=R!R969E<F5N8V5S(&$@8G5F9F5R+"!E=F5N(&EF"@H*
  70. XM"E5N:7@@(" @(" @(" @(" @(" @($QA<W0@8VAA;F=E.B Q.2\V+S$Y.3(@
  71. XM(" @(" @(" @(" @(" @(" @(" Q"@H*"@H*"EA622@Q*2 @(" @(" @(" @
  72. XM(" @(" @("!54T52($-/34U!3D13(" @(" @(" @(" @(" @(" @(" @6%9)
  73. XM*#$I"@H*"B @(" @;F\@(&9I;&4@(&ES("!B96EN9R @961I=&5D+B @(%1H
  74. XM92 @9F]L;&]W:6YG("!C;VUM86YD<R @87)E"B @(" @879A:6QA8FQE(&9O
  75. XM<B!O<&5R871I;F<@;VX@8G5F9F5R<R!A;F0@=VEN9&]W<SH*"B @(" @.F)U
  76. XM9F9E<@H)("!C<F5A=&4@82!N97<@8G5F9F5R(&EN(&$@;F5W('=I;F1O=SL@
  77. XM8V%N(&)E(&9O;&QO=V5D(&)Y"@D@(&$@9FEL96YA;64L('=H:6-H('=I;&P@
  78. XM8F4@961I=&5D(&EN('1H92!N97<@8G5F9F5R+@H*(" @(" Z<W!L:70*"2 @
  79. XM8W)E871E(&$@(&YE=R @=VEN9&]W("!O;B @=&\@('1H92 @8W5R<F5N=" @
  80. XM8G5F9F5R("!B>0H)("!S<&QI='1I;F<@("!T:&4@("!C=7)R96YT("!W:6YD
  81. XM;W<@(&EN("!H86QF+B @(%1H92 @='=O"@D@(')E<W5L=&EN9R!W:6YD;W=S
  82. XM(&%R92!S:6UI;&%R("!T;R @7PAV7PAI7PAE7PAW7PAP7PAO7PAR7PAT7PAS
  83. XM("!O;B @=&\@(&$*"2 @<VEN9VQE("!E9&ET:6YG("!B=69F97(L("!I;B @
  84. XM=&AA=" @8VAA;F=E<R!M861E(&EN(&]N90H)("!W:6YD;W<@87)E(')E9FQE
  85. XM8W1E9"!I;B!T:&4@;W1H97(@;VYE+@H*(" @(" Z8VQO<V4*"2 @8VQO<V4@
  86. XM=&AE(&-U<G)E;G0@=VEN9&]W.R!W:6QL(&%L<V\@8VQO<V4@=&AE(&)U9F9E
  87. XM<B!I9@H)("!T:&ES(&ES('1H92!L87-T('=I;F1O=R!O;B!T;R!I="X*"B @
  88. XM(" @.G@@+R!:6@H)("!C;&]S92!O;FQY('1H92!C=7)R96YT('=I;F1O=RX@
  89. XM($EF('1H92 @=VEN9&]W("!I<R @=&AE"@D@(&]N;'D@;VYE(&]N('1O('1H
  90. XM92!B=69F97(L('1H92!B=69F97(@=VEL;"!B92!C;&]S960@87,*"2 @=V5L
  91. XM;"P@=W)I=&EN9R!I="!F:7)S="!I9B!I="!I<R!M;V1I9FEE9"X*"B @(" @
  92. XM9R @("!M;W9E('1O('1H92!N97AT('=I;F1O=RX*"B @(" @7E<@("!I;F-R
  93. XM96%S92!T:&4@<VEZ92!O9B!T:&4@8W5R<F5N="!W:6YD;W<@*&UA>2!B92!G
  94. XM:79E;B!A"@D@(&YU;65R:6,@<')E9FEX+"!D969A=6QT(&ES(&]N92!L:6YE
  95. XM*2X*"B @(" @7E0@("!D96-R96%S92!T:&4@<VEZ92!O9B!T:&4@8W5R<F5N
  96. XM="!W:6YD;W<@*&UA>2!B92!G:79E;B!A"@D@(&YU;65R:6,@<')E9FEX+"!D
  97. XM969A=6QT(&ES(&]N92!L:6YE*2X*"B @(" @7D\@("!M86ME('1H92!C=7)R
  98. XM96YT('=I;F1O=R!A<R!L87)G92!A<R!P;W-S:6)L92X*"B @(" @7ET@("!A
  99. XM<R @9F]R("!V:2P@(&)U=" @8W)E871E("!A("!N97<@(&)U9F9E<B @('=I
  100. XM;F1O=R @(&EF"@D@(&%P<')O<')I871E("AA;F0@:68@875T;W-P;&ET(&%L
  101. XM;&]W<RDN"@H@(" @($YO=&4@=&AA="!T:&4@.G%U:70@8V]M;6%N9"!Q=6ET
  102. XM<R!O=70@;V8@=&AE(&5D:71O<BP@;F]T(&]U= H@(" @(&]F("!A("!W:6YD
  103. XM;W<N("!4:&4@.F-L;W-E(&-O;6UA;F0@:7,@=&AU<R!T:&4@97%U:79A;&5N
  104. XM="!O9@H@(" @(#IQ=6ET(&9O<B!W:6YD;W=S+B @5&AE<F4@:7,@;F\@97%U
  105. XM:79A;&5N="!O9B Z>"!O<B @6EH@(&9O<@H@(" @('1H92!W:&]L92!E9&ET
  106. XM;W([('1H97-E(&AA=F4@8F5E;B!H:6IA8VME9"!F;W(@;W!E<F%T:6]N<R!O
  107. XM;@H@(" @('=I;F1O=W,N"@H@(" @(%1H92!N=6UE<FEC(&%U=&]S<&QI="!P
  108. XM87)A;65T97(@<W!E8VEF:65S('1H92!M87AI;75M(&YU;6)E<@H@(" @(&]F
  109. XM(" @8G5F9F5R("!W:6YD;W=S("!T:&%T("!W:6QL("!B92 @8W)E871E9" @
  110. XM875T;VUA=&EC86QL>0H@(" @('=H96YE=F5R('EO=2!E:71H97(@961I="!M
  111. XM;W)E('1H86X@;VYE(&9I;&4L(&]R('5S92!T86=S("!T;PH@(" @(&5D:70@
  112. XM82!D:69F97)E;G0@9FEL92X*"B @(" @56YD;R!W;W)K<R!P97(@8G5F9F5R
  113. XM+"!A<R!D;R!M87)K<SL@>6%N:R]P=70@86YD(')E9&\@*'1H92 N"B @(" @
  114. XM8V]M;6%N9"D@=V]R:R!O=F5R(&%L;"!B=69F97)S+"!I+F4N('EO=2!C86X@
  115. XM9&5L971E(&9R;VT@;VYE"B @(" @8G5F9F5R(&%N9"!P=70@=&AE('1E>'0@
  116. XM:6YT;R!A(&1I9F9E<F5N="!B=69F97(N"@H*"@H*56YI>" @(" @(" @(" @
  117. XM(" @(" @3&%S="!C:&%N9V4Z(#$Y+S8O,3DY,B @(" @(" @(" @(" @(" @
  118. XM(" @(#(*"@H*"@H*6%9)*#$I(" @(" @(" @(" @(" @(" @(%5315(@0T]-
  119. XM34%.1%,@(" @(" @(" @(" @(" @(" @("!85DDH,2D*"@H*("!&:6QE('!R
  120. XM97-E<G9A=&EO;@H@(" @(%)A=&AE<B!T:&%N('5S92!V:2=S(%5N:7@M<W!E
  121. XM8VEF:6,@;65T:&]D(&9O<B @<')E<V5R=F%T:6]N+ H@(" @('AV:2 @9&]E
  122. XM<R!P97)I;V1I8R!P<F5S97)V871I;VX@;V8@86QL(&9I;&5S(&-U<G)E;G1L
  123. XM>2!B96EN9PH@(" @(&5D:71E9"!I;G1O('1E;7!O<F%R>2!F:6QE<R!I;B!T
  124. XM:&4@<V%M92!D:7)E8W1O<GDN("!)="!T<FEE<PH@(" @('1O("!D;R!T:&ES
  125. XM('=H96X@>6]U(&%R96XG="!T>7!I;F<L('-O('1H870@>6]U('=O;B=T(&YO
  126. XM=&EC90H@(" @('1H92!S:&]R="!D96QA>2!W:&5N('1H92 @=&5M<&]R87)Y
  127. XM("!F:6QE("!I<R @=W)I='1E;B @;W5T+@H@(" @($]B=FEO=7-L>2P@;VYL
  128. XM>2!C:&%N9V5D(&9I;&5S(&%R92!P<F5S97)V960@:6X@=&AI<R!W87DL(&%N
  129. XM9 H@(" @('1H92!T96UP;W)A<GD@9FEL92!I<R!R96UO=F5D(&]N8V4@=&AE
  130. XM(')E86P@(&9I;&4@(&AA<R @8F5E;@H@(" @('-U8V-E<W-F=6QL>2!W<FET
  131. XM=&5N+@H*(" X+6)I="!C:&%R86-T97(@<W5P<&]R= H@(" @($-H87)A8W1E
  132. XM<G,@=VET:"!T:&4@=&]P(&)I="!S970@87)E(&%C8V5P=&5D(&)Y('AV:2P@
  133. XM8G5T("!I= H@(" @(&ES("!N;W0@('EE=" @<&]S<VEB;&4@('1O("!H879E
  134. XM(&YU;&P@*"=<,"<I(&)Y=&5S(&EN(&$@9FEL90H@(" @(&)U9F9E<BX@($AO
  135. XM=R!C:&%R86-T97)S(&%R92!D:7-P;&%Y960@8V%N(&)E("!C;VYT<F]L;&5D
  136. XM("!B>0H@(" @('1H92 @8V-H87)S("!A;F0@(&UC:&%R<R @<&%R86UE=&5R
  137. XM<RP@('=H:6-H+" @:68@<V5T+"!C875S90H@(" @(&-O;G1R;VP@(&%N9" @
  138. XM;65T82UC:&%R86-T97)S("!R97-P96-T:79E;'D@('1O("!B92 @(&]U='!U
  139. XM= H@(" @('5N8VAA;F=E9#L@("!O=&AE<G=I<V4@("!T:&5Y("!A<F4@('-H
  140. XM;W=N("!A<R @<V5Q=65N8V5S("!O9@H@(" @('!R:6YT86)L92!C:&%R86-T
  141. XM97)S+@H*(" @("!486)S(&%R92!N;W)M86QL>2!D:7-P;&%Y960@87,@82!S
  142. XM97)I97,@(&]F("!S<&%C97,@(&]F("!T:&4*(" @("!A<'!R;W!R:6%T92 @
  143. XM;&5N9W1H(" H86-C;W)D:6YG("!T;R!T:&4@=&%B<W1O<',@<&%R86UE=&5R
  144. XM*3L*(" @("!S971T:6YG(&QI<W0@;6]D92!W:6QL(&-A=7-E('1H96T@=&\@
  145. XM8F4@9&ES<&QA>65D(&%S(&-O;G1R;VP*(" @("!C:&%R86-T97)S+" @87,@
  146. XM('=I;&P@=6YS971T:6YG('1H92!T86)S('!A<F%M971E<BX@($AO=R!T:&4*
  147. XM(" @("!T86(@8VAA<F%C=&5R(&ES(&1I<W!L87EE9"!I<R!T:&5N('5N9&5R
  148. XM('1H92!C;VYT<F]L(&]F("!T:&4*(" @("!C8VAA<G,@<&%R86UE=&5R+@H*
  149. XM(" @("!9;W4@8V%N('5S92!T:&4@7E\@*&-O;G1R;VPM=6YD97)S8V]R92D@
  150. XM8V]M;6%N9"!T;R!F;&EP("!T:&4*(" @("!T;W @(&)I=" @;V8@('1H92 @
  151. XM8VAA<F%C=&5R("!T:&4@8W5R<V]R(&ES(&]N+B @5&AI<R!M87D@8F4*(" @
  152. XM("!U<V5F=6P@;VX@<WES=&5M<R!W:&5R92!I="!I<R!O=&AE<G=I<V4@:6UP
  153. XM;W-S:6)L92!T;R @96YT97(*(" @(" X+6)I="!C:&%R86-T97)S+@H*("!&
  154. XM:6QE(&9O<FUA=',*(" @("!8=FD@8V%N(')E860@86YD('=R:71E('1E>'0@
  155. XM9FEL97,@:6X@;F]N+55N:7@@9F]R;6%T<RX@("!4:&4*(" @("!C=7)R96YT
  156. XM(" @9F]R;6%T("!I<R @9VEV96X@(&)Y("!T:&4@('9A;'5E("!O9B @=&AE
  157. XM("!F;W)M870*(" @("!P87)A;65T97(L('=H:6-H(&UA>2!B92!S970@=&\@
  158. XM(G5N:7@B+" B;7-D;W,B+"!E=&,N("!4;R!S964*(" @("!A(&QI<W0@;V8@
  159. XM879A:6QA8FQE(&9O<FUA=',L('1Y<&4*"@D@(#IS92!F;70]/PH*("!%>'1E
  160. XM;F1E9"!R96=U;&%R(&5X<')E<W-I;VYS"B @(" @=FDG<R @;6%G:6,@('!A
  161. XM<F%M971E<B @:7,@('-U<&5R<V5D960@(&)Y(" @=&AE(" @<F5G97AT>7!E
  162. XM"B @(" @<&%R86UE=&5R+"!W:&EC:"!C86X@=&%K92!T:&4@9F]L;&]W:6YG
  163. XM('9A;'5E<SH*"B @(" @=&%G<R!O;FQY(%X@86YD("0@87)E('-I9VYI9FEC
  164. XM86YT("AU<V5D(&9O<B!T86=S*0H*(" @("!G<F5P(&QI:V4@9W)E<"@Q*2P@
  165. XM8G5T('=I=&@@7#P@86YD(%P^(&%D9&5D"@H@(" @(&5G<F5P"@D@(&QI:V4@
  166. XM96=R97 H,2DL(&)U="!W:71H(%P\(&%N9"!</B!A9&1E9 H*(" @("!4:&4@
  167. XM9&5F875L="!I<R!G<F5P+@H*"@H*56YI>" @(" @(" @(" @(" @(" @3&%S
  168. XM="!C:&%N9V4Z(#$Y+S8O,3DY,B @(" @(" @(" @(" @(" @(" @(#,*"@H*
  169. XM"@H*6%9)*#$I(" @(" @(" @(" @(" @(" @(%5315(@0T]-34%.1%,@(" @
  170. XM(" @(" @(" @(" @(" @("!85DDH,2D*"@H*(" @("!.;W1E('1H870@:70@
  171. XM:7,@<W1I;&P@<&]S<VEB;&4@=&\@<V5T(&]R('5N<V5T(&UA9VEC("!A<R @
  172. XM:6X*(" @("!V:3L@('1H:7,@('=I;&P@('-I;7!L>2 @<F5S=6QT("!I;B @
  173. XM<F5G97AT>7!E("!B96EN9R!S970@87,*(" @("!A<'!R;W!R:6%T92X*"B @
  174. XM(" @5&AE('-E8W1I;VYS(&%N9"!P87)A9W)A<&AS("!P87)A;65T97)S("!D
  175. XM969I;F4@(&5G<F5P+7-T>6QE"B @(" @<&%T=&5R;G,@('1O("!S96%R8V@@
  176. XM(&9O<BP@(')A=&AE<B!T:&%N('9I)W,@<VEM<&QI<W1I8R H86YD"B @(" @
  177. XM=')O9F8M9&5P96YD96YT*2!C:&%R86-T97(@<&%I<G,N"@H@($EM<')O=F5D
  178. XM(')E<&QA8V4@;6]D90H@(" @(%1H92!2(&-O;6UA;F0@86-T<R!M;W)E(&EN
  179. XM=&5L;&EG96YT;'D@=VAE;B!Y;W4@<')E<W,@(')E='5R;@H@(" @("T@(&ET
  180. XM("!L96%V97,@('1H92 @<F5S="!O9B!T:&4@8W5R<F5N="!L:6YE(&%L;VYE
  181. XM+"!A;F0@:G5S= H@(" @('-T87)T<R!R97!L86-I;F<@=&5X="!O;B!T:&4@
  182. XM(&YE>'0@(&QI;F4L("!S=&%R=&EN9R @870@('1H90H@(" @('-C<F5E;B!C
  183. XM;VQU;6X@=VAE<F4@>6]U(&9I<G-T('1Y<&5D(%(N"@H@($-O;6UA;F0@<F4M
  184. XM97AE8W5T:6]N"B @(" @07,@=V5L;"!A<R!T:&4@;F]R;6%L(&YA;65D(" H
  185. XM8V]N:G5G871E*2 @8G5F9F5R<RP@(&%N9" @=&AE"B @(" @9&5F875L=" @
  186. XM;VYE("AN86UE9"! *2P@=&AE<F4@97AI<W0@<V5V97)A;"!E>'1R82!O;F5S
  187. XM(&YA;65D"B @(" @.BP@+RP@/R!A;F0@(2P@=VAI8V@@8V]N=&%I;B!T:&4@
  188. XM;&%S="!C;VUM86YD(&QI;F5S('1Y<&5D('1O"B @(" @96%C:" @;V8@('1H
  189. XM92 @9VEV96X@8V]M;6%N9',N("!3;R!F;W(@:6YS=&%N8V4L($ Z('=I;&P@
  190. XM<F4M"B @(" @97AE8W5T92!T:&4@;&%S="!E>"!C;VUM86YD+"!O<B!Y;W4@
  191. XM8V%N(&EN<V5R="!I="!I;G1O("!Y;W5R"B @(" @8G5F9F5R+"!E9&ET(&ET
  192. XM(&%N9"!T:&5N(')E+65X96-U=&4@:70@*&4N9RX@=VET:"!D9$! *2X*"B @
  193. XM2G5M<'-C<F]L; H@(" @(%=H96X@;75L=&EP;&4@=VEN9&]W<R!A<F4@=7-E
  194. XM9"P@>'9I(&YO<FUA;&QY(&AA<R!T;R!B92 @86)L90H@(" @('1O("!S8W)O
  195. XM;&P@(&EN9&EV:61U86P@('=I;F1O=W,@('=I=&AO=70@<V-R;VQL:6YG('1H
  196. XM92!W:&]L90H@(" @('-C<F5E;BX@(%1H:7,@8V%N(&)E('9E<GD@:6YE9F9I
  197. XM8VEE;G0@;VX@('1E<FUI;F%L<R @=VET:&]U= H@(" @('-C<F]L;&EN9R @
  198. XM<F5G:6]N<RP@('-O('1H92!J=6UP<V-R;VQL('!A<F%M971E<B!I<R!P<F]V
  199. XM:61E9 H@(" @('1O(&-O;G1R;VP@=&AE(&5D:71O<B=S('-C<F]L;&EN9R!B
  200. XM96AA=FEO=7(N("!)="!C86X@8F4@('-E= H@(" @('1O(&]N92!O9CH*"B @
  201. XM(" @;V9F("!7:&5N('1H92!C=7)S;W(@;6]V97,@;W5T<VED92 @82 @=VEN
  202. XM9&]W)W,@(&)O=6YD87)I97,L"@D@(&%N9" @=&AE("!N97<@('!O<VET:6]N
  203. XM(&ES(&YE87(@96YO=6=H+"!T:&4@=VEN9&]W('=I;&P*"2 @<V-R;VQL('1O
  204. XM('1H92!N97<@<&]S:71I;VXN"@H@(" @(&]N(" @5VAE;B!T:&4@8W5R<V]R
  205. XM(&UO=F5S(&]U='-I9&4@(&$@('=I;F1O=R=S("!B;W5N9&%R:65S+ H)("!T
  206. XM:&4@=VEN9&]W('=I;&P@86QW87ES(&IU;7 @=&\@=&AE(&YE=R!P;W-I=&EO
  207. XM;BX*"B @(" @875T;R!!('=I;F1O=R!W:6QL('-C<F]L;"!O;FQY(&EF(&ET
  208. XM(&-A;B!D;R!S;R @969F:6-I96YT;'D["@D@(&]T:&5R=VES92!I="!W:6QL
  209. XM(&IU;7 N"@H@(" @(%1H92!D969A=6QT('9A;'5E(&ES(&%U=&\N"@H@(" @
  210. XM($]N("!)4T$M='EP92 @<WES=&5M<R @=VAI8V@@(&AA=F4@(&UE;6]R>2UM
  211. XM87!P960@(&1I<W!L87ES+ H@(" @(&AA<F1W87)E(" @(&-H87)A8W1E<B @
  212. XM(&=E;F5R871O<G,@("!A;F0@("!R96%S;VYA8FQY(" @9F%S= H@(" @('!R
  213. XM;V-E<W-O<G,L(&IU;7!S8W)O;&P@('-H;W5L9" @9V5N97)A;&QY("!B92 @
  214. XM<V5T("!T;R @;V9F.PH@(" @(&AO=V5V97(L("!O;B!,0T0@<V-R965N<R!O
  215. XM<B!O=&AE<B!D:7-P;&%Y<R!W:71H(&$@;&]N9R!I;6%G90H@(" @('!E<G-I
  216. XM<W1E;F-E+"!T:&ES(&UA>2!A8W1U86QL>2!M86ME('1H92!T97AT(&UO<F4@
  217. XM(&1I9F9I8W5L= H@(" @('1O("!R96%D+" @86YD("!M86YY("!U<V5R<R @
  218. XM;6%Y(&)E(&UO<F4@8V]M9F]R=&%B;&4@=VET:"!I= H@(" @('1U<FYE9"!O
  219. XM;BX*"B @(" @17AP;&EC:70@<V-R;VQL(&-O;6UA;F1S("AE+F<N("!>1"!A
  220. XM;F0@7D4I(&%R92!N;W0@(&%F9F5C=&5D"B @(" @8GD@=&AE(&IU;7!S8W)O
  221. XM;&P@<&%R86UE=&5R+@H*"@I5;FEX(" @(" @(" @(" @(" @("!,87-T(&-H
  222. XM86YG93H@,3DO-B\Q.3DR(" @(" @(" @(" @(" @(" @(" @- H*"@H*"@I8
  223. XM5DDH,2D@(" @(" @(" @(" @(" @(" @55-%4B!#3TU-04Y$4R @(" @(" @
  224. XM(" @(" @(" @(" @(%A622@Q*0H*"@H@($-O;&]U<@H@(" @(%1H97)E(&%R
  225. XM92!F;W5R(&YE=R!P87)A;65T97)S('1O(&-O;G1R;VP@<V-R965N(&-O;&]U
  226. XM<G,Z"@H@(" @(&-O;&]U<B @(" @(&-O;&]U<B!U<V5D(&9O<B!T97AT"@H@
  227. XM(" @('-T871U<V-O;&]U<F-O;&]U<B!U<V5D(&9O<B!S=&%T=7,@;&EN97,*
  228. XM"B @(" @<F]S8V]L;W5R(" @87,@<W1A='5S8V]L;W5R+"!B=70@9F]R(')E
  229. XM861O;FQY(&9I;&5S"@H@(" @('-Y<W1E;6-O;&]U<F-O;&]U<B!U<V5D(&9O
  230. XM<B!S>7-T96T@;6]D92 H:2YE+B!S=6)S:&5L;',@(&%N9 H@(" @(&%F=&5R
  231. XM('1E<FUI;F%T:6]N*0H*(" @("!4:&5S92!P87)A;65T97)S(&%R92!N=6UE
  232. XM<FEC+"!A;F0@=&AE('9A;'5E(&UE86YS("!D:69F97)E;G0*(" @("!T:&EN
  233. XM9W,@(&]N("!D:69F97)E;G0@(&]P97)A=&EN9R!S>7-T96US+B @3VX@56YI
  234. XM>"P@:70@:7,@86X*(" @("!I;F1E>"!I;G1O('1H92!T97)M8V%P*#4I(&5N
  235. XM=')I97,@(F,P(B!T;R @(F,Y(BP@('=H:6-H("!A<F4*(" @("!A<W-U;65D
  236. XM("!T;R @8F4@(&-O;&]U<BUS971T:6YG(&5S8V%P92!S97%U96YC97,@:68@
  237. XM=&AE>2!A<F4*(" @("!P<F5S96YT+B @268@=&AE>2!A<F4@(&YO=" @<')E
  238. XM<V5N="P@(")S;R(@("AB96=I;B @<W1A;F1O=70*(" @("!M;V1E*2!A;F0@
  239. XM(G-E(B H96YD('-T86YD;W5T(&UO9&4I(&%R92!U<V5D(&EN<W1E860N("!6
  240. XM86QU97,*(" @("!O9B P(&%N9" Q(&=I=F4@(&YO<FUA;" @=&5X="P@('=H
  241. XM97)E87,@(#(@(&%N9" @86)O=F4@(&=I=F4*(" @("!S=&%N9&]U="!M;V1E
  242. XM+@H*(" @("!4:&4@(&1E9F%U;'0@(&-O;&]U<B @9F]R("!T:&4@(')O<V-O
  243. XM;&]U<B @('!A<F%M971E<B @('=I;&P*(" @("!G96YE<F%L;'D@(&EN=F]L
  244. XM=F4@(')E9" @:68@(&-O;&]U<G,@(&%R92!A=F%I;&%B;&4[('1H:7,@:7,*
  245. XM(" @("!I;G1E;F1E9"!T;R!P<F]V:61E(&$@=V%R;FEN9R!T;R!T:&4@=7-E
  246. XM<B!T:&%T("!W<FET:6YG("!T:&4*(" @("!F:6QE(&UA>2!N;W0@8F4@<&]S
  247. XM<VEB;&4N"@H@($]N+6QI;F4@:&5L< H@(" @($$@<')I;6ET:79E(&AE;' @
  248. XM9F%C:6QI='D@:7,@879A:6QA8FQE.R @=&AE(" Z:&5L<" @8V]M;6%N9 H@
  249. XM(" @('-I;7!L>2 @8W)E871E<R @82 @;F5W("!B=69F97(@=VEN9&]W(&]N
  250. XM('1O(&$@<W1A;F1A<F0@:&5L< H@(" @(&9I;&4N("!4:&4@;F%M92!O9B!T
  251. XM:&4@9FEL92!W:&EC:"!I<R!E9&ET960@:7,@9VEV96X@8GD@('1H90H@(" @
  252. XM(&AE;'!F:6QE("!S=')I;F<@('!A<F%M971E<CL@=&AE(&1E9F%U;'0@;VX@
  253. XM56YI>"!V97)S:6]N<R!I<PH@(" @("(O=7-R+VQI8B]X=FDN:&5L<"(N("!.
  254. XM;W1E('1H870@=&AE(&AE;' @9FEL92!B=69F97(@=VEL;"!B90H@(" @(&UA
  255. XM<FME9" @(FYO=" @961I=&%B;&4B("!W:&5N("!I="!I<R!C<F5A=&5D+"!W
  256. XM:&EC:"!P<F5V96YT<PH@(" @(&%C8VED96YT86P@;W9E<G=R:71I;F<@;V8@
  257. XM=&AE(&AE;' @9FEL92!E=F5N('=H96X@('1H92 @9FEL90H@(" @('!E<FUI
  258. XM<W-I;VYS('=O=6QD(&%L;&]W(&ET+@H*("!-:7-C96QL86YE;W5S"B @(" @
  259. XM5&AE(&-O;6UA;F0@.G=N("AW<FET92!F:6QE(&%N9"!E9&ET(&YE>'0I(&ES
  260. XM("!P<F]V:61E9"P@(&%S"B @(" @:6X@4$,M=FDN"@H@(" @(%1H92!N97<@
  261. XM961I="!P87)A;65T97(@8V]N=')O;',@('=H971H97(@(&$@(&)U9F9E<B @
  262. XM8V%N("!B90H@(" @(&UO9&EF:65D+B @(%1H:7,@;6%Y(&)E('5S960@=&\@
  263. XM:6UP;&5M96YT(&$@;FEC97(@=F5R<VEO;B!O9@H@(" @('9I97<H,2D@=&AA
  264. XM;B!T:&4@<W1A;F1A<F0@=FD@=F5R<VEO;BP@<VEN8V4@(&ET("!W;VXG=" @
  265. XM9F]O; H@(" @('EO=2 @:6YT;R @=&AI;FMI;F<@('1H870@(&5D:71I;F<@
  266. XM('1H92!B=69F97(@:7,@:6X@86YY('=A>0H@(" @('-A9F4N("!"92!W87)N
  267. XM960Z(&]N8V4@:&%V:6YG('-E="!N;V5D:70L(&ET(&ES(&YO="!P;W-S:6)L
  268. XM90H@(" @('1O(&1O(&$@.G-E="!E9&ET(&%N>2!M;W)E+B @270G<R!A(&]N
  269. XM92UW87D@<W1R965T+@H*(" @("!);B!I;G-E<G0@86YD(')E<&QA8V4@;6]D
  270. XM97,L(%Y!(&AA<R!T:&4@<V%M92!M96%N:6YG("!A<R @7D *(" @("!I;B @
  271. XM=FDL("!E>&-E<'0@('1H870@:70@=V]R:W,@870@86YY('1I;64L(&YO="!J
  272. XM=7-T(&9O<B!T:&4*(" @("!F:7)S="!C:&%R86-T97(N("!!;'-O+"!T>7!I
  273. XM;F<@7D)?"'@@=VAE<F4@7PAX(&ES('1H92!N86UE(&]F("!A"B @(" @8V]N
  274. XM:G5G871E("!B=69F97(L("!I;G-E<G1S('1H92!C;VYT96YT<R!O9B!T:&%T
  275. XM(&)U9F9E<B!I;G1O"B @(" @=&AE(&EN<'5T('-T<F5A;2!A="!T:&%T('!O
  276. XM:6YT+B @5&AE(&)U9F9E<B!N86UE9" @/" @86QW87ES"@H*"E5N:7@@(" @
  277. XM(" @(" @(" @(" @($QA<W0@8VAA;F=E.B Q.2\V+S$Y.3(@(" @(" @(" @
  278. XM(" @(" @(" @(" U"@H*"@H*"EA622@Q*2 @(" @(" @(" @(" @(" @("!5
  279. XM4T52($-/34U!3D13(" @(" @(" @(" @(" @(" @(" @6%9)*#$I"@H*"B @
  280. XM(" @8V]N=&%I;G,@=&AE(&QA<W0@=&AI;F<@:6YS97)T960L('-O('1H870@
  281. XM7D(\(&ES('1H92!S86UE(&%S"B @(" @7D$N"@I,24U)5$%424].4PH@($5X
  282. XM(&UO9&4*(" @("!4:&4@;6%I;B!A<F5A(&EN('=H:6-H('AV:2!I<R!L86-K
  283. XM:6YG(&ES('9I)W,@97@@;6]D92P@=VAI8V@*(" @("!I<R @;F]T(&EM<&QE
  284. XM;65N=&5D(&%T(&%L;" H86YD(&YE:71H97(@87)E(&5D:70L(&4L(&]R(&]P
  285. XM96X*(" @("!M;V1E<RDN("!(;W=E=F5R+"!M86YY(&]F('1H92!E>"!C;VUM
  286. XM86YD<R!A<F4@(&%V86EL86)L92 @:6X*(" @("!V:2 @;6]D92!A<R!C;VQO
  287. XM;B!C;VUM86YD<SL@=&AE(&-O;&]N(&-O;6UA;F1S('1H870@:&%V92!N;W0*
  288. XM(" @("!B965N(&EM<&QE;65N=&5D(&%R92 @;6]S=&QY("!T:&]S92 @=VAI
  289. XM8V@@(&]F9F5R("!T:&4@('-A;64*(" @("!F=6YC=&EO;F%L:71Y(&%S(&]T
  290. XM:&5R(&-O;6UA;F1S(&EN('9I(&UO9&4N"@H@(" @($EN('!A<G1I8W5L87(L
  291. XM(&%B8G)E=FEA=&4L(&%P<&5N9"P@8VAA;F=E+"!E>"P@:6YS97)T+"!J;VEN
  292. XM+ H@(" @(&]P96XL(')E8V]V97(L('5N86)B<F5V:6%T92P@=6YD;RP@=W)I
  293. XM=&4^/BP@>B!A;F0@?"!H879E(&YO= H@(" @(&)E96X@:6UP;&5M96YT960@
  294. XM87,@8V]L;VX@8V]M;6%N9',@>65T+@H*("!6:2!M;V1E"B @(" @26X@=FD@
  295. XM;6]D92P@=&AE("!5("!A;F0@(#T@(&-O;6UA;F1S("!A<F4@(&YO=" @:6UP
  296. XM;&5M96YT960L"B @(" @86QT:&]U9V@@('1H97)E("!I<R @;F\@(')E86P@
  297. XM(')E87-O;B!W:'D@=&AE>2!S:&]U;&1N)W0@8F4L"B @(" @=VAI;'-T(%$@
  298. XM:7,@:6YA<'!R;W!R:6%T92!I;B!T:&4@8V]N=&5X="!O9B!X=FDL('-I;F-E
  299. XM('1H97)E"B @(" @:7,@;F\@97@@;6]D92X*"B @4&%R86UE=&5R<PH@(" @
  300. XM($UA;GD@;V8@=FDG<R @<&%R86UE=&5R<R @:&%V92 @;F]T("!B965N("!I
  301. XM;7!L96UE;G1E9#L@('1H90H@(" @(&-O;6UA;F0@(#IS92!A;&P@9VEV97,@
  302. XM82!C;VUP;&5T92!L:7-T+"!W:71H(&-U<G)E;G0@=F%L=65S+ H@(" @(&]F
  303. XM('1H;W-E('1H870@:&%V92!B965N+@H*("!-:7-C96QL86YE;W5S"B @(" @
  304. XM4F5P96%T(&-O=6YT<R!B969O<F4@:6YS97)T:6]N<R!D;VXG="!W;W)K+@H*
  305. XM(" @("!!<'!E;F1I;F<@=&\@;F%M960@8G5F9F5R<R!I<R!N;W0@>65T(&EM
  306. XM<&QE;65N=&5D+@H*(" @("!4>7!I;F<@7E$@:6X@:6YP=70@;6]D92!D;V5S
  307. XM(&YO="!M96%N('1H92 @<V%M92 @87,@(%Y6.R @:70*(" @("!J=7-T("!I
  308. XM;G-E<G1S("!A(&!>42<L(&%S<W5M:6YG(&ET(&=E=',@87,@9F%R(&%S('1H
  309. XM92!E9&ET;W(*(" @("!A="!A;&PN"@H@(" @(%1Y<&EN9R!>5R!I;B!I;G-E
  310. XM<G0@;6]D92!D;V5S(&YO="!B86-K('5P(&]N92!W;W)D(&%S(&EN('9I+@H*
  311. XM(" @("!)="!I<R!N;W0@<&]S<VEB;&4@=&\@(&EN=&5R<G5P=" @=&AE("!E
  312. XM9&ET;W(@('=H:6QE("!I=" @:7,*(" @("!P97)F;W)M:6YG("!C97)T86EN
  313. XM("!O<&5R871I;VYS+B @($EF("!Y;W4@('-T87)T("!O9F8@82!B:6<*(" @
  314. XM("!G;&]B86P@8V]M;6%N9"P@>6]U(&AA=F4@=&\@=V%I="!F;W(@:70@=&\@
  315. XM9FEN:7-H+@H*(" @("!&;&%G<R!A;F0@8V]U;G1S(&%F=&5R(&5X(&UO9&4@
  316. XM8V]M;6%N9',@87)E(&YO="!S=7!P;W)T960N"@H@(" @($ET(&ES(&YO="!P
  317. XM;W-S:6)L92!T;R!R96%D('1H92!O=71P=70@;V8@(&$@('-Y<W1E;2 @8V]M
  318. XM;6%N9 H@(" @('5S:6YG"@H)(" Z<B A7PAC7PAO7PAM7PAM7PAA7PAN7PAD
  319. XM"@H@(" @(&]R('1O('=R:71E(&EN=&\@82!C;VUM86YD('5S:6YG"@H)(" Z
  320. XM=R A7PAC7PAO7PAM7PAM7PAA7PAN7PAD+@H*"@I5;FEX(" @(" @(" @(" @
  321. XM(" @("!,87-T(&-H86YG93H@,3DO-B\Q.3DR(" @(" @(" @(" @(" @(" @
  322. XM(" @-@H*"@H*"@I85DDH,2D@(" @(" @(" @(" @(" @(" @55-%4B!#3TU-
  323. XM04Y$4R @(" @(" @(" @(" @(" @(" @(%A622@Q*0H*"@H@(" @(%)E9W5L
  324. XM87(@97AP<F5S<VEO;G,L(&%L=&AO=6=H(&EM<&QE;65N=&5D(" H<V5E("!A
  325. XM8F]V92DL("!D;PH@(" @(&YO=" @<W5P<&]R="!T:&4@?B!M971A8VAA<F%C
  326. XM=&5R.R!A;'-O+"!T:&4@7'4@86YD(%QL(&5S8V%P90H@(" @('-E<75E;F-E
  327. XM<R @87)E("!N;W0@('-U<'!O<G1E9" @:6X@('-U8G-T:71U=&4@("!R97!L
  328. XM86-E;65N= H@(" @('!A='1E<FYS+B @($YE=VQI;F5S("!I;F-L=61E9" @
  329. XM;VX@('1H92!R:6=H="!H86YD('-I9&4@;V8@80H@(" @('-U8G-T:71U=&EO
  330. XM;B!D;R!N;W0@8W5R<F5N=&QY(&-A=7-E('1H92!L:6YE("!T;R @8F4@('-P
  331. XM;&ET.PH@(" @('1H92!N97=L:6YE(&-H87)A8W1E<B!I<R!L:71E<F%L;'D@
  332. XM:6YS97)T960@:6YT;R!T:&4@;&EN92X*"B @(" @5&AE(#IG;&]B86P@8V]M
  333. XM;6%N9"!O;FQY('-U<'!O<G1S('1H92!C;VUM86YD<R!;;'!S)GYD72X*"D]4
  334. XM2$52($1)1D9%4D5.0T53($923TT@5DD*(" @("!4:&4@6%9)3DE4(&5N=FER
  335. XM;VYM96YT('9A<FEA8FQE(&ES(')E860@:6YS=&5A9" @;V8@($5824Y)5"X*
  336. XM(" @("!7:&EL<W0@;F\@9FEL97,@87)E('-O=7)C960@875T;VUA=&EC86QL
  337. XM>2P@=7-E<G,@=VAO('=I<V@@=&\*(" @("!H879E(&$@<W1A<G1U<"!F:6QE
  338. XM(&-A;B!A<G)A;F=E(&ET('9E<GD@(&5A<VEL>2X@("!S:"@Q*2 @;W(*(" @
  339. XM("!K<V@H,2D@=7-E<G,@<VAO=6QD(&%D9"!T:&ES(&QI;F4@=&\@=&AE:7(@
  340. XM)$A/344O+G!R;V9I;&4Z"@H)("!85DE.250])W-O=7)C92!?"'A?"'9?"&DM
  341. XM7PAS7PAT7PAA7PAR7PAT7PAU7PAP+5\(9E\(:5\(;%\(92<[(&5X<&]R="!8
  342. XM5DE.250*"B @(" @8W-H*#$I('5S97)S('-H;W5L9"!A9&0@=&AI<R!T;R!T
  343. XM:&5I<B D2$]-12\N;&]G:6XZ"@H)("!S971E;G8@6%9)3DE4("=S;W5R8V4@
  344. XM7PAX7PAV7PAI+5\(<U\(=%\(85\(<E\(=%\(=5\(<"U?"&9?"&E?"&Q?"&4G
  345. XM"@H@(" @(%1H92!T86=S('!A<F%M971E<B!C86X@8F4@('5S960@('1O("!S
  346. XM<&5C:69Y("!M=6QT:7!L92 @=&%G<PH@(" @(&9I;&5S.R @=&AE<V4@(&-A
  347. XM;B @8F4@<V5P87)A=&5D(&)Y(&5I=&AE<B!@8%P@)R<@*&)A8VMS;&%S: H@
  348. XM(" @('-P86-E*2!O<B!@8"PG)R H8V]M;6$I+@H*(" @("!!;'1E<FYA=&4@
  349. XM9FEL97,@87)E(&AA;F1L960@<VQI9VAT;'D@9&EF9F5R96YT;'DL("!O=VEN
  350. XM9R @=&\*(" @("!T:&4@('!R97-E;F-E("!O9B @8G5F9F5R(&%N9"!W:6YD
  351. XM;W<@:&%N9&QI;F<N("!%<W-E;G1I86QL>2P*(" @("!W:&5N('EO=2!C;&]S
  352. XM92!A(&)U9F9E<BP@:71S(&9I;&5N86UE(&ES(')E;65M8F5R960@(&%S("!T
  353. XM:&4*(" @("!A;'1E<FYA=&4@(&9I;&4[("!W:&5N("!Y;W4@(&EN=F]K92!T
  354. XM:&4@7EX@;W(@.F4@(R!C;VUM86YD<RP*(" @("!T:&ES(&9I;&4@:7,@<F4M
  355. XM961I=&5D+B @3F]T92!T:&%T(%Y>("!E9&ET<R @=&AE("!A;'1E<FYA=&4*
  356. XM(" @("!F:6QE(&EN(&$@;F5W(&)U9F9E<B!W:6YD;W<L(&EF(&%U=&]S<&QI
  357. XM="!A;&QO=W,N"@H@(" @($AI='1I;F<@=&AE(&5S8V%P92!K97D@=VAI;&4@
  358. XM:6X@=&AE(&-O;6UA;F0@(&QI;F4@(&1O97,@(&YO= H@(" @('1E<FUI;F%T
  359. XM92 @:6YP=70[("!I;G-T96%D+" @:70@8V%N8V5L<R!I;G!U="P@<F5T=7)N
  360. XM:6YG('1H90H@(" @('!R;VUP="!T;R!T:&4@8F5G:6YN:6YG(&]F('1H92!L
  361. XM:6YE+B @5&AI<R!A<'!L:65S('1O("!I;G!U= H@(" @(&9O<B Z+" O+" _
  362. XM(&%N9" A+@H*1DE,15,*(" @(" O=7-R+VQI8B]X=FDN:&5L<$1E9F%U;'0@
  363. XM:&5L<"!F:6QE+@H*4T5%($%,4T\*(" @("!E>"@Q*2P@=FDH,2DL('1E<FUC
  364. XM87 H-2DN"B @(" @7PA37PAU7PAM7PAM7PAA7PAR7PAY(%\(;U\(9B!?"$1?
  365. XM"&E?"&9?"&9?"&5?"')?"&5?"&Y?"&-?"&5?"',@7PAB7PAE7PAT7PAW7PAE
  366. XM7PAE7PAN(%\(5E\(:2!?"&%?"&Y?"&0@7PA87PAV7PAI+@H*0E5'4PH@(" @
  367. XM(&\(*R @("!7:&5N('1H92!C=7)S;W(@:7,@;VX@=&AE(&QA<W0@=V]R9"!O
  368. XM9B @82 @8G5F9F5R+" @=&AE"@D@(&-O;6UA;F0@(&1W("!L96%V97,@('1H
  369. XM92 @;&%S=" @8VAA<F%C=&5R("!O9B @=&AE('=O<F0*"2 @=6YD96QE=&5D
  370. XM+@H*(" @("!O""L@(" @4V]M92!S8W)E96X@=7!D871E<R!D;R @;F]T("!G
  371. XM970@('-H;W=N("!P<F]P97)L>2 @=VAE;@H)("!B=69F97)S("!A<F4@('-P
  372. XM;&ET+"!A;F0@8V5R=&%I;B!C;VUM86YD<R H92YG+B @>"D@87)E"@D@(&5X
  373. XM96-U=&5D+@H*"@I5;FEX(" @(" @(" @(" @(" @("!,87-T(&-H86YG93H@
  374. XM,3DO-B\Q.3DR(" @(" @(" @(" @(" @(" @(" @-PH*"@H*"@I85DDH,2D@
  375. XM(" @(" @(" @(" @(" @(" @55-%4B!#3TU-04Y$4R @(" @(" @(" @(" @
  376. XM(" @(" @(%A622@Q*0H*"@H@(" @(&\(*R @("!)9B!Y;W4@9&\@<V]M971H
  377. XM:6YG(&QI:V4@8V8N5T]21#Q?"&5?"'-?"&,^(&%N9"!T:&5N(')E9&\@:70L
  378. XM"@D@(&%N9" @=&AE("!F+B @9F%I;',L("!T:&5N("!T:&4@5T]21#Q?"&5?
  379. XM"'-?"&,^(&=E=',@=&%K96X@87,*"2 @;F]R;6%L(&EN<'5T+B @5&AE(')E
  380. XM<W0@;V8@=&AE(&EN<'5T('-H;W5L9" @<F5A;&QY("!B90H)("!C86YC96QL
  381. XM960@=VAE;B!P87)T(&]F(&$@<F5D;R!F86EL<RX*"B @(" @;P@K(" @($$@
  382. XM8V]M;6%N9"!O9B!T:&4@9F]R;2 Z+W!A="\[*S%M+B!W:6QL(&YO="!W;W)K
  383. XM(&)E8V%U<V4*"2 @=&AE("!E9&ET;W(@(&EN8V]R<F5C=&QY("!D971E8W1S
  384. XM("!A("!C;VYF;&EC=" @8F5T=V5E;@H)("!S;W5R8V4@86YD(&1E<W1I;F%T
  385. XM:6]N+@H*(" @("!O""L@(" @5&AE(&5D:71O<B!I;B!I=',@<')E<V5N="!F
  386. XM;W)M(&ES('9E<GD@(&EN969F:6-I96YT("!I;@H)("!T97)M<R!O9B!#4%4@
  387. XM8WEC;&5S+@H*(" @("!O""L@(" @36]S="!T97)M8V%P*#4I('1E<FUI;F%L
  388. XM(&1E<V-R:7!T:6]N<R!A<F4@(&]N;'D@('1E<W1E9 H)("!W:71H("!V:2@Q
  389. XM*2 @*&%N9"!P;W-S:6)L>2!R;V=U92@V*2DN("!3:6YC92!X=FD@:7,L(&EN
  390. XM"@D@('-O;64@=V%Y<RP@;6]R92!D96UA;F1I;F<@=&AA;B!V:2!I;B!I=',@
  391. XM=7-E(&]F('1E<FUC87 *"2 @8V%P86)I;&ET:65S+"!I="!S;VUE=&EM97,@
  392. XM97AP;W-E<R!B=6=S(&]R(&EN861E<75A8VEE<PH)("!I;B @=&5R;6-A<" @
  393. XM96YT<FEE<RX@("!4:&ES("!A<'!L:65S(" @97-P96-I86QL>2 @('1O"@D@
  394. XM('-C<F]L;&EN9R!R96=I;VYS+@H*059!24Q!0DE,2519"B @(" @6'9I(&AA
  395. XM<R!B965N('!O<G1E9"!T;R!-4RU$3U,L($]3+S(L(%%.6"!A;F0@;6%N>2 @
  396. XM9&EF9F5R96YT"B @(" @=F5R<VEO;G,@(&]F("!5;FEX+B @(%-O=7)C92 @
  397. XM8V]D92 @:7,@(&%V86EL86)L92 @9G)O;2 @=&AE"B @(" @875T:&]R<RX*
  398. XM"D%55$A/4E,*(" @("!#:')I<R!A;F0@2F]H;B!$;W=N97DN"@H@(" @($1E
  399. XM<FEV960@9G)O;2 @4U1%5DE%+" @=W)I='1E;B @8GD@(%1I;2 @5&AO;7!S
  400. XM;VX@(&%N9" @5&]N>0H@(" @($%N9')E=W,N"@H*"@H*"@H*"@H*"@H*"@H*
  401. XM"@H*"@H*"@H*56YI>" @(" @(" @(" @(" @(" @3&%S="!C:&%N9V4Z(#$Y
  402. XA+S8O,3DY,B @(" @(" @(" @(" @(" @(" @(#@*"@H*
  403. Xend
  404. END_OF_FILE
  405.   if test 23204 -ne `wc -c <'xvi/doc/xvi.lst.UU'`; then
  406.     echo shar: \"'xvi/doc/xvi.lst.UU'\" unpacked with wrong size!
  407.   else
  408.     echo shar: Uudecoding \"'xvi/doc/xvi.lst'\" \(16818 characters\)
  409.     cat 'xvi/doc/xvi.lst.UU' | uudecode
  410.     if test -f 'xvi/doc/xvi.lst' ; then
  411.       if test 16818 -ne `wc -c <'xvi/doc/xvi.lst'`; then
  412.         echo shar: \"'xvi/doc/xvi.lst'\" uudecoded with wrong size!
  413.       else
  414.         rm 'xvi/doc/xvi.lst.UU'
  415.       fi 
  416.     else
  417.       echo shar: \"'xvi/doc/xvi.lst'\" uudecode failed!
  418.     fi
  419.   fi
  420.   # end of 'xvi/doc/xvi.lst.UU'
  421. fi
  422. if test -f 'xvi/src/makefile.aix' -a "${1}" != "-c" ; then 
  423.   echo shar: Will not clobber existing file \"'xvi/src/makefile.aix'\"
  424. else
  425.   echo shar: Extracting \"'xvi/src/makefile.aix'\" \(1993 characters\)
  426.   sed "s/^X//" >'xvi/src/makefile.aix' <<'END_OF_FILE'
  427. X# Copyright (c) 1990,1991,1992 Chris and John Downey
  428. X#***
  429. X#
  430. X# @(#)makefile.aix    2.2 (Chris & John Downey) 7/31/92
  431. X#
  432. X# program name:
  433. X#    xvi
  434. X# function:
  435. X#    PD version of UNIX "vi" editor, with extensions.
  436. X# module name:
  437. X#    makefile.aix
  438. X# module function:
  439. X#    Makefile for AIX (IBM's SysV-compatible UNIX).
  440. X# history:
  441. X#    STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  442. X#    Originally by Tim Thompson (twitch!tjt)
  443. X#    Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  444. X#    Heavily modified by Chris & John Downey
  445. X#***
  446. X
  447. XSYSDEFS=    -DUNIX -DAIX -DTERMIO
  448. XINCDIRS=
  449. X
  450. XLIBS=        -lcurses
  451. XLDFLAGS=
  452. X
  453. X# Don't use -O flag here because on the RT/PC (on which
  454. X# this version was developed) compilation takes 4 times as
  455. X# long if you use it (8 lines per second rather than 33).
  456. XCFLAGS=        $(SYSDEFS) $(INCDIRS)
  457. XLINTFLAGS=    $(SYSDEFS) $(INCDIRS) -ah
  458. X
  459. XMACHSRC=    unix.c termcap.c defscr.c
  460. XMACHOBJ=    unix.o termcap.o defscr.o
  461. XMACHINC=    unix.h termcap.h
  462. X
  463. XGENINC=        ascii.h param.h ptrfunc.h regexp.h regmagic.h xvi.h virtscr.h
  464. X
  465. XGENSRC=        alloc.c ascii.c buffers.c cmdline.c cursor.c \
  466. X        edit.c ex_cmds1.c ex_cmds2.c events.c fileio.c \
  467. X        find.c flexbuf.c map.c mark.c misccmds.c movement.c \
  468. X        normal.c param.c pipe.c preserve.c ptrfunc.c \
  469. X        regexp.c screen.c search.c signal.c startup.c status.c \
  470. X        tags.c undo.c version.c windows.c yankput.c
  471. X
  472. XGENOBJ=        alloc.o ascii.o buffers.o cmdline.o cursor.o \
  473. X        edit.o ex_cmds1.o ex_cmds2.o events.o fileio.o \
  474. X        find.o flexbuf.o map.o mark.o misccmds.o movement.o \
  475. X        normal.o param.o pipe.o preserve.o ptrfunc.o \
  476. X        regexp.o screen.o search.o signal.o startup.o status.o \
  477. X        tags.o undo.o version.o windows.o yankput.o
  478. X
  479. Xall:        xvi
  480. X
  481. Xxvi:        $(GENOBJ) $(MACHOBJ)
  482. X        $(CC) $(CFLAGS) -o xvi $(GENOBJ) $(MACHOBJ) $(LIBS)
  483. X
  484. X.c.o:        $< $(GENINC) $(MACHINC) param.c
  485. X        $(CC) $(CFLAGS) -c -o $@ $<
  486. X
  487. Xlint:
  488. X        lint $(LINTFLAGS) $(GENSRC) $(MACHSRC)
  489. X
  490. Xtags:        $(GENSRC) $(MACHSRC)
  491. X        ctags -t $(GENSRC) $(MACHSRC) $(GENINC) $(MACHINC)
  492. X
  493. Xclean:
  494. X        rm $(GENOBJ) $(MACHOBJ) xvi
  495. X
  496. X$(GENOBJ):    $(GENINC) $(MACHINC)
  497. END_OF_FILE
  498.   if test 1993 -ne `wc -c <'xvi/src/makefile.aix'`; then
  499.     echo shar: \"'xvi/src/makefile.aix'\" unpacked with wrong size!
  500.   fi
  501.   # end of 'xvi/src/makefile.aix'
  502. fi
  503. if test -f 'xvi/src/search.c' -a "${1}" != "-c" ; then 
  504.   echo shar: Will not clobber existing file \"'xvi/src/search.c'\"
  505. else
  506.   echo shar: Extracting \"'xvi/src/search.c'\" \(27204 characters\)
  507.   sed "s/^X//" >'xvi/src/search.c' <<'END_OF_FILE'
  508. X/* Copyright (c) 1990,1991,1992 Chris and John Downey */
  509. X#ifndef lint
  510. Xstatic char *sccsid = "@(#)search.c    2.1 (Chris & John Downey) 7/29/92";
  511. X#endif
  512. X
  513. X/***
  514. X
  515. X* program name:
  516. X    xvi
  517. X* function:
  518. X    PD version of UNIX "vi" editor, with extensions.
  519. X* module name:
  520. X    search.c
  521. X* module function:
  522. X    Regular expression searching, including global command.
  523. X* history:
  524. X    STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  525. X    Originally by Tim Thompson (twitch!tjt)
  526. X    Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  527. X    Heavily modified by Chris & John Downey
  528. X
  529. X***/
  530. X
  531. X#include "xvi.h"
  532. X#include "regexp.h"    /* Henry Spencer's regular expression routines */
  533. X#include "regmagic.h"    /* Henry Spencer's regular expression routines */
  534. X
  535. X#ifdef    MEGAMAX
  536. Xoverlay "search"
  537. X#endif
  538. X
  539. X/*
  540. X * String searches
  541. X *
  542. X * The actual searches are done using Henry Spencer's regular expression
  543. X * library.
  544. X */
  545. X
  546. X/*
  547. X * Names of values for the P_regextype enumerated parameter.
  548. X */
  549. Xchar    *rt_strings[] =
  550. X{
  551. X    "tags",
  552. X    "grep",
  553. X    "egrep",
  554. X    NULL
  555. X};
  556. X
  557. X/*
  558. X * Used by g/re/p to remember where we are and what we are doing.
  559. X */
  560. Xstatic    Line    *curline;
  561. Xstatic    Line    *lastline;
  562. Xstatic    long    curnum;
  563. Xstatic    bool_t    greptype;
  564. X
  565. Xstatic    Posn    *bcksearch P((Xviwin *, Line *, int, bool_t));
  566. Xstatic    Posn    *fwdsearch P((Xviwin *, Line *, int, bool_t));
  567. Xstatic    char    *mapstring P((char **, int));
  568. Xstatic    char    *compile P((char *, int, bool_t));
  569. Xstatic    char    *grep_line P((void));
  570. Xstatic    long    substitute P((Xviwin *, Line *, Line *, char *, char *));
  571. X
  572. X/*
  573. X * Convert a regular expression to egrep syntax: the source string can
  574. X * be either tags compatible (only ^ and $ are significant), vi
  575. X * compatible or egrep compatible (but also using \< and \>)
  576. X *
  577. X * Our first parameter here is the address of a pointer, which we
  578. X * point to the closing delimiter character if we found one, otherwise
  579. X * the closing '\0'.
  580. X */
  581. Xstatic char *
  582. Xmapstring(sp, delim)
  583. Xchar    **sp;        /* pointer to pointer to pattern string */
  584. Xint    delim;        /* delimiter character */
  585. X{
  586. X    static Flexbuf    ns;
  587. X    int            rxtype;    /* can be rt_TAGS, rt_GREP or rt_EGREP */
  588. X    register enum {
  589. X    m_normal,    /* nothing special */
  590. X    m_startccl,    /* just after [ */
  591. X    m_negccl,    /* just after [^ */
  592. X    m_ccl,        /* between [... or [^... and ] */
  593. X    m_escape    /* just after \ */
  594. X    }    state = m_normal;
  595. X    register char    *s;
  596. X
  597. X    rxtype = Pn(P_regextype);
  598. X
  599. X    flexclear(&ns);
  600. X    for (s = *sp; *s != '\0' && (*s != delim || state != m_normal); s++) {
  601. X    switch (state) {
  602. X    case m_normal:
  603. X        switch (*s) {
  604. X        case '\\':
  605. X        state = m_escape;
  606. X        break;
  607. X
  608. X        case '(': case ')': case '+': case '?': case '|':
  609. X        /* egrep metacharacters */
  610. X        if (rxtype != rt_EGREP)
  611. X            (void) flexaddch(&ns, '\\');
  612. X        (void) flexaddch(&ns, *s);
  613. X        break;
  614. X
  615. X        case '*': case '.': case '[':
  616. X        /* grep metacharacters */
  617. X        if (rxtype == rt_TAGS) {
  618. X            (void) flexaddch(&ns, '\\');
  619. X        } else if (*s == '[') {
  620. X            /* start of character class */
  621. X            state = m_startccl;
  622. X        }
  623. X         /* fall through ... */
  624. X
  625. X        default:
  626. X        (void) flexaddch(&ns, *s);
  627. X        }
  628. X        break;
  629. X
  630. X    case m_startccl:
  631. X    case m_negccl:
  632. X        (void) flexaddch(&ns, *s);
  633. X        state = (*s == '^' && state == m_startccl) ? m_negccl : m_ccl;
  634. X        break;
  635. X
  636. X    case m_ccl:
  637. X        (void) flexaddch(&ns, *s);
  638. X        if (*s == ']')
  639. X        state = m_normal;
  640. X        break;
  641. X
  642. X    case m_escape:
  643. X        switch (*s) {
  644. X        case '(':        /* bracket conversion */
  645. X        case ')':
  646. X        if (rxtype != rt_GREP)
  647. X            (void) flexaddch(&ns, '\\');
  648. X        (void) flexaddch(&ns, *s);
  649. X        break;
  650. X
  651. X        case '.':        /* egrep metacharacters */
  652. X        case '\\':
  653. X        case '[':
  654. X        case '*':
  655. X        case '?':
  656. X        case '+':
  657. X        case '^':
  658. X        case '$':
  659. X        case '|':
  660. X        (void) lformat(&ns, "\\%c", *s);
  661. X        break;
  662. X
  663. X        default:        /* a normal character */
  664. X        if (*s != delim)
  665. X            (void) flexaddch(&ns, '\\');
  666. X        (void) flexaddch(&ns, *s);
  667. X        }
  668. X        state = m_normal;
  669. X    }
  670. X    }
  671. X
  672. X    *sp = s;
  673. X
  674. X    /*
  675. X     * This is horrible, but the real vi does it, so ...
  676. X     */
  677. X    if (state == m_escape) {
  678. X    (void) lformat(&ns, "\\\\");
  679. X    }
  680. X    return flexgetstr(&ns);
  681. X}
  682. X
  683. X/**********************************************************
  684. X *                              *
  685. X * Abstract type definition.                  *
  686. X *                              *
  687. X * Regular expression node, with pointer reference count. *
  688. X *                              *
  689. X * We need this for global substitute commands.          *
  690. X *                              *
  691. X **********************************************************/
  692. X
  693. Xtypedef struct {
  694. X    regexp    *rn_ptr;
  695. X    int        rn_count;
  696. X} Rnode;
  697. X
  698. X/*
  699. X * Node for last successfully compiled regular expression.
  700. X */
  701. Xstatic Rnode    *lastprogp = NULL;
  702. X
  703. X/*
  704. X * Last regular expression used in a substitution.
  705. X */
  706. Xstatic    Rnode    *last_lhs = NULL;
  707. X
  708. X/*
  709. X * Last rhs for a substitution.
  710. X */
  711. Xstatic    char    *last_rhs = NULL;
  712. X
  713. X/*
  714. X * rn_new(), rn_delete() & rn_duplicate() perform operations on Rnodes
  715. X * which are respectively analogous to open(), close() & dup() for
  716. X * Unix file descriptors.
  717. X */
  718. X
  719. X/*
  720. X * Make a new Rnode, given a pattern string.
  721. X */
  722. Xstatic Rnode *
  723. Xrn_new(str)
  724. X    char    *str;
  725. X{
  726. X    Rnode    *retp;
  727. X
  728. X    if ((retp = (Rnode *) alloc(sizeof (Rnode))) == NULL)
  729. X    return NULL;
  730. X    if ((retp->rn_ptr = regcomp(str)) == NULL) {
  731. X    free ((char *) retp);
  732. X    return NULL;
  733. X    }
  734. X    retp->rn_count = 1;
  735. X    return retp;
  736. X}
  737. X
  738. X/*
  739. X * Make a copy of an Rnode pointer & increment the Rnode's reference
  740. X * count.
  741. X */
  742. X#define rn_duplicate(s)    ((s) ? ((s)->rn_count++, (s)) : NULL)
  743. X
  744. X/*
  745. X * Decrement an Rnode's reference count, freeing it if there are no
  746. X * more pointers pointing to it.
  747. X *
  748. X * In C++, this would be a destructor for an Rnode.
  749. X */
  750. Xstatic void
  751. Xrn_delete(rp)
  752. XRnode    *rp;
  753. X{
  754. X    if (rp != NULL && --rp->rn_count <= 0) {
  755. X    free((char *) rp->rn_ptr);
  756. X    free((char *) rp);
  757. X    }
  758. X}
  759. X
  760. X#if 0
  761. X/*
  762. X * Increment the reference count for the current prog,
  763. X * and return it to the caller.
  764. X */
  765. Xstatic Rnode *
  766. Xinccount()
  767. X{
  768. X    if (lastprogp != NULL) {
  769. X    lastprogp->rn_count++;
  770. X    }
  771. X    return(lastprogp);
  772. X}
  773. X
  774. X#endif
  775. X
  776. X#define    cur_prog()    (lastprogp->rn_ptr)
  777. X
  778. X/*
  779. X * Compile given regular expression from string.
  780. X *
  781. X * The opening delimiter for the regular expression is supplied; the
  782. X * end of it is marked by an unescaped matching delimiter or, if
  783. X * delim_only is FALSE, by a '\0' character. We return a pointer to
  784. X * the terminating '\0' or to the character following the closing
  785. X * delimiter, or NULL if we failed.
  786. X *
  787. X * If, after we've found a delimiter, we have an empty pattern string,
  788. X * we use the last compiled expression if there is one.
  789. X *
  790. X * The regular expression is converted to egrep syntax by mapstring(),
  791. X * which also finds the closing delimiter. The actual compilation is
  792. X * done by regcomp(), from Henry Spencer's regexp routines.
  793. X *
  794. X * If we're successful, the compiled regular expression will be
  795. X * pointed to by lastprogp->rn_ptr, & lastprogp->rn_count will be > 0.
  796. X */
  797. Xstatic char *
  798. Xcompile(pat, delimiter, delim_only)
  799. Xchar    *pat;
  800. Xint    delimiter;
  801. Xbool_t    delim_only;
  802. X{
  803. X    Rnode    *progp;
  804. X
  805. X    if (pat == NULL) {
  806. X    return(NULL);
  807. X    }
  808. X
  809. X    /*
  810. X     * If we get an empty regular expression, we just use the last
  811. X     * one we compiled (if there was one).
  812. X     */
  813. X    if (*pat == '\0') {
  814. X    return((delim_only || lastprogp == NULL) ? NULL : pat);
  815. X    }
  816. X    if (*pat == delimiter) {
  817. X    return((lastprogp == NULL) ? NULL : &pat[1]);
  818. X    }
  819. X
  820. X    progp = rn_new(mapstring(&pat, delimiter));
  821. X    if (progp == NULL) {
  822. X    return(NULL);
  823. X    }
  824. X
  825. X    if (*pat == '\0') {
  826. X    if (delim_only) {
  827. X        rn_delete(progp);
  828. X        return(NULL);
  829. X    }
  830. X    } else {
  831. X    pat++;
  832. X    }
  833. X    rn_delete(lastprogp);
  834. X    lastprogp = progp;
  835. X    return(pat);
  836. X}
  837. X
  838. XPosn *
  839. Xsearch(window, startline, startindex, dir, strp)
  840. XXviwin        *window;
  841. XLine        *startline;
  842. Xint        startindex;
  843. Xint        dir;        /* FORWARD or BACKWARD */
  844. Xchar        **strp;
  845. X{
  846. X    Posn    *pos;
  847. X    Posn    *(*sfunc) P((Xviwin *, Line *, int, bool_t));
  848. X    char    *str;
  849. X
  850. X    str = compile(*strp, (dir == FORWARD) ? '/' : '?', FALSE);
  851. X    if (str == NULL) {
  852. X    return(NULL);
  853. X    }
  854. X    *strp = str;
  855. X
  856. X    if (dir == BACKWARD) {
  857. X    sfunc = bcksearch;
  858. X    } else {
  859. X    sfunc = fwdsearch;
  860. X    }
  861. X    pos = (*sfunc)(window, startline, startindex, Pb(P_wrapscan));
  862. X
  863. X    return(pos);
  864. X}
  865. X
  866. X/*
  867. X * Search for the given expression, ignoring regextype, without
  868. X * wrapscan & and without using the compiled regular expression for
  869. X * anything else (so 'n', 'N', etc., aren't affected). We do, however,
  870. X * cache the compiled form for the last string we were given.
  871. X */
  872. XPosn *
  873. Xnsearch(window, startline, startindex, dir, str)
  874. XXviwin        *window;
  875. XLine        *startline;
  876. Xint        startindex;
  877. Xint        dir;
  878. Xchar        *str;
  879. X{
  880. X    static Rnode    *progp = NULL;
  881. X    static char        *last_str = NULL;
  882. X    Rnode        *old_progp;
  883. X    Posn        *pos;
  884. X    Posn        *(*sfunc) P((Xviwin *, Line *, int, bool_t));
  885. X
  886. X    if (str == NULL) {
  887. X    return(NULL);
  888. X    }
  889. X    if (str != last_str &&
  890. X    (last_str == NULL || strcmp(str, last_str) != 0)) {
  891. X    if (progp) {
  892. X        rn_delete(progp);
  893. X    }
  894. X    progp = rn_new(str);
  895. X    last_str = str;
  896. X    }
  897. X    if (progp == NULL) {
  898. X    last_str = NULL;
  899. X    return(NULL);
  900. X    }
  901. X
  902. X    if (dir == BACKWARD) {
  903. X    sfunc = bcksearch;
  904. X    } else {
  905. X    sfunc = fwdsearch;
  906. X    }
  907. X
  908. X    old_progp = lastprogp;
  909. X
  910. X    lastprogp = progp;
  911. X    pos = (*sfunc)(window, startline, startindex, FALSE);
  912. X
  913. X    lastprogp = old_progp;
  914. X
  915. X    return(pos);
  916. X}
  917. X
  918. X/*
  919. X * Perform line-based search, returning a pointer to the first line
  920. X * (forwards or backwards) on which a match is found, or NULL if there
  921. X * is none in the buffer specified.
  922. X */
  923. XLine *
  924. Xlinesearch(window, dir, strp)
  925. XXviwin    *window;
  926. Xint    dir;
  927. Xchar    **strp;
  928. X{
  929. X    Posn    pos;
  930. X    Posn    *newpos;
  931. X
  932. X    pos = *(window->w_cursor);
  933. X    if (dir == FORWARD) {
  934. X    /*
  935. X     * We don't want a match to occur on the current line,
  936. X     * but setting the starting position to the next line
  937. X     * is wrong because we will not match a pattern at the
  938. X     * start of the line. So go to the end of this line.
  939. X     */
  940. X    if (gchar(&pos) != '\0') {
  941. X        while (inc(&pos) == mv_SAMELINE) {
  942. X        ;
  943. X        }
  944. X    }
  945. X    } else {
  946. X    pos.p_index = 0;
  947. X    }
  948. X
  949. X    newpos = search(window, pos.p_line, pos.p_index, dir, strp);
  950. X    return((newpos != NULL) ? newpos->p_line : NULL);
  951. X}
  952. X
  953. X/*
  954. X * regerror - called by regexp routines when errors are detected.
  955. X */
  956. Xvoid
  957. Xregerror(s)
  958. Xchar    *s;
  959. X{
  960. X    if (echo & e_REGERR) {
  961. X    show_error(curwin, "%s", s);
  962. X    }
  963. X    echo &= ~(e_REGERR | e_NOMATCH);
  964. X}
  965. X
  966. X/*
  967. X * Find a match at or after "ind" on the given "line"; return
  968. X * pointer to Posn of match, or NULL if no match was found.
  969. X */
  970. Xstatic Posn *
  971. Xmatch(line, ind)
  972. XLine    *line;
  973. Xint    ind;
  974. X{
  975. X    static Posn    matchposn;
  976. X    char    *s;
  977. X    regexp    *prog;
  978. X
  979. X    s = line->l_text + ind;
  980. X    prog = cur_prog();
  981. X
  982. X    if (regexec(prog, s, (ind == 0))) {
  983. X    matchposn.p_line = line;
  984. X    matchposn.p_index = (int) (prog->startp[0] - line->l_text);
  985. X
  986. X    /*
  987. X     * If the match is after the end of the line,
  988. X     * move it to the last character of the line,
  989. X     * unless the line has no characters at all.
  990. X     */
  991. X    if (line->l_text[matchposn.p_index] == '\0' &&
  992. X                    matchposn.p_index > 0) {
  993. X        matchposn.p_index -= 1;
  994. X    }
  995. X
  996. X    return(&matchposn);
  997. X    } else {
  998. X    return(NULL);
  999. X    }
  1000. X}
  1001. X
  1002. X/*
  1003. X * Like match(), but returns the last available match on the given
  1004. X * line which is before the index given in maxindex.
  1005. X */
  1006. Xstatic Posn *
  1007. Xrmatch(line, ind, maxindex)
  1008. XLine        *line;
  1009. Xregister int    ind;
  1010. Xint        maxindex;
  1011. X{
  1012. X    register int    lastindex = -1;
  1013. X    Posn        *pos;
  1014. X    register char    *ltp;
  1015. X
  1016. X    ltp = line->l_text;
  1017. X    for (; (pos = match(line, ind)) != NULL; ind++) {
  1018. X    ind = pos->p_index;
  1019. X    if (ind >= maxindex)
  1020. X        break;
  1021. X    /*
  1022. X     * If we've found a match on the last
  1023. X     * character of the line, return it here or
  1024. X     * we could get into an infinite loop.
  1025. X     */
  1026. X    if (ltp[lastindex = ind] == '\0' || ltp[ind + 1] == '\0')
  1027. X        break;
  1028. X    }
  1029. X
  1030. X    if (lastindex >= 0) {
  1031. X    static Posn    lastmatch;
  1032. X
  1033. X    lastmatch.p_index = lastindex;
  1034. X    lastmatch.p_line = line;
  1035. X    return &lastmatch;
  1036. X    } else {
  1037. X    return NULL;
  1038. X    }
  1039. X}
  1040. X
  1041. X/*
  1042. X * Search forwards through the buffer for a match of the last
  1043. X * pattern compiled.
  1044. X */
  1045. Xstatic Posn *
  1046. Xfwdsearch(window, startline, startindex, wrapscan)
  1047. XXviwin        *window;
  1048. XLine        *startline;
  1049. Xint        startindex;
  1050. Xbool_t        wrapscan;
  1051. X{
  1052. X    static Posn    *pos;        /* location of found string */
  1053. X    Line    *lp;        /* current line */
  1054. X    Line    *last;
  1055. X
  1056. X    last = window->w_buffer->b_lastline;
  1057. X
  1058. X    /*
  1059. X     * First, search for a match on the current line
  1060. X     * after the cursor position.
  1061. X     */
  1062. X    pos = match(startline, startindex + 1);
  1063. X    if (pos != NULL) {
  1064. X    return(pos);
  1065. X    }
  1066. X
  1067. X    /*
  1068. X     * Now search all the lines from here to the end of the file,
  1069. X     * and from the start of the file back to here if (wrapscan).
  1070. X     */
  1071. X    for (lp = startline->l_next; lp != startline; lp = lp->l_next) {
  1072. X    /*
  1073. X     * Wrap around to the start of the file.
  1074. X     */
  1075. X    if (lp == last) {
  1076. X        if (wrapscan) {
  1077. X        lp = window->w_buffer->b_line0;
  1078. X        continue;
  1079. X        }
  1080. X         /* else */
  1081. X        return(NULL);
  1082. X    }
  1083. X
  1084. X    pos = match(lp, 0);
  1085. X    if (pos != NULL) {
  1086. X        return(pos);
  1087. X    }
  1088. X    }
  1089. X
  1090. X    /*
  1091. X     * Finally, search from the start of the cursor line
  1092. X     * up to the cursor position. (Wrapscan was set if
  1093. X     * we got here.)
  1094. X     */
  1095. X    pos = match(startline, 0);
  1096. X    if (pos != NULL) {
  1097. X    if (pos->p_index <= startindex) {
  1098. X        return(pos);
  1099. X    }
  1100. X    }
  1101. X
  1102. X    return(NULL);
  1103. X}
  1104. X
  1105. X/*
  1106. X * Search backwards through the buffer for a match of the last
  1107. X * pattern compiled.
  1108. X *
  1109. X * Because we're searching backwards, we have to return the
  1110. X * last match on a line if there is more than one, so we call
  1111. X * rmatch() instead of match().
  1112. X */
  1113. Xstatic Posn *
  1114. Xbcksearch(window, startline, startindex, wrapscan)
  1115. XXviwin        *window;
  1116. XLine        *startline;
  1117. Xint        startindex;
  1118. Xbool_t        wrapscan;
  1119. X{
  1120. X    Posn    *pos;        /* location of found string */
  1121. X    Line    *lp;        /* current line */
  1122. X    Line    *line0;
  1123. X
  1124. X    /*
  1125. X     * First, search for a match on the current line before the
  1126. X     * current cursor position; if "begword" is set, it must be
  1127. X     * before the current cursor position minus one.
  1128. X     */
  1129. X    pos = rmatch(startline, 0, startindex);
  1130. X    if (pos != NULL) {
  1131. X    return(pos);
  1132. X    }
  1133. X
  1134. X    /*
  1135. X     * Search all lines back to the start of the buffer,
  1136. X     * and then from the end of the buffer back to the
  1137. X     * line after the cursor line if wrapscan is set.
  1138. X     */
  1139. X    line0 = window->w_buffer->b_line0;
  1140. X    for (lp = startline->l_prev; lp != startline; lp = lp->l_prev) {
  1141. X
  1142. X    if (lp == line0) {
  1143. X        if (wrapscan) {
  1144. X        /*
  1145. X         * Note we do a continue here so that
  1146. X         * the loop control works properly.
  1147. X         */
  1148. X        lp = window->w_buffer->b_lastline;
  1149. X        continue;
  1150. X        } else {
  1151. X        return(NULL);
  1152. X        }
  1153. X    }
  1154. X    pos = rmatch(lp, 0, INT_MAX);
  1155. X    if (pos != NULL)
  1156. X        return pos;
  1157. X    }
  1158. X
  1159. X    /*
  1160. X     * Finally, try for a match on the cursor line
  1161. X     * after (or at) the cursor position.
  1162. X     */
  1163. X    pos = rmatch(startline, startindex, INT_MAX);
  1164. X    if (pos != NULL) {
  1165. X    return(pos);
  1166. X    }
  1167. X
  1168. X    return(NULL);
  1169. X}
  1170. X
  1171. X/*
  1172. X * Execute a global command of the form:
  1173. X *
  1174. X * g/pattern/X
  1175. X *
  1176. X * where 'x' is a command character, currently one of the following:
  1177. X *
  1178. X * d    Delete all matching lines
  1179. X * l    List all matching lines
  1180. X * p    Print all matching lines
  1181. X * s    Perform substitution
  1182. X * &    Repeat last substitution
  1183. X * ~    Apply last right-hand side used in a substitution to last
  1184. X *    regular expression used
  1185. X *
  1186. X * The command character (as well as the trailing slash) is optional, and
  1187. X * is assumed to be 'p' if missing.
  1188. X *
  1189. X * The "lp" and "up" parameters are the first line to be considered, and
  1190. X * the last line to be considered. If these are NULL, the whole buffer is
  1191. X * considered; if only up is NULL, we consider the single line "lp".
  1192. X *
  1193. X * The "matchtype" parameter says whether we are doing 'g' or 'v'.
  1194. X */
  1195. Xvoid
  1196. Xdo_global(window, lp, up, cmd, matchtype)
  1197. XXviwin        *window;
  1198. XLine        *lp, *up;
  1199. Xchar        *cmd;
  1200. Xbool_t        matchtype;
  1201. X{
  1202. X    Rnode        *globprogp;
  1203. X    regexp        *prog;        /* compiled pattern */
  1204. X    long        ndone;        /* number of matches */
  1205. X    register char    cmdchar = '\0';    /* what to do with matching lines */
  1206. X
  1207. X    /*
  1208. X     * compile() compiles the pattern up to the first unescaped
  1209. X     * delimiter: we place the character after the delimiter in
  1210. X     * cmdchar. If there is no such character, we default to 'p'.
  1211. X     */
  1212. X    if (*cmd == '\0' || (cmd = compile(&cmd[1], *cmd, FALSE)) == NULL) {
  1213. X    regerror(matchtype ?
  1214. X        "Usage: :g/search pattern/command" :
  1215. X        "Usage: :v/search pattern/command");
  1216. X    return;
  1217. X    }
  1218. X    /*
  1219. X     * Check we can do the command before starting.
  1220. X     */
  1221. X    switch (cmdchar = *cmd) {
  1222. X    case '\0':
  1223. X    cmdchar = 'p';
  1224. X     /* fall through ... */
  1225. X    case 'l':
  1226. X    case 'p':
  1227. X    break;
  1228. X    case 's':
  1229. X    case '&':
  1230. X    case '~':
  1231. X    cmd++;    /* cmd points at char after modifier */
  1232. X     /* fall through ... */
  1233. X    case 'd':
  1234. X    if (!start_command(window)) {
  1235. X        return;
  1236. X    }
  1237. X    break;
  1238. X    default:
  1239. X    regerror("Invalid command character");
  1240. X    return;
  1241. X    }
  1242. X
  1243. X    ndone = 0;
  1244. X
  1245. X    /*
  1246. X     * If no range was given, do every line.
  1247. X     * If only one line was given, just do that one.
  1248. X     * Ensure that "up" points at the line after the
  1249. X     * last one in the range, to make the loop easier.
  1250. X     */
  1251. X    if (lp == NULL) {
  1252. X    lp = window->w_buffer->b_file;
  1253. X    up = window->w_buffer->b_lastline;
  1254. X    } else if (up == NULL) {
  1255. X    up = lp->l_next;
  1256. X    } else {
  1257. X    up = up->l_next;
  1258. X    }
  1259. X
  1260. X    /*
  1261. X     * If we are going to print lines, it is sensible
  1262. X     * to find out the line number of the first line in
  1263. X     * the range before we start, and increment it as
  1264. X     * we go rather than finding out the line number
  1265. X     * for each line as it is printed.
  1266. X     */
  1267. X    switch (cmdchar) {
  1268. X    case 'p':
  1269. X    case 'l':
  1270. X    curnum = lineno(window->w_buffer, lp);
  1271. X    curline = lp;
  1272. X    lastline = up;
  1273. X    greptype = matchtype;
  1274. X    disp_init(window, grep_line, (int) Columns,
  1275. X          (cmdchar == 'l'));
  1276. X    return;
  1277. X    }
  1278. X
  1279. X    /*
  1280. X     * This is tricky. do_substitute() might default to
  1281. X     * using cur_prog(), if the command is of the form
  1282. X     *
  1283. X     *    :g/pattern/s//.../
  1284. X     *
  1285. X     * so cur_prog() must still reference the expression we
  1286. X     * compiled. On the other hand, it may compile a
  1287. X     * different regular expression, so we have to be able
  1288. X     * to maintain a separate one (which is what globprogp
  1289. X     * is for). Moreover, if it does compile a different
  1290. X     * expression, one of them has to be freed afterwards.
  1291. X     *
  1292. X     * This is why we use Rnodes, which contain
  1293. X     * reference counts. An Rnode, & the compiled
  1294. X     * expression it points to, are only freed when its
  1295. X     * reference count is decremented to 0.
  1296. X     */
  1297. X    globprogp = rn_duplicate(lastprogp);
  1298. X    prog = cur_prog();
  1299. X
  1300. X    /*
  1301. X     * Place the cursor at bottom left of the window,
  1302. X     * so the user knows what we are doing.
  1303. X     * It is safe not to put the cursor back, because
  1304. X     * we are going to produce some more output anyway.
  1305. X     */
  1306. X    gotocmd(window, FALSE);
  1307. X    flush_output();
  1308. X
  1309. X    /*
  1310. X     * Try every line from lp up to (but not including) up.
  1311. X     */
  1312. X    ndone = 0;
  1313. X    while (lp != up) {
  1314. X    if (matchtype == regexec(prog, lp->l_text, TRUE)) {
  1315. X        Line    *thisline;
  1316. X
  1317. X        /*
  1318. X         * Move the cursor to the line before
  1319. X         * doing anything. Also move the line
  1320. X         * pointer on one before calling any
  1321. X         * functions which might alter or delete
  1322. X         * the line.
  1323. X         */
  1324. X        move_cursor(window, lp, 0);
  1325. X
  1326. X        thisline = lp;
  1327. X        lp = lp->l_next;
  1328. X
  1329. X        switch (cmdchar) {
  1330. X        case 'd':    /* delete the line */
  1331. X        repllines(window, thisline, 1L,
  1332. X            (Line *) NULL);
  1333. X        ndone++;
  1334. X        break;
  1335. X        case 's':    /* perform substitution */
  1336. X        case '&':
  1337. X        case '~':
  1338. X        {
  1339. X        register long    (*func) P((Xviwin *, Line *, Line *, char *));
  1340. X        unsigned    savecho;
  1341. X
  1342. X        switch (cmdchar) {
  1343. X        case 's':
  1344. X            func = do_substitute;
  1345. X            break;
  1346. X        case '&':
  1347. X            func = do_ampersand;
  1348. X            break;
  1349. X        case '~':
  1350. X            func = do_tilde;
  1351. X        }
  1352. X
  1353. X        savecho = echo;
  1354. X
  1355. X        echo &= ~e_NOMATCH;
  1356. X        ndone += (*func)
  1357. X        (window, thisline, thisline, cmd);
  1358. X
  1359. X        echo = savecho;
  1360. X        break;
  1361. X        }
  1362. X        }
  1363. X    } else {
  1364. X        lp = lp->l_next;
  1365. X    }
  1366. X    }
  1367. X
  1368. X    /*
  1369. X     * If globprogp is still the current prog, this should just
  1370. X     * decrement its reference count to 1: otherwise, if
  1371. X     * do_substitute() has compiled a different pattern, then that
  1372. X     * counts as the last compiled pattern, globprogp's reference
  1373. X     * count should be decremented to 0, & it should be freed.
  1374. X     */
  1375. X    rn_delete(globprogp);
  1376. X
  1377. X    switch (cmdchar) {
  1378. X    case 'd':
  1379. X    case 's':
  1380. X    case '&':
  1381. X    case '~':
  1382. X    end_command(window);
  1383. X    if (ndone) {
  1384. X        update_buffer(window->w_buffer);
  1385. X        cursupdate(window);
  1386. X        begin_line(window, TRUE);
  1387. X        if (ndone >= Pn(P_report)) {
  1388. X        show_message(window,
  1389. X             (cmdchar == 'd') ?
  1390. X             "%ld fewer line%c" :
  1391. X             "%ld substitution%c",
  1392. X             ndone,
  1393. X             (ndone > 1) ?
  1394. X             's' : ' ');
  1395. X        }
  1396. X    }
  1397. X    }
  1398. X
  1399. X    if (ndone == 0 && (echo & e_NOMATCH)) {
  1400. X    regerror("No match");
  1401. X    }
  1402. X}
  1403. X
  1404. Xstatic char *
  1405. Xgrep_line()
  1406. X{
  1407. X    static Flexbuf    b;
  1408. X    regexp        *prog;
  1409. X
  1410. X    prog = cur_prog();
  1411. X    for ( ; curline != lastline; curline = curline->l_next, curnum++) {
  1412. X
  1413. X    if (greptype == regexec(prog, curline->l_text, TRUE)) {
  1414. X
  1415. X        flexclear(&b);
  1416. X        if (Pb(P_number)) {
  1417. X        (void) lformat(&b, NUM_FMT, curnum);
  1418. X        }
  1419. X        (void) lformat(&b, "%s", curline->l_text);
  1420. X        break;
  1421. X    }
  1422. X    }
  1423. X
  1424. X    if (curline == lastline) {
  1425. X    return(NULL);
  1426. X    } else {
  1427. X    curline = curline->l_next;
  1428. X    curnum++;
  1429. X    return(flexgetstr(&b));
  1430. X    }
  1431. X}
  1432. X
  1433. X/*
  1434. X * regsubst - perform substitutions after a regexp match
  1435. X *
  1436. X * Adapted from a routine from Henry Spencer's regexp package. The
  1437. X * original copyright notice for all these routines is in regexp.c,
  1438. X * which is distributed herewith.
  1439. X */
  1440. X
  1441. X#ifndef CHARBITS
  1442. X#    define    UCHARAT(p)    ((int)*(unsigned char *)(p))
  1443. X#else
  1444. X#    define    UCHARAT(p)    ((int)*(p)&CHARBITS)
  1445. X#endif
  1446. X
  1447. Xstatic void
  1448. Xregsubst(prog, src, dest)
  1449. Xregister regexp    *prog;
  1450. Xregister char    *src;
  1451. XFlexbuf        *dest;
  1452. X{
  1453. X    register int    c;
  1454. X
  1455. X    if (prog == NULL || src == NULL || dest == NULL) {
  1456. X    regerror("NULL parameter to regsubst");
  1457. X    return;
  1458. X    }
  1459. X
  1460. X    if (UCHARAT(prog->program) != MAGIC) {
  1461. X    regerror("Damaged regexp fed to regsubst");
  1462. X    return;
  1463. X    }
  1464. X
  1465. X    while ((c = *src++) != '\0') {
  1466. X    register int no;
  1467. X
  1468. X    /*
  1469. X     * First check for metacharacters.
  1470. X     */
  1471. X    if (c == '&') {
  1472. X        no = 0;
  1473. X    } else if (c == '\\' && '0' <= *src && *src <= '9') {
  1474. X        no = *src++ - '0';
  1475. X    } else {
  1476. X        no = -1;
  1477. X    }
  1478. X
  1479. X    if (no < 0) {
  1480. X        /*
  1481. X         * It's an ordinary character.
  1482. X         */
  1483. X        if (c == '\\' && *src != '\0')
  1484. X        c = *src++;
  1485. X
  1486. X        (void) flexaddch(dest, c);
  1487. X
  1488. X    } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
  1489. X        register char *bracketp;
  1490. X
  1491. X        /*
  1492. X         * It isn't an ordinary character, but a reference
  1493. X         * to a string matched on the lhs. Notice that we
  1494. X         * just do nothing if we find a reference to a null
  1495. X         * match, or one that doesn't exist; we can't tell
  1496. X         * the difference at this stage.
  1497. X         */
  1498. X
  1499. X        for (bracketp = prog->startp[no]; bracketp < prog->endp[no];
  1500. X                                 bracketp++) {
  1501. X        if (*bracketp == '\0') {
  1502. X            regerror("Damaged match string");
  1503. X            return;
  1504. X        } else {
  1505. X            (void) flexaddch(dest, *bracketp);
  1506. X        }
  1507. X        }
  1508. X    }
  1509. X    }
  1510. X}
  1511. X
  1512. X/*
  1513. X * do_substitute(window, lp, up, cmd)
  1514. X *
  1515. X * Perform a substitution from line 'lp' up to (but not including)
  1516. X * line 'up' using the command pointed to by 'cmd' which should be
  1517. X * of the form:
  1518. X *
  1519. X * /pattern/substitution/g
  1520. X *
  1521. X * The trailing 'g' is optional and, if present, indicates that multiple
  1522. X * substitutions should be performed on each line, if applicable.
  1523. X * The usual escapes are supported as described in the regexp docs.
  1524. X */
  1525. Xlong
  1526. Xdo_substitute(window, lp, up, command)
  1527. XXviwin    *window;
  1528. XLine    *lp, *up;
  1529. Xchar    *command;
  1530. X{
  1531. X    char    *copy;        /* for copy of command */
  1532. X    regexp    *prog;
  1533. X    char    *sub;
  1534. X    char    *cp;
  1535. X    char    delimiter;
  1536. X    long    nsubs;
  1537. X
  1538. X    copy = alloc((unsigned) strlen(command) + 1);
  1539. X    if (copy == NULL) {
  1540. X    return(0);
  1541. X    }
  1542. X    (void) strcpy(copy, command);
  1543. X
  1544. X    delimiter = *copy;
  1545. X    if (delimiter == '\0' ||
  1546. X                (cp = compile(©[1], delimiter, TRUE)) == NULL) {
  1547. X    regerror("Usage: :s/search pattern/replacement/");
  1548. X    free(copy);
  1549. X    return(0);
  1550. X    }
  1551. X    sub = cp;
  1552. X    prog = cur_prog();
  1553. X
  1554. X    /*
  1555. X     * Scan past the rhs to the flags, if any.
  1556. X     */
  1557. X    for (; *cp != '\0'; cp++) {
  1558. X    if (*cp == '\\') {
  1559. X        if (*++cp == '\0') {
  1560. X        break;
  1561. X        }
  1562. X    } else if (*cp == delimiter) {
  1563. X        *cp++ = '\0';
  1564. X        break;
  1565. X    }
  1566. X    }
  1567. X
  1568. X    /*
  1569. X     * Save the regular expression for do_ampersand().
  1570. X     */
  1571. X    if (last_lhs) {
  1572. X    rn_delete(last_lhs);
  1573. X    }
  1574. X    last_lhs = rn_duplicate(lastprogp);
  1575. X
  1576. X    /*
  1577. X     * Save the rhs.
  1578. X     */
  1579. X    if (last_rhs != NULL) {
  1580. X    free(last_rhs);
  1581. X    }
  1582. X    last_rhs = strsave(sub);
  1583. X
  1584. X    nsubs = substitute(window, lp, up, sub, cp);
  1585. X
  1586. X    free(copy);
  1587. X
  1588. X    return(nsubs);
  1589. X}
  1590. X
  1591. X/*
  1592. X * Repeat last substitution.
  1593. X *
  1594. X * For vi compatibility, this also changes the value of the last
  1595. X * regular expression used.
  1596. X */
  1597. Xlong
  1598. Xdo_ampersand(window, lp, up, flags)
  1599. XXviwin    *window;
  1600. XLine    *lp, *up;
  1601. Xchar    *flags;
  1602. X{
  1603. X    long    nsubs;
  1604. X
  1605. X    if (last_lhs == NULL || last_rhs == NULL) {
  1606. X    show_error(window, "No substitute to repeat!");
  1607. X    return(0);
  1608. X    }
  1609. X    rn_delete(lastprogp);
  1610. X    lastprogp = rn_duplicate(last_lhs);
  1611. X    nsubs = substitute(window, lp, up, last_rhs, flags);
  1612. X    return(nsubs);
  1613. X}
  1614. X
  1615. X/*
  1616. X * Apply last right-hand side used in a substitution to last regular
  1617. X * expression used.
  1618. X *
  1619. X * For vi compatibility, this also changes the value of the last
  1620. X * substitution.
  1621. X */
  1622. Xlong
  1623. Xdo_tilde(window, lp, up, flags)
  1624. XXviwin    *window;
  1625. XLine    *lp, *up;
  1626. Xchar    *flags;
  1627. X{
  1628. X    long    nsubs;
  1629. X
  1630. X    if (lastprogp == NULL || last_rhs == NULL) {
  1631. X    show_error(window, "No substitute to repeat!");
  1632. X    return(0);
  1633. X    }
  1634. X    if (last_lhs) {
  1635. X    rn_delete(last_lhs);
  1636. X    }
  1637. X    last_lhs = rn_duplicate(lastprogp);
  1638. X    nsubs = substitute(window, lp, up, last_rhs, flags);
  1639. X    return(nsubs);
  1640. X}
  1641. X
  1642. Xstatic long
  1643. Xsubstitute(window, lp, up, sub, flags)
  1644. XXviwin    *window;
  1645. XLine    *lp, *up;
  1646. Xchar    *sub;
  1647. Xchar    *flags;
  1648. X{
  1649. X    long    nsubs;
  1650. X    Flexbuf    ns;
  1651. X    regexp    *prog;
  1652. X    bool_t    do_all;        /* true if 'g' was specified */
  1653. X
  1654. X    if (!start_command(window)) {
  1655. X    return(0);
  1656. X    }
  1657. X
  1658. X    prog = cur_prog();
  1659. X
  1660. X    do_all = (*flags == 'g');
  1661. X
  1662. X    nsubs = 0;
  1663. X
  1664. X    /*
  1665. X     * If no range was given, do the current line.
  1666. X     * If only one line was given, just do that one.
  1667. X     * Ensure that "up" points at the line after the
  1668. X     * last one in the range, to make the loop easier.
  1669. X     */
  1670. X    if (lp == NULL) {
  1671. X    lp = window->w_cursor->p_line;
  1672. X    }
  1673. X    if (up == NULL) {
  1674. X    up = lp->l_next;
  1675. X    } else {
  1676. X    up = up->l_next;
  1677. X    }
  1678. X    flexnew(&ns);
  1679. X    for (; lp != up; lp = lp->l_next) {
  1680. X    if (regexec(prog, lp->l_text, TRUE)) {
  1681. X        char    *p, *matchp;
  1682. X
  1683. X        /*
  1684. X         * Save the line that was last changed for the final
  1685. X         * cursor position (just like the real vi).
  1686. X         */
  1687. X        move_cursor(window, lp, 0);
  1688. X
  1689. X        flexclear(&ns);
  1690. X        p = lp->l_text;
  1691. X
  1692. X        do {
  1693. X        /*
  1694. X         * Copy up to the part that matched.
  1695. X         */
  1696. X        while (p < prog->startp[0]) {
  1697. X            (void) flexaddch(&ns, *p);
  1698. X            p++;
  1699. X        }
  1700. X
  1701. X        regsubst(prog, sub, &ns);
  1702. X
  1703. X        /*
  1704. X         * Continue searching after the match.
  1705. X         *
  1706. X         * Watch out for null matches - we
  1707. X         * don't want to go into an endless
  1708. X         * loop here.
  1709. X         */
  1710. X        matchp = p = prog->endp[0];
  1711. X        if (prog->startp[0] >= p) {
  1712. X            if (*p == '\0') {
  1713. X            /*
  1714. X             * End of the line.
  1715. X             */
  1716. X            break;
  1717. X            } else {
  1718. X            matchp++;
  1719. X            }
  1720. X        }
  1721. X
  1722. X        } while (do_all && regexec(prog, matchp, FALSE));
  1723. X
  1724. X        /*
  1725. X         * Copy the rest of the line, that didn't match.
  1726. X         */
  1727. X        (void) lformat(&ns, "%s", p);
  1728. X        replchars(window, lp, 0, strlen(lp->l_text),
  1729. X          flexgetstr(&ns));
  1730. X        nsubs++;
  1731. X    }
  1732. X    }
  1733. X    flexdelete(&ns);            /* free the temp buffer */
  1734. X    end_command(window);
  1735. X
  1736. X    if (!nsubs && (echo & e_NOMATCH)) {
  1737. X    regerror("No match");
  1738. X    }
  1739. X    return(nsubs);
  1740. X}
  1741. END_OF_FILE
  1742.   if test 27204 -ne `wc -c <'xvi/src/search.c'`; then
  1743.     echo shar: \"'xvi/src/search.c'\" unpacked with wrong size!
  1744.   fi
  1745.   # end of 'xvi/src/search.c'
  1746. fi
  1747. echo shar: End of archive 10 \(of 18\).
  1748. cp /dev/null ark10isdone
  1749. MISSING=""
  1750. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  1751.     if test ! -f ark${I}isdone ; then
  1752.     MISSING="${MISSING} ${I}"
  1753.     fi
  1754. done
  1755. if test "${MISSING}" = "" ; then
  1756.     echo You have unpacked all 18 archives.
  1757.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1758. else
  1759.     echo You still must unpack the following archives:
  1760.     echo "        " ${MISSING}
  1761. fi
  1762. exit 0
  1763. exit 0 # Just in case...
  1764.