function code_machine_source_file_sfun(fileNameInfo)
% CODE_MACHINE_SOURCE_FILE(FILENAMEINFO,MACHINE,TARGET)

%   Copyright 1995-2018 The MathWorks, Inc.
%     


    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%  GLOBAL VARIABLES
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    global gMachineInfo  gTargetInfo %#ok<GVMIS>

   machine = gMachineInfo.machineId;

    fileName = fullfile(fileNameInfo.targetDirName,fileNameInfo.machineSourceFile);
   sf_echo_generating('Coder',fileName);

   file = fopen(fileName,'Wt');
   if file<3
     construct_coder_error([],sprintf('Failed to create file: %s.',fileName),1);
     return;
   end

fprintf(file,'/* Include files */\n');
    customCodeSettings = get_custom_code_settings(gMachineInfo.target,gMachineInfo.parentTarget);
    customCodeString = customCodeSettings.customCode;
    if(~isempty(customCodeString))
fprintf(file,'#define IN_SF_MACHINE_SOURCE 1\n');
    end
fprintf(file,'#include "%s"\n',fileNameInfo.machineHeaderFile);
    for i = 1:length(fileNameInfo.chartHeaderFiles)
        for j = 1:length(fileNameInfo.chartHeaderFiles{i})
            if ~gMachineInfo.codingLLVM{i}(j)
fprintf(file,'#include "%s"\n',fileNameInfo.chartHeaderFiles{i}{j});
            end
        end
    end

    if ~fileNameInfo.hasSLCCCustomCode && ...
       ~isempty(customCodeSettings.customSourceCode)
        % No extra file then emit the custom code in the machine's source file
fprintf(file,'/* Custom Source Code */\n');
fprintf(file,'%s\n',customCodeSettings.customSourceCode);
    end

    file = dump_module(fileName,file,machine,'source');
    if file < 3
      return;
    end

    fclose(file);

   machineInfo.fileName = fileName;
   machineInfo.targetId = gMachineInfo.target;
   machineInfo.machineId = gMachineInfo.machineId;
   machineInfo.charts = gMachineInfo.charts;
   machineInfo.codingLLVM = gMachineInfo.codingLLVM;
   machineInfo.machineName = gMachineInfo.machineName;
   if(gTargetInfo.codingLibrary)
       machineInfo.codingLibrary = true;
   else
       machineInfo.codingLibrary = false;
   end
   
   if gTargetInfo.codingExtMode
       machineInfo.codingExtMode = true;
   else
       machineInfo.codingExtMode = false;
   end
   
   if gTargetInfo.codingDebug
       machineInfo.codingDebug = true;
   else
       machineInfo.codingDebug = false;
   end
   sf('Cg', 'dump_machine_source_file_sfun', machineInfo);

   file = fopen(fileName,'a');
   if file<3
     construct_coder_error([],sprintf('Failed to create file: %s.',fileName),1);
     return;
   end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%% Exported data registration
    %%%% We want to generate a function looking like:
    %%%%
    %%%% void machinename_register_exported_symbols(SimStruct* S)
    %%%% {
    %%%%    ssRegMdlInfo(S, "x1", MDL_INFO_ID_MACHINE_EXPORTED, 0, 0, (void*) NULL);     
    %%%%    ssRegMdlInfo(S, "x2", MDL_INFO_ID_MACHINE_EXPORTED, 0, 0, (void*) NULL);     
    %%%%    ssRegMdlInfo(S, "x3", MDL_INFO_ID_MACHINE_EXPORTED, 0, 0, (void*) NULL);     
    %%%%    ssRegMdlInfo(S, "x4", MDL_INFO_ID_MACHINE_EXPORTED, 0, 0, (void*) NULL);     
    %%%% } 
    %%%% 
    %%%% This will register all exported data with simulink and if there is a name
    %%%% clash it will be detected by simulink and an error will be reported
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

fprintf(file,'\n');
fprintf(file,'  void %s_register_exported_symbols(SimStruct* S)\n',gMachineInfo.machineName);
fprintf(file,'  {\n');
       for i=1:length(gMachineInfo.exportedData)
           exportedId = gMachineInfo.exportedData(i);
           exportedDataName = sf('get',exportedId,'data.name');
fprintf(file,'        ssRegMdlInfo(S, "%s", MDL_INFO_ID_MACHINE_EXPORTED, 0, 0, (void*) NULL);   \n',exportedDataName);
       end
fprintf(file,'}\n');

fprintf(file,'static mxArray* sRtwOptimizationInfoStruct=NULL;\n');
fprintf(file,'typedef struct SfOptimizationInfoFlagsTag {\n');
fprintf(file,'     boolean_T isRtwGen;\n');
fprintf(file,'     boolean_T isModelRef;\n');
fprintf(file,'     boolean_T isExternal;\n');
fprintf(file,'} SfOptimizationInfoFlags;\n');
fprintf(file,'static SfOptimizationInfoFlags sOptimizationInfoFlags;\n');
fprintf(file,'void unload_%s_optimization_info(void);\n',gMachineInfo.machineName);
fprintf(file,'mxArray* load_%s_optimization_info(boolean_T isRtwGen, boolean_T isModelRef, boolean_T isExternal)\n',gMachineInfo.machineName);
fprintf(file,'{\n');
       mainMachineName = sf('get',gMachineInfo.mainMachineId,'machine.name');
fprintf(file,'    if(sOptimizationInfoFlags.isRtwGen != isRtwGen || sOptimizationInfoFlags.isModelRef != isModelRef || sOptimizationInfoFlags.isExternal != isExternal) {\n');
fprintf(file,'         unload_%s_optimization_info();\n',gMachineInfo.machineName);
fprintf(file,'    }\n');
fprintf(file,'    sOptimizationInfoFlags.isRtwGen = isRtwGen;\n');
fprintf(file,'    sOptimizationInfoFlags.isModelRef = isModelRef;\n');
fprintf(file,'    sOptimizationInfoFlags.isExternal = isExternal;\n');
fprintf(file,'    if(sRtwOptimizationInfoStruct==NULL) {\n');
fprintf(file,'         sRtwOptimizationInfoStruct = sf_load_rtw_optimization_info("%s", "%s");\n',gMachineInfo.machineName,mainMachineName);
fprintf(file,'         mexMakeArrayPersistent(sRtwOptimizationInfoStruct);\n');
fprintf(file,'    }\n');
fprintf(file,'    return(sRtwOptimizationInfoStruct);\n');
fprintf(file,'        \n');
fprintf(file,'}\n');
fprintf(file,'void unload_%s_optimization_info(void)\n',gMachineInfo.machineName);
fprintf(file,'{\n');
fprintf(file,'    if(sRtwOptimizationInfoStruct!=NULL) {\n');
fprintf(file,'        mxDestroyArray(sRtwOptimizationInfoStruct);\n');
fprintf(file,'        sRtwOptimizationInfoStruct = NULL;\n');
fprintf(file,'    }\n');
fprintf(file,'}\n');
fprintf(file,'\n');

    fclose(file);
    try_indenting_file(fileName);



