home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
wp_dtp
/
xdme1821.lha
/
XDME
/
cmd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-04
|
35KB
|
1,829 lines
/******************************************************************************
MODUL
cmd.c
DESCRIPTION
In this file you find all routines for programming like
IF, WHILE, REPEAT
NOTES
BUGS
TODO
EXAMPLES
SEE ALSO
INDEX
HISTORY
14. Nov 1992 ada created
******************************************************************************/
/**************************************
Includes
**************************************/
#include "defs.h"
#define MYDEBUG 0
#include "debug.h"
/**************************************
Globale Variable
**************************************/
Prototype void do_if (void);
Prototype void do_repeat (void);
Prototype int do_toggle (int);
Prototype void do_scanf (void);
Prototype void do_push (void);
Prototype void do_pop (void);
Prototype void do_swap (void);
Prototype void check_stack (ED *);
/**************************************
Interne Defines & Strukturen
**************************************/
typedef enum
{
_IT_POS,
_IT_MODIFIED,
_IT_ICONMODE,
_IT_TABSTOP,
_IT_MARGIN,
_IT_INSERTMODE,
_IT_IGNORECASE,
_IT_WORDWRAP,
_IT_WWCOL,
_IT_WINDOW,
_IT_ICON,
_IT_PENS,
_IT_BLOCK,
_IT_AUTO,
_IT_SAVETABS,
_IT_ED,
_IT_DISCARD,
} ItemType;
struct Item
{
ItemType type; /* _IT_xxx */
USHORT size; /* 1-normal, 2-special, 3-malloc'd */
ULONG value; /* value */
};
/**************************************
Interne Variable
**************************************/
static ULONG MAX_STACK_SIZE = 0;
static struct Item * ItemStack = NULL;
static USHORT ItemStackDepth = 0;
/**************************************
Interne Prototypes
**************************************/
static ItemType identify_item (char *);
/*
IF condition trueaction, IFELSE condition trueaction falseaction
condition: !condition NOT the specified condition.
# toggle number is SET
top top of file (on first line)
bot end of file (on last line)
left start of line (leftmost column)
right end of line (nothing but spaces under and to the right)
modified text has been modified
insert currently in insert mode
y[<=>]# cursor is (any OR combo of <,>,=) row # (line numbers start at 1)
x[<=>]# cursor is (<,>,<=,>=,<>) column # (columns start at 1)
<> means 'not equal'
cl char under cursor is lower case
cu char under cursor is upper case
ca char under cursor is alpha
cn char under cursor is numeric
cb char within selected block
c[<=>]# char under cursor is (combo of <,>,and =) #,
where # can be a
ASCII-code (numeric: hex, oct, dez)
String (enclosed in ""). The cursor must
be on the first letter of "string".
Character-Group: [], i.e. c=[1-9] will be true
if cursor is on any number. c=[a-zA-DF-H]
is a valid construct !
block will BLOCK fail ?
selnext will SELECT NEXT succeed ?
selprev will SELECT PREV succeed ?
and especially for WHILE
true infinite-loop (!)
*/
void do_if (void)
{
BOOL haselse = (av[0][2] == 'e'), /* is there an ELSE ? */
iswhile = (av[0][0] == 'w'), /* is this a WHILE ? */
istrue, /* result of condition */
notop = 0; /* NOT ? */
BOOL c,
cx,
cc;
UBYTE * buf1, /* two buffers */
* buf2,
* ptr; /* tmp ptr */
ED * ep = Ep;
int i,
j, /* PATCH_NULL */
n, /* PATCH_NULL */
cxn,
cn;
buf1 = (UBYTE *)malloc(MAXLINELEN); /* get two buffers */
buf2 = (UBYTE *)malloc(MAXLINELEN);
if (buf1 == NULL || buf2 == NULL)
{
if (buf1) free(buf1); /* :-( */
if (buf2) free(buf2);
warn ("No Memory!");
nomemory ();
return;
}
/* prepare for Ctrl-C checking */
breakreset ();
ptr = av[1];
/* check for NOT */
if (*ptr == '!')
{
notop = 1;
++ptr;
}
c = tolower(ptr[0]);
cn = atoi ((char *)ptr);
cx = tolower(ptr[1]);
cxn = atoi ((char *)ptr+1);
strcpy ((char *)buf1, (char *)av[2]);
loop:
istrue = 0;
i = 0;
j = 1; /* PATCH_NULL */
switch (c)
{
case '$':
case '&':
{
char ci;
char * str;
for (j = 1; isalnum(ptr[j]); ++j);
ci = ptr[j];
ptr[j] = 0;
str = getvar(ptr+1);
ptr[j] = ci;
i = 0;
if (str)
{
if (!is_number(str))
{
error ("%s:\nvariable %s does not contain an integer",av[1], ptr+1);
goto done;
} /* if */
i = atoi(str);
free(str);
} else
{
error ("%s:\nunknown variable %s", av[0], ptr+1);
goto done;
}
if (ci)
goto conditional;
istrue = (i != 0);
break;
}
case 'x':
i = ep->column + 1;
case 'y':
if (!i)
i = ep->line + 1;
conditional:
{
/* int j, n; */
char any = 0;
for (; ptr[j] != '<' && ptr[j] != '>' && ptr[j] != '=' && ptr[j]; ++j); /* j=1 deleted */
if (!ptr[j])
{
error ("%s:\nBad conditional:\n`%s'", av[0], av[1]);
goto done;
}
for ( ; (ptr[j] == '<' || ptr[j] == '>' || ptr[j] == '=') && ptr[j]; ++j)
{
switch(ptr[j])
{
case '<':
any |= 1;
break;
case '=':
any |= 2;
break;
case '>':
any |= 4;
break;
}
}
if (!ptr[j] || !any || any == 7)
{
error ("%s:\nBad conditional `%s':\nUnexp. EOL or wrong compare", av[0], av[1]);
goto done;
}
for ( ; isspace (ptr[j]); ++j);
if (!ptr[j])
{
error ("%s:\nBad conditional `%s':\nUnexp. EOL", av[0], av[1]);
goto done;
}
if (ptr[j] == '"')
{
j ++;
for (n=j; ptr[j] != '"' && ptr[j]; j ++);
j -= n;
if (ep->config.ignorecase)
n = strnicmp(AddressOfElement(Current.text,ep->column),
&ptr[n], j);
else
n = strncmp (AddressOfElement(Current.text,ep->column),
&ptr[n], j);
} else if (ptr[j] == '[')
{
if (any != 2 && any != 5)
{
error ("%s:\nBad conditional `%s':\ncompare with [] must be '=' or '<>'", av[0], av[1]);
goto done;
}
j ++;
ReadElements (Current.text, &cc, ep->column, 1);
for (n=j; ptr[j] != ']' && ptr[j]; j ++)
{
if (ptr[j] == '\\') j ++;
else if (ptr[j+1] == '-')
{
if (!ptr[j+2] || ptr[j+2] == ']')
{
error ("%s:\nBad conditional `%s':\nString ended too early", av[0], av[1]);
goto done;
}
if (cc >= ptr[j] && cc <= ptr[j+2])
{
cc = ptr[j];
break;
}
j += 3;
continue;
}
if (cc == ptr[j]) break;
}
istrue = (cc==ptr[j] && any==2) || (cc!=ptr[j] && any==5);
break;
} else if (isdigit(ptr[j]) || ptr[j] == '+' || ptr[j] == '-')
{
n = i - atoi((char *)ptr+j);
} else
{
error ("%s:\nUnknown conditional `%s'", av[0], av[1]);
goto done;
}
istrue = (any&1 && n<0) || (any&2 && !n) || (any&4 && n>0);
}
break;
case 't':
if (cx == 'r')
istrue = 1;
else
istrue = ep->line == 0;
break;
case 'b':
if (cx == 'l')
istrue = block_ok ();
else istrue = ep->line == ep->lines-1;
break;
case 'l':
istrue = ep->column == 0;
break;
case 'r':
istrue = ep->column >= Clen();
break;
case 'm':
text_sync ();
istrue = ep->modified != 0;
break;
case 'e':
istrue = globalflags.Comlinemode != 0;
break;
case 'i':
istrue = ep->config.insertmode != 0;
break;
case 'c':
ReadElements (Current.text, &cc, ep->column, 1);
switch(cx)
{
case 'b':
istrue = is_inblock (ep->line, -1) != 0;
break;
case 'l':
istrue = islower (cc);
break;
case 'u':
istrue = isupper (cc);
break;
case 'a':
istrue = isalnum (cc);
break;
case 'n':
istrue = isdigit (cc);
break;
default: /* c[<=>]# */
ReadElements (Current.text, i, ep->column, 1);
goto conditional;
break;
}
break;
case 's': /* SELNEXT/SELPREV */
switch (tolower (ptr[3]))
{
case 'n':
if (GetSucc ((struct Node *)Ep))
istrue = 1;
break;
case 'p':
if (GetPred ((struct Node *)Ep))
istrue = 1;
break;
}
break;
case 'g': /* PATCH_NULL: */
if (is_number(ptr+1))
{
cn = atoi(ptr+1);
c = '0';
} /* if */
/* fall-through */
default:
if (isdigit (c))
istrue = do_toggle(cn) != 0;
else
{
error ("%s:\nBad condition\n`%s'", av[0], av[1]);
}
break;
}
istrue ^= notop;
if (istrue)
{
strcpy((char *)buf2, (char *)buf1); /* could be executed multiple
times */
if (do_command((char *)buf2) == 0)
goto done;
if (iswhile && !globalflags.Abortcommand)
{
if (breakcheck())
{
globalflags.Abortcommand = 1;
} else if (LoopCont)
{
LoopCont = 0; /* PATCH_NULL [14 Feb 1993] : func <-> ass */
goto loop;
} else if (LoopBreak)
{
LoopBreak = 0; /* PATCH_NULL [14 Feb 1993] : func <-> ass */
}
else
goto loop;
}
} else
{
if (haselse)
{ /* only executed once */
strcpy((char *)buf2, (char *)av[3]);
do_command((char *)buf2);
}
}
done:
free(buf1);
free(buf2);
} /* do_if */
/*
* repeat X command
*
* (if X is not a number it can be abbr. with 2 chars)
*
* X = N -number of repeats
* line -current line # (lines begin at 1)
* lbot -#lines to the bottom, inc. current
* cleft -column # (columns begin at 0)
* (thus is also chars to the left)
* cright-#chars to eol, including current char
* tr -#char positions to get to next tab stop
* tl -#char positions to get to next backtab stop
*/
#define SC(a,b) ((a)<<8|(b))
void do_repeat (void)
{
UBYTE *ptr = av[1];
unsigned long n;
char *buf1, *buf2;
if (!(buf1 = AllocMem (MAXLINELEN*2, 0)) )
{
globalflags.Abortcommand = 1;
return;
}
buf2 = buf1 + MAXLINELEN;
breakreset ();
strcpy (buf1, av[2]);
switch (SC(ptr[0],ptr[1]))
{
case SC('l','i'):
n = text_lineno ();
break;
case SC('l','b'):
n = text_lines () - text_lineno () + 1;
break;
case SC('c','l'):
n = text_colno ();
break;
case SC('c','r'):
n = text_cols () - text_colno ();
break;
case SC('t','r'):
n = text_tabsize () - (text_colno () % text_tabsize ());
break;
case SC('t','l'):
n = text_colno () % text_tabsize ();
if (n == 0)
n = text_tabsize ();
break;
default:
n = atoi (av[1]);
break;
}
while (n > 0)
{
strcpy(buf2, buf1);
if (do_command (buf2) == 0 || breakcheck ())
{
globalflags.Abortcommand = 1;
break;
}
if (LoopBreak)
{
LoopBreak = 0; /* PATCH_NULL [14 Feb 1993] : func <-> ass */
break;
} else if (LoopCont)
{
LoopCont = 0; /* PATCH_NULL [14 Feb 1993] : func <-> ass */
} /* if */
--n;
}
FreeMem (buf1, MAXLINELEN*2);
} /* do_repeat */
/*
* TOGGLE #, SETTOGGLE #, RESETTOGGLE #
*/
UBYTE bit[] =
{
0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80
};
int do_toggle (int n)
{
extern UBYTE tg[MAXTOGGLE/8];
int i;
if (n >= 0)
{
if (n >= MAXTOGGLE)
return(0);
/*printf ("Pos %d (%d/%d) %02x\n", n, n/8, n&7, tg[n/8]);*/
return(tg[n/8] & bit[n&7]);
}
i = atoi((char *)av[1]);
n = i/8;
i &= 7;
if (i >= 0 && i < MAXTOGGLE)
{
switch(av[0][0])
{
case 't':
tg[n] ^= bit[i];
break;
case 's':
tg[n] |= bit[i];
break;
case 'r':
tg[n] &= ~bit[i];
break;
}
}
return (0);
} /* do_toggle */
/*
* SCANF controlstring
*
* The C scanf routine. Only one variable, a string, is allowed in the
* control string.
*
* Modified by A. Digulla to be more useful for a text-editor.
*
* %s and %[] are still working
*
* Additional : (w)ord (l)ine (n)umber (b)lock (c)har
* (t)ext (a)lpha (r)emark
*
* w - get word
* l - get line with EVERYTHING
* b - get all that fits into isalphanum()
* c - get single char
* t - like line, but without preceding and trailing spaces
* a - all that fits into isalpha()
* r - get c-style comment
*
* if you precede a '+' to any of these, SCANF will start at the beginning
* to the left
*/
void do_scanf (void)
{
UBYTE buf[MAXLINELEN], *ptr, *bptr;
SHORT t;
BOOL left;
buf[0] = 0;
ptr = av[1];
if (*ptr == '%')
{
ptr ++;
if (*ptr == 's' || *ptr == '[')
{
if (*ptr == 's')
{
ptr ++;
*ptr = 0; /* Make sure there is nothing else */
} else
{
ptr ++;
if (*ptr == '~') *ptr = '^';
while (*ptr != ']') ptr ++;
ptr ++;
*ptr = 0; /* dito */
} /* if (*ptr == 's') */
sscanf (AddressOfElement (Current, Ep->column), av[1], buf);
} else
{
*buf = 0;
} /* if (*ptr == 's' && *ptr == '[') */
} else
{
char c;
error ("SCANF:\nTemporary disabled.");
#ifdef NOTDEF
if (*ptr == '+')
{
left = TRUE;
ptr ++;
} else
left = FALSE;
switch (*ptr)
{
case ('w') :
{
t = Ep->column;
if (t > Clen)
{
buf[0] = 0;
break;
}
if (left)
{
ReadElements (Current.text, &c, t, 1);
while (t && c != ' ')
{
t --;
ReadElements (Current.text, &c, t, 1);
}
}
while (c == ' ' && t < Clen ())
{
t ++;
ReadElements (Current.text, &c, t, 1);
}
if (t == Clen ())
{
buf[0] = 0;
break;
}
bptr = buf;
while (*ptr != ' ' && *ptr)
*bptr++ = *ptr++;
*bptr = 0;
break; } /* case ('w') */
case ('l') :
{
if (left)
{
strncpy ((char *)buf, (char *)Current, Clen);
buf[Clen] = 0;
} else
{
strncpy ((char *)buf, (char *)Current+Ep->column,
Clen-Ep->column);
buf[Clen - Ep->column] = 0;
}
break; } /* case ('l') */
case ('n') :
{
t = Ep->column;
if (t > Clen)
{
buf[0] = 0;
break;
}
ptr = Current+t;
if (left)
{
while (t && isdigit(*ptr))
{
ptr --;
t --;
}
if (t)
{
ptr ++;
t ++;
}
}
while (*ptr == ' ' && t < Clen)
{
ptr ++;
t ++;
}
if (t == Clen)
{
buf[0] = 0;
break;
}
bptr = buf;
while (isdigit(*ptr))
*bptr++ = *ptr++;
*bptr = 0;
break; } /* case ('n') */
case ('b') :
{
t = Ep->column;
if (t > Clen)
{
buf[0] = 0;
break;
}
ptr = Current+t;
if (left)
{
while (t && isalnum(*ptr))
{
ptr --;
t --;
}
if (t)
{
ptr ++;
t ++;
}
}
while (*ptr == ' ' && t < Clen)
{
ptr ++;
t ++;
}
if (t == Clen)
{
buf[0] = 0;
break;
}
bptr = buf;
while (isalnum(*ptr))
*bptr++ = *ptr++;
*bptr = 0;
break; } /* case ('b') */
case ('c') :
{
*buf = *(Current+Ep->column);
buf[1] = 0;
break; } /* case ('c') */
case ('t') :
{
if (left)
{
ptr = Current;
t = 0;
} else
{
t = Ep->column;
ptr = Current+t;
}
if (t >= Clen || Clen == 0)
{
buf[0] = 0;
break;
}
while (*ptr == ' ')
{
ptr ++;
t ++;
}
if (t >= Clen)
{
buf[0] = 0;
break;
}
strncpy ((char *)buf, (char *)ptr, Clen-t);
ptr = buf + Clen - t - 1;
while (*ptr == ' ')
ptr --;
ptr[1] = 0;
break; } /* case ('t') */
case ('a') :
{
t = Ep->column;
ptr = Current+t;
if (left)
{
while (isalpha(*ptr) && t)
{
ptr --;
t --;
}
if (t)
{
ptr ++;
t ++;
}
}
bptr = buf;
while (isalpha(*ptr))
*bptr++ = *ptr ++;
*bptr = 0;
break; } /* case ('a') */
case ('r') :
{
t = Ep->column;
ptr = Current+t;
if (left)
{
while (t)
{
if (*ptr == '*' && *(ptr-1) == '/')
{
ptr ++;
break;
}
t --;
ptr --;
}
if (!t)
{
*buf = 0;
break;
} else
{
t ++;
ptr ++;
}
}
if (t > Clen)
{
*buf = 0;
break;
}
bptr = buf;
while (t < Clen)
{
if (*ptr == '*' && ptr[1] == '/')
{
bptr --;
break;
}
*bptr++ = *ptr ++;
t ++;
}
*bptr = 0;
break; } /* case ('r') */
} /* switch (*ptr) */
#endif
} /* if (*ptr == '%') */
if (String)
free (String);
if (String = (char *)malloc (strlen ((char *)buf)+1))
{
strcpy ((char *)String, (char *)buf);
title (String);
}
} /* do_scanf */
/*****************************************************************************
NAME
do_push
PARAMETER
item
DESCRIPTION
Pushes an item on the internal stack.
******************************************************************************/
void do_push (void)
{
if (ItemStackDepth == MAX_STACK_SIZE)
{
struct Item * stack;
if (stack = AllocMem (sizeof(struct Item) * (MAX_STACK_SIZE + 32), 0))
{
if (MAX_STACK_SIZE)
movmem (ItemStack, stack, sizeof(struct Item)*MAX_STACK_SIZE);
MAX_STACK_SIZE += 32;
ItemStack = stack;
} else
{
error ("push:\nCannot push %s:\nStack full", av[1]);
return;
}
}
switch (ItemStack[ItemStackDepth].type = identify_item (av[1]))
{
case _IT_POS:
{
struct TextMarker * pos;
if (pos = malloc (sizeof(struct TextMarker)))
{
pos->ep = Ep;
pos->line = Ep->line;
pos->column = Ep->column;
ItemStack[ItemStackDepth].value = (ULONG)pos;
ItemStack[ItemStackDepth].size = 3;
} else
{
out_of_memory:
warn ("push: Out of memory error");
globalflags.Abortcommand = 1;
return;
}
} break;
case _IT_MODIFIED:
ItemStack[ItemStackDepth].value = Ep->modified;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_ICONMODE:
ItemStack[ItemStackDepth].value = Ep->iconmode;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_TABSTOP:
ItemStack[ItemStackDepth].value = Ep->config.tabstop;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_MARGIN:
ItemStack[ItemStackDepth].value = Ep->config.margin;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_INSERTMODE:
ItemStack[ItemStackDepth].value = Ep->config.insertmode;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_IGNORECASE:
ItemStack[ItemStackDepth].value = Ep->config.ignorecase;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_WORDWRAP:
ItemStack[ItemStackDepth].value = Ep->config.wordwrap;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_WWCOL:
ItemStack[ItemStackDepth].value = Ep->config.wwcol;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_SAVETABS:
ItemStack[ItemStackDepth].value = globalflags.Savetabs;
ItemStack[ItemStackDepth].size = 1;
break;
case _IT_ED:
ItemStack[ItemStackDepth].value = (ULONG)Ep;
ItemStack[ItemStackDepth].size = 2;
break;
case _IT_WINDOW:
{
USHORT * array;
if (array = malloc (4*sizeof(USHORT)))
{
if (!Ep->iconmode)
{
array[0] = Ep->config.winx;
array[1] = Ep->config.winy;
array[2] = Ep->config.winwidth;
array[3] = Ep->config.winheight;
} else
{
array[0] = Ep->win->LeftEdge;
array[1] = Ep->win->TopEdge;
array[2] = Ep->win->Width;
array[3] = Ep->win->Height;
}
ItemStack[ItemStackDepth].value = (ULONG)array;
ItemStack[ItemStackDepth].size = 3;
} else
{
goto out_of_memory;
}
} break;
case _IT_ICON:
{
USHORT * array;
if (array = malloc (2*sizeof(USHORT)))
{
if (Ep->iconmode)
{
array[0] = Ep->config.iwinx;
array[1] = Ep->config.iwiny;
} else
{
array[0] = Ep->win->LeftEdge;
array[1] = Ep->win->TopEdge;
}
ItemStack[ItemStackDepth].value = (ULONG)array;
ItemStack[ItemStackDepth].size = 3;
} else
{
goto out_of_memory;
}
} break;
case _IT_PENS:
{
ULONG * array;
if (array = malloc (5*sizeof(ULONG)))
{
array[0] = TEXT_FPEN;
array[1] = TEXT_BPEN;
array[2] = BLOCK_FPEN;
array[3] = BLOCK_BPEN;
array[4] = TITLE_BPEN;
ItemStack[ItemStackDepth].value = (ULONG)array;
ItemStack[ItemStackDepth].size = 3;
} else
{
goto out_of_memory;
}
} break;
case _IT_BLOCK:
{
Block * block;
if (block = malloc (sizeof(Block)))
{
movmem (&ActualBlock, block, sizeof (Block));
ItemStack[ItemStackDepth].value = (ULONG)block;
ItemStack[ItemStackDepth].size = 3;
if (!Ep->iconmode)
text_redrawblock (0);
} else
{
goto out_of_memory;
}
} break;
default:
error ("push:\nUnknown item\n`%s'", av[1]);
return;
break;
}
ItemStackDepth ++;
#if MYDEBUG
if (globalflags.debug)
D(bug("PUSH Stack %d\n", ItemStackDepth));
#endif
} /* do_push */
/*****************************************************************************
NAME
POP/PEEK item
PARAMETER
item / AUTO / DISCARD
DESCRIPTION
Pops an item from the internal stack or (PICK) just get's the value
of it without poping it from the stack.
******************************************************************************/
void do_pop (void)
{
ItemType type;
if (ItemStackDepth == 0)
{
error ("%s:\nCannot pop %s:\nStack empty", av[0], av[1]);
return;
}
ItemStackDepth --;
#if MYDEBUG
if (globalflags.debug)
D(bug("POP Stack %d\n", ItemStackDepth));
#endif
type = identify_item (av[1]);
if (type == _IT_AUTO)
type = ItemStack[ItemStackDepth].type;
switch (type)
{
case _IT_POS:
struct TextMarker * pos;
if (ItemStack[ItemStackDepth].type != _IT_POS)
error ("pop:\nCannot pop position\nto something else");
pos = (struct TextMarker *)ItemStack[ItemStackDepth].value;
text_sync ();
text_cursor (1);
switch_ed (pos->ep);
text_cursor (0);
if (IntuitionBase->ActiveWindow != Ep->win)
{
WindowToFront (Ep->win);
ActivateWindow (Ep->win);
}
if (pos->line >= Ep->lines)
Ep->line = Ep->lines - 1;
else
Ep->line = pos->line;
Ep->column = pos->column;
text_load ();
text_adjust (FALSE);
break;
case _IT_MODIFIED:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto modified");
Ep->modified = ItemStack[ItemStackDepth].value;
break;
case _IT_ICONMODE:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto iconmode");
if (Ep->iconmode != ItemStack[ItemStackDepth].value)
{
if (ItemStack[ItemStackDepth].value)
iconify ();
else
uniconify ();
}
break;
case _IT_TABSTOP:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto tabstop");
Ep->config.tabstop = ItemStack[ItemStackDepth].value;
break;
case _IT_MARGIN:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto margin");
Ep->config.margin = ItemStack[ItemStackDepth].value;
break;
case _IT_INSERTMODE:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto insertmode");
Ep->config.insertmode = ItemStack[ItemStackDepth].value;
break;
case _IT_IGNORECASE:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto ignorecase");
Ep->config.ignorecase = ItemStack[ItemStackDepth].value;
break;
case _IT_WORDWRAP:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto wordwrap");
Ep->config.wordwrap = ItemStack[ItemStackDepth].value;
break;
case _IT_WWCOL:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto wordwrapcolumn");
Ep->config.wwcol = ItemStack[ItemStackDepth].value;
break;
case _IT_SAVETABS:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto savetabs");
globalflags.Savetabs = ItemStack[ItemStackDepth].value;
break;
case _IT_ED:
if (ItemStack[ItemStackDepth].type != _IT_ED)
error ("pop:\nCannot pop ed\nto something else");
switch_ed ((ED *)ItemStack[ItemStackDepth].value);
break;
case _IT_WINDOW:
{
USHORT * array;
if (ItemStack[ItemStackDepth].type != _IT_WINDOW)
error ("pop:\nCannot pop window\nto something else");
array = (USHORT *)ItemStack[ItemStackDepth].value;
Ep->config.winx = array[0];
Ep->config.winy = array[1];
Ep->config.winwidth = array[2];
Ep->config.winheight = array[3];
if (!Ep->iconmode)
{
MoveWindow (Ep->win, Ep->config.winx - Ep->win->LeftEdge,
Ep->config.winy - Ep->win->TopEdge);
SizeWindow (Ep->win, Ep->config.winwidth - Ep->win->Width,
Ep->config.winheight - Ep->win->Height);
}
} break;
case _IT_ICON:
{
USHORT * array;
if (ItemStack[ItemStackDepth].type != _IT_ICON)
error ("pop:\nCannot pop icon\nto something else");
Ep->config.iwinx = array[0];
Ep->config.iwiny = array[1];
if (Ep->iconmode)
{
MoveWindow (Ep->win, Ep->config.iwinx - Ep->win->LeftEdge,
Ep->config.iwiny - Ep->win->TopEdge);
}
} break;
case _IT_PENS:
{
ULONG * array;
if (ItemStack[ItemStackDepth].type != _IT_PENS)
error ("pop:\nCannot pop pens\nto something else");
array = (ULONG *)ItemStack[ItemStackDepth].value;
TEXT_FPEN = array[0];
TEXT_BPEN = array[1];
BLOCK_FPEN = array[2];
BLOCK_BPEN = array[3];
TITLE_BPEN = array[4];
if (!Ep->iconmode)
text_redisplay ();
globalflags.MForceTitle = 1;
} break;
case _IT_BLOCK:
{
Block * block;
if (ItemStack[ItemStackDepth].type != _IT_BLOCK)
error ("pop:\nCannot pop block\nto something else");
block = (Block *) ItemStack[ItemStackDepth].value;
movmem (block, &ActualBlock, sizeof (Block));
if (!Ep->iconmode)
text_redrawblock (1);
} break;
case _IT_DISCARD:
break;
default:
error ("pop:\nUnknown item\n`%s'", av[1]);
break;
}
/* free only, if POP. If PEEK, restore Depth */
if (av[0][1] != 'e')
{
if (ItemStack[ItemStackDepth].size == 3)
free ((void *)ItemStack[ItemStackDepth].value);
} else
ItemStackDepth ++;
} /* do_pop */
/*****************************************************************************
NAME
SWAP item
PARAMETER
item / AUTO / DISCARD
DESCRIPTION
This exchanges the actual item with the item on stack, ie. the
topmost item from stack is poped and the actual item is pushed.
******************************************************************************/
void do_swap (void)
{
ItemType type;
ULONG value;
if (ItemStackDepth == 0)
{
error ("push:\nCannot swap %s:\nStack empty", av[1]);
return;
}
ItemStackDepth --;
value = ItemStack[ItemStackDepth].value;
#if MYDEBUG
if (globalflags.debug)
D(bug("Stack %d\n", ItemStackDepth));
#endif
type = identify_item (av[1]);
if (type == _IT_AUTO)
type = ItemStack[ItemStackDepth].type;
switch (type)
{
case _IT_POS:
struct TextMarker pos;
if (ItemStack[ItemStackDepth].type != _IT_POS)
error ("pop:\nCannot pop position\nto something else");
pos.ep = Ep;
pos.line = Ep->line;
pos.column = Ep->column;
swapmem ((void *)value, &pos, sizeof (struct TextMarker));
text_sync ();
text_cursor (1);
switch_ed (pos.ep);
text_cursor (0);
if (IntuitionBase->ActiveWindow != Ep->win)
{
WindowToFront (Ep->win);
ActivateWindow (Ep->win);
}
if (pos.line >= Ep->lines)
Ep->line = Ep->lines - 1;
else
Ep->line = pos.line;
Ep->column = pos.column;
text_load ();
text_adjust (FALSE);
break;
case _IT_MODIFIED:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto modified");
ItemStack[ItemStackDepth].value = Ep->modified;
Ep->modified = value;
break;
case _IT_ICONMODE:
warn ("Not yet");
break;
case _IT_TABSTOP:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto tabstop");
ItemStack[ItemStackDepth].value = Ep->config.tabstop;
Ep->config.tabstop = value;
break;
case _IT_MARGIN:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto margin");
ItemStack[ItemStackDepth].value = Ep->config.margin;
Ep->config.margin = value;
break;
case _IT_INSERTMODE:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto insertmode");
ItemStack[ItemStackDepth].value = Ep->config.insertmode;
Ep->config.insertmode = value;
break;
case _IT_IGNORECASE:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto ignorecase");
ItemStack[ItemStackDepth].value = Ep->config.ignorecase;
Ep->config.ignorecase = value;
break;
case _IT_WORDWRAP:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto wordwrap");
ItemStack[ItemStackDepth].value = Ep->config.wordwrap;
Ep->config.wordwrap = value;
break;
case _IT_WWCOL:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto wordwrapcolumn");
ItemStack[ItemStackDepth].value = Ep->config.wwcol;
Ep->config.wwcol = value;
break;
case _IT_SAVETABS:
if (ItemStack[ItemStackDepth].size != 1)
error ("pop:\nCannot pop a struct\nto savetabs");
ItemStack[ItemStackDepth].value = globalflags.Savetabs;
globalflags.Savetabs = value;
break;
case _IT_ED:
if (ItemStack[ItemStackDepth].type != _IT_ED)
error ("pop:\nCannot pop ed\nto something else");
ItemStack[ItemStackDepth].value = Ep;
switch_ed ((ED *)value);
break;
case _IT_WINDOW:
{
USHORT array[4];
if (ItemStack[ItemStackDepth].type != _IT_WINDOW)
error ("pop:\nCannot pop window\nto something else");
if (!Ep->iconmode)
{
array[0] = Ep->config.winx;
array[1] = Ep->config.winy;
array[2] = Ep->config.winwidth;
array[3] = Ep->config.winheight;
} else
{
array[0] = Ep->win->LeftEdge;
array[1] = Ep->win->TopEdge;
array[2] = Ep->win->Width;
array[3] = Ep->win->Height;
}
swapmem ((void *)value, array, sizeof(USHORT)*4);
Ep->config.winx = array[0];
Ep->config.winy = array[1];
Ep->config.winwidth = array[2];
Ep->config.winheight = array[3];
if (!Ep->iconmode)
{
MoveWindow (Ep->win, Ep->config.winx - Ep->win->LeftEdge,
Ep->config.winy - Ep->win->TopEdge);
SizeWindow (Ep->win, Ep->config.winwidth - Ep->win->Width,
Ep->config.winheight - Ep->win->Height);
}
} break;
case _IT_ICON:
{
USHORT array[2];
if (ItemStack[ItemStackDepth].type != _IT_ICON)
error ("pop:\nCannot pop icon\nto something else");
if (Ep->iconmode)
{
array[0] = Ep->config.iwinx;
array[1] = Ep->config.iwiny;
} else
{
array[0] = Ep->win->LeftEdge;
array[1] = Ep->win->TopEdge;
}
swapmem ((void *)value, array, sizeof(USHORT)*2);
Ep->config.iwinx = array[0];
Ep->config.iwiny = array[1];
if (Ep->iconmode)
{
MoveWindow (Ep->win, Ep->config.iwinx - Ep->win->LeftEdge,
Ep->config.iwiny - Ep->win->TopEdge);
}
} break;
case _IT_PENS:
{
ULONG array[5];
if (ItemStack[ItemStackDepth].type != _IT_PENS)
error ("pop:\nCannot pop pens\nto something else");
array[0] = TEXT_FPEN;
array[1] = TEXT_BPEN;
array[2] = BLOCK_FPEN;
array[3] = BLOCK_BPEN;
array[4] = TITLE_BPEN;
swapmem ((void *)value, array, sizeof(ULONG)*5);
TEXT_FPEN = array[0];
TEXT_BPEN = array[1];
BLOCK_FPEN = array[2];
BLOCK_BPEN = array[3];
TITLE_BPEN = array[4];
if (!Ep->iconmode)
text_redisplay ();
globalflags.MForceTitle = 1;
} break;
case _IT_BLOCK:
{
Block block;
if (ItemStack[ItemStackDepth].type != _IT_BLOCK)
error ("pop:\nCannot pop block\nto something else");
movmem (&ActualBlock, &block, sizeof (Block));
if (!Ep->iconmode)
text_redrawblock (0);
swapmem ((void *)value, &block, sizeof (Block));
movmem (&block, &ActualBlock, sizeof (Block));
if (!Ep->iconmode)
text_redrawblock (1);
} break;
default:
error ("swap:\nUnknown item\n`%s'", av[1]);
break;
}
ItemStackDepth ++;
} /* do_pop */
static ItemType identify_item (char * itemname)
{
static CONST struct
{
char * name;
ItemType type;
} items[] =
{
"auto", _IT_AUTO
"block", _IT_BLOCK,
"discard", _IT_DISCARD,
"ed", _IT_ED,
"icon", _IT_ICON,
"iconmode", _IT_ICONMODE,
"ignorecase", _IT_IGNORECASE,
"insertmode", _IT_INSERTMODE,
"margin", _IT_MARGIN,
"modified", _IT_MODIFIED
"pens", _IT_PENS,
"pos", _IT_POS,
"savetabs", _IT_SAVETABS,
"tabstop", _IT_TABSTOP,
"window", _IT_WINDOW,
"wordwrap", _IT_WORDWRAP,
"wwcol", _IT_WWCOL,
};
short low,
high,
t,
diff;
low = 0;
high = sizeof (items) / sizeof (items[0]) -1;
do
{
t = (low + high) / 2;
if (!(diff = stricmp (itemname, items[t].name)) )
break;
else if (diff < 0)
high = t-1;
else
low = t+1;
} while (low <= high);
if (!diff)
return (items[t].type);
return (-1);
} /* identify_item */
/*****************************************************************************
NAME
check_stack
PARAMETER
ED * ep;
DESCRIPTION
Checks the stack for thing left from editor ep or if ep == NULL
cleans the full stack.
******************************************************************************/
void check_stack (ED * ep)
{
short i, j;
if (ep)
{
for (i=j=0; i<ItemStackDepth; i ++)
{
if (!((ItemStack[i].type == _IT_ED ||
ItemStack[i].type == _IT_POS ||
ItemStack[i].type == _IT_BLOCK) &&
ep == *(ED **)ItemStack[i].value) )
{
if (i != j)
{
ItemStack[j] = ItemStack[i];
}
j ++;
}
}
ItemStackDepth = j;
} else
{
for (i=0; i<ItemStackDepth; i ++)
{
if (ItemStack[i].size == 3)
free ((void *)ItemStack[i].value);
}
ItemStackDepth = 0;
}
} /* check_stack */
/******************************************************************************
***** ENDE cmd.c
******************************************************************************/