home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume16 / fep / part01 next >
Text File  |  1988-11-09  |  35KB  |  1,730 lines

  1. Subject:  v16i061:  Front end editor program, Part01/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Kazumasa Utashiro <kddlab!sra.junet!utashiro>
  7. Posting-number: Volume 16, Issue 61
  8. Archive-name: fep/part01
  9.  
  10. Dear moderator,
  11.  
  12. FEP is a general purpose front end for any line-oriented command on
  13. UNIX. This command was developed on Berkeley UNIX, but will probably
  14. run on most UNIX system which have pseudo tty and the select system
  15. call.
  16.  
  17.             Kazumasa Utashiro
  18.             Software Research Associates, Inc.
  19.             1-1-1 Hirakawa-cho, Chiyoda-ku, Tokyo 102, Japan
  20.                 UUCP:    kddlab!srava.sra.junet!utashiro
  21.                 ARPA:    utashiro%sra.junet@uunet.uu.net
  22.                 JUNET:    utashiro@sra.junet
  23.  
  24. #!/bin/sh
  25. # to extract, remove the header and type "sh filename"
  26. if `test ! -s ./fep_funcs.c`
  27. then
  28. echo "writing ./fep_funcs.c"
  29. cat > ./fep_funcs.c << '\End\Of\File\'
  30. /*    Copyright (c) 1987, 1988 by Software Research Associates, Inc.    */
  31.  
  32. #ifndef lint
  33. static char rcsid[]=
  34. "$Header: fep_funcs.c,v 4.0 88/08/05 20:22:12 utashiro Rel $ (SRA)";
  35. #endif lint
  36.  
  37. #include <stdio.h>
  38. #include "fep_funcs.h"
  39.  
  40. /*
  41.  * FunctionNameTable
  42.  */
  43. FunctionTableEnt FunctionNameTable[] = {
  44.     {mark,                "mark",
  45.      "Mark position"},
  46.     {abort,                "abort",
  47.      "Abort function"},
  48.     {self_insert,            "self-insert",
  49.      "Insert the character"},
  50.     {beginning_of_line,        "beginning-of-line",
  51.      "Jump to beginning of line"},
  52.     {backward_character,        "backward-character",
  53.      "Backward character"},
  54.     {backward_word,            "backward-word",
  55.      "Backward word (alpha-numeric)"},
  56.     {backward_Word,            "backward-Word",
  57.      "Backward word (non-space)"},
  58.     {end_of_line,            "end-of-line",
  59.      "Jump to end of line"},
  60.     {forward_character,        "forward-character",
  61.      "Forward character"},
  62.     {forward_word,            "forward-word",
  63.      "Forward word (alpha-numeric)"},
  64.     {forward_Word,            "forward-Word",
  65.      "Forward word (non-space)"}, 
  66.     {forward_to_end_of_word,    "forward-to-end-of-word",
  67.      "Forward to end of word (alpha-numeric)"},
  68.     {forward_to_end_of_Word,    "forward-to-end-of-Word",
  69.      "Forward to end of word (non-space)"},
  70.     {delete_previous_character,    "delete-previous-character",
  71.      "Delete previous character"},
  72.     {delete_next_character,        "delete-next-character",
  73.      "Delete next character"},
  74.     {insert_tab,            "insert-tab",
  75.      "Insert tab"},
  76.     {new_line,            "new-line",
  77.      "Insert newline"},
  78.     {insert_and_flush,        "insert-and-flush",
  79.      "Insert the character and flush buffer"},
  80.     {send_eof,            "send-eof",
  81.      "Send eof"},
  82.     {kill_to_end_of_line,        "kill-to-end-of-line",
  83.      "Delete current position to eol"},
  84.     {kill_to_top_of_line,        "kill-to-top-of-line",
  85.      "Delete tol to current position"},
  86.     {delete_to_kill_buffer,        "delete-to-kill-buffer",
  87.      "Delete resion to buffer"},
  88.     {yank_from_kill_buffer,        "yank-from-kill-buffer",
  89.      "Yank from kill buffer"},
  90.     {clear_screen,            "clear-screen",
  91.      "Clear screen"},
  92.     {next_history,            "next-history",
  93.      "Get next history"},
  94.     {previous_history,        "previous-history",
  95.      "Get previous history"},
  96.     {ignore,            "ignore",
  97.      "Ignore"},
  98.     {delete_line,            "delete-line",
  99.      "Delete whole line"},
  100.     {literal_next,            "literal-next",
  101.      "Treat next character as literal"},
  102.     {delete_previous_word,        "delete-previous-word",
  103.      "Delete previous word (alpha-numeric)"},
  104.     {delete_previous_Word,        "delete-previous-Word",
  105.      "Delete previous word (non-space)"},
  106.     {delete_next_word,        "delete-next-word",
  107.      "Delete next word (alpha-numeric)"},
  108.     {delete_next_Word,        "delete-next-Word",
  109.      "Delete next word (non-space)"},
  110.     {reprint,            "reprint",
  111.      "Reprint line"},
  112.     {show_history,            "show-history",
  113.      "Show history"},
  114.     {show_bindings,            "show-bindings",
  115.      "Show binding table"},
  116.     {expand_file_name,        "expand-file-name",
  117.      "Expand file name"},
  118.     {list_file_name,        "list-file-name",
  119.      "List file name"},
  120.     {terminate,            "terminate",
  121.      "Terminate fep"},
  122.     {suspend,            "suspend",
  123.      "Suspend fep"},
  124.     {toggle_transparency,        "toggle-transparency",
  125.      "Change transparency mode"},
  126.     {fix_transparency,        "fix-transparency",
  127.      "Check tty and change transparency mode"},
  128.     {invoke_shell,            "invoke-shell",
  129.      "Invoke shell process"},
  130.     {search_reverse,        "search-reverse",
  131.      "Search backward last !history"},
  132.     {search_forward,        "search-forward",
  133.      "Search forward last !history"},
  134.     {fep_start_script,        "start-script",
  135.      "Start script"},
  136.     {fep_end_script,        "end-script",
  137.      "End script"},
  138.     {fep_repaint,            "repaint",
  139.      "Repaint screen"},
  140.     {show_help,            "help",
  141.      "Show help"},
  142.  
  143.     {vi_c,                "vi-c",
  144.      "Vi c? commands"},
  145.     {vi_d,                "vi-d",
  146.      "Vi d? commands"},
  147.     {vi_edit,            "vi-edit",
  148.      "Vi edit commands"},
  149.     {vi_ins_edit,            "vi-ins-edit",
  150.      "Vi insert mode"},
  151.     {vi_motion,            "vi-motion",
  152.      "Vi cursor motion commands"},
  153.     {vi_new_line,            "vi-new-line",
  154.      "Vi new line"},
  155.     {vi_num,            "vi-num",
  156.      "Vi prefix number"},
  157.  
  158.     {NULL,                NULL}
  159. };
  160.  
  161. /*
  162.  * Table of built-in functions
  163.  */
  164. FunctionTableEnt BuiltinFuncTable[] = {
  165.     {bind_to_key,            "fep-bind",
  166.      "Change binding table"},
  167.     {alias,                "fep-alias",
  168.      "Set or show aliases"},
  169.     {unalias,            "fep-unalias",
  170.      "Delete alias"},
  171.     {set,                "fep-set",
  172.      "Set or show variables"},
  173.     {unset,                "fep-unset",
  174.      "Unset variables"},
  175.     {fep_chdir,            "fep-cd",
  176.      "Change directory"},
  177.     {fep_chdir,            "fep-chdir",
  178.      "Change directory"},
  179.     {fep_pwd,            "fep-pwd",
  180.      "Print working directory"},
  181.     {fep_history,            "fep-history",
  182.      "Show history"},
  183.     {fep_echo,            "fep-echo",
  184.      "Print arguments"},
  185.     {fep_source,            "fep-source",
  186.      "Read and execute file"},
  187.     {fep_command,            "fep-command",
  188.      "Invoke unix command"},
  189.     {fep_command,            "fep-!",
  190.      "Same as fep_command"},
  191.     {fep_save_history,        "fep-save-history",
  192.      "Save history to file"},
  193.     {fep_read_history,        "fep-read-history",
  194.      "Read history from file"},
  195.     {fep_read_from_file,        "fep-read-from-file",
  196.      "Send file contens to slave command"},
  197.     {fep_read_from_file,        "fep-<",
  198.      "Same as fep_read_from_file"},
  199.     {fep_read_from_command,        "fep-read-from-command",
  200.      "Send output of command to slave command"},
  201.     {fep_read_from_command,        "fep-<!",
  202.      "Same as fep_read_from_command"},
  203.     {fep_start_script,        "fep-start-script",
  204.      "Start script"},
  205.     {fep_start_script,        "fep-script",
  206.      "Start script"},
  207.     {fep_end_script,        "fep-end-script",
  208.      "End script"},
  209.     {fep_if,            "fep-if",
  210.      "Operation \"if\""},
  211.     {fep_if,            "fep-elseif",
  212.      "Operation \"endif\""},
  213.     {fep_else,            "fep-else",
  214.      "Operation \"else\""},
  215.     {fep_endif,            "fep-endif",
  216.      "Operation \"endif\""},
  217.     {terminate,            "fep-exit",
  218.      "Terminate fep"},
  219.     {suspend,            "fep-suspend",
  220.      "Suspend fep"},
  221.     {show_bindings,            "fep-show-bind",
  222.      "Print bindings"},
  223.     {show_bindings,            "fep-showbind",
  224.      "Print bindings"},
  225.     {fep_repaint,            "fep-repaint",
  226.      "Repaint screen"},
  227. #ifdef STAT
  228.     {fep_showstat,            "fep-showstat",
  229.      "Show statistical information"},
  230. #endif
  231.     {NULL,                NULL}
  232. };
  233. \End\Of\File\
  234. else
  235.   echo "will not over write ./fep_funcs.c"
  236. fi
  237. if `test ! -s ./fep_set.c`
  238. then
  239. echo "writing ./fep_set.c"
  240. cat > ./fep_set.c << '\End\Of\File\'
  241. /*    Copyright (c) 1987, 1988 by Software Research Associates, Inc.    */
  242.  
  243. #ifndef lint
  244. static char rcsid[]=
  245. "$Header: fep_set.c,v 4.0 88/08/05 20:22:22 utashiro Rel $ (SRA)";
  246. #endif lint
  247.  
  248. #include <stdio.h>
  249. #include "fep_defs.h"
  250. #include "fep_glob.h"
  251.  
  252. VAR default_set_vars [] = {
  253.     {"expand-tilde",    "",
  254.      "Expand ~ to home directory name",    (VAR*)0},
  255.     {"ignore-empty-line",    "",
  256.      "Don't put empty line to history",    (VAR*)0},
  257.     {"ignore-same-line",    "",
  258.      "Don't put same line to history",    (VAR*)0},
  259.     {"editmode",        "emacs",
  260.      "Fep command line edit mode",        (VAR*)0},
  261.     {"history-file",    ".fephistory",
  262.      "Name of history file",        (VAR*)0},
  263.     {"shell",        "/bin/sh",
  264.      "Shell name used by invoke-shell",    (VAR*)0},
  265.     {"auto-tty-fix",    "",
  266.      "Fix tty mode automatically",        (VAR*)0},
  267.     {"script-file",        "fepscript",
  268.      "Script file name",            (VAR*)0},
  269.     {"crt",            "24",
  270.      "Terminal lines",            (VAR*)0},
  271.     {"showhist",        "24",
  272.      "History length used by show-history",    (VAR*)0},
  273.     {"delimiters",        " \t",
  274.      "Argument delemiter characters",    (VAR*)0},
  275.     {NULL,            NULL,
  276.      NULL,                    (VAR*)0}
  277. };
  278.  
  279. VAR default_unset_vars [] = {
  280.     /* below from here is unset by default */
  281.     {"alarm-on-eof",    "",
  282.      "Alarm once to eof character",        (VAR*)0},
  283.     {"ignore-eof",        "",
  284.      "Never treat eof character as eof",    (VAR*)0}, 
  285.     {"savehist",        "",
  286.      "Length of save history",        (VAR*)0},
  287.     {"verbose",        "",
  288.      NULL,                    (VAR*)0}, 
  289.     {"search-string",    "",
  290.      NULL,                    (VAR*)0},
  291.     {"noalias",        "",
  292.      "Not use alias",            (VAR*)0},
  293.     {"tty-fix-bell",    "",
  294.      "Ring bell when tty mode changed",    (VAR*)0},
  295.     {"auto-repaint",    "",
  296.      "Repaint screen when restarting",    (VAR*)0},
  297.     {"clear-repaint",    "",
  298.      "Clear screen before repaint",        (VAR*)0},
  299.     {NULL,            NULL,
  300.      NULL,                    (VAR*)0}
  301. };
  302.  
  303. #ifdef HASH
  304. #define HASHNUM    10
  305. VAR *var_htab[HASHNUM];
  306. #else HASH
  307. VAR var_top = {"top", "top", (char *)0, (VAR *)0};
  308. VAR *var_list = &var_top;
  309. #endif HASH
  310.  
  311. /*
  312.  * Functions
  313.  */
  314. int    set_var        (/* char *name, char *value */);
  315. char    *look_var    (/* char *name */);
  316. int    lookd_var    (/* char *name */);
  317. VAR    *getvp        (/* char *name */);
  318.  
  319. extern    char    *allocAndCopyThere();
  320. extern    char    *prompt;
  321.  
  322. /*
  323.  * Set default variables
  324.  */
  325. set_default_vars ()
  326. {
  327.     register VAR *vp;
  328.  
  329.     for (vp = default_set_vars; vp->v_name; vp++)
  330.     set_only_var (vp->v_name, vp->v_value);
  331. }
  332.  
  333. /*
  334.  * Set variable
  335.  */
  336. set_var (name, value)
  337.     char *name;
  338.     char *value;
  339. {
  340.     set_only_var (name, value);
  341.  
  342.     /*
  343.      * Process special variable
  344.      */
  345.     if (eq (name, "history"))
  346.     changeHistorySize (lookd_var ("history"));
  347.     if (eq (name, "prompt")) {
  348.     free (prompt);
  349.     prompt = allocAndCopyThere (value);
  350.     }
  351.     if (eq (name, "editmode")) {
  352.     if (eq (value, "emacs")) {
  353.         editmode = EMACS;
  354.         initEmacsBindings (curFuncTab, altFuncTab);
  355.     }
  356.     else if (eq (value, "vi")) {
  357.         editmode = VI;
  358.         initViBindings (curFuncTab, altFuncTab);
  359.     }
  360.     else
  361.         printf ("%s: Unknown editmode\n", value);
  362.     }
  363.     if (eq (name, "auto-tty-fix"))
  364.     auto_tty_fix = ON;
  365.     if (eq (name, "debug"))
  366.     debug = ON;
  367.     if (eq (name, "tty-fix-bell"))
  368.     tty_fix_bell = ON;
  369.     if (eq (name, "delimiters"))
  370.     delimiters = look_var ("delimiters");
  371.     if (eq (name, "crt"))
  372.     lines = atoi (look_var("crt"));
  373.  
  374. }
  375.  
  376. set_only_var (name, value)
  377.     char *name, *value;
  378. {
  379.     VAR *vp;
  380.  
  381.     vp = getvp (name, 1, 0);
  382.  
  383.     if (vp->v_value)
  384.     free (vp->v_value);
  385.  
  386.     vp->v_value = allocAndCopyThere (value);
  387. }
  388.  
  389. /*
  390.  * Unset variable
  391.  */
  392. unset_var (name)
  393.     char *name;
  394. {
  395.     VAR *vp, *prev;
  396.  
  397.     vp = getvp (name, 0, &prev);
  398.  
  399.     if (!vp)
  400.     return;
  401.  
  402.     prev->v_next = vp->v_next;
  403.     free (vp->v_name);
  404.     free (vp->v_value);
  405.     free (vp);
  406.  
  407.     if (eq (name, "auto-tty-fix"))
  408.     auto_tty_fix = OFF;
  409.  
  410.     if (eq (name, "debug"))
  411.     debug = OFF;
  412.  
  413.     if (eq (name, "tty-fix-bell"))
  414.     tty_fix_bell = OFF;
  415.  
  416.     if (eq (name, "delimiters"))
  417.     delimiters = DEFAULT_DELIMITERS;
  418.     return;
  419. }
  420.  
  421. /*
  422.  * Look up variable
  423.  */
  424. char *
  425. look_var (name)
  426.     char *name;
  427. {
  428.  
  429.     VAR *vp;
  430.  
  431.     vp = getvp (name, 0, 0);
  432.  
  433.     if (vp && vp->v_value)
  434.     return (vp->v_value);
  435.     else
  436.     return ((char *)0);
  437. }
  438.  
  439. /*
  440.  * Look up variable and get integer result
  441.  */
  442. int
  443. lookd_var (name)
  444.     char *name;
  445. {
  446.     VAR *vp;
  447.  
  448.     vp = getvp (name, 0, 0);
  449.  
  450.     if (vp && vp->v_value)
  451.     return (atoi (vp->v_value));
  452.     else
  453.     return (0);
  454. }
  455.  
  456. /*
  457.  * Show variable list
  458.  */
  459. show_varlist ()
  460. {
  461. #ifdef HASH
  462.     register int i;
  463.  
  464.     for (i = 0; i< HASHNUM; i++) {
  465.     register VAR *vp;
  466.  
  467.     vp = var_htab[i];
  468.     if (vp == (VAR *)0)
  469.         continue;
  470.  
  471.     for (; vp != (VAR *)0; vp = vp->v_next)
  472.         printf ("%-16s %s\n", vp->v_name, vp->v_value);
  473.     }
  474. #else HASH
  475.     register VAR *vp;
  476.  
  477.     for (vp = var_list->v_next; vp; vp = vp->v_next)
  478.     printf ("%-16s %s\n", vp->v_name, vp->v_value);
  479. #endif HASH
  480. }
  481.  
  482. #ifdef HASH
  483. /*
  484.  * Get hash index from variable name
  485.  */
  486. static getindex (s)
  487.     register char *s;
  488. {
  489.     register int sum = 0;
  490.  
  491.     while (*s)
  492.     sum += *s++;
  493.  
  494.     return (sum % HASHNUM);
  495. }
  496. #endif HASH
  497.  
  498. /*
  499.  * Get pointer to VAR.
  500.  * If there is no memoly associated to the variable and alloc argument is 1,
  501.  * allocate the area and initialize name field.
  502.  */
  503. VAR *
  504. getvp (name, alloc, lastvp)
  505.     char *name;
  506.     int alloc;
  507.     VAR **lastvp;
  508. {
  509. #ifdef HASH
  510.     register i = getindex (name);
  511. #endif HASH
  512.     VAR *vp, *last = (VAR *)0;
  513.  
  514. #ifdef HASH
  515.     for (vp = var_htab[i]; vp; last = vp, vp->v_next) {
  516.     if (strcmp (name, vp->v_value) == 0)
  517.         return (vp);
  518.     }
  519. #else HASH
  520.     for (vp = var_list->v_next, last = var_list; vp; last = vp, vp = vp->v_next) {
  521.     int r;
  522.  
  523.     r = strcmp (name, vp->v_name);
  524.     if (r == 0) {
  525.         if (lastvp)
  526.         *lastvp = last;
  527.         return (vp);
  528.     }
  529.     else if (r < 0)
  530.         break;
  531.     }
  532. #endif HASH
  533.  
  534.     if (alloc == 0)
  535.     return (0);
  536.  
  537.     vp = (VAR *) calloc (sizeof (VAR), 1);
  538.     vp->v_value = (char *)0;
  539.     vp->v_next = (VAR *) 0;
  540.     vp->v_name = allocAndCopyThere (name);
  541.  
  542. #ifdef HASH
  543.     if (last) {
  544.     vp->v_next = last->v_next;
  545.     last->v_next = vp;
  546.     }
  547.     else {
  548.     var_htab[i] = vp;
  549.     }
  550. #else HASH
  551.     vp->v_next = last->v_next;
  552.     last->v_next = vp;
  553. #endif HASH
  554.     return (vp);
  555. }
  556. \End\Of\File\
  557. else
  558.   echo "will not over write ./fep_set.c"
  559. fi
  560. if `test ! -s ./fep_vi.c`
  561. then
  562. echo "writing ./fep_vi.c"
  563. cat > ./fep_vi.c << '\End\Of\File\'
  564. /*    Copyright (c) 1987, 1988 by Software Research Associates, Inc.    */
  565.  
  566. #ifndef lint
  567. static char rcsid[]=
  568. "$Header: fep_vi.c,v 4.0 88/08/05 20:22:27 utashiro Rel $ (SRA)";
  569. #endif lint
  570.  
  571. #include <stdio.h>
  572. #include <sgtty.h>
  573. #include <ctype.h>
  574. #include "fep_defs.h"
  575. #include "fep_glob.h"
  576. #include "fep_funcs.h"
  577.  
  578. enum {INSERTMODE, COMMANDMODE} vi_mode = COMMANDMODE;
  579. int vi_count;
  580.  
  581. extern char *CommandLine;
  582. extern int CurrentPosition;
  583.  
  584. /*
  585.  * Default binding table
  586.  */
  587. BINDENT viComBindings[] = {
  588.     /* 1       */    {"1",        vi_num},
  589.     /* 2       */    {"2",        vi_num},
  590.     /* 3       */    {"3",        vi_num},
  591.     /* 4       */    {"4",        vi_num},
  592.     /* 5       */    {"5",        vi_num},
  593.     /* 6       */    {"6",        vi_num},
  594.     /* 7       */    {"7",        vi_num},
  595.     /* 8       */    {"8",        vi_num},
  596.     /* 9       */    {"9",        vi_num},
  597.  
  598.     /* ~       */    {"~",        vi_edit},
  599.     /* A       */    {"A",        vi_edit},
  600.     /* C       */    {"C",        vi_edit},
  601.     /* D       */    {"D",        vi_edit},
  602.     /* P       */    {"P",        vi_edit},
  603.     /* S       */    {"S",        vi_edit},
  604.     /* I       */    {"I",        vi_edit},
  605.     /* a       */    {"a",        vi_edit},
  606.     /* i       */    {"i",        vi_edit},
  607.     /* p       */    {"p",        vi_edit},
  608.     /* r       */    {"r",        vi_edit},
  609.     /* s       */    {"s",        vi_edit},
  610.     /* x       */    {"x",        vi_edit},
  611.     /* X       */    {"X",        vi_edit},
  612.     /* ^U      */    {"\\^U",    vi_edit},
  613.  
  614.     /*         */    {" ",        vi_motion},
  615.     /* ^H      */    {"\b",        vi_motion},
  616.     /* l       */    {"l",        vi_motion},
  617.     /* h       */    {"h",        vi_motion},
  618.     /* k       */    {"k",        vi_motion},
  619.     /* j       */    {"j",        vi_motion},
  620.     /* b       */    {"b",        vi_motion},
  621.     /* B       */    {"B",        vi_motion},
  622.     /* e       */    {"e",        vi_motion},
  623.     /* E       */    {"E",        vi_motion},
  624.     /* w       */    {"w",        vi_motion},
  625.     /* W       */    {"W",        vi_motion},
  626.     /* n       */    {"n",        vi_motion},
  627.     /* N       */    {"N",        vi_motion},
  628.     /* 0       */    {"0",        vi_motion},
  629.     /* ^       */    {"^",        vi_motion},
  630.     /* $       */    {"$",        vi_motion},
  631.     /* |       */    {"|",        vi_motion},
  632.     /* -       */    {"-",        vi_motion},
  633.     /* +       */    {"+",        vi_motion},
  634.  
  635.     /* cb      */    {"cb",        vi_c},
  636.     /* cB      */    {"cb",        vi_c},
  637.     /* cw      */    {"cw",        vi_c},
  638.     /* cW      */    {"cW",        vi_c},
  639.     /* c0      */    {"c0",        vi_c},
  640.     /* c^      */    {"c^",        vi_c},
  641.     /* c$      */    {"c$",        vi_c},
  642.     /* cc      */    {"cc",        vi_c},
  643.  
  644.     /* db      */    {"db",        vi_d},
  645.     /* dB      */    {"dB",        vi_d},
  646.     /* dw      */    {"dw",        vi_d},
  647.     /* dW      */    {"dW",        vi_d},
  648.     /* d0      */    {"d0",        vi_d},
  649.     /* d^      */    {"d^",        vi_d},
  650.     /* d$      */    {"d$",        vi_d},
  651.     /* dd      */    {"dd",        vi_d},
  652.  
  653.     /* ^E      */    {"\\^E",    expand_file_name},
  654.     /* ^J      */    {"\\^J",    vi_new_line},
  655.     /* ^L      */    {"\\^L",    list_file_name},
  656.     /* ^M      */    {"\\^M",    vi_new_line},
  657.     /* ^P      */    {"\\^P",    previous_history},
  658.     /* ^N      */    {"\\^N",    next_history},
  659.     /* ^R      */    {"\\^R",    reprint},
  660.     /* ^^      */    {"\\^^",    toggle_transparency},
  661.     /* ^X-^B   */    {"\\^X\\^B",    show_bindings},
  662.     /* ^X-B       */    {"\\^XB",    show_bindings},
  663.     /* ^X-b       */    {"\\^Xb",    show_bindings},
  664.     /* ^X-^H   */    {"\\^X\\^H",    show_history},
  665.     /* ^X-h    */    {"\\^Xh",    show_history},
  666.     /* ^X-H    */    {"\\^XH",    show_history},
  667.     /* ^X-l    */    {"\\^Xl",    list_file_name},
  668.     /* ^X-L    */    {"\\^XL",    list_file_name},
  669.     /* ^X-^L   */    {"\\^X\\^L",    fep_repaint},
  670.     /* ^X-^X   */    {"\\^X\\^X",    expand_file_name},
  671.     /* ^X-?    */    {"\\^X?",    show_bindings},
  672.     /* ^X-^C   */    {"\\^X\\^C",    terminate},
  673.     /* ^X-^D   */    {"\\^X\\^D",    send_eof},
  674.     /* ^X-(       */    {"\\^X(",    fep_start_script},
  675.     /* ^X-)       */    {"\\^X)",    fep_end_script},
  676.     /*         */    {NULL,        NULL}
  677. };
  678.  
  679. BINDENT viInsertBindings[] = {
  680.     /* ^H      */    {"\\^H",    vi_ins_edit},
  681.     /* ^W      */    {"\\^W",    vi_ins_edit},
  682.     /* ^U      */    {"\\^U",    vi_ins_edit},
  683.     /* ^V      */    {"\\^V",    vi_ins_edit},
  684.     /* ^J      */    {"\\^J",    vi_new_line},
  685.     /* ^L      */    {"\\^L",    list_file_name},
  686.     /* ^M      */    {"\\^M",    vi_new_line},
  687.     /* ^P      */    {"\\^P",    previous_history},
  688.     /* ^N      */    {"\\^N",    next_history},
  689.     /* ESC     */    {"\\^[",    vi_ins_edit},
  690.     /* ^E      */    {"\\^E",    expand_file_name},
  691.     /* ^^      */    {"\\^^",    toggle_transparency},
  692.     /* ^X-^B   */    {"\\^X\\^B",    show_bindings},
  693.     /* ^X-B       */    {"\\^XB",    show_bindings},
  694.     /* ^X-b       */    {"\\^Xb",    show_bindings},
  695.     /* ^X-^H   */    {"\\^X\\^H",    show_history},
  696.     /* ^X-h    */    {"\\^Xh",    show_history},
  697.     /* ^X-H    */    {"\\^XH",    show_history},
  698.     /* ^X-l    */    {"\\^Xl",    list_file_name},
  699.     /* ^X-L    */    {"\\^XL",    list_file_name},
  700.     /* ^X-^L   */    {"\\^X\\^L",    fep_repaint},
  701.     /* ^X-^X   */    {"\\^X\\^X",    expand_file_name},
  702.     /* ^X-?    */    {"\\^X?",    show_bindings},
  703.     /* ^X-^C   */    {"\\^X\\^C",    terminate},
  704.     /* ^X-^D   */    {"\\^X\\^D",    send_eof},
  705.     /* ^X-(       */    {"\\^X(",    fep_start_script},
  706.     /* ^X-)       */    {"\\^X)",    fep_end_script},
  707.     /*         */    {NULL,        NULL}
  708. };
  709.  
  710. FUNC *viComTable;
  711. FUNC *viInsTable;
  712.  
  713. initViBindings (cft, aft)
  714. FUNC cft[], aft[];
  715. {
  716.     register int i;
  717.     BINDENT *ftp;
  718.  
  719.     for (i = 0; i < 256; i++)
  720.     aft[i] = abort;
  721.     for (i = 0; i < 256; i++)
  722.     cft[i] = self_insert;
  723.  
  724.     for (ftp = viComBindings; ftp->bt_s; ftp++) {
  725.     bind_key (aft, ftp->bt_func, ftp->bt_s, abort);
  726.     }
  727.     for (ftp = viInsertBindings; ftp->bt_s; ftp++) {
  728.     bind_key (cft, ftp->bt_func, ftp->bt_s, abort);
  729.     }
  730.  
  731.     /* Now, using cbreak mode
  732.     cft[(int) tchars_buf.t_startx] = ignore;
  733.     cft[(int) tchars_buf.t_stopc] = ignore;
  734.     */
  735.     cft[(int) tchars_buf.t_intrc] = insert_and_flush;
  736.     aft[(int) tchars_buf.t_intrc] = insert_and_flush;
  737.     cft[(int) tchars_buf.t_quitc] = insert_and_flush;
  738.     cft[(int) tchars_buf.t_eofc] = send_eof;
  739.     cft[(int) tchars_buf.t_brkc] = insert_and_flush;
  740.     cft[(int) ltchars_buf.t_suspc] = insert_and_flush;
  741.     cft[(int) ltchars_buf.t_dsuspc] = self_insert;
  742.     cft[(int) ltchars_buf.t_rprntc] = reprint;
  743.     cft[(int) ltchars_buf.t_flushc] = self_insert;
  744.     cft[(int) ltchars_buf.t_werasc] = delete_previous_word;
  745.     cft[(int) ltchars_buf.t_lnextc] = literal_next;
  746.     cft[(int) initial_ttymode.sg_erase] = delete_previous_character;
  747.     cft[(int) initial_ttymode.sg_kill] = delete_line;
  748.  
  749.     viInsTable = cft;
  750.     viComTable = aft;
  751.     vi_mode = INSERTMODE;
  752. }
  753.  
  754. vi_edit (c)
  755.     int c;
  756. {
  757.     int count = vi_count ? vi_count : 1;
  758.  
  759.     switch (c) {
  760.     case '~':
  761.         {
  762.         char c = CommandLine [CurrentPosition];
  763.  
  764.         if (isalpha (c)) {
  765.             (void) delete_next_character (c);
  766.             c ^= 0040;
  767.             (void) self_insert (c);
  768.         }
  769.         else
  770.             (void) forward_character (c);
  771.         }
  772.         break;
  773.  
  774.     case 'a':
  775.         if (!is_eol())
  776.         (void) forward_character (c);
  777.     case 'i':
  778.         (void) altenateEditmode (c);
  779.         break;
  780.  
  781.     case 'A':
  782.         (void) end_of_line (c);
  783.         (void) altenateEditmode ();
  784.         break;
  785.  
  786.     case 'I':
  787.         (void) beginning_of_line (c);
  788.         (void) altenateEditmode ();
  789.         break;
  790.  
  791.     case 'C':
  792.         (void) kill_to_end_of_line (c);
  793.         (void) altenateEditmode (c);
  794.         break;
  795.  
  796.     case 'D':
  797.         (void) kill_to_end_of_line (c);
  798.         break;
  799.  
  800.     case 'S':
  801.         (void) delete_line (c);
  802.         (void) altenateEditmode ();
  803.         break;
  804.  
  805.     case 'r':
  806.         (void) delete_next_character (c);
  807.         (void) self_insert (getcharacter ());
  808.         break;
  809.  
  810.     case 's':
  811.         (void) delete_next_n_character (count);
  812.         (void) altenateEditmode ();
  813.         break;
  814.  
  815.     case 'x':
  816.         (void) delete_next_n_character (count);
  817.         break;
  818.  
  819.     case 'X':
  820.         (void) delete_previous_n_character (count);
  821.         break;
  822.  
  823.     case 'p':
  824.         (void) forward_character ();
  825.     case 'P':
  826.         (void) yank_from_kill_buffer ();
  827.         (void) backward_character ();
  828.         break;
  829.  
  830.     case CTRL(U):
  831.         (void) delete_line (c);
  832.         (void) altenateEditmode ();
  833.         break;
  834.     }
  835.     vi_count = 0;
  836.     return (0);
  837. }
  838.  
  839. altenateEditmode ()
  840. {
  841.     FUNC *tmp;
  842.  
  843.     tmp = curFuncTab;
  844.     curFuncTab = altFuncTab;
  845.     altFuncTab = tmp;
  846.     vi_mode = (vi_mode == INSERTMODE) ? COMMANDMODE : INSERTMODE;
  847.  
  848.     return (0);
  849. }
  850.  
  851. vi_num (c)
  852.     int c;
  853. {
  854.     vi_count = vi_count * 10 + ((int)c - (int)'0');
  855.     return (0);
  856. }
  857.  
  858. vi_motion (c)
  859.     int c;
  860. {
  861.     int count = vi_count ? vi_count : 1;
  862.  
  863.     switch (c) {
  864.  
  865.     case 'w':
  866.         (void) forward_n_word (count);
  867.         break;
  868.  
  869.     case 'W':
  870.         (void) forward_n_Word (count);
  871.         break;
  872.  
  873.     case 'e':
  874.         (void) forward_to_end_of_n_word (count);
  875.         break;
  876.  
  877.     case 'E':
  878.         (void) forward_to_end_of_n_Word (count);
  879.         break;
  880.  
  881.     case 'b':
  882.         (void) backward_n_word (count);
  883.         break;
  884.  
  885.     case 'B':
  886.         (void) backward_n_Word (count);
  887.         break;
  888.  
  889.     case 'l':
  890.     case ' ':
  891.         (void) forward_n_character (count);
  892.         break;
  893.  
  894.     case 'h':
  895.     case '\b':
  896.         (void) backward_n_character (count);
  897.         break;
  898.  
  899.     case 'k':
  900.     case '-':
  901.         (void) previous_history (c);
  902.         break;
  903.  
  904.     case 'j':
  905.     case '+':
  906.         (void) next_history (c);
  907.         break;
  908.  
  909.     case 'n':
  910.         (void) search_reverse (c);
  911.         break;
  912.  
  913.     case 'N':
  914.         (void) search_forward (c);
  915.         break;
  916.  
  917.     case '0':
  918.         if (vi_count)
  919.         return (vi_num (c));
  920.         /* falling down */
  921.  
  922.     case '^':
  923.         (void) beginning_of_line (c);
  924.         break;
  925.  
  926.     case '$':
  927.         (void) end_of_line (c);
  928.         break;
  929.  
  930.     case '|':
  931.         (void) moveto (count - 1);
  932.         /***
  933.         if (strlen (CommandLine) >= count) {
  934.         (void) beginning_of_line (c);
  935.         (void) forward_n_character (count - 1);
  936.         }
  937.         else
  938.         (void) end_of_line (c);
  939.         ***/
  940.         break;
  941.  
  942.     default:
  943.         (void) abort (c);
  944.         break; 
  945.     }
  946.     vi_count = 0;
  947.     return (0);
  948. }
  949.  
  950. vi_c (c)
  951.     int c;
  952. {
  953.     int count = vi_count ? vi_count : 1;
  954.  
  955.     switch (c) {
  956.     case '0':
  957.     case '^':
  958.         (void) kill_to_top_of_line (c);
  959.         break;
  960.  
  961.     case 'c':
  962.         delete_line(c);
  963.         break;
  964.  
  965.     case 'w':
  966.         (void) delete_next_n_word (count);
  967.         break;
  968.  
  969.     case 'W':
  970.         (void) delete_next_n_Word (count);
  971.         break;
  972.  
  973.     case 'b':
  974.         (void) delete_previous_n_word (count);
  975.         break;
  976.  
  977.     case 'B':
  978.         (void) delete_previous_n_Word (count);
  979.         break;
  980.  
  981.     case '$':
  982.         (void) kill_to_end_of_line(c);
  983.         break;
  984.  
  985.     default:
  986.         return (abort (c));
  987.     }
  988.     vi_count = 0;
  989.     altenateEditmode ();
  990.     return (0);
  991. }
  992.  
  993. vi_d (c)
  994.     int c;
  995. {
  996.     int count = vi_count ? vi_count : 1;
  997.  
  998.     switch (c) {
  999.     case '0':
  1000.     case '^':
  1001.         (void) kill_to_top_of_line (c);
  1002.         break;
  1003.  
  1004.     case 'd':
  1005.         delete_line(c);
  1006.         break;
  1007.  
  1008.     case 'w':
  1009.         (void) delete_next_n_word (count);
  1010.         break;
  1011.  
  1012.     case 'W':
  1013.         (void) delete_next_n_Word (count);
  1014.         break;
  1015.  
  1016.     case 'b':
  1017.         (void) delete_previous_n_word (count);
  1018.         break;
  1019.  
  1020.     case 'B':
  1021.         (void) delete_previous_n_Word (count);
  1022.         break;
  1023.  
  1024.     case '$':
  1025.         (void) kill_to_end_of_line(c);
  1026.         break;
  1027.  
  1028.     default:
  1029.         return (abort (c));
  1030.     }
  1031.     vi_count = 0;
  1032.     return (0);
  1033. }
  1034.  
  1035. vi_new_line (c)
  1036.     int c;
  1037. {
  1038.     int count = vi_count ? vi_count : 1;
  1039.  
  1040.     vi_count = 0;
  1041.  
  1042.     (void) new_line (c);
  1043.     if (vi_mode == COMMANDMODE)
  1044.     altenateEditmode ();
  1045.  
  1046.     return (1);
  1047. }
  1048.  
  1049. vi_ins_edit (c)
  1050.     int c;
  1051. {
  1052.     switch (c) {
  1053.  
  1054.     case CTRL(H):
  1055.         (void) delete_previous_character (c);
  1056.         break;
  1057.  
  1058.     case CTRL(W):
  1059.         (void) delete_previous_word (c);
  1060.         break;
  1061.  
  1062.     case CTRL(U):
  1063.         (void) delete_line (c);
  1064.         break;
  1065.  
  1066.     case CTRL(V):
  1067.         (void) literal_next (c);
  1068.         break;
  1069.  
  1070.     case '\033':
  1071.         (void) altenateEditmode ();
  1072.         (void) backward_character ();
  1073.         break;
  1074.     }
  1075.     return (0);
  1076. }
  1077. \End\Of\File\
  1078. else
  1079.   echo "will not over write ./fep_vi.c"
  1080. fi
  1081. if `test ! -s ./fep_util.c`
  1082. then
  1083. echo "writing ./fep_util.c"
  1084. cat > ./fep_util.c << '\End\Of\File\'
  1085. /*    Copyright (c) 1987, 1988 by Software Research Associates, Inc.    */
  1086.  
  1087. #ifndef lint
  1088. static char rcsid[]=
  1089. "$Header: fep_util.c,v 4.0 88/08/05 20:22:24 utashiro Rel $ (SRA)";
  1090. #endif lint
  1091.  
  1092. #ifndef MKARGDEBUG
  1093.  
  1094. #include <stdio.h>
  1095. #include <pwd.h>
  1096. #include <sys/types.h>
  1097. #include <sys/dir.h>
  1098. #include <ctype.h>
  1099. #include "fep_defs.h"
  1100.  
  1101. message(messageString)
  1102.     char *messageString;
  1103. {
  1104.     write (2, messageString, strlen (messageString));
  1105. }
  1106.  
  1107. errorBell()
  1108. {
  1109.     write (2, "\007", 1);
  1110. }
  1111.  
  1112. ctlprint(string)
  1113.     char *string;
  1114. {
  1115.     register char  *cp;
  1116.  
  1117.     for (cp = string; *cp; cp++) {
  1118.     if (isctlchar (*cp)) {
  1119.         putchar ('^');
  1120.         putchar (unctl (*cp));
  1121.     }
  1122.     else
  1123.         putchar (*cp);
  1124.     }
  1125.     fputs ("\r\n", stdout);
  1126.     fflush (stdout);
  1127. }
  1128.  
  1129. /*
  1130.  * Print string using "^" for control characters
  1131.  */
  1132. printS (string)
  1133.     char *string;
  1134. {
  1135.     char *cp;
  1136.  
  1137.     for (cp = string; *cp; cp++)
  1138.     putChar (*cp);
  1139. }
  1140.  
  1141. /*
  1142.  * Check the line is empty or not
  1143.  */
  1144. is_empty_line(line)
  1145.     char *line;
  1146. {
  1147.     register char *cp;
  1148.  
  1149.     for (cp = line; *cp; cp++) {
  1150.         if (!isspace(*cp)) {
  1151.         return(0);
  1152.     }
  1153.     }
  1154.     return(1);
  1155. }
  1156.  
  1157. /*
  1158.  * Put character using "^" for control characters
  1159.  */
  1160. putChar(c)
  1161.     char c;
  1162. {
  1163.     if (isctlchar(c)) {
  1164.     (void) putchar('^');
  1165.     (void) putchar(unctl(c));
  1166.     }
  1167.     else
  1168.     (void) putchar(c);
  1169. }
  1170.  
  1171. char *
  1172. x_dirname (dir)
  1173.     char *dir;
  1174. {
  1175.     static char dirname [256];
  1176.     char *index();
  1177.  
  1178.     if (*dir != '~')
  1179.     strcpy (dirname, dir);
  1180.     else {
  1181.     struct passwd *pw;
  1182.  
  1183.     if (*(dir+1) == '/' || *(dir+1) == '\0') {
  1184.         pw = getpwuid (getuid ());
  1185.     }
  1186.     else {
  1187.         char user [64], *sp, *dp;
  1188.  
  1189.         for (sp = dir+1, dp = user; *sp && *sp != '/'; sp++, dp++)
  1190.         *dp = *sp;
  1191.         *dp = '\0';
  1192.         pw = getpwnam (user);
  1193.     }
  1194.  
  1195.     if (pw) {
  1196.         strcpy (dirname, pw->pw_dir);
  1197.         if (any ('/', dir))
  1198.         strcat (dirname, index (dir, '/'));
  1199.     }
  1200.     else {
  1201.         strcpy (dirname, dir);
  1202.     }    
  1203.     }
  1204.  
  1205.     return (dirname);
  1206. }
  1207.  
  1208. DIR *
  1209. x_opendir (dir)
  1210.     char *dir;
  1211. {
  1212.     return (opendir (x_dirname (dir)));
  1213. }
  1214.  
  1215. /*
  1216.  * Strring compare for qsort
  1217.  */
  1218. scmp (a, b)
  1219.     char **a, **b;
  1220. {
  1221.  
  1222.     return (strcmp (*a, *b));
  1223. }
  1224.  
  1225. /*
  1226.  * Return 1 if "str" is prefixed by "sub"
  1227.  */
  1228. prefix (sub, str)
  1229.     register char *sub, *str;
  1230. {
  1231.  
  1232.     for (;;) {
  1233.     if (*sub == 0)
  1234.         return (1);
  1235.     if (*str == 0)
  1236.         return (0);
  1237.     if (*sub++ != *str++)
  1238.         return (0);
  1239.     }
  1240. }
  1241.  
  1242. /*
  1243.  * Return 1 if s includes character c
  1244.  */
  1245. any (c, s)
  1246.     register int c;
  1247.     register char *s;
  1248. {
  1249.  
  1250.     while (*s)
  1251.     if (*s++ == c)
  1252.         return(1);
  1253.     return(0);
  1254. }
  1255.  
  1256. #ifndef max
  1257. /*
  1258.  * Return maximum number of d1 and d2
  1259.  */
  1260. max (d1, d2)
  1261.     int d1, d2;
  1262. {
  1263.     return (d1 > d2 ? d1 : d2);
  1264. }
  1265. #endif max
  1266.  
  1267. #else MKARGDEBUG
  1268.  
  1269. #include <stdio.h>
  1270. #include <ctype.h>
  1271.  
  1272. #define MAXARGS    64
  1273.  
  1274. main()
  1275. {
  1276.     char s[128];
  1277.     char *argv[MAXARGS];
  1278.  
  1279.     while (gets (s)) {
  1280.     register int c;
  1281.  
  1282.     showArgs (s);
  1283.     }
  1284. }
  1285. #endif MKARGDEBUG
  1286.  
  1287. showArgs (comline)
  1288.     char *comline;
  1289. {
  1290.     char *argv[MAXARGS];
  1291.     register int c;
  1292.     register char **argp;
  1293.     register int i;
  1294.  
  1295.     c = mkargv (comline, argv, MAXARGS);
  1296.     if (c < 0) {
  1297.     printf ("%s\n", argv[0]);
  1298.     return;
  1299.     }
  1300.     printf ("argc = %d\n", c);
  1301.     for (i = 0, argp = argv; *argp; argp++, i++) {
  1302.     printf ("\"%s\" ", *argp);
  1303.     }
  1304.     printf ("\n");
  1305. }
  1306.  
  1307. mkargv (s, argv, maxarg)
  1308.     char *s;
  1309.     char *argv[];
  1310.     int maxarg;
  1311. {
  1312.     register char *cp;
  1313.     register int argc = 0;
  1314.     int insquot = 0, indquot = 0, ignorenext = 0;
  1315.     enum {STRING, SPACE} status = SPACE;
  1316.     static char buf[1024], *bp;
  1317.  
  1318.     for (cp = s, bp = buf; *cp; cp++) {
  1319.  
  1320.     if (argc > maxarg)
  1321.         return (argc);
  1322.  
  1323.     /*
  1324.      * Found white space
  1325.      */
  1326.     if (isspace (*cp)) {
  1327.         /*
  1328.          * In outside of quotation
  1329.          */
  1330.         if (!ignorenext && !insquot && !indquot) {
  1331.         /*
  1332.          * If status was in string, go next arg
  1333.          */
  1334.         if (status == STRING) {
  1335.             status = SPACE;
  1336.             *bp++ = '\0';
  1337.             continue;
  1338.         }
  1339.         else
  1340.             continue;
  1341.         }
  1342.     }
  1343.  
  1344. #    define SPECIALCHARS "\"\'\\"
  1345.     if (!ignorenext && index (SPECIALCHARS, *cp)) {
  1346.         switch (*cp) {
  1347.  
  1348.         /*
  1349.          * Literal next character
  1350.          */
  1351.         case '\\':
  1352.             if (indquot || insquot)
  1353.             goto THROUGH;
  1354.             else {
  1355.             ignorenext = 1;
  1356.             continue;
  1357.             }
  1358.  
  1359.         /*
  1360.          * Double quotation
  1361.          */
  1362.         case '\"':
  1363.             if (insquot)
  1364.             goto THROUGH;
  1365.             if (indquot && *(bp-1) == '\\') {
  1366.             bp--;
  1367.             goto THROUGH;
  1368.             }
  1369.             indquot = !indquot;
  1370.             break;
  1371.  
  1372.         /*
  1373.          * Single quotation
  1374.          */
  1375.         case '\'':
  1376.             if (indquot)
  1377.             goto THROUGH;
  1378.             if (insquot && *(bp-1) == '\\') {
  1379.             bp--;
  1380.             goto THROUGH;
  1381.             }
  1382.             insquot = !insquot;
  1383.             break;
  1384.             }
  1385.  
  1386.         /*
  1387.          * Only in " or ' case.
  1388.          */
  1389.         if (status == SPACE) {
  1390.         status = STRING;
  1391.         argc++;
  1392.         argv[argc-1] = bp;
  1393.         *bp = 0;
  1394.         }
  1395.         continue;
  1396.     }
  1397.  
  1398. THROUGH:
  1399.     /*
  1400.      * Found non-space character
  1401.      */
  1402.     ignorenext = 0;
  1403.     if (status == SPACE) {
  1404.         status = STRING;
  1405.         argc++;
  1406.         argv[argc-1] = bp;
  1407.     }
  1408.     *bp++ = *cp;
  1409.     }
  1410.  
  1411.     if (indquot || insquot) {
  1412.     argv[0] = indquot ? "Unmatched \"." : "Unmatched \'.";
  1413.     return (-1);
  1414.     }
  1415.  
  1416.     *bp = '\0';
  1417.     argv[argc] = (char *)0;
  1418.     return (argc);
  1419. }
  1420.  
  1421. reverse_strcpy (to, from)
  1422.     register char *to, *from;
  1423. {
  1424.     register int len;
  1425.  
  1426.     for (len = strlen (from); len >= 0; len--)
  1427.     *(to + len) = *(from + len);
  1428. }
  1429.  
  1430. #ifdef KANJI
  1431. /*
  1432.  * Uuuuuuuum. I hate search kanji in Shift-JIS code from the end of string
  1433.  * This function check if i'th character is first byte of KANJI code
  1434.  * in string starting from s.
  1435.  * It is assumed that first byte of strint s can't be second byte of KANJI
  1436.  * code.
  1437.  */
  1438. iskanji_in_string (s, i)
  1439.     char *s;
  1440.     int i;
  1441. {
  1442.     register char *cp = s, *target = s + i;
  1443.  
  1444.     if (i < 0)
  1445.     return (0);
  1446.  
  1447.     while (cp < target) {
  1448.     if (iskanji (*cp))
  1449.         cp += 2;
  1450.     else
  1451.         cp++;
  1452.     }
  1453.  
  1454.     if (cp != target)
  1455.     return (0);
  1456.     else
  1457.     return (iskanji (*cp));
  1458. }
  1459. #endif KANJI
  1460. \End\Of\File\
  1461. else
  1462.   echo "will not over write ./fep_util.c"
  1463. fi
  1464. if `test ! -s ./fep_alias.c`
  1465. then
  1466. echo "writing ./fep_alias.c"
  1467. cat > ./fep_alias.c << '\End\Of\File\'
  1468. /*    Copyright (c) 1987, 1988 by Software Research Associates, Inc.    */
  1469.  
  1470. #ifndef lint
  1471. static char rcsid[]=
  1472. "$Header: fep_alias.c,v 4.0 88/08/05 20:22:00 utashiro Rel $ (SRA)";
  1473. #endif lint
  1474.  
  1475. #include <stdio.h>
  1476. #include <ctype.h>
  1477. #include "fep_defs.h"
  1478. #include "fep_glob.h"
  1479.  
  1480. typedef struct _alias {
  1481.     char *al_name;
  1482.     char *al_value;
  1483.     struct _alias *al_next;
  1484. } ALIAS;
  1485.  
  1486. ALIAS    alias_top = {"top", "top", (ALIAS *)0};
  1487. ALIAS    *alias_list = &alias_top;
  1488. CHAR    aliased_line[MAXCOMLEN+1];
  1489.  
  1490. /*
  1491.  * Functions
  1492.  */
  1493. int    set_alias    (/* char *name, char *value */);
  1494. char    *look_alias    (/* char *name */);
  1495. ALIAS    *getap        (/* char *name */);
  1496.  
  1497. extern    char    *allocAndCopyThere();
  1498. extern    char    *prompt;
  1499.  
  1500. /*
  1501.  * Check alias list, and if found alias change command by its value
  1502.  */
  1503. CHAR *
  1504. check_alias (comline)
  1505.     char *comline;
  1506. {
  1507.     char *argv[MAXARGS];
  1508.     int argc;
  1509.     char *av;
  1510.  
  1511.     while (isspace (*comline))
  1512.     ++comline;
  1513.     if (*comline == NULL)
  1514.     return ((CHAR *)0);
  1515.  
  1516.     argc = mkargv (comline, argv, MAXARGS);
  1517.  
  1518.     if (av = look_alias (argv[0])) {
  1519.     int len = strlen (argv[0]);
  1520.  
  1521.     strcpy (aliased_line, av);
  1522.     strcat (aliased_line, comline + len);
  1523.     return (aliased_line);
  1524.     }
  1525.     else
  1526.     return ((CHAR *)0);
  1527. }
  1528.  
  1529. /*
  1530.  * Set alias
  1531.  */
  1532. set_alias (name, value)
  1533.     char *name, *value;
  1534. {
  1535.     ALIAS *vp;
  1536.  
  1537.     vp = getap (name, 1, 0);
  1538.  
  1539.     if (vp->al_value)
  1540.     free (vp->al_value);
  1541.  
  1542.     vp->al_value = allocAndCopyThere (value);
  1543. }
  1544.  
  1545. /*
  1546.  * Unset alias
  1547.  */
  1548. unset_alias (name)
  1549.     char *name;
  1550. {
  1551.     ALIAS *vp, *prev;
  1552.  
  1553.     vp = getap (name, 0, &prev);
  1554.  
  1555.     if (!vp)
  1556.     return;
  1557.  
  1558.     prev->al_next = vp->al_next;
  1559.     free (vp->al_name);
  1560.     free (vp->al_value);
  1561.     free (vp);
  1562.     return;
  1563. }
  1564.  
  1565. /*
  1566.  * Look up alias
  1567.  */
  1568. char *
  1569. look_alias (name)
  1570.     char *name;
  1571. {
  1572.  
  1573.     ALIAS *vp;
  1574.  
  1575.     vp = getap (name, 0, 0);
  1576.  
  1577.     if (vp && vp->al_value)
  1578.     return (vp->al_value);
  1579.     else
  1580.     return ((char *)0);
  1581. }
  1582.  
  1583. /*
  1584.  * Show alias list
  1585.  */
  1586. show_aliaslist (a)
  1587.     char *a;
  1588. {
  1589.     register ALIAS *vp;
  1590.  
  1591.     for (vp = alias_list->al_next; vp; vp = vp->al_next) {
  1592.     if (a && strcmp (a, vp->al_name))
  1593.         continue;
  1594.     printf ("%-16s %s\n", vp->al_name, vp->al_value);
  1595.     }
  1596. }
  1597.  
  1598.  
  1599. /*
  1600.  * Get pointer to ALIAS.
  1601.  * If there is no memoly associated to the alias and alloc argument is 1,
  1602.  * allocate the area and initialize name field.
  1603.  */
  1604. ALIAS *
  1605. getap (name, alloc, lastvp)
  1606.     char *name;
  1607.     int alloc;
  1608.     ALIAS **lastvp;
  1609. {
  1610.     ALIAS *vp, *last = (ALIAS *)0;
  1611.  
  1612.     for (vp = alias_list->al_next, last = alias_list; vp; last = vp, vp = vp->al_next) {
  1613.     int r;
  1614.  
  1615.     r = strcmp (name, vp->al_name);
  1616.     if (r == 0) {
  1617.         if (lastvp)
  1618.         *lastvp = last;
  1619.         return (vp);
  1620.     }
  1621.     else if (r < 0)
  1622.         break;
  1623.     }
  1624.  
  1625.     if (alloc == 0)
  1626.     return (0);
  1627.  
  1628.     vp = (ALIAS *) calloc (sizeof (ALIAS), 1);
  1629.     vp->al_value = (char *)0;
  1630.     vp->al_next = (ALIAS *) 0;
  1631.     vp->al_name = allocAndCopyThere (name);
  1632.  
  1633.     vp->al_next = last->al_next;
  1634.     last->al_next = vp;
  1635.     return (vp);
  1636. }
  1637. \End\Of\File\
  1638. else
  1639.   echo "will not over write ./fep_alias.c"
  1640. fi
  1641. if `test ! -s ./feprc.sample`
  1642. then
  1643. echo "writing ./feprc.sample"
  1644. cat > ./feprc.sample << '\End\Of\File\'
  1645. #
  1646. # This is a sample .feprc file.
  1647. #
  1648.  
  1649. set alarm-on-eof
  1650. set savehist=50
  1651.  
  1652. echo "Welcome to fep! Editmode is" $editmode
  1653. echo "I'm a front end processor for" $command
  1654.  
  1655. if $editmode == emacs
  1656.     fep-bind delete-to-kill-buffer "\^X\^W"
  1657. endif
  1658.  
  1659. if $command == sh
  1660.     set ignore-eof
  1661.     set history-file .fephistdir/sh
  1662.     set delimiters="     \"';&<>()|^%"
  1663.     set auto-repaint
  1664.     set clear-repaint
  1665.  
  1666.     if $editmode == vi
  1667.         fep-bind list-file-name "\^D"
  1668.     endif
  1669.  
  1670. elseif $command == adb
  1671.     set history-file .fephistdir/adb
  1672.  
  1673. elseif $command == bc
  1674.     unset alarm-on-eof
  1675.     unset alarm-on-eof
  1676.  
  1677. elseif $command == dbx
  1678.     set history-file .fephistdir/dbx
  1679.  
  1680. else
  1681.     echo "History will be saved to" $history-file
  1682. endif
  1683. \End\Of\File\
  1684. else
  1685.   echo "will not over write ./feprc.sample"
  1686. fi
  1687. if `test ! -s ./README`
  1688. then
  1689. echo "writing ./README"
  1690. cat > ./README << '\End\Of\File\'
  1691. Copyright (c) 1987,1988 by Software Research Associates, Inc.
  1692.  
  1693. FEP is a general purpose front end for any line-oriented command on
  1694. UNIX. This command was developed on Berkeley UNIX, but will probably
  1695. run on most UNIX system which have pseudo tty and the select system
  1696. call.
  1697.  
  1698. Making FEP
  1699.  
  1700.     Just type 'make'.
  1701.     If your system is running ASCII UNIX or some compatible system,
  1702.     the -DKANJI flag makes fep handle kanji character input.
  1703.  
  1704. Using FEP
  1705.  
  1706.     See man page fep.1 for detail.
  1707.     The help command (ESC-?) and show-bindings command (^X-^B) are
  1708.     very convenient when running fep.
  1709.  
  1710. Distribution
  1711.  
  1712.     Distribution without fee is permitted as long as all
  1713.     copyright notices are included.
  1714.  
  1715. Any comments will be greatly appreciated. Have fun.
  1716.  
  1717.             Kazumasa Utashiro
  1718.             Software Research Associates, Inc.
  1719.             1-1-1 Hirakawa-cho, Chiyoda-ku, Tokyo 102, Japan
  1720.                 UUCP:    kddlab!srava.sra.junet!utashiro
  1721.                 ARPA:    utashiro%sra.junet@uunet.uu.net
  1722.                 JUNET:    utashiro@sra.junet
  1723. \End\Of\File\
  1724. else
  1725.   echo "will not over write ./README"
  1726. fi
  1727. echo "Finished archive 1 of 5"
  1728. exit
  1729.  
  1730.