/** Function: rtwCAPI_EncodePath =============================================== * Abatract: * Escape all '|' characters in bpath. For examples 'aaa|b' will become * 'aaa~|b'. The caller is responsible for freeing the returned string * * * NOTE: returned string can be NULL in two cases: * (1) string passed in was NULL * (2) a memory allocation error occurred * In the second case, the caller need to report the error */ char* rtwCAPI_EncodePath(const char* path) { char* encodedPath = NULL; size_t pathLen = (path==NULL) ? 0:strlen(path) + 1; size_t encodedPathLen = pathLen; unsigned i; unsigned j = 0; if (path == NULL) return NULL; for (i = 0; i < pathLen; ++i) { if (path[i] == '|' || path[i] == '~') ++encodedPathLen; } encodedPath = (char_T*)utMalloc(encodedPathLen*sizeof(char_T)); if (encodedPath == NULL) return encodedPath; for (i = 0; i < pathLen; ++i) { char ch = path[i]; if (ch == '~' || ch == '|') encodedPath[j++] = '~'; encodedPath[j++] = ch; } utAssert(j == encodedPathLen); utAssert(encodedPath[j-1] == '\0'); return encodedPath; } /* rtwCAPI_EncodePath */
/** Function: rtwCAPI_UpdateFullPaths =========================================* * */ const char_T* rtwCAPI_UpdateFullPaths(rtwCAPI_ModelMappingInfo* mmi, const char_T* path, boolean_T isCalledFromTopModel) { int_T i; int_T nCMMI; size_t pathLen; char_T* mmiPath; size_t mmiPathLen; char_T* relMMIPath; size_t relMMIPathLen; if (mmi == NULL) return NULL; utAssert(path != NULL); utAssert( rtwCAPI_GetFullPath(mmi) == NULL ); pathLen = strlen(path)+1; if (isCalledFromTopModel) { /* If called from top model - FullPath is same as path */ mmiPath = (char_T*)utMalloc(pathLen*sizeof(char_T)); (void)memcpy(mmiPath, path, pathLen*sizeof(char_T)); } else { relMMIPath = rtwCAPI_EncodePath(rtwCAPI_GetPath(mmi)); if ( (relMMIPath== NULL) && (rtwCAPI_GetPath(mmi) != NULL)) { return rtwCAPI_mallocError; } relMMIPathLen = relMMIPath ? (strlen(relMMIPath) + 1) : 0; mmiPathLen = pathLen + relMMIPathLen; mmiPath = (char_T*)utMalloc(mmiPathLen*sizeof(char_T)); if (mmiPath == NULL) return rtwCAPI_mallocError; (void)memcpy(mmiPath, path, pathLen*sizeof(char_T)); utAssert(mmiPath[pathLen-1] == '\0'); if (relMMIPath) { /* mmiPath = path + | + relMMIPath + '\0' */ mmiPath[pathLen-1] = '|'; (void)memcpy(&(mmiPath[pathLen]), relMMIPath, relMMIPathLen*sizeof(char_T)); utAssert(mmiPath[mmiPathLen-1] == '\0'); utFree(relMMIPath); } } rtwCAPI_SetFullPath(*mmi, mmiPath); nCMMI = rtwCAPI_GetChildMMIArrayLen(mmi); for (i = 0; i < nCMMI; ++i) { rtwCAPI_ModelMappingInfo* cMMI = rtwCAPI_GetChildMMI(mmi,i); const char_T* errstr = rtwCAPI_UpdateFullPaths(cMMI, mmiPath, 0); if (errstr != NULL) return errstr; } return NULL; } /* rtwCAPI_UpdateFullPaths */
/** Function: rtwCAPI_GetNumContStateRecords =================================== * */ int_T rtwCAPI_GetNumContStateRecords(const rtwCAPI_ModelMappingInfo* mmi) { int_T i; int_T nRecs; int_T nCMMI; int_T nCStateRecs; const rtwCAPI_States* states; const rtwCAPI_DataTypeMap* dataTypeMap; if (mmi == NULL) return 0; nCStateRecs = 0; states = rtwCAPI_GetStates(mmi); dataTypeMap = rtwCAPI_GetDataTypeMap(mmi); nRecs = rtwCAPI_GetNumStates(mmi); for (i = 0; i < nRecs; i++) { if (rtwCAPI_IsAContinuousState(states,i)) { ++nCStateRecs; /* All continuous states should be able to be logged to MAT-File * so we do not need to skip any states here. */ utAssert(rtwCAPI_CanLogStateToMATFile(dataTypeMap, states, i)); } } nCMMI = rtwCAPI_GetChildMMIArrayLen(mmi); for (i = 0; i < nCMMI; ++i) { const rtwCAPI_ModelMappingInfo* cMMI = rtwCAPI_GetChildMMI(mmi,i); nCStateRecs += rtwCAPI_GetNumContStateRecords(cMMI); } return nCStateRecs; } /* rtwCAPI_GetNumContStateRecords */
static void verifyTree( olNode node) { olNode parent = olNodeGetParentRootNode(node); olNode left = olNodeGetLeftRootNode(node); olNode right = olNodeGetRightRootNode(node); utAssert(parent == olNodeNull || olNodeGetLeftRootNode(parent) == node || olNodeGetRightRootNode(parent) == node); if(left != olNodeNull) { utAssert(!olNodeIsRedRootNode(node) || !olNodeIsRedRootNode(left)); verifyTree(left); } if(right != olNodeNull) { utAssert(!olNodeIsRedRootNode(node) || !olNodeIsRedRootNode(right)); verifyTree(right); } }
uint32 olVerifyTree( olNode node) { olNode parent = olNodeGetParentRootNode(node); olNode left = olNodeGetLeftRootNode(node); olNode right = olNodeGetRightRootNode(node); uint32 leftDepth = 0, rightDepth = 0; utAssert(parent == olNodeNull || olNodeGetLeftRootNode(parent) == node || olNodeGetRightRootNode(parent) == node); utAssert(parent != olNodeNull || !olNodeIsRedRootNode(node)); if(left != olNodeNull) { utAssert(!olNodeIsRedRootNode(node) || !olNodeIsRedRootNode(left)); utAssert(olNodeGetKey(node) >= olNodeGetKey(left)); leftDepth = olVerifyTree(left); } if(right != olNodeNull) { utAssert(!olNodeIsRedRootNode(node) || !olNodeIsRedRootNode(right)); utAssert(olNodeGetKey(node) <= olNodeGetKey(right)); rightDepth = olVerifyTree(right); } utAssert(leftDepth == rightDepth); if(olNodeIsRedRootNode(node)) { return leftDepth; } return leftDepth + 1; }
/** Function: rtwCAPI_GetFullStateBlockPath =================================== * */ char* rtwCAPI_GetFullStateBlockPath(const char* stateBlockPath, const char* mmiPath, size_t mmiPathLen, boolean_T crossingModel) { char_T* blockPath = NULL; char_T* fullStateBlockPath = NULL; size_t fullStateBlockPathLen; if (stateBlockPath == NULL) goto EXIT_POINT; /* fullStateBlockPath = mmiPath + | + blockPath + '\0' */ /* If crossing a model boundary encode, otherwise do not */ if (crossingModel) { blockPath = rtwCAPI_EncodePath(stateBlockPath); if (blockPath == NULL) goto EXIT_POINT; } else { size_t len = strlen(stateBlockPath)+1; blockPath = (char*)utMalloc(len*sizeof(char)); if (blockPath == NULL) goto EXIT_POINT; (void)strcpy(blockPath,stateBlockPath); } utAssert(blockPath != NULL); fullStateBlockPathLen = ( (mmiPath==NULL) ? strlen(blockPath) + 1 : mmiPathLen + strlen(blockPath) + 2 ); fullStateBlockPath = (char*)utMalloc(fullStateBlockPathLen*sizeof(char)); if (fullStateBlockPath == NULL) goto EXIT_POINT; if (mmiPath != NULL) { (void)strcpy(fullStateBlockPath, mmiPath); fullStateBlockPath[mmiPathLen] = '|'; fullStateBlockPath[mmiPathLen+1] = '\0'; (void)strcat(fullStateBlockPath, blockPath); } else { (void)strcpy(fullStateBlockPath, blockPath); fullStateBlockPath[fullStateBlockPathLen-1] = '\0'; } utAssert(fullStateBlockPath[fullStateBlockPathLen-1] == '\0'); EXIT_POINT: utFree(blockPath); return fullStateBlockPath; /* caller is responsible for free */ }
void olVerifyOrderedList( olRoot root) { olNode node; olNode rootNode = olRootGetRootNode(root); olNode prevNode = olNodeNull; olForeachRootNode(root, node) { utAssert(prevNode == olNodeNull || olRootCompareNode(prevNode, node) >= 0); } olEndRootNode;
int_T rtwCAPI_GetStateWidth(const rtwCAPI_DimensionMap* dimMap, const uint_T* dimArray, const rtwCAPI_States* states, int_T iState) { int_T mapIdx = rtwCAPI_GetStateDimensionIdx(states, iState); utAssert( rtwCAPI_GetNumDims(dimMap,mapIdx) == 2 ); mapIdx = rtwCAPI_GetDimArrayIndex(dimMap, mapIdx); return (dimArray[mapIdx] * dimArray[mapIdx+1]); }
/** Function: rtwCAPI_FreeFullPaths ============================================ * */ void rtwCAPI_FreeFullPaths(rtwCAPI_ModelMappingInfo* mmi) { int_T i; int_T nCMMI; char_T* fullPath; if (mmi == NULL) return; fullPath = rtwCAPI_GetFullPath(mmi); utAssert(fullPath != NULL); utFree(fullPath); rtwCAPI_SetFullPath(*mmi, NULL); nCMMI = rtwCAPI_GetChildMMIArrayLen(mmi); for (i = 0; i < nCMMI; ++i) { rtwCAPI_ModelMappingInfo* cMMI = rtwCAPI_GetChildMMI(mmi,i); rtwCAPI_FreeFullPaths(cMMI); } } /* rtwCAPI_FreeFullPaths */
// Find the previous position to point to. static void setPrevLocation(uint32 pos, peGraphType type) { if(pos == 0) { return; } peLocation location = peRootGetiLocation(peTheRoot, pos); uint32 prevPos = 0; switch(type) { case SLIDING_WINDOW: prevPos = findSlidingWindowPos(pos); break; case RAND_CUBED: prevPos = findRandCubedPos(pos); break; case RAND: prevPos = findRandPos(pos); break; case CATENA: prevPos = findCatenaPos(pos); break; case SLIDING_REVERSE: prevPos = findSlidingReversePos(pos); break; case REVERSE: prevPos = findReversePos(pos); break; default: utExit("Unknown graph type\n"); } if(prevPos == UINT32_MAX || prevPos + 1 == pos) { return; // No edge } peLocation prevLocation = peRootGetiLocation(peTheRoot, prevPos); utAssert(prevPos + 1 < pos); peLocationAppendLocation(prevLocation, location); }
/** Function: rtwCAPI_GetSigLogRecordInfo ====================================== * */ const char_T* rtwCAPI_GetSigLogRecordInfo(const rtwCAPI_ModelMappingInfo* mmi, const char_T** sigBlockName, const char_T** sigLabel, int_T* sigWidth, int_T* sigDataType, int_T* logDataType, int_T* sigComplexity, void** sigDataAddr, boolean_T* sigCrossMdlRef, int_T* sigIdx, boolean_T crossingModel, boolean_T rtwLogging) { int_T i; int_T nCMMI; int_T nSignals; const char_T* mmiPath; size_t mmiPathLen; const rtwCAPI_Signals* signals; const rtwCAPI_DimensionMap* dimMap; const uint_T* dimArray; const rtwCAPI_DataTypeMap* dataTypeMap; void** dataAddrMap; const char_T* errstr = NULL; uint8_T isPointer = 0; char* blockPath = NULL; if (mmi == NULL) goto EXIT_POINT; nCMMI = rtwCAPI_GetChildMMIArrayLen(mmi); for (i = 0; i < nCMMI; ++i) { rtwCAPI_ModelMappingInfo* cMMI = rtwCAPI_GetChildMMI(mmi,i); errstr = rtwCAPI_GetSigLogRecordInfo(cMMI, sigBlockName, sigLabel, sigWidth, sigDataType, logDataType, sigComplexity, sigDataAddr, sigCrossMdlRef, sigIdx, true, rtwLogging); if (errstr != NULL) goto EXIT_POINT; } nSignals = rtwCAPI_GetNumSignals(mmi); if (nSignals < 1) goto EXIT_POINT; mmiPath = rtwCAPI_GetFullPath(mmi); mmiPathLen = (mmiPath==NULL)? 0 : strlen(mmiPath); signals = rtwCAPI_GetSignals(mmi); dimMap = rtwCAPI_GetDimensionMap(mmi); dimArray = rtwCAPI_GetDimensionArray(mmi); dataTypeMap = rtwCAPI_GetDataTypeMap(mmi); dataAddrMap = rtwCAPI_GetDataAddressMap(mmi); for (i = 0; i < nSignals; ++i) { uint_T mapIdx; size_t sigPathLen; char* sigPath; /* For RTW logging, skip states that cannot be logged to MAT-File. */ if ((rtwLogging) && (rtwCAPI_CanLogSignalToMATFile(dataTypeMap, signals, i) == false)) continue; /* sigBlockPath = mmiPath + | + BlockPath + '\0' */ /* If crossing a model boundary encode, otherwise do not */ if (crossingModel) { blockPath = rtwCAPI_EncodePath(rtwCAPI_GetSignalBlockPath(signals, i)); if ( (blockPath == NULL) && (rtwCAPI_GetSignalBlockPath(signals, i) != NULL)) { errstr = rtwCAPI_mallocError; goto EXIT_POINT; } } else { const char* constBlockPath = rtwCAPI_GetSignalBlockPath(signals, i); blockPath = (char*)utMalloc((strlen(constBlockPath)+1)*sizeof(char)); (void)strcpy(blockPath, constBlockPath); } utAssert(blockPath != NULL); sigPathLen = ( (mmiPath==NULL) ? strlen(blockPath) + 1 : mmiPathLen + strlen(blockPath) + 2 ); sigPath = (char*)utMalloc(sigPathLen*sizeof(char)); if (sigPath == NULL) { errstr = rtwCAPI_mallocError; goto EXIT_POINT; } if (mmiPath != NULL) { (void)strcpy(sigPath, mmiPath); sigPath[mmiPathLen] = '|'; sigPath[mmiPathLen+1] = '\0'; (void)strcat(sigPath, blockPath); } else { (void)strcpy(sigPath, blockPath); sigPath[sigPathLen-1] = '\0'; } /* need to free for every iteration of the loop, but also have * the free below EXIT_POINT in case of error */ utFree(blockPath); blockPath = NULL; utAssert(sigPath[sigPathLen-1] == '\0'); sigBlockName[*sigIdx] = sigPath; /* caller is responsible for free */ /* Label */ sigLabel[*sigIdx] = rtwCAPI_GetSignalName(signals, i); /* Width */ mapIdx = rtwCAPI_GetSignalDimensionIdx(signals, i); utAssert( rtwCAPI_GetNumDims(dimMap,mapIdx) == 2 ); mapIdx = rtwCAPI_GetDimArrayIndex(dimMap, mapIdx); sigWidth[*sigIdx] = dimArray[mapIdx] * dimArray[mapIdx+1]; /* DataType and logDataType */ mapIdx = rtwCAPI_GetSignalDataTypeIdx(signals, i); sigDataType[*sigIdx] = rtwCAPI_GetDataTypeSLId(dataTypeMap, mapIdx); /* this mimics code in simulink.dll:mapSigDataTypeToLogDataType */ if ( SS_DOUBLE || SS_SINGLE || SS_INT8 || SS_UINT8 || SS_INT16 || SS_UINT16 || SS_INT32 || SS_UINT32 || SS_BOOLEAN ) { logDataType[*sigIdx] = sigDataType[*sigIdx]; } else { logDataType[*sigIdx] = SS_DOUBLE; } /* Complexity */ sigComplexity[*sigIdx] = rtwCAPI_GetDataIsComplex(dataTypeMap, mapIdx); /* Data Access - Pointer or Direct*/ isPointer = ((uint8_T)rtwCAPI_GetDataIsPointer(dataTypeMap, mapIdx)); /* Address */ mapIdx = rtwCAPI_GetSignalAddrIdx(signals, i); rtwCAPI_GetSigAddrFromMap(isPointer, sigComplexity, sigDataType, sigDataAddr, sigIdx, mapIdx, dataAddrMap); /* CrossingModelBoundary */ sigCrossMdlRef[*sigIdx] = crossingModel; ++(*sigIdx); } EXIT_POINT: utFree(blockPath); return(errstr); } /* rtwCAPI_GetSigLogRecordInfo */
/** Function: rtwCAPI_GetSigAddrFromMap ======================================== * */ void rtwCAPI_GetSigAddrFromMap(uint8_T isPointer, int_T* sigComplexity, int_T* sigDataType, void** sigDataAddr, int_T* sigIdx, uint_T mapIdx, void** dataAddrMap) { if (isPointer) { /* Dereference pointer and cache the address */ /* Imported Pointers cannot be complex - Assert */ utAssert(sigComplexity[*sigIdx] != 1); UNUSED_PARAMETER(sigComplexity); /* Check for data type and dereference accordingly */ switch (sigDataType[*sigIdx]) { case SS_DOUBLE: sigDataAddr[*sigIdx] = \ (void*) *((real_T **) dataAddrMap[mapIdx]); break; case SS_SINGLE: sigDataAddr[*sigIdx] = \ (void*) *((real32_T **) dataAddrMap[mapIdx]); break; case SS_UINT32: sigDataAddr[*sigIdx] = \ (void*) *((uint32_T **) dataAddrMap[mapIdx]); break; case SS_INT32: sigDataAddr[*sigIdx] = \ (void*) *((int32_T **) dataAddrMap[mapIdx]); break; case SS_UINT16: sigDataAddr[*sigIdx] = \ (void*) *((uint16_T **) dataAddrMap[mapIdx]); break; case SS_INT16: sigDataAddr[*sigIdx] = \ (void*) *((int16_T **) dataAddrMap[mapIdx]); break; case SS_UINT8: sigDataAddr[*sigIdx] = \ (void*) *((uint8_T **) dataAddrMap[mapIdx]); break; case SS_INT8: sigDataAddr[*sigIdx] = \ (void*) *((int8_T **) dataAddrMap[mapIdx]); break; case SS_BOOLEAN: sigDataAddr[*sigIdx] = \ (void*) *((boolean_T **) dataAddrMap[mapIdx]); break; default: sigDataAddr[*sigIdx] = \ (void*) *((real_T **) dataAddrMap[mapIdx]); break; } /* end switch */ } else { /* if Data is not a pointer store the address directly */ sigDataAddr[*sigIdx] = dataAddrMap[mapIdx]; } } /* rtwCAPI_GetSigAddrFromMap */
/** Function: rtwCAPI_GetFullContStateBlockPaths =============================== * */ const char_T* rtwCAPI_GetFullContStateBlockPaths ( const rtwCAPI_ModelMappingInfo* mmi, char_T** blockPathsArray, size_t arrayLen, size_t startIndex, boolean_T crossingModel ) { int_T iCMMI; int_T nCMMI; int_T iState; int_T nStates; const rtwCAPI_States* states; const rtwCAPI_DimensionMap* dimMap; const uint_T* dimArray; const char_T* mmiPath; size_t mmiPathLen; const char_T* errstr = NULL; if (mmi == NULL) goto EXIT_POINT; nCMMI = rtwCAPI_GetChildMMIArrayLen(mmi); for (iCMMI = 0; iCMMI < nCMMI; ++iCMMI) { rtwCAPI_ModelMappingInfo* cMMI = rtwCAPI_GetChildMMI(mmi,iCMMI); size_t cMMIStartIndex; int_T contStartIdx; if (rtwCAPI_GetNumStates(cMMI) < 1) continue; contStartIdx = rtwCAPI_MMIGetContStateStartIndex(cMMI); /* No continuous states */ if(contStartIdx == -1) continue; utAssert(contStartIdx >= 0); cMMIStartIndex = ( startIndex + (size_t)contStartIdx); utAssert(cMMIStartIndex < arrayLen); errstr = rtwCAPI_GetFullContStateBlockPaths(cMMI, blockPathsArray, arrayLen, cMMIStartIndex, true); if (errstr != NULL) goto EXIT_POINT; } nStates = rtwCAPI_GetNumStates(mmi); if (nStates < 1) goto EXIT_POINT; mmiPath = rtwCAPI_GetFullPath(mmi); mmiPathLen = (mmiPath == NULL) ? 0 : strlen(mmiPath); dimMap = rtwCAPI_GetDimensionMap(mmi); dimArray = rtwCAPI_GetDimensionArray(mmi); states = rtwCAPI_GetStates(mmi); for (iState = 0; iState < nStates; ++iState) { int_T nCS; int_T iCS; size_t iStateStartIdx; if ( !rtwCAPI_IsAContinuousState(states,iState) ) continue; nCS = rtwCAPI_GetStateWidth(dimMap, dimArray, states, iState); utAssert(rtwCAPI_GetContStateStartIndex(states,iState) >= 0); iStateStartIdx = startIndex + rtwCAPI_GetContStateStartIndex(states,iState); for (iCS = 0; iCS < nCS; ++iCS) { size_t idx = iStateStartIdx + iCS; utAssert(idx < arrayLen); utAssert(blockPathsArray[idx] == NULL); blockPathsArray[idx] = rtwCAPI_GetFullStateBlockPath(rtwCAPI_GetStateBlockPath(states, iState), mmiPath,mmiPathLen,crossingModel); if (blockPathsArray[idx] == NULL) { errstr = rtwCAPI_mallocError; goto EXIT_POINT; } } } EXIT_POINT: return errstr; } /* rtwCAPI_GetContStateBlockPath */
/** Function: rtwCAPI_GetStateRecordInfo ======================================= * */ const char_T* rtwCAPI_GetStateRecordInfo(const rtwCAPI_ModelMappingInfo* mmi, const char_T** sigBlockName, const char_T** sigLabel, const char_T** sigName, int_T* sigWidth, int_T* sigDataType, int_T* logDataType, int_T* sigComplexity, void** sigDataAddr, boolean_T* sigCrossMdlRef, const char_T** sigPathAlias, real_T* sigSampleTime, int_T* sigIdx, boolean_T crossingModel, real_T* contStateDeriv, boolean_T rtwLogging) { int_T i; int_T nCMMI; int_T nStates; const char_T* mmiPath; size_t mmiPathLen; const rtwCAPI_States* states; const rtwCAPI_DimensionMap* dimMap; const uint_T* dimArray; const rtwCAPI_DataTypeMap* dataTypeMap; void** dataAddrMap; const char_T* errstr = NULL; uint8_T isPointer = 0; if (mmi == NULL) goto EXIT_POINT; nCMMI = rtwCAPI_GetChildMMIArrayLen(mmi); for (i = 0; i < nCMMI; ++i) { rtwCAPI_ModelMappingInfo* cMMI = rtwCAPI_GetChildMMI(mmi,i); real_T* childContStateDeriv = NULL; if (contStateDeriv) { int_T idx = rtwCAPI_MMIGetContStateStartIndex(cMMI); if(idx == -1) continue; childContStateDeriv = &contStateDeriv[idx]; } errstr = rtwCAPI_GetStateRecordInfo(cMMI, sigBlockName, sigLabel, sigName, sigWidth, sigDataType, logDataType, sigComplexity, sigDataAddr, sigCrossMdlRef, sigPathAlias, sigSampleTime, sigIdx, 0x1, /* true, */ childContStateDeriv, rtwLogging); if (errstr != NULL) goto EXIT_POINT; } nStates = rtwCAPI_GetNumStates(mmi); if (nStates < 1) goto EXIT_POINT; mmiPath = rtwCAPI_GetFullPath(mmi); mmiPathLen = (mmiPath==NULL)? 0 : strlen(mmiPath); states = rtwCAPI_GetStates(mmi); dimMap = rtwCAPI_GetDimensionMap(mmi); dimArray = rtwCAPI_GetDimensionArray(mmi); dataTypeMap = rtwCAPI_GetDataTypeMap(mmi); dataAddrMap = rtwCAPI_GetDataAddressMap(mmi); for (i = 0; i < nStates; ++i) { uint_T mapIdx; /* If collecting continuous states, skip non-continuous states */ if (contStateDeriv && !rtwCAPI_IsAContinuousState(states,i)) continue; /* For RTW logging, skip states that cannot be logged to MAT-File. */ if ((rtwLogging) && (rtwCAPI_CanLogStateToMATFile(dataTypeMap, states, i) == false)) continue; /* BlockPath (caller is responsible for free) */ sigBlockName[*sigIdx] = rtwCAPI_GetFullStateBlockPath(rtwCAPI_GetStateBlockPath(states,i), mmiPath, mmiPathLen, crossingModel); if (sigBlockName[*sigIdx] == NULL) { errstr = rtwCAPI_mallocError; goto EXIT_POINT; } /* Label */ if (rtwCAPI_IsAContinuousState(states,i)){ sigLabel[*sigIdx] = "CSTATE"; } else { sigLabel[*sigIdx] = "DSTATE"; } sigName[*sigIdx] = rtwCAPI_GetStateName(states, i); /* Width */ sigWidth[*sigIdx] = rtwCAPI_GetStateWidth(dimMap, dimArray, states, i); /* DataType and logDataType */ mapIdx = rtwCAPI_GetStateDataTypeIdx(states, i); sigDataType[*sigIdx] = rtwCAPI_GetDataTypeSLId(dataTypeMap, mapIdx); /* this mimics code in simulink.dll:DtGetDataTypeLoggingId() */ if (logDataType) { switch (sigDataType[*sigIdx]) { case SS_DOUBLE: case SS_SINGLE: case SS_INT8: case SS_UINT8: case SS_INT16: case SS_UINT16: case SS_INT32: case SS_UINT32: case SS_BOOLEAN: logDataType[*sigIdx] = sigDataType[*sigIdx]; break; case SS_ENUM_TYPE: logDataType[*sigIdx] = SS_INT32; break; default: logDataType[*sigIdx] = SS_DOUBLE; break; } } /* Complexity */ sigComplexity[*sigIdx] = rtwCAPI_GetDataIsComplex(dataTypeMap, mapIdx); /* Data Access - Pointer or Direct*/ isPointer = ((uint8_T)rtwCAPI_GetDataIsPointer(dataTypeMap, mapIdx)); /* Address */ if (contStateDeriv) { int_T csvIdx = rtwCAPI_GetContStateStartIndex(states,i); utAssert(csvIdx >= 0); sigDataAddr[*sigIdx] = &contStateDeriv[csvIdx]; } else { mapIdx = rtwCAPI_GetStateAddrIdx(states,i); rtwCAPI_GetSigAddrFromMap(isPointer, sigComplexity, sigDataType, sigDataAddr, sigIdx, mapIdx, dataAddrMap); } /* CrossingModelBoundary */ sigCrossMdlRef[*sigIdx] = crossingModel; if (sigPathAlias && rtwCAPI_GetStatePathAlias(states,i) != NULL && rtwCAPI_GetStatePathAlias(states,i)[0] != '\0') { sigPathAlias[*sigIdx] = rtwCAPI_GetFullStateBlockPath(rtwCAPI_GetStatePathAlias(states,i), mmiPath, mmiPathLen, crossingModel); } /* Sample Time */ if (sigSampleTime) { const rtwCAPI_SampleTimeMap* tsMap = rtwCAPI_GetSampleTimeMap(mmi); int_T TID; mapIdx = rtwCAPI_GetStateSampleTimeIdx(states, i); TID = rtwCAPI_GetSampleTimeTID(tsMap, mapIdx); if (TID >= 0) { sigSampleTime[2*(*sigIdx)] = *((const real_T*)rtwCAPI_GetSamplePeriodPtr(tsMap,mapIdx)); sigSampleTime[2*(*sigIdx)+1] = *((const real_T*)rtwCAPI_GetSampleOffsetPtr(tsMap,mapIdx)); } else { /* triggered */ utAssert(TID==-1); sigSampleTime[2*(*sigIdx)] = -1.0; sigSampleTime[2*(*sigIdx)+1] = -1.0; } } ++(*sigIdx); } EXIT_POINT: return(errstr); } /* rtwCAPI_GetStateRecordInfo */