integer function vtable_add(var, entry) result(result)
type(an_variable), intent(out):: var
type(an_variable_search), intent(in):: entry
type(an_variable_entry), allocatable:: tmp_table(:)
integer:: i, n
! --- 必要なら初期確保 ---
if (.not. allocated(antab)) then
allocate(antab(antab_init_size), stat=result)
if (result /= 0) goto 999
do, i = 1, antab_init_size
antab(i)%fileid = 0
antab(i)%varid = 0
antab(i)%dimid = 0
antab(i)%attrid = 0
nullify(antab(i)%dimids)
enddo
endif
! --- 同じ内容が既登録ならばそれを返す (attrid は変更しない) ---
do, i = 1, size(antab)
if (antab(i)%fileid == entry%fileid .and. antab(i)%varid == entry%varid .and. antab(i)%dimid == entry%dimid) then
var = an_variable(i)
result = NF_NOERR
call DbgMessage('an_vartable.add: found %d', i=(/i/))
return
endif
enddo
!
! --- 空き地があればそこに割り当て ---
var = an_variable(-1)
do, i = 1, size(antab)
if (antab(i)%fileid == 0) then
var = an_variable(i)
exit
endif
enddo
if (var%id == -1) then
! --- 空き地はなかったのだから倍幅確保 ---
n = size(antab)
allocate(tmp_table(n), stat=result)
if (result /= 0) goto 999
tmp_table(:) = antab(:)
deallocate(antab, stat=result)
if (result /= 0) goto 999
allocate(antab(n * 2), stat=result)
if (result /= 0) goto 999
antab(1:n) = tmp_table(1:n)
deallocate(tmp_table, stat=result)
if (result /= 0) goto 999
!
antab(n+2)%fileid = 0
antab(n+2)%varid = 0
antab(n+2)%dimid = 0
antab(n+2)%attrid = 0
nullify(antab(n+2)%dimids)
antab(n+3: n*2) = antab(n+2)
! 確保域の先頭を使用
var = an_variable(n + 1)
endif
antab(var%id)%fileid = entry%fileid
antab(var%id)%varid = entry%varid
antab(var%id)%dimid = entry%dimid
!
! --- 次元表の確保 ---
call internal_build_dimids(antab(var%id), result)
if (result /= nf_noerr) goto 999
!
result = nf_noerr
call DbgMessage('an_vartable.add: added %d', i=(/var%id/))
return
!
999 continue
var = an_variable(-1)
result = NF_ENOMEM
return
contains
end function