function file = code_sfun_glue_code(~,file,...
chart,...
chartUniqueName,...
specsIdx)

% Copyright 1995-2020 The MathWorks, Inc.
%

fprintf(file,' #include <stdio.h>\n');
fprintf(file,' #include <stdlib.h>\n');
fprintf(file,' #include <string.h>\n');
%%%%%%%%%%%%%%%%%%%%%%%%% Coding options
global gTargetInfo gChartInfo gMachineInfo %#ok<GVMIS>

% Chart data info has to be calculated after chart specialization is
% known. i.e. during the chart code generation loop.
initialize_data_information(gChartInfo.chartData,gChartInfo.chartDataNumbers,chart);

chartFileNumber = sf('get',chart,'chart.chartFileNumber');
chartNumber = sf('get',chart,'chart.number');

exportedFcns = [];
if sf('get', chart, 'chart.exportChartFunctions')
lookUnderBoxes = false;
exportedFcns = sf('FunctionsOf', chart, lookUnderBoxes);
end

fprintf(file,'/* SFunction Glue Code */\n');
fprintf(file,'\n');

if gChartInfo.hasTestPoint
fprintf(file,'static void init_test_point_mapping_info(SimStruct *S);\n');
end

fprintf(file,'void sf_%s_get_check_sum(mxArray *plhs[])\n',chartUniqueName);
fprintf(file,'{\n');
% TLTODO: Remove chart.checksum and this function if we unify
% single instantiated chart file naming scheme with that of a
% multi-instantiated chart.

numSpecs = length(gMachineInfo.specializations{chartNumber+1});
if numSpecs > 1
checksumVector = CGXE.Utils.md5(gMachineInfo.specializations{chartNumber+1}{specsIdx});
else
checksumVector = sf('get',chart,'chart.checksum');
end

for i=1:4
fprintf(file,' ((real_T *)mxGetPr((plhs[0])))[%.17g] = (real_T)(%.17gU);\n',(i-1),checksumVector(i));
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'\n');
fprintf(file,'mxArray *sf_%s_third_party_uses_info(void)\n',chartUniqueName);
fprintf(file,'{\n');
chart3pUses = sf('Cg','third_party_uses',chart);
fprintf(file,' mxArray * mxcell3p = mxCreateCellMatrix(1,%.17g);\n',numel(chart3pUses));
for i = 1:numel(chart3pUses)
fprintf(file,' mxSetCell(mxcell3p, %.17g, mxCreateString("%s"));\n',(i-1),chart3pUses{i});
end
fprintf(file,' return(mxcell3p);\n');

fprintf(file,'}\n');
fprintf(file,'\n');

fprintf(file,'\n');
fprintf(file,'mxArray *sf_%s_jit_fallback_info(void)\n',chartUniqueName);
fprintf(file,'{\n');

fprintf(file,' const char *infoFields[] = {"fallbackType","fallbackReason","hiddenFallbackType","hiddenFallbackReason","incompatibleSymbol"};\n');
fprintf(file,' mxArray *mxInfo = mxCreateStructMatrix(1, 1, 5, infoFields);\n');
fprintf(file,' mxArray *fallbackType = mxCreateString("%s");\n',gChartInfo.jitFallbackInfo.fallbackType);
fprintf(file,' mxArray *fallbackReason = mxCreateString("%s");\n',gChartInfo.jitFallbackInfo.fallbackReason);
fprintf(file,' mxArray *hiddenFallbackType = mxCreateString("%s");\n',gChartInfo.jitFallbackInfo.hiddenFallbackType);
fprintf(file,' mxArray *hiddenFallbackReason = mxCreateString("%s");\n',gChartInfo.jitFallbackInfo.hiddenFallbackReason);
fprintf(file,' mxArray *incompatibleSymbol = mxCreateString("%s");\n',gChartInfo.jitFallbackInfo.incompatibleSymbol);
fprintf(file,' mxSetField(mxInfo, 0, infoFields[0], fallbackType);\n');
fprintf(file,' mxSetField(mxInfo, 0, infoFields[1], fallbackReason);\n');
fprintf(file,' mxSetField(mxInfo, 0, infoFields[2], hiddenFallbackType);\n');
fprintf(file,' mxSetField(mxInfo, 0, infoFields[3], hiddenFallbackReason);\n');
fprintf(file,' mxSetField(mxInfo, 0, infoFields[4], incompatibleSymbol);\n');
fprintf(file,' return mxInfo;\n');

fprintf(file,'}\n');
fprintf(file,'\n');

fprintf(file,'\n');
fprintf(file,'mxArray *sf_%s_updateBuildInfo_args_info(void)\n',chartUniqueName);
fprintf(file,'{\n');
updateBuildInfoArgs = sf('Cg','updateBuildInfo_args',chart);
numTp = length(updateBuildInfoArgs);
if numTp > 0
encStr = sf('Cg', 'mx_encode', updateBuildInfoArgs);
fprintf(file,' mxArray *mxBIArgs = sf_mex_decode(\n');
dump_string_in_chunks(file, encStr);
fprintf(file,' ); \n');
else
fprintf(file,' mxArray *mxBIArgs = mxCreateCellMatrix(1,0); \n');
end
fprintf(file,' return mxBIArgs;\n');
fprintf(file,'}\n');
fprintf(file,' \n');
fprintf(file,'static const mxArray *sf_get_sim_state_info_%s(void)\n',chartUniqueName);
fprintf(file,'{\n');
fprintf(file,' const char *infoFields[] = {"chartChecksum", "varInfo"};\n');
fprintf(file,' mxArray *mxInfo = mxCreateStructMatrix(1, 1, 2, infoFields);\n');
simStateVarInfo = sf('get', chart, 'chart.sfunInfo.simSnapshotVarInfo');
encStr = sf('Cg', 'mx_encode', simStateVarInfo);
fprintf(file,' mxArray *mxVarInfo = sf_mex_decode(\n');
dump_string_in_chunks(file, encStr)
fprintf(file,' );\n');
fprintf(file,' mxArray *mxChecksum = mxCreateDoubleMatrix(1, 4, mxREAL);\n');
fprintf(file,' sf_%s_get_check_sum(&mxChecksum);\n',chartUniqueName);
fprintf(file,' mxSetField(mxInfo, 0, infoFields[0], mxChecksum);\n');
fprintf(file,' mxSetField(mxInfo, 0, infoFields[1], mxVarInfo);\n');
fprintf(file,' return mxInfo;\n');
fprintf(file,'}\n');
fprintf(file,'\n');

fprintf(file,'static const char* sf_get_instance_specialization(void)\n');
fprintf(file,'{\n');
fprintf(file,' return "%s";\n',gMachineInfo.specializations{chartNumber+1}{specsIdx});
fprintf(file,'}\n');

fprintf(file,'\n');
fprintf(file,'static void sf_opaque_initialize_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
%G236089: initialize parameters before we initialize chart
fprintf(file,' initialize_params_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
fprintf(file,' initialize_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
%G236089: initialize parameters before we initialize chart
fprintf(file,' initialize_params_%s();\n',chartUniqueName);
fprintf(file,' initialize_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_enable_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' enable_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' enable_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_disable_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' disable_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' disable_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
if sf('DoesChartHaveZeroCrossings', chart)
fprintf(file,' static void sf_opaque_zeroCrossings_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,' {\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' mdlZeroCrossings_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' mdlZeroCrossings_%s();\n',chartUniqueName);
end
fprintf(file,' }\n');
end
if sf('IsPlantModelChartPostCompile', chart)
fprintf(file,' static void sf_opaque_derivatives_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,' {\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' mdlDerivatives_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' mdlDerivatives_%s();\n',chartUniqueName);
end
fprintf(file,' }\n');
end
fprintf(file,'\n');
if sf('IsPlantModelChartPostCompile', chart) || sf('HasSeparateOutputUpdate', chart)
fprintf(file,' static void sf_opaque_outputs_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,' {\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' outputs_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' outputs_%s();\n',chartUniqueName);
end
fprintf(file,' }\n');
end
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_gateway_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' sf_gateway_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' sf_gateway_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');

if instrument_ext_mode_exec
fprintf(file,'static void sf_opaque_ext_mode_exec_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' ext_mode_exec_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' ext_mode_exec_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
end

fprintf(file,'static const mxArray* sf_opaque_get_sim_state_%s(SimStruct* S)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' return get_sim_state_%s((%s *)sf_get_chart_instance_ptr(S)); /* raw sim ctx */\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' return get_sim_state_%s(); /* raw sim ctx */\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_set_sim_state_%s(SimStruct* S, const mxArray *st)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' set_sim_state_%s((%s*)sf_get_chart_instance_ptr(S), st);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' set_sim_state_%s(st); /* raw sim ctx */\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_cleanup_runtime_resources_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' if(chartInstanceVar!=NULL) {\n');
fprintf(file,' SimStruct *S = ((%s*) chartInstanceVar)->S;\n',gChartInfo.chartInstanceTypedef);
fprintf(file,' if (sim_mode_is_rtw_gen(S) || sim_mode_is_external(S)) {\n');
fprintf(file,' sf_clear_rtw_identifier(S);\n');
fprintf(file,' unload_%s_optimization_info();\n',gMachineInfo.machineName);
fprintf(file,' }\n');
fprintf(file,' mdl_cleanup_runtime_resources_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);

if gChartInfo.hasTestPoint
fprintf(file,' if(!sim_mode_is_rtw_gen(S)) {\n');
fprintf(file,' ssSetModelMappingInfoPtr(S, NULL);\n');
fprintf(file,' }\n');
end
if gTargetInfo.gencpp
fprintf(file,' ((%s*) chartInstanceVar)->~%s();\n',gChartInfo.chartInstanceTypedef,gChartInfo.chartInstanceTypedef);
end
fprintf(file,' utFree(chartInstanceVar);\n');
fprintf(file,' if (ssGetUserData(S)!= NULL) {\n');
fprintf(file,' sf_free_ChartRunTimeInfo(S);\n');
fprintf(file,' } \n');
fprintf(file,' ssSetUserData(S,NULL);\n');
fprintf(file,' }\n');
else
fprintf(file,' if (sim_mode_is_rtw_gen(chartInstance.S) || sim_mode_is_external(chartInstance.S)) {\n');
fprintf(file,' sf_clear_rtw_identifier(chartInstance.S);\n');
fprintf(file,' }\n');
fprintf(file,' mdl_cleanup_runtime_resources_%s();\n',chartUniqueName);
fprintf(file,' if (ssGetUserData(chartInstance.S)!= NULL) {\n');
fprintf(file,' sf_free_ChartRunTimeInfo(chartInstance.S);\n');
fprintf(file,' } \n');
fprintf(file,' ssSetUserData(chartInstance.S,NULL);\n');
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_mdl_start_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' mdl_start_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' mdl_start_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_mdl_terminate_%s(void *chartInstanceVar)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' mdl_terminate_%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' mdl_terminate_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
if gChartInfo.chartHasContinuousTime && ~sf('IsPlantModelChartPostCompile', chart)
fprintf(file,'static void sf_opaque_store_current_config(void *chartInstanceVar)\n');
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' store_current_config((%s*) chartInstanceVar);\n',gChartInfo.chartInstanceTypedef);
else
fprintf(file,' store_current_config();\n');
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_restore_before_last_major_step(void *chartInstanceVar)\n');
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' restore_before_last_major_step((%s*) chartInstanceVar);\n',gChartInfo.chartInstanceTypedef);
else
fprintf(file,' restore_before_last_major_step();\n');
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_restore_last_major_step(void *chartInstanceVar)\n');
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' restore_last_major_step((%s*) chartInstanceVar);\n',gChartInfo.chartInstanceTypedef);
else
fprintf(file,' restore_last_major_step();\n');
end
fprintf(file,'}\n');
fprintf(file,'\n');
end
fprintf(file,'\n');
fprintf(file,'static void sf_opaque_init_subchart_simstructs(void *chartInstanceVar)\n');
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' initSimStructs%s((%s*) chartInstanceVar);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' initSimStructs%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
if ~isempty(exportedFcns)
fprintf(file,'static void sfcs_opaque_exported_fcn_call_dispatcher_%s(void *chartInstanceVar, const char* fcnName, void* args)\n',chartUniqueName);
fprintf(file,'{\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' sfcs_exported_fcn_dispatcher_%s((%s*) chartInstanceVar, fcnName, (_ssFcnCallExecArgs*)args);\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' sfcs_exported_fcn_dispatcher_%s(fcnName, (_ssFcnCallExecArgs*)args);\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
end

fprintf(file,' \n');
fprintf(file,'extern unsigned int sf_machine_global_initializer_called(void);\n');
fprintf(file,'static void mdlProcessParameters_%s(SimStruct *S)\n',chartUniqueName);
fprintf(file,'{\n');
fprintf(file,' int i;\n');
fprintf(file,' for(i=0;i<ssGetNumRunTimeParams(S);i++) {\n');
fprintf(file,' if(ssGetSFcnParamTunable(S,i)) {\n');
fprintf(file,' ssUpdateDlgParamAsRunTimeParam(S,i);\n');
fprintf(file,' }\n');
fprintf(file,' }\n');
fprintf(file,' sf_warn_if_symbolic_dimension_param_changed(S);\n');
%% G340326: mdlProcessParameters is called prior to
%% mdlSetupRuntimeResources
%% for modelreference normal-mode simulation. In this case
%% we should return early and not worry about updating our internal
%% cache of param values (which causes crashes). We will get a chance to react to them
%% during mdlInitconds anyway.
fprintf(file,' if(sf_machine_global_initializer_called()) {\n');
if gTargetInfo.codingMultiInstance
fprintf(file,' initialize_params_%s((%s*)sf_get_chart_instance_ptr(S));\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
%% we make this call to initSimstructHere to make sure that subchart data has correct pointers to main data
fprintf(file,' initSimStructs%s((%s*)sf_get_chart_instance_ptr(S));\n',chartUniqueName,gChartInfo.chartInstanceTypedef);
else
fprintf(file,' initialize_params_%s();\n',chartUniqueName);
fprintf(file,' initSimStructs%s();\n',chartUniqueName);
end
fprintf(file,' }\n');

fprintf(file,'}\n');
fprintf(file,'\n');

postCodegenInfo = sf('Cg', 'get_encoded_postcodegen_info', chart);
fprintf(file,'const char* sf_%s_get_post_codegen_info(void)\n',chartUniqueName);
fprintf(file,'{\n');
fprintf(file,' int i;\n');
len = length(postCodegenInfo);
maxCount = 1 + ceil(len/75);
fprintf(file,' const char* encStrCodegen [%.17g] = {\n',maxCount);
dump_string_in_chunks_of_char_array(file, postCodegenInfo);
fprintf(file,' };\n');

stringLength = len + 1;
fprintf(file,' static char newstr [%.17g] = "";\n',stringLength);
fprintf(file,' newstr[0] = ''\\0'';\n');
fprintf(file,' for (i = 0; i < %.17g; i++) {\n',maxCount);
fprintf(file,' strcat(newstr, encStrCodegen[i]);\n');
fprintf(file,' }\n');
fprintf(file,' return newstr;\n');
fprintf(file,'}\n');
fprintf(file,'static void mdlSetWorkWidths_%s(SimStruct *S)\n',chartUniqueName);
fprintf(file,'{\n');
fprintf(file,' const char* newstr = sf_%s_get_post_codegen_info();\n',chartUniqueName);
fprintf(file,' sf_set_work_widths(S, newstr);\n');

checksumVector = double((sf('get',chart,'chart.rtwChecksum')));
dataSetLoggingEnabled = sfprivate('dataSetLoggingEnabled', gChartInfo, gMachineInfo);
if dataSetLoggingEnabled
fprintf(file,' if (sim_mode_is_modelref_sim(S)) \n');
fprintf(file,' {\n');
fprintf(file,' mxArray *prhs[2];\n');
fprintf(file,' mxArray *plhs[1];\n');
fprintf(file,' uint32_T newChkSum[4];\n');
fprintf(file,' double *inPr, *outPr;\n');
fprintf(file,' int i;\n');
fprintf(file,' int firstSlashIdx = 0;\n');
fprintf(file,'\n');
fprintf(file,' for (i = 0; i < 999 && S->path[i] != ''\\0'' ; ++i) {\n');
fprintf(file,' if (S->path[i] == ''/'') {\n');
fprintf(file,' firstSlashIdx = i;\n');
fprintf(file,' break;\n');
fprintf(file,' }\n');
fprintf(file,' }\n');
fprintf(file,'\n');
fprintf(file,' prhs[0] = mxCreateDoubleMatrix(1, 4, mxREAL);\n');
fprintf(file,' prhs[1] = mxCreateString(S->path + firstSlashIdx + 1);\n');
fprintf(file,'\n');
fprintf(file,' inPr = mxGetPr(prhs[0]);\n');
fprintf(file,' inPr[0] = %.17gU;\n',checksumVector(1));
fprintf(file,' inPr[1] = %.17gU;\n',checksumVector(2));
fprintf(file,' inPr[2] = %.17gU;\n',checksumVector(3));
fprintf(file,' inPr[3] = %.17gU;\n',checksumVector(4));
fprintf(file,'\n');
fprintf(file,' mexCallMATLAB(1, plhs, 2, prhs, "CGXE.Utils.md5");\n');
fprintf(file,'\n');
fprintf(file,' outPr = mxGetPr(plhs[0]);\n');
fprintf(file,' for (i = 0; i < 4; ++i) {\n');
fprintf(file,' newChkSum[i] = (uint32_T) outPr[i];\n');
fprintf(file,' }\n');
fprintf(file,'\n');
fprintf(file,' ssSetChecksum0(S, newChkSum[0]);\n');
fprintf(file,' ssSetChecksum1(S, newChkSum[1]);\n');
fprintf(file,' ssSetChecksum2(S, newChkSum[2]);\n');
fprintf(file,' ssSetChecksum3(S, newChkSum[3]);\n');
fprintf(file,' \n');
fprintf(file,' mxDestroyArray(plhs[0]);\n');
fprintf(file,' mxDestroyArray(prhs[0]);\n');
fprintf(file,' mxDestroyArray(prhs[1]);\n');
fprintf(file,' } else {\n');
fprintf(file,' ssSetChecksum0(S,(%.17gU));\n',checksumVector(1));
fprintf(file,' ssSetChecksum1(S,(%.17gU));\n',checksumVector(2));
fprintf(file,' ssSetChecksum2(S,(%.17gU));\n',checksumVector(3));
fprintf(file,' ssSetChecksum3(S,(%.17gU));\n',checksumVector(4));
fprintf(file,' }\n');

else

fprintf(file,' ssSetChecksum0(S,(%.17gU));\n',checksumVector(1));
fprintf(file,' ssSetChecksum1(S,(%.17gU));\n',checksumVector(2));
fprintf(file,' ssSetChecksum2(S,(%.17gU));\n',checksumVector(3));
fprintf(file,' ssSetChecksum3(S,(%.17gU));\n',checksumVector(4));
end
fprintf(file,'\n');
fprintf(file,'\n');

fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'static void mdlRTW_%s(SimStruct *S)\n',chartUniqueName);
fprintf(file,'{\n');
fprintf(file,' if(sim_mode_is_rtw_gen(S)) {\n');
if sfprivate('is_eml_chart',chart)
fprintf(file,' ssWriteRTWStrParam(S, "StateflowChartType", "Embedded MATLAB");\n');
elseif sfprivate('is_truth_table_chart',chart)
fprintf(file,' ssWriteRTWStrParam(S, "StateflowChartType", "Truth Table");\n');
else
fprintf(file,' ssWriteRTWStrParam(S, "StateflowChartType", "Stateflow");\n');
end
fprintf(file,' }\n');
fprintf(file,' \n');
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'\n');
fprintf(file,'static void mdlSetupRuntimeResources_%s(SimStruct *S)\n',chartUniqueName);
fprintf(file,'{\n');
% Error if we are not a combinatorial chart and we inherit a
% continuous sample time.
if gTargetInfo.codingMultiInstance
fprintf(file,' %s *chartInstance;\n',gChartInfo.chartInstanceTypedef);
fprintf(file,' chartInstance = (%s *)utMalloc(sizeof(%s));\n',gChartInfo.chartInstanceTypedef,gChartInfo.chartInstanceTypedef);
fprintf(file,' if(chartInstance==NULL) {\n');
fprintf(file,' sf_mex_error_message("Could not allocate memory for chart instance.");\n');
fprintf(file,' }\n');
fprintf(file,' memset(chartInstance, 0, sizeof(%s));\n',gChartInfo.chartInstanceTypedef);
if gTargetInfo.gencpp
fprintf(file,' chartInstance = new (chartInstance) %s;\n',gChartInfo.chartInstanceTypedef);
end
fprintf(file,' %schartInfo.chartInstance = chartInstance;\n',gChartInfo.chartInstanceVarName);
else
dataSetLoggingEnabled = sfprivate('dataSetLoggingEnabled', gChartInfo, gMachineInfo);
if gChartInfo.hasLoggedSignals && dataSetLoggingEnabled
loggedSig = gChartInfo.loggedSignals;
logArrSize = length(loggedSig.data) + length(loggedSig.state) + length(loggedSig.aslStates);
fprintf(file,' memset(get_dataset_logging_obj_vector(), 0, %.17g * sizeof(void*));\n',logArrSize);
end
fprintf(file,' %schartInfo.chartInstance = NULL;\n',gChartInfo.chartInstanceVarName);
end

if sfprivate('is_eml_based_chart', chart) && ~sf('IsCombinatorial', chart)
fprintf(file,' if (ssGetSampleTime(S, 0) == CONTINUOUS_SAMPLE_TIME && ssGetOffsetTime(S, 0) == 0 && ssGetNumContStates(ssGetRootSS(S)) > 0 && !supportsLegacyBehaviorForPersistentVarInContinuousTime(S)) {\n');
fprintf(file,' sf_error_out_about_continuous_sample_time_with_persistent_vars(S);\n');
fprintf(file,' }\n');
end

if sf('IsPlantModelChartPostCompile', chart)
slFcnsWhichShouldBeReadonly = sf('GetSimulinkFunctionsWhichShouldBeReadonly', chart);
for i=1:length(slFcnsWhichShouldBeReadonly)
slFcnBlockName = slFcnsWhichShouldBeReadonly{i}.blockName;
slFcnSSID = slFcnsWhichShouldBeReadonly{i}.simFcnSSIDNumber;
slFcnUserSSID = slFcnsWhichShouldBeReadonly{i}.userSSIDNumber;
fprintf(file,' sf_error_check_illegal_use_of_simulink_fcn(S, "%s", %.17g, %.17g);\n',slFcnBlockName,slFcnSSID,slFcnUserSSID);
end
end

fprintf(file,' %schartInfo.isEMLChart = %.17g;\n',gChartInfo.chartInstanceVarName,sfprivate('is_eml_chart',chart));
fprintf(file,' %schartInfo.chartInitialized = 0;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.sFunctionGateway = sf_opaque_gateway_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.initializeChart = sf_opaque_initialize_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.mdlStart = sf_opaque_mdl_start_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.mdlTerminate = sf_opaque_mdl_terminate_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.mdlCleanupRuntimeResources = sf_opaque_cleanup_runtime_resources_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.enableChart = sf_opaque_enable_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.disableChart = sf_opaque_disable_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.getSimState = sf_opaque_get_sim_state_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.setSimState = sf_opaque_set_sim_state_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.getSimStateInfo = sf_get_sim_state_info_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
if sf('IsPlantModelChartPostCompile', chart)
fprintf(file,' %schartInfo.zeroCrossings = sf_opaque_zeroCrossings_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.outputs = sf_opaque_outputs_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.derivatives = sf_opaque_derivatives_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
elseif sf('DoesChartHaveZeroCrossings', chart)
fprintf(file,' %schartInfo.zeroCrossings = sf_opaque_zeroCrossings_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
elseif sf('HasSeparateOutputUpdate', chart)
fprintf(file,' %schartInfo.zeroCrossings = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.outputs = sf_opaque_outputs_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.derivatives = NULL;\n',gChartInfo.chartInstanceVarName);
else
fprintf(file,' %schartInfo.zeroCrossings = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.outputs = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.derivatives = NULL;\n',gChartInfo.chartInstanceVarName);
end
fprintf(file,' %schartInfo.mdlRTW = mdlRTW_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,' %schartInfo.mdlSetWorkWidths = mdlSetWorkWidths_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);

if instrument_ext_mode_exec
fprintf(file,' %schartInfo.extModeExec = sf_opaque_ext_mode_exec_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
else
fprintf(file,' %schartInfo.extModeExec = NULL;\n',gChartInfo.chartInstanceVarName);
end

if gChartInfo.chartHasContinuousTime && ~sf('IsPlantModelChartPostCompile', chart)
fprintf(file,' %schartInfo.restoreLastMajorStepConfiguration = sf_opaque_restore_last_major_step;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.restoreBeforeLastMajorStepConfiguration = sf_opaque_restore_before_last_major_step;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.storeCurrentConfiguration = sf_opaque_store_current_config;\n',gChartInfo.chartInstanceVarName);
else
fprintf(file,' %schartInfo.restoreLastMajorStepConfiguration = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.restoreBeforeLastMajorStepConfiguration = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,' %schartInfo.storeCurrentConfiguration = NULL;\n',gChartInfo.chartInstanceVarName);
end

if sf('ChartBehaveLikeSubchart', chart)
fprintf(file,'%schartInfo.callAtomicSubchartUserFcn = sf_exported_auto_userFcnGateway%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,'%schartInfo.callAtomicSubchartAutoFcn = sf_exported_auto_autoFcnGateway%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,'%schartInfo.callAtomicSubchartEventFcn = sf_exported_auto_eventFcnGateway%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
else
fprintf(file,'%schartInfo.callAtomicSubchartUserFcn = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,'%schartInfo.callAtomicSubchartAutoFcn = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,'%schartInfo.callAtomicSubchartEventFcn = NULL;\n',gChartInfo.chartInstanceVarName);
end

chartH = idToHandle(sfroot, chart);
if slfeature('StateflowStateReset') && isa(chartH, 'Stateflow.Chart') && chartH.StateAccess.Enabled
fprintf(file,'%schartInfo.chartStateSetterFcn = sf_set_state_config_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
fprintf(file,'%schartInfo.chartStateGetterFcn = sf_get_state_config_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
else
fprintf(file,'%schartInfo.chartStateSetterFcn = NULL;\n',gChartInfo.chartInstanceVarName);
fprintf(file,'%schartInfo.chartStateGetterFcn = NULL;\n',gChartInfo.chartInstanceVarName);
end

fprintf(file,' %sS = S;\n',gChartInfo.chartInstanceVarName);

if ~isempty(exportedFcns)
fprintf(file,' %schartInfo.dispatchToExportedFcn = sfcs_opaque_exported_fcn_call_dispatcher_%s;\n',gChartInfo.chartInstanceVarName,chartUniqueName);
else
fprintf(file,' %schartInfo.dispatchToExportedFcn = NULL;\n',gChartInfo.chartInstanceVarName);
end

specialization = '';
if length(gMachineInfo.specializations{chartNumber+1}) > 1
specialization = [ gMachineInfo.specializations{chartNumber+1}{specsIdx}, '_' ];
end
fprintf(file,' sf_init_ChartRunTimeInfo(S, &(%schartInfo), false, %.17g, %sc%.17g_%sJITStateAnimation, %sc%.17g_%sJITTransitionAnimation);\n',gChartInfo.chartInstanceVarName,sf('HasSeparateOutputUpdate', chart),gChartInfo.chartInstanceVarName,chartFileNumber,specialization,gChartInfo.chartInstanceVarName,chartFileNumber,specialization);
if gTargetInfo.codingMultiInstance
fprintf(file,' init_dsm_address_info(chartInstance);\n');
fprintf(file,' init_simulink_io_address(chartInstance);\n');
else
fprintf(file,' init_dsm_address_info();\n');
fprintf(file,' init_simulink_io_address();\n');
end
fprintf(file,' if(!sim_mode_is_rtw_gen(S)) {\n');
if gChartInfo.hasTestPoint
fprintf(file,' init_test_point_mapping_info(S);\n');
end
fprintf(file,' }\n');

if gTargetInfo.codingMultiInstance
fprintf(file,' mdl_setup_runtime_resources_%s(chartInstance);\n',chartUniqueName);
else
fprintf(file,' mdl_setup_runtime_resources_%s();\n',chartUniqueName);
end
fprintf(file,'}\n');
fprintf(file,'\n');
fprintf(file,'void %s_method_dispatcher(SimStruct *S, int_T method, void *data)\n',chartUniqueName);
fprintf(file,'{\n');
fprintf(file,' switch (method) {\n');
fprintf(file,' case SS_CALL_MDL_SETUP_RUNTIME_RESOURCES:\n');
fprintf(file,' mdlSetupRuntimeResources_%s(S);\n',chartUniqueName);
fprintf(file,' break;\n');
fprintf(file,' case SS_CALL_MDL_SET_WORK_WIDTHS:\n');
fprintf(file,' mdlSetWorkWidths_%s(S);\n',chartUniqueName);
fprintf(file,' break;\n');
fprintf(file,' case SS_CALL_MDL_PROCESS_PARAMETERS:\n');
fprintf(file,' mdlProcessParameters_%s(S);\n',chartUniqueName);
fprintf(file,' break;\n');
fprintf(file,' default:\n');
fprintf(file,' /* Unhandled method */\n');
fprintf(file,' sf_mex_error_message("Stateflow Internal Error:\\n"\n');
fprintf(file,' "Error calling %s_method_dispatcher.\\n"\n',chartUniqueName);
fprintf(file,' "Can''t handle method %%d.\\n", method);\n');
fprintf(file,' break;\n');
fprintf(file,' }\n');
fprintf(file,'}\n');
fprintf(file,'\n');

if gChartInfo.hasTestPoint
dump_capi_data_mapping_info_code(file, chart);
end

return;

function result = instrument_ext_mode_exec

global gChartInfo %#ok<GVMIS>

result = gChartInfo.codingDebug && gChartInfo.codingExtMode;

return;

function dump_string_in_chunks_of_char_array(file, encStr)
idxs = [1:75:length(encStr), length(encStr)+1];
for i=1:(length(idxs)-1)
startIdx = idxs(i);
endIdx = idxs(i+1)-1;
chunk = encStr(startIdx:endIdx);
fprintf(file,' "%s",\n',chunk);
end
fprintf(file,' ""\n');

function dump_string_in_chunks(file, encStr)
idxs = [1:75:length(encStr), length(encStr)+1];
for i=1:(length(idxs)-1)
startIdx = idxs(i);
endIdx = idxs(i+1)-1;
chunk = encStr(startIdx:endIdx);
fprintf(file,' "%s"\n',chunk);
end