home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3967 < prev    next >
Encoding:
Text File  |  1991-09-04  |  56.5 KB  |  2,947 lines

  1. Newsgroups: alt.sources
  2. Path: wupost!zaphod.mps.ohio-state.edu!qt.cs.utexas.edu!yale.edu!cmcl2!sbcs.sunysb.edu!libserv1.ic.sunysb.edu!jallen
  3. From: jallen@libserv1.ic.sunysb.edu (Joseph Allen)
  4. Subject: JOE Version 0.1.0: Part 3 of 3
  5. Message-ID: <1991Sep3.205037.10654@sbcs.sunysb.edu>
  6. Originator: jallen@libserv1.ic.sunysb.edu
  7. Sender: rcarter@wpi.wpi.edu
  8. Nntp-Posting-Host: libserv1.ic.sunysb.edu
  9. Organization: State University of New York at Stony Brook
  10. Date: Tue, 3 Sep 1991 20:50:37 GMT
  11.  
  12.       {
  13.       if(fmeof()) break;
  14.       if(fmrc()==NL) break;
  15.       if(fmrc()==TAB)
  16.        {
  17.        fmdel(1);
  18.        break;
  19.        }
  20.       else fmdel(1);
  21.       ++foo;
  22.       }
  23.       while(foo&7);
  24.      }
  25.     else if(ch!=TAB && fmrc()==TAB)
  26.      {
  27.      TXTSIZ tt;
  28.      tabmark();
  29.      if(tt=tabcol)
  30.       {
  31.       fminsc(ch);
  32.       tabmark();
  33.       fmdel(1);
  34.       if(tabcol!=tt) fmdel(1);
  35.       }
  36.      }
  37.     else
  38.      {
  39.      fmdel(1);
  40.      if(ch!=TAB && ox<(width-2)) uuu=1;
  41.      }
  42.    else if(ox<(width-2) && ch!=TAB) uuu=1;
  43.   }
  44.  if(wrap)
  45.   {
  46.   unsigned char xx;
  47.   if(getrcol()<rmargin) goto skip;
  48.   if(ch==' ')
  49.    type(NL);
  50.   else
  51.    {
  52.    temp=fmnote();
  53.    while(1)
  54.     {
  55.     if(fmnote())
  56.      {
  57.      fmpoint(fmnote()-1);
  58.      xx=fmrc();
  59.      if(xx==NL) break;
  60.      if(xx==' ' || x==TAB)
  61.       {
  62.       fmdel(1);
  63.       added=0;
  64.       type(NL);
  65.       temp+=added;
  66.       break;
  67.       }
  68.      }
  69.     else break;
  70.     }
  71.    fmpoint(temp);
  72.    fminsc(ch);
  73.    rtarw();
  74.    uuu=0;
  75.    }
  76.   }
  77.  else
  78.   {
  79. skip:
  80.   if(overwrite || ch==TAB) fminsc(ch);
  81.   else
  82.    {
  83.    tabmark();
  84.    fminsc(ch);
  85.    tabfix();
  86.    }
  87.   if(ch!=TAB && ch!=NL)
  88.    {
  89.    int cc=showas(ch);
  90.    if(fmnote()>=markb && fmnote()<marke) cc^=INVERSE;
  91.    fmgetc();
  92.    tputcc(cc);
  93.    scrn[ypos*width+oxpos]=cc;
  94.    oxpos++;
  95.    if(fmeof()) { if(!eflag && ox<width-2) uuu=1; }
  96.    else if(fmrc()==NL && !eflag && ox<width-2) uuu=1;
  97.    }
  98.   else fmgetc();
  99.   }
  100.  }
  101. }
  102.  
  103. itype(ch)
  104. unsigned char ch;
  105. {
  106. int x,y;
  107. TXTSIZ temp,temp1;
  108. if(extend)
  109.  {
  110.  if(ch!= NL) fillup();
  111.  else extend=0;
  112.  }
  113. if(ch==NL)
  114.  {
  115.  fminsc(ch);
  116.  fmgetc();
  117.  newy=1;
  118.  if(autoind)
  119.   {
  120.   temp=fmnote();
  121.   uparw();
  122.   for(x=0;1;x++)
  123.    {
  124.    ch=fmgetc();
  125.    if(!(ch==' ' || ch==TAB)) break;
  126.    temp1=fmnote();
  127.    fmpoint(temp);
  128.    fminsc(ch);
  129.    added++;
  130.    fmpoint(temp1);
  131.    temp++;
  132.    }
  133.   fmpoint(fmnote()-(x+1));
  134.   dnarw();
  135.   y=overwrite, overwrite=0;
  136.   for(;x;x--) rtarw();
  137.   overwrite=y;
  138.   }
  139.  }
  140. else
  141.  {
  142.  if(overwrite)
  143.   if(!fmeof()) fmdel(1);
  144.  if(wrap)
  145.   {
  146.   if(getrcol()<rmargin) goto skip;
  147.   if(ch==' ')
  148.    itype(NL);
  149.   else
  150.    {
  151.    temp=fmnote();
  152.    while(1)
  153.     {
  154.     if(fmnote())
  155.      {
  156.      fmpoint(fmnote()-1);
  157.      x=fmrc();
  158.      if(x==NL) break;
  159.      if(x==' ' || x==TAB)
  160.       {
  161.       fmdel(1);
  162.       added=0;
  163.       itype(NL);
  164.       temp+=added;
  165.       break;
  166.       }
  167.      }
  168.     else break;
  169.     }
  170.    fmpoint(temp);
  171.    fminsc(ch);
  172.    rtarw();
  173.    }
  174.   }
  175.  else
  176.   {
  177. skip:
  178.   fminsc(ch);
  179.   rtarw();
  180.   }
  181.  }
  182. }
  183.  
  184. /* Insert space */
  185.  
  186. inss()
  187. {
  188. int t=overwrite;
  189. if(extend)
  190.  {
  191.  extend=0;
  192.  return;
  193.  }
  194. overwrite=0;
  195. type(' ');
  196. ltarw();
  197. overwrite=t;
  198. }
  199.  
  200. /* Deleting backspace */
  201.  
  202. backs()
  203. {
  204. int flag=0,c;
  205. if(extend)
  206.  {
  207.  extend=0;
  208.  return;
  209.  }
  210. if(fmeof()) c=1;
  211. else if(fmrc()==NL) c=1;
  212. if(fmnote())
  213.  {
  214.  ultarw();
  215.  if(fmrc()==TAB) flag=1;
  216.  if(overwrite && !tabmagic)
  217.   {
  218.   itype(' ');
  219.   ultarw();
  220.   }
  221.  else if(overwrite && tabmagic)
  222.   {
  223.   if(c) delch();
  224.   else if(!flag)
  225.    {
  226.    itype(' ');
  227.    ltarw();
  228.    }
  229.   }
  230.  else delch();
  231.  if(oxpos && !flag)
  232.   {
  233.   eputc(8), tputcc(32), eputc(8), oxpos--,scrn[oypos*width+oxpos]=32;
  234.   if(fmeof()) uuu=1;
  235.   else if(fmrc()==NL || overwrite) uuu=1;
  236.   }
  237.  }
  238. }
  239.  
  240. /* quit: exit without saving */
  241.  
  242. eexit()
  243. {
  244. int c;
  245. if(curwin->next==curwin)
  246.  {
  247.  if(changed)
  248.   {
  249.   c=askyn("Do you really want to throw away this file?"); 
  250.   if(c=='N') return;
  251.   if(c== -1) return;
  252.   dclose("File not saved.");
  253.   }
  254.  else
  255.   {
  256.   dclose("File not changed so no update needed");
  257.   }
  258.  leave=1;
  259.  }
  260. else
  261.  {
  262.  struct window *t=curwin;
  263.  if(changed && curbuf->count==1)
  264.   {
  265.   c=askyn("Do you really want to throw away this file?");
  266.   if(c=='N') return;
  267.   if(c== -1) return;
  268.   }
  269.  if(curbuf->count==1)
  270.   {
  271.   struct undorec *u;
  272.   for(u=undorecs;u;u=u->next) if(u->buf==curbuf) u->buf=0;
  273.   free(curbuf->buf), free(curbuf);
  274.   if(curbuf==markbuf) markbuf=0;
  275.   }                           
  276.  else curbuf->count--;
  277.  curwin->next->prev=curwin->prev;
  278.  curwin->prev->next=curwin->next;
  279.  curwin=curwin->prev;
  280.  free(t);
  281.  ldwin(curwin);
  282.  if(topwin==t) topwin=curwin;
  283.  wfit();
  284.  }
  285. }
  286.  
  287. pgup()
  288. {
  289. int nlins=curwin->height-1;
  290. int hlins=nlins/2;
  291. int x,y;
  292. TXTSIZ curpos,z;
  293. if(!hlins) hlins=1;
  294. z=getcol();
  295. curpos=fmnote();
  296. fmpoint(saddr);
  297. for(x=0;x<hlins;x++)
  298.  {
  299.  if(!fmnrnl())
  300.   {
  301.   if(!x)
  302.    {
  303.    gocol(z);
  304.    newy=1;
  305.    return;
  306.    }
  307.   else
  308.    break;
  309.   }
  310.  }
  311. if(fmnrnl()) fmgetc();
  312. saddr=fmnote();
  313. fmpoint(curpos);
  314. setregn(curwin->wind+1,(curwin->wind+curwin->height-1));
  315. cpos(curwin->wind+1,oxpos);
  316. attrib(0);
  317. for(y=0;y<x;y++)
  318.  {
  319.  if(scroll) eputs("\033M");
  320.  fmnrnl();
  321.  }
  322. if(fmnrnl()) fmgetc();
  323. cpos(oypos,oxpos);
  324. gocol(z);
  325. x*=width;
  326. if(scroll) for(y=(curwin->wind+1)*width;y<x+(curwin->wind+1)*width;y++)
  327.  {
  328.  scrn[y+x]=scrn[y];
  329.  scrn[y]= ' ';
  330.  }
  331. }
  332.  
  333. pgdn()
  334. {
  335. int nlins=curwin->height-1;
  336. int hlins=nlins/2;
  337. TXTSIZ curpos,z;
  338. int x,y;
  339. z=getcol();
  340. curpos=fmnote();
  341. x=nlins;
  342. fmpoint(saddr);
  343. do
  344.  {
  345.  if(fmfnl()) fmgetc();
  346.  else
  347.   {
  348.   newy=1;
  349.   gocol(z);
  350.   return;
  351.   }
  352.  }
  353.  while(--x);
  354. for(x=1;x<hlins;x++)
  355.  {
  356.  if(fmfnl()) fmgetc();
  357.  else break;
  358.  }
  359.  
  360. fmpoint(saddr);
  361. for(y=0;y<x;y++)
  362.  {
  363.  fmfnl();
  364.  fmgetc();
  365.  }
  366. saddr=fmnote();
  367.  
  368. setregn(curwin->wind+1,(curwin->wind+curwin->height-1));
  369. cpos((curwin->wind+curwin->height-1),oxpos);
  370. fmpoint(curpos);
  371. attrib(0);
  372. for(y=0;y<x;y++)
  373.  {
  374.  fmfnl();
  375.  fmgetc();
  376.  if(scroll) eputc(10);
  377.  }
  378.  
  379. gocol(z);
  380. cpos(ypos,xpos);
  381. if(scroll)
  382.  {
  383.  y=width*x;
  384.  for(curpos=(curwin->wind+1)*width+y;curpos<(curwin->wind+curwin->height)*
  385.      width;curpos++)
  386.   scrn[curpos-y]=scrn[curpos];
  387.  for(curpos=(curwin->wind+curwin->height)*width-width*x;
  388.      curpos<(curwin->wind+curwin->height)*width;curpos++)
  389.   scrn[curpos]= ' ';
  390.  }
  391. }
  392.  
  393. deleol()
  394. {
  395. TXTSIZ temp=fmnote();
  396. TXTSIZ temp1;
  397. if(extend && pic) return;
  398. extend=0;
  399. fmfnl();
  400. temp1=fmnote()-temp;
  401. fmpoint(temp);
  402. if(temp1) fmdel(temp1);
  403. }
  404.  
  405. killlin()
  406. {
  407. extend=0;
  408. if(!fmeof())
  409.  {
  410.  if(fmrc()==NL) delch();
  411.  else deleol();
  412.  }
  413. }
  414.  
  415. dellin()
  416. {
  417. bol();
  418. deleol();
  419. delch();
  420. }
  421.  
  422. fixpath(s)
  423. unsigned char *s;
  424. {
  425. unsigned char tmp[PATHSIZE], *p, c;
  426. struct passwd *passwd;
  427. if(*s=='~')
  428.  {
  429.  p=s+1;
  430.  while(*p!='/' && *p) ++p;
  431.  if(c= *p)
  432.   {
  433.   *p=0;
  434.   if(passwd=getpwnam(s+1))
  435.    {
  436.    *p=c;
  437.    strcpy(tmp,passwd->pw_dir);
  438.    strcat(tmp,p);
  439.    strcpy(s,tmp);
  440.    }
  441.   }
  442.  }
  443. }
  444.  
  445. exsave()
  446. {
  447. unsigned char sting[PATHSIZE];
  448. if(!changed)
  449.  {
  450.  eexit();
  451.  return;
  452.  }
  453. if(gfnam[0]==0)
  454.  {
  455.  if(!getl("Save file",gfnam))
  456.   return;
  457.  fixpath(gfnam);
  458.  }
  459. else if(!backup)
  460.  {
  461.  sprintf(sting,"/bin/cp %s %s~",gfnam,gfnam);
  462.  cpos(height-2,0);
  463.  system(sting);
  464.  cpos(ypos,xpos);
  465.  }
  466. if(saveit1(gfnam))
  467.  {
  468.  sprintf(sting,"File %s saved.",gfnam);
  469.  if(curwin->next==curwin)
  470.   {
  471.   dclose(sting);
  472.   leave=1;
  473.   }
  474.  else
  475.   eexit();
  476.  }
  477. }
  478.  
  479. saveit()
  480. {
  481. unsigned char gfnam1[PATHSIZE];
  482. unsigned char sting[PATHSIZE];
  483. strcpy(gfnam1,gfnam);
  484. if(!getl("Save file",gfnam1))
  485.  return;
  486. fixpath(gfnam1);
  487. if(!backup && !strcmp(gfnam1,gfnam))
  488.  {
  489.  sprintf(sting,"/bin/cp %s %s~",gfnam,gfnam);
  490.  cpos(height-2,0);
  491.  system(sting);
  492.  cpos(ypos,xpos);
  493.  }
  494. saveit1(gfnam1);
  495. }
  496.  
  497. findline()
  498. {
  499. unsigned char sting[PATHSIZE];
  500. TXTSIZ x;
  501. sting[0]=0;
  502. if(!getl("Goto line",sting))
  503.  return;
  504. x=atol(sting);
  505. if(!x)
  506.  {
  507.  msg("\\iBad line number\\i");
  508.  return;
  509.  }
  510. x--;
  511. bof();
  512. for(;x;x--)
  513.  {
  514.  if(!fmfnl()) break;
  515.  fmgetc();
  516.  }
  517. newy=1;
  518. cntr=1;
  519. return;
  520. }
  521.  
  522. int search()
  523. {
  524. if(options&s_backwards)
  525.  {
  526.  while(fmnote())
  527.   {
  528.   fmrgetc();
  529.   if(options&s_ignore) { if(!fmicmp(sstring,len)) return 1; }
  530.   else if(!fmcmp(sstring,len)) return 1;
  531.   }
  532.  return 0;
  533.  }
  534. else
  535.  {
  536.  while(fmnote()+len<=fmsize())
  537.   {
  538.   if(!(options&s_ignore)) { if(!fmcmp(sstring,len)) return 1; }
  539.   else if(!fmicmp(sstring,len)) return 1;
  540.   fmgetc();
  541.   }
  542.  return 0;
  543.  }
  544. }
  545.  
  546. find(c)
  547. {
  548. int x;
  549. int opts=0;
  550. int n=0;
  551. int rest=0;
  552. int rlen;
  553. TXTSIZ p;
  554. unsigned char ss[80];
  555. extend=0;
  556. if(c=='L'-'@' && sstring[0]) goto srch;
  557. ss[0]=0;
  558. if(!(x=getl("Search string",ss))) return;
  559. if(x== -1)
  560.  {
  561.  if(ss[0])
  562.   strcpy(sstring,ss);
  563.  goto srch;
  564.  }
  565. if(!ss[0]) return;
  566. strcpy(sstring,ss);
  567. ss[0]=0;
  568. if(!getl("(I)gnore case (B)ackwards (R)eplace n",ss)) return;
  569. for(x=0;ss[x];x++)
  570.  {
  571.  if(ss[x]=='i' || ss[x]=='I') opts|=s_ignore;
  572.  if(ss[x]=='b' || ss[x]=='B') opts|=s_backwards;
  573.  if(ss[x]=='r' || ss[x]=='R') opts|=s_replace;
  574.  if(ss[x]=='x' || ss[x]=='X') opts|=s_regex;
  575.  if(ss[x]>='0' && ss[x]<='9') n*=10, n+=ss[x]-'0';
  576.  }
  577. options=opts;
  578. if(options&s_replace)
  579.  {
  580.  ss[0]=0;
  581.  if(!(x=getl("Replace with",ss))) return;
  582.  if(x!= -1)
  583.   strcpy(rstring,ss);
  584.  }
  585. srch:
  586. if(!sstring[0]) return;
  587. len=strlen(sstring);
  588. rlen=strlen(rstring);
  589. rpt:
  590. p=fmnote();
  591. if(search())
  592.  {
  593.  if(!(options&s_backwards)) fmpoint(fmnote()+len);
  594.  if(options&s_replace)
  595.   {
  596.   if(rest) goto dn;
  597.   newy=1;
  598.   upd=1;
  599.   cntr=1;
  600.   extend=0;
  601.   dupdate();
  602. again:
  603.   x=nquery(
  604.   "Replace? (Yes, No, ^C to abort or R to replace rest without asking)");
  605.   if(x=='n' || x=='N') goto rpt;
  606.   if(x== 3) return;
  607.   if(x=='y' || x=='Y') goto dn;
  608.   if(x=='r' || x=='R')
  609.    {
  610.    rest=1;
  611.    goto dn;
  612.    }
  613.   goto again;
  614. dn:
  615.   if(options&s_backwards)
  616.    {
  617.    fmdel(len);
  618.    fminss(rstring,rlen);
  619.    }
  620.   else
  621.    {
  622.    fmpoint(fmnote()-len);
  623.    fmdel(len);
  624.    fminss(rstring,rlen);
  625.    fmpoint(fmnote()+rlen);
  626.    }
  627.   if(n)
  628.    if(n==1) goto exi;
  629.    else n--;
  630.   goto rpt;
  631.   }
  632.  else if(n)
  633.   {
  634.   if(n==1) goto exi;
  635.   n--;
  636.   goto rpt;
  637.   }
  638.  }
  639. else
  640.  {
  641.  if(!(options&s_replace) || n>1)
  642.   msg("Not found");
  643.  fmpoint(p);
  644.  return;
  645.  }
  646. exi:
  647. cntr=1;
  648. newy=1;
  649. }
  650.  
  651. findnext()
  652. {
  653. find('L'-'@');
  654. }
  655.  
  656. findfirst()
  657. {
  658. find(0);
  659. }
  660.  
  661. struct buffer *markbuf;
  662.  
  663. setbeg()
  664. {
  665. markb=fmnote();
  666. if(markbuf!=curbuf)
  667.  {
  668.  markbuf=curbuf;
  669.  marke=0;
  670.  }
  671. }
  672.  
  673. setend()
  674. {
  675. marke=fmnote();
  676. if(markbuf!=curbuf)
  677.  {
  678.  markbuf=curbuf;
  679.  markb=0;
  680.  }
  681. }
  682.  
  683. writeblk()
  684. {
  685. unsigned char gfnam1[PATHSIZE];
  686. unsigned char sting[PATHSIZE];
  687. TXTSIZ sv=fmnote();
  688. struct buffer *bt=curbuf;
  689. if(markbuf)
  690.  {
  691.  stbuf(curbuf);
  692.  ldbuf(markbuf);
  693.  }
  694. if(markb>=marke || marke>fmsize() || !markbuf)
  695.  {
  696.  msg("\\iNo block\\i");
  697.  if(markbuf)
  698.   ldbuf(bt);
  699.  return;
  700.  }
  701. gfnam1[0]=0;
  702. if(!getl("File to write block to",gfnam1))
  703.  {
  704.  ldbuf(bt);
  705.  return;
  706.  }
  707. fixpath(gfnam1);
  708. handle=fopen(gfnam1,"w+");
  709. if(handle)
  710.  {
  711.  fmpoint(markb);
  712.  if(!fmsave(handle,marke-markb))
  713.   {
  714.   sprintf(sting,"\\iError writting to file %s\\i",gfnam1);
  715.   msg(sting);
  716.   }
  717.  stbuf(markbuf);
  718.  ldbuf(bt);
  719.  fmpoint(sv);
  720.  fclose(handle);
  721.  }
  722. else
  723.  {
  724.  ldbuf(bt);
  725.  sprintf(sting,"\\iError opening file %s\\i",gfnam1);
  726.  msg(sting);
  727.  }
  728. }
  729.  
  730. delblk()
  731. {
  732. struct buffer *bt=curbuf;
  733. TXTSIZ x=fmnote();
  734. TXTSIZ sz;
  735. if(markbuf)
  736.  {
  737.  stbuf(curbuf);
  738.  ldbuf(markbuf);
  739.  }
  740. if(marke<=markb || marke>fmsize() || !markbuf)
  741.  {
  742.  msg("\\iNo block\\i");
  743.  if(markbuf)
  744.   ldbuf(bt);
  745.  return;
  746.  }
  747. if(bt==markbuf) if(x>=markb && x<marke) x=markb;
  748. sz=marke-markb;
  749. fmpoint(markb);
  750. fmdel(sz);
  751. if(bt==markbuf) if(x>markb) x-=sz;
  752. stbuf(markbuf);
  753. ldbuf(bt);
  754. fmpoint(x);
  755. updall=1;
  756. newy=1;
  757. }
  758.  
  759. moveblk()
  760. {
  761. unsigned char *t;
  762. TXTSIZ sz, x=fmnote();
  763. struct buffer *bt=curbuf;
  764. if(markbuf)
  765.  {
  766.  stbuf(curbuf);
  767.  ldbuf(markbuf);
  768.  }
  769. if(marke<=markb || marke>fmsize() || !markbuf)
  770.  {
  771.  msg("\\iNo block\\i");
  772.  if(markbuf)
  773.   ldbuf(bt);
  774.  return;
  775.  }
  776. if(x>=markb && x<=marke && bt==markbuf)
  777.  {
  778.  x=markb;
  779.  ldbuf(bt);
  780.  return;
  781.  }
  782. sz=marke-markb;
  783. t=(unsigned char *)malloc(sz);
  784. fmpoint(markb);
  785. fmcpy(t,sz);
  786. fmdel(sz);
  787. if(bt==markbuf) if(x>markb) x-=sz, newy=1;
  788. stbuf(markbuf); 
  789. ldbuf(bt);
  790. fmpoint(x);
  791. fminss(t,sz);
  792. free(t);
  793. markb=x;
  794. marke=x+sz;
  795. markbuf=bt;
  796. updall=1;
  797. }
  798.  
  799. cpyblk()
  800. {
  801. unsigned char *t;
  802. TXTSIZ x=fmnote();
  803. struct buffer *bt=curbuf;
  804. TXTSIZ sz;
  805. if(markbuf)
  806.  {
  807.  stbuf(curbuf);
  808.  ldbuf(markbuf);
  809.  }
  810. if(marke<=markb || marke>fmsize() || !markbuf)
  811.  {
  812.  msg("\\iNo block\\i");
  813.  if(markbuf)
  814.   ldbuf(bt);
  815.  return;
  816.  }
  817. sz=marke-markb;
  818. t=(unsigned char *)malloc(sz);
  819. fmpoint(markb);
  820. fmcpy(t,sz);
  821. stbuf(markbuf);
  822. ldbuf(bt); 
  823. fmpoint(x);
  824. fminss(t,sz);
  825. free(t);
  826. marke=x+sz;
  827. markb=x;
  828. markbuf=bt;
  829. updall=1;
  830. }
  831.  
  832. insfil()
  833. {
  834. unsigned char gfnam1[PATHSIZE];
  835. unsigned char sting[PATHSIZE];
  836. gfnam1[0]=0;
  837. if(!getl("File to insert",gfnam1)) return;
  838. fixpath(gfnam1);
  839. handle=fopen(gfnam1,"r");
  840. if(handle)
  841.  {
  842.  if(!fminsfil(handle))
  843.   {
  844.   sprintf(sting,"\\iError inserting file %s\\i",gfnam1);
  845.   msg(sting);
  846.   }
  847.  newy=1;
  848.  fclose(handle);
  849.  }
  850. else
  851.  {
  852.  sprintf(sting,"\\iError opening file %s\\i",gfnam1);
  853.  msg(sting);
  854.  return;
  855.  }
  856. }
  857.  
  858. push()
  859. {
  860. unsigned char *ssh=(unsigned char *)getenv("SHELL");
  861. if(!ssh)
  862.  {
  863.  msg("Couldn't find shell");
  864.  return;
  865.  }
  866. dclose("You are at the command shell.  Type 'exit' to continue editing");
  867. shell(ssh);
  868. rewrite();
  869. }
  870.  
  871. mode()
  872. {
  873. unsigned char s[PATHSIZE];
  874. s[0]=0;
  875. strcat(s,"(R)ght Mrgn ");
  876. if(overwrite) strcat(s,"(I) Overtype ");
  877. else strcat(s,"(I)nsert ");
  878. if(tabmagic) strcat(s,"(T)ab Magic on ");
  879. else strcat(s,"(T)ab Magic off ");
  880. if(wrap) strcat(s,"(W)rap on ");
  881. else strcat(s,"(W)rap off ");
  882. if(autoind) strcat(s,"(A) Indent on ");
  883. else strcat(s,"(A) Indent off ");
  884. if(pic) strcat(s,"(P)ic on: ");
  885. else strcat(s,"(P)ic off: ");
  886. switch(query(s))
  887.  {
  888.  case 'i':
  889.  case 'I':
  890.  case 'o':
  891.  case 'O':
  892.   overwrite= !overwrite;
  893.   break;
  894.  case 'W':
  895.  case 'w':
  896.   wrap= !wrap;
  897.   break;
  898.  case 'a':
  899.  case 'A':
  900.   autoind= !autoind;
  901.   break;
  902.  case 't':
  903.  case 'T':
  904.   tabmagic= !tabmagic;
  905.   break;
  906.  case 'p':
  907.  case 'P':
  908.   pic= !pic;
  909.   break;
  910.  case 'r':
  911.  case 'R':
  912.   {
  913.   char sting[80];
  914.   sprintf(sting,"%d",rmargin);
  915.   if(!getl("Right margin",sting)) return;
  916.   rmargin=atol(sting);
  917.   if(rmargin<2) rmargin=2;
  918.   }
  919.  }
  920. }
  921.  
  922. /* Center the current line */
  923.  
  924. ctrlin()
  925. {
  926. TXTSIZ x;
  927. int tmp=pic;
  928. int y;
  929. unfill();
  930. bol();
  931. while(y=fmrc(), y==' ' || y=='\t') fmdel(1);
  932. eol();
  933. x=fmnote();
  934. bol();
  935. if(x-fmnote()>rmargin) return;
  936. y=(rmargin/2)-(x-fmnote())/2;
  937. while(y--) fminsc(' ');
  938. pic=1;
  939. udnarw();
  940. pic=tmp;
  941. }
  942.  
  943. /* Reformat a paragraph */
  944.  
  945. reformat()
  946. {
  947. TXTSIZ tmp,idt,idt1,b,e;
  948. unsigned char ch;
  949.  
  950. /* First, determine indentation on current or first non-blank line */
  951.  
  952. up:
  953. idt=calcs();
  954. if(fmeof()) return;     /* Not if at end of file */
  955. if(fmrc()==NL)  /* Ignore any blank lines */
  956.  {
  957.  dnarw();
  958.  goto up;
  959.  }
  960. bol();
  961.  
  962. /* Now find beginning of paragraph */
  963. /* It will be indicated by a change of indentation or a blank line or bof */
  964.  
  965. while(fmnote())         /* Beginning is at bof */
  966.  {
  967.  uparw();
  968.  idt1=calcs();
  969.  if(fmrc()==NL) /* Beginning is blank line */
  970.   {
  971.   bol();
  972.   dnarw();
  973.   break;
  974.   }
  975.  bol();
  976.  if(idt1>idt) break;
  977.  if(idt1<idt)
  978.   {
  979.   dnarw();
  980.   break;
  981.   }
  982.  }
  983.  
  984. /* Point is now at beginning of paragraph (hopefully) */
  985. /* Set the mark */
  986.  
  987. b=fmnote();
  988.  
  989. idt=calcs(); bol();    /* Save indentation level of first line of paragraph */
  990.  
  991. /* Now move to after end of paragraph */
  992. while(1)
  993.  {
  994.  tmp=fmnote();
  995.  dnarw();
  996.  if(fmnote()==tmp)      /* Paragraph ends on end of file */
  997.   {
  998.   eol();
  999.   fminsc(NL);        /* Stick in a NL */
  1000.   fmgetc();
  1001.   extend=0;        /* I don't think I have to do this but... */
  1002.   break;
  1003.   }
  1004.  idt1=calcs();
  1005.  if(fmrc()==NL)        /* Paragraph ends on blank line */
  1006.   {
  1007.   bol();
  1008.   break;
  1009.   }
  1010.  bol();
  1011.  if(idt1>idt) break;    /* Paragraph ends when indentation increases */
  1012.  }
  1013.  
  1014. /* Point now after end of paragraph, cut paragraph */
  1015. e=fmnote();
  1016.  
  1017. /* Now reinsert paragraph in a nice way */
  1018.  
  1019. if(e>b)
  1020.  {
  1021.  unsigned oldwrap=wrap;
  1022.  unsigned oldoverwrite=overwrite;
  1023.  unsigned oldauto=autoind;
  1024.  unsigned flag=0;
  1025.  unsigned char ccc=0;
  1026.  TXTSIZ ppp=b; 
  1027.  overwrite=0;
  1028.  wrap=1;
  1029.  while(ppp!=e)
  1030.   {
  1031.   tmp=fmnote();
  1032.   fmpoint(ppp);
  1033.   ppp++;
  1034.   ch=fmrc();
  1035.   fmpoint(tmp);
  1036.   if(ch==NL) ch=' ';
  1037.   if(ch==' ' || ch==TAB)
  1038.    {
  1039.    if(flag==0) itype(ch);
  1040.    else if(flag==1)
  1041.      {
  1042.      itype(' ');
  1043.      if(!(ccc=='.' || ccc==':' || ccc=='?' || ccc=='!' || ccc=='\"' ||
  1044.           ccc==';')) flag=2;
  1045.      }
  1046.    }
  1047.   else
  1048.    {
  1049.    flag=1;
  1050.    itype(ch);
  1051.    }
  1052.   ccc=ch;
  1053.   }
  1054.  autoind=0;
  1055.  if(flag) itype(NL);
  1056.  wrap=oldwrap;
  1057.  overwrite=oldoverwrite;
  1058.  autoind=oldauto;
  1059.  tmp=fmnote();
  1060.  fmpoint(b);
  1061.  fmdel(e-b);
  1062.  fmpoint(tmp-(e-b));
  1063.  newy=1;
  1064.  }
  1065. }
  1066.  
  1067. killword()
  1068. {
  1069. unsigned char ch;
  1070. ch=fmrc();
  1071. if(((ch>='a' && ch<='z') || (ch>='A' && ch <='Z')) && !fmeof())
  1072.  do
  1073.   {
  1074.   delch();
  1075.   ch=fmrc();
  1076.   } while (((ch>='a' && ch<='z') || (ch>='A' && ch <='Z')) && !fmeof());
  1077. else
  1078.  if((ch==' ' || ch==TAB || ch==NL) && !fmeof())
  1079.   do
  1080.    {
  1081.    delch();
  1082.    ch=fmrc();
  1083.    } while (!fmeof() && (ch==' ' || ch==NL || ch==TAB));
  1084. else
  1085.  if(ch>='0' && ch<='9' && !fmeof())
  1086.   do
  1087.    {
  1088.    delch();
  1089.    ch=fmrc();
  1090.    } while (!fmeof() && ch>='0' && ch<='9');
  1091. else delch();
  1092. }
  1093.  
  1094. backword()
  1095. {
  1096. unsigned char ch;
  1097. if(fmnote())
  1098.  {
  1099.  fmpoint(fmnote()-1);
  1100.  ch=fmgetc();
  1101.  if((ch>='a' && ch<='z') || (ch>='A' && ch <='Z'))
  1102.   {
  1103. up:
  1104.   backs();
  1105.   if(fmnote())
  1106.    {
  1107.    fmpoint(fmnote()-1);
  1108.    ch=fmrc();
  1109.    fmgetc();
  1110.    if((ch>='a' && ch<='z') || (ch>='A' && ch <='Z')) goto up;
  1111.    }
  1112.   }
  1113.  else if(ch==' ' || ch==TAB || ch==NL)
  1114.    {
  1115. up1:
  1116.    backs();
  1117.    if(fmnote())
  1118.     {
  1119.     fmpoint(fmnote()-1);
  1120.     ch=fmrc();
  1121.     fmgetc();
  1122.     if(ch==' ' || ch==TAB || ch==NL) goto up1;
  1123.     }
  1124.    }
  1125.  else if(ch>='0' && ch<='9')
  1126.    {
  1127. up2:
  1128.    backs();
  1129.    if(fmnote())
  1130.     {
  1131.     fmpoint(fmnote()-1);
  1132.     ch=fmrc();
  1133.     fmgetc();
  1134.     if(ch>='0' && ch<='9') goto up2;
  1135.     }
  1136.    }
  1137.  else backs();
  1138.  }
  1139. }
  1140.  
  1141. word()
  1142. {
  1143. int c;
  1144. if(fmnote()==fmsize()) return 0;
  1145. c=fmrc();
  1146. if(c>='a' && c<='z') return 1;
  1147. if(c>='A' && c<='Z') return 1;
  1148. if(c>='0' && c<='9') return 1;
  1149. return 0;
  1150. }
  1151.  
  1152. wrdl()
  1153. {
  1154. extend=0;
  1155. newy=1;
  1156. if(!fmnote()) return;
  1157. fmrgetc();
  1158. while(!word())
  1159.  {
  1160.  if(!fmnote()) return;
  1161.  fmrgetc();
  1162.  }
  1163. while(word())
  1164.  {
  1165.  if(!fmnote()) return;
  1166.  fmrgetc();
  1167.  }
  1168. fmgetc();
  1169. }
  1170.  
  1171. wrdr()
  1172. {
  1173. extend=0;
  1174. newy=1;
  1175. while(!word())
  1176.  {
  1177.  if(fmnote()==fmsize()) return;
  1178.  fmgetc();
  1179.  }
  1180. while(word())
  1181.  {
  1182.  if(fmnote()==fmsize()) return;
  1183.  fmgetc();
  1184.  }
  1185. }
  1186.  
  1187. unsigned char lft[]="{[(<`";
  1188. unsigned char rht[]="}])>'";
  1189.  
  1190. gotomatching()
  1191. {
  1192. TXTSIZ cur=fmnote(),cnt;
  1193. unsigned char c;
  1194. int x;
  1195. extend=0;
  1196. if(fmeof()) return;
  1197. c=fmrc();
  1198. for(x=0;x!=strlen(lft);++x)
  1199.  if(lft[x]==c)
  1200.   {
  1201.   cnt=0;
  1202.   while(!fmeof())
  1203.    {
  1204.    c=fmgetc();
  1205.    if(lft[x]==c) ++cnt;
  1206.    if(rht[x]==c)
  1207.     if(!--cnt)
  1208.      {
  1209.      newy=1;
  1210.      fmrgetc();
  1211.      return;
  1212.      }
  1213.    }
  1214.   fmpoint(cur);
  1215.   return;
  1216.   }
  1217.  else if(rht[x]==c)
  1218.   {
  1219.   cnt=1;
  1220.   while(fmnote())
  1221.    {
  1222.    c=fmrgetc();
  1223.    if(rht[x]==c) ++cnt;
  1224.    if(lft[x]==c)
  1225.     if(!--cnt)
  1226.      {
  1227.      newy=1;
  1228.      return;
  1229.      }
  1230.    }
  1231.   fmpoint(cur);
  1232.   return;
  1233.   }
  1234. }
  1235.  
  1236. int setindent()
  1237. {
  1238. TXTSIZ idt,idt1,cur=fmnote(),tmp;
  1239. if(curbuf==markbuf && cur>=markb && cur<marke) return 1;
  1240. markbuf=curbuf; markb=0; marke=0;
  1241. /* Find beginning */
  1242. idt=calcs();
  1243. if(fmeof()) goto done;
  1244. if(fmrc()==NL) goto done;
  1245. while(fmnrnl())
  1246.  {
  1247.  idt1=calcs();
  1248. /* if(fmrc()!=NL) if(idt1<idt) Use this line instead of one below for
  1249.    setindent to ignore blank lines */
  1250.  if(fmrc()==NL || idt1<idt)
  1251.   {
  1252.   if(fmfnl()) fmgetc();
  1253.   break;
  1254.   }
  1255.  }
  1256. /* Point is now at beginning of block (hopefully) */
  1257. /* Set the mark */
  1258. markb=fmnote();
  1259.  
  1260. while(fmfnl())
  1261.  {
  1262.  fmgetc();
  1263.  idt1=calcs();
  1264. /* if(fmrc()!=NL) if(idt1<idt) Use this line instead of one below for
  1265.    setindent to ignore blank lines */
  1266.  if(fmrc()==NL || idt1<idt)
  1267.   {
  1268.   bol();
  1269.   break;
  1270.   }
  1271.  }
  1272. marke=fmnote();
  1273. done: fmpoint(cur);
  1274. return 0;
  1275.  
  1276. indentr()
  1277. {
  1278. TXTSIZ cur=fmnote(),tmp;
  1279. if(!setindent()) return;
  1280. fmpoint(markb);
  1281. while(fmnote()<marke)
  1282.  {
  1283.  calcs();
  1284.  if(fmeof()) break;
  1285.  if(fmrc()!=NL)
  1286.   {
  1287.   if(fmnote()<=cur) ++cur;
  1288.   fminsc(' ');
  1289.   }
  1290.  if(fmfnl()) fmgetc();
  1291.  else break;
  1292.  }
  1293. done: fmpoint(cur);
  1294. return;
  1295. }
  1296.  
  1297. indentl()
  1298. {
  1299. TXTSIZ cur=fmnote(),idt,tmp;
  1300. if(!setindent()) return;
  1301. fmpoint(markb);
  1302. while(fmnote()<marke)
  1303.  {
  1304.  idt=calcs();
  1305.  if(fmeof()) break;
  1306.  if(fmrc()!=NL) if(!idt) goto done;
  1307.  if(fmfnl()) fmgetc();
  1308.  else break;
  1309.  }
  1310. fmpoint(markb);
  1311. while(fmnote()<marke)
  1312.  {
  1313.  calcs();
  1314.  if(fmeof()) break;
  1315.  if(fmrc()!=NL)
  1316.   {
  1317.   if(fmnote()<=cur) --cur;
  1318.   fmrgetc();
  1319.   fmdel(1);
  1320.   }
  1321.  if(fmfnl()) fmgetc();
  1322.  else break;
  1323.  }
  1324. done: fmpoint(cur);
  1325. return;
  1326. }
  1327.  
  1328. struct window *curwin;
  1329. struct buffer *curbuf;
  1330. struct window *topwin;
  1331.  
  1332. ldbuf(zuffer)
  1333. struct buffer *zuffer;
  1334. {
  1335. if(zuffer==curbuf) return;
  1336. curbuf=zuffer;
  1337. backup=zuffer->backup;
  1338. strcpy(gfnam,zuffer->gfnam);
  1339. bufsiz=zuffer->bufsiz;
  1340. buffer=zuffer->buf;
  1341. filend=zuffer->filend;
  1342. hole=zuffer->hole;
  1343. ehole=zuffer->ehole;
  1344. changed=zuffer->changed;
  1345. }
  1346.  
  1347. ldbuf1(zuffer)
  1348. struct buffer *zuffer;
  1349. {
  1350. curbuf=zuffer;
  1351. backup=zuffer->backup;
  1352. strcpy(gfnam,zuffer->gfnam);
  1353. bufsiz=zuffer->bufsiz;
  1354. buffer=zuffer->buf;
  1355. filend=zuffer->filend;
  1356. hole=zuffer->hole;
  1357. ehole=zuffer->ehole;
  1358. changed=zuffer->changed;
  1359. }
  1360.  
  1361. stbuf(zuffer)
  1362. struct buffer *zuffer;
  1363. {
  1364. zuffer->backup=backup;
  1365. strcpy(zuffer->gfnam,gfnam);
  1366. zuffer->bufsiz=bufsiz;
  1367. zuffer->buf=buffer;
  1368. zuffer->filend=filend;
  1369. zuffer->hole=hole;
  1370. zuffer->ehole=ehole;
  1371. zuffer->changed=changed;
  1372. }
  1373.  
  1374. ldwin(window)
  1375. struct window *window;
  1376. {
  1377. saddr=window->saddr;
  1378. xoffset=window->xoffset;
  1379. pic=window->pic;
  1380. autoind=window->autoind;
  1381. overwrite=window->overwrite;
  1382. wrap=window->wrap;
  1383. tabmagic=window->tabmagic;
  1384. rmargin=window->rmargin;
  1385. extend=window->extend;
  1386. ldbuf1(window->buffer);
  1387. fmpoint(window->cursor);
  1388. }
  1389.                                    
  1390. stwin(window)
  1391. struct window *window;
  1392. window->saddr=saddr;
  1393. window->xoffset=xoffset;
  1394. window->pic=pic;
  1395. window->autoind=autoind;
  1396. window->overwrite=overwrite;
  1397. window->wrap=wrap;
  1398. window->tabmagic=tabmagic;
  1399. window->rmargin=rmargin;
  1400. window->extend=extend;
  1401. window->cursor=fmnote();
  1402. stbuf(window->buffer);
  1403. }
  1404.  
  1405. wfit()
  1406. {
  1407. struct window *x;
  1408. int total;
  1409. updall=1;
  1410. newy=1;
  1411. up:
  1412. total=height-wind;
  1413. for(x=topwin;1;x=x->next)
  1414.  {
  1415.  if(x->height<3) x->height=3;
  1416.  if(curwin==x && total>=3) break;
  1417.  if(total<3) goto in;
  1418.  total-=x->height;
  1419.  if(total<0)
  1420.   {
  1421.   in:
  1422.   topwin=topwin->next;
  1423.   goto up;
  1424.   }
  1425.  }
  1426. for(x=topwin,total=wind;1;x=x->next)
  1427.  {
  1428.  x->wind=total;
  1429.  if(x->height<3) x->height=3;
  1430.  total+=x->height;
  1431.  if(total>=height || x->next==topwin)
  1432.   {
  1433.   total-=x->height;
  1434.   x->height=height-total;
  1435.   return;
  1436.   }
  1437.  }
  1438. }
  1439.  
  1440. wnext()
  1441. {
  1442. stwin(curwin);
  1443. curwin=curwin->next;
  1444. ldwin(curwin);
  1445. wfit();
  1446. }
  1447.  
  1448. wprev()
  1449. {
  1450. stwin(curwin);
  1451. curwin=curwin->prev;
  1452. ldwin(curwin);
  1453. wfit();
  1454. }
  1455.  
  1456. wexplode()
  1457. {
  1458. struct window *x;
  1459. int y;
  1460. if(curwin->height!=height-wind)
  1461.  { /* Make curwin only */
  1462.  topwin=curwin;
  1463.  x=topwin;
  1464.  do
  1465.   {
  1466.   x->height=height-wind;
  1467.   x->wind=wind;
  1468.   x=x->next;
  1469.   }
  1470.   while(x!=topwin);
  1471.  newy=1;
  1472.  }
  1473. else
  1474.  { /* Show all windows */
  1475.  x=topwin; y=0;
  1476.  do y++, x=x->next; while(x!=topwin);
  1477.  if((height-wind)/y<3) y=3;
  1478.  else y=(height-wind)/y;
  1479.  x=topwin;
  1480.  do x->height=y, x=x->next; while(x!=topwin);
  1481.  wfit();
  1482.  }
  1483. }
  1484.  
  1485. wgrow()
  1486. {
  1487. if(curwin->wind+curwin->height==height)
  1488.  {
  1489.  if(curwin->wind!=wind) if(curwin->prev->height>3)
  1490.   curwin->prev->height--, curwin->height++, curwin->wind--, updall=1;
  1491.  }
  1492. else
  1493.  {
  1494.  if(curwin->next->height>3)
  1495.   curwin->height++, curwin->next->wind++, curwin->next->height--, updall=1;
  1496.  }
  1497. newy=1;
  1498. }
  1499.  
  1500. wshrink()
  1501. {
  1502. if(curwin->wind+curwin->height==height)
  1503.  {
  1504.  if(curwin->wind!=wind) if(curwin->height>3)
  1505.  curwin->height--, curwin->prev->height++, curwin->wind++, updall=1;
  1506.  }
  1507. else
  1508.  {
  1509.  if(curwin->height>3)
  1510.  curwin->height--, curwin->next->wind--, curwin->next->height++, updall=1;
  1511.  }
  1512. newy=1;
  1513. }
  1514.  
  1515. wsplit()
  1516. {
  1517. struct window *new;
  1518. if(curwin->height<6) return;
  1519. new=(struct window *)malloc(sizeof(struct window));
  1520. new->buffer=curbuf;
  1521. stwin(new);
  1522. new->next=curwin->next;
  1523. new->prev=curwin;
  1524. curwin->next->prev=new;
  1525. curwin->next=new;
  1526. if(curwin->height&1)
  1527.  {
  1528.  curwin->height/=2;
  1529.  new->height=curwin->height+1;
  1530.  }
  1531. else
  1532.  {
  1533.  curwin->height/=2;
  1534.  new->height=curwin->height;
  1535.  }
  1536. if(curwin->hheight&1)
  1537.  {
  1538.  curwin->hheight/=2;
  1539.  new->hheight=curwin->hheight+1;
  1540.  }
  1541. else
  1542.  {
  1543.  curwin->hheight/=2;
  1544.  new->hheight=curwin->hheight;
  1545.  }
  1546. new->wind=curwin->wind+curwin->height;
  1547. curwin=new;
  1548. curbuf->count++;
  1549. updall=1;
  1550. newy=1;
  1551. }
  1552.  
  1553. wedit()
  1554. {
  1555. unsigned char gfnam1[PATHSIZE];
  1556. unsigned char sting[PATHSIZE];
  1557. int c;
  1558. struct window *x;
  1559. stwin(curwin);
  1560. if(curbuf->count==1 && curbuf->changed)
  1561.  {
  1562.  c=askyn("Do you really want to throw away this file?"); 
  1563.  if(c=='N') return;
  1564.  if(c== -1) return;
  1565.  }
  1566. gfnam1[0]=0;
  1567. if(!getl("File to edit",gfnam1)) return;
  1568. fixpath(gfnam1);
  1569. x=topwin;
  1570. do
  1571.  {
  1572.  if(!strcmp(gfnam1,x->buffer->gfnam))
  1573.   {
  1574.   if(curbuf->count==1)
  1575.    {
  1576.    free(curbuf->buf), free(curbuf);
  1577.    if(curbuf==markbuf) markbuf=0;
  1578.    }                           
  1579.   else 
  1580.    curbuf->count--;
  1581.   curwin->buffer=x->buffer;
  1582.   curwin->buffer->count++;
  1583.   ldbuf(x->buffer);
  1584.   bof();
  1585.   return;
  1586.   }
  1587.  x=x->next;
  1588.  }
  1589.  while(x!=topwin);
  1590. strcpy(gfnam,gfnam1);
  1591. stmode(gfnam);
  1592. if(curbuf->count==1) free(curbuf->buf),
  1593.                              free(curbuf);
  1594. else curbuf->count--;
  1595. curwin->buffer=(struct buffer *)malloc(sizeof(struct buffer));
  1596. curbuf=curwin->buffer;
  1597. curbuf->count=1;
  1598. fmopen();
  1599. bof();
  1600. handle=fopen(gfnam1,"r");
  1601. if(handle)
  1602.  {
  1603.  if(!fminsfil(handle))
  1604.   {
  1605.   sprintf(sting,"\\iError loading file %s\\i",gfnam1);
  1606.   msg(sting);
  1607.   }
  1608.  changed=0;
  1609.  newy=1;
  1610.  fclose(handle);
  1611.  }
  1612. else
  1613.  {
  1614.  newy=1;
  1615.  upd=1;
  1616.  if(errno==ENOENT)
  1617.   {
  1618.   dupdate();
  1619.   msgout(curwin->wind+1,"New File",0);
  1620.   cpos(curwin->wind+1,0);
  1621.   backup=1;
  1622.   }
  1623.  else
  1624.   {
  1625.   dupdate();
  1626.   msgout(curwin->wind+1,"\\iError opening file\\i",0);
  1627.   cpos(curwin->wind+1,0);
  1628.   }
  1629.  dokey(anext());
  1630.  return;
  1631.  }
  1632. }
  1633.  
  1634. rtn()
  1635. {
  1636. type(NL);
  1637. }
  1638.  
  1639. stquote()
  1640. {
  1641. quoteflg=1;
  1642. }
  1643.  
  1644. stquote8th()
  1645. {
  1646. quote8th=1;
  1647. }
  1648.  
  1649. CMD kkm[55]=
  1650. {
  1651.  {"uparw",0,uuparw},
  1652.  {"rtarw",0,urtarw},
  1653.  {"ltarw",0,ultarw},
  1654.  {"dnarw",0,udnarw},
  1655.  {"eol",0,eol},
  1656.  {"pgdn",0,pgdn},
  1657.  {"bol",0,bol},
  1658.  {"pgup",0,pgup},
  1659.  {"ctrlin",0,ctrlin},
  1660.  {"setbeg",0,setbeg},
  1661.  {"cpyblk",0,cpyblk},
  1662.  {"saveit",0,saveit},
  1663.  {"wedit",0,wedit},
  1664.  {"findfirst",0,findfirst},
  1665.  {"findnext",0,findnext},
  1666.  {"wgrow",0,wgrow},
  1667.  {"thelp",0,thelp},
  1668.  {"wexplode",0,wexplode},
  1669.  {"reformat",0,reformat},
  1670.  {"setend",0,setend},
  1671.  {"findline",0,findline},
  1672.  {"moveblk",0,moveblk},
  1673.  {"wnext",0,wnext},
  1674.  {"wprev",0,wprev},
  1675.  {"wsplit",0,wsplit},
  1676.  {"insfil",0,insfil},
  1677.  {"wshrink",0,wshrink},
  1678.  {"bof",0,bof},
  1679.  {"eof",0,eof},
  1680.  {"writeblk",0,writeblk},
  1681.  {"exsave",0,exsave},
  1682.  {"delblk",0,delblk},
  1683.  {"push",0,push},
  1684.  {"eexit",0,eexit},
  1685.  {"delch",0,delch},
  1686.  {"inss",0,inss},
  1687.  {"backs",0,backs},
  1688.  {"type",0,type},
  1689.  {"deleol",0,deleol},
  1690.  {"rtn",0,rtn},
  1691.  {"backword",0,backword},
  1692.  {"rewrite",0,rewrite},
  1693.  {"mode",0,mode},
  1694.  {"killword",0,killword},
  1695.  {"wrdr",0,wrdr},
  1696.  {"dellin",0,dellin},
  1697.  {"wrdl",0,wrdl},
  1698.  {"stquote8th",0,stquote8th},
  1699.  {"stquote",0,stquote},
  1700.  {"gotomatching",0,gotomatching},
  1701.  {"indentl",0,indentl},
  1702.  {"indentr",0,indentr},
  1703.  {"undo",0,undo},
  1704.  {"redo",0,redo},
  1705.  {"killlin",0,killlin}
  1706.  };
  1707.  
  1708. CONTEXT km={0, "main", 0, 55, kkm};
  1709.  
  1710. /** Key sequence processing functions **/
  1711.  
  1712. struct kmap *curmap;
  1713. int quoteflg=0;
  1714. int quote8th=0;
  1715.  
  1716. int dokey(k)
  1717. unsigned char k;
  1718. {
  1719. int above=curmap->len;
  1720. int below=0;
  1721. int new;
  1722. struct kmap *r;
  1723. if(quoteflg)
  1724.  {
  1725.  quoteflg=0;
  1726.  if(k>='@' && k<='_') k-='@';
  1727.  if(k>='a' && k<='z') k-='`';
  1728.  if(k=='?') k=127;
  1729.  type(k);
  1730.  goto abcd;
  1731.  }
  1732. goto in;
  1733. do
  1734.  {
  1735.  new=(above+below)/2;
  1736.  if((curmap->keys[new].k&KEYMASK)==k)
  1737.   if(curmap->keys[new].k&KEYSUB)
  1738.    {
  1739.    curmap=(KMAP *)(curmap->keys[new].n);
  1740.    return Kaccept;
  1741.    }
  1742.   else
  1743.    {
  1744.    int h=height, w=width;
  1745.    getsize();
  1746.    if(h!=height || w!=width) resize();
  1747.    r=curmap;
  1748.    curmap=km.kmap;
  1749.    if(km.cmd[r->keys[new].n].func!=redo &&
  1750.       km.cmd[r->keys[new].n].func!=undo) undoptr=0;
  1751.    km.cmd[r->keys[new].n].func(k);
  1752.    abcd:
  1753.    if(!leave)
  1754.     {
  1755.     if(!uuu) upd=1;
  1756.     else uuu=0;
  1757.     dupdate();
  1758.     }
  1759.    return 0;
  1760.    }
  1761.  else if((curmap->keys[new].k&KEYMASK)>k)
  1762.   {
  1763.   above=new;
  1764.   in:
  1765.   if(above==below) break;
  1766.   }
  1767.  else if(below==new) break;
  1768.  else below=new;
  1769.  } while(1);
  1770. curmap=km.kmap;
  1771. return Kbad;
  1772. }
  1773.  
  1774. edit()
  1775. {
  1776. newy=1;
  1777. dupdate();
  1778. imsg();
  1779. dokey(anext());
  1780. if(leave) return;
  1781. upd=1;
  1782. newy=1;
  1783. do
  1784.  dokey(anext());
  1785.  while(!leave);
  1786. }
  1787.  
  1788. struct mpair
  1789.  {
  1790.  struct mpair *next;
  1791.  unsigned char *s;
  1792.  int wrap;
  1793.  int autoind;
  1794.  int pic;
  1795.  int overwrite;
  1796.  int tabmagic;
  1797.  TXTSIZ rmargin;
  1798.  };
  1799.  
  1800. struct mpair *mpairs=0;
  1801.  
  1802. stmode(name)
  1803. unsigned char *name;
  1804. {
  1805. int x=strlen(name);
  1806. struct mpair *mp=mpairs;
  1807. while(mp)
  1808.  if(!strcmp(mp->s,name+x-strlen(mp->s)))
  1809.   {
  1810.   autoind=mp->autoind;
  1811.   wrap=mp->wrap;
  1812.   overwrite=mp->overwrite;
  1813.   pic=mp->pic;
  1814.   tabmagic=mp->tabmagic;
  1815.   break;
  1816.   }
  1817.  else mp=mp->next;
  1818. }
  1819.  
  1820. int process(name,cmds)
  1821. unsigned char *name;
  1822. CONTEXT *cmds;
  1823. {
  1824. CONTEXT *context=0;
  1825. unsigned char buf[PATHSIZE];
  1826. KMAP *kmap;
  1827. FILE *fd=fopen(name,"r");
  1828. int x,y,n,z;
  1829. if(!fd) return -1;
  1830. printf("Processing keymap file %s ...",name);
  1831. fflush(stdout);
  1832. while(fgets(buf,256,fd))
  1833.  {
  1834.  if(buf[0]=='{')
  1835.   {
  1836.   up:
  1837.   if(!fgets(buf,256,fd)) break;
  1838.   if(buf[0]=='}') continue;
  1839.   if(helpsize+strlen(buf)>helpblksize)
  1840.    {
  1841.    if(help) help=(unsigned char *)realloc(help,helpblksize+strlen(buf)+320);
  1842.    else help=(unsigned char *)malloc(strlen(buf)+320);
  1843.    helpblksize+=strlen(buf)+320;
  1844.    }
  1845.   strcat(help,buf);
  1846.   helpsize=strlen(help);
  1847.   ++helplines;
  1848.   goto up;
  1849.   }
  1850.  if(buf[0]=='*')
  1851.   {
  1852.   struct mpair *mp=(struct mpair *)calloc(sizeof(struct mpair),1);
  1853.   int c=0;
  1854.   mp->next=mpairs;
  1855.   mpairs=mp;
  1856.   for(x=0;buf[x];x++)
  1857.    if(buf[x]==' ' || buf[x]=='\t' || buf[x]=='\n')
  1858.     {
  1859.     c=buf[x];
  1860.     buf[x]=0;
  1861.     break;
  1862.     }
  1863.   mp->s=strdupp(buf+1);
  1864.   buf[x]=c;
  1865.   while(buf[x])
  1866.    if(buf[x]!=' ' && buf[x]!='\t' && buf[x]!='\n') break;
  1867.    else x++;
  1868.   while(buf[x] && buf[x]!=' ' && buf[x]!='\t' && buf[x]!='\n')
  1869.    {
  1870.    switch(buf[x])
  1871.     {
  1872.    case 'O':
  1873.    case 'o': mp->overwrite=1;
  1874.    break;
  1875.    case 'W':
  1876.    case 'w': mp->wrap=1;
  1877.    break;
  1878.    case 'a':
  1879.    case 'A': mp->autoind=1;
  1880.    break;
  1881.    case 'p':
  1882.    case 'P': mp->pic=1;
  1883.    break;
  1884.    case 't':
  1885.    case 'T': mp->tabmagic=1;
  1886.     }
  1887.    x++;
  1888.    }
  1889.   continue;
  1890.   }
  1891.  if(buf[0]==':' && buf[1]!=' ' && buf[1]!='\t')
  1892.   {
  1893.   for(x=0;buf[x];x++)
  1894.    if(buf[x]==' ' || buf[x]=='\t' || buf[x]=='\n')
  1895.     {
  1896.     buf[x]=0;
  1897.     break;
  1898.     }
  1899.   context=cmds;
  1900.   while(strcmp(buf+1,context->name))
  1901.    {
  1902.    context=context->next;
  1903.    if(!context)
  1904.     {
  1905.     printf("Unknown context name in keyboard file\n");
  1906.     return -1;
  1907.     }
  1908.    }
  1909.   continue;
  1910.   }
  1911.  for(x=0;buf[x];x++) if(buf[x]==' ' || buf[x]=='\t' || buf[x]=='\n') break;
  1912.  if(buf[0]==' ' || buf[0]=='\t' || buf[0]=='\n' || !buf[x]) continue;
  1913.  if(!context)
  1914.   {
  1915.   printf("No context selected for key\n");
  1916.   return -1;
  1917.   }
  1918.  buf[x]=0;
  1919.  for(y=0;y!=context->size;y++)
  1920.    if(!strcmp(context->cmd[y].name,buf)) goto foundit;
  1921.  printf("Key function not found %s\n",buf);
  1922.  continue;
  1923.  foundit:
  1924.  kmap=0;
  1925.  n= -1;
  1926.  for(++x;buf[x];x++) if(buf[x]!=' ' && buf[x]!='\t') break;
  1927.  while(1)
  1928.   {
  1929.   int c;
  1930.   if(buf[x]==' ') x++;
  1931.   if(!buf[x]) break;
  1932.   if(buf[x]=='\n' || buf[x]==' ' || buf[x]=='\t') break;
  1933.   /* Got Next key */
  1934.   x++;
  1935.   if(buf[x-1]=='^')
  1936.    if(buf[x]==' ' || buf[x]=='\t' || buf[x]=='\n' || !buf[x]) c='^';
  1937.    else if(buf[x]=='?') c=127, x++;
  1938.    else c=(buf[x]&0x1f), x++;
  1939.   else if((buf[x-1]&0x5f)=='S' && (buf[x]&0x5f)=='P') c=' ', x++;
  1940.   else c=buf[x-1];
  1941.   /* Add it as if it were a submap */
  1942.   if(!kmap)
  1943.    {
  1944.    if(!(kmap=context->kmap))
  1945.     {
  1946.     kmap=(KMAP *)malloc(sizeof(KMAP));
  1947.     kmap->keys=(KEY *)malloc(4*sizeof(KEY));
  1948.     kmap->size=4;
  1949.     kmap->len=0;
  1950.     context->kmap=kmap;
  1951.     }
  1952.    }
  1953.   else
  1954.    if(kmap->keys[n].k&KEYSUB) kmap=(KMAP *)(kmap->keys[n].n);
  1955.    else
  1956.     {
  1957.     kmap->keys[n].n=(unsigned)malloc(sizeof(KMAP));
  1958.     kmap->keys[n].k|=KEYSUB;
  1959.     kmap=(KMAP *)(kmap->keys[n].n);
  1960.     kmap->keys=(KEY *)malloc(4*sizeof(KEY));
  1961.     kmap->len=0;
  1962.     kmap->size=4;
  1963.     }
  1964.   for(n=0;n!=kmap->len;n++)
  1965.    if((kmap->keys[n].k&KEYMASK)==c) goto sub;
  1966.    else if((kmap->keys[n].k&KEYMASK)>c) break;
  1967.   if(kmap->len==kmap->size)
  1968.    kmap->keys=(KEY *)realloc(kmap->keys,sizeof(KEY)*(kmap->size+=8));
  1969.   for(z=kmap->len;z!=n;z--) kmap->keys[z]=kmap->keys[z-1];
  1970.   kmap->len++;
  1971.   kmap->keys[n].k=c;
  1972.   kmap->keys[n].n=y;
  1973.   sub:;
  1974.   }
  1975.  }
  1976. fclose(fd);
  1977. printf("done\n");
  1978. return 0;
  1979. }
  1980.  
  1981. int main(argc,argv)
  1982. unsigned char *argv[];
  1983. {
  1984. if(process(KEYMAP,&km))
  1985.  {
  1986.  unsigned char *hh=(unsigned char *)getenv("HOME");
  1987.  if(!hh) goto in;
  1988.  strcpy(gfnam,hh);
  1989.  strcat(gfnam,"/");
  1990.  strcat(gfnam,KEYMAP);
  1991.  if(process(gfnam,&km))
  1992.   {
  1993.   in:
  1994.   if(process(KEYDEF,&km))
  1995.    {
  1996.    printf("Couldn't open keymap\n");
  1997.    return 1;
  1998.    }
  1999.   }
  2000.  }
  2001. curmap=km.kmap;
  2002. if(argc>2)
  2003.  {
  2004.  fputs("\nIllegal number of command line arguments",stderr);
  2005.  fputs("\nEditor Command Format:  joe [filename]\n",stderr);
  2006.  return 0;
  2007.  }
  2008. termtype();
  2009. curwin=(struct window *)malloc(sizeof(struct window));
  2010. topwin=curwin;
  2011. curwin->next=curwin;
  2012. curwin->prev=curwin;
  2013. markbuf=0;
  2014. curwin->height=height;
  2015. curwin->wind=0;
  2016. curwin->buffer=(struct buffer *)malloc(sizeof(struct buffer));
  2017. curbuf=curwin->buffer;
  2018. curbuf->count=1;
  2019. aopen();
  2020. dopen();
  2021. fmopen();
  2022. bof();
  2023. options=0;
  2024. sstring[0]=0;
  2025. rstring[0]=0;
  2026. leave=0;
  2027.  
  2028. rmargin=width-2;
  2029. tabmagic=0;
  2030. wrap=1;
  2031. autoind=0;
  2032. overwrite=0;
  2033. pic=0;
  2034. stmode("");
  2035.  
  2036. gfnam[0]=0;
  2037.  
  2038. if(argc==2)
  2039.  {
  2040.  strcpy(gfnam,argv[1]);
  2041.  stmode(gfnam);
  2042.  handle=fopen(argv[1],"r");
  2043.  if(handle)
  2044.   {
  2045.   if(!fminsfil(handle))
  2046.    omsg=(unsigned char *)"\\iError reading file\\i";
  2047.   else
  2048.    changed=0;
  2049.   fclose(handle);
  2050.   }
  2051.  else
  2052.   {
  2053.   if(errno==ENOENT)
  2054.    {
  2055.    omsg=(unsigned char *)"New File";
  2056.    backup=1;
  2057.    }
  2058.   else
  2059.    omsg=(unsigned char *)"\\iError opening file\\i";
  2060.   }
  2061.  }
  2062. else omsg=(unsigned char *)"New File";
  2063. edit();
  2064. aclose();
  2065. return 0;
  2066. }
  2067.  
  2068. tsignal(sig)
  2069. {
  2070. handle=fopen(ABORT,"w+");
  2071. fmpoint(0);
  2072. fmsave(handle,fmsize());
  2073. fclose(handle);
  2074. /*
  2075. aclose();
  2076. printf("\rE aborted by signal %d\r\n",sig);
  2077. printf("Last edit file stored in file called aborted.e\r\n");
  2078. */
  2079. _exit(1);
  2080. }
  2081. SHAR_EOF
  2082. if test 58207 -ne "`wc -c < 'joe.c'`"
  2083. then
  2084.     echo shar: error transmitting "'joe.c'" '(should have been 58207 characters)'
  2085. fi
  2086. fi # end of overwriting check
  2087. if test -f 'joe.h'
  2088. then
  2089.     echo shar: will not over-write existing file "'joe.h'"
  2090. else
  2091. cat << \SHAR_EOF > 'joe.h'
  2092. /* JOE header file
  2093.    Copyright (C) 1991 Joseph H. Allen
  2094.  
  2095. This file is part of JOE (Joe's Own Editor)
  2096.  
  2097. JOE is free software; you can redistribute it and/or modify it under the terms
  2098. of the GNU General Public License as published by the Free Software
  2099. Foundation; either version 1, or (at your option) any later version.  
  2100.  
  2101. JOE is distributed in the hope that it will be useful, but WITHOUT ANY
  2102. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  2103. A PARTICULAR PURPOSE.  See the GNU General Public License for more details.  
  2104.  
  2105. You should have received a copy of the GNU General Public License along with
  2106. JOE; see the file COPYING.  If not, write to the Free Software Foundation, 675
  2107. Mass Ave, Cambridge, MA 02139, USA.  */ 
  2108.  
  2109. /* File characteristics */
  2110.  
  2111. #define NL '\n'            /* End of line character */
  2112. #define TAB '\t'        /* Tab character */
  2113. #define TABWIDTH 8        /* Tab width */
  2114. #define NOHIGHBIT        /* Comment this out to send characters with
  2115.                    high bit set to terminal as is.  See
  2116.                    the function 'showas'. */
  2117.  
  2118. /* Types used in the file buffer */
  2119.  
  2120. typedef unsigned char * TXTPTR;    /* Pointer to text in the buffer */
  2121. typedef unsigned TXTSIZ;    /* Integer to hold size of file */
  2122. #define TXTFREE(a) free(a)    /* Free a buffer */
  2123. #define TXTMALLOC(a) malloc(a)    /* Allocate a buffer */
  2124. #define TXTREALLOC(a,b) realloc((a),(b))    /* Reallocate a buffer */
  2125.  
  2126. /* File names and characteristics */
  2127.  
  2128. #define PATHSIZE 256        /* Maximum path length */
  2129. #define KEYMAP ".joerc"        /* Keymap file */
  2130. /* #define KEYDEF "/usr/bin/.joerc"    Default keymap file */
  2131. #define ABORT "aborted"        /* Aborted file */
  2132.  
  2133. /* The current file buffer */
  2134. /* When you change windows, these variables get stored in the 'struct buffer'
  2135.    associated with the old window and are load with the values in the
  2136.    'struct buffer' for the new window */
  2137.  
  2138. extern TXTSIZ bufsiz;        /* Size of malloc block buffer is in */
  2139. extern TXTPTR point;        /* The point (cursor) */
  2140. extern TXTPTR buffer;        /* The buffer */
  2141. extern TXTPTR filend;        /* First char not in buffer */
  2142. extern TXTPTR hole;        /* Address of hole */
  2143. extern TXTPTR ehole;        /* First char not in hole */
  2144. extern int changed;        /* Set if buffer changed */
  2145. extern int backup;        /* Set if backup file has been made */
  2146. extern unsigned char gfnam[PATHSIZE];
  2147.                 /* Current edit file name.  "" for unnamed */
  2148.  
  2149. #define HOLESIZE 1024        /* Amount file buffer grows by */
  2150.  
  2151. /*******************************************************/
  2152. /* Basic file buffer manipulation functions and macros */
  2153. /*******************************************************/
  2154.  
  2155. int fminsu();        /* fminsu(size) Adjust pointers by amnt inserted */
  2156. int fmdelu();        /* fmdelu(size) Adjust pointers by amount deleted */ 
  2157. /* The pointers the above two functions currently update include:
  2158.     The pointer to start of each window which references the current
  2159.     buffer.
  2160.  
  2161.     The pointer to cursor in each window which reference the current
  2162.     buffer but not the one for the current window.
  2163.  
  2164.     The begin & end pointers to the marked block if they are in the
  2165.     current buffer.
  2166. */
  2167.  
  2168. /* Return size of hole */
  2169.  
  2170. #define fmholesize() (ehole-hole)
  2171.  
  2172. /* Read character at the point */
  2173.  
  2174. #define fmrc() (point==hole?*(point=ehole):*point)
  2175.  
  2176. /* Overtype character at the point */
  2177.  
  2178. #define fmwc(c) (((point==hole)?point=ehole:0),((point==filend)?(fmexpand(1),\
  2179. filend++):0),*point=(c),changed=1)
  2180.  
  2181. /* Read character at point and advance point */
  2182.  
  2183. #define fmgetc() ((point==hole)?(point=ehole+1,*ehole):*(point++))
  2184.  
  2185. /* Overtype character at point and advance point */
  2186.  
  2187. #define fmputc(c) (((point==hole)?point=ehole:0),((point==filend)?(fmexpand(1),\
  2188. filend++):0),*(point++)=(c),changed=1)
  2189.  
  2190. /* Insert character at point */
  2191.  
  2192. #define fminsc(c) ( fminsu(1), \
  2193. (point!=hole?fmhole():0), (hole==ehole?fmbig(1):0),\
  2194. *(hole++)=(c), changed=1)
  2195.  
  2196. /* Return the byte offset from the beginning of the buffer to the point */
  2197.  
  2198. #define fmnote() ((point>=ehole)?(point-buffer)-(ehole-hole):point-buffer)
  2199.  
  2200. /* Return the size of the file in the buffer */
  2201.  
  2202. #define fmsize() ((filend-buffer)-(ehole-hole))
  2203.  
  2204. /* Return true if the point is at the end of the file */
  2205.  
  2206. #define fmeof() ((point==hole)?(ehole==filend):(point==filend))
  2207.  
  2208. /* Position the point to a byte offset from the beginning of the file */
  2209.  
  2210. #define fmpoint(x) (point=buffer+(x), (point>hole)?(point+=ehole-hole):0)
  2211.  
  2212. /* Retreat the point and then read the character that's there */
  2213.  
  2214. #define fmrgetc() (point==ehole?*(point=hole-1):*(--point))
  2215.  
  2216. /* Position the point to the next NL or the end of the file.  If the point
  2217.    is already at a NL, it is set to the next NL. Return 0 if not found, 1
  2218.    if found */
  2219.  
  2220. #define fmnnl() (fmeof()?0:(fmgetc(),fmfnl()))
  2221.  
  2222. /* Set the point to the beginning of the file or the previous NL.  If the
  2223.    point is already at a NL, it is set to the one before it.  Return 0 if
  2224.    not found, 0 if found */
  2225.  
  2226. #define fmnrnl() (fmnote()?(fmrgetc(),fmrnl()):0)
  2227.  
  2228. int fmopen();            /* fmopen() Initialize current edit buffer */
  2229. int fmexpand();            /* fmexpand(amount) Make buffer bigger */
  2230. int fmhole();            /* fmhole() Move hole to point */
  2231. int fmbig();            /* fmbig(size) Make hole at least size */
  2232. int fmfnl();            /* Find first NL.  Returns 0 if not found */
  2233.                 /* If at an NL already, point is not moved */
  2234. int fmrnl();            /* Find NL in reverse.  Rtns 0 if not found */
  2235.                 /* If at an NL already, point is not moved */
  2236. int fminss();            /* fminss(blk,size) Insert a block at point */
  2237. int fmcmp();            /* fmcmp(blk,size) return 0 if matching */
  2238. int tupp();            /* tupp(c) Convert char to uppercase */
  2239. int fmicmp();            /* Same as fmcmp but ignore case */
  2240. int fmsave();            /* fmsave(FILE,size) Save at point in file */
  2241. int fminsfil();            /* fminsfil(FILE) Insert file at point */
  2242.  
  2243. /******************/
  2244. /* Terminal stuff */
  2245. /******************/
  2246.  
  2247. /* Terminal characteristics (terminal must be vt100ish) */
  2248.  
  2249. extern int width;        /* Screen width */
  2250. extern int height;        /* Screen height */
  2251. extern int scroll;        /* Set if terminal has scrolling regions */
  2252.  
  2253. /* Terminal state */
  2254.  
  2255. extern int smode;        /* Current character attributes */
  2256. extern int tops;        /* Scroll region top (-1 for unknown) */
  2257. extern int bots;        /* Scroll region bottem */
  2258. extern int oxpos;        /* Cursor position */
  2259. extern int oypos;
  2260. extern int *scrn;        /* Screen buffer
  2261.                     -1 means unknown character
  2262.                     0 - 255 means known character
  2263.                 */
  2264.  
  2265. extern unsigned char *omsg;    /* Opening message */
  2266. int dopen();                        /* Open display (clear it, allocate scrn,
  2267.                    etc.) */
  2268. int dclose();                       /* dclose(s) Show final message and close
  2269.                    display */
  2270.  
  2271. int cposs();            /* cpos(row,col) Set cursor position */
  2272. int cpos();                /* cpos(row,col) Set cursor position and
  2273.                    update ox/oypos */
  2274. int setregn();            /* setregn(top,bot) Set scroll region */
  2275.  
  2276. int attrib();            /* attrib(mask) Set attributes */
  2277. #define INVERSE 256
  2278. #define BLINK 512
  2279. #define UNDERLINE 1024
  2280. #define BOLD 2048
  2281.  
  2282. /*****************/
  2283. /* Screen update */
  2284. /*****************/
  2285.  
  2286. /* Flags which high-level edit functions set to control the screen
  2287.    update.  All three are initialized to 0 before an edit function
  2288.    is executed */
  2289.  
  2290. extern int uuu;            /* Set is no screen update needed */
  2291. extern int cntr;        /* Set to center cursor to middle of
  2292.                    screen if the screen will scroll
  2293.                    (for search/replace) */
  2294. extern int newy;        /* Set if row changed */
  2295. extern int updall;        /* Set to update all windows, not just
  2296.                    the ones with same buffer */
  2297.  
  2298. /* Flags which indicate the current progress of a screen update (I.E., so
  2299.    we can continue if user interrupts screen update) */
  2300.  
  2301. extern int upd;            /* Set if a screen update should be done */
  2302. extern int hupd;        /* Set if a help update should be done */
  2303.  
  2304. extern int helpon;        /* Set if help screen is on */
  2305. extern int wind;        /* Number of help lines */
  2306.  
  2307. extern int xpos;        /* Requested x & y positions (as determined */
  2308. extern int ypos;        /* by scroll calculator: dupdate1 */
  2309.  
  2310. extern TXTSIZ saddr;        /* Byte offset to first char of first screen
  2311.                    line (of current window) */
  2312. extern TXTSIZ xoffset;        /* Cols current window is scrolled to right */
  2313. extern TXTSIZ extend;        /* Column number if past end of line or in
  2314.                    tab stop */
  2315.  
  2316. /* Functions for doing screen update */
  2317.  
  2318. int clreolchk();        /* clreolchk(lin,col) Clear to end of line if needed */
  2319. int udline();        /* udline(lin) Update a single line.  Return true
  2320.                EOF reached */
  2321. int udscrn();        /* Update screen (returns true if it finished) */
  2322. int dupdate1();        /* dupdate1(flg) Recalculate cursor, scroll & update
  2323.                screen (sets cursor position if flg is set) */
  2324. int dupdatehelp();        /* Update help */
  2325. int dupdate();        /* Update help and screen */
  2326. int invalidate();        /* invalidate(lin) Invalidate a line so it gets upd. */
  2327.  
  2328. /****************/
  2329. /* Window Stuff */
  2330. /****************/
  2331.  
  2332. /* Each file that's edited has a 'struct buffer' associated with it.
  2333.    This stores the buffer variables when the buffer is not the current
  2334.    buffer (I.E., when the cursor is in a window for another file).
  2335. */
  2336.  
  2337. struct buffer
  2338.  {
  2339.  int count;        /* Reference count (No. windows into this buffer) */
  2340.  TXTSIZ bufsiz;        /* Size of malloc block buffer is in */
  2341.  TXTPTR buf;        /* The buffer */
  2342.  TXTPTR filend;        /* First char not in buffer */
  2343.  TXTPTR hole;        /* Address of hole */
  2344.  TXTPTR ehole;        /* First char not in hole */
  2345.  int changed;        /* Set if buffer changed */
  2346.  int backup;        /* Set if backup file has been made */
  2347.  unsigned char gfnam[PATHSIZE];    /* Current edit file name.  "" for unnamed */
  2348.  };
  2349.  
  2350. /* Each window has a 'struct window' associated with it */
  2351.  
  2352. struct window
  2353.  {
  2354.  struct window *next;    /* Doubly linked list of windows */
  2355.  struct window *prev;
  2356.  
  2357.  struct buffer *buffer;    /* The buffer this window looks at */
  2358.  
  2359.  /* Screen variables for each window */
  2360.  
  2361.  TXTSIZ saddr;        /* Byte offset to first character of first line in
  2362.                 window */
  2363.  TXTSIZ xoffset;    /* No. columns the screen is scrolled to the right */
  2364.  
  2365.  /* Window size */
  2366.  
  2367.  int wind;         /* Starting screen line */
  2368.             /* wind is not the same as 'wind' the number of
  2369.                help lines */
  2370.  int height;       /* Height of window */
  2371.  int hheight;      /* Height before help turned on */
  2372.  
  2373.  /* Edit modes */
  2374.  
  2375.  int pic;
  2376.  int autoind;
  2377.  int overwrite;
  2378.  int wrap;
  2379.  int tabmagic;
  2380.  TXTSIZ rmargin;
  2381.  
  2382.  /* Cursor position */
  2383.  
  2384.  TXTSIZ extend;        /* Column number if cursor is past end of line or
  2385.                 if it's in a tab stop */
  2386.  TXTSIZ cursor;        /* Byte offset (in buffer) to the cursor */
  2387.  
  2388.  };
  2389.  
  2390. extern struct window *wfirst;    /* Doubly linked list of windows */
  2391. extern struct window *wlast;
  2392.  
  2393. extern struct window *curwin;    /* Current window */
  2394. extern struct buffer *curbuf;    /* Current buffer */
  2395. extern struct window *topwin;    /* First window on the screen */
  2396.  
  2397. /* Keyboard and command table handler */
  2398.  
  2399. typedef struct key KEY;
  2400. struct key
  2401.  {
  2402.  int k;                 /* Key value */
  2403.  int n;                 /* Command number or submap address */
  2404.             /* sizeof(int) had better = sizeof(KMAP *) */
  2405.  };
  2406.  
  2407. typedef struct kmap KMAP;
  2408. struct kmap
  2409.  {
  2410.  int len;          /* Number of KEY entries */
  2411.  int size;         /* Size of malloc block */
  2412.  KEY *keys;             /* KEYs.  Sorted. */
  2413.  };
  2414.  
  2415. /* Masks & bits for k */
  2416.  
  2417. #define KEYMASK 0x7fff
  2418. #define KEYSUB 0x8000    /* Set for submap */
  2419.  
  2420. /* A command entry */
  2421.  
  2422. typedef struct cmd CMD;
  2423. struct cmd
  2424.  {
  2425.  char *name;
  2426.  int flag;
  2427.  int (*func)();
  2428.  };
  2429.  
  2430. /* A context (group of related commands) */
  2431.  
  2432. typedef struct context CONTEXT;
  2433. struct context
  2434.  {
  2435.  CONTEXT *next;        /* List of all contexts */
  2436.  char *name;            /* Name of this context */
  2437.  KMAP *kmap;        /* Top level keymap for this context */
  2438.  int size;        /* Number of entries in this context */
  2439.  CMD *cmd;        /* The entries themselves (sorted) */
  2440.  };
  2441.  
  2442. int dokey();        /* dokey(c) Execute next key */
  2443. extern int quoteflg;    /* Set if next key is quoted */
  2444. extern int quote8th;    /* Set if next key is quoted */
  2445.  
  2446. /* dokey() Return values */
  2447.  
  2448. #define Kaccept -1    /* Key accepted but not executed */
  2449. #define Kbad -2        /* Bad key */
  2450. /* dokey() used to return a function number; now it executes the function
  2451.    itself so the return values are meaningless */
  2452.  
  2453. /* Messages and queries */
  2454.  
  2455. /* These are all hacks because they return/check for exact key values
  2456.    and don't know about the key table.  Someday a key 'context' should
  2457.    be added for these
  2458. */
  2459.  
  2460. int getl();        /* getl(prompt,line) Get a line of input */
  2461.             /* Returns: -1 if user hits ^L
  2462.                      1 if user hits \n or \r
  2463.                      0 if user hits ^C
  2464.                 (yes this is a stupid hack)
  2465.             */
  2466.  
  2467. int msg();            /* msg(s) Show a message until user hits a key */
  2468.  
  2469. int askyn();        /* askyn(s) Yes/No question 
  2470.             Returns: 'Y', 'N' or -1 for ^C */
  2471.  
  2472. int query();        /* query(s) Show message, wait for user to hit a key,
  2473.                then return key. */
  2474.  
  2475. int nquery();        /* nquery(s) Same as query but leave cursor on
  2476.                edit screen */
  2477. int imsg();                 /* imsg() Show opening message */
  2478.  
  2479. /*******************************************/
  2480. /* High-level edit functions and variables */
  2481. /*******************************************/
  2482.  
  2483. /* Edit modes */
  2484.  
  2485. extern int pic;            /* Set for picture mode */
  2486. extern int autoind;        /* Set for autoindent */
  2487. extern int overwrite;        /* Set for overwrite */
  2488. extern int wrap;        /* Set for autowrap */
  2489. extern int tabmagic;        /* Set for magical tabs */
  2490. extern TXTSIZ rmargin;        /* Current right margin */
  2491.  
  2492. /****************************/
  2493. /* Search and replace stuff */
  2494. /****************************/
  2495.  
  2496. /* Search & replace options */
  2497.  
  2498. #define s_ignore 1        /* Ignore case */
  2499. #define s_backwards 2        /* Search backwards */
  2500. #define s_replace 4        /* Replace */
  2501. #define s_regex 8        /* Regular expression search */
  2502.  
  2503. extern int options;        /* Search options */
  2504. extern unsigned char sstring[PATHSIZE];    /* Search string */
  2505. extern unsigned char rstring[PATHSIZE];    /* Replace string */
  2506. extern int len;            /* Length of search string */
  2507.  
  2508. /**********/
  2509. /* Blocks */
  2510. /**********/
  2511.  
  2512. extern TXTSIZ markb;        /* Begining of block */
  2513. extern TXTSIZ marke;        /* End of block */
  2514. extern struct buffer *markbuf;    /* Buffer block is in or 0 for no block */
  2515.  
  2516. /**************************************/
  2517. /* High level edit function utilities */
  2518. /**************************************/
  2519.  
  2520. extern int leave;        /* Edit function sets this to leave the editor
  2521.                    after the function returns */
  2522.  
  2523. int dnarw();            /* Move cursor to next line */
  2524.                 /* Column number is preserved */
  2525. TXTSIZ calcs();            /* Calculate number of whitespace columns
  2526.                    at beginning of line.  Cursor is left
  2527.                    at first non-whitespace character */
  2528. int saveit1();            /* saveit1(s) Save buffer in file & clear
  2529.                    changed */
  2530. int itype();
  2531. int ltarw();            /* Move cursor left (goes to end of previous
  2532.                    line if at beginning of line) */
  2533. int uparw();            /* Move cursor up (preserves column) */
  2534. int rtarw();                        /* Move cursor right (goes to beginning of
  2535.                    next line if at end of line) */
  2536.  
  2537. /* Return current column number of cursor */
  2538.  
  2539. #define getcol() (extend?extend:getrcol())
  2540.  
  2541. TXTSIZ getrcol();        /* Get column number of point */
  2542. int gocol();            /* gocol(col) Set cursor (point/extend) to
  2543.                    column number */
  2544. int unfill();            /* Remove trailing spaces from line */
  2545. int fillup();                       /* Fill to extend position (use this only
  2546.                    if extend if past end of line, not for
  2547.                    if extend is in tab stop) */
  2548.  
  2549. int search();            /* Execute a search.  Returns 1 if found,
  2550.                    0 if not */
  2551.  
  2552. /* Window functions */
  2553.  
  2554. int ldwin();            /* ldwin(window) load window */
  2555. int stwin();            /* stwin(window) save window */
  2556. int ldbuf();            /* ldbuf(buf) load buf if it's not already */
  2557. int ldbuf1();            /* ldbuf1(buf) load buf always */
  2558. int stbuf();            /* stbuf(buf) store buffer */
  2559. int wfit();            /* make sure the current window is on screen */
  2560.  
  2561. /* High Level (user) edit functions */
  2562.  
  2563. int wnext();            /* goto next window */
  2564. int wprev();            /* goto previous window */
  2565. int wexplode();            /* show 1 or all windows */
  2566. int wgrow();            /* make window bigger */
  2567. int wshrink();            /* make window smaller */
  2568. int wedit();            /* edit a new file */
  2569. int wsplit();            /* Split window into 2 */
  2570.  
  2571. int rewrite();            /* Rewrite screen */
  2572. int thelp();            /* Toggle help screen */
  2573. int bof();            /* Goto beginning of file */
  2574. int eof();            /* Goto end of file */
  2575. int bol();            /* Goto beginning of line */
  2576. int eol();                /* Goto end of line */
  2577. int urtarw();            /* Move cursor right (scroll if need to) */
  2578. int ultarw();
  2579. int uuparw();
  2580. int udnarw();
  2581. int delch();            /* Delete character */
  2582. int type();                /* type(c) type a character */
  2583. int inss();                /* insert a space */
  2584. int backs();            /* backspace */
  2585. int eexit();            /* Exit & abort */
  2586. int pgup();                /* 1/2 Page up */
  2587. int pgdn();                /* 1/2 Page down */
  2588. int deleol();            /* Erase end of line */
  2589. int dellin();            /* Erase entire line */
  2590. int exsave();            /* Save and exit */
  2591. int saveit();            /* Save current file */
  2592. int findline();            /* Goto line No. */
  2593. int findfirst();            /* Find some text */
  2594. int findnext();            /* Find next occurance */
  2595. int setbeg();            /* Set beginning of block */
  2596. int setend();            /* Set end of block */
  2597. int writeblk();            /* Write block to file */
  2598. int moveblk();            /* Move block to point */
  2599. int cpyblk();            /* Copy block to point */
  2600. int delblk();            /* Delete block */
  2601. int insfil();            /* Insert a file */
  2602. int push();                /* Execute a shell */
  2603. int mode();                /* Change edit mode */
  2604. int ctrlin();            /* Center current line */
  2605. int reformat();            /* Reformat current paragraph */
  2606. int killword();            /* Delete word */
  2607. int backword();            /* Delete word to the left */
  2608. int wrdl();                /* goto previous word */
  2609. int wrdr();                /* goto next word */
  2610. int edit();                /* Main edit loop */
  2611.  
  2612. extern FILE *handle;        /* File handle used for many various things */
  2613. extern TXTSIZ added;        /* Number of chars autoindent added
  2614.                 (obsolete?) */
  2615.  
  2616. /* Portable strdup() */
  2617.  
  2618. #define strdupp(x) ((unsigned char *)strcpy((unsigned char *)malloc(strlen(x)+1),(x)))
  2619. SHAR_EOF
  2620. if test 17677 -ne "`wc -c < 'joe.h'`"
  2621. then
  2622.     echo shar: error transmitting "'joe.h'" '(should have been 17677 characters)'
  2623. fi
  2624. fi # end of overwriting check
  2625. if test -f '.joerc'
  2626. then
  2627.     echo shar: will not over-write existing file "'.joerc'"
  2628. else
  2629. cat << \SHAR_EOF > '.joerc'
  2630.                           Initializtaion file for JOE
  2631.  
  2632.  JOE looks for this file in:
  2633.         1 - Current directory
  2634.         2 - User's home directory
  2635.         3 - /usr/bin  (or whatever KEYDEF was set to in the Makefile)
  2636.  
  2637.  Comments:
  2638.    Any line beginning with whitespace is a comment line.  At least 2
  2639.    characters of whitespace past the end of a line also begin a comment.
  2640.  
  2641.  FIRST SECTION:  File name dependant mode settings
  2642.  
  2643.  Each line with '*' in the first column indicates the modes which should be
  2644.  set for a particular extension (or ending actually).  If there are more than
  2645.  one of these lines which match a particular file name, then the last line
  2646.  which matches the name is the one which is chosen.
  2647.  
  2648.  Here is a list of characters.  Each sets a particular mode.  If the character
  2649.  is missing, then the mode shown in the parenthasis is set.
  2650.  
  2651.         a    autoindent (no auto indent)
  2652.         o    overwrite  (insert)
  2653.         p    picture mode (no picture mode)
  2654.         w    word wrap (no word wrap)
  2655.         t    tab magic (no tab magic)
  2656.  
  2657.  Here are the file name dependant mode setting lines:
  2658.  
  2659. *        wt        Default for unknown extensions.  This line
  2660.                 must appear first.
  2661. *.c        at        C programs
  2662. *.h        at        C header files
  2663. *.p        at        Pascal programs
  2664. *.f        at        Fortran programs
  2665. *.joerc        at        This file
  2666.  
  2667.  SECOND SECTION:  Lines between the { and the } are the on-line help text.  Use
  2668.  \u to turn underline on or off.  Use \i to turn inverse on or off.  Use \\
  2669.  to display \
  2670.  
  2671. {
  2672. \i   Help Screen    turn off with ^KH                                            \i
  2673. \i \i\uGO\u \uTO\u              \uDELETE\u    \uMISC\u      \uBLOCK\u    \uFIND\u     \uQUOTE\u    \uWINDOW\u     \i \i
  2674. \i \i^B left  ^F right ^D single ^T  mode   ^KB mark ^KF text `  Ctrl  ^KO split  \i \i
  2675. \i \i^Z word  ^X word  ^W >word  ^R  retype ^KK end  ^L  next ^\\ bit-7 ^KI 1 / all\i \i
  2676. \i \i^A edge  ^E edge  ^O word<  ^KA center ^KC copy ^KL line \uFILE\u     ^KP up     \i \i
  2677. \i \i^P up    ^N down  ^J >line  ^KJ format ^KM move \uEXIT\u     ^KD save ^KN down   \i \i
  2678. \i \i^U page  ^V page  ^Y line   ^KZ shell  ^KW save ^KX save ^KR read ^KG grow   \i \i
  2679. \i \i^KU top ^KV end   ^K- undo  ^K, indnt< ^KY kill ^C abort/         ^KT shrink \i \i
  2680. \i \i^G matching ([<{` ^K+ redo  ^K. indnt>             close window  ^KE get file\i \i
  2681. }
  2682.  
  2683.  THIRD SECTION:  Key sequence to command bindings.  Use ^@ to ^_ and ^? to
  2684.  specify control characters.
  2685.  
  2686. :main
  2687.  
  2688. backs        ^H            Backspace
  2689. backs        ^?
  2690. backword    ^O            Backspace word
  2691. bof        ^K U            Move cursor to beginning of file
  2692. bof        ^K ^U
  2693. bof        ^K u
  2694. bol        ^A            Move cursor to beginning of line
  2695. bol        ^[ [ H
  2696. bol        ^K ^[ [ H
  2697. bol        ^[ O P
  2698. bol        ^K ^[ O P
  2699. cpyblk        ^K C            Copy previously marked block
  2700. cpyblk        ^K ^C
  2701. cpyblk        ^K c
  2702. ctrlin        ^K A            Center line
  2703. ctrlin        ^K ^A
  2704. ctrlin        ^K a
  2705. delblk        ^K Y            Delete previously marked block
  2706. delblk        ^K ^Y
  2707. delblk        ^K y
  2708. delch        ^D            Delete character
  2709. deleol        ^J            Delete to end of line
  2710. dellin        ^Y            Delete entire line
  2711. dnarw        ^N            Move cursor down
  2712. dnarw        ^[ [ B
  2713. dnarw        ^[ O B
  2714. dnarw        ^K ^[ [ B
  2715. dnarw        ^K ^[ O B
  2716. eexit        ^C            Exit (window/file)
  2717. eexit        ^K Q
  2718. eexit        ^K q
  2719. eof        ^K V            Move cursor to end of file
  2720. eof        ^K ^V
  2721. eof        ^K v
  2722. eol        ^E            Move cursor to end of line
  2723. eol        ^[ [ F
  2724. eol        ^K ^[ [ F
  2725. eol        ^[ O S
  2726. eol        ^K ^[ O S
  2727. exsave        ^K X            Save & exit
  2728. exsave        ^K ^X
  2729. exsave        ^K x
  2730. findfirst    ^K F            Find text
  2731. findfirst    ^K ^F
  2732. findfirst    ^K f
  2733. findnext    ^L            Find next
  2734. findline    ^K L            Goto line number
  2735. findline    ^K ^L
  2736. findline    ^K l
  2737. gotomatching    ^G
  2738. indentl        ^K ,            Indent left
  2739. indentr        ^K .            Indent right
  2740. insfil        ^K R            Insert a file
  2741. insfil        ^K ^R
  2742. insfil        ^K r
  2743.  inss        ^G            Insert a space
  2744. inss        ^[ [ L
  2745. inss        ^K ^[ [ L
  2746. killlin        ^K |            Emacs-style kill line
  2747. killword    ^W            Delete word under cursor
  2748. ltarw        ^B            Move cursor left
  2749. ltarw        ^[ [ D
  2750. ltarw        ^K ^[ [ D
  2751. ltarw        ^[ O D
  2752. ltarw        ^K ^[ O D
  2753. mode        ^T            Change mode
  2754. moveblk        ^K M            Move previously marked block
  2755. moveblk        ^K ^M
  2756. moveblk        ^K m
  2757. pgdn        ^V            Move cursor 1/2 page down
  2758. pgdn        ^[ [ G
  2759. pgdn        ^K ^[ [ G
  2760. pgdn        ^[ [ 6 ~
  2761. pgdn        ^K ^[ [ 6 ~
  2762. pgup        ^U            Move cursor 1/2 page up
  2763. pgup        ^[ [ I
  2764. pgup        ^K ^[ [ I
  2765. pgup        ^[ [ 5 ~
  2766. pgup        ^K ^[ [ 5 ~
  2767. push        ^K Z            Push to a shell
  2768. push        ^K ^Z
  2769. push        ^K z
  2770. redo        ^K +            Redo
  2771. reformat    ^K J            Reformat paragraph
  2772. reformat    ^K ^J
  2773. reformat    ^K j
  2774. rewrite        ^R            Retype screen
  2775. rtarw        ^F            Move cursor right
  2776. rtarw        ^[ [ C
  2777. rtarw        ^K ^[ [ C
  2778. rtarw        ^[ O C
  2779. rtarw        ^K ^[ O C
  2780. rtn        ^M            The return key
  2781. saveit        ^K D            Save file
  2782. saveit        ^K ^D
  2783. saveit        ^K d
  2784. saveit        ^K S
  2785. saveit        ^K s
  2786. setbeg        ^K B            Set beginning of block
  2787. setbeg        ^K ^B
  2788. setbeg        ^K b
  2789. setend        ^K K            Set end of block
  2790. setend        ^K ^K
  2791. setend        ^K k
  2792. stquote        `            Next character is a control character
  2793. stquote8th    ^\            Next character has 7th bit set
  2794. thelp        ^K H            Toggle help text on/off
  2795. thelp        ^K ^H
  2796. thelp        ^K h
  2797. thelp        ^[ [ 2 8 ~
  2798. thelp        ^K ^[ [ 2 8 ~
  2799. undo        ^K -            Undelete
  2800. uparw        ^P            Move cursor up
  2801. uparw        ^[ [ A
  2802. uparw        ^K ^[ [ A
  2803. uparw        ^[ O A
  2804. uparw        ^K ^[ O A
  2805. wedit        ^K E            Edit another file
  2806. wedit        ^K ^E
  2807. wedit        ^K e
  2808. wexplode    ^K I            Show 1 or all windows
  2809. wexplode    ^K ^I
  2810. wexplode    ^K i
  2811. wgrow        ^K G            Grow window
  2812. wgrow        ^K ^G
  2813. wgrow        ^K g
  2814. wnext        ^K N            Goto next window
  2815. wnext        ^K ^N
  2816. wnext        ^K n
  2817. wprev        ^K P            Goto previous window
  2818. wprev        ^K ^P
  2819. wprev        ^K p
  2820. wrdl        ^Z            Move to previous word
  2821. wrdl        ^[ O Q
  2822. wrdl        ^K ^[ O Q
  2823. wrdr        ^X            Move to next word
  2824. wrdr        ^[ O R
  2825. wrdr        ^K ^[ O R
  2826. writeblk    ^K W            Write previously marked block to a file
  2827. writeblk    ^K ^W
  2828. writeblk    ^K w
  2829. wshrink        ^K T            Shrink window
  2830. wshrink        ^K ^T
  2831. wshrink        ^K t
  2832. wsplit        ^K O            Split window
  2833. wsplit        ^K ^O
  2834. wsplit        ^K o
  2835.  
  2836. type        ^I            Tab
  2837.  
  2838. type        sp            Typable characters
  2839. type        !
  2840. type        "
  2841. type        #       
  2842. type        $
  2843. type        %
  2844. type        &
  2845. type        '
  2846. type        (
  2847. type        )
  2848. type        *
  2849. type        +
  2850. type        ,
  2851. type        -
  2852. type        .
  2853. type        /
  2854. type        0
  2855. type        1
  2856. type        2
  2857. type        3
  2858. type        4
  2859. type        5
  2860. type        6
  2861. type        7
  2862. type        8
  2863. type        9
  2864. type        :
  2865. type        ;
  2866. type        <
  2867. type        =
  2868. type        >
  2869. type        ?
  2870. type        @
  2871. type        A
  2872. type        B
  2873. type        C
  2874. type        D
  2875. type        E
  2876. type        F
  2877. type        G
  2878. type        H
  2879. type        I
  2880. type        J
  2881. type        K
  2882. type        L
  2883. type        M
  2884. type        N
  2885. type        O
  2886. type        P
  2887. type        Q
  2888. type        R
  2889. type        S
  2890. type        T
  2891. type        U
  2892. type        V
  2893. type        W
  2894. type        X
  2895. type        Y
  2896. type        Z
  2897. type        [
  2898. type        \
  2899. type        ]
  2900. type        ^
  2901. type        _
  2902. type        a
  2903. type        b
  2904. type        c
  2905. type        d
  2906. type        e
  2907. type        f
  2908. type        g
  2909. type        h
  2910. type        i
  2911. type        j
  2912. type        k
  2913. type        l
  2914. type        m
  2915. type        n
  2916. type        o
  2917. type        p
  2918. type        q
  2919. type        r
  2920. type        s
  2921. type        t
  2922. type        u
  2923. type        v
  2924. type        w
  2925. type        x
  2926. type        y
  2927. type        z
  2928. type        {
  2929. type        |
  2930. type        }
  2931. type        ~
  2932. SHAR_EOF
  2933. if test 6221 -ne "`wc -c < '.joerc'`"
  2934. then
  2935.     echo shar: error transmitting "'.joerc'" '(should have been 6221 characters)'
  2936. fi
  2937. fi # end of overwriting check
  2938. #    End of shell archive
  2939. exit 0
  2940. -- 
  2941. /*  rcarter@wpi.wpi.edu */      /* Amazing */             /* Joseph H. Allen */
  2942. int a[1817];main(z,p,q,r){for(p=80;q+p-80;p-=2*a[p])for(z=9;z--;)q=3&(r=time(0)
  2943. +r*57)/7,q=q?q-1?q-2?1-p%79?-1:0:p%79-77?1:0:p<1659?79:0:p>158?-79:0,q?!a[p+q*2
  2944. ]?a[p+=a[p+=q]=q]=q:0:0;for(;q++-1817;)printf(q%79?"%c":"%c\n"," #"[!a[q-1]]);}
  2945.