Class dc_url
In: src/dc_url.f90

変数 URL の文字列解析

Methods

Included Modules

dcstring_base dc_types dc_string dc_trace

Public Instance methods

result :character(len = string)
file :character(len = *), intent(in)
var :character(len = *), intent(in)

空文字列の成分はないとみなされる。

[Source]




    function url_merge_cc(file, var) result(result)

        character(len = string):: result
        character(len = *), intent(in):: file
        character(len = *), intent(in):: var
    continue
        result = url_merge_cccc(file, var, "", "")
    end function
result :type(VSTRING)
file :type(VSTRING), intent(in)
var :type(VSTRING), intent(in), optional
attr :type(VSTRING), intent(in), optional
iorange :type(VSTRING), intent(in), optional

空文字列の成分はないとみなされる。

[Source]


        type(VSTRING) function     url_merge_v_vvv(file, var, attr, iorange) result(result)
        type(VSTRING), intent(in):: file
        type(VSTRING), intent(in), optional:: var
        type(VSTRING), intent(in), optional:: attr
        type(VSTRING), intent(in), optional:: iorange
        result = file .cat. GT_ATMARK
        if (present(var)) result = result .cat. var
        if (present(attr)) then
            if (attr /= "") result = result .cat. GT_COLON .cat. attr
        endif
        if (present(iorange)) then
            if (extract(iorange, 1, 1) == GT_COMMA) then
                result = result .cat. iorange
            else if (iorange /= "") then
                result = result .cat. GT_COMMA .cat. iorange
            endif
        endif
    end function
result :character(len = string)
file :character(len = *), intent(in)
var :character(len = *), intent(in)
attr :character(len = *), intent(in)
iorange(:) :character(len = *), intent(in)

空文字列の成分はないとみなされる。

[Source]




    function url_merge_cccca(file, var, attr, iorange) result(result)

        character(len = string):: result
        character(len = *), intent(in):: file
        character(len = *), intent(in):: var
        character(len = *), intent(in):: attr
        character(len = *), intent(in):: iorange(:)
        integer:: i
    continue
        if (file /= "") then
            result = trim(file) // gt_atmark
        else
            result = gt_atmark
        endif
        if (var /= "") result = trim(result) // var
        if (attr /= "") then
            result = trim(result) // gt_colon // attr
        endif
        do i = 1, size(iorange)
           if (iorange(i) /= "") then
              if (iorange(i)(1:1) == gt_comma) then
                 result = trim(result) // trim(iorange(i))
              else
                 result = trim(result) // gt_comma // trim(iorange(i))
              endif
           endif
        end do
    end function
result :character(len = string)
file :character(len = *), intent(in)
var :character(len = *), intent(in)
attr :character(len = *), intent(in)
iorange :character(len = *), intent(in)

空文字列の成分はないとみなされる。

[Source]



    function url_merge_cccc(file, var, attr, iorange) result(result)

        character(len = string):: result
        character(len = *), intent(in):: file
        character(len = *), intent(in):: var
        character(len = *), intent(in):: attr
        character(len = *), intent(in):: iorange
    continue
        if (trim(file) /= "") then
            result = trim(file) // gt_atmark
        else
            result = gt_atmark
        endif
        if (trim(var) /= "") result = trim(result) // var
        if (trim(attr) /= "") then
            result = trim(result) // gt_colon // attr
        endif
        if (trim(iorange) /= "") then
            if (iorange(1:1) == gt_comma) then
                result = trim(result) // iorange
            else
                result = trim(result) // gt_comma // iorange
            endif
        endif
    end function
result :character(len = STRING)
relative :character(len = *), intent(in)
base :character(len = *), intent(in)

相対リンクを解決 ===

[Source]


    function url_resolve_c(relative, base) result(result)

    implicit none
        character(len = *), intent(in):: relative
        character(len = *), intent(in):: base
        character(len = STRING):: result
        integer, parameter:: FILE = 1, VAR = 2, ATTR = 3, IOR = 4
        character(len = STRING):: rel(FILE:IOR), bas(FILE:IOR)
        character(3), parameter:: PATHDELIM = "/:" // achar(94)
        integer:: idir_r, idir_b
    continue
        call beginsub('urlresolve', 'rel=<%c> base=<%c>', c1=relative, c2=base)
        call UrlSplit(trim(relative), file=rel(FILE), var=rel(VAR),  attr=rel(ATTR), iorange=rel(IOR))
        call DbgMessage('rel -> file=<%c> var=<%c> attr=<%c>',  c1=trim(rel(FILE)), c2=trim(rel(VAR)),  c3=(trim(rel(ATTR)) // '> ior=<' // trim(rel(IOR))))
        call UrlSplit(base, file=bas(FILE), var=bas(VAR),  attr=bas(ATTR), iorange=bas(IOR))
        call DbgMessage('base -> file=<%s> var=<%s> attr=<%s> ior=<%s>',  c1=trim(bas(FILE)), c2=trim(bas(VAR)),  c3=(trim(bas(ATTR)) // '> ior=<' // trim(bas(IOR))))
        ! --- ファイル名を欠くばあいは単に補う ---
        if (rel(FILE) == "") then
            rel(FILE) = bas(FILE)
            if (rel(VAR) == "")  rel(VAR) = bas(VAR)
            result = UrlMerge(file=rel(FILE), var=rel(VAR),  attr=rel(ATTR), iorange=rel(IOR))
            call endsub('urlresolve', '1 result=%c', c1=trim(result))
            return
        endif
        ! --- 絶対パス (と見られる) ファイル名はそのまま使用 ---
        if (StrHead(rel(FILE), "file:")  .OR. StrHead(rel(FILE), "http:")  .OR. StrHead(rel(FILE), "ftp:")  .OR. StrHead(rel(FILE), "news:")  .OR. StrHead(rel(FILE), "www")  .OR. StrHead(rel(FILE), "/")  .OR. StrHead(rel(FILE), achar(94))  .OR. rel(FILE)(2:2) == ":"             ) then
            result = relative
            call endsub('urlresolve', '2 result=%c', c1=trim(result))
            return
        endif
        ! ディレクトリ名の取り出し
        idir_b = scan(bas(FILE), PATHDELIM, back=.TRUE.) 
        if (idir_b == 0) then
            ! が、できなければ、(エラーとすべきかもしれぬが)
            ! 相対パスをそのまま使用
            result = relative
            call endsub('urlresolve', '3 result=%c', c1=trim(result))
            return
        endif
        ! 相対パスのほうのディレクトリ名の取り出し
        idir_r = scan(rel(FILE), PATHDELIM, back=.TRUE.)
        if (idir_r == 0) then
            ! ができなければ全体を使用
            idir_r = 1
        endif
        result = base(1: idir_b) // relative(idir_r: )
        call endsub('urlresolve', '4 result=%c', c1=trim(result))
    end function
result :character(len = string)
fullname :character(len = *), intent(in)
iovar :character(len = *), intent(in)

[Source]

    function url_search_iorange(fullname, iovar) result(result)

        character(len = *), intent(in):: fullname
        character(len = *), intent(in):: iovar
        character(len = string):: result
        character(string):: file, var, attr, iorange
        character(string), pointer :: ioranges_slice(:) => null()
        integer :: i, eqpos, atmark
    continue
        result = ""
        ! @ または ? が含まれているなら urlsplit で分離
        atmark = index(fullname, GT_QUESTION)
        if (atmark == 0) atmark = index(fullname, GT_ATMARK)
        if (atmark /= 0) then
           call urlsplit(fullname, file=file, var=var, attr=attr, iorange=iorange)
        else
           iorange = fullname
        end if
        call Split(iorange, ioranges_slice, GT_COMMA)
        do i = 1, size(ioranges_slice)
           eqpos = index(ioranges_slice(i), GT_EQUAL)
           if (ioranges_slice(i)(1:eqpos-1) == trim(iovar)) then
              result = trim(ioranges_slice(i)(eqpos+1:))
              exit
           end if
        end do
        deallocate(ioranges_slice)
    end function
fullname :character(len = *), intent(in)
file :character(len = *), intent(out), optional
var :character(len = *), intent(out), optional
attr :character(len = *), intent(out), optional
iorange :character(len = *), intent(out), optional

見つからない成分には空文字列が代入される。

[Source]

    subroutine url_split_c(fullname, file, var, attr, iorange)

        character(len = *), intent(in):: fullname
        character(len = *), intent(out), optional:: file, var, attr, iorange
        character(len = string):: varpart
        integer:: atmark, colon, comma
        character(len = *), parameter:: VARNAME_SET             = "0123456789eEdD+-=^,.:_"             // "ABCDEFGHIJKLMNOPQRSTUVWXYZ"             // "abcdefghijklmnopqrstuvwxyz"
    continue
        ! まず URL と変数属性指定 (? または @ 以降) を分離する。
        ! URL は @ を含みうるため、最後の @ 以降に対して変数属性
        ! として許されない文字(典型的には '/')が含まれていたら
        ! 当該 @ は URL の一部とみなす。
        atmark = index(fullname, GT_QUESTION)
        if (atmark == 0) then
            atmark = index(fullname, GT_ATMARK, back=.TRUE.)
            if (atmark /= 0) then
                if (verify(trim(fullname(atmark+1: )), VARNAME_SET) /= 0) then
                    atmark = 0
                endif
            endif
        endif
        if (atmark == 0) then
            ! 変数属性指定はなかった。
            if (present(file)) file = fullname
            if (present(var)) var = ''
            if (present(attr)) attr = ''
            if (present(iorange)) iorange = ''
            return
        endif
        varpart = fullname(atmark+1: )
        ! 変数属性指定があった。
        if (present(file)) file = fullname(1: atmark - 1)
        ! 範囲指定を探索する。
        comma = index(varpart, GT_COMMA)
        if (comma /= 0) then
            ! 範囲指定がみつかった。
            if (present(var)) var = varpart(1: comma - 1)
            if (present(attr)) attr = ''
            if (present(iorange)) iorange = varpart(comma + 1: )
            return
        endif
        if (present(iorange)) iorange = ''
        ! 範囲指定がなかったので、属性名の検索をする。
        colon = index(varpart, GT_COLON)
        if (colon == 0) then
            if (present(var)) var = varpart
            if (present(attr)) attr = ''
            varpart = ''
            return
        endif
        if (present(var)) var = varpart(1: colon - 1)
        if (present(attr)) attr = varpart(colon + 1: )
        varpart = ''
    end subroutine
fullname :type(VSTRING), intent(in)
file :type(VSTRING), intent(out), optional
var :type(VSTRING), intent(out), optional
attr :type(VSTRING), intent(out), optional
iorange :type(VSTRING), intent(out), optional

見つからない成分には空文字列が代入される。

[Source]



    subroutine url_split_v(fullname, file, var, attr, iorange)

        type(VSTRING), intent(in):: fullname
        type(VSTRING), intent(out), optional::        file, var, attr, iorange
        type(VSTRING):: varpart
        integer:: atmark, colon, comma
        character(len = *), parameter:: VARNAME_SET             = "0123456789eEdD+-=^,.:_"             // "ABCDEFGHIJKLMNOPQRSTUVWXYZ"             // "abcdefghijklmnopqrstuvwxyz"
    continue
        ! まず URL と変数属性指定 (? または @ 以降) を分離する。
        ! URL は @ を含みうるため、最後の @ 以降に対して変数属性
        ! として許されない文字(典型的には '/')が含まれていたら
        ! 当該 @ は URL の一部とみなす。
        atmark = vindex(fullname, GT_QUESTION)
        if (atmark == 0) then
            atmark = vindex(fullname, GT_ATMARK, .TRUE.)
            if (atmark /= 0) then
                varpart = extract(fullname, atmark + 1)
                if (vverify(varpart, VARNAME_SET) /= 0) then
                    atmark = 0
                endif
            endif
        endif
        if (atmark == 0) then
            ! 変数属性指定はなかった。
            if (present(file)) file = fullname
            if (present(var)) var = ''
            if (present(attr)) attr = ''
            if (present(iorange)) iorange = ''
            return
        endif
        varpart = extract(fullname, atmark + 1)
        ! 変数属性指定があった。
        if (present(file)) file = extract(fullname, 1, atmark - 1)
        ! 範囲指定を探索する。
        comma = vindex(varpart, GT_COMMA)
        if (comma /= 0) then
            ! 範囲指定がみつかった。
            if (present(var)) var = extract(varpart, 1, comma - 1)
            if (present(attr)) attr = ''
            if (present(iorange)) iorange = extract(varpart, comma + 1)
            return
        endif
        if (present(iorange)) iorange = ''
        ! 範囲指定がなかったので、属性名の検索をする。
        colon = vindex(varpart, GT_COLON)
        if (colon == 0) then
            if (present(var)) var = varpart
            if (present(attr)) attr = ''
            varpart = ''
            return
        endif
        if (present(var)) var = extract(varpart, 1, colon - 1)
        if (present(attr)) attr = extract(varpart, colon + 1)
        varpart = ''
    end subroutine
fullname :character(len = *), intent(in)
: url 全体
iorange :character(len = *), intent(out)
: iorange 部分のみを返す
remainder :character(len = *), intent(out)
: 残りの部分を返す

[Source]

    subroutine url_chop_iorange(fullname, iorange, remainder)

        ! url 全体
        character(len = *), intent(in):: fullname
        ! iorange 部分のみを返す
        character(len = *), intent(out):: iorange
        ! 残りの部分を返す
        character(len = *), intent(out):: remainder
        character(string):: file, var, attr
        call urlsplit(fullname, file=file, var=var, attr=attr, iorange=iorange)
        remainder = url_merge_cccc(file=file, var=var, attr=attr, iorange="")
    end subroutine

[Validate]