home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d131 / mg1b.lha / Mg1b / Source / main.c < prev    next >
C/C++ Source or Header  |  1988-03-14  |  8KB  |  337 lines

  1. /*
  2.  *        Mainline, macro commands.
  3.  */
  4. #include    "def.h"
  5.  
  6. int    thisflag;            /* Flags, this command        */
  7. int    lastflag;            /* Flags, last command        */
  8. int    curgoal;            /* Goal column            */
  9. BUFFER    *curbp;                /* Current buffer        */
  10. WINDOW    *curwp;                /* Current window        */
  11. BUFFER    *bheadp;            /* BUFFER listhead        */
  12. WINDOW    *wheadp = (WINDOW *)NULL;    /* WINDOW listhead        */
  13. KEY    kbdm[NKBDM];            /* Macro            */
  14. KEY    *kbdmip;            /* Input  for above        */
  15. KEY    *kbdmop;            /* Output for above        */
  16. KEY    *kbdnext;            /* one past the end of the current */
  17. KEY    *kbdloc();            /* Takes a key and installs it  */
  18. char    pat[NPAT];            /* Pattern            */
  19. #ifdef    HASH
  20. SYMBOL    *symbol[NSHASH];        /* Symbol table listhead.    */
  21. #else
  22. /* should really be a *symbol, but don't want to break the hash code yet */
  23. SYMBOL  *symbol[1] = {(SYMBOL *)NULL};
  24. #endif
  25. SYMBOL    *binding[NKEYS];        /* Key bindings.        */
  26. #ifdef    DPROMPT
  27. extern char prompt[], *promptp;        /* delayed prompting        */
  28. #endif
  29. VOID    edinit();
  30.  
  31. VOID
  32. main(argc, argv) char *argv[]; {
  33.     register KEY    c;
  34.     register int    f;
  35.     register int    n;
  36.     register int    mflag;
  37. #ifdef    STARTUP
  38.     char        *sfile, *startupfile();
  39. #endif
  40.     char        bname[NBUFN];
  41.  
  42.     kbdminit();                /* initialize macros */
  43. #ifdef SYSINIT
  44.     SYSINIT;                /* system dependent.    */
  45. #endif
  46.     vtinit();                /* Virtual terminal.    */
  47.     edinit();                /* Buffers, windows.    */
  48.     keymapinit();                /* Symbols, bindings.    */
  49.     /* doing update() before reading files causes the error messages from
  50.      * the file I/O show up on the screen.  (and also an extra display
  51.      * of the mode line if there are files specified on the command line.)
  52.      */
  53.     update();
  54. #ifdef    STARTUP                    /* User startup file.    */
  55.     if ((sfile = startupfile()) != NULL)
  56.         (VOID) load(sfile);
  57. #endif
  58.     while (--argc > 0) {
  59.         adjustcase(*++argv);
  60.                 makename(bname, *argv);
  61.         curbp = bfind(bname, TRUE);
  62.         (VOID) showbuffer(curbp, curwp, 0);
  63.         (VOID) readin(*argv);
  64.     }
  65.     lastflag = 0;                /* Fake last flags.    */
  66. loop:
  67. #ifdef    DPROMPT
  68.     *(promptp = prompt) = '\0';
  69.     if(epresf == KPROMPT) eerase();
  70. #endif
  71.     update();                /* Fix up the screen.    */
  72.     c = getkey(KPROMPT);
  73.     if (epresf == TRUE) {
  74.         eerase();
  75.         update();
  76.     }
  77.     f = FALSE;
  78.     n = 1;
  79.     if (((KMETA|'0') <= c && c <= (KMETA|'9')) || c == (KMETA|'-')) {
  80.         f = TRUE;
  81.         c = c & ~KMETA;
  82.     } else if (c == (KCTRL|'U')) {
  83.         f = TRUE;
  84.         n = 4;
  85.         while ((c=getkey(KNOMAC | KPROMPT)) == (KCTRL|'U')) 
  86.             n *= 4;
  87.     }
  88.     if (f == TRUE) {
  89.         if ((c>='0' && c<='9') || c=='-') {
  90.             if (c == '-') {
  91.                 n = 0;
  92.                 mflag = TRUE;
  93.             } else {
  94.                 n = ((int) c) - '0';
  95.                 mflag = FALSE;
  96.             }
  97.             while ((c=getkey(KNOMAC | KPROMPT))>='0' && c<='9')
  98.                 n = 10*n + ((int) c) - '0';
  99.             if (mflag != FALSE)
  100.                 n = -n;
  101.         }
  102.     }
  103.     if (kbdmip != NULL) {            /* Terminate macros.    */
  104.         if (c!=(KCTLX|')') && kbdmip>&kbdm[NKBDM-6]) {
  105.             (VOID) ctrlg(FALSE, 0, KRANDOM);
  106.             goto loop;
  107.         }
  108.         if (f != FALSE) {
  109.             kbdmip[-1] = (KEY) (KCTRL|'U');/* overwrite ESC */
  110.             *kbdmip++ = (KEY) n;
  111.             *kbdmip++ = (KEY) c;
  112.         }
  113.     }
  114.     switch (execute(c, f, n)) {        /* Do it.        */
  115.         case TRUE: break;
  116.         case ABORT:
  117.                ewprintf("Quit");    /* and fall through */
  118.         case FALSE: default:
  119.                ttbeep();
  120.                if (kbdmip != NULL) {
  121.                    kbdm[0] = (KEY) (KCTLX|')');
  122.                    kbdmip = NULL;
  123.                    kbdnext = kbdm + 1 ;
  124.                }
  125.     }
  126.     goto loop;
  127. }
  128.  
  129. /*
  130.  * Command execution. Look up the binding in the the
  131.  * binding array, and do what it says. Return a very bad status
  132.  * if there is no binding, or if the symbol has a type that
  133.  * is not usable (there is no way to get this into a symbol table
  134.  * entry now). Also fiddle with the flags.
  135.  */
  136. execute(c, f, n) KEY c; {
  137.     register SYMBOL    *sp;
  138.     register int    status;
  139.  
  140.     if ((sp=binding[c]) != NULL) {
  141.         thisflag = 0;
  142.         status = (*sp->s_funcp)(f, n, c);
  143.         lastflag = thisflag;
  144.         return (status);
  145.     }
  146.     lastflag = 0;
  147.     return (FALSE);
  148. }
  149.  
  150. /*
  151.  * Initialize all of the buffers
  152.  * and windows. The buffer name is passed down as
  153.  * an argument, because the main routine may have been
  154.  * told to read in a file by default, and we want the
  155.  * buffer name to be right.
  156.  */
  157. VOID
  158. edinit() {
  159.     register BUFFER    *bp;
  160.     register WINDOW    *wp;
  161.  
  162.     bheadp = NULL;
  163.     bp = bfind("*scratch*", TRUE);        /* Text buffer.        */
  164.     wp = (WINDOW *)malloc(sizeof(WINDOW));    /* Initial window.    */
  165.     if (bp==NULL || wp==NULL) panic("edinit");
  166.     curbp  = bp;                /* Current ones.    */
  167.     wheadp = wp;
  168.     curwp  = wp;
  169.     wp->w_wndp  = NULL;            /* Initialize window.    */
  170.     wp->w_bufp  = bp;
  171.     bp->b_nwnd  = 1;            /* Displayed.        */
  172.     wp->w_linep = bp->b_linep;
  173.     wp->w_dotp  = bp->b_linep;
  174.     wp->w_doto  = 0;
  175.     wp->w_markp = NULL;
  176.     wp->w_marko = 0;
  177.     wp->w_toprow = 0;
  178.     wp->w_ntrows = nrow-2;            /* 2 = mode, echo.    */
  179.     wp->w_force = 0;
  180.     wp->w_flag  = WFMODE|WFHARD;        /* Full.        */
  181. }
  182.  
  183. /*
  184.  * Quit command. If an argument, always
  185.  * quit. Otherwise confirm if a buffer has been
  186.  * changed and not written out. Normally bound
  187.  * to "C-X C-C".
  188.  */
  189. /*ARGSUSED*/
  190. quit(f, n, k) {
  191.     register int    s;
  192.  
  193.     if ((s = anycb(FALSE)) == ABORT) return ABORT;
  194.     if (s == FALSE
  195.     || eyesno("Some modified buffers exist, really exit") == TRUE) {
  196.         vttidy();
  197.         exit(GOOD);
  198.     }
  199.     return TRUE;
  200. }
  201.  
  202. /*
  203.  * Begin a keyboard macro.
  204.  * Error if not at the top level
  205.  * in keyboard processing. Set up
  206.  * variables and return.
  207.  *
  208.  *   Note that if we define a macro from another macro or
  209.  *   the startup file, we don't execute the thing.
  210.  */
  211. /*ARGSUSED*/
  212. ctlxlp(f, n, k) {
  213.     if (kbdmip!=NULL) {
  214.         ewprintf("Already defining kbd macro!");
  215.         return (FALSE);
  216.     }
  217.     if (kbdmop) {
  218.         kbdmip = kbdm ;
  219.         while (*kbdmop != (KCTLX|')'))
  220.             *kbdmip++ = *kbdmop++ ;
  221.         *kbdmip++ = *kbdmop++ ;
  222.         kbdnext = kbdmip ;
  223.         kbdmip = NULL ;
  224.         return(TRUE) ;
  225.     } else {
  226.         ewprintf("Defining kbd macro...");
  227.         kbdmip = kbdm;
  228.         return (TRUE);
  229.     }
  230. }
  231.  
  232. /*
  233.  * End keyboard macro. Check for
  234.  * the same limit conditions as the
  235.  * above routine. Set up the variables
  236.  * and return to the caller.
  237.  */
  238. /*ARGSUSED*/
  239. ctlxrp(f, n, k) {
  240.     if (kbdmip == NULL) {
  241.         ewprintf("Not defining kbd macro.");
  242.         return (FALSE);
  243.     }
  244.     ewprintf("Keyboard macro defined");
  245.     kbdnext = kbdmip ;
  246.     kbdmip = NULL;
  247.     return (TRUE);
  248. }
  249.  
  250. /*
  251.  * Execute a macro.
  252.  * The command argument is the
  253.  * number of times to loop. Quit as
  254.  * soon as a command gets an error.
  255.  * Return TRUE if all ok, else
  256.  * FALSE.
  257.  */
  258. /*ARGSUSED*/
  259. ctlxe(f, n, k) {
  260.     register KEY    c;
  261.     register int    af;
  262.     register int    an;
  263.     register int    s;
  264.     register KEY    *skbdmip ;
  265.  
  266.     if (kbdmip && k==(KCTLX | 'E')) {
  267.         ewprintf("Not now") ;
  268.         flushkbdm() ;
  269.         return(FALSE) ;
  270.     }
  271.     skbdmip = kbdmip ;
  272.     kbdmip = NULL ;
  273.     if (kbdmop!=NULL) {
  274.         if (pushkbdm(kbdmop)) {
  275.            ewprintf("Out of macro stack") ;
  276.            flushkbdm() ;
  277.            kbdmip = skbdmip ;
  278.            return(FALSE) ;
  279.         }
  280.     }
  281.     if (n < 0) {
  282.         popkbdm() ;
  283.         kbdmip = skbdmip ;
  284.         return (TRUE);
  285.     }
  286.     do {
  287.         kbdmop = kbdloc(k) ;
  288.         if (kbdmop)
  289.             do {
  290.                 af = FALSE;
  291.                 an = 1;
  292.                 if ((c = *kbdmop++) == (KCTRL|'U')) {
  293.                     af = TRUE;
  294.                     an = (int) *kbdmop++;
  295.                     c  = *kbdmop++;
  296.                 }
  297.                 s = TRUE;
  298. /*
  299.  *   We changed this condition to allow you to define macros
  300.  *   within an execute command.
  301.  */
  302.             } while ((c!=(KCTLX|')') || kbdmip) &&
  303.                              (s=execute(c, af, an))==TRUE);
  304.         else
  305.             s = FALSE ;
  306.         kbdmop = NULL;
  307.     } while (s==TRUE && --n);
  308.     if (s == TRUE) {
  309.        popkbdm() ;
  310.     } else {
  311.        flushkbdm() ;
  312.     }
  313.         kbdmip = skbdmip ;
  314.     return (s);
  315. }
  316.  
  317. /*
  318.  * User abort. Should be called by any input routine that sees a C-g
  319.  * to abort whatever C-g is aborting these days. Currently does
  320.  * nothing.
  321.  */
  322. /*ARGSUSED*/
  323. ctrlg(f, n, k) {
  324.     return (ABORT);
  325. }
  326.  
  327. /*
  328.  * Display the version. All this does
  329.  * is copy the version string onto the echo line.
  330.  */
  331. /*ARGSUSED*/
  332. showversion(f, n, k) {
  333.  
  334.     ewprintf(version);
  335.     return TRUE ;
  336. }
  337.