home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / tools / workbench / fv-220 / prompt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-18  |  20.3 KB  |  986 lines

  1. /* fv is a binary file editor written by Chris Hooper (cdh@mtu.edu)
  2.  *    on 6-2-91 and has gone through many revisions since then.
  3.  *      Much inspiration was given by Bill Moore, the first real user!
  4.  *
  5.  *   Author:  CHRISTOPHER D HOOPER
  6.  *
  7.  *   fv source Copyright (c) 1992 - 1998  Chris Hooper
  8.  *
  9.  *   Modification and redistribution is strictly prohibited.
  10.  *   Sale of this software above media cost is prohibited.
  11.  *
  12.  *   Except for above two restrictions, this software may be used for
  13.  *       any purpose, commercial or private.
  14.  *
  15.  *   Disclaimer:  This product is fit for no use, foreign or domestic.
  16.  *                Use implies knowledge you intend to destroy something.
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <curses.h>
  21. #include "main.h"
  22. #if !defined(Amiga) && !defined(OS9) && !defined(FreeBSD)
  23. #    include <malloc.h>
  24. #endif
  25. #if defined(Win32) || defined(Solaris1)
  26. char *strdup();
  27. #else
  28. #include <strings.h>
  29. #endif
  30.  
  31. #include "screen.h"
  32. #include "io.h"
  33.  
  34. #ifdef LINT
  35. #    include "lint.h"
  36. #endif
  37.  
  38. #ifdef OS9
  39. char *strdup();
  40. #endif
  41.  
  42. extern ulong cursor_address;
  43. extern ulong inbuf_size;
  44. extern int status_line;
  45. extern char *NONWORD;
  46.  
  47. #define MARKS   64
  48.  
  49. char    markchar[MARKS];
  50. int    markpos[MARKS];
  51. int    marks = 0;
  52.  
  53. char *ubar = "_____________________________________________________________________________________________________________________________________________________________________________________________________";
  54.  
  55.  
  56. void delchars();
  57. void delword();
  58. void help_me_prompt();
  59. static char *xbytes();
  60. #ifdef COLON_MODE
  61. static int know_file();
  62. #endif
  63.  
  64. int save_changes(prompt_user)
  65. int prompt_user;
  66. {
  67.     char ch;
  68.     int saveprompt = 0;
  69.     int yes = 1;
  70.  
  71.     if (!dirty)
  72.         return(0);
  73.  
  74. #if !defined(Dynix) && !defined(Linux) && !defined(FreeBSD) && !defined(HPUX)
  75.     if (!noscreen)
  76.         raw();
  77. #endif
  78.  
  79.     if ((ronly | force_ronly) && !force_write) {
  80.         xmove(status_window, 0, COLS - 44);
  81.         xaddstr(status_window,
  82.                 "  File is read only, discard changes? (Y/n)");
  83.     } else {
  84.         saveprompt = 1;
  85.         xmove(status_window, 0, COLS - 22);
  86.         xaddstr(status_window, "  Save changes? (Y/n)");
  87.     }
  88.     xclrtoeol(status_window);
  89.     xrefresh(status_window);
  90.  
  91.     while (prompt_user) {
  92.         ch = get_key();
  93.         switch (ch) {
  94.         case 27:    /* ESC */
  95.         case 3:     /* ^C */
  96.         case 24:    /* ^X */
  97.             goto no_save;
  98.         case 'y':    /* Yes */
  99.         case 'Y':
  100.         case 13:    /* ^M */
  101.         case 10:    /* ^J */
  102.             prompt_user = 0;
  103.             break;
  104.         case 'n':    /* No */
  105.         case 'N':
  106.             yes = 0;
  107.             prompt_user = 0;
  108.             break;
  109.         }
  110.     }
  111.  
  112.     if (yes && saveprompt)
  113.         buf_write(daddr, buffer, inbuf_size);
  114.  
  115.     if (yes || saveprompt)
  116.         dirty = 0;
  117.  
  118.     no_save:
  119.     xmove(status_window, 0, COLS - 44);
  120.     xclrtoeol(status_window);
  121.     xrefresh(status_window);
  122.     status_mode();
  123.  
  124. #if !defined(Dynix) && !defined(Linux) && !defined(FreeBSD) && !defined(HPUX)
  125.     if (!noscreen) {
  126.         noraw();
  127. #    if defined(Solaris2)
  128.         cbreak();
  129. #    endif
  130.     }
  131. #endif
  132.     return(dirty);
  133. }
  134.  
  135. int confirm(message)
  136. char *message;
  137. {
  138.     char ch = ' ';
  139.  
  140.     xmove(status_window, 0, 20);
  141.     xclrtoeol(status_window);
  142.     xmove(status_window, 0, COLS - strlen(message) - 1);
  143.     xaddstr(status_window, message);
  144.     xrefresh(status_window);
  145.     while ((ch != 'y') && (ch != 'n')) {
  146.         ch = get_key();
  147.         if ((ch == 'Y') || (ch == '\015') || (ch == '\012'))
  148.             ch = 'y';
  149.         if (ch == 'N')
  150.             ch = 'n';
  151.     }
  152.     xmove(status_window, 0, COLS - 20);
  153.     xclrtoeol(status_window);
  154.     xrefresh(status_window);
  155.     if (ch == 'y')
  156.         return(1);
  157.     else
  158.         return(0);
  159. }
  160.  
  161. int get_jump(start)
  162. int start;
  163. {
  164.     char    ch = ' ';
  165.     char    str[12];
  166.     int    index;
  167.     static    int hexdec = -1;
  168.     ulong    retval;
  169.     WINDOW    *jump_window;
  170.  
  171.     if (hexdec == -1)
  172.         hexdec = wdismode;
  173.  
  174.     jump_window = xnewwin(1, 34, status_line, COLS - 34);
  175.     xmove(jump_window, 0, 0);
  176.     xclrtoeol(jump_window);
  177.     xaddstr(jump_window, "Go to address:");
  178.  
  179.     xrefresh(jump_window);
  180.  
  181.     str[0] = '\0';
  182.  
  183.     index = 0;
  184.     while (ch != 13) {    /* ^M */
  185.         xmove(jump_window, 0, 15);
  186.         xclrtoeol(jump_window);
  187.         xmove(jump_window, 0, 30);
  188.         if (hexdec)
  189.         xaddstr(jump_window, "Dec");
  190.         else
  191.         xaddstr(jump_window, "Hex");
  192.         xmove(jump_window, 0, 15);
  193.         xaddstr(jump_window, str);
  194.         xrefresh(jump_window);
  195.         ch = get_key();
  196.         switch (ch) {
  197.         case 8:        /* ^H - delete */
  198.         case 127:    /* ^? */
  199.             if (index > 0) {
  200.             index--;
  201.             str[index] = '\0';
  202.             }
  203.             break;
  204.         case 21:    /* ^U */
  205.             index = 0;
  206.             str[index] = '\0';
  207.             break;
  208.         case 'g':
  209.             ch = 13;
  210.             break;
  211.         case 9:        /* TAB */
  212.         case 't':
  213.         case 'T':
  214.             hexdec = !hexdec;
  215.  
  216.             if (index != 0) {
  217.             if (hexdec) {
  218.                 sscanf(str, "%x", (uint *) &retval);
  219.                 sprintf(str, "%d", (uint) retval);
  220.             } else {
  221.                 sscanf(str, "%d", (uint *) &retval);
  222.                 sprintf(str, "%x", (uint) retval);
  223.             }
  224.                 index = strlen(str);
  225.             }
  226.             break;
  227.         case 'q':    /* ^X */
  228.         case 24:    /* ^X */
  229.         case 27:    /* ESC */
  230.             index = 0;
  231.             ch = 13;
  232.             break;
  233.         default:
  234.             if ((ch >= 'A') && (ch <= 'F'))
  235.             ch += 'a' - 'A';
  236.  
  237.             if (hexdec) {    /* DEC */
  238.             if ((index < 10) && (ch >= '0') && (ch <= '9')) {
  239.                 str[index] = ch;
  240.                 index++;
  241.                 str[index] = '\0';
  242.             }
  243.             } else        /* HEX */
  244.             if ((index < 8) &&
  245.                     (((ch >= '0') && (ch <= '9')) ||
  246.                      ((ch >= 'a') && (ch <= 'f')))) {
  247.                 str[index] = ch;
  248.                 index++;
  249.                 str[index] = '\0';
  250.             }
  251.         }
  252.  
  253.     }
  254.     retval = start;
  255.  
  256.     if (index == 0)
  257.         return(-1);
  258.  
  259.     if (hexdec)
  260.         sscanf(str, "%d", (uint *) &retval);
  261.     else
  262.         sscanf(str, "%x", (uint *) &retval);
  263.  
  264.     if (retval == fend)
  265.         retval = fend - 1;
  266.  
  267.     xmove(jump_window, 0, 0);
  268.     xclrtoeol(jump_window);
  269.     xrefresh(jump_window);
  270.  
  271.     xdelwin(jump_window);
  272.     return(retval);
  273. }
  274.  
  275. int set_mark(addr)
  276. int addr;
  277. {
  278.     char ch;
  279.     int index;
  280.  
  281.     ch = get_key();
  282.     for (index = 0; index < MARKS; index++)
  283.         if (markchar[index] == ch) {
  284.         markpos[index] = addr;
  285.         return(0);
  286.         }
  287.     markchar[marks]    = ch;
  288.     markpos[marks]    = addr;
  289.     marks = (marks + 1) % MARKS;
  290.     return(0);
  291. }
  292.  
  293. int get_mark(start)
  294. int start;
  295. {
  296.     int    ch;
  297.     int    index;
  298.  
  299.     ch = get_key();
  300.     if ((ch == '\'') || (ch == '`'))
  301.         return(last_viewed);
  302.     for (index = 0; index < MARKS; index++)
  303.         if (markchar[index] == ch)
  304.         return(markpos[index]);
  305.     return(start);
  306. }
  307.  
  308.  
  309. int prompt_string(string, title)
  310. char *string;
  311. char *title;
  312. {
  313.     char    ch    = ' ';
  314.     char    ch2;
  315.     WINDOW    *jump_window;
  316.     char    *prevstr;
  317.     char    *origstr;
  318.     char    *temp;
  319.     int    index    = 0;
  320.     int    index2;
  321.     int    slen;
  322.     int    origlen;
  323. #ifdef STRICT_VI
  324.     int    emode = -1;
  325. #else
  326.     int    emode = 0;
  327. #endif
  328.     int    rc = 0;
  329.     int    titlelen = 0;
  330.  
  331.     /* must take into account that string length can be greater
  332.        then the maximum displayable area on the line. */
  333.  
  334.     /* original copy of string */
  335.     origstr    = (char *) malloc(EDIT_STRLEN);
  336.     if (origstr == NULL)
  337.         error_exit("edit_prompt_string: malloc failed");
  338.     strcpy(origstr, string);
  339.  
  340.     /* edit updated copy of string */
  341.     prevstr    = (char *) malloc(EDIT_STRLEN);
  342.     if (prevstr == NULL)
  343.         error_exit("edit_prompt_string: malloc failed");
  344.     strcpy(prevstr, string);
  345.  
  346.     origlen     = strlen(string);
  347.     titlelen = strlen(title);
  348.     index     = origlen - 1;
  349.  
  350.     jump_window = xnewwin(1, COLS - 31, status_line, 20);
  351.     xmove(jump_window, 0, 0);
  352.     xaddstr(jump_window, title);
  353.  
  354.     while ((ch != 13) && (ch != 4)) {    /* ^M or ^D */
  355.         slen = strlen(string);
  356.         xstandout(jump_window);
  357.         xmove(jump_window, 0, titlelen);
  358.         if (slen <= origlen) {
  359.             sprintf(out_string, "%s", string);
  360.             xaddstr(jump_window, out_string);
  361.             sprintf(out_string, "%.*s", origlen -
  362.             (int) strlen(out_string), ubar);
  363.             xaddstr(jump_window, out_string);
  364.             xstandend(jump_window);
  365.             sprintf(out_string, "%.*s", EDIT_STRLEN - origlen, ubar);
  366.             xaddstr(jump_window, out_string);
  367.         } else {
  368.             sprintf(out_string, "%.*s", origlen, string);
  369.             xaddstr(jump_window, out_string);
  370.             xstandend(jump_window);
  371.             sprintf(out_string, "%s", string + origlen);
  372.             xaddstr(jump_window, out_string);
  373.             sprintf(out_string, "%.*s", EDIT_STRLEN - slen, ubar);
  374.             xaddstr(jump_window, out_string);
  375.         }
  376.         xmove(jump_window, 0, index + titlelen);
  377.         xrefresh(jump_window);
  378.  
  379.         ch = get_key();
  380.  
  381.         switch (ch) {
  382.             case 2:     /* ^B */
  383.                 index = 0;
  384.                 break;
  385.             case 5:     /* ^E */
  386.                 index = slen + emode;
  387.                 break;
  388.             case 8:     /* ^H - delete */
  389.             case 127:    /* ^? */
  390. #ifdef STRICT_VI
  391.                 if (emode) {
  392.                     if (index > 0)
  393.                         index--;
  394.                     break;
  395.                 }
  396. #endif
  397.                 strcpy(prevstr, string);
  398.                 if (index > 0) {
  399.                     index--;
  400.                     for (index2 = index; index2 < slen; index2++)
  401.                             string[index2] = string[index2 + 1];
  402.                 }
  403.                 break;
  404.             case ' ':
  405.                 if (index > 0)
  406.                     index--;
  407.                 break;
  408.             case 12:     /* ^L */
  409.                 if (index < slen)
  410.                     index++;
  411.                 break;
  412.             case 10:    /* ^J */
  413.             ch = 13;
  414.             case 13:    /* ^M */
  415.             case 4:     /* ^D */
  416.                 break;
  417.             case 21:    /* ^U */
  418.                 strcpy(prevstr, string);
  419.                 index = 0;
  420.             string[index] = '\0';
  421.             xmove(jump_window, 0, titlelen);
  422.             xclrtoeol(jump_window);
  423.             break;
  424.         case 24:    /* ^X */
  425.         case 3:        /* ^C */
  426.             goto quit;
  427.             break;
  428.         case 27:    /* ESC */
  429.             emode = -1;
  430.             if (index > slen - 1)
  431.             index--;
  432.             break;
  433.         default:
  434.             if (emode) {
  435.             switch(ch) {
  436.                 case 'a':
  437.                 strcpy(prevstr, string);
  438.                 emode = 0;
  439.                 if (index < slen)
  440.                     index++;
  441.                 break;
  442.                 case 'A':
  443.                 strcpy(prevstr, string);
  444.                 emode = 0;
  445.                 index = slen;
  446.                 break;
  447.                 case 'c':
  448.                 emode = 0;
  449.                 case 'd':
  450.                 strcpy(prevstr, string);
  451.                 ch2 = get_key();
  452.                 if (ch2 == 'w')
  453.                     delword(string + index, slen);
  454.                 else if (ch2 == 't') {
  455.                     ch2 = get_key();
  456.                     for (index2 = index + 1; index2 < slen;
  457.                     index2++)
  458.                     if (string[index2] == ch2) {
  459.                         delchars(string + index, index2 -
  460.                              index, slen);
  461.                         break;
  462.                     }
  463.                 }
  464.                 if (index > ((int) strlen(string) - 1))
  465.                     index = strlen(string) - 1;
  466.                 break;
  467.                 case 'H':
  468.                 case '?':
  469.                 help_me(3);
  470.                 xtouchwin(jump_window);
  471.                 xtouchwin(main_window);
  472.                 xrefresh(jump_window);
  473.                 xrefresh(main_window);
  474.                 break;
  475.                 case 'h':
  476.                 case 'k':
  477.                 case 2:    /* ^B */
  478.                 if (index > 0)
  479.                     index--;
  480.                 break;
  481.                 case 'I':
  482.                 index = 0;
  483.                 case 'i':
  484.                 strcpy(prevstr, string);
  485.                 emode = 0;
  486.                 break;
  487.                 case 'j':
  488.                 case 'l':
  489.                 case ' ':
  490.                 case 6:    /* ^F */
  491.                 if (index < slen - 1)
  492.                     index++;
  493.                 break;
  494.                 case 'r':
  495.                 case 's':
  496.                 strcpy(prevstr, string);
  497.                 string[index] = get_key();
  498.                 break;
  499.                 case 't':
  500.                 case 'T':
  501.                 ch2 = get_key();
  502.                 for (index2 = index + 1; index2 < slen;index2++)
  503.                     if (string[index2] == ch2) {
  504.                         index = index2 - 1;
  505.                         break;
  506.                     }
  507.                 break;
  508.                 case 'u':
  509.                 temp    = prevstr;
  510.                 prevstr    = string;
  511.                 string    = temp;
  512.                 break;
  513.                 case 'U':
  514.                 temp    = prevstr;
  515.                 prevstr    = string;
  516.                 string    = temp;
  517.                 strcpy(string, origstr);
  518.                 break;
  519.                 case 'x':
  520.                 strcpy(prevstr, string);
  521.                 for (index2 = index; index2 < slen;index2++)
  522.                     string[index2] = string[index2 + 1];
  523.                 if (index == slen - 1)
  524.                     index--;
  525.                 break;
  526.                 case '0':
  527.                 case '^':
  528.                 index = 0;
  529.                 break;
  530.                 case '$':
  531.                 index = slen;
  532.                 break;
  533.             }
  534.             break;
  535.             }
  536.             if (ch == 22)    /* ^V */
  537.             ch = get_key();
  538.             if (slen == EDIT_STRLEN)
  539.             break;
  540.             for (index2 = slen; index2 > index; index2--)
  541.             string[index2] = string[index2 - 1];
  542.             string[slen + 1] = '\0';
  543.             string[index++] = ch;
  544.             ch = ' ';
  545.             break;
  546.         }
  547.     }
  548.  
  549.     if ((ch == '\015') || (ch == '\012'))
  550.         rc = 2;
  551.     else
  552.         rc = 1;
  553.  
  554.     quit:
  555.  
  556.     xmove(jump_window, 0, 0);
  557.     xclrtoeol(jump_window);
  558.     xrefresh(jump_window);
  559.  
  560.     xdelwin(jump_window);
  561.  
  562.     return(rc);
  563. }
  564.  
  565. void delword(string, slen)
  566. char    *string;
  567. int    slen;
  568. {
  569.     int index;
  570.  
  571.     for (index = 1; index < slen; index++)
  572.         if (strchr(NONWORD, string[index]))
  573.         break;
  574.     delchars(string, index, slen);
  575. }
  576.  
  577. void delchars(string, index, slen)
  578. char    *string;
  579. int    index;
  580. int    slen;
  581. {
  582.     int index2;
  583.  
  584.     for (index2 = index; index2 <= slen; index2++)
  585.         string[index2 - index] = string[index2];
  586. }
  587.  
  588. int write_file(first, last, type)
  589. int first;
  590. int last;
  591. int type;
  592. {
  593.     char    name[128];
  594.     char    tmp[128];
  595.     char    *buf;
  596.     ulong    size;
  597.     FILE    *out_file;
  598.  
  599.     size = last - first;
  600.     if (size > 65536) {
  601.         if (wdismode)
  602.         sprintf(tmp, "Write %d-%d, %s?  (Y/n)",
  603.             first, last, xbytes(size));
  604.         else
  605.         sprintf(tmp, "Write %08x-%08x, %s?  (Y/n)",
  606.             first, last, xbytes(size));
  607.         if (!confirm(tmp))
  608.         return(0);
  609.     }
  610.     
  611.     top:
  612.     strcpy(name, "output");
  613.  
  614.     buf = (char *) malloc(size);
  615.     if (buf == NULL)
  616.         error_exit("write_file: malloc failed");
  617.     if (prompt_string(name, "Filename: ")) {
  618.         if (type) {
  619. #ifdef Win32
  620.         out_file = fopen(name, "ab+");
  621.         if (out_file == NULL)
  622.             out_file = fopen(name, "wb");
  623.         } else
  624.         out_file = fopen(name, "wb");
  625. #else
  626.         out_file = fopen(name, "a+");
  627.         if (out_file == NULL)
  628.             out_file = fopen(name, "w");
  629.         } else
  630.         out_file = fopen(name, "w");
  631. #endif
  632.         if (out_file == NULL) {
  633.         sprintf(tmp, "Unable to open %s for writing.  Another?", name);
  634.         if (confirm(tmp))
  635.             goto top;
  636.         else {
  637.             xmove(status_window, 0, 20);
  638.             xclrtoeol(status_window);
  639.             xrefresh(status_window);
  640.             return(0);
  641.         }
  642.         }
  643.         if (buf_read(first, buf, size) == 0)
  644.         fwrite(buf, size, 1, out_file);
  645.         fclose(out_file);
  646.     }
  647.     xmove(status_window, 0, 20);
  648.     if (wdismode)
  649.         sprintf(tmp, "Wrote %d-%d, %s.", first, last, xbytes(size));
  650.     else
  651.         sprintf(tmp, "Wrote %08x-%08x, %s.", first, last, xbytes(size));
  652.     xaddstr(status_window, tmp);
  653.  
  654.     xclrtoeol(status_window);
  655.     xrefresh(status_window);
  656.     return(1);
  657. }
  658.  
  659. int write_mark(start, type)
  660. int start;
  661. int type;
  662. {
  663.     int    ch;
  664.     int    temp;
  665.     int    end = 0;
  666.  
  667.     if (MARKS == 0) {
  668.         xmove(status_window, 0, 20);
  669.         xaddstr(status_window, "No marks set, press return.");
  670.         goto mark_error;
  671.     }
  672.     leaveok(status_window, FALSE);
  673.     xmove(status_window, 0, 20);
  674.     xaddstr(status_window, "pick end mark ");
  675.     xclrtoeol(status_window);
  676.     xrefresh(status_window);
  677.  
  678.     if ((ch = get_key()) == '\'') {
  679.         xmove(status_window, 0, 20);
  680.         xaddstr(status_window, "pick end mark \'");
  681.         xrefresh(status_window);
  682.         ch = get_key();
  683.     }
  684.     leaveok(status_window, TRUE);
  685.  
  686.     switch (ch) {
  687.         case 27:    /* ESC */
  688.         case 10:    /* LF */
  689.         case 13:    /* CR */
  690.             xmove(status_window, 0, 20);
  691.             xclrtoeol(status_window);
  692.             xrefresh(status_window);
  693.             return(1);    
  694.     }
  695.  
  696.     for (temp = 0; temp < MARKS; temp++)
  697.         if (markchar[temp] == ch) {
  698.             end = markpos[temp];
  699.             break;
  700.         }
  701.  
  702.     if (temp == MARKS) {
  703.         xmove(status_window, 0, 20);
  704.         xaddstr(status_window, "Mark ");
  705.         if (ch < ' ') {
  706.             xaddch(status_window, '^');
  707.             xaddch(status_window, ch + '@');
  708.         } else
  709.             xaddch(status_window, ch);
  710.             xaddstr(status_window, " unknown, press return.");
  711.         goto mark_error;
  712.     }
  713.     
  714.     if (start > end) {
  715.         write_file(end, start, type);
  716.         return(0);
  717.     } else if (start < end) {
  718.         write_file(start, end, type);
  719.         return(0);
  720.     }
  721.  
  722.     xmove(status_window, 0, 20);
  723.     xaddstr(status_window, "Can't write 0 bytes, press return.");
  724.  
  725.     mark_error:
  726.     xclrtoeol(status_window);
  727.     xrefresh(status_window);
  728.     while ((ch = get_key()) != EOF)
  729.         if ((ch == 13) || (ch == 10))    /* ^M or ^J */
  730.             break;
  731.     xmove(status_window, 0, 20);
  732.     xclrtoeol(status_window);
  733.     xrefresh(status_window);
  734.     return(1);
  735. }
  736.  
  737. static char *xbytes_val[] = {
  738.     "", "K", "M", "G", "T"
  739. };
  740.  
  741. static char *xbytes(value)
  742. ulong value;
  743. {
  744.     static char buf[32];
  745.     int mul = 0;
  746.     while ((value > 65535) || ((mul > 1) && (value > 8192))) {
  747.         value >>= 10;
  748.         mul++;
  749.     }
  750.     sprintf(buf, "%d %sbytes", (uint) value, xbytes_val[mul]);
  751.  
  752.     return(buf);
  753. }
  754.  
  755. #ifdef COLON_MODE
  756. int colon_mode()
  757. {
  758.     char ch;
  759.     char buf[128];
  760.     int index = 0;
  761.     int rc = 0;
  762.     int temp;
  763.     char *ptr;
  764.     char *ptr2;
  765.  
  766.     leaveok(status_window, FALSE);
  767.     xmove(status_window, 0, 0);
  768.     xaddch(status_window, ':');
  769.     xclrtoeol(status_window);
  770.     xrefresh(status_window);
  771.  
  772.     buf[0] = '\0';
  773.     do {
  774.         xmove(status_window, 0, 1);
  775.         xaddstr(status_window, buf);
  776.         xrefresh(status_window);
  777.         ch = get_key();
  778.         switch (ch) {
  779.         case 13:    /* ^M */
  780.         case 10:    /* ^J */
  781.             ch = 13;
  782.             break;
  783.         case 8:        /* ^H */
  784.         case 127:    /* ^? */
  785.             if (index > 0) {
  786.             xmove(status_window, 0, index);
  787.             xclrtoeol(status_window);
  788.             buf[--index] = '\0';
  789.             } else
  790.             ch = 13;
  791.             break;
  792.         default:
  793.             buf[index++] = ch;
  794.             buf[index] = '\0';
  795.         }
  796.     } while (ch != 13);     /* ^M */
  797.  
  798.     leaveok(status_window, TRUE);
  799.     xmove(status_window, 0, 0);
  800.     xclrtoeol(status_window);
  801.     xrefresh(status_window);
  802.  
  803.     switch (buf[0]) {
  804.         case '\0':
  805.         break;
  806.         case 'h':
  807.         if ((buf[1] != '\0') &&
  808.             ((buf[1] != 'e') || (buf[2] != 'l') || (buf[3] != 'p')))
  809.             goto bad_command;
  810.         case '?':
  811.         help_me(5);
  812.         xtouchwin(main_window);
  813.         xrefresh(main_window);
  814.         break;
  815.         case 'e':
  816.         if ((buf[1] != '\0') && (buf[1] != '!') && (buf[1] != ' ') &&
  817.             ((buf[1] != 'd') || (buf[2] != 'i') || (buf[3] != 't')))
  818.             goto bad_command;
  819.  
  820.         for (ptr = buf; *ptr != '\0'; ptr++)
  821.             if (*ptr == ' ') {
  822.             ptr++;
  823.             break;
  824.             }
  825.  
  826.         index = filenum;
  827.         for (ptr2 = ptr; *ptr != '\0'; ptr++)
  828.             if ((*ptr == ' ') || (*ptr == '\t')) {
  829.             *ptr = '\0';
  830.             if (index == filenum)
  831.                 index = know_file(ptr2);
  832.             else
  833.                 know_file(ptr2);
  834.             ptr2 = ptr + 1;
  835.             }
  836.  
  837.         if (*ptr2 != '\0')
  838.             if (index == filenum)
  839.             index = know_file(ptr2);
  840.             else
  841.             know_file(ptr2);
  842.  
  843.         temp = index;
  844.         if ((buf[1] == '!') || (buf[4] == '!'))
  845.             dirty = 0;
  846.  
  847.         goto new_file;
  848.         
  849.         break;
  850.         case 'n':
  851.         if ((buf[1] != '\0') &&
  852.             ((buf[1] != 'e') || (buf[2] != 'x') || (buf[3] != 't')))
  853.             goto bad_command;
  854.  
  855.         temp = filenum + 1;
  856.         if (temp == filenames) {
  857.             xmove(status_window, 0, 20);
  858.             xaddstr(status_window, "No more files to edit");
  859.             xrefresh(status_window);
  860.             break;
  861.         }
  862.  
  863.         new_file:
  864.         if (save_changes(1))
  865.             break;
  866.  
  867.         close_file();
  868.         view_address = 0;
  869.         cursor_address = 0;
  870.         daddr = -1;
  871.         xmove(status_window, 0, 0);
  872.         xclrtoeol(status_window);
  873.         if (open_file(temp))
  874.             filenum = temp;
  875.         else if (open_file(filenum) == 0) {
  876.             sprintf(out_string, "cannot reopen %s!\n",
  877.                     filename[filenum]);
  878.             error_exit(out_string);
  879.         }
  880.         rc = 1;
  881.         break;
  882.         case 'p':
  883.         if ((buf[1] != '\0') &&
  884.             ((buf[1] != 'r') || (buf[2] != 'e')))
  885.             goto bad_command;
  886.  
  887.         temp = filenum - 1;
  888.         if (temp == -1) {
  889.             xmove(status_window, 0, 20);
  890.             xaddstr(status_window, "No previous file to edit");
  891.             xrefresh(status_window);
  892.             break;
  893.         }
  894.         goto new_file;
  895.         case 'q':
  896.         if ((buf[1] != '\0') && (buf[1] != '!') &&
  897.             ((buf[1] != 'u') || (buf[2] != 'i') || (buf[3] != 't')))
  898.             goto bad_command;
  899.  
  900.         /* if not q! then check if dirty, then if more files */
  901.         if ((buf[1] != '!') && (buf[4] != '!')) {
  902.             if (dirty) {
  903.             xmove(status_window, 0, 20);
  904.             xaddstr(status_window, "No write since last change");
  905.             xrefresh(status_window);
  906.             break;
  907.             }
  908.             if (filenum != filenames - 1) {
  909.             char buf[32];
  910.             if (filenum == filenames - 2)
  911.                 sprintf(buf, "There is one more file to edit.");
  912.             else
  913.                 sprintf(buf, "There are %d more files to edit.",
  914.                         filenames - filenum - 1);
  915.             xmove(status_window, 0, 20);
  916.             xaddstr(status_window, buf);
  917.             xrefresh(status_window);
  918.             break;
  919.             }
  920.         }
  921.         dirty = 0;
  922.         rc = -1;
  923.         break;
  924.         case 'r':
  925.         if ((buf[1] != '\0') &&
  926.             ((buf[1] != 'e') || (buf[2] != 'w')))
  927.             goto bad_command;
  928.  
  929.         temp = 0;
  930.         goto new_file;
  931.         case 'w':
  932.         if ((buf[1] != '\0') &&
  933.             ((buf[1] != 'r') || (buf[2] != 'i') ||
  934.              (buf[3] != 't') || (buf[4] != 'e')) &&
  935.                     ((buf[1] != 'q') || (buf[2] != '\0')))
  936.             goto bad_command;
  937.  
  938.         if (buf[1] == 'q') {
  939.             save_changes(0);
  940.             rc = -1;
  941.             break;
  942.         }
  943.         dirty = 1;
  944.         save_changes(0);
  945.         xmove(status_window, 0, 20);
  946.         xaddstr(status_window, "Updated ");
  947.         xaddstr(status_window, filename[filenum]);
  948.         xrefresh(status_window);
  949.         break;
  950.         case 'x':
  951.         if ((buf[1] != '\0') &&
  952.             ((buf[1] != 'i') || (buf[2] != 't')))
  953.             goto bad_command;
  954.  
  955.         if (save_changes(0))
  956.             rc = 0;
  957.         else
  958.             rc = -1;
  959.         break;
  960.         default:
  961.         bad_command:
  962.         xmove(status_window, 0, 20);
  963.         xaddstr(status_window, "Unknown command ");
  964.         xaddstr(status_window, buf);
  965.         xrefresh(status_window);
  966.         break;
  967.     }
  968.  
  969.     return(rc);
  970. }
  971.  
  972. static int know_file(name)
  973. char *name;
  974. {
  975.     int index;
  976.  
  977.     for (index = 0; index < filenames; index++)
  978.     if (!strcmp(filename[index], name))
  979.         return(index);
  980.  
  981.     filename[filenames] = strdup(name);
  982.  
  983.     return(filenames++);
  984. }
  985. #endif /* COLON_MODE */
  986.