home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / alt / sources / 2588 < prev    next >
Encoding:
Text File  |  1992-11-20  |  56.0 KB  |  2,313 lines

  1. Newsgroups: alt.sources
  2. Path: sparky!uunet!paladin.american.edu!darwin.sura.net!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!eff!world!jhallen
  3. From: jhallen@world.std.com (Joseph H Allen)
  4. Subject: JOE 1.0.5 Part 2 of 10
  5. Message-ID: <By2MFz.Krt@world.std.com>
  6. Organization: The World Public Access UNIX, Brookline, MA
  7. Date: Sat, 21 Nov 1992 14:47:58 GMT
  8. Lines: 2303
  9.  
  10. Submitted-by: jhallen@world.std.com
  11. Archive-name: joe1.0.5part2
  12.  
  13. /* Fast block move/copy subroutines
  14. X   Copyright (C) 1992 Joseph H. Allen
  15. X
  16. This file is part of JOE (Joe's Own Editor)
  17. X
  18. JOE is free software; you can redistribute it and/or modify it under the 
  19. terms of the GNU General Public License as published by the Free Software 
  20. Foundation; either version 1, or (at your option) any later version.  
  21. X
  22. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  23. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  24. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  25. details.  
  26. X
  27. You should have received a copy of the GNU General Public License along with 
  28. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  29. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  30. X
  31. X
  32. /* Take a look at the configuration information in types.h */
  33. /* This module requires that AUTOINC, ALIGNED, ISIZ, SHFT and BITS be defined
  34. X * correctly
  35. X */
  36. #include "blocks.h"
  37. X
  38. /* Set 'sz' 'int's beginning at 'd' to the value 'c' */
  39. /* Returns address of block.  Does nothing if 'sz' equals zero */
  40. X
  41. int *msetI(d,c,sz)
  42. register int *d, c;
  43. register int sz;
  44. {
  45. int *orgd=d;
  46. while(sz>=16)
  47. X {
  48. #ifdef AUTOINC
  49. X *d++=c; *d++=c; *d++=c; *d++=c; *d++=c; *d++=c; *d++=c; *d++=c;
  50. X *d++=c; *d++=c; *d++=c; *d++=c; *d++=c; *d++=c; *d++=c; *d++=c;
  51. #else
  52. X d[0]=c; d[1]=c; d[2]=c; d[3]=c; d[4]=c; d[5]=c; d[6]=c; d[7]=c;
  53. X d[8]=c; d[9]=c; d[10]=c; d[11]=c; d[12]=c; d[13]=c; d[14]=c; d[15]=c;
  54. X d+=16;
  55. #endif
  56. X sz-=16;
  57. X }
  58. switch(sz)
  59. X {
  60. #ifdef AUTOINC
  61. case 15: *d++=c;
  62. case 14: *d++=c;
  63. case 13: *d++=c;
  64. case 12: *d++=c;
  65. case 11: *d++=c;
  66. case 10: *d++=c;
  67. case 9: *d++=c;
  68. case 8: *d++=c;
  69. case 7: *d++=c;
  70. case 6: *d++=c;
  71. case 5: *d++=c;
  72. case 4: *d++=c;
  73. case 3: *d++=c;
  74. case 2: *d++=c;
  75. case 1: *d++=c;
  76. #else
  77. case 15: d[14]=c;
  78. case 14: d[13]=c;
  79. case 13: d[12]=c;
  80. case 12: d[11]=c;
  81. case 11: d[10]=c;
  82. case 10: d[9]=c;
  83. case 9: d[8]=c;
  84. case 8: d[7]=c;
  85. case 7: d[6]=c;
  86. case 6: d[5]=c;
  87. case 5: d[4]=c;
  88. case 4: d[3]=c;
  89. case 3: d[2]=c;
  90. case 2: d[1]=c;
  91. case 1: d[0]=c;
  92. #endif
  93. case 0:;
  94. X }
  95. return orgd;
  96. }
  97. X
  98. /* Set 'sz' 'char's beginning at 'd' to the value 'c' */
  99. /* Returns address of block.  Does nothing if 'sz' equals zero */
  100. X
  101. char *mset(d,c,sz)
  102. register char *d, c;
  103. register int sz;
  104. {
  105. char *orgd=d;
  106. if(sz<16)
  107. X switch(sz)
  108. X  {
  109. #ifdef AUTOINC
  110. X  case 15: *d++=c;
  111. X  case 14: *d++=c;
  112. X  case 13: *d++=c;
  113. X  case 12: *d++=c;
  114. X  case 11: *d++=c;
  115. X  case 10: *d++=c;
  116. X  case 9: *d++=c;
  117. X  case 8: *d++=c;
  118. X  case 7: *d++=c;
  119. X  case 6: *d++=c;
  120. X  case 5: *d++=c;
  121. X  case 4: *d++=c;
  122. X  case 3: *d++=c;
  123. X  case 2: *d++=c;
  124. X  case 1: *d++=c;
  125. #else
  126. X  case 15: d[14]=c;
  127. X  case 14: d[13]=c;
  128. X  case 13: d[12]=c;
  129. X  case 12: d[11]=c;
  130. X  case 11: d[10]=c;
  131. X  case 10: d[9]=c;
  132. X  case 9: d[8]=c;
  133. X  case 8: d[7]=c;
  134. X  case 7: d[6]=c;
  135. X  case 6: d[5]=c;
  136. X  case 5: d[4]=c;
  137. X  case 4: d[3]=c;
  138. X  case 3: d[2]=c;
  139. X  case 2: d[1]=c;
  140. X  case 1: d[0]=c;
  141. #endif
  142. X  case 0:;
  143. X  }
  144. else
  145. X {
  146. X int z=ISIZ-((int)d&(ISIZ-1));
  147. X if(z!=ISIZ)
  148. X  switch(z)
  149. X   {
  150. #ifdef AUTOINC
  151. X  case 7: *d++=c;
  152. X  case 6: *d++=c;
  153. X  case 5: *d++=c;
  154. X  case 4: *d++=c;
  155. X  case 3: *d++=c;
  156. X  case 2: *d++=c;
  157. X  case 1: *d++=c;
  158. X  case 0:;
  159. #else
  160. X  case 7: d[6]=c;
  161. X  case 6: d[5]=c;
  162. X  case 5: d[4]=c;
  163. X  case 4: d[3]=c;
  164. X  case 3: d[2]=c;
  165. X  case 2: d[1]=c;
  166. X  case 1: d[0]=c;
  167. X  case 0:;
  168. X          d+=z;
  169. #endif
  170. X   sz-=z;
  171. X   }
  172. X msetI(d,
  173. #if ISIZ>=8
  174. X (c<<(BITS*7))+(c<<(BITS*6))+(c<<(BITS*5))+(c<<(BITS*4))+
  175. #endif
  176. #if ISIZ>=4
  177. X (c<<(BITS*3))+(c<<(BITS*2))+
  178. #endif
  179. #if ISIZ>=2
  180. X (c<<BITS)+
  181. #endif
  182. X c,sz>>SHFT);
  183. X d+=sz&~(ISIZ-1);
  184. X switch(sz&(ISIZ-1))
  185. X  {
  186. #ifdef AUTOINC
  187. X case 7: *d++=c;
  188. X case 6: *d++=c;
  189. X case 5: *d++=c;
  190. X case 4: *d++=c;
  191. X case 3: *d++=c;
  192. X case 2: *d++=c;
  193. X case 1: *d++=c;
  194. #else
  195. X case 7: d[6]=c;
  196. X case 6: d[5]=c;
  197. X case 5: d[4]=c;
  198. X case 4: d[3]=c;
  199. X case 3: d[2]=c;
  200. X case 2: d[1]=c;
  201. X case 1: d[0]=c;
  202. #endif
  203. X case 0:;
  204. X  }
  205. X }
  206. return orgd;
  207. }
  208. X
  209. /* Copy a block of integers */
  210. /* Copy from highest address to lowest */
  211. X
  212. static int *mbkwdI(d,s,sz)
  213. register int *d, *s;
  214. register int sz;
  215. {
  216. if(d==s) return d;
  217. d+=sz; s+=sz;
  218. while(sz>=16)
  219. X {
  220. #ifdef AUTOINC
  221. X *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s; 
  222. X *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s; 
  223. X *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s;
  224. #else
  225. X d-=16; s-=16;
  226. X d[15]=s[15]; d[14]=s[14]; d[13]=s[13]; d[12]=s[12]; d[11]=s[11]; d[10]=s[10];
  227. X d[9]=s[9]; d[8]=s[8]; d[7]=s[7]; d[6]=s[6]; d[5]=s[5]; d[4]=s[4]; d[3]=s[3];
  228. X d[2]=s[2]; d[1]=s[1]; d[0]=s[0];
  229. #endif
  230. X sz-=16;
  231. X }
  232. #ifndef AUTOINC
  233. X d-=sz; s-=sz;
  234. #endif
  235. switch(sz)
  236. X {
  237. #ifdef AUTOINC
  238. X case 15: *--d= *--s;
  239. X case 14: *--d= *--s;
  240. X case 13: *--d= *--s;
  241. X case 12: *--d= *--s;
  242. X case 11: *--d= *--s;
  243. X case 10: *--d= *--s;
  244. X case 9: *--d= *--s;
  245. X case 8: *--d= *--s;
  246. X case 7: *--d= *--s;
  247. X case 6: *--d= *--s;
  248. X case 5: *--d= *--s;
  249. X case 4: *--d= *--s;
  250. X case 3: *--d= *--s;
  251. X case 2: *--d= *--s;
  252. X case 1: *--d= *--s;
  253. #else
  254. X case 15: d[14]=s[14];
  255. X case 14: d[13]=s[13];
  256. X case 13: d[12]=s[12];
  257. X case 12: d[11]=s[11];
  258. X case 11: d[10]=s[10];
  259. X case 10: d[9]=s[9];
  260. X case 9: d[8]=s[8];
  261. X case 8: d[7]=s[7];
  262. X case 7: d[6]=s[6];
  263. X case 6: d[5]=s[5];
  264. X case 5: d[4]=s[4];
  265. X case 4: d[3]=s[3];
  266. X case 3: d[2]=s[2];
  267. X case 2: d[1]=s[1];
  268. X case 1: d[0]=s[0];
  269. #endif
  270. X case 0:;
  271. X }
  272. return d;
  273. }
  274. X
  275. /* Copy a block of 'int's.  Copy from lowest address to highest */
  276. X
  277. static int *mfwrdI(d,s,sz)
  278. register int *d, *s;
  279. register int sz;
  280. {
  281. int *od=d;
  282. if(s==d) return d;
  283. while(sz>=16)
  284. X {
  285. #ifdef AUTOINC
  286. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  287. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  288. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  289. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  290. #else
  291. X d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; d[4]=s[4]; d[5]=s[5]; d[6]=s[6];
  292. X d[7]=s[7]; d[8]=s[8]; d[9]=s[9]; d[10]=s[10]; d[11]=s[11]; d[12]=s[12];
  293. X d[13]=s[13]; d[14]=s[14]; d[15]=s[15];
  294. X s+=16; d+=16;
  295. #endif
  296. X sz-=16;
  297. X }
  298. #ifndef AUTOINC
  299. s-=15-sz; d-=15-sz;
  300. #endif
  301. switch(sz)
  302. X {
  303. #ifdef AUTOINC
  304. X case 15: *d++= *s++;
  305. X case 14: *d++= *s++;
  306. X case 13: *d++= *s++;
  307. X case 12: *d++= *s++;
  308. X case 11: *d++= *s++;
  309. X case 10: *d++= *s++;
  310. X case 9: *d++= *s++;
  311. X case 8: *d++= *s++;
  312. X case 7: *d++= *s++;
  313. X case 6: *d++= *s++;
  314. X case 5: *d++= *s++;
  315. X case 4: *d++= *s++;
  316. X case 3: *d++= *s++;
  317. X case 2: *d++= *s++;
  318. X case 1: *d++= *s++;
  319. #else
  320. X case 15: d[0]=s[0];
  321. X case 14: d[1]=s[1];
  322. X case 13: d[2]=s[2];
  323. X case 12: d[3]=s[3];
  324. X case 11: d[4]=s[4];
  325. X case 10: d[5]=s[5];
  326. X case 9: d[6]=s[6];
  327. X case 8: d[7]=s[7];
  328. X case 7: d[8]=s[8];
  329. X case 6: d[9]=s[9];
  330. X case 5: d[10]=s[10];
  331. X case 4: d[11]=s[11];
  332. X case 3: d[12]=s[12];
  333. X case 2: d[13]=s[13];
  334. X case 1: d[14]=s[14];
  335. #endif
  336. X case 0:;
  337. X }
  338. return od;
  339. }
  340. X
  341. /* Copy the block of 'sz' bytes beginning at 's' to 'd'.  If 'sz' is zero or
  342. X * if 's'=='d', nothing happens.  The bytes at the highest address ('s'+'sz'-1)
  343. X * are copied before the ones at the lowest ('s') are.
  344. X */ 
  345. X
  346. char *mbkwd(d,s,sz)
  347. register char *d, *s;
  348. register int sz;
  349. {
  350. if(s==d) return d;
  351. s+=sz; d+=sz;
  352. #ifdef ALIGNED
  353. if( sz>=16 )
  354. #else
  355. if( ((int)s&(ISIZ-1))==((int)d&(ISIZ-1)) && sz>=16)
  356. #endif
  357. X {
  358. X int z=((int)s&(ISIZ-1));
  359. #ifndef AUTOINC
  360. X s-=z; d-=z;
  361. #endif
  362. X switch(z)
  363. X  {
  364. #ifdef AUTOINC
  365. X  case 7: *--d= *--s;
  366. X  case 6: *--d= *--s;
  367. X  case 5: *--d= *--s;
  368. X  case 4: *--d= *--s;
  369. X  case 3: *--d= *--s;
  370. X  case 2: *--d= *--s;
  371. X  case 1: *--d= *--s;
  372. #else
  373. X  case 7: d[6]=s[6];
  374. X  case 6: d[5]=s[5];
  375. X  case 5: d[4]=s[4];
  376. X  case 4: d[3]=s[3];
  377. X  case 3: d[2]=s[2];
  378. X  case 2: d[1]=s[1];
  379. X  case 1: d[0]=s[0];
  380. #endif
  381. X  case 0:;
  382. X  }
  383. X sz-=z;
  384. X mbkwdI(d-(sz&~(ISIZ-1)),s-(sz&~(ISIZ-1)),sz>>SHFT);
  385. #ifndef AUTOINC
  386. X d-=sz; s-=sz;
  387. #else
  388. X d-=(sz&~(ISIZ-1)); s-=(sz&~(ISIZ-1));
  389. #endif
  390. X switch(sz&(ISIZ-1))
  391. X  {
  392. #ifdef AUTOINC
  393. X  case 7: *--d= *--s;
  394. X  case 6: *--d= *--s;
  395. X  case 5: *--d= *--s;
  396. X  case 4: *--d= *--s;
  397. X  case 3: *--d= *--s;
  398. X  case 2: *--d= *--s;
  399. X  case 1: *--d= *--s;
  400. #else
  401. X  case 7: d[6]=s[6];
  402. X  case 6: d[5]=s[5];
  403. X  case 5: d[4]=s[4];
  404. X  case 4: d[3]=s[3];
  405. X  case 3: d[2]=s[2];
  406. X  case 2: d[1]=s[1];
  407. X  case 1: d[0]=s[0];
  408. #endif
  409. X  case 0:;
  410. X  }
  411. X }
  412. else
  413. X {
  414. X while(sz>=16)
  415. X  {
  416. #ifdef AUTOINC
  417. X *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s;
  418. X *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s;
  419. X *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s;
  420. X *--d= *--s; *--d= *--s; *--d= *--s; *--d= *--s;
  421. #else
  422. X  d-=16; s-=16;
  423. X  d[15]=s[15]; d[14]=s[14]; d[13]=s[13]; d[12]=s[12]; d[11]=s[11]; d[10]=s[10];
  424. X  d[9]=s[9]; d[8]=s[8]; d[7]=s[7]; d[6]=s[6]; d[5]=s[5]; d[4]=s[4]; d[3]=s[3];
  425. X  d[2]=s[2]; d[1]=s[1]; d[0]=s[0];
  426. #endif
  427. X  sz-=16;
  428. X  }
  429. #ifndef AUTOINC
  430. X d-=sz; s-=sz;
  431. #endif
  432. X switch(sz)
  433. X  {
  434. #ifdef AUTOINC
  435. X  case 15: *--d= *--s;
  436. X  case 14: *--d= *--s;
  437. X  case 13: *--d= *--s;
  438. X  case 12: *--d= *--s;
  439. X  case 11: *--d= *--s;
  440. X  case 10: *--d= *--s;
  441. X  case 9: *--d= *--s;
  442. X  case 8: *--d= *--s;
  443. X  case 7: *--d= *--s;
  444. X  case 6: *--d= *--s;
  445. X  case 5: *--d= *--s;
  446. X  case 4: *--d= *--s;
  447. X  case 3: *--d= *--s;
  448. X  case 2: *--d= *--s;
  449. X  case 1: *--d= *--s;
  450. #else
  451. X  case 15: d[14]=s[14];
  452. X  case 14: d[13]=s[13];
  453. X  case 13: d[12]=s[12];
  454. X  case 12: d[11]=s[11];
  455. X  case 11: d[10]=s[10];
  456. X  case 10: d[9]=s[9];
  457. X  case 9: d[8]=s[8];
  458. X  case 8: d[7]=s[7];
  459. X  case 7: d[6]=s[6];
  460. X  case 6: d[5]=s[5];
  461. X  case 5: d[4]=s[4];
  462. X  case 4: d[3]=s[3];
  463. X  case 3: d[2]=s[2];
  464. X  case 2: d[1]=s[1];
  465. X  case 1: d[0]=s[0];
  466. #endif
  467. X  case 0:;
  468. X  }
  469. X }
  470. return d;
  471. }
  472. X
  473. char *mmove(d,s,sz)
  474. char *d, *s;
  475. int sz;
  476. {
  477. if(d>s) mbkwd(d,s,sz);
  478. else mfwrd(d,s,sz);
  479. }
  480. X
  481. /* Copy the block of 'sz' bytes beginning at 's' to 'd'.  If 'sz' is zero or
  482. X * if 's'=='d', nothing happens.  The bytes at the lowest address ('s')
  483. X * are copied before the ones at the highest ('s'+'sz'-1) are.
  484. X */ 
  485. X
  486. char *mfwrd(d,s,sz)
  487. register char *d, *s;
  488. register int sz;
  489. {
  490. char *od=d;
  491. if(d==s) return d;
  492. #ifdef ALIGNED
  493. if(sz>=16)
  494. #else
  495. if( ((int)d&(ISIZ-1))==((int)s&(ISIZ-1)) && sz>=16 )
  496. #endif
  497. X {
  498. X int z=((int)s&(ISIZ-1));
  499. X if(z)
  500. X  {
  501. #ifndef AUTOINC
  502. X  s-=z; d-=z;
  503. X  switch(ISIZ-z)
  504. X   {
  505. #if ISIZ==8
  506. X   case 7: d[1]=s[1];
  507. X   case 6: d[2]=s[2];
  508. X   case 5: d[3]=s[3];
  509. X   case 4: d[4]=s[4];
  510. X   case 3: d[5]=s[5];
  511. X   case 2: d[6]=s[6];
  512. X   case 1: d[7]=s[7];
  513. X   case 0:;
  514. #else
  515. #if ISIZ==4
  516. X   case 3: d[1]=s[1];
  517. X   case 2: d[2]=s[2];
  518. X   case 1: d[3]=s[3];
  519. X   case 0:;
  520. #else
  521. #if ISIZ==2
  522. X   case 1: d[1]=s[1];
  523. X   case 0:;
  524. #endif
  525. #endif
  526. #endif
  527. X   }
  528. X  s+=ISIZ; d+=ISIZ;
  529. #else
  530. X  switch(ISIZ-z)
  531. X   {
  532. X   case 7: *d++= *s++;
  533. X   case 6: *d++= *s++;
  534. X   case 5: *d++= *s++;
  535. X   case 4: *d++= *s++;
  536. X   case 3: *d++= *s++;
  537. X   case 2: *d++= *s++;
  538. X   case 1: *d++= *s++;
  539. X   case 0:;
  540. X   }
  541. #endif
  542. X  sz-=ISIZ-z;
  543. X  }
  544. X mfwrdI(d,s,sz>>SHFT);
  545. #ifdef AUTOINC
  546. X s+=(sz&~(ISIZ-1)); d+=(sz&~(ISIZ-1));
  547. X switch(sz&(ISIZ-1))
  548. X  {
  549. X  case 7: *d++= *s++;
  550. X  case 6: *d++= *s++;
  551. X  case 5: *d++= *s++;
  552. X  case 4: *d++= *s++;
  553. X  case 3: *d++= *s++;
  554. X  case 2: *d++= *s++;
  555. X  case 1: *d++= *s++;
  556. X  case 0:;
  557. X  }
  558. #else
  559. X s+=sz-(ISIZ-1); d+=sz-(ISIZ-1);
  560. X switch(sz&(ISIZ-1))
  561. X  {
  562. #if ISIZ==8
  563. X case 7: d[0]=s[0];
  564. X case 6: d[1]=s[1];
  565. X case 5: d[2]=s[2];
  566. X case 4: d[3]=s[3];
  567. X case 3: d[4]=s[4];
  568. X case 2: d[5]=s[5];
  569. X case 1: d[6]=s[6];
  570. X case 0:;
  571. #else
  572. #if ISIZ==4
  573. X  case 3: d[0]=s[0];
  574. X  case 2: d[1]=s[1];
  575. X  case 1: d[2]=s[2];
  576. X  case 0:;
  577. #else
  578. #if ISIZ==2
  579. X  case 1: d[0]=s[0];
  580. X  case 0:;
  581. #endif
  582. #endif
  583. #endif
  584. X  }
  585. #endif
  586. X }
  587. else
  588. X {
  589. X while(sz>=16)
  590. X  {
  591. #ifdef AUTOINC
  592. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  593. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  594. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  595. X *d++= *s++; *d++= *s++; *d++= *s++; *d++= *s++;
  596. #else
  597. X  d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; d[4]=s[4]; d[5]=s[5]; d[6]=s[6];
  598. X  d[7]=s[7]; d[8]=s[8]; d[9]=s[9]; d[10]=s[10]; d[11]=s[11]; d[12]=s[12];
  599. X  d[13]=s[13]; d[14]=s[14]; d[15]=s[15];
  600. X  s+=16; d+=16;
  601. #endif
  602. X  sz-=16;
  603. X  }
  604. #ifndef AUTOINC
  605. X s-=15-sz; d-=15-sz;
  606. #endif
  607. X switch(sz)
  608. X  {
  609. #ifdef AUTOINC
  610. X case 15: *d++= *s++;
  611. X case 14: *d++= *s++;
  612. X case 13: *d++= *s++;
  613. X case 12: *d++= *s++;
  614. X case 11: *d++= *s++;
  615. X case 10: *d++= *s++;
  616. X case 9: *d++= *s++;
  617. X case 8: *d++= *s++;
  618. X case 7: *d++= *s++;
  619. X case 6: *d++= *s++;
  620. X case 5: *d++= *s++;
  621. X case 4: *d++= *s++;
  622. X case 3: *d++= *s++;
  623. X case 2: *d++= *s++;
  624. X case 1: *d++= *s++;
  625. X case 0:;
  626. #else
  627. X  case 15: d[0]=s[0];
  628. X  case 14: d[1]=s[1];
  629. X  case 13: d[2]=s[2];
  630. X  case 12: d[3]=s[3];
  631. X  case 11: d[4]=s[4];
  632. X  case 10: d[5]=s[5];
  633. X  case 9: d[6]=s[6];
  634. X  case 8: d[7]=s[7];
  635. X  case 7: d[8]=s[8];
  636. X  case 6: d[9]=s[9];
  637. X  case 5: d[10]=s[10];
  638. X  case 4: d[11]=s[11];
  639. X  case 3: d[12]=s[12];
  640. X  case 2: d[13]=s[13];
  641. X  case 1: d[14]=s[14];
  642. X  case 0:;
  643. #endif
  644. X  }
  645. X }
  646. return od;
  647. }
  648. X
  649. /* Utility to count number of lines within a segment */
  650. X
  651. int mcnt(blk,c,size)
  652. char *blk,c;
  653. int size;
  654. {
  655. int nlines=0;
  656. while(size>=16)
  657. X {
  658. X if(blk[0]==c) ++nlines;
  659. X if(blk[1]==c) ++nlines;
  660. X if(blk[2]==c) ++nlines;
  661. X if(blk[3]==c) ++nlines;
  662. X if(blk[4]==c) ++nlines;
  663. X if(blk[5]==c) ++nlines;
  664. X if(blk[6]==c) ++nlines;
  665. X if(blk[7]==c) ++nlines;
  666. X if(blk[8]==c) ++nlines;
  667. X if(blk[9]==c) ++nlines;
  668. X if(blk[10]==c) ++nlines;
  669. X if(blk[11]==c) ++nlines;
  670. X if(blk[12]==c) ++nlines;
  671. X if(blk[13]==c) ++nlines;
  672. X if(blk[14]==c) ++nlines;
  673. X if(blk[15]==c) ++nlines;
  674. X blk+=16; size-=16;
  675. X }
  676. while(size--) if(*blk++=='\n') ++nlines;
  677. return nlines;
  678. }
  679. SHAR_EOF
  680. chmod 0600 blocks.c ||
  681. echo 'restore of blocks.c failed'
  682. Wc_c="`wc -c < 'blocks.c'`"
  683. test 12881 -eq "$Wc_c" ||
  684.     echo 'blocks.c: original size 12881, current size' "$Wc_c"
  685. fi
  686. # ============= blocks.h ==============
  687. if test -f 'blocks.h' -a X"$1" != X"-c"; then
  688.     echo 'x - skipping blocks.h (File already exists)'
  689. else
  690. echo 'x - extracting blocks.h (Text)'
  691. sed 's/^X//' << 'SHAR_EOF' > 'blocks.h' &&
  692. /* Fast block move/copy subroutines
  693. X   Copyright (C) 1992 Joseph H. Allen
  694. X
  695. This file is part of JOE (Joe's Own Editor)
  696. X
  697. JOE is free software; you can redistribute it and/or modify it under the 
  698. terms of the GNU General Public License as published by the Free Software 
  699. Foundation; either version 1, or (at your option) any later version.  
  700. X
  701. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  702. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  703. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  704. details.  
  705. X
  706. You should have received a copy of the GNU General Public License along with 
  707. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  708. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  709. X
  710. X
  711. #ifndef _Iblocks
  712. #define _Iblocks 1
  713. X
  714. #include "config.h"
  715. X
  716. /* Warning: Don't use mfwrd or mbkwd for filling an area.  Use them only
  717. X * for copying, inserting or deleting.  Since they copy ints at a time, they
  718. X * will not work for filling.
  719. X */
  720. X
  721. /* char *mfwrd(char *d,char *s,int sz); Copy 'sz' bytes from 's' to 'd'.
  722. X   The copy occures in the forward direction (use for deletes)
  723. X   Nothing happens if 'd'=='s' or 'sz'==0
  724. X   Returns original value of 'd'
  725. X */
  726. char *mfwrd();
  727. X
  728. /* char *mbkwd(char *d,char *s,int sz); Copy 'sz' bytes from 's' to 'd'.
  729. X   The copy occures in the backward direction (use for inserts)
  730. X   Nothing happens if 'd'=='s' or 'sz'==0
  731. X   Returns original value of 'd'
  732. X */
  733. char *mbkwd();
  734. X
  735. /* char *mmove(char *d,char *s,int sz); Copy 'sz' bytes from 's' to 'd'.  Chooses
  736. X * either mbkwd or mfwrd to do this such that the data won't get clobbered.
  737. X */
  738. char *mmove();
  739. X
  740. /* Use this for non-overlapping copies */
  741. #define mcpy mbkwd
  742. X
  743. /* char *mset(char *d,char c,int sz); Set 'sz' bytes at 'd' to 'c'.
  744. X * If 'sz'==0 nothing happens
  745. X * Return original value of 'd'
  746. X */
  747. char *mset();
  748. X
  749. /* int *msetI(int *d,int c,int sz); Set 'sz' ints at 'd' to 'c'.
  750. X * If 'sz'==0 nothing happens
  751. X * Returns orininal value of 'd'
  752. X */
  753. X
  754. int *msetI();
  755. X
  756. /* int mcnt(char *blk,char c,int size);
  757. X *
  758. X * Count number of occurances a character appears in a block
  759. X */
  760. int mcnt();
  761. X
  762. #endif
  763. SHAR_EOF
  764. chmod 0600 blocks.h ||
  765. echo 'restore of blocks.h failed'
  766. Wc_c="`wc -c < 'blocks.h'`"
  767. test 2144 -eq "$Wc_c" ||
  768.     echo 'blocks.h: original size 2144, current size' "$Wc_c"
  769. fi
  770. # ============= bw.c ==============
  771. if test -f 'bw.c' -a X"$1" != X"-c"; then
  772.     echo 'x - skipping bw.c (File already exists)'
  773. else
  774. echo 'x - extracting bw.c (Text)'
  775. sed 's/^X//' << 'SHAR_EOF' > 'bw.c' &&
  776. /* Edit buffer window generation
  777. X   Copyright (C) 1992 Joseph H. Allen
  778. X
  779. This file is part of JOE (Joe's Own Editor)
  780. X
  781. JOE is free software; you can redistribute it and/or modify it under the 
  782. terms of the GNU General Public License as published by the Free Software 
  783. Foundation; either version 1, or (at your option) any later version.  
  784. X
  785. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  786. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  787. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  788. details.  
  789. X
  790. You should have received a copy of the GNU General Public License along with 
  791. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  792. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  793. X
  794. #include "config.h"
  795. #include "heap.h"
  796. #include "tty.h"
  797. #include "vfile.h"
  798. #include "toomany.h"
  799. #include "termcap.h"
  800. #include "kbd.h"
  801. #include "b.h"
  802. #include "scrn.h"
  803. #include "w.h"
  804. #include "bw.h"
  805. X
  806. /* Display modes */
  807. int dspasis=0;
  808. extern int square;
  809. X
  810. P *getto(p,cur,top,line)
  811. P *p,*cur,*top;
  812. long line;
  813. {
  814. long dist=MAXLONG;
  815. long d;
  816. P *best;
  817. if(!p)
  818. X {
  819. X if(d=(line-cur->line>=0?line-cur->line:cur->line-line), d<dist)
  820. X  dist=d, best=cur;
  821. X if(d=(line-top->line>=0?line-top->line:top->line-line), d<dist)
  822. X  dist=d, best=top;
  823. X p=pdup(best);
  824. X pbol(p);
  825. X }
  826. while(line>p->line) if(!pnextl(p)) break;
  827. if(line<p->line)
  828. X {
  829. X while(line<p->line) pprevl(p);
  830. X pboln(p);
  831. X }
  832. return p;
  833. }
  834. X
  835. /* Scroll window to follow cursor */
  836. X
  837. int mid=0;
  838. X
  839. void bwfllw(w)
  840. BW *w;
  841. {
  842. P *newtop;
  843. if(w->cursor->line<w->top->line)
  844. X {
  845. X newtop=pdup(w->cursor);
  846. X pbol(newtop);
  847. X if(mid)
  848. X  if(newtop->line>=w->h/2) pline(newtop,newtop->line-w->h/2);
  849. X  else pset(newtop,newtop->b->bof);
  850. X if(w->top->line-newtop->line<w->h)
  851. X  {
  852. X  nscrldn(w->t->t,w->y,w->y+w->h,(int)(w->top->line-newtop->line));
  853. X  scrldn(w->t->t->updtab,w->y,w->y+w->h,(int)(w->top->line-newtop->line));
  854. X  }
  855. X else msetI(w->t->t->updtab+w->y,1,w->h);
  856. X pset(w->top,newtop);
  857. X prm(newtop);
  858. X }
  859. else if(w->cursor->line>=w->top->line+w->h)
  860. X {
  861. X newtop=pdup(w->top);
  862. X if(mid) newtop=getto(NULL,w->cursor,w->top,w->cursor->line-w->h/2);
  863. X else newtop=getto(NULL,w->cursor,w->top,w->cursor->line-(w->h-1));
  864. X if(newtop->line-w->top->line<w->h)
  865. X  {
  866. X  nscrlup(w->t->t,
  867. X            w->y,
  868. X            w->y+w->h,
  869. X            (int)(newtop->line-w->top->line));
  870. X  scrlup(w->t->t->updtab,w->y,w->y+w->h,(int)(newtop->line-w->top->line));
  871. X  }
  872. X else msetI(w->t->t->updtab+w->y,1,w->h);
  873. X pset(w->top,newtop);
  874. X prm(newtop);
  875. X }
  876. X
  877. /* Adjust column */
  878. if(w->cursor->xcol<w->offset)
  879. X {
  880. X w->offset=w->cursor->xcol;
  881. X msetI(w->t->t->updtab+w->y,1,w->h);
  882. X }
  883. else if(w->cursor->xcol>=w->offset+w->w)
  884. X {
  885. X w->offset=w->cursor->xcol-(w->w-1);
  886. X msetI(w->t->t->updtab+w->y,1,w->h);
  887. X }
  888. }
  889. X
  890. /* Scroll a buffer window after an insert occured.  'flg' is set to 1 if
  891. X * the first line was split
  892. X */
  893. X
  894. void bwins(w,l,n,flg)
  895. BW *w;
  896. long l,n;
  897. int flg;
  898. {
  899. if(l+flg+n<w->top->line+w->h && l+flg>=w->top->line && l+flg<=w->b->eof->line)
  900. X {
  901. X int y;
  902. X if(flg) w->t->t->sary[w->y+l-w->top->line]=w->t->t->li;
  903. X nscrldn(w->t->t,(int)(w->y+l+flg-w->top->line),w->y+w->h,(int)n);
  904. X scrldn(w->t->t->updtab,(int)(w->y+l+flg-w->top->line),w->y+w->h,(int)n);
  905. X }
  906. if(l<w->top->line+w->h && l>=w->top->line)
  907. X if(n>=w->h-(l-w->top->line))
  908. X  msetI(w->t->t->updtab+w->y+l-w->top->line,1,w->h-(int)(l-w->top->line));
  909. X else
  910. X  msetI(w->t->t->updtab+w->y+l-w->top->line,1,(int)n+1);
  911. }
  912. X
  913. /* Scroll current windows after a delete */
  914. X
  915. void bwdel(w,l,n,flg)
  916. BW *w;
  917. long l,n;
  918. int flg;
  919. {
  920. if(l<w->top->line+w->h && l>=w->top->line)
  921. X w->t->t->updtab[w->y+l-w->top->line]=1;
  922. if(l+n<w->top->line+w->h && l+n>=w->top->line)
  923. X w->t->t->updtab[w->y+l+n-w->top->line]=1;
  924. X
  925. if(l<w->top->line+w->h &&
  926. X   (l+n>=w->top->line+w->h || l+n==w->b->eof->line))
  927. X if(l>=w->top->line)
  928. X  scrlup(w->t->t->updtab,w->y+l-w->top->line,w->y+w->h,
  929. X         w->y+w->h-(w->y+l-w->top->line));
  930. X else
  931. X  scrlup(w->t->t->updtab,w->y,w->y+w->h,w->h);
  932. else if(l+n<w->top->line+w->h &&
  933. X        l+n>w->top->line &&
  934. X        l+n<w->b->eof->line)
  935. X if(l+flg>=w->top->line)
  936. X  {
  937. X  nscrlup(w->t->t,(int)(w->y+l+flg-w->top->line),w->y+w->h,(int)n);
  938. X  scrlup(w->t->t->updtab,(int)(w->y+l+flg-w->top->line),w->y+w->h,(int)n);
  939. X  }
  940. X else
  941. X  {
  942. X  nscrlup(w->t->t,w->y,w->y+w->h,(int)(l+n-w->top->line));
  943. X  scrlup(w->t->t->updtab,w->y,w->y+w->h,(int)(l+n-w->top->line));
  944. X  }
  945. }
  946. X
  947. /* Update a single line */
  948. X
  949. static int lgen(t,y,screen,x,w,p,scr,from,to)
  950. SCRN *t;
  951. int y;
  952. int *screen;    /* Screen line address */
  953. int w;        /* Window */
  954. P *p;        /* Buffer pointer */
  955. long scr;    /* Starting column to display */
  956. long from,to;    /* Range for marked block */
  957. {
  958. int done=1;
  959. long col=0;
  960. long byte=p->byte;
  961. char *bp;        /* Buffer pointer, 0 if not set */
  962. int amnt;        /* Amount left in this segment of the buffer */
  963. int c, ta;
  964. unsigned char bc;
  965. X
  966. /* Initialize bp and amnt from p */
  967. if(p->ofst>=p->hdr->hole)
  968. X {
  969. X bp=p->ptr+p->hdr->ehole+p->ofst-p->hdr->hole;
  970. X amnt=SEGSIZ-p->hdr->ehole-(p->ofst-p->hdr->hole);
  971. X }
  972. else
  973. X {
  974. X bp=p->ptr+p->ofst;
  975. X amnt=p->hdr->hole-p->ofst;
  976. X }
  977. X
  978. if(col==scr) goto loop;
  979. lp:        /* Display next character */
  980. if(amnt) do
  981. X {
  982. X bc= *bp++;
  983. X if(square)
  984. X  {
  985. X  if(col>=from && col<to) c=INVERSE;
  986. X  else c=0;
  987. X  }
  988. X else
  989. X  {
  990. X  if(byte>=from && byte<to) c=INVERSE;
  991. X  else c=0;
  992. X  }
  993. X ++byte;
  994. X if(bc=='\t')
  995. X  {
  996. X  ta=p->b->tab-col%p->b->tab;
  997. X  if(ta+col>scr)
  998. X   {
  999. X   ta-=scr-col;
  1000. X   goto dota;
  1001. X   }
  1002. X  if((col+=ta)==scr) { --amnt; goto loop; }
  1003. X  }
  1004. X else if(bc=='\n') goto eobl;
  1005. X else if(++col==scr) { --amnt; goto loop; }
  1006. X }
  1007. X while(--amnt);
  1008. if(bp==p->ptr+SEGSIZ)
  1009. X {
  1010. X if(pnext(p))
  1011. X  {
  1012. X  bp=p->ptr;
  1013. X  amnt=p->hdr->hole;
  1014. X  goto lp;
  1015. X  }
  1016. X else
  1017. X  {
  1018. X  bp=p->ptr;
  1019. X  amnt=p->hdr->hole+1;
  1020. X  }
  1021. X }
  1022. else
  1023. X {
  1024. X bp=p->ptr+p->hdr->ehole;
  1025. X amnt=SEGSIZ-p->hdr->ehole;
  1026. X goto lp;
  1027. X }
  1028. goto eof;
  1029. X
  1030. loop:        /* Display next character */
  1031. if(amnt) do
  1032. X {
  1033. X bc= *bp++;
  1034. X if(square)
  1035. X  if(col+x>=from && col+x<to) c=INVERSE;
  1036. X  else c=0;
  1037. X else
  1038. X  if(byte>=from && byte<to) c=INVERSE;
  1039. X  else c=0;
  1040. X ++byte;
  1041. X if(bc=='\t')
  1042. X  {
  1043. X  ta=p->b->tab-((x+scr)%p->b->tab);
  1044. X  dota:
  1045. X  do
  1046. X   {
  1047. X   if(screen[x]!=' '+c)
  1048. X    {
  1049. X    screen[x]=' '+c;
  1050. X    if(t->ins) clrins(t);
  1051. X    if(t->x!=x || t->y!=y) cpos(t,x,y);
  1052. X    if(c!=t->attrib) attr(t,c);
  1053. X    ttputc(' '); ++t->x;
  1054. X    if(have) goto bye;
  1055. X    }
  1056. X   if(++x==w) goto eosl;
  1057. X   }
  1058. X   while(--ta);
  1059. X  }
  1060. X else if(bc=='\n') goto eobl;
  1061. X else
  1062. X  {
  1063. X  if(!dspasis || bc<160 || bc>254)
  1064. X   {
  1065. X   if(bc&128) c^=INVERSE, bc&=127;
  1066. X   if(bc==127) c|=UNDERLINE, bc='?';
  1067. X   else if(bc<32) c|=UNDERLINE, bc+='@';
  1068. X   }
  1069. X  if(t->hz && bc=='~') bc='\\';
  1070. X  if(screen[x]!=c+bc)
  1071. X   {
  1072. X   screen[x]=c+bc;
  1073. X   if(t->ins) clrins(t);
  1074. X   if(t->x!=x || t->y!=y) cpos(t,x,y);
  1075. X   if(c!=t->attrib) attr(t,c);
  1076. X   ttputc(bc); ++t->x;
  1077. X   if(have) goto bye;
  1078. X   }
  1079. X  if(++x==w) goto eosl;
  1080. X  }
  1081. X }
  1082. X while(--amnt);
  1083. if(bp==p->ptr+SEGSIZ)
  1084. X {
  1085. X if(pnext(p))
  1086. X  {
  1087. X  bp=p->ptr;
  1088. X  amnt=p->hdr->hole;
  1089. X  goto loop;
  1090. X  }
  1091. X else
  1092. X  {
  1093. X  bp=p->ptr;
  1094. X  amnt=p->hdr->hole+1;
  1095. X  }
  1096. X }
  1097. else
  1098. X {
  1099. X bp=p->ptr+p->hdr->ehole;
  1100. X amnt=SEGSIZ-p->hdr->ehole;
  1101. X goto loop;
  1102. X }
  1103. goto eof;
  1104. X
  1105. eobl:        /* End of buffer line found.  Erase to end of screen line */
  1106. ++p->line;
  1107. eof:
  1108. if(x!=w) done=eraeol(t,x,y);
  1109. else done=0;
  1110. X
  1111. /* Set p to bp/amnt */
  1112. bye:
  1113. if(bp-p->ptr<=p->hdr->hole) p->ofst=bp-p->ptr;
  1114. else p->ofst=bp-p->ptr-(p->hdr->ehole-p->hdr->hole);
  1115. p->byte=byte;
  1116. return done;
  1117. X
  1118. eosl:
  1119. if(bp-p->ptr<=p->hdr->hole) p->ofst=bp-p->ptr;
  1120. else p->ofst=bp-p->ptr-(p->hdr->ehole-p->hdr->hole);
  1121. p->byte=byte;
  1122. pnextl(p);
  1123. return 0;
  1124. }
  1125. X
  1126. /* Generate line into an array */
  1127. X
  1128. static int lgena(t,y,screen,x,w,p,scr,from,to)
  1129. SCRN *t;
  1130. int y;
  1131. int *screen;    /* Screen line address */
  1132. int w;        /* Window */
  1133. P *p;        /* Buffer pointer */
  1134. long scr;    /* Starting column to display */
  1135. long from,to;    /* Range for marked block */
  1136. {
  1137. int done=1;
  1138. long col=0;
  1139. long byte=p->byte;
  1140. char *bp;        /* Buffer pointer, 0 if not set */
  1141. int amnt;        /* Amount left in this segment of the buffer */
  1142. int c, ta;
  1143. unsigned char bc;
  1144. X
  1145. /* Initialize bp and amnt from p */
  1146. if(p->ofst>=p->hdr->hole)
  1147. X {
  1148. X bp=p->ptr+p->hdr->ehole+p->ofst-p->hdr->hole;
  1149. X amnt=SEGSIZ-p->hdr->ehole-(p->ofst-p->hdr->hole);
  1150. X }
  1151. else
  1152. X {
  1153. X bp=p->ptr+p->ofst;
  1154. X amnt=p->hdr->hole-p->ofst;
  1155. X }
  1156. X
  1157. if(col==scr) goto loop;
  1158. lp:        /* Display next character */
  1159. if(amnt) do
  1160. X {
  1161. X bc= *bp++;
  1162. X if(square)
  1163. X  {
  1164. X  if(col>=from && col<to) c=INVERSE;
  1165. X  else c=0;
  1166. X  }
  1167. X else
  1168. X  {
  1169. X  if(byte>=from && byte<to) c=INVERSE;
  1170. X  else c=0;
  1171. X  }
  1172. X ++byte;
  1173. X if(bc=='\t')
  1174. X  {
  1175. X  ta=p->b->tab-col%p->b->tab;
  1176. X  if(ta+col>scr)
  1177. X   {
  1178. X   ta-=scr-col;
  1179. X   goto dota;
  1180. X   }
  1181. X  if((col+=ta)==scr) { --amnt; goto loop; }
  1182. X  }
  1183. X else if(bc=='\n') goto eobl;
  1184. X else if(++col==scr) { --amnt; goto loop; }
  1185. X }
  1186. X while(--amnt);
  1187. if(bp==p->ptr+SEGSIZ)
  1188. X {
  1189. X if(pnext(p))
  1190. X  {
  1191. X  bp=p->ptr;
  1192. X  amnt=p->hdr->hole;
  1193. X  goto lp;
  1194. X  }
  1195. X else
  1196. X  {
  1197. X  bp=p->ptr;
  1198. X  amnt=p->hdr->hole+1;
  1199. X  }
  1200. X }
  1201. else
  1202. X {
  1203. X bp=p->ptr+p->hdr->ehole;
  1204. X amnt=SEGSIZ-p->hdr->ehole;
  1205. X goto lp;
  1206. X }
  1207. goto eobl;
  1208. X
  1209. loop:        /* Display next character */
  1210. if(amnt) do
  1211. X {
  1212. X bc= *bp++;
  1213. X if(square)
  1214. X  if(col+x>=from && col+x<to) c=INVERSE;
  1215. X  else c=0;
  1216. X else
  1217. X  if(byte>=from && byte<to) c=INVERSE;
  1218. X  else c=0;
  1219. X ++byte;
  1220. X if(bc=='\t')
  1221. X  {
  1222. X  ta=p->b->tab-((x+scr)%p->b->tab);
  1223. X  dota:
  1224. X  do
  1225. X   {
  1226. X   screen[x]=' '+c;
  1227. X   if(++x==w) goto eosl;
  1228. X   }
  1229. X   while(--ta);
  1230. X  }
  1231. X else if(bc=='\n') goto eobl;
  1232. X else
  1233. X  {
  1234. X  if(!dspasis || bc<160 || bc>254)
  1235. X   {
  1236. X   if(bc&128) c^=INVERSE, bc&=127;
  1237. X   if(bc==127) c|=UNDERLINE, bc='?';
  1238. X   else if(bc<32) c|=UNDERLINE, bc+='@';
  1239. X   }
  1240. X  screen[x]=c+bc;
  1241. X  if(++x==w) goto eosl;
  1242. X  }
  1243. X }
  1244. X while(--amnt);
  1245. if(bp==p->ptr+SEGSIZ)
  1246. X {
  1247. X if(pnext(p))
  1248. X  {
  1249. X  bp=p->ptr;
  1250. X  amnt=p->hdr->hole;
  1251. X  goto loop;
  1252. X  }
  1253. X else
  1254. X  {
  1255. X  bp=p->ptr;
  1256. X  amnt=p->hdr->hole+1;
  1257. X  }
  1258. X }
  1259. else
  1260. X {
  1261. X bp=p->ptr+p->hdr->ehole;
  1262. X amnt=SEGSIZ-p->hdr->ehole;
  1263. X goto loop;
  1264. X }
  1265. goto eof;
  1266. eobl:        /* End of buffer line found.  Erase to end of screen line */
  1267. ++p->line;
  1268. eof:
  1269. while(x!=w) screen[x++]=' ';
  1270. done=0;
  1271. X
  1272. /* Set p to bp/amnt */
  1273. bye:
  1274. if(bp-p->ptr<=p->hdr->hole) p->ofst=bp-p->ptr;
  1275. else p->ofst=bp-p->ptr-(p->hdr->ehole-p->hdr->hole);
  1276. p->byte=byte;
  1277. return done;
  1278. X
  1279. eosl:
  1280. if(bp-p->ptr<=p->hdr->hole) p->ofst=bp-p->ptr;
  1281. else p->ofst=bp-p->ptr-(p->hdr->ehole-p->hdr->hole);
  1282. p->byte=byte;
  1283. pnextl(p);
  1284. return 0;
  1285. }
  1286. X
  1287. void bwgen(w)
  1288. BW *w;
  1289. {
  1290. int *screen;
  1291. P *p=0;
  1292. P *q=pdup(w->cursor);
  1293. int bot=w->h+w->y;
  1294. int y;
  1295. int dosquare=0;
  1296. long from,to;
  1297. from=to=0;
  1298. if(w->t->markb && w->t->markk && w->t->markb->b==w->t->markk->b &&
  1299. X   w->t->markb->b==w->b)
  1300. X if(square) from=w->t->markb->col, to=w->t->markk->col, dosquare=1;
  1301. X else from=w->t->markb->byte, to=w->t->markk->byte;
  1302. X
  1303. y=w->cursor->line-w->top->line+w->y;
  1304. for(screen=w->t->t->scrn+y*w->t->w;y!=bot; ++y, screen+=w->t->w)
  1305. X {
  1306. X if(have) break;
  1307. X if(w->t->t->updtab[y])
  1308. X  {
  1309. X  p=getto(p,w->cursor,w->top,w->top->line+y-w->y);
  1310. X  if(w->t->t->insdel && !w->x)
  1311. X   {
  1312. X   pset(q,p);
  1313. X   if(dosquare)
  1314. X    if(w->top->line+y-w->y>=w->t->markb->line &&
  1315. X       w->top->line+y-w->y<=w->t->markk->line)
  1316. X     lgena(w->t->t,y,w->t->t->compose,w->x,w->x+w->w,q,w->offset,from,to);
  1317. X    else
  1318. X     lgena(w->t->t,y,w->t->t->compose,w->x,w->x+w->w,q,w->offset,0L,0L);
  1319. X   else
  1320. X    lgena(w->t->t,y,w->t->t->compose,w->x,w->x+w->w,q,w->offset,from,to);
  1321. X   magic(w->t->t,y,screen,w->t->t->compose,
  1322. X         (int)(w->cursor->xcol-w->offset+w->x));
  1323. X   }
  1324. X  if(dosquare)
  1325. X   if(w->top->line+y-w->y>=w->t->markb->line &&
  1326. X      w->top->line+y-w->y<=w->t->markk->line)
  1327. X    w->t->t->updtab[y]=lgen(w->t->t,y,screen,w->x,w->x+w->w,p,w->offset,
  1328. X                            from,to);
  1329. X   else
  1330. X    w->t->t->updtab[y]=lgen(w->t->t,y,screen,w->x,w->x+w->w,p,w->offset,
  1331. X                            0L,0L);
  1332. X  else
  1333. X   w->t->t->updtab[y]=lgen(w->t->t,y,screen,w->x,w->x+w->w,p,w->offset,
  1334. X                           from,to);
  1335. X  }
  1336. X }
  1337. y=w->y;
  1338. for(screen=w->t->t->scrn+w->y*w->t->w; y!=w->y+w->cursor->line-w->top->line;
  1339. X    ++y, screen+=w->t->w)
  1340. X {
  1341. X if(have) break;
  1342. X if(w->t->t->updtab[y])
  1343. X  {
  1344. X  p=getto(p,w->cursor,w->top,w->top->line+y-w->y);
  1345. X  if(w->t->t->insdel && !w->x)
  1346. X   {
  1347. X   pset(q,p);
  1348. X   if(dosquare)
  1349. X    if(w->top->line+y-w->y>=w->t->markb->line &&
  1350. X       w->top->line+y-w->y<=w->t->markk->line)
  1351. X     lgena(w->t->t,y,w->t->t->compose,w->x,w->x+w->w,q,w->offset,from,to);
  1352. X    else
  1353. X     lgena(w->t->t,y,w->t->t->compose,w->x,w->x+w->w,q,w->offset,0L,0L);
  1354. X   else
  1355. X    lgena(w->t->t,y,w->t->t->compose,w->x,w->x+w->w,q,w->offset,from,to);
  1356. X   magic(w->t->t,y,screen,w->t->t->compose,
  1357. X         (int)(w->cursor->xcol-w->offset+w->x));
  1358. X   }
  1359. X  if(dosquare)
  1360. X   if(w->top->line+y-w->y>=w->t->markb->line &&
  1361. X      w->top->line+y-w->y<=w->t->markk->line)
  1362. X    w->t->t->updtab[y]=lgen(w->t->t,y,screen,w->x,w->x+w->w,p,w->offset,
  1363. X                            from,to);
  1364. X   else
  1365. X    w->t->t->updtab[y]=lgen(w->t->t,y,screen,w->x,w->x+w->w,p,w->offset,
  1366. X                            0L,0L);
  1367. X  else
  1368. X   w->t->t->updtab[y]=lgen(w->t->t,y,screen,w->x,w->x+w->w,p,w->offset,
  1369. X                           from,to);
  1370. X  }
  1371. X }
  1372. prm(q);
  1373. if(p) prm(p);
  1374. }
  1375. X
  1376. void bwmove(w,x,y)
  1377. BW *w;
  1378. int x,y;
  1379. {
  1380. w->x=x;
  1381. w->y=y;
  1382. }
  1383. X
  1384. void bwresz(w,wi,he)
  1385. BW *w;
  1386. int wi, he;
  1387. {
  1388. if(he>w->h && w->y!= -1) msetI(w->t->t->updtab+w->y+w->h,1,he-w->h);
  1389. w->w=wi;
  1390. w->h=he;
  1391. }
  1392. X
  1393. BW *bwmk(t,b,x,y,wi,h)
  1394. SCREEN *t;
  1395. B *b;
  1396. int x,y,wi,h;
  1397. {
  1398. BW *w=(BW *)malloc(sizeof(BW));
  1399. w->b=b;
  1400. w->x=x;
  1401. w->y=y;
  1402. w->w=wi;
  1403. w->h=h;
  1404. X
  1405. w->lmargin=0;
  1406. w->rmargin=76;
  1407. w->autoindent=0;
  1408. w->wordwrap=0;
  1409. w->overtype=0;
  1410. w->indentc=' ';
  1411. w->istep=1;
  1412. X
  1413. w->top=pdup(b->bof);
  1414. w->cursor=pdup(w->top);
  1415. w->t=t; 
  1416. w->object=NULL;
  1417. w->offset=0;
  1418. return w;
  1419. }
  1420. X
  1421. void bwrm(w)
  1422. BW *w;
  1423. {
  1424. prm(w->top);
  1425. prm(w->cursor);
  1426. brm(w->b);
  1427. free(w);
  1428. }
  1429. X
  1430. void ustat(w)
  1431. W *w;
  1432. {
  1433. BW *bw=(BW *)w->object;
  1434. static char buf[80];
  1435. unsigned c=brc(bw->cursor);
  1436. if(c==MAXINT)
  1437. X sprintf(buf,"** ROW=%ld COL=%ld BYTE=%ld/0x%X **",
  1438. X         bw->cursor->line+1,bw->cursor->col+1,bw->cursor->byte,
  1439. X         bw->cursor->byte,bw->b->eof->line+1,bw->b->eof->byte+1);
  1440. else
  1441. X sprintf(buf,"** ROW=%ld COL=%ld BYTE=%ld/0x%X CHAR=%d/0%o/0x%X **",
  1442. X         bw->cursor->line+1,bw->cursor->col+1,bw->cursor->byte,
  1443. X         bw->cursor->byte,c,c,c);
  1444. msgnw(w,buf);
  1445. }
  1446. SHAR_EOF
  1447. chmod 0600 bw.c ||
  1448. echo 'restore of bw.c failed'
  1449. Wc_c="`wc -c < 'bw.c'`"
  1450. test 13764 -eq "$Wc_c" ||
  1451.     echo 'bw.c: original size 13764, current size' "$Wc_c"
  1452. fi
  1453. # ============= bw.h ==============
  1454. if test -f 'bw.h' -a X"$1" != X"-c"; then
  1455.     echo 'x - skipping bw.h (File already exists)'
  1456. else
  1457. echo 'x - extracting bw.h (Text)'
  1458. sed 's/^X//' << 'SHAR_EOF' > 'bw.h' &&
  1459. /* Edit buffer window generation
  1460. X   Copyright (C) 1992 Joseph H. Allen
  1461. X
  1462. This file is part of JOE (Joe's Own Editor)
  1463. X
  1464. JOE is free software; you can redistribute it and/or modify it under the 
  1465. terms of the GNU General Public License as published by the Free Software 
  1466. Foundation; either version 1, or (at your option) any later version.  
  1467. X
  1468. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1469. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1470. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1471. details.  
  1472. X
  1473. You should have received a copy of the GNU General Public License along with 
  1474. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1475. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1476. X
  1477. #ifndef _Ibw
  1478. #define _Ibw 1
  1479. X
  1480. #include "config.h"
  1481. #include "b.h"
  1482. #include "w.h"
  1483. X
  1484. extern int dspasis;
  1485. X
  1486. typedef struct bw BW;
  1487. X
  1488. struct bw
  1489. X {
  1490. X B *b;
  1491. X P *top;
  1492. X P *cursor;
  1493. X long offset;
  1494. X SCREEN *t;
  1495. X int h,w,x,y;
  1496. X long lmargin;
  1497. X long rmargin;
  1498. X int autoindent;
  1499. X int wordwrap;
  1500. X int overtype;
  1501. X long istep;
  1502. X int indentc;
  1503. X void *object;
  1504. X };
  1505. X
  1506. extern int mid;
  1507. void bwfllw();
  1508. void bwins();
  1509. void bwdel();
  1510. void bwgen();
  1511. BW *bwmk();
  1512. void bwmove();
  1513. void bwresz();
  1514. void bwrm();
  1515. void ustat();
  1516. X
  1517. #endif
  1518. SHAR_EOF
  1519. chmod 0600 bw.h ||
  1520. echo 'restore of bw.h failed'
  1521. Wc_c="`wc -c < 'bw.h'`"
  1522. test 1252 -eq "$Wc_c" ||
  1523.     echo 'bw.h: original size 1252, current size' "$Wc_c"
  1524. fi
  1525. # ============= config.h ==============
  1526. if test -f 'config.h' -a X"$1" != X"-c"; then
  1527.     echo 'x - skipping config.h (File already exists)'
  1528. else
  1529. echo 'x - extracting config.h (Text)'
  1530. sed 's/^X//' << 'SHAR_EOF' > 'config.h' &&
  1531. /* Configuration file for 32-bit systems */
  1532. X
  1533. #ifndef _Iconfig
  1534. #define _Iconfig 1
  1535. X
  1536. /* Integer size quantities
  1537. X * MAXINT Maximum signed integer
  1538. X * ISIZ   Number of chars in an int
  1539. X * SHFT   LOG2 of ISIZ
  1540. X */
  1541. X
  1542. #define MAXINT 0x7FFFFFFF
  1543. #define ISIZ 4
  1544. #define SHFT 2
  1545. X
  1546. /* Support for segmented systems
  1547. X * physical(addr)   Return a linear address given a pointer
  1548. X * normalize(addr)  Normalize a pointer so that the offset part is minimized
  1549. X */
  1550. X
  1551. #define physical(a) ((long)(a))
  1552. #define normalize(a) (a)
  1553. X
  1554. #define BITS 8            /* Number of bits in a char */
  1555. #define MAXLONG 0x7FFFFFFF
  1556. X
  1557. /* Uncomment the following line if your compiler has trouble with void */
  1558. /* #define void int */
  1559. X
  1560. #ifndef NULL
  1561. #define NULL ((void *)0)
  1562. #endif
  1563. X
  1564. /* These are for optimizing blocks.c */
  1565. /* #define AUTOINC */    /* Define this if CPU can autoincrement faster than
  1566. X               it can do [reg+offset] addressing */
  1567. /* #define ALIGNED */    /* Define this if CPU can access unaligned ints */
  1568. X            /* (tries to align ints even if defined) */
  1569. X
  1570. /* System calls we use */
  1571. char *getenv();
  1572. long time();
  1573. /*
  1574. int chdir();
  1575. int creat();
  1576. int open();
  1577. int close();
  1578. int read();
  1579. int write();
  1580. int lseek();
  1581. */
  1582. X
  1583. #endif
  1584. SHAR_EOF
  1585. chmod 0600 config.h ||
  1586. echo 'restore of config.h failed'
  1587. Wc_c="`wc -c < 'config.h'`"
  1588. test 1152 -eq "$Wc_c" ||
  1589.     echo 'config.h: original size 1152, current size' "$Wc_c"
  1590. fi
  1591. # ============= config16.h ==============
  1592. if test -f 'config16.h' -a X"$1" != X"-c"; then
  1593.     echo 'x - skipping config16.h (File already exists)'
  1594. else
  1595. echo 'x - extracting config16.h (Text)'
  1596. sed 's/^X//' << 'SHAR_EOF' > 'config16.h' &&
  1597. /* Configuration file for 16-bit systems */
  1598. X
  1599. #ifndef _Iconfig
  1600. #define _Iconfig 1
  1601. X
  1602. /* Integer size quantities
  1603. X * MAXINT Maximum signed integer
  1604. X * ISIZ   Number of chars in an int
  1605. X * SHFT   LOG2 of ISIZ
  1606. X */
  1607. X
  1608. #define MAXINT 0x7FFF
  1609. #define ISIZ 2
  1610. #define SHFT 1
  1611. X
  1612. /* Support for segmented systems
  1613. X * physical(addr)   Return a linear address given a pointer
  1614. X * normalize(addr)  Normalize a pointer so that the offset part is minimized
  1615. X */
  1616. X
  1617. #define physical(a) ((long)(a))
  1618. #define normalize(a) (a)
  1619. X
  1620. #define BITS 8            /* Number of bits in a char */
  1621. #define MAXLONG 0x7FFFFFFF
  1622. X
  1623. /* Uncomment the following line if your compiler has trouble with void */
  1624. /* #define void int */
  1625. X
  1626. /* NULL should only be used for data-pointers, not function pointers,
  1627. X * (because of medium model MSDOS)
  1628. X */
  1629. #ifndef NULL
  1630. #define NULL ((void *)0)
  1631. #endif
  1632. X
  1633. /* These are for optimizing blocks.c */
  1634. /* #define AUTOINC */    /* Define this if CPU can autoincrement faster than
  1635. X               it can do [reg+offset] addressing */
  1636. /* #define ALIGNED */    /* Define this if CPU can access unaligned ints */
  1637. X            /* (tries to align ints even if defined) */
  1638. X
  1639. /* System calls we use */
  1640. char *getenv();
  1641. char *getcwd();
  1642. long time();
  1643. /*
  1644. int chdir();
  1645. int creat();
  1646. int open();
  1647. int close();
  1648. int read();
  1649. int write();
  1650. int lseek();
  1651. */
  1652. X
  1653. #endif
  1654. SHAR_EOF
  1655. chmod 0600 config16.h ||
  1656. echo 'restore of config16.h failed'
  1657. Wc_c="`wc -c < 'config16.h'`"
  1658. test 1273 -eq "$Wc_c" ||
  1659.     echo 'config16.h: original size 1273, current size' "$Wc_c"
  1660. fi
  1661. # ============= config32.h ==============
  1662. if test -f 'config32.h' -a X"$1" != X"-c"; then
  1663.     echo 'x - skipping config32.h (File already exists)'
  1664. else
  1665. echo 'x - extracting config32.h (Text)'
  1666. sed 's/^X//' << 'SHAR_EOF' > 'config32.h' &&
  1667. /* Configuration file for 32-bit systems */
  1668. X
  1669. #ifndef _Iconfig
  1670. #define _Iconfig 1
  1671. X
  1672. /* Integer size quantities
  1673. X * MAXINT Maximum signed integer
  1674. X * ISIZ   Number of chars in an int
  1675. X * SHFT   LOG2 of ISIZ
  1676. X */
  1677. X
  1678. #define MAXINT 0x7FFFFFFF
  1679. #define ISIZ 4
  1680. #define SHFT 2
  1681. X
  1682. /* Support for segmented systems
  1683. X * physical(addr)   Return a linear address given a pointer
  1684. X * normalize(addr)  Normalize a pointer so that the offset part is minimized
  1685. X */
  1686. X
  1687. #define physical(a) ((long)(a))
  1688. #define normalize(a) (a)
  1689. X
  1690. #define BITS 8            /* Number of bits in a char */
  1691. #define MAXLONG 0x7FFFFFFF
  1692. X
  1693. /* Uncomment the following line if your compiler has trouble with void */
  1694. /* #define void int */
  1695. X
  1696. #ifndef NULL
  1697. #define NULL ((void *)0)
  1698. #endif
  1699. X
  1700. /* These are for optimizing blocks.c */
  1701. /* #define AUTOINC */    /* Define this if CPU can autoincrement faster than
  1702. X               it can do [reg+offset] addressing */
  1703. /* #define ALIGNED */    /* Define this if CPU can access unaligned ints */
  1704. X            /* (tries to align ints even if defined) */
  1705. X
  1706. /* System calls we use */
  1707. char *getenv();
  1708. long time();
  1709. /*
  1710. int chdir();
  1711. int creat();
  1712. int open();
  1713. int close();
  1714. int read();
  1715. int write();
  1716. int lseek();
  1717. */
  1718. X
  1719. #endif
  1720. SHAR_EOF
  1721. chmod 0600 config32.h ||
  1722. echo 'restore of config32.h failed'
  1723. Wc_c="`wc -c < 'config32.h'`"
  1724. test 1152 -eq "$Wc_c" ||
  1725.     echo 'config32.h: original size 1152, current size' "$Wc_c"
  1726. fi
  1727. # ============= config86.h ==============
  1728. if test -f 'config86.h' -a X"$1" != X"-c"; then
  1729.     echo 'x - skipping config86.h (File already exists)'
  1730. else
  1731. echo 'x - extracting config86.h (Text)'
  1732. sed 's/^X//' << 'SHAR_EOF' > 'config86.h' &&
  1733. /* Configuration file for 8086 segmented systems */
  1734. X
  1735. #ifndef _Iconfig
  1736. #define _Iconfig 1
  1737. X
  1738. /* Integer size quantities
  1739. X * MAXINT Maximum signed integer
  1740. X * ISIZ   Number of chars in an int
  1741. X * SHFT   LOG2 of ISIZ
  1742. X */
  1743. X
  1744. #define MAXINT 0x7FFF
  1745. #define ISIZ 2
  1746. #define SHFT 1
  1747. X
  1748. /* Support for segmented systems
  1749. X * physical(addr)   Return a linear address given a pointer
  1750. X * normalize(addr)  Normalize a pointer so that the offset part is minimized
  1751. X */
  1752. X
  1753. #define physical(a) (((long)(a)&0xFFFF)+(((unsigned long)(a)&0xFFFF0000)>>12))
  1754. #define normalize(a) \
  1755. X ((void *)(((long)(a)&0xFFFF000F)+(((long)(a)&0x0000FFF0)<<12)))
  1756. X
  1757. #define BITS 8            /* Number of bits in a char */
  1758. #define MAXLONG 0x7FFFFFFF
  1759. X
  1760. /* Uncomment the following line if your compiler has trouble with void */
  1761. /* #define void int */
  1762. X
  1763. /* NULL should only be used for data-pointers, not function pointers,
  1764. X * (because of medium model MSDOS)
  1765. X */
  1766. #ifndef NULL
  1767. #define NULL ((void *)0)
  1768. #endif
  1769. X
  1770. /* These are for optimizing blocks.c */
  1771. /* #define AUTOINC */    /* Define this if CPU can autoincrement faster than
  1772. X               it can do [reg+offset] addressing */
  1773. /* #define ALIGNED */    /* Define this if CPU can access unaligned ints */
  1774. X            /* (tries to align ints even if defined) */
  1775. X
  1776. /* System calls we use */
  1777. char *getenv();
  1778. char *getcwd();
  1779. long time();
  1780. /*
  1781. int chdir();
  1782. int creat();
  1783. int open();
  1784. int close();
  1785. int read();
  1786. int write();
  1787. int lseek();
  1788. */
  1789. X
  1790. #endif
  1791. SHAR_EOF
  1792. chmod 0600 config86.h ||
  1793. echo 'restore of config86.h failed'
  1794. Wc_c="`wc -c < 'config86.h'`"
  1795. test 1391 -eq "$Wc_c" ||
  1796.     echo 'config86.h: original size 1391, current size' "$Wc_c"
  1797. fi
  1798. # ============= copying ==============
  1799. if test -f 'copying' -a X"$1" != X"-c"; then
  1800.     echo 'x - skipping copying (File already exists)'
  1801. else
  1802. echo 'x - extracting copying (Text)'
  1803. sed 's/^X//' << 'SHAR_EOF' > 'copying' &&
  1804. X
  1805. X            GNU GENERAL PUBLIC LICENSE
  1806. X             Version 1, February 1989
  1807. X
  1808. X Copyright (C) 1989 Free Software Foundation, Inc.
  1809. X                    675 Mass Ave, Cambridge, MA 02139, USA
  1810. X Everyone is permitted to copy and distribute verbatim copies
  1811. X of this license document, but changing it is not allowed.
  1812. X
  1813. X                Preamble
  1814. X
  1815. X  The license agreements of most software companies try to keep users
  1816. at the mercy of those companies.  By contrast, our General Public
  1817. License is intended to guarantee your freedom to share and change free
  1818. software--to make sure the software is free for all its users.  The
  1819. General Public License applies to the Free Software Foundation's
  1820. software and to any other program whose authors commit to using it.
  1821. You can use it for your programs, too.
  1822. X
  1823. X  When we speak of free software, we are referring to freedom, not
  1824. price.  Specifically, the General Public License is designed to make
  1825. sure that you have the freedom to give away or sell copies of free
  1826. software, that you receive source code or can get it if you want it,
  1827. that you can change the software or use pieces of it in new free
  1828. programs; and that you know you can do these things.
  1829. X
  1830. X  To protect your rights, we need to make restrictions that forbid
  1831. anyone to deny you these rights or to ask you to surrender the rights.
  1832. These restrictions translate to certain responsibilities for you if you
  1833. distribute copies of the software, or if you modify it.
  1834. X
  1835. X  For example, if you distribute copies of a such a program, whether
  1836. gratis or for a fee, you must give the recipients all the rights that
  1837. you have.  You must make sure that they, too, receive or can get the
  1838. source code.  And you must tell them their rights.
  1839. X
  1840. X  We protect your rights with two steps: (1) copyright the software, and
  1841. (2) offer you this license which gives you legal permission to copy,
  1842. distribute and/or modify the software.
  1843. X
  1844. X  Also, for each author's protection and ours, we want to make certain
  1845. that everyone understands that there is no warranty for this free
  1846. software.  If the software is modified by someone else and passed on, we
  1847. want its recipients to know that what they have is not the original, so
  1848. that any problems introduced by others will not reflect on the original
  1849. authors' reputations.
  1850. X
  1851. X  The precise terms and conditions for copying, distribution and
  1852. modification follow.
  1853. X
  1854. X            GNU GENERAL PUBLIC LICENSE
  1855. X   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  1856. X
  1857. X  0. This License Agreement applies to any program or other work which
  1858. contains a notice placed by the copyright holder saying it may be
  1859. distributed under the terms of this General Public License.  The
  1860. "Program", below, refers to any such program or work, and a "work based
  1861. on the Program" means either the Program or any work containing the
  1862. Program or a portion of it, either verbatim or with modifications.  Each
  1863. licensee is addressed as "you".
  1864. X
  1865. X  1. You may copy and distribute verbatim copies of the Program's source
  1866. code as you receive it, in any medium, provided that you conspicuously and
  1867. appropriately publish on each copy an appropriate copyright notice and
  1868. disclaimer of warranty; keep intact all the notices that refer to this
  1869. General Public License and to the absence of any warranty; and give any
  1870. other recipients of the Program a copy of this General Public License
  1871. along with the Program.  You may charge a fee for the physical act of
  1872. transferring a copy.
  1873. X
  1874. X  2. You may modify your copy or copies of the Program or any portion of
  1875. it, and copy and distribute such modifications under the terms of Paragraph
  1876. 1 above, provided that you also do the following:
  1877. X
  1878. X    a) cause the modified files to carry prominent notices stating that
  1879. X    you changed the files and the date of any change; and
  1880. X
  1881. X    b) cause the whole of any work that you distribute or publish, that
  1882. X    in whole or in part contains the Program or any part thereof, either
  1883. X    with or without modifications, to be licensed at no charge to all
  1884. X    third parties under the terms of this General Public License (except
  1885. X    that you may choose to grant warranty protection to some or all
  1886. X    third parties, at your option).
  1887. X
  1888. X    c) If the modified program normally reads commands interactively when
  1889. X    run, you must cause it, when started running for such interactive use
  1890. X    in the simplest and most usual way, to print or display an
  1891. X    announcement including an appropriate copyright notice and a notice
  1892. X    that there is no warranty (or else, saying that you provide a
  1893. X    warranty) and that users may redistribute the program under these
  1894. X    conditions, and telling the user how to view a copy of this General
  1895. X    Public License.
  1896. X
  1897. X    d) You may charge a fee for the physical act of transferring a
  1898. X    copy, and you may at your option offer warranty protection in
  1899. X    exchange for a fee.
  1900. X
  1901. Mere aggregation of another independent work with the Program (or its
  1902. derivative) on a volume of a storage or distribution medium does not bring
  1903. the other work under the scope of these terms.
  1904. X
  1905. X  3. You may copy and distribute the Program (or a portion or derivative of
  1906. it, under Paragraph 2) in object code or executable form under the terms of
  1907. Paragraphs 1 and 2 above provided that you also do one of the following:
  1908. X
  1909. X    a) accompany it with the complete corresponding machine-readable
  1910. X    source code, which must be distributed under the terms of
  1911. X    Paragraphs 1 and 2 above; or,
  1912. X
  1913. X    b) accompany it with a written offer, valid for at least three
  1914. X    years, to give any third party free (except for a nominal charge
  1915. X    for the cost of distribution) a complete machine-readable copy of the
  1916. X    corresponding source code, to be distributed under the terms of
  1917. X    Paragraphs 1 and 2 above; or,
  1918. X
  1919. X    c) accompany it with the information you received as to where the
  1920. X    corresponding source code may be obtained.  (This alternative is
  1921. X    allowed only for noncommercial distribution and only if you
  1922. X    received the program in object code or executable form alone.)
  1923. X
  1924. Source code for a work means the preferred form of the work for making
  1925. modifications to it.  For an executable file, complete source code means
  1926. all the source code for all modules it contains; but, as a special
  1927. exception, it need not include source code for modules which are standard
  1928. libraries that accompany the operating system on which the executable
  1929. file runs, or for standard header files or definitions files that
  1930. accompany that operating system.
  1931. X
  1932. X  4. You may not copy, modify, sublicense, distribute or transfer the
  1933. Program except as expressly provided under this General Public License.
  1934. Any attempt otherwise to copy, modify, sublicense, distribute or transfer
  1935. the Program is void, and will automatically terminate your rights to use
  1936. the Program under this License.  However, parties who have received
  1937. copies, or rights to use copies, from you under this General Public
  1938. License will not have their licenses terminated so long as such parties
  1939. remain in full compliance.
  1940. X
  1941. X  5. By copying, distributing or modifying the Program (or any work based
  1942. on the Program) you indicate your acceptance of this license to do so,
  1943. and all its terms and conditions.
  1944. X
  1945. X  6. Each time you redistribute the Program (or any work based on the
  1946. Program), the recipient automatically receives a license from the original
  1947. licensor to copy, distribute or modify the Program subject to these
  1948. terms and conditions.  You may not impose any further restrictions on the
  1949. recipients' exercise of the rights granted herein.
  1950. X
  1951. X  7. The Free Software Foundation may publish revised and/or new versions
  1952. of the General Public License from time to time.  Such new versions will
  1953. be similar in spirit to the present version, but may differ in detail to
  1954. address new problems or concerns.
  1955. X
  1956. Each version is given a distinguishing version number.  If the Program
  1957. specifies a version number of the license which applies to it and "any
  1958. later version", you have the option of following the terms and conditions
  1959. either of that version or of any later version published by the Free
  1960. Software Foundation.  If the Program does not specify a version number of
  1961. the license, you may choose any version ever published by the Free Software
  1962. Foundation.
  1963. X
  1964. X  8. If you wish to incorporate parts of the Program into other free
  1965. programs whose distribution conditions are different, write to the author
  1966. to ask for permission.  For software which is copyrighted by the Free
  1967. Software Foundation, write to the Free Software Foundation; we sometimes
  1968. make exceptions for this.  Our decision will be guided by the two goals
  1969. of preserving the free status of all derivatives of our free software and
  1970. of promoting the sharing and reuse of software generally.
  1971. X
  1972. X                NO WARRANTY
  1973. X
  1974. X  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  1975. FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  1976. OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  1977. PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  1978. OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  1979. MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  1980. TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  1981. PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  1982. REPAIR OR CORRECTION.
  1983. X
  1984. X  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  1985. WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  1986. REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  1987. INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  1988. OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  1989. TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  1990. YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  1991. PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  1992. POSSIBILITY OF SUCH DAMAGES.
  1993. X
  1994. X             END OF TERMS AND CONDITIONS
  1995. X
  1996. X    Appendix: How to Apply These Terms to Your New Programs
  1997. X
  1998. X  If you develop a new program, and you want it to be of the greatest
  1999. possible use to humanity, the best way to achieve this is to make it
  2000. free software which everyone can redistribute and change under these
  2001. terms.
  2002. X
  2003. X  To do so, attach the following notices to the program.  It is safest to
  2004. attach them to the start of each source file to most effectively convey
  2005. the exclusion of warranty; and each file should have at least the
  2006. "copyright" line and a pointer to where the full notice is found.
  2007. X
  2008. X    <one line to give the program's name and a brief idea of what it does.>
  2009. X    Copyright (C) 19yy  <name of author>
  2010. X
  2011. X    This program is free software; you can redistribute it and/or modify
  2012. X    it under the terms of the GNU General Public License as published by
  2013. X    the Free Software Foundation; either version 1, or (at your option)
  2014. X    any later version.
  2015. X
  2016. X    This program is distributed in the hope that it will be useful,
  2017. X    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2018. X    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2019. X    GNU General Public License for more details.
  2020. X
  2021. X    You should have received a copy of the GNU General Public License
  2022. X    along with this program; if not, write to the Free Software
  2023. X    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2024. X
  2025. Also add information on how to contact you by electronic and paper mail.
  2026. X
  2027. If the program is interactive, make it output a short notice like this
  2028. when it starts in an interactive mode:
  2029. X
  2030. X    Gnomovision version 69, Copyright (C) 19xx name of author
  2031. X    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  2032. X    This is free software, and you are welcome to redistribute it
  2033. X    under certain conditions; type `show c' for details.
  2034. X
  2035. The hypothetical commands `show w' and `show c' should show the
  2036. appropriate parts of the General Public License.  Of course, the
  2037. commands you use may be called something other than `show w' and `show
  2038. c'; they could even be mouse-clicks or menu items--whatever suits your
  2039. program.
  2040. X
  2041. You should also get your employer (if you work as a programmer) or your
  2042. school, if any, to sign a "copyright disclaimer" for the program, if
  2043. necessary.  Here a sample; alter the names:
  2044. X
  2045. X  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  2046. X  program `Gnomovision' (a program to direct compilers to make passes
  2047. X  at assemblers) written by James Hacker.
  2048. X
  2049. X  <signature of Ty Coon>, 1 April 1989
  2050. X  Ty Coon, President of Vice
  2051. X
  2052. That's all there is to it!
  2053. SHAR_EOF
  2054. chmod 0600 copying ||
  2055. echo 'restore of copying failed'
  2056. Wc_c="`wc -c < 'copying'`"
  2057. test 12488 -eq "$Wc_c" ||
  2058.     echo 'copying: original size 12488, current size' "$Wc_c"
  2059. fi
  2060. # ============= edfuncs.c ==============
  2061. if test -f 'edfuncs.c' -a X"$1" != X"-c"; then
  2062.     echo 'x - skipping edfuncs.c (File already exists)'
  2063. else
  2064. echo 'x - extracting edfuncs.c (Text)'
  2065. sed 's/^X//' << 'SHAR_EOF' > 'edfuncs.c' &&
  2066. /* User edit functions
  2067. X   Copyright (C) 1992 Joseph H. Allen
  2068. X
  2069. This file is part of JOE (Joe's Own Editor)
  2070. X
  2071. JOE is free software; you can redistribute it and/or modify it under the 
  2072. terms of the GNU General Public License as published by the Free Software 
  2073. Foundation; either version 1, or (at your option) any later version.  
  2074. X
  2075. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  2076. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  2077. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  2078. details.  
  2079. X
  2080. You should have received a copy of the GNU General Public License along with 
  2081. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  2082. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  2083. X
  2084. #include <stdio.h>
  2085. #include "config.h"
  2086. #include "tty.h"
  2087. #include "b.h"
  2088. #include "w.h"
  2089. #include "termcap.h"
  2090. #include "vfile.h"
  2091. #include "toomany.h"
  2092. #include "scrn.h"
  2093. #include "vs.h"
  2094. #include "bw.h"
  2095. #include "pw.h"
  2096. #include "tw.h"
  2097. #include "zstr.h"
  2098. #include "main.h"
  2099. #include "edfuncs.h"
  2100. X
  2101. int square=0;        /* Rectangle mode */
  2102. X
  2103. B *filehist=0;
  2104. B *filthist=0;
  2105. B *linehist=0;
  2106. B *taghist=0;
  2107. X
  2108. char *msgs[]=
  2109. {
  2110. "Error writing file",
  2111. "Error opening file",
  2112. "Error seeking file",
  2113. "Error reading file",
  2114. "New File"
  2115. };
  2116. X
  2117. /****************/
  2118. /* Window stuff */
  2119. /****************/
  2120. X
  2121. void uprevw(w)
  2122. W *w;
  2123. {
  2124. wprev(w->t);
  2125. }
  2126. X
  2127. void unextw(w)
  2128. W *w;
  2129. {
  2130. wnext(w->t);
  2131. }
  2132. X
  2133. void ugroww(w)
  2134. W *w;
  2135. {
  2136. wgrow(w);
  2137. }
  2138. X
  2139. void ushrnk(w)
  2140. W *w;
  2141. {
  2142. wshrink(w);
  2143. }
  2144. X
  2145. void uexpld(w)
  2146. W *w;
  2147. {
  2148. if(w->t->h-w->t->wind==getgrouph(w)) wshowall(w->t);
  2149. else wshowone(w);
  2150. }
  2151. X
  2152. /******************************/
  2153. /* Rectangle mode subroutines */
  2154. /******************************/
  2155. X
  2156. void pfill(p,to,usetabs)
  2157. P *p;
  2158. long to;
  2159. {
  2160. if(usetabs)
  2161. X while(p->col<to)
  2162. X  if(p->col+p->b->tab-p->col%p->b->tab<=to) binsc(p,'\t'), pgetc(p);
  2163. X  else binsc(p,' '), pgetc(p);
  2164. else while(p->col<to) binsc(p,' '), pgetc(p);
  2165. }
  2166. X
  2167. /* Insert rectangle into buffer
  2168. X * returns width of inserted matter
  2169. X */
  2170. X
  2171. long pinsrect(cur,tmp)
  2172. P *cur;
  2173. B *tmp;
  2174. {
  2175. P *p=pdup(cur);
  2176. P *q=pdup(tmp->bof);
  2177. P *r=pdup(q);
  2178. int usetabs=0;
  2179. long width=0;
  2180. do
  2181. X {
  2182. X long wid=cur->col;
  2183. X while(!piseol(q))
  2184. X  if(pgetc(q)=='\t') wid+=cur->b->tab-wid%cur->b->tab, usetabs=1;
  2185. X  else ++wid;
  2186. X if(wid-cur->col>width) width=wid-cur->col;
  2187. X } while(pgetc(q)!=MAXINT);
  2188. if(width)
  2189. X {
  2190. X pset(q,tmp->bof);
  2191. X while(pset(r,q), peol(q), (q->line!=tmp->eof->line || q->col))
  2192. X  {
  2193. X  pcol(p,cur->col);
  2194. X  if(p->col<cur->col) pfill(p,cur->col,usetabs);
  2195. X  binsb(p,r,q); pfwrd(p,q->byte-r->byte);
  2196. X  if(p->col<cur->col+width) pfill(p,cur->col+width,usetabs);
  2197. X  if(!pnextl(p)) binsc(p,'\n'), pgetc(p);
  2198. X  if(pgetc(q)==MAXINT) break;
  2199. X  }
  2200. X }
  2201. prm(p); prm(q); prm(r);
  2202. return width;
  2203. }
  2204. X
  2205. /* Overwrite version of above */
  2206. X
  2207. long povrrect(cur,tmp)
  2208. P *cur;
  2209. B *tmp;
  2210. {
  2211. P *p=pdup(cur);
  2212. P *q=pdup(tmp->bof);
  2213. P *r=pdup(q);
  2214. P *z=pdup(cur);
  2215. int usetabs=0;
  2216. long width=0;
  2217. long curcol=cur->col;
  2218. do
  2219. X {
  2220. X long wid=curcol;
  2221. X while(!piseol(q))
  2222. X  if(pgetc(q)=='\t') wid+=cur->b->tab-wid%cur->b->tab, usetabs=1;
  2223. X  else ++wid;
  2224. X if(wid-curcol>width) width=wid-curcol;
  2225. X } while(pgetc(q)!=MAXINT);
  2226. if(width)
  2227. X {
  2228. X pset(q,tmp->bof);
  2229. X while(pset(r,q), peol(q), (q->line!=tmp->eof->line || q->col))
  2230. X  {
  2231. X  pcol(p,curcol);
  2232. X  if(p->col<curcol) pfill(p,curcol,usetabs);
  2233. X  pset(z,p); pcol(z,curcol+width); bdel(p,z);
  2234. X  binsb(p,r,q); pfwrd(p,q->byte-r->byte);
  2235. X  if(p->col<curcol+width) pfill(p,curcol+width,usetabs);
  2236. X  if(!pnextl(p)) binsc(p,'\n'), pgetc(p);
  2237. X  if(pgetc(q)==MAXINT) break;
  2238. X  }
  2239. X }
  2240. prm(p); prm(q); prm(r); prm(z);
  2241. return width;
  2242. }
  2243. X
  2244. /* Extract rectangle into a buffer */
  2245. X
  2246. B *pextrect(up,down,left,right)
  2247. P *up, *down;
  2248. long left,right;
  2249. {
  2250. P *p=pdup(up);
  2251. P *q=pdup(p);
  2252. B *tmp=bmk();
  2253. P *z=pdup(tmp->eof);
  2254. pbol(p);
  2255. do
  2256. X {
  2257. X pcol(p,left);
  2258. X pset(q,p);
  2259. X pcol(q,right);
  2260. X pset(z,tmp->eof); binsb(z,p,q);
  2261. X pset(z,tmp->eof); binsc(z,'\n');
  2262. X } while(pnextl(p) && p->line<=down->line);
  2263. prm(p); prm(q); prm(z);
  2264. return tmp;
  2265. }
  2266. X
  2267. /* Delete rectangle.  Returns true if tabs were used */
  2268. X
  2269. int pdelrect(up,down,left,right,overtype)
  2270. P *up, *down;
  2271. long left,right;
  2272. {
  2273. P *p=pdup(up);
  2274. P *q=pdup(p);
  2275. int usetabs=0;
  2276. if(overtype)
  2277. X {
  2278. X int c;
  2279. X pbol(p);
  2280. X do
  2281. X  {
  2282. X  pcol(p,left);
  2283. X  pset(q,p);
  2284. X  pcol(q,right);
  2285. X  while(p->byte<q->byte) if(pgetc(p)=='\t') { usetabs=1; break; }
  2286. X  if(usetabs) break;
  2287. X  } while(pnextl(p) && p->line<=down->line);
  2288. X pset(p,up);
  2289. X }
  2290. pbol(p);
  2291. do
  2292. X {
  2293. X pcol(p,left);
  2294. X pset(q,p);
  2295. X pcol(q,right);
  2296. X bdel(p,q);
  2297. X if(overtype) pfill(p,right,usetabs);
  2298. X } while(pnextl(p) && p->line<=down->line);
  2299. prm(p); prm(q);
  2300. return usetabs;
  2301. }
  2302. X
  2303. /***************/
  2304. /* Block stuff */
  2305. /***************/
  2306. X
  2307. void umarkb(w)
  2308. W *w;
  2309. {
  2310.