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

  1. /* keyboard macros for MicroGnuEmacs 3a */
  2.  
  3. #include    "no_macro.h"
  4.  
  5. #ifndef NO_MACRO
  6. #include "fkeys.h"
  7. #include "def.h"
  8. #include "macro.h"
  9. #include "key.h"
  10.  
  11. #ifdef    ANSI
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #endif
  15.  
  16. /* KBD macro grows by MGROWSIZE macros at a time */
  17. #define    MGROWSIZE    50
  18.  
  19. int             macrodef;
  20. struct macro   *inmacro = NULL;
  21. struct macro    kbdmacro;
  22. static struct macro savemac;    /* Place to put macro being defined */
  23.  
  24. static int      growmacro
  25. PROTO((struct macro *));
  26. static struct macro *makemacro
  27. PROTO((char *, KCHAR *, int));
  28. static int      finsert
  29. PROTO((KCHAR));
  30.  
  31. /* ARGSUSED */
  32. definemacro(f, n)
  33.     int             f, n;
  34. {
  35.     if (macrodef) {
  36.         ewprintf("Already defining macro!");
  37.         return macrodef = FALSE;
  38.     }
  39.     savemac = kbdmacro;
  40.     kbdmacro.m_max = kbdmacro.m_count = 0;
  41.     kbdmacro.m_text = NULL;
  42.     ewprintf("Defining Keyboard Macro...");
  43.     return macrodef = TRUE;
  44. }
  45.  
  46. /* ARGSUSED */
  47. finishmacro(f, n)
  48.     int             f, n;
  49. {
  50.     if (inmacro)
  51.         return TRUE;
  52.     if (!macrodef) {
  53.         ewprintf("Not defining kbd macro.");
  54.         return FALSE;
  55.     }
  56.     ewprintf("Keyboard macro defined");
  57.     macrodef = FALSE;
  58.     if (savemac.m_text)
  59.         free((char *) savemac.m_text);
  60.     if ((f & FFARG) == 0)
  61.         kbdmacro.m_count -= key.k_count;
  62.     else if (n != 1)
  63.         return runmacro(&kbdmacro, f, n - 1, FALSE);
  64.     return TRUE;
  65. }
  66.  
  67. VOID
  68. restore_macro()
  69. {
  70.  
  71.     if (kbdmacro.m_max > 0)
  72.         free((char *) kbdmacro.m_text);
  73.     kbdmacro = savemac;
  74. }
  75.  
  76. /* ARGSUSED */
  77. executemacro(f, n)
  78.     int             f, n;
  79. {
  80.     if (macrodef) {
  81.         ewprintf("Can't execute anonymous macro while defining one");
  82.         return FALSE;
  83.     }
  84.     if (kbdmacro.m_count == 0) {
  85.         ewprintf("No kbd macro has been defined");
  86.         return FALSE;
  87.     }
  88.     return runmacro(&kbdmacro, f, n, FALSE);
  89. }
  90.  
  91. runmacro(run, f, count, onecommand)
  92.     struct macro   *run;
  93.     int             f, count, onecommand;
  94. {
  95.     int             status = TRUE;
  96.     struct macro   *save;
  97.  
  98.     if (run->m_count == 0)
  99.         return TRUE;
  100.     run->m_max = (f & FFARG) ? count : 1;
  101.     save = inmacro;
  102.     inmacro = run;
  103.     while (run->m_max != 0) {
  104.         run->m_cur = run->m_text;
  105.         while (run->m_cur - run->m_text < run->m_count) {
  106.             if ((status = doin()) != TRUE || onecommand) {
  107.                 /* Error or abort */
  108.                 run->m_max = 0;
  109.                 break;
  110.             }
  111.             lastflag = thisflag;
  112.             thisflag = 0;
  113.         }
  114.         if (run->m_max > 0)
  115.             run->m_max -= 1;
  116.     }
  117.     inmacro = save;
  118.     return status != TRUE ? status
  119.         : (run->m_cur - run->m_text < run->m_count
  120.            ? FALSE
  121.            : TRUE);
  122. }
  123.  
  124. VOID
  125. add_key_to_macro(c, mac)
  126.     KCHAR           c;
  127.     struct macro   *mac;
  128. {
  129.  
  130.     if (mac->m_count >= mac->m_max && growmacro(mac) != TRUE)
  131.         return;
  132.     mac->m_text[mac->m_count++] = c;
  133. }
  134.  
  135. VOID
  136. add_string_to_macro(string, mac)
  137.     char           *string;
  138.     struct macro   *mac;
  139. {
  140.     int             length;
  141.  
  142.     if (!string)
  143.         return;
  144.     length = strlen(string);
  145.     while (length + mac->m_count >= mac->m_max)
  146.         if (growmacro(mac) != TRUE)
  147.             return;
  148.     while (*string)
  149.         mac->m_text[mac->m_count++] = *string++;
  150. }
  151.  
  152. static int
  153. growmacro(mac)
  154.     struct macro   *mac;
  155. {
  156.     KCHAR          *oldtext;
  157.     int             size;
  158.  
  159.     oldtext = mac->m_text;
  160.     size = mac->m_max + MGROWSIZE;
  161.     if ((mac->m_text = (KCHAR *) malloc(size * sizeof(KCHAR))) == NULL) {
  162.         ewprintf("Can't get %d bytes", size * sizeof(KCHAR));
  163.         mac->m_text = oldtext;
  164.         return FALSE;
  165.     }
  166.     bcopy((char *) oldtext, (char *) mac->m_text,
  167.           mac->m_count * sizeof(KCHAR));
  168.     free((char *) oldtext);
  169.     mac->m_max = size;
  170.     return TRUE;
  171. }
  172.  
  173. insertmacro(f, n)
  174.     int             f, n;
  175. {
  176.     register KCHAR *k;
  177.     register int    i;
  178.     char            macname[NMACN];
  179.     struct macro   *out;
  180.  
  181.     if (eread("Insert kbd macro (name): ", macname, NMACN, EFNEW | EFMACRO) != TRUE)
  182.         return FALSE;
  183.     if ((out = find_macro(macname)) == NULL) {    /* shouldn't happen */
  184.         ewprintf("Macro %s not found!", macname);
  185.         return FALSE;
  186.     }
  187.     if (sinsert("fset ") == FALSE || sinsert(macname) == FALSE
  188.         || sinsert(" \"") == FALSE)
  189.         return FALSE;
  190.     /* Insert all chars but the C-x ) used to end it */
  191.     for (k = out->m_text, i = out->m_count; i > 0; i -= 1, k += 1)
  192. #ifdef    FKEYS
  193.         if (*k >= KFIRST && *k <= KLAST) {
  194.             if (sinsert("\\f") == FALSE)
  195.                 return FALSE ;
  196.             if (finsert((KCHAR) (*k - KFIRST)) == FALSE)
  197.                 return FALSE ;
  198.         } else
  199. #endif    
  200.         if (*k < ' ') {
  201.             if (sinsert("\\^") == FALSE || linsert(1, CCHR(*k)) == FALSE)
  202.                 return FALSE;
  203.         } else if (*k == '"') {
  204.             if (sinsert("\\\"") == FALSE)
  205.                 return FALSE;
  206.         } else if (*k == '\\') {
  207.             if (sinsert("\\\\") == FALSE)
  208.                 return FALSE;
  209.         } else if (*k > CCHR('?')) {
  210.             if (linsert(1, '\\') == FALSE || finsert(*k) == FALSE)
  211.                 return FALSE;
  212.         } else if (linsert(1, *k) == FALSE)
  213.             return FALSE;
  214.  
  215.     if (sinsert("\"\n") == FALSE)
  216.         return FALSE;
  217.     if (f & FFARG)
  218.         sinsert("; Need to put binding code here\n");
  219.     return TRUE;
  220. }
  221.  
  222. macroset(f, n)
  223.     int             f, n;
  224. {
  225.     register int    c, count;
  226.     struct macro   *out;
  227.     char            macname[NMACN];
  228.     KCHAR           mactext[NXNAME];
  229.  
  230.     if (!inmacro)
  231.         return FALSE;    /* Only useable from eval-expression */
  232.  
  233.     if (eread("", macname, NMACN, EFNEW) != TRUE)
  234.         return FALSE;
  235.     count = 0;
  236.     while ((c = getkey(SEESCR)) != SOFTCR) {
  237.         if (count >= NXNAME)
  238.             return FALSE;
  239.         mactext[count++] = c;
  240.     }
  241.     if ((out = makemacro(macname, mactext, count)) == NULL)
  242.         return FALSE;
  243.     return TRUE;
  244. }
  245.  
  246. macroquery(f, n)
  247.     int             f, n;
  248. {
  249.     struct macro   *save;
  250.  
  251.     if (macrodef)
  252.         return TRUE;
  253.     if (!inmacro) {
  254.         ewprintf("Not defining or executing kbd macro");
  255.         return TRUE;
  256.     }
  257.     save = inmacro;
  258.     inmacro = NULL;
  259.     update();
  260.     for (;;) {
  261.         ewprintf("Proceed with macro? (Space, DEL or C-d)");
  262.         switch (getkey(FALSE)) {
  263.         case CCHR('G'):
  264.             return ABORT;
  265.         case CCHR('D'):/* Terminate all reps */
  266.             save->m_max = 1;
  267.             /* no more reps, so fall through to */
  268.         case CCHR('?'):/* Terminate this repition */
  269.             save->m_cur = &(save->m_text[save->m_count + 1]);
  270.         case ' ':    /* Keep going as as is */
  271.             eerase();
  272.             inmacro = save;
  273.             return TRUE;
  274.         }
  275.     }
  276. }
  277.  
  278. namemacro(f, n)
  279.     int             f, n;
  280. {
  281.     struct macro   *out;
  282.     char            macname[NMACN];
  283.  
  284.     /* Get a valid name */
  285.     if (kbdmacro.m_count == 0) {
  286.         ewprintf("No keyboard macro defined");
  287.         return FALSE;
  288.     }
  289.     if (eread("Name for last kbd macro: ", macname, NMACN, EFNEW) != TRUE)
  290.         return FALSE;
  291.  
  292.     if ((out = makemacro(macname, kbdmacro.m_text, kbdmacro.m_count)) == NULL)
  293.         return FALSE;
  294.     return TRUE;
  295. }
  296.  
  297. static struct macro *
  298. makemacro(name, text, count)
  299.     char           *name;
  300.     KCHAR          *text;
  301.     int             count;
  302. {
  303.     register struct macro *out;
  304.     char           *ntmp;
  305.     KCHAR          *ctmp;
  306.  
  307.     /* Space for strings */
  308.     if ((ntmp = (char *) malloc(strlen(name) + 1)) == NULL) {
  309.         ewprintf("Can't get %d bytes", strlen(name) + 1);
  310.         return NULL;
  311.     }
  312.     if ((ctmp = (KCHAR *) malloc(count * sizeof(KCHAR))) == NULL) {
  313.         ewprintf("Can't get %d bytes", count * sizeof(KCHAR));
  314.         free(ntmp);
  315.         return NULL;
  316.     }
  317.     if (name_function(name) != NULL) {
  318.         ewprintf("Function %s is already defined and not a keyboard macro.",
  319.              name);
  320.         return NULL;
  321.     }
  322.     /* Get a macro to (re)use */
  323.     if ((out = find_macro(name)) != NULL) {
  324.         free(out->m_name);
  325.         free(out->m_text);
  326.     } else if ((out = (struct macro *) malloc(sizeof(struct macro))) == NULL) {
  327.         ewprintf("Can't get %d bytes", sizeof(struct macro));
  328.         free((char *) (ctmp));
  329.         free(ntmp);
  330.         return NULL;
  331.     } else {        /* Add the new macro to the chain */
  332.         out->m_macp = kbdmacro.m_macp;
  333.         kbdmacro.m_macp = out;
  334.     }
  335.  
  336.     /* Now, fill the silly bugger */
  337.     bcopy((char *) text, (char *) ctmp, count * sizeof(KCHAR));
  338.     strcpy(ntmp, name);
  339.     out->m_text = ctmp;
  340.     out->m_cur = NULL;
  341.     out->m_max = 0;
  342.     out->m_count = count;
  343.     out->m_name = ntmp;
  344.     return out;
  345. }
  346.  
  347. struct macro   *
  348. find_macro(name)
  349.     char           *name;
  350. {
  351.     register struct macro *out;
  352.  
  353.     if (!name)
  354.         return NULL;
  355.     out = kbdmacro.m_macp;
  356.     while (out) {
  357.         if (strcmp(out->m_name, name) == 0)
  358.             return out;
  359.         out = out->m_macp;
  360.     }
  361.     return NULL;
  362. }
  363.  
  364. /*
  365.  * Insert a string into the current buffer. For insertmacro. 
  366.  */
  367. sinsert(s)
  368.     register char  *s;
  369. {
  370.  
  371.     while (*s) {
  372.         if (((*s == '\n') ? lnewline() : linsert(1, *s)) != TRUE)
  373.             return FALSE;
  374.         s += 1;
  375.     }
  376.     return TRUE;
  377. }
  378.  
  379. /*
  380.  * insert a number into the current buffer. For insertmacro. 
  381.  */
  382. static
  383. finsert(k)
  384.     register KCHAR  k;
  385. {
  386.  
  387.     if (k > 7 && finsert((KCHAR) (k >> 3)) == FALSE)
  388.         return FALSE;
  389.     return linsert(1, (k & 7) + '0');
  390. }
  391.  
  392. #else
  393. #include "nullfile.h"
  394. #endif
  395.