class NaslDoc::CLI::Comment

Attributes

anonparams[RW]

Tag attributes.

anonparams_type[RW]

Tag attributes.

categories[RW]

Tag attributes.

deprecated[RW]

Tag attributes.

description[RW]

Freeform text attributes.

filename[RW]

File attributes.

function[RW]

Export and function attributes.

includes[RW]

Tag attributes.

name[R]

Common attributes.

nessus[RW]

Tag attributes.

params[RW]
params_type[RW]
remarks[RW]
return[RW]
signed[RW]

File attributes.

summary[RW]

Freeform text attributes.

type[R]

Common attributes.

valid[R]

Common attributes.

variables[RW]

Global attributes.

Public Class Methods

new(node, path) click to toggle source
# File lib/nasldoc/cli/comment.rb, line 78
def initialize(node, path)
        # Create common attributes.
        @name = nil
        @type = nil
        @valid = false

        # Create freeform text attributes.
        @summary = nil
        @description = nil

        # Create tag attributes.
        @anonparams = {}
        @anonparams_type = {}
        @categories = []
        @deprecated = nil
        @includes = []
        @nessus = nil
        @params = {}
        @params_type = {}
        @remarks = []
        @return = nil

        # Create export and function attributes.
        @function = nil

        # Create file attributes.
        @filename = nil
        @signed = nil

        # Create global attributes.
        @variables = []

        # Determine if this is a nasldoc comment.
        text = node.text.body;
        @valid = !Regexp.new("(^\s*\#{2,3}\s*$|#{trusted_regex})").match(text).nil?
        return unless @valid

        # Remember the type.
        unless node.next.nil?
                @type = node.next.class.name.gsub(/.*::/, '').downcase.to_sym
        else
                # The first comment in a file might not have a next node.
                @type = :file
        end

        # Store any other attributes we may need, since we're not keeping a
        # reference to the node.
        case @type
        when :export
                extract_function(node.function)
        when :file
                extract_file(node, path)
        when :function
                extract_function(node)
        when :global
                extract_global(node)
        else
                raise UnsupportedClassException, "The class #{node.next.class.name} is not supported."
        end

        # Parse the comment's text.
        parse(text)
end

Public Instance Methods

extract_file(node, path) click to toggle source
# File lib/nasldoc/cli/comment.rb, line 306
def extract_file(node, path)
        # Remember the filename.
        @filename = File.basename(path)

        # Name this comment for use in error messages.
        @name = "file #@filename"

        # Determine whether the filename is signed, but don't validate the
        # signature.
        @signed = !Regexp.new(trusted_regex).match(node.text.body).nil?
end
extract_function(node) click to toggle source
# File lib/nasldoc/cli/comment.rb, line 318
def extract_function(node)
        # Remember the function name.
        fn = node.next
        @function = fn.to_s
        @fn_type = fn.fn_type

        # Name this comment for use in error messages.
        @name = "function " + fn.name.name

        # Add in all named parameters, even ones that weren't annotated.
        fn.params.each { |arg| @params[arg.name] = nil }
end
extract_global(node) click to toggle source
# File lib/nasldoc/cli/comment.rb, line 331
def extract_global(node)
        # Remember all the variables.
        @variables = node.next.idents.map &:name

        # Name this comment for use in error messages.
        @name = "global variable(s) #{@variables.join(', ')}"
end
parse(text) click to toggle source
# File lib/nasldoc/cli/comment.rb, line 142
def parse(text)
        # Remove the trusted header.
        re_sig = Regexp.new(trusted_regex)
        text.gsub!(re_sig, '');

        # strip out empty comment lines with accidental whitespace afterwards
        text.gsub!(/^#+[ \t]+$/, '');
        # Remove the comment prefixes ('#') from the text.
        text.gsub!(/^#+/, '');

        # Parse all the paragraphs of free-form text.
        parse_paragraphs(text)

        # Parse all the tags.
        parse_tags(text)
end
parse_paragraphs(text) click to toggle source
# File lib/nasldoc/cli/comment.rb, line 159
def parse_paragraphs(text)
        re_none = Regexp.new(/[^[:space:]]/)
        re_tags = Regexp.new(tags_regex)

        # Collect together a list of paragraphs.
        min = 9999
        paras = []
        text.each_line('') do |para|
                # Skip if the paragraph has a line starting with a tag, or has no
                # content.
                next unless para =~ re_none
                next if para =~ re_tags
                para.rstrip!
                paras << para

                # Determine the minimum indentation across all paragraphs.
                para.each_line do |line|
                        padding = line[/^ */]
                        min = [min, padding.length].min

                        # No point in continuing if we hit the lower bound.
                        break if min == 0
                end
        end

        # Strip the minimum number of spaces from the left.
        if min > 0
                regex = Regexp.new("^ {#{min}}")
                paras.map! { |p| p.gsub(regex, '') }
        end

        # The first paragraph is the summary.
        @summary = paras.shift

        # The following paragraphs are the description.
        @description = paras
end
parse_tags(text) click to toggle source
# File lib/nasldoc/cli/comment.rb, line 197
def parse_tags(text)
        re_name = Regexp.new("(<|\\[)?[_a-zA-Z0-9:]*(\\]|>)?")
        re_tags = Regexp.new(tags_regex)

        # Tags start a line which continues until the next tag or blank line.
        text.each_line('') do |para|
                # Skip if the paragraph it doesn't have a line starting with a tag.
                next if para !~ re_tags

                # Break the paragraphs into blocks, each starting with a tag.
                until para.empty?
                        # Find the bounds of the block.
                        beg = para.index(re_tags)
                        break if beg.nil?
                        fin = para.index(re_tags, beg + 1) || -1

                        # Pull the block out of the paragraph.
                        block = para[beg..fin]
                        para = para[fin..-1]

                        # Remove the tag from the block.
                        tag = block[re_tags]
                        block = block[tag.length..-1]
                        next if block.nil?

                        # Squash all spaces on the block, being mindful that if the block is
                        # nil the tag is useless.
                        block.gsub!(/[ \n\r\t]+/, ' ')
                        next if block.nil?
                        block.strip!
                        next if block.nil?

                        # Squash the tag and trim the '@' off for accessing the object's
                        # attribute.
                        tag.lstrip!
                        attr = tag[1..-1]

                        case tag
                                when '@anonparam', '@param'
                                        # Parse the argument name.
                                        parts_str = block[re_name]
                                        if parts_str.nil?
                                                raise TagFormatException, "Failed to parse the #{tag}'s name for #@name."
                                        end

                                        parts = parts_str.split(':')

                                        name = parts[0]
                                        name = name.gsub(/[\[\]<>]/, '')

                                        block = block[parts_str.length..-1]

                                        if block.nil?
                                                raise TagFormatException, "Failed to parse the #{tag}'s block for #@name."
                                        end

                                        block.lstrip!

                                        type = nil
                                        if(parts.length > 1)
                                                  type = parts[1]
                                                  type = type.gsub(/[\[\]<>]/, '')
                                        end

                                        # Check for previous declarations of this name.
                                        if @anonparams.key?(name)
                                                raise DuplicateTagException, "The param '#{name}' was previously declared as an @anonparam for #@name."
                                        end

                                        if @params.key?(name) and not @params[name].nil?
                                                raise DuplicateTagException, "The param '#{name}' was previously declared as a @param for #@name."
                                        end
                                        hash = self.send(attr + 's')
                                        hash[name] = block
                                        
                                        if(!type.nil?)
                                          hash1 = self.send(attr + 's_type')
                                          hash1[name] = type
                                        end
                                        
                                when '@category'
                                        unless @categories.empty?
                                                raise DuplicateTagException, "The #{tag} tag appears more than once for #@name."
                                        end

                                        @categories = block.split(/,/).map &:strip
                                when '@deprecated', '@nessus', '@return'
                                        unless self.send(attr).nil?
                                                raise DuplicateTagException, "The #{tag} tag appears more than once for #@name."
                                        end

                                        self.send(attr + '=', block)
                                when '@include', '@remark'
                                        self.send(attr + 's').push(block)
                                else
                                        raise UnrecognizedTagException, "The #{tag} tag is not recognized in #@name."
                        end
                end
        end
end
tags_regex() click to toggle source
# File lib/nasldoc/cli/comment.rb, line 298
def tags_regex
        "^\s*@(#{@@tags.join('|')})"
end
trusted_regex() click to toggle source
# File lib/nasldoc/cli/comment.rb, line 302
def trusted_regex
        "^#TRUSTED [[:xdigit:]]{1024}$"
end