home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / vim / part09 < prev    next >
Encoding:
Text File  |  1993-04-22  |  56.0 KB  |  1,947 lines

  1. Newsgroups: comp.sources.misc
  2. From: mool@oce.nl (Bram Moolenaar)
  3. Subject: v37i009:  vim - Vi IMitation editor v1.27, Part09/24
  4. Message-ID: <1993Apr23.173702.18518@sparky.imd.sterling.com>
  5. X-Md4-Signature: 9198928b4c843a98c1cd69bf7df98d94
  6. Date: Fri, 23 Apr 1993 17:37:02 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: mool@oce.nl (Bram Moolenaar)
  10. Posting-number: Volume 37, Issue 9
  11. Archive-name: vim/part09
  12. Environment: UNIX, AMIGA, MS-DOS
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 9 (of 23)."
  21. # Contents:  vim/macros/maze/maze.mac.uue vim/src/buffers.c
  22. #   vim/src/fileio.c
  23. # Wrapped by mool@oce-rd2 on Mon Apr 19 15:50:09 1993
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'vim/macros/maze/maze.mac.uue' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'vim/macros/maze/maze.mac.uue'\"
  27. else
  28. echo shar: Extracting \"'vim/macros/maze/maze.mac.uue'\" \(17071 characters\)
  29. sed "s/^X//" >'vim/macros/maze/maze.mac.uue' <<'END_OF_FILE'
  30. X
  31. Xbegin 644 maze.mac
  32. XM(B!4:&5S92!M86-R;W,@)W-O;'9E)R!A;GD@;6%Z92!P<F]D=6-E9"!B>2!TQ
  33. XM:&4@82UM87IE+6EN9R!M87IE+F,@<')O9W)A;2X*(B`*(B!&:7)S="P@82!B&
  34. XM:70@;V8@;6%Z92!T:&5O<GDN"B(@268@>6]U('=E<F4@<'5T(&EN=&\@82!MT
  35. XM87IE+"!A(&=U87)A;G1E960@;65T:&]D(&]F(&9I;F1I;F<@>6]U<B!W87D*L
  36. XM(B!O=70@;V8@=&AE(&UA>F4@:7,@=&\@<'5T('EO=7(@;&5F="!H86YD(&]NG
  37. XM=&\@82!W86QL(&%N9"!J=7-T(&ME97`@=V%L:VEN9RP*(B!N979E<B!T86MI@
  38. XM;F<@>6]U<B!H86YD(&]F9B!T:&4@=V%L;"X@5&AI<R!T96-H;FEQ=64@:7,@S
  39. XM;VYL>2!G=6%R86YT965D('1O"B(@=V]R:R!I9B!T:&4@;6%Z92!D;V5S(&YOY
  40. XM="!H879E(&%N>2`G:7-L86YD<R<L(&]R(&EF('1H92`G97AI="<@:7,@;VX@Z
  41. XM=&AE"B(@<V%M92!I<VQA;F0@87,@>6]U<B!S=&%R=&EN9R!P;VEN="X@5&AEV
  42. XM<V4@8V]N9&ET:6]N<R!H;VQD(&9O<B!T:&4@;6%Z97,*(B!U;F1E<B!C;VYS^
  43. XM:61E<F%T:6]N+@HB(`HB($%S<W5M:6YG('1H870@=&AE(&UA>F4@:7,@;6%D9
  44. XM92!U<"!O9B!H;W)I>F]N=&%L(&%N9"!V97)T:6-A;"!W86QL<R!S<&%C960*S
  45. XM(B!O;F4@<W1E<"!A<&%R="!A;F0@=&AA="!Y;W4@8V%N(&UO=F4@96ET:&5R#
  46. XM(&YO<G1H+"!S;W5T:"P@96%S="!O<B!W97-T+`HB('1H96X@>6]U(&-A;B!A>
  47. XM=71O;6%T92!T:&ES('!R;V-E9'5R92!B>2!C87)R>6EN9R!O=70@=&AE(&9O(
  48. XM;&QO=VEN9R!S=&5P<RX*(B`*(B`Q+B!0=70@>6]U<G-E;&8@<V]M97=H97)E1
  49. XM(&EN('1H92!M87IE(&YE87(@82!W86QL+@HB(#(N($-H96-K(&EF('EO=2!H(
  50. XM879E(&$@=V%L;"!O;B!Y;W5R(&QE9G0N($EF('-O+"!G;R!T;R!S=&5P(#0N&
  51. XM"B(@,RX@5&AE<F4@:7,@;F\@=V%L;"!O;B!Y;W5R(&QE9G0L('-O('1U<FX@\
  52. XM;VX@=&AE('-P;W0@=&\@>6]U<B!L969T(&%N9"!S=&5P"B(@("`@9F]R=V%R-
  53. XM9"!B>2!O;F4@<W1E<"!A;F0@<F5P96%T('-T97`@,BX*(B`T+B!#:&5C:R!WP
  54. XM:&%T(&ES(&1I<F5C=&QY(&EN(&9R;VYT(&]F('EO=2X@268@:70@:7,@82!WY
  55. XM86QL+"!T=7)N(&]N('1H90HB("`@('-P;W0@=&\@>6]U<B!R:6=H="!B>2`YB
  56. XM,"!D96=R965S(&%N9"!R97!E870@<W1E<"`T+@HB(#4N(%1H97)E(&ES(&YO!
  57. XM('=A;&P@:6X@9G)O;G0@;V8@>6]U+"!S;R!S=&5P(&9O<G=A<F0@;VYE('-T*
  58. XM97`@86YD"B(@("`@9V\@=&\@<W1E<"`R+@HB(`HB($EN('1H:7,@=V%Y('EOI
  59. XM=2!W:6QL(&-O=F5R(&%L;"!T:&4@8V]R<FED;W)S(&]F('1H92!M87IE("AU=
  60. XM;G1I;"!Y;W4@9V5T(&)A8VL*(B!T;R!W:&5R92!Y;W4@<W1A<G1E9"!F<F]M7
  61. XM+"!I9B!Y;W4@9&\@;F]T('-T;W`I+@HB(`HB($)Y(&5X86UI;FEN9R!A(&UA;
  62. XM>F4@<')O9'5C960@8GD@=&AE(&UA>F4N8R!P<F]G<F%M('EO=2!W:6QL('-ET
  63. XM92!T:&%T(`HB(&5A8V@@<W%U87)E(&]F('1H92!M87IE(&ES(&]N92!C:&%RC
  64. XM86-T97(@:&EG:"!A;F0@='=O(&-H87)A8W1E<G,@=VED92X*(B!4;R!G;R!NF
  65. XM;W)T:"!O<B!S;W5T:"P@>6]U(&UO=F4@8GD@82!O;F4@8VAA<F%C=&5R('-T#
  66. XM97`L(&)U="!T;R!M;W9E(&5A<W0@;W(*(B!W97-T('EO=2!M;W9E(&)Y(&$@3
  67. XM='=O(&-H87)A8W1E<B!S=&5P+B!!;'-O(&YO=&4@=&AA="!I;B!A;GD@<&]S8
  68. XM:71I;VX*(B!T:&5R92!A<F4@9F]U<B!P;&%C97,@=VAE<F4@=V%L;',@8V]UX
  69. XM;&0@8F4@<'5T("T@=&\@=&AE(&YO<G1H+"!T;R!T:&4@<V]U=&@L"B(@=&\@*
  70. XM=&AE(&5A<W0@86YD('1O('1H92!W97-T+@HB($$@=V%L;"!E>&ES=',@=&\@6
  71. XM=&AE(&YO<G1H(&]F('EO=2!I9B!T:&4@8VAA<F%C=&5R('1O('1H92!N;W)TB
  72. XM:"!O9@HB('EO=2!I<R!A(%\@*&]T:&5R=VES92!I="!I<R!A('-P86-E*2X*K
  73. XM(B!!('=A;&P@97AI<W1S('1O('1H92!E87-T(&]F('EO=2!I9B!T:&4@8VAA2
  74. XM<F%C=&5R('1O('1H92!E87-T(&]F('EO=0HB(&ES(&$@?"`H;W1H97)W:7-E+
  75. XM(&ET(&ES(&$@+BDN"B(@02!W86QL(&5X:7-T<R!T;R!T:&4@=V5S="!O9B!Y1
  76. XM;W4@:68@=&AE(&-H87)A8W1E<B!T;R!T:&4@=V5S="!O9B!Y;W4*(B!I<R!AC
  77. XM('P@*&]T:&5R=VES92!I="!I<R!A("XI+@HB($$@=V%L;"!E>&ES=',@=&\@=
  78. XM=&AE('-O=71H(&]F('EO=2!I9B!T:&4@8VAA<F%C=&5R('=H97)E('EO=2!A<
  79. XM<F4*(B!I<R!A(%\@*&]T:&5R=VES92!I="!I<R!A('-P86-E*2X*(B`*(B!.$
  80. XM;W1E('1H92!D:69F97)E;F-E(&9O<B!D:7)E8W1I;VX@<V]U=&@L('=H97)E6
  81. XM('=E(&UU<W0@97AA;6EN92!T:&4@8VAA<F%C=&5R"B(@=VAE<F4@=&AE(&-U:
  82. XM<G-O<B!I<R!R871H97(@=&AA;B!A;B!A9&IA8V5N="!C96QL+@HB(`HB($EFQ
  83. XM('EO=2!W97)E(&EM<&QE;65N=&EN9R!T:&4@86)O=F4@<')O8V5D=7)E(&ESL
  84. XM(&$@;F]R;6%L(&-O;7!U=&5R(&QA;F=U86=E"B(@>6]U(&-O=6QD('5S92!AK
  85. XM(&QO;W`@=VET:"!I9B!S=&%T96UE;G1S(&%N9"!C;VYT:6YU92!S=&%T96UEX
  86. XM;G1S+"`*(B!(;W=E=F5R+"!T:&5S92!C;VYS=')U8W1S(&%R92!N;W0@879A+
  87. XM:6QA8FQE(&EN('9I(&UA8W)O<R!S;R!)(&AA=F4@=7-E9`HB(&$@<W1A=&4@2
  88. XM;6%C:&EN92!W:71H(#@@<W1A=&5S+B!%86-H('-T871E('-I9VYI9FEE<R!TR
  89. XM:&4@9&ER96-T:6]N('EO=0HB(&%R92!G;VEN9R!I;B!A;F0@=VAE=&AE<B!O3
  90. XM<B!N;W0@>6]U(&AA=F4@8VAE8VME9"!I9B!T:&5R92!I<R!A('=A;&P@;VX*&
  91. XM(B!Y;W5R(&QE9G0N"B(@"B(@5&AE('1R86YS:71I;VX@9G)O;2!S=&%T92!T7
  92. XM;R!S=&%T92!A;F0@=&AE(&%C=&EO;G,@=&%K96X@;VX@96%C:"!T<F%N<VET[
  93. XM:6]N"B(@87)E(&=I=F5N(&EN('1H92!S=&%T92!T86)L92!B96QO=RX*(B!4+
  94. XM:&4@;F%M97,@;V8@=&AE('-T871E<R!A<F4@3C$L($XR+"!3,2P@4S(L($4QQ
  95. XM+"!%,BP@5S$L(%<R+"!W:&5R92!E86-H(&QE='1E<@HB('-T86YD<R!F;W(@4
  96. XM82!D:7)E8W1I;VX@;V8@=&AE(&-O;7!A<W,L('1H92!N=6UB97(@,2!I;F1IY
  97. XM8V%T97,@=&AA="!T:&4@=V4*(B!H879E(&YO="!Y970@8VAE8VME9"!T;R!S.
  98. XM964@:68@=&AE<F4@:7,@82!W86QL(&]N(&]U<B!L969T(&%N9"!T:&4@;G5M@
  99. XM8F5R(#(*(B!I;F1I8V%T97,@=&AA="!W92!H879E(&-H96-K960@86YD('1H2
  100. XM97)E(&ES(&$@=V%L;"!O;B!O=7(@;&5F="X*(B`*(B!&;W(@96%C:"!S=&%T!
  101. XM92!W92!M=7-T(&-O;G-I9&5R('1H92!E>&ES=&5N8V4@;W(@;F]T(&]F(&$@2
  102. XM=V%L;"!I;B!A"B(@<&%R=&EC=6QA<B!D:7)E8W1I;VXN(%1H:7,@9&ER96-T-
  103. XM:6]N(&ES(&=I=F5N(&EN('1H92!F;VQL;W=I;F<@=&%B;&4N"B(@"B(@3F5X=
  104. XM=$-H87(@=&%B;&4Z"B(@<W1A=&4@("`@("`@(&1I<F5C=&EO;B`@("`@("!V8
  105. XM:2!C;VUM86YD<PHB("!.,2`@("`@("`@("`@("`@5R`@("`@("`@("`@("`@=
  106. XM(&A&"B(@($XR("`@("`@("`@("`@("!.("`@("`@("`@("`@("`@:T8*(B`@%
  107. XM4S$@("`@("`@("`@("`@($4@("`@("`@("`@("`@("!L1@HB("!3,B`@("`@L
  108. XM("`@("`@("`@4R`@("`@("`@("`@("`@($8*(B`@13$@("`@("`@("`@("`@;
  109. XM($X@("`@("`@("`@("`@("!K1@HB("!%,B`@("`@("`@("`@("`@12`@("`@'
  110. XM("`@("`@("`@(&Q&"B(@(%<Q("`@("`@("`@("`@("!3("`@("`@("`@("`@Y
  111. XM("`@1@HB("!7,B`@("`@("`@("`@("`@5R`@("`@("`@("`@("`@(&A&"B(@,
  112. XM"B(@=VAE<F4@1B!I<R!A(&UA8W)O('=H:6-H('EA;FMS('1H92!C:&%R86-T,
  113. XM97(@=6YD97(@=&AE(&-U<G-O<B!I;G1O"B(@=&AE($YE>'1#:&%R(')E9VES2
  114. XM=&5R("AN*2X*(B`*(B!3=&%T92!T86)L93H*(B!);B!T:&4@)W9I(&-O;6UA*
  115. XM;F1S)R!C;VQU;6X@:7,@9VEV96X@=&AE(&%C=&EO;G,@=&\@8V%R<GD@;W5T]
  116. XM('=H96X@:6X*(B!T:&ES('-T871E(&%N9"!T:&4@3F5X=$-H87(@:7,@87,@/
  117. XM9VEV96XN(%1H92!C;VUM86YD<R!K+"!J+"!L;"P@:&@@;6]V90HB('1H92!CB
  118. XM=7)R96YT('!O<VET:6]N(&YO<G1H+"!S;W5T:"P@96%S="!A;F0@=V5S="!R`
  119. XM97-P96-T:79E;'DN(%1H90HB(&-O;6UA;F0@;6T@:7,@=7-E9"!A<R!A(&YO`
  120. XM+6]P(&-O;6UA;F0N"B(@26X@=&AE("=N97AT('-T871E)R!C;VQU;6X@:7,@5
  121. XM9VEV96X@=&AE(&YE=R!S=&%T92!O9B!T:&4@;6%C:&EN92!A9G1E<@HB('1H*
  122. XM92!A8W1I;VX@:7,@8V%R<FEE9"!O=70N"B(@"B(@8W5R<F5N="!S=&%T92`@[
  123. XM("`@("`@3F5X=$-H87(@("`@=FD@8V]M;6%N9',@(&YE>'0@<W1A=&4*(B`@:
  124. XM("`@($XQ("`@("`@("`@("`@("`@("`N("`@("`@("`@("`@:&@@("`@("`@]
  125. XM("`@5S$*(B`@("`@($XQ("`@("`@("`@("`@("`@("!\("`@("`@("`@("`@O
  126. XM;6T@("`@("`@("`@3C(*(B`@("`@($XR("`@("`@("`@("`@("`@("!?("`@E
  127. XM("`@("`@("`@;6T@("`@("`@("`@13$*(B`@("`@($XR("`@("`@("`@("`@<
  128. XM("`@<W!A8V4@("`@("`@("`@:R`@("`@("`@("`@3C$*(B`@("`@(%,Q("`@&
  129. XM("`@("`@("`@("`@("`N("`@("`@("`@("`@;&P@("`@("`@("`@13$*(B`@H
  130. XM("`@(%,Q("`@("`@("`@("`@("`@("!\("`@("`@("`@("`@;6T@("`@("`@:
  131. XM("`@4S(*(B`@("`@(%,R("`@("`@("`@("`@("`@("!?("`@("`@("`@("`@5
  132. XM;6T@("`@("`@("`@5S$*(B`@("`@(%,R("`@("`@("`@("`@("`@<W!A8V4@?
  133. XM("`@("`@("`@:B`@("`@("`@("`@4S$*(B`@("`@($4Q("`@("`@("`@("`@0
  134. XM("`@<W!A8V4@("`@("`@("`@:R`@("`@("`@("`@3C$*(B`@("`@($4Q("`@X
  135. XM("`@("`@("`@("`@("!?("`@("`@("`@("`@;6T@("`@("`@("`@13(*(B`@<
  136. XM("`@($4R("`@("`@("`@("`@("`@("!\("`@("`@("`@("`@;6T@("`@("`@-
  137. XM("`@4S$*(B`@("`@($4R("`@("`@("`@("`@("`@("`N("`@("`@("`@("`@5
  138. XM;&P@("`@("`@("`@13$*(B`@("`@(%<Q("`@("`@("`@("`@("`@<W!A8V4@.
  139. XM("`@("`@("`@:B`@("`@("`@("`@4S$*(B`@("`@(%<Q("`@("`@("`@("`@B
  140. XM("`@("!?("`@("`@("`@("`@;6T@("`@("`@("`@5S(*(B`@("`@(%<R("`@W
  141. XM("`@("`@("`@("`@("!\("`@("`@("`@("`@;6T@("`@("`@("`@3C$*(B`@!
  142. XM("`@(%<R("`@("`@("`@("`@("`@("`N("`@("`@("`@("`@:&@@("`@("`@'
  143. XM("`@5S$*(@HB(`HB($-O;7!L86EN="!A8F]U="!V:2!M86-R;W,Z"B(@270@5
  144. XM<V5E;7,@=&AA="!Y;W4@8V%N;F]T(&AA=F4@;6]R92!T:&%N(&]N92`G=6YD@
  145. XM;RUA8FQE)R!V:2!C;VUM86YD"B(@:6X@=&AE(&]N92!M86-R;RP@<V\@>6]U8
  146. XM(&AA=F4@=&\@;6%K92!L;W1S(&]F(&QI='1L92!M86-R;W,@86YD"B(@<'5TG
  147. XM('1H96T@=&]G971H97(N"B(*(B!))VQL(&5X<&QA:6X@=VAA="!)(&UE86X@M
  148. XM8GD@86X@97AA;7!L92X@161I="!A(&9I;&4@86YD"B(@='EP92`G.FUA<"!1\
  149. XM(')862<N(%1H:7,@<VAO=6QD(&UA<"!T:&4@42!K97D@=&\@)W)E<&QA8V4@>
  150. XM=&AE"B(@8VAA<F%C=&5R('5N9&5R('1H92!C=7)S;W(@=VET:"!8(&%N9"!Y7
  151. XM86YK('1H92!L:6YE)RX*(B!"=70@=VAE;B!)('1Y<&4@42P@=FD@=&5L;',@,
  152. XM;64@)T-A;B=T('EA;FL@:6YS:61E(&=L;V)A;"]M86-R;R<@86YD"B(@9V]E(
  153. XM<R!I;G1O(&5X(&UO9&4N($AO=V5V97(@:68@22!T>7!E("<Z;6%P(%$@<EA4E
  154. XM)R!A;F0@)SIM87`@5"!9)RP*(B!E=F5R>71H:6YG(&ES($]++B!)8&T@9&]I`
  155. XM;F<@86QL('1H:7,@;VX@82!3<&%R8W-T871I;VXN"B(@268@86YY;VYE(')EI
  156. XM861I;F<@=&AI<R!H87,@86X@86YS=V5R('1O('1H:7,@<')O8FQE;2P@=&AE/
  157. XM(&%U=&AO<B!W;W5L9`HB(&QO=F4@=&\@9FEN9"!O=70N($UA:6P@=&\@9W)EN
  158. XM9VU`;W1C+F]T8V$N;WHN874N"B(*(B!4:&4@;6%C<F]S.@HB(%1H92!M86-R@
  159. XM;R!T;R!R=6X@=&AE(&UA>F4@<V]L=F5R(&ES("=G)RX@5&AI<R!S:6UP;'D@E
  160. XM8V%L;',@='=O(&]T:&5R"B(@;6%C<F]S.B!)+"!T;R!I;FET:6%L:7-E(&5VT
  161. XM97)Y=&AI;F<L(&%N9"!,+"!T;R!L;V]P(&9O<F5V97(@<G5N;FEN9PHB('1H`
  162. XM<F]U9V@@=&AE('-T871E('1A8FQE+@HB($)O=&@@;V8@=&AE<V4@;6%C<F]S)
  163. XM(&%R92!L;VYG('-E<75E;F-E<R!O9B!C86QL<R!T;R!O=&AE<B!M86-R;W,N0
  164. XM($%L;`HB(&]F('1H97-E(&]T:&5R(&UA8W)O<R!A<F4@<75I=&4@<VEM<&QE$
  165. XM(&%N9"!S;R!T;R!U;F1E<G-T86YD(&AO=R!T:&ES"B(@=V]R:W,L(&%L;"!Y6
  166. XM;W4@;F5E9"!T;R!D;R!I<R!E>&%M:6YE(&UA8W)O<R!)(&%N9"!,(&%N9"!L%
  167. XM96%R;B!W:&%T('1H97D*(B!D;R`H82!S:6UP;&4@<V5Q=65N8V4@;V8@=FD@3
  168. XM86-T:6]N<RD@86YD(&AO=R!,(&QO;W!S("AB>2!C86QL:6YG(%4L('=H:6-H%
  169. XM"B(@<VEM<&QY(&-A;&QS($P@86=A:6XI+@HB"B(@36%C<F\@22!S971S('5PS
  170. XM('1H92!S=&%T92!T86)L92!A;F0@3F5X=$-H87(@=&%B;&4@870@=&AE(&5N+
  171. XM9"!O9B!T:&4@9FEL92X*(B!-86-R;R!,('1H96X@<V5A<F-H97,@=&AE<V4@H
  172. XM=&%B;&5S('1O(&9I;F0@;W5T('=H870@86-T:6]N<R!T;R!P97)F;W)M(&%NI
  173. XM9`HB('=H870@<W1A=&4@8VAA;F=E<R!T;R!M86ME+@HB"B(@5&AE(&5N=')IH
  174. XM97,@:6X@=&AE('-T871E('1A8FQE(&%L;"!B96=I;B!W:71H(&$@:V5Y(&-O/
  175. XM;G-I<W1I;F<@;V8@=&AE"B(@;&5T=&5R("=S)RP@=&AE(&-U<G)E;G0@<W1A:
  176. XM=&4@86YD('1H92!.97AT0VAA<BX@($%F=&5R('1H:7,@:7,@=&AE"B(@86-TC
  177. XM:6]N('1O('1A:V4@:6X@=&AI<R!S=&%T92!A;F0@869T97(@=&AI<R!I<R!T+
  178. XM:&4@;F5X="!S=&%T92!T;R!C:&%N9V4@=&\N"B(*(B!4:&4@96YT<FEE<R!IC
  179. XM;B!T:&4@3F5X=$-H87(@=&%B;&4@8F5G:6X@=VET:"!A(&ME>2!C;VYS:7-T"
  180. XM:6YG(&]F('1H90HB(&QE='1E<B`G;B<@86YD('1H92!C=7)R96YT('-T871ED
  181. XM+B!!9G1E<B!T:&ES(&ES('1H92!A8W1I;VX@=&\@=&%K92!T;PHB(&]B=&%IY
  182. XM;B!.97AT0VAA<B`M('1H92!C:&%R86-T97(@=&AA="!M=7-T(&)E(&5X86UI[
  183. XM;F5D('1O(&-H86YG92!S=&%T92X*(@HB($]N92!W87D@=&\@<V5E('=H870@.
  184. XM96%C:"!P87)T(&]F('1H92!M86-R;W,@:7,@9&]I;F<@:7,@=&\@='EP92!IZ
  185. XM;B!T:&4*(B!B;V1Y(&]F('1H92!M86-R;W,@22!A;F0@3"!M86YU86QL>2`HW
  186. XM:6YS=&5A9"!O9B!T>7!I;F<@)V<G*2!A;F0@<V5E"B(@=VAA="!H87!P96YS5
  187. XM(&%T(&5A8V@@<W1E<"X*(@HB($=O;V0@;'5C:RX*(@HB(%)E9VES=&5R<R!US
  188. XM<V5D(&)Y('1H92!M86-R;W,Z"B(@<R`H4W1A=&4I("`@("`@("`M(&AO;&1S/
  189. XM('1H92!S=&%T92!T:&4@;6%C:&EN92!I<R!I;@HB(&,@*$-H87(I("`@("`@)
  190. XM("`@+2!H;VQD<R!T:&4@8VAA<F%C=&5R('5N9&5R('1H92!C=7)R96YT('!OV
  191. XM<VET:6]N"B(@;2`H36%C<F\I("`@("`@("`M(&AO;&1S(&$@=FD@8V]M;6%NT
  192. XM9"!S=')I;F<@=&\@8F4@97AE8W5T960@;&%T97(*(B!N("A.97AT0VAA<BD@<
  193. XM("`@("T@:&]L9',@=&AE(&-H87)A8W1E<B!W92!M=7-T(&5X86UI;F4@=&\@D
  194. XM8VAA;F=E('-T871E"B(@<B`H4V5C;VYD($UA8W)O*2`M(&AO;&1S(&$@<V5CG
  195. XM;VYD('9I(&-O;6UA;F0@<W1R:6YG('1O(&)E(&5X96-U=&5D(&QA=&5R"B(*%
  196. XM<V5T(')E;6%P"G-E="!N;VUA9VEC"G-E="!N;W1E<G-E"G-E="!W<F%P<V-AR
  197. XM;@HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T].
  198. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]"B(@9R`M(&=O(')U;G,@=&AE('=HV
  199. XM;VQE('-H;W<*(B`@("`@("`@22`M(&EN:71I86QI<V4*(B`@("`@("`@3"`MS
  200. XM('1H96X@;&]O<"!F;W)E=F5R"FUA<"!G("`@24P*(@HB/3T]/3T]/3T]/3T]Z
  201. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  202. XM/3T]/3T]/0HB($D@+2!I;FET:6%L:7-E(&5V97)Y=&AI;F<@8F5F;W)E(')U7
  203. XM;FYI;F<@=&AE(&QO;W`*(B`@($<D/RY>32`M(&9I;F0@=&AE(&QA<W0@+B!I^
  204. XM;B!T:&4@;6%Z90HB("`@("`@("!>("T@<F5P;&%C92!I="!W:71H(&%N(%@@/
  205. XM*'1H92!G;V%L*0HB("`@1UE+9410("T@<')I;G0@=&AE('-T871E('1A8FQEI
  206. XM(&%N9"!N97AT(&-H87(@=&%B;&4@870@=&AE(&5N9"!O9B!T:&4@9FEL90HB'
  207. XM("`@("`@(#!3("T@:6YI=&EA;&ES92!T:&4@<W1A=&4@;V8@=&AE(&UA8VAI5
  208. XM;F4@=&\@13$*(B`@("`@(#)';"`M(&UO=F4@=&\@=&AE('1O<"!L969T(&-EK
  209. XM;&P@;V8@=&AE(&UA>F4*;6%P($D@("!')#\N#5Y'64ME1%`P4S)';`HB"B(]P
  210. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  211. XM/3T]/3T]/3T]/3T]/3T]/3T]"B(@3"`M('1H92!L;V]P('=H:6-H(&ES(&5X6
  212. XM96-U=&5D(&9O<F5V97(*(B`@("`@("`@42`M('-A=F4@=&AE(&-U<G)E;G0@0
  213. XM8VAA<F%C=&5R(&EN('1H92!#:&%R(')E9VES=&5R"B(@("`@("`@($$@+2!RT
  214. XM97!L86-E('1H92!C=7)R96YT(&-H87)A8W1E<B!W:71H(&%N("=/)PHB("`@/
  215. XM("`@(&UA("T@;6%R:R!T:&4@8W5R<F5N="!P;W-I=&EO;B!W:71H(&UA<FL@&
  216. XM)V$G"B(@("`@("!'3D(@+2!O;B!B;W1T;VT@;&EN92P@8W)E871E(&$@8V]M9
  217. XM;6%N9"!T;R!S96%R8V@@=&AE($YE>'1#:&%R('1A8FQE"B(@("`@("`@("`@K
  218. XM("!F;W(@=&AE(&-U<G)E;G0@<W1A=&4*(B`P33!%0&U>32`M('EA;FL@=&AEC
  219. XM(&-O;6UA;F0@:6YT;R!T:&4@36%C<F\@<F5G:7-T97(@86YD(&5X96-U=&4@7
  220. XM:70*(B`@("`@("!W6"`M('=E(&AA=F4@;F]W(&9O=6YD('1H92!E;G1R>2!IQ
  221. XM;B!T:&4@=&%B;&4L(&YO=R!Y86YK('1H90HB("`@("`@("`@("`@9F]L;&]W*
  222. XM:6YG('=O<F0@:6YT;R!T:&4@36%C<F\@<F5G:7-T97(*(B`@("`@8&%`;2`MS
  223. XM(&=O(&)A8VL@=&\@=&AE(&-U<G)E;G0@<&]S:71I;VX@86YD(&5X96-U=&4@)
  224. XM=&AE(&UA8W)O+"!T:&ES('=I;&P*(B`@("`@("`@("`@('EA;FL@=&AE($YEB
  225. XM>'1#:&%R(&EN(')E9VES=&5R(&X*(B`@($=4)$(D4B`M(&]N(&)O='1O;2!L"
  226. XM:6YE+"!C<F5A=&4@82!C;VUM86YD('1O('-E87)C:"!T:&4@<W1A=&4@=&%B.
  227. XM;&4*(B`@("`@("`@("`@(&9O<B!T:&4@8W5R<F5N="!S=&%T92!A;F0@3F5XG
  228. XM=$-H87(*(B`P33!%0&U>32`M('EA;FL@=&AE(&-O;6UA;F0@:6YT;R!T:&4@C
  229. XM36%C<F\@<F5G:7-T97(@86YD(&5X96-U=&4@:70*(B`@("`@(#)74R`M('=EK
  230. XM(&AA=F4@;F]W(&9O=6YD('1H92!E;G1R>2!I;B!T:&4@=&%B;&4L(&YO=R!Y@
  231. XM86YK('1H90HB("`@("`@("`@("`@;F5X="!S=&%T92!I;G1O('1H92!3=&%T^
  232. XM92!M86-R;PHB("`@("`@(&)8("T@86YD('EA;FL@=&AE(&%C=&EO;B!C;W)RE
  233. XM97-P;VYD:6YG('1O('1H:7,@<W1A=&4@=&%B;&4@96YT<GD*(B`@("`@("`@)
  234. XM("`@(&EN=&\@=&AE($UA8W)O(')E9VES=&5R"B(@("`@("!'5DH@+2!O;B!B1
  235. XM;W1T;VT@;&EN92P@8W)E871E(&$@8V]M;6%N9"!T;R!R97-T;W)E('1H92!C&
  236. XM=7)R96YT(&-H87)A8W1E<@HB("`@("`@(#!(("T@86YD('-A=F4@=&AE(&-OS
  237. XM;6UA;F0@:6YT;R!T:&4@<V5C;VYD($UA8W)O(')E9VES=&5R"B(@("`@(&!A(
  238. XM0'(@+2!G;R!B86-K('1O('1H92!C=7)R96YT('!O<VET:6]N(&%N9"!E>&5C:
  239. XM='5T92!T:&4@;6%C<F\@=&\@<F5S=&]R90HB("`@("`@("`@("`@=&AE(&-UA
  240. XM<G)E;G0@8VAA<F%C=&5R"B(@("`@("`@0&T@+2!E>&5C=71E('1H92!A8W1IS
  241. XM;VX@87-S;V-I871E9"!W:71H('1H:7,@<W1A=&4*(B`@("`@("`@52`M(&%N/
  242. XM9"!R97!E870*;6%P($P@("!106UA1TY",$TP14!M#7=88&%`;4=4)$(D4C!-M
  243. XM,$5`;0TR5U-B6$=62C!(8&%`<D!M50HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]X
  244. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  245. XM"B(@52`M(&YO('1A:6P@<F5C=7)S:6]N(&%L;&]W960@:6X@=FD@;6%C<F]S2
  246. XM('-O(&-H96%T(&%N9"!S970@52`]($P*;6%P(%4@("!,"B(*(CT]/3T]/3T]-
  247. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  248. XM/3T]/3T]/3T]/3T*(B!3("T@>6%N:R!T:&4@;F5X="!T=V\@8VAA<F%C=&5RE
  249. XM<R!I;G1O('1H92!3=&%T92!R96=I<W1E<@IM87`@4R`@(")S>3)L"B(*(CT]M
  250. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  251. XM/3T]/3T]/3T]/3T]/3T]/3T*(B!1("T@<V%V92!T:&4@8W5R<F5N="!C:&%R(
  252. XM86-T97(@:6X@=&AE($-H87(@<F5G:7-T97(*;6%P(%$@("`B8WEL"B(*(CT]?
  253. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  254. XM/3T]/3T]/3T]/3T]/3T]/3T*(B!!("T@<F5P;&%C92!T:&4@8W5R<F5N="!CJ
  255. XM:&%R86-T97(@=VET:"!A;B`G3R<*;6%P($$@("!R3PHB"B(]/3T]/3T]/3T]6
  256. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  257. XM/3T]/3T]/3T]"B(@3B`M(')E<&QA8V4@=&AI<R!L:6YE('=I=&@@=&AE('-TL
  258. XM<FEN9R`G;B<*;6%P($X@("!#+VX;"B(*(CT]/3T]/3T]/3T]/3T]/3T]/3T]Y
  259. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T*&
  260. XM(B!"("T@<'5T('1H92!C=7)R96YT('-T871E"FUA<"!"("`@(G-P"B(*(CT]P
  261. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  262. XM/3T]/3T]/3T]/3T]/3T]/3T*(B!-("T@>6%N:R!T:&ES(&QI;F4@:6YT;R!T4
  263. XM:&4@36%C<F\@<F5G:7-T97(*;6%P($T@("`B;7DD"B(*(CT]/3T]/3T]/3T]<
  264. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  265. XM/3T]/3T]/3T*(B!%("T@9&5L971E('1O('1H92!E;F0@;V8@=&AE(&QI;F4*\
  266. XM;6%P($4@("!D)`HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]&
  267. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]"B(@6"`M('EA;FL@!
  268. XM=&AI<R!W;W)D(&EN=&\@=&AE($UA8W)O(')E9VES=&5R"FUA<"!8("`@(FUY.
  269. XM="`*(@HB/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]W
  270. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/0HB(%0@+2!R97!L86-E('1H:7,@6
  271. XM;&EN92!W:71H('1H92!S=')I;F<@)W,G"FUA<"!4("`@0R]S&PHB"B(]/3T]E
  272. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  273. XM/3T]/3T]/3T]/3T]/3T]"B(@4B`M('!U="!.97AT0VAA<@IM87`@4B`@(")N>
  274. XM<`HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]0
  275. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]"B(@5B`M(&%D9"!T:&4@;&5T=&5R!
  276. XM("=R)R`H=&AE(')E<&QA8V4@=FD@8V]M;6%N9"D*;6%P(%8@("!A<AL*(@HBP
  277. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  278. XM/3T]/3T]/3T]/3T]/3T]/3T]/0HB($H@+2!R97-T;W)E('1H92!C=7)R96YT2
  279. XM(&-H87)A8W1E<@IM87`@2B`@(")C<`HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]S
  280. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  281. XM"B(@2"`M('EA;FL@=&AI<R!L:6YE(&EN=&\@=&AE('-E8V]N9"!-86-R;R!R/
  282. XM96=I<W1E<@IM87`@2"`@(")R>20*(@HB/3T]/3T]/3T]/3T]/3T]/3T]/3T]-
  283. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/0HBK
  284. XM($8@+2!Y86YK($YE>'1#:&%R("AT:&ES(&UA8W)O(&ES(&-A;&QE9"!F<F]M*
  285. XM('1H92!-86-R;R!R96=I<W1E<BD*;6%P($8@("`B;GEL"B(*(CT]/3T]/3T]D
  286. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  287. XM/3T]/3T]/3T]/3T*(B!>("T@<F5P;&%C92!T:&4@8W5R<F5N="!C:&%R86-T,
  288. XM97(@=VET:"!A;B`G6"<*;6%P(%X@("!R6`HB"B(]/3T]/3T]/3T]/3T]/3T]`
  289. XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]Y
  290. XM/3T]"B(@64ME1%`@+2!C<F5A=&4@=&AE('-T871E('1A8FQE+"!.97AT0VAA"
  291. XM<B!T86)L92!A;F0@:6YI=&EA;"!S=&%T90HB($YO=&4@=&AA="!Y;W4@:&%V'
  292. XM92!T;R!E<V-A<&4@=&AE(&)A<B!C:&%R86-T97(L('-I;F-E(&ET(&ES('-P6
  293. XM96-I86P@=&\*(B!T:&4@;6%P(&-O;6UA;F0@*&ET(&EN9&EC871E<R!A(&YE8
  294. XM=R!L:6YE*2X*;6%P(%D@("!O<T4Q("!K("!.,2`@("`@("!S13%?(&UM($4RR
  295. XM("`@("`@('-%,A9\(&UM(%,Q("`@("`@('-%,BX@;&P@13$;"FUA<"!+("`@N
  296. XM;W-7,2`@:B`@4S$@("`@("`@<U<Q7R!M;2!7,B`@("`@("!S5S(6?"!M;2!.+
  297. XM,2`@("`@("!S5S(N(&AH(%<Q&PIM87`@92`@(&]S3C$N(&AH(%<Q("`@("`@"
  298. XM('-.,19\(&UM($XR("`@("`@('-.,B`@:R`@3C$@("`@("`@<TXR7R!M;2!%,
  299. XM,1L*;6%P($0@("!O<U,Q+B!L;"!%,2`@("`@("!S4S$6?"!M;2!3,B`@("`@B
  300. XM("!S4S(@(&H@(%,Q("`@("`@('-3,E\@;6T@5S$;"FUA<"!0("`@;VY%,2!K0
  301. XM1B!N13(@;$8@;E<Q($<D2D8@;E<R(&A&(&Y.,2!H1B!N3C(@:T8@;E,Q(&Q&1
  302. X/(&Y3,B!')$I&(`U%,1L*V
  303. X``
  304. Xend
  305. Xsize 12165
  306. END_OF_FILE
  307. if test 17071 -ne `wc -c <'vim/macros/maze/maze.mac.uue'`; then
  308.     echo shar: \"'vim/macros/maze/maze.mac.uue'\" unpacked with wrong size!
  309. fi
  310. # end of 'vim/macros/maze/maze.mac.uue'
  311. fi
  312. if test -f 'vim/src/buffers.c' -a "${1}" != "-c" ; then 
  313.   echo shar: Will not clobber existing file \"'vim/src/buffers.c'\"
  314. else
  315. echo shar: Extracting \"'vim/src/buffers.c'\" \(17483 characters\)
  316. sed "s/^X//" >'vim/src/buffers.c' <<'END_OF_FILE'
  317. X/* vi:ts=4:sw=4
  318. X *
  319. X * VIM - Vi IMitation
  320. X *
  321. X * Code Contributions By:    Bram Moolenaar            mool@oce.nl
  322. X *                            Tim Thompson            twitch!tjt
  323. X *                            Tony Andrews            onecom!wldrdg!tony 
  324. X *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  325. X */
  326. X
  327. X/*
  328. X * buffers.c
  329. X *
  330. X * manipulations with redo buffer and stuff buffer
  331. X */
  332. X
  333. X#include "vim.h"
  334. X#include "globals.h"
  335. X#include "proto.h"
  336. X#include "param.h"
  337. X
  338. X
  339. X/*
  340. X * structure used to store one block of the stuff/redo/macro buffers
  341. X */
  342. Xstruct bufblock
  343. X{
  344. X        struct bufblock *b_next;        /* pointer to next bufblock */
  345. X        u_char            b_str[1];        /* contents (actually longer) */
  346. X};
  347. X
  348. X#define MINIMAL_SIZE 20                 /* minimal size for b_str */
  349. X
  350. X/*
  351. X * header used for the stuff buffer and the redo buffer
  352. X */
  353. Xstruct buffheader
  354. X{
  355. X        struct bufblock bh_first;        /* first (dummy) block of list */
  356. X        struct bufblock *bh_curr;        /* bufblock for appending */
  357. X        int             bh_index;        /* index for reading */
  358. X        int             bh_space;        /* space in bh_curr for appending */
  359. X};
  360. X
  361. Xstatic struct buffheader stuffbuff = {{NULL, {NUL}}, NULL, 0, 0};
  362. Xstatic struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
  363. Xstatic struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
  364. X
  365. X    /*
  366. X     * when block_redo is TRUE redo buffer will not be changed
  367. X     * used by edit() to repeat insertions and 'V' command for redoing
  368. X     */
  369. Xstatic int        block_redo = FALSE;
  370. X
  371. Xstruct mapblock
  372. X{
  373. X    struct mapblock *m_next;        /* next mapblock */
  374. X    char            *m_keys;        /* mapped from */
  375. X    char            *m_str;         /* mapped to */
  376. X    int              m_mode;        /* valid mode */
  377. X    int                 m_noremap;        /* no re-mapping for this one */
  378. X};
  379. X
  380. X/* variables used by vgetorpeek() and flush_buffers */
  381. X#define MAXMAPLEN 10    /* maximum length of key sequence to be mapped */
  382. Xstatic char        typeahead[MAXMAPLEN + 2];
  383. Xstatic int        typelen = 0;    /* number of characters in typeahead[] */
  384. Xstatic char        *mapstr = NULL;    /* mapped characters */
  385. Xstatic int        maplen = 0;        /* number of characters in mapstr */
  386. X
  387. Xstatic void        free_buff __ARGS((struct buffheader *));
  388. Xstatic void        add_buff __ARGS((struct buffheader *, char *));
  389. Xstatic void        add_num_buff __ARGS((struct buffheader *, long));
  390. Xstatic u_char    read_stuff __ARGS((int));
  391. Xstatic int        start_stuff __ARGS((void));
  392. Xstatic int        read_redo __ARGS((int));
  393. Xstatic u_char    vgetorpeek __ARGS((int));
  394. Xstatic void        showmap __ARGS((struct mapblock *));
  395. X
  396. X/*
  397. X * free and clear a buffer
  398. X */
  399. X    static void
  400. Xfree_buff(buf)
  401. X    struct buffheader *buf;
  402. X{
  403. X        register struct bufblock *p, *np;
  404. X
  405. X        for (p = buf->bh_first.b_next; p != NULL; p = np)
  406. X        {
  407. X                np = p->b_next;
  408. X                free((char *)p);
  409. X        }
  410. X        buf->bh_first.b_next = NULL;
  411. X}
  412. X
  413. X/*
  414. X * return the contents of a buffer as a single string
  415. X */
  416. X    u_char *
  417. Xget_bufcont(buffer)
  418. X    struct buffheader *buffer;
  419. X{
  420. X        unsigned        count = 0;
  421. X        u_char            *p = NULL;
  422. X        struct bufblock    *bp;
  423. X
  424. X/* compute the total length of the string */
  425. X        for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
  426. X                count += strlen((char *)bp->b_str);
  427. X
  428. X        if (count != 0 && (p = (u_char *)alloc(count + 1)) != NULL)
  429. X        {
  430. X                *p = NUL;
  431. X                for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
  432. X                        strcat((char *)p, (char *)bp->b_str);
  433. X        }
  434. X        return (p);
  435. X}
  436. X
  437. X/*
  438. X * return the contents of the record buffer as a single string
  439. X *    and clear the record buffer
  440. X */
  441. X    u_char *
  442. Xget_recorded()
  443. X{
  444. X        u_char *p;
  445. X
  446. X        p = get_bufcont(&recordbuff);
  447. X        free_buff(&recordbuff);
  448. X        return (p);
  449. X}
  450. X
  451. X/*
  452. X * return the contents of the redo buffer as a single string
  453. X */
  454. X    u_char *
  455. Xget_inserted()
  456. X{
  457. X        return(get_bufcont(&redobuff));
  458. X}
  459. X
  460. X/*
  461. X * add string "s" after the current block of buffer "buf"
  462. X */
  463. X    static void
  464. Xadd_buff(buf, s)
  465. X    register struct buffheader    *buf;
  466. X    char                        *s;
  467. X{
  468. X        struct bufblock *p;
  469. X        int             n;
  470. X        int             len;
  471. X
  472. X        if ((n = strlen(s)) == 0)        /* don't add empty strings */
  473. X                return;
  474. X
  475. X        if (buf->bh_first.b_next == NULL)        /* first add to list */
  476. X        {
  477. X                buf->bh_space = 0;
  478. X                buf->bh_curr = &(buf->bh_first);
  479. X        }
  480. X        else if (buf->bh_curr == NULL)    /* buffer has already been read */
  481. X        {
  482. X                emsg("Add to read buffer");
  483. X                return;
  484. X        }
  485. X        else if (buf->bh_index != 0)
  486. X                strcpy((char *)buf->bh_first.b_next->b_str, (char *)buf->bh_first.b_next->b_str + buf->bh_index);
  487. X        buf->bh_index = 0;
  488. X
  489. X        if (buf->bh_space >= n)
  490. X        {
  491. X                strcat((char *)buf->bh_curr->b_str, s);
  492. X                buf->bh_space -= n;
  493. X        }
  494. X        else
  495. X        {
  496. X                if (n < MINIMAL_SIZE)
  497. X                        len = MINIMAL_SIZE;
  498. X                else
  499. X                        len = n;
  500. X                p = (struct bufblock *)alloc((unsigned)(sizeof(struct bufblock) + len));
  501. X                if (p == NULL)
  502. X                        return; /* no space, just forget it */
  503. X                buf->bh_space = len - n;
  504. X                strcpy((char *)p->b_str, s);
  505. X
  506. X                p->b_next = buf->bh_curr->b_next;
  507. X                buf->bh_curr->b_next = p;
  508. X                buf->bh_curr = p;
  509. X        }
  510. X        return;
  511. X}
  512. X
  513. X    static void
  514. Xadd_num_buff(buf, n)
  515. X    struct buffheader *buf;
  516. X    long               n;
  517. X{
  518. X        char    number[32];
  519. X
  520. X        sprintf(number, "%ld", n);
  521. X        add_buff(buf, number);
  522. X}
  523. X
  524. X/*
  525. X * get one character from the stuff buffer
  526. X * If advance == TRUE go to the next char.
  527. X */
  528. X    static u_char
  529. Xread_stuff(advance)
  530. X    int            advance;
  531. X{
  532. X        register u_char c;
  533. X        register struct bufblock *curr;
  534. X
  535. X
  536. X        if (stuffbuff.bh_first.b_next == NULL)    /* buffer is empty */
  537. X            return NUL;
  538. X
  539. X        curr = stuffbuff.bh_first.b_next;
  540. X        c = curr->b_str[stuffbuff.bh_index];
  541. X
  542. X        if (advance)
  543. X        {
  544. X            if (curr->b_str[++stuffbuff.bh_index] == NUL)
  545. X            {
  546. X                stuffbuff.bh_first.b_next = curr->b_next;
  547. X                free((char *)curr);
  548. X                stuffbuff.bh_index = 0;
  549. X            }
  550. X        }
  551. X        return c;
  552. X}
  553. X
  554. X/*
  555. X * prepare stuff buffer for reading (if it contains something)
  556. X */
  557. X    static int
  558. Xstart_stuff()
  559. X{
  560. X    if (stuffbuff.bh_first.b_next == NULL)
  561. X        return FALSE;
  562. X    stuffbuff.bh_curr = &(stuffbuff.bh_first);
  563. X    stuffbuff.bh_space = 0;
  564. X    return TRUE;
  565. X}
  566. X
  567. X/*
  568. X * check if the stuff buffer is empty
  569. X */
  570. X    int
  571. Xstuff_empty()
  572. X{
  573. X    if (stuffbuff.bh_first.b_next == NULL)
  574. X        return TRUE;
  575. X    return FALSE;
  576. X}
  577. X
  578. X/*
  579. X * remove all typeahead characters (used in case of an error).
  580. X */
  581. X    void
  582. Xflush_buffers()
  583. X{
  584. X    start_stuff();
  585. X    while (read_stuff(TRUE) != NUL)
  586. X        ;
  587. X    typelen = 0;
  588. X    maplen = 0;
  589. X    if (mapstr)
  590. X        *mapstr = 0;
  591. X}
  592. X
  593. X    void
  594. XResetBuffers()
  595. X{
  596. X    if (!block_redo)
  597. X        free_buff(&redobuff);
  598. X}
  599. X
  600. X    void
  601. XAppendToRedobuff(s)
  602. X    char           *s;
  603. X{
  604. X    if (!block_redo)
  605. X        add_buff(&redobuff, s);
  606. X}
  607. X
  608. X    void
  609. XAppendNumberToRedobuff(n)
  610. X    long             n;
  611. X{
  612. X    if (!block_redo)
  613. X        add_num_buff(&redobuff, n);
  614. X}
  615. X
  616. X    void
  617. XstuffReadbuff(s)
  618. X    char           *s;
  619. X{
  620. X    add_buff(&stuffbuff, s);
  621. X}
  622. X
  623. X    void
  624. XstuffnumReadbuff(n)
  625. X    long    n;
  626. X{
  627. X    add_num_buff(&stuffbuff, n);
  628. X}
  629. X
  630. X/*
  631. X * Read a character from the redo buffer.
  632. X * The redo buffer is left as it is.
  633. X */
  634. X    static int
  635. Xread_redo(init)
  636. X    int            init;
  637. X{
  638. X    static struct bufblock    *bp;
  639. X    static u_char            *p;
  640. X    int                        c;
  641. X
  642. X    if (init)
  643. X    {
  644. X        if ((bp = redobuff.bh_first.b_next) == NULL)
  645. X            return TRUE;
  646. X        p = bp->b_str;
  647. X        return FALSE;
  648. X    }
  649. X    if ((c = *p) != NUL)
  650. X    {
  651. X        if (*++p == NUL && bp->b_next != NULL)
  652. X        {
  653. X            bp = bp->b_next;
  654. X            p = bp->b_str;
  655. X        }
  656. X    }
  657. X    return c;
  658. X}
  659. X
  660. X/*
  661. X * copy the rest of the redo buffer into the stuff buffer (could be done faster)
  662. X */
  663. X    void
  664. Xcopy_redo()
  665. X{
  666. X    register int c;
  667. X
  668. X    while ((c = read_redo(FALSE)) != NUL)
  669. X        stuffReadbuff(mkstr(c));
  670. X}
  671. X
  672. Xextern int redo_Quote_busy;        /* this is in normal.c */
  673. X
  674. X/*
  675. X * Stuff the redo buffer into the stuffbuff.
  676. X * Insert the redo count into the command.
  677. X */
  678. X    int
  679. Xstart_redo(count)
  680. X    long count;
  681. X{
  682. X        register int c;
  683. X
  684. X        if (read_redo(TRUE))    /* init the pointers; return if nothing to redo */
  685. X                return FALSE;
  686. X
  687. X        c = read_redo(FALSE);
  688. X
  689. X/* copy the buffer name, if present */
  690. X        if (c == '"')
  691. X        {
  692. X                add_buff(&stuffbuff, "\"");
  693. X                c = read_redo(FALSE);
  694. X
  695. X        /* if a numbered buffer is used, increment the number */
  696. X                if (c >= '1' && c < '9')
  697. X                        ++c;
  698. X                add_buff(&stuffbuff, mkstr(c));
  699. X                c = read_redo(FALSE);
  700. X        }
  701. X
  702. X        if (c == 'q')    /* redo Quoting */
  703. X        {
  704. X            Quote = Curpos;
  705. X            redo_Quote_busy = TRUE;
  706. X            c = read_redo(FALSE);
  707. X        }
  708. X
  709. X/* try to enter the count (in place of a previous count) */
  710. X        if (count)
  711. X        {
  712. X                while (isdigit(c))        /* skip "old" count */
  713. X                        c = read_redo(FALSE);
  714. X                add_num_buff(&stuffbuff, count);
  715. X        }
  716. X
  717. X/* copy from the redo buffer into the stuff buffer */
  718. X        add_buff(&stuffbuff, mkstr(c));
  719. X        copy_redo();
  720. X        return TRUE;
  721. X}
  722. X
  723. X/*
  724. X * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing the redo buffer
  725. X * into the stuffbuff.
  726. X */
  727. X    int
  728. Xstart_redo_ins()
  729. X{
  730. X        register u_char c;
  731. X
  732. X        if (read_redo(TRUE))
  733. X                return FALSE;
  734. X        start_stuff();
  735. X
  736. X/* skip the count and the command character */
  737. X        while ((c = read_redo(FALSE)) != NUL)
  738. X        {
  739. X            c = toupper(c);
  740. X            if (strchr("AIRO", c) != NULL)
  741. X            {
  742. X                if (c == 'O')
  743. X                    stuffReadbuff(NL_STR);
  744. X                break;
  745. X            }
  746. X        }
  747. X
  748. X/* copy the typed text from the redo buffer into the stuff buffer */
  749. X        copy_redo();
  750. X        block_redo = TRUE;
  751. X        return TRUE;
  752. X}
  753. X
  754. X    void
  755. Xset_redo_ins()
  756. X{
  757. X        block_redo = TRUE;
  758. X}
  759. X
  760. X    void
  761. Xstop_redo_ins()
  762. X{
  763. X        block_redo = FALSE;
  764. X}
  765. X
  766. Xstruct mapblock maplist = {NULL, NULL, NULL}; /* first dummy entry in maplist */
  767. X
  768. X/*
  769. X * insert a string in front of the map-buffer (for '@' command and vgetorpeek)
  770. X */
  771. X    int
  772. Xins_mapbuf(str)
  773. X    char *str;
  774. X{
  775. X    register char *s;
  776. X    register int newlen;
  777. X
  778. X    newlen = maplen + strlen(str) + 1;
  779. X    if (newlen < 0)                /* string is getting too long */
  780. X    {
  781. X        emsg(e_toocompl);        /* also calls flush_buffers */
  782. X        setcursor();
  783. X        return -1;
  784. X    }
  785. X    s = alloc(newlen);
  786. X    if (s == NULL)
  787. X        return -1;
  788. X    strcpy(s, str);
  789. X    if (mapstr)
  790. X    {
  791. X        strcat(s, mapstr);
  792. X        free(mapstr);
  793. X    }
  794. X    mapstr = s;
  795. X    maplen = strlen(mapstr);
  796. X    return 0;
  797. X}
  798. X
  799. Xextern int arrow_used;        /* this is in edit.c */
  800. X
  801. X/*
  802. X * get a character: 1. from the stuffbuffer
  803. X *                    2. from the user
  804. X *
  805. X * KeyTyped is set to TRUE in the case the user typed the key.
  806. X * If advance is TRUE, we really get the character. Otherwise we just look
  807. X * whether there is a character available.
  808. X */
  809. X    static u_char
  810. Xvgetorpeek(advance)
  811. X    int        advance;
  812. X{
  813. X    register int    c;
  814. X    int                n = 0;        /* init for GCC */
  815. X    char            *str;
  816. X    int                len;
  817. X    struct mapblock *mp;
  818. X    int                mode = State;
  819. X    static int        nomapping = 0;        /* number of characters that should
  820. X                                            not be mapped */
  821. X    int                timedout = FALSE;    /* waited for more than 1 second
  822. X                                                for mapping to complete */
  823. X    int                mapdepth = 0;        /* check for recursive mapping */
  824. X
  825. X    if (mode == REPLACE || mode == CMDLINE)
  826. X        mode = INSERT;            /* treat replace mode just like insert mode */
  827. X    else if (mode == NORMAL_BUSY)
  828. X        mode = NORMAL;
  829. X
  830. X    start_stuff();
  831. X    do
  832. X    {
  833. X        c = read_stuff(advance);
  834. X        if (c != NUL)
  835. X            KeyTyped = FALSE;
  836. X        else
  837. X        {
  838. X            /*
  839. X             * Loop until we either find a matching mapped key, or we
  840. X             * are sure that it is not a mapped key.
  841. X             * We do this first for mapstr and then for typeahead.
  842. X             * If a mapped key sequence is found we go back to mapstr to
  843. X             * try re-mapping.
  844. X             */
  845. X            if (maplen)        /* first try mapstr */
  846. X            {
  847. X                str = mapstr;
  848. X                len = maplen;
  849. X            }
  850. X            else            /* no mapped chars, try typeahead[] */
  851. X            {
  852. X                str = typeahead;
  853. X                len = typelen;
  854. X            }
  855. X
  856. X            for (;;)        /* loop until we got a character */
  857. X            {
  858. X                breakcheck();                /* check for CTRL-C */
  859. X                if (got_int)
  860. X                {
  861. X                    typelen = 0;            /* flush all typeahead */
  862. X                    maplen = 0;
  863. X                    len = 0;
  864. X                }
  865. X                else if (len > 0)    /* see if we have a mapped key sequence */
  866. X                {
  867. X                    /*
  868. X                     * walk through the maplist until we find an
  869. X                     * entry that matches (if not timed out).
  870. X                     */
  871. X                    mp = NULL;
  872. X                    if (!timedout && (str != mapstr || (p_remap && nomapping == 0)))
  873. X                    {
  874. X                        for (mp = maplist.m_next; mp; mp = mp->m_next)
  875. X                        {
  876. X                            if (mp->m_mode != mode)
  877. X                                continue;
  878. X                            n = strlen(mp->m_keys);
  879. X                            if (!strncmp(mp->m_keys, str, (size_t)(n > len ? len : n)))
  880. X                                break;
  881. X                        }
  882. X                    }
  883. X                    if (mp == NULL || (str == mapstr && n > len))
  884. X                    {                                /* no match found */
  885. X                        c = str[0] & 255;
  886. X                        if (str == mapstr)
  887. X                            KeyTyped = FALSE;
  888. X                        else
  889. X                            KeyTyped = TRUE;
  890. X                        if (advance)
  891. X                        {
  892. X                            strncpy(&str[0], &str[1], (size_t)len);
  893. X                            if (str == mapstr)
  894. X                                --maplen;
  895. X                            else
  896. X                                --typelen;
  897. X                            if (nomapping)
  898. X                                --nomapping;
  899. X                        }
  900. X                        break;
  901. X                    }
  902. X                    if (n <= len)    /* complete match */
  903. X                    {
  904. X                            /* remove the mapped keys */
  905. X                        len -= n;
  906. X                        strncpy(&str[0], &str[n], (size_t)(len + 1));
  907. X                        if (str == mapstr)
  908. X                            maplen = len;
  909. X                        else
  910. X                            typelen = len;
  911. X
  912. X                        /*
  913. X                         * Put the replacement string in front of mapstr.
  914. X                         * The depth check catches ":map x y" and ":map y x".
  915. X                         */
  916. X                        if (++mapdepth == 1000)
  917. X                        {
  918. X                            emsg("recursive mapping");
  919. X                            setcursor();
  920. X                            maplen = 0;
  921. X                            c = -1;
  922. X                            break;
  923. X                        }
  924. X                        if (ins_mapbuf(mp->m_str) < 0)
  925. X                        {
  926. X                            c = -1;
  927. X                            break;
  928. X                        }
  929. X                        if (mp->m_noremap)
  930. X                            nomapping += strlen(mp->m_str);
  931. X                        str = mapstr;
  932. X                        len = maplen;
  933. X                        continue;
  934. X                    }
  935. X                }
  936. X                                            /* inchar() will reset got_int */
  937. X                c = inchar(!advance, len == 0 || !p_timeout);
  938. X                if (c <= NUL || !advance)    /* no character available or async */
  939. X                {
  940. X                    if (!advance)
  941. X                        break;
  942. X                    if (len)                /* timed out */
  943. X                    {
  944. X                        timedout = TRUE;
  945. X                        continue;
  946. X                    }
  947. X                }
  948. X                else
  949. X                {
  950. X                    typeahead[typelen++] = c;
  951. X                    updatescript(c);
  952. X                    if (Recording)
  953. X                        add_buff(&recordbuff, mkstr(c));
  954. X
  955. X                            /* do not sync in insert mode, unless cursor key has
  956. X                             * been used */
  957. X                    if (mode != INSERT || arrow_used)        
  958. X                        u_sync();
  959. X                }
  960. X                len = typelen;
  961. X                str = typeahead;
  962. X            }
  963. X        }
  964. X    } while (c < 0 || (advance && c == NUL));
  965. X                        /* if advance is FALSE don't loop on NULs */
  966. X
  967. X    return (u_char) c;
  968. X}
  969. X
  970. X    u_char
  971. Xvgetc()
  972. X{
  973. X    return (vgetorpeek(TRUE));
  974. X}
  975. X
  976. X    u_char
  977. Xvpeekc()
  978. X{
  979. X    return (vgetorpeek(FALSE));
  980. X}
  981. X
  982. X/*
  983. X * unmap[!] {lhs}            : remove key mapping for {lhs}
  984. X * map[!]                    : show all key mappings
  985. X * map[!] {lhs}                : show key mapping for {lhs}
  986. X * map[!] {lhs} {rhs}        : set key mapping for {lhs} to {rhs}
  987. X * noremap[!] {lhs} {rhs}    : same, but no remapping for {rhs}
  988. X *
  989. X * maptype == 1 for unmap command, 2 for noremap command.
  990. X * arg is pointer to any arguments.
  991. X * mode is INSERT if [!] is present.
  992. X * 
  993. X * Return 0 for success
  994. X *          1 for invalid arguments
  995. X *          2 for no match
  996. X *          3 for ambiguety
  997. X *          4 for out of mem
  998. X */
  999. X    int
  1000. Xdomap(maptype, keys, mode)
  1001. X    int        maptype;
  1002. X    char    *keys;
  1003. X    int        mode;
  1004. X{
  1005. X        struct mapblock        *mp, *mprev;
  1006. X        char                *arg;
  1007. X        char                *p;
  1008. X        int                    n = 0;            /* init for GCC */
  1009. X        int                    len = 0;        /* init for GCC */
  1010. X        char                *newstr;
  1011. X        int                    hasarg;
  1012. X
  1013. X/*
  1014. X * find end of keys and remove CTRL-Vs in it
  1015. X */
  1016. X        p = keys;
  1017. X        while (*p && *p != ' ' && *p != '\t')
  1018. X        {
  1019. X            if (*p == Ctrl('V') && p[1] != NUL)
  1020. X                strcpy(p, p + 1);            /* remove CTRL-V */
  1021. X            ++p;
  1022. X        }
  1023. X        if (*p != NUL)
  1024. X            *p++ = NUL;
  1025. X        skipspace(&p);
  1026. X        hasarg = (*p != NUL);
  1027. X        arg = p;
  1028. X/*
  1029. X * remove CTRL-Vs from argument
  1030. X */
  1031. X        while (*p)
  1032. X        {
  1033. X            if (*p == Ctrl('V') && p[1] != NUL)
  1034. X                strcpy(p, p + 1);            /* remove CTRL-V */
  1035. X            ++p;
  1036. X        }
  1037. X
  1038. X/*
  1039. X * check arguments and translate function keys
  1040. X */
  1041. X        if (*keys != NUL)
  1042. X        {
  1043. X                if (maptype == 1 && hasarg)            /* unmap has no arguments */
  1044. X                    return 1;
  1045. X                if (*keys == '#' && isdigit(*(keys + 1)))    /* function key */
  1046. X                {
  1047. X                    if (*++keys == '0')
  1048. X                        *(u_char *)keys = K_F10;
  1049. X                    else
  1050. X                        *keys += K_F1 - '1';
  1051. X                }
  1052. X                len = strlen(keys);
  1053. X                if (len > MAXMAPLEN)            /* maximum lenght of 10 chars */
  1054. X                    return 2;
  1055. X        }
  1056. X
  1057. X/*
  1058. X * Find an entry in the maplist that matches.
  1059. X */
  1060. X#ifdef AMIGA
  1061. X        if (*keys == NUL || (maptype != 1 && !hasarg))
  1062. X            settmode(0);                /* set cooked mode so output can be halted */
  1063. X#endif
  1064. X        for (mp = maplist.m_next, mprev = &maplist; mp; mprev = mp, mp = mp->m_next)
  1065. X        {
  1066. X            if (mp->m_mode != mode)
  1067. X                continue;
  1068. X            n = strlen(mp->m_keys);
  1069. X            if (*keys == NUL)
  1070. X                showmap(mp);
  1071. X            else if (!strncmp(mp->m_keys, keys, (size_t)(n < len ? n : len)))
  1072. X            {
  1073. X                if (maptype != 1 && !hasarg)
  1074. X                    showmap(mp);
  1075. X                else
  1076. X                    break;
  1077. X            }
  1078. X        }
  1079. X        if (*keys == NUL || (maptype != 1 && !hasarg))
  1080. X        {
  1081. X#ifdef AMIGA
  1082. X                settmode(1);
  1083. X#endif
  1084. X                wait_return(TRUE);
  1085. X                return 0;                /* listing finished */
  1086. X        }
  1087. X
  1088. X        if (mp == NULL)         /* new entry or nothing to remove */
  1089. X        {
  1090. X                if (maptype == 1)
  1091. X                        return 2;        /* no match */
  1092. X
  1093. X                /* allocate a new entry for the maplist */
  1094. X                mp = (struct mapblock *)alloc((unsigned)sizeof(struct mapblock));
  1095. X                if (mp == NULL)
  1096. X                        return 4;        /* no mem */
  1097. X                mp->m_keys = strsave(keys);
  1098. X                mp->m_str = strsave(arg);
  1099. X                if (mp->m_keys == NULL || mp->m_str == NULL)
  1100. X                {
  1101. X                        free(mp->m_keys);
  1102. X                        free(mp->m_str);
  1103. X                        free(mp);
  1104. X                        return 4;        /* no mem */
  1105. X                }
  1106. X                mp->m_noremap = maptype;
  1107. X
  1108. X                /* add the new entry in front of the maplist */
  1109. X                mp->m_next = maplist.m_next;
  1110. X                mp->m_mode = mode;
  1111. X                maplist.m_next = mp;
  1112. X                return 0;                /* added OK */
  1113. X        }
  1114. X        if (n != len)
  1115. X            return 3;                    /* ambigious */
  1116. X
  1117. X        if (maptype == 1)
  1118. X        {
  1119. X                free(mp->m_keys);
  1120. X                free(mp->m_str);
  1121. X                mprev->m_next = mp->m_next;
  1122. X                free(mp);
  1123. X                return 0;                /* removed OK */
  1124. X        }
  1125. X
  1126. X/*
  1127. X * replace existing entry
  1128. X */
  1129. X        newstr = strsave(arg);
  1130. X        if (newstr == NULL)
  1131. X                return 4;                /* no mem */
  1132. X        free(mp->m_str);
  1133. X        mp->m_str = newstr;
  1134. X        mp->m_noremap = maptype;
  1135. X
  1136. X        return 0;                        /* replaced OK */
  1137. X}
  1138. X
  1139. X    static void
  1140. Xshowmap(mp)
  1141. X    struct mapblock *mp;
  1142. X{
  1143. X    int len;
  1144. X
  1145. X    len = outtrans(mp->m_keys, -1);    /* get length of what we have written */
  1146. X    while (len < MAXMAPLEN)
  1147. X    {
  1148. X        outchar(' ');                /* padd with blanks */
  1149. X        ++len;
  1150. X    }
  1151. X    if (mp->m_noremap)
  1152. X        outchar('*');
  1153. X    else
  1154. X        outchar(' ');
  1155. X    outtrans(mp->m_str, -1);
  1156. X    outchar('\n');
  1157. X    flushbuf();
  1158. X}
  1159. X
  1160. X/*
  1161. X * Write map commands for the current mapping to an .exrc file.
  1162. X * Return 1 on error.
  1163. X */
  1164. X    int
  1165. Xmakemap(fd)
  1166. X    FILE *fd;
  1167. X{
  1168. X    struct mapblock *mp;
  1169. X
  1170. X    for (mp = maplist.m_next; mp; mp = mp->m_next)
  1171. X    {
  1172. X        if (fprintf(fd, "map%c %s %s\n", mp->m_mode == INSERT ? '!' : ' ',
  1173. X                                    mp->m_keys, mp->m_str) < 0)
  1174. X            return 1;
  1175. X    }
  1176. X    return 0;
  1177. X}
  1178. END_OF_FILE
  1179. if test 17483 -ne `wc -c <'vim/src/buffers.c'`; then
  1180.     echo shar: \"'vim/src/buffers.c'\" unpacked with wrong size!
  1181. fi
  1182. # end of 'vim/src/buffers.c'
  1183. fi
  1184. if test -f 'vim/src/fileio.c' -a "${1}" != "-c" ; then 
  1185.   echo shar: Will not clobber existing file \"'vim/src/fileio.c'\"
  1186. else
  1187. echo shar: Extracting \"'vim/src/fileio.c'\" \(17623 characters\)
  1188. sed "s/^X//" >'vim/src/fileio.c' <<'END_OF_FILE'
  1189. X/* vi:ts=4:sw=4
  1190. X *
  1191. X * VIM - Vi IMitation
  1192. X *
  1193. X * Code Contributions By:    Bram Moolenaar            mool@oce.nl
  1194. X *                            Tim Thompson            twitch!tjt
  1195. X *                            Tony Andrews            onecom!wldrdg!tony 
  1196. X *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  1197. X */
  1198. X
  1199. X/*
  1200. X * fileio.c: read from and write to a file
  1201. X */
  1202. X
  1203. X/*
  1204. X * special feature of this version: NUL characters in the file are
  1205. X * replaced by newline characters in memory. This allows us to edit
  1206. X * binary files!
  1207. X */
  1208. X
  1209. X#include "vim.h"
  1210. X#include "globals.h"
  1211. X#include "proto.h"
  1212. X#include "param.h"
  1213. X#include "fcntl.h"
  1214. X
  1215. X#ifdef LATTICE
  1216. X# include <proto/dos.h>        /* for Lock() and UnLock() */
  1217. X#endif
  1218. X
  1219. X#define BUFSIZE 4096
  1220. Xstatic void do_mlines __ARGS((void));
  1221. X
  1222. X    void
  1223. Xfilemess(name, s)
  1224. X    char        *name;
  1225. X    char        *s;
  1226. X{
  1227. X    smsg("\"%s\" %s", ((name == NULL) ? "" : name), s);
  1228. X}
  1229. X
  1230. X/*
  1231. X * Read lines from file 'fname' into the buffer after line 'from'.
  1232. X *
  1233. X * 1. We allocate blocks with m_blockalloc, as big as possible.
  1234. X * 2. Each block is filled with characters from the file with a single read().
  1235. X * 3. The lines are inserted in the buffer with appendline().
  1236. X *
  1237. X * (caller must check that fname != NULL)
  1238. X */
  1239. X    int
  1240. Xreadfile(fname, from, newfile)
  1241. X    char           *fname;
  1242. X    linenr_t        from;
  1243. X    int                newfile;
  1244. X{
  1245. X#ifdef UNIX
  1246. X    int                 fd = -1;
  1247. X#else
  1248. X    int                 fd;
  1249. X#endif
  1250. X    register u_char     c;
  1251. X    register linenr_t    lnum = from;
  1252. X    register u_char     *ptr = NULL;            /* pointer into read buffer */
  1253. X    register u_char        *buffer = NULL;            /* read buffer */
  1254. X    register long        size;
  1255. X    long                filesize;
  1256. X#define UNKNOWN        0x0fffffff                    /* file size is unknown */
  1257. X    linenr_t            linecnt = line_count;
  1258. X    int                    incomplete = FALSE;     /* was the last line incomplete? */
  1259. X    int                 error = 0;                /* read errors encountered */
  1260. X    long                linerest = 0;            /* remaining characters in line */
  1261. X    long                filerest;                /* remaining characters in file */
  1262. X
  1263. X    if (bufempty())        /* special case: buffer has no lines */
  1264. X        linecnt = 0;
  1265. X
  1266. X    if (
  1267. X#ifdef UNIX
  1268. X        !(getperm(fname) & 0200) ||                /* root's way to check RO */
  1269. X#endif
  1270. X        (fd = open(fname, O_RDWR)) == -1)        /* cannot open r/w */
  1271. X    {
  1272. X        if ((fd = open(fname, O_RDONLY)) == -1) /* cannot open at all */
  1273. X        {
  1274. X            if (newfile)
  1275. X                filemess(fname, "[New File]");
  1276. X
  1277. X#ifdef MSDOS        /* the screen may be messed up by the "insert disk
  1278. X                            in drive b: and hit return" message */
  1279. X            updateScreen(CLEAR);
  1280. X#endif
  1281. X            return TRUE;
  1282. X        }
  1283. X        if (newfile)                            /* set file readonly */
  1284. X            p_ro = TRUE;
  1285. X    }
  1286. X    else if (newfile && !readonlymode)        /* set file not readonly */
  1287. X        p_ro = FALSE;
  1288. X
  1289. X    if (
  1290. X#ifdef MSDOS
  1291. X    /* the CR characters disappear in read(), so the file lenght is wrong */
  1292. X        p_tx == TRUE ||
  1293. X#endif
  1294. X            (filesize = lseek(fd, 0L, 2)) < 0)    /* get length of file */
  1295. X        filesize = UNKNOWN;
  1296. X    lseek(fd, 0L, 0);
  1297. X
  1298. X    filemess(fname, "");
  1299. X
  1300. X    for (filerest = filesize; !error && !got_int && filerest != 0; breakcheck())
  1301. X    {
  1302. X        /*
  1303. X         * We allocate as much space for the file as we can get, plus
  1304. X         * space for the old line, one NUL in front and one NUL at the tail.
  1305. X         * The amount is limited by the fact that read() only can read
  1306. X         * upto max_unsigned characters.
  1307. X         * If we don't know the file size, just get one Kbyte.
  1308. X         */
  1309. X        if (filesize >= UNKNOWN)
  1310. X            size = 1024;
  1311. X        else if (filerest > 0xff00L)
  1312. X            size = 0xff00L;
  1313. X        else if (filerest < 10)
  1314. X            size = 10;
  1315. X        else
  1316. X            size = filerest;
  1317. X
  1318. X        for ( ; size >= 10; size /= 2)
  1319. X        {
  1320. X            if ((buffer = (u_char *)m_blockalloc((u_long)(size + linerest + 4), FALSE))
  1321. X                        != NULL)
  1322. X                break;
  1323. X        }
  1324. X        if (buffer == NULL)
  1325. X        {
  1326. X            emsg(e_outofmem);
  1327. X            error = 1;
  1328. X            break;
  1329. X        }
  1330. X        buffer[0] = NUL;    /* make sure there is a NUL in front of the first line */
  1331. X        ++buffer;
  1332. X        if (linerest)        /* copy characters from the previous buffer */
  1333. X        {
  1334. X            ptr -= linerest;
  1335. X            memmove((char *)buffer, (char *)ptr, linerest);
  1336. X            memset((char *)ptr, 1, linerest);    /* fill with non-NULs */
  1337. X            ptr[linerest - 1] = NUL;            /* add a NUL on the end */
  1338. X            free_line((char *)ptr);                /* free the space we don't use */
  1339. X        }
  1340. X        ptr = buffer + linerest;
  1341. X        
  1342. X        if ((size = (unsigned)read(fd, (char *)ptr, (size_t)size)) <= 0)
  1343. X        {
  1344. X            error = 2;
  1345. X            break;
  1346. X        }
  1347. X        if (filesize >= UNKNOWN)            /* if we don't know the file size */
  1348. X            filesize += size;                /* .. count the number of characters */
  1349. X        else                                /* .. otherwise */
  1350. X            filerest -= size;                /* .. compute the remaining length */
  1351. X
  1352. X        /*
  1353. X         * This loop is executed once for every character read.
  1354. X         * Keep it fast!
  1355. X         */
  1356. X        --ptr;
  1357. X        while (++ptr, --size >= 0)
  1358. X        {
  1359. X            if ((c = *ptr) != NUL && c != NL)    /* catch most common case */
  1360. X                continue;
  1361. X            if (c == NUL)
  1362. X                *ptr = NL;        /* NULs are replaced by newlines! */
  1363. X            else
  1364. X            {
  1365. X                *ptr = NUL;        /* end of line */
  1366. X                if (!appendline(lnum, (char *)buffer))
  1367. X                {
  1368. X                    error = 1;
  1369. X                    break;
  1370. X                }
  1371. X                ++lnum;
  1372. X                buffer = ptr + 1;
  1373. X            }
  1374. X        }
  1375. X        linerest = ptr - buffer;
  1376. X    }
  1377. X    if (error != 1 && linerest != 0)
  1378. X    {
  1379. X        /*
  1380. X         * If we get EOF in the middle of a line, note the fact and
  1381. X         * complete the line ourselves.
  1382. X         */
  1383. X        incomplete = TRUE;
  1384. X        *ptr = NUL;
  1385. X        if (!appendline(lnum, (char *)buffer))
  1386. X            error = 1;
  1387. X    }
  1388. X    if (error == 2 && filesize >= UNKNOWN)    /* no error, just EOF encountered */
  1389. X    {
  1390. X        filesize -= UNKNOWN;
  1391. X        error = 0;
  1392. X    }
  1393. X
  1394. X    close(fd);
  1395. X
  1396. X#ifdef MSDOS        /* the screen may be messed up by the "insert disk
  1397. X                            in drive b: and hit return" message */
  1398. X    updateScreen(CLEAR);
  1399. X#endif
  1400. X
  1401. X    if (got_int)
  1402. X    {
  1403. X        filemess(fname, e_interr);
  1404. X        return FALSE;            /* an interrupt isn't really an error */
  1405. X    }
  1406. X
  1407. X    linecnt = line_count - linecnt;
  1408. X    smsg("\"%s\" %s%s%s%ld line%s, %ld character%s",
  1409. X            fname,
  1410. X            p_ro ? "[readonly] " : "",
  1411. X            incomplete ? "[Incomplete last line] " : "",
  1412. X            error ? "[READ ERRORS] " : "",
  1413. X            (long)linecnt, plural((long)linecnt),
  1414. X            filesize, plural(filesize));
  1415. X
  1416. X    u_clearline();        /* cannot use "U" command after adding lines */
  1417. X
  1418. X    if (newfile)        /* edit a new file: read mode from lines */
  1419. X        do_mlines();
  1420. X    if (from < line_count)
  1421. X    {
  1422. X        Curpos.lnum = from + 1;    /* put cursor at first new line */
  1423. X        Curpos.col = 0;
  1424. X    }
  1425. X
  1426. X    return FALSE;
  1427. X}
  1428. X
  1429. X/*
  1430. X * writeit - write to file 'fname' lines 'start' through 'end'
  1431. X *
  1432. X * We do our own buffering here because fwrite() is so slow.
  1433. X *
  1434. X * If forceit is true, we don't care for errors when attempting backups (jw).
  1435. X * In case of an error everything possible is done to restore the original file.
  1436. X * But when forceit is TRUE, we risk loosing it.
  1437. X */
  1438. X    int
  1439. Xwriteit(fname, start, end, append, forceit)
  1440. X    char            *fname;
  1441. X    linenr_t        start, end;
  1442. X    int                append;
  1443. X    int                forceit;
  1444. X{
  1445. X    int                 fd;
  1446. X    char               *backup = NULL;
  1447. X    register char       *s;
  1448. X    register u_char       *ptr;
  1449. X    register u_char        c;
  1450. X    register int        len;
  1451. X    register linenr_t    lnum;
  1452. X    long                nchars;
  1453. X    char                *errmsg = NULL;
  1454. X    char                *buffer;
  1455. X    long                 perm = -1;            /* file permissions */
  1456. X    int                    retval = TRUE;
  1457. X    int                    newfile = FALSE;    /* TRUE if file does not exist yet */
  1458. X#ifdef UNIX
  1459. X    struct stat            old;
  1460. X    int                    made_writable = FALSE;    /* 'w' bit has been set */
  1461. X#endif
  1462. X#ifdef AMIGA
  1463. X    BPTR                flock;
  1464. X#endif
  1465. X
  1466. X    if (fname == NULL || *fname == NUL)        /* safety check */
  1467. X        return FALSE;
  1468. X
  1469. X    /*
  1470. X     * Disallow writing from .exrc and .vimrc in current directory for
  1471. X     * security reasons.
  1472. X     */
  1473. X    if (secure)
  1474. X    {
  1475. X        secure = 2;
  1476. X        emsg(e_curdir);
  1477. X        return FALSE;
  1478. X    }
  1479. X
  1480. X    filemess(fname, "");        /* show that we are busy */
  1481. X
  1482. X    buffer = alloc(BUFSIZE);
  1483. X    if (buffer == NULL)
  1484. X        return FALSE;
  1485. X
  1486. X#ifdef UNIX
  1487. X        /* get information about original file (if there is one) */
  1488. X    old.st_dev = old.st_ino = 0;
  1489. X    if (stat(fname, &old))
  1490. X        newfile = TRUE;
  1491. X    else
  1492. X        perm = old.st_mode;
  1493. X/*
  1494. X * If we are not appending, the file exists, and the 'writebackup' or
  1495. X * 'backup' option is set, try to make a backup copy of the file.
  1496. X */
  1497. X    if (!append && perm >= 0 && (p_wb || p_bk) &&
  1498. X                    (fd = open(fname, O_RDONLY)) >= 0)
  1499. X    {
  1500. X        int                bfd, buflen, wlen;
  1501. X        char            buf[BUFSIZE + 1], *wp;
  1502. X        int                some_error = FALSE;
  1503. X        struct stat        new;
  1504. X
  1505. X        new.st_dev = new.st_ino = 0;
  1506. X
  1507. X        /*
  1508. X         * Unix semantics has it, that we may have a writable file, 
  1509. X         * that cannot be recreated with a simple open(..., O_CREATE, ) e.g:
  1510. X         *  - the directory is not writable, 
  1511. X         *  - the file may be a symbolic link, 
  1512. X         *  - the file may belong to another user/group, etc.
  1513. X         *
  1514. X         * For these reasons, the existing writable file must be truncated and
  1515. X         * reused. Creation of a backup COPY will be attempted.
  1516. X         */
  1517. X        if ((backup = modname(fname, ".bak")) == NULL)
  1518. X        {
  1519. X            some_error = TRUE;
  1520. X            goto nobackup;
  1521. X        }            
  1522. X        stat(backup, &new);
  1523. X        if (new.st_dev == old.st_dev && new.st_ino == old.st_ino)
  1524. X        {
  1525. X            /*
  1526. X             * may happen when modname gave the same file back.
  1527. X             * E.g. silly link, or filename-length reached.
  1528. X             * If we don't check here, we either ruin the file when
  1529. X             * copying or erase it after writing. jw.
  1530. X             */
  1531. X            errmsg = "Invalid backup file";
  1532. X            free(backup);
  1533. X            backup = NULL;    /* there is no backup file to delete */
  1534. X            goto nobackup;
  1535. X        }
  1536. X        remove(backup);        /* remove old backup, if present */
  1537. X        if ((bfd = open(backup, O_WRONLY | O_CREAT, 0666)) < 0)
  1538. X        {
  1539. X            char *home;
  1540. X
  1541. X            /* 
  1542. X             * oops, no write/create permission here?
  1543. X             * try again in p_bdir directory. 
  1544. X             */
  1545. X            for (wp = fname + strlen(fname); wp >= fname; wp--)
  1546. X                if (*wp == '/')
  1547. X                    break;
  1548. X            ++wp;
  1549. X            if (p_bdir[0] == '~' && p_bdir[1] == '/' &&
  1550. X                            (home = (char *)vimgetenv("HOME")) != NULL)
  1551. X                sprintf(buf, "%s/%s/%s", home, p_bdir + 2, wp);
  1552. X            else
  1553. X                sprintf(buf, "%s/%s", p_bdir, wp);
  1554. X            free(backup);
  1555. X            if ((backup = modname(buf, ".bak")) == NULL)
  1556. X            {
  1557. X                some_error = TRUE;
  1558. X                goto nobackup;
  1559. X            }
  1560. X            stat(backup, &new);
  1561. X            if (new.st_dev == old.st_dev && new.st_ino == old.st_ino)
  1562. X            {
  1563. X                errmsg = "Invalid backup file";
  1564. X                free(backup);
  1565. X                backup = NULL;    /* there is no backup file to delete */
  1566. X                goto nobackup;
  1567. X            }
  1568. X            remove(backup);
  1569. X            if ((bfd = open(backup, O_WRONLY | O_CREAT, 0666)) < 0)
  1570. X            {
  1571. X                free(backup);
  1572. X                backup = NULL;    /* there is no backup file to delete */
  1573. X                errmsg = "Can't make backup file";
  1574. X                goto nobackup;
  1575. X            }
  1576. X        }
  1577. X        /* set file protection same as original file, but strip s-bit */
  1578. X        setperm(backup, perm & 0777);
  1579. X
  1580. X        /* copy the file. */
  1581. X        while ((buflen = read(fd, buf, BUFSIZE)) > 0)
  1582. X        {
  1583. X            wp = buf;
  1584. X            do
  1585. X            {
  1586. X                if ((wlen = write(bfd, wp, buflen)) <= 0)
  1587. X                {
  1588. X                    errmsg = "Can't write to backup file";
  1589. X                    goto writeerr;
  1590. X                }
  1591. X                wp += wlen;
  1592. X                buflen -= wlen;
  1593. X            }
  1594. X            while (buflen > 0);
  1595. X        }
  1596. Xwriteerr:
  1597. X        close(bfd);
  1598. X        if (buflen < 0)
  1599. X            errmsg = "Can't read file for backup";
  1600. Xnobackup:
  1601. X        close(fd);
  1602. X    /* ignore errors when forceit is TRUE */
  1603. X        if ((some_error || errmsg) && !forceit)
  1604. X        {
  1605. X            retval = FALSE;
  1606. X            goto fail;
  1607. X        }
  1608. X        errmsg = NULL;
  1609. X    }
  1610. X        /* if forceit and the file was read-only: make it writable */
  1611. X    if (forceit && (old.st_uid == getuid()) && perm >= 0 && !(perm & 0200))
  1612. X     {
  1613. X        perm |= 0200;    
  1614. X        made_writable = TRUE;
  1615. X        setperm(fname, perm);
  1616. X     }
  1617. X#else /* UNIX */
  1618. X
  1619. X/*
  1620. X * If we are not appending, the file exists, and the 'writebackup' or
  1621. X * 'backup' option is set, make a backup.
  1622. X * Do not make any backup, if "writebackup" and "backup" are 
  1623. X * both switched off. This helps when editing large files on
  1624. X * almost-full disks. (jw)
  1625. X */
  1626. X    perm = getperm(fname);
  1627. X    if (perm < 0)
  1628. X        newfile = TRUE;
  1629. X    if (!append && perm >= 0 && (p_wb || p_bk))
  1630. X    {
  1631. X        /*
  1632. X         * Form the backup file name - change path/fo.o.h to path/fo.o.h.bak
  1633. X         */
  1634. X        backup = modname(fname, ".bak");
  1635. X        if (backup == NULL)
  1636. X        {
  1637. X            if (!forceit)
  1638. X                goto fail;
  1639. X        }
  1640. X        else
  1641. X        {
  1642. X            /*
  1643. X             * Delete any existing backup and move the current version to the backup.
  1644. X             * For safety, we don't remove the backup until the write has finished
  1645. X             * successfully. And if the 'backup' option is set, leave it around.
  1646. X             */
  1647. X#ifdef AMIGA
  1648. X            /*
  1649. X             * With MSDOS-compatible filesystems (crossdos, messydos) it is
  1650. X             * possible that the name of the backup file is the same as the
  1651. X             * original file. To avoid the chance of accidently deleting the
  1652. X             * original file (horror!) we lock it during the remove.
  1653. X             * This should not happen with ":w", because startscript() should
  1654. X             * detect this problem and set thisfile_sn, causing modname to
  1655. X             * return a correct ".bak" filename. This problem does exist with
  1656. X             * ":w filename", but then the original file will be somewhere else
  1657. X             * so the backup isn't really important. If autoscripting is off
  1658. X             * the rename may fail.
  1659. X             */
  1660. X            flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
  1661. X#endif
  1662. X            remove(backup);
  1663. X#ifdef AMIGA
  1664. X            if (flock)
  1665. X                UnLock(flock);
  1666. X#endif
  1667. X            len = rename(fname, backup);
  1668. X            if (len != 0)
  1669. X            {
  1670. X                if (forceit)
  1671. X                {
  1672. X                    free(backup);    /* don't do the rename below */
  1673. X                    backup = NULL;
  1674. X                }
  1675. X                else
  1676. X                {
  1677. X                    errmsg = "Can't make backup file";
  1678. X                    goto fail;
  1679. X                }
  1680. X            }
  1681. X        }
  1682. X    }
  1683. X#endif /* UNIX */
  1684. X
  1685. X        /* 
  1686. X         * We may try to open the file twice: If we can't write to the
  1687. X         * file and forceit is TRUE we delete the existing file and try to create
  1688. X         * a new one. If this still fails we may have lost the original file!
  1689. X         * (this may happen when the user reached his quotum for number of files).
  1690. X         */
  1691. X    while ((fd = open(fname, O_WRONLY | (append ? O_APPEND : (O_CREAT | O_TRUNC)), 0666)) < 0)
  1692. X     {
  1693. X        /*
  1694. X         * A forced write will try to create a new file if the old one is
  1695. X         * still readonly. This may also happen when the directory is
  1696. X         * read-only. In that case the remove() will fail.
  1697. X         */
  1698. X        if (!errmsg)
  1699. X        {
  1700. X            errmsg = "Can't open file for writing";
  1701. X            if (forceit)
  1702. X            {
  1703. X#ifdef UNIX
  1704. X                /* we write to the file, thus it should be marked
  1705. X                                                    writable after all */
  1706. X                perm |= 0200;        
  1707. X                made_writable = TRUE;
  1708. X                if (old.st_uid != getuid() || old.st_gid != getgid())
  1709. X                    perm &= 0777;
  1710. X#endif /* UNIX */
  1711. X                remove(fname);
  1712. X                continue;
  1713. X            }
  1714. X        }
  1715. X/*
  1716. X * If we failed to open the file, we don't need a backup. Throw it away.
  1717. X * If we moved or removed the original file try to put the backup in its place.
  1718. X */
  1719. X         if (backup)
  1720. X        {
  1721. X#ifdef UNIX
  1722. X            struct stat st;
  1723. X
  1724. X            /*
  1725. X             * There is a small chance that we removed the original, try
  1726. X             * to move the copy in its place.
  1727. X             * This won't work if the backup is in another file system!
  1728. X             * In that case we leave the copy around.
  1729. X             */
  1730. X            if (stat(fname, &st) < 0)    /* file does not exist */
  1731. X                rename(backup, fname);    /* put the copy in its place */
  1732. X            if (stat(fname, &st) >= 0)    /* original file does exist */
  1733. X                remove(backup);            /* throw away the copy */
  1734. X#else
  1735. X             rename(backup, fname);    /* try to put the original file back */
  1736. X#endif
  1737. X        }
  1738. X         goto fail;
  1739. X     }
  1740. X    errmsg = NULL;
  1741. X
  1742. X    len = 0;
  1743. X    s = buffer;
  1744. X    nchars = 0;
  1745. X    for (lnum = start; lnum <= end; ++lnum)
  1746. X    {
  1747. X        /*
  1748. X         * The next loop is done once for each character written.
  1749. X         * Keep it fast!
  1750. X         */
  1751. X        ptr = (u_char *)nr2ptr(lnum) - 1;
  1752. X        while ((c = *++ptr) != NUL)
  1753. X        {
  1754. X            if (c == NL)
  1755. X                *s = NUL;        /* replace newlines with NULs */
  1756. X            else
  1757. X                *s = c;
  1758. X            ++s;
  1759. X            if (++len != BUFSIZE)
  1760. X                continue;
  1761. X            if (write(fd, buffer, (size_t)BUFSIZE) == -1)
  1762. X            {
  1763. X                end = 0;                /* write error: break loop */
  1764. X                break;
  1765. X            }
  1766. X            nchars += BUFSIZE;
  1767. X            s = buffer;
  1768. X            len = 0;
  1769. X        }
  1770. X        *s = NL;
  1771. X        ++s;
  1772. X        if (++len == BUFSIZE)
  1773. X        {
  1774. X            if (write(fd, buffer, (size_t)BUFSIZE) == -1)
  1775. X                end = 0;                /* write error: break loop */
  1776. X            nchars += BUFSIZE;
  1777. X            s = buffer;
  1778. X            len = 0;
  1779. X        }
  1780. X    }
  1781. X    if (len)
  1782. X    {
  1783. X        if (write(fd, buffer, (size_t)len) == -1)
  1784. X            end = 0;                /* write error */
  1785. X        nchars += len;
  1786. X    }
  1787. X
  1788. X    if (close(fd) != 0)
  1789. X    {
  1790. X        errmsg = "Close failed";
  1791. X        goto fail;
  1792. X    }
  1793. X#ifdef UNIX
  1794. X    if (made_writable)
  1795. X        perm &= ~0200;            /* reset 'w' bit for security reasons */
  1796. X#endif
  1797. X    if (perm >= 0)
  1798. X        setperm(fname, perm);    /* set permissions of new file same as old file */
  1799. X
  1800. X    if (end == 0)
  1801. X    {
  1802. X        errmsg = "write error (file system full?)";
  1803. X        goto fail;
  1804. X    }
  1805. X
  1806. X#ifdef MSDOS        /* the screen may be messed up by the "insert disk
  1807. X                            in drive b: and hit return" message */
  1808. X    updateScreen(CLEAR);
  1809. X#endif
  1810. X
  1811. X    lnum -= start;        /* compute number of written lines */
  1812. X    smsg("\"%s\"%s %ld line%s, %ld character%s",
  1813. X            fname,
  1814. X            newfile ? " [New File]" : " ",
  1815. X            (long)lnum, plural((long)lnum),
  1816. X            nchars, plural(nchars));
  1817. X    if (start == 1 && end == line_count)        /* when written everything */
  1818. X    {
  1819. X        UNCHANGED;
  1820. X        startscript();        /* re-start auto script file */
  1821. X    }
  1822. X
  1823. X    /*
  1824. X     * Remove the backup unless 'backup' option is set
  1825. X     */
  1826. X    if (!p_bk && backup != NULL && remove(backup) != 0)
  1827. X        emsg("Can't delete backup file");
  1828. X    
  1829. X    goto nofail;
  1830. X
  1831. Xfail:
  1832. X#ifdef MSDOS        /* the screen may be messed up by the "insert disk
  1833. X                            in drive b: and hit return" message */
  1834. X    updateScreen(CLEAR);
  1835. X#endif
  1836. Xnofail:
  1837. X
  1838. X    free((char *) backup);
  1839. X    free(buffer);
  1840. X
  1841. X    if (errmsg != NULL)
  1842. X    {
  1843. X        filemess(fname, errmsg);
  1844. X        retval = FALSE;
  1845. X    }
  1846. X    return retval;
  1847. X}
  1848. X
  1849. X/*
  1850. X * do_mlines() - process mode lines for the current file
  1851. X *
  1852. X * Returns immediately if the "ml" parameter isn't set.
  1853. X */
  1854. Xstatic void     chk_mline __ARGS((linenr_t));
  1855. X
  1856. X    static void
  1857. Xdo_mlines()
  1858. X{
  1859. X        linenr_t        lnum;
  1860. X        int             nmlines;
  1861. X
  1862. X        if ((nmlines = p_ml) == 0)
  1863. X                return;
  1864. X
  1865. X        for (lnum = 1; lnum <= line_count && lnum <= nmlines; ++lnum)
  1866. X                chk_mline(lnum);
  1867. X
  1868. X        for (lnum = line_count; lnum > 0 && lnum > nmlines &&
  1869. X                                lnum > line_count - nmlines; --lnum)
  1870. X                chk_mline(lnum);
  1871. X}
  1872. X
  1873. X/*
  1874. X * chk_mline() - check a single line for a mode string
  1875. X */
  1876. X    static void
  1877. Xchk_mline(lnum)
  1878. X    linenr_t lnum;
  1879. X{
  1880. X    register char    *s;
  1881. X    register char    *e;
  1882. X    char            *cs;            /* local copy of any modeline found */
  1883. X    char            prev;
  1884. X    int                end;
  1885. X
  1886. X    prev = ' ';
  1887. X    for (s = nr2ptr(lnum); *s != NUL; ++s)
  1888. X    {
  1889. X        if (isspace(prev) && (strncmp(s, "vi:", (size_t)3) == 0 || strncmp(s, "ex:", (size_t)3) == 0))
  1890. X        {
  1891. X            s += 3;
  1892. X            end = FALSE;
  1893. X            s = cs = strsave(s);
  1894. X            if (cs == NULL)
  1895. X                break;
  1896. X            while (end == FALSE)
  1897. X            {
  1898. X                while (*s == ' ' || *s == TAB)
  1899. X                    ++s;
  1900. X                if (*s == NUL)
  1901. X                    break;
  1902. X                for (e = s; *e != ':' && *e != NUL; ++e)
  1903. X                    ;
  1904. X                if (*e == NUL)
  1905. X                    end = TRUE;
  1906. X                *e = NUL;
  1907. X                doset(s);
  1908. X                s = e + 1;
  1909. X            }
  1910. X            free(cs);
  1911. X            break;
  1912. X        }
  1913. X        prev = *s;
  1914. X    }
  1915. X}
  1916. END_OF_FILE
  1917. if test 17623 -ne `wc -c <'vim/src/fileio.c'`; then
  1918.     echo shar: \"'vim/src/fileio.c'\" unpacked with wrong size!
  1919. fi
  1920. # end of 'vim/src/fileio.c'
  1921. fi
  1922. echo shar: End of archive 9 \(of 23\).
  1923. cp /dev/null ark9isdone
  1924. MISSING=""
  1925. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
  1926.     if test ! -f ark${I}isdone ; then
  1927.     MISSING="${MISSING} ${I}"
  1928.     fi
  1929. done
  1930. if test "${MISSING}" = "" ; then
  1931.     echo You have unpacked all 23 archives.
  1932.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1933. else
  1934.     echo You still need to unpack the following archives:
  1935.     echo "        " ${MISSING}
  1936. fi
  1937. ##  End of shell archive.
  1938. exit 0
  1939. -------------8<----------------8<----------------8<---------------8<--------
  1940. Bram Moolenaar                             | DISCLAIMER:  This  note  does  not
  1941. Oce Nederland B.V., Research & Development | necessarily represent the position
  1942. p.o. box 101, 5900 MA  Venlo               | of  Oce-Nederland  B.V.  Therefore
  1943. The Netherlands        phone +31 77 594077 | no liability or responsibility for
  1944. UUCP: mool@oce.nl        fax +31 77 595450 | whatever will be accepted.
  1945.  
  1946. exit 0 # Just in case...
  1947.