|
/*ScianScripts.c
Stuff for scripts in scian
Eric Pepke
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianArrays.h"
#include "ScianIDs.h"
#include "ScianEvents.h"
#include "ScianRecorders.h"
#include "ScianColors.h"
#include "ScianWindows.h"
#include "ScianObjWindows.h"
#include "ScianDialogs.h"
#include "ScianVisWindows.h"
#include "ScianScripts.h"
#include "ScianSliders.h"
#include "ScianTimers.h"
#include "ScianMethods.h"
#include "ScianLists.h"
#include "ScianErrors.h"
#include "ScianGarbageMan.h"
#include "ScianSpaces.h"
#include "ScianIcons.h"
#include "ScianSockets.h"
#include "ScianObjFunctions.h"
#include "ScianHelp.h"
#include "ScianStyle.h"
#include "ScianNames.h"
#define SCRIPTALLOCBATCH 200 /*Batch to allocate script*/
Bool runningScript = false; /*True iff running script*/
Bool settingUp = false; /*True iff setting up*/
WinInfoPtr scriptWindow = 0; /*The current window of the script*/
extern ObjPtr perspecControlClass; /*Class of perspecive controls*/
long framesLeft = 0; /*Frames left to record*/
Bool abortScript = false; /*Abort script*/
FILE *curScript = 0; /*Current script being read, if any*/
char *scriptLine = 0; /*Current line of the script*/
int nScriptCharsAllocated = 0; /*Number of script characters allocated*/
Bool lineAccepted = true; /*True iff last script line was accepted*/
/*IDs for running tasks*/
#define RT_NONE 0 /*No running task*/
#define RT_RECORDING 1 /*Recording some time*/
int runningTask = RT_NONE; /*Current running task*/
#define MAXSTACKDEPTH 100 /*Maximum depth of block stack*/
/*Block in a stack*/
typedef struct
{
int command; /*The command*/
ObjPtr object; /*The (optional) object this is about*/
} Block;
Block commandStack[MAXSTACKDEPTH]; /*Stack of commands*/
int nextStackElement = 0; /*Next element on the stack*/
typedef struct /*Element of file logging stack*/
{
FILE *logFile; /*File pointer for logging*/
int logInhibit; /*Counter to inhibit logging*/
WinInfoPtr logWindow; /*Current window set in log*/
} LogElement;
#define MAXLOGFILES 50 /*Maximum number of log files open*/
LogElement logStack[MAXLOGFILES]; /*Stack of log files*/
int nextLogElement = 0; /*Next element on the stack*/
#define KWBEGIN 0 /*Begin a block*/
#define KWEND 1 /*End current modal command*/
#define KWRECORDER 2 /*(set) recorder*/
#define KWDESELECT 3 /*Deselect an icon*/
#define KWSELECT 4 /*Select an icon*/
#define KWSHELL 5 /*Shell escape*/
#define KWALIGNMENT 6 /*(Set) alignment*/
#define KWLOCATION 7 /*(Set) location*/
#define KWVIDEOSCREEN 8 /*Resize current window to video screen*/
#define KWFULLSCREEN 9 /*Resize current window to full screen*/
#define KWROTATE 10 /*Rotate space*/
#define KWSHOW 11 /*Show something*/
#define KWPANEL 12 /*(Show/Hide) the panel of icons*/
#define KWRECORDING 13 /*(Begin/End) recording*/
#define KWSNAP 14 /*Snap a single frame*/
#define KWWINDOW 15 /*Select a new window*/
#define KWSET 16 /*Set something*/
#define KWCONTROLS 17 /*(Show) controls for a vis object*/
#define KWPUSHWINDOW 18 /*Push a window behind all others*/
#define KWQUIT 19 /*Quit*/
#define KWSHEAR 20 /*Shear the matrix*/
#define KWFPS 21 /*(Set) fps*/
#define KWEYEPOSN 22 /*Eye position*/
#define KWROLL 23 /*Roll of eyeball*/
#define KWPITCH 24 /*Pitch of eyeball*/
#define KWYAW 25 /*Yaw of eyeball*/
#define KWRECTANGLE 26 /*Rectangle*/
#define KWHIDE 27 /*Hide the frame of a window*/
#define KWEXIT 28 /*Exit on next loop*/
#define KWVALUE 29 /*(Set) value of a something*/
#define KWFONT 30 /*(Set) the font of something*/
#define KWSIZE 31 /*(Set) the size of something's font*/
#define KWCLOSE 32 /*Closes a window*/
#define KWENDPOINTS 33 /*(Set) endpoints*/
#define KWDROP 34 /*Drops whatever is in the drag buffer*/
#define KWBOUNDS 35 /*(Set) the bounds of an object*/
#define KWTILE 36 /*Tile to a certain width and height*/
#define KWANNOTATION 37 /*Add annotation*/
#define KWFRAME 38 /*(Show/Hide) the frame of a window*/
#define KWLOCATE 39 /*Locate a window*/
#define KWDELETE 40 /*Delete stuff*/
#define KWSCRSAVE 41 /*Save the screen*/
#define KWRECORD 42 /*Record some number of seconds*/
#define KWSCREEN 43 /*(Set) screen*/
#define KWCOLOR 44 /*(Set) color*/
#define KWPREFERENCES 45 /*(Show) preferences*/
#define KWTIME 46 /*Time*/
#define KWOFF 47 /*(Turn) off*/
#define KWTURN 48 /*Turn (on/off)*/
#define KWON 49 /*(Turn) on*/
#define KWLINE 50 /*Make a new line*/
#define KWFUNCTIONBOX 51 /*(Set) Function box*/
#define KWFILESWINDOW 52 /*(Show) FilesWindow*/
#define KWSELECTALL 53 /*Selectall*/
#define KWDESELECTALL 54 /*Deselectall*/
#define KWHELP 55 /*(Show) help*/
#define KWFILEREADERS 56 /*(Show) fileReaders*/
#define KWDATASETS 57 /*(Show) datasets*/
#define KWROTATION 58 /*(Set) rotation*/
#define KWVERSION 59 /*Version*/
#define KWFRONT 60 /*(Show) front (panel controls)*/
#define KWBACK 61 /*(Show) back (panel controls)*/
#define KWSETUP 62 /*(Begin/End) setup*/
#define KWSAVE 63 /*Save something*/
#define KWTIMEREADOUT 64 /*Make a time readout*/
#define KWSPACE 65 /*(Show) space (controls)*/
#define KWEFFECT 66 /*Color special effect*/
#define KWKEEP 67 /*Keep changes to palette*/
#define KWREVERT 68 /*Revert to last saved palette*/
#define KWMODEL 69 /*Color model*/
#define KWSNAPSHOT 70 /*(Begin) Snapshot*/
#define KWOBSERVER 71 /*(Begin Snapshot) Observer*/
#define KWVARIABLE 72 /*(set) Variable */
#define KWOBJECT 73 /*(Begin Snapshot) */Object
#define NKEYWORDS 74 /*Number of keywords*/
char *keywords[NKEYWORDS] =
{
"begin",
"end",
"recorder",
"deselect",
"select",
"shell",
"alignment",
"location",
"videoscreen",
"fullscreen",
"rotate",
"show",
"panel",
"recording",
"snap",
"window",
"set",
"controls",
"pushwindow",
"quit",
"shear",
"fps",
"eyeposn",
"roll",
"pitch",
"yaw",
"rectangle",
"hide",
"exit",
"value",
"font",
"size",
"close",
"endpoints",
"drop",
"bounds",
"tile",
"annotation",
"frame",
"locate",
"delete",
"scrsave",
"record",
"screen",
"color",
"preferences",
"time",
"off",
"turn",
"on",
"line",
"functionbox",
"fileswindow",
"selectall",
"deselectall",
"help",
"filereaders",
"datasets",
"rotation",
"version",
"front",
"back",
"setup",
"save",
"timereadout",
"space",
"effect",
"keep",
"revert",
"model",
"snapshot",
"observer",
"variable",
"object"
};
char *wholeLine; /*Pointer to the whole line for error*/
char *begToken, *endToken; /*Beginning and ending of current token*/
#ifdef PROTO
Bool BeginCommand(char *);
Bool EndCommand(char *);
#else
Bool BeginCommand();
Bool EndCommand();
#endif
FILE *OpenLogFile(name)
char *name;
/*Opens a log file named name in the current directory. OpenLogFile and
CloseLogFile may be nested. If !name, it's stdout*/
{
struct timeval date;
if (name)
{
logStack[nextLogElement] . logFile = fopen(name, "w");
}
else
{
logStack[nextLogElement] . logFile = stdout;
}
if (logStack[nextLogElement] . logFile)
{
logStack[nextLogElement] . logInhibit = 0;
logStack[nextLogElement] . logWindow = 0;
}
else
{
WinInfoPtr alertWindow;
char msg[300];
getcwd(tempStr, TEMPSTRSIZE);
sprintf(msg, "File %s cannot be saved in directory %s.",
name, tempStr);
alertWindow = AlertUser(UIERRORALERT, (WinInfoPtr) NULLOBJ,
msg, (FuncTyp) 0, 1, "Oh Well");
SetVar((ObjPtr) alertWindow, HELPSTRING,
NewString("A file cannot be saved in the specified directory. \
This is probably because the permissions on the directory are not set up to allow \
you to write to it. Check the permissions on the directory and try again."));
return 0;
}
/*Write out a version number as first line in file*/
fprintf(logStack[nextLogElement] . logFile, "%s\n", SCIANVERSION);
/*And a time stamp*/
gettimeofday(&date, (struct timezone *)0);
fprintf(logStack[nextLogElement] . logFile, "time %s\n", ctime(&date.tv_sec));
++nextLogElement;
}
void CloseLogFile()
/*Closes a log file opened by OpenLogFile.*/
{
if (!nextLogElement) return;
--nextLogElement;
if (logStack[nextLogElement] . logFile != stdout)
{
fclose(logStack[nextLogElement] . logFile);
}
}
Bool logBeginning = true; /*True iff it's at the beginning of a log line*/
Bool AnyLogging()
/*Returns true iff any logging is to be done*/
{
if (!logging)
{
return false;
}
if (logStack[nextLogElement - 1] . logInhibit)
{
return false;
}
return true;
}
void Log(s)
char *s;
/*Logs command s to all the open log files*/
{
int whichLog;
char *t;
if (selWinInfo && GetPredicate((ObjPtr) selWinInfo, INHIBITLOGGING))
{
return;
}
for (whichLog = nextLogElement - 1; whichLog >= 0; --whichLog)
{
if (logStack[whichLog] . logInhibit)
{
/*Done; don't do no more.*/
break;
}
if (logBeginning && selWinInfo && logStack[whichLog] . logWindow != selWinInfo)
{
/*Make a window command*/
char windowName[256];
int k;
/*Copy window title*/
t = selWinInfo -> winTitle;
k = 0;
while (*t)
{
if (*t == ' ')
{
windowName[k++] = '_';
++t;
}
else
{
if (!isalpha(*t) && ((k == 0) || !isdigit(*t)))
{
windowName[k++] = '\\';
}
windowName[k++] = *t++;
}
}
windowName[k] = 0;
fprintf(logStack[whichLog] . logFile, "window %s\n", windowName);
logStack[whichLog] . logWindow = selWinInfo;
}
fputs(s, logStack[whichLog] . logFile);
}
/*Determine if it's in a line*/
t = s;
if (*t)
{
while (*t) ++t;
--t;
if (*t == '\n')
{
logBeginning = true;
}
else
{
logBeginning = false;
}
}
}
#ifdef PROTO
void InhibitLogging(Bool whether)
#else
void InhibitLogging(whether)
Bool whether;
#endif
/*Inhibits or disinhibits logging based on whether*/
{
if (nextLogElement)
{
if (whether)
{
++logStack[nextLogElement - 1] . logInhibit;
}
else
{
--logStack[nextLogElement - 1] . logInhibit;
}
}
}
#ifdef PROTO
void LogVariable(ObjPtr object, NameTyp variable)
#else
void LogVariable(object, variable)
ObjPtr object; NameTyp variable;
#endif
/*Logs a variable*/
{
if (AnyLogging() && !GetPredicate(object, INHIBITLOGGING))
{
char cmd[256];
char *s;
sprintf(cmd, " set variable %s ", GetInternalString(variable));
s = &(cmd[0]);
while (*s) ++s;
PrintScriptObject(s, GetVar(object, variable));
while (*s) ++s;
*s++ = '\n';
*s = 0;
Log(cmd);
}
}
void LogControl(object)
ObjPtr object;
{
if (AnyLogging() && !GetPredicate(object, INHIBITLOGGING))
{
char cmd[256];
char *s;
sprintf(cmd, "set value ");
s = &(cmd[0]);
while (*s) ++s;
MakeObjectName(s, object);
while (*s) ++s;
*s++ = ' ';
PrintScriptObject(s, GetVar(object, VALUE));
while (*s) ++s;
*s++ = '\n';
*s = 0;
Log(cmd);
}
}
void LogObjectName(object)
ObjPtr object;
/*Logs the name of an object*/
{
char objName[400];
MakeObjectName(objName, object);
Log(objName);
}
void ScriptError(e)
char *e;
/*Prints out an error e*/
{
char *runner;
fprintf(stderr, "%s\n", wholeLine);
runner = wholeLine;
while (runner < begToken)
{
fprintf(stderr, *runner == '\t' ? "\t" : " ");
++runner;
}
if (runner < endToken)
{
while (runner < endToken)
{
fprintf(stderr, "-");
++runner;
}
}
else
{
fprintf(stderr, "^");
}
fprintf(stderr, "\n");
fprintf(stderr, "%s\n", e);
if (abortScriptP)
{
abortScript = true;
}
}
void SelectNamedWindow(name)
char *name;
/*Selects a window by name name*/
{
WinInfoPtr namedWindow;
namedWindow = GetWinFromTitle(name);
if (!namedWindow)
{
ScriptError("Cannot find a unique window by that name.");
return;
}
SelWindow(namedWindow);
scriptWindow = namedWindow;
}
static ObjPtr testObj;
static WinInfoPtr repWindow;
static ObjPtr globalRep;
void TestWindowOnObject(window)
WinInfoPtr window;
/*Tests to see if window has an object which represents testObj*/
{
ObjPtr rep;
if (rep = ObjectWhichRepresents(window, testObj))
{
repWindow = window;
globalRep = rep;
}
}
void MakeObjectName(dest, object)
char *dest;
ObjPtr object;
/*Makes a long object name from object and puts it into dest*/
{
register char *s;
ObjPtr name;
ObjPtr representative = NULLOBJ;
if (!IsWindow(object) &&
((!IsValidWindow(selWinInfo)) ||
(!(representative = ObjectWhichRepresents(selWinInfo, object)))))
{
/*Must find a window that knows about the object*/
testObj = object;
repWindow = (WinInfoPtr) 0;
ForAllWindows(TestWindowOnObject);
if (repWindow)
{
representative = globalRep;
MakeObjectName(dest, (ObjPtr) repWindow);
while (*dest) ++dest;
}
else
{
*dest++ = '?';
}
*dest++ = ':';
}
if (representative)
{
object = representative;
}
name = GetStringVar("MakeObjectName", object, NAME);
if (!name)
{
*dest = 0;
return;
}
/*Copy name*/
s = GetString(name);
if (isdigit(*s))
{
*dest++ = '\\';
}
while (*s)
{
if (*s == ' ')
{
*dest++ = '_';
++s;
}
else
{
if (!isalpha(*s) && !isdigit(*s))
{
*dest++ = '\\';
}
*dest++ = *s++;
}
}
*dest = 0;
}
int ParseKeyword(s, l, n)
char *s;
char *l[];
int n;
/*Parses keyword s in list l with number of elements n.Returns its number or -1 == not found, -2 ==
ambiguious.*/
{
int match = -1; /*Last found match*/
int i, k; /*Counters*/
/*Seek an exact match*/
for (k = 0; k < n; ++k)
{
for (i = 0; s[i]; ++i)
{
if (tolower(s[i]) != tolower(l[k][i]))
{
break;
}
}
if (!s[i] && !keywords[k][i])
{
/*It's a match!*/
return k;
}
}
/*Seek a partial match*/
for (k = 0; k < n; ++k)
{
for (i = 0; s[i]; ++i)
{
if (tolower(s[i]) != tolower(l[k][i]))
{
break;
}
}
if (!s[i])
{
/*It's a match!*/
if (match >= 0)
{
/*Double match*/
return -2;
}
match = k;
}
}
return match;
}
#ifdef PROTO
char *ParseArray(char *s, ObjPtr *o)
#else
char *ParseArray(s, o)
char *s;
ObjPtr *o;
#endif
/*
Parses an array at s
Returns
s if the object was syntactically bad or null
the first character after the object if it was OK.
Puts in o the object if it was semantically valid
Leavs o alone if it was not
Generates a script error if syntactically or semantically invalid.
Doesn't yet do arrays of higher order than vectors by recursion
*/
{
char *r;
r = s;
SKIPBLANKS(r);
if (*r != '[')
{
ScriptError("This is not a valid array");
return s;
}
++r;
SKIPBLANKS(r);
/*Now, it's either some subvectors or a number*/
if (*r == '[')
{
/*Subvector*/
ScriptError("Arrays of higher order than vectors are not supported yet");
return s;
}
else
{
/*Simple numerical vector.*/
real *numBuf; /*Temporary buffer for holding real numbers*/
long bufSize; /*Size of temporary buffer*/
long vecSize; /*Size of the vector so far*/
char num[256]; /*Temporary number space*/
/*Allocate some storage*/
bufSize = 1000;
vecSize = 0;
numBuf = malloc(sizeof(real) * bufSize);
if (!numBuf)
{
OMErr();
return s;
}
while (*r != ']')
{
SHIFTNUM(num, r);
if (1 != sscanf(num, "%g", numBuf + vecSize))
{
ScriptError("This cannot be read as a number");
free(numBuf);
return s;
}
++vecSize;
if (vecSize > bufSize)
{
bufSize += 1000;
numBuf = realloc(numBuf, bufSize);
if (!numBuf)
{
OMErr();
return s;
}
}
SKIPBLANKS(r);
}
++r;
/*Now make it into a vector*/
*o = NewRealArray(1, vecSize);
if (!o)
{
free(numBuf);
return s;
}
CArray2Array(*o, numBuf);
free(numBuf);
return r;
}
}
#ifdef PROTO
char *ParseObjectArg(char *s, ObjPtr *o)
#else
char *ParseObjectArg(s, o)
char *s;
ObjPtr *o;
#endif
/*
Parses an object at s
Returns
s if the object was syntactically bad or null
the first character after the object if it was OK.
Puts in o the object if it was semantically valid
Leavs o alone if it was not
Generates a script error if syntactically or semantically invalid.
*/
{
char arg[256];
char *r;
r = s;
/*Get to the first character*/
SKIPBLANKS(r);
/*Based on one-char lookahead, parse the argument*/
if (*r == '-' || *r == '+' || *r == '.' || isdigit(*r))
{
double val;
/*It's a number*/
SHIFTNUM(arg, r);
if (1 == sscanf(arg, "%lg", &val))
{
*o = NewReal((real) val);
}
else
{
ScriptError("This number has bad syntax");
return s;
}
}
else if (isalpha(*r) || (*r == '\\'))
{
/*It's an object name or NULLOBJ*/
SHIFTKW(arg, r);
if (0 == strcmp2(arg, "NULLOBJ"))
{
*o = NULLOBJ;
}
else
{
ObjPtr list = NULLOBJ;
if (*r == ':')
{
char arg2[256];
WinInfoPtr window;
/*Compound name*/
++r;
SHIFTKW(arg2, r);
if (strlen(arg2))
{
window = GetWinFromTitle(arg);
if (window)
{
list = FindNamedObject((ObjPtr) window, arg2);
}
else
{
ScriptError("Cannot find a unique window by that name.");
return s;
}
}
else
{
ScriptError("An object name is expected after the window name.");
return s;
}
}
else
{
if (scriptWindow && IsValidWindow(scriptWindow))
{
list = FindNamedObject((ObjPtr) scriptWindow, arg);
}
else
{
ScriptError("There is no currently selected window.");
}
}
if (!list || !LISTOF(list))
{
ScriptError("There is no object by that name.");
}
else if (LISTOF(list) -> next)
{
ScriptError("That name is not unique.");
}
else
{
*o = LISTOF(list) -> thing;
}
}
}
else if (*r == '[')
{
return ParseArray(r, o);
}
else if (*r == '"')
{
int k;
/*It's a string*/
begToken = r;
++r;
k = 0;
while (*r && *r != '"')
{
if (*r == '\\')
{
++r;
if (isdigit(*r))
{
int nDigits, value;
value = 0;
nDigits = 0;
do
{
value *= 8;
value += *r - '0';
++nDigits;
++r;
} while (isdigit(*r) && nDigits < 3);
tempStr[k++] = value;
}
else
switch (*r)
{
case 'n':
case 'N':
tempStr[k++] = '\n';
++r;
break;
case 't':
case 'T':
tempStr[k++] = '\t';
++r;
break;
case 'r':
case 'R':
tempStr[k++] = '\r';
++r;
break;
default: tempStr[k++] = *r++;
}
}
else
{
tempStr[k++] = *r++;
}
}
if (*r == '"') ++r;
endToken = r;
tempStr[k] = 0;
*o = NewString(tempStr);
}
else switch(*r)
{
case 0: /*End of string, null object*/
*o = NULLOBJ;
break;
default: /*Who knows? Error*/
ScriptError("This is an unrecognized object");
return s;
}
return r;
}
char *PrintScriptString(dest, s)
char *dest, *s;
/*Prints a script string from s into dest*/
{
*dest++ = '"';
while (*s)
{
if (*s == '"')
{
*dest++ = '\\';
}
if (*s == '\n')
{
*dest++ = '\\';
*dest++ = 'n';
}
else if (*s == '\t')
{
*dest++ = '\\';
*dest++ = 't';
}
else if (*s == '\r')
{
*dest++ = '\\';
*dest++ = 'r';
}
else if (*s < ' ')
{
*dest++ = '\\';
sprintf(tempStr, "%3o", *s);
*dest++ = tempStr[0];
*dest++ = tempStr[1];
*dest++ = tempStr[2];
}
else
{
*dest++ = *s;
}
++s;
}
*dest++ = '"';
*dest = 0;
return dest;
}
char *PrintScriptObject(s, object)
char *s;
ObjPtr object;
/*Prints object into s as for inclusion into a script. Returns a pointer
to the null afterward*/
{
char *retVal;
retVal = s;
if (object == 0)
{
sprintf(retVal, "NULLOBJ");
while (*retVal) ++retVal;
}
else if (IsReal(object))
{
/*Real number*/
sprintf(retVal, "%g", (float) GetReal(object));
while (*retVal) ++retVal;
}
else if (IsInt(object))
{
sprintf(retVal, "%ld", (long) GetInt(object));
while (*retVal) ++retVal;
}
else if (IsRealArray(object) && RANK(object) == 1)
{
/*Vector*/
int k;
real *meat;
*retVal++ = '[';
meat = ArrayMeat(object);
for (k = 0; k < DIMS(object)[0]; ++k)
{
sprintf(retVal, "%g", *meat++);
while (*retVal) ++retVal;
if (k < DIMS(object)[0] - 1) *retVal++ = ' ';
}
*retVal++ = ']';
}
else if (IsString(object))
{
/*String*/
retVal = PrintScriptString(retVal, GetString(object));
}
*retVal = 0;
return retVal;
}
int FindCommandInStack(command)
int command;
/*Finds the topmost command command in the stack. Returns it's index or -1
if not found.*/
{
int k;
for (k = nextStackElement - 1; k >= 0; --k)
{
if (commandStack[k] . command == command)
{
break;
}
}
return k;
}
Bool BeginCommand(args)
char *args;
/*Begins a begin-end block with command in args.*/
{
char cmdNum;
char arg[256];
if (nextStackElement >= MAXSTACKDEPTH)
{
ScriptError("There are too many nested begin-end blocks.");
return true;
}
SHIFTKW(arg, args);
if (strlen(arg))
{
cmdNum = ParseKeyword(arg, keywords, NKEYWORDS);
if (cmdNum == -1)
{
ScriptError("This command is unknown.");
return true;
}
else if (cmdNum == -2)
{
ScriptError("This command is ambiguous.");
return true;
}
}
else
{
/*It's an anonymous block*/
cmdNum = KWBEGIN;
}
commandStack[nextStackElement] . command = cmdNum;
commandStack[nextStackElement] . object = NULLOBJ;
switch (cmdNum)
{
case KWBEGIN:
Log("begin\n");
break;
case KWRECORDING:
Log("begin recording\n");
if (FindCommandInStack(KWRECORDING) >= 0)
{
ScriptError("The begin recording command cannot be nested.");
return true;
}
else
{
real nSeconds;
SHIFTNUM(arg, args);
if (1 != sscanf(arg, "%g", &nSeconds))
{
ScriptError("A maximum time in seconds is expected here.");
return true;
}
if (nSeconds < 0.0) nSeconds = -nSeconds;
if (ConnectRecorder())
{
int nFrames;
nFrames = (int) (nSeconds * 30.0);
if (!PrepareToRecord(nFrames))
{
ScriptError("There is a problem recording that many frames.");
return true;
}
}
else
{
ScriptError("Could not connect to the recorder.");
return true;
}
}
break;
case KWSETUP:
Log("begin setup\n");
settingUp = true;
break;
case KWSNAPSHOT:
/*Beginning of an object snapshot*/
{
ObjPtr value;
value = ERROBJ;
SKIPBLANKS(args);
Log("begin snapshot ");
Log(args);
Log("\n");
args = ParseObjectArg(args, &value);
if (value != ERROBJ)
{
commandStack[nextStackElement] . object = value;
}
else
{
ScriptError("An object for the snapshot is expected here");
commandStack[nextStackElement] . object = NULLOBJ;
}
}
break;
default:
ScriptError("This command may not start a begin-end block");
return true;
}
++nextStackElement;
return true;
}
Bool EndCommand(args)
char *args;
/*Ends the top command on the stack, or up to command in args*/
{
char arg[256];
if (!nextStackElement)
{
ScriptError("There are too many ends and not enough begins.");
return true;
}
SHIFTKW(arg, args);
if (strlen(arg))
{
int cmdNum, cmdWhere;
cmdNum = ParseKeyword(arg, keywords, NKEYWORDS);
cmdWhere = FindCommandInStack(cmdNum);
if (cmdWhere < 0)
{
ScriptError("There is no such block in force.");
return true;
}
else
{
do
{
EndCommand("");
} while (commandStack[nextStackElement] . command != cmdNum);
}
}
else
{
/*End the top command*/
--nextStackElement;
switch(commandStack[nextStackElement] . command)
{
case KWBEGIN:
Log("end\n");
break;
case KWRECORDING:
Log("end recording\n");
StopRecording();
DisconnectRecorder();
break;
case KWSNAPSHOT:
Log("end snapshot\n");
if (commandStack[nextStackElement] . object)
{
ImInvalid(commandStack[nextStackElement] . object);
}
break;
case KWSETUP:
Log("end setup\n");
settingUp = false;
break;
}
}
return true;
}
Bool DoSetCommand(kwn, args)
int kwn;
char *args;
/*Does a set command*/
{
char arg[256];
switch(kwn)
{
case KWVARIABLE:
/*Set a variable within a snapshot*/
{
int element;
/*DIKEO put in type checking*/
element = FindCommandInStack(KWSNAPSHOT);
if (element >= 0)
{
/*Do a setvar, just like it says*/
NameTyp internalID;
ObjPtr value;
SHIFTKW(arg, args);
internalID = GetInternalID(arg);
value = ERROBJ;
args = ParseObjectArg(args, &value);
if (value != ERROBJ)
{
if (commandStack[element] . object)
{
SetVar(commandStack[element] . object, internalID, value);
LogVariable(commandStack[element] . object, internalID);
}
}
else
{
ScriptError("A valid value is expected here");
}
}
else
{
ScriptError("A set variable command can only occur within a snapshot");
}
}
break;
case KWRECORDER:
{
ObjPtr object;
if (FindCommandInStack(KWRECORDING) >= 0)
{
ScriptError("You can't set the recorder while recording");
break;
}
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsString(object))
{
if (!SetRecorder(GetString(object)))
{
ScriptError("This recorder does not exist");
}
}
else
{
ScriptError("A quoted name of a recorder is expected here");
}
}
}
break;
case KWVALUE:
/*Set the value of a control*/
{
ObjPtr object, value;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (object && IsObject(object))
{
value = ERROBJ;
args = ParseObjectArg(args, &value);
if (value != ERROBJ)
{
SetValue(object, value);
}
else
{
ScriptError("A valid value is expected here");
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWROTATION:
{
ObjPtr rotation, axis;
rotation = ERROBJ;
args = ParseObjectArg(args, &rotation);
if (rotation != ERROBJ)
{
if (rotation && IsReal(rotation))
{
axis = ERROBJ;
args = ParseObjectArg(args, &axis);
if (axis != ERROBJ && axis &&
IsRealArray(axis) && RANK(axis) == 1 && DIMS(axis)[0] == 3)
{
real *elements;
real degrees;
elements = ELEMENTS(axis);
degrees = GetReal(rotation);
SetRotationMotor(degrees * M_PI / 180.0, elements[0], elements[1], elements[2]);
}
else
{
ScriptError("A rotation axis is expected here");
}
}
else
{
ScriptError("A rotation speed is expected here");
}
}
}
break;
case KWFUNCTIONBOX:
{
ObjPtr object, functionBox;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
functionBox = ERROBJ;
args = ParseObjectArg(args, &functionBox);
if (functionBox != ERROBJ)
{
SetFunctionBox(object, functionBox);
InhibitLogging(true);
ImposeColorFunction(object);
ForAllVisWindows(ImInvalid);
InhibitLogging(false);
}
else
{
ScriptError("A valid function box is expected here");
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWCOLOR:
{
ObjPtr object;
int which, r, g, b;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
if (4 == sscanf(args, " %d %d %d %d \n", &which, &r, &g, &b))
{
SetColorBarColor(object, which, r, g, b);
}
else
{
ScriptError("A color number and components are expected here");
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWFONT:
{
ObjPtr object, value;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
SHIFTKW(arg, args);
SetFont(object, arg);
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWSIZE:
{
ObjPtr object, value;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
int size;
SHIFTNUM(arg, args);
if (1 == sscanf(arg, "%d", &size))
{
SetSize(object, size);
}
else
{
ScriptError("A font size is expected here");
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWALIGNMENT:
{
ObjPtr object, value;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
int alignment;
SHIFTNUM(arg, args);
if (1 == sscanf(arg, "%d", &alignment))
{
SetAlignment(object, alignment);
}
else
{
ScriptError("An integer text alignment is expected here");
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWLOCATION:
{
ObjPtr object, value;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
real location[3];
if (3 == sscanf(args, " [%g %g %g]",
&(location[0]),
&(location[1]),
&(location[2])))
{
ObjPtr var;
var = NewRealArray(1, 3L);
CArray2Array(var, location);
SetVar(object, LOCATION, var);
ImInvalid(object);
if (logging)
{
char cmd[300];
char *s;
sprintf(cmd, "set location ");
s = &(cmd[0]);
while (*s) ++s;
MakeObjectName(s, object);
while (*s) ++s;
sprintf(s, " [%g %g %g]\n",
location[0],
location[1],
location[2]);
Log(cmd);
}
}
else
{
ScriptError("A vector location is expected here");
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWBOUNDS:
{
ObjPtr object;
ObjPtr bounds;
char *oldArgs;
object = ERROBJ;
oldArgs = args;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
bounds = ERROBJ;
args = ParseObjectArg(args, &bounds);
if (bounds != ERROBJ)
{
if (IsRealArray(bounds) && RANK(bounds) == 1)
{
ObjPtr testBounds;
testBounds = GetVar(object, BOUNDS);
if (!testBounds ||
(IsRealArray(testBounds) &&
RANK(testBounds) == 1 &&
DIMS(testBounds)[0] == DIMS(bounds)[0]))
{
if (logging)
{
char cmd[256];
sprintf(cmd, "set bounds %s\n", oldArgs);
Log(cmd);
}
SetVar(object, BOUNDS, bounds);
ImInvalid(object);
}
else
{
ScriptError("These bounds are of wrong size for the object");
}
}
else
{
ScriptError("A vector is expected here");
}
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWENDPOINTS:
{
ObjPtr object;
int x1, y1, x2, y2;
char *oldArgs;
object = ERROBJ;
oldArgs = args;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
if (4 == sscanf(args, " %d %d %d %d", &x1, &y1, &x2, &y2))
{
SetEndpoints(object, x1, y1, x2, y2);
ImInvalid(object);
}
else
{
ScriptError("Four endpoint coordinates are expected here");
}
}
else
{
ScriptError("An object name is expected here");
}
}
}
break;
case KWSCREEN:
{
/*Set the size of the recording screen*/
int x, y;
if (2 != sscanf(args, " %d %d", &x, &y))
{
ScriptError("A width and height of the recording screen is expected here");
break;
}
recScrWidth = x;
recScrHeight = y;
}
break;
case KWFPS:
{
/*Set the frames per second*/
real fps;
if (1 != sscanf(args, " %g", &fps))
{
ScriptError("A number of frames per second is expected here");
break;
}
SetFPS(fps);
}
break;
default:
ScriptError("This is not a paramater that can be set");
break;
}
return true;
}
Bool DoSaveCommand(kwn, args)
int kwn;
char *args;
/*Does a save command*/
{
char arg[256];
switch(kwn)
{
case KWCONTROLS:
DoSaveObject();
break;
default:
ScriptError("This is not something that can be saved");
return;
break;
}
return true;
}
Bool DoShowHideCommand(showp, kwn, args)
Bool showp;
int kwn;
char *args;
/*Does a show or hide command, showp is true iff it's show*/
{
char arg[256];
switch(kwn)
{
case KWPANEL:
if (showp)
{
DoShowPanel();
}
else
{
DoHidePanel();
}
break;
case KWPREFERENCES:
if (showp)
{
DoShowPreferences();
}
else
{
ScriptError("You can't hide preferences this way. Close the window instead");
}
break;
case KWHELP:
if (showp)
{
DoShowHelp();
}
else
{
ScriptError("You can't hide help this way. Close the window instead");
}
break;
case KWDATASETS:
if (showp)
{
PopDatasetsWindow();
}
else
{
ScriptError("You can't hide the datasets window this way. Close the window instead");
}
break;
case KWFILEREADERS:
if (showp)
{
PopFileReadersWindow();
}
else
{
ScriptError("You can't hide the file readers window this way. Close the window instead");
}
break;
case KWFILESWINDOW:
if (showp)
{
DoNewFileWindow();
}
else
{
ScriptError("You can't hide the file window this way. Close the window instead");
}
break;
case KWFRAME:
if (showp)
{
DoShowFrame();
}
else
{
DoHideFrame();
}
break;
case KWFRONT:
if (showp)
{
DoShowFrontPanelControls();
}
else
{
ScriptError("You can't hide the front panel controls this way. Close the window instead");
}
break;
case KWBACK:
if (showp)
{
DoShowBackPanelControls();
}
else
{
ScriptError("You can't hide the back panel controls this way. Close the window instead");
}
break;
case KWSPACE:
if (showp)
{
DoShowSpaceControls();
}
else
{
ScriptError("You can't hide the space controls this way. Close the window instead");
}
break;
default:
ScriptError("This keyword is not a settable parameter");
break;
}
return true;
}
#ifdef PROTO
void ShowScriptControlPanels(Bool whether)
#else
void ShowScriptControlPanels(whether)
Bool whether;
#endif
/*Turns subsequent showing of control panels within a script on or off*/
{
showControlPanels = whether;
Log(whether ? "turn show controls on\n" : "turn show controls off");
}
void VersionCommand(args)
char *args;
/*Does a version command*/
{
char arg[256];
float scianVersion, scriptVersion;
SHIFTNUM(arg, args);
if (1 != sscanf(arg, "%g", &scriptVersion))
{
ScriptError("A number is expected here");
return;
}
if (1 != sscanf(SCIANVERSION, "Version %g", &scianVersion))
{
ReportError("VersionCommand", "Internal error: cannot parse SciAn version");
return;
}
if (scianVersion < scriptVersion)
{
ScriptError("The script is newer than this version of SciAn");
if (abortScriptP)
{
abortScript = true;
}
}
if (scianVersion > scriptVersion)
{
#if 0
ScriptError("The script is older than this version of SciAn");
if (abortScriptP)
{
abortScript = true;
}
#endif
}
}
#ifdef PROTO
void SelectCommand(char *args, Bool selectP)
#else
void SelectCommand(args, selectP)
char *args;
Bool selectP;
#endif
/*Does select or deselect depending on selectP*/
{
ObjPtr object;
object = ERROBJ;
args = ParseObjectArg(args, &object);
if (object != ERROBJ)
{
if (IsObject(object))
{
Select(object, selectP);
}
else
{
ScriptError("An object name is expected here");
}
}
}
#ifdef PROTO
void TurnCommand(char *args)
#else
void TurnCommand(args)
char *args;
#endif
/*Does turn show controls on/off. Normal turn on/off done by obj
functions.*/
{
char arg[256];
int kwn;
SHIFTKW(arg, args);
kwn = ParseKeyword(arg, keywords, NKEYWORDS);
if (kwn == KWSHOW)
{
SHIFTKW(arg, args);
kwn = ParseKeyword(arg, keywords, NKEYWORDS);
if (kwn == KWCONTROLS)
{
SHIFTKW(arg, args);
kwn = ParseKeyword(arg, keywords, NKEYWORDS);
if (kwn == KWON)
{
ShowScriptControlPanels(true);
}
else if (kwn == KWOFF)
{
ShowScriptControlPanels(false);
}
}
else
{
ScriptError("'Controls' is expected here");
}
}
else
{
ScriptError("Either 'on' or 'off' is expected here");
}
}
Bool DoScriptCommand(kwn, args)
int kwn;
char *args;
/*Does command kwn with args*/
{
char arg[256];
switch(kwn)
{
case KWVERSION:
VersionCommand(args);
break;
case KWTIME:
break;
case KWDELETE:
DoDelete();
break;
case KWTURN:
/*Turn show controls on/off. Turn on/off handled by objfunctions*/
TurnCommand(args);
break;
case KWSELECT:
SelectCommand(args, true);
break;
case KWDESELECT:
SelectCommand(args, false);
break;
case KWSELECTALL:
DoSelectAllIcons();
break;
case KWDESELECTALL:
DeselectAll();
break;
case KWANNOTATION:
case KWTIMEREADOUT:
case KWRECTANGLE:
{
char name[256];
ObjPtr bounds;
SHIFTKW(name, args);
if (strlen(name))
{
bounds = ERROBJ;
args = ParseObjectArg(args, &bounds);
if (bounds != ERROBJ)
{
if (IsRealArray(bounds) && RANK(bounds) == 1 &&
DIMS(bounds)[0] == 4)
{
switch(kwn)
{
case KWANNOTATION:
AddAnnotation(name, ArrayMeat(bounds));
break;
case KWTIMEREADOUT:
AddTimeReadout(name, ArrayMeat(bounds));
break;
case KWRECTANGLE:
AddRectangle(name, ArrayMeat(bounds));
break;
}
}
else
{
ScriptError("A 4-vector is expected here");
}
}
}
else
{
ScriptError("A name is expected here");
}
}
break;
case KWLINE:
{
char name[256];
int x1, y1, x2, y2;
SHIFTKW(name, args);
if (strlen(name))
{
if (4 == sscanf(args, " %d %d %d %d", &x1, &y1, &x2, &y2))
{
AddLine(name, x1, y1, x2, y2);
}
else
{
ScriptError("Four endpoint coordinates are expected here");
}
}
else
{
ScriptError("A name is expected here");
}
}
break;
case KWSET: /*Set something or other*/
{
int k;
SHIFTKW(arg, args);
/*Find out what to set*/
kwn = ParseKeyword(arg, keywords, NKEYWORDS);
if (kwn == -1)
{
ScriptError("This parameter is unknown.");
break;
}
else if (kwn == -2)
{
ScriptError("This parameter is ambiguous.");
break;
}
else
{
return DoSetCommand(kwn, args);
}
}
break;
case KWSAVE: /*Save something or other*/
{
int k;
SHIFTKW(arg, args);
/*Find out what to set*/
kwn = ParseKeyword(arg, keywords, NKEYWORDS);
if (kwn == -1)
{
ScriptError("This parameter is unknown.");
break;
}
else if (kwn == -2)
{
ScriptError("This parameter is ambiguous.");
break;
}
else
{
return DoSaveCommand(kwn, args);
}
}
break;
case KWSHOW: /*Show something or other*/
{
int k;
SHIFTKW(arg, args);
/*Find out what to set*/
kwn = ParseKeyword(arg, keywords, NKEYWORDS);
if (kwn == -1)
{
ScriptError("This parameter is unknown.");
break;
}
else if (kwn == -2)
{
ScriptError("This parameter is ambiguous.");
break;
}
else
{
return DoShowHideCommand(true, kwn, args);
}
}
break;
case KWHIDE: /*Hide something or other*/
{
int k;
SHIFTKW(arg, args);
/*Find out what to set*/
kwn = ParseKeyword(arg, keywords, NKEYWORDS);
if (kwn == -1)
{
ScriptError("This parameter is unknown.");
break;
}
else if (kwn == -2)
{
ScriptError("This parameter is ambiguous.");
break;
}
else
{
return DoShowHideCommand(false, kwn, args);
}
}
break;
case KWDROP:
{
int dropX, dropY;
SHIFTNUM(arg, args);
if (1 != sscanf(arg, "%d", &dropX))
{
ScriptError("A number is expected here");
break;
}
SHIFTNUM(arg, args);
if (1 != sscanf(arg, "%d", &dropY))
{
ScriptError("A number is expected here");
break;
}
if (scriptWindow && dragBuffer)
{
FuncTyp method;
/*Drop*/
method = GetMethod((ObjPtr) scriptWindow, DROPOBJECTS);
if (method)
{
iconXOff = 0;
iconYOff = 0;
if (logging)
{
char cmd[256];
sprintf(cmd, "drop %d %d\n", dropX, dropY);
Log(cmd);
InhibitLogging(true);
}
(*method)(scriptWindow, dragBuffer, dropX, dropY);
DeleteThing(dragBuffer);
dragBuffer = NULLOBJ;
if (logging)
{
InhibitLogging(false);
}
}
}
else
{
ScriptError("There is no selected window");
}
}
break;
case KWVIDEOSCREEN:
DoVideoScreen();
break;
case KWFULLSCREEN:
DoMaxScreen();
break;
case KWTILE:
{
int width, height;
SHIFTNUM(arg, args);
if (1 != sscanf(arg, "%d", &width))
{
ScriptError("A width is expected here");
break;
}
SHIFTNUM(arg, args);
if (1 != sscanf(arg, "%d", &height))
{
ScriptError("A height is expected here");
break;
}
Tile(width, height);
}
break;
case KWLOCATE:
{
int l, r, b, t;
if (4 != sscanf(args, " %d %d %d %d", &l, &r, &b, &t))
{
ScriptError("The bounds of the window are expected here.");
return true;
}
LocateWindow(l, r, b, t);
}
break;
case KWEYEPOSN:
{
if (scriptWindow)
{
ObjPtr array, observer /*, observers*/;
array = ERROBJ;
args = ParseObjectArg(args, &array);
if (array != ERROBJ)
{
observer = FindObserver(scriptWindow);
if (!observer) break;
if (IsArray(array) && RANK(array) == 1 && DIMS(array)[0] == 3)
{
real *p;
SetVar(observer, LOCATION, array);
ImInvalid(observer);
p = ELEMENTS(array);
if (logging)
{
char cmd[256];
sprintf(cmd, "eyeposn [%g %g %g]\n",
p[0], p[1], p[2]);
Log(cmd);
}
}
else
{
ScriptError("A 3-vector is expected here");
}
}
}
}
break;
case KWROLL:
{
float value;
SHIFTKW(arg, args);
if (strlen(arg) && 1 == sscanf(arg, " %g", &value))
{
if (scriptWindow)
{
ObjPtr observer /*, observers*/;
observer = FindObserver(scriptWindow);
if (!observer) break;
SetVar(observer, ROLL, NewReal(value));
}
}
else
{
ScriptError("An amount to roll is expected here.");
}
}
break;
case KWPITCH:
{
float value;
SHIFTKW(arg, args);
if (strlen(arg) && 1 == sscanf(arg, " %g", &value))
{
if (scriptWindow)
{
ObjPtr observer/*, observers*/;
observer = FindObserver(scriptWindow);
if (!observer) break;
SetVar(observer, PITCH, NewReal(value));
}
}
else
{
ScriptError("An amount to pitch is expected here.");
}
}
break;
case KWYAW:
{
ScriptError("YAW is no longer supported.");
}
break;
case KWROTATE:
{
char axis;
float amount;
SHIFTKW(arg, args);
if (strlen(arg) == 1 && (*arg == 'x' || *arg == 'y' || *arg == 'z'))
{
axis = *arg;
SHIFTNUM(arg, args);
if (!strlen(arg) || 1 != sscanf(arg, "%f", &amount))
{
ScriptError("An amount to rotate is expected here.");
return true;
}
if (scriptWindow)
{
RotateOrthoWindow(scriptWindow, axis, amount);
}
}
else
{
ScriptError("Unrecognized keyword. An axis (x, y, or z) is expected.");
}
return true;
}
break;
case KWSHEAR:
ScriptError("Shearing is no longer supported.");
return true;
break;
case KWRECORD:
if (FindCommandInStack(KWRECORDING) < 0)
{
ScriptError("This command can only exist within a BEGIN RECORDING block.");
return true;
}
else
{
real nSecs;
if (1 != sscanf(args, " %g", &nSecs))
{
ScriptError("A number of seconds to record is expected here.");
}
else
{
runningTask = RT_RECORDING;
framesLeft = nSecs * 30 + 0.5;
}
return false;
}
case KWBEGIN:
return BeginCommand(args);
case KWEND:
return EndCommand(args);
case KWSNAP:
if (FindCommandInStack(KWRECORDING) < 0)
{
ScriptError("This command can only exist within a BEGIN RECORDING block.");
return true;
}
if (!SnapOneFrame())
{
ScriptError("Could not snap a single frame.");
}
++TrashDayFlag;
break;
case KWWINDOW:
SHIFTKW(arg, args);
if (!strlen(arg))
{
ScriptError("The name of a window is expected here");
return true;
}
SelectNamedWindow(arg);
break;
case KWEXIT:
case KWQUIT:
DoQuit();
break;
case KWCLOSE:
CloseWindow(scriptWindow);
SelWindow(0);
scriptWindow = 0;
break;
case KWPUSHWINDOW:
if (scriptWindow)
{
PushWindow(scriptWindow);
}
else
{
ScriptError("There is no current window");
}
break;
case KWSHELL: /*Shell escape*/
SKIPBLANKS(args);
if ((getuid() == geteuid()) &&
(getgid() == getegid()))
{
system(args);
}
break;
case KWSCRSAVE:
{
char fileName[256];
int l, r, b, t;
int n;
n = sscanf(args, " %s %d %d %d %d", fileName, &l, &r, &b, &t);
if (n == 5)
{
sprintf(tempStr, "scrsave %s %d %d %d %d", fileName, l, r, b, t);
if ((getuid() == geteuid()) &&
(getgid() == getegid()))
{
system(tempStr);
}
}
else if (n == 1)
{
sprintf(tempStr, "scrsave %s", fileName);
if ((getuid() == geteuid()) &&
(getgid() == getegid()))
{
system(tempStr);
}
}
else
{
ScriptError("A filename and four sides are expected here");
return true;
}
}
break;
case KWEFFECT:
{
/*Color effect*/
int whichFunc;
SHIFTKW(arg, args);
whichFunc = ParseKeyword(arg, spfNames, NPALETTEFUNCS);
if (whichFunc >= 0)
{
#ifdef MENUSFROM0
SimpleFuncFromMenu(whichFunc);
#else
SimpleFuncFromMenu(whichFunc + 1);
#endif
}
else
{
ScriptError("This special effect is not defined");
}
}
break;
case KWMODEL:
{
/*Color model*/
int whichFunc;
SHIFTKW(arg, args);
whichFunc = ParseKeyword(arg, colorModelNames, NCOLORMODELS);
if (whichFunc >= 0)
{
#ifdef MENUSFROM0
ColorModelFromMenu(whichFunc);
#else
ColorModelFromMenu(whichFunc + 1);
#endif
}
else
{
ScriptError("This color model is not defined");
}
}
break;
case KWKEEP:
DoKeepPalette();
break;
case KWREVERT:
DoRevertPalette();
break;
default:
ScriptError("This keyword is not a command");
break;
}
return true;
}
#ifdef PROTO
void BeginScript(char *name)
#else
void BeginScript(name)
char *name;
#endif
/*Begins a new script opened from file name*/
{
curScript = fopen(name, "r");
if (curScript)
{
runningScript = true;
abortScript = false;
}
else
{
fprintf(stderr, "BeginScript: Cannot open script file %s.\n", name);
}
}
void EndScript()
/*Ends a script*/
{
if (curScript)
{
while (nextStackElement)
{
EndCommand("");
}
/*Make control panels shown*/
ShowScriptControlPanels(true);
fclose(curScript);
curScript = 0;
runningScript = false;
MySetCursor(0);
}
}
Bool ReadScriptLine()
/*Reads and does a script line*/
{
if (curScript)
{
int k, c;
if (!lineAccepted)
{
lineAccepted = InterpretScriptLine(scriptLine);
return true;
}
if (abortScript)
{
fprintf(stderr, "Aborting script.\n");
EndScript();
return false;
}
/*Read a script line*/
k = 0;
while((c = fgetc(curScript)) != EOF && c != '\n')
{
if (k >= nScriptCharsAllocated)
{
if (nScriptCharsAllocated)
{
nScriptCharsAllocated += SCRIPTALLOCBATCH;
scriptLine = realloc(scriptLine, nScriptCharsAllocated + 1);
}
else
{
nScriptCharsAllocated = SCRIPTALLOCBATCH;
scriptLine = malloc(nScriptCharsAllocated + 1);
}
}
scriptLine[k] = c;
++k;
}
if (k == 0 && c == EOF)
{
EndScript();
return false;
}
else if (k != 0)
{
scriptLine[k] = 0;
lineAccepted = InterpretScriptLine(scriptLine);
return true;
}
}
return true;
}
static Bool ScriptTask()
/*Run the current script task*/
{
switch(runningTask)
{
case RT_RECORDING:
if (framesLeft <= 0)
{
runningTask = 0;
return true;
}
if (!SnapOneFrame())
{
ScriptError("Could not snap a single frame.");
}
++TrashDayFlag;
--framesLeft;
break;
}
return false;
}
Bool InterpretScriptLine(s)
char *s;
/*Interprets a script line in character string s. Returns true iff the script
line needs to be thrown away*/
{
char curKeyword[256];
int kwn;
Bool retVal;
if (runningTask != RT_NONE)
{
/*There's a running task*/
return ScriptTask();
}
/*Set up whole line for script stuff*/
wholeLine = s;
/*Look at first keyword*/
SKIPBLANKS(s);
if (*s == '#')
{
if (logging)
{
Log(wholeLine);
}
return true;
}
if (scriptWindow && IsValidWindow(scriptWindow))
{
SelWindow(scriptWindow);
}
else
{
SelWindow((WinInfoPtr) 0);
}
if (ObjFunctionScriptLine(s))
{
retVal = true;
}
else
{
SHIFTKW(curKeyword, s);
if (!strlen(curKeyword))
{
retVal = true;
}
else
{
/*Find out what it is*/
kwn = ParseKeyword(curKeyword, keywords, NKEYWORDS);
if (kwn == -1)
{
ScriptError("This command is unknown.");
retVal = true;
}
else if (kwn == -2)
{
ScriptError("This command is ambiguous.");
retVal = true;
}
else
{
retVal = DoScriptCommand(kwn, s);
}
}
}
return retVal;
}
|