home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / compiler / small_c / cb / sources / edt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-09-12  |  9.2 KB  |  420 lines

  1. /*
  2. ** edt.c -- edit text
  3. **
  4. ** Copyright 1982 J. E. Hendrix.  All rights reserved.
  5. */
  6. #include <stdio.h>
  7. #include "tools.h"
  8. #define NOCCARGC
  9. #define OK 1
  10. #define RESERVE 600
  11. #define PREV 0
  12. #define NEXT 2
  13. #define MARK 4
  14. #define TEXT 5
  15. #define INTEGER 2
  16. #define LONG 4
  17. #define LINE0 0
  18. #define NOSTATUS 0
  19. #define CURLINE '.'
  20. #define LASTLINE '|'
  21. #define SCAN '/'
  22. #define BACKSCAN '\\'
  23. #define FORWARD 1
  24. #define BACKWARD 0
  25. #define PERIOD '.'
  26. #define COMMA ','
  27. #define SEMICOL ';'
  28. #define PLUS '+'
  29. #define MINUS '-'
  30. #define BLANK ' '
  31. #define TAB '\t'
  32. #define ESC 27
  33. #define PROMPT '#'
  34. #define CLFLAG '*'
  35.  
  36. #define PRINT 'p'
  37. #define LINE 'l'
  38. #define GLOBAL 'g'
  39. #define EXCLUDE 'x'
  40. #define APPEND 'a'
  41. #define CHANGE 'c'
  42. #define DELETE 'd'
  43. #define INSERT 'i'
  44. #define JOIN 'j'
  45. #define MOVE 'm'
  46. #define SUBSTITUTE 's'
  47. #define ENTER 'e'
  48. #define FILE 'f'
  49. #define READ 'r'
  50. #define WRITE 'w'
  51. #define QUIT 'q'
  52. #define VIEW 'v'
  53. #define ZIP 'z'
  54.  
  55. int
  56.   line1,   /* first line number */
  57.   line2,   /* second line number */
  58.   nlines,  /* number of line numbers given */
  59.   curln,   /* current line (value of dot) */
  60.   lastln;  /* last line (value of $) */
  61.  
  62. char *buf;    /* buffer for pointers and text */
  63. /*
  64. ** buf[k+0] PREV     (2 bytes)  previous line
  65. ** buf[k+2] NEXT     (2 bytes)  next line
  66. ** buf[k+4] MARK     (1 byte)   mark for global commands
  67. ** buf[k+5] TEXT
  68. */
  69. int  lastbf;  /* last element used in buf */
  70. char *txt,    /* text line for matching and output */
  71.      *savfil, /* remembered file name */
  72.      *file;
  73. int
  74.   scr,        /* scratch file id */
  75.   scrend[2];  /* end of info on scratch file */
  76. char *lin, *pat, *sub, updtflag, nbrstr[7];
  77. int cursav, i, status, maxbuf, context, view;
  78.  
  79. main(argc, argv) int argc, *argv; {
  80.   if(isatty(stdin)) view=1; else view=0;
  81.   txt=malloc(MAXLINE);
  82.   lin=malloc(MAXLINE);
  83.   pat=malloc(MAXPAT);
  84.   sub=malloc(MAXPAT);
  85.   file=malloc(MAXFN);
  86.   savfil=malloc(MAXFN);
  87.   maxbuf=avail(YES)-RESERVE;
  88.   if(maxbuf < 0) maxbuf=32767;
  89.   buf=malloc(maxbuf);
  90.   setbuf();
  91.   updtflag=NO;
  92.   pat[0]=savfil[0]=nbrstr[6]=NULL;
  93.   context=7;
  94.   i=0;
  95.   while(getarg(++i, txt, MAXFN, argc, argv)!=EOF) {
  96.     if(txt[0]=='-') {
  97.       if(same(txt[1], 'v')&(txt[2]==NULL)) view = 1 - view;
  98.       else {
  99.         fputs("usage: EDT [file] [-V]\n", stderr);
  100.         abort(7);
  101.         }
  102.       }
  103.     else scopy(txt, 0, savfil, 0);
  104.     }
  105.   if(*savfil) {
  106.     if(enter(savfil)==ERR) {
  107.       fputs("error\n", stderr);
  108.       }
  109.     }
  110.   if(isatty(stdin))
  111.     fputc(PROMPT, stderr);
  112.   while(fgets(lin, MAXLINE, stdin)!=NULL) {
  113.     poll(YES);
  114.     trim(lin);
  115.     i=0;
  116.     cursav=curln;
  117.     if(getlst()==OK) {
  118.       if(ckglob()==OK)
  119.         status=doglob();
  120.       else if(status!= ERR)
  121.         status=docmd(NO);
  122.       /* else error, do nothing */
  123.       }
  124.     if(status==ERR) {
  125.       fputs("\7error\n", stderr);
  126.       curln=cursav;
  127.       }
  128.     else if(status==EOF) break;
  129.     /* else OK, then loop */
  130.     if(isatty(stdin)) fputc(PROMPT, stderr);
  131.     }
  132.   }
  133.  
  134. /*
  135. ** docmd -- handle all commands except globals
  136. */
  137. docmd(glob) int glob; {
  138.   int gflag, line3, pflag;
  139.   pflag=NO;
  140.   status=ERR;
  141.   switch(tolower(lin[i])) {
  142.     case APPEND:
  143.       if(ckp(lin, i+1, &pflag)==OK)
  144.         status=append(line2, glob);
  145.       break;
  146.     case CHANGE:
  147.       if(ckp(lin, i+1, &pflag)==OK) {
  148.         if(defalt(curln, curln)==OK) {
  149.           if((status=append(line2, glob))!=ERR) {
  150.             kill(line1, line2);
  151.             ++curln;
  152.             }
  153.           }
  154.         }
  155.       break;
  156.     case DELETE:
  157.       if(ckp(lin, i+1, &pflag)==OK) {
  158.         if(defalt(curln, curln)==OK) {
  159.           kill(line1, line2);
  160.           if(curln < lastln) curln=nextln(curln);
  161.           }
  162.         }
  163.       break;
  164.     case INSERT:
  165.       if(ckp(lin, i+1, &pflag)==OK)
  166.         status=append(prevln(line2), glob);
  167.       break;
  168.     case LINE:
  169.       if(lin[i+1]==NULL) {
  170.         itou(curln, nbrstr, 6);
  171.         puts(nbrstr);
  172.         status=OK;
  173.         }
  174.       break;
  175.     case JOIN:
  176.       if(ckp(lin, i+1, &pflag)==OK) {
  177.         if(defalt(curln, curln+1)==OK) {
  178.           if((status=join(line1, line2))==OK) {
  179.             curln=line2;
  180.             if((status=inject(txt))==OK)
  181.               kill(line1, line2);
  182.               ++curln;
  183.             }
  184.           }
  185.         }
  186.       break;
  187.     case MOVE:
  188.       ++i;
  189.       if(getone(&line3)==EOF) status=ERR;
  190.       if(status==OK) {
  191.         if(ckp(lin, i, &pflag)==OK) {
  192.           if(defalt(curln, curln)==OK) status=move(line3);
  193.           }
  194.         }
  195.       break;
  196.     case SUBSTITUTE:
  197.       ++i;
  198.       if(optpat()==OK) {
  199.         if(getrhs(lin, &i, sub, &gflag)==OK) {
  200.           if(ckp(lin, i+1, &pflag)==OK) {
  201.             if(defalt(curln, curln)==OK)
  202.               status=subst(sub, gflag);
  203.             }
  204.           }
  205.         }
  206.       break;
  207.     case ENTER:
  208.       if(chkupdt()==ERR) status=OK;
  209.       else if(nlines==0) {
  210.         if(getfn(lin, i, file, MAXFN)==OK) {
  211.           scopy(file, 0, savfil, 0);
  212.           clrbuf();
  213.           setbuf();
  214.           status=enter(file);
  215.           }
  216.         }
  217.       break;
  218.     case FILE:
  219.       if(nlines==0) {
  220.         if(getfn(lin, i, file, MAXFN)==OK) {
  221.           scopy(file, 0, savfil, 0);
  222.           puts(savfil);
  223.           }
  224.         itou(maxbuf-lastbf, nbrstr, 6);
  225.         puts(nbrstr);
  226.         status=OK;
  227.         }
  228.       break;
  229.     case READ:
  230.       if(getfn(lin, i, file, MAXFN)==OK)
  231.         status=doread(line2, file);
  232.       pflag=view;
  233.       break;
  234.     case WRITE:
  235.       if(getfn(lin, i, file, MAXFN)==OK) {
  236.         if(defalt(1, lastln)==OK)
  237.           status=dowrit(line1, line2, file);
  238.         }
  239.       break;
  240.     case ZIP:
  241.       if(defalt(curln, lastln)==OK)
  242.         status=doprnt(line1, line2, glob);
  243.       break;
  244.     case PRINT:
  245.       if(defalt(curln, curln)==OK)
  246.         status=doprnt(line1, line2, glob);
  247.       break;
  248.     case NULL:
  249.       if((nlines==0)&(glob==NO)) line2=nextln(curln);
  250.       if(view) status=doprnt(line2, line2, glob);
  251.       else {
  252.         curln=line2;
  253.         status=OK;
  254.         }
  255.       break;
  256.     case QUIT:
  257.       if((lin[i+1]==NULL)&(nlines==0)&(glob==NO)) {
  258.         if(chkupdt()==ERR) status=OK;
  259.         else status=EOF;
  260.         }
  261.       break;
  262.     case VIEW:
  263.       view=1-view;
  264.       status=OK;
  265.     }
  266.   /* else status is ERR */
  267.   if(curln < 1) curln = nextln(0);
  268.   if((status==OK)&(pflag==YES))
  269.     status=doprnt(curln, curln, glob);
  270.   return status;
  271.   }
  272.  
  273. /*
  274. ** chkupdt -- warn if update not written to disk
  275. */
  276. chkupdt() {
  277.   if(updtflag) {
  278.     fputs("didn't write to disk!\n", stderr);
  279.     updtflag=NO;
  280.     return ERR;
  281.     }
  282.   return OK;
  283.   }
  284.  
  285. /*
  286. ** ctoi -- convert string at in[*i] to integer, bump *i
  287. */
  288. ctoi(in, i) char in[]; int *i; {
  289.   int dd, num;
  290.   char *digits;
  291.   digits="0123456789";
  292.   while((in[*i]==BLANK)|(in[*i]==TAB)) *i = *i + 1;
  293.   num=0;
  294.   while(in[*i]!=NULL) {
  295.     dd=index(digits, in[*i]);
  296.     if(dd < 0) break;
  297.     num = 10*num + dd;
  298.     *i = *i + 1;
  299.     }
  300.   return num;
  301.   }
  302.  
  303. /*
  304. ** skipbl -- skip blanks and tabs
  305. */
  306. skipbl(lin, i) char lin[]; int *i; {
  307.   while((lin[*i]==' ')|(lin[*i]=='\t')) *i = *i + 1;
  308.   }
  309.  
  310. /*
  311. ** nextln -- get line after ln
  312. */
  313. nextln(ln) int ln; {
  314.   if(++ln > lastln) return 0;
  315.   return ln;
  316.   }
  317.  
  318. /*
  319. ** prevln -- get line before ln
  320. */
  321. prevln(ln) int ln; {
  322.   if(--ln < 0) return lastln;
  323.   return ln;
  324.   }
  325.  
  326. /*
  327. ** join -- put line1 thru line2 together into txt
  328. */
  329. join(ln1, ln2) int ln1, ln2; {
  330.   int i, j;
  331.   j=0;
  332.   while(ln1 <= ln2) {
  333.     i=getind(ln1++)+TEXT;
  334.     while(txt[j++]=buf[i++])
  335.       if(j >= MAXLINE) return ERR;
  336.     --j;
  337.     }
  338.   return OK;
  339.   }
  340.  
  341. /*
  342. ** doread -- read "file" after "line"
  343. */
  344. doread(line, file) int line; char file[]; {
  345.   int fd, stat;
  346.   if((fd=fopen(file, "r"))==NULL) {
  347.     fputs("open ", stderr);
  348.     return ERR;
  349.     }
  350.   curln=line;
  351.   stat=input(fd);
  352.   fclose(fd);
  353.   return stat;
  354.   }
  355.  
  356. /*
  357. ** getlst -- collect line numbers (if any) at lin[i], bump i
  358. */
  359. getlst() {
  360.   int num;
  361.   line2=0;
  362.   nlines=0;
  363.   while(getone(&num)==OK) {
  364.     line1=line2;
  365.     line2=num;
  366.     ++nlines;
  367.     if((lin[i]!=COMMA)&(lin[i]!=SEMICOL)) break;
  368.     if(lin[i]==SEMICOL) curln=num;
  369.     ++i;
  370.     }
  371.   if(nlines>2) nlines=2;
  372.   if(nlines==0) line2=curln;
  373.   if(nlines<=1) line1=line2;
  374.   if(status!=ERR) status=OK;
  375.   return status;
  376.   }
  377.  
  378. /*
  379. ** getone -- evaluate one line number expression
  380. */
  381. getone(num) int *num; {
  382.   int istart, mul, pnum;
  383.   skipbl(lin, &i);
  384.   istart=i;
  385.   if((lin[i]==PLUS)|(lin[i]==MINUS)) *num=curln;
  386.   else *num=0;
  387.   if(getnum(num)==OK)
  388.     while(YES) {
  389.       skipbl(lin, &i);
  390.       if((lin[i]!=PLUS)&(lin[i]!=MINUS)) {
  391.         status=EOF;
  392.         break;
  393.         }
  394.       if(lin[i]==PLUS) mul = 1;
  395.       else mul = -1;
  396.       ++i;
  397.       skipbl(lin, &i);
  398.       pnum=1;
  399.       getnum(&pnum);
  400.       *num = *num + mul*pnum;
  401.       if(status==EOF) status=ERR;
  402.       if(status!=OK) break;
  403.       }
  404.   if((*num<0)|(*num>lastln)) return (status=ERR);
  405.   if(i<=istart) return (status=EOF);
  406.   return (status=OK);
  407.   }
  408.  
  409. #include "edt2.c"
  410. #include "same.c"
  411. #include "pat.c"
  412. #include "buf.c"
  413. #include "error.c"
  414. #include "index.c"
  415. #include "maksub.c"
  416. #include "catsub.c"
  417. #include "scopy.c"
  418. #include "trim.c"
  419.  
  420.