home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume4 / tvx / part07 < prev    next >
Internet Message Format  |  1986-11-30  |  55KB

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