classdef (Hidden = true) CCodeWriter < rtw.connectivity.CodeWriter
%CCODEWRITER This class provides code writing for the C programming
%language.
%
%   This is an undocumented class. Its methods and properties are likely to
%   change without warning from one release to the next.

%   Copyright 2011-2013 The MathWorks, Inc.
    
    
    
    properties(Access = protected)
        BlockStartString = '{'
        BlockEndString = '}'
        CommentStartString = '/*'
        CommentEndString = '*/'
        IsLineComment = false
    end
    
    
    
    properties(Constant, Access = private)
        % A list of keywords for which we will print the tag at the end of
        % the block.
        BlockKeywords = { 'if', 'while', 'for', 'switch', 'do' }
        
        % We build this map for faster membership testing
        BlockKeywordsMap = containers.Map(rtw.connectivity.CCodeWriter.BlockKeywords, false(size(rtw.connectivity.CCodeWriter.BlockKeywords)))
    end
    
    
    
    methods(Hidden)
        function this = CCodeWriter(outWriter)
            this@rtw.connectivity.CodeWriter(outWriter);
        end
    end
    
    
    
    methods % Language-specific write methods
        
        function wMultilineCommentStart(this, comment)
            
            % Go to a fresh line, if necessary.
            if ~this.IsFreshLine
                this.wNewLine();
            end
            
            % Print the indent
            this.indent();
            
            
            % Now print the start of the multi-line comment.
            if nargin < 2 || isempty(comment)
                this.raw([ this.CommentStartString '*' ]);
            else
                this.raw([ this.CommentStartString this.SpaceString comment ]);
            end
            
            this.wNewLine();
            
        end
        
        
        function wMultilineCommentMiddle(this, comment)
            
            % Go to a fresh line, if necessary.
            if ~this.IsFreshLine
                this.wNewLine();
            end
            
            % Print the indent
            this.indent();
            
            
            % Now print the start of the multi-line comment.
            this.raw(' *');
            if nargin >= 2 && ~isempty(comment)
                this.raw([ this.SpaceString comment ]);
            end
            
            this.wNewLine();
            
        end
        
        
        function wMultilineCommentEnd(this, comment)
            
            % Go to a fresh line, if necessary.
            if ~this.IsFreshLine
                this.wNewLine();
            end
            
            % Print the indent
            this.indent();
            
            
            % Now print the start of the multi-line comment.
            if nargin < 2 || isempty(comment)
                this.raw([ ' ' this.CommentEndString ]);
            else
                this.raw([ ' *' this.SpaceString comment this.SpaceString this.CommentEndString ]);
            end
            
            this.wNewLine();
            
        end
        
    end
    
    
    methods (Hidden, Access = public)
        % methods to bridge CCodeWriter with SimTargetCodeWriter. This
        % allows us to re-use the SIM Target functionality with our
        % CCodeWriter. These methods print out the contents "as-is" with no
        % formatting. This matches what SimTargetCodeWriter does.
        function writeString(this, content)
            this.raw(content);
        end
        function writeChar(this, content)
            this.raw(content);
        end        
    end
    
    
    
    methods(Access = protected)
        
        function endTag = getEndTag(this, startBlockComment)
        % GETENDTAG This specific implementation for C prints an end-tag
        % only if it is a control structure keyword.
            endTag = getEndTag@rtw.connectivity.CodeWriter(this, startBlockComment);
            if ~isKey(rtw.connectivity.CCodeWriter.BlockKeywordsMap, endTag)
                endTag = '';
            end
        end
        
    end
    
end
