home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d352 / mg.lha / MG / src.LZH / mg / extend.c < prev    next >
C/C++ Source or Header  |  1990-05-23  |  7KB  |  320 lines

  1. /*
  2.  * Extended commands (M-X) and startup file processing.
  3.  */
  4.  
  5. #include "no_startup.h"
  6. #include "no_macro.h"
  7. #include "fkeys.h"
  8. #include "do_eval.h"
  9. #include "def.h"
  10.  
  11. #ifndef    NO_MACRO
  12. #include "macro.h"
  13. #endif
  14.  
  15. #include "line.h"
  16. #include "buffer.h"
  17.  
  18. #ifdef    ANSI
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #endif
  22.  
  23. static char    *skipwhite
  24.                 PROTO((char *s, char *end));
  25. static char    *skiptowhite
  26.                 PROTO((char *s, char *end));
  27. static KCHAR    backquote
  28.                 PROTO((char **inp));
  29.  
  30. /*
  31.  * Extended command. Call the message line routine to read in the command
  32.  * name and apply autocompletion to it. When it comes back, look the name up
  33.  * in the symbol table and run the command if it is found. Print an error if
  34.  * there is anything wrong.
  35.  */
  36. extend(f, n)
  37. {
  38.     int             (*funct) PROTO((int, int));
  39. #ifndef    NO_MACRO
  40.     struct macro   *m;
  41. #endif
  42.     int             s;
  43.     char            xname[NXNAME];
  44.  
  45.     if (!(f & FFARG))
  46.         s = eread("M-x ", xname, NXNAME, EFNEW | EFFUNC);
  47.     else
  48.         s = eread("%d M-x ", xname, NXNAME, EFNEW | EFFUNC, n);
  49.     if (s != TRUE)
  50.         return s;
  51.     if ((funct = name_function(xname)) != NULL)
  52.         return (*funct) (f, n);
  53. #ifndef    NO_MACRO
  54.     else if ((m = find_macro(xname)) != NULL)
  55.         return runmacro(m, f, n, FALSE);
  56. #endif
  57.     ewprintf("[No match]");
  58.     return FALSE;
  59. }
  60.  
  61. #ifdef DO_EVAL
  62. /*
  63.  * Define the commands needed to do startup-file processing. This code is
  64.  * mostly a kludge just so we can get startup-file processing.
  65.  * 
  66.  * We define eval-expression because it's easy.     It can make *-set-key or
  67.  * define-key set an arbitrary key sequence, so it isn't useless.
  68.  */
  69.  
  70. /*
  71.  * evalexpr - get one line from the user, and run it.
  72.  */
  73. /* ARGSUSED */
  74. evalexpr(f, n)
  75. {
  76.     int             s;
  77.     char            exbuf[NXNAME];
  78.  
  79.     if ((s = ereply("Eval: ", exbuf, NXNAME)) != TRUE)
  80.         return s;
  81.     return excline(exbuf, strlen(exbuf));
  82. }
  83. /*
  84.  * evalbuffer - evaluate the current buffer as line commands. Useful for
  85.  * testing startup files.
  86.  */
  87. /* ARGSUSED */
  88. evalbuffer(f, n)
  89. {
  90.     register struct line *lp;
  91.     register struct buffer *bp = curbp;
  92.     register int    s;
  93.  
  94.     for (lp = lforw(bp->b_linep); lp != bp->b_linep; lp = lforw(lp)) {
  95.         if (llength(lp) >= NLINE)
  96.             return FALSE;
  97.         if ((s = excline(ltext(lp), llength(lp))) != TRUE)
  98.             return s;
  99.     }
  100.     return TRUE;
  101. }
  102. /*
  103.  * evalfile - go get a file and evaluate it as line commands. You can go get
  104.  * your own startup file if need be.
  105.  */
  106. /* ARGSUSED */
  107. evalfile(f, n)
  108. {
  109.     register int    s;
  110.     char            fname[NFILEN];
  111.  
  112.     if ((s = ereply("Load file: ", fname, NFILEN)) != TRUE)
  113.         return s;
  114.     return load(fname);
  115. }
  116.  
  117. /*
  118.  * load - go load the file name we got passed.
  119.  */
  120. load(fname)
  121.     char           *fname;
  122. {
  123.     int             s = TRUE;
  124.     int             nbytes;
  125.     char            excbuf[128];
  126.  
  127.     if ((fname = adjustname(fname)) == NULL)
  128.         return FALSE;    /* just to be careful */
  129.  
  130.     if (ffropen(fname) != FIOSUC)
  131.         return FALSE;
  132.     while ((s = ffgetline(excbuf, sizeof(excbuf) - 1, &nbytes)) == FIOSUC) {
  133.         if (excline(excbuf, nbytes) != TRUE) {
  134.             s = FIOERR;
  135.             ewprintf("Error loading file %s", fname);
  136.             break;
  137.         }
  138.     }
  139.     (VOID) ffclose();
  140.     if (s != FIOEOF || (nbytes && excline(excbuf, nbytes) != TRUE))
  141.         return FALSE;
  142.     return TRUE;
  143. }
  144.  
  145. /*
  146.  * excline - run a line from a load file or eval-expression.
  147.  */
  148. excline(line, len)
  149.     char    *line;
  150.     int    len;
  151. {
  152.     /* end points to where the terminating null should be */
  153.     char           *funcp, *argp = NULL, *end, *inline;
  154.     struct macro   *eval;
  155.     int             status;
  156.  
  157.     /* Make a copy we can scrawl on */
  158.     if (len == 0) return TRUE ;
  159.     if ((inline = malloc(len + 1)) == NULL) return FALSE ;
  160.     (VOID) bcopy(line, inline, len + 1);
  161.     line = inline ;
  162.  
  163.     end = line + len;    /* End of string marker */
  164.     funcp = skipwhite(line, end);
  165.     if (funcp >= end) {
  166.         free(inline) ;
  167.         return TRUE;    /* No error on blank lines */
  168.         }
  169.     line = skiptowhite(funcp, end);
  170.     *line++ = '\0';
  171.     if (line < end) {
  172.         argp = skipwhite(line, end);
  173.         if (*argp != '-' && (*argp < '0' || '9' < *argp))
  174.             argp = NULL;
  175.         else {
  176.             line = skiptowhite(argp, end);
  177.             *line++ = '\0';
  178.         }
  179.     }
  180.     if ((eval = (struct macro *) malloc(sizeof(struct macro))) == NULL) {
  181.         free(inline) ;
  182.         return FALSE;
  183.         }
  184.     eval->m_count = eval->m_max = 0;
  185.     eval->m_text = eval->m_cur = NULL;
  186.     if (argp != NULL) {
  187.         add_key_to_macro(CCHR('U'), eval);
  188.         add_string_to_macro(argp, eval);
  189.     }
  190.     add_key_to_macro(METACH, eval);
  191.     add_key_to_macro('X', eval);
  192.  
  193.     /* Pack in function */
  194.     add_string_to_macro(funcp, eval);
  195.     add_key_to_macro(SOFTCR, eval);
  196.  
  197.     /* Pack away all the args now...     */
  198.     while (line < end) {
  199.         argp = skipwhite(line, end);
  200.         if (argp >= end)
  201.             break;
  202.  
  203.         if (*argp != '"') {
  204.             line = skiptowhite(argp, end);
  205.             *line++ = '\0';
  206.             add_string_to_macro(argp, eval);
  207.         } else {        /* Quoted strings special again */
  208.             ++argp;
  209.             while (*argp != '"' && argp < end) {
  210.                 if (*argp != '\\')
  211.                     add_key_to_macro((KCHAR) *argp++, eval);
  212.                 else
  213.                     add_key_to_macro(backquote(&argp), eval);
  214.             }
  215.             line = argp + 1;
  216.         }
  217.         add_key_to_macro(SOFTCR, eval);
  218.     }
  219.     status = runmacro(eval, FFOTHARG, 1, TRUE);
  220.     free((char *) eval->m_text);
  221.     free((char *) eval);
  222.     free(inline) ;
  223.     return status;
  224. }
  225. /*
  226.  * a pair of utility functions for the above
  227.  */
  228. static char    *
  229. skipwhite(s, end)
  230.     register char  *s;
  231.     register char  *end;
  232. {
  233.     while (*s == ' ' || *s == '\t' && s < end)
  234.         s++;
  235.     if (*s == ';')
  236.         return end;
  237.     return s;
  238. }
  239.  
  240. static char    *
  241. skiptowhite(s, end)
  242.     register char  *s;
  243.     register char  *end;
  244. {
  245.     while (s < end && *s != ' ' && *s != '\t')
  246.         s++;
  247.     return s;
  248. }
  249.  
  250. /*
  251.  * Put a backquoted string element into the keyboard macro. Return pointer to
  252.  * char following backquoted stuff.
  253.  */
  254. static          KCHAR
  255. backquote(inp)
  256.     char          **inp;
  257. {
  258.     register char  *in;
  259.     register KCHAR  c;
  260.  
  261.     in = *inp;
  262.     in += 1;        /* Skip over backquote */
  263.     c = *in++;
  264.     switch (ISUPPER(c) ? TOLOWER(c) : c) {
  265.     case 't':
  266.         c = CCHR('I');
  267.         break;
  268.     case 'n':
  269.         c = CCHR('J');
  270.         break;
  271.     case 'r':
  272.         c = CCHR('M');
  273.         break;
  274.     case '^':
  275.         c = *in++;
  276.         if (ISLOWER(c))
  277.             c = TOUPPER(c);
  278.         c = CCHR(c);
  279.         break;
  280.     case 'e':
  281.         c = METACH;
  282.         break;
  283. #ifdef    FKEYS
  284.     case 'f':
  285.         c = 0;
  286.         if (ISDIGIT(*in))
  287.             c += *in++ - '0';
  288.         if (ISDIGIT(*in))
  289.             c = (10 * c) + *in++ - '0';
  290.         if ((c += KFIRST) > KLAST)
  291.             c = KLAST;
  292.         break;
  293. #endif
  294.     case '0':
  295.     case '1':
  296.     case '2':
  297.     case '3':
  298.     case '4':
  299.     case '5':
  300.     case '6':
  301.     case '7':
  302.         c = *in - '0';
  303.         if (in[1] <= '7' && in[1] >= '0') {
  304.             c <<= 3;
  305.             c += *++in - '0';
  306.             if (in[1] <= '7' && in[1] >= '0') {
  307.                 c <<= 3;
  308.                 c += *++in - '0';
  309.             }
  310.         }
  311.         break;
  312.     default:
  313.         c = CHARMASK(c);
  314.         break;
  315.     }
  316.     *inp = in;        /* put the pointer back */
  317.     return c;
  318. }
  319. #endif
  320.