|
TNTmips

|
smlapp.c
/* SMLSDK.c
*
* example of extending SML functions with SDK
*
* See instr.sml for sample usage
*
* !!! YOU MUST COMPILE smlsdk.c AND RUN IT'S EXECUTABLE BEFORE USING instr.sml !!!
*
* Follow these steps - Windows 95
*
* 1. Build instr.exe - the sample make file is for Windows 95 machines
* 2. Move instr.exe to your TNTMips directory
* 3. Start TNTMips
* 4. Using Windows Explorer or MS-DOS Window - execute instr.exe
*
* TNTMips should start an SML session with the custom functions installed
*
* This example program updated 30 April 1998.
* Now shows how to access a raster variable passed to a function.
*/
//#define ALLOW_GRE // Uncomment this if you want display functions
//#define ALLOW_MIE // Uncomment this if you want import/export
// Note, MIE requires you to link to a bunch
// of extra libs too. See comment in the makefile.
#ifdef ALLOW_GRE
#define SML_DEFINE_SML_TNTDISP_ONLY_FUNCS
#include <mi32/gre.h>
#endif
#ifdef ALLOW_MIE
#include <mi32/mie.h>
#endif
#include <mi32/sml.h>
#include <mi32/smlfuncs.h>
#include <mgui/appmain.h>
#include <mi32/mdlg.h>
/*****************************************************************************/
/*
** InStr(searchstr$, find$, start)
**
** function to find substring in a string
** starts searching at char position defined by start
** if start is greater than length of searchstr
**
** When creating your own function, name the function however you want
** it to show up in SML. In this example, we're creating a function named
** InStr.
**
** The names of the SMLPARM array must be the same as the function with
** _Parms append to the end (ie: InStr_Parms). You must also #define the
** _CreateDate, _ModDate, and _FuncType. The macro SMLFUNCDEF2 uses
** these #defines. This allows everything about the function to be
** defined in one place.
*/
/* SMLPARM structures sent to function - form is */
/* name, type STYPE_Xxxxx (see sml.h), PARM_Optional (1) or 0 if required */
static SMLPARM InStr_Parms [] = {
{"searchstr$", STYPE_String, 0}, /* the string to search */
{"findstr$", STYPE_String, 0}, /* the substring to search for */
{"start", STYPE_Constant, 0}, /* where to start searching */
{ NULL }
};
#define InStr_CreateDate 19980101 /* Date function written (YYYYMMDD) */
#define InStr_ModDate 19980430 /* Date function last modified */
#define InStr_FuncType STYPE_BFunction /* or STYPE_BProcedure if void */
static double InStr (
int numargs, /* Number of parameters the user actually passed */
SMLARG *arg, /* Array of parameters */
UINT8 *type, /* Parameter types. Usually ignored (see comment below) */
SMLCONTEXT *context /* context for various functions that need it */
) {
int MaxArg = numargs - 1;
int startPos, srchLen, findLen;
double pos;
enum { ParmSearchStr, ParmFindStr, ParmStart };
/* Note: You don't actually have to do this check unless the parm
* Is marked as being PARM_Optional */
if (MaxArg < ParmSearchStr) {
context->SetArgError(SML_ENotEnoughArgs, ParmSearchStr, NULL);
return(-1);
}
/*
** Make sure the parameters are the correct type
**
** Note, you don't actually have to do this unless
** the parameter list specifies STYPE_AnyVal. In
** that case, the user could pass an STYPE_String
** or an STYPE_Constant. If your parameter list
** requests a specific type, you'll get it or the
** script will get a syntax error
*/
if (type[ParmSearchStr] != STYPE_String) {
context->SetArgError(SML_EArgNotString, ParmSearchStr, NULL);
return(-1);
}
if (type[ParmFindStr] != STYPE_String) {
context->SetArgError(SML_EArgNotString, ParmFindStr, NULL);
return(-1);
}
/* first char in SML is 1 - but we want it to be zero for "C" */
startPos = (int)arg[ParmStart].val - 1;
if (startPos < 0) {
context->SetArgError(SML_EBadParmAssign, ParmStart, NULL);
return(-1);
}
/*
** Get the strings
*/
const MISTRING ucSearchStr = *arg[ParmSearchStr].str;
srchLen = ucSearchStr.GetLength();
const MISTRING ucFindStr = *arg[ParmSearchStr].str;
findLen = ucFindStr.GetLength();
/* check for start position past the end of search string */
/* - if it is then return 0 */
if (startPos < srchLen) {
pos = ucSearchStr.FindNextOf(ucFindStr, startPos);
}
else {
pos = 0;
}
return((double) pos);
}
/*************************************************************************
*
* Another sample SML Function: This function does nothing useful, it just
* demonstrates how to do several things. As an example, it takes
* a raster and sets it to a constant. (something better done in
* SML by the command:
* R = x
* But hey, this is an exmaple.
*
**************************************************************************/
/* The parameters for the function SetRast */
static SMLPARM SetRast_Parms[] = {
{"Raster", STYPE_Raster, 0},
{"number", STYPE_Constant, 0},
{"name$", STYPE_String, PARM_Optional},
{ NULL } /* Must always end with a NULL */
};
#define SetRast_CreateDate 19980429 /* created April 29, 1998 */
#define SetRast_ModDate 19980429 /* Last modified April 29, 1998 */
#define SetRast_FuncType STYPE_BProcedure /* Function returns nothing */
static void SetRast ( /* The function name given here is what it will be called in SML */
int numargs, /* Number of parameters passed to the function */
SMLARG *args, /* Array of parameters passed to the function */
UINT8 *type, /* Array of parameter types (usually ignored) */
SMLCONTEXT *context /* SMLCONTEXT needed for many SML_Xxxx functions */
) {
UINT8 *buf = NULL;
SMLRASTEROBJECT *srast;
int i, err;
args[0].sym->GetObject(&srast);
if (srast == NULL) return;
/*
** Closing the object flushes SML's buffers. If the object
** isn't open, it does nothing.
*/
srast->Close();
/* Make sure the raster is open for writing */
err = srast->Open(RVCMODE_RW);
if (err < 0) {
context->SetErrorCode(err); /* Will cause script to exit */
return;
}
if ((err = MmAllocC((void **)&buf, srast->GetNumCols())) < 0) {
context->SetErrorCode(err); /* Will cause script to exit */
return;
}
/* Show accessing a Unicode string parameter */
if (numargs > 2) { /* Since it was optional above */
MISTRING mistr = *args[2].str;
/*
* Do whatever you need to do with the string here
* This function doesn't actually need a string parameter.
* I just put this here to show how to access the string.
* An MISTRING can be treated like a Unicode string
*/
}
/* Fill a buffer with whatver the 2nd parameter was (args[1]) */
for (i = 0 ; i < srast->GetNumLins() ; ++i) {
buf[i] = (UINT8)args[1].val;
}
/*
* Fill the raster with the buffer. You could allocate an array of
* doubles instead of UINT8 and use RASTMODE_ConvToDouble, but if
* you know the raster will be 8-bit unsigned, this is faster
*/
for (i = 0 ; i < srast->GetNumLins() ; ++i) {
err = MfWriteRastConv(srast->GetObjHandle(), i, 0, srast->GetNumCols(), buf, RASTMODE_ConvToByte);
if (err < 0) {
context->SetErrorCode(err); /* Will cause script to exit */
MmFree(buf);
return;
}
}
MmFree(buf);
/* We don't need to close the raster. SML will do it later */
return;
}
/*****************************************************************************/
/*
** List of functions to install. There can be as many functions in the
** list as you want.
*/
static SMLFUNC MyFuncList[] = {
SMLFUNCDEF2 (InStr),
SMLFUNCDEF2 (SetRast),
{ NULL } /* NULL indicates end of list */
};
/*****************************************************************************/
/*
** Function for SML to call after it creates the context. You can
** install your own functions here. You could do other things too
** if you wanted to.
**
** When installing the functions, this example will create a "Custom"
** group for the functions to go into. If you wanted to put them into
** an existing group, you'd just use that group's name. If you wanted
** to install to more than one group, you'd create a function list for
** each group and install them separately.
*/
static void MCB_InstallMyFuncs (
SMLCALLBACKSTRUCT *cbs,
void *
) {
cbs->context->InstallFunctions("Custom", MyFuncList);
#ifdef ALLOW_GRE
// The following line will add all of the functions that standalone SML
// would have when run from tntdisp (where it resides). Without it, you
// dont get all of the GRE classes and display functions, but your program
// would be much smaller.
cbs->context->InstallFunctionList(SML_TNTDispFuncList);
#endif
}
/***********************************************************************
* Main routine to install custom functions
***********************************************************************/
class APP_SML : public MGUI::APP_BASE {
public:
APP_SML() { }
private:
// overrides from APP_BASE
virtual const char* v_GetProcessName (
) const {
return "SML_SDK_Example";
}
virtual void v_ExitInstance();
virtual bool v_InitInstance();
};
void APP_SML::v_ExitInstance (
) {
#ifdef ALLOW_GRE
GRE_SYSTEM::StopX();
#endif
}
bool APP_SML::v_InitInstance (
) {
Widget toplevel = MxInitLegacy(LEGACYINIT_NoAutoSetExit|LEGACYINIT_NoRealize);
SMLCONTEXT::CallbackAddGlobal((McbCallbackFunc)MCB_InstallMyFuncs, 0, MsmlCR_InstallFuncsSML);
#ifdef ALLOW_MIE
MieAddFormatsAll();
SML_EnableImportExport();
#endif
#ifdef ALLOW_GRE
GRE_SYSTEM::InitX(); // Uncomment these if you want GRE support
GRE_SYSTEM::RegisterLayoutLayerTypes();
#endif
ERRVALUE err;
SMLCONTEXT* context = 0;
if ((err = SML_InitExt(&context)) < 0) {
MdlgShowErrorCode(0, err);
return(false);
}
SIMPLE_ARRAY<const char*> cmdparms;
cmdparms.Reserve(GetCmdParmCount());
for (int i = 1; (i < GetCmdParmCount()) ; ++i) {
cmdparms.Append(GetCmdParm(i));
}
if ((err = SML_Main(toplevel, context, cmdparms, cmdparms.GetNumItems(), QFLAG_NonModal|QFLAG_SML|QFLAG_SetExitOnQuit)) < 0) {
MdlgShowErrorCode(0, err);
return(false);
}
return(true);
}
class MAIN : public MGUI::APP_MAIN {
public:
MAIN () : m_pApp(new APP_SML) {}
~MAIN() {}
private:
APP_SML* m_pApp;
};
static MAIN MainApp;
©MicroImages, Inc. 2013 Published in the United States of America
11th Floor - Sharp Tower, 206 South 13th Street, Lincoln NE 68508-2010 USA
Business & Sales: (402)477-9554 Support: (402)477-9562 Fax: (402)477-9559
Business info@microimages.com
Support support@microimages.com
Web webmaster@microimages.com
| |