home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / editor / tvx_edit.arc / TVX_IO.C < prev    next >
C/C++ Source or Header  |  1986-03-17  |  45KB  |  2,008 lines

  1. /* ------------------------ tvx_io.c ---------------------------- */
  2. #include "tvx_defs.ic"
  3. #include "tvx_glbl.ic"
  4.  
  5. #define SWITCH '-'
  6. #define FILESEP '.'
  7.  
  8. #ifdef MSDOS
  9. #define TEMPEXT ".$$1"        /* name of temporary file */
  10. #define BACKEXT ".BAK"        /* name of backup file */
  11. #endif
  12.  
  13. #ifdef OSCPM
  14. #define TEMPEXT ".$$1"        /* name of temporary file */
  15. #define BACKEXT ".BAK"        /* name of backup file */
  16. #endif
  17.  
  18. #ifdef GEMDOS
  19. #define TEMPEXT ".Z1X"        /* name of temporary file */
  20. #define BACKEXT ".BAK"        /* name of backup file */
  21. #endif
  22.  
  23. #ifdef UNIX
  24. #define BACKEXT ".B"        /* name of backup file */
  25. #endif
  26.  
  27.     FILE *fopen();
  28.  
  29. /* local globals (used by tv terminal driver section) */
  30.  
  31.     static int linptr; /* common "linot" */
  32.     static char linout[242];
  33.  
  34.     static char stemp[FNAMESIZE+1];
  35.  
  36. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  37.  
  38.     FILE IO section
  39.  
  40.    File handling algorithm:
  41.  
  42.     The original name specified on command line is called orig_file.
  43.     It will remain untouched throughout the editing session.  At the
  44.     very end (normal exit), it will be renamed to the ".BAK" name.
  45.  
  46.     source_file is the current name of the file with source.  It will
  47.     orignally be the same as orig_file, but may change to a generated
  48.     scratch name depending on the operating system.  source_file is
  49.     always the lastest fully written version of the file (like after
  50.     file beginning, for example). 
  51.  
  52.     work_file is the output file.  On normal exit, this is the
  53.     file renamed to dest_file.  On buffer beginning, it will be
  54.     moved to source_file, possibly after renameing.
  55.     
  56.     dest_file is the ultimate destination file.  This name is not
  57.     actually used until the final rename on normal exit.  It is
  58.     checked to be sure it is a valid name to be opened, however.
  59.  
  60.    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  61.  
  62. /* =============================>>> ABORT <<<============================= */
  63.   abort()
  64.   {    /* abort - close files, abort operation */
  65.  
  66.     char rply[4];
  67.  
  68.     tvclr();
  69.     ask("Abort, are you sure? ",rply,1);
  70.     if (clower(rply[0]) != 'y')
  71.       {
  72.     verify(1);
  73.     return;
  74.       }
  75.     abort2();
  76.   }
  77.  
  78. /* =============================>>> ABORT2 <<<============================= */
  79.   abort2()
  80.   {
  81.     clobak();
  82.     tvclr();
  83.  
  84.     if (!newfil)
  85.     fclose(infile);
  86.     if (!rdonly)
  87.     fclose(outfile);
  88.  
  89.     if (strcmp(orig_file,source_file) != 0)
  90.       {
  91.     prompt("File begin used, intermediate edits in: ");
  92.     remark(source_file);
  93.       }
  94.     unlink(work_file);        /* delete the work file */
  95.  
  96.     reset();
  97.     quit();
  98.   }
  99.  
  100. /* =============================>>> FBEG   <<<============================= */
  101.   int fbeg()
  102.   { /* fbeg - go back to file top */
  103.  
  104.     SLOW int fbegv;
  105.  
  106.     if (rdonly)
  107.       {
  108.     tverrb("Can't: R/O");    /* can't do this for read only access */
  109.     return (FALSE);
  110.       }
  111.  
  112.     for (wtpage(1) ; rdpage() ; wtpage(1) )    /* write out rest */
  113.     ;
  114.  
  115.     if ((! newfil))
  116.       {
  117.     fclose(infile);            /* close source_file */
  118.       }
  119.     if (usecz)
  120.     fputc(ENDFILE,outfile);
  121.  
  122.     fclose(outfile);            /* close work_file */
  123.  
  124. /* files closed now, re-open */ 
  125.  
  126.     newfil = FALSE;        /* not a new file any more */
  127.  
  128.     strcpy(source_file,work_file);    /* new source file */
  129.     temp_name(work_file,FALSE);        /* make a new temporary name */
  130.  
  131.     if (!(infile = fopen(source_file,FILEREAD)))
  132.     goto l900;
  133.     else
  134.     ineof = FALSE;
  135.  
  136.     unlink(work_file);            /* get rid of previous copies */
  137.  
  138.     if (!(outfile = fopen(work_file,FILEWRITE)))
  139.       {
  140.     goto l900;
  141.       }
  142.  
  143.     fbegv=rdpage();        /* read in new buffer */
  144.     newscr();
  145.     return (fbegv);
  146.  
  147. l900: tverrb("Error re-opening");
  148.     return (FALSE);
  149.   }
  150.  
  151. /* =============================>>> FILE_EXIT <<<============================= */
  152.   file_exit()
  153.   { /* close the input and output files, rename */
  154.  
  155.     SLOW int i;
  156.  
  157.     if (!newfil)        /* don't close input if new file */
  158.       {
  159.     fclose(infile);
  160.       }
  161.  
  162.     while (!rdonly && !*dest_file)
  163.       {
  164.     remark("No name for output file has been specified.");
  165.     prompt("Enter new name for output file: ");
  166.     reply(dest_file,FNAMESIZE);
  167.       }
  168.  
  169.     if (!rdonly)    /* don't close output if read only access */
  170.       {
  171.     if (usecz)
  172.         fputc(ENDFILE,outfile);
  173.     set_mode(outfile);        /* set output mode if can */
  174.     fclose(outfile);
  175.  
  176.     /*    orig_file has the name to be renamed to .bak
  177.     work_file has the file name we want to be dest_name
  178.     */
  179.     if (strcmp(orig_file,dest_file) == 0)    /* make backup version */
  180.       {
  181.         strcpy(stemp,orig_file);
  182. #ifndef COMMA_BAK
  183.         if ((i = rindx(stemp,FILESEP)) > 0)    /* see if extenstion */
  184.         scopy(BACKEXT,0,stemp,i);        /* make .bak */
  185.         else
  186.           {
  187.         scopy(BACKEXT,0,stemp,strlen(stemp));    /* just add on */
  188.           }
  189. #else
  190.         i = rindx(orig_file,'/')+1;
  191.         scopy(".,",0,stemp,i);
  192.         scopy(orig_file,i,stemp,strlen(stemp));
  193. #endif
  194.  
  195.         unlink(stemp);            /* delete previous generation */
  196.         ren_file(orig_file,stemp);        /* rename the file */
  197.         if (!makebackup)            /* don't want to keep old one */
  198.         unlink(stemp);    /* delete it if don't want backup file */
  199.       }
  200.  
  201.     if (strcmp(orig_file,source_file) != 0)    /* delete intermediate file */
  202.         unlink(source_file);
  203.  
  204.  
  205.     while (infile = fopen(dest_file,FILEREAD))    /* output exists? */
  206.       {
  207.         fclose(infile);
  208.         prompt("Output file "); prompt(dest_file);
  209.         prompt(" already exists.  Overwrite it? (y/n) ");
  210.         ureply(stemp,1);
  211.         if (*stemp == 'Y')
  212.           {
  213.         unlink(dest_file);
  214.         break;
  215.           }
  216.         prompt("Enter new name for output file: ");
  217.         reply(dest_file,FNAMESIZE);
  218.       }
  219.  
  220.     ren_file(work_file,dest_file);        /* finally, rename last file */
  221.       }
  222.  
  223.   }
  224.  
  225. /* =============================>>> FOPENX  <<<============================= */
  226.   fopenx(argc,argv)
  227.   int argc;
  228.   char *argv[];
  229.   {  /* open the input file
  230.     This routine picks up file name from the user, creates a backup
  231.     version in some appropriate manner, and opens the file for input
  232.     and output. */
  233.  
  234.     SLOW int iswval, iswbeg, argnum, set_ttymode;
  235.     SLOW char ch, tmpc;
  236.     char rply[4];
  237.  
  238.     usebak = logdef;        /* if useing backup log file */
  239.  
  240.     ttymode = FALSE;        /* not in tty mode, so io ok */
  241.     ttynext = 1000;        /* force read */
  242.  
  243.     if (argc <= 1)
  244.       {
  245.     remark("Usage: tvx filename [-b -i -l -o=f -r -s -t -w -# {-z -c=f}]");
  246. #ifdef FULLHELP
  247.     remark("");
  248.     starthelp();        /* print start help message */
  249.     prompt(" Options: "); remark(VERSION);
  250.     remark("  -[no]b : backup file   -[no]i : autoindent");
  251.     remark("  -[no]l : make command log file");
  252.     remark("  -o=outputfile          -r : read only");
  253.     remark("  -s : big save buff     -[no]w : word processing mode");
  254.     remark("  -t : tty edit mode     -# : set virtual window lines to #");
  255. #ifdef MSDOS
  256.     remark("  -[no]z : use control-z for end of file");
  257. #endif
  258. #ifdef CONFIGFILE
  259. #ifdef MSDOS
  260.     remark("  -c=configfile        -c : use /bin/config.tvx");
  261. #endif
  262. #ifdef GEMDOS
  263.     remark("  -c=configfile        -c : use /bin/config.tvx");
  264. #endif
  265. #ifdef OSCPM
  266.     remark("  -c=configfile        -c : use A:config.tvx");
  267. #endif
  268. #endif
  269. #ifdef UNIX
  270.     remark("  {options not available for unix}");
  271. #endif
  272. #endif
  273.     remark("");
  274.     reset();
  275.     quit();
  276.       }
  277.  
  278.     newfil=                /* assume opening an old file */
  279.     rdonly = FALSE;            /* assume not read only */
  280.     makebackup = MAKE_BACKUP;        /* default value for make a backup */
  281.     blimit = BUFFLIMIT;
  282.  
  283.     for (argnum = 1 ; argnum < argc ; ++argnum)
  284.       {
  285.     strcpy(stemp,argv[argnum]);    /* pick up the file name or switch */
  286. REDO:
  287.     if (stemp[0] == SWITCH)        /* switch in form "/R filename" only */
  288.       {
  289.         iswbeg=1;        /* start at 1 */
  290.         iswval = TRUE;
  291.         if (clower(stemp[1]) == 'n' && clower(stemp[2]) == 'o')
  292.           {
  293.         iswval = FALSE ; iswbeg = 3 ;
  294.           }
  295.  
  296.         ch = clower(stemp[iswbeg]);        /* get the char */
  297.         if (ch == 'r')        /* read only access */
  298.         rdonly=iswval;
  299.         else if (ch == 'i')        /* auto indent */
  300.         autoin = iswval;
  301.         else if (ch == 'w')        /* word processing mode */
  302.           {
  303.         if (iswval)
  304.             wraplm = 70;
  305.         else
  306.             wraplm = 0;
  307.           }
  308.         else if (ch == 'l')        /* log file */
  309.         usebak = iswval;
  310.         else if (ch == 'b')
  311.         makebackup = iswval;    /* make a backup file */
  312.         else if (ch == 'z')
  313.         usecz = iswval;
  314.         else if (ch == 'o' && (stemp[iswbeg+1] == '=' ||
  315.           stemp[iswbeg+1] == ':'))    /* specifying output */
  316.           {
  317.         if (!iswval)        /* wrong order! */
  318.           {
  319.             remark("Bad -O= switch");
  320.             quit();
  321.           }
  322.         scopy(stemp,iswbeg+2,dest_file,0);  /* remember name */
  323.           }
  324. #ifdef CONFIGFILE
  325.         else if (stemp[iswbeg] == 'c' && stemp[iswbeg+1] == 0) /* default cfg */
  326.           {
  327.         strcpy(stemp,cfgname);
  328.           goto REDO;
  329.           }
  330.         else if (stemp[iswbeg] == 'c' && (stemp[iswbeg+1] == '=' ||
  331.           stemp[iswbeg+1] == ':'))    /* specifying config */
  332.           {
  333.         expand_name(&stemp[iswbeg+2]);
  334.         if ((bkuin = fopen(&stemp[iswbeg+2],FILEREAD))==0)
  335.           {
  336.             remark("Can't open configuration file.");
  337.             continue;
  338.           }
  339.         rdcfg(lexsym,LEXVALUES+1);
  340.         rdcfg(synofr,20);
  341.         rdcfg(synoto,20);
  342.         rdcfg(funchar,50);
  343.         rdcfg(funcmd,50);
  344.         rdcfg(&funkey,1);
  345.         rdcfg(&tmpc,1); autoin = (int) tmpc;
  346.         rdcfg(&tmpc,1); ddline = (int) tmpc;
  347.         rdcfg(&tmpc,1); dscrl = (int) tmpc;
  348.         rdcfg(&tmpc,1); dxcase = (int) tmpc;
  349.         rdcfg(&tmpc,1); wraplm = (int) tmpc;
  350.         rdcfg(&tmpc,1); use_wild = (int) tmpc;
  351.         rdcfg(&tmpc,1); usebak = (int) tmpc;
  352.         logdef = usebak;
  353.         rdcfg(&tmpc,1); cut_mode = (int) tmpc;
  354. #ifdef MSDOS
  355.         rdcfg(&tmpc,1); usecz = (int) tmpc;
  356. #endif
  357. #ifdef GEMDOS
  358.         rdcfg(&tmpc,1); usecz = (int) tmpc;
  359. #endif
  360.         fclose(bkuin);
  361.           }
  362. #endif
  363.         else if (ch == 's')    /* big save buffer */
  364.           {
  365.         if (!iswval)
  366.             blimit=BUFFLIMIT;
  367.         else
  368.             blimit=BUFFLIMIT*3;
  369.           }
  370. #ifndef VTERM
  371.         else if (ch == 't')    /* tty mode */
  372.         set_ttymode = iswval;    /* make a backup file */
  373. #endif
  374.         else if (ch >= '0' && ch <= '9')    /* making a virtual window */
  375.           {
  376.         tvlins = atoi(&stemp[iswbeg]);    /* get virtual screen size */
  377.         if (tvlins < 3 || tvlins > tvhardlines)    /* invalid window */
  378.           {
  379.             remark("Invalid window size");
  380.             tvlins = tvhardlines;
  381.           }
  382.         else
  383.           {
  384.             ddline = (tvlins / 2) + 1;    /* fix home line */
  385.             setdscrl();
  386.           }
  387.           }
  388.         else                /* illegal switch */
  389.           {
  390.         prompt("Unknown switch -"); ttwt(ch);
  391.         prompt(": Ignore and continue? (y/n) ");
  392.         ureply(rply,1);
  393.         if (*rply != 'Y')
  394.           {
  395.             reset();  quit();
  396.           }
  397.           }
  398.       }
  399.     else            /* must have a file name */
  400.       {
  401.         strcpy(orig_file,stemp);
  402.       }
  403.       }        /* end for */
  404.  
  405. /*    now open file properly - make copies to all 4 names */
  406.  
  407. GETNAME:
  408.     while (!*orig_file)
  409.       {
  410.         ask("Edit file? ",orig_file,FNAMESIZE);
  411.       }
  412.  
  413.     expand_name(orig_file);        /* expand on unix */
  414.  
  415.     if (!(infile = fopen(orig_file,FILEREAD)))    /* can open? */
  416.       {
  417.         prompt("Create file "); prompt(orig_file);
  418.         prompt("? (y/n) ");
  419.         ureply(rply,1);
  420.         if (*rply != 'Y')
  421.           {
  422.         *orig_file = 0; goto GETNAME;
  423.           }
  424.         if (*dest_file)
  425.         remark("New file, -o= switch ignored");
  426.         *dest_file = 0;
  427.         newfil = TRUE;        /* a new file */
  428.         rdonly = FALSE;
  429.       }
  430.  
  431. /* orig_file now has the name of the source file, and it might be open */
  432.  
  433.     ineof = FALSE;
  434.     strcpy(source_file,orig_file);    /* copy to other names */
  435.     strcpy(work_file,orig_file);
  436.     if (!*dest_file)        /* no -o specified */
  437.         strcpy(dest_file,orig_file);
  438.  
  439.  
  440.     if (!newfil)            /* not new file */
  441.       {
  442.         fclose(infile);        /* close orig file */
  443.         if (!(infile = fopen(source_file,FILEREAD)))    /* re-open */
  444.           {
  445.         remark("Internal editor error, aborting");
  446.         exit(100);
  447.           }
  448.         get_mode(infile);        /* get mode of original file */
  449.       }
  450.     else
  451.       {
  452.         *orig_file = *source_file = 0; 
  453.       }
  454.  
  455. /* now see if we can make an output file */
  456.     
  457.     if (!rdonly)
  458.       {
  459.         temp_name(work_file,TRUE);    /* make into a temporary name 1st time */
  460.         if ((outfile = fopen(work_file,FILEREAD)))
  461.           {
  462.         /* this code is needed when the temp_name might not be
  463.            unique - which happens when you push (^O) and try to
  464.            edit a file with the same main name but perhaps a different
  465.            extension - the temp file will be the same, and the child
  466.            version of tvx will then delete the temprorary file created
  467.            by the parent.  This can happen again if fbeg, but let's
  468.            assume the 'y' applies forever.
  469.         */
  470.         fclose(outfile);    /* close up the file */
  471.         prompt("Work file already exists: ");
  472.         remark(work_file);
  473.         prompt("Erase it and continue with editing? (y/n) ");
  474.         ureply(rply,1);
  475.         if (*rply != 'Y')
  476.           {
  477.             reset();
  478.             exit(100);        /* abnormal exit */
  479.           }
  480.           }
  481.  
  482.         unlink(work_file);    /* get rid if already there */
  483.  
  484.         if (!(outfile = fopen(work_file,FILEWRITE)))
  485.           {
  486.         prompt("Unable to create output work file: ");
  487.         remark(work_file);
  488.         if (!newfil)
  489.           {
  490.             prompt("Continue in read only mode? (y/n) ");
  491.             ureply(rply,1);
  492.             if (*rply != 'Y')
  493.               {
  494.             fclose(infile);
  495.             reset();
  496.             exit(100);        /* abnormal exit */
  497.               }
  498.           }
  499.         *dest_file = *work_file = 0;
  500.         rdonly = TRUE;
  501.           }
  502.       }
  503.     else
  504.       {
  505.         *dest_file = *work_file = 0;
  506.       }
  507.  
  508.     ttymode = force_tty ? TRUE : set_ttymode;    /* now safe to set ttymode */
  509.   }
  510.  
  511. /* =============================>>> setdscrl <<<============================= */
  512.   setdscrl()
  513.   {    /* compute a new value for dscrl */
  514.  
  515.     if (dscrl == 0)
  516.     return;            /* if already 0, don't change */
  517.     dscrl = tvlins / 3;
  518.     if ((ddline + dscrl) >= tvlins)    /* looks ugly if hits last line */
  519.     dscrl--;
  520.     if (dscrl < 0)        /* don't allow this */
  521.     dscrl = 0;
  522.   }
  523.  
  524. #ifdef CONFIGFILE
  525. /* =============================>>> RDCFG <<<============================= */
  526.   rdcfg(toset,cnt)
  527.   char *toset;
  528.   int cnt;
  529.     {    /* read cnt vals from bkuin */
  530.  
  531.     FAST int i,val;
  532.  
  533.     for (i = 0 ; i < cnt ; ++i)
  534.       {
  535.     if ((val = fgetc(bkuin)) == EOF)
  536.      {
  537.         remark("Invalid configuration file, aborting");
  538.         fclose(bkuin);
  539.         quit();
  540.      }
  541.     *toset++ = val;    /* replace with new commands */
  542.       }
  543.   }
  544. #endif
  545.  
  546. /* =============================>>> ADDFIL <<<============================= */
  547.   int addfil(rw)
  548.   int rw;
  549.   {  /* addfil - add contents of external file to save buffer
  550.     positive means read into buffer, negative means write save buffer */
  551.  
  552.     SLOW int chr;
  553.     SLOW int limit;
  554.  
  555.     SLOW BUFFINDEX fromch;
  556.     SLOW int i;
  557.     SLOW FILE *f;
  558.  
  559.     if (rw >= 0)    /* read a file */
  560.       {
  561.     if (!gbgcol(nxtchr))    /* gc first */
  562.       {
  563.         newscr();
  564.         tverrb("No save room");
  565.         return (FALSE);
  566.       }
  567.  
  568.     tvclr();
  569. #ifdef LASL
  570.     ask("Read external filename: ",stemp,FNAMESIZE);
  571. #else
  572.     ask("Yank filename: ",stemp,FNAMESIZE);
  573. #endif
  574.  
  575.     expand_name(stemp);            /* expand on some systems */
  576.  
  577.     if (!(f = fopen(stemp,FILEREAD)) || !*stemp)
  578.       {
  579.         newscr();
  580. #ifdef LASL
  581.         tverrb(" Unable to open external file ");
  582. #else
  583.         tverrb(" Unable to open yank file ");
  584. #endif
  585.         return (FALSE);
  586.      }
  587.  
  588.     savlin=0 ; savlen=0 ; nxtsav =mxbuff ;    /* clear out save buffer */
  589.  
  590.     limit = max(nxtchr,mxbuff/2) + ALMOSTOUT;
  591.     do
  592.       {
  593.         if ((chr = getchr(f)) < 0)
  594.           {
  595.         newscr();
  596.         fclose(f);
  597.         return (TRUE);
  598.           }
  599.         if (chr == NEWLINE)
  600.           {
  601. #ifdef FILELF
  602.         getchr(f);
  603. #endif
  604.         chr=ENDLINE;
  605.         ++savlin;
  606.           }
  607.         *(buff+nxtsav--) = chr;
  608.         if (nxtsav <= limit)
  609.           {
  610.         newscr();
  611.         tverrb("File only partly read");
  612.         break;
  613.           }
  614.       }
  615.     while (1);
  616.     fclose(f);
  617.     return (TRUE);
  618.       }
  619.  
  620.     /* --------------- to here, then writing from save buffer --------------*/
  621.  
  622.  
  623.     if (nxtsav==mxbuff)        /* nothing to save */
  624.       {
  625.      tverrb("Save buffer empty!");
  626.     return (TRUE);
  627.       }
  628.  
  629.     tvclr();
  630.     ask("Write to external filename: ",stemp,FNAMESIZE);
  631.  
  632.     expand_name(stemp);            /* expand on some systems */
  633.  
  634.     if (!(f = fopen(stemp,FILEWRITE)) || !*stemp)
  635.       {
  636.     newscr();
  637.     tverrb(" Unable to open external file ");
  638.     return (FALSE);
  639.       }
  640.  
  641.     
  642. /*   # move down line to make space for new */
  643.     fromch = mxbuff;        /* where taking saved stuff from */
  644.     for (i = 0 ; i < savlin ; ++i)
  645.       {
  646.     for ( ; ; )        /* scan save buffer */
  647.       {
  648.          if ((chr = *(buff+fromch--)) == ENDLINE)
  649.           {
  650.         fputc(NEWLINE,f);
  651. #ifdef FILELF
  652.         fputc(LF,f);
  653. #endif
  654.         break;
  655.           }
  656.         else
  657.         fputc(chr,f);
  658.       }
  659.       }
  660.  
  661.     if (usecz)
  662.     fputc(ENDFILE,f);
  663.     fclose(f);
  664.     newscr();
  665.     return (TRUE);
  666.  
  667.   }
  668.  
  669. /*=============================>>> SCOPY  <<<================================*/
  670.   scopy(old,oldbeg,new,newbeg)
  671.   char old[], new[];
  672.   int oldbeg,newbeg;
  673.   {
  674.     while (old[oldbeg])
  675.     new[newbeg++]=old[oldbeg++];
  676.     new[newbeg] = 0;
  677.   }
  678.  
  679. /* **************************************************************************
  680.  
  681.     Following code is for non-unix systems
  682.  
  683.  **************************************************************************** */
  684. #ifndef UNIX
  685. /* =============================>>> get_mode <<<============================= */
  686.   get_mode(f)
  687.   FILE *f;
  688.   {        /* gets access mode of open file f */
  689.   }
  690.  
  691. /* =============================>>> set_mode <<<============================= */
  692.   set_mode(f)
  693.   FILE *f;
  694.   {        /* sets access mode of open file f */
  695.   }
  696.  
  697. /* ==========================>>> expand_name <<<============================ */
  698.   expand_name(n)
  699.   char *n;
  700.   {        /* expands unix file names */
  701.   }
  702.  
  703. /* =============================>>> ren_file <<<=========================== */
  704.   ren_file(old,new)
  705.   char *old, *new;
  706.   {
  707. #ifndef GEMDOS
  708.     if (rename(old,new) != 0)
  709.       {
  710.     prompt(old) ; prompt(" not renamed to "); remark(new);
  711.       }
  712. #endif
  713. #ifdef GEMDOS
  714.     gemdos(0x56,0,old,new);    /* can't find C version */
  715. #endif
  716.   }
  717.  
  718. /* =============================>>> temp_name <<<=========================== */
  719.   temp_name(n,first)
  720.   char *n;
  721.   int first;
  722.   {
  723.     /* generates a temporary name from n.  Depending on value of
  724.        first, it will either add a 1 or 2 to name */
  725.  
  726.     SLOW int i;
  727.  
  728.     if (first)
  729.       {
  730.     if ((i = rindx(n,FILESEP)) > 0)    /* see if extenstion */
  731.         scopy(TEMPEXT,0,n,i);        /* make .bak */
  732.     else
  733.       {
  734.         scopy(TEMPEXT,0,n,strlen(n));    /* just add on */
  735.       }
  736.       }
  737.     else
  738.       {
  739.     i = strlen(n);
  740.     if (n[i-1] == '1')
  741.         n[i-1] = '2';
  742.     else
  743.         n[i-1] = '1';
  744.       }
  745.   }
  746. #endif
  747.  
  748. /* **************************************************************************
  749.  
  750.     This section is for the version supporting command logfile
  751.     backup.  The code necessary for this version is included here,
  752.     and may be compiled by defining VB to be a blank.
  753.  
  754.  **************************************************************************** */
  755.  
  756. /* =============================>>> OPNBAK <<<============================= */
  757.   opnbak()
  758.   { 
  759.     /* opnbak - open the backup log file
  760.        if VB defined as ' ', then backup version created */
  761.  
  762. #ifdef VB
  763.  
  764.     if (! usebak)
  765.       {
  766.     bakflg = FALSE;
  767.     return;
  768.       }
  769.  
  770.     bkuout = fopen(BACKUPNAME,FILEWRITE);
  771.     bakpos = 1;
  772. #endif
  773.  
  774.   }
  775.  
  776. /* =============================>>> PUTBAK <<<============================= */
  777.   putbak(chr)
  778.   char chr;
  779.   { /* putbak - put a character into the backup file */
  780.  
  781. #ifdef VB
  782.     static char copy;
  783.  
  784.     if (! usebak)
  785.     return;
  786.     copy=chr;
  787.     if (copy < 32 || copy == '@' || copy==delkey)
  788.       {
  789.     fputc('@',bkuout);
  790.     bakcrlf();
  791.     if (copy < 32)
  792.         copy += '@';
  793.     else if (copy==delkey)
  794.         copy = '?';     /* let @? be rubout */
  795.       }
  796.     fputc(copy,bkuout);
  797.     bakcrlf();
  798. #endif
  799.   }
  800.  
  801. #ifdef VB
  802. /* =============================>>> BAKCRLF <<<============================= */
  803.   bakcrlf()
  804.   {    /* conditionally put a cr/lf to backup file */
  805.  
  806.     if (++bakpos > 63)
  807.       {
  808.     fputc(NEWLINE,bkuout);
  809. #ifdef FILELF
  810.     fputc(LF,bkuout);
  811. #endif
  812.     bakpos = 1;
  813.       }
  814.   }
  815. #endif
  816.  
  817. /* =============================>>> CLOBAK <<<============================= */
  818.   clobak()
  819.   {
  820.  
  821. #ifdef VB
  822.     if (! usebak)
  823.     return;
  824.     fputc(NEWLINE,bkuout);
  825. #ifdef FILELF
  826.     fputc(LF,bkuout);
  827. #endif
  828.     if (usecz)
  829.     fputc(ENDFILE,bkuout);
  830.  
  831.     fclose(bkuout);
  832. #endif
  833.   }
  834.  
  835. /* =============================>>> GETBAK <<<============================= */
  836.   getbak(chr)
  837.   char *chr;
  838.   {  /* get one char from back up file if there */
  839.  
  840. #ifdef VB
  841.     SLOW int ich;
  842.  
  843. l10:
  844.     if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
  845.       {
  846. l15:    fclose(bkuin);
  847.     *chr=0;            /* harmless character */
  848.     bakflg=FALSE;
  849.     verify();
  850.     return;
  851.       }
  852.     if (ich == NEWLINE)
  853.     goto l10;
  854. #ifdef FILELF
  855.     if (ich == LF)
  856.     goto l10;
  857. #endif
  858.     *chr=ich;
  859.     if (ich=='@')
  860.       {
  861. l20:    if ((ich = getchr(bkuin)) < 0 || ich == ENDFILE)
  862.       {
  863.         goto l15;
  864.       }
  865.     if (ich == NEWLINE)
  866.         goto l20;
  867. #ifdef FILELF
  868.     if (ich == LF)
  869.         goto l20;
  870. #endif
  871.     *chr=ich;
  872.     if (ich == '?')
  873.         *chr=delkey;
  874.     else if (*chr != '@')
  875.         *chr= ich - '@';
  876.       }
  877. #endif
  878.   }
  879.  
  880. /* =============================>>> OPNATF <<<============================= */
  881.   opnatf()
  882.   { /* open an indirect command file */
  883.  
  884. #ifdef VB
  885.  
  886.     tvclr();
  887.  
  888.     ask("Name of command file: ",stemp,FNAMESIZE);
  889.         /* read in the file name from the terminal */
  890.  
  891.     expand_name(stemp);
  892.  
  893.     if (!*stemp)
  894.       {
  895.     verify();
  896.     return;
  897.       }
  898.  
  899.     if (!(bkuin = fopen(stemp,FILEREAD)))
  900.       {
  901.     verify();
  902.     tverrb("Bad @ name");
  903.     return;
  904.       }
  905.     bakflg=TRUE;
  906.     newscr();
  907. #endif
  908.   }
  909.  
  910. /* **************************************************************************
  911.  
  912.     This section contains code to write and read buffers of data
  913.  
  914.  **************************************************************************** */
  915.  
  916. /* =============================>>> RDPAGE <<<============================= */
  917.   int rdpage()
  918.   { /* rdpage - read in file up to buffer limit
  919.        only place text read from edited file */
  920.  
  921.     SLOW int chr;
  922.     SLOW int l,newlns;
  923. #ifdef GETSIO
  924.     char inbuff[256];
  925.     FAST char *bp;    /* ptr to inbuff */
  926.     SLOW int do_read;    /* flag if need to read */
  927.  
  928.     do_read = TRUE;    /* need to do read first time */
  929. #endif
  930.  
  931.     if (newfil)        /* can't read in when a new file */
  932.       {
  933.     return (FALSE);
  934.       }
  935.     if (nxtlin > mxline || nxtchr > mxbuff-130)    /* error check */
  936.       {
  937.     tverrb("Lines filled ");
  938.     return (FALSE);
  939.       }
  940.  
  941.     newlns=0;            /* begin at the beginning */
  942.  
  943.     while (mxline-nxtlin > LINELIMIT  && nxtsav-nxtchr > blimit && !ineof)
  944.       {             /* read in while have room */
  945. #ifdef GETSIO
  946.     if (do_read)
  947.       {
  948.         if (fgets(inbuff,255,infile) == NULL)
  949.           {
  950.         ineof = TRUE;
  951.         break;
  952.           }
  953.         do_read = FALSE;    /* a line has been read */
  954.         bp = inbuff;    /* point to beginning of buffer */
  955.       }
  956.     chr = *bp++;        /* "read" the character */
  957. #else
  958.     if ((chr = fgetc(infile)) == EOF)
  959.       {
  960.         ineof = TRUE;
  961.         break;
  962.       }
  963. #endif
  964.  
  965.     if (chr == ENDFILE && usecz)
  966.       {
  967.         ineof = TRUE;
  968.         break;
  969.       }
  970. #ifdef FILELF
  971.     if (chr == LF)
  972.         continue;
  973. #endif
  974.     *(buff+nxtchr) = BEGLINE;
  975.     *(lines+nxtlin) = nxtchr++;
  976.     ++newlns ;
  977.         
  978.     while (chr != NEWLINE)        /* store a line */
  979.       {
  980.         *(buff+nxtchr++) = chr;
  981. #ifdef GETSIO
  982.         chr = *bp++;        /* "read" the character */
  983. #else
  984.         if ((chr = fgetc(infile)) == EOF)
  985.           {
  986.         ineof = TRUE;
  987.         break;
  988.           }
  989. #endif
  990.         if (chr == ENDFILE && usecz)
  991.           {
  992.         ineof = TRUE;
  993.         break;
  994.           }
  995.       }    /* end of while != NEWLINE */
  996. #ifdef GETSIO
  997.     do_read = TRUE;
  998. #endif
  999.  
  1000.     *(buff+nxtchr++) = ENDLINE;
  1001.     ++nxtlin;
  1002.       }
  1003.  
  1004.     if (nxtlin > 1)        /* we really read something */
  1005.       {
  1006.     curlin=1;        /* point to top of char */
  1007.     curchr = *(lines+1)+1;    /* point to first character */
  1008.       }
  1009.     return (newlns > 0) ;
  1010.   }
  1011.  
  1012. /* =============================>>> WTPAGE <<<============================= */
  1013.   wtpage(whow)
  1014.   int whow;
  1015.   { /* wtpage - write out contents of text buffer, and clear line list */
  1016.  
  1017.     FAST int i;
  1018.     FAST char *chrp;
  1019.     SLOW char *lim;
  1020.     SLOW int wlimit;
  1021. #ifdef GETSIO
  1022.     char outbuff[256];
  1023.     FAST char *bp;    /* ptr to outbuff */
  1024.     SLOW int buff_len;
  1025. #endif
  1026.  
  1027.     if (whow < 0)        /* allow writing partial buffer */
  1028.     wlimit = curlin - 1;
  1029.     else
  1030.     wlimit = nxtlin -1;
  1031.  
  1032.     if (nxtlin <= 1 || rdonly)
  1033.       {
  1034.     tverr("Empty buffer");
  1035.     goto zapb;
  1036.       }
  1037.  
  1038.     if (whow < 0)
  1039.     tverr("Writing partial buffer");
  1040.     else
  1041.     tverr("Writing buffer");
  1042.  
  1043.     tvhdln();
  1044.  
  1045.     for (i = 1 ; i <= wlimit ; ++i)
  1046.       {
  1047.     chrp = buff + (*(lines+i)+1);    /* ptr to first char of line */
  1048. #ifdef GETSIO
  1049.     bp = outbuff;            /* pt to buffer */
  1050.     buff_len = 0;
  1051.     while (*chrp != ENDLINE && buff_len < 253)
  1052.       {
  1053.         *bp++ = *chrp++;        /* copy character */
  1054.       }
  1055.     *bp++ = NEWLINE;
  1056. #ifdef FILELF
  1057.     *bp++ = LF;
  1058. #endif
  1059.     *bp = 0;            /* end of string */
  1060.     fputs(outbuff,outfile);        /* and write all at once */
  1061. #else
  1062.     while (*chrp != ENDLINE)
  1063.       {
  1064.         fputc(*chrp++, outfile);
  1065.       }
  1066.     fputc(NEWLINE,outfile);
  1067. #ifdef FILELF
  1068.     fputc(LF,outfile);
  1069. #endif
  1070.  
  1071. #endif
  1072.       }
  1073.  
  1074. zapb:
  1075.  
  1076.     if (whow < 0)
  1077.       {
  1078.     killin(-(curlin-1));    /* kill to top of buffer */
  1079.     if (!gbgcol(nxtchr))    /* gc first */
  1080.       {
  1081.         newscr();
  1082.         tverrb("Warning: no extra room created");
  1083.         return (FALSE);
  1084.       }
  1085.     return (TRUE);
  1086.       }
  1087.     else
  1088.       {
  1089.     lim = buff + nxtsav;
  1090.     for (chrp=buff ; chrp < lim ; *chrp++ = GARBAGE)
  1091.         ;
  1092.     tvdlin =            /* start on first line again */
  1093.     nxtlin =            /* reset to initial state */
  1094.     nxtchr = 1;
  1095.     curchr =
  1096.     curlin=0;
  1097.     return (TRUE);
  1098.       }
  1099.   }
  1100.  
  1101. /* **************************************************************************
  1102.  
  1103.     This section contains misc. stuff likely to be operating system dependent
  1104.  
  1105.  **************************************************************************** */
  1106.  
  1107. /* ===========================>>> OPSYSTEM <<<============================== */
  1108.   opsystem()
  1109.   {
  1110. #ifdef MSDOS            /* !!! cii-86 dependent */
  1111.  
  1112.     char rp[80];
  1113.  
  1114. MS_AGAIN:
  1115.     tvclr();
  1116.     ask("DOS command (any key to resume edit when done): ",rp,79);
  1117.     remark("");
  1118.     if (system(rp) != 0)
  1119.       {
  1120.         tvxy(1,1);
  1121.     ask("Sorry, but couldn't find COMMAND.COM.",rp,1);
  1122.       }
  1123.     else
  1124.       {
  1125.     tvxy(1,1);
  1126.     ask("",rp,1);
  1127.     if (*rp == '!')
  1128.        goto MS_AGAIN;
  1129.       }
  1130.     verify(1);
  1131. #endif
  1132. #ifdef UNIX
  1133.     unix_sys();
  1134. #endif
  1135. #ifdef GEMDOS
  1136.     return;
  1137. #endif
  1138.   }
  1139.  
  1140. #ifndef UNIX
  1141. /* ===========================>>> TTINIT <<<============================== */
  1142.   ttinit()
  1143.   { /*  this routine could be used to set up keyboard input, perhaps
  1144.     turning on non-echoed input */
  1145.     return;
  1146.   }
  1147.  
  1148. /* ===========================>>> TTCLOS <<<============================== */
  1149.   ttclos()
  1150.   {  /* this routine could undo anything ttinit() did */
  1151.     return;
  1152.   }
  1153. #endif
  1154.  
  1155. #ifndef VTERM
  1156. /* ===========================>>> TTRD <<<============================== */
  1157.   ttrd()
  1158.   { /* this routine is called to read one unechoed char from the keyboard */
  1159.  
  1160.   static int tc, i;
  1161.   static char chr;
  1162.  
  1163. RDTOP:
  1164.     if (ttymode)
  1165.     tc = rdtty();        /* get a char from the tty */
  1166.     else
  1167.       {
  1168.  
  1169. #ifdef OSCPM
  1170.     while (!(tc = bdos(6,-1)))        /* cp/m implementation */
  1171.     ;
  1172. #endif
  1173. #ifdef MSDOS
  1174.     tc = bdos(7,-1);        /* ms-dos implementation  (!!! cii-86) */
  1175. #endif
  1176. #ifdef GEMDOS
  1177.     tc = gemdos(7);        /* GEMDOS application */
  1178. #endif
  1179. #ifdef UNIX
  1180.     tc = ttrd_unix();
  1181. #endif
  1182.        }
  1183.  
  1184.     chr = tc & 0377;
  1185.  
  1186.     if (chr == funkey)            /* function key */
  1187.       {
  1188.     if (ttymode)
  1189.       {
  1190.         tc = rdtty();        /* get a char from the tty */
  1191.       }
  1192.     else
  1193.       {
  1194. #ifdef OSCPM
  1195.     while (!(tc = bdos(6,-1)))        /* cp/m implementation */
  1196.         ;
  1197. #endif
  1198. #ifdef MSDOS
  1199.     tc = bdos(7,-1);        /* ms-dos implementation */
  1200. #endif
  1201. #ifdef GEMDOS
  1202.     tc = gemdos(7);        /* GEMDOS application */
  1203. #endif
  1204. #ifdef UNIX
  1205.     tc = ttrd_unix();
  1206. #endif
  1207.       }
  1208.     chr = tc & 0377;
  1209.     for (i = 0 ; i < 50 && funchar[i] ; ++i)
  1210.       {
  1211.         if (chr == funchar[i])
  1212.           {
  1213.         tc = funcmd[i] & 0377;
  1214.         return (tc);
  1215.           }
  1216.       }
  1217.     goto RDTOP;            /* ignore invalid function keys */
  1218.       }
  1219.     tc = chr & 0377;
  1220.     return (tc);
  1221.  
  1222.   }
  1223. #endif
  1224.  
  1225. #ifndef UNIX
  1226. /* ===========================>>> TTWT <<<============================== */
  1227.   ttwt(chr)
  1228.   char chr;
  1229.   { /*  this routine is called to write one char to the keyboard
  1230.     It also interprets print direction */
  1231.  
  1232.     if (ttymode)
  1233.     return;
  1234.     dispch(chr);    /* cp/m, ms-dos version */
  1235.     if (useprint)
  1236.     printc(chr);
  1237.   }
  1238. #endif
  1239.  
  1240. #ifdef MSDOS
  1241. #define DEFGETCHR
  1242. #endif
  1243.  
  1244. #ifdef OSCPM
  1245. #define DEFGETCHR
  1246. #endif
  1247.  
  1248. #ifdef GEMDOS
  1249. #define DEFGETCHR
  1250. #endif
  1251.  
  1252. #ifdef DEFGETCHR
  1253. /* ===========================>>> GETCHR <<<============================== */
  1254.   getchr(filnum)
  1255.   FILE *filnum;
  1256.   {  /* get a character from filnum */
  1257.  
  1258. #define EOFBYTE 26
  1259.  
  1260.     FAST int ichr;
  1261.  
  1262.     if (((ichr = fgetc(filnum)) == EOFBYTE))
  1263.       {
  1264.     if (usecz)
  1265.         return (EOF);
  1266.       }
  1267.  
  1268.     return (ichr);
  1269.   }
  1270. #endif
  1271.  
  1272. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1273.  
  1274.     TVX TERMINAL DRIVER  for various terminals
  1275.  
  1276.    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  1277.  
  1278.  
  1279. /* =============================>>> TRMINI <<<============================= */
  1280.   trmini()
  1281.   {  /* initialize term if necessary */
  1282.  
  1283.     sendcs(cinit);
  1284.     tvclr();
  1285.   }
  1286.  
  1287. /* =============================>>> reset <<<============================= */
  1288.   reset()
  1289.   {
  1290.     sendcs(cendit);
  1291.     ttclos();
  1292.   }
  1293.  
  1294. /* =============================>>> ttyverify <<<============================= */
  1295.   ttyverify(knt)
  1296.   int knt;
  1297.   {
  1298.     SLOW BUFFINDEX oldline, oldchr, limit;        /* current position */
  1299.  
  1300.     oldline = curlin; oldchr = curchr;    /* remember where we were */
  1301.  
  1302.     ttymode = FALSE;            /* enable output stuff */
  1303.  
  1304.     if (knt < 0)            /* type some above */
  1305.       {
  1306.     curchr = 0;
  1307.     curlin = curlin + knt ;        /* back n lines */
  1308.     if (curlin < 1)
  1309.        curlin = 1;
  1310.     while (curlin < oldline)    /* write out the lines */
  1311.         ttyline(curlin++);    /* write line, no cursor */
  1312.       }
  1313.     else
  1314.       {
  1315.     ttyline(curlin);        /* type current line */
  1316.     curchr = 0;            /* this turns off cursor */
  1317.     limit = oldline + knt - 1;
  1318.     if (limit >= nxtlin)
  1319.         limit = nxtlin - 1;
  1320.     while (++curlin <= limit)
  1321.         ttyline(curlin);
  1322.       }
  1323.     curchr = oldchr;
  1324.     curlin = oldline;
  1325.     ttymode = TRUE;
  1326.   }
  1327.  
  1328. /* =============================>>> ttyline <<<============================= */
  1329.   ttyline(linenr,cursor)
  1330.   BUFFINDEX linenr;
  1331.   {
  1332.     SLOW BUFFINDEX chrc;
  1333.     SLOW int outlen;
  1334.     
  1335.     chrc = *(lines+linenr)+1;    /* point to first character in line */
  1336.     outlen = 0;            /* nothing out yet */
  1337.     for ( ; ; )
  1338.       {
  1339.     if (chrc == curchr)    /* at cursor */
  1340.       {
  1341.         outlen += 2;
  1342.         if (outlen > 78)    /* line wrap */
  1343.           {
  1344.         remark("");
  1345.         ttwt('_');
  1346.         outlen = 3;
  1347.           }
  1348.         ttwt('/'); ttwt('\\');
  1349.       }
  1350.         if (*(buff+chrc) == ENDLINE)    /* done */
  1351.         break;
  1352.     outlen += ttywtch(*(buff+chrc));    /* watch for line wrap */
  1353.     if (outlen > 78)
  1354.       {
  1355.         remark("");
  1356.         ttwt('_');
  1357.         outlen = 1;
  1358.       }
  1359.     ++chrc;            /* next character */
  1360.       }
  1361.     remark("");
  1362.   }
  1363.   
  1364. /* =============================>>> ttywtch <<<============================= */
  1365.   ttywtch(chr)
  1366.   char chr;
  1367.   {
  1368.     if (chr >= ' ')        /* regular character */
  1369.       {
  1370.     ttwt(chr);
  1371.     return 1;
  1372.       }
  1373.     else            /* control character */
  1374.       {
  1375.     ttwt('^');
  1376.     ttwt(chr+'@');
  1377.     return 2;
  1378.       }
  1379.   }
  1380.   
  1381. /* =============================>>> rdtty <<<============================= */
  1382.   rdtty(knt)
  1383.   int knt;
  1384.   {        /* fake rdtt for ttymode - only called when in ttymode */
  1385.  
  1386. #define RDBUFFSIZE 81
  1387.     static char rdtbuf[RDBUFFSIZE];
  1388.  
  1389. RDTOP:
  1390.     ttymode = FALSE;            /* take out of ttymode for echo */
  1391.     if (ttynext >= RDBUFFSIZE)        /* need to read a line */
  1392.       {
  1393.     if (ins_mode)            /* different prompts for modes */
  1394.         prompt("+");
  1395.     else
  1396.         prompt("tvx>");
  1397.     reply(rdtbuf,80);        /* read a line */
  1398.     ttynext = 0;            /* reset pointer */
  1399.       }
  1400.     ttymode = TRUE;            /* no echo again */
  1401.     if (rdtbuf[ttynext] == 0)        /* end of buffer */
  1402.       {
  1403.     ttynext = 1000;
  1404.     if (ins_mode)
  1405.         return (CR);        /* return a carriage return for ins */
  1406.     else
  1407.         goto RDTOP;            /* read another line */
  1408.       }
  1409.     else
  1410.       {
  1411.     return (rdtbuf[ttynext++]);    /* return character */
  1412.       }
  1413.   }
  1414.  
  1415. /* =============================>>> TVPLIN <<<============================= */
  1416.   tvplin(chrptr)
  1417.   BUFFINDEX chrptr;
  1418.   { /* tvplin - put line beginning at chrptr
  1419.         will only type what will fit on screen (using xout) */
  1420.  
  1421.     SLOW char tmp;
  1422.     SLOW int linlen, origx;
  1423.     SLOW BUFFINDEX i;
  1424.  
  1425. #ifdef ULBD
  1426.     SLOW int ul, bd, useul, usebd;
  1427.  
  1428.     ul = bd = useul = usebd = FALSE;
  1429. #endif
  1430.  
  1431.     last_col_out = linptr = 0;
  1432.     origx = xoutcm;            /* save x so can get true linelen */
  1433.     for (i=chrptr; *(buff+i)!=ENDLINE && xoutcm <= 240; ++i)
  1434.       {
  1435. #ifdef NO_EXTEND_CHAR
  1436.     if ((*(buff+i) < ' ' && *(buff+i) >= 0) || (*(buff+i) & 0x80) )
  1437.         /* control character? */
  1438. #else
  1439.     if (*(buff+i)<' ' && *(buff+i) >= 0)    /* control character? */
  1440. #endif
  1441.       {
  1442.         if (*(buff+i) == TAB)
  1443.           {
  1444.         if (tabspc > 0)
  1445.           {
  1446.             do 
  1447.               {
  1448.             linout[linptr++] = ' ';    /* replace with blanks */
  1449.             ++xoutcm;
  1450.               }
  1451.             while ( ((xoutcm-1) % tabspc) != 0);
  1452.           }
  1453.         else
  1454.           {
  1455.             linout[linptr++] = '^';
  1456.             linout[linptr++] = 'I';
  1457.             xoutcm += 2;
  1458.           }
  1459.         continue;
  1460.           }
  1461.         else        /*  other control character */
  1462.           {
  1463.         linout[linptr++] = (*(buff+i) & 0x80) ? '~' : '^';
  1464.         ++xoutcm;
  1465.         if (xoutcm==tvcols && *(buff+i) != ENDLINE)
  1466.             continue;
  1467.  
  1468. /*  #$$$    ascii machines!!!! */
  1469.         tmp = *(buff+i);
  1470.         if ((tmp &= 0x7f) < ' ')    /* ok to mix extended, ctrl */
  1471.             tmp += '@';
  1472.         linout[linptr++]=tmp;
  1473.  
  1474. #ifdef ULBD
  1475.         if ( *(buff+i)==TOGUNDERLINE && cundlb[0] != 0)
  1476.           {
  1477.             if (ul)
  1478.               {
  1479.             strcopy(cundle,0,linout,&linptr);
  1480.             ul = FALSE;
  1481.               }
  1482.             else
  1483.               {
  1484.             strcopy(cundlb,0,linout,&linptr);
  1485.             useul = TRUE;
  1486.             ul = TRUE;
  1487.               }
  1488.           }
  1489.         if (*(buff+i) == TOGBOLD && cboldb[0] != 0)
  1490.           {
  1491.             if (bd)
  1492.               {
  1493.             strcopy(cbolde,0,linout,&linptr);
  1494.             bd = FALSE;
  1495.               }
  1496.             else
  1497.               {
  1498.             strcopy(cboldb,0,linout,&linptr);
  1499.             usebd = TRUE;
  1500.             bd = TRUE;
  1501.               }
  1502.           }
  1503. #endif          
  1504.           }
  1505.       } /*# end if control character */
  1506.     else 
  1507.       {
  1508.         linout[linptr++] = *(buff+i);
  1509.       }
  1510.     ++xoutcm;
  1511.       }
  1512.  
  1513.     if (*(buff+chrptr-1)==BEGLINE)        /* write whole line */
  1514.       {
  1515.     last_col_out = linlen = min(tvcols,linptr-leftmg+1);
  1516.     if (linlen > 0)
  1517.       {
  1518.         tvlout(&linout[leftmg-1],linlen);
  1519.       }
  1520.       }
  1521.     else
  1522.       {
  1523.     linlen = min(tvcols-origx+1,linptr);
  1524.     last_col_out = linlen + origx - 1;
  1525.     if (linlen > 0)
  1526.         tvlout(linout,linlen);
  1527.       }
  1528. #ifdef ULBD
  1529.     if (useul)
  1530.     sendcs(cundle);
  1531.     if (usebd)
  1532.     sendcs(cbolde);
  1533. #endif
  1534.     
  1535.   }
  1536.  
  1537. /* =============================>>> TVLOUT <<<============================= */
  1538.   tvlout(chrbuf,lenbuf)
  1539.   char chrbuf[];
  1540.   int lenbuf;
  1541.   {  /* tvlout - intercepts tvcout calls to use line I/O */
  1542.  
  1543.     if (!(echof && !bakflg))
  1544.     return;
  1545.     ttwtln(chrbuf,lenbuf);    /* write out whole line */
  1546.   }
  1547.  
  1548. /* =============================>>> TVTYPE <<<============================= */
  1549.   tvtype(ibeg,icnt)
  1550.   int ibeg,icnt;
  1551.   { /* tytype - type icnt lines starting at lines[ibeg]
  1552.         no cr/lf on the last line */
  1553.  
  1554.     FAST int i,lim;
  1555.     SLOW BUFFINDEX start;
  1556.  
  1557.     if (!echof)
  1558.     return;
  1559.     xoutcm=tvx;
  1560.     lim = ibeg+icnt-1;
  1561.  
  1562.     for (i = ibeg ; i<=lim && i<nxtlin ; ++i)
  1563.       {
  1564.     start = (*(lines+i))+1;
  1565.     tvplin(start);    /* type out a line */
  1566.     xoutcm=1;
  1567.     if (celin[0] && last_col_out < tvcols)
  1568.         tvelin();    /* erase rest of line */
  1569.     if ( i != lim )
  1570.       {
  1571.         tvcout(CR);
  1572. #ifdef USELF
  1573.         tvcout(LF);
  1574. #endif
  1575.       }
  1576.       }
  1577. #ifdef SCR_BUF
  1578.     ttflush();
  1579. #endif
  1580.   }
  1581.  
  1582. /* =============================>>> SCRPRINT <<<============================= */
  1583.   scrprint()
  1584.   {    /* print screen on printer */
  1585.  
  1586. #ifndef UNIX
  1587.  
  1588.    SLOW beg, cnt;
  1589.  
  1590.     tvclr();        /* clear screen first */
  1591.     finddl(&beg, &cnt);
  1592.     useprint = TRUE;    /* enable printing */
  1593.     tvtype(beg,cnt);    /* and display/print */
  1594.     printc(CR);        /* force closing cr/lf */
  1595. #ifdef USELF
  1596.     printc(LF);
  1597. #endif
  1598.     useprint = FALSE;
  1599. #endif
  1600.     verify(1);        /* reset screen */
  1601.   }
  1602.  
  1603. /* =============================>>> VERIFY <<<============================= */
  1604.   verify(knt)
  1605.   int knt;
  1606.   { /* verify - rewrite the screen or type current line with cursor */
  1607.  
  1608.     SLOW int xf;
  1609.  
  1610.     if (ttymode)
  1611.     ttyverify(knt);
  1612.     else
  1613.       {
  1614.     newscr();
  1615.     xf = findx();
  1616.     tvxy(xf,tvy);    /* reset cursor to current position */
  1617.       }
  1618. #ifdef SCR_BUF
  1619.     ttflush();
  1620. #endif
  1621.   }
  1622.  
  1623. /* =============================>>> CSRCMD <<<============================= */
  1624.   csrcmd()
  1625.   {
  1626.     ins_mode = FALSE;        /* let world know in command mode */
  1627.     sendcs(ccsrcm);
  1628. #ifdef SCR_BUF
  1629.     ttflush();
  1630. #endif
  1631.   }
  1632.  
  1633. /* =============================>>> CSRINS <<<============================= */
  1634.   csrins()
  1635.   {
  1636.     SLOW int oldx,oldy,oldxot;
  1637.  
  1638.     ins_mode = TRUE;        /* in insert mode */
  1639.     sendcs(ccsrin);
  1640.  
  1641.     if (tvdlin != tvhardlines)
  1642.       {
  1643.         oldx = tvx; oldy = tvy; oldxot = xoutcm;
  1644.     tvmsg("### Insert Mode ###",FALSE);
  1645.     tvxy(oldx,oldy);
  1646.     xoutcm = oldxot;
  1647.       }
  1648. #ifdef SCR_BUF
  1649.     ttflush();
  1650. #endif
  1651.   }
  1652.   
  1653. /* **************************************************************************
  1654.  
  1655.    tv screen primitives follow
  1656.  
  1657. *************************************************************************** */
  1658.  
  1659. /* =============================>>> TVBOTB <<<============================= */
  1660.   tvbotb(n)
  1661.   int n;
  1662.   {  /* tvbotb - make n blank lines at the bottom of the screen */
  1663.  
  1664.     FAST int i,j;
  1665.  
  1666. /*  All versions  control sequences */
  1667.  
  1668.     if (n >= tvlins)
  1669.       {
  1670.     tvclr();
  1671.       }
  1672.     else 
  1673.       {
  1674.     tvxy(1,tvhardlines);    /* go to real last line */
  1675.     for (i = 1 ; i <= n ; ++i)    /* and write n blank lines */
  1676.       {
  1677.         sendcs(cbotb);
  1678.         if (dsp_mem)
  1679.         tvelin();    /* might scroll non-blank line */
  1680.       }
  1681.     j=tvlins-n+1;    /* home to virtual last line */
  1682.     tvxy(1,j);    /* position at first new blank line */
  1683.       }
  1684. #ifdef SCR_BUF
  1685.     ttflush();
  1686. #endif
  1687.   }
  1688.  
  1689. /* =============================>>> TVCLR  <<<============================= */
  1690.   tvclr()
  1691.   {  /* tvclr - clear the entire screen and home */
  1692.  
  1693.     if (cclears[0])
  1694.     sendcs(cclears);
  1695.     else
  1696.       {
  1697.     tvxy(1,1);
  1698.     tvescr();
  1699.       }
  1700. #ifdef SCR_BUF
  1701.     ttflush();
  1702. #endif
  1703.   }
  1704.  
  1705. /* =============================>>> TVCOUT <<<============================= */
  1706.   tvcout(chr)
  1707.   char chr;
  1708.   {  /* tvcout - send one character to the terminal */
  1709.  
  1710.     if (echof && !bakflg)
  1711.     ttwt(chr);
  1712.   }
  1713.  
  1714. /* =============================>>> TVELIN <<<============================= */
  1715.   tvelin()
  1716.   {  /* tvelin - erase the rest of the current line */
  1717.  
  1718.     sendcs(celin);
  1719.   }
  1720.  
  1721. /* =============================>>> TVESCR <<<============================= */
  1722.   tvescr()
  1723.   {  /* tvescr - erase from current cursor position to end of screen */
  1724.  
  1725.     SLOW int oldx,oldy;
  1726.     FAST int i;
  1727.  
  1728.     if (cescr[0])
  1729.     sendcs(cescr);
  1730.     else
  1731.       {
  1732.     oldx = tvx ; oldy = tvy ;
  1733.     tvelin();
  1734.     for (i = oldy+1 ; i <= tvhardlines ; ++i)
  1735.       {
  1736.         tvxy(1,i);
  1737.         tvelin();
  1738.       }
  1739.     tvxy(oldx,oldy);
  1740.       }
  1741.   }
  1742.  
  1743. /* =============================>>> TVINSL <<<============================= */
  1744.   tvinsl()
  1745.   {  /* tvinsl - insert line, handle virtual screen size */
  1746.  
  1747.     SLOW int oldx,oldy;
  1748.     FAST int i;
  1749.  
  1750.     oldx = tvx ; oldy = tvy ;
  1751.     sendcs(ciline);
  1752.     if (tvlins != tvhardlines)
  1753.       {
  1754.     tvxy(1,tvlins+1);    /* kill scrolled down line */
  1755.     tvelin();
  1756.     tvxy(oldx,oldy);
  1757.       }
  1758.   }
  1759.  
  1760. /* =============================>>> TVTOPB <<<============================= */
  1761.   tvtopb(n)
  1762.   int n;
  1763.   {  /* tvtopb - create n blank lines at the top of the screen */
  1764.  
  1765.     FAST int i;
  1766.  
  1767.     if (! ctopb[0])
  1768.     return;
  1769.     tvxy(1,1);        /* home first */
  1770.     if ( n >= tvlins)
  1771.     tvescr();    /* simply erase the screen */
  1772.     else
  1773.       {
  1774.     for (i = 1 ; i <= n ; ++i)
  1775.       {
  1776.         sendcs(ctopb);
  1777.         if (dsp_mem)        /* non blank line might be scrolled */
  1778.         tvelin();
  1779.       }
  1780.     if (tvlins != tvhardlines)
  1781.       {
  1782.         tvxy(1,tvlins+1);    /* kill scrolled down line */
  1783.         tvelin();
  1784.         tvxy(1,1);
  1785.       }
  1786.       }
  1787.   }
  1788.  
  1789. /* =============================>>> TVXY   <<<============================= */
  1790.   tvxy(ix,iy)
  1791.   int ix,iy;
  1792.   {  /* tvxy - position cursor at position x,y 
  1793.         x=0 is left most column
  1794.         y=0 is top most line    */
  1795.  
  1796. #ifdef TERMCAP            /* TERMCAP different */
  1797.  
  1798.     tvx=ix;
  1799.     tvy=iy;
  1800.     tcapxy(ix,iy);        /* call termcap version of xy */
  1801.  
  1802. #else                /* generic version of tvxy */
  1803.  
  1804.     SLOW int x,y, coord1, coord2;
  1805.     FAST int i;
  1806.     SLOW char chrrep[4];
  1807.  
  1808.     x = min(ix+addx,tvcols+addx);    /* column is addx */
  1809.     y = iy+addy;            /* same for row */
  1810.     tvx = ix;
  1811.     tvy = iy;
  1812.  
  1813.     sendcs(cxybeg);        /* opening control sequence */
  1814.     if (cxy1st == 'l')
  1815.       {
  1816.     coord1 = y ; coord2 = x;
  1817.       }
  1818.     else
  1819.       {
  1820.     coord1 = x ; coord2 = y;
  1821.       }
  1822.  
  1823.     if (cxychr)
  1824.       {
  1825.     itoa(coord1,chrrep);
  1826.     sendcs(chrrep);
  1827.       }
  1828.     else
  1829.     tvcout(coord1);
  1830.  
  1831.     sendcs(cxymid);        /* middle control sequence */
  1832.  
  1833.     if (cxychr)
  1834.       {
  1835.     itoa(coord2,chrrep);
  1836.     sendcs(chrrep);
  1837.       }
  1838.     else
  1839.     tvcout(coord2);
  1840.  
  1841.     sendcs(cxyend);        /* send terminating sequence */
  1842.  
  1843. #endif                /* end of gerneric version */
  1844.   }
  1845.  
  1846. /* =============================>>> SENDCS <<<============================= */
  1847.   sendcs(cs)
  1848.   char cs[];
  1849.   {    /* send a control sequencs to terminal */
  1850.  
  1851.     FAST int i;
  1852.  
  1853. #ifndef UNIX
  1854.  
  1855.     for (i = 0 ; cs[i] ; ++i)
  1856.     tvcout(cs[i]);
  1857. #else                /* unix version */
  1858.  
  1859. #ifdef TERMCAP            /* termcap uses special output */
  1860.     tcapcs(cs);            /* send control string to termcap */
  1861. #else
  1862.     i = strlen(cs);
  1863.     tvlout(cs,i);
  1864. #endif                /* terminal specific unix version */
  1865.  
  1866. #endif                /* end of unix version */
  1867.   
  1868.   }
  1869.  
  1870. /* =============================>>> GKBD   <<<============================= */
  1871.   gkbd(chr)
  1872.   char *chr;
  1873.   {  /* gkbd - get one character from the keyboard */
  1874.  
  1875. #ifdef VB
  1876.     if (!bakflg)
  1877.       {
  1878. #endif
  1879.     do 
  1880.       {
  1881.         *chr = ttrd();    /* read only if non-backup version */
  1882.       }
  1883.     while (*chr == 0);    /* ignore EOS character */
  1884. #ifdef VB
  1885.       }
  1886.     else
  1887.     getbak(chr);
  1888.     putbak(*chr);    /* save to backup file */
  1889. #endif
  1890.   }
  1891.  
  1892. #ifndef UNIX
  1893. /* =============================>>> TTWTLN <<<============================= */
  1894.   ttwtln(chrbuf,len)
  1895.   char chrbuf[];
  1896.   int len;
  1897.   {  /*  write one line to terminal, generic version, unix uses its own */
  1898.  
  1899.     FAST int i;
  1900.  
  1901. #ifndef GEMDOS
  1902.     for (i = 0 ; i < len ; i++)
  1903.     ttwt(chrbuf[i]);
  1904. #else
  1905.     char oldc;
  1906.     oldc = chrbuf[len];        /* I'm not sure just who calls ttwtln */
  1907.     chrbuf[len] = 0;        /* so be safe, be sure 0 terminated */
  1908.     gemdos(9,chrbuf);        /* gemdos write line to terminal */
  1909.     chrbuf[len] = oldc;        /* restore, just in case */
  1910. #endif
  1911.   } 
  1912. #endif
  1913.  
  1914. #ifdef OSCPM
  1915. /* ===========================>>> DISPCH <<<============================== */
  1916.   dispch(chr)
  1917.   char chr;
  1918.   {
  1919.  
  1920.     bdos(2,chr);    /* cp/m, ms-dos version */
  1921.   }
  1922. /* =============================>>> USER_1 <<<============================= */
  1923.   user_1(knt)
  1924.   int knt;
  1925.   {
  1926.     return (TRUE);
  1927.   }
  1928.  
  1929. /* =============================>>> USER_2 <<<============================= */
  1930.   user_2(knt)
  1931.   int knt;
  1932.   {
  1933.     return (TRUE);
  1934.   }
  1935. #endif
  1936.  
  1937. #ifdef MSDOS
  1938. #ifndef IBMPC
  1939. /* ===========================>>> DISPCH <<<============================== */
  1940.   dispch(chr)
  1941.   char chr;
  1942.   {
  1943.  
  1944.     bdos(2,chr);    /* cp/m, ms-dos version */
  1945.   }
  1946. #endif
  1947. /* =============================>>> USER_1 <<<============================= */
  1948.   user_1(knt)
  1949.   int knt;
  1950.   {
  1951.     return (TRUE);
  1952.   }
  1953.  
  1954. /* =============================>>> USER_2 <<<============================= */
  1955.   user_2(knt)
  1956.   int knt;
  1957.   {
  1958.     return (TRUE);
  1959.   }
  1960. #endif
  1961.  
  1962. #ifdef GEMDOS
  1963. /* ===========================>>> DISPCH <<<============================== */
  1964.   dispch(chr)
  1965.   char chr;
  1966.   {
  1967.  
  1968.     gemdos(2,chr);    /* cp/m, ms-dos version */
  1969.   }
  1970.  
  1971. /* =============================>>> USER_1 <<<============================= */
  1972.   user_1(knt)
  1973.   int knt;
  1974.   {
  1975.     /* toggle screen res */
  1976.  
  1977.     if (tvhardlines > 25)    /* already in 50 line mode */
  1978.       {
  1979.     if (rez25())        /* make sure not color */
  1980.       {
  1981.         tvhardlines = tvlins = 25;
  1982.         ddline = 13;
  1983.       }
  1984.       }
  1985.     else            /* in 25 line mode */
  1986.       {
  1987.     if (rez50())        /* make sure not color */
  1988.       {
  1989.         tvhardlines = tvlins = 50;
  1990.         ddline = 26;
  1991.       }
  1992.       }
  1993.  
  1994.     setdscrl();            /* reset scroll region */
  1995.     tvidefs();            /* reset defaults */
  1996.     verify(1);
  1997.     return (TRUE);
  1998.   }
  1999.  
  2000. /* =============================>>> USER_2 <<<============================= */
  2001.   user_2(knt)
  2002.   int knt;
  2003.   {
  2004.     return (TRUE);
  2005.   }
  2006. #endif
  2007. /* ------------------------ tvx_io.c ---------------------------- */
  2008.