%%
%%
%%
%%
%%Copyright1994-2019TheMathWorks,Inc.
%%
%%Abstract:
%%ThissystemTLClibraryfilecontainsfunctionsthatarecommon
%%betweenthedifferentcodegeneratorsforproducingthethemodel's
%%blockIOstructuredefinition.
 
%if EXISTS("_COMMONHDR_BLKIOLIB_") == 0
%assign _COMMONHDR_BLKIOLIB_ = 1
 
 
%%============================================================================
%%Createglobalcachevariablestoholdeachstructuredefinition
%%============================================================================
 
%<LibAddToCompiledModel("BlockIOStructDefn", 0)>
%<LibAddToCompiledModel("ConstBlockIOStructDefn", 0)>
 
%%TopTester:test/toolbox/simulink/variants/inlineVariants/ivGeneral/tIVfcnCall_neg.m
%%
%function FcnGenBlockIODefNotHandledInVarGroup(bo)
  %openfile retBuf
  %assign blkName = SLibGrBlockName(bo.GrSrc)
  %assign boId = LibGetRecordIdentifier(bo)
  %if bo.DeclareAsPointer == "yes" || bo.Autosar4p0ImplicitRead == "yes"
    %with bo
      %assign comment = "/* " + SLibGrBlockCommentName(GrSrc) + " */"
      %assign dataType = SLibGetRecordDataTypeName(bo, "")
      %assign width = LibGetRecordWidth(bo)
      %assign optWidth = LibOptionalVectorWidth(width)
       
      %assert SLibAutosarActive()
      %assign constPrefix = SLibAutosarGetPtrConstPrefix()
      %if width > 1
        %if bo.Autosar4p0ImplicitRead == "yes"
          %<constPrefix> %<dataType> *%<boId>; %<comment>
        %else
          %<constPrefix> %<dataType> (*%<boId>)%<optWidth>; %<comment>
        %endif
      %else
        %<constPrefix> %<dataType> *%<boId>; %<comment>
      %endif
    %endwith
  %else
    %if bo.BitFieldWidth > 0
      %with bo
        %assign bitfldtype = SLibGetTypeForBitfield(BitFieldWidth)
        %assign comment = "/* '" + SLibGrBlockName(GrSrc) + "' */"
        %<bitfldtype> %<boId>:%<BitFieldWidth>; %<comment>
      %endwith
    %endif
  %endif
  %closefile retBuf
   
  %if !ISEMPTY(retBuf)
    %assign traceMarker = SLibAddBlockTrace(blkName)
    %assign retBuf = "%<SLibTraceBegin(traceMarker)>%<retBuf>%<SLibTraceEnd(traceMarker)>"
  %endif
  %return retBuf
%endfunction
 
%%Function:LibCacheSystemBlkIOStructDef======================================
%%Abstract:
%%CachethedefinitionofthesystemBlockIOstructure.
%%TopTester:test/toolbox/simulink/variants/codevariants/tcodevariants9.m
%%
%function LibCacheSystemBlkIOStructDef(sysIdx) void
  %if !SLibSystemHasOwnDataScope(System[sysIdx])
    %return
  %endif
  %assign blockioBuff = SLibGetSystemDataDefUsingVarGroup(sysIdx,"BlockIO", TLC_FALSE)
  %assign blockIoDef = ""
  %assign identifierTag = ""
  %if (sysIdx < (NumSystems-1))
    %if !GenerateClassInterface || !IsModelReferenceBaseSys(System[sysIdx])
      %assign identifier = FcnSysVarGroupType(System[sysIdx],"BlockIO")
    %else
      %assign identifier = ::tBlockIOType
    %endif
    %assign sysInfo = GetSystemNameForComments(System[sysIdx])
    %openfile comment
    /* Block signals for %<sysInfo> */
    %closefile comment
  %else
    %assign ::CompiledModel.BlockIOStructDefn = ...
      WHITE_SPACE(blockioBuff[0])?"":"NonEmpty"
    %assign identifier = ::tBlockIOType
    %if SLibAutosarActive()
      %assign identifierTag = ::CompiledModel.GlobalScope.tBlockIOTypeTag
    %endif
    %openfile comment
    /* Block signals (%<::AutoOrDefaultStorageClass> storage) */
    %closefile comment
  %endif
  %%
  %assign userTypes = LibDumpTypedefsCache()
 
  %% If the user defines some types in a SFcn, ensure that they go to
  %% model_types.h instead of model.h. Since the file model_types.h is
  %% included by the subsystem header file, the type will be available to
  %% the subsystem just in case it needs it. Ref geck: g1833321
  %if userTypes!=""
    %openfile userTypedef
    %<userTypes>
    %closefile userTypedef
     
    %if System[sysIdx].Type == "root"
      %<SLibCacheCodeToFile("mdl_data_typedef", userTypedef)>
    %else
      %<SLibCacheSystemCodeToFile("sys_data_BIO_typedef", System[sysIdx], userTypedef)>
    %endif
  %endif
 
  %% Reset the cache after the types are dumped
  %assign ::CompiledModel.TypedefsCache = ""
  %if blockioBuff[1] > 0
    %openfile blockIoDef
    %if blockioBuff[1] > 0
        %<comment>/
        %assign nonInlSysIdx = System[sysIdx].NonInlinedParentSystemIdx
        %assign needToExportDWork = LibSystemIsReusedLibraryFcn(System[nonInlSysIdx]) || ...
          SLibModelHasServicePortDWork()
        %if !needToExportDWork
          %<GetHideChildDefineSymbol("ifndef")>/
        %endif
        %assign align = -1
        %if structDAFlag.supported && !fieldDAFlag.supported
          %assign align = blockioBuff[2]
        %endif
        %<SLibDumpStructDefWithAlignment(identifierTag, identifier, align, blockioBuff[0])>
        %if !needToExportDWork
          %<GetHideChildDefineSymbol("endif")>/
        %endif
    %endif
    %closefile blockIoDef
  %endif
  %%
   
  %if SLibIsSystemTypesModelClassNamespace(System[sysIdx])
    %<SLibCacheCPPEncapModelData("Typedefs", blockIoDef)>
  %else
    %<SLibCacheSystemCodeToFile("sys_data_BIO_typedef", System[sysIdx], blockIoDef)>
  %endif
%endfunction
 
%%Function:LibCacheSystemConstBlkIOStructDef=================================
%%Abstract:
%%CachethedefinitionofthesystemconstantBlockIOstructure.
%%TopTester:test/toolbox/simulink/variants/vssSigObj/tVSSSigObj.m
%%TopTester:test/toolbox/simulink/variants/normalMATLABVariableSupport/tNormalMatlabVariable2.m
%%TopTester:test/toolbox/simulink/variants/modelVariants/tVariantsBasic.m
%%
%function LibCacheSystemConstBlkIOStructDef(sysIdx) void
  %if !SLibSystemHasOwnDataScope(System[sysIdx])
    %return
  %endif
  %assign blockioBuff = SLibGetSystemDataDefUsingVarGroup(sysIdx, "ConstBlockIO", TLC_FALSE)
  %assign blockIoDef = ""
  %assign trailer = ""
  %assign identifierTag = ""
   
  %if (sysIdx < (NumSystems-1))
    %assign identifier = FcnSysVarGroupType(System[sysIdx],"ConstBlockIO")
    %assign varGrpIdx = FcnSysVarGroupIndex(System[sysIdx],"ConstBlockIO",0)
    %if varGrpIdx >= 0 && ::GenCPP
      %assign identifierTag = ::CompiledModel.VarGroups.VarGroup[varGrpIdx].VarGroupTypeTag
    %endif
 
    %assign sysInfo = GetSystemNameForComments(System[sysIdx])
    %openfile comment
    /* Invariant block signals for %<sysInfo> */
    %closefile comment
  %else
    %assign ::CompiledModel.ConstBlockIOStructDefn = ...
      WHITE_SPACE(blockioBuff[0])?"":"Nonempty"
    %assign identifier = ::tConstBlockIOType
    %if ::GenCPP
      %assign identifierTag = ::CompiledModel.GlobalScope.tConstBlockIOTypeTag
    %endif
    %openfile comment
    /* Invariant block signals (%<::AutoOrDefaultStorageClass> storage) */
    %closefile comment
    %%
    %% The #define below is not done for RealTime because of name clash
    %if (CodeFormat != "RealTime" && !SLibIsERTCodeFormat())
      %openfile trailer
      /* For easy access from the SimStruct */
      %assign str = "(%<::tConstBlockIOType> *) " ...
        "%<RTMuGet("ConstBlockIO")>"
      #define %<::tConstBlockIOStruct> (%<str>)
       
      %undef str
      %closefile trailer
    %endif
  %endif
   
  %assign constQualifier = ((::GenCPP) ? "const" : "")
  %if blockioBuff[1] > 0
    %openfile blockIoDef
    %if blockioBuff[1] > 0
 
    %<comment>/
    %assign nonInlSysIdx = System[sysIdx].NonInlinedParentSystemIdx
    %assign needToExportDWork = LibSystemIsReusedLibraryFcn(System[nonInlSysIdx]) || ...
      SLibModelHasServicePortDWork()
    %if !needToExportDWork
      %<GetHideChildDefineSymbol("ifndef")>/
    %endif
    %assign align = ""
    %if structDAFlag.supported && blockioBuff[2] > 0
      %assign align = SLibGetAlignmentSyntax(::CompiledModel.Name, identifier, "", ...
                                             blockioBuff[2], "DATA_ALIGNMENT_WHOLE_STRUCT")
    %endif
    %if align != ""
      %if structDAFlag.position == "DATA_ALIGNMENT_PREDIRECTIVE"
        typedef %<constQualifier> struct %<align> %<identifierTag> {
      %elseif structDAFlag.position == "DATA_ALIGNMENT_PRECEDING_STATEMENT"
        %<align>
        typedef %<constQualifier> struct %<identifierTag> {
      %else
        typedef %<constQualifier> struct %<identifierTag> {
      %endif
    %else
      typedef %<constQualifier> struct %<identifierTag> {
    %endif
      %
    %if align != ""
      %if structDAFlag.position == "DATA_ALIGNMENT_POSTDIRECTIVE"
        } %<identifier> %<align>;
      %elseif structDAFlag.position == "DATA_ALIGNMENT_FOLLOWING_STATEMENT"
        } %<identifier>;
        %<align>
      %else
        } %<identifier>;
      %endif
    %else
      } %<identifier>;
    %endif
    %<trailer>/
    %if !needToExportDWork
      %<GetHideChildDefineSymbol("endif")>/
    %endif
    %endif
    %closefile blockIoDef
  %endif
  %%
  %if SLibIsSystemTypesModelClassNamespace(System[sysIdx])
    %<SLibCacheCPPEncapModelData("Typedefs", blockIoDef)>
  %else
    %<SLibCacheSystemCodeToFile("sys_data_constBIO_typedef", System[sysIdx], blockIoDef)>
  %endif
%endfunction
 
 
%%Function:LibBlockIOStructIsEmpty==========================================
%%Abstract:
%%DoestherootsystemhaveanyblockIO?
%%TopTester:test/toolbox/simulink/variants/vssSigObj/tVSSSigObj.m
%%
%function LibBlockIOStructIsEmpty() void
  %assign baseSysIdx = GetBaseSystemIdx()
  %assert (LibGetFieldSet(System[baseSysIdx], "HasBlockIOArg") == 1)
  %assert !((::CompiledModel.DWorkAndBlockIOCombined == 1) && ...
    (System[baseSysIdx].HasBlockIOArg == 1))
  %return (System[baseSysIdx].HasBlockIOArg == 0)
%endfunction
 
%%Function:SLibModelBlockIOStructIsEmpty=====================================
%%Abstract:
%%DoesthemodelhaveanyblockIO.
%%
%function SLibModelBlockIOStructIsEmpty() void
  %assert !((::CompiledModel.DWorkAndBlockIOCombined == 1) && ...
    (::CompiledModel.HasBlockIOArg == 1))
  %return (::CompiledModel.HasBlockIOArg == 0)
%endfunction
 
 
%%Function:LibConstBlockIOStructIsEmpty=====================================
%%Abstract:
%%DoestherootsystemhaveanyconstBlockIO?
%%
%function LibConstBlockIOStructIsEmpty() void
  %assign baseSysIdx = GetBaseSystemIdx()
  %assert (LibGetFieldSet(System[baseSysIdx], "HasConstBlockIOArg") == 1)
  %return (System[baseSysIdx].HasConstBlockIOArg == 0)
%endfunction
 
%%Function:SLibModelConstBlockIOStructIsEmpty================================
%%Abstract:
%%DoesthemodelhaveanyconstBlockIO.
%%
%function SLibModelConstBlockIOStructIsEmpty() void
  %return (::CompiledModel.HasConstBlockIOArg == 0)
%endfunction
 
%%Function:SLibVerifyBlockOutputPorts========================================
%%Abstract:
%%Verifythatforeachdataoutputportintheglobalblockoutputsandthe
%%localblockoutputspointstothecorrectrecordinthesystem.
%%TopTester:test/toolbox/simulink/variants/CondExecutedVSS/tContPortGecks.m
%%
%function SLibVerifyBlockOutputPorts() void
  %% Check the global block outputs.
  %foreach boIdx = ::CompiledModel.BlockOutputs.NumGlobalBlockOutputs
    %assign blkOut = ::CompiledModel.BlockOutputs.GlobalBlockOutput[boIdx]
    %if SLibOmitRecord(blkOut) || ISEMPTY(blkOut.SigSrc)
      %continue
    %endif
    %assign sysIdx = blkOut.SigSrc[0]
    %assign blkIdx = blkOut.SigSrc[2]
    %assign portIdx = blkOut.SigSrc[3]
    %assign block = ::CompiledModel.System[sysIdx].Block[blkIdx]
    %%
    %% The opaque block always lives in the root system, so we won't be able
    %% to trace canonical outputs correctly. This code will be removed,
    %% once we depricate input and output port records of the opaque block.
    %% Those are only maintained to facilitate TLC code that is not part of
    %% the main code generation.
    %%
    %if block.Type == "Opaque"
      %continue
    %endif
    %assign port = block.DataOutputPort[portIdx]
    %assign idNum = IDNUM(port.SignalSrc[0])
     
    %if idNum[0] == "y" %% The block output can point to a canonical output of a
      %continue %% reusable subsystem. In this case the signal can't be
    %endif %% traced back directly.
    %assign boId1 = LibGetRecordIdentifier(blkOut)
    %assign reverseBlkOut = ::CompiledModel.BlockOutputs.GlobalBlockOutput[idNum[1]]
    %assign boId2 = LibGetRecordIdentifier(reverseBlkOut)
     
    %if boId1 != boId2
      %warning %<boId1> != %<boId2>
      %warning LogicalSource == %<reverseBlkOut.LogicalSrc>
      %return TLC_FALSE
    %endif
  %endforeach
 
  %return TLC_TRUE
%endfunction
 
 
%endif %% _COMMONHDR_BLKIOLIB_