m32script: infinite loop safety halt (send a SIGINT), saved input history, states can be invoked without "state" keyword when in OSD

git-svn-id: https://svn.eduke32.com/eduke32@1661 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2010-06-25 23:01:54 +00:00
parent 068d3c0e52
commit 1905a1cf02
9 changed files with 167 additions and 72 deletions

View file

@ -134,6 +134,10 @@ static inline int32_t wallength(int16_t i)
#define CLEARLINES2D(Startline, Numlines, Color) clearbuf((char *)(frameplace + ((Startline)*bytesperline)), (bytesperline*(Numlines))>>2, (Color))
#define SCRIPTHISTSIZ 32 // should be the same as OSD_HISTORYDEPTH for maximum win
extern const char *scripthist[SCRIPTHISTSIZ];
extern int32_t scripthistend;
#ifdef __cplusplus
}
#endif

View file

@ -190,5 +190,12 @@ void OSD_WriteCvars(FILE *fp);
#define OSD_ERROR OSDTEXT_DARKRED OSDTEXT_BRIGHT
#define TEXTSIZE 32768
#define OSD_EDITLENGTH 511
#define OSD_HISTORYDEPTH 32
extern char osdhistorybuf[OSD_HISTORYDEPTH][OSD_EDITLENGTH+1]; // history strings
extern int32_t osdhistorysize; // number of entries in history
extern int32_t osdhistorytotal; // number of total history entries
#endif // __osd_h__

View file

@ -6020,7 +6020,7 @@ void showsectordata(int16_t sectnum)
DOPRINT(32, "^10CEILING:^O");
DOPRINT(48, "Flags (hex): %x", sec->ceilingstat);
DOPRINT(56, "(X, Y)pan: %d, %d", sec->ceilingxpanning, sec->ceilingypanning);
DOPRINT(56, "(X,Y)pan: %d, %d", sec->ceilingxpanning, sec->ceilingypanning);
DOPRINT(64, "Shade byte: %d", sec->ceilingshade);
DOPRINT(72, "Z-coordinate: %d", sec->ceilingz);
DOPRINT(80, "Tile number: %d", sec->ceilingpicnum);
@ -6031,7 +6031,7 @@ void showsectordata(int16_t sectnum)
DOPRINT(32, "^10FLOOR:^O");
DOPRINT(48, "Flags (hex): %x", sec->floorstat);
DOPRINT(56, "(X, Y)pan: %d, %d", sec->floorxpanning, sec->floorypanning);
DOPRINT(56, "(X,Y)pan: %d, %d", sec->floorxpanning, sec->floorypanning);
DOPRINT(64, "Shade byte: %d", sec->floorshade);
DOPRINT(72, "Z-coordinate: %d", sec->floorz);
DOPRINT(80, "Tile number: %d", sec->floorpicnum);
@ -6072,8 +6072,8 @@ void showwalldata(int16_t wallnum)
DOPRINT(48, "Flags (hex): %x", wal->cstat);
DOPRINT(56, "Shade: %d", wal->shade);
DOPRINT(64, "Pal: %d", wal->pal);
DOPRINT(72, "(X, Y)repeat: %d, %d", wal->xrepeat, wal->yrepeat);
DOPRINT(80, "(X, Y)pan: %d, %d", wal->xpanning, wal->ypanning);
DOPRINT(72, "(X,Y)repeat: %d, %d", wal->xrepeat, wal->yrepeat);
DOPRINT(80, "(X,Y)pan: %d, %d", wal->xpanning, wal->ypanning);
DOPRINT(88, "Tile number: %d", wal->picnum);
DOPRINT(96, "OverTile number: %d", wal->overpicnum);
@ -6125,8 +6125,8 @@ void showspritedata(int16_t spritenum)
DOPRINT(48, "Flags (hex): %x", spr->cstat);
DOPRINT(56, "Shade: %d", spr->shade);
DOPRINT(64, "Pal: %d", spr->pal);
DOPRINT(72, "(X, Y)repeat: %d, %d", spr->xrepeat, spr->yrepeat);
DOPRINT(80, "(X, Y)offset: %d, %d", spr->xoffset, spr->yoffset);
DOPRINT(72, "(X,Y)repeat: %d, %d", spr->xrepeat, spr->yrepeat);
DOPRINT(80, "(X,Y)offset: %d, %d", spr->xoffset, spr->yoffset);
DOPRINT(88, "Tile number: %d", spr->picnum);
col++;

View file

@ -112,7 +112,7 @@ extern int32_t ParentalLock;
int32_t loadsetup(const char *fn)
{
BFILE *fp;
#define VL 256
#define VL 1024
char val[VL];
int32_t i;
@ -265,6 +265,30 @@ int32_t loadsetup(const char *fn)
if ((p=strchr(p,','))==0)break; p++;
}
}
// load m32script history
for (i=0; i<SCRIPTHISTSIZ; i++)
{
Bsprintf(val, "hist%d", i);
if (readconfig(fp, val, val, VL) <= 0)
break;
scripthist[i] = Bstrdup(val);
}
scripthistend = i;
// copy script history into OSD history
for (i=0; i<min(scripthistend, OSD_HISTORYDEPTH); i++)
{
Bstrncpy(osdhistorybuf[i], scripthist[scripthistend-1-i], OSD_EDITLENGTH+1);
osdhistorybuf[i][OSD_EDITLENGTH] = 0;
osdhistorysize++;
osdhistorytotal++;
}
scripthistend %= SCRIPTHISTSIZ;
Bfclose(fp);
return 0;
@ -273,7 +297,7 @@ int32_t loadsetup(const char *fn)
int32_t writesetup(const char *fn)
{
BFILE *fp;
int32_t i,first=1;
int32_t i,j,first=1;
fp = Bfopen(fn,"wt");
if (!fp) return -1;
@ -492,7 +516,16 @@ int32_t writesetup(const char *fn)
Bfprintf(fp,first?"%02X-%02X":",%02X-%02X",i,remap[i]);
first=0;
}
Bfprintf(fp,"\n");
Bfprintf(fp,"\n\n");
// save m32script history
first = 1;
for (i=scripthistend, j=0; first || i!=scripthistend; i=(i+1)%SCRIPTHISTSIZ, first=0)
{
if (scripthist[i])
Bfprintf(fp, "hist%d = %s\n", j++, scripthist[i]);
}
Bfclose(fp);
return 0;

View file

@ -59,9 +59,8 @@ static int32_t keytime=0;
static int32_t osdscrtime = 0;
// command prompt editing
#define EDITLENGTH 511
static char osdeditbuf[EDITLENGTH+1]; // editing buffer
static char osdedittmp[EDITLENGTH+1]; // editing buffer temporary workspace
static char osdeditbuf[OSD_EDITLENGTH+1]; // editing buffer
static char osdedittmp[OSD_EDITLENGTH+1]; // editing buffer temporary workspace
static int32_t osdeditlen=0; // length of characters in edit buffer
static int32_t osdeditcursor=0; // position of cursor in edit buffer
static int32_t osdeditwinstart=0;
@ -69,11 +68,10 @@ static int32_t osdeditwinend=60-1-3;
#define editlinewidth (osdcols-1-3)
// command processing
#define HISTORYDEPTH 32
static int32_t osdhistorypos=-1; // position we are at in the history buffer
static char osdhistorybuf[HISTORYDEPTH][EDITLENGTH+1]; // history strings
static int32_t osdhistorysize=0; // number of entries in history
static int32_t osdhistorytotal=0; // number of total history entries
char osdhistorybuf[OSD_HISTORYDEPTH][OSD_EDITLENGTH+1]; // history strings
int32_t osdhistorysize=0; // number of entries in history
int32_t osdhistorytotal=0; // number of total history entries
// execution buffer
// the execution buffer works from the command history
@ -630,7 +628,7 @@ static int32_t _internal_osdfunc_history(const osdfuncparm_t *parm)
int32_t i, j = 0;
UNREFERENCED_PARAMETER(parm);
OSD_Printf(OSDTEXT_RED "Command history:\n");
for (i=HISTORYDEPTH-1; i>=0; i--)
for (i=OSD_HISTORYDEPTH-1; i>=0; i--)
if (osdhistorybuf[i][0])
OSD_Printf("%4d \"%s\"\n",osdhistorytotal-osdhistorysize+(++j),osdhistorybuf[i]);
return OSDCMD_OK;
@ -858,7 +856,7 @@ static void OSD_HistoryPrev(void)
if (osdhistorypos >= osdhistorysize-1) return;
osdhistorypos++;
Bmemcpy(osdeditbuf, osdhistorybuf[osdhistorypos], EDITLENGTH+1);
Bmemcpy(osdeditbuf, osdhistorybuf[osdhistorypos], OSD_EDITLENGTH+1);
osdeditcursor = 0;
while (osdeditbuf[osdeditcursor]) osdeditcursor++;
@ -897,7 +895,7 @@ static void OSD_HistoryNext(void)
}
osdhistorypos--;
Bmemcpy(osdeditbuf, osdhistorybuf[osdhistorypos], EDITLENGTH+1);
Bmemcpy(osdeditbuf, osdhistorybuf[osdhistorypos], OSD_EDITLENGTH+1);
osdeditcursor = 0;
while (osdeditbuf[osdeditcursor]) osdeditcursor++;
@ -1055,7 +1053,7 @@ int32_t OSD_HandleChar(char ch)
{
for (i=osdeditcursor; i>0; i--) if (osdeditbuf[i-1] == ' ') break;
osdeditlen = i;
for (j=0; tabc->name[j] && osdeditlen <= EDITLENGTH
for (j=0; tabc->name[j] && osdeditlen <= OSD_EDITLENGTH
&& (osdeditlen < commonsize); i++,j++,osdeditlen++)
osdeditbuf[i] = tabc->name[j];
osdeditcursor = osdeditlen;
@ -1085,11 +1083,11 @@ int32_t OSD_HandleChar(char ch)
osdeditbuf[osdeditlen] = 0;
if (Bstrcmp(osdhistorybuf[0], osdeditbuf))
{
Bmemmove(osdhistorybuf[1], osdhistorybuf[0], (HISTORYDEPTH-1)*(EDITLENGTH+1));
Bmemmove(osdhistorybuf[0], osdeditbuf, EDITLENGTH+1);
if (osdhistorysize < HISTORYDEPTH) osdhistorysize++;
Bmemmove(osdhistorybuf[1], osdhistorybuf[0], (OSD_HISTORYDEPTH-1)*(OSD_EDITLENGTH+1));
Bmemmove(osdhistorybuf[0], osdeditbuf, OSD_EDITLENGTH+1);
if (osdhistorysize < OSD_HISTORYDEPTH) osdhistorysize++;
osdhistorytotal++;
if (osdexeccount == HISTORYDEPTH)
if (osdexeccount == OSD_HISTORYDEPTH)
OSD_Printf("Command Buffer Warning: Failed queueing command "
"for execution. Buffer full.\n");
else
@ -1097,7 +1095,7 @@ int32_t OSD_HandleChar(char ch)
}
else
{
if (osdexeccount == HISTORYDEPTH)
if (osdexeccount == OSD_HISTORYDEPTH)
OSD_Printf("Command Buffer Warning: Failed queueing command "
"for execution. Buffer full.\n");
else
@ -1150,7 +1148,7 @@ int32_t OSD_HandleChar(char ch)
{
if ((osdflags & OSD_OVERTYPE) == 0)
{
if (osdeditlen == EDITLENGTH) // buffer full, can't insert another char
if (osdeditlen == OSD_EDITLENGTH) // buffer full, can't insert another char
return 0;
if (osdeditcursor < osdeditlen)
Bmemmove(osdeditbuf+osdeditcursor+1, osdeditbuf+osdeditcursor, osdeditlen-osdeditcursor);

View file

@ -813,16 +813,19 @@ defstate resetallws // reset all sprites and walls to default repeat/panning
}
ends
defstate js // jump to current sprite
set posx .x
set posy .y
set posz .z
updatecursectnum
ends
defstate jumptosec // (tmp)
for i allsectors
{
ife i tmp
{
set j sector[i].wallptr
set posx wall[j].x
set posy wall[j].y
}
}
ifge tmp 0 ifl tmp numsectors nullop else return
set j sector[tmp].wallptr
set posx wall[j].x
set posy wall[j].y
updatecursectnum
ends
// Map corruption checker

View file

@ -52,6 +52,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <shellapi.h>
#endif
#include <signal.h>
#define BUILDDATE " 20100521"
static int32_t floor_over_floor;
@ -89,6 +91,8 @@ static struct strllist
}
*CommandPaths = NULL, *CommandGrps = NULL;
const char *scripthist[SCRIPTHISTSIZ];
int32_t scripthistend = 0;
//////////////////// Key stuff ////////////////////
@ -7498,7 +7502,7 @@ static int32_t osdcmd_disasm(const osdfuncparm_t *parm)
static int32_t osdcmd_do(const osdfuncparm_t *parm)
{
intptr_t tscrofs;
intptr_t oscrofs;
char *tp;
int32_t i, j, slen, ofs;
int32_t onumconstants=g_numSavedConstants;
@ -7506,7 +7510,7 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
if (parm->numparms==0)
return OSDCMD_SHOWHELP;
tscrofs = (g_scriptPtr-script);
oscrofs = (g_scriptPtr-script);
ofs = 2*(parm->numparms>0); // true if "do" command
slen = Bstrlen(parm->raw+ofs);
@ -7527,7 +7531,7 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
if (g_numCompilerErrors)
{
// g_scriptPtr = script + tscrofs; // handled in C_Compile()
// g_scriptPtr = script + oscrofs; // handled in C_Compile()
return OSDCMD_OK;
}
@ -7540,11 +7544,21 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
g_numSavedConstants = onumconstants;
*g_scriptPtr = CON_RETURN + (g_lineNumber<<12);
g_scriptPtr = script + tscrofs;
g_scriptPtr = script + oscrofs;
insptr = script + tscrofs;
insptr = script + oscrofs;
Bmemcpy(&vm, &vm_default, sizeof(vmstate_t));
VM_Execute(0);
if (!(vm.flags&VMFLAG_ERROR))
{
if (scripthist[scripthistend])
Bfree((void *)scripthist[scripthistend]);
scripthist[scripthistend] = Bstrdup(parm->raw);
scripthistend++;
scripthistend %= SCRIPTHISTSIZ;
}
// asksave = 1; // handled in Access(Sprite|Sector|Wall)
}
@ -7587,7 +7601,7 @@ static int32_t osdcmd_endisableevent(const osdfuncparm_t *parm)
{
for (i=0; i<MAXEVENTS; i++)
aEventEnabled[i] = enable?1:0;
OSD_Printf("Enabled all events.\n");
OSD_Printf("%sabled all events.\n", enable?"En":"Dis");
return OSDCMD_OK;
}
}
@ -8427,6 +8441,16 @@ void ExtPreLoadMap(void)
/// ^^^
static void m32script_interrupt_handler(int signo)
{
if (signo==SIGINT)
{
vm.flags |= VMFLAG_ERROR;
OSD_Printf("M32 script execution interrupted.\n");
Bmemset(aEventEnabled, 0, sizeof(aEventEnabled));
}
}
int32_t ExtInit(void)
{
int32_t rv = 0;
@ -8635,6 +8659,8 @@ int32_t ExtInit(void)
ReadHelpFile("m32help.hlp");
signal(SIGINT, m32script_interrupt_handler);
return rv;
}

View file

@ -76,6 +76,7 @@ static int32_t label_allocsize = 512;
int32_t g_stateCount = 0;
statesinfo_t *statesinfo = NULL;
static int32_t statesinfo_allocsize = 512;
static int32_t interactive_compilation = 0;
static char tempbuf[2048];
static char tlabel[MAXLABELLEN];
@ -748,9 +749,11 @@ static int32_t C_GetKeyword(void)
return hash_find(&h_keywords, tempbuf);
}
static int32_t C_GetNextKeyword(void) //Returns its code #
//Returns its code # if keyword, -1 on eof or non-keyword
static int32_t C_GetNextKeyword(void)
{
int32_t i, l;
int32_t i, l, olinenum = g_lineNumber, havequickstate=0;
const char *otextptr = textptr;
C_SkipComments();
@ -780,39 +783,58 @@ static int32_t C_GetNextKeyword(void) //Returns its code #
}
tempbuf[l] = 0;
i = hash_find(&h_keywords, tempbuf);
if (i>=0)
{
if (i == CON_LEFTBRACE || i == CON_RIGHTBRACE || i == CON_NULLOP)
*g_scriptPtr = i + (IFELSE_MAGIC<<12);
else
*g_scriptPtr = i + (g_lineNumber<<12);
textptr += l;
g_scriptPtr++;
// if (!(g_numCompilerErrors || g_numCompilerWarnings) && g_scriptDebug)
// initprintf("%s:%d: debug: translating keyword `%s'.\n",g_szScriptFileName,g_lineNumber,keyw[i]);
return i;
}
textptr += l;
if (tempbuf[0] == '{' && tempbuf[1] != 0)
i = hash_find(&h_keywords, tempbuf);
if (i<0)
{
C_CUSTOMERROR("expected whitespace between `{' and `%s'", tempbuf+1);
}
else if (tempbuf[0] == '}' && tempbuf[1] != 0)
{
C_CUSTOMERROR("expected whitespace between `}' and `%s'", tempbuf+1);
}
else
{
C_ReportError(ERROR_EXPECTEDKEYWORD);
g_numCompilerErrors++;
if (tempbuf[0]=='{' && tempbuf[1])
{
C_CUSTOMERROR("expected whitespace between `{' and `%s'", tempbuf+1);
return -1;
}
else if (tempbuf[0]=='}' && tempbuf[1])
{
C_CUSTOMERROR("expected whitespace between `}' and `%s'", tempbuf+1);
return -1;
}
else
{
// if compiling from OSD, try state name
if (interactive_compilation)
i = hash_find(&h_states, tempbuf);
if (i<0)
{
C_ReportError(ERROR_EXPECTEDKEYWORD);
g_numCompilerErrors++;
return -1;
}
else
{
havequickstate = 1;
i = CON_STATE;
}
}
}
return -1;
if (i == CON_LEFTBRACE || i == CON_RIGHTBRACE || i == CON_NULLOP)
*g_scriptPtr = i + (IFELSE_MAGIC<<12);
else
*g_scriptPtr = i + (g_lineNumber<<12);
if (havequickstate)
{
g_lineNumber = olinenum;
// reset textptr so that case CON_STATE in C_ParseCommand() can insert the state number
textptr = otextptr;
}
g_scriptPtr++;
// if (!(g_numCompilerErrors || g_numCompilerWarnings) && g_scriptDebug)
// initprintf("%s:%d: debug: translating keyword `%s'.\n",g_szScriptFileName,g_lineNumber,keyw[i]);
return i;
}
#define GetGamevarID(szGameLabel) hash_find(&h_gamevars, szGameLabel)
@ -3314,6 +3336,8 @@ void C_Compile(const char *filenameortext, int32_t isfilename)
instype* oscriptPtr;
int32_t ostateCount = g_stateCount;
interactive_compilation = !isfilename;
if (firstime)
{
label = Bmalloc(label_allocsize * MAXLABELLEN * sizeof(char));

View file

@ -137,7 +137,7 @@ void VM_OnEvent(register int32_t iEventID, register int32_t iActor)
{
if (iEventID < 0 || iEventID >= MAXEVENTS)
{
M32_PRINTERROR("invalid event ID");
M32_PRINTERROR("Invalid event ID");
return;
}