subroutinecollect_docsprivate
subroutine collect_docs(src, s, docs, file_doc)
Find the documentation of each code statement.
Arguments
| Name | Type | Intent | Attributes | Description |
|---|---|---|---|---|
| src | type(source_t) | in | the source | |
| s | type(settings_t) | in | the settings | |
| docs | type(doc_lines_t) | out | allocatabledimension(:) | the documentation of each item |
| file_doc | type(string_t) | out | allocatabledimension(:) | documentation before the first statement |
Calls
- comment_line
- push
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