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

  1. Newsgroups: alt.sources
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!hamblin.math.byu.edu!news.byu.edu!eff!world!jhallen
  3. From: jhallen@world.std.com (Joseph H Allen)
  4. Subject: JOE 1.0.5 Part 5 of 10
  5. Message-ID: <By2MJv.Kyq@world.std.com>
  6. Organization: The World Public Access UNIX, Brookline, MA
  7. Date: Sat, 21 Nov 1992 14:50:19 GMT
  8. Lines: 2303
  9.  
  10. Submitted-by: jhallen@world.std.com
  11. Archive-name: joe1.0.5part5
  12.  
  13. X  }
  14. X else execmd(m->n,m->k);
  15. if(leave) return;
  16. if(flg) umclear();
  17. X
  18. undomark();
  19. }
  20. X
  21. void exemac(m)
  22. MACRO *m;
  23. {
  24. record(m);
  25. exmacro(m);
  26. }
  27. X
  28. static int eungotten;
  29. static int eungottenc;
  30. X
  31. static CONTEXT *cntxts[]= { &cmain, &cprmpt,&cttab,&cfprmpt,&cthelp,0 };
  32. X
  33. void eungetc(c)
  34. {
  35. if(c==MAXINT) return;
  36. if(curmacro)
  37. X {
  38. X --macroptr;
  39. X return;
  40. X }
  41. else
  42. X {
  43. X eungotten=1;
  44. X eungottenc=c;
  45. X unmac();
  46. X }
  47. }
  48. X
  49. int dengetc()
  50. {
  51. int c;
  52. if(eungotten)
  53. X {
  54. X eungotten=0;
  55. X c=eungottenc;
  56. X }
  57. else c=ngetc(maint->t);
  58. return c;
  59. }
  60. X
  61. int engetc()
  62. {
  63. MACRO *m;
  64. int c;
  65. if(eungotten)
  66. X {
  67. X eungotten=0;
  68. X c=eungottenc;
  69. X }
  70. else if(curmacro)
  71. X {
  72. X if(curmacro->n!=macroptr && !curmacro->steps[macroptr]->steps &&
  73. X    curmacro->steps[macroptr]->n==typen) c=curmacro->steps[macroptr++]->k;
  74. X else c=MAXINT;
  75. X }
  76. else c=ngetc(maint->t);
  77. record(m=mkmacro(c,1,typen)); rmmacro(m);
  78. return c;
  79. }
  80. X
  81. void edupd()
  82. {
  83. W *w;
  84. dofollows();
  85. ttflsh();
  86. nscroll(maint->t);
  87. dsphlp(maint);
  88. w=maint->curwin; do
  89. X {
  90. X if(w->y!= -1)
  91. X  {
  92. X  w->watom->disp(w);
  93. X  if(w->msgb)
  94. X   {
  95. X   msgout(w->t->t,w->y+w->h-1,w->msgb);
  96. X   w->msgb=0;
  97. X   w->t->t->updtab[w->y+w->h-1]=1;
  98. X   }
  99. X  if(w->msgt)
  100. X   {
  101. X   int y=w->h>1?1:0;
  102. X   msgout(w->t->t,w->y+y,w->msgt);
  103. X   w->msgt=0;
  104. X   w->t->t->updtab[w->y+y]=1;
  105. X   }
  106. X  }
  107. X w=(W *)(w->link.next);
  108. X }
  109. X while(w!=maint->curwin);
  110. cpos(maint->t,
  111. X     maint->curwin->x+maint->curwin->curx,
  112. X     maint->curwin->y+maint->curwin->cury);
  113. }
  114. X
  115. int edgetc()
  116. {
  117. edupd();
  118. return engetc();
  119. }
  120. X
  121. int dedgetc()
  122. {
  123. edupd();
  124. return dengetc();
  125. }
  126. X
  127. int main(argc,argv)
  128. int argc;
  129. char *argv[];
  130. {
  131. char *s;
  132. SCRN *n;
  133. W *w;
  134. int c;
  135. P *p;
  136. typen=findcmd(&cmdtab,"type");
  137. if(prokbd(".joerc",cntxts))
  138. X {
  139. X s=getenv("HOME");
  140. X if(!s) goto in;
  141. X s=vsncpy(NULL,0,sz(s));
  142. X s=vsncpy(s,sLEN(s),sc("/.joerc"));
  143. X if(prokbd(s,cntxts))
  144. X  {
  145. X  in:;
  146. X  if(prokbd(s=JOERC,cntxts))
  147. X   {
  148. X   fprintf(stderr,"Couldn\'t open keymap file \'%s\'\n",s);
  149. X   return 1;
  150. X   }
  151. X  }
  152. X }
  153. if(!(n=nopen())) return 1;
  154. maint=screate(n);
  155. X
  156. if(argc<2)
  157. X {
  158. X W *w=wmktw(maint,bmk());
  159. X BW *bw=(BW *)w->object;
  160. X setoptions(bw,"");
  161. X }
  162. else
  163. X {
  164. X long lnum;
  165. X int omid;
  166. X for(c=1,lnum=0;argv[c];++c)
  167. X  if(argv[c][0]=='+' && argv[c][1])
  168. X   {
  169. X   lnum=0;
  170. X   sscanf(argv[c]+1,"%ld",&lnum);
  171. X   if(lnum) --lnum;
  172. X   }
  173. X  else
  174. X   {
  175. X   B *b=bfind(argv[c]);
  176. X   BW *bw;
  177. X   int fl=0;
  178. X   if(!b)
  179. X    {
  180. X    b=bmk();
  181. X    fl=bload(b,argv[c]);
  182. X    }
  183. X   w=wmktw(maint,b);
  184. X   if(fl) w->msgt=msgs[5+fl];
  185. X   bw=(BW *)w->object;
  186. X   setoptions(bw,argv[c]);
  187. X   pline(bw->cursor,lnum);
  188. X   lnum=0;
  189. X   }
  190. X wshowall(maint);
  191. X omid=mid; mid=1;
  192. X dofollows();
  193. X mid=omid;
  194. X }
  195. if(help) helpon(maint);
  196. msgnw(lastw(maint),"\\i** Joe's Own Editor v1.0.5 ** Copyright (C) 1992 Joseph H. Allen **\\i");
  197. do
  198. X {
  199. X int wid,hei;
  200. X MACRO *m=dokey(maint->curwin->kbd,dedgetc());
  201. X ttgtsz(&wid,&hei);
  202. X if(wid>=2 && wid!=maint->w ||
  203. X    hei>=1 && hei!=maint->h)
  204. X  {
  205. X  nresize(maint->t,wid,hei);
  206. X  sresize(maint);
  207. X  }
  208. X if(m) exemac(m);
  209. X }
  210. X while(!leave);
  211. nclose(n);
  212. if(exmsg) fprintf(stderr,"\n%s\n",exmsg);
  213. return 0;
  214. }
  215. SHAR_EOF
  216. chmod 0600 main.c ||
  217. echo 'restore of main.c failed'
  218. Wc_c="`wc -c < 'main.c'`"
  219. test 10617 -eq "$Wc_c" ||
  220.     echo 'main.c: original size 10617, current size' "$Wc_c"
  221. fi
  222. # ============= main.h ==============
  223. if test -f 'main.h' -a X"$1" != X"-c"; then
  224.     echo 'x - skipping main.h (File already exists)'
  225. else
  226. echo 'x - extracting main.h (Text)'
  227. sed 's/^X//' << 'SHAR_EOF' > 'main.h' &&
  228. /* Editor startup and edit loop
  229. X   Copyright (C) 1992 Joseph H. Allen
  230. X
  231. This file is part of JOE (Joe's Own Editor)
  232. X
  233. JOE is free software; you can redistribute it and/or modify it under the 
  234. terms of the GNU General Public License as published by the Free Software 
  235. Foundation; either version 1, or (at your option) any later version.  
  236. X
  237. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  238. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  239. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  240. details.  
  241. X
  242. You should have received a copy of the GNU General Public License along with 
  243. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  244. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  245. X
  246. #ifndef _Imain
  247. #define _Imain 1
  248. X
  249. #include "config.h"
  250. #include "w.h"
  251. X
  252. #include "config.h"
  253. X
  254. extern char *exmsg;        /* Exit message */
  255. extern int help;
  256. extern SCREEN *maint;        /* Primary screen */
  257. X
  258. void eungetc();        /* Unget a character into editor kbd input */
  259. void edupd();
  260. int edgetc();        /* Get kbd character / refresh screen */
  261. int engetc();        /* Get kbd character */
  262. X
  263. #endif
  264. SHAR_EOF
  265. chmod 0600 main.h ||
  266. echo 'restore of main.h failed'
  267. Wc_c="`wc -c < 'main.h'`"
  268. test 1140 -eq "$Wc_c" ||
  269.     echo 'main.h: original size 1140, current size' "$Wc_c"
  270. fi
  271. # ============= makefile ==============
  272. if test -f 'makefile' -a X"$1" != X"-c"; then
  273.     echo 'x - skipping makefile (File already exists)'
  274. else
  275. echo 'x - extracting makefile (Text)'
  276. sed 's/^X//' << 'SHAR_EOF' > 'makefile' &&
  277. # Makefile for Joe's Own Editor
  278. X
  279. CC = cc
  280. CFLAGS = -O -D_HPUX_SOURCE -DJOERC=\"/usr/local/lib/joerc\"
  281. OBJS = main.o termcap.o vfile.o pathfunc.o queue.o blocks.o vs.o va.o scrn.o \
  282. X       b.o bw.o tw.o pw.o help.o heap.o toomany.o queue.o zstr.o edfuncs.o \
  283. X       kbd.o w.o reg.o tab.o pattern.o random.o regex.o undo.o menu.o macro.o \
  284. X       poshist.o
  285. X
  286. foo:
  287. X    @echo Type make followed by one of the following
  288. X    @echo
  289. X    @echo bsd hpux xenix sv posix termidx install clean
  290. X
  291. xenix: $(OBJS) ttyxenix.o olddir.o
  292. X    $(CC) $(CFLAGS) -o joe $(OBJS) ttyxenix.o olddir.o -lx
  293. X
  294. posix: $(OBJS) ttyposix.o
  295. X    $(CC) $(CFLAGS) -o joe $(OBJS) ttyposix.o
  296. X
  297. bsd: $(OBJS) ttybsd.o
  298. X    $(CC) $(CFLAGS) -o joe $(OBJS) ttybsd.o
  299. X
  300. sv: $(OBJS) ttysv.o
  301. X    $(CC) $(CFLAGS) -o joe $(OBJS) ttysv.o
  302. X
  303. hpux: $(OBJS) ttyhpux.o
  304. X    $(CC) $(CFLAGS) -o joe $(OBJS) ttyhpux.o
  305. X
  306. termidx: termidx.o
  307. X    $(CC) $(CFLAGS) -o termidx termidx.o
  308. X
  309. install: joe termidx
  310. X    strip joe
  311. X    strip termidx
  312. X    mv joe /usr/local/bin
  313. X    cp joerc /usr/local/lib/joerc
  314. X    mv termidx /usr/local/bin
  315. X    chmod a+x /usr/local/bin/joe
  316. X    chmod a+r /usr/local/lib/joerc
  317. X    chmod a+x /usr/local/bin/termidx
  318. X
  319. clean:
  320. X    rm -f $(OBJS) ttyxenix.o ttyposix.o ttybsd.o ttyhpux.o ttysv.o
  321. SHAR_EOF
  322. chmod 0600 makefile ||
  323. echo 'restore of makefile failed'
  324. Wc_c="`wc -c < 'makefile'`"
  325. test 1179 -eq "$Wc_c" ||
  326.     echo 'makefile: original size 1179, current size' "$Wc_c"
  327. fi
  328. # ============= menu.c ==============
  329. if test -f 'menu.c' -a X"$1" != X"-c"; then
  330.     echo 'x - skipping menu.c (File already exists)'
  331. else
  332. echo 'x - extracting menu.c (Text)'
  333. sed 's/^X//' << 'SHAR_EOF' > 'menu.c' &&
  334. /* Menu selection window
  335. X   Copyright (C) 1992 Joseph H. Allen
  336. X
  337. This file is part of JOE (Joe's Own Editor)
  338. X
  339. JOE is free software; you can redistribute it and/or modify it under the 
  340. terms of the GNU General Public License as published by the Free Software 
  341. Foundation; either version 1, or (at your option) any later version.  
  342. X
  343. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  344. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  345. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  346. details.  
  347. X
  348. You should have received a copy of the GNU General Public License along with 
  349. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  350. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  351. X
  352. #include "config.h"
  353. #include "heap.h"
  354. #include "scrn.h"
  355. #include "vs.h"
  356. #include "va.h"
  357. #include "menu.h"
  358. X
  359. void menufllw(m)
  360. MENU *m;
  361. {
  362. m->top=m->cursor-m->cursor%m->perline;
  363. }
  364. X
  365. void menugen(m)
  366. MENU *m;
  367. {
  368. int col;
  369. int x;
  370. int *s=m->t->t->scrn+m->x+m->y*m->t->t->co;
  371. col=0;
  372. for(x=0;x!=m->perline && m->list[x+m->top];++x)
  373. X {
  374. X int atr,z;
  375. X if(x+m->top==m->cursor) atr=INVERSE;
  376. X else atr=0;
  377. X if(col==m->w) break;
  378. X for(z=0;m->list[x+m->top][z];++z)
  379. X  {
  380. X  if(col==m->w) break;
  381. X  if(s[col]!=(unsigned char)m->list[x+m->top][z]+atr)
  382. X   {
  383. X   s[col]=(unsigned char)m->list[x+m->top][z]+atr;
  384. X   outatr(m->t->t,m->x+col,m->y,s[col]);
  385. X   }
  386. X  ++col;
  387. X  }
  388. X while(z<m->width)
  389. X  {
  390. X  if(col==m->w) break;
  391. X  if(s[col]!=' ')
  392. X   s[col]=' ', outatr(m->t->t,m->x+col,m->y,' ');
  393. X  ++col; ++z;
  394. X  }
  395. X if(col!=m->w)
  396. X  {
  397. X  if(s[col]!=' ')
  398. X   s[col]=' ', outatr(m->t->t,m->x+col,m->y,' ');
  399. X  ++col;
  400. X  }
  401. X }
  402. if(col!=m->w) eraeol(m->t->t,m->x+col,m->y);
  403. }
  404. X
  405. void menumove(m,x,y)
  406. MENU *m;
  407. {
  408. m->x=x;
  409. m->y=y;
  410. }
  411. X
  412. void menuresz(m,wi,he)
  413. MENU *m;
  414. {
  415. m->w=wi;
  416. m->h=he;
  417. }
  418. X
  419. void mconfig(m)
  420. MENU *m;
  421. {
  422. /* Configure menu display parameters */
  423. int x;
  424. for(x=0,m->width=0;m->list[x];++x)
  425. X if(zlen(m->list[x])>m->width) m->width=zlen(m->list[x]);
  426. if(m->width>m->w) m->width=m->w-1;
  427. m->perline=m->w/(m->width+1);
  428. }
  429. X
  430. MENU *mkmenu(t,s,x,y,wi,h)
  431. SCREEN *t;
  432. char **s;
  433. {
  434. MENU *m=(MENU *)malloc(sizeof(MENU));
  435. m->list=s;
  436. m->top=0;
  437. m->cursor=0;
  438. m->t=t;
  439. m->h=h; m->w=wi; m->x=x; m->y=y;
  440. m->object=0;
  441. mconfig(m);
  442. return m;
  443. }
  444. X
  445. void menurm(m)
  446. MENU *m;
  447. {
  448. free(m);
  449. }
  450. X
  451. void mbol(m)
  452. MENU *m;
  453. {
  454. m->cursor=m->top;
  455. }
  456. X
  457. void mbof(m)
  458. MENU *m;
  459. {
  460. m->cursor=0;
  461. }
  462. X
  463. void meof(m)
  464. MENU *m;
  465. {
  466. if(aLEN(m->list)) m->cursor=aLEN(m->list)-1;
  467. }
  468. X
  469. void meol(m)
  470. MENU *m;
  471. {
  472. if(m->top+m->perline<aLEN(m->list))
  473. X m->cursor=m->top+m->perline-1;
  474. else meof(m);
  475. }
  476. X
  477. void mrtarw(m)
  478. MENU *m;
  479. {
  480. if(m->cursor+1<aLEN(m->list)) ++m->cursor;
  481. }
  482. X
  483. void mltarw(m)
  484. MENU *m;
  485. {
  486. if(m->cursor) --m->cursor;
  487. }
  488. X
  489. void muparw(m)
  490. MENU *m;
  491. {
  492. if(m->cursor>=m->perline) m->cursor-=m->perline;
  493. }
  494. X
  495. void mdnarw(m)
  496. MENU *m;
  497. {
  498. if(m->cursor+m->perline<aLEN(m->list)) m->cursor+=m->perline;
  499. else if(m->top+m->perline<aLEN(m->list)) meof(m);
  500. }
  501. SHAR_EOF
  502. chmod 0600 menu.c ||
  503. echo 'restore of menu.c failed'
  504. Wc_c="`wc -c < 'menu.c'`"
  505. test 2874 -eq "$Wc_c" ||
  506.     echo 'menu.c: original size 2874, current size' "$Wc_c"
  507. fi
  508. # ============= menu.h ==============
  509. if test -f 'menu.h' -a X"$1" != X"-c"; then
  510.     echo 'x - skipping menu.h (File already exists)'
  511. else
  512. echo 'x - extracting menu.h (Text)'
  513. sed 's/^X//' << 'SHAR_EOF' > 'menu.h' &&
  514. /* Menu selection window
  515. X   Copyright (C) 1992 Joseph H. Allen
  516. X
  517. This file is part of JOE (Joe's Own Editor)
  518. X
  519. JOE is free software; you can redistribute it and/or modify it under the 
  520. terms of the GNU General Public License as published by the Free Software 
  521. Foundation; either version 1, or (at your option) any later version.  
  522. X
  523. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  524. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  525. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  526. details.  
  527. X
  528. You should have received a copy of the GNU General Public License along with 
  529. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  530. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  531. X
  532. #ifndef _Imenu
  533. #define _Imenu 1
  534. X
  535. #include "config.h"
  536. #include "w.h"
  537. X
  538. typedef struct menu MENU;
  539. X
  540. struct menu
  541. X {
  542. X char **list;        /* List of items */
  543. X int top;        /* First item on screen */
  544. X int cursor;        /* Item cursor is on */
  545. X int width;        /* Width of widest item, up to 'w' max */
  546. X int perline;        /* Number of items on each line */
  547. X SCREEN *t;
  548. X int h,w,x,y;
  549. X void *object;
  550. X };
  551. X
  552. MENU *mkmenu();
  553. void menufllw();
  554. void menugen();
  555. void menumove();
  556. void menuresz();
  557. void menurm();
  558. X
  559. void muparw(), mdnarw(), mltarw(), mrtarw(), mbof(), meof(), mbol(), meol();
  560. X
  561. #endif
  562. SHAR_EOF
  563. chmod 0600 menu.h ||
  564. echo 'restore of menu.h failed'
  565. Wc_c="`wc -c < 'menu.h'`"
  566. test 1318 -eq "$Wc_c" ||
  567.     echo 'menu.h: original size 1318, current size' "$Wc_c"
  568. fi
  569. # ============= msdir.c ==============
  570. if test -f 'msdir.c' -a X"$1" != X"-c"; then
  571.     echo 'x - skipping msdir.c (File already exists)'
  572. else
  573. echo 'x - extracting msdir.c (Text)'
  574. sed 's/^X//' << 'SHAR_EOF' > 'msdir.c' &&
  575. /* TURBO-C directory interface
  576. X   Copyright (C) 1992 Joseph H. Allen
  577. X
  578. This file is part of JOE (Joe's Own Editor)
  579. X
  580. JOE is free software; you can redistribute it and/or modify it under the 
  581. terms of the GNU General Public License as published by the Free Software 
  582. Foundation; either version 1, or (at your option) any later version.  
  583. X
  584. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  585. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  586. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  587. details.  
  588. X
  589. You should have received a copy of the GNU General Public License along with 
  590. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  591. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  592. X
  593. #include "config.h"
  594. #include "heap.h"
  595. #include "zstr.h"
  596. #include "blocks.h"
  597. #include "dir.h"
  598. X
  599. int findfirst();
  600. int findnext();
  601. X
  602. struct ffblk
  603. X {
  604. X char ff_reserved[21];
  605. X char ff_attrib;
  606. X int ff_ftime;
  607. X int ff_fdate;
  608. X long ff_fsize;
  609. X char ff_name[13];
  610. X };
  611. X
  612. struct duh
  613. X {
  614. X struct ffblk ffblk;
  615. X int first;
  616. X };
  617. X
  618. void *opendir(name)
  619. char *name;
  620. {
  621. struct duh *duh=(struct duh *)malloc(sizeof(struct duh));
  622. duh->first=findfirst("*.*",&duh->ffblk,0);
  623. return duh;
  624. }
  625. X
  626. void closedir(f)
  627. struct duh *f;
  628. {
  629. free(f);
  630. }
  631. X
  632. struct direct *readdir(f)
  633. struct duh *f;
  634. {
  635. static struct direct direct;
  636. while(f->first!= -1)
  637. X if(!f->first)
  638. X  {
  639. X  zcpy(direct.d_name,f->ffblk.ff_name);
  640. X  f->first=1;
  641. X  return &direct;
  642. X  }
  643. X else f->first=findnext(&f->ffblk);
  644. return 0;
  645. }
  646. SHAR_EOF
  647. chmod 0600 msdir.c ||
  648. echo 'restore of msdir.c failed'
  649. Wc_c="`wc -c < 'msdir.c'`"
  650. test 1505 -eq "$Wc_c" ||
  651.     echo 'msdir.c: original size 1505, current size' "$Wc_c"
  652. fi
  653. # ============= olddir.c ==============
  654. if test -f 'olddir.c' -a X"$1" != X"-c"; then
  655.     echo 'x - skipping olddir.c (File already exists)'
  656. else
  657. echo 'x - extracting olddir.c (Text)'
  658. sed 's/^X//' << 'SHAR_EOF' > 'olddir.c' &&
  659. /* Directory package for older UNIXs
  660. X   Copyright (C) 1992 Joseph H. Allen
  661. X
  662. This file is part of JOE (Joe's Own Editor)
  663. X
  664. JOE is free software; you can redistribute it and/or modify it under the 
  665. terms of the GNU General Public License as published by the Free Software 
  666. Foundation; either version 1, or (at your option) any later version.  
  667. X
  668. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  669. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  670. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  671. details.  
  672. X
  673. You should have received a copy of the GNU General Public License along with 
  674. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  675. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  676. X
  677. #include <stdio.h>
  678. #include <sys/types.h>
  679. #include <sys/dir.h>    /* If this doesn't exist, use: */
  680. /* You'll also have to include in each module which uses these directory
  681. X * functions
  682. struct direct
  683. X {
  684. X short d_ino;
  685. X char d_name[14];
  686. X };
  687. */
  688. #include "config.h"
  689. #include "vs.h"
  690. X
  691. void *opendir(name)
  692. char *name;
  693. {
  694. return fopen(name,"r");
  695. }
  696. X
  697. static struct direct direct;
  698. X
  699. struct direct *readdir(f)
  700. void *f;
  701. {
  702. while(1==fread(&direct,sizeof(struct direct),1,(FILE *)f))
  703. X if(direct.d_ino) return &direct;
  704. return 0;
  705. }
  706. X
  707. void closedir(f)
  708. FILE *f;
  709. {
  710. fclose(f);
  711. }
  712. X
  713. int mkdir(s)
  714. char *s;
  715. {
  716. char *y=0;
  717. int rtval;
  718. y=vsncpy(y,0,sc("/bin/mkdir "));
  719. y=vsncpy(y,sLEN(y),sz(s));
  720. y=vsncpy(y,sLEN(y),sc(" 2>/dev/null"));
  721. rtval=system(y);
  722. vsrm(y);
  723. return rtval;
  724. }
  725. SHAR_EOF
  726. chmod 0600 olddir.c ||
  727. echo 'restore of olddir.c failed'
  728. Wc_c="`wc -c < 'olddir.c'`"
  729. test 1513 -eq "$Wc_c" ||
  730.     echo 'olddir.c: original size 1513, current size' "$Wc_c"
  731. fi
  732. # ============= pathfunc.c ==============
  733. if test -f 'pathfunc.c' -a X"$1" != X"-c"; then
  734.     echo 'x - skipping pathfunc.c (File already exists)'
  735. else
  736. echo 'x - extracting pathfunc.c (Text)'
  737. sed 's/^X//' << 'SHAR_EOF' > 'pathfunc.c' &&
  738. /* Directory and path functions
  739. X   Copyright (C) 1992 Joseph H. Allen
  740. X
  741. This file is part of JOE (Joe's Own Editor)
  742. X
  743. JOE is free software; you can redistribute it and/or modify it under the 
  744. terms of the GNU General Public License as published by the Free Software 
  745. Foundation; either version 1, or (at your option) any later version.  
  746. X
  747. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  748. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  749. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  750. details.  
  751. X
  752. You should have received a copy of the GNU General Public License along with 
  753. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  754. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  755. X
  756. #include <stdio.h>
  757. #include "config.h"
  758. #include "vs.h"
  759. #include "tty.h"
  760. #include "pathfunc.h"
  761. X
  762. char *abspth(path)
  763. char *path;
  764. {
  765. char *s=0;
  766. int x=0;
  767. int y;
  768. if(path[0]=='/')
  769. X {
  770. X s=vsadd(s,'/');
  771. X while(path[x]=='/') x++;
  772. X y=1;
  773. X }
  774. else
  775. X {
  776. X if(!(s=pwd())) return 0;
  777. X s=vsncpy(NULL,0,sz(s));
  778. X if(s[1]) s=vsadd(s,'/');
  779. X y=sLEN(s);
  780. X }
  781. while(path[x])
  782. X {
  783. X if(path[x]=='.' && (path[x+1]==0 || path[x+1]=='/'))
  784. X  {
  785. X  x++;
  786. X  while(path[x]=='/') x++;
  787. X  continue;
  788. X  }
  789. X if(path[x]=='.' && path[x+1]=='.' &&
  790. X    (path[x+2]==0 || path[x+2]=='/'))
  791. X  {
  792. X  x+=2;
  793. X  while(path[x]=='/') x++;
  794. X  if(y!=1)
  795. X   {
  796. X   --y;
  797. X   while(s[y-1]!='/') --y;
  798. X   }
  799. X  continue;
  800. X  }
  801. X do
  802. X  s=vsset(s,y,path[x]), ++y, ++x;
  803. X  while(path[x] && path[x]!='/');
  804. X s=vsset(s,y,'/'), ++y;
  805. X while(path[x]=='/') x++;
  806. X }
  807. if(y!=1 && s[y-1]=='/') --y;
  808. s=vstrunc(s,y);
  809. return s;
  810. }
  811. X
  812. char *namprt(path)
  813. char *path;
  814. {
  815. char *z=path+slen(path);
  816. while(z!=path)
  817. X if(z[-1]=='/') break;
  818. X else --z;
  819. return vsncpy(NULL,0,sz(z));
  820. }
  821. X
  822. char *dirprt(path)
  823. char *path;
  824. {
  825. char *z=path+slen(path);
  826. while(z!=path)
  827. X if(*(z-1)=='/') break;
  828. X else --z;
  829. return vsncpy(NULL,0,path,z-path);
  830. }
  831. X
  832. char *begprt(path)
  833. char *path;
  834. {
  835. char *z=path+slen(path);
  836. while(z!=path && z[-1]=='/') --z;
  837. if(z==path) return vsncpy(NULL,0,sz(path));
  838. else
  839. X {
  840. X while(z!=path)
  841. X  if(z[-1]=='/') break;
  842. X  else --z;
  843. X return vsncpy(NULL,0,path,z-path);
  844. X }
  845. }
  846. X
  847. char *endprt(path)
  848. char *path;
  849. {
  850. char *z=path+slen(path);
  851. while(z!=path && z[-1]=='/') --z;
  852. if(z==path) return vsncpy(NULL,0,sc(""));
  853. else
  854. X {
  855. X while(z!=path)
  856. X  if(z[-1]=='/') break;
  857. X  else --z;
  858. X return vsncpy(NULL,0,sz(z));
  859. X }
  860. }
  861. X
  862. int mkpath(path)
  863. char *path;
  864. {
  865. char *s;
  866. if(path[0]=='/')
  867. X {
  868. X if(chddir("/")) return 1;
  869. X s=path;
  870. X goto in;
  871. X }
  872. while(path[0])
  873. X {
  874. X int c;
  875. X while(*s && *s!='/') s++;
  876. X c= *s; *s=0;
  877. X if(chddir(path))
  878. X  {
  879. X  if(mkdir(path,0777)) return 1;
  880. X  if(chddir(path)) return 1;
  881. X  }
  882. X *s=c;
  883. X in:
  884. X while(*s=='/') s++;
  885. X path=s;
  886. X }
  887. return 0;
  888. }
  889. X
  890. /* Create a temporary file */
  891. X
  892. char *mktmp(where)
  893. char *where;
  894. {
  895. static int seq=0;
  896. char *name=0;
  897. int fd;
  898. loop:
  899. name=vsfmt(name,"%sJ%d%d.tmp",where,seq++%1000,(int)time(NULL)%1000);
  900. if((fd=open(name,0))!= -1)
  901. X {
  902. X close(fd);
  903. X goto loop;
  904. X }
  905. if((fd=creat(name,0777))== -1) return 0;
  906. if(close(fd)) return 0;
  907. return name;
  908. }
  909. SHAR_EOF
  910. chmod 0600 pathfunc.c ||
  911. echo 'restore of pathfunc.c failed'
  912. Wc_c="`wc -c < 'pathfunc.c'`"
  913. test 2984 -eq "$Wc_c" ||
  914.     echo 'pathfunc.c: original size 2984, current size' "$Wc_c"
  915. fi
  916. # ============= pathfunc.h ==============
  917. if test -f 'pathfunc.h' -a X"$1" != X"-c"; then
  918.     echo 'x - skipping pathfunc.h (File already exists)'
  919. else
  920. echo 'x - extracting pathfunc.h (Text)'
  921. sed 's/^X//' << 'SHAR_EOF' > 'pathfunc.h' &&
  922. /* Directory and path functions
  923. X   Copyright (C) 1992 Joseph H. Allen
  924. X
  925. This file is part of JOE (Joe's Own Editor)
  926. X
  927. JOE is free software; you can redistribute it and/or modify it under the 
  928. terms of the GNU General Public License as published by the Free Software 
  929. Foundation; either version 1, or (at your option) any later version.  
  930. X
  931. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  932. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  933. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  934. details.  
  935. X
  936. You should have received a copy of the GNU General Public License along with 
  937. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  938. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  939. X
  940. #ifndef _Ipathfunc
  941. #define _Ipathfunc
  942. X
  943. #include "config.h"
  944. X
  945. /* These comments aren't quite right: no drive and no conversion to lower
  946. X * case for UNIX systems...
  947. X */
  948. X
  949. /* char *abspth(char *path);
  950. X * Convert given path into an absolute path (a path beginning with a drive
  951. X * letter and ":\" and with no "."s or ".."s).
  952. X *
  953. X * This can be used to check if two paths refer to the same file:  Convert the
  954. X * two paths into absolute paths and then compare the absolute paths.
  955. X *
  956. X * Also, this can be used to get the current drive and directory:
  957. X * Use abspath("")
  958. X *
  959. X * Or, to get the current directory on another drive:  Use abspath("a:")
  960. X *
  961. X * Returns an malloc block containing the absolute path string or
  962. X * 0 if the given path was in error or if couldn't read the current
  963. X * directory (because the floppy was removed from the drive).
  964. X */
  965. char *abspth();
  966. X
  967. /* char *namprt(char *path);
  968. X * Return name part of a path.  There may not be one if the last character
  969. X * in the path is '/'.
  970. X */
  971. char *namprt();
  972. X
  973. /* char *dirprt(char *path);
  974. X * Return directory and drive part of a path.  I.E., everything to the
  975. X * left of the name part.
  976. X */
  977. char *dirprt();
  978. X
  979. char *begprt();
  980. char *endprt();
  981. X
  982. /* int mkpath(char *path);
  983. X * Make sure path exists.  If it doesn't, try to create it
  984. X *
  985. X * Returns 1 for error or 0 for success.  The current directory
  986. X * and drive will be at the given path if successful, otherwise
  987. X * the drive and path will be elsewhere (not necessarily where they
  988. X * were before mkpath was called).
  989. X */
  990. int mkpath();
  991. X
  992. /* char *mktmp(char *);
  993. X * Create an empty temporary file.  The file name created is the string passed
  994. X * to this function postfixed with JXXXXXX.tmp, where XXXXXX is some number.
  995. X */
  996. char *mktmp();
  997. X
  998. /* Change drive:directory
  999. X */
  1000. #define chddir chdir
  1001. X
  1002. #endif
  1003. SHAR_EOF
  1004. chmod 0600 pathfunc.h ||
  1005. echo 'restore of pathfunc.h failed'
  1006. Wc_c="`wc -c < 'pathfunc.h'`"
  1007. test 2548 -eq "$Wc_c" ||
  1008.     echo 'pathfunc.h: original size 2548, current size' "$Wc_c"
  1009. fi
  1010. # ============= pattern.c ==============
  1011. if test -f 'pattern.c' -a X"$1" != X"-c"; then
  1012.     echo 'x - skipping pattern.c (File already exists)'
  1013. else
  1014. echo 'x - extracting pattern.c (Text)'
  1015. sed 's/^X//' << 'SHAR_EOF' > 'pattern.c' &&
  1016. /* Pattern matching system
  1017. X   Copyright (C) 1992 Joseph H. Allen
  1018. X
  1019. This file is part of JOE (Joe's Own Editor)
  1020. X
  1021. JOE is free software; you can redistribute it and/or modify it under the 
  1022. terms of the GNU General Public License as published by the Free Software 
  1023. Foundation; either version 1, or (at your option) any later version.  
  1024. X
  1025. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1026. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1027. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1028. details.  
  1029. X
  1030. You should have received a copy of the GNU General Public License along with 
  1031. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1032. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1033. X
  1034. #include <stdio.h>
  1035. #include <sys/types.h>
  1036. #include <sys/stat.h>
  1037. #include "config.h"
  1038. #include "heap.h"
  1039. #include "termcap.h"
  1040. #include "toomany.h"
  1041. #include "vfile.h"
  1042. #include "scrn.h"
  1043. #include "tty.h"
  1044. #include "queue.h"
  1045. #include "b.h"
  1046. #include "regex.h"
  1047. #include "kbd.h"
  1048. #include "bw.h"
  1049. #include "vs.h"
  1050. #include "w.h"
  1051. #include "pathfunc.h"
  1052. #include "va.h"
  1053. #include "edfuncs.h"
  1054. #include "pattern.h"
  1055. X
  1056. B *findhist=0;
  1057. X
  1058. void pfnext();
  1059. X
  1060. #define SRBACKWARDS 1
  1061. #define SRIGNORE 2
  1062. #define SRREPLACE 4
  1063. X
  1064. static void set_replace(w,s)
  1065. X W *w;
  1066. X char *s;
  1067. X { 
  1068. X if(w->t->replace) vsrm(w->t->replace);
  1069. X w->t->replace=s;
  1070. X pfnext(w);
  1071. X }
  1072. X
  1073. static void set_options(w,s)
  1074. X W *w;
  1075. X char *s;
  1076. X {
  1077. X int x;
  1078. X w->t->options=0;
  1079. X w->t->repeat= -1;
  1080. X for(x=0;s[x];++x)
  1081. X  switch(s[x])
  1082. X   {
  1083. X  case 'r': case 'R': w->t->options|=SRREPLACE; break;
  1084. X  case 'b': case 'B': w->t->options|=SRBACKWARDS; break;
  1085. X  case 'i': case 'I': w->t->options|=SRIGNORE; break;
  1086. X  case '0': case '1': case '2': case '3': case '4':
  1087. X  case '5': case '6': case '7': case '8': case '9':
  1088. X   if(w->t->repeat== -1) w->t->repeat=0;
  1089. X   w->t->repeat=w->t->repeat*10+s[x]-'0';
  1090. X   break;
  1091. X   }
  1092. X vsrm(s);
  1093. X if(w->t->options&SRREPLACE) wmkpw(w,"Replace with (^C to abort): ",&findhist,set_replace,"Search");
  1094. X else pfnext(w);
  1095. X }
  1096. X
  1097. static void set_pattern(w,s)
  1098. X W *w;
  1099. X char *s;
  1100. X {
  1101. X if(w->t->pattern) vsrm(w->t->pattern);
  1102. X w->t->pattern=s;
  1103. X wmkpw(w,"(I)gnore case (R)eplace (B)ackwards NNN (^C to abort): ",NULL,set_options,"Search");
  1104. X }
  1105. X
  1106. void pffirst(w)
  1107. X W *w;
  1108. X {
  1109. X wmkpw(w,"Find (^C to abort): ",&findhist,set_pattern,"Search"); 
  1110. X }
  1111. X
  1112. char *entire=0;
  1113. X
  1114. static int searchf(w)
  1115. W *w;
  1116. {
  1117. BW *bw=(BW *)w->object;
  1118. P *start=pdup(bw->cursor);
  1119. P *end=pdup(bw->cursor);
  1120. int x;
  1121. for(x=0;x!=sLEN(w->t->pattern) && w->t->pattern[x]!='\\';++x);
  1122. if(w->t->options&SRIGNORE)
  1123. X while(pfindfni(start,w->t->pattern,x))
  1124. X  {
  1125. X  pset(end,start);
  1126. X  pfwrd(end,x);
  1127. X  if(pimatch(w->t->pattern+x,sLEN(w->t->pattern)-x,end,0))
  1128. X   {
  1129. X   w->t->foundlen=end->byte-start->byte;
  1130. X   entire=vstrunc(entire,w->t->foundlen);
  1131. X   brmem(start,entire,w->t->foundlen);
  1132. X   pset(bw->cursor,end);
  1133. X   prm(start); prm(end);
  1134. X   pfcol(bw->cursor);
  1135. X   bw->cursor->xcol=bw->cursor->col;
  1136. X   return 1;
  1137. X   }
  1138. X  if(pgetc(start)== MAXINT) break;
  1139. X  }
  1140. else
  1141. X while(pfindfn(start,w->t->pattern,x))
  1142. X  {
  1143. X  pset(end,start);
  1144. X  pfwrd(end,x);
  1145. X  if(pmatch(w->t->pattern+x,sLEN(w->t->pattern)-x,end,0))
  1146. X   {
  1147. X   w->t->foundlen=end->byte-start->byte;
  1148. X   entire=vstrunc(entire,w->t->foundlen);
  1149. X   brmem(start,entire,w->t->foundlen);
  1150. X   pset(bw->cursor,end);
  1151. X   prm(start); prm(end);
  1152. X   pfcol(bw->cursor);
  1153. X   bw->cursor->xcol=bw->cursor->col;
  1154. X   return 1;
  1155. X   }
  1156. X  if(pgetc(start)== MAXINT) break;
  1157. X  }
  1158. prm(start); prm(end);
  1159. return 0;
  1160. }
  1161. X
  1162. static int searchb(w)
  1163. W *w;
  1164. {
  1165. BW *bw=(BW *)w->object;
  1166. P *start=pdup(bw->cursor);
  1167. P *end=pdup(bw->cursor);
  1168. int x;
  1169. for(x=0;x!=sLEN(w->t->pattern) && w->t->pattern[x]!='\\';++x);
  1170. if(w->t->options&SRIGNORE)
  1171. X while(pbkwdf(start,1L) && pfindrni(start,w->t->pattern,x))
  1172. X  {
  1173. X  pset(end,start);
  1174. X  pfwrd(end,x);
  1175. X  if(pimatch(w->t->pattern+x,sLEN(w->t->pattern)-x,end,0))
  1176. X   {
  1177. X   w->t->foundlen=end->byte-start->byte;
  1178. X   entire=vstrunc(entire,w->t->foundlen);
  1179. X   brmem(start,entire,w->t->foundlen);
  1180. X   pset(bw->cursor,start);
  1181. X   prm(start); prm(end);
  1182. X   pfcol(bw->cursor);
  1183. X   bw->cursor->xcol=bw->cursor->col;
  1184. X   return 1;
  1185. X   }
  1186. X  }
  1187. else
  1188. X while(pbkwdf(start,1L) && pfindrn(start,w->t->pattern,x))
  1189. X  {
  1190. X  pset(end,start);
  1191. X  pfwrd(end,x);
  1192. X  if(pmatch(w->t->pattern+x,sLEN(w->t->pattern)-x,end,0))
  1193. X   {
  1194. X   w->t->foundlen=end->byte-start->byte;
  1195. X   entire=vstrunc(entire,w->t->foundlen);
  1196. X   brmem(start,entire,w->t->foundlen);
  1197. X   pset(bw->cursor,start);
  1198. X   prm(start); prm(end);
  1199. X   pfcol(bw->cursor);
  1200. X   bw->cursor->xcol=bw->cursor->col;
  1201. X   return 1;
  1202. X   }
  1203. X  }
  1204. prm(start); prm(end);
  1205. return 0;
  1206. }
  1207. X
  1208. static void insert(bw,s,len)
  1209. BW *bw;
  1210. char *s;
  1211. {
  1212. int x;
  1213. while(len)
  1214. X {
  1215. X for(x=0;x!=len && s[x]!='\\';++x);
  1216. X if(x)
  1217. X  {
  1218. X  binsm(bw->cursor,s,x);
  1219. X  pfwrd(bw->cursor,x);
  1220. X  len-=x;
  1221. X  s+=x;
  1222. X  }
  1223. X else if(len>=2)
  1224. X  {
  1225. X  if(s[1]=='\\') binsc(bw->cursor,'\\'), pgetc(bw->cursor);
  1226. X  else if(s[1]=='n') binsc(bw->cursor,'\n'), pgetc(bw->cursor);
  1227. X  else if((s[1]>='a' && s[1]<='z' ||
  1228. X          s[1]>='A' && s[1]<='Z') && pieces[(s[1]&0x1f)-1])
  1229. X   {
  1230. X   binsm(bw->cursor,sv(pieces[(s[1]&0x1f)-1]));
  1231. X   pfwrd(bw->cursor,sLEN(pieces[(s[1]&0x1f)-1]));
  1232. X   }
  1233. X  else if(s[1]>='0' && s[1]<='9' && pieces[s[1]-'0'])
  1234. X   {
  1235. X   binsm(bw->cursor,sv(pieces[s[1]-'0']));
  1236. X   pfwrd(bw->cursor,sLEN(pieces[s[1]-'0']));
  1237. X   }
  1238. X  else if(s[1]=='&' && entire)
  1239. X   {
  1240. X   binsm(bw->cursor,sv(entire));
  1241. X   pfwrd(bw->cursor,sLEN(entire));
  1242. X   }
  1243. X  s+=2; len-=2;
  1244. X  }
  1245. X else len=0;
  1246. X }
  1247. }
  1248. X
  1249. static void replace(w)
  1250. W *w;
  1251. {
  1252. BW *bw=(BW *)w->object;
  1253. P *q=pdup(bw->cursor);
  1254. if(w->t->options&SRBACKWARDS)
  1255. X {
  1256. X q=pfwrd(q,w->t->foundlen);
  1257. X bdel(bw->cursor,q);
  1258. X prm(q);
  1259. X }
  1260. else
  1261. X {
  1262. X q=pbkwd(q,w->t->foundlen);
  1263. X bdel(q,bw->cursor);
  1264. X prm(q);
  1265. X }
  1266. insert(bw,sv(w->t->replace));
  1267. }
  1268. X
  1269. void pfnext(w)
  1270. X W *w;
  1271. X {
  1272. X BW *bw=(BW *)w->object;
  1273. X int c;
  1274. X int rest=0;
  1275. X int flg=0;
  1276. X int orgmid=mid;
  1277. X mid=1;
  1278. X if(!w->t->pattern) { pffirst(w); goto done; }
  1279. X next:
  1280. X if(w->t->repeat!= -1)
  1281. X  if(!w->t->repeat) goto done;
  1282. X  else --w->t->repeat;
  1283. X if(w->t->options&SRBACKWARDS)
  1284. X  { if(!searchb(w)) { if(!flg || !(w->t->options&SRREPLACE)) msgnw(w,"Not found"); w->t->repeat= -1; goto done; } }
  1285. X else
  1286. X  if(!searchf(w)) { if(!flg || !(w->t->options&SRREPLACE)) msgnw(w,"Not found"); w->t->repeat= -1; goto done; }
  1287. X flg=1;
  1288. X if(w->t->options&SRREPLACE)
  1289. X  if(rest) { replace(w); goto next; }
  1290. X  else
  1291. X   {
  1292. X   do
  1293. X    {
  1294. X    P *mb=w->t->markb, *mk=w->t->markk;
  1295. X    if(w->t->options&SRBACKWARDS)
  1296. X     {
  1297. X     w->t->markb=pdup(bw->cursor);
  1298. X     w->t->markk=pdup(bw->cursor);
  1299. X     pfwrd(w->t->markk,w->t->foundlen);
  1300. X     }
  1301. X    else
  1302. X     {
  1303. X     w->t->markk=pdup(bw->cursor);
  1304. X     w->t->markb=pdup(bw->cursor);
  1305. X     pbkwd(w->t->markb,w->t->foundlen);
  1306. X     }
  1307. X    updall();
  1308. X    c=queryn(w,"Replace (Y)es (N)o (R)est (^C to abort)?");
  1309. X    prm(w->t->markb); prm(w->t->markk);
  1310. X    w->t->markb=mb; w->t->markk=mk;
  1311. X    if(c=='N' || c=='n') { goto next; }
  1312. X    if(c=='Y' || c=='y') { replace(w); goto next; }
  1313. X    if(c=='R' || c=='r') { replace(w); rest=1; goto next; }
  1314. X    }
  1315. X    while(c!=MAXINT && c!='C'-'@');
  1316. X   }
  1317. X else if(w->t->repeat!= -1) goto next;
  1318. X done:
  1319. X updall();
  1320. X bw->cursor->xcol=bw->cursor->col;
  1321. X mid=orgmid;
  1322. X }
  1323. SHAR_EOF
  1324. chmod 0600 pattern.c ||
  1325. echo 'restore of pattern.c failed'
  1326. Wc_c="`wc -c < 'pattern.c'`"
  1327. test 7010 -eq "$Wc_c" ||
  1328.     echo 'pattern.c: original size 7010, current size' "$Wc_c"
  1329. fi
  1330. # ============= pattern.h ==============
  1331. if test -f 'pattern.h' -a X"$1" != X"-c"; then
  1332.     echo 'x - skipping pattern.h (File already exists)'
  1333. else
  1334. echo 'x - extracting pattern.h (Text)'
  1335. sed 's/^X//' << 'SHAR_EOF' > 'pattern.h' &&
  1336. /* Pattern matching system
  1337. X   Copyright (C) 1992 Joseph H. Allen
  1338. X
  1339. This file is part of JOE (Joe's Own Editor)
  1340. X
  1341. JOE is free software; you can redistribute it and/or modify it under the 
  1342. terms of the GNU General Public License as published by the Free Software 
  1343. Foundation; either version 1, or (at your option) any later version.  
  1344. X
  1345. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1346. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1347. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1348. details.  
  1349. X
  1350. You should have received a copy of the GNU General Public License along with 
  1351. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1352. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1353. X
  1354. #ifndef _Ipattern
  1355. #define _Ipattern 1
  1356. X
  1357. void pffirst();
  1358. void pfnext();
  1359. X
  1360. #endif
  1361. SHAR_EOF
  1362. chmod 0600 pattern.h ||
  1363. echo 'restore of pattern.h failed'
  1364. Wc_c="`wc -c < 'pattern.h'`"
  1365. test 841 -eq "$Wc_c" ||
  1366.     echo 'pattern.h: original size 841, current size' "$Wc_c"
  1367. fi
  1368. # ============= poshist.c ==============
  1369. if test -f 'poshist.c' -a X"$1" != X"-c"; then
  1370.     echo 'x - skipping poshist.c (File already exists)'
  1371. else
  1372. echo 'x - extracting poshist.c (Text)'
  1373. sed 's/^X//' << 'SHAR_EOF' > 'poshist.c' &&
  1374. /* Position history
  1375. X   Copyright (C) 1992 Joseph H. Allen
  1376. X
  1377. This file is part of JOE (Joe's Own Editor)
  1378. X
  1379. JOE is free software; you can redistribute it and/or modify it under the 
  1380. terms of the GNU General Public License as published by the Free Software 
  1381. Foundation; either version 1, or (at your option) any later version.  
  1382. X
  1383. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1384. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1385. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1386. details.  
  1387. X
  1388. You should have received a copy of the GNU General Public License along with 
  1389. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1390. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1391. X
  1392. #include "poshist.h"
  1393. #include "queue.h"
  1394. #include "b.h"
  1395. #include "w.h"
  1396. #include "bw.h"
  1397. X
  1398. typedef struct pos POS;
  1399. X
  1400. struct pos
  1401. X {
  1402. X LINK(POS) link;
  1403. X P *p;
  1404. X W *w;
  1405. X };
  1406. X
  1407. POS pos={{&pos,&pos}};
  1408. POS *curpos=&pos;
  1409. int npos=0;
  1410. X
  1411. void markpos(w,p)
  1412. W *w;
  1413. P *p;
  1414. {
  1415. POS *new=(POS *)malloc(sizeof(POS));
  1416. new->p=pdup(p);
  1417. new->w=w;
  1418. enqueb(POS,link,&pos,new);
  1419. if(++npos==20)
  1420. X {
  1421. X new=pos.link.next;
  1422. X if(new->p) prm(new->p);
  1423. X free(deque(POS,link,new));
  1424. X }
  1425. }
  1426. X
  1427. void afterpos()
  1428. {
  1429. if(curpos!=&pos)
  1430. X {
  1431. X demote(POS,link,&pos,curpos);
  1432. X curpos=&pos;
  1433. X }
  1434. }
  1435. X
  1436. void aftermove(w,p)
  1437. W *w;
  1438. P *p;
  1439. {
  1440. if(pos.link.prev!=&pos &&
  1441. X   pos.link.prev->w==w &&
  1442. X   pos.link.prev->p &&
  1443. X   Iabs(pos.link.prev->p->line-p->line)<3
  1444. X  )
  1445. X pset(pos.link.prev->p,p);
  1446. else markpos(w,p);
  1447. }
  1448. X
  1449. void windie(w)
  1450. W *w;
  1451. {
  1452. POS *n;
  1453. for(n=pos.link.prev;n!=&pos;n=n->link.prev) if(n->w==w) n->w=0;
  1454. }
  1455. X
  1456. void unextpos(w)
  1457. W *w;
  1458. {
  1459. lp:
  1460. if(curpos->link.next!=&pos && curpos!=&pos)
  1461. X {
  1462. X BW *bw;
  1463. X curpos=curpos->link.next;
  1464. X if(!curpos->p || !curpos->w) goto lp;
  1465. X if(w->t->curwin==curpos->w &&
  1466. X    curpos->p->byte==((BW *)w->t->curwin->object)->cursor->byte) goto lp;
  1467. X if(w->t->curwin!=curpos->w)
  1468. X  {
  1469. X  w->t->curwin=curpos->w;
  1470. X  if(w->t->curwin->y== -1) wfit(w->t);
  1471. X  }
  1472. X w=w->t->curwin;
  1473. X bw=(BW *)w->object;
  1474. X if(bw->cursor->byte!=curpos->p->byte) pset(bw->cursor,curpos->p);
  1475. X }
  1476. }
  1477. X
  1478. void uprevpos(w)
  1479. W *w;
  1480. {
  1481. lp:
  1482. if(curpos->link.prev!=&pos)
  1483. X {
  1484. X BW *bw;
  1485. X curpos=curpos->link.prev;
  1486. X if(!curpos->p || !curpos->w) goto lp;
  1487. X if(w->t->curwin==curpos->w &&
  1488. X    curpos->p->byte==((BW *)w->t->curwin->object)->cursor->byte) goto lp;
  1489. X if(w->t->curwin!=curpos->w)
  1490. X  {
  1491. X  w->t->curwin=curpos->w;
  1492. X  if(w->t->curwin->y== -1) wfit(w->t);
  1493. X  }
  1494. X w=w->t->curwin;
  1495. X bw=(BW *)w->object;
  1496. X if(bw->cursor->byte!=curpos->p->byte) pset(bw->cursor,curpos->p);
  1497. X }
  1498. }
  1499. SHAR_EOF
  1500. chmod 0600 poshist.c ||
  1501. echo 'restore of poshist.c failed'
  1502. Wc_c="`wc -c < 'poshist.c'`"
  1503. test 2503 -eq "$Wc_c" ||
  1504.     echo 'poshist.c: original size 2503, current size' "$Wc_c"
  1505. fi
  1506. # ============= poshist.h ==============
  1507. if test -f 'poshist.h' -a X"$1" != X"-c"; then
  1508.     echo 'x - skipping poshist.h (File already exists)'
  1509. else
  1510. echo 'x - extracting poshist.h (Text)'
  1511. sed 's/^X//' << 'SHAR_EOF' > 'poshist.h' &&
  1512. /* Position history
  1513. X   Copyright (C) 1992 Joseph H. Allen
  1514. X
  1515. This file is part of JOE (Joe's Own Editor)
  1516. X
  1517. JOE is free software; you can redistribute it and/or modify it under the 
  1518. terms of the GNU General Public License as published by the Free Software 
  1519. Foundation; either version 1, or (at your option) any later version.  
  1520. X
  1521. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1522. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1523. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1524. details.  
  1525. X
  1526. You should have received a copy of the GNU General Public License along with 
  1527. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1528. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1529. X
  1530. #ifndef _Iposhist
  1531. #define _Iposhist 1
  1532. X
  1533. #include "config.h"
  1534. X
  1535. void afterpos();
  1536. void aftermove();
  1537. void windie();
  1538. void uprevpos();
  1539. void unextpos();
  1540. X
  1541. #endif
  1542. SHAR_EOF
  1543. chmod 0600 poshist.h ||
  1544. echo 'restore of poshist.h failed'
  1545. Wc_c="`wc -c < 'poshist.h'`"
  1546. test 908 -eq "$Wc_c" ||
  1547.     echo 'poshist.h: original size 908, current size' "$Wc_c"
  1548. fi
  1549. # ============= pw.c ==============
  1550. if test -f 'pw.c' -a X"$1" != X"-c"; then
  1551.     echo 'x - skipping pw.c (File already exists)'
  1552. else
  1553. echo 'x - extracting pw.c (Text)'
  1554. sed 's/^X//' << 'SHAR_EOF' > 'pw.c' &&
  1555. /* Prompt windows
  1556. X   Copyright (C) 1992 Joseph H. Allen
  1557. X
  1558. This file is part of JOE (Joe's Own Editor)
  1559. X
  1560. JOE is free software; you can redistribute it and/or modify it under the 
  1561. terms of the GNU General Public License as published by the Free Software 
  1562. Foundation; either version 1, or (at your option) any later version.  
  1563. X
  1564. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1565. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1566. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1567. details.  
  1568. X
  1569. You should have received a copy of the GNU General Public License along with 
  1570. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1571. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1572. X
  1573. #include "config.h"
  1574. #include "heap.h"
  1575. #include "w.h"
  1576. #include "vfile.h"
  1577. #include "toomany.h"
  1578. #include "termcap.h"
  1579. #include "b.h"
  1580. #include "edfuncs.h"
  1581. #include "kbd.h"
  1582. #include "scrn.h"
  1583. #include "bw.h"
  1584. #include "zstr.h"
  1585. #include "help.h"
  1586. #include "tab.h"
  1587. #include "undo.h"
  1588. #include "pw.h"
  1589. X
  1590. CONTEXT cprmpt={"prompt",0};
  1591. CONTEXT cfprmpt={"fprompt",0};
  1592. X
  1593. /* Move prompt window */
  1594. X
  1595. static void movepw(w,x,y)
  1596. W *w;
  1597. int x,y;
  1598. {
  1599. }
  1600. X
  1601. /* Resize prompt window */
  1602. X
  1603. static void resizepw(w,wi,he)
  1604. W *w;
  1605. int wi,he;
  1606. {
  1607. }
  1608. X
  1609. /* Abort prompt window */
  1610. X
  1611. static void killpw(w)
  1612. W *w;
  1613. {
  1614. BW *bw=(BW *)w->object;
  1615. PW *pw=(PW *)bw->object;
  1616. bwrm(bw);
  1617. free(pw->prompt);
  1618. free(pw);
  1619. }
  1620. X
  1621. /* Update a prompt window */
  1622. X
  1623. static void followpw(w)
  1624. W *w;
  1625. {
  1626. BW *bw=(BW *)w->object;
  1627. bwfllw(bw);
  1628. }
  1629. X
  1630. static void disppw(w)
  1631. W *w;
  1632. {
  1633. int x;
  1634. BW *bw=(BW *)w->object;
  1635. PW *pw=(PW *)bw->object;
  1636. X
  1637. /* Scroll buffer and position prompt */
  1638. if(pw->promptlen>w->w/2+w->w/4)
  1639. X {
  1640. X pw->promptofst=pw->promptlen-w->w/2;
  1641. X if(bw->cursor->col<w->w-(pw->promptlen-pw->promptofst))
  1642. X  bw->offset=0;
  1643. X else
  1644. X  bw->offset=bw->cursor->col-(w->w-(pw->promptlen-pw->promptofst)-1);
  1645. X }
  1646. else
  1647. X { 
  1648. X if(bw->cursor->col<w->w-pw->promptlen) pw->promptofst=0, bw->offset=0;
  1649. X else if(bw->cursor->col>=w->w)
  1650. X  pw->promptofst=pw->promptlen, bw->offset=bw->cursor->col-(w->w-1);
  1651. X else
  1652. X  pw->promptofst=pw->promptlen-(w->w-bw->cursor->col-1),
  1653. X  bw->offset=bw->cursor->col-(w->w-(pw->promptlen-pw->promptofst)-1);
  1654. X }
  1655. X
  1656. /* Set cursor position */
  1657. w->curx=bw->cursor->col-bw->offset+pw->promptlen-pw->promptofst;
  1658. w->cury=0;
  1659. X
  1660. /* Generate prompt */
  1661. w->t->t->updtab[w->y]=1;
  1662. genfmt(w->t->t,w->x,w->y,pw->promptofst,pw->prompt,0);
  1663. X
  1664. /* Position and size buffer */
  1665. bwmove(bw,w->x+pw->promptlen-pw->promptofst,w->y);
  1666. bwresz(bw,w->w-(pw->promptlen-pw->promptofst),1);
  1667. X
  1668. /* Generate buffer */
  1669. bwgen(bw);
  1670. }
  1671. X
  1672. /* When user hits return in a prompt window */
  1673. X
  1674. void upromptrtn(w)
  1675. W *w;
  1676. {
  1677. BW *bw=(BW *)w->object;
  1678. PW *pw=(PW *)bw->object;
  1679. char *s;
  1680. W *win;
  1681. void (*pfunc)();
  1682. peol(bw->cursor);
  1683. s=brvs(bw->top,bw->cursor->byte-bw->top->byte);
  1684. if(pw->hist)
  1685. X if(bw->b->chnged)
  1686. X  {
  1687. X  P *q=pdup(pw->hist->eof);
  1688. X  binsm(q,s,bw->cursor->byte-bw->top->byte);
  1689. X  peof(q);
  1690. X  binsc(q,'\n');
  1691. X  prm(q);
  1692. X  }
  1693. X else
  1694. X  {
  1695. X  P *q=pdup(pw->hist->bof);
  1696. X  P *r;
  1697. X  P *t;
  1698. X  pline(q,bw->top->line);
  1699. X  r=pdup(q);
  1700. X  pnextl(r);
  1701. X  t=pdup(pw->hist->eof);
  1702. X  binsb(t,q,r);
  1703. X  bdel(q,r);
  1704. X  prm(q); prm(r); prm(t);
  1705. X  }
  1706. win=w->win;
  1707. X
  1708. pfunc=pw->pfunc;
  1709. wabort(w);
  1710. pfunc(win,s);
  1711. }
  1712. X
  1713. /* When user aborts a prompt window ^C */
  1714. X
  1715. void uabortpw(w)
  1716. W *w;
  1717. {
  1718. wabort(w);
  1719. }
  1720. X
  1721. static void inspw(w,b,l,n,flg)
  1722. W *w;
  1723. B *b;
  1724. long l,n;
  1725. int flg;
  1726. {
  1727. BW *bw=(BW *)w->object;
  1728. if(b==bw->b) bwins(bw,l,n,flg);
  1729. }
  1730. X
  1731. static void delpw(w,b,l,n,flg)
  1732. W *w;
  1733. B *b;
  1734. long l,n;
  1735. int flg;
  1736. {
  1737. BW *bw=(BW *)w->object;
  1738. if(b==bw->b) bwdel(bw,l,n,flg);
  1739. }
  1740. X
  1741. static WATOM watompw=
  1742. {
  1743. &cprmpt,
  1744. disppw,
  1745. followpw,
  1746. killpw,
  1747. resizepw,
  1748. movepw,
  1749. inspw,
  1750. delpw,
  1751. TYPEPW
  1752. };
  1753. X
  1754. static WATOM watomfpw=
  1755. {
  1756. &cfprmpt,
  1757. disppw,
  1758. followpw,
  1759. killpw,
  1760. resizepw,
  1761. movepw,
  1762. inspw,
  1763. delpw,
  1764. TYPEPW
  1765. };
  1766. X
  1767. /* Create a prompt window */
  1768. X
  1769. W *wmkpw(w,prompt,history,func,huh)
  1770. W *w;
  1771. char *prompt;
  1772. B **history;
  1773. void (*func)();
  1774. char *huh;
  1775. {
  1776. W *new;
  1777. PW *pw;
  1778. BW *bw;
  1779. new=wcreate(w->t,&watompw,w,w,w->main,1,huh);
  1780. if(!new) return 0;
  1781. new->object=(void *)(bw=bwmk(new->t,bmk(),new->x,new->y,new->w,1));
  1782. bw->object=(void *)(pw=(PW *)malloc(sizeof(PW)));
  1783. pw->prompt=zdup(prompt);
  1784. pw->promptlen=fmtlen(prompt);
  1785. pw->promptofst=0;
  1786. pw->pfunc=func;
  1787. if(history)
  1788. X {
  1789. X if(!*history) *history=bmk();
  1790. X pw->hist= *history;
  1791. X binsb(bw->cursor,pw->hist->bof,pw->hist->eof);
  1792. X bw->b->chnged=0;
  1793. X peof(bw->cursor); peof(bw->top); pbol(bw->top);
  1794. X }
  1795. else pw->hist=0;
  1796. w->t->curwin=new;
  1797. return new;
  1798. }
  1799. X
  1800. W *wmkfpw(w,prompt,history,func,huh)
  1801. W *w;
  1802. char *prompt;
  1803. B **history;
  1804. void (*func)();
  1805. char *huh;
  1806. {
  1807. W *new;
  1808. PW *pw;
  1809. BW *bw;
  1810. new=wcreate(w->t,&watomfpw,w,w,w->main,1,huh);
  1811. if(!new) return 0;
  1812. new->object=(void *)(bw=bwmk(new->t,bmk(),new->x,new->y,new->w,1));
  1813. bw->object=(void *)(pw=(PW *)malloc(sizeof(PW)));
  1814. pw->prompt=zdup(prompt);
  1815. pw->promptlen=fmtlen(prompt);
  1816. pw->promptofst=0;
  1817. pw->pfunc=func;
  1818. if(history)
  1819. X {
  1820. X if(!*history) *history=bmk();
  1821. X pw->hist= *history;
  1822. X binsb(bw->cursor,pw->hist->bof,pw->hist->eof);
  1823. X bw->b->chnged=0;
  1824. X peof(bw->cursor); peof(bw->top); pbol(bw->top);
  1825. X }
  1826. else pw->hist=0;
  1827. w->t->curwin=new;
  1828. return new;
  1829. }
  1830. SHAR_EOF
  1831. chmod 0600 pw.c ||
  1832. echo 'restore of pw.c failed'
  1833. Wc_c="`wc -c < 'pw.c'`"
  1834. test 4996 -eq "$Wc_c" ||
  1835.     echo 'pw.c: original size 4996, current size' "$Wc_c"
  1836. fi
  1837. # ============= pw.h ==============
  1838. if test -f 'pw.h' -a X"$1" != X"-c"; then
  1839.     echo 'x - skipping pw.h (File already exists)'
  1840. else
  1841. echo 'x - extracting pw.h (Text)'
  1842. sed 's/^X//' << 'SHAR_EOF' > 'pw.h' &&
  1843. /* Prompt windows
  1844. X   Copyright (C) 1992 Joseph H. Allen
  1845. X
  1846. This file is part of JOE (Joe's Own Editor)
  1847. X
  1848. JOE is free software; you can redistribute it and/or modify it under the 
  1849. terms of the GNU General Public License as published by the Free Software 
  1850. Foundation; either version 1, or (at your option) any later version.  
  1851. X
  1852. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1853. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1854. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1855. details.  
  1856. X
  1857. You should have received a copy of the GNU General Public License along with 
  1858. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1859. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1860. X
  1861. #ifndef _Ipw
  1862. #define _Ipw 1
  1863. X
  1864. #include "config.h"
  1865. #include "kbd.h"
  1866. X
  1867. typedef struct pw PW;
  1868. X
  1869. struct pw
  1870. X {
  1871. X void (*pfunc)();        /* Func which gets called when RTN is hit */
  1872. X char *prompt;            /* Prompt string */
  1873. X int promptlen;            /* Width of prompt string */
  1874. X int promptofst;        /* Prompt scroll offset */
  1875. X B *hist;            /* History buffer */
  1876. X };
  1877. X
  1878. #define TYPEPW 0x200
  1879. X
  1880. extern CONTEXT cprmpt, cfprmpt;
  1881. X
  1882. /* W *wmkpw(W *w,char *prompt,void (*func)());
  1883. X * Create a prompt window for the given window
  1884. X */
  1885. W *wmkpw();
  1886. X
  1887. /* W *wmkfpw(W *w,char *prompt,void (*func)());
  1888. X * Create a prompt window for the given window
  1889. X * Use mappings for file names
  1890. X */
  1891. W *wmkfpw();
  1892. X
  1893. void uabortpw();
  1894. void upromptrtn();
  1895. X
  1896. #endif
  1897. SHAR_EOF
  1898. chmod 0600 pw.h ||
  1899. echo 'restore of pw.h failed'
  1900. Wc_c="`wc -c < 'pw.h'`"
  1901. test 1442 -eq "$Wc_c" ||
  1902.     echo 'pw.h: original size 1442, current size' "$Wc_c"
  1903. fi
  1904. # ============= queue.c ==============
  1905. if test -f 'queue.c' -a X"$1" != X"-c"; then
  1906.     echo 'x - skipping queue.c (File already exists)'
  1907. else
  1908. echo 'x - extracting queue.c (Text)'
  1909. sed 's/^X//' << 'SHAR_EOF' > 'queue.c' &&
  1910. /* Doubly linked list primitives
  1911. X   Copyright (C) 1992 Joseph H. Allen
  1912. X
  1913. This file is part of JOE (Joe's Own Editor)
  1914. X
  1915. JOE is free software; you can redistribute it and/or modify it under the 
  1916. terms of the GNU General Public License as published by the Free Software 
  1917. Foundation; either version 1, or (at your option) any later version.  
  1918. X
  1919. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1920. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1921. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1922. details.  
  1923. X
  1924. You should have received a copy of the GNU General Public License along with 
  1925. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1926. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1927. X
  1928. #include "config.h"
  1929. #include "queue.h"
  1930. X
  1931. void *QUEUE;
  1932. void *ITEM;
  1933. void *LAST;
  1934. SHAR_EOF
  1935. chmod 0600 queue.c ||
  1936. echo 'restore of queue.c failed'
  1937. Wc_c="`wc -c < 'queue.c'`"
  1938. test 846 -eq "$Wc_c" ||
  1939.     echo 'queue.c: original size 846, current size' "$Wc_c"
  1940. fi
  1941. # ============= queue.h ==============
  1942. if test -f 'queue.h' -a X"$1" != X"-c"; then
  1943.     echo 'x - skipping queue.h (File already exists)'
  1944. else
  1945. echo 'x - extracting queue.h (Text)'
  1946. sed 's/^X//' << 'SHAR_EOF' > 'queue.h' &&
  1947. /* Doubly linked list primitives
  1948. X   Copyright (C) 1992 Joseph H. Allen
  1949. X
  1950. This file is part of JOE (Joe's Own Editor)
  1951. X
  1952. JOE is free software; you can redistribute it and/or modify it under the 
  1953. terms of the GNU General Public License as published by the Free Software 
  1954. Foundation; either version 1, or (at your option) any later version.  
  1955. X
  1956. JOE is distributed in the hope that it will be useful, but WITHOUT ANY 
  1957. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  1958. FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  1959. details.  
  1960. X
  1961. You should have received a copy of the GNU General Public License along with 
  1962. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 
  1963. 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
  1964. X
  1965. #ifndef _Iqueue
  1966. #define _Iqueue 1
  1967. X
  1968. #include "config.h"
  1969. X
  1970. extern void *ITEM;
  1971. extern void *QUEUE;
  1972. extern void *LAST;
  1973. X
  1974. #define LINK(type) struct { type *next; type *prev; }
  1975. X
  1976. #define izque(type,member,item) \
  1977. X    ( \
  1978. X    QUEUE=(void *)(item), \
  1979. X    ((type *)QUEUE)->member.prev=(type *)QUEUE, \
  1980. X    ((type *)QUEUE)->member.next=(type *)QUEUE, \
  1981. X    (type *)QUEUE \
  1982. X    )
  1983. X
  1984. #define deque(type,member,item) \
  1985. X    ( \
  1986. X    ITEM=(void *)(item), \
  1987. X    ((type *)ITEM)->member.prev->member.next=((type *)ITEM)->member.next, \
  1988. X    ((type *)ITEM)->member.next->member.prev=((type *)ITEM)->member.prev, \
  1989. X    (type *)ITEM \
  1990. X    )
  1991. X
  1992. #define qempty(type,member,item) \
  1993. X    ( \
  1994. X    QUEUE=(void *)(item), \
  1995. X    (type *)QUEUE==((type *)QUEUE)->member.next \
  1996. X    )
  1997. X
  1998. #define enquef(type,member,queue,item) \
  1999. X    ( \
  2000. X    ITEM=(void *)(item), \
  2001. X    QUEUE=(void *)(queue), \
  2002. X    ((type *)ITEM)->member.next=((type *)QUEUE)->member.next, \
  2003. X    ((type *)ITEM)->member.prev=(type *)QUEUE, \
  2004. X    ((type *)QUEUE)->member.next->member.prev=(type *)ITEM, \
  2005. X    ((type *)QUEUE)->member.next=(type *)ITEM, \
  2006. X    (type *)ITEM \
  2007. X    )
  2008. X
  2009. #define enqueb(type,member,queue,item) \
  2010. X    ( \
  2011. X    ITEM=(void *)(item), \
  2012. X    QUEUE=(void *)(queue), \
  2013. X    ((type *)ITEM)->member.next=(type *)QUEUE, \
  2014. X    ((type *)ITEM)->member.prev=((type *)QUEUE)->member.prev, \
  2015. X    ((type *)QUEUE)->member.prev->member.next=(type *)ITEM, \
  2016. X    ((type *)QUEUE)->member.prev=(type *)ITEM, \
  2017. X    (type *)ITEM \
  2018. X    )
  2019. X
  2020. #define promote(type,member,queue,item) \
  2021. X    ( \
  2022. X    enquef(type,member,(queue),deque(type,member,(item))) \
  2023. X    )
  2024. X
  2025. #define demote(type,member,queue,item) \
  2026. X    ( \
  2027. X    enqueb(type,member,(queue),deque(type,member,(item))) \
  2028. X    )
  2029. X
  2030. #define splicef(type,member,queue,chain) \
  2031. X    ( \
  2032. X    ITEM=(void *)(chain), \
  2033. X    LAST=(void *)((type *)ITEM)->member.prev, \
  2034. X    QUEUE=(void *)(queue), \
  2035. X    ((type *)LAST)->member.next=((type *)QUEUE)->member.next, \
  2036. X    ((type *)ITEM)->member.prev=(type *)QUEUE, \
  2037. X    ((type *)QUEUE)->member.next->member.prev=(type *)LAST, \
  2038. X    ((type *)QUEUE)->member.next=(type *)ITEM, \
  2039. X    (type *)ITEM \
  2040. X    )
  2041. X
  2042. #define spliceb(type,member,queue,chain) \
  2043. X    ( \
  2044. X    ITEM=(void *)(chain), \
  2045. X    LAST=(void *)((type *)ITEM)->member.prev, \
  2046. X    QUEUE=(void *)(queue), \
  2047. X    ((type *)LAST)->member.next=(type *)QUEUE, \
  2048. X    ((type *)ITEM)->member.prev=((type *)QUEUE)->member.prev, \
  2049. X    ((type *)QUEUE)->member.prev->member.next=(type *)ITEM, \
  2050. X    ((type *)QUEUE)->member.prev=(type *)LAST, \
  2051. X    (type *)ITEM \
  2052. X    )
  2053. X
  2054. #define snip(type,member,first,last) \
  2055. X    ( \
  2056. X    ITEM=(void *)(first), \
  2057. X    LAST=(void *)(last), \
  2058. X    ((type *)LAST)->member.next->member.prev=((type *)ITEM)->member.prev, \
  2059. X    ((type *)ITEM)->member.prev->member.next=((type *)LAST)->member.next, \
  2060. X    ((type *)ITEM)->member.prev=(type *)LAST, \
  2061. X    ((type *)LAST)->member.next=(type *)ITEM, \
  2062. X    (type *)ITEM \
  2063. X    )
  2064. X
  2065. #endif
  2066. SHAR_EOF
  2067. chmod 0600 queue.h ||
  2068. echo 'restore of queue.h failed'
  2069. Wc_c="`wc -c < 'queue.h'`"
  2070. test 3442 -eq "$Wc_c" ||
  2071.     echo 'queue.h: original size 3442, current size' "$Wc_c"
  2072. fi
  2073. # ============= random.c ==============
  2074. if test -f 'random.c' -a X"$1" != X"-c"; then
  2075.     echo 'x - skipping random.c (File already exists)'
  2076. else
  2077. echo 'x - extracting random.c (Text)'
  2078. sed 's/^X//' << 'SHAR_EOF' > 'random.c' &&
  2079. /*
  2080. X * Copyright (c) 1983 Regents of the University of California.
  2081. X * All rights reserved.
  2082. X *
  2083. X * Redistribution and use in source and binary forms are permitted
  2084. X * provided that the above copyright notice and this paragraph are
  2085. X * duplicated in all such forms and that any documentation,
  2086. X * advertising materials, and other materials related to such
  2087. X * distribution and use acknowledge that the software was developed
  2088. X * by the University of California, Berkeley.  The name of the
  2089. X * University may not be used to endorse or promote products derived
  2090. X * from this software without specific prior written permission.
  2091. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  2092. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  2093. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  2094. X */
  2095. X
  2096. /*
  2097. X * This is derived from the Berkeley source:
  2098. X *    @(#)random.c    5.5 (Berkeley) 7/6/88
  2099. X * It was reworked for the GNU C Library by Roland McGrath.
  2100. X * Fixed to be portable to MSDOS by jhallen
  2101. X */
  2102. X
  2103. #include "config.h"
  2104. #include "random.h"
  2105. X
  2106. /* An improved random number generation package.  In addition to the standard
  2107. X   rand()/srand() like interface, this package also has a special state info
  2108. X   interface.  The initstate() routine is called with a seed, an array of
  2109. X   bytes, and a count of how many bytes are being passed in; this array is
  2110. X   then initialized to contain information for random number generation with
  2111. X   that much state information.  Good sizes for the amount of state
  2112. X   information are 32, 64, 128, and 256 bytes.  The state can be switched by
  2113. X   calling the setstate() function with the same array as was initiallized
  2114. X   with initstate().  By default, the package runs with 128 bytes of state
  2115. X   information and generates far better random numbers than a linear
  2116. X   congruential generator.  If the amount of state information is less than
  2117. X   32 bytes, a simple linear congruential R.N.G. is used.  Internally, the
  2118. X   state information is treated as an array of longs; the zeroeth element of
  2119. X   the array is the type of R.N.G. being used (small integer); the remainder
  2120. X   of the array is the state information for the R.N.G.  Thus, 32 bytes of
  2121. X   state information will give 7 longs worth of state information, which will
  2122. X   allow a degree seven polynomial.  (Note: The zeroeth word of state
  2123. X   information also has some other information stored in it; see setstate
  2124. X   for details).  The random number generation technique is a linear feedback
  2125. X   shift register approach, employing trinomials (since there are fewer terms
  2126. X   to sum up that way).  In this approach, the least significant bit of all
  2127. X   the numbers in the state table will act as a linear feedback shift register,
  2128. X   and will have period 2^deg - 1 (where deg is the degree of the polynomial
  2129. X   being used, assuming that the polynomial is irreducible and primitive).
  2130. X   The higher order bits will have longer periods, since their values are
  2131. X   also influenced by pseudo-random carries out of the lower bits.  The
  2132. X   total period of the generator is approximately deg*(2**deg - 1); thus
  2133. X   doubling the amount of state information has a vast influence on the
  2134. X   period of the generator.  Note: The deg*(2**deg - 1) is an approximation
  2135. X   only good for large deg, when the period of the shift register is the
  2136. X   dominant factor.  With deg equal to seven, the period is actually much
  2137. X   longer than the 7*(2**7 - 1) predicted by this formula.  */
  2138. X
  2139. /* For each of the currently supported random number generators, we have a
  2140. X   break value on the amount of state information (you need at least thi
  2141. X   bytes of state info to support this random number generator), a degree for
  2142. X   the polynomial (actually a trinomial) that the R.N.G. is based on, and
  2143. X   separation between the two lower order coefficients of the trinomial.  */
  2144. X
  2145. /* Linear congruential.  */
  2146. #define    TYPE_0        0
  2147. #define    BREAK_0        8
  2148. #define    DEG_0        0
  2149. #define    SEP_0        0
  2150. X
  2151. /* x**7 + x**3 + 1.  */
  2152. #define    TYPE_1        1
  2153. #define    BREAK_1        32
  2154. #define    DEG_1        7
  2155. #define    SEP_1        3
  2156. X
  2157. /* x**15 + x + 1.  */
  2158. #define    TYPE_2        2
  2159. #define    BREAK_2        64
  2160. #define    DEG_2        15
  2161. #define    SEP_2        1
  2162. X
  2163. /* x**31 + x**3 + 1.  */
  2164. #define    TYPE_3        3
  2165. #define    BREAK_3        128
  2166. #define    DEG_3        31
  2167. #define    SEP_3        3
  2168. X
  2169. /* x**63 + x + 1.  */
  2170. #define    TYPE_4        4
  2171. #define    BREAK_4        256
  2172. #define    DEG_4        63
  2173. #define    SEP_4        1
  2174. X
  2175. /* Array versions of the above information to make code run faster.
  2176. X   Relies on fact that TYPE_i == i.  */
  2177. X
  2178. #define    MAX_TYPES    5    /* Max number of types above.  */
  2179. X
  2180. static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
  2181. static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
  2182. X
  2183. /* Initially, everything is set up as if from:
  2184. X    initstate(1, randtbl, 128);
  2185. X   Note that this initialization takes advantage of the fact that srandom
  2186. X   advances the front and rear pointers 10*rand_deg times, and hence the
  2187. X   rear pointer which starts at 0 will also end up at zero; thus the zeroeth
  2188. X   element of the state information, which contains info about the current
  2189. X   position of the rear pointer is just
  2190. X    (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3.  */
  2191. X
  2192. static long randtbl[DEG_3 + 1] =
  2193. X  { TYPE_3,
  2194. X      0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342,
  2195. X      0xde3b81e0, 0xdf0a6fb5, 0xf103bc02, 0x48f340fb,
  2196. X      0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
  2197. X      0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86,
  2198. X      0xda672e2a, 0x1588ca88, 0xe369735d, 0x904f35f7,
  2199. X      0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
  2200. X      0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b,
  2201. X      0xf5ad9d0e, 0x8999220b, 0x27fb47b9
  2202. X    };
  2203. X
  2204. /* FPTR and RPTR are two pointers into the state info, a front and a rear
  2205. X   pointer.  These two pointers are always rand_sep places aparts, as they
  2206. X   cycle through the state information.  (Yes, this does mean we could get
  2207. X   away with just one pointer, but the code for random is more efficient
  2208. X   this way).  The pointers are left positioned as they would be from the call:
  2209. X    initstate(1, randtbl, 128);
  2210. X   (The position of the rear pointer, rptr, is really 0 (as explained above
  2211. X   in the initialization of randtbl) because the state table pointer is set
  2212. X   to point to randtbl[1] (as explained below).)  */
  2213. X
  2214. static long *fptr = &randtbl[SEP_3 + 1];
  2215. static long *rptr = &randtbl[1];
  2216. X
  2217. X
  2218. X
  2219. /* The following things are the pointer to the state information table,
  2220. X   the type of the current generator, the degree of the current polynomial
  2221. X   being used, and the separation between the two pointers.
  2222. X   Note that for efficiency of random, we remember the first location of
  2223. X   the state information, not the zeroeth.  Hence it is valid to access
  2224. X   state[-1], which is used to store the type of the R.N.G.
  2225. X   Also, we remember the last location, since this is more efficient than
  2226. X   indexing every time to find the address of the last element to see if
  2227. X   the front and rear pointers have wrapped.  */
  2228. X
  2229. static long *state = &randtbl[1];
  2230. X
  2231. static int rand_type = TYPE_3;
  2232. static int rand_deg = DEG_3;
  2233. static int rand_sep = SEP_3;
  2234. X
  2235. static long *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
  2236. X
  2237. /* Initialize the random number generator based on the given seed.  If the
  2238. X   type is the trivial no-state-information type, just remember the seed.
  2239. X   Otherwise, initializes state[] based on the given "seed" via a linear
  2240. X   congruential generator.  Then, the pointers are set to known locations
  2241. X   that are exactly rand_sep places apart.  Lastly, it cycles the state
  2242. X   information a given number of times to get rid of any initial dependencies
  2243. X   introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
  2244. X   for default usage relies on values produced by this routine.  */
  2245. X
  2246. void srandom(x)
  2247. unsigned x;
  2248. {
  2249. X  state[0] = x;
  2250. X  if (rand_type != TYPE_0)
  2251. X    {
  2252. X      register long i;
  2253. X      for (i = 1; i < rand_deg; ++i)
  2254. X    state[i] = (1103515145 * state[i - 1]) + 12345;
  2255. X      fptr = &state[rand_sep];
  2256. X      rptr = &state[0];
  2257. X      for (i = 0; i < 10 * rand_deg; ++i) random();
  2258. X    }
  2259. }
  2260. X
  2261. /* Initialize the state information in the given array of N bytes for
  2262. X   future random number generation.  Based on the number of bytes we
  2263. X   are given, and the break values for the different R.N.G.'s, we choose
  2264. X   the best (largest) one we can and set things up for it.  srandom is
  2265. X   then called to initialize the state information.  Note that on return
  2266. X   from srandom, we set state[-1] to be the type multiplexed with the current
  2267. X   value of the rear pointer; this is so successive calls to initstate won't
  2268. X   lose this information and will be able to restart with setstate.
  2269. X   Note: The first thing we do is save the current state, if any, just like
  2270. X   setstate so that it doesn't matter when initstate is called.
  2271. X   Returns a pointer to the old state.  */
  2272. X
  2273. void *initstate(seed, arg_state, n)
  2274. unsigned seed;
  2275. void *arg_state;
  2276. {
  2277. X  void *ostate = (void *) &state[-1];
  2278. X
  2279. X  if (rand_type == TYPE_0)
  2280. X    state[-1] = rand_type;
  2281. X  else
  2282. X    state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
  2283. X  if (n < BREAK_1)
  2284. X    {
  2285. X      if (n < BREAK_0)
  2286. X    {
  2287. X      return NULL;
  2288. X    }
  2289. X      rand_type = TYPE_0;
  2290. X      rand_deg = DEG_0;
  2291. X      rand_sep = SEP_0;
  2292. X    }
  2293. X  else if (n < BREAK_2)
  2294. X    {
  2295. X      rand_type = TYPE_1;
  2296. X      rand_deg = DEG_1;
  2297. X      rand_sep = SEP_1;
  2298. X    }
  2299. X  else if (n < BREAK_3)
  2300. X    {
  2301. X      rand_type = TYPE_2;
  2302. X      rand_deg = DEG_2;
  2303. X      rand_sep = SEP_2;
  2304. X    }
  2305. X  else if (n < BREAK_4)
  2306. X    {
  2307. X      rand_type = TYPE_3;
  2308. X      rand_deg = DEG_3;
  2309. X      rand_sep = SEP_3;
  2310. X    }
  2311. X  else
  2312. X    {
  2313.