%% ==============================================================================
%% $RCSfile: codetemplatelib.tlc,v $
%% $Revision: 1.10.4.12 $
%% $Date: 2004/12/16 21:20:43 $
%%
%% Abstract:
%%   Output file template library
%%
%% Copyright 1994-2004 The MathWorks, Inc.
%%
%selectfile NULL_FILE

%% =============================================================================
%% Public functions
%% =============================================================================

%% DocFunction{Code Configuration Functions}: LibGetNumSourceFile ===============
%% Abstract:
%%   Get the number of source files (.c and .h) that have been created.
%%
%% Call syntax:
%%   %assign numFiles = LibGetNumSourceFiles()
%%
%% Returns:
%%   Returns the number of files (Number).

%function LibGetNumSourceFiles() void
  %return LibGetNumModelFiles()
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetSourceFileTag ===============
%% Abstract:
%%   Returns <fileName>_h and <fileName>_c for header and source files,
%%   respectively where fileName is the name of the model file.
%%
%% Call syntax:
%%   %assign tag = LibGetSourceFileTag(fileIdx)
%%
%% Arguments:
%%   fileIndex (Number) - File index.
%%
%% Returns:
%%   Returns the tag (String).

%function LibGetSourceFileTag(fileIdx) void
  %return LibGetModelFileTag(fileIdx)
%endfunction

%% DocFunction{Code Configuration Functions}: LibCreateSourceFile ===============
%% Abstract:
%%   Create a new C file, and return its reference.  If the file already exists,
%%   simply return its reference.
%%
%% Call syntax:
%%   %assign fileH = LibCreateSourceFile("Source", "Custom", "foofile")
%%
%% Arguments:
%%   type (String):
%%     Valid values are "Source" and "Header" for .c and .h files,
%%     respectively.
%%
%%   creator (String):
%%     Who's creating the file?  An error is reported if different creators
%%     attempt to create the same file.
%%
%%   name (String):
%%     Base name of the file (i.e., without the extension).
%%
%% Note: File are not written to disk if they are empty.
%%
%% Returns:
%%   Reference to the model file (Scope).

%function LibCreateSourceFile(type,creator,name) void
  %assign type = (type == "Source") ? "SystemBody" : "SystemHeader"
  %return SLibAddModelFile(type,creator,name)
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetSourceFileFromIdx ===========
%% Abstract:
%%   Return a model file reference based on its index.  This is very useful
%%   for a common operation on all files.  For example, to set the leading file
%%   banner of all files.
%%
%% Call syntax:
%%   %assign fileH = LibGetSourceFileFromIdx(fileIdx)
%%
%% Arguments:
%%   fileIdx (Number): Index of model file (that is internally managed by RTW).
%%
%% Returns:
%%   Reference (Scope) to the model file.

%function LibGetSourceFileFromIdx(fileIdx) void
  %return ModelFiles.ModelFile[fileIdx]
%endfunction

%% DocFunction{Code Configuration Functions}: LibSetSourceFileSection ===========
%% Abstract:
%%   Add to the contents of a file.  Valid attributes include:
%%
%%   Banner            - Set the file banner (comment) at the top of the file.
%%   Includes          - Append to the #include section.
%%   Defines           - Append to the #define section.
%%   IntrinsicTypes    - Append to the intrinsic typedef section.  Intrinsic
%%                       types are those that only depend on intrinsic C types.
%%   PrimitiveTypedefs - Append to the primitive typedef section.  Primitive
%%                       typedefs are those that only depend on intrinsic C types
%%                       and any typedefs previously defined in the
%%                       IntrinsicTypes section.
%%   UserTop           - Append to the "user top" section.
%%   Typedefs          - Append to the typedef section.  Typedefs can depend on
%%                       any previously defined type.
%%   Enums             - Append to the enumerated types section.
%%   Definitions       - Append to the data definition section.
%%   ExternData        - (reserved) RTW extern data.
%%   ExternFcns        - (reserved) RTW extern functions.
%%   FcnPrototypes     - (reserved) RTW function prototypes.
%%   Declarations      - Append to the data declaration section.
%%   Functions         - Append to the C functions section.
%%   CompilerErrors    - Append to the #warning section.
%%   CompilerWarnings  - Append to the #error section.
%%   Documentation     - Append to the documentation (comment) section.
%%   UserBottom        - Append to the "user bottom" section.
%%
%%  Code is emitted by Real-Time Workshop in the order in which it is listed
%%  above.
%%
%%  Example call syntax (iterating over all file):
%%
%%  %openfile tmpBuf
%%    whatever
%%  %closefile tmpBuf
%%
%%  %foreach fileIdx = LibGetNumSourceFiles()
%%    %assign fileH = LibGetSourceFileFromIdx(fileIdx)
%%    %<LibSetSourceFileSection(fileH,"SectionOfInterest",tmpBuf)>
%%  %endforeach
%%
%%  %assign fileH = LibCreateSourceFile("Header","Custom","foofile")
%%  %<LibSetSourceFileSection(fileH,"Defines","#define FOO 5.0\n")
%%
%%  Arguments:
%%    fileH   - Reference or index to a file (Scope or Number).
%%    section - File section of interest (String).
%%    value   - Value (String).

%function LibSetSourceFileSection(fileH, section, value) void
  %if TYPE(fileH) != "Scope"
    %if TYPE(fileH) == "Number"
      %assign fileH = ModelFiles.ModelFile[fileH]
    %else
      %assign errTxt = "LibSetSourceFileSection expects a reference or " ...
	"and index to a file.  It was passed a %<TYPE(fileH)>"
      %<LibReportError(errTxt)>
    %endif
  %endif
  %if section == "ExternData" || section == "ExternFcns" || section == "FcnPrototypes"
    %assign errTxt = "%<section> is reserved for Real-Time Workshop."
    %setcommandswitch "-v1"
    %<LibReportError(errTxt)>
  %endif
  %<SLibSetModelFileAttribute(fileH,section,value)>
%endfunction

%% Function: LibGetSourceFileSection ============================================
%% Abstract:
%%   Get the contents of a file.  See LibSetSourceFileSection for list of valid
%%   sections.
%%
%%  Arguments:
%%    fileIndex - Reference or index to a file (Scope or Number).
%%    section   - File section of interest (String).

%function LibGetSourceFileSection(fileIdx, section) void
  %if TYPE(fileIdx) != "Number"
    %if TYPE(fileIdx) == "Scope"
      %assign fileIdx = fileIdx.Index
    %else
      %assign errTxt = "LibGetSourceFileSection expects an index or a " ...
	"reference to a file."
      %<LibReportError(errTxt)>
    %endif
  %endif
  %return LibGetModelFileAttribute(fileIdx,section)
%endfunction

%% Function: LibGetSourceFileIndent ============================================
%% Abstract:
%%   Get the Indent flag of a file.
%%
%%  Arguments:
%%    fileIndex - Reference or index to a file (Scope or Number).

%function LibGetSourceFileIndent(fileIdx) void
  %if TYPE(fileIdx) != "Number"
    %if TYPE(fileIdx) == "Scope"
      %assign fileIdx = fileIdx.Index
    %else
      %assign errTxt = "LibGetSourceFileSection expects an index or a " ...
	"reference to a file."
      %<LibReportError(errTxt)>
    %endif
  %endif
  %return ModelFiles.ModelFile[fileIdx].Indent
%endfunction

%% Function: LibGetSourceFileShared ============================================
%% Abstract:
%%   Get the Shared flag of a file.
%%
%%  Arguments:
%%    fileIndex - Reference or index to a file (Scope or Number).

%function LibGetSourceFileShared(fileIdx) void
  %if TYPE(fileIdx) != "Number"
    %if TYPE(fileIdx) == "Scope"
      %assign fileIdx = fileIdx.Index
    %else
      %assign errTxt = "LibGetSourceFileSection expects an index or a " ...
	"reference to a file."
      %<LibReportError(errTxt)>
    %endif
  %endif
  %return ModelFiles.ModelFile[fileIdx].Shared
%endfunction

%% Function: LibIndentSourceFile ================================================
%% Abstract:
%%   Indent a file with RTW's c_indent utility (from within TLC environment).
%%
%% Call syntax:
%%   %<LibIndentSourceFile("foofile.c","")>
%%
%% Arguments:
%%   name - Name of file (String).
%%   opts - options to pass c_indent.

%function LibIndentSourceFile(name,opts) void
  %<SLibIndentFile(name,opts)>
%endfunction

%% DocFunction{Code Configuration Functions}: LibSetSourceFileCodeTemplate ======
%% Abstract:
%%   By default, *.c and *.h files are generated with the code templates
%%   specified in the RTW GUI.  This function allows you to change the
%%   the template for a file.  Uses the "Code templates" entered into the
%%   RTW Templates UI.
%%
%%   Note: Custom templates is a feature of RTW Embedded Coder.
%%
%% Call syntax:
%%   %assign tag = LibSetSourceFileCodeTemplate(opFile,name)
%%
%% Arguments:
%%   opFile (Scope)  - Reference to file
%%   name   (String) - Name of the desired template
%%
%% Returns:
%%   None

%function LibSetSourceFileCodeTemplate(opFile,name) void
  %<SLibSetModelFileAttribute(opFile,"CodeTemplate",name)>
%endfunction

%% DocFunction{Code Configuration Functions}: LibSetSourceFileOutputDirectory ===
%% Abstract:
%%   By default, *.c and *.h files are generated into the RTW build directory.
%%   This function allows you to change the default location.  Note that
%%   the caller is reponsible for specifying a valid directory.
%%
%% Call syntax:
%%   %assign tag = LibSetSourceFileOutputDirectory(opFile,dirName)
%%
%% Arguments:
%%   opFile  (Scope)  - Reference to file
%%   dirName (String) - Name of the desired output directory
%%
%% Returns:
%%   None

%function LibSetSourceFileOutputDirectory(opFile,name) void
  %<SLibSetModelFileAttribute(opFile,"OutputDirectory",name)>
%endfunction


%% DocFunction{Code Configuration Functions}: LibCallModelInitialize ============
%% Abstract:
%%   Returns necessary code for calling the model's initialize function (valid
%%   for ERT only).

%function LibCallModelInitialize() void
  %openfile tmpFcnBuf
  %<Name>_initialize(%<SLibModelFcnArgs("Initialize",TLC_TRUE,"")>);
  %closefile tmpFcnBuf
  %return tmpFcnBuf
%endfunction

%% DocFunction{Code Configuration Functions}: LibCallModelStep ==================
%% Abstract:
%%   Returns necessary code for calling the model's step function (valid
%%   for ERT only).

%function LibCallModelStep(tid) void
  %if LibIsSingleRateModel()
    %assign tid = ""
  %endif
  %openfile tmpFcnBuf
  %if CombineOutputUpdateFcns
    %<Name>_step(%<SLibModelFcnArgs("Output",TLC_TRUE,tid)>);
  %else
    %<Name>_output(%<SLibModelFcnArgs("Output",TLC_TRUE,tid)>);
    %<Name>_update(%<SLibModelFcnArgs("Update",TLC_TRUE,tid)>);
  %endif
  %closefile tmpFcnBuf
  %return tmpFcnBuf
%endfunction

%% DocFunction{Code Configuration Functions}: LibCallModelTerminate =============
%% Abstract:
%%   Returns necessary code for calling the model's terminate function (valid
%%   for ERT only).

%function LibCallModelTerminate() void
  %openfile tmpFcnBuf
  %if IncludeMdlTerminateFcn
    %<Name>_terminate(%<SLibModelFcnArgs("Terminate",TLC_TRUE,"")>);
  %endif
  %closefile tmpFcnBuf
  %return tmpFcnBuf
%endfunction

%% DocFunction{Code Configuration Functions}: LibCallSetEventForThisBaseStep ====
%% Abstract:
%%   Returns necessary code for calling the model's set events function (valid
%%   for ERT only).
%%
%% Args:
%%   buffername - Name of the variable used to buffer the events.  For the
%%                example ert_main.c this is "eventFlags".

%function LibCallSetEventForThisBaseStep(buffername) void
  %assign fcnName = "%<Name>_SetEventsForThisBaseStep"
  %openfile tmpFcnBuf
  %if MultiInstanceERTCode
    %<fcnName>(%<buffername>, %<tSimStruct>);
  %else
    %<fcnName>(%<buffername>);
  %endif
  %closefile tmpFcnBuf
  %return tmpFcnBuf
%endfunction

%% DocFunction{Code Configuration Functions}: LibWriteModelData =================
%% Abstract:
%%   Returns necessary data for the model (valid for ERT only).

%function LibWriteModelData() void
  %return SLibDeclareModelFcnArgs(TLC_TRUE)
%endfunction
  
%% DocFunction{Code Configuration Functions}: LibSetRTModelErrorStatus ==========
%% Abstract:
%%   Returns the code required set the model error status
%%
%% Args:
%%   str (String) - char * to a C string
%%
%% Call syntax:
%%   %<LibSetRTModelErrorStatus("\"Overrun\"")>;

%function LibSetRTModelErrorStatus(str) void
  %return RTMSetErrStat(str)
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetRTModelErrorStatus ==========
%% Abstract:
%%   Returns the code required to get the model error status
%%
%% Call syntax:
%%   %<LibGetRTModelErrorStatus()>;

%function LibGetRTModelErrorStatus() void
  %return RTMGetErrStat()
%endfunction

%% DocFunction{Sample Time Functions}: LibIsSingleRateModel =====================
%% Abstract:
%%   Return true if model is single rate and false otherwise.

%function LibIsSingleRateModel() void
  %assign rootSystem = System[NumSystems-1]
  %return LibIsSingleRateSystem(rootSystem)
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetModelName ===================
%% Abstract:
%%   Return name of the model (no extension)

%function LibGetModelName() void
  %return Name
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetMdlSrcBaseName ==============
%% Abstract:
%%   Return the base name of the model's main source (e.g., model.c) file

%function LibGetMdlSrcBaseName() void
  %return Name
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetMdlPubHdrBaseName ===========
%% Abstract:
%%   Return the base name of the model's public header (e.g., model.h) file

%function LibGetMdlPubHdrBaseName() void
  %return Name
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetMdlPrvHdrBaseName ===========
%% Abstract:
%%   Return the base name of the model's private header (e.g., model_private.h)
%%   file

%function LibGetMdlPrvHdrBaseName() void
  %return Name + "_private"
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetModelDocCFile ==============
%% Abstract:
%%   Get the record for the model.c file. Additional code can then be cached
%%   using LibSetSourceFileSection().
%%
%% Call syntax:
%%   %assign srcFile = LibGetModelDotCFile()
%%   %<LibSetSourceFileSection(srcFile, "Functions", mybuf)>
%% 
%% Returns:
%%   Returns the model.c source file record.

%function LibGetModelDotCFile() void
  %return LibCreateSourceFile("Source","Simulink",CompiledModel.Name)
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetModelDocHFile ==============
%% Abstract:
%%   Get the record for the model.h file. Additional code can then be cached
%%   using LibSetSourceFileSection().
%%
%% Call syntax:
%%   %assign hdrFile = LibGetModelDotHFile()
%%   %<LibSetSourceFileSection(hdrFile, "Functions", mybuf)>
%% 
%% Returns:
%%   Returns the model.h source file record.

%function LibGetModelDotHFile() void
  %return LibCreateSourceFile("Header","Simulink",CompiledModel.Name)
%endfunction

%% Function: LibIsSingleTasking =================================================
%% Abstract:
%%   Return true if the model is configured for singletasking execution and
%%   false otherwise (i.e., multitasking).

%function LibIsSingleTasking() void
  %return SLibSingleTasking()
%endfunction

%% DocFunction{Code Configuration Functions}: LibWriteModelInput ================
%% Abstract:
%%   Return the code necessary to write to a particular root input (i.e., a
%%   model inport block).  Valid for ERT only.
%%
%% Args:
%%   tid (Number):  Task identifier (0 is fastest rate and n is the slowest)
%%   rollThreshold: Width of signal before wrapping in a for loop.

%function LibWriteModelInput(tid,rollThreshold) void
  %openfile tmpFcnBuf
  %if MultiInstanceERTCode && !RootIOStructures
    %assign localUQualifier = "_"
  %else
    %assign localUQualifier = "."
  %endif
  %foreach idx = ExternalInputs.NumExternalInputs
    %assign extInp = CompiledModel.ExternalInputs.ExternalInput[idx]
    %with extInp
      %if TID == tid
	%assign rhs = "your_value"
	/* InportID: %<idx>, TaskID: %<tid> */
	%assign id = Identifier
	%assign optStr = ""
	%if StorageClass == "Auto"
	  %assign optStr = "%<tInput>%<localUQualifier>"
	%endif
	%if StorageClass == "ImportedExternPointer"
	  %assign id = "%<Identifier>_value"
	%endif
	%assign portWidth = Width
	%assign isComplex = (ComplexSignal=="yes")
	%if portWidth == 1
	  %if isComplex
	    %<optStr>%<id>.re = %<rhs>;
	    %<optStr>%<id>.im = %<rhs>;
	  %else
	    %<optStr>%<id> = %<rhs>;
	  %endif
	%elseif portWidth < rollThreshold
	  %foreach sigIdx = portWidth
	    %if isComplex
	      %<optStr>%<id>[%<sigIdx>].re = %<rhs>;
	      %<optStr>%<id>[%<sigIdx>].im = %<rhs>;
	    %else  
	      %<optStr>%<id>[%<sigIdx>] = %<rhs>;
	    %endif
	  %endforeach
	%else %% portWidth > rollThreshold
	  {
	    int i = 0;
	    for(i = 0; i < %<portWidth>; i++) {
	      %if isComplex
		%<optStr>%<id>[i].re = %<rhs>;
		%<optStr>%<id>[i].im = %<rhs>;
	      %else
		%<optStr>%<id>[i] = %<rhs>;
	      %endif
	    }
	  }
	%endif
      %endif
    %endwith %% extInp
  %endforeach
  %closefile tmpFcnBuf
  %return tmpFcnBuf
%endfunction

%% DocFunction{Code Configuration Functions}: LibWriteModelOutput ===============
%% Abstract:
%%   Return the code necessary to write to a particular root output (i.e., a
%%   model outport block).  Valid for ERT only.
%%
%% Args:
%%   tid (Number):  Task identifier (0 is fastest rate and n is the slowest)
%%   rollThreshold: Width of signal before wrapping in a for loop.

%function LibWriteModelOutput(tid,rollThreshold) void
  %openfile tmpFcnBuf
  %if MultiInstanceERTCode && !RootIOStructures
    %assign localYQualifier = "_"
  %else
    %assign localYQualifier = "."
  %endif
  %assign lhs = "your_variable"
  %foreach idx = ExternalOutputs.NumExternalOutputs
    %assign extOut       = ExternalOutputs.ExternalOutput[idx]
    %assign sysIdx       = extOut.Block[0]
    %assign blkIdx       = extOut.Block[1]
    %assign outportBlock = System[sysIdx].Block[blkIdx]
    %with System[sysIdx]
      %with outportBlock
	%if tid == TID
	  %assign portWidth = LibBlockInputSignalWidth(0)
	  /* OutportID: %<idx>, TaskID: %<tid> */
	  %if portWidth == 1
	    %if SLibExternalOutputIsVirtual(outportBlock)
	      %<lhs> = %<LibBlockInputSignal(0, "", "", 0)>;
	    %else
	      %<lhs> = %<tOutput>%<localYQualifier>%<Identifier>;
	    %endif
	  %elseif portWidth < rollThreshold
	    %foreach sigIdx = portWidth
	      %if SLibExternalOutputIsVirtual(outportBlock)
		%<lhs> = %<LibBlockInputSignal(0, "", "", sigIdx)>;
	      %else
		%<lhs> = %<tOutput>%<localYQualifier>%<Identifier>[%<sigIdx>];
	      %endif
	    %endforeach
	  %else %% portWidth > rollThreshold
	    {
	      int i = 0;
	      for(i = 0; i < %<portWidth>; i++) {
		%if SLibExternalOutputIsVirtual(outportBlock)
		  %<lhs>[i] = %<LibBlockInputSignal(0, "i", "", 0)>;
		%else
		  %<lhs>[i] = %<tOutput>%<localYQualifier>%<Identifier>[i];
		%endif
	      }
	    }
	  %endif
	%endif
      %endwith %% outportBlock
    %endwith %% System[sysIdx]
  %endforeach
  %closefile tmpFcnBuf
  %return tmpFcnBuf
%endfunction

%% DocFunction{Code Configuration Functions}: LibWriteModelInputs ===============
%% Abstract:
%%   Return the code necessary to write to root inputs (i.e., all the
%%   model inport blocks).  Valid for ERT only.

%function LibWriteModelInputs() void
  %openfile varbufs
  %foreach tid = LibNumDiscreteSampleTimes()
    %<LibWriteModelInput(tid,RollThreshold)>\
  %endforeach
  %closefile varbufs
  
  %if WHITE_SPACE(varbufs)
    %return ""
  %else
    %openfile tmpFcnBuf
    #if 0
    %<varbufs>\
    #endif
    %closefile tmpFcnBuf
    %return tmpFcnBuf
  %endif
%endfunction

%% DocFunction{Code Configuration Functions}: LibWriteModelOutputs ==============
%% Abstract:
%%   Return the code necessary to write to root outputs (i.e., all the
%%   model outport blocks).  Valid for ERT only.

%function LibWriteModelOutputs() void
  %openfile varbufs
  %foreach tid = LibNumDiscreteSampleTimes()
    %<LibWriteModelOutput(tid,RollThreshold)>\
  %endforeach
  %closefile varbufs
  
  %if WHITE_SPACE(varbufs)
    %return ""
  %else
    %openfile tmpFcnBuf
    #if 0
    %<varbufs>\
    #endif
    %closefile tmpFcnBuf
    %return tmpFcnBuf
  %endif
%endfunction

%% DocFunction{Sample Time Functions}: LibNumDiscreteSampleTimes ================
%% Abstract:
%%   Return the number of discrete sample times in the model

%function LibNumDiscreteSampleTimes() void
  %return NumSynchronousSampleTimes
%endfunction

%% DocFunction{Sample Time Functions}: LibNumAsynchronousSampleTimes ============
%% Abstract:
%%   Return the number of discrete sample times in the model

%function LibNumAsynchronousSampleTimes() void
  %return NumAsynchronousSampleTimes
%endfunction

%% DocFunction{Code Configuration Functions}: LibAddSourceFileCustomSection =====
%% Abstract:
%%   Add a custom section to a source file.  You must associate a custom
%%   section with one of the built-in sections: Includes, Defines, Types,
%%   Enums, Definitions, Declarations, Functions, or Documentation.
%%
%%   No action if the section already exists, except to report an error
%%   if a inconsistent built-in section association is attempted.
%%
%%   Only available with Real-Time Workshop Embedded Coder.
%%
%% Arguments:
%%   file           - Source file reference (Scope)
%%   builtInSection - Name of the associated built-in section (String)
%%   newSection     - Name of the new (custom) section (String)

%function LibAddSourceFileCustomSection(file,builtInSection,newSection) void
  %if CompiledModel.ConfigSet.IsERTTarget == TLC_FALSE
    %assign errTxt = "LibAddSourceFileCustomSection is only available with " ...
      "ERT-based (Real-Time Workshop Embedded Coder) targets."
    %<LibReportError(errTxt)>
  %endif
  %assign cc = file.CustomContents
  %if !ISFIELD(cc,newSection)
    %assign c = file.Contents
    %switch builtInSection
      %case "Types"
	%% Valid association, and required (note Types are associated with
	%% Typedefs since there is no built-in Types section)
	%assign section = "Typedefs"
	%assign isRequired = TLC_TRUE
	%break
      %case "Includes"
      %case "Defines"
      %case "Enums"
      %case "Definitions"
      %case "Declarations"
      %case "Functions"
	%% Valid association, and required
	%assign section = builtInSection
	%assign isRequired = TLC_TRUE
	%break
      %case "Documentation"
	%% Valid association, and not required
	%assign section = builtInSection
	%assign isRequired = TLC_FALSE
	%break
      %default
	%% Invalid association
	%assign errTxt = "You are attempting to associate '%<newSection>' " ...
	  "with '%<builtInSection>', which is not a valid association."
	%<LibReportError(errTxt)>
    %endswitch
    %addtorecord cc                 \
    CustomContent {                 \
      Name           newSection     \
      BuiltInSection section        \
      IsRequired     isRequired     \
      Value          ""             \
      IsRetrieved    TLC_FALSE      \
    }
    %addtorecord cc %<newSection> cc.CustomContent[cc.NumCustomContents]
    %assign cc.NumCustomContents = cc.NumCustomContents + 1
  %else
    %assign cs = cc.%<newSection>
    %if cs.BuiltInSection != builtInSection
      %assign errTxt = "Attempt to create a custom model file section " ...
	"'%<newSection>' with an '%<builtInSection>' association, " ...
	"however, this custom section has already been created " ...
	"with an '%<cs.BuiltInSection>' association."
      %<LibReportError(errTxt)>
    %endif
  %endif
%endfunction

%% DocFunction{Code Configuration Functions}: LibSetSourceFileCustomSection =====
%% Abstract:
%%   Set a custom section previously created with LibAddSourceFileCustomSection.
%%
%%   Only available with Real-Time Workshop Embedded Coder.
%%
%% Arguments:
%%   file   - Source file reference or index  (Scope or Number)
%%   attrib - Name of custom section          (String)
%%   value  - value to be appended to section (String)

%function LibSetSourceFileCustomSection(file,attrib,value) void
  %if TYPE(file) != "Scope"
    %if TYPE(file) == "Number"
      %assign file = ModelFiles.ModelFile[file]
    %else
      %assign errTxt = "LibSetSourceFileCustomSection expect a " ...
	"reference or an index to a file.  It was passed a: " ...
	"%<TYPE(file)>"
      %<LibReportError(errTxt)>
    %endif
  %endif
  %assign cc = file.CustomContents
  %if !ISFIELD(cc,attrib)
    %assign errTxt = "Attempt to set the value of an custom attribute " ...
      "that does not exist for source file %<file.Name>: %<attrib>."
    %<LibReportError(errTxt)>
  %endif
  %if !ISEMPTY(value) && !WHITE_SPACE(value)
    %assign cs = cc.%<attrib>
    %assign cs.Value = cs.Value + value
    %assign file.IsEmpty = TLC_FALSE
  %endif
%endfunction

%% DocFunction{Code Configuration Functions}: LibGetSourceFileCustomSection =====
%% Abstract:
%%   Get a custom section previously created with LibAddSourceFileCustomSection.
%%
%% Arguments:
%%   file   - Source file reference or index (Scope or Number)
%%   attrib - Name of custom section         (String)

%function LibGetSourceFileCustomSection(file,attrib) void
  %if TYPE(file) != "Scope"
    %if TYPE(file) == "Number"
      %assign file = ModelFiles.ModelFile[file]
    %else
      %assign errTxt = "LibGetSourceFileCustomSection expect a " ...
	"reference or an index to a file.  It was passed a: " ...
	"%<TYPE(file)>"
    %endif
  %endif
  %assign cc = file.CustomContents
  %if !ISFIELD(cc,attrib)
    %% Never been created, so just return empty string.
    %return ""
  %else
    %assign cs = cc.%<attrib>
    %if cs.IsRetrieved
      %assign codeTemplate = file.CodeTemplate
      %if ISEMPTY(FEVAL("regexp",codeTemplate,"_cgt.tlc"))
	%assign actFile = codeTemplate
      %else
	%assign actFile = FEVAL("rtw_cgt_name_conv",codeTemplate,"tlc2cgt")
      %endif
      %assign warnTxt = "%<cs.Name> symbol is used more than once in " + ...
	"Code Template file: %<actFile>.\n%<cs.Name> can be used only" + ...
	" once in the template file."
      %<LibReportWarning(warnTxt)>
      %return ""
    %else
      %assign cs.IsRetrieved = TLC_TRUE
      %if ISEMPTY(cs.Value)
	%return ""
      %else
	%return cs.Value
      %endif
    %endif
  %endif
%endfunction

%% =============================================================================
%% Add ModelFiles to CompiledModel
%% =============================================================================

%with CompiledModel
  %addtorecord CompiledModel \
  ModelFiles {               \
    NumModelFiles    0       \
    NumSupportFiles  0       \
    ComplianceLevel -1       \
  }
%endwith %% CompiledModel

%% =============================================================================
%% Private functions (MathWorks use only)
%% =============================================================================

%function SLibGetTag(type, name) void

  %% In case name contains . and other funny char
  %assign name = LibConvertNameToIdentifier(name)

  %switch type
    %case "SystemHeader"
      %assign tag = "%<name>_h"
      %break
    %case "SystemBody"
      %assign tag = "%<name>_c"
      %break
    %default
      %assign errTxt = "unknown type: %<type>"
      %<LibReportFatalError(errTxt)>
  %endswitch
  %return tag
%endfunction
  
%% Function: SLibSetSourceFileCustomTokenInUse =================================
%% Abstract:
%%   The rtw_expand_template script identifies and set customs tokens with
%%   this function.  This allows custom sections to be placed in the
%%   appropriate section when a token is missing.
%%
%function SLibSetSourceFileCustomTokenInUse(fileIdx,token) void
  %assign cc = ModelFiles.ModelFile[fileIdx].CustomContents
  %<SETFIELD(cc, token + "_InUse", TLC_TRUE)>
%endfunction


%% Function: FcnAppendMissingTokens ============================================
%% Abstract:
%%   Since custom sections can be added without a corresponding token in
%%   the code template file, we need to gracefully accomodate missing tokens.
%%   If the custom token is missing, it's placed just below it's registered
%%   built-in section.
%%
%function FcnAppendMissingTokens(opFile,section) void
  %assign c = opFile.Contents
  %with opFile.CustomContents
    %foreach idx = NumCustomContents
      %assign cc = CustomContent[idx]
      %assign tokenInUse = ISFIELD(opFile.CustomContents, cc.Name + "_InUse")
      %if cc.IsRequired && !tokenInUse && cc.BuiltInSection == section
	%assign c.%<section> = c.%<section> + cc.Value
	%assert !cc.IsRetrieved
	%assign cc.IsRetrieved = TLC_TRUE
      %endif
    %endforeach
  %endwith
%endfunction


%% Check if model file exists
%function SLibDoesModelFileExist(type,name) void
  
  %% Check hash name
  %assign tag = SLibGetTag(type, name)
  
  %% Return hashed value if file already created
  
  %if ISFIELD(ModelFiles,tag)
    %assign mf = ModelFiles.ModelFile[ModelFiles.%<tag>]
    %return mf
  %else
    %return ""
  %endif
%endfunction

  
%% Create a new model file, or return its existing reference.
%function SLibAddModelFile(type,creator,name) void

  %assign mf = SLibDoesModelFileExist(type, name)
  
  %if TYPE(mf) == "Scope" %% file exists
    %if creator != mf.Creator
      %assign errTxt = "%<creator> is attempting to create " ...
	"file %<name>, however, this file was already created " ...
	"by %<mf.Creator>."
      %<LibReportFatalError(errTxt)>
    %endif
    %return mf
  %endif
  
  %assign tag = SLibGetTag(type, name)
  
  %if ERTCustomFileBanners
    %assign template = (type == "SystemBody") ? ...
      ERTSrcFileBannerTemplate : ERTHdrFileBannerTemplate
  %else
    %assign template = "rtw_code.tlc"
  %endif

  %% Add model file record
  
  %addtorecord CompiledModel.ModelFiles   \
  ModelFile {                              \
    Name                   "%<name>"       \
    Type                   "%<type>"       \
    Creator                "%<creator>"    \
    Index                  ModelFiles.NumModelFiles \
    SystemsInFile          []              \
    RequiredIncludes       []              \
    Filter                 0               \
    IsEmpty                TLC_TRUE        \
    Indent                 TLC_FALSE       \
    Shared                 TLC_FALSE       \
    CodeTemplate           template        \
    OutputDirectory        ""              \
    Contents {                             \
      Banner               ""              \
      Includes             ""              \
      Defines              ""              \
      IntrinsicTypes       ""              \
      PrimitiveTypedefs    ""              \
      UserTop              ""              \
      Typedefs             ""              \
      Enums                ""              \
      Definitions          ""              \
      ExternData           ""              \
      ExternFcns           ""              \
      FcnPrototypes        ""              \
      Declarations         ""              \
      Functions            ""              \
      CompilerErrors       ""              \
      CompilerWarnings     ""              \
      Documentation        ""              \
      UserBottom           ""              \
    }                                      \
    CustomContents {                       \
      NumCustomContents 0                  \
    }                                      \
  }
  %addtorecord CompiledModel.ModelFiles %<tag> %<ModelFiles.NumModelFiles>
  
  %assign CompiledModel.ModelFiles.NumModelFiles = ModelFiles.NumModelFiles + 1

  %return ModelFiles.ModelFile[ModelFiles.NumModelFiles - 1]

%endfunction


%function SLibSetContentsAttribute(opFile, c, attrib, value) void
  %if !ISFIELD(c,attrib)
    %assign errTxt = "Attempt to set the value of an attribute that does " ...
      "not exist for source file %<opFile.Name>: %<attrib>."
    %<LibReportError(errTxt)>
  %endif
  %if !WHITE_SPACE(value)
    %assign c.%<attrib> = c.%<attrib> + value
    %assign opFile.IsEmpty = TLC_FALSE
  %endif
%endfunction


%function SLibSetModelFileAttribute(opFile,attrib,value) void
  %% After LibClearModelFileBuffers() is called, Contents will not
  %% exist. However, still allow access to SystemsInFile,
  %% RequiredIncludes, NeedsModelHeader.
  %if ISFIELD(opFile,"Contents")
    %assign c = opFile.Contents
  %endif

  %switch attrib
    %case "SystemsInFile"
      %foreach idx = SIZE(opFile.SystemsInFile,1)
	%if opFile.SystemsInFile[idx] == value
	  %% already in list
	  %return ""
	%endif
      %endforeach
      %assign opFile.SystemsInFile = opFile.SystemsInFile + value
      %break
    %case "RequiredIncludes"
      %foreach idx = SIZE(opFile.RequiredIncludes,1)
	%if opFile.RequiredIncludes[idx] == value
	  %% already in list
	  %return ""
	%endif
      %endforeach
      %assign opFile.RequiredIncludes = opFile.RequiredIncludes + value
      %break
    %case "Filter"
      %assert (value == 1)
      %assign opFile.Filter = value
      %break
    %case "Banner"
      %if IncludeFileBanners
	%<SLibSetContentsAttribute(opFile, c, attrib, value)>
      %endif
      %break
    %case "CodeTemplate"
    %case "OutputDirectory"
      %assign opFile.%<attrib> = value
      %break
    %default
      %<SLibSetContentsAttribute(opFile, c, attrib, value)>
  %endswitch      
%endfunction


%function SLibGetModelFileIndent(opFile) void
  %return opFile.Indent
%endfunction

%function SLibSetModelFileIndent(opFile, setting) void
  %assign opFile.Indent = setting
%endfunction


%function SLibGetModelFileShared(opFile) void
  %return opFile.Shared
%endfunction

%function SLibSetModelFileShared(opFile, setting) void
  %assign opFile.Shared = setting
%endfunction

%function SLibGetModelFileIsEmpty(opFile) void
  %return opFile.IsEmpty
%endfunction

%function SLibGetModelFileFromTag(tag) void
  %return ModelFiles.ModelFile[ModelFiles.%<tag>]
%endfunction

%% Function: LibGetNumModelFiles ================================================
%% Abstract:
%%   Get the number of generated files.
%%
%function LibGetNumModelFiles() void
  %return ModelFiles.NumModelFiles
%endfunction


%% Function: LibGetModelFileTag =================================================
%% Abstract:
%%   Get the unique hash symbol for a model file.  This is useful for creating
%%   a header file multiple inclusion guaurd.  For example,
%%
%%   __RTW_GENERATED_HEADER_FILE_%<LibGetModelFileTag()>__
%%
%function LibGetModelFileTag(fileIdx) void
  %assign mf = ModelFiles.ModelFile[fileIdx]
  %assign ext  = mf.Type == "SystemBody" ? "_c" : "_h"
  %return "%<mf.Name>%<ext>"
%endfunction


%% Function: LibGetModelFileNeedHeaderGuard ====================================
%% Abstract:
%%   Return true if a header file guard is requried, and false otherwise.
%%
%function LibGetModelFileNeedHeaderGuard(fileIdx) void
  %if LibGetModelFileAttribute(fileIdx,"Type") != "SystemHeader"
    %return 0
  %elseif LibGetSourceFileShared(fileIdx)
    %return 0
  %else
    %if CodeFormat != "S-Function" && CodeFormat != "RealTimeMalloc"
      %return 1
    %else
      %if CodeFormat == "S-Function"
        %assign tag = LibGetModelFileTag(fileIdx)
        %return tag != "%<OrigName>_mid_h" && tag != "%<OrigName>_sid_h"
      %else
        %assign tag = LibGetModelFileTag(fileIdx)
        %return tag != "%<Name>_reg_h" && tag != "%<Name>_prm_h"
      %endif
    %endif
  %endif
%endfunction


%% Function: LibGetModelFileAttribute ===========================================
%% Abstract:
%%
%%   MathWorks internal function.  Use LibGetSourceFileSection instead.
%%
%function LibGetModelFileAttribute(fileIdx, attrib) void
  
  %if ModelFiles.ComplianceLevel == -1
    %assign errTxt = "Must set code template compliance level with " ...
      "TLC function LibSetCodeTemplateComplianceLevel()."
    %<LibReportFatalError(errTxt)>
  %endif
  
  %assign opFile = ModelFiles.ModelFile[fileIdx]

  %% After LibClearModelFileBuffers() is called, Contents will not
  %% exist. However, still allow access to Name, Type and Creator.
  %if ISFIELD(opFile,"Contents")
    %assign c = opFile.Contents
  %endif

  %switch attrib
    %case "Name"
      %assign headerExt = ".h"
      %assign sourceExt = "." + ::LangFileExt
      %assign extension = opFile.Type == "SystemHeader" ? headerExt : sourceExt
      %return "%<opFile.Name>%<extension>"
    %case "Type"
    %case "Creator"
    %case "Filter"
    %case "IsEmpty"
    %case "CodeTemplate"
    %case "OutputDirectory"
      %return opFile.%<attrib>
    %case "Banner"
      %return c.%<attrib>
    %case "Includes"
    %case "Defines"
    %case "IntrinsicTypes"
    %case "PrimitiveTypedefs"
    %case "UserTop"
    %case "Typedefs"
    %case "Enums"
    %case "Definitions"
    %case "ExternData"
    %case "ExternFcns"
    %case "FcnPrototypes"
    %case "Declarations"
    %case "Functions"
    %case "CompilerErrors"
    %case "CompilerWarnings"
    %case "Documentation"
    %case "UserBottom"
      %<FcnAppendMissingTokens(opFile,attrib)>
      %if !WHITE_SPACE(c.%<attrib>)
	%return "\n" + c.%<attrib>
      %else
	%return ""
      %endif
    %default
      %assign errTxt = "Uknown file attribute: %<attrib>"
      %<LibReportFatalError(errTxt)>
  %endswitch
%endfunction  %% LibGetModelFileAttribute


%% Function: LibClearModelFileBuffers ==========================================
%% Abstract:
%%   Clear the variables associated with Model File contents.
%%
%function LibClearModelFileBuffers() void
  %if ResetTLCGlobalsAfterUse
    %with CompiledModel.ModelFiles
      %foreach idx = NumModelFiles
	%with ModelFile[idx]
	  %undef Contents
	%endwith
      %endforeach
    %endwith %% CompiledModel.ModelFiles
  %endif
%endfunction


%% Function: LibWriteToStandardOutput ==========================================
%% Abstract:
%%   Assuming the current file is NULL_FILE, write text to the MATLAB command
%%   window.  If the current file is not NULL_FILE, you need to reselect the
%%   appropriate file after a call to this function.
%%
%function LibWriteToStandardOutput(txt) void
%%
%% DO NOT INDENT THIS TLC CODE !!!
%%
%selectfile STDOUT
%if RTWVerbose
%<txt>
%endif
%selectfile NULL_FILE
%endfunction  %% LibWriteToStandardOutput


%% Function: LibSetCodeTemplateComplianceLevel =================================
%% Abstract:
%%   Synchronize a custom code template with RTW.  This function must be
%%   called from a code template.
%%
%function LibSetCodeTemplateComplianceLevel(level) void
  %if level != 1 && level != 2
    %assign errTxt = "Unknown code template compliance level: %<level>"
    %<LibReportError(errTxt)>
  %endif
  %assign CompiledModel.ModelFiles.ComplianceLevel = level
%endfunction

%% [EOF] codetemplatelib.tlc
