// SIMetrix Technologies Ltd. 2007 // Module main.cpp // created 7.05.07 // Library: // Notes: // A simple application to demonstrate the SIMetrix Remote Data Interface. #include #include #include #include #include "sxremotedatainterface.h" //---------- Macro definitions ---------// #define SWITCH_CHAR '-' //--------------------------------------// //---------- Type definitions ----------// class CommandLineSwitch { bool exists ; int numValuesCopied ; char * values[4] ; public: CommandLineSwitch (int argc, char **argv, char *name, int numValues=0) ; operator bool () const { return exists ; } const char *operator [](int idx) const ; int size() const { return numValuesCopied ; } } ; //--------------------------------------// //--------- Extern functions -----------// //--------------------------------------// //---------- Extern data ---------------// //--------------------------------------// //--------- Local functions ------------// //--------------------------------------// //---------- Local Data-----------------// SRD_Interface *getInterface(int &major, int &minor) ; int runCommand(SRD_Interface *srdif, void **handle, int argc, const char **argv, int ident, int major, int minor) ; void displayErrorMessage(SRD_ErrorCode code) ; //--------------------------------------// //---------- Public data ---------------// //--------------------------------------// int main(int argc, char **argv) { CommandLineSwitch ident(argc, argv, "ident", 1) ; int intIdent = 0 ; if (ident) intIdent = atoi(ident[0]) ; int rv = 0, major = SRD_MAJOR_VERSION, minor = SRD_MINOR_VERSION ; SRD_Interface *srdif = getInterface(major, minor) ; if (srdif!=NULL) { char line[256] ; memset(line, 0, sizeof(line)) ; printf(">>") ; void *handle=NULL ; SRD_ErrorCode errcode = (SRD_ErrorCode)srdif->openInterface(ident, &handle) ; while( fgets(line, sizeof(line)-1, stdin)!=NULL ) { int numArgs ; const char *args[10] ; char *context = NULL ; args[0] = strtok_s(line, " \t\n", &context) ; for(numArgs=1 ; (args[numArgs] = strtok_s(NULL, " \t\n", &context))!=NULL && numArgs>") ; } srdif->closeInterface(handle) ; } else { fprintf(stderr, "Could not link to interface DLL\n") ; rv = -1 ; } return rv ; } int runCommand(SRD_Interface *srdif, void **handle, int argc, const char **argv, int ident, int major, int minor) { int rv ; SRD_ErrorCode errcode = SRDE_Ok ; if (!*handle) errcode = (SRD_ErrorCode)srdif->openInterface(ident, handle) ; if (errcode==SRDE_Ok) { if (!_strcmpi(argv[0],"help") || *argv[0]=='?') { printf("%s\n", "Commands: GetGroups GetVectorInfo GetVectorData Quit OpenSxCommand SendCommand\nType \" ?\" for help") ; } else if (!_strcmpi(argv[0], "GetVectorData")) { if (argc>2 && *argv[1]!='?') { const char *groupName = argv[1] ; const char *vecName = argv[2] ; SRD_Options options ; options.divisionIndex = argc>3 ? atoi(argv[3]) : 0 ; options.offset = argc>4 ? atoi(argv[4]) : 0 ; if (argc>5) { if (!_strcmpi(argv[5], "Y")) options.dataOptions = SRDV_Y ; else if (!_strcmpi(argv[5], "X")) options.dataOptions = SRDV_X ; else if (!_strcmpi(argv[5], "XY")) options.dataOptions = SRDV_XY ; else if (!_strcmpi(argv[5], "LitAlias")) options.dataOptions = SRDV_AliasLiteral ; else options.dataOptions = SRDV_Y ; } else { options.dataOptions = SRDV_Y ; } options.incremental = argc>6 ? !_strcmpi(argv[6], "true") : false ; SRD_VectorData *vectorData ; errcode = (SRD_ErrorCode)srdif->getVectorData(*handle, groupName, vecName, &options, &vectorData) ; if (errcode==SRDE_Ok) { int idx ; if (options.dataOptions==SRDV_Y || options.dataOptions==SRDV_XY || options.dataOptions==SRDV_AliasLiteral) { if (vectorData->dataType==SRDD_Real) { for (idx=0 ; idxnumElems ; idx++) { printf("%d: %g\n", idx, vectorData->d.realData[idx]) ; } } else if (vectorData->dataType==SRDD_Complex) { for (idx=0 ; idxnumElems ; idx++) { printf("%d: (%g,%g)\n", idx, vectorData->d.complexData[idx].real, vectorData->d.complexData[idx].imag) ; } } else if (vectorData->dataType==SRDD_String) { for (idx=0 ; idxnumElems ; idx++) { printf("%d: %s\n", idx, vectorData->d.stringData[idx]) ; } } else { printf("%s\n", "Unexpected data type returned") ; } } if (options.dataOptions==SRDV_X || options.dataOptions==SRDV_XY) { assert(vectorData->refData!=NULL) ; printf("X data\n") ; for (idx=0 ; idxnumElems ; idx++) { printf("%d: %g\n", idx, vectorData->refData[idx]) ; } } // The vector's data will also be destroyed when closeHandle is called // if not previously destroyed by this function errcode = (SRD_ErrorCode)srdif->destroyData(*handle, vectorData) ; } } else { printf( "%s\n", "Usage: GetVectorData \n" " [ [ [ Y|XY|X|LitAlias [ true|false ]]]]\n\n" "Returns vector's data\n" "\n" " : value 0 or greater is index of division in multi-division\n" " vector. (e.g. for Monte Carlo)\n\n" " : Default=0, start data output at elements into\n" " vector\n\n" "Y|XY|X|LitAlias : Y, output y-data only (default),\n" " XY, output both X and Y data,\n" " X, output x-data only\n" " LitAlias, output literal value of alias or y-data if vector is not an alias\n\n" "true|false : true: use 'incremental' option\n") ; } } else if (!_strcmpi(argv[0], "GetGroups")) { if (argc==1 || *argv[1]!='?') { SRD_Strings *groupNames ; errcode = (SRD_ErrorCode)srdif->getGroupNames(*handle, &groupNames) ; if (errcode==SRDE_Ok) { int idx ; for (idx=0 ; idxnumStrings ; idx++) { printf("%s\n", groupNames->strings[idx]) ; } rv = 0 ; } } else { printf("%s\n", "Usage: GetGroups\nReturns list of data groups available") ; } } else if (!_strcmpi(argv[0], "GetVectorInfo")) { if (argc>1 && *argv[1]!='?') { const char *vecName = argc>3 ? argv[3] : NULL ; const char *groupName = argv[1] ; SRD_VectorInfoArray *vecInfoArray ; SRD_Options options ; options.opMode = argc>2 ? ( !_strcmpi(argv[2],"opinfo") ? SRDO_Literal : (!_strcmpi(argv[2],"opinfoall") ? SRDO_All :SRDO_None ) ) : SRDO_None ; errcode = (SRD_ErrorCode)srdif->getVectorInfo(*handle, groupName, vecName, &options, &vecInfoArray) ; if (errcode==SRDE_Ok) { int idx ; SRD_VectorInfo *vi = vecInfoArray->vectorInfo ; for(idx=0 ; idxnumElems ; idx++) { const char *refName ; if (vi[idx].refIndex>=0 && vi[idx].refIndexnumElems) refName = vi[vi[idx].refIndex].name ; else refName = "" ; if (options.opMode==SRDO_None) printf("%s, dataType=%d, len=%d, numdiv=%d, phystype=%s, ref=%s\n", vi[idx].name, vi[idx].dataType, vi[idx].totalLength, vi[idx].numDivisions, vi[idx].physTypeName, refName) ; else printf("%s, dataType=%d, len=%d, numdiv=%d, phystype=%s, ref=%s, val=%g\n", vi[idx].name, vi[idx].dataType, vi[idx].totalLength, vi[idx].numDivisions, vi[idx].physTypeName, refName, vi[idx].scalarVal) ; } } } else { printf("%s\n", "Usage: GetVectorInfo [ none|opinfo|opinfoall []]\n" "Returns information about specified vector.\n\n" "If no vector name supplied, all vectors in group are listed\n\n" "Specify 'opinfo' to get value of vec[0] for all non-aliassed numeric vectors\n" "Specify 'opinfoall' to get value of vec[0]\nfor all numeric vectors including aliasses\n") ; } } else if (!_strcmpi(argv[0], "OpenSxCommand")) { if (argc>1 && *argv[1]=='?') { printf("%s\n", "Usage: OpenSxCommand\nOpen SxCommand interface. Must call this prior to using SendCommand\n") ; } else { if (major>1 || minor>0) errcode = srdif->openSxCommand(*handle) ; else errcode = SRDE_BadVersion ; } } else if (!_strcmpi(argv[0], "SendCommand")) { if (argc>1 && *argv[1]!='?') { if (major>1 || minor>0) { char buffer[32768] = {0} ; for (int argidx=1 ; argidx1) strcat_s(buffer, " ") ; strcat_s(buffer, argv[argidx]) ; } errcode = srdif->sendCommand(*handle, buffer) ; } else { errcode = SRDE_BadVersion ; } } else { printf("%s\n", "Usage: SendCommand []\nSends a command to SIMetrix.\nMust call OpenSxCommand first\n") ; } } else { fprintf(stderr, "Unknown command %s\n", argv[0]) ; rv = -3 ; } } if (errcode!=SRDE_Ok) { displayErrorMessage(errcode) ; rv = -4 ; } return rv ; } void displayErrorMessage(SRD_ErrorCode code) { const char *msg ; switch (code) { // user errors case SRDE_ConnectionClosed: msg = "No Connection to SIMetrix" ; break ; case SRDE_NoGroup: msg = "Unknown group name" ; break ; case SRDE_NoVec: msg = "Unknown vector" ; break ; case SRDE_BadDivisionIndex: msg = "Division index out of range" ; break ; case SRDE_BadOffset: msg = "Offset out of range" ; break ; case SRDE_BadXVec: msg = "Vector has no x-values" ; break ; // user error at SIMetrix end case SRDE_BadAlias: msg = "Alias could not be resolved" ; break ; // Errors in calling application case SRDE_BadHandle: msg = "Bad handle passed to interface function" ; break ; case SRDE_BadVersion: msg = "Incompatible interface version" ; break ; case SRDE_BadArgs: msg = "Bad arguments passed to interface function" ; break ; // Interface errors case SRDE_BadCommand: msg = "Unknown command sent to remote application" ; break ; // Remote interface errors case SRDE_AllocFail: msg = "Allocation failed in remote application" ; break ; case SRDE_Exception: msg = "Remote application threw an exception while executing request" ; break ; case SRDE_UnexpectedReply: msg = "Remote application returned an unexpected reply" ; break ; case SRDE_UnsupportedXDataType: case SRDE_UnexpectedDataType: msg = "Remote application returned unexpected data" ; break ; case SRDE_NoSxCommandInterface: msg = "SxCommand interface has not been opened" ; break ; case SRDE_SxCommandFailed: msg = "Command failed" ; break ; case SRDE_SxCommandBusy: msg = "SIMetrix is busy" ; break ; case SRDE_Unknown: msg = "Unknown error" ; break ; default: msg = "Unknown error" ; break ; } fprintf(stderr, "Error: %s\n", msg) ; } SRD_Interface *getInterface(int &major, int &minor) { SRD_InitialiseInterfaceProc srd_InitialiseInterface = NULL ; HMODULE module = LoadLibraryA("sxrdif.dll") ; static SRD_Interface srdif ; SRD_Interface *rv = NULL ; if (module) { srd_InitialiseInterface = (SRD_InitialiseInterfaceProc)GetProcAddress(module, SRD_INITIALISE_INTERFACE) ; if (srd_InitialiseInterface) { SRD_ErrorCode errcode = (SRD_ErrorCode)srd_InitialiseInterface(&srdif, &major, &minor) ; if (errcode==SRDE_Ok) rv = &srdif ; } } return rv ; } // general class to read command line switches CommandLineSwitch::CommandLineSwitch(int argc, char **argv, char *name, int numValues) { int idx ; exists = false ; numValuesCopied = 0 ; memset(values, 0, sizeof(values)) ; for (idx=0 ; idx(int)sizeof(values)/sizeof(*values)) numValues = sizeof(values)/sizeof(*values) ; if (numValues>=argc-idx) numValues = argc-idx-1 ; numValuesCopied = 0 ; for (valIdx=0 ; valIdx=numValuesCopied) return "" ; return values[idx] ; }