home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / xdme1821.lha / XDME / cmd.c < prev    next >
C/C++ Source or Header  |  1993-04-04  |  35KB  |  1,829 lines

  1. /******************************************************************************
  2.  
  3.     MODUL
  4.     cmd.c
  5.  
  6.     DESCRIPTION
  7.     In this file you find all routines for programming like
  8.     IF, WHILE, REPEAT
  9.  
  10.     NOTES
  11.  
  12.     BUGS
  13.  
  14.     TODO
  15.  
  16.     EXAMPLES
  17.  
  18.     SEE ALSO
  19.  
  20.     INDEX
  21.  
  22.     HISTORY
  23.     14. Nov 1992    ada created
  24.  
  25. ******************************************************************************/
  26.  
  27. /**************************************
  28.         Includes
  29. **************************************/
  30. #include "defs.h"
  31. #define MYDEBUG     0
  32. #include "debug.h"
  33.  
  34.  
  35. /**************************************
  36.         Globale Variable
  37. **************************************/
  38. Prototype void do_if        (void);
  39. Prototype void do_repeat    (void);
  40. Prototype int  do_toggle    (int);
  41. Prototype void do_scanf     (void);
  42. Prototype void do_push        (void);
  43. Prototype void do_pop        (void);
  44. Prototype void do_swap        (void);
  45. Prototype void check_stack  (ED *);
  46.  
  47.  
  48. /**************************************
  49.       Interne Defines & Strukturen
  50. **************************************/
  51. typedef enum
  52. {
  53.     _IT_POS,
  54.     _IT_MODIFIED,
  55.     _IT_ICONMODE,
  56.     _IT_TABSTOP,
  57.     _IT_MARGIN,
  58.     _IT_INSERTMODE,
  59.     _IT_IGNORECASE,
  60.     _IT_WORDWRAP,
  61.     _IT_WWCOL,
  62.     _IT_WINDOW,
  63.     _IT_ICON,
  64.     _IT_PENS,
  65.     _IT_BLOCK,
  66.     _IT_AUTO,
  67.     _IT_SAVETABS,
  68.     _IT_ED,
  69.     _IT_DISCARD,
  70. } ItemType;
  71.  
  72. struct Item
  73. {
  74.     ItemType type;        /* _IT_xxx */
  75.     USHORT   size;        /* 1-normal, 2-special, 3-malloc'd */
  76.     ULONG    value;        /* value */
  77. };
  78.  
  79.  
  80. /**************************************
  81.         Interne Variable
  82. **************************************/
  83. static ULONG         MAX_STACK_SIZE = 0;
  84. static struct Item * ItemStack        = NULL;
  85. static USHORT         ItemStackDepth = 0;
  86.  
  87.  
  88. /**************************************
  89.        Interne Prototypes
  90. **************************************/
  91. static ItemType identify_item (char *);
  92.  
  93.  
  94. /*
  95.    IF condition trueaction, IFELSE condition trueaction falseaction
  96.  
  97.     condition:    !condition  NOT the specified condition.
  98.         #        toggle number is SET
  99.         top        top of file (on first line)
  100.         bot        end of file (on last line)
  101.         left        start of line (leftmost column)
  102.         right        end of line (nothing but spaces under and to the right)
  103.         modified    text has been modified
  104.         insert        currently in insert mode
  105.         y[<=>]#     cursor is (any OR combo of <,>,=) row #  (line numbers start at 1)
  106.         x[<=>]#     cursor is (<,>,<=,>=,<>) column #        (columns start at 1)
  107.                 <> means 'not equal'
  108.  
  109.         cl        char under cursor is lower case
  110.         cu        char under cursor is upper case
  111.         ca        char under cursor is alpha
  112.         cn        char under cursor is numeric
  113.         cb        char within selected block
  114.         c[<=>]#     char under cursor is (combo of <,>,and =) #,
  115.                 where # can be a
  116.  
  117.                 ASCII-code (numeric: hex, oct, dez)
  118.                 String (enclosed in ""). The cursor must
  119.                     be on the first letter of "string".
  120.                 Character-Group: [], i.e. c=[1-9] will be true
  121.                     if cursor is on any number. c=[a-zA-DF-H]
  122.                     is a valid construct !
  123.  
  124.         block        will BLOCK fail ?
  125.         selnext     will SELECT NEXT succeed ?
  126.         selprev     will SELECT PREV succeed ?
  127.  
  128.  and especially for WHILE
  129.  
  130.         true       infinite-loop (!)
  131.  
  132. */
  133.  
  134.  
  135. void do_if (void)
  136. {
  137.     BOOL    haselse = (av[0][2] == 'e'),    /* is there an ELSE ? */
  138.         iswhile = (av[0][0] == 'w'),    /* is this a WHILE ? */
  139.         istrue,                /* result of condition */
  140.         notop   = 0;            /* NOT ? */
  141.     BOOL    c,
  142.         cx,
  143.         cc;
  144.     UBYTE * buf1,                /* two buffers */
  145.       * buf2,
  146.       * ptr;                /* tmp ptr */
  147.     ED      * ep = Ep;
  148.     int     i,
  149.         j, /* PATCH_NULL */
  150.         n, /* PATCH_NULL */
  151.         cxn,
  152.         cn;
  153.  
  154.     buf1 = (UBYTE *)malloc(MAXLINELEN);     /* get two buffers */
  155.     buf2 = (UBYTE *)malloc(MAXLINELEN);
  156.  
  157.     if (buf1 == NULL || buf2 == NULL)
  158.     {
  159.     if (buf1) free(buf1);               /* :-( */
  160.     if (buf2) free(buf2);
  161.  
  162.     warn ("No Memory!");
  163.     nomemory ();
  164.     return;
  165.     }
  166.  
  167.     /* prepare for Ctrl-C checking */
  168.  
  169.     breakreset ();
  170.  
  171.     ptr = av[1];
  172.  
  173.     /* check for NOT */
  174.  
  175.     if (*ptr == '!')
  176.     {
  177.     notop = 1;
  178.     ++ptr;
  179.     }
  180.  
  181.     c    = tolower(ptr[0]);
  182.     cn    = atoi ((char *)ptr);
  183.     cx    = tolower(ptr[1]);
  184.     cxn = atoi ((char *)ptr+1);
  185.  
  186.     strcpy ((char *)buf1, (char *)av[2]);
  187.  
  188. loop:
  189.     istrue = 0;
  190.     i       = 0;
  191.     j       = 1; /* PATCH_NULL */
  192.  
  193.     switch (c)
  194.     {
  195.     case '$':
  196.     case '&':
  197.         {
  198.         char   ci;
  199.         char * str;
  200.  
  201.         for (j = 1; isalnum(ptr[j]); ++j);
  202.         ci = ptr[j];
  203.         ptr[j] = 0;
  204.         str = getvar(ptr+1);
  205.         ptr[j] = ci;
  206.         i = 0;
  207.         if (str)
  208.         {
  209.             if (!is_number(str))
  210.             {
  211.             error ("%s:\nvariable %s does not contain an integer",av[1], ptr+1);
  212.             goto done;
  213.             } /* if */
  214.             i = atoi(str);
  215.             free(str);
  216.         } else
  217.         {
  218.             error ("%s:\nunknown variable %s", av[0], ptr+1);
  219.             goto done;
  220.         }
  221.         if (ci)
  222.             goto conditional;
  223.         istrue = (i != 0);
  224.         break;
  225.         }
  226.     case 'x':
  227.         i = ep->column + 1;
  228.  
  229.     case 'y':
  230.         if (!i)
  231.         i = ep->line + 1;
  232.  
  233. conditional:
  234.         {
  235.         /* int j, n; */
  236.         char any = 0;
  237.  
  238.         for (; ptr[j] != '<' && ptr[j] != '>' && ptr[j] != '=' && ptr[j]; ++j); /* j=1 deleted */
  239.         if (!ptr[j])
  240.         {
  241.             error ("%s:\nBad conditional:\n`%s'", av[0], av[1]);
  242.             goto done;
  243.         }
  244.  
  245.         for ( ; (ptr[j] == '<' || ptr[j] == '>' || ptr[j] == '=') && ptr[j]; ++j)
  246.         {
  247.             switch(ptr[j])
  248.             {
  249.             case '<':
  250.                 any |= 1;
  251.                 break;
  252.             case '=':
  253.                 any |= 2;
  254.                 break;
  255.             case '>':
  256.                 any |= 4;
  257.                 break;
  258.             }
  259.         }
  260.  
  261.         if (!ptr[j] || !any || any == 7)
  262.         {
  263.             error ("%s:\nBad conditional `%s':\nUnexp. EOL or wrong compare", av[0], av[1]);
  264.             goto done;
  265.         }
  266.  
  267.         for ( ; isspace (ptr[j]); ++j);
  268.         if (!ptr[j])
  269.         {
  270.             error ("%s:\nBad conditional `%s':\nUnexp. EOL", av[0], av[1]);
  271.             goto done;
  272.         }
  273.  
  274.  
  275.         if (ptr[j] == '"')
  276.         {
  277.             j ++;
  278.             for (n=j; ptr[j] != '"' && ptr[j]; j ++);
  279.             j -= n;
  280.  
  281.             if (ep->config.ignorecase)
  282.             n = strnicmp(AddressOfElement(Current.text,ep->column),
  283.                 &ptr[n], j);
  284.             else
  285.             n = strncmp (AddressOfElement(Current.text,ep->column),
  286.                 &ptr[n], j);
  287.         } else if (ptr[j] == '[')
  288.         {
  289.             if (any != 2 && any != 5)
  290.             {
  291.             error ("%s:\nBad conditional `%s':\ncompare with [] must be '=' or '<>'", av[0], av[1]);
  292.             goto done;
  293.             }
  294.  
  295.             j ++;
  296.             ReadElements (Current.text, &cc, ep->column, 1);
  297.  
  298.             for (n=j; ptr[j] != ']' && ptr[j]; j ++)
  299.             {
  300.             if (ptr[j] == '\\') j ++;
  301.             else if (ptr[j+1] == '-')
  302.             {
  303.                 if (!ptr[j+2] || ptr[j+2] == ']')
  304.                 {
  305.                 error ("%s:\nBad conditional `%s':\nString ended too early", av[0], av[1]);
  306.                 goto done;
  307.                 }
  308.  
  309.                 if (cc >= ptr[j] && cc <= ptr[j+2])
  310.                 {
  311.                 cc = ptr[j];
  312.                 break;
  313.                 }
  314.  
  315.                 j += 3;
  316.                 continue;
  317.             }
  318.  
  319.             if (cc == ptr[j]) break;
  320.             }
  321.  
  322.             istrue = (cc==ptr[j] && any==2) || (cc!=ptr[j] && any==5);
  323.  
  324.             break;
  325.         } else if (isdigit(ptr[j]) || ptr[j] == '+' || ptr[j] == '-')
  326.         {
  327.             n = i - atoi((char *)ptr+j);
  328.         } else
  329.         {
  330.             error ("%s:\nUnknown conditional `%s'", av[0], av[1]);
  331.             goto done;
  332.         }
  333.  
  334.         istrue = (any&1 && n<0) || (any&2 && !n) || (any&4 && n>0);
  335.         }
  336.     break;
  337.  
  338.     case 't':
  339.         if (cx == 'r')
  340.         istrue = 1;
  341.         else
  342.         istrue = ep->line == 0;
  343.     break;
  344.  
  345.     case 'b':
  346.         if (cx == 'l')
  347.         istrue = block_ok ();
  348.         else istrue = ep->line == ep->lines-1;
  349.     break;
  350.  
  351.     case 'l':
  352.         istrue = ep->column == 0;
  353.     break;
  354.  
  355.     case 'r':
  356.         istrue = ep->column >= Clen();
  357.     break;
  358.  
  359.     case 'm':
  360.         text_sync ();
  361.         istrue = ep->modified != 0;
  362.     break;
  363.  
  364.     case 'e':
  365.         istrue = globalflags.Comlinemode != 0;
  366.     break;
  367.  
  368.     case 'i':
  369.         istrue = ep->config.insertmode != 0;
  370.     break;
  371.  
  372.     case 'c':
  373.         ReadElements (Current.text, &cc, ep->column, 1);
  374.  
  375.         switch(cx)
  376.         {
  377.         case 'b':
  378.             istrue = is_inblock (ep->line, -1) != 0;
  379.         break;
  380.  
  381.         case 'l':
  382.             istrue = islower (cc);
  383.         break;
  384.  
  385.         case 'u':
  386.             istrue = isupper (cc);
  387.         break;
  388.  
  389.         case 'a':
  390.             istrue = isalnum (cc);
  391.         break;
  392.  
  393.         case 'n':
  394.             istrue = isdigit (cc);
  395.         break;
  396.  
  397.         default:        /* c[<=>]#  */
  398.             ReadElements (Current.text, i, ep->column, 1);
  399.             goto conditional;
  400.         break;
  401.         }
  402.     break;
  403.  
  404.     case 's':       /* SELNEXT/SELPREV */
  405.         switch (tolower (ptr[3]))
  406.         {
  407.         case 'n':
  408.             if (GetSucc ((struct Node *)Ep))
  409.             istrue = 1;
  410.         break;
  411.  
  412.         case 'p':
  413.             if (GetPred ((struct Node *)Ep))
  414.             istrue = 1;
  415.         break;
  416.         }
  417.     break;
  418.  
  419.     case 'g':                       /* PATCH_NULL: */
  420.         if (is_number(ptr+1))
  421.         {
  422.         cn = atoi(ptr+1);
  423.         c  = '0';
  424.         } /* if */
  425.     /* fall-through */
  426.  
  427.     default:
  428.         if (isdigit (c))
  429.         istrue = do_toggle(cn) != 0;
  430.         else
  431.         {
  432.         error ("%s:\nBad condition\n`%s'", av[0], av[1]);
  433.         }
  434.  
  435.     break;
  436.     }
  437.  
  438.     istrue ^= notop;
  439.  
  440.     if (istrue)
  441.     {
  442.     strcpy((char *)buf2, (char *)buf1); /* could be executed multiple
  443.                            times */
  444.     if (do_command((char *)buf2) == 0)
  445.         goto done;
  446.  
  447.     if (iswhile && !globalflags.Abortcommand)
  448.     {
  449.  
  450.         if (breakcheck())
  451.         {
  452.         globalflags.Abortcommand = 1;
  453.         } else if (LoopCont)
  454.         {
  455.         LoopCont = 0;        /* PATCH_NULL [14 Feb 1993] : func <-> ass */
  456.         goto loop;
  457.         } else if (LoopBreak)
  458.         {
  459.         LoopBreak = 0;        /* PATCH_NULL [14 Feb 1993] : func <-> ass */
  460.         }
  461.         else
  462.         goto loop;
  463.     }
  464.     } else
  465.     {
  466.     if (haselse)
  467.     {       /* only executed once */
  468.         strcpy((char *)buf2, (char *)av[3]);
  469.         do_command((char *)buf2);
  470.     }
  471.     }
  472.  
  473. done:
  474.     free(buf1);
  475.     free(buf2);
  476. } /* do_if */
  477.  
  478.  
  479. /*
  480.  * repeat X command
  481.  *
  482.  * (if X is not a number it can be abbr. with 2 chars)
  483.  *
  484.  * X =    N     -number of repeats
  485.  *    line  -current line # (lines begin at 1)
  486.  *    lbot  -#lines to the bottom, inc. current
  487.  *    cleft -column # (columns begin at 0)
  488.  *        (thus is also chars to the left)
  489.  *    cright-#chars to eol, including current char
  490.  *    tr    -#char positions to get to next tab stop
  491.  *    tl    -#char positions to get to next backtab stop
  492.  */
  493.  
  494. #define SC(a,b) ((a)<<8|(b))
  495.  
  496. void do_repeat (void)
  497. {
  498.     UBYTE *ptr = av[1];
  499.     unsigned long n;
  500.     char *buf1, *buf2;
  501.  
  502.     if (!(buf1 = AllocMem (MAXLINELEN*2, 0)) )
  503.     {
  504.     globalflags.Abortcommand = 1;
  505.     return;
  506.     }
  507.  
  508.     buf2 = buf1 + MAXLINELEN;
  509.  
  510.     breakreset ();
  511.     strcpy (buf1, av[2]);
  512.  
  513.     switch (SC(ptr[0],ptr[1]))
  514.     {
  515.     case SC('l','i'):
  516.         n = text_lineno ();
  517.         break;
  518.  
  519.     case SC('l','b'):
  520.         n = text_lines () - text_lineno () + 1;
  521.         break;
  522.  
  523.     case SC('c','l'):
  524.         n = text_colno ();
  525.         break;
  526.  
  527.     case SC('c','r'):
  528.         n = text_cols () - text_colno ();
  529.         break;
  530.  
  531.     case SC('t','r'):
  532.         n = text_tabsize () - (text_colno () % text_tabsize ());
  533.         break;
  534.  
  535.     case SC('t','l'):
  536.         n = text_colno () % text_tabsize ();
  537.  
  538.         if (n == 0)
  539.         n = text_tabsize ();
  540.  
  541.         break;
  542.     default:
  543.         n = atoi (av[1]);
  544.         break;
  545.     }
  546.  
  547.     while (n > 0)
  548.     {
  549.     strcpy(buf2, buf1);
  550.  
  551.     if (do_command (buf2) == 0 || breakcheck ())
  552.     {
  553.         globalflags.Abortcommand = 1;
  554.         break;
  555.     }
  556.     if (LoopBreak)
  557.     {
  558.         LoopBreak = 0;        /* PATCH_NULL [14 Feb 1993] : func <-> ass */
  559.         break;
  560.     } else if (LoopCont)
  561.     {
  562.         LoopCont = 0;        /* PATCH_NULL [14 Feb 1993] : func <-> ass */
  563.     } /* if */
  564.  
  565.     --n;
  566.     }
  567.  
  568.     FreeMem (buf1, MAXLINELEN*2);
  569. } /* do_repeat */
  570.  
  571.  
  572. /*
  573.  * TOGGLE #, SETTOGGLE #, RESETTOGGLE #
  574.  */
  575.  
  576. UBYTE bit[] =
  577. {
  578.     0x01, 0x02, 0x04, 0x08,
  579.     0x10, 0x20, 0x40, 0x80
  580. };
  581.  
  582. int do_toggle (int n)
  583. {
  584.     extern UBYTE tg[MAXTOGGLE/8];
  585.     int i;
  586.  
  587.     if (n >= 0)
  588.     {
  589.     if (n >= MAXTOGGLE)
  590.         return(0);
  591.  
  592. /*printf ("Pos %d (%d/%d) %02x\n", n, n/8, n&7, tg[n/8]);*/
  593.  
  594.     return(tg[n/8] & bit[n&7]);
  595.     }
  596.  
  597.     i = atoi((char *)av[1]);
  598.  
  599.     n = i/8;
  600.     i &= 7;
  601.  
  602.     if (i >= 0 && i < MAXTOGGLE)
  603.     {
  604.     switch(av[0][0])
  605.     {
  606.         case 't':
  607.         tg[n] ^= bit[i];
  608.         break;
  609.         case 's':
  610.         tg[n] |= bit[i];
  611.         break;
  612.         case 'r':
  613.         tg[n] &= ~bit[i];
  614.         break;
  615.     }
  616.     }
  617.  
  618.     return (0);
  619. } /* do_toggle */
  620.  
  621.  
  622.  
  623. /*
  624.  *  SCANF controlstring
  625.  *
  626.  *  The C scanf routine.  Only one variable, a string, is allowed in the
  627.  *  control string.
  628.  *
  629.  *  Modified by A. Digulla to be more useful for a text-editor.
  630.  *
  631.  *   %s and %[] are still working
  632.  *
  633.  *   Additional :     (w)ord    (l)ine    (n)umber  (b)lock   (c)har
  634.  *             (t)ext    (a)lpha   (r)emark
  635.  *
  636.  *   w - get word
  637.  *   l - get line with EVERYTHING
  638.  *   b - get all that fits into isalphanum()
  639.  *   c - get single char
  640.  *   t - like line, but without preceding and trailing spaces
  641.  *   a - all that fits into isalpha()
  642.  *   r - get c-style comment
  643.  *
  644.  *   if you precede a '+' to any of these, SCANF will start at the beginning
  645.  *   to the left
  646.  */
  647.  
  648. void do_scanf (void)
  649. {
  650.     UBYTE buf[MAXLINELEN], *ptr, *bptr;
  651.     SHORT t;
  652.     BOOL  left;
  653.  
  654.     buf[0] = 0;
  655.     ptr = av[1];
  656.  
  657.     if (*ptr == '%')
  658.     {
  659.     ptr ++;
  660.  
  661.     if (*ptr == 's' || *ptr == '[')
  662.     {
  663.         if (*ptr == 's')
  664.         {
  665.         ptr ++;
  666.         *ptr = 0;      /* Make sure there is nothing else */
  667.         } else
  668.         {
  669.         ptr ++;
  670.         if (*ptr == '~') *ptr = '^';
  671.  
  672.         while (*ptr != ']') ptr ++;
  673.         ptr ++;
  674.         *ptr = 0;      /* dito */
  675.         } /* if (*ptr == 's') */
  676.  
  677.         sscanf (AddressOfElement (Current, Ep->column), av[1], buf);
  678.     } else
  679.     {
  680.         *buf = 0;
  681.     } /* if (*ptr == 's' && *ptr == '[') */
  682.     } else
  683.     {
  684.     char c;
  685.  
  686.     error ("SCANF:\nTemporary disabled.");
  687.  
  688. #ifdef NOTDEF
  689.     if (*ptr == '+')
  690.     {
  691.         left = TRUE;
  692.         ptr ++;
  693.     } else
  694.         left = FALSE;
  695.  
  696.     switch (*ptr)
  697.     {
  698.         case ('w') :
  699.         {
  700.         t = Ep->column;
  701.  
  702.         if (t > Clen)
  703.         {
  704.             buf[0] = 0;
  705.             break;
  706.         }
  707.  
  708.         if (left)
  709.         {
  710.             ReadElements (Current.text, &c, t, 1);
  711.  
  712.             while (t && c != ' ')
  713.             {
  714.             t --;
  715.             ReadElements (Current.text, &c, t, 1);
  716.             }
  717.         }
  718.  
  719.         while (c == ' ' && t < Clen ())
  720.         {
  721.             t ++;
  722.             ReadElements (Current.text, &c, t, 1);
  723.         }
  724.  
  725.         if (t == Clen ())
  726.         {
  727.             buf[0] = 0;
  728.             break;
  729.         }
  730.  
  731.         bptr = buf;
  732.  
  733.         while (*ptr != ' ' && *ptr)
  734.             *bptr++ = *ptr++;
  735.  
  736.         *bptr = 0;
  737.         break; } /* case ('w') */
  738.  
  739.         case ('l') :
  740.         {
  741.         if (left)
  742.         {
  743.             strncpy ((char *)buf, (char *)Current, Clen);
  744.             buf[Clen] = 0;
  745.         } else
  746.         {
  747.             strncpy ((char *)buf, (char *)Current+Ep->column,
  748.                 Clen-Ep->column);
  749.             buf[Clen - Ep->column] = 0;
  750.         }
  751.  
  752.         break; } /* case ('l') */
  753.  
  754.         case ('n') :
  755.         {
  756.         t = Ep->column;
  757.  
  758.         if (t > Clen)
  759.         {
  760.             buf[0] = 0;
  761.             break;
  762.         }
  763.  
  764.         ptr = Current+t;
  765.  
  766.         if (left)
  767.         {
  768.             while (t && isdigit(*ptr))
  769.             {
  770.             ptr --;
  771.             t --;
  772.             }
  773.  
  774.             if (t)
  775.             {
  776.             ptr ++;
  777.             t ++;
  778.             }
  779.         }
  780.  
  781.         while (*ptr == ' ' && t < Clen)
  782.         {
  783.             ptr ++;
  784.             t ++;
  785.         }
  786.  
  787.         if (t == Clen)
  788.         {
  789.             buf[0] = 0;
  790.             break;
  791.         }
  792.  
  793.         bptr = buf;
  794.  
  795.         while (isdigit(*ptr))
  796.             *bptr++ = *ptr++;
  797.  
  798.         *bptr = 0;
  799.  
  800.         break; } /* case ('n') */
  801.  
  802.         case ('b') :
  803.         {
  804.         t = Ep->column;
  805.  
  806.         if (t > Clen)
  807.         {
  808.             buf[0] = 0;
  809.             break;
  810.         }
  811.  
  812.         ptr = Current+t;
  813.  
  814.         if (left)
  815.         {
  816.             while (t && isalnum(*ptr))
  817.             {
  818.             ptr --;
  819.             t --;
  820.             }
  821.  
  822.             if (t)
  823.             {
  824.             ptr ++;
  825.             t ++;
  826.             }
  827.         }
  828.  
  829.         while (*ptr == ' ' && t < Clen)
  830.         {
  831.             ptr ++;
  832.             t ++;
  833.         }
  834.  
  835.         if (t == Clen)
  836.         {
  837.             buf[0] = 0;
  838.             break;
  839.         }
  840.  
  841.         bptr = buf;
  842.  
  843.         while (isalnum(*ptr))
  844.             *bptr++ = *ptr++;
  845.  
  846.         *bptr = 0;
  847.  
  848.         break; } /* case ('b') */
  849.  
  850.         case ('c') :
  851.         {
  852.         *buf = *(Current+Ep->column);
  853.         buf[1] = 0;
  854.  
  855.         break; } /* case ('c') */
  856.  
  857.         case ('t') :
  858.         {
  859.         if (left)
  860.         {
  861.             ptr = Current;
  862.             t = 0;
  863.         } else
  864.         {
  865.             t = Ep->column;
  866.             ptr = Current+t;
  867.         }
  868.  
  869.         if (t >= Clen || Clen == 0)
  870.         {
  871.             buf[0] = 0;
  872.             break;
  873.         }
  874.  
  875.         while (*ptr == ' ')
  876.         {
  877.             ptr ++;
  878.             t ++;
  879.         }
  880.  
  881.         if (t >= Clen)
  882.         {
  883.             buf[0] = 0;
  884.             break;
  885.         }
  886.  
  887.         strncpy ((char *)buf, (char *)ptr, Clen-t);
  888.  
  889.         ptr = buf + Clen - t - 1;
  890.  
  891.         while (*ptr == ' ')
  892.             ptr --;
  893.  
  894.         ptr[1] = 0;
  895.  
  896.         break; } /* case ('t') */
  897.  
  898.         case ('a') :
  899.         {
  900.         t = Ep->column;
  901.         ptr = Current+t;
  902.  
  903.         if (left)
  904.         {
  905.             while (isalpha(*ptr) && t)
  906.             {
  907.             ptr --;
  908.             t --;
  909.             }
  910.  
  911.             if (t)
  912.             {
  913.             ptr ++;
  914.             t ++;
  915.             }
  916.         }
  917.  
  918.         bptr = buf;
  919.  
  920.         while (isalpha(*ptr))
  921.             *bptr++ = *ptr ++;
  922.  
  923.         *bptr = 0;
  924.  
  925.         break; } /* case ('a') */
  926.  
  927.         case ('r') :
  928.         {
  929.         t = Ep->column;
  930.         ptr = Current+t;
  931.  
  932.         if (left)
  933.         {
  934.             while (t)
  935.             {
  936.             if (*ptr == '*' && *(ptr-1) == '/')
  937.             {
  938.                 ptr ++;
  939.                 break;
  940.             }
  941.  
  942.             t --;
  943.             ptr --;
  944.             }
  945.  
  946.             if (!t)
  947.             {
  948.             *buf = 0;
  949.             break;
  950.             } else
  951.             {
  952.             t ++;
  953.             ptr ++;
  954.             }
  955.         }
  956.  
  957.         if (t > Clen)
  958.         {
  959.             *buf = 0;
  960.             break;
  961.         }
  962.  
  963.         bptr = buf;
  964.  
  965.         while (t < Clen)
  966.         {
  967.             if (*ptr == '*' && ptr[1] == '/')
  968.             {
  969.             bptr --;
  970.             break;
  971.             }
  972.  
  973.             *bptr++ = *ptr ++;
  974.             t ++;
  975.         }
  976.  
  977.         *bptr = 0;
  978.  
  979.         break; } /* case ('r') */
  980.  
  981.     } /* switch (*ptr) */
  982. #endif
  983.     } /* if (*ptr == '%') */
  984.  
  985.     if (String)
  986.     free (String);
  987.  
  988.     if (String = (char *)malloc (strlen ((char *)buf)+1))
  989.     {
  990.     strcpy ((char *)String, (char *)buf);
  991.  
  992.     title (String);
  993.     }
  994. } /* do_scanf */
  995.  
  996.  
  997. /*****************************************************************************
  998.  
  999.     NAME
  1000.     do_push
  1001.  
  1002.     PARAMETER
  1003.     item
  1004.  
  1005.     DESCRIPTION
  1006.     Pushes an item on the internal stack.
  1007.  
  1008. ******************************************************************************/
  1009.  
  1010. void do_push (void)
  1011. {
  1012.     if (ItemStackDepth == MAX_STACK_SIZE)
  1013.     {
  1014.     struct Item * stack;
  1015.  
  1016.     if (stack = AllocMem (sizeof(struct Item) * (MAX_STACK_SIZE + 32), 0))
  1017.     {
  1018.         if (MAX_STACK_SIZE)
  1019.         movmem (ItemStack, stack, sizeof(struct Item)*MAX_STACK_SIZE);
  1020.  
  1021.         MAX_STACK_SIZE += 32;
  1022.         ItemStack = stack;
  1023.     } else
  1024.     {
  1025.         error ("push:\nCannot push %s:\nStack full", av[1]);
  1026.         return;
  1027.     }
  1028.     }
  1029.  
  1030.     switch (ItemStack[ItemStackDepth].type = identify_item (av[1]))
  1031.     {
  1032.     case _IT_POS:
  1033.     {
  1034.         struct TextMarker * pos;
  1035.  
  1036.         if (pos = malloc (sizeof(struct TextMarker)))
  1037.         {
  1038.         pos->ep     = Ep;
  1039.         pos->line   = Ep->line;
  1040.         pos->column = Ep->column;
  1041.  
  1042.         ItemStack[ItemStackDepth].value = (ULONG)pos;
  1043.         ItemStack[ItemStackDepth].size    = 3;
  1044.         } else
  1045.         {
  1046. out_of_memory:
  1047.         warn ("push: Out of memory error");
  1048.         globalflags.Abortcommand = 1;
  1049.         return;
  1050.         }
  1051.     } break;
  1052.  
  1053.     case _IT_MODIFIED:
  1054.         ItemStack[ItemStackDepth].value = Ep->modified;
  1055.         ItemStack[ItemStackDepth].size  = 1;
  1056.     break;
  1057.  
  1058.     case _IT_ICONMODE:
  1059.         ItemStack[ItemStackDepth].value = Ep->iconmode;
  1060.         ItemStack[ItemStackDepth].size  = 1;
  1061.     break;
  1062.  
  1063.     case _IT_TABSTOP:
  1064.         ItemStack[ItemStackDepth].value = Ep->config.tabstop;
  1065.         ItemStack[ItemStackDepth].size  = 1;
  1066.     break;
  1067.  
  1068.     case _IT_MARGIN:
  1069.         ItemStack[ItemStackDepth].value = Ep->config.margin;
  1070.         ItemStack[ItemStackDepth].size  = 1;
  1071.     break;
  1072.  
  1073.     case _IT_INSERTMODE:
  1074.         ItemStack[ItemStackDepth].value = Ep->config.insertmode;
  1075.         ItemStack[ItemStackDepth].size  = 1;
  1076.     break;
  1077.  
  1078.     case _IT_IGNORECASE:
  1079.         ItemStack[ItemStackDepth].value = Ep->config.ignorecase;
  1080.         ItemStack[ItemStackDepth].size  = 1;
  1081.     break;
  1082.  
  1083.     case _IT_WORDWRAP:
  1084.         ItemStack[ItemStackDepth].value = Ep->config.wordwrap;
  1085.         ItemStack[ItemStackDepth].size  = 1;
  1086.     break;
  1087.  
  1088.     case _IT_WWCOL:
  1089.         ItemStack[ItemStackDepth].value = Ep->config.wwcol;
  1090.         ItemStack[ItemStackDepth].size  = 1;
  1091.     break;
  1092.  
  1093.     case _IT_SAVETABS:
  1094.         ItemStack[ItemStackDepth].value = globalflags.Savetabs;
  1095.         ItemStack[ItemStackDepth].size  = 1;
  1096.     break;
  1097.  
  1098.     case _IT_ED:
  1099.         ItemStack[ItemStackDepth].value = (ULONG)Ep;
  1100.         ItemStack[ItemStackDepth].size  = 2;
  1101.     break;
  1102.  
  1103.     case _IT_WINDOW:
  1104.     {
  1105.         USHORT * array;
  1106.  
  1107.         if (array = malloc (4*sizeof(USHORT)))
  1108.         {
  1109.         if (!Ep->iconmode)
  1110.         {
  1111.             array[0] = Ep->config.winx;
  1112.             array[1] = Ep->config.winy;
  1113.             array[2] = Ep->config.winwidth;
  1114.             array[3] = Ep->config.winheight;
  1115.         } else
  1116.         {
  1117.             array[0] = Ep->win->LeftEdge;
  1118.             array[1] = Ep->win->TopEdge;
  1119.             array[2] = Ep->win->Width;
  1120.             array[3] = Ep->win->Height;
  1121.         }
  1122.  
  1123.         ItemStack[ItemStackDepth].value = (ULONG)array;
  1124.         ItemStack[ItemStackDepth].size    = 3;
  1125.         } else
  1126.         {
  1127.         goto out_of_memory;
  1128.         }
  1129.     } break;
  1130.  
  1131.     case _IT_ICON:
  1132.     {
  1133.         USHORT * array;
  1134.  
  1135.         if (array = malloc (2*sizeof(USHORT)))
  1136.         {
  1137.         if (Ep->iconmode)
  1138.         {
  1139.             array[0] = Ep->config.iwinx;
  1140.             array[1] = Ep->config.iwiny;
  1141.         } else
  1142.         {
  1143.             array[0] = Ep->win->LeftEdge;
  1144.             array[1] = Ep->win->TopEdge;
  1145.         }
  1146.  
  1147.         ItemStack[ItemStackDepth].value = (ULONG)array;
  1148.         ItemStack[ItemStackDepth].size    = 3;
  1149.         } else
  1150.         {
  1151.         goto out_of_memory;
  1152.         }
  1153.     } break;
  1154.  
  1155.     case _IT_PENS:
  1156.     {
  1157.         ULONG * array;
  1158.  
  1159.         if (array = malloc (5*sizeof(ULONG)))
  1160.         {
  1161.         array[0] = TEXT_FPEN;
  1162.         array[1] = TEXT_BPEN;
  1163.         array[2] = BLOCK_FPEN;
  1164.         array[3] = BLOCK_BPEN;
  1165.         array[4] = TITLE_BPEN;
  1166.  
  1167.         ItemStack[ItemStackDepth].value = (ULONG)array;
  1168.         ItemStack[ItemStackDepth].size    = 3;
  1169.         } else
  1170.         {
  1171.         goto out_of_memory;
  1172.         }
  1173.     } break;
  1174.  
  1175.     case _IT_BLOCK:
  1176.     {
  1177.         Block * block;
  1178.  
  1179.         if (block = malloc (sizeof(Block)))
  1180.         {
  1181.         movmem (&ActualBlock, block, sizeof (Block));
  1182.  
  1183.         ItemStack[ItemStackDepth].value = (ULONG)block;
  1184.         ItemStack[ItemStackDepth].size    = 3;
  1185.  
  1186.         if (!Ep->iconmode)
  1187.             text_redrawblock (0);
  1188.         } else
  1189.         {
  1190.         goto out_of_memory;
  1191.         }
  1192.     } break;
  1193.  
  1194.     default:
  1195.         error ("push:\nUnknown item\n`%s'", av[1]);
  1196.         return;
  1197.     break;
  1198.     }
  1199.  
  1200.     ItemStackDepth ++;
  1201.  
  1202. #if MYDEBUG
  1203.     if (globalflags.debug)
  1204.     D(bug("PUSH Stack %d\n", ItemStackDepth));
  1205. #endif
  1206. } /* do_push */
  1207.  
  1208.  
  1209. /*****************************************************************************
  1210.  
  1211.     NAME
  1212.     POP/PEEK item
  1213.  
  1214.     PARAMETER
  1215.     item / AUTO / DISCARD
  1216.  
  1217.     DESCRIPTION
  1218.     Pops an item from the internal stack or (PICK) just get's the value
  1219.     of it without poping it from the stack.
  1220.  
  1221. ******************************************************************************/
  1222.  
  1223. void do_pop (void)
  1224. {
  1225.     ItemType type;
  1226.  
  1227.     if (ItemStackDepth == 0)
  1228.     {
  1229.     error ("%s:\nCannot pop %s:\nStack empty", av[0], av[1]);
  1230.     return;
  1231.     }
  1232.  
  1233.     ItemStackDepth --;
  1234.  
  1235. #if MYDEBUG
  1236.     if (globalflags.debug)
  1237.     D(bug("POP Stack %d\n", ItemStackDepth));
  1238. #endif
  1239.  
  1240.     type = identify_item (av[1]);
  1241.  
  1242.     if (type == _IT_AUTO)
  1243.     type = ItemStack[ItemStackDepth].type;
  1244.  
  1245.     switch (type)
  1246.     {
  1247.     case _IT_POS:
  1248.         struct TextMarker * pos;
  1249.  
  1250.         if (ItemStack[ItemStackDepth].type != _IT_POS)
  1251.         error ("pop:\nCannot pop position\nto something else");
  1252.  
  1253.         pos = (struct TextMarker *)ItemStack[ItemStackDepth].value;
  1254.  
  1255.         text_sync ();
  1256.  
  1257.         text_cursor (1);
  1258.         switch_ed (pos->ep);
  1259.         text_cursor (0);
  1260.  
  1261.         if (IntuitionBase->ActiveWindow != Ep->win)
  1262.         {
  1263.         WindowToFront (Ep->win);
  1264.         ActivateWindow (Ep->win);
  1265.         }
  1266.  
  1267.         if (pos->line >= Ep->lines)
  1268.         Ep->line = Ep->lines - 1;
  1269.         else
  1270.         Ep->line = pos->line;
  1271.  
  1272.         Ep->column = pos->column;
  1273.  
  1274.         text_load ();
  1275.         text_adjust (FALSE);
  1276.     break;
  1277.  
  1278.     case _IT_MODIFIED:
  1279.         if (ItemStack[ItemStackDepth].size != 1)
  1280.         error ("pop:\nCannot pop a struct\nto modified");
  1281.  
  1282.         Ep->modified = ItemStack[ItemStackDepth].value;
  1283.     break;
  1284.  
  1285.     case _IT_ICONMODE:
  1286.         if (ItemStack[ItemStackDepth].size != 1)
  1287.         error ("pop:\nCannot pop a struct\nto iconmode");
  1288.  
  1289.         if (Ep->iconmode != ItemStack[ItemStackDepth].value)
  1290.         {
  1291.         if (ItemStack[ItemStackDepth].value)
  1292.             iconify ();
  1293.         else
  1294.             uniconify ();
  1295.         }
  1296.     break;
  1297.  
  1298.     case _IT_TABSTOP:
  1299.         if (ItemStack[ItemStackDepth].size != 1)
  1300.         error ("pop:\nCannot pop a struct\nto tabstop");
  1301.  
  1302.         Ep->config.tabstop = ItemStack[ItemStackDepth].value;
  1303.     break;
  1304.  
  1305.     case _IT_MARGIN:
  1306.         if (ItemStack[ItemStackDepth].size != 1)
  1307.         error ("pop:\nCannot pop a struct\nto margin");
  1308.  
  1309.         Ep->config.margin = ItemStack[ItemStackDepth].value;
  1310.     break;
  1311.  
  1312.     case _IT_INSERTMODE:
  1313.         if (ItemStack[ItemStackDepth].size != 1)
  1314.         error ("pop:\nCannot pop a struct\nto insertmode");
  1315.  
  1316.         Ep->config.insertmode = ItemStack[ItemStackDepth].value;
  1317.     break;
  1318.  
  1319.     case _IT_IGNORECASE:
  1320.         if (ItemStack[ItemStackDepth].size != 1)
  1321.         error ("pop:\nCannot pop a struct\nto ignorecase");
  1322.  
  1323.         Ep->config.ignorecase = ItemStack[ItemStackDepth].value;
  1324.     break;
  1325.  
  1326.     case _IT_WORDWRAP:
  1327.         if (ItemStack[ItemStackDepth].size != 1)
  1328.         error ("pop:\nCannot pop a struct\nto wordwrap");
  1329.  
  1330.         Ep->config.wordwrap = ItemStack[ItemStackDepth].value;
  1331.     break;
  1332.  
  1333.     case _IT_WWCOL:
  1334.         if (ItemStack[ItemStackDepth].size != 1)
  1335.         error ("pop:\nCannot pop a struct\nto wordwrapcolumn");
  1336.  
  1337.         Ep->config.wwcol = ItemStack[ItemStackDepth].value;
  1338.     break;
  1339.  
  1340.     case _IT_SAVETABS:
  1341.         if (ItemStack[ItemStackDepth].size != 1)
  1342.         error ("pop:\nCannot pop a struct\nto savetabs");
  1343.  
  1344.         globalflags.Savetabs = ItemStack[ItemStackDepth].value;
  1345.     break;
  1346.  
  1347.     case _IT_ED:
  1348.         if (ItemStack[ItemStackDepth].type != _IT_ED)
  1349.         error ("pop:\nCannot pop ed\nto something else");
  1350.  
  1351.         switch_ed ((ED *)ItemStack[ItemStackDepth].value);
  1352.     break;
  1353.  
  1354.     case _IT_WINDOW:
  1355.     {
  1356.         USHORT * array;
  1357.  
  1358.         if (ItemStack[ItemStackDepth].type != _IT_WINDOW)
  1359.         error ("pop:\nCannot pop window\nto something else");
  1360.  
  1361.  
  1362.         array = (USHORT *)ItemStack[ItemStackDepth].value;
  1363.  
  1364.         Ep->config.winx     = array[0];
  1365.         Ep->config.winy     = array[1];
  1366.         Ep->config.winwidth  = array[2];
  1367.         Ep->config.winheight = array[3];
  1368.  
  1369.         if (!Ep->iconmode)
  1370.         {
  1371.         MoveWindow (Ep->win, Ep->config.winx - Ep->win->LeftEdge,
  1372.                      Ep->config.winy - Ep->win->TopEdge);
  1373.         SizeWindow (Ep->win, Ep->config.winwidth  - Ep->win->Width,
  1374.                      Ep->config.winheight - Ep->win->Height);
  1375.         }
  1376.     } break;
  1377.  
  1378.     case _IT_ICON:
  1379.     {
  1380.         USHORT * array;
  1381.  
  1382.         if (ItemStack[ItemStackDepth].type != _IT_ICON)
  1383.         error ("pop:\nCannot pop icon\nto something else");
  1384.  
  1385.         Ep->config.iwinx      = array[0];
  1386.         Ep->config.iwiny      = array[1];
  1387.  
  1388.         if (Ep->iconmode)
  1389.         {
  1390.         MoveWindow (Ep->win, Ep->config.iwinx - Ep->win->LeftEdge,
  1391.                      Ep->config.iwiny - Ep->win->TopEdge);
  1392.         }
  1393.     } break;
  1394.  
  1395.     case _IT_PENS:
  1396.     {
  1397.         ULONG * array;
  1398.  
  1399.         if (ItemStack[ItemStackDepth].type != _IT_PENS)
  1400.         error ("pop:\nCannot pop pens\nto something else");
  1401.  
  1402.         array = (ULONG *)ItemStack[ItemStackDepth].value;
  1403.  
  1404.         TEXT_FPEN  = array[0];
  1405.         TEXT_BPEN  = array[1];
  1406.         BLOCK_FPEN = array[2];
  1407.         BLOCK_BPEN = array[3];
  1408.         TITLE_BPEN = array[4];
  1409.  
  1410.         if (!Ep->iconmode)
  1411.         text_redisplay ();
  1412.  
  1413.         globalflags.MForceTitle = 1;
  1414.     } break;
  1415.  
  1416.     case _IT_BLOCK:
  1417.     {
  1418.         Block * block;
  1419.  
  1420.         if (ItemStack[ItemStackDepth].type != _IT_BLOCK)
  1421.         error ("pop:\nCannot pop block\nto something else");
  1422.  
  1423.         block = (Block *) ItemStack[ItemStackDepth].value;
  1424.  
  1425.         movmem (block, &ActualBlock, sizeof (Block));
  1426.  
  1427.         if (!Ep->iconmode)
  1428.         text_redrawblock (1);
  1429.     } break;
  1430.  
  1431.     case _IT_DISCARD:
  1432.     break;
  1433.  
  1434.     default:
  1435.         error ("pop:\nUnknown item\n`%s'", av[1]);
  1436.     break;
  1437.     }
  1438.  
  1439.     /* free only, if POP. If PEEK, restore Depth */
  1440.     if (av[0][1] != 'e')
  1441.     {
  1442.     if (ItemStack[ItemStackDepth].size == 3)
  1443.         free ((void *)ItemStack[ItemStackDepth].value);
  1444.     } else
  1445.     ItemStackDepth ++;
  1446. } /* do_pop */
  1447.  
  1448.  
  1449. /*****************************************************************************
  1450.  
  1451.     NAME
  1452.     SWAP item
  1453.  
  1454.     PARAMETER
  1455.     item / AUTO / DISCARD
  1456.  
  1457.     DESCRIPTION
  1458.     This exchanges the actual item with the item on stack, ie. the
  1459.     topmost item from stack is poped and the actual item is pushed.
  1460.  
  1461. ******************************************************************************/
  1462.  
  1463. void do_swap (void)
  1464. {
  1465.     ItemType type;
  1466.     ULONG    value;
  1467.  
  1468.     if (ItemStackDepth == 0)
  1469.     {
  1470.     error ("push:\nCannot swap %s:\nStack empty", av[1]);
  1471.     return;
  1472.     }
  1473.  
  1474.     ItemStackDepth --;
  1475.  
  1476.     value = ItemStack[ItemStackDepth].value;
  1477.  
  1478. #if MYDEBUG
  1479.     if (globalflags.debug)
  1480.     D(bug("Stack %d\n", ItemStackDepth));
  1481. #endif
  1482.  
  1483.     type = identify_item (av[1]);
  1484.  
  1485.     if (type == _IT_AUTO)
  1486.     type = ItemStack[ItemStackDepth].type;
  1487.  
  1488.     switch (type)
  1489.     {
  1490.     case _IT_POS:
  1491.         struct TextMarker pos;
  1492.  
  1493.         if (ItemStack[ItemStackDepth].type != _IT_POS)
  1494.         error ("pop:\nCannot pop position\nto something else");
  1495.  
  1496.         pos.ep     = Ep;
  1497.         pos.line   = Ep->line;
  1498.         pos.column = Ep->column;
  1499.  
  1500.         swapmem ((void *)value, &pos, sizeof (struct TextMarker));
  1501.  
  1502.         text_sync ();
  1503.  
  1504.         text_cursor (1);
  1505.         switch_ed (pos.ep);
  1506.         text_cursor (0);
  1507.  
  1508.         if (IntuitionBase->ActiveWindow != Ep->win)
  1509.         {
  1510.         WindowToFront (Ep->win);
  1511.         ActivateWindow (Ep->win);
  1512.         }
  1513.  
  1514.         if (pos.line >= Ep->lines)
  1515.         Ep->line = Ep->lines - 1;
  1516.         else
  1517.         Ep->line = pos.line;
  1518.  
  1519.         Ep->column = pos.column;
  1520.  
  1521.         text_load ();
  1522.         text_adjust (FALSE);
  1523.     break;
  1524.  
  1525.     case _IT_MODIFIED:
  1526.         if (ItemStack[ItemStackDepth].size != 1)
  1527.         error ("pop:\nCannot pop a struct\nto modified");
  1528.  
  1529.         ItemStack[ItemStackDepth].value = Ep->modified;
  1530.         Ep->modified = value;
  1531.     break;
  1532.  
  1533.     case _IT_ICONMODE:
  1534.         warn ("Not yet");
  1535.     break;
  1536.  
  1537.     case _IT_TABSTOP:
  1538.         if (ItemStack[ItemStackDepth].size != 1)
  1539.         error ("pop:\nCannot pop a struct\nto tabstop");
  1540.  
  1541.         ItemStack[ItemStackDepth].value = Ep->config.tabstop;
  1542.         Ep->config.tabstop = value;
  1543.     break;
  1544.  
  1545.     case _IT_MARGIN:
  1546.         if (ItemStack[ItemStackDepth].size != 1)
  1547.         error ("pop:\nCannot pop a struct\nto margin");
  1548.  
  1549.         ItemStack[ItemStackDepth].value = Ep->config.margin;
  1550.         Ep->config.margin = value;
  1551.     break;
  1552.  
  1553.     case _IT_INSERTMODE:
  1554.         if (ItemStack[ItemStackDepth].size != 1)
  1555.         error ("pop:\nCannot pop a struct\nto insertmode");
  1556.  
  1557.         ItemStack[ItemStackDepth].value = Ep->config.insertmode;
  1558.         Ep->config.insertmode = value;
  1559.     break;
  1560.  
  1561.     case _IT_IGNORECASE:
  1562.         if (ItemStack[ItemStackDepth].size != 1)
  1563.         error ("pop:\nCannot pop a struct\nto ignorecase");
  1564.  
  1565.         ItemStack[ItemStackDepth].value = Ep->config.ignorecase;
  1566.         Ep->config.ignorecase = value;
  1567.     break;
  1568.  
  1569.     case _IT_WORDWRAP:
  1570.         if (ItemStack[ItemStackDepth].size != 1)
  1571.         error ("pop:\nCannot pop a struct\nto wordwrap");
  1572.  
  1573.         ItemStack[ItemStackDepth].value = Ep->config.wordwrap;
  1574.         Ep->config.wordwrap = value;
  1575.     break;
  1576.  
  1577.     case _IT_WWCOL:
  1578.         if (ItemStack[ItemStackDepth].size != 1)
  1579.         error ("pop:\nCannot pop a struct\nto wordwrapcolumn");
  1580.  
  1581.         ItemStack[ItemStackDepth].value = Ep->config.wwcol;
  1582.         Ep->config.wwcol = value;
  1583.     break;
  1584.  
  1585.     case _IT_SAVETABS:
  1586.         if (ItemStack[ItemStackDepth].size != 1)
  1587.         error ("pop:\nCannot pop a struct\nto savetabs");
  1588.  
  1589.         ItemStack[ItemStackDepth].value = globalflags.Savetabs;
  1590.         globalflags.Savetabs = value;
  1591.     break;
  1592.  
  1593.     case _IT_ED:
  1594.         if (ItemStack[ItemStackDepth].type != _IT_ED)
  1595.         error ("pop:\nCannot pop ed\nto something else");
  1596.  
  1597.         ItemStack[ItemStackDepth].value = Ep;
  1598.         switch_ed ((ED *)value);
  1599.     break;
  1600.  
  1601.     case _IT_WINDOW:
  1602.     {
  1603.         USHORT array[4];
  1604.  
  1605.         if (ItemStack[ItemStackDepth].type != _IT_WINDOW)
  1606.         error ("pop:\nCannot pop window\nto something else");
  1607.  
  1608.         if (!Ep->iconmode)
  1609.         {
  1610.         array[0] = Ep->config.winx;
  1611.         array[1] = Ep->config.winy;
  1612.         array[2] = Ep->config.winwidth;
  1613.         array[3] = Ep->config.winheight;
  1614.         } else
  1615.         {
  1616.         array[0] = Ep->win->LeftEdge;
  1617.         array[1] = Ep->win->TopEdge;
  1618.         array[2] = Ep->win->Width;
  1619.         array[3] = Ep->win->Height;
  1620.         }
  1621.  
  1622.         swapmem ((void *)value, array, sizeof(USHORT)*4);
  1623.  
  1624.         Ep->config.winx     = array[0];
  1625.         Ep->config.winy     = array[1];
  1626.         Ep->config.winwidth  = array[2];
  1627.         Ep->config.winheight = array[3];
  1628.  
  1629.         if (!Ep->iconmode)
  1630.         {
  1631.         MoveWindow (Ep->win, Ep->config.winx - Ep->win->LeftEdge,
  1632.                      Ep->config.winy - Ep->win->TopEdge);
  1633.         SizeWindow (Ep->win, Ep->config.winwidth  - Ep->win->Width,
  1634.                      Ep->config.winheight - Ep->win->Height);
  1635.         }
  1636.     } break;
  1637.  
  1638.     case _IT_ICON:
  1639.     {
  1640.         USHORT array[2];
  1641.  
  1642.         if (ItemStack[ItemStackDepth].type != _IT_ICON)
  1643.         error ("pop:\nCannot pop icon\nto something else");
  1644.  
  1645.         if (Ep->iconmode)
  1646.         {
  1647.         array[0] = Ep->config.iwinx;
  1648.         array[1] = Ep->config.iwiny;
  1649.         } else
  1650.         {
  1651.         array[0] = Ep->win->LeftEdge;
  1652.         array[1] = Ep->win->TopEdge;
  1653.         }
  1654.  
  1655.         swapmem ((void *)value, array, sizeof(USHORT)*2);
  1656.  
  1657.         Ep->config.iwinx      = array[0];
  1658.         Ep->config.iwiny      = array[1];
  1659.  
  1660.         if (Ep->iconmode)
  1661.         {
  1662.         MoveWindow (Ep->win, Ep->config.iwinx - Ep->win->LeftEdge,
  1663.                      Ep->config.iwiny - Ep->win->TopEdge);
  1664.         }
  1665.     } break;
  1666.  
  1667.     case _IT_PENS:
  1668.     {
  1669.         ULONG array[5];
  1670.  
  1671.         if (ItemStack[ItemStackDepth].type != _IT_PENS)
  1672.         error ("pop:\nCannot pop pens\nto something else");
  1673.  
  1674.         array[0] = TEXT_FPEN;
  1675.         array[1] = TEXT_BPEN;
  1676.         array[2] = BLOCK_FPEN;
  1677.         array[3] = BLOCK_BPEN;
  1678.         array[4] = TITLE_BPEN;
  1679.  
  1680.         swapmem ((void *)value, array, sizeof(ULONG)*5);
  1681.  
  1682.         TEXT_FPEN  = array[0];
  1683.         TEXT_BPEN  = array[1];
  1684.         BLOCK_FPEN = array[2];
  1685.         BLOCK_BPEN = array[3];
  1686.         TITLE_BPEN = array[4];
  1687.  
  1688.         if (!Ep->iconmode)
  1689.         text_redisplay ();
  1690.  
  1691.         globalflags.MForceTitle = 1;
  1692.     } break;
  1693.  
  1694.     case _IT_BLOCK:
  1695.     {
  1696.         Block block;
  1697.  
  1698.         if (ItemStack[ItemStackDepth].type != _IT_BLOCK)
  1699.         error ("pop:\nCannot pop block\nto something else");
  1700.  
  1701.         movmem (&ActualBlock, &block, sizeof (Block));
  1702.  
  1703.         if (!Ep->iconmode)
  1704.         text_redrawblock (0);
  1705.  
  1706.         swapmem ((void *)value, &block, sizeof (Block));
  1707.  
  1708.         movmem (&block, &ActualBlock, sizeof (Block));
  1709.  
  1710.         if (!Ep->iconmode)
  1711.         text_redrawblock (1);
  1712.     } break;
  1713.  
  1714.     default:
  1715.         error ("swap:\nUnknown item\n`%s'", av[1]);
  1716.     break;
  1717.     }
  1718.  
  1719.     ItemStackDepth ++;
  1720. } /* do_pop */
  1721.  
  1722.  
  1723. static ItemType identify_item (char * itemname)
  1724. {
  1725.     static CONST struct
  1726.     {
  1727.     char   * name;
  1728.     ItemType type;
  1729.     } items[] =
  1730.     {
  1731.     "auto",         _IT_AUTO
  1732.     "block",        _IT_BLOCK,
  1733.     "discard",      _IT_DISCARD,
  1734.     "ed",           _IT_ED,
  1735.     "icon",         _IT_ICON,
  1736.     "iconmode",     _IT_ICONMODE,
  1737.     "ignorecase",   _IT_IGNORECASE,
  1738.     "insertmode",   _IT_INSERTMODE,
  1739.     "margin",       _IT_MARGIN,
  1740.     "modified",     _IT_MODIFIED
  1741.     "pens",         _IT_PENS,
  1742.     "pos",          _IT_POS,
  1743.     "savetabs",     _IT_SAVETABS,
  1744.     "tabstop",      _IT_TABSTOP,
  1745.     "window",       _IT_WINDOW,
  1746.     "wordwrap",     _IT_WORDWRAP,
  1747.     "wwcol",        _IT_WWCOL,
  1748.     };
  1749.     short low,
  1750.       high,
  1751.       t,
  1752.       diff;
  1753.  
  1754.     low = 0;
  1755.     high = sizeof (items) / sizeof (items[0]) -1;
  1756.  
  1757.     do
  1758.     {
  1759.     t = (low + high) / 2;
  1760.  
  1761.     if (!(diff = stricmp (itemname, items[t].name)) )
  1762.         break;
  1763.     else if (diff < 0)
  1764.         high = t-1;
  1765.     else
  1766.         low = t+1;
  1767.     } while (low <= high);
  1768.  
  1769.     if (!diff)
  1770.     return (items[t].type);
  1771.  
  1772.     return (-1);
  1773. } /* identify_item */
  1774.  
  1775.  
  1776. /*****************************************************************************
  1777.  
  1778.     NAME
  1779.     check_stack
  1780.  
  1781.     PARAMETER
  1782.     ED * ep;
  1783.  
  1784.     DESCRIPTION
  1785.     Checks the stack for thing left from editor ep or if ep == NULL
  1786.     cleans the full stack.
  1787.  
  1788. ******************************************************************************/
  1789.  
  1790. void check_stack (ED * ep)
  1791. {
  1792.     short i, j;
  1793.  
  1794.     if (ep)
  1795.     {
  1796.     for (i=j=0; i<ItemStackDepth; i ++)
  1797.     {
  1798.         if (!((ItemStack[i].type == _IT_ED ||
  1799.             ItemStack[i].type == _IT_POS ||
  1800.             ItemStack[i].type == _IT_BLOCK) &&
  1801.             ep == *(ED **)ItemStack[i].value) )
  1802.             {
  1803.         if (i != j)
  1804.         {
  1805.             ItemStack[j] = ItemStack[i];
  1806.         }
  1807.  
  1808.         j ++;
  1809.         }
  1810.     }
  1811.  
  1812.     ItemStackDepth = j;
  1813.     } else
  1814.     {
  1815.     for (i=0; i<ItemStackDepth; i ++)
  1816.     {
  1817.         if (ItemStack[i].size == 3)
  1818.         free ((void *)ItemStack[i].value);
  1819.     }
  1820.  
  1821.     ItemStackDepth = 0;
  1822.     }
  1823. } /* check_stack */
  1824.  
  1825.  
  1826. /******************************************************************************
  1827. *****  ENDE cmd.c
  1828. ******************************************************************************/
  1829.