%%
%%Copyright1994-2019TheMathWorks,Inc.
%%
 
%if EXISTS("_CUSTOMSTORAGELIB_") == 0
%assign _CUSTOMSTORAGELIB_ = 1
 
%%Forinternaltesting
%if EXISTS("CustomStorageIncludeFile")
  %include "%<CustomStorageIncludeFile>"
%endif
 
%%==================================%%
%%Customstoragesupportfunctions%%
%%==================================%%
 
%%Function:LibHasCustomStorage================================================
%%Abstract:
%%Return1ifthedatarecordhasacustomstorageclass,otherwise0.
%%TopTester:test/toolbox/simulink/variants/tCompositePorts.m
%%
%function LibHasCustomStorage(record) void
  %if record.StorageClass == "Custom"
    %if LibGetCustomStorageClassName(record) == ""
      %assign errTxt = "The custom storage class property is not " + ...
      "defined for data with identifier '%<LibGetRecordIdentifier(record)>'"
      %<LibReportFatalError(errTxt)>
    %endif
    %return 1
  %elseif SLibIsLegacyStorageClassForDataRecord(record)
    %return 1
  %endif
  %return 0
%endfunction
 
%%Function:LibCustomDataIsComplex============================================
%%Abstract:
%%Returnwhetherthecustomdataiscomplex.
%%TopTester:test/toolbox/simulink/variants/codevariants/tcodevariants9.m
%%
%function LibCustomDataIsComplex(record)
  %switch record.RecordType
    %case "ZcSignalInfo"
    %case "BlockOutput"
    %case "ExternalInput"
    %case "ExternalOutput"
    %case "ModelParameter"
      %return LibGetRecordIsComplex(record)
      %%break
     
    %case "DWork"
      %return SLibDWorkIsComplex(record)
      %%break
     
    %case "MachineData"
      %assign errTxt = "Custom storage classes are not supported for Stateflow machine data"
      %<LibReportFatalError(errTxt)>
       
    %default
      %assign errTxt = "Unknown record type: %<record.RecordType>"
      %<LibReportFatalError(errTxt)>
  %endswitch
%endfunction
 
%%TopTester:test/toolbox/simulink/variants/codevariants/tcodevariants9.m
%%
%function LibTrackFcnScope(record, type)
  %if !ISFIELD(record, "isFcnScoped")
    %return TLC_FALSE
  %endif
    
  %assign activeFcn = FcnGetActiveFcnForDecl()
  %if activeFcn == "GlobalMap"
    %return TLC_FALSE
  %endif
 
  %% Maybe we should also include initialize? Thought can't really initialize
  %% function scope data in the same way.
  %if (type == "contents") || (type == "address")
    %assign declareInFcnScope = "DeclareIn%<activeFcn>FcnScope"
    %assign record.%<declareInFcnScope> = 1
    %<ReAssignLocalBlockOutputTID(record)>
    %return TLC_FALSE
  %endif
   
  %return TLC_TRUE
%endfunction
%%Function:LibAccessCustomData================================================
%%Abstract:
%%Callthe"DataAccess"methodforthedatarecord'scustomstorage
%%class,usingthespecifiedaccesstype.Accesstypesmaybe
%%predefined(e.g."contents","declare")oruser-defined.
%%TopTester:test/toolbox/simulink/variants/CondExecutedVSS/tContPortFcnCall2.m
%%
%function LibAccessCustomData(record,type,idx,reim,extra) void
  %assign cscDefn = SLibGetCSCDefForData(record)
 
  %% Call "Data Access" method without evaluating need for a cast
  %assign retVal = SLibAccessCustomDataNoMacroCasts(record,type,idx,reim,extra)
 
  %% Track function scope variables so we know to declare them
  %<LibTrackFcnScope(record, type)>
 
  %% Check if cast is needed
  %if type == "contents"
    %assign dtId = SLibGetRecordDataTypeId(record)
    %assign needCast = ((SLibGetDataInitForData(cscDefn, record) == "Macro") && ...
      ((SLibGetDataScope(cscDefn, record) == "Imported") || ...
       ( SLibIsIntegerDataTypeNotSizeofTargetInt(dtId))))
 
    %% Cast MACRO's to correct datatype
    %if needCast
      %assign dtypeName = LibGetRecordCompositeDataTypeName(record)
      %assign retVal = "((%<dtypeName>)%<retVal>)"
    %endif
 
  %endif
 
  %return retVal
%endfunction
 
%%Function:LibIsAccessingCustomDataForSILPIL
%%Abstract:
%%ReturnstrueiftheDataAccessfunctionassociatedwithsignal,
%%parameter,orcustomstorageclassrecord'record'isbeingcalledto
%%requestinformationneededtobuildtheinterfaceforSILorPIL.
%function LibIsAccessingCustomDataForSILPIL(record) void
    %return ISFIELD(record, "DataAccessForSILPIL") && ...
        record.DataAccessForSILPIL == TLC_TRUE
%endfunction
 
%%Function:SLibCustomDataNoMacroCasts
%%Abstract:
%%Callthe"DataAccess"methodforthedatarecord'scustomstorage
%%class,usingthespecifiedaccesstype.Accesstypesmaybe
%%predefined(e.g."contents","declare")oruser-defined.
%%TopTester:test/toolbox/simulink/variants/codevariants/tvss_code_variants.m
%%
%function SLibAccessCustomDataNoMacroCasts(record,type,idx,reim,extra) void
  %assign genType = SLibGetGenerateTypeForData(record)
  %assign dTypeId = LibGetRecordDataTypeId(record)
  %assign isComplex = LibCustomDataIsComplex(record)
  %assign isMultiWord = LibIsDataTypeMultiWordFixpt(dTypeId)
 
   
  %% we cannot tell whether a bus field is complex or not from
  %% the bus signal record. always add reim part if it is a bus.
  %if isComplex || LibDataTypeIsBus(dTypeId)
    %% If the record is complex, prepend with a dot if necessary
    %switch reim
      %case tRealPart
      %case tImagPart
    %assign dot_reim = ".%<reim>"
    %break
      %default
    %assign dot_reim = reim
    %break
    %endswitch
    %% If it is not complex, slam it to null
  %else
    %assign dot_reim = ""
  %endif
 
  %if record.CustomStorageClassVersion > 1 || ...
    ISFIELD(record, "InstanceSpecificVersion")
    %if isMultiWord && type == "set" && LibIsMultiWordValue(extra)
      %%Mutliword case: set value
      %assign dTypeName = LibGetDataTypeNameFromId(dTypeId)
      %assign tmpVar = "temp"
      %assign retVal = ""
      %openfile retVal
      {
        %<dTypeName> %<tmpVar> = %<extra>;
        %<GENERATE_TYPE(record,"DataAccess",genType,type,idx,dot_reim,tmpVar)>
      }
      %closefile retVal
      %%
    %elseif isMultiWord && type == "initialize"
      %%Mutliword case: initialize
      %assign grndName = SLibGetDtGroundName(dTypeId, isComplex, reim)
      %assign retVal = GENERATE_TYPE(record,"DataAccess",genType,"set",idx,dot_reim,grndName)
      %%
    %else
      %%Multiword else + single word
      %assign retVal = GENERATE_TYPE(record,"DataAccess",genType,type,idx,dot_reim,extra)
    %endif
  %else
    %if !ISEMPTY(extra)
      %assign errTxt = "Can not call custom storage class version 1 with " + ...
    "LibAccessCustomData unless the fifth argument is empty"
      %<LibReportFatalError(errTxt)>
    %endif
    %if isMultiWord && type == "initialize"
      %%Multiword case: initialize
      %assign grndName = SLibGetDtGroundName(dTypeId, isComplex, reim)
      %assign retVal = ""
      %openfile retVal
      %<GENERATE_TYPE(record,"DataAccess",genType,"contents",idx,dot_reim)> = %<grndName>;
      %closefile retVal
    %else
      %assign retVal = GENERATE_TYPE(record,"DataAccess",genType,type,idx,dot_reim)
    %endif
  %endif
 
  %if type == "define" || type == "declare"
    %if !ISEMPTY(retVal) && TYPE(retVal) != "String"
      %assert (TYPE(retVal) == "Scope")
      %if ISFIELD(retVal, "CustomDeclare")
        %assign fieldName = "CustomDeclare"
      %elseif ISFIELD(retVal, "CustomDefine")
        %assign fieldName = "CustomDefine"
      %else
        %assign errTxt = "When Custom TLC file returns non-empty data declaration/definition, " + ...
        "the content must be put into a record field CustomDeclare/CustomDefine respectively"
        %<LibReportFatalError(errTxt)>
      %endif
 
      %assign contents = retVal.%<fieldName>
      %if !ISEMPTY(contents)
        %assign retVal.%<fieldName> = contents
      %endif
    %endif
  %endif
 
  %return retVal
%endfunction
 
%%Function:LibCustomDataIsAddressable=====================================
%%Abstract:
%%Isdataaddressable?
%%
%function LibCustomDataIsAddressable(record) void
  %assign dataLayout = LibCustomData(record, "layout", "", "")
  %return dataLayout[0] != "other"
%endfunction
 
%%Function:LibCustomData================================================
%%Abstract:
%%OlderversionofLibAccessCustomData
%%
%function LibCustomData(record,type,idx,reim) void
 
  %switch type
 
   %case "qualifier"
     %assign msDefn = SLibGetMemorySectionDefForData(record)
     %return SLibGetQualifier(msDefn)
     %%break
 
   %default
     %return LibAccessCustomData(record,type,idx,reim,"")
     %%break
      
  %endswitch
%endfunction
 
%%Function:LibCustomClass=====================================================
%%Abstract:
%%Callthe"ClassAccess"methodforthedatarecord'scustomstorage
%%class,usingthespecifiedaccesstype.Accesstypesmaybe
%%predefined(e.g."setup","comment")oruser-defined.
%%
%function LibCustomClass(record,type) void
  %assign genType = SLibGetGenerateTypeForCSC(record)
 
  %return GENERATE_TYPE(record, "ClassAccess", genType, type)
%endfunction
 
%%=========================%%
%%Recordaccessfunctions%%
%%=========================%%
 
 
%%Function:LibGetDataRecord===================================================
%%Abstract:
%%Returntherecordcorrespondingtotheidx'thentryinthe
%%segmentoftheglobalmemorymapcorrespondingtothespecified
%%customstorageclass
%%
%function LibGetDataRecord(class, idx) void
  %return class.Data[idx].RTWRecord
%endfunction
 
%%Function:LibGetRecordIdentifier=============================================
%%Abstract:
%%Returntheidentifierassociatedwithagivendatarecord
%%
%function LibGetRecordIdentifier(record) void
  %if ISFIELD(record, "VarGroupIdx")
    %return SLibVarGroupElementName(record.VarGroupIdx[0], record.VarGroupIdx[1])
  %else
    %return record.Identifier
  %endif
%endfunction
 
%%Function:LibSetRecordIdentifier=============================================
%%Abstract:
%%Modifiestheidentifierassociatedwithagivendatarecord
%%
%function LibSetRecordIdentifier(record, newIdentifier) void
  %if ISFIELD(record, "VarGroupIdx")
    %<SLibVarGroupSetElementName(...
      record.VarGroupIdx[0], record.VarGroupIdx[1], newIdentifier)>
  %endif
  %if ISFIELD(record, "Identifier")
    %assign record.Identifier = newIdentifier
  %endif
%endfunction
 
%%Function:LibGetRecordVarName================================================
%%Abstract:
%%Returnthevariablenameforthedatarecord
%%(maybedifferenttotheidentifierduetoaliasnames)
%%
%function LibGetRecordVarName(record) void
  %if ISEMPTY(record.OrigIdentifier)
    %return LibGetRecordIdentifier(record)
  %else
    %return record.OrigIdentifier
  %endif
%endfunction
 
%%Function:LibGetCustomStorageClassName=======================================
%%Abstract:
%%Returnthenameofthecustomstorageclassassociatedwithadata
%%record
%%
%function LibGetCustomStorageClassName(record) void
  %assign rtwInfo = LibGetRTWInfoObjectProperties(record)
  %return rtwInfo.CustomStorageClass
%endfunction
 
%%Function:SLibGetRTWInfoObject============================================
%%Abstract:
%%ReturnRTWInfoobjectfordatarecord
%%TopTester:test/toolbox/simulink/variants/CondExecutedVSS/tContPortFcnCall3.m
%%
%function SLibGetRTWInfoObject(record) void
  %% XXX (kramkuma) Function needs clean up
  %if ISFIELD (record, "Object")
    %assign parentProps = record.Object.ObjectProperties
     
    %if ISFIELD(parentProps, "RTWInfo")
      %return parentProps.RTWInfo.Object
    %else
      %return parentProps.CoderInfo.Object
    %endif
  %elseif (ISFIELD (record, "VarGroupIdx"))
    %assign coderGroupId = SLibGetCoderGroupIdForDataRecord(record)
    %if coderGroupId >= 0
      %assign coderGroup = ::CompiledModel.CoderDataGroup[coderGroupId]
      %return coderGroup.Object
    %else
      %return []
    %endif
  %elseif (ISFIELD (record, "RTWRecord"))
    %assign coderGroupId = SLibGetCoderGroupIdForDataRecord(record.RTWRecord)
    %if coderGroupId >= 0
      %assign coderGroup = ::CompiledModel.CoderDataGroup[coderGroupId]
      %return coderGroup.Object
    %else
      %return []
    %endif
  %else
    %return []
  %endif
%endfunction
 
%%Function:LibGetRTWInfoObjectProperties======================================
%%Abstract:
%%ReturntheRTWInfopropertiesassociatedwithadatarecord
%%correspondingtoaSimulinkdataobject
%%
%function LibGetRTWInfoObjectProperties(record) void
  %assign rtwInfoObj = SLibGetRTWInfoObject(record)
  %return rtwInfoObj.ObjectProperties
%endfunction
 
%%Function:LibGetRTWInfoObjectPackage=========================================
%%Abstract:
%%ReturntheRTWInfopackageassociatedwithadatarecord
%%correspondingtoaSimulinkdataobject
%%
%function LibGetRTWInfoObjectPackage(record) void
  %% Get package name from property "CSCPackageName" if it exists
  %assign rtwInfo = LibGetRTWInfoObjectProperties(record)
  %if ISFIELD(rtwInfo, "CSCPackageName")
    %return rtwInfo.CSCPackageName
  %else
    %% Otherwise, get package name of the RTWInfo object
    %assign rtwInfoObj = SLibGetRTWInfoObject(record)
    %return rtwInfoObj.Package
  %endif
%endfunction
 
%%Function:LibGetRTWInfoObjectClass===========================================
%%Abstract:
%%ReturntheRTWInfoclassassociatedwithadatarecord
%%correspondingtoaSimulinkdataobject
%%
%function LibGetRTWInfoObjectClass(record) void
  %assign rtwInfoObj = SLibGetRTWInfoObject(record)
  %return rtwInfoObj.Class
%endfunction
 
%%Function:LibGetCustomStorageAttributes======================================
%%Abstract:
%%Returnthestorageclassattributesassociatedwithadatarecord
%%correspondingtoaSimulink.CustomParameterorSimulink.CustomSignal
%%
%function LibGetCustomStorageAttributes(record) void
  %assign rtwInfo = LibGetRTWInfoObjectProperties(record)
  %return rtwInfo.CustomAttributes.Object.ObjectProperties
%endfunction
 
 
%%=============================================================================
%function LibGetInstanceSpecificProp(cscDefn, customAttrProps, propname) void
%%Abstract:
%%Returntheinstance-specificpropertyvalue(fromCustomAttributes)if
%%itexists.Otherwise,returnthedefaultvalue(fromtheCSCdefinition)
%%
  %assert !ISEMPTY(cscDefn)
 
  %% Get the default value
  %if ISFIELD(cscDefn, propname)
    %assign propVal = cscDefn.%<propname>
  %elseif ISFIELD(cscDefn.CSCTypeAttributes, propname)
    %assign propVal = cscDefn.CSCTypeAttributes.%<propname>
  %else
    %assign errTxt = "Instance specific property '%<propname>' does not " + ...
                     "have a default counterpart in custom storage class " + ...
                     "definition '%<cscDefn.Name>'"
    %<LibReportFatalError(errTxt)>
  %endif
 
  %% Override with the instance-specific value
  %if LibIsPropInstanceSpecific(cscDefn, customAttrProps, propname)
    %assign propVal = customAttrProps.%<propname>
  %endif
 
  %return propVal
%endfunction
 
 
%%=============================================================================
%function LibIsPropInstanceSpecific(cscDefn, customAttrProps, propname) void
%%Abstract:
%%ReturntrueifthenamedCSCpropertyisinstance-specific
%%
  %assert !ISEMPTY(cscDefn)
 
  %if ISFIELD(customAttrProps, propname)
    %return TLC_TRUE
  %else
    %return TLC_FALSE
  %endif
%endfunction
 
 
%%=============================================================================
%function SLibGetDescriptionForData(record) void
  %assign desc = ""
  %if (record.HasObject == 1) && (ConfigSet.SimulinkDataObjDesc == 1)
    %assign desc = record.Object.ObjectProperties.Description
    %if !ISEMPTY(desc)
      %assign desc = FEVAL("strrep", desc, "/*", "/+")
      %assign desc = FEVAL("strrep", desc, "*/", "+/")
    %endif
  %endif
 
  %return desc
%endfunction
 
 
%%=============================================================================
%function SLibGetCSCDefForName(rtwInfoPkg, cscName) void
  %assign cscDefn = []
 
  %assign pkgRec = GETFIELD(::CompiledModel.CustomStorageClasses.CSCReg, rtwInfoPkg)
  %assign cscDefn = GETFIELD(pkgRec.CSCDefs, cscName)
  %return cscDefn
%endfunction
 
 
%%=============================================================================
%%Abstract:
%%Returnthememorysectiondefinition,givenapackageandmemorysectionname.
%%
%function SLibGetMemorySectionDefForName(rtwInfoPkg, msName) void
  %assign msDefn = []
  %if ISFIELD(::CompiledModel.CustomStorageClasses.CSCReg, rtwInfoPkg)
    %assign prec = GETFIELD(::CompiledModel.CustomStorageClasses.CSCReg, rtwInfoPkg)
 
    %if !ISEMPTY(prec.MemorySectionDefs) && ISFIELD(prec.MemorySectionDefs, msName)
      %assign msDefn = GETFIELD(prec.MemorySectionDefs, msName)
    %endif
  %endif
   
  %if ISEMPTY(msDefn)
    %assign errMsg = ...
      "Could not find memory section '%<msName>' in package '%<rtwInfoPkg>'./n" + ...
      "Select a valid memory section on the 'Memory Sections' tab " + ...
      "in the Configuration Parameters dialog."
    %<LibReportError(errMsg)>
  %endif
   
  %return msDefn
%endfunction
 
%%=============================================================================
%%Abstract:
%%ReturntheCSCDefinitionassociatedwiththerecord.TheCSCdefinition
%%isafunctionoftheCSCNameandPackageNameoftherecord.
%%ThedefinitionisaddedtotherecordatTLCsetupstage.See
%%FcnAddCustomDatainglobalmaplib.tlc
%function SLibGetCSCDefForData(record) void
  %% Taking a data record as argument
 
  %return record.CSCDefn
%endfunction
 
 
%%=============================================================================
%%Abstract:
%%ReturntheMemorySectionDefinitionassociatedwiththerecord.The
%%memorysectionisafunctionofthememorysectionname(instancespecific)
%%andPackageNameoftherecord.
%%ThedefinitionisaddedtotherecordatTLCsetupstage.See
%%FcnAddCustomDatainglobalmaplib.tlc
%function SLibGetMemorySectionDefForData(record) void
  %% Taking a data record as argument
 
  %return record.MSDefn
%endfunction
 
 
%%=============================================================================
%%NOTE:DataInitcouldbeinstancespecific
%%
%function SLibGetDataInitForData(cscDefn, datarec) void
  %assign customAttrProps = LibGetCustomStorageAttributes(datarec)
  %assign dataInit = LibGetInstanceSpecificProp(cscDefn, customAttrProps, "DataInit")
  %assert !ISEMPTY(dataInit)
 
  %return dataInit
%endfunction
 
 
%%=============================================================================
%%NOTE:DataAccesscouldbeinstancespecific
%%
%function SLibGetDataAccess(cscDefn, datarec) void
  %assign customAttrProps = LibGetCustomStorageAttributes(datarec)
  %assign dataAccess = LibGetInstanceSpecificProp(cscDefn, customAttrProps, "DataAccess")
  %assert !ISEMPTY(dataAccess)
 
  %return dataAccess
%endfunction
 
%%=============================================================================
%%NOTE:DataScopecouldbeinstancespecific
%%
%function SLibGetDataScope(cscDefn, datarec) void
  %assign customAttrProps = LibGetCustomStorageAttributes(datarec)
  %assign dataScope = LibGetInstanceSpecificProp(cscDefn, customAttrProps, "DataScope")
  %assert !ISEMPTY(dataScope)
 
  %return dataScope
%endfunction
 
%%=============================================================================
%%NOTE:HeaderFilecouldbeinstancespecific
%%
%function SLibGetHeaderFile(cscDefn, datarec) void
  %assign customAttrProps = LibGetCustomStorageAttributes(datarec)
  %assign hdr = LibGetInstanceSpecificProp(cscDefn, customAttrProps, "HeaderFile")
  %if ISEMPTY(hdr)
    %assign hdr = ""
  %endif
 
  %return hdr
%endfunction
 
%%=============================================================================
%%NOTE:GettheAccessDataThroughMacropropertyfromthecscrecord
%%
%function SLibGetAccessDataThroughMacro(cscDefn) void
  %assert (cscDefn.CSCType == "AccessFunction")
  %return cscDefn.CSCTypeAttributes.AccessDataThroughMacro
%endfunction
 
%%=============================================================================
%%NOTE:GettheIsReusablepropertyfromthecscrecord
%%
%function SLibGetIsReusable(record) void
  %assert (record.StorageClass == "Custom") || ...
           SLibIsLegacyStorageClassForDataRecord(record)
  %if ISFIELD(record, "IsRemovedInIR") && SLibOmitRecord(record)
    %return TLC_FALSE
  %endif
  %assign cscDefn = record.CSCDefn
  %assign customAttrProps = LibGetCustomStorageAttributes(record)
  %return LibGetInstanceSpecificProp(cscDefn, customAttrProps, "IsReusable")
%endfunction
 
%%=============================================================================
%function SLibAddHeaderFileDelimeter(hdrfile) void
  %assert !ISEMPTY(hdrfile)
 
  %% Add "" as default if there's no delimiter
  %assign hlen = SIZE(hdrfile, 1)
  %if ((hdrfile[0] == "/"") && (hdrfile[hlen-1] == "/"")) || ...
      ((hdrfile[0] == "<") && (hdrfile[hlen-1] == ">"))
    %assign newhdr = hdrfile
  %else
    %assign newhdr = "/"" + hdrfile + "/""
  %endif
 
  %return newhdr
%endfunction
 
%function SLibGetQualifierString(aQualifier, aIsConst, aIsVolatile) void
  %assign qualifier = ISEMPTY(aQualifier) ? "" : "%<aQualifier> "
  %assign const = (aIsConst) ? "const " : ""
  %assign volatile = (aIsVolatile) ? "volatile " : ""
  %return "%<qualifier>%<const>%<volatile>"
%endfunction
 
%%=============================================================================
%function SLibGetQualifier(msDefn) void
  %return SLibGetQualifierString(msDefn.Qualifier, msDefn.IsConst, msDefn.IsVolatile)
%endfunction
 
%%=============================================================================
%function SLibGetQualifierWithoutConst(msDefn) void
    %assign qualifier = msDefn.Qualifier
    %assign qualifier = ISEMPTY(qualifier) ? "" : "%<qualifier> "
    %assign volatile = (msDefn.IsVolatile) ? "volatile " : ""
    %return "%<qualifier>%<volatile>"
%endfunction
 
%%=============================================================================
%function SLibGetCSCDefForCSC(record) void
  %% Taking a class record as argument
 
  %assign rtwInfoPkg = record.Package
    %% RTWInfo package. May not be same as cscDefn.OwnerPackage.
 
  %assign cscName = record.Name
 
  %return SLibGetCSCDefForName(rtwInfoPkg, cscName)
%endfunction
 
 
%%=============================================================================
%function SLibGetMemorySectionDefForCSC(record) void
  %% Taking a class record as argument
 
  %assign rtwInfoPkg = record.Package
    %% RTWInfo package. May not be same as cscDefn.OwnerPackage.
 
  %assign cscDefn = SLibGetCSCDefForCSC(record)
  %assign msName = cscDefn.MemorySection
 
  %return SLibGetMemorySectionDefForName(cscDefn.MSPackage, msName)
%endfunction
 
%%Function:SLibCheckForUndefinedImportedMacros===============================
%%Abstract:
%%Cachecodetovalidateimportedmacros.
%%TopTester:test/toolbox/simulink/variants/codevariants/-tcodevariants10.m
%%TopTester:test/toolbox/rtw/targets/ert/tcodevariants.m
%%
%function SLibCheckForUndefinedImportedMacros(csc) void
  %assign cscDefn = SLibGetCSCDefForCSC(csc)
  %assign mdlPrivateBuffer = ""
  %assign mdlTypesBuffer = ""
  %assign numData = SIZE(csc.Data)[1]
  %openfile mdlPrivateBuffer
  %openfile mdlTypesBuffer
  %foreach dataIdx = numData
    %selectfile NULL_FILE
    %% Get Data Record
    %assign dataRec = csc.Data[dataIdx]
    %assign props = LibGetCustomStorageAttributes(dataRec)
 
    %if (SLibGetDataInitForData(cscDefn, dataRec) == "Macro" && ...
         cscDefn.DataScope == "Imported")
 
      %% emit check to see if the macro is defined
      %assign id = LibGetRecordIdentifier(dataRec.RTWRecord)
      %assign varName = LibGetRecordVarName(dataRec.RTWRecord)
      %% Skip this if we have pre-processor conditions on CSC set in global map
      %% this is to ensure that when we generate error checking code for CSC's
      %% we need to make sure VariantObject data is dumped. It is found that this
      %% function is called from many places even while generating global definitions
      %% for CSC's in model .c file. So with pre-processor conditions we need to defer
      %% it to a later stage while generating commonheader file for model.
      %% check the 'empty' because default is empty
      %if EXISTS(dataRec.PPIf) && !ISEMPTY(dataRec.PPIf)
        %continue
      %endif
      %if SLibParamIsVariantControlParam(LibGetDataRecord(csc, dataIdx))
        %selectfile mdlTypesBuffer
      %else
        %selectfile mdlPrivateBuffer
      %endif
      %if varName == id
        %assign idDescr = "variable for the parameter /"%<varName>/""
      %else
        %assign idDescr = "variable /"%<id>/" for the parameter /"%<varName>/""
      %endif
      #ifndef %<id>
      #error The %<idDescr> is not defined
      #endif
    %endif
  %endforeach
  %closefile mdlPrivateBuffer
  %closefile mdlTypesBuffer
  %assign mdlPrivateCodeExists = !WHITE_SPACE(mdlPrivateBuffer)
  %assign mdlTypesCodeExists = !WHITE_SPACE(mdlTypesBuffer)
  %if mdlPrivateCodeExists || mdlTypesCodeExists
    %openfile prequel
     
    /*
     * Check that imported macros with storage class "%<csc.Name>" are defined
     */
     %closefile prequel
     %if mdlTypesCodeExists
       %<SLibCacheCodeToFile("data_simulink_variant_define", prequel+mdlTypesBuffer)>
     %endif
     %if mdlPrivateCodeExists
       %<SLibCacheCodeToFile("mdl_priv_macro_define", prequel+mdlPrivateBuffer)>
     %endif
   %endif
%endfunction
 
%%=============================================================================
%%TopTester:test/toolbox/simulink/variants/inlineVariants/variantSource/systemtests/tmg1208119_SSwithZeroActiveVC_VC1.m
%%TopTester:test/toolbox/simulink/variants/vssSigObj/tVSSSigObj.m
%%
%function SLibExpandGroundForStaticInit(width, isSymbolic, cmplx, gnd) void
  %if cmplx
    %assign initStr = "{%<gnd>, %<gnd>}"
  %elseif TYPE(gnd) == "String"
    %assign initStr = gnd
  %else
    %assign initStr = STRING(gnd)
  %endif
 
  %if width == "1"
    %return initStr
  %elseif isSymbolic
    %% the width is symbolic, so we just initialize the first
    %% element. Although it is incomplete, it is only needed by
    %% compiler and not because of correctness so it is fine.
    %return "{%<initStr>}"
  %else
    %% the width is fixed size
    %openfile gndBuf
    {/
    %foreach idx = %<width>
      %if idx < %<width> - 1
        %<gnd>,/
      %else
        %<gnd>/
      %endif
    %endforeach
    }/
    %closefile gndBuf
    %return gndBuf
  %endif
%endfunction
 
 
%%=============================================================================
%%TopTester:test/toolbox/simulink/variants/inlineVariants/variantSource/systemtests/tmFunctionCallSplitBlock_hidden_VC1.m
%%
%function SLibExpandInitialValueForStaticInit(width, isSymbolic, cmplx, dtIdx, iv) void
  %openfile ivBuf
  %%
  %if isSymbolic || %<width> > 1
    {/
  %endif
  %%
  %% symbolic matrix must be emitted as array (need { and }). But we will
  %% initialize only the first element. Although it is incomplete, it is only
  %% needed by compiler and not because of correctness so it is fine.
  %if isSymbolic
    %assign width = 1
  %else
    %assign width = %<width>
  %endif
  %%
  %foreach idx = width
    %%
    %if cmplx
      %assign rval = SLibGetFormattedValueFromId(dtIdx, REAL(iv[idx]))
      %assign ival = SLibGetFormattedValueFromId(dtIdx, IMAG(iv[idx]))
      %assign val = "{%<rval>, %<ival>}"
    %elseif LibDataTypeIsBus(dtIdx)
      %assign val = "{%<SLibGetFormattedValueFromId(dtIdx, iv[idx])>}"
    %else
      %assign val = SLibGetFormattedValueFromId(dtIdx, iv[idx])
    %endif
    %%
    %if idx < (width - 1)
      %<val>,/
    %else
      %<val>/
    %endif
  %endforeach
  %%
  %if isSymbolic || width > 1
    }/
  %endif
  %%
  %closefile ivBuf
  %return ivBuf
%endfunction
 
 
%%=============================================================================
%%TopTester:test/toolbox/simulink/variants/tCompositePorts.m
%%
%function LibDataAccessInSpecificTLC(toPackage, toTLCName, record, request, idx, reim) void
 
  %assign genType = toPackage + "::" + toTLCName
 
  %if !%<GENERATE_TYPE_FUNCTION_EXISTS(record, "DataAccess", genType)>
    %assign toFilePath = FcnGetTLCPathFromPackageName(toPackage, toTLCName)
 
    %generatefile "%<genType>" "%<toFilePath>"
 
    %if !%<GENERATE_TYPE_FUNCTION_EXISTS(record, "DataAccess", genType)>
      %assign myPackage = LibGetRTWInfoObjectPackage(record)
      %assign cscName = LibGetCustomStorageClassName(record)
      %assign errTxt = "The DataAccess function does not exist in file: %<toFilePath>, " + ...
    "but it is needed for custom storage class: %<myPackage>::%<cscName>"
      %<LibReportFatalError(errTxt)>
    %endif
  %endif
 
  %return GENERATE_TYPE(record, "DataAccess", genType, request, idx, reim)
%endfunction
 
 
%%=============================================================================
%%TopTester:test/toolbox/simulink/variants/tCompositePorts.m
%%
%function LibClassAccessInSpecificTLC(toPackage, toTLCName, record, request) void
  %assign myPackage = record.Package
  %assign cscName = record.Name
 
  %assign genType = toPackage + "::" + toTLCName
 
  %if !%<GENERATE_TYPE_FUNCTION_EXISTS(record, "ClassAccess", genType)>
    %assign toFilePath = FcnGetTLCPathFromPackageName(toPackage, toTLCName)
   
    %generatefile "%<genType>" "%<toFilePath>"
   
    %if !%<GENERATE_TYPE_FUNCTION_EXISTS(record, "ClassAccess", genType)>
      %assign errTxt = "The ClassAccess function does not exist in file: %<toFilePath>, " + ...
    "but it is needed for custom storage class: %<myPackage>::%<cscName>"
      %<LibReportFatalError(errTxt)>
    %endif
  %endif
 
  %return GENERATE_TYPE(record, "ClassAccess", genType, request)
%endfunction
 
 
%%Function:LibCustomStorageRecordIsCustomStorageClassInMap====================
%%Abstract:
%%Returnwhetherarecordisacustomstorageclassrecordin
%%theglobalmemorymap.
%%
%function LibCustomStorageRecordIsCustomStorageClassInMap(record) void
  %return (record.RecordType == "CustomStorageClassInMap")
%endfunction
 
 
 
%%Function:LibCustomStorageRecordIsModelParameter=============================
%%Abstract:
%%Returnwhetherarecordisamodelparameter.
%%
%function LibCustomStorageRecordIsModelParameter(record) void
  %return (record.RecordType == "ModelParameter")
%endfunction
 
 
 
%%Function:LibCustomStorageRecordIsBlockState=================================
%%Abstract:
%%Returnwhetherarecordisablockstate
%%
%function LibCustomStorageRecordIsBlockState(record) void
  %return (record.RecordType == "DWork")
%endfunction
 
 
%%Function:LibCustomStorageRecordIsBlockOutput================================
%%Abstract:
%%Returnwhetherarecordisablockoutput
%%
%function LibCustomStorageRecordIsBlockOutput(record) void
  %return (record.RecordType == "BlockOutput")
%endfunction
 
 
%%Function:LibCustomStorageRecordIsExternalInput==============================
%%Abstract:
%%Returnwhetherarecordisanexternalinput
%%
%function LibCustomStorageRecordIsExternalInput(record) void
  %return (record.RecordType == "ExternalInput")
%endfunction
 
 
%%Function:LibCustomStorageRecordIsExternalOutput=============================
%%Abstract:
%%Returnwhetherarecordisanexternaloutput
%%
%function LibCustomStorageRecordIsExternalOutput(record) void
  %return (record.RecordType == "ExternalOutput")
%endfunction
 
 
%%Function:LibCustomStorageVerifyRecordIsModelParameter=======================
%%Abstract:
%%Reportanerrorifrecordisnotaparameteryetthecustomstorage
%%classassociatedwiththerecordonlysupportsparameters
%%
%function LibCustomStorageVerifyRecordIsModelParameter(record) void
  %if LibCustomStorageRecordIsModelParameter(record) == 0
    %assign varName = LibGetRecordVarName(record)
    %assign sc = LibGetCustomStorageClassName(record)
    %assign errTxt = "Custom storage class '%<sc>' " + ...
      "is not legal for '%<varName>' because it is not a parameter"
    %<LibReportError(errTxt)>
  %endif
  %return
%endfunction
 
 
%%Function:LibCustomStorageVerifyAttributesIsNotEmpty============================
%%Abstract:
%%Reportanerrorifthespecifiedcustomattributespropertydoesnotexistor
%%isempty
%%
%function LibCustomStorageVerifyAttributesIsNotEmpty(record, propName) void
  %assign customAttribs = LibGetCustomStorageAttributes(record)
  %assign varName = LibGetRecordVarName(record)
  %if ISFIELD(customAttribs, propName)
    %if ISEMPTY(customAttribs.%<propName>)
      %assign errTxt = "Data '%<varName>' must have '%<propName>' set"
      %<LibReportError(errTxt)>
    %endif
  %else
    %assign errTxt = "Data '%<varName>' does not have custom attribute '%<propName>'"
    %<LibReportError(errTxt)>
  %endif
  %return
%endfunction
 
 
%%Function:LibCustomStorageVerifyRecordIsScalar===============================
%%Abstract:
%%Reportanerrorifrecordisnotascalaryetthecustomstorage
%%classassociatedwiththerecordonlysupportsscalars
%%
%function LibCustomStorageVerifyRecordIsScalar(record) void
  %if LibGetDataWidth(record) != 1
    %assign varName = LibGetRecordVarName(record)
    %assign sc = LibGetCustomStorageClassName(record)
    %assign errTxt = "Custom storage class '%<sc>' " + ...
      "is not legal for '%<varName>' because it is not a scalar"
    %<LibReportError(errTxt)>
  %endif
  %return
%endfunction
 
 
 
%%Function:LibCustomStorageVerifyRecordIsNonComplex===========================
%%Abstract:
%%Reportanerrorifrecordiscomplexyetthecustomstorage
%%classassociatedwiththerecordonlysupportsnon-complex
%%
%function LibCustomStorageVerifyRecordIsNonComplex(record) void
  %if LibGetRecordIsComplex(record)
    %assign varName = LibGetRecordVarName(record)
    %assign sc = LibGetCustomStorageClassName(record)
    %assign errTxt = "Custom storage class '%<sc>' " + ...
      "is not legal for %<varName> because it is complex"
    %<LibReportError(errTxt)>
  %endif
  %return
%endfunction
 
%%Function:LibCustomStorageVerifyRecordIsNonStruct===========================
%%Abstract:
%%Reportanerrorifrecordisstructyetthecustomstorage
%%classassociatedwiththerecordonlysupportsnon-struct
%%
%function LibCustomStorageVerifyRecordIsNonStruct(record) void
  %assign dataTypeId = ...
        LibGetDataTypeIdAliasedThruToFromId(LibGetRecordDataTypeId(record))
  %if LibIsStructDataType(dataTypeId)
    %assign varName = LibGetRecordVarName(record)
    %assign sc = LibGetCustomStorageClassName(record)
    %assign errTxt = "Custom storage class '%<sc>' " + ...
      "is not legal for %<varName> because it is a structure"
    %<LibReportError(errTxt)>
  %endif
  %return
%endfunction
 
%%Function:FcnErrorForIdentifierSub==========================================
%%Abstract:
%%Erroroutif$Nisfoundinpragmastring.
%%
%function FcnErrorForIdentifierSub(pragma) void
  %if !ISEMPTY(FEVAL("strfind", pragma, "$N"))
    return TLC_TRUE
  %endif
  %return TLC_FALSE
%endfunction
   
%%Function:SLibCheckMemorySectionConsistency==================
%%Abstract:
%%ThisfunctionputstheCSCDefnandMemorySectionof
%%thepackagethatispassedinintothe::CompiledModel
%%
%%TopTester:test/toolbox/simulink/variants/tCompositePorts.m
%%
%function SLibCheckPackageConsistency(CSCDefs, MemorySectionDefs) void
  %if !ISEMPTY(MemorySectionDefs)
    %assign memSecDefns = FIELDNAMES(MemorySectionDefs)
    %assign numMemSecs = SIZE(memSecDefns)[1]
    %foreach memIdx = numMemSecs
      %assign memSecName = memSecDefns[memIdx]
      %assign memSecDef = MemorySectionDefs.%<memSecName>
 
      %% If the pragmas go around all variables for this MS
      %if !memSecDef.PragmaPerVar
         
        %% We should not find $N in pragma strings
        %if (%<FcnErrorForIdentifierSub(memSecDef.PrePragma)> || ...
             %<FcnErrorForIdentifierSub(memSecDef.PostPragma)>)
          %assign errTxt = ...
            "%<memSecName>: Identifier substution not allowed in " ...
            "memory section if pragmas do not apply to individual variables."
          %<LibReportError(errTxt)>
        %endif
      %endif
    %endforeach
 
    %if !ISEMPTY(CSCDefs)
      %assign cscDefns = FIELDNAMES(CSCDefs)
      %assign numCscs = SIZE(cscDefns)[1]
      %foreach cscIdx = numCscs
        %assign cscDef = CSCDefs.%
   
        %% If the csc is not of type 'Unstructured'
        %if cscDef.CSCType != "Unstructured"
          %assign memSecDef = SLibGetMemorySectionDefForName(cscDef.MSPackage, cscDef.MemorySection)
           
          %if (%<FcnErrorForIdentifierSub(memSecDef.PrePragma)> || ...
            %<FcnErrorForIdentifierSub(memSecDef.PostPragma)>)
            %assign errTxt = "%: Memory section cannot " ...
              "do identifier substitution if CSC is not Unstructured."
            %<LibReportError(errTxt)>
          %endif
           
        %endif
      %endforeach
    %endif
  %endif
  %return
%endfunction
 
%%Function:FcnLoadAllRelatedPackages========================
%%Abstract:
%%ThisisarecursivefunctionwhichaddstheCSC/MSdefinitions
%%throughMATLABcodeifthepackagedoesnotexistinthecompiledmodel
%%TopTester:test/toolbox/simulink/variants/inlineVariants/variantSource/systemtests/tmFunctionCallSplitBlock_hidden_VC1.m
%%
%function FcnLoadAllRelatedPackages(packagename) void
  %% If the package is not already registered, add it now
  %if !ISFIELD(::CompiledModel.CustomStorageClasses.CSCReg, packagename)
     
    %% Add Record
    %addtorecord ::CompiledModel.CustomStorageClasses.CSCReg %<packagename> {}
    %assign prec = GETFIELD(::CompiledModel.CustomStorageClasses.CSCReg, packagename)
     
    %% Get CSCs and check for any errors
    %assign userDefs = FEVAL("cscdefn2struct", packagename)
    %if !ISEMPTY(userDefs.ErrorString)
      %<LibReportError(userDefs.ErrorString)>
    %endif
     
    %if ISEMPTY(userDefs.CSCDefs)
      %addtorecord prec CSCDefs {}
    %else
      %addtorecord prec CSCDefs %<userDefs.CSCDefs>
    %endif
     
    %if ISEMPTY(userDefs.MemorySectionDefs)
      %addtorecord prec MemorySectionDefs {}
    %else
      %addtorecord prec MemorySectionDefs %<userDefs.MemorySectionDefs>
    %endif
     
    %% CSCDefs.%_cscDefns[cscIdx]>
    %% Add packages of CSCs/MSs being refered to
    %assign cscdefns = FIELDNAMES(prec.CSCDefs)
    %assign numOfCSCs = SIZE(cscdefns)[1]
    %foreach idx = numOfCSCs
      %assign mspkgname = prec.CSCDefs.%.MSPackage
      %if !ISFIELD(::CompiledModel.CustomStorageClasses.CSCReg, mspkgname)
        %<FcnLoadAllRelatedPackages(mspkgname)>
      %endif
    %endforeach
     
  %endif
  %return
%endfunction
      
%%Function:SLibCacheRTWInfoPackage===========================
%%Abstract:
%%ThisfunctionputstheCSCDefnandMemorySectionof
%%thepackagethatispassedinintothe::CompiledModel
%%
%function SLibCacheRTWInfoPackage(packagename) void
    %<FcnLoadAllRelatedPackages(packagename)>
    %assign prec = GETFIELD(::CompiledModel.CustomStorageClasses.CSCReg, packagename)
    %<SLibCheckPackageConsistency(prec.CSCDefs, prec.MemorySectionDefs)>
    %return
%endfunction
      
%%Function:SLibAreInternalMemorySectionsDefined==============================
%%Abstract:
%%Checkifinternalmemorysectionsaredefined.
%%
%%NOTE:Formodel-leveldata/functions,thesystemistheConfigSet.
%%
%function SLibAreInternalMemorySectionsDefined() void
  %if SLibIsERTTarget()
    %return ( (::CompiledModel.CoderDictionary.DefaultMemorySections.MemSecPackage != "--- None ---") || ...
      SIZE(::CompiledModel.CoderDictionary.AllPackages, 1) > 0 )
  %else
    %return TLC_FALSE
  %endif
 
%endfunction
 
%%Function:SLibGetInternalMemorySectionDefForName============================
%%Abstract:
%%Returnthememorysectiondefinitionforinternaldata/functions
%%givenamemorysectionname.
%%
%function SLibGetInternalMemorySectionDefForName(memsecname)
  %assert(SLibAreInternalMemorySectionsDefined())
   
  %assign memSecPkg = ::CompiledModel.CoderDictionary.DefaultMemorySections.MemSecPackage
  %return SLibGetMemorySectionDefForName(memSecPkg, memsecname)
%endfunction
 
%%Function:SLibGetInternalLegacyMemorySectionDefForCoderGroup============================
%%Abstract:
%%Returnthelegacymemorysectiondefinitionforinternaldata/functions
%%givenaCoderGroup
%%
%function SLibGetInternalLegacyMemorySectionDefForCoderGroup(group)
  %assert(SLibAreInternalMemorySectionsDefined())
   
  %assign memSecPkg = group.MemorySectionPackage
  %assign memSecName = group.MemorySection
  %return SLibGetMemorySectionDefForName(memSecPkg, memSecName)
%endfunction
   
%%Function:SLibSetupInternalMemorySections===================================
%%Abstract:
%%ThisfunctionputstheCSCDefnandMemorySectioninthe
%%::CompiledModelforthepackagedefinedbyMemSecPackageintheConfigSet
%%
%function SLibSetupInternalMemorySections() void
  %if (!SLibAreInternalMemorySectionsDefined())
    %return
  %endif
 
  %assign packages = ::CompiledModel.CoderDictionary.AllPackages
  %if SIZE(packages, 1) == 0
    %% There are no packages in the coder dictionary. So look in the ConfigSet.
    %assign packages = ::CompiledModel.CoderDictionary.DefaultMemorySections.MemSecPackage
  %endif
   
  %if TYPE(packages) == "String"
    %%
    %% Cache all registered CSCDefs/MemorySectionDefs of given RTWInfo package
    %% into ::CompiledModel.CustomStorageClasses.CSCReg.$msPkg if not
    %% already done so.
    %%
    %<SLibCacheRTWInfoPackage(packages)>
  %else
    %foreach idx = SIZE(packages, 1)
      %assign msPkg = packages[idx]
      %%
      %% Cache all registered CSCDefs/MemorySectionDefs of given RTWInfo package
      %% into ::CompiledModel.CustomStorageClasses.CSCReg.$msPkg if not
      %% already done so.
      %%
      %<SLibCacheRTWInfoPackage(msPkg)>
    %endforeach
  %endif
   
%endfunction
 
%%Function:SLibPragmaRegexp=====================================
%%Abstract:
%%Performtokensubstitutionsassociatedwithmemorysectiondefinitions
%%
%function SLibPragmaRegexp(MemorySectionName, pragmastring) void
 
  %if !ISEMPTY(pragmastring)
    %assign AUTOSAR_COMPONENT = SLibAutosarActive() ? AutosarSWCName() : LibGetModelName()
    %assign pragmastring = FEVAL("regexprep", pragmastring, "/%<AUTOSAR_COMPONENT>", AUTOSAR_COMPONENT)
    %assign pragmastring = FEVAL("regexprep", pragmastring, "/%<MemorySectionName>", MemorySectionName)
  %endif
 
  %return pragmastring
 
%endfunction
 
%%Function:SLibSetupCustomStorageClasses=====================================
%%Abstract:
%%Performactionsassociatedwithcustomstorageclassespriorto
%%theiruse
%%TopTester:test/toolbox/simulink/variants/inlineVariants/variantSource/systemtests/tmFunctionCallSplitBlock_hidden_VC1.m
%%TopTester:test/toolbox/rtw/targets/AUTOSAR/Variants/dimensionVariants/tDimensionVariants.m
%%
%function SLibSetupCustomStorageClasses() void
 
  %with ::CompiledModel.CustomStorageClasses
   
    %% Set up the record to cache CSC & Memory Sections
    %if !ISFIELD(::CompiledModel.CustomStorageClasses, "CSCReg")
      %addtorecord ::CompiledModel.CustomStorageClasses CSCReg {}
    %endif
 
    %foreach idx = NumCustomStorageClasses
      %assign sc = CustomStorageClass[idx]
      %assign cscName = sc.Name
      %assign rtwInfoPkg = sc.Package
      %% RTWInfo package. May not be same as cscDefn.OwnerPackage.
   
      %%
      %% Cache all registered CSCDefs/MemorySectionDefs of given RTWInfo package
      %% into ::CompiledModel.CustomStorageClasses.CSCReg.$rtwInfoPkg if not
      %% already done so.
      %%
      %<SLibCacheRTWInfoPackage(rtwInfoPkg)>
   
      %%
      %% Setup the generate type to the right TLC file of this custom storage class
      %%
      %addtorecord sc Data {}
      %assign dummyScope = sc
 
      %assign filePkgAndName = FcnGetTLCFilePackageAndName(rtwInfoPkg, cscName)
      %assign filePkg = filePkgAndName[0]
      %assign fileName = filePkgAndName[1]
 
      %assign filePath = FcnGetTLCPathFromPackageName(filePkg, fileName)
  
      %if !FILE_EXISTS(filePath)
        %assign errTxt = "The file %<filePath> does not exist, " + ...
        "but it is needed for the custom storage class %<rtwInfoPkg>::%<cscName>"
        %<LibReportError(errTxt)>
      %endif
   
      %assign genType = SLibGetGenerateTypeForName(rtwInfoPkg, cscName)
      %generatefile "%<genType>" "%<filePath>"
 
      %if !%<GENERATE_TYPE_FUNCTION_EXISTS(dummyScope, "DataAccess", genType)>
    %assign errTxt = "The DataAccess function does not exist in file: %<filePath>, " + ...
      "but it is needed for custom storage class: %<rtwInfoPkg>::%<cscName>"
        %<LibReportFatalError(errTxt)>
      %endif
 
      %if !%<GENERATE_TYPE_FUNCTION_EXISTS(dummyScope, "ClassAccess", genType)>
    %assign errTxt = "The ClassAccess function does not exist in file: %<filePath>, " + ...
      "but it is needed for custom storage class: %<rtwInfoPkg>::%<cscName>"
        %<LibReportFatalError(errTxt)>
      %endif
 
    %endforeach %% idx in CustomStorageClass
     
    %%
    %% If MemSecPackage is not '--- None ---', load the MemSecPackage.
    %%
    %<SLibSetupInternalMemorySections()>
     
    %%
    %% Create the custom part of the map
    %%
    %<SLibMapCustomData()>
     
    %%
    %% Loop through RTWInfo packages and Sanitize user strings for use in TLC
    %%
    %assign rtwInfoPkgNames = FIELDNAMES(CSCReg)
    %assign numRTWInfoPkgs = SIZE(rtwInfoPkgNames)[1]
    %foreach idx = numRTWInfoPkgs
   
      %assign rtwInfoPkg = rtwInfoPkgNames[idx]
      %assign rtwInfoPkgDefs = CSCReg.%<rtwInfoPkg>
 
      %% Sanitize CSC Definitions in this RTWInfo package
      %assign cscDefns = FIELDNAMES(rtwInfoPkgDefs.CSCDefs)
      %assign numCSCs = SIZE(cscDefns)[1]
      %foreach cscIdx = numCSCs
        %assign cscDefn = rtwInfoPkgDefs.CSCDefs.%
         
        %if SLibIsCSCObjectBasedByName(cscDefn.OwnerPackage, cscDefn.Name)
          %% Object-based CSCs have all comments generated from RTWCG/IR directly
          %assign cscRec = LibGetCustomStorageInMap(rtwInfoPkg, cscDefn.Name)
          %if !ISEMPTY(cscRec)
            %assign cscDefn.TypeComment = ""
            %assign declFcnName = "SLibObjectCSCClass_Decl_" + cscDefn.OwnerPackage + "_" + cscDefn.Name
            %assign cscDefn.DeclareComment = %<declFcnName>()
            %assign defnFcnName = "SLibObjectCSCClass_Defn_" + cscDefn.OwnerPackage + "_" + cscDefn.Name
            %assign cscDefn.DefineComment = %<defnFcnName>()
          %endif
        %elseif cscDefn.CommentSource == "Default"
          %assign cscRec = LibGetCustomStorageInMap(rtwInfoPkg, cscDefn.Name)
          %if !ISEMPTY(cscRec)
            %assign cscDefn.TypeComment = LibCustomClass(cscRec, "typeComment")
            %assign cscDefn.DeclareComment = LibCustomClass(cscRec, "declComment")
            %assign cscDefn.DefineComment = LibCustomClass(cscRec, "defnComment")
          %endif
        %else
          %assign cscDefn.TypeComment = FcnSanitizeUserString(cscDefn.TypeComment)
          %assign cscDefn.DeclareComment = /
                                     FcnSanitizeUserString(cscDefn.DeclareComment)
          %assign cscDefn.DefineComment = /
                                     FcnSanitizeUserString(cscDefn.DefineComment)
        %endif
   
        %assign cscDefn.HeaderFile = FcnSanitizeUserString(cscDefn.HeaderFile)
        %assign cscDefn.DefinitionFile = FcnSanitizeUserString(cscDefn.DefinitionFile)
        %assign cscDefn.Owner = FcnSanitizeUserString(cscDefn.Owner)
      %endforeach
   
      %% Sanitize Memory Section comments in this RTWInfo package
      %assign memSecDefns = FIELDNAMES(rtwInfoPkgDefs.MemorySectionDefs)
      %assign numMemSecs = SIZE(memSecDefns)[1]
      %foreach memIdx = numMemSecs
        %assign memSecDef = rtwInfoPkgDefs.MemorySectionDefs.%
        %assign memSecDef.Comment = FcnSanitizeUserString(memSecDef.Comment)
        %assign memSecDef.PrePragma = SLibPragmaRegexp(memSecDef.Name, FcnSanitizeUserString(memSecDef.PrePragma))
        %assign memSecDef.PostPragma = SLibPragmaRegexp(memSecDef.Name, FcnSanitizeUserString(memSecDef.PostPragma))
      %endforeach
   
    %endforeach
 
    %%
    %% Call the create method for the storage class, passing the map entry as
    %% the record
    %%
 
    %foreach idx = NumCustomStorageClasses
      %assign sc = CustomStorageClass[idx]
      %assign cscName = sc.Name
      %assign rtwInfoPkg = sc.Package
      %assign class = LibGetCustomStorageInMap(rtwInfoPkg, cscName)
      %%
      %% Do not call LibCustomClass when there are no instances of a
      %% recognized class. When there are no instances the class record
      %% is empty.
      %%
      %% This allows classes that have been emptied by custom target
      %% preprocessing. Removing this will cause errors to any custom
      %% target code generation process that removes all instances of
      %% data that are of a CustomStorageClass.
      %%
      %if !ISEMPTY(class)
        %<LibCustomClass(class, "setup")>
      %endif
    %endforeach
  %endwith
 
%endfunction
 
%%FunctionLibDefaultCustomStorageDeclare======================================
%%Abstract:
%%Generatedefaultdatadeclarationfordatawithacustomstorage
%%class.Thedeclarationtakestheformofastandaloneglobal
%%variable,e.g.
%%
%%real32_Tx;
%%uint8_Ty[3];
%%
%function LibDefaultCustomStorageDeclare(record)
  %assign id = LibGetRecordIdentifier(record)
  %assign dt = LibGetRecordCompositeDataTypeName(record)
  %assign width = LibGetDataWidth(record)
  %if width == 1
    %assign dims = ""
  %else
    %assign dims = "[%<width>]"
  %endif
  %return "%<dt> %<id>%<dims>;"
%endfunction
 
%%FunctionLibDefaultCustomStorageInitialize===================================
%%Abstract:
%%GeneratedefaultdatainitializationforexternalI/Oandstates.The
%%initializationistothevalueofgroundforthedatatype,e.g.
%%
%%x=0.0;
%%y[1]=0;
%%y[2]=0;
%%y[3]=0;
%%
%function LibDefaultCustomStorageInitialize(record, idxInfo, reim)
  %if record.RecordType == "ModelParameter"
    %return ""
  %else
    %assign gndValue = LibGetGroundValue(record, tRealPart)
    %return ...
      "%<LibDefaultCustomStorageContents(record, idxInfo, reim)> = " + ...
      "%<gndValue>;"
  %endif
%endfunction
 
%%FunctionLibDefaultCustomStorageDefine=======================================
%%Abstract:
%%Generatedefaultdatadefinitionfordatawithacustomstorage
%%class.Ifthedataisaparameter,thedefinitionincludesits
%%initializationtoitsnominalvalue.Thedefinitiontakesthe
%%formofastandaloneglobalvariable,e.g.
%%
%%real32_Tx;
%%uint8_Tp[3]={4,27,92};
%%uint8_Ty[3];
%%
%function LibDefaultCustomStorageDefine(record)
  %assign id = LibGetRecordIdentifier(record)
  %assign dt = LibGetRecordCompositeDataTypeName(record)
  %assign width = LibGetDataWidth(record)
  %if width == 1
    %assign dims = ""
  %else
    %assign dims = "[%<width>]"
  %endif
  %if record.RecordType == "ModelParameter"
    %openfile initStr
     %<dt> %<id>%<dims> = %<LibParameterInstanceInitStr(record)>;
    %closefile initStr
    %return initStr
  %else
    %return "%<dt> %<id>%<dims>;"
  %endif
%endfunction
 
%%FunctionLibDefaultCustomStorageContents=====================================
%%Abstract:
%%Generatedefaultdataaccessfordatawithacustomstorage
%%class.Thedefinitiontakestheformofastandaloneglobal
%%variable,e.g.
%%
%%x
%%y[2]
%%
%%TopTester:test/toolbox/simulink/variants/inlineVariants/simulinkFunction/-tVariantSimulinkFunctionAutoInherit.m
%%
%function LibDefaultCustomStorageContents(record, idxInfo, reim)
  %assign cscDefn = SLibGetCSCDefForData(record)
  %assign msDefn = SLibGetMemorySectionDefForData(record)
  %if SLibIsAuxBufferForReusableCSC(record) && ...
    !ISFIELD(record, "IsAtRootInputOrOutput")
    %assign id = record.ReuseBufferName
  %else
    %assign id = LibGetRecordIdentifier(record)
  %endif
  %assign scalar = ((LibGetDataWidth(record) == 1) && !LibRecordHasSymbolicWidth(record))
  %assign pointer = (SLibGetDataAccess(cscDefn, record) == "Pointer")
   
  %if SLibIsContainerCGTypeND(record)
    %% Insert an nD reference to the first element if a flat index is
    %% used on an nD variable; g1738124, g2010853.
    %if !ISEMPTY(idxInfo) && !LibIsNdIndex(idxInfo)
      %assign recNumDims = LibCGTypeNumDimensions(SLibGetRecordContainerCGTypeIdx(record))
      %assign id = LibGetAddressOfFirstElement(id, recNumDims)
    %endif
  %endif
 
  %if (scalar && pointer)
    %% Scalar data with pointer access
    %assign rtn = "(*%<id>)%<idxInfo>%<reim>"
  %else
    %% Two cases:
    %% 1. Direct access
    %% 2. Non-scalar data with pointer access
    %assign rtn = "%<id>%<idxInfo>%<reim>"
  %endif
   
  %return rtn
%endfunction
 
%%FunctionLibDefaultCustomStorageSet=====================================
%%Abstract:
%%Generatedefaultdataaccessfordatawithacustomstorage
%%class.Thedefinitiontakestheformofastandaloneglobal
%%variable,e.g.
%%
%%x=u;
%%y[2]=u;
%%
%function LibDefaultCustomStorageSet(record, idxInfo, reim, value)
  %return "%<LibDefaultCustomStorageContents(record, idxInfo, reim)> = %<value>;/n"
%endfunction
 
%%FunctionLibDefaultCustomStorageAddress======================================
%%Abstract:
%%Generatedefaultdataaddressfordatawithacustomstorage
%%class.Thedefinitiontakestheformofastandaloneglobal
%%variable,e.g.
%%
%%&(x)
%%y[2]
%%
%function LibDefaultCustomStorageAddress(record, idxInfo, reim)
  %assign msDefn = SLibGetMemorySectionDefForData(record)
  %assign dtypeId = LibGetRecordDataTypeId(record)
  %assign cmplx = LibGetRecordIsComplex(record)
  %assign cast = LibGetNonVolatileCmplxPointerCast(msDefn, dtypeId, cmplx, idxInfo)
   
  %return "%<cast>&%<LibDefaultCustomStorageContents(record, idxInfo, reim)>"
%endfunction
 
%%FunctionLibDefaultCustomStorageLayout=======================================
%%Abstract:
%%Foragivenrecord,returnavectorcontaininginformationabout
%%thelayoutofthatdata;seeLibGetDataLayout()formoreinformation.
%%
%function LibDefaultCustomStorageLayout(record)
  %return LibGetDataLayout(record)
%endfunction
 
%%FunctionLibDefaultCustomStorageDataDeclComment==============================
%%Abstract:
%%Foragivendatarecord,returnacommenttobeinsertedbefore/attheend
%%of/afterdeclarationsofthatdata.
%%
%function LibDefaultCustomStorageDataDeclComment(record)
  %return ["", "", ""]
%endfunction
 
%%FunctionLibDefaultCustomStorageDataDefnComment==============================
%%Abstract:
%%Foragivendatarecord,returnacommenttobeinsertedbefore/attheend
%%of/afterdefinitionofthatdata.
%%
%function LibDefaultCustomStorageDataDefnComment(record)
  %return ["", "", ""]
%endfunction
 
%%FunctionLibDefaultCustomStorageComment======================================
%%Abstract:
%%Foragivenclassrecord,returnacommenttobegenerallyinsertedbefore
%%thedataofthatclass
%%
%function LibDefaultCustomStorageComment(record)
  %return "/* Data with custom storage class %<record.Name> */"
%endfunction
 
%%FunctionLibDefaultCustomStorageTypeComment==================================
%%Abstract:
%%Foragivenclassrecord,returnacommenttobeinsertedbefore
%%typedefinition(ifthereis)ofthedataofthatclass
%%
%function LibDefaultCustomStorageTypeComment(record)
  %return "/* Type definition of data with custom storage class %<record.Name> */"
%endfunction
 
%%FunctionLibDefaultCustomStorageDeclComment==================================
%%Abstract:
%%Foragivenclassrecord,returnacommenttobeinsertedbefore
%%declarationofthedataofthatclass
%%
%function LibDefaultCustomStorageDeclComment(record)
  %return "/* Declaration of data with custom storage class %<record.Name> */"
%endfunction
 
%%FunctionLibDefaultCustomStorageDefnComment==================================
%%Abstract:
%%Foragivenclassrecord,returnacommenttobeinsertedbefore
%%definitionofthedataofthatclass
%%
%function LibDefaultCustomStorageDefnComment(record)
  %return "/* Definition of data with custom storage class %<record.Name> */"
%endfunction
 
%%FunctionLibDefaultCustomStorageUnknownDataAccessType========================
%%Abstract:
%%HandlethecasewhereanunknownaccesstypeisusedwhencallingDataAccess
%%TopTester:test/toolbox/simulink/variants/codevariants/tvss_code_variants.m
%%
%function LibDefaultCustomStorageUnknownDataAccessType ...
  (record, type, idxInfo, reim) void
   
  %switch type
    %case "layout"
      %% Assume worst case if not defined
      %return ["other"]
      %%break
 
    %case "qualifier"
      %% Return the default type qualifier if not defined
      %return ""
      %%break
 
    %case "declComment"
    %case "defnComment"
      %% Return empty strings for comments to place
      %% before / on same line / after code.
      %return ["", "", ""]
      %%break
       
    %% These are critical and must be defined
    %case "initialize"
    %case "contents"
    %case "address"
    %case "declare"
    %case "define"
    %% Unknown access type
    %default
      %assign rtwInfoPkg = LibGetRTWInfoObjectPackage(record)
      %assign cscName = LibGetCustomStorageClassName(record)
      %assign varName = LibGetRecordVarName(record)
      %assign errTxt = "The access type '%<type>' is not defined for " + ...
    "custom storage class '%<cscName>' used by data item " + ...
    "'%<varName>' of package '%<rtwInfoPkg>'"
      %<LibReportFatalError(errTxt)>
      %break
 
  %endswitch
%endfunction
 
%%FunctionLibDefaultCustomStorageUnknownClassAccessType=======================
%%Abstract:
%%Handlethecasewhereanunknownaccesstypeisusedwhencalling
%%ClassAccess
%%
%function LibDefaultCustomStorageUnknownClassAccessType(record, type) void
 
  %switch type
 
    %% For backward compatibility, the following will fall back to "comment"
    %case "typeComment"
    %case "declComment"
    %case "defnComment"
      %assign genType = SLibGetGenerateTypeForCSC(record)
 
      %return GENERATE_TYPE(record, "ClassAccess", genType, "comment")
      %%break
 
    %case "comment"
      %% Just return a null if not defined
      %return [""]
      %%break
 
    %% These are critical and must be defined
    %case "setup"
    %% Unknown access type
    %default
      %assign rtwInfoPkg = record.Package
      %assign cscName = record.Name
      %assign errTxt = "The access type '%<type>' is not defined for " + ...
    "custom storage class '%<cscName>' used by data of " + ...
        "package '%<rtwInfoPkg>'"
      %<LibReportFatalError(errTxt)>
      %break
 
  %endswitch
%endfunction
 
%%FunctionLibCustomStorageClassRecordNumData==================================
%%Abstract:
%%intheClassAccessmethod,returnthenumberofdatasubrecordsinthe
%%classrecord
%%
%function LibCustomStorageClassRecordNumData(record) void
  %return record.NumData
%endfunction
 
 
%%FunctionLibConvertNameToIdentifier==========================================
%%Abstract:
%%convertfilenametolegalCidentifier
%%
%function LibConvertNameToIdentifier(s) void
  %assign str = "char(bitor(bitand('%<s>'>='0','%<s>'<='9')," + ...
    "bitor(bitand('%<s>'>='a','%<s>'<='z'),bitand('%<s>'>='A'," + ...
    "'%<s>'<='Z'))).*'%<s>' + ~bitor(bitand('%<s>'>='0','%<s>'<='9')" + ...
    ",bitor(bitand('%<s>'>='a','%<s>'<='z'),bitand('%<s>'>='A'," + ...
    "'%<s>'<='Z'))).*'_')"
  %return "_INCLUDED_" + FEVAL("eval", str) + "_"
%endfunction
 
%%FunctionSLibCustomStorageStructTemplateDataAccess===========================
%%Abstract:
%%DefineDataAccess()templatefunctionforarbitraryflatdatastructures.
%%
%function SLibCustomStorageStructTemplateDataAccess(record, request, ...
  idx, reim, structInstanceName)
 
  %switch request
 
    %% The "initialize" request is used by the model registration
    %% function to zero internal or external data.
    %case "initialize"
      %assign props = LibGetCustomStorageAttributes(record)
      %assign gnd = LibGetGroundValue(record, tRealPart)
      %return "%<structInstanceName>.%<props.FieldName> = %<gnd>;"
 
    %% The "contents" request is used to generate code corresponding
    %% to the usage of data on the left-hand or right-hand side of
    %% an assignment.
    %case "contents"
      %assign props = LibGetCustomStorageAttributes(record)
      %return "%<structInstanceName>.%<props.FieldName>"
       
    %% The "address" request is used to generate code corresponding
    %% to the address of data.
    %case "address"
      %assign props = LibGetCustomStorageAttributes(record)
      %return "&(%<structInstanceName>.%<props.FieldName>)"
       
    %% Since the data is embedded as fields in a composite, we will
    %% not declare or define it individually using the "declare"
    %% and "define" requests
    %case "declare"
    %case "define"
      %return ""
 
    %% The "layout" request is used to define the way data is mapped to
    %% memory. In this case, the data is simply scalar elements
    %% (embedded in a structure) so we can use the default layout.
    %case "layout"
      %return LibDefaultCustomStorageLayout(record)
      %%break
 
    %% Handle unrecognized requests
    %default
       
      %% You should invoke LibDefaultCustomStorageUnknownDataAccessType
      %% for unrecognized requests. It gracefully errs out for unknown
      %% or known, critical requests not handled above, but supplies
      %% safe defaults for known, noncritical requests not handled above.
      %return LibDefaultCustomStorageUnknownDataAccessType ...
    (record, request, idx, reim)
      %%break
       
  %endswitch
   
%endfunction
 
 
%%FunctionSLibCustomStorageStructTemplateClassAccess===================
%%Abstract:
%%defineClassAccess()functionfortheStructtemplate
%%
%%NOTE:Thisfunctionisobsolete.
%%
%function SLibCustomStorageStructTemplateClassAccess(record, request, ...
  structTypeName, structInstanceName, structFieldNames, ...
  booleanBitField)
 
  %if structTypeName == ""
    %<LibReportFatalError("Undefined structure type name")>
  %endif
  %if structInstanceName == ""
    %<LibReportFatalError("Undefined structure instance name")>
  %endif
  %if structFieldNames == []
    %<LibReportFatalError("Undefined structure field names")>
  %endif
     
  %switch request
 
    %% The "setup" request performs class-wide operations prior to
    %% code generation.
    %case "setup"
 
      %% Do some error checking: for each object in this class,
      %% * make sure it is a scalar, noncomplex
      %% * make sure it is the only object referencing a particular field
      %% * make sure it uses a valid fieldname
      %%
      %% Also, establish data type for each field and initial value for
      %% each field.
      %createrecord fieldProps {}
      %assign numFields = SIZE(structFieldNames)[1]
      %foreach idx = numFields
        %if booleanBitField
        %addtorecord fieldProps % ...
           { Used 0;/
             CDataType "unsigned int";/
             InitValue "false" /
       }
     %else
        %addtorecord fieldProps % ...
           { Used 0;/
             CDataType "real_T";/
             InitValue "0.0" /
       }
     %endif
      %endforeach
      %assign numData = LibCustomStorageClassRecordNumData(record)
 
      %foreach idx = numData
    %% Get the idx'th data record with BitField storage
    %assign item = LibGetDataRecord(record, idx)
 
    %% Make sure the data is scalar and noncomplex
    %<LibCustomStorageVerifyRecordIsScalar(item)>
    %<LibCustomStorageVerifyRecordIsNonComplex(item)>
 
    %% If this is a boolean bitfield, make sure the datatype is boolean
    %if booleanBitField && ...
      LibGetDataTypeIdAliasedThruToFromId(LibGetRecordDataTypeId(item)) != tSS_BOOLEAN
      %assign errTxt = "Bitfields are only supported for boolean data"
      %<LibReportError(errTxt)>
    %endif
     
    %% Make sure the object's fieldname is OK with what the TLC
    %% says the legal fieldnames are, and that no two objects utilize
    %% the same field.
    %assign varName = LibGetRecordVarName(item)
        %assign props = LibGetCustomStorageAttributes(item)
    %assign fieldName = props.FieldName
        %if !ISFIELD(fieldProps, fieldName)
      %assign errTxt = "The field name '%<fieldName>' of object '%<varName>' " +...
        "is not defined as a legal field name by the custom storage " +...
        "TLC file defining the '%<structTypeName>' type"
      %<LibReportError(errTxt)>
    %endif
        %assign field = GETFIELD(fieldProps, fieldName)
    %if field.Used != 0
      %assign errTxt = "The object field '%<fieldName>' " +...
        "is used by multiple objects"
      %<LibReportError(errTxt)>
    %else
      %assign field.Used = field.Used + 1
    %endif
     
    %% Cache away the C data type, and the initial value of the field.
    %assign field.CDataType = LibGetRecordCompositeDataTypeName(item)
    %if LibCustomStorageRecordIsModelParameter(item)
      %assign field.InitValue = LibParameterInstanceInitStr(item)
    %else
      %assign field.InitValue = LibGetGroundValue(item, tRealPart)
    %endif
      %endforeach
 
      %% Build up the type definition
      %openfile structTypeBuf
      /* %<structTypeName> data type */
      typedef struct {
    %foreach idx = numFields
      %assign fieldName = structFieldNames[idx]
          %assign field = GETFIELD(fieldProps, fieldName)
          %if booleanBitField
        unsigned int %<fieldName>:1;
      %else
        %<field.CDataType> %<fieldName>;
      %endif
    %endforeach
      } %<structTypeName>;
      %closefile structTypeBuf
       
      %% Build up the structure initializer
      %openfile structInitBuf
      {/
    %foreach idx = numFields
      %assign fieldName = structFieldNames[idx]
          %assign field = GETFIELD(fieldProps, fieldName)
      %if idx > 0
        , /
      %endif
      %<field.InitValue>/
    %endforeach
      } /
      %closefile structInitBuf
       
      %% Cache the structure type definition and instance definition
      %<LibHeaderFileCustomCode(structTypeBuf,"trailer")>
      %<LibPrmFileCustomCode(...
    "%<structTypeName> %<structInstanceName>" + ...
    " = %<structInitBuf>;/n","trailer")>
      %return ""
      %%break
 
    %case "comment"
      %% No individual data declarations or definitions.
      %return ""
      %%break
 
    %case "groupTypeDeclDefn"
      %return ["", "", ""]
      %%break
 
    %% Handle unrecognized requests
    %default
       
      %return LibDefaultCustomStorageUnknownClassAccessType ...
    (record, request)
      %%break
       
  %endswitch
       
%endfunction
 
%%Function:LibBlockAssignOutputSignal========================================
%%Abstract:
%%Assignablock'soutputtoaspecifiedright-hand-sidevalue
%%TopTester:test/toolbox/simulink/variants/codevariants/tcodevariants3.m
%%
%function LibBlockAssignOutputSignal(portIdx, ucv, lcv, sigIdx, rhs) void
  %assign op = FcnGetOutputPortRecord(portIdx)
  %assign sigRec = SLibGetSourceRecord(op, 0)
  %if (ISFIELD(sigRec, "StorageClass") && ...
       sigRec.StorageClass == "Custom" && ...
       sigRec.CustomStorageClassVersion > 1)
    %assign tmpVect = SLibGetReimAndIdx(sigIdx)
    %assign reim = tmpVect[0]
    %assign sigIdx = tmpVect[1]
    %% Index into memory in code may be different to signal index in Simulink
    %% (e.g., concatenation block combines memory for multiple inputs).
    %assign portObj = FcnGetOutputPortRecord(portIdx)
    %assign sigRecAndMapInfo = SLibGetSourceRecordAndMapInfo(portObj, sigIdx, TLC_TRUE, TLC_FALSE)
    %assign sigOffset = sigRecAndMapInfo.signalOffset
    %assign sigIndexer = SLibGet1DArrayIndexer(LibGetRecordWidth(sigRec), ucv, lcv, sigOffset)
    %return LibAccessCustomData(sigRec, "set", sigIndexer, reim, rhs)
  %elseif sigRec.UseAccessFunctions && (sigRec.AccessMode == "Value")
    %assign tmpVect = SLibGetReimAndIdx(sigIdx)
    %assign reim = tmpVect[0]
    %assign sigIdx = tmpVect[1]
    %% Index into memory in code may be different to signal index in Simulink
    %% (e.g., concatenation block combines memory for multiple inputs).
    %assign portObj = FcnGetOutputPortRecord(portIdx)
    %assign sigRecAndMapInfo = SLibGetSourceRecordAndMapInfo(portObj, sigIdx, TLC_TRUE, TLC_FALSE)
    %assign sigOffset = sigRecAndMapInfo.signalOffset
    %assign sigIndexer = SLibGet1DArrayIndexer(LibGetRecordWidth(sigRec), ucv, lcv, sigOffset)
    %return FcnSetAccessFunctionSignalReference(sigRec, sigIndexer, rhs)
  %else
    %return "%<LibBlockOutputSignal(portIdx, ucv, lcv, sigIdx)> = %<rhs>;/n"
  %endif
%endfunction
 
 
%%Function:LibBlockAssignDWork===============================================
%%Abstract:
%%Assignablock'sdworktoaspecifiedright-hand-sidevalue
%%
%function LibBlockAssignDWork(dwork, ucv, lcv, sigIdx, rhs) void
  %assign dworkAndRec = FcnGetDworkAndRec(dwork)
  %assign dworkRec = dworkAndRec.DWorkRec
 
  %if dworkRec.StorageClass == "Custom" && ...
    dworkRec.CustomStorageClassVersion > 1
    %assign tmpVect = SLibGetReimAndIdx(sigIdx)
    %assign reim = tmpVect[0]
    %assign sigIdx = tmpVect[1]
    %assign sigIndexer = SLibGet1DArrayIndexer(SLibDWorkWidth(dworkRec), ucv, lcv, sigIdx)
    %return LibAccessCustomData(dworkRec, "set", sigIndexer, reim, rhs)
  %else
    %return "%<LibBlockDWork(dwork, ucv, lcv, sigIdx)> = %<rhs>;/n"
  %endif
%endfunction
 
%%Function:SLibAssignCustomData===============================================
%%Abstract:
%%Assigndatatoaspecifiedright-hand-sidevalue
%%
%function SLibAssignCustomData(data, idx, reim, rhs) void
  %assert data.StorageClass == "Custom"
  %if data.StorageClass == "Custom" && ...
    data.CustomStorageClassVersion > 1
    %return LibAccessCustomData(data, "set", idx, reim, rhs)
  %else
    %return "%<LibAccessCustomData(data, "contents", idx, reim, "")> = %<rhs>;/n"
  %endif
%endfunction
 
%%Function:VerifyCustomStorageCompliance=====================================
%%Abstract:
%%Verifyablock'sdworksandoutputsofwithcustomstorageclass
%%arenotaversionhigherthanthatwhichtheblockiscompliantto
%%TopTester:test/toolbox/simulink/variants/codevariants/tcodevariants9.m
%%
%function VerifyCustomStorageCompliance() void
  %foreach sysIdx = NumSystems
    %assign system = System[sysIdx]
    %with system
    %foreach blkIdx = NumBlocks
      %assign block = Block[blkIdx]
      %assign cscComplianceLvl = SLibBlockGetCustomStorageComplianceLevel(block)
      %%
      %% The opaque block might include ports of block, which aren't CS2
      %% compliant. The error will be reported by those blocks. The auto-
      %% generated TLC code for the opaque block is always CS2 compliant.
      %%
      %if block.Type == "Opaque"
        %continue
      %endif
      %with block
      %if NumDWork > 0
    %foreach idx = NumDWork
      %assign dwork = DWork[idx]
      %assign dworkAndRec = FcnGetDworkAndRec(dwork)
      %assign dworkRec = dworkAndRec.DWorkRec
      %if dworkRec.StorageClass == "Custom" && ...
        dworkRec.CustomStorageClassVersion > cscComplianceLvl
        %assign errTxt = ...
          "DWork %<LibGetRecordVarName(dworkRec)> " + ...
          "uses custom storage class, level " + ...
          "%<dworkRec.CustomStorageClassVersion> but the compliance " + ...
          "level of this block is only " + ...
          "%<cscComplianceLvl>; use a different block or " + ...
          "a different custom storage class, level " + ...
          "%<cscComplianceLvl> or lower"
        %<LibBlockReportError(block, errTxt)>
          %elseif ISFIELD(dworkRec, "UseAccessFunctions") && dworkRec.UseAccessFunctions && ...
            ISFIELD(dworkRec, "AccessMode") && (dworkRec.AccessMode == "Value") && ...
            cscComplianceLvl < 2
              %assign errTxt = ...
                "DWork %<LibGetRecordVarName(dworkRec)> " + ...
                "uses an access method with mode 'ByValue', " + ...
                "but the custom storage class compliance " + ...
                "level of this block is only " + ...
                "%<cscComplianceLvl>; use a different block or " + ...
                "an access method with mode 'ByPointer'."
              %<LibBlockReportError(block, errTxt)>
      %endif
    %endforeach
      %endif
      %if NumDataOutputPorts > 0
    %foreach idx = NumDataOutputPorts
      %assign op = FcnGetOutputPortRecord(idx)
      %assign sigSrc = IDNUM(op.SignalSrc[0])[0]
      %if (sigSrc == "E") || (sigSrc == "Y")
        %assign sigRec = SLibGetSourceRecord(op, 0)
        %if sigRec.StorageClass == "Custom" && ...
          sigRec.CustomStorageClassVersion > cscComplianceLvl
              %assign errTxt = ...
                "Block output %<LibGetRecordVarName(sigRec)> " + ...
                "uses custom storage class, level " + ...
                "%<sigRec.CustomStorageClassVersion> but the compliance " + ...
                "level of this block is only " + ...
                "%<cscComplianceLvl>; use a different block or " + ...
                "a different custom storage class, level " + ...
                "%<cscComplianceLvl> or lower"
              %<LibBlockReportError(block, errTxt)>
            %elseif ISFIELD(sigRec, "UseAccessFunctions") && sigRec.UseAccessFunctions && ...
              ISFIELD(sigRec, "AccessMode") && (sigRec.AccessMode == "Value") && ...
              cscComplianceLvl < 2
              %assign errTxt = ...
                "Block output %<LibGetRecordVarName(sigRec)> " + ...
                "uses an access method with mode 'ByValue', " + ...
                "but the custom storage class compliance " + ...
                "level of this block is only " + ...
                "%<cscComplianceLvl>; use a different block or " + ...
                "an access method with mode 'ByPointer'."
              %<LibBlockReportError(block, errTxt)>
            %endif
      %endif
    %endforeach
      %endif
      %endwith
    %endforeach
  %endwith
  %endforeach
%endfunction
 
%%Function:FcnSanitizeUserString==========================================
%%
%function FcnSanitizeUserString(userString) void
  %if ISEMPTY(userString)
    %return ""
  %elseif WHITE_SPACE(userString)
    %return ""
  %endif
  %return userString
%endfunction
 
 
%%=============================================================================
%function FcnGetTLCFilePackageAndName(rtwInfoPkg, cscName) void
  %assign filePkg = ""
  %assign fileName = ""
 
  %assign cscDefn = SLibGetCSCDefForName(rtwInfoPkg, cscName)
  %if cscDefn.CSCType != "Other"
    %% ie. Unstructured, FlatStructure or AccessFunction
    %assign filePkg = "Simulink"
     
  %else
    %% MSPackage controls actual path of TLCFileName. Not RTWInfo package.
    %assign filePkg = cscDefn.MSPackage
  %endif
   
  %assign fileName = cscDefn.TLCFileName
 
  %if ISEMPTY(fileName)
    %assign fileName = cscName + ".tlc"
  %endif
 
  %return ["%<filePkg>", "%<fileName>"]
   
%endfunction %% of FcnGetTLCFilePackageAndName()
 
 
%%=============================================================================
%function SLibGetGenerateTypeForName(rtwInfoPkg, cscName) void
  %assign filePkgAndName = FcnGetTLCFilePackageAndName(rtwInfoPkg, cscName)
 
  %assign genType = filePkgAndName[0] + "::" + filePkgAndName[1]
   
  %return genType
%endfunction
 
 
%%=============================================================================
%function SLibGetGenerateTypeForCSC(record) void
  %assign rtwInfoPkg = record.Package
    %% RTWInfo package. May not be same as cscDefn.OwnerPackage.
 
  %assign cscName = record.Name
 
  %return SLibGetGenerateTypeForName(rtwInfoPkg, cscName)
%endfunction
 
%%=============================================================================
%%Abstract:
%%ReturntheGenerateTypeattributeoftherecord.TheGenerateTypeattribute
%%isafunctionoftheCSCNameandPackageNameoftherecord.
%%TheGenerateTypeattributeisaddedtotherecordatTLCsetupstage.See
%%FcnAddCustomDatainglobalmaplib.tlc
%function SLibGetGenerateTypeForData(record) void
   
  %return record.GenerateType
 
%endfunction
 
 
 
%%Function:LibGetSLDataObjectInfo================================================
%%Abstract:
%%ReturntherequestedpropertyvalueoftheSimulinkdataobjectassociated
%%withadatarecord
%function LibGetSLDataObjectInfo(record, property) void
  
  %if !ISFIELD(record, "Object") || !ISFIELD(record.Object, "ObjectProperties")
      %assign errTxt = "Invalid record for requesting data object property"
      %<LibReportFatalError(errTxt)>
  %endif
 
  %assign baseProps = record.Object.ObjectProperties
  %assign RTWInfoProps = LibGetRTWInfoObjectProperties(record)
  %assign cusAttriProps = LibGetCustomStorageAttributes(record)
  %if ISEQUAL(property,"Class")
      %assign propValue = record.Object.Class
      %return propValue
  %elseif ISEQUAL(property,"DataType")
      %assign propValue = DataTypes.DataType[LibGetRecordDataTypeId(record)].DTName
      %return propValue
  %else
      %if ISFIELD(baseProps, property)
        %assign propValue = GETFIELD(baseProps, property)
        %return propValue
      %elseif ISFIELD(RTWInfoProps, property)
        %assign propValue = GETFIELD(RTWInfoProps, property)
        %return propValue
      %elseif ISFIELD(cusAttriProps, property)
        %assign propValue = GETFIELD(cusAttriProps, property)
        %return propValue
      %else
        %assign errTxt = "Invalid property %<property>"
        %<LibReportFatalError(errTxt)>
      %endif
  %endif
 
%endfunction
 
%endif %% _CUSTOMSTORAGELIB_
 
%%Function:FcnGetTLCPathFromPackageName================================================
%%Abstract:
%%Returnspathoftlccodeforcustomstorageclasses.
 
%function FcnGetTLCPathFromPackageName(filePkg, toTLCName) void
   
  %assign tmpstr = "fileparts(which('%<filePkg>.csc_registration'))"
  %% Need to use FEVAL("eval" since which('pkg.class') needs to be
  %% evaluated before evaluating file parts
  %assign filePkgPath = FEVAL("eval", tmpstr)
 
  %return "%<filePkgPath>/tlc/%<toTLCName>"
   
%endfunction
 
%%Function:SLibIsIntegerDataTypeNotSizeofTargetInt==========================================
%%Abstract:
%%IntegerSizeMismatchprovidesanAPIforcheckingwhetherthesizeof
%%anintegerspecifiedviamodelmatcheswiththeintegersizeoftargetplatform
%%
%%NOTE:
%%ReferencefunctionSLibGetFormattedValueFromIdforitshandlingtypecastingonnumericvalue
%function SLibIsIntegerDataTypeNotSizeofTargetInt(id)
 
  %assign dTypeId = LibGetDataTypeIdAliasedThruToFromId(id)
  %assign dTypeStorageId = LibGetDataTypeStorageIdFromId(dTypeId)
  %switch dTypeStorageId
     %case tSS_UINT8
     %case tSS_UINT16
     %case tSS_UINT32
     %case tSS_INT8
     %case tSS_INT16
     %case tSS_INT32
        %% function LibGetDataTypeSLSizeFromId() does not return real size of data type
        %% specified by model (e.g. target supports 24-bit short, datatye is fixdt(0,22,1,0))
        %if DataTypes.DataType[dTypeId].ActualBits != IntegerSizes.IntNumBits
            %return TLC_TRUE
        %endif
        %break
     %default
        %break
  %endswitch
  %return TLC_FALSE
%endfunction
 
%%Function:LibDoesStringContainDot===========================================
%function LibDoesStringContainDot(inputStr) void
  %assign result = TLC_FALSE
  %assign len = SIZE(inputStr,1)
  %foreach idx = len
    %if inputStr[idx] == "."
      %assign result = TLC_TRUE
      %break
    %endif
  %endforeach
   
  %return result
%endfunction
 
%%Function:LibDoesStringContainDot===========================================
%function LibDoesStringContainDotOrArrow(inputStr) void
  %assign result = TLC_FALSE
  %assign len = SIZE(inputStr,1)
  %foreach idx = len
    %if inputStr[idx] == "."
      %assign result = TLC_TRUE
      %break
    %endif
    %if inputStr[idx] == "-" && ...
      (idx + 1 <= len) && ...
      inputStr[idx+1] == ">"
      %assign result = TLC_TRUE
      %break
    %endif
  %endforeach
  %return result
%endfunction
 
%%Function:FcnGetElementDataTypeFromIndexInfo===========================
%%Abstract:Getsthedatatypeofastructurefieldwiththegivenindex
%%information.ReturnsboththedatatypeIDandthestructurefieldindex
%%asatwoelementarray:[dataTypeId,fieldIndex]
%function FcnGetElementDataTypeFromIndexInfo(structTypeId, indexInfo) void
  %assert (LibIsStructDataType(structTypeId))
  %assign retVal = ""
  %foreach idx = LibDataTypeNumElements(structTypeId)
    %assign eName = LibDataTypeElementName(structTypeId, idx)
    %assign translatedEName = FEVAL("regexptranslate", "escape", eName)
    %assign pat = "^//[//d+//]//.%<translatedEName>//." + "|"
    %assign pat = pat + "^//.%<translatedEName>//." + "|"
    %assign pat = pat + "^//[//d+//]//.%<translatedEName>(//[(/////*.*//*///)?//d+//])+" + "|"
    %assign pat = pat + "^//.%<translatedEName>(//[(/////*.*//*///)?//d+//])+" + "|"
    %assign pat = pat + "^//.%<translatedEName>$"
    %assign resultingIndexInfo = FEVAL("regexprep", indexInfo, pat, "")
    %if !ISEQUAL(resultingIndexInfo, indexInfo)
      %assign eId = LibDataTypeElementDataTypeId(structTypeId, idx)
      %if ISEMPTY(resultingIndexInfo)
        %assign retVal = [%<eId>, %<idx>]
      %else
        %if resultingIndexInfo[0] != "."
          %assign resultingIndexInfo = ".%<resultingIndexInfo>"
        %endif
        %assert (LibIsStructDataType((eId)))
        %assign retVal = FcnGetElementDataTypeFromIndexInfo(eId, resultingIndexInfo)
      %endif
      %return retVal
    %endif
  %endforeach
  %assert (!ISEMPTY(retVal))
%endfunction
 
%%Function:FcnNonVolatilePointerCast======================================
%%Abstract:
%%Returnthecodenecessarytocastawaythevolatilityofapointertothe
%%givendatatype.Iftheprovidedmemorysectiondefinitiondoesnotspecify
%%volatilethenreturntheemptystring.
%%TopTester:test/toolbox/simulink/variants/codevariants/tvss_code_variants.m
%%
%function FcnNonVolatilePointerCast(msDefn, dtypeId, cmplx, indexInfo) void
 
  %assign cast = ""
      
  %if msDefn.IsVolatile
 
    %assign constCast = ""
    %if msDefn.IsConst
      %assign constCast = "const "
    %endif
     
    %% If indexInfo contains a dot, virtual bus selection is involved
    %if LibIsStructDataType(dtypeId) && LibDoesStringContainDot(indexInfo)
      %assign retFieldInfo = FcnGetElementDataTypeFromIndexInfo(dtypeId, indexInfo)
      %assign eId = retFieldInfo[0]
      %if !ISEMPTY(eId)
        %assign fieldIdx = retFieldInfo[1]
        %assign cmplx = LibDataTypeElementIsComplex(dtypeId, fieldIdx)
        %assign dtypeId = eId
      %endif
    %endif
 
    %if cmplx
      %assign dtypeName = LibGetDataTypeComplexNameFromId(dtypeId)
    %else
      %assign dtypeName = LibGetDataTypeNameFromId(dtypeId)
    %endif
 
    %assign cast = "(%<constCast>%<dtypeName> *)"
  %endif
    
  %return cast
%endfunction
 
%%Function:LibGetNonVolatilePointerCast======================================
%%Abstract:
%%Returnthecodenecessarytocastawaythevolatilityofapointertothe
%%givenrealdatatype.Iftheprovidedmemorysectiondefinitiondoesnotspecify
%%volatilethenreturntheemptystring.
%function LibGetNonVolatilePointerCast(msDefn, dtypeId, indexInfo) void
 
  %return FcnNonVolatilePointerCast(msDefn, dtypeId, TLC_FALSE, indexInfo)
   
%endfunction
 
%%Function:LibGetNonVolatileCmplxPointerCast=================================
%%Abstract:
%%Returnthecodenecessarytocastawaythevolatilityofapointertothe
%%givenpotentiallycomplexdatatype.Iftheprovidedmemorysectiondefinition
%%doesnotspecifyvolatilethenreturntheemptystring.
%function LibGetNonVolatileCmplxPointerCast(msDefn, dtypeId, cmplx, indexInfo) void
 
  %return FcnNonVolatilePointerCast(msDefn, dtypeId, cmplx, indexInfo)
   
%endfunction
 
 
%%Function:SLibIsAuxBufferForReusableCSC======================================
%%Abstract:
%%ReturniftherecordisanauxiliarybufferofareusableCSC
%function SLibIsAuxBufferForReusableCSC(record) void
  %return (record.StorageClass == "Custom" && SLibGetIsReusable(record)) && ...
    ISFIELD(record, "ReuseBufferName") && ...
    record.ReuseBufferName != record.Identifier
%endfunction
 
%%Function:SLibHasReusableCSCWithoutReusableBuffer(record)
%%Abstract:
%%Returnstrueiffagivenrecordisreusablebutdoesnotneedanauxiliarybuffer.
%function SLibHasReusableCSCWithoutReusableBuffer(record) void
  %return (record.StorageClass == "Custom" && SLibGetIsReusable(record)) && ...
    !ISFIELD(record, "ReuseBufferName")
%endfunction
 
%%Function:SLibIsAuxBufferForReusableCSCOrAutoSar=============================
%%Abstract:
%%ReturniftherecordisanauxiliarybufferofareusableCSCoranAutoSar
%%buffer
%function SLibIsAuxBufferForReusableCSCOrAutoSar(record) void
  %return ((record.StorageClass == "Custom" && SLibGetIsReusable(record)) || ...
    ISFIELD(record, "AutosarPRPortVarIdx")) && ...
    ISFIELD(record, "ReuseBufferName") && ...
    record.ReuseBufferName != record.Identifier
%endfunction
 
%%[EOF]customstoragelib.tlc