gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dc_url.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
60
61module dc_url
62 implicit none
63 private
64
65 public:: url_chop_iorange
66 public:: operator(.onthesamefile.)
67
68 public:: urlmerge
69 interface urlmerge
70! module procedure url_merge_v_vvv
71 module procedure url_merge_cc
72 module procedure url_merge_cccc
73 module procedure url_merge_cccca
74 end interface
75
76 public:: urlsplit
77 interface urlsplit
78! module procedure url_split_v
79 module procedure url_split_c
80 end interface
81
82 public:: urlresolve
83 interface urlresolve
84 module procedure url_resolve_c
85 end interface
86
87 public:: urlsearchiorange
89 module procedure url_search_iorange
90 end interface
91
92 interface operator(.onthesamefile.)
93 module procedure urlonthesamefile
94 end interface
95
96 character, public, parameter:: gt_atmark = "@"
97 ! ファイル名と変数名の区切りに用いられます。
98 character, public, parameter:: gt_question = "?"
99 ! ファイル名と変数名の区切りに用いられます。
100 character, public, parameter:: gt_colon = ":"
101 ! 変数の属性を示す時に用いられます。
102 character, public, parameter:: gt_comma = ","
103 ! 入出力範囲の限定に用いられます。
104 character, public, parameter:: gt_equal = "="
105 ! 入出力範囲の限定に用いられます。
106 character, public, parameter:: gt_circumflex = "^"
107 ! 座標の位置を値ではなく、
108 ! 格子点番号で指定する時に用いられます。
109 character, public, parameter:: gt_plus = "+"
110 ! 属性の行頭にこの文字がつく場合、大域属性を示します。
111
112contains
113
114 ! ANUrlMerge - 変数 URL の合成
115 ! 空文字列の成分はないとみなされる。
116
117! type(VSTRING) function &
118! & url_merge_v_vvv(file, var, attr, iorange) result(result) !:nodoc:
119! use dcstring_base, only: VSTRING, operator(.cat.), operator(/=), &
120! & extract, operator(==) !:nodoc:
121! implicit none
122! type(VSTRING), intent(in):: file
123! type(VSTRING), intent(in), optional:: var
124! type(VSTRING), intent(in), optional:: attr
125! type(VSTRING), intent(in), optional:: iorange
126! result = file .cat. GT_ATMARK
127! if (present(var)) result = result .cat. var
128! if (present(attr)) then
129! if (attr /= "") result = result .cat. GT_COLON .cat. attr
130! endif
131! if (present(iorange)) then
132! if (extract(iorange, 1, 1) == GT_COMMA) then
133! result = result .cat. iorange
134! else if (iorange /= "") then
135! result = result .cat. GT_COMMA .cat. iorange
136! endif
137! endif
138! end function
139
160 function url_merge_cc(file, var) result(result)
161 use dc_types, only: string
162 character(len = STRING):: result
163 character(len = *), intent(in):: file
164 character(len = *), intent(in):: var
165 continue
166 result = url_merge_cccc(file, var, "", "")
167 end function url_merge_cc
168
198 function url_merge_cccca(file, var, attr, iorange) result(result)
199 use dc_types, only: string
200 character(len = STRING):: result
201 character(len = *), intent(in):: file
202 character(len = *), intent(in):: var
203 character(len = *), intent(in):: attr
204 character(len = *), intent(in):: iorange(:)
205 integer:: i
206 continue
207 if (file /= "") then
208 result = trim(file) // gt_atmark
209 else
210 result = gt_atmark
211 endif
212 if (var /= "") result = trim(result) // var
213 if (attr /= "") then
214 result = trim(result) // gt_colon // attr
215 endif
216 do i = 1, size(iorange)
217 if (iorange(i) /= "") then
218 if (iorange(i)(1:1) == gt_comma) then
219 result = trim(result) // trim(iorange(i))
220 else
221 result = trim(result) // gt_comma // trim(iorange(i))
222 endif
223 endif
224 end do
225 end function url_merge_cccca
226
252 function url_merge_cccc(file, var, attr, iorange) result(result)
253 use dc_types, only: string
254 character(len = STRING):: result
255 character(len = *), intent(in):: file
256 character(len = *), intent(in):: var
257 character(len = *), intent(in):: attr
258 character(len = *), intent(in):: iorange
259 continue
260 if (trim(file) /= "") then
261 result = trim(file) // gt_atmark
262 else
263 result = gt_atmark
264 endif
265 if (trim(var) /= "") result = trim(result) // var
266 if (trim(attr) /= "") then
267 result = trim(result) // gt_colon // attr
268 endif
269 if (trim(iorange) /= "") then
270 if (iorange(1:1) == gt_comma) then
271 result = trim(result) // iorange
272 else
273 result = trim(result) // gt_comma // iorange
274 endif
275 endif
276 end function url_merge_cccc
277
300 subroutine url_chop_iorange(fullname, iorange, remainder)
301 use dc_types, only: string
302 character(len = *), intent(in):: fullname
303 character(len = *), intent(out):: iorange ! 入出力範囲指定部分
304 character(len = *), intent(out):: remainder ! 残りの部分
305 character(STRING):: file, var, attr
306 call urlsplit(fullname, file=file, var=var, attr=attr, iorange=iorange)
307 remainder = url_merge_cccc(file=file, var=var, attr=attr, iorange="")
308 end subroutine url_chop_iorange
309
345 function url_search_iorange(fullname, dimvar) result(result)
346 use dc_types, only: string
347 use dc_string, only: split
348 character(len = *), intent(in):: fullname
349 character(len = *), intent(in):: dimvar
350 character(len = STRING):: result
351 character(STRING):: file, var, attr, iorange
352 character(STRING), pointer :: ioranges_slice(:) => null()
353 integer :: i, eqpos, atmark
354 continue
355 result = ""
356 ! @ または ? が含まれているなら urlsplit で分離
357 atmark = index(fullname, gt_question)
358 if (atmark == 0) atmark = index(fullname, gt_atmark)
359 if (atmark /= 0) then
360 call urlsplit(fullname, file=file, var=var, attr=attr, iorange=iorange)
361 else
362 iorange = fullname
363 end if
364 call split(iorange, ioranges_slice, gt_comma)
365 do i = 1, size(ioranges_slice)
366 eqpos = index(ioranges_slice(i), gt_equal)
367 if (ioranges_slice(i)(1:eqpos-1) == trim(dimvar)) then
368 result = trim(ioranges_slice(i)(eqpos+1:))
369 exit
370 end if
371 end do
372 deallocate(ioranges_slice)
373 end function url_search_iorange
374
403 subroutine url_split_c(fullname, file, var, attr, iorange)
404 use dc_types, only: string
405 character(len = *), intent(in):: fullname
406 character(len = *), intent(out), optional:: file, var, attr, iorange
407 character(len = STRING):: varpart
408 integer:: atmark, colon, comma
409 character(len = *), parameter:: VARNAME_SET &
410 = "0123456789eEdD+-=^,.:_" &
411 // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" &
412 // "abcdefghijklmnopqrstuvwxyz"
413 continue
414 ! まず URL と変数属性指定 (? または @ 以降) を分離する。
415 ! URL は @ を含みうるため、最後の @ 以降に対して変数属性
416 ! として許されない文字(典型的には '/')が含まれていたら
417 ! 当該 @ は URL の一部とみなす。
418 atmark = index(fullname, gt_question)
419 if (atmark == 0) then
420 atmark = index(fullname, gt_atmark, back=.true.)
421 if (atmark /= 0) then
422 if (verify(trim(fullname(atmark+1: )), varname_set) /= 0) then
423 atmark = 0
424 endif
425 endif
426 endif
427 if (atmark == 0) then
428 ! 変数属性指定はなかった。
429 if (present(file)) file = fullname
430 if (present(var)) var = ''
431 if (present(attr)) attr = ''
432 if (present(iorange)) iorange = ''
433 return
434 endif
435 varpart = fullname(atmark+1: )
436 ! 変数属性指定があった。
437 if (present(file)) file = fullname(1: atmark - 1)
438 ! 範囲指定を探索する。
439 comma = index(varpart, gt_comma)
440 if (comma /= 0) then
441 ! 範囲指定がみつかった。
442 if (present(var)) var = varpart(1: comma - 1)
443 if (present(attr)) attr = ''
444 if (present(iorange)) iorange = varpart(comma + 1: )
445 return
446 endif
447 if (present(iorange)) iorange = ''
448 ! 範囲指定がなかったので、属性名の検索をする。
449 colon = index(varpart, gt_colon)
450 if (colon == 0) then
451 if (present(var)) var = varpart
452 if (present(attr)) attr = ''
453 varpart = ''
454 return
455 endif
456 if (present(var)) var = varpart(1: colon - 1)
457 if (present(attr)) attr = varpart(colon + 1: )
458 varpart = ''
459 end subroutine url_split_c
460
461! subroutine url_split_v(fullname, file, var, attr, iorange) !:nodoc:
462! use dcstring_base, only: VSTRING, operator(.cat.), operator(/=), &
463! & extract, operator(==) !:nodoc:
464! use dc_string
465! implicit none
466! type(VSTRING), intent(in):: fullname
467! type(VSTRING), intent(out), optional:: file, var, attr, iorange
468! type(VSTRING):: varpart
469! integer:: atmark, colon, comma
470! character(len = *), parameter:: VARNAME_SET &
471! = "0123456789eEdD+-=^,.:_" &
472! // "ABCDEFGHIJKLMNOPQRSTUVWXYZ" &
473! // "abcdefghijklmnopqrstuvwxyz"
474! continue
475! ! まず URL と変数属性指定 (? または @ 以降) を分離する。
476! ! URL は @ を含みうるため、最後の @ 以降に対して変数属性
477! ! として許されない文字(典型的には '/')が含まれていたら
478! ! 当該 @ は URL の一部とみなす。
479! atmark = vindex(fullname, GT_QUESTION)
480! if (atmark == 0) then
481! atmark = vindex(fullname, GT_ATMARK, .TRUE.)
482! if (atmark /= 0) then
483! varpart = extract(fullname, atmark + 1)
484! if (vverify(varpart, VARNAME_SET) /= 0) then
485! atmark = 0
486! endif
487! endif
488! endif
489! if (atmark == 0) then
490! ! 変数属性指定はなかった。
491! if (present(file)) file = fullname
492! if (present(var)) var = ''
493! if (present(attr)) attr = ''
494! if (present(iorange)) iorange = ''
495! return
496! endif
497! varpart = extract(fullname, atmark + 1)
498! ! 変数属性指定があった。
499! if (present(file)) file = extract(fullname, 1, atmark - 1)
500! ! 範囲指定を探索する。
501! comma = vindex(varpart, GT_COMMA)
502! if (comma /= 0) then
503! ! 範囲指定がみつかった。
504! if (present(var)) var = extract(varpart, 1, comma - 1)
505! if (present(attr)) attr = ''
506! if (present(iorange)) iorange = extract(varpart, comma + 1)
507! return
508! endif
509! if (present(iorange)) iorange = ''
510! ! 範囲指定がなかったので、属性名の検索をする。
511! colon = vindex(varpart, GT_COLON)
512! if (colon == 0) then
513! if (present(var)) var = varpart
514! if (present(attr)) attr = ''
515! varpart = ''
516! return
517! endif
518! if (present(var)) var = extract(varpart, 1, colon - 1)
519! if (present(attr)) attr = extract(varpart, colon + 1)
520! varpart = ''
521! end subroutine url_split_v
522
549 logical function urlonthesamefile(url_a, url_b) result(result)
550 use dc_string
551 use dc_types, only: string
552 character(len = *), intent(in) :: url_a
553 character(len = *), intent(in) :: url_b
554 character(len = STRING) :: filepart_a
555 character(len = STRING) :: filepart_b
556 call urlsplit(url_a, file=filepart_a)
557 call urlsplit(url_b, file=filepart_b)
558 result = (filepart_a == filepart_b)
559 end function urlonthesamefile
560
584 function url_resolve_c(relative, base) result(result)
585 use dc_string, only: strhead
586 use dc_types, only: string
588 implicit none
589 character(len = *), intent(in):: relative
590 character(len = *), intent(in):: base
591 character(len = STRING):: result
592 integer, parameter:: file = 1, var = 2, attr = 3, ior = 4
593 character(len = STRING):: rel(file:ior), bas(file:ior)
594 character(3), parameter:: pathdelim = "/:" // achar(94)
595 integer:: idir_r, idir_b
596 continue
597 call beginsub('urlresolve', 'rel=<%c> base=<%c>', c1=relative, c2=base)
598 call urlsplit(trim(relative), file=rel(file), var=rel(var), &
599 & attr=rel(attr), iorange=rel(ior))
600 call dbgmessage('rel -> file=<%c> var=<%c> attr=<%c>', &
601 & c1=trim(rel(file)), c2=trim(rel(var)), &
602 & c3=(trim(rel(attr)) // '> ior=<' // trim(rel(ior))))
603 call urlsplit(base, file=bas(file), var=bas(var), &
604 & attr=bas(attr), iorange=bas(ior))
605 call dbgmessage('base -> file=<%s> var=<%s> attr=<%s> ior=<%s>', &
606 & c1=trim(bas(file)), c2=trim(bas(var)), &
607 & c3=(trim(bas(attr)) // '> ior=<' // trim(bas(ior))))
608 ! --- ファイル名を欠くばあいは単に補う ---
609 if (rel(file) == "") then
610 rel(file) = bas(file)
611 if (rel(var) == "") &
612 & rel(var) = bas(var)
613 result = urlmerge(file=rel(file), var=rel(var), &
614 & attr=rel(attr), iorange=rel(ior))
615 call endsub('urlresolve', '1 result=%c', c1=trim(result))
616 return
617 endif
618 ! --- 絶対パス (と見られる) ファイル名はそのまま使用 ---
619 if (strhead(rel(file), "file:") &
620 & .OR. strhead(rel(file), "http:") &
621 & .OR. strhead(rel(file), "ftp:") &
622 & .OR. strhead(rel(file), "news:") &
623 & .OR. strhead(rel(file), "www") &
624 & .OR. strhead(rel(file), "/") &
625 & .OR. strhead(rel(file), achar(94)) &
626 & .OR. rel(file)(2:2) == ":" &
627 ) then
628 result = relative
629 call endsub('urlresolve', '2 result=%c', c1=trim(result))
630 return
631 endif
632 ! ディレクトリ名の取り出し
633 idir_b = scan(bas(file), pathdelim, back=.true.)
634 if (idir_b == 0) then
635 ! が、できなければ、(エラーとすべきかもしれぬが)
636 ! 相対パスをそのまま使用
637 result = relative
638 call endsub('urlresolve', '3 result=%c', c1=trim(result))
639 return
640 endif
641 ! 相対パスのほうのディレクトリ名の取り出し
642 idir_r = scan(rel(file), pathdelim, back=.true.)
643 if (idir_r == 0) then
644 ! ができなければ全体を使用
645 idir_r = 1
646 endif
647 result = base(1: idir_b) // relative(idir_r: )
648 call endsub('urlresolve', '4 result=%c', c1=trim(result))
649 end function url_resolve_c
650
652end module dc_url
Handling character types.
Definition dc_string.f90:83
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public dbgmessage(fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:680
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:476
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:599
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
Variable URL string parser.
Definition dc_url.f90:61
character, parameter, public gt_atmark
Definition dc_url.f90:96
character, parameter, public gt_plus
Definition dc_url.f90:109
character, parameter, public gt_comma
Definition dc_url.f90:102
subroutine, public url_chop_iorange(fullname, iorange, remainder)
Definition dc_url.f90:301
character, parameter, public gt_equal
Definition dc_url.f90:104
character, parameter, public gt_colon
Definition dc_url.f90:100
character, parameter, public gt_circumflex
Definition dc_url.f90:106
character, parameter, public gt_question
Definition dc_url.f90:98