fdoc

subroutinecollect_docsprivate

subroutine collect_docs(src, s, docs, file_doc)

Find the documentation of each code statement.

Arguments

NameTypeIntentAttributesDescription
srctype(source_t)in

the source

stype(settings_t)in

the settings

docstype(doc_lines_t)outallocatabledimension(:)

the documentation of each item

file_doctype(string_t)outallocatabledimension(:)

documentation before the first statement

Calls

Source

Show the code
subroutine collect_docs(src, s, docs, file_doc)
    type(source_t), intent(in) :: src                       !! the source
    type(settings_t), intent(in) :: s                       !! the settings
    type(doc_lines_t), allocatable, intent(out) :: docs(:)  !! the documentation of each item
    type(string_t), allocatable, intent(out) :: file_doc(:) !! documentation before the first statement
    type(string_t), allocatable :: pending(:)
    logical :: in_predoc, in_predoc_alt, in_alt
    integer :: k, t, last

    allocate (docs(src%stmts%n), pending(0), file_doc(0))
    in_predoc = .false.
    in_predoc_alt = .false.
    in_alt = .false.
    last = 0
    do k = 1, src%stmts%n
        associate (item => src%stmts%s(k))
            select case (item%kind)
            case (SK_COMMENT)
                do t = item%first, item%last
                    if (src%tokens%tok(t)%kind == TK_COMMENT) then
                        call comment_line(src%text(src%tokens%tok(t)%first:src%tokens%tok(t)%last))
                    end if
                end do
            case (SK_BLANK)
                in_alt = .false.
                if (last > 0 .and. .not. in_predoc .and. .not. in_predoc_alt .and. size(pending) == 0) then
                    if (allocated(docs(last)%lines)) then
                        if (size(docs(last)%lines) > 0) call push(docs(last)%lines, '')
                    end if
                end if
            case (SK_CODE)
                call move_alloc(pending, docs(k)%lines)
                allocate (pending(0))
                in_predoc = .false.
                in_predoc_alt = .false.
                in_alt = .false.
                last = k
                do t = item%first, item%last
                    if (src%tokens%tok(t)%kind == TK_COMMENT) then
                        call comment_line(src%text(src%tokens%tok(t)%first:src%tokens%tok(t)%last))
                        in_alt = .false.
                    end if
                end do
            end select
        end associate
    end do

contains

    !> Handle one comment.
    subroutine comment_line(c)
        character(len=*), intent(in) :: c   !! the comment, from its `!`

        if (has_mark(c, s%predocmark)) then
            in_predoc = .true.
            in_alt = .false.
            in_predoc_alt = .false.
            call push(pending, strip_trailing(c(2 + len(s%predocmark):)))
        else if (has_mark(c, s%predocmark_alt)) then
            in_predoc_alt = .true.
            in_predoc = .false.
            in_alt = .false.
            call push(pending, strip_trailing(c(2 + len(s%predocmark_alt):)))
        else if (has_mark(c, s%docmark_alt)) then
            in_alt = .true.
            in_predoc = .false.
            in_predoc_alt = .false.
            call add_post(c(2 + len(s%docmark_alt):))
        else if (has_mark(c, s%docmark)) then
            in_alt = .false.
            in_predoc_alt = .false.
            if (in_predoc) then
                call push(pending, strip_trailing(c(2 + len(s%docmark):)))
            else
                call add_post(c(2 + len(s%docmark):))
            end if
        else if (in_predoc_alt) then
            call push(pending, strip_trailing(c(2:)))
        else if (in_alt) then
            call add_post(c(2:))
        end if
    end subroutine comment_line

    !> Add a line to the documentation of the last statement, or of the file before any statement.
    subroutine add_post(line)
        character(len=*), intent(in) :: line    !! the line
        if (last == 0) then
            call push(file_doc, strip_trailing(line))
        else
            if (.not. allocated(docs(last)%lines)) allocate (docs(last)%lines(0))
            call push(docs(last)%lines, strip_trailing(line))
        end if
    end subroutine add_post

end subroutine collect_docs

Graphs

Calls

Called by