%if EXISTS("_ROLLLIB_") == 0
%assign _ROLLLIB_ = 1
%function FcnEmptyTq(tq) void
%return (WHITE_SPACE(tq) || (tq == "Auto"))
%endfunction
%function SLibInitializeRollingModelParameters() void
%foreach paramIdx = Parameters[0]
%assign param = Parameter[paramIdx]
%assign param_array = SLibGetAllASTParamsForBlockParam(param)
%foreach idx = SIZE(param_array, 1)
%assign mdlParamIdx = param_array[idx]
%if mdlParamIdx > -1
%assign mdlParam = ModelParameters.Parameter[mdlParamIdx]
%assign mdlParam.RollVarDeclared = 0
%endif
%endforeach
%endforeach
%endfunction
%function LibDeclareRollVariables(block, sigOffset, numIterations, rolledCount, rollVars) void
%openfile tmpBuffer
%<SLibInitializeRollingModelParameters()>
%foreach varIdx = SIZE(rollVars, 1)
%assign varType = "%"
%if varType[0] == "<"
%assign sysName = SYSNAME(varType)
%assign idNum = [%, %]
%else
%assign idNum = IDNUM(varType)
%endif
%switch idNum[0]
%case "U"
%if NumDataInputPorts == 0
%assign errTxt = "Inputs are not rollable, or do not exist."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%foreach uIdx = NumDataInputPorts
%if LibGetRecordWidth(DataInputPort[uIdx]) > 1 && !LibBlockInputSignalIsExpr(uIdx)
%assign rhs = LibBlockInputSignalAddr(uIdx,"","",sigOffset)
%if rolledCount == 0
%assign dt = LibBlockInputSignalDataTypeName(uIdx,"")
%assign tq = LibBlockInputSignalStorageTypeQualifier(uIdx,sigOffset)
%if !::CompiledModel.RollInputIsWritable && FcnEmptyTq(tq)
%assign tq = "const"
%endif
%if !SLibBlockSrcSignalIsGnd(uIdx,sigOffset)
%<tq> %<dt> *u%<uIdx> = %<rhs>;
%else
%if DataInputPort[uIdx].HaveGround == "yes"
%<tq> %<dt> *u%<uIdx>;
%endif
%endif
%elseif !SLibBlockSrcSignalIsGnd(uIdx,sigOffset)
u%<uIdx> = %<rhs>;
%endif
%endif
%endforeach
%break
%case "u"
%assign uIdx = idNum[1]
%if uIdx < 0 || uIdx >= NumDataInputPorts
%assign errTxt = "Invalid port index: %<uIdx>"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if LibGetRecordWidth(DataInputPort[uIdx]) > 1 && !LibBlockInputSignalIsExpr(uIdx)
%assign rhs = LibBlockInputSignalAddr(uIdx,"","",sigOffset)
%if rolledCount == 0
%assign dt = LibBlockInputSignalDataTypeName(uIdx,"")
%assign sc = LibBlockInputSignalStorageClass(uIdx,sigOffset)
%assign tq = FcnIsRTWClass(sc) ? "" : ...
LibBlockInputSignalStorageTypeQualifier(uIdx,sigOffset)
%if FcnEmptyTq(tq)
%assign tq = "const"
%endif
%if !SLibBlockSrcSignalIsGnd(uIdx,sigOffset)
%<tq> %<dt> *u%<uIdx> = %<rhs>;
%elseif DataInputPort[uIdx].HaveGround == "yes"
%<tq> %<dt> *u%<uIdx>;
%endif
%elseif !SLibBlockSrcSignalIsGnd(uIdx,sigOffset)
u%<uIdx> = %<rhs>;
%endif
%endif
%break
%case "Y"
%if NumDataOutputPorts == 0
%assign errTxt = "Inputs are not rollable, or do not exist."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%foreach yIdx = NumDataOutputPorts
%if LibBlockOutputSignalWidth(yIdx) > 1
%if 1 == block.HasSymbolicDims
%assign rhs = LibBlockOutputSignalAddr(yIdx, ...
::CompiledModel.CurrentSymbolicLoopOffset, "", 0)
%else
%assign rhs = LibBlockOutputSignalAddr(yIdx,"","",sigOffset)
%endif
%if rolledCount == 0
%assign dt = LibBlockOutputSignalDataTypeName(yIdx,"")
%assign sc = LibBlockOutputSignalStorageClass(yIdx)
%assign tq = FcnIsRTWClass(sc) ? "" : ...
LibBlockOutputSignalStorageTypeQualifier(yIdx)
%<tq> %<dt> *y%<yIdx> = %<rhs>;
%else
y%<yIdx> = %<rhs>;
%endif
%endif
%endforeach
%break
%case "y"
%assign yIdx = idNum[1]
%if yIdx < 0 || yIdx >= NumDataOutputPorts
%assign errTxt = "Invalid output port index: %<yIdx>"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if LibBlockOutputSignalWidth(yIdx) > 1
%if 1 == block.HasSymbolicDims
%assign rhs = LibBlockOutputSignalAddr(yIdx, ...
::CompiledModel.CurrentSymbolicLoopOffset, "", 0)
%else
%assign rhs = LibBlockOutputSignalAddr(yIdx, "", "", sigOffset)
%endif
%if rolledCount == 0
%assign dt = LibBlockOutputSignalDataTypeName(yIdx,"")
%assign sc = LibBlockOutputSignalStorageClass(yIdx)
%assign tq = FcnIsRTWClass(sc) ? "" : ...
LibBlockOutputSignalStorageTypeQualifier(yIdx)
%<tq> %<dt> *y%<yIdx> = %<rhs>;
%else
y%<yIdx> = %<rhs>;
%endif
%endif
%break
%case "outportblk"
%assign loc = idNum[0]
%if block.Type != "Outport"
%assign errTxt = "Block type %<Type> does not support roll variable: %<loc>"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if LibBlockInputSignalWidth(0) > 1
%assign yIdx = idNum[1]
%assign rhs = LibBlockDstSignalLocation(loc,"","",sigOffset)
%if rolledCount == 0
%assign dtype = LibBlockInputSignalDataTypeName(0,"")
%<dtype> *y%<yIdx> = &%<rhs>;
%else
y%<yIdx> = &%<rhs>;
%endif
%endif
%break
%case "xd"
%case "Xd"
%if DiscStates[0] == 0
%assign errTxt = "No discrete states to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if DiscStates[0] > 1
%assign rhs = LibBlockDiscreteState("", "", sigOffset)
%if rolledCount == 0
real_T *xd = &%<rhs>;
%else
xd = &%<rhs>;
%endif
%endif
%break
%case "xc"
%case "Xc"
%if ContStates[0] == 0
%assign errTxt = "No continuous states to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ContStates[0] > 1
%assign rhs = LibBlockContinuousState("", "", sigOffset)
%if rolledCount == 0
real_T *xc = &%<rhs>;
%else
xc = &%<rhs>;
%endif
%endif
%break
%case "xdot"
%case "Xdot"
%if ContStates[0] == 0
%assign errTxt = "No continuous state derivatives to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ContStates[0] > 1
%assign rhs = LibBlockContinuousStateDerivative("", "", sigOffset)
%if rolledCount == 0
real_T *xdot = &%<rhs>;
%else
xdot = &%<rhs>;
%endif
%endif
%break
%case "xdis"
%case "Xdis"
%if ContStates[0] == 0
%assign errTxt = "No continuous state disabled to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ContStates[0] > 1
%assign rhs = LibBlockContStateDisabled("", "", sigOffset)
%if rolledCount == 0
boolean_T *xdis = &%<rhs>;
%else
xdis = &%<rhs>;
%endif
%endif
%break
%case "xAbsTol"
%case "XAbsTol"
%if ContStates[0] == 0 || ::CompiledModel.SolverType != "VariableStep"
%assign errTxt = "No continuous state absolute tolerance to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ContStates[0] > 1
%assign rhs = LibBlockContStateAbsoluteTolerance("", "", sigOffset)
%if rolledCount == 0
real_T *xAbsTol = &%<rhs>;
%else
xAbsTol = &%<rhs>;
%endif
%endif
%break
%case "xPerturbMin"
%if ContStates[0] == 0 || ::CompiledModel.SolverType != "VariableStep"
%assign errTxt = "No continuous state perturb min to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ContStates[0] > 1
%assign rhs = LibBlockContStatePerturbMin("", "", sigOffset)
%if rolledCount == 0
real_T *xPerturbMin = &%<rhs>;
%else
xPerturbMin = &%<rhs>;
%endif
%endif
%break
%case "XPerturbMax"
%if ContStates[0] == 0 || ::CompiledModel.SolverType != "VariableStep"
%assign errTxt = "No continuous state perturb max to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ContStates[0] > 1
%assign rhs = LibBlockContStatePerturbMax("", "", sigOffset)
%if rolledCount == 0
real_T *xPerturbMax = &%<rhs>;
%else
xPerturbMax = &%<rhs>;
%endif
%endif
%break
%case "P"
%if Parameters[0] == 0
%assign errTxt = "No parameters to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%foreach paramIdx = Parameters[0]
%assign param = Parameter[paramIdx]
%assign param_array = SLibGetAllASTParamsForBlockParam(param)
%assign name = Parameter[paramIdx].Name
%<SLibDeclareBlockParamRollVars(name, param_array, sigOffset, ...
rolledCount)>
%endforeach
%break
%case "param"
%assign name = idNum[1]
%if EXISTS("%<name>") == 0
%assign errTxt = "Unable to declare roll variable p_%<name>."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%assign param = %<name>
%assign param_array = SLibGetAllASTParamsForBlockParam(param)
%<SLibDeclareBlockParamRollVars(name, param_array, sigOffset, ...
rolledCount)>
%break
%case "RWork"
%if (NumRWorkDefines < 0)
%assign errTxt = "Unable to roll R-work (it must be defined)"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%foreach rwIdx = NumRWorkDefines
%assign rwork = RWorkDefine[rwIdx]
%assign name = RWorkDefine[rwIdx].Name
%if LibGetRecordWidth(rwork) > 1
%assign rhs = LibBlockRWork(rwork, "", "", sigOffset)
%if rolledCount == 0
real_T *rw_%<name> = &%<rhs>;
%else
rw_%<name> = &%<rhs>;
%endif
%endif
%endforeach
%break
%case "rwork"
%assign name = idNum[1]
%assign rwork = %<name>
%if EXISTS("%<name>") == 0
%assign errTxt = "Unable to roll R-work rw_%<name> (it must be defined)."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if LibGetRecordWidth(rwork) > 1
%assign rhs = LibBlockRWork(rwork, "", "", sigOffset)
%if rolledCount == 0
real_T *rw_%<name> = &%<rhs>;
%else
rw_%<name> = &%<rhs>;
%endif
%endif
%break
%case "IWork"
%if (NumIWorkDefines < 0)
%assign errTxt = "Unable to roll I-work (it must be defined)"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%foreach iwIdx = NumIWorkDefines
%assign iwork = IWorkDefine[iwIdx]
%assign name = IWorkDefine[iwIdx].Name
%if LibGetRecordWidth(iwork) > 1
%assign rhs = LibBlockIWork(iwork, "", "", sigOffset)
%if rolledCount == 0
int_T *iw_%<name> = &%<rhs>;
%else
iw_%<name> = &%<rhs>;
%endif
%endif
%endforeach
%break
%case "iwork"
%assign name = idNum[1]
%assign iwork = %<name>
%if EXISTS("%<name>") == 0
%assign errTxt = "Unable to roll I-work iw_%<name> (it must be defined)."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if LibGetRecordWidth(iwork) > 1
%assign rhs = LibBlockIWork(iwork, "", "", sigOffset)
%if rolledCount == 0
int_T *iw_%<name> = &%<rhs>;
%else
iw_%<name> = &%<rhs>;
%endif
%endif
%break
%case "PWork"
%if (NumPWorkDefines < 0)
%assign errTxt = "Unable to roll P-work (it must be defined)"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%foreach pwIdx = NumPWorkDefines
%assign pwork = PWorkDefine[pwIdx]
%assign name = PWorkDefine[pwIdx].Name
%if LibGetRecordWidth(pwork) > 1
%assign rhs = LibBlockPWork(pwork, "", "", sigOffset)
%if rolledCount == 0
void **pw_%<name> = &%<rhs>;
%else
pw_%<name> = &%<rhs>;
%endif
%endif
%endforeach
%break
%case "pwork"
%assign name = idNum[1]
%assign pwork = %<name>
%if EXISTS("%<name>") == 0
%assign errTxt = "Unable to roll P-work pw_%<name> (it must be defined)."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if LibGetRecordWidth(pwork) > 1
%assign rhs = LibBlockPWork(pwork, "", "", sigOffset)
%if rolledCount == 0
void **pw_%<name> = &%<rhs>;
%else
pw_%<name> = &%<rhs>;
%endif
%endif
%break
%case "DWork"
%if NumDWork == 0
%assign errTxt = "Unable to roll D-work (it must be defined)"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%foreach dwIdx = NumDWork
%assign dwork = DWork[dwIdx]
%assign name = dwork.Name
%if LibBlockDWorkWidth(dwork) > 1
%assign rhs = LibBlockDWorkAddr(dwork,"","",sigOffset)
%if rolledCount == 0
%assign dtype = LibBlockDWorkDataTypeName(dwork, "")
%assign sc = LibBlockDWorkStorageClass(dwork)
%assign tq = FcnIsRTWClass(sc) ? "" : ...
LibBlockDWorkStorageTypeQualifier(dwork)
%<tq> %<dtype> *dw_%<name> = %<rhs>;
%else
dw_%<name> = %<rhs>;
%endif
%endif
%endforeach
%break
%case "dwork"
%assign name = idNum[1]
%assign dwork = %<name>
%if EXISTS("%<name>") == 0
%assign errTxt = "Unable to roll D-work dw_%<name> (it must be defined)."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if LibBlockDWorkWidth(dwork) > 1
%assign rhs = LibBlockDWorkAddr(dwork,"","",sigOffset)
%if rolledCount == 0
%assign dtype = LibBlockDWorkDataTypeName(dwork,"")
%assign sc = LibBlockDWorkStorageClass(dwork)
%assign tq = FcnIsRTWClass(sc) ? "" : ...
LibBlockDWorkStorageTypeQualifier(dwork)
%<tq> %<dtype> *dw_%<name> = %<rhs>;
%else
dw_%<name> = %<rhs>;
%endif
%endif
%break
%case "Mode"
%if ModeVector[0] == 0
%assign errTxt = "No modes to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ModeVector[0] > 1
%assign rhs = LibBlockMode("", "", sigOffset)
%if rolledCount == 0
int_T *mode = &%<rhs>;
%else
mode = &%<rhs>;
%endif
%endif
%break
%case "PZCS"
%if ZCEvents[0] == 0
%assign errTxt = "No previous zero-crossings to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ZCEvents[0] > 1
%assign blkZcRecIdx = BlkZcRec.BlkZcRecIdx
%assign numZcSignal = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].NumZcSignalInfos
%foreach zcsIdx = numZcSignal
%assign zcs = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].ZcSignalInfo[zcsIdx]
%if zcs.NeedsEvent == 1
%assign rhs1 = LibBlockPrevZCSignalState( "", "", zcsIdx, sigOffset)
%if rolledCount == 0
uint8_T *pzc%<zcsIdx> = &%<rhs1>;
%else
pzc%<zcsIdx> = &%<rhs1>;
%endif
%endif
%endforeach
%endif
%break
%case "PZC"
%if ZCEvents[0] == 0
%assign errTxt = "No previous zero-crossings to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if ZCEvents[0] > 1
%assign blkZcRecIdx = BlkZcRec.BlkZcRecIdx
%assign numZcSignal = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].NumZcSignalInfos
%foreach zcsIdx = numZcSignal
%assign zcs = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].ZcSignalInfo[zcsIdx]
%if zcs.NeedsEvent == 1
%assign rhs1 = LibBlockPrevZCSignalState( "", "", zcsIdx, sigOffset)
%if rolledCount == 0
uint8_T *pzc = &%<rhs1>;
%else
pzc = &%<rhs1>;
%endif
%break
%endif
%endforeach
%endif
%break
%case "pzc"
%assign zcsIdx = idNum[1]
%assign blkZcRecIdx = BlkZcRec.BlkZcRecIdx
%assign zcs = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].ZcSignalInfo[zcsIdx]
%assign numZcSignal = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].NumZcSignalInfos
%if zcsIdx < 0 || zcsIdx >= numZcSignal
%assign errTxt = "Invalid zcSignal index: %<zcsIdx>"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if zcs.NeedsEvent != 1
%assign errTxt = "No previous zero-crossings to roll."
%<LibBlockReportFatalError(block,errTxt)>
%else
%assign rhs1 = LibBlockPrevZCSignalState("", "", zcsIdx, sigOffset)
%if rolledCount == 0
uint8_T *pzc%<zcsIdx>= &%<rhs1>;
%else
pzc%<zcsIdx> = &%<rhs1>;
%endif
%endif
%break
%case "NSZC"
%if NumNonsampledZCs == 0
%assign errTxt = "No continuous zero-crossings to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if NumNonsampledZCs > 1
%assign blkZcRecIdx = BlkZcRec.BlkZcRecIdx
%assign blkZcRec = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx]
%assign numZcSignal = blkZcRec.NumZcSignalInfos
%foreach zcsIdx = numZcSignal
%assign zcs = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].ZcSignalInfo[zcsIdx]
%if zcs.ZcSignalType != "Discrete"
%assign rhs = LibBlockZCSignalValue("", "", zcsIdx, sigOffset)
%if rolledCount == 0
real_T *zcsv = &%<rhs>;
%else
zcsv = &%<rhs>;
%endif
%break
%endif
%endforeach
%endif
%break
%case "ZCSV"
%if NumNonsampledZCs == 0
%assign errTxt = "No continuous zero-crossings to roll."
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if NumNonsampledZCs > 1
%assign blkZcRecIdx = BlkZcRec.BlkZcRecIdx
%assign blkZcRec = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx]
%assign numZcSignal = blkZcRec.NumZcSignalInfos
%foreach zcsIdx = numZcSignal
%assign zcs = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].ZcSignalInfo[zcsIdx]
%if zcs.ZcSignalType != "Discrete"
%assign rhs = LibBlockZCSignalValue("", "", zcsIdx, sigOffset)
%if rolledCount == 0
real_T *zcsv%<zcsIdx> = &%<rhs>;
%else
zcsv%<zcsIdx> = &%<rhs>;
%endif
%endif
%endforeach
%endif
%break
%case "zcsv"
%assign zcsIdx = idNum[1]
%assign blkZcRecIdx = BlkZcRec.BlkZcRecIdx
%assign blkZcRec = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx]
%assign zcs = ::CompiledModel.ZcRec.BlkZcRec[blkZcRecIdx].ZcSignalInfo[zcsIdx]
%assign numZcSignal = blkZcRec.NumZcSignalInfos
%if zcsIdx < 0 || zcsIdx >= numZcSignal
%assign errTxt = "Invalid zcSignal index: %<zcsIdx>"
%<LibBlockReportFatalError(block,errTxt)>
%endif
%if zcs.ZcSignalType == "Discrete"
%assign errTxt = "No continuous zero-crossings to roll."
%<LibBlockReportFatalError(block,errTxt)>
%else
%assign rhs = LibBlockZCSignalValue("", "", zcsIdx, sigOffset)
%if rolledCount == 0
real_T *zcsv%<zcsIdx> = &%<rhs>;
%else
zcsv%<zcsIdx> = &%<rhs>;
%endif
%endif
%break
%default
%assign errTxt = "Unknown roll variable specified: %"
%<LibBlockReportFatalError(block,errTxt)>
%endswitch
%endforeach
%closefile tmpBuffer
%return tmpBuffer
%endfunction
%function LibGetRollRegions1(rollRegions) void
%assign rrSz = SIZE(rollRegions,1)
%if rrSz < 3
%if rrSz <= 1
%assign rollRegions1 = []
%else
%assign rollRegions1 = [1]
%endif
%return rollRegions1
%endif
%assign inpStr = "%<rollRegions>"
%assign strLen = SIZE(inpStr, 1)
%assign vect3 = FcnGetNextRollRegion(inpStr, 0, strLen)
%assign outStr = "[1"
%assign offset = vect3[2]
%if vect3[1] > 1
%assign outStr = outStr + ":%"
%elseif vect3[1] == 0
%assign vect3 = FcnGetNextRollRegion(inpStr, vect3[2], strLen)
%assign offset = vect3[2]
%if vect3[1] > 1
%assign outStr = outStr + ":%"
%endif
%endif
%foreach idx = strLen-offset
%assign outStr = outStr + inpStr[idx+offset]
%endforeach
%assign rollRegions1 = %<outStr>
%return rollRegions1
%endfunction
%function LibGetIndexedElement(name, width, lcv, idx) void
%assign answer = name
%if lcv == ""
%assign answer = answer + "[%<idx>]"
%else
%if CurrentLoopOffset == 0
%assign lhsIdx = lcv
%else
%assign lhsIdx = lcv + "+ %<CurrentLoopOffset>"
%endif
%assign answer = answer + "[%<lhsIdx>]"
%endif
%return answer
%endfunction
%function FcnGetNextRollRegion(inpStr, startIdx, strLen) void
%assign idx0 = -1
%assign startRoll = ""
%foreach idx = strLen-startIdx
%assign ch = inpStr[idx+startIdx]
%if ch != "[" && ch != "," && ch != " "
%assign idx0 = idx+startIdx+1
%assign startRoll = "%"
%break
%endif
%endforeach
%if idx0 == -1
%assign errTxt = "Invalid input argument: %<inpStr>"
%<LibBlockReportFatalError([], errTxt)>
%endif
%assign idx1 = -1
%assign outStr = ""
%foreach idx = strLen-idx0
%assign ch = inpStr[idx+idx0]
%if ch == ":"
%assign idx1 = idx+idx0+1
%break
%endif
%if ch == "]" || ch == ","
%assign outStr = "[%<startRoll>, %<startRoll>, %]"
%break
%endif
%assign startRoll = startRoll + ch
%endforeach
%if outStr != ""
%assign outVec = %<outStr>
%return outVec
%endif
%if idx1 == -1
%assign errTxt = "Invalid input argument: %<inpStr>"
%<LibBlockReportFatalError([], errTxt)>
%endif
%assign idx2 = -1
%assign endRoll = "%"
%foreach idx = strLen-idx1-1
%assign ch = inpStr[idx+idx1+1]
%if ch == "," || ch == "]"
%assign idx2 = idx+idx1+1
%break
%endif
%assign endRoll = endRoll + ch
%endforeach
%if idx2 == -1
%assign errTxt = "Invalid input argument: %<inpStr>"
%<LibBlockReportFatalError([], errTxt)>
%endif
%assign outStr = "[%<startRoll>, %<endRoll>, %<idx2>]"
%assign outVec = %<outStr>
%return outVec
%endfunction
/% Examples
idx OldRoll NewRoll
0 [0, 1, 2:4] [1, 2:4]
1 [0, 1, 2:4] [0, 2:4]
2 [0, 1, 2:4] [0, 1, 3:4]
3 [0, 1, 2:4] [0, 1, 2, 4]
4 [0, 1, 2:4] [0, 1, 2:3]
5 [0, 1, 2:4] [0, 1, 2:4]
idx OldRoll NewRoll
0 [2:7, 9] [2:7, 9]
1 [2:7, 9] [2:7, 9]
2 [2:7, 9] [3:7, 9]
3 [2:7, 9] [2, 4:7, 9]
4 [2:7, 9] [2:3, 5:7, 9]
5 [2:7, 9] [2:4, 6:7, 9]
6 [2:7, 9] [2:5, 7, 9]
7 [2:7, 9] [2:6, 9]
8 [2:7, 9] [2:7, 9]
9 [2:7, 9] [2:7]
[2:7]
%/
%function LibRemoveRollRegions(rollRegions,idx) void
%assign rollRegionsStr = "%<rollRegions>"
%assign newRollRegionsStr = "["
%assign curNumberStr = ""
%assign isMiddleRange = 0
%assign isBeginRoll = 1
%assign numChar = SIZE(rollRegionsStr,1)
%foreach i = numChar
%assign curChar = rollRegionsStr[i]
%if ( ( curChar == "0" ) || ( curChar == "1" ) || ...
( curChar == "2" ) || ( curChar == "3" ) || ...
( curChar == "4" ) || ( curChar == "5" ) || ...
( curChar == "6" ) || ( curChar == "7" ) || ...
( curChar == "8" ) || ( curChar == "9" ) )
%assign curNumberStr = curNumberStr + curChar
%elseif ( curChar == ":" )
%assign prevNumber = %<curNumberStr>
%assign curNumberStr = ""
%assign isMiddleRange = 1
%else
%if curNumberStr != ""
%assign curNumber = %<curNumberStr>
%if isBeginRoll
%assign beforeStr = ""
%else
%assign beforeStr = ", "
%endif
%if isMiddleRange
%if ( idx < prevNumber) || ( curNumber < idx )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(prevNumber) + ":" + STRING(curNumber)
%elseif ( prevNumber == idx ) && ( idx == (curNumber-1) )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr + STRING(idx+1)
%elseif ( prevNumber == idx )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(idx+1) + ":" + STRING(curNumber)
%elseif ( (prevNumber+1) == idx ) && ( idx == curNumber )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr + STRING(idx-1)
%elseif ((prevNumber+1) == idx ) && ( idx == (curNumber-1))
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(idx-1) + ", " ...
+ STRING(idx+1)
%elseif ( (prevNumber+1) == idx )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(idx-1) + ", " ...
+ STRING(idx+1) + ":" + STRING(curNumber)
%elseif ( idx == curNumber )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(prevNumber) + ":" + STRING(idx-1)
%elseif ( idx == (curNumber-1) )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(prevNumber) + ":" + STRING(idx-1) ...
+ ", " ...
+ STRING(idx+1)
%else
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(prevNumber) + ":" + STRING(idx-1) ...
+ ", " ...
+ STRING(idx+1) + ":" + STRING(curNumber)
%endif
%assign isBeginRoll = 0
%else
%if ( curNumber != idx )
%assign newRollRegionsStr = newRollRegionsStr ...
+ beforeStr ...
+ STRING(curNumber)
%assign isBeginRoll = 0
%endif
%endif
%assign curNumberStr = ""
%assign isMiddleRange = 0
%endif
%endif
%endforeach
%assign newRollRegionsStr = newRollRegionsStr + "]"
%assign newRollRegions = %<newRollRegionsStr>
%return newRollRegions
%endfunction
%function LibRollRegions2StartEndMatrix(rollRegions) void
%assign str1 = "[eval(strrep('%<rollRegions>',':','*1+0*'));"+...
"eval(strrep('%<rollRegions>',':','*0+1*'))]"
%assign rangePoints = FEVAL("eval",str1)
%return rangePoints
%endfunction
%function LibInRollRegion(rollRegions,idx) void
%assign startEndMatrix = LibRollRegions2StartEndMatrix(rollRegions)
%assign iMax = SIZE(startEndMatrix,1)
%foreach i = iMax
%if (idx >= startEndMatrix[0][i]) && (idx <= startEndMatrix[1][i])
%return 1
%endif
%endforeach
%return 0
%endfunction
%function LibInVector(vector,idx) void
%assign iMax = SIZE(vector,1)
%foreach i = iMax
%if (idx == vector[i])
%return 1
%endif
%endforeach
%return 0
%endfunction
%function LibIntersectRollRegions(rollRegions1,rollRegions2) void
%assign sizeRR1 = SIZE(rollRegions1,1)
%assign sizeRR2 = SIZE(rollRegions2,1)
%if sizeRR1 != sizeRR2
%assign errTxt = "Rollregions must be same size for intersection."
%<LibBlockReportFatalError([], errTxt)>
%endif
%foreach i = sizeRR1
%assign scalar1 = rollRegions1[i]
%assign scalar2 = rollRegions2[i]
%if scalar1 != scalar2
%assign errTxt = "Rollregions must hold same scalars for intersection."
%<LibBlockReportFatalError([], errTxt)>
%endif
%if i > 0
%if scalar1 <= scalarLast
%assign errTxt = "Rollregions must be increasing for intersection."
%<LibBlockReportFatalError([], errTxt)>
%endif
%endif
%assign scalarLast = scalar1
%endforeach
%if sizeRR1 == 1
%assign intersectRollRegions = [%<scalar1>]
%else
%assign rangePoints1 = LibRollRegions2StartEndMatrix(rollRegions1)
%assign rangePoints1end = rangePoints1[1]
%assign rangePoints2 = LibRollRegions2StartEndMatrix(rollRegions2)
%assign rangePoints2end = rangePoints2[1]
%assign intersectRollRegions = "["
%assign leftIdx = ""
%foreach i = sizeRR1
%assign rightIdx = rollRegions1[i]
%if "%<leftIdx>" == ""
%assign leftIdx = rightIdx
%endif
%if LibInVector(rangePoints1end,rightIdx) || ...
LibInVector(rangePoints2end,rightIdx)
%if leftIdx == rightIdx
%if i == (sizeRR1-1)
%assign newRange = "%<leftIdx>]"
%else
%assign newRange = "%<leftIdx>,"
%endif
%else
%if i == (sizeRR1-1)
%assign newRange = "%<leftIdx>:%<rightIdx>]"
%else
%assign newRange = "%<leftIdx>:%<rightIdx>,"
%endif
%endif
%assign intersectRollRegions = intersectRollRegions + newRange
%assign leftIdx = ""
%endif
%endforeach
%assign intersectRollRegions = %<intersectRollRegions>
%endif
%return intersectRollRegions
%endfunction
%function SLibDeclareBlockParamRollVars(pName, param_array, sigOffset, ...
rolledCount) void
%openfile tmpBuf
%foreach idx = SIZE(param_array, 1)
%assign mdlParamIdx = param_array[idx]
%if mdlParamIdx > -1
%assign mdlParam = ModelParameters.Parameter[mdlParamIdx]
%if mdlParam.RollVarDeclared == 0
%assign prmSize = SLibGetSizeOfValueFromParamRec(mdlParam)
%if prmSize[1] > 1
%assign rhs = LibModelParameterAddr(mdlParam, "", "", sigOffset)
%if mdlParam.Tunable == "yes"
%assign varName = "p_%<LibGetRecordIdentifier(mdlParam)>"
%assign mdlParam.RollVarDeclared = 1
%else
%assign varName = "p_%<pName>"
%endif
%if rolledCount == 0
%assign sc = SLibGetModelParameterStorageClass(mdlParam)
%assign dt = LibModelParameterDataTypeName(mdlParam)
%assign tq = FcnIsRTWClass(sc) ? "" : ...
SLibGetModelParameterTypeQualifier(mdlParam)
%if FcnEmptyTq(tq)
%assign tq = "const"
%endif
%<tq> %<dt> *%<varName> = %<rhs>;
%else
%<varName> = %<rhs>;
%endif
%endif
%endif
%endif
%endforeach
%closefile tmpBuf
%return tmpBuf
%endfunction
%function FcnIsRTWClass(storageClass) void
%if storageClass == "Auto"
%return 1
%else
%return 0
%endif
%endfunction
%function SLibRollInputIsWritable(isWritable) void
%assign ::CompiledModel.RollInputIsWritable = isWritable
%endfunction
%endif