home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / HSRC_117.ZIP / EDITOR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-08  |  26.1 KB  |  1,285 lines

  1. /* Editor.C File */
  2.  
  3. #include "msgg.h"
  4. #include "twindow.h"
  5. #include "headedit.h"
  6. #include "keys.h"
  7.  
  8. extern void pascal dcls(void);
  9. extern void pascal dputc(int x, int y, int c);
  10. extern int  pascal dputs(int x, int y, char *s);
  11. extern void pascal dclrwnd(int x1, int y1, int x2, int y2);
  12. extern void pascal dscrollup(int x1, int y1, int x2, int y2);
  13. extern void pascal dscrolldn(int x1, int y1, int x2, int y2);
  14.  
  15. extern word vbase;
  16. extern word maxx;
  17. extern word maxy;
  18. extern char current_color;
  19. extern word videomethod;
  20.  
  21. #define TRUE         1
  22. #define FALSE        0
  23. #define TABS        4
  24. #define NEXTTAB        (TABS-(x%TABS))
  25. #define LASTTAB        (((wwd-1)/TABS)*TABS)
  26. #define PREVTAB        (((x-1)%TABS)+1)
  27. #define curr(x,y)     (bfptr+(y)*wwd+(x))
  28. #define lineno(y)   ((int)(bfptr-topptr)/wwd+(y))
  29. #define sayline(y)  ((unsigned int)((unsigned int)bfptr-(unsigned int)topptr)/(unsigned int)wwd+((unsigned int)y))
  30.  
  31. extern int VSG;
  32. int last_x,last_y;
  33. static char qstr[7];
  34. char keybuf[256]="";
  35. static int quoting=0;
  36. static int wht;
  37. static int wwd;
  38. static int wsz;
  39. static char *topptr;
  40. static char *bfptr;
  41. static char *lstptr;
  42. static int lines;
  43. static char *endptr;
  44. static int blkbeg;
  45. static int blkend;
  46. static int inserting;
  47. static WINDOW *wnd;
  48. static int do_display_text=1;
  49. char abortedit;
  50.  
  51. /* Local function prototypes */
  52.  
  53. extern int  pascal do_macro (int c);
  54. extern char * pascal get_string (char *text,char len,char *deflt,char type);
  55. extern char pascal ask_question (char *text);
  56. void pascal file_funcs(int y,int command);
  57. void pascal save_text(int justblk,int append);
  58. void pascal load_text(int y,int insertit);
  59. void pascal unquote(int *x,int *y);
  60. void pascal quote_mark (int x,int y);
  61. void pascal erase_buffer(int *x,int *y);
  62. char pascal ask_quit(void);
  63. char pascal ask_save(void);
  64. int  pascal lastword(int x,int y);
  65. void pascal last_char(int *x,int *y);
  66. void pascal test_para(int x,int y);
  67. int  pascal trailing_spaces(int y);
  68. int  pascal first_wordlen(int y);
  69. void pascal paraform(int x,int y,char);
  70. int  pascal blankline(int line);
  71. void pascal delete_word(int x,int y);
  72. void pascal delete_line(int y);
  73. void pascal delete_block(void);
  74. void pascal copy_block(int y);
  75. void pascal move_block(int y);
  76. void pascal mvblock(int y,int moving);
  77. void pascal findlast(void);
  78. void pascal find_end(int *x,int *y);
  79. void pascal carrtn(int *x,int *y,int insert);
  80. void pascal backspace(int *x,int *y);
  81. void pascal fore_word(int *x,int *y,char *bf);
  82. int  pascal spaceup(int *x,int *y,char **bf);
  83. void pascal back_word(int *x,int *y,char *bf);
  84. int  pascal spacedn(int *x,int *y,char **bf);
  85. void pascal forward(int *x,int *y);
  86. int  pascal downward(int *y);
  87. void pascal upward(int *y);
  88. void pascal display_text(void);
  89. void pascal disp_line(int y);
  90. void pascal insert_line(void);
  91.  
  92. extern char notefile[133];
  93.  
  94.  
  95.  
  96. /* Process text entry for a window */
  97.  
  98. char * pascal text_editor (WINDOW *wnd1,char *bf,unsigned int bsize) {
  99.  
  100.   char lastun;
  101.   char *b,*buff,*pp;
  102.   int depart=FALSE,i,c;
  103.   int x,y,svx,svlw,tx,tabctr=0;
  104.  
  105.   memset(qstr,0,6);    /* Build quote string */
  106.   *qstr=' ';
  107.   if(*msg.to) {
  108.         qstr[1]=*msg.to;
  109.         pp=strchr(msg.to,' ');
  110.         if(pp && pp[1]) qstr[2]=pp[1];
  111.   }
  112.   strcat(qstr,"> ");
  113.   abortedit=0;
  114.   wnd=wnd1;
  115.   wht=HEIGHT-2;
  116.   wwd=WIDTH-2;
  117.   wsz=wwd*wht;
  118.   topptr=bfptr=bf;
  119.   lines=bsize/wwd;
  120.   endptr=bf+wwd*lines;
  121.   blkbeg=0;
  122.   blkend=0;
  123.   inserting=TRUE;
  124.   x=(maxx-1)-strlen(notefile);
  125.   if(x<49)x=49;
  126.   current_color=readtextcolor + (readtextback * 16);
  127.   lowvideo();
  128.   dprintf(x,6,"%0.28s",notefile);
  129.   x=y=0;
  130.   memset(bf,' ',bsize);
  131.   load_text(0,0);    /* Initial load */
  132.   display_text();
  133.  
  134.   while (TRUE) {
  135.    last_x=COL+1+x;
  136.    last_y=ROW+1+y;
  137.    if(last_y>(maxy-1)) {
  138.     last_y--;
  139.     y--;
  140.    }
  141.    cursor(last_x,last_y);
  142.    buff=curr(x,y);
  143.    if (tabctr) {
  144.       --tabctr;
  145.       c=' ';
  146.    }
  147.    else {
  148.       if(*keybuf) {
  149.         c=*keybuf;
  150.         memmove(keybuf,&keybuf[1],strlen(&keybuf[1])+1);
  151.       }
  152.       else if (quoting) quote_mark(x,y);
  153.       else {
  154.  
  155.         current_color=readtextcolor + (readtextback * 16);
  156.         lowvideo();
  157.         dprintf(3,6,"%3u | %-3u",x+1,sayline(y)+1);
  158.         c=get_char();
  159.       }
  160.       clear_message();
  161.    }
  162.    switch(c) {
  163.       case CTRL_W:                /* Wrap on/off */
  164.     if(!stricmp(notefile,"MSGTMP")) {
  165.         wrapit=1-wrapit;
  166.         if(wrapit) any_message(" Wrap at save off ");
  167.         else any_message(" Wrap at save on ");
  168.         pause();
  169.     }
  170.     break;
  171.       case CTRL_O:                /* Origin toggle */
  172.     if(!stricmp(notefile,"MSGTMP")) {
  173.         usedefault=1-usedefault;
  174.         if(usedefault) {
  175.             get_origin();
  176.         }
  177.         else {
  178.             any_message(" Looking up Origin line in ORIGINS.BBS ");
  179.             pause();
  180.         }
  181.     }
  182.     break;
  183.       case ALT_F1:        /* Spawn keys */
  184.       case ALT_F2:
  185.       case ALT_F3:
  186.       case ALT_F4:
  187.       case ALT_F5:
  188.       case ALT_F6:
  189.       case ALT_F7:
  190.       case ALT_F8:
  191.       case ALT_F9:
  192.       case ALT_F10:
  193.     do_spawn(convertstring(fkey[c-ALT_F1]));
  194.     break;
  195.       case ALT_M:                /* Macros */
  196.     set_help("macrohelp ",0,0);
  197.     any_message(" Press macro key: ");
  198.     c=get_char();
  199.     set_help("edithelp  ",0,0);
  200.     clear_message();
  201.     if(!do_macro(c)) {
  202.         if(c!=ESC) {
  203.             error_message(" Undefined macro key ");
  204.             pause();
  205.         }
  206.     }
  207.     break;
  208.       case ALT_P:                /* Literal */
  209.     any_message(" Press literal key: ");
  210.     set_help("lithelp   ",0,0);
  211.     c=get_char();
  212.     set_help("edithelp  ",0,0);
  213.     clear_message();
  214.     goto LiteralBreakIn;
  215.       case ALT_R:                /* Read block */
  216.     file_funcs(y,4);
  217.     break;
  218.       case ALT_W:                /* Write block */
  219.     file_funcs(y,5);
  220.     break;
  221.       case ALT_L:                /* Load new file */
  222.     file_funcs(y,2);
  223.     break;
  224.       case ALT_S:                /* Save file */
  225.     file_funcs(y,1);
  226.     break;
  227.       case ALT_C:                /* Change filename */
  228.     file_funcs(y,3);
  229.     break;
  230.       case ALT_F:                /* File functions */
  231.     file_funcs(y,0);
  232.     break;
  233.       case CTRL_E:                /* Edit header */
  234.     if(!stricmp(notefile,"MSGTMP")) {
  235.         edit_mess(2);
  236.         show_header(0);
  237.     }
  238.     break;
  239.       case CTRL_U:                /* Unquote text */
  240.     if(blankline(lineno(y)+1)) if (!blankline(lineno(y+1)+1)) downward(&y);
  241.     unquote(&x,&y);
  242.     break;
  243.       case ALT_Q:                /* Set quote string */
  244.     memset(qstr,0,6);    /* Build quote string */
  245.     *qstr=' ';
  246.     if(*msg.to) {
  247.         qstr[1]=*msg.to;
  248.         pp=strchr(msg.to,' ');
  249.         if(pp && pp[1]) qstr[2]=pp[1];
  250.     }
  251.     strcat(qstr,"> ");
  252.     set_help("quotshelp ",0,0);
  253.     pp=get_string("Enter quote string:",6,qstr,'a');
  254.     if(*pp) {
  255.         strcpy(qstr,pp);
  256.         if(strlen(qstr)<6 && qstr[strlen(qstr)-1]!=' ') strcat(qstr," ");
  257.     }
  258.     set_help("edithelp  ",0,0);
  259.     break;
  260.       case CTRL_Q:                /* Quote text */
  261.     if(blankline(lineno(y)+1)) if (!blankline(lineno(y+1)+1)) downward(&y);
  262.     quote_mark(x,y);
  263.     break;
  264.       case '\r':                /* CR */
  265.     carrtn(&x,&y,inserting);
  266.     break;
  267.       case DN:                    /* Down */
  268.         downward(&y);
  269.     break;
  270.       case PGUP:                /* Page Up */
  271.     y=0;
  272.     for(i=0;i<wht;i++) upward(&y);
  273.     x=0;
  274.     break;
  275.       case PGDN:                /* Page Down */
  276.     y=HEIGHT-2;
  277.     for(i=0;i<wht;i++)
  278.       downward(&y);
  279.     y=0;
  280.     break;
  281.       case '\t':                /* Tab */
  282.     if (x + NEXTTAB < wwd) {
  283.       if (inserting)
  284.         tabctr=NEXTTAB;
  285.       else
  286.         x+=NEXTTAB;
  287.     }
  288.     else
  289.       carrtn(&x,&y,inserting);
  290.     break;
  291.       case SHIFT_HT:            /* Shift-tab */
  292.     if (x<TABS) {
  293.       upward(&y);
  294.       x=LASTTAB;
  295.     }
  296.     else
  297.       x-=PREVTAB;
  298.     break;
  299.       case CTRL_FWD:            /* CTRL-=> */
  300.     fore_word(&x,&y,buff);
  301.     break;
  302.       case CTRL_BS:                /* CTRL-<= */
  303.     back_word(&x,&y,buff);
  304.     break;
  305.       case CTRL_PGUP:            /* Top of paragraph */
  306.     while(curr(0,y)>topptr) {
  307.         upward(&y);
  308.         if(blankline(lineno(y)+1)) break;
  309.     }
  310.     break;
  311.       case CTRL_PGDN:
  312.     while(curr(0,y)<endptr) {
  313.         downward(&y);
  314.         if(blankline(lineno(y)+1)) break;
  315.     }
  316.     break;
  317.       case CTRL_B:                /* Bottom of page */
  318.     y=wht-1;
  319.     last_char (&x,&y);
  320.     break;
  321.       case CTRL_T:                /* Top of page */
  322.     x=y=0;
  323.     break;
  324.       case CTRL_HOME:            /* Top of file */
  325.     x=y=0;
  326.     bfptr=topptr;
  327.     display_text();
  328.     break;
  329.       case HOME:                /* Start of line */
  330.     x=0;
  331.     break;
  332.       case CTRL_END:            /* End of file */
  333.     find_end(&x,&y);
  334.     last_char (&x,&y);
  335.     display_text();
  336.     break;
  337.       case END:                    /* End of line */
  338.     last_char (&x,&y);
  339.     break;
  340.       case UP:                    /* up-arrow */
  341.     upward(&y);
  342.     break;
  343.       case CTRL_A:                /* Abort; no save */
  344.     abortedit=ask_quit();
  345.       case ALT_X:                /* Ask to save */
  346.     if(!abortedit) abortedit=ask_save();
  347.     if(abortedit==2) {
  348.         abortedit=0;
  349.         break;
  350.     }
  351.       case F2:                    /* Finished */
  352.     depart=TRUE;
  353.     break;
  354.       case '\b':
  355.       case BS:                    /* Backspace or <= */
  356.     if (curr(x,y)==topptr)
  357.       break;
  358.     backspace(&x,&y);
  359.     if (x==wwd-1)
  360.       last_char(&x,&y);
  361.     if (c==BS)
  362.       break;
  363.     buff=curr(x,y);
  364.       case DEL:                    /* Delete */
  365.      if(blankline(lineno(y)+1)) {
  366.         delete_line(y);
  367.         break;
  368.      }
  369.      lastun=*buff;
  370.      movmem(buff+1,buff,wwd-1-x);
  371.      *(buff+wwd-1-x)=' ';
  372.      disp_line(y);
  373.      if(lastun==' ' && !blankline(lineno(y+1)+1)) {
  374.  
  375.         int xx=0;
  376.         int ts,fw;
  377.  
  378.  
  379.         buff=curr(x,y);
  380.         while(buff[xx]==' ' && (xx+x)<(wwd-1)) xx++;
  381.         if((xx+x)<wwd && buff[xx]==' ') {
  382.             ts=trailing_spaces(y);
  383.             fw=first_wordlen(y+1);
  384.             if (fw && ts>fw) {
  385.                 pp=curr(0,y+1);
  386.                 xx=0;
  387.                 while(*pp!=' ' ) {
  388.                     buff[xx++]=*pp;
  389.                     memmove(pp,&pp[1],wwd-1);
  390.                     pp[wwd-1]=' ';
  391.                 }
  392.                 xx=0;
  393.                 while(*pp==' ' && ++xx<wwd) memmove(pp,&pp[1],wwd-1);
  394.                 if(blankline(lineno(y+1)+1)) delete_line(y+1);
  395.                 display_text();
  396.             }
  397.         }
  398.         else test_para(x,y);
  399.      }
  400.     break;
  401. #define ALT_Y 21+128
  402.       case ALT_Y:                /* Kill to EOL */
  403.      pp=curr(x,y);
  404.      while(pp<(curr(0,y)+wwd)) {
  405.         *pp=' ';
  406.         pp++;
  407.      }
  408.      disp_line(y);
  409.      break;
  410.       case CTRL_Y:                /* Kill line */
  411.       case ALT_D:
  412.      delete_line(y);
  413.     break;
  414.       case CTRL_D:                /* Kill word */
  415.      delete_word(x,y);
  416.      test_para(x,y);
  417.     break;
  418.       case INS:                    /* Toggle insert mode */
  419.      inserting ^=TRUE;
  420.      insert_line();
  421.     break;
  422.       case F3:                    /* New buffer (erase file) */
  423.      erase_buffer(&x,&y);
  424.     break;
  425.       case ALT_B:
  426.       case F4:                    /* Reformat paragraph */
  427.      paraform(0,y,0);
  428.     break;
  429.       case F5:                    /* Mark start of block */
  430.     blkbeg=lineno(y)+1;
  431.     if (blkbeg>blkend) blkend=lines;
  432.     display_text();
  433.         break;
  434.       case F6:                    /* Mark end of block */
  435.         blkend=lineno(y)+1;
  436.     if (blkend<blkbeg) blkbeg=1;
  437.     display_text();
  438.     break;
  439.       case F7:                    /* Move a block */
  440.     move_block(y);
  441.     break;
  442.       case F8:                    /* Copy a block */
  443.     copy_block(y);
  444.     break;
  445.       case F9:                    /* Delete a block */
  446.     delete_block();
  447.     break;
  448.       case ALT_J:                /* Jump to DOS */
  449.     do_spawn("");
  450.     break;
  451.       case ALT_U:
  452.       case F10:                    /* Unmark a block */
  453.     blkbeg=blkend=0;
  454.     display_text();
  455.     break;
  456.       case FWD:                    /* => */
  457.     forward(&x,&y);
  458.     break;
  459.       default:
  460.         if (!isprint(c))
  461.       break;
  462. LiteralBreakIn:
  463.     if (curr(x,y)==endptr-1 || (lineno(y)+1>=lines && inserting && *curr(wwd-2,y)!=' ')) {
  464.       error_message(" End of Buffer ");
  465.       break;
  466.     }
  467.     if (inserting) {
  468.       buff=curr(x,y);
  469.       movmem(buff,buff+1,wwd-1-x);
  470.     }
  471.     buff=curr(x,y);
  472.     if (buff < endptr) {
  473.       if (buff >= lstptr) lstptr=buff+1;
  474.       *buff=c;
  475.       disp_line(y);
  476.     }
  477.     buff=curr(wwd-1,y);
  478.     if (endptr && *buff !=' ') {
  479.       for (b=buff+1;b<endptr;b++)
  480.         if (*b==' ' && *(b+1)==' ') break;
  481.       movmem(buff+1,buff+2,(unsigned int)(b-buff-1));
  482.       *(buff+1)=' ';
  483.       svx=x;
  484.       svlw=lastword(x,y);
  485.       x=wwd-1;
  486.       if (*(buff-1) !=' ') back_word(&x,&y,buff);
  487.       tx=x;
  488.       carrtn(&x,&y,TRUE);
  489.       if (svlw) x=svx-tx;
  490.       else {
  491.         x=svx;
  492.         --y;
  493.       }
  494.     }
  495.     forward(&x,&y);
  496.     break;
  497.    }
  498.     if (depart) break;
  499.   }
  500.   inserting = TRUE;
  501.   insert_line();
  502.   findlast();
  503.   return(lstptr);
  504. }
  505.  
  506. /* Erase the buffer */
  507.  
  508. static void pascal erase_buffer (int *x,int *y) {
  509.  
  510.   if(ask_question(" Erase text window\n Are you sure? (y/N)")=='Y') {
  511.       lstptr=bfptr=topptr;
  512.       *x=*y=0;
  513.       memset(bfptr,' ',(unsigned int)(lines * wwd));
  514.       blkbeg=blkend=0;
  515.       display_text();
  516.   }
  517. }
  518.  
  519. /* Ask to save */
  520.  
  521. static char pascal ask_save (void) {
  522.  
  523.   char retval;
  524.  
  525.   retval=ask_question(" Exit Mini Text Editor\n Save file? (Y/n)");
  526.   switch ((int)retval) {
  527.     case '\r':
  528.     case 'Y':    return 0;
  529.     case 'N':    return 1;
  530.     case ESC:    return 2;
  531.   }
  532.   return -1;
  533. }
  534.  
  535. /* Ask to quit */
  536.  
  537. static char pascal ask_quit (void) {
  538.  
  539.   char retval;
  540.  
  541.   retval=ask_question(" Abort entry of this\n file? (Y/n)");
  542.   switch ((int)retval) {
  543.     case '\r':
  544.     case 'Y':    return 1;
  545.     case ESC:
  546.     case 'N':    return 2;
  547.   }
  548.   return -1;
  549. }
  550.  
  551.  
  552. /* See if a word is the last word on the line */
  553.  
  554. static int pascal lastword (int x,int y) {
  555.  
  556.   char *bf=curr(x,y);
  557.  
  558.   while(x++<wwd-1)
  559.     if(*bf++==' ')
  560.       return 0;
  561.   return 1;
  562. }
  563.  
  564. /* Go to the last displayable character on line */
  565.  
  566. static void pascal last_char (int *x,int *y) {
  567.  
  568.   char *bf;
  569.  
  570.   *x=wwd-1;
  571.   bf=curr(0,*y);
  572.   while(*x && *(bf+ *x) == ' ')
  573.     --(*x);
  574.     if (*x && *x < wwd-1)
  575.       (*x)++;
  576. }
  577.  
  578. /* Test to see if paragraph should be reformed */
  579.  
  580. static void pascal test_para (int x,int y) {
  581.  
  582.   int ts,fw;
  583.   char *p;
  584.  
  585.   if ((scroll_lock() || quoting) && y< lines) {
  586.     p=curr(0,y+1);
  587.     if(memchr(p,'>',6)) return;
  588.     if(blankline(lineno(y)+1)) return;
  589.     ts=trailing_spaces(y);
  590.     fw=first_wordlen(y+1);
  591.     if (fw && ts>fw) paraform(x,y,0);
  592.   }
  593. }
  594.  
  595. /* Count the trailing spaces on a line */
  596. static int pascal trailing_spaces (int y) {
  597.  
  598.   int x=wwd-1,ct=0;
  599.   char *bf=curr(0,y);
  600.  
  601.   while(x>=0) {
  602.     if (*(bf+x)!=' ')
  603.       break;
  604.     --x;
  605.     ct++;
  606.   }
  607.   return ct;
  608. }
  609.  
  610. /* Count the length of the first word on a line */
  611.  
  612. static int pascal first_wordlen (int y) {
  613.   int ct=0,x=0;
  614.   char *bf=curr(0,y);
  615.  
  616.   while(x<wwd-1 && *(bf+x)==' ')
  617.     x++;
  618.   while (x+ct < wwd-1 && *(bf+x+ct)!=' ')
  619.     ct++;
  620.   return ct;
  621. }
  622.  
  623. /* Form paragraph */
  624.  
  625. static void pascal paraform (int x,int y, char longer) {
  626.  
  627.   char *cp1,*cp2,*cpend,*svcp;
  628.   int x1,oneline=0;
  629.  
  630.   if(longer>1) {
  631.     oneline=1;
  632.     longer=1;
  633.   }
  634.   if (blankline(lineno(y)+1))
  635.      return;
  636.   if (!blkbeg) {
  637.     blkbeg=blkend=lineno(y)+1;
  638.     blkend++;
  639.     if(!oneline) {
  640.         while(blkend<lines) {
  641.           if (blankline(blkend)) break;
  642.           blkend++;
  643.         }
  644.         --blkend;
  645.     }
  646.     else if(blkend<lines && !blankline(blkend)) blkend++;
  647.   }
  648.   if (lineno(y)!=blkbeg-1) x=0;
  649.   x1=x;
  650.   cp1=topptr+(blkbeg-1)* wwd+x;
  651.     if(!oneline) {
  652.       while(*cp1==' ') {
  653.         cp1++;
  654.         x1++;
  655.       }
  656.   }
  657.   cp2=cp1;
  658.   cpend=topptr+blkend * wwd;
  659.   while(cp2<cpend) {
  660.     if(memchr((topptr+(blkbeg-1)*wwd+x),'>',6))    {
  661.         blkbeg++;
  662.         cp1=topptr+(blkbeg-1)*wwd+x;
  663.         cp2=cp1;
  664.         continue;
  665.     }
  666.     while(*cp2==' '&& cp2 < cpend) cp2++;
  667.       if (cp2==cpend) break; /* at a word */
  668.       while (*cp2 != ' ' && cp2<cpend) {
  669.         if(x1>=(wwd-1)) { /* wrap the word */
  670.           svcp=cp1+(wwd-x1);
  671.           while(*--cp1 !=' ') {
  672.             *cp1=' ';
  673.             --cp2;
  674.           }
  675.           x1=0;
  676.           blkbeg++;
  677.           cp1=svcp;
  678.         }
  679.         *cp1++ =*cp2++;
  680.         x1++;
  681.       }
  682.       if (cp2<cpend) {
  683.         *cp1++ = ' ';
  684.         x1++;
  685.       }
  686.   }
  687.   while(cp1<cpend) *cp1++ = ' ';
  688.   blkbeg++;
  689.   if (blkbeg<=blkend) delete_block();
  690.   blkbeg=blkend=0;
  691.   display_text();
  692.   findlast();
  693. }
  694.  
  695. /* Test for a blank line */
  696.  
  697. static int pascal blankline (int line) {
  698.  
  699.   char *cp;
  700.   int x;
  701.  
  702.   cp=topptr+(line-1)* wwd;
  703.   for (x=0;x<wwd;x++)
  704.     if(*(cp+x)!=' ')
  705.       break;
  706.   return(x==wwd);
  707. }
  708.  
  709. /* Delete a word */
  710.  
  711. static void pascal delete_word (int x,int y) {
  712.  
  713.   int wct=0;
  714.   char *cp1, *cp2;
  715.  
  716.   cp1=cp2=curr(x,y);
  717.   if(*cp2 == ' ')
  718.     while (*cp2 == ' ' && x+wct<wwd) {
  719.       wct++;
  720.       cp2++;
  721.     }
  722.   else {
  723.     while (*cp2 !=' ' && x + wct < wwd) {
  724.       wct++;
  725.       cp2++;
  726.     }
  727.     while (*cp2 == ' ' && x+wct<wwd) {
  728.       wct++;
  729.       cp2++;
  730.     }
  731.   }
  732.   movmem(cp2,cp1,wwd-x-wct);
  733.   setmem(cp1+wwd-x-wct,wct,' ');
  734.   display_text();
  735.   findlast();
  736. }
  737.  
  738. /* Delete a line */
  739.  
  740. static void pascal delete_line (int y) {
  741.  
  742.   char *cp1,*cp2;
  743.   int len;
  744.  
  745.   cp1=bfptr+y*wwd;
  746.   cp2=cp1+wwd;
  747.   if (cp1<lstptr) {
  748.     len=(int)(endptr-cp2);
  749.     movmem(cp2,cp1,len);
  750.     lstptr -=wwd;
  751.     setmem(endptr - wwd,(int)wwd,' ');
  752.     display_text();
  753.   }
  754.   else findlast();
  755. }
  756.  
  757. /* Delete a block */
  758.  
  759. static void pascal delete_block () {
  760.  
  761.   char *cp1,*cp2;
  762.   int len;
  763.  
  764.   if(!blkbeg || !blkend) {
  765.     putchar(BELL);
  766.     return;
  767.   }
  768.   cp1=topptr+blkend*wwd;
  769.   cp2=topptr+(blkbeg-1)*wwd;
  770.   len=(int)(endptr-cp1);
  771.   movmem (cp1,cp2,len);
  772.   setmem(cp2+len,(int)(endptr-(cp2+len)),' ');
  773.   blkbeg=blkend=0;
  774.   lstptr-=(cp1-cp2);
  775.   display_text();
  776. }
  777.  
  778. /* Move and copy text blocks */
  779.  
  780. static void pascal mvblock (int y,int moving) {
  781.  
  782.   char *cp1,*cp2,*hd;
  783.   int len;
  784.   if (!blkbeg || !blkend) {
  785.     putchar (BELL);
  786.     return;
  787.   }
  788.   if (lineno(y)>=blkbeg-1 && lineno(y)<=blkend-1) {
  789.     error_message("Can't move/copy a block onto itself");
  790.     return;
  791.   }
  792.   len=(blkend-blkbeg+1)*wwd;
  793.   if ((hd=malloc(len))==0)
  794.     return;
  795.   cp1=topptr+(blkbeg-1) * wwd;
  796.   movmem(cp1,hd,len);
  797.   cp2=topptr+lineno(y)*wwd;
  798.   if (moving) {
  799.     if (lineno(y)>blkbeg-1)
  800.       cp2-=len;
  801.     do_display_text=0;
  802.     delete_block();
  803.     do_display_text=1;
  804.   }
  805.   if (cp2+len<=endptr) {
  806.     movmem(cp2,cp2+len,(unsigned int)(endptr-cp2-len));
  807.     movmem(hd,cp2,len);
  808.   }
  809.   free(hd);
  810.   blkbeg=blkend=0;
  811.   display_text();
  812. }
  813.  
  814. /* Copy a block */
  815.  
  816. static void pascal copy_block (int y) {
  817.  
  818.   mvblock(y,FALSE);
  819.   findlast();
  820. }
  821.  
  822. /* Move a block */
  823.  
  824. static void pascal move_block (int y) {
  825.  
  826.   mvblock(y,TRUE);
  827. }
  828.  
  829. /* Find last character in buffer */
  830.  
  831. static void pascal findlast () {
  832.  
  833.   register char *lp=endptr-1;
  834.   register char *tp=topptr;
  835.  
  836.   while (lp>tp && (*lp==' ' || *lp == '\0')) {
  837.     if (*lp=='\0')
  838.       *lp=' ';
  839.     --lp;
  840.   }
  841.   if (*lp !=' ')
  842.     lp++;
  843.   lstptr=lp;
  844. }
  845.  
  846. /* Go to end of data in buffer */
  847.  
  848. static void pascal find_end (int *x,int *y) {
  849.  
  850.   int ct;
  851.  
  852.   bfptr=lstptr;
  853.   ct=(int)((lstptr-topptr)%wsz);
  854.   bfptr-=ct;
  855.   if(bfptr+wsz>endptr)
  856.     bfptr=endptr-wsz;
  857.   *y=(ct/wwd);
  858.   *x=0;
  859.   downward(y);
  860. }
  861.  
  862. /* Carriage return */
  863.  
  864. static void pascal carrtn (int *x,int *y,int insert) {
  865.  
  866.   int insct;
  867.   char *cp,*nl;
  868.   int ctl=2;
  869.  
  870.   cp=curr(*x,*y);
  871.   nl=cp+((cp-topptr)%wwd);
  872.   if (lineno(*y) +2<lines)
  873.     if(insert && nl < endptr) {
  874.       insct = (int)wwd-*x;
  875.       while(ctl--) {
  876.     if(endptr>cp+insct) {
  877.       movmem(cp,cp+insct,(unsigned int)(endptr-insct-cp));
  878.       setmem(cp,insct,' ');
  879.     }
  880.     else if (ctl==1)
  881.       setmem(cp,(int)(endptr-cp),' ');
  882.     cp+=insct * 2;
  883.     insct = *x;
  884.       }
  885.     }
  886.   *x=0;
  887.   downward(y);
  888.   if (insert) {
  889.     test_para(*x,*y);
  890.     display_text();
  891.   }
  892.   if (lineno(*y) +2<lines)
  893.     if (insert)
  894.       if ((lstptr + wwd)<=endptr)
  895.     if (lstptr > curr(*x,*y))
  896.       lstptr+=wwd;
  897. }
  898.  
  899. /* Move buffer offset back one position */
  900.  
  901. static void pascal backspace (int *x,int *y) {
  902.  
  903.   if (*x==0) {
  904.     *x=wwd-1;
  905.     upward(y);
  906.   }
  907.   else
  908.     --(*x);
  909. }
  910.  
  911. /* Move the buffer offset foreward one word */
  912.  
  913. static void pascal fore_word (int *x,int *y,char *bf) {
  914.  
  915.   while (*bf!=' ') {
  916.     if (spaceup(x,y,&bf)==0)
  917.       return;
  918.     if (*x==0)
  919.       break;
  920.   }
  921.   while (*bf==' ')
  922.     if (spaceup(x,y,&bf)==0)
  923.       return;
  924. }
  925.  
  926. static int pascal spaceup(int *x,int *y,char **bf) {
  927.  
  928.   if (*bf == lstptr)
  929.     return 0;
  930.   (*bf)++;
  931.   forward(x,y);
  932.   return 1;
  933. }
  934.  
  935. /* Move the buffer offset backward one word */
  936.  
  937. static void pascal back_word (int *x,int *y,char *bf) {
  938.  
  939.   spacedn(x,y,&bf);
  940.   while (*bf==' ')
  941.     if(spacedn(x,y,&bf) == 0)
  942.       return;
  943.   while (*bf!=' ') {
  944.     if(*x==0)
  945.       return;
  946.     if (spacedn(x,y,&bf)==0)
  947.       return;
  948.   }
  949.   spaceup(x,y,&bf);
  950. }
  951.  
  952. static int pascal spacedn (int *x,int *y,char **bf) {
  953.  
  954.   if (*bf==topptr)
  955.     return 0;
  956.   --(*bf);
  957.   backspace(x,y);
  958.   return 1;
  959. }
  960.  
  961. /* Move the buffer offset forward one position */
  962.  
  963. static void pascal forward (int *x,int *y) {
  964.  
  965.   int ww=wwd;
  966.  
  967.   (*x)++;
  968.   if(*x == ww) {
  969.     downward(y);
  970.     *x=0;
  971.   }
  972. }
  973.  
  974. /* Move the buffer offset down one position */
  975.  
  976. static int pascal downward (int *y) {
  977.  
  978.   if (*y < wht-1) {
  979.     (*y)++;
  980.     return 1;
  981.   }
  982.   else if ((bfptr + wsz)<endptr) {
  983.     bfptr+=wwd;
  984.     scroll(wnd,UP);
  985.     disp_line(wht-1);
  986.     return 1;
  987.   }
  988.   return 0;
  989. }
  990.  
  991. /* Move the buffer offset up one position */
  992.  
  993. static void pascal upward (int *y) {
  994.  
  995.   if (*y)
  996.     --(*y);
  997.   else if ((topptr+wwd)<=bfptr) {
  998.     bfptr-=wwd;
  999.     scroll(wnd,DN);
  1000.     disp_line(0);
  1001.   }
  1002. }
  1003.  
  1004. /* Display all lines in a window */
  1005.  
  1006. static void pascal display_text () {
  1007.  
  1008.   int y=0;
  1009.  
  1010.   if (do_display_text)
  1011.     while (y<wht)
  1012.       disp_line(y++);
  1013. }
  1014.  
  1015. /* Display a line */
  1016.  
  1017. static void pascal disp_line (int y) {
  1018.  
  1019.   int x=0,atr=WNORMAL;
  1020.  
  1021.   if (blkbeg || blkend) if (lineno(y) >=blkbeg-1) if (lineno(y)<=blkend-1) atr=WACCENT;
  1022.  
  1023.   while (x<wwd) {
  1024.     displ(wnd,x+1,y+1,*(bfptr+y*wwd+x),atr);
  1025.     x++;
  1026.   }
  1027. }
  1028.  
  1029. /* Set insert/exchange cursor shape */
  1030.  
  1031. static void pascal insert_line () {
  1032.  
  1033.   set_cursor_type(inserting ? 0x0607: 0x0106);
  1034. }
  1035.  
  1036.  
  1037. /* Quote-mark the text in the buffer */
  1038.  
  1039.  
  1040. static void pascal quote_mark (int x,int y) {
  1041.  
  1042.     char *pp;
  1043.  
  1044.     x=0;
  1045.     if(blankline(lineno(y)+1)) {
  1046.         quoting=0;
  1047.         *keybuf=0;
  1048.         return;
  1049.     }
  1050.     if(pp=(memchr(curr(x,y),'>',6))) {
  1051.         memmove(&pp[1],pp,(curr(x,y)+wwd)-&pp[1]);
  1052.         *pp='>';
  1053.         disp_line(y);
  1054.         sprintf(keybuf,"%c%c",DN,HOME);
  1055.     }
  1056.     else {
  1057.         sprintf(keybuf,"%s%c%c",qstr,DN,HOME);
  1058.     }
  1059.     quoting=inserting=TRUE;
  1060. }
  1061.  
  1062.  
  1063. /* UnQuote-mark the text in the buffer */
  1064.  
  1065. static void pascal unquote (int *x,int *y) {
  1066.  
  1067.     char *p;
  1068.     char *pp;
  1069.  
  1070.     *x=0;
  1071.     p=curr(*x,*y);
  1072.     while(p<endptr) {
  1073.         if(blankline(lineno(*y)+1)) {
  1074.             break;
  1075.         }
  1076.         pp=memchr(p,'>',6);
  1077.         if(pp) {
  1078.             if(pp[1]=='>') {    /* Must have been requoted */
  1079.                 memmove(pp,&pp[1],(curr(*x,*y)+wwd)-&pp[1]);
  1080.                 p[wwd-1]=' ';
  1081.             }
  1082.             else {        /* Must be first-time quote */
  1083.                 if(pp[1]==' ') pp+=2;
  1084.                 else pp++;
  1085.                 memmove(p,pp,(curr(*x,*y)+wwd)-pp);
  1086.                 pp=&p[(curr(*x,*y)+wwd)-pp];
  1087.                 while(pp<&p[wwd]) {
  1088.                     *pp=' ';
  1089.                     pp++;
  1090.                 }
  1091.             }
  1092.         }
  1093.         disp_line(*y);
  1094.         if(!downward(y)) break;
  1095.         p=curr(*x,*y);
  1096.     }
  1097. }
  1098.  
  1099.  
  1100. void pascal save_text (int justblk, int append) {    /* Save file or block */
  1101.  
  1102.     int fp;
  1103.     char *p;
  1104.     char *endit;
  1105.     char temp[90];
  1106.  
  1107.       findlast();
  1108.       endit=lstptr;
  1109.       p=topptr;
  1110.       if(justblk) {
  1111.           if(!blkbeg || !blkend) {
  1112.             error_message(" No block marked ");
  1113.             pause();
  1114.             return;
  1115.           }
  1116.           p=topptr+(blkbeg-1)* wwd;
  1117.           endit=topptr+(blkend-1)*wwd;
  1118.           if(endit>lstptr) endit=lstptr;
  1119.       }
  1120.       if(endit>p) {
  1121.           any_message(" Saving ");        /* Save file */
  1122.           unlink(notefile);
  1123.           if(!append)fp=creat(notefile,S_IWRITE);
  1124.           else fp=_open(notefile,O_RDWR | O_DENYWRITE | O_BINARY | O_APPEND);
  1125.           if(fp== -1) {
  1126.             error_message(" Couldn't create/open file ");
  1127.             pause();
  1128.           }
  1129.           else {
  1130.               lseek(fp,0L,SEEK_END);
  1131.               while(p<lstptr) {
  1132.                 strncpy(temp,p,wwd);
  1133.                 p+=wwd;
  1134.                 temp[wwd]='\0';
  1135.                 rstrip(temp);
  1136.                 if(*temp) {
  1137.                     _write(fp,temp,strlen(temp));
  1138.                     if(!stricmp(notefile,"MSGTMP") && !wrapit && !(currarea->attr & ANSI) && !blkbeg && !blkend) {
  1139.                         if(*p==' ') _write(fp,"\r",1);
  1140.                         else if(memchr(p,'>',6)) _write(fp,"\r",1);
  1141.                         else if (memchr(temp,'>',6)) _write(fp,"\r",1);
  1142.                         else if (strlen(temp)<(wwd-9)) {
  1143.                             if (strcspn(p," ")>(wwd-9)-strlen(temp)) _write(fp,"\r",1);
  1144.                             else {
  1145.                                 _write(fp," ",1);
  1146.                                 if(strchr("?!.",temp[strlen(temp)-1])) _write(fp," ",1);
  1147.                             }
  1148.                         }
  1149.                         else {
  1150.                             _write(fp," ",1);
  1151.                             if(strchr("?!.",temp[strlen(temp)-1])) _write(fp," ",1);
  1152.                         }
  1153.                     }
  1154.                     else _write(fp,"\r\n",2);    /* Trailing cr/lf */
  1155.                 }
  1156.                 else _write(fp,"\r\n",2);        /* Just cr/lf (blank line) */
  1157.               }
  1158.               _close(fp);
  1159.           }
  1160.       }
  1161.     clear_message();
  1162. }
  1163.  
  1164.  
  1165.  
  1166. void pascal load_text (int y, int insertit) {    /* Load to line #y */
  1167.  
  1168.   int fp;
  1169.   char *p;
  1170.   char temp[90];
  1171.  
  1172.   p=curr(0,y);
  1173.   if(!insertit) {
  1174.     memset(p,' ',(unsigned int)(wwd * (lines-y)));
  1175.   }
  1176.   fp=_open(notefile,O_RDONLY | O_BINARY | O_DENYNONE);
  1177.   if (fp != -1) {                                /* Load file */
  1178.     any_message(" Loading ");
  1179.     while (!eof(fp) && p<endptr) {
  1180.         if(!fgetsx(temp,wwd,fp)) break;        /* line at a time */
  1181.         if(*temp==26) break;                /* end of file marker */
  1182.         temp[wwd]=0;
  1183.         while(*temp && temp[strlen(temp)-1]=='\n') temp[strlen(temp)-1]=0;    /* Strip trailing cr's */
  1184.         if(!insertit) {
  1185.             memcpy(p,temp,strlen(temp));
  1186.         }
  1187.         else {
  1188.             memmove(&p[wwd],p,(unsigned int)(endptr-&p[wwd]));
  1189.             memset(p,' ',wwd);    /* Set this line to blanks */
  1190.             memcpy(p,temp,strlen(temp));
  1191.         }
  1192.         p+=wwd;
  1193.     }
  1194.     if (!eof(fp)) {                                /* Didn't get whole file */
  1195.         any_message(" Not enough room for whole file... ");
  1196.         pause();
  1197.         *endptr=0;
  1198.         lstptr=endptr;
  1199.     }
  1200.     _close(fp);
  1201.   }
  1202.   else if (strcmp(notefile,"MSGTMP")) {
  1203.     error_message(" Couldn't open file. ");
  1204.     pause();
  1205.   }
  1206.   findlast();
  1207.   clear_message();
  1208.   display_text();
  1209. }
  1210.  
  1211.  
  1212.  
  1213. static void pascal file_funcs (int y,int command) {
  1214.  
  1215.   int c;
  1216.   WINDOW *sur;
  1217.   char selcs[]="SLCRWM";
  1218.   char *p;
  1219.   char s[133];
  1220.   struct ffblk f;
  1221.   int x;
  1222.  
  1223.   if(!command) {
  1224.       sur=establish_window(9,3,7,21);
  1225.       set_help("filehelp  ",maxy-1,19);
  1226.       set_colors(sur,ALL,RED,YELLOW,BRIGHT);
  1227.       set_title(sur," File Funcs ");
  1228.       display_window(sur);
  1229.       wprintf(sur," Save         (aS)\n Load         (aL)\n Change Name  (aC)\n Read Block   (aR)\n Write Block  (aW)");
  1230.       c=get_selection(sur,1,selcs);
  1231.       delete_window(sur);
  1232.   }
  1233.   else c=command;
  1234.   switch(c) {
  1235.     case 1: save_text(0,0);
  1236.             break;
  1237.     case 2: any_message(" WARNING: Any changes will be lost! ");
  1238.             sleep(1);
  1239.             p=get_string("File to load:",78,notefile,'A');
  1240.             if(*p) {
  1241.                 strcpy(notefile,p);
  1242.                 load_text(0,0);
  1243.             }
  1244.             break;
  1245.     case 3:    p=get_string("New Filename:",78,notefile,'A');
  1246.             if(*p) {
  1247.                  strcpy(notefile,p);
  1248.                  wframe(wnd);
  1249.                  x=(maxx-1)-strlen(notefile);
  1250.                  if(x<49)x=49;
  1251.                  current_color=readtextcolor + (readtextback * 16);
  1252.                  lowvideo();
  1253.                  dprintf(x,6,"%0.28s",notefile);
  1254.             }
  1255.             break;
  1256.     case 4: strcpy(s,notefile);
  1257.             p=get_string("File to insert:",78,NULL,'A');
  1258.             if(*p) {
  1259.                 strcpy(notefile,p);
  1260.                 load_text(y,1);
  1261.                 strcpy(notefile,s);
  1262.             }
  1263.             break;
  1264.     case 5: strcpy(s,notefile);
  1265.             p=get_string("File to write:",78,NULL,'A');
  1266.             if(*p) {
  1267.                 strcpy(notefile,p);
  1268.                 if(!findfirst(p,&f,0)) {
  1269.                     c=ask_question(" File exists.\n Overwrite? (Y/n) ");
  1270.                     if(c=='\r' || c=='Y') save_text(1,0);
  1271.                     else {
  1272.                         c=ask_question(" Append to existing\n File? (Y/n) ");
  1273.                         if(c=='\r' || c=='Y') save_text(1,1);
  1274.                     }
  1275.                 }
  1276.                 else {
  1277.                     save_text(1,0);
  1278.                 }
  1279.             }
  1280.             strcpy(notefile,s);
  1281.             break;
  1282.   }
  1283.   set_help("edithelp  ",0,0);
  1284. }
  1285.