home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / TEXT / UTILITY / MORE13.ZIP / MORE.C next >
Encoding:
C/C++ Source or Header  |  1990-06-26  |  29.2 KB  |  1,416 lines

  1. /* Special More */
  2.  
  3. #ifndef __COMPACT__
  4. #error Use COMPACT memory model
  5. #endif
  6.  
  7. #include <stdio.h>
  8. #include <io.h>
  9. #include <stdlib.h>
  10. #include <alloc.h>
  11. #include <assert.h>
  12. #include <conio.h>
  13. #include <string.h>
  14. #include <process.h>
  15. #include <dir.h>
  16.  
  17. #define MAXLINES    32000
  18. #define MAXLEN      2048
  19.  
  20. #define CASE_SEN    1
  21. #define NORMAL      2
  22. #define REPEAT      3
  23. #define REVERSE     4
  24.  
  25. #define GET        0
  26. #define SET        1
  27.  
  28. #define WRITE_FILE    0
  29. #define WRITE_BLOCK    1
  30.  
  31. #define highlight() { textcolor(col[2]);textbackground(col[5]); }
  32. #define inverse()   { textcolor(col[1]);textbackground(col[4]); }
  33. #define normal()    { textcolor(col[0]);textbackground(col[3]); }
  34. #define flashing()  { textcolor(col[2] + BLINK);textbackground(col[5]); }
  35.  
  36. #define rest_keys() gotoxy(1,25);inverse();cprintf(keys);clreol();normal()
  37. #define rest_message() gotoxy(1,1);inverse();cprintf(message);clreol();normal()
  38.  
  39. #define open_con_w() freopen("con","wt",stdout); setbuf(stdout, NULL)
  40.  
  41. #define ESC         27
  42. #define UPARROW     72+256
  43. #define DOWNARROW   80+256
  44. #define LEFTARROW   75+256
  45. #define RIGHTARROW  77+256
  46. #define HOME        71+256
  47. #define END         79+256
  48. #define PGUP        73+256
  49. #define PGDN        81+256
  50. #define CTRLPGUP    132+256
  51. #define CTRLPGDN    118+256
  52. #define CTRLRIGHT    115+256
  53. #define F1          59+256
  54. #define F7          65+256
  55. #define F8          66+256
  56. #define F9          67+256
  57. #define F10         68+256
  58.  
  59. void read_file(void);
  60. void display(void);
  61. void putseg(int loc, int line, int start);
  62. void disp_page(int column, int line);
  63. void open_kbd(void);
  64. void open_file(void);
  65. int  open_prn(void);
  66. int  getscan(void);
  67. char *_cgets(char *s);
  68. char getline(char *s);
  69. void strseg(char *dest, char *src, int start, int len);
  70. int  find(int type, int line);
  71. void help(int line, int column);
  72. void print(int line, int column);
  73. void print_all(void);
  74.  
  75. void colors(int column, int line);
  76. void printer(int column, int line);
  77. void editor(int column, int line);
  78. void read_setup(void);
  79. void write_setup(void);
  80.  
  81. int  bookmark(int cmd, int line);
  82. int  goto_line(int line);
  83.  
  84. void read_name(void);
  85.  
  86. void write_file(int func);
  87. void edit(void);
  88.  
  89. int  tot_lines;
  90. char filename[129];
  91. char prg_path[129];
  92. char message_str[66];
  93. char file_r;
  94. int  block_begin = -32767;
  95. int  block_end = -32767;
  96.  
  97. struct str_struct *ptrs[(MAXLINES/32)+1];
  98.  
  99. int col[6] = { LIGHTGRAY, BLACK, WHITE, BLACK, LIGHTGRAY, BLACK };
  100.  
  101. #define NOSTOR "%s: insufficent memory for file"
  102. #define FNDERR "%s: structure managament error"
  103.  
  104. int cr = 0;
  105.  
  106. #define chkptr(x) if( x == NULL ) { clrscr(); printf(NOSTOR,name); exit(2); }
  107. #define chkfail() if( find_fail ) { clrscr(); printf(FNDERR,name); exit(2); }
  108. #define str_size sizeof(struct str_struct)
  109.  
  110. struct str_struct {
  111.     int rec_num;
  112.     long pos;
  113.     char *str[32];
  114. };
  115.  
  116. char *ptr(int line);
  117. void setptr(int line, char *s);
  118.  
  119. int bookmarks[10] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
  120.  
  121. char port[68] = "prn";
  122. char edit_cmd[68] = "edit @";
  123.  
  124. char prg_name[128];
  125. char name[9];
  126.  
  127. char *keys = "Keys: cursor, Find Case Next Back, Print All, block: +-*, Get Set, Line F1=Help";
  128. char *message = "Enhanced More by Daniel Sachs. Copyright 1990 by Daniel Sachs.";
  129. char *date = __DATE__;
  130.  
  131. void main(int argc, char *argv[])
  132. {
  133.      argc--;
  134.  
  135.     open_con_w();
  136.  
  137.     strcpy(prg_name,argv[0]);
  138.     read_name();
  139.  
  140.      if (argv[0] == NULL)
  141.      {
  142.         printf("%s: DOS 3.0 or greater required",name);
  143.           exit(2);
  144.      }
  145.  
  146.      if (argc > 1)
  147.      {
  148.         printf("%s: too many arguments. syntax: %s <filename>\n\r",name,name);
  149.         printf("%s: if no file is specified, reads standard input",name);
  150.           exit(2);
  151.      }
  152.  
  153.      if (argc == 1)
  154.      {
  155.           file_r = 1;
  156.           strcpy(filename,argv[1]);
  157.           open_file();
  158.                if (strlen(filename) < 65)
  159.                {
  160.                     strcpy(message_str,filename);
  161.                     message = strupr(message_str);
  162.             }
  163.             else
  164.             {
  165.                 int i,j;
  166.  
  167.                 strcpy(message_str,"\x11\xc4\xc4");
  168.  
  169.                 j = strlen(filename)-56;
  170.  
  171.                 for(i=0;i<60;i++)
  172.                     message_str[i+3]=*(filename+j+i);
  173.  
  174.                 message_str[i] = 0;
  175.  
  176.                 message = strupr(message_str);
  177.             }
  178.      }
  179.      else
  180.         file_r = 0;
  181.  
  182.      directvideo = 1;
  183.  
  184.      read_setup();
  185.  
  186.      normal();
  187.      clrscr();
  188.  
  189.      highlight();
  190.      gotoxy(1,24);
  191.  
  192.      if (!file_r)
  193.           cputs("Reading standard input, please wait...");
  194.      else
  195.           cputs("Reading file, please wait...");
  196.  
  197.      gotoxy(23,5);
  198.     cputs("E N H A N C E D   M O R E   v1.3\n\n\n\r");
  199.      normal();
  200.      cputs("written 6/90 by Daniel Sachs, copyright 1990 by Daniel Sachs\n\r");
  201.      cputs("written in Turbo C. Portions copyright 1988 by Borland, Inc.");
  202.      cprintf("\r\n\nCompiled on %s.",date);
  203.      read_file();
  204.      display();
  205.      window(1,1,80,25);
  206.      gotoxy(1,25);
  207.      clreol();
  208.      exit(0);
  209. }
  210.  
  211. void read_name(void)
  212. {
  213.     char fdrive[3];
  214.     char fdir[65];
  215.     char fext[5];
  216.  
  217.     fnsplit(prg_name,fdrive,fdir,name,fext);
  218.     strlwr(name);
  219. }
  220.  
  221. void read_file(void)
  222. {
  223.     char s[MAXLEN],eof,*tmp;
  224.     int i,j;
  225.  
  226.      gotoxy(1,20);
  227.  
  228.      for (i=0;;i++)
  229.      {
  230.           if (i == MAXLINES)
  231.           {
  232.                clrscr();
  233.             printf("%s: file is too long",name);
  234.                exit(2);
  235.           }
  236.         eof = getline(s);
  237.  
  238.         tmp = malloc(strlen(s)+1);
  239.  
  240.         if (tmp == NULL)
  241.           {
  242.                clrscr();
  243.             printf("%s: insufficient memory for file",name);
  244.                exit(2);
  245.         }
  246.  
  247.         strcpy(tmp,s);
  248.  
  249.         setptr(i,tmp);
  250.  
  251.           if ((i % 40) == 0)
  252.           {
  253.                gotoxy(50,24);
  254.             cprintf("Line %5i. %3iK Free.",i,(int)(coreleft()/1024));
  255.                gotoxy(1,20);
  256.           }
  257.  
  258.         if (eof)
  259.         {
  260.             for(j=0;j<strlen(s);j++)
  261.                 if(s[j] != 32)
  262.                 {
  263.                     i++;
  264.                     break;
  265.                 }
  266.             break;
  267.         }
  268.      }
  269.  
  270.      tot_lines = i-1;
  271.  
  272.      for (;i < tot_lines+24;i++)
  273.         setptr(i,"");
  274. }
  275.  
  276. void read_setup(void)
  277. {
  278.      FILE *setup;
  279.  
  280.      char fdrive[3];
  281.      char fdir[65];
  282.      char fnam[9];
  283.      char fext[5];
  284.  
  285.      char name[127];
  286.  
  287.      fnsplit(prg_name, fdrive, fdir, fnam, fext);
  288.      strcpy(fext,".CFG");
  289.      fnmerge(name, fdrive, fdir, fnam, fext);
  290.  
  291.      setup = fopen(name,"rt");
  292.  
  293.      if (setup != NULL)
  294.      {
  295.           fread(edit_cmd, 1, 68, setup);
  296.           fread(port, 1, 68, setup);
  297.           fread(col, 2, 6, setup);
  298.           fclose(setup);
  299.      }
  300. }
  301.  
  302. void write_setup(void)
  303. {
  304.      FILE *setup;
  305.  
  306.      char fdrive[3];
  307.      char fdir[66];
  308.      char fnam[10];
  309.      char fext[5];
  310.  
  311.      char path[127];
  312.  
  313.      fnsplit(prg_name, fdrive, fdir, fnam, fext);
  314.      strcpy(fext,".CFG");
  315.      fnmerge(path, fdrive, fdir, fnam, fext);
  316.  
  317.      setup = fopen(path,"wb");
  318.  
  319.      if (setup != NULL)
  320.      {
  321.           fwrite(edit_cmd, 1, 68, setup);
  322.           fwrite(port, 1, 68, setup);
  323.           fwrite(col, 2, 6, setup);
  324.           fclose(setup);
  325.      }
  326.      else
  327.           putchar(7);
  328. }
  329.  
  330. void open_kbd(void)
  331. {
  332.      freopen("con","rt",stdin);
  333.      assert(stdin != NULL);
  334. }
  335.  
  336. void open_file(void)
  337. {
  338.      FILE *filetest;
  339.  
  340.      filetest=freopen(filename,"rt",stdin);
  341.      if (filetest == NULL)
  342.      {
  343.         printf("%s: unable to open file",name);
  344.           exit(4);
  345.      }
  346. }
  347.  
  348. int open_prn(void)
  349. {
  350.      FILE *filetest;
  351.  
  352.      filetest=freopen(port,"wt",stdprn);
  353.  
  354.      return(filetest != NULL);
  355. }
  356.  
  357. char getline(char *s)
  358. {
  359.      int i,j,x,eof,col;
  360.      char t[MAXLEN];
  361.      static char message = 0;
  362.  
  363.      for(i=0;;i++)
  364.      {
  365.           x = getchar();
  366.           eof = x == EOF;
  367.           if (((x != EOF) && (x != '\n')) && (i < MAXLEN-1))
  368.                t[i]=(char)x;
  369.           else
  370.                break;
  371.      }
  372.      t[i]=0;
  373.  
  374.      if ((i>=MAXLEN-1) && !message)
  375.      {
  376.           gotoxy(1,23);
  377.         cprintf("%s: lines too long, split...",name);
  378.           message=1;
  379.           gotoxy(1,20);
  380.      }
  381.  
  382.      x = 0;
  383.      col = 1;
  384.  
  385.      for (i=0;i<strlen(t);i++)
  386.      {
  387.           if (t[i]!='\t')
  388.           {
  389.                s[x++]=t[i];
  390.                col++;
  391.           }
  392.           else
  393.                for(j=0;j<((col%8)+8*((col%8)==0));j++)
  394.                {
  395.                     s[x++]=32;
  396.                     col++;
  397.                }
  398.           if (MAXLEN-x < 8)
  399.                {
  400.                     strcpy(s,t);
  401.                     x=MAXLEN-1;
  402.                     break;
  403.                }
  404.           }
  405.  
  406.      s[x]=0;
  407.  
  408.      return (eof);
  409. }
  410.  
  411. void strseg(char *dest, char *src, int start, int len)
  412. {
  413.      int i,j;
  414.  
  415.      j=0;
  416.  
  417.      for (i=start;i<len+start;i++)
  418.      {
  419.           dest[j++]=src[i];
  420.           if (src[i]==0)
  421.                break;
  422.      }
  423.  
  424.      dest[j]=0;
  425. }
  426.  
  427. void putseg(int loc, int line, int start)
  428. {
  429.      char x[MAXLEN];
  430.  
  431.      if (((loc >= block_begin) && (loc <= block_end))
  432.      && ((block_begin >= 0) && (block_end >= 0)))
  433.           highlight();
  434.  
  435.     if (start >= strlen(ptr(loc)))
  436.      {
  437.           gotoxy(1,line);
  438.           clreol();
  439.      }
  440.      else
  441.      {
  442.         strseg(x,ptr(loc),start,80);
  443.           gotoxy(1,line);
  444.           cputs(x);
  445.           if (wherey() == line)
  446.                clreol();
  447.      }
  448.      normal();
  449. }
  450.  
  451. void disp_page(int column, int line)
  452. {
  453.      int i,y;
  454.  
  455.      i=line;
  456.  
  457.      for (y=2; y<25; y++)
  458.           putseg(i++,y,column);
  459. }
  460.  
  461. int getscan(void)
  462. {
  463.      int a;
  464.  
  465.      a = getch();
  466.      if (a == 0)
  467.           a = getch() + 256;
  468.  
  469.      return (a);
  470. }
  471.  
  472. void display(void)
  473. {
  474.      int line, column, key, old_line, old_col;
  475.      char exit;
  476.  
  477.      line = column = 0;
  478.  
  479.      open_kbd();
  480.  
  481.      rest_message();
  482.  
  483.      rest_keys();
  484.  
  485.      exit = 1;
  486.  
  487.      disp_page(column,line);
  488.  
  489.      do
  490.      {
  491.           gotoxy(65,1);
  492.           inverse();
  493.         cprintf("%5i, %4i",line+1,column+1);
  494.           normal();
  495.           gotoxy(80,25);
  496.  
  497.           key = getscan();
  498.  
  499.           old_line = line;
  500.         old_col  = column;
  501.  
  502.           switch (key)
  503.           {
  504.                case ESC: exit = 0; break;
  505.  
  506.                case UPARROW:       line = line >= 1 ? line - 1 : 0; break;
  507.                case DOWNARROW:     line = line < tot_lines ? line + 1 : line; break;
  508.                case LEFTARROW:     column = (column >= 19) ? column - 20 : column; break;
  509.             case RIGHTARROW:    column = (column+20 < MAXLEN) ? column + 20 : column; break;
  510.  
  511.             case CTRLRIGHT:    column = 0; break;
  512.  
  513.                case CTRLPGUP:      line = line >= 12 ? line - 12 : 0; break;
  514.                case CTRLPGDN:      line = line < tot_lines-12 ? line + 12 : tot_lines; break;
  515.  
  516.                case HOME:line = 0; break;
  517.             case END: line = tot_lines; break;
  518.  
  519.                case PGUP:line = line >= 22 ? line - 22 : 0; break;
  520.                case PGDN:line = line < tot_lines-22 ? line + 22 : tot_lines; break;
  521.  
  522.                case F1:  help(column,line); break;
  523.                case F7:  colors(column,line); break;
  524.                case F8:  printer(column,line); break;
  525.                case F9:  editor(column,line); break;
  526.                case F10: write_setup();
  527.  
  528.                case '+': block_begin = line; disp_page(column,line); break;
  529.                case '-': block_end = line; disp_page(column,line); break;
  530.                case '*': block_begin = -32767; block_end = -32767; disp_page(column, line); break;
  531.  
  532.             case 'l':
  533.             case 'L': line = goto_line(line); break;
  534.  
  535.             case 'g':
  536.             case 'G': line = bookmark(GET,line); break;
  537.  
  538.             case 's':
  539.             case 'S': bookmark(SET,line); break;
  540.  
  541.                case 'E':
  542.                case 'e': edit(); break;
  543.  
  544.                case 'W':
  545.             case 'w': write_file(WRITE_FILE); break;
  546.  
  547.             case 'D':
  548.             case 'd': write_file(WRITE_BLOCK); break;
  549.  
  550.                case 'P':
  551.                case 'p': print(line,column); break;
  552.  
  553.                case 'A':
  554.                case 'a': print_all(); break;
  555.  
  556.                case 'F':
  557.                case 'f': line = find(NORMAL,line); break;
  558.  
  559.                case 'N':
  560.                case 'n': line = find(REPEAT,line); break;
  561.  
  562.                case 'C':
  563.                case 'c': line = find(CASE_SEN,line); break;
  564.  
  565.                case 'B':
  566.                case 'b': line = find(REVERSE,line); break;
  567.           }
  568.  
  569.     if (line == -1)
  570.         line = 0;
  571.  
  572.      if (old_col != column)
  573.           disp_page(column,line);
  574.  
  575.      if (old_line != line)
  576.           if (abs(old_line-line)>1)
  577.                disp_page(column,line);
  578.           else
  579.           if (old_line - line == -1)
  580.           {
  581.                movetext(1,3,80,24,1,2);
  582.                putseg(line+22,24,column);
  583.           }
  584.           else
  585.           {
  586.                movetext(1,2,80,23,1,3);
  587.                putseg(line,2,column);
  588.           }
  589.  
  590.      }
  591.      while (exit);
  592. }
  593.  
  594. int find(int type,int line)
  595. {
  596.      static char search_string[75] = "";
  597.      static int  search_type = 1;
  598.      static int  len = 0;
  599.  
  600.      int i,j,flag,escape;
  601.  
  602.      if ((type == NORMAL) || (type == CASE_SEN))
  603.      {
  604.           search_type = type;
  605.  
  606.           search_string[0] = 65;
  607.  
  608.           highlight();
  609.  
  610.           gotoxy(1,25);
  611.         cprintf("%sFind \x1a ",type == CASE_SEN ? "Case " : "");
  612.           clreol();
  613.  
  614.           normal();
  615.  
  616.           if(_cgets(search_string) == NULL)
  617.           {
  618.                rest_keys();
  619.                return(line);
  620.           }
  621.  
  622.           len = search_string[1];
  623.  
  624.           for(i=0;i<len+1;i++)
  625.                search_string[i]=search_string[i+2];
  626.  
  627.           type = REPEAT;
  628.      }
  629.  
  630.      gotoxy(1,25);
  631.      flashing();
  632.      cprintf("Searching...");
  633.      normal();
  634.      clreol();
  635.  
  636.      flag = 0;
  637.      escape = 0;
  638.  
  639.      for(i=line + 1-2*(type == REVERSE);(i <= tot_lines) && (i >= 0);
  640.           i += 1-2*(type == REVERSE))
  641.      {
  642.         if (strlen(ptr(i)) < len)
  643.                continue;
  644.         for(j=0;j<strlen(ptr(i))-len+1;j++)
  645.           {
  646.                if(search_type == CASE_SEN)
  647.                 flag=!strncmp(ptr(i)+j,search_string,len);
  648.                else
  649.                 flag=!strnicmp(ptr(i)+j,search_string,len);
  650.                if (flag)
  651.                {
  652.                     flag = i;
  653.                     break;
  654.                }
  655.           }
  656.      if (flag)
  657.           break;
  658.      if (kbhit())
  659.           if (getscan() == 27)
  660.           {
  661.                escape = 1;
  662.                break;
  663.           }
  664.      }
  665.  
  666.      if (!flag && !escape)
  667.           putchar(7);
  668.  
  669.      rest_keys();
  670.  
  671.      return (flag == 0 ? line : flag);
  672. }
  673.  
  674. void help(int line, int column)
  675. {
  676.      window(1,2,80,24);
  677.      clrscr();
  678.  
  679.      window(1,1,80,24);
  680.      inverse();
  681.      gotoxy(65,1);
  682.      clreol();
  683.      cputs("Help Page");
  684.      normal();
  685.  
  686.      window(1,2,80,24);
  687.  
  688.     highlight();
  689.     cputs(  "\r\nScrolling/Paging Functions");
  690.     normal();
  691.  
  692.     cputs(  "\r\n     \x18 Scroll Up one line");
  693.      cputs(  "\r\n     \x19 Scroll Down one line");
  694.      cputs(  "\r\n     \x1b Scroll Left 20 columns");
  695.     cputs(  "\r\n     \x1a Scroll Right 20 columns");
  696.     cputs(  "\r\n     Ctrl-\x1b Go To Left Margin");
  697.      cputs("\r\n\n     PgUp Scroll Up One Page");
  698.      cputs(  "\r\n     PgDn Scroll Down One Page");
  699.      cputs(  "\r\n     Ctrl-PgUp Scroll Up Half Page");
  700.     cputs(  "\r\n     Ctrl-PgDn Scroll Down Half Page");
  701.  
  702.     highlight();
  703.     cputs("\r\n\nSearch Functions");
  704.     normal();
  705.  
  706.     cputs(  "\r\n     'F' Find Text");
  707.     cputs(  "\r\n     'C' Case Sensitive Find");
  708.     cputs(  "\r\n     'N' Find Next");
  709.     cputs(  "\r\n     'B' Find Previous");
  710.  
  711.     highlight();
  712.     cputs("\r\n\nWrite-To-Disk Functions");
  713.     normal();
  714.     cputs(  "\r\n     'W' Write File to Disk");
  715.     cputs(  "\r\n     'D' Write Block to Disk");
  716.  
  717.     window(41,2,80,24);
  718.  
  719.     highlight();
  720.     cputs( "\r\nPrint Functions");
  721.     normal();
  722.  
  723.     cputs(  "\r\n     'P' Print Block");
  724.      cputs(  "\r\n     'A' Print File");
  725.      cputs(  "\r\n     '+' Mark beginning of Block");
  726.      cputs(  "\r\n     '-' Mark end of Block");
  727.      cputs(  "\r\n     '*' Clear Block");
  728.  
  729.     highlight();
  730.     cputs("\r\n\nSetup Functions");
  731.     normal();
  732.  
  733.     cputs(  "\r\n     F7  Change Screen Colors");
  734.      cputs(  "\r\n     F8  Change Printer Port");
  735.      cputs(  "\r\n     F9  Define Editor");
  736.      cputs(  "\r\n     F10 Write Setup to Disk");
  737.  
  738.     highlight();
  739.     cputs("\r\n\nMisc. Functions");
  740.     normal();
  741.  
  742.     cputs(  "\r\n     'S' Set Bookmark");
  743.     cputs(  "\r\n     'G' Go To Bookmark");
  744.     cputs(  "\r\n     'L' Go To Line\n");
  745.  
  746.      if (file_r)
  747.         cputs(  "\r\n     'E' Invoke Editor");
  748.     cputs(  "\r\n     Esc Exit To DOS or Cancel");
  749.      window(1,1,80,25);
  750.      gotoxy(1,25);
  751.      inverse();
  752.      cprintf("Press any key to return to file viewer screen");
  753.      clreol();
  754.  
  755.      getscan();
  756.  
  757.      rest_keys();
  758.  
  759.      disp_page(line,column);
  760. }
  761.  
  762. void print(int line,int column)
  763. {
  764.      int i;
  765.  
  766.      if((block_begin < 0) || (block_end < 0))
  767.           return;
  768.  
  769.      flashing();
  770.      gotoxy(1,25);
  771.      clreol();
  772.      cprintf("Printing...");
  773.  
  774.      if (open_prn())
  775.      {
  776.           normal();
  777.  
  778.           for(i=block_begin;i<=block_end;i++)
  779.           {
  780.             fputs(ptr(i),stdprn);
  781.                putc('\r',stdprn);
  782.                putc('\n',stdprn);
  783.                if (kbhit())
  784.                {
  785.                     if (getscan() == 27)
  786.                          break;
  787.                }
  788.           }
  789.      }
  790.      else
  791.           putchar(7);
  792.  
  793.      fclose(stdprn);
  794.  
  795.      rest_keys();
  796.  
  797.      disp_page(column,line);
  798. }
  799.  
  800. void print_all(void)
  801. {
  802.      int i;
  803.  
  804.      flashing();
  805.      gotoxy(1,25);
  806.      clreol();
  807.      cprintf("Printing...");
  808.      normal();
  809.  
  810.      if(open_prn())
  811.      {
  812.           for(i=0;i<=tot_lines;i++)
  813.           {
  814.             fputs(ptr(i),stdprn);
  815.                putc('\r',stdprn);
  816.                putc('\n',stdprn);
  817.                if (kbhit())
  818.                {
  819.                     if (getscan() == 27)
  820.                          break;
  821.                     }
  822.           }
  823.      }
  824.  
  825.      fclose(stdprn);
  826.  
  827.      rest_keys();
  828. }
  829.  
  830. void edit(void)
  831. {
  832.      char dest[127],cmd[127];
  833.      char *argv[15];
  834.      char *prgm;
  835.  
  836.      int i,j,pos;
  837.  
  838.      if (!file_r)
  839.           return;
  840.  
  841.      gotoxy(1,25);
  842.      clreol();
  843.      highlight();
  844.      cprintf("Loading Editor...");
  845.      normal();
  846.  
  847.      pos = 0;
  848.  
  849.      for(i = 0; i < strlen(edit_cmd); i++)
  850.           if (*(edit_cmd + i) == '@')
  851.                for(j=0; j < strlen(filename); j++)
  852.                     dest[pos++] = *(filename + j);
  853.           else
  854.                dest[pos++] = *(edit_cmd + i);
  855.  
  856.      dest[pos] = 0;
  857.  
  858.      strcpy(cmd,dest);
  859.  
  860.      prgm = strtok(dest," ");
  861.      j = 1;
  862.  
  863.      do
  864.           argv[j] = strtok(NULL," ");
  865.      while (argv[j++] != NULL);
  866.  
  867.      execvp(prgm,argv);
  868.  
  869.      putchar(7);
  870.      rest_keys();
  871.  
  872. }
  873.  
  874. void write_file(int func)
  875. {
  876.     int i,j,len;
  877.     int beg,end;
  878.     char fail;
  879.     char append;
  880.     FILE *test;
  881.  
  882.     if( (func == WRITE_BLOCK) && ((block_begin == -32767) || (block_end == -32767)) )
  883.     {
  884.         putchar(7);
  885.         return;
  886.     }
  887.  
  888.      gotoxy(1,25);
  889.      highlight();
  890.     cprintf("%sFile \x1a ",func == WRITE_BLOCK ? "Block\x1a" : "Write ");
  891.      normal();
  892.      clreol();
  893.  
  894.      filename[0]=65;
  895.  
  896.      if(_cgets(filename) == NULL)
  897.      {
  898.           rest_keys();
  899.           return;
  900.      }
  901.  
  902.      len = filename[1];
  903.  
  904.      for(i=0;i<len+1;i++)
  905.           filename[i]=filename[i+2];
  906.  
  907.      test = freopen(filename,"r",stdout);
  908.  
  909.     j = 0;
  910.     append = 0;
  911.  
  912.      if (test != NULL)
  913.      {
  914.           open_con_w();
  915.           putchar(7);
  916.           gotoxy(1,25);
  917.           highlight();
  918.         cprintf("Rewrite \"%s\"? (y/n/a)",filename);
  919.           normal();
  920.           clreol();
  921.           j = -1;
  922.           do
  923.           {
  924.             i = getscan();
  925.             if ((i == 'a') || (i == 'A'))
  926.             {
  927.                 j = 2;
  928.                 append = 1;
  929.             }
  930.                if ((i == 'y') || (i == 'Y'))
  931.                     j = 1;
  932.             if (((i == 'n') || (i == 'N')) || (i == ESC))
  933.                     j = 0;
  934.           }
  935.           while (j == -1);
  936.  
  937.           if (!j)
  938.           {
  939.                rest_keys();
  940.                return;
  941.           }
  942.      }
  943.  
  944.      gotoxy(1,25);
  945.      highlight();
  946.  
  947.      cprintf("Writing file...");
  948.      clreol();
  949.  
  950.     if(append)
  951.         test = freopen(filename,"at",stdout);
  952.     else
  953.         test = freopen(filename,"wt",stdout);
  954.  
  955.      if (test == NULL)
  956.      {
  957.           open_con_w();
  958.           putchar(7);
  959.           rest_keys();
  960.           return;
  961.     }
  962.  
  963.     beg = func == WRITE_BLOCK ? block_begin : 0;
  964.     end = func == WRITE_BLOCK ? block_end   : tot_lines;
  965.  
  966.     for (i = beg, fail = 0;(i <= end) && (!fail); i++)
  967.         fail = (puts(ptr(i)) == EOF) + 2*(kbhit() ? getscan() == 27 : 0);
  968.  
  969.      open_con_w();
  970.  
  971.      if (fail == 1)
  972.           putchar(7);
  973.  
  974.      if (fail)
  975.      {
  976.         if(!append)
  977.             unlink(filename);
  978.           rest_keys();
  979.           return;
  980.     }
  981.  
  982.     if( ((!file_r) && (func == WRITE_FILE)) && (!append) )
  983.     {
  984.         file_r = 1;
  985.  
  986.         message = strupr(filename);
  987.         rest_message();
  988.     }
  989.  
  990.     rest_keys();
  991. }
  992.  
  993. void colors(int column, int line)
  994. {
  995.      int i,old_i,exit,c,key;
  996.      int old_fore = col[0],old_back = col[3];
  997.  
  998.      gotoxy(1,25);
  999.      inverse();
  1000.      cprintf("Follow instructions in above area to change colors");
  1001.      clreol();
  1002.      normal();
  1003.  
  1004.      window(1,2,80,24);
  1005.      clrscr();
  1006.  
  1007.      cprintf("\n\n");
  1008.  
  1009.      for (i = 0; i <= WHITE; i++)
  1010.      {
  1011.           textcolor(i);
  1012.           textbackground(i == 0 ? 7 : 0);
  1013.           cprintf("%2i",i);
  1014.           textbackground(0);
  1015.           textcolor(7);
  1016.           cprintf(" ");
  1017.      }
  1018.  
  1019.      cprintf("         ");
  1020.  
  1021.      for (i = 0; i <= LIGHTGRAY; i++)
  1022.      {
  1023.           textbackground(i);
  1024.           textcolor(i == 7 ? 0 : 7);
  1025.           cprintf("%1i",i);
  1026.           textbackground(0);
  1027.           cprintf(" ");
  1028.      }
  1029.  
  1030.      clreol();
  1031.      normal();
  1032.  
  1033.      gotoxy(1,5);
  1034.      cprintf("Use \x18\x19 to move, \x1b\x1a to change colors (listed above). Esc exits to file.");
  1035.  
  1036.      cprintf("\r\n\n     Normal Foreground");
  1037.      cprintf(  "\r\n     Info. Line Foreground");
  1038.      cprintf(  "\r\n     Highlighted Foreground");
  1039.      cprintf("\r\n\n     Normal Background");
  1040.      cprintf(  "\r\n     Info. Line Background");
  1041.      cprintf(  "\r\n     Highlighted Background");
  1042.  
  1043.      for(i=1;i<7;i++)
  1044.      {
  1045.           gotoxy(30,6+i+(i>3));
  1046.           cprintf("%2i",col[i-1]);
  1047.      }
  1048.  
  1049.      i = 1;
  1050.      exit = 0;
  1051.  
  1052.      gotoxy(1,20);
  1053.      normal();
  1054.      cprintf("Normal Text Sample");
  1055.      inverse();
  1056.      cprintf("\n\rInfo. Line Text Sample");
  1057.      highlight();
  1058.      cprintf("\n\rHighlighted Text Sample");
  1059.  
  1060.      normal();
  1061.  
  1062.      gotoxy(3,7);
  1063.      cprintf("\xc4\x10");
  1064.  
  1065.      do
  1066.      {
  1067.           key = getscan();
  1068.  
  1069.           c = 0; old_i = i;
  1070.  
  1071.           switch (key)
  1072.           {
  1073.                case UPARROW:       i = i > 1 ? i-1 : 6; c = 7; break;
  1074.                case DOWNARROW:     i = i < 6 ? i+1 : 1; c = 7; break;
  1075.                case LEFTARROW:     c = -1; break;
  1076.                case RIGHTARROW:    c = +1; break;
  1077.  
  1078.                case ESC:           exit = 1; break;
  1079.           }
  1080.  
  1081.           if (c == 7)
  1082.           {
  1083.                gotoxy(3,6+old_i+(old_i>3));
  1084.                cprintf("   ");
  1085.                gotoxy(3,6+i+(i>3));
  1086.                cprintf("\xc4\x10");
  1087.           }
  1088.           else
  1089.                if (c != 0)
  1090.                {
  1091.                     col[i-1] += c;
  1092.                     if (col[i-1] < 0)
  1093.                          col[i-1] = i > 3 ? 7 : 15;
  1094.                     if (col[i-1] > (i > 3 ? 7 : 15))
  1095.                          col[i-1] = 0;
  1096.                     for(old_i=1;old_i<7;old_i++)
  1097.                     {
  1098.                          gotoxy(30,6+old_i+(old_i>3));
  1099.                          cprintf("%2i",col[old_i-1]);
  1100.                     }
  1101.                     gotoxy(1,20);
  1102.                     normal();
  1103.                     cprintf("Normal Text Sample");
  1104.                     inverse();
  1105.                     cprintf("\n\rInfo. Line Text Sample");
  1106.                     highlight();
  1107.                     cprintf("\n\rHighlighted Text Sample");
  1108.  
  1109.                     textcolor(old_fore);
  1110.                     textbackground(old_back);
  1111.  
  1112.                     gotoxy(5,6+i+(i>3));
  1113.                }
  1114.      }
  1115.      while (!exit);
  1116.  
  1117.      window(1,1,80,25);
  1118.  
  1119.      rest_keys();
  1120.      rest_message();
  1121.      disp_page(column,line);
  1122. }
  1123.  
  1124. void editor(column,line)
  1125. {
  1126.      int i;
  1127.      char tmp[67];
  1128.  
  1129.      gotoxy(1,25);
  1130.      inverse();
  1131.      cputs("Change editor command using instructions above");
  1132.      clreol();
  1133.      normal();
  1134.  
  1135.      window(1,2,80,24);
  1136.      clrscr();
  1137.  
  1138.      gotoxy(1,12);
  1139.      cputs("Enter the command that you would type at the DOS command line to run your\n\r");
  1140.      cputs("editor. Replace the filename with a '@' sign. However, if the editor is a batch\n\r");
  1141.      cputs("file you need to preface the command with 'RUN' in order for it to execute.\n\r");
  1142.      cputs("\n\rPress Esc (or Enter a blank line) to keep the same editor command.\n\r");
  1143.  
  1144.      gotoxy(1,5);
  1145.      cprintf("Change Editor Command Line:\n\n\r");
  1146.      highlight();
  1147.      cprintf("Current \x1a ");
  1148.      normal();
  1149.      cputs(edit_cmd);
  1150.      highlight();
  1151.      cprintf("\r\n\nNew \x1a ");
  1152.      normal();
  1153.  
  1154.      strcpy(tmp,edit_cmd);
  1155.  
  1156.      edit_cmd[0]=64;
  1157.  
  1158.      if (_cgets(edit_cmd) == NULL)
  1159.      {
  1160.           strcpy(edit_cmd,tmp);
  1161.           window(1,1,80,25);
  1162.           rest_keys();
  1163.           disp_page(column,line);
  1164.           return;
  1165.      }
  1166.  
  1167.      if (edit_cmd[1] == 0)
  1168.           strcpy(edit_cmd,tmp);
  1169.      else
  1170.           for(i=2;i<=strlen(edit_cmd);i++)
  1171.                edit_cmd[i-2] = edit_cmd[i];
  1172.  
  1173.      window(1,1,80,25);
  1174.  
  1175.      rest_keys();
  1176.      disp_page(column,line);
  1177. }
  1178.  
  1179. void printer(int column,int line)
  1180. {
  1181.      int i;
  1182.      char tmp[67];
  1183.  
  1184.      gotoxy(1,25);
  1185.      inverse();
  1186.      cputs("Change printer port using the instructions above");
  1187.      clreol();
  1188.      normal();
  1189.  
  1190.      window(1,2,80,24);
  1191.      clrscr();
  1192.  
  1193.      gotoxy(1,12);
  1194.      cputs("The printer port is the DOS logical device used for printer output. Usually,\r\n");
  1195.      cputs("this will be 'prn' (printer) but can be: \r\n\n");
  1196.      cputs("     PRN      Printer Port = LPT1. This should work for most printers.\n\r");
  1197.      cputs("     LPTx     Parellel Port #x\n\r");
  1198.      cputs("     COMx     Serial Port #x (must be set up using the MODE command)\n\r");
  1199.      cputs("\nYou can also type a filename; a print jobs will be sent to that file. However,\n\r");
  1200.      cputs("the file gets overwritten with every job you print.");
  1201.      cputs("\n\n\rTo leave without changing the port, hit Esc or Enter a blank line.\n\r");
  1202.  
  1203.      gotoxy(1,5);
  1204.      cprintf("Change Printer Port:\n\n\r");
  1205.      highlight();
  1206.      cprintf("Current \x1a ");
  1207.      normal();
  1208.      cputs(port);
  1209.      highlight();
  1210.      cprintf("\r\n\nNew \x1a ");
  1211.      normal();
  1212.  
  1213.      strcpy(tmp,port);
  1214.  
  1215.      port[0]=65;
  1216.      if(_cgets(port) == NULL)
  1217.      {
  1218.           window(1,1,80,25);
  1219.           strcpy(port,tmp);
  1220.           rest_keys();
  1221.           disp_page(column,line);
  1222.           return;
  1223.      }
  1224.  
  1225.      if (port[1] == 0)
  1226.           strcpy(port,tmp);
  1227.      else
  1228.           for(i=2;i<=strlen(port);i++)
  1229.                port[i-2] = port[i];
  1230.  
  1231.      window(1,1,80,25);
  1232.  
  1233.      rest_keys();
  1234.      disp_page(column,line);
  1235. }
  1236.  
  1237. char *_cgets(char *s)
  1238. {
  1239.      int i,loc,max,x,y;
  1240.      char *edit;
  1241.  
  1242.      loc = 0;
  1243.      edit = (s + 2);
  1244.      max = *s;
  1245.  
  1246.      for(;;)
  1247.      {
  1248.           i = getscan();
  1249.  
  1250.           if (i > 255)
  1251.                continue;
  1252.  
  1253.           if ((i > 31) && (loc < max))
  1254.           {
  1255.                *(edit+(loc++)) = i;
  1256.                cprintf("%c",(char)i);
  1257.           }
  1258.  
  1259.           if ((i == 8) && (loc > 0))
  1260.           {
  1261.                loc--;
  1262.                x = wherex();
  1263.                y = wherey();
  1264.  
  1265.                y = x == 1 ? y-1 : y;
  1266.                x = x == 1 ? 80 : x-1;
  1267.  
  1268.                gotoxy(x,y);
  1269.                cprintf(" ");
  1270.                gotoxy(x,y);
  1271.           }
  1272.  
  1273.           if (i == 27)
  1274.           {
  1275.                *(s + 1) = loc;
  1276.                *(s + loc) = 0;
  1277.                return(NULL);
  1278.           }
  1279.  
  1280.           if (i == 13)
  1281.           {
  1282.                *(s + 1) = loc;
  1283.                *(edit + loc) = 0;
  1284.  
  1285.                return(edit);
  1286.           }
  1287.      }
  1288. }
  1289.  
  1290. char *ptr(int line)
  1291. {
  1292.     return ptrs[line/32]->str[line%32];
  1293. }
  1294.  
  1295. void setptr(int line, char *s)
  1296. {
  1297.     if( ptrs[line/32] != NULL )
  1298.         ptrs[line/32]->str[line%32] = s;
  1299.     else
  1300.     {
  1301.         ptrs[line/32] = malloc(str_size);
  1302.         chkptr(ptrs[line/32]);
  1303.         ptrs[line/32]->str[line%32] = s;
  1304.     }
  1305. }
  1306.  
  1307. int goto_line(int line)
  1308. {
  1309.     char s[8];
  1310.     char *tmp;
  1311.  
  1312.     int x;
  1313.  
  1314.     gotoxy(1,25);
  1315.     highlight();
  1316.     cprintf("Line \x1a ");
  1317.     clreol();
  1318.  
  1319.     normal();
  1320.  
  1321.     s[0] = 5;
  1322.     tmp = _cgets(s);
  1323.  
  1324.     if( tmp == NULL )
  1325.     {
  1326.         inverse();
  1327.         gotoxy(1,25);
  1328.         cprintf(keys);
  1329.         clreol();
  1330.         normal();
  1331.         return(line);
  1332.     }
  1333.  
  1334.     tmp = s + 2;
  1335.  
  1336.     x = atoi(tmp);
  1337.  
  1338.     if( x == 0 )
  1339.     {
  1340.         putchar(7);
  1341.         x = line+1;
  1342.     }
  1343.  
  1344.     if( (x > tot_lines+1) || (x < 1) )
  1345.     {
  1346.         putchar(7);
  1347.         x = line+1;
  1348.     }
  1349.  
  1350.     inverse();
  1351.     gotoxy(1,25);
  1352.     cprintf(keys);
  1353.     clreol();
  1354.     normal();
  1355.  
  1356.     return(x-1);
  1357. }
  1358.  
  1359. int bookmark(int cmd, int line)
  1360. {
  1361.     char s[8];
  1362.     char *tmp;
  1363.     int x;
  1364.     int num;
  1365.  
  1366.     gotoxy(1,25);
  1367.     highlight();
  1368.     cprintf("Bookmark %s (0 - 9) \x1a ", cmd == GET ? "Find" : "Set");
  1369.     clreol();
  1370.  
  1371.     normal();
  1372.  
  1373.     s[0] = 1;
  1374.     tmp = _cgets(s);
  1375.  
  1376.     if( tmp == NULL )
  1377.     {
  1378.         inverse();
  1379.         gotoxy(1,25);
  1380.         cprintf(keys);
  1381.         clreol();
  1382.         normal();
  1383.         return(line);
  1384.     }
  1385.  
  1386.     num = s[2] - 48;
  1387.  
  1388.     if((s[2] < '0') || (s[2] > '9'))
  1389.     {
  1390.         putchar(7);
  1391.         x = line;
  1392.     }
  1393.     else
  1394.         if(cmd == GET)
  1395.         {
  1396.             x = bookmarks[num];
  1397.             if( x == -1 )
  1398.             {
  1399.                 putchar(7);
  1400.                 x = line;
  1401.             }
  1402.         }
  1403.         else
  1404.         {
  1405.             bookmarks[num] = line;
  1406.             x = line;
  1407.         }
  1408.  
  1409.     inverse();
  1410.     gotoxy(1,25);
  1411.     cprintf(keys);
  1412.     clreol();
  1413.     normal();
  1414.  
  1415.     return(x);
  1416. }