go_string.F90 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573
  1. !###############################################################################
  2. !
  3. ! NAME
  4. ! GO_String - general objects for character strings
  5. !
  6. ! PROCEDURES
  7. !
  8. ! call goSplitLine( 'ab#cd', s1, '#', s2, status )
  9. !
  10. ! Splits a string like 'ab#cd' at the first '#', and returns
  11. ! the leading part in s1, and the rest in s2.
  12. ! One or both of s1 and s2 might be empty.
  13. !
  14. ! call goReadFromLine( line, x, status [,sep=','] [,default=value] )
  15. !
  16. ! Splits the string "line" at the first komma
  17. ! (or the character specified by the optional argument "sep"),
  18. ! fills the integer|real|logical|character variable "x" with the
  19. ! leading part, and returns the remainder in "line".
  20. ! If the leading part is empty, the default is returned if presend
  21. ! or otherwise an error is raised.
  22. !
  23. ! call goSplitString( 'aa c', n, values, status )
  24. !
  25. ! Split the input string at white spaces and return fields:
  26. ! n : integer, number of fields extracted
  27. ! values : character or real array to store fields;
  28. ! error status returned if size or lengths are not sufficient
  29. !
  30. ! call MatchValue( 'aa' , (/'aa ','bbb','c ','ddd'/), ind, status [,quiet=.false.] )
  31. !
  32. ! Compare character value with values in character list,
  33. ! return index of matching element.
  34. ! Negative status if not found.
  35. ! Print error messages unless quiet is true.
  36. ! Case independent.
  37. !
  38. ! call MatchValues( 'aa c' , (/'aa ','bbb','c ','ddd'/), n, values, inds, status [,quiet=.false.] )
  39. ! call MatchValues( '0 1 2', 1, 10 , n, values , status [,quiet=.false.] )
  40. !
  41. ! Read the values from the input line and compare with a
  42. ! list of character values or a range of integers. Output:
  43. ! n : integer, number of values in list (and output arrays)
  44. ! values : array with found values, same type as input list
  45. ! inds : integer indices in list with possible values
  46. !
  47. !
  48. ! bb = 'default'
  49. ! call goVarValue( 'aa=1;bb=xyz;cc=U123', ';', 'bb', '=', bb, status )
  50. !
  51. ! Read value from a line with multiple <name><is><value> triples,
  52. ! seperated by the specified character.
  53. ! If multiple matching values are found, the last one is returned.
  54. ! Return status:
  55. ! <0 : variable not found, val remains the same
  56. ! 0 : variable(s) found, val reset;
  57. ! >0 : error
  58. !
  59. ! s = goNum2Str( i [,fmt='(i6)'] )
  60. !
  61. ! Returns a 6-character string with the representation of the
  62. ! integer value i in the first characters.
  63. ! Use
  64. ! trim(gonum2str(i))
  65. ! to obtain a string of smallest size.
  66. !
  67. ! s2 = goUpCase( s1 )
  68. ! s2 = goLoCase( s1 )
  69. !
  70. ! Convert to upper or lower case
  71. !
  72. ! call goTab2Space( s )
  73. !
  74. ! Replaces each tab-character in s by a space.
  75. !
  76. ! call goReplace( line, key, s, status )
  77. ! call goReplace( line, key, fmt, i, status )
  78. ! call goReplace( line, key, fmt, r, status )
  79. !
  80. ! Replace all instances of the key in the line by the
  81. ! character replacement s, or by a formatted integer or real value.
  82. !
  83. ! call goTranslate( line, chars, repl, status )
  84. !
  85. ! Replace all instances of the characters in 'chars' by 'repl' .
  86. ! Example:
  87. ! s = '2000-01-02 03:04:05'
  88. ! print *, 'before translation : "'//trim(s)//'"'
  89. ! call goTranslate( s, '-:', ' ', status )
  90. ! print *, 'after translation : "'//trim(s)//'"'
  91. ! will show:
  92. ! before translation : "2000-01-02 03:04:05"
  93. ! after translation : "2000 01 02 03 04 05"
  94. !
  95. !
  96. !### macro's #####################################################
  97. !
  98. #define TRACEBACK write (gol,'("in ",a," (",a,i6,")")') rname, __FILE__, __LINE__ ; call goErr
  99. !
  100. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  101. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  102. !
  103. !#################################################################
  104. module GO_String
  105. use GO_Print, only : gol, goPr, goErr
  106. implicit none
  107. ! --- in/out -----------------------------
  108. private
  109. public :: goSplitLine
  110. public :: goReadFromLine
  111. public :: goSplitString
  112. public :: goMatchValue
  113. public :: goMatchValues
  114. public :: goVarValue
  115. public :: goNum2str
  116. public :: goUpCase, goLoCase
  117. public :: goWriteKeyNum
  118. public :: goTab2Space
  119. public :: goReplace, goTranslate
  120. ! --- const ---------------------------------
  121. character(len=*), parameter :: mname = 'GO_String'
  122. ! --- interfaces -------------------------------------
  123. interface goReadFromLine
  124. module procedure ReadFromLine_i
  125. module procedure ReadFromLine_r
  126. module procedure ReadFromLine_l
  127. module procedure ReadFromLine_s
  128. end interface
  129. interface goSplitString
  130. module procedure goSplitString_s
  131. module procedure goSplitString_r
  132. end interface
  133. interface goMatchValue
  134. module procedure MatchValue_s
  135. end interface
  136. interface goMatchValues
  137. module procedure MatchValues_s
  138. module procedure MatchValues_i
  139. end interface
  140. interface goVarValue
  141. module procedure goVarValue_s
  142. module procedure goVarValue_i
  143. module procedure goVarValue_r
  144. module procedure goVarValue_l
  145. end interface
  146. interface goNum2str
  147. module procedure num2str_i
  148. module procedure num2str_r
  149. end interface
  150. interface goUpCase
  151. module procedure UpCase
  152. end interface
  153. interface goLoCase
  154. module procedure LoCase
  155. end interface
  156. interface goWriteKeyNum
  157. module procedure WriteKeyNum
  158. end interface
  159. interface goReplace
  160. module procedure goReplace_s
  161. module procedure goReplace_i
  162. end interface
  163. contains
  164. !**********************************************************************
  165. subroutine goSplitLine( line, s1, c, s2, status )
  166. ! --- in/out ----------------------------
  167. character(len=*), intent(in) :: line
  168. character(len=*), intent(out) :: s1
  169. character(len=1), intent(in) :: c
  170. character(len=*), intent(out) :: s2
  171. integer, intent(out) :: status
  172. ! --- local -----------------------------
  173. integer :: l, pos
  174. character(len=len(line)) :: s
  175. ! --- begin -----------------------------
  176. s = line
  177. l = len_trim(s)
  178. pos = scan(s,c)
  179. if ( (pos<1) .or. (pos>l) ) then
  180. ! s='abcd' -> s1='abcd', s2=''
  181. !call AdjustLeft( s1, s(1:l) )
  182. s1 = AdjustL( s(1:l) )
  183. s2 = ''
  184. else if (pos==1) then
  185. ! s=',' or s=',abcd' -> s1='', s2='' or 'abcd'
  186. s1 = ''
  187. if (l==1) then
  188. ! s=','
  189. s2 = ''
  190. else
  191. !call AdjustLeft( s2, s(pos+1:l) )
  192. s2 = AdjustL( s(pos+1:l) )
  193. end if
  194. else
  195. ! s='ab,' or s='ab,cd'
  196. !call AdjustLeft( s1, s(1:pos-1) )
  197. s1 = AdjustL( s(1:pos-1) )
  198. if (pos==l) then
  199. ! s='ab,'
  200. s2 = ''
  201. else
  202. ! s='ab,cd'
  203. !call AdjustLeft( s2, s(pos+1:l) )
  204. s2 = AdjustL( s(pos+1:l) )
  205. end if
  206. end if
  207. ! ok
  208. status = 0
  209. end subroutine goSplitLine
  210. ! ***
  211. ! subroutine AdjustLeft( t, s )
  212. !
  213. ! ! --- in/out ----------------------
  214. !
  215. ! character(len=*), intent(out) :: t
  216. ! character(len=*), intent(in) :: s
  217. !
  218. ! ! --- local -----------------------
  219. !
  220. ! integer :: is,ls, lt
  221. !
  222. ! ! --- local -----------------------
  223. !
  224. ! lt = len(t)
  225. !
  226. ! ls = len_trim(s)
  227. ! if (ls==0) then
  228. ! t = ''
  229. ! else
  230. ! is = 0
  231. ! do
  232. ! is = is + 1
  233. ! if (s(is:is)/=' ') exit
  234. ! if (is==ls) exit
  235. ! end do
  236. ! if (ls-is+1 > lt) then
  237. ! print *, 'AdjustLeft : error : target is to small ', &
  238. ! '(',lt,') to contain "'//s//'".'
  239. ! stop
  240. ! end if
  241. ! t = s(is:ls)
  242. ! end if
  243. !
  244. ! end subroutine AdjustLeft
  245. ! *****************************************************
  246. subroutine ReadFromLine_i( s, i, status, sep, default )
  247. ! --- in/out --------------------------
  248. character(len=*), intent(inout) :: s
  249. integer, intent(inout) :: i
  250. integer, intent(out) :: status
  251. character(len=1), intent(in), optional :: sep
  252. integer, intent(in), optional :: default
  253. ! --- const ----------------------------
  254. character(len=*), parameter :: rname = mname//'/ReadFromLine_i'
  255. ! --- local ----------------------------
  256. character(len=len(s)) :: s1, s2
  257. character(len=1) :: thesep
  258. ! --- begin ----------------------------
  259. ! default seperation character provided as argument:
  260. thesep = ','
  261. if (present(sep)) thesep = sep
  262. ! split at seperation character:
  263. call goSplitLine( s, s1, thesep, s2, status )
  264. IF_ERROR_RETURN(status=1)
  265. ! empty leading part ?
  266. if ( len_trim(s1) == 0 ) then
  267. ! default provided ?
  268. if ( present(default) ) then
  269. i = default
  270. else
  271. write (gol,'("found empty leading part while no default specified:")'); call goErr
  272. write (gol,'(" line : `",a,"`")') trim(s); call goErr
  273. write (gol,'(" sep : `",a,"`")') trim(thesep); call goErr
  274. TRACEBACK; status=1; return
  275. end if
  276. else
  277. ! read from leading part:
  278. read (s1,*,iostat=status) i
  279. if ( status /= 0 ) then
  280. write (gol,'(a," while reading integer out of `",a,"`")') trim(s); call goErr
  281. write (gol,'("in ",a)') rname; call goErr; status=1; return
  282. end if
  283. end if
  284. ! return remainder:
  285. s = s2
  286. ! ok
  287. status = 0
  288. end subroutine ReadFromLine_i
  289. ! ***
  290. subroutine ReadFromLine_r( s, r, status, sep, default )
  291. ! --- in/out --------------------------
  292. character(len=*), intent(inout) :: s
  293. real, intent(out) :: r
  294. integer, intent(out) :: status
  295. character(len=1), intent(in), optional :: sep
  296. real, intent(in), optional :: default
  297. ! --- const ------------------------------
  298. character(len=*), parameter :: rname = mname//'/ReadFromLine_r'
  299. ! --- local ----------------------------
  300. character(len=len(s)) :: s1, s2
  301. character(len=1) :: thesep
  302. ! --- begin ----------------------------
  303. ! default seperation character provided as argument:
  304. thesep = ','
  305. if (present(sep)) thesep = sep
  306. ! split at seperation character:
  307. call goSplitLine( s, s1, thesep, s2, status )
  308. IF_ERROR_RETURN(status=1)
  309. ! empty leading part ?
  310. if ( len_trim(s1) == 0 ) then
  311. ! default provided ?
  312. if ( present(default) ) then
  313. r = default
  314. else
  315. write (gol,'("found empty leading part while no default specified:")'); call goErr
  316. write (gol,'(" line : `",a,"`")') trim(s); call goErr
  317. write (gol,'(" sep : `",a,"`")') trim(thesep); call goErr
  318. TRACEBACK; status=1; return
  319. end if
  320. else
  321. ! read from leading part:
  322. read (s1,*,iostat=status) r
  323. if ( status /= 0 ) then
  324. write (gol,'("error while reading real out `",a,"`")') trim(s); call goErr
  325. write (gol,'("in ",a)') rname; call goErr; status=1; return
  326. end if
  327. end if
  328. ! return remainder:
  329. s = s2
  330. ! ok
  331. status = 0
  332. end subroutine ReadFromLine_r
  333. ! ***
  334. subroutine ReadFromLine_l( s, l, status, sep, default )
  335. ! --- in/out --------------------------
  336. character(len=*), intent(inout) :: s
  337. logical, intent(out) :: l
  338. integer, intent(out) :: status
  339. character(len=1), intent(in), optional :: sep
  340. logical, intent(in), optional :: default
  341. ! --- const ------------------------------
  342. character(len=*), parameter :: rname = mname//'/ReadFromLine_l'
  343. ! --- local ----------------------------
  344. character(len=len(s)) :: s1, s2
  345. character(len=1) :: thesep
  346. ! --- begin ----------------------------
  347. ! default seperation character provided as argument:
  348. thesep = ','
  349. if (present(sep)) thesep = sep
  350. ! split at seperation character:
  351. call goSplitLine( s, s1, thesep, s2, status )
  352. IF_ERROR_RETURN(status=1)
  353. ! empty leading part ?
  354. if ( len_trim(s1) == 0 ) then
  355. ! default provided ?
  356. if ( present(default) ) then
  357. l = default
  358. else
  359. write (gol,'("found empty leading part while no default specified:")'); call goErr
  360. write (gol,'(" line : `",a,"`")') trim(s); call goErr
  361. write (gol,'(" sep : `",a,"`")') trim(thesep); call goErr
  362. TRACEBACK; status=1; return
  363. end if
  364. else
  365. ! read from leading part:
  366. read (s1,*,iostat=status) l
  367. if ( status /= 0 ) then
  368. write (gol,'("while reading logical out `",a,"`")') trim(s); call goErr
  369. write (gol,'("in ",a)') rname; call goErr; status=1; return
  370. end if
  371. end if
  372. ! return remainder:
  373. s = s2
  374. ! ok
  375. status = 0
  376. end subroutine ReadFromLine_l
  377. ! ***
  378. subroutine ReadFromLine_s( s, ss, status, sep )
  379. ! --- in/out --------------------------
  380. character(len=*), intent(inout) :: s
  381. character(len=*), intent(out) :: ss
  382. integer, intent(out) :: status
  383. character(len=1), intent(in), optional :: sep
  384. ! --- const ------------------------------
  385. character(len=*), parameter :: rname = mname//'/ReadFromLine_s'
  386. ! --- local ----------------------------
  387. character(len=len(s)) :: s1, s2
  388. character(len=1) :: thesep
  389. integer :: l, ll
  390. ! --- begin ----------------------------
  391. ! default seperation character provided as argument:
  392. thesep = ','
  393. if (present(sep)) thesep = sep
  394. ! split at seperation character:
  395. call goSplitLine( s, s1, thesep, s2, status )
  396. IF_ERROR_RETURN(status=1)
  397. ! check storage:
  398. l = len_trim(s1)
  399. ll = len(ss)
  400. if ( ll < l ) then
  401. write (gol,'("size of output string not sufficient:")'); call goErr
  402. write (gol,'(" first part of input : ",a )') trim(s1) ; call goErr
  403. write (gol,'(" output length : ",i4)') ll ; call goErr
  404. write (gol,'("in ",a)') rname; call goErr; status=1; return
  405. end if
  406. ! store:
  407. ss = trim(s1)
  408. ! return remainder:
  409. s = s2
  410. ! ok
  411. status = 0
  412. end subroutine ReadFromLine_s
  413. ! *****************************************************
  414. subroutine goSplitString_s( line, n, values, status, sep )
  415. ! --- in/out --------------------------------
  416. character(len=*), intent(in) :: line
  417. integer, intent(out) :: n
  418. character(len=*), intent(out) :: values(:)
  419. integer, intent(out) :: status
  420. character(len=1), intent(in), optional :: sep
  421. ! --- const ----------------------------
  422. character(len=*), parameter :: rname = mname//'/goSplitString'
  423. ! --- local ---------------------------------
  424. character(len=1) :: the_sep
  425. character(len=len(line)) :: line_curr
  426. character(len=len(line)) :: val
  427. ! --- begin ---------------------------------
  428. ! seperation character:
  429. the_sep = ' '
  430. if ( present(sep) ) the_sep = sep
  431. ! copy input:
  432. line_curr = line
  433. ! no parts extracted yet:
  434. n = 0
  435. ! loop until all elements in line_curr are processed:
  436. do
  437. ! empty ? then finished:
  438. if ( len_trim(line_curr) == 0 ) exit
  439. ! next number:
  440. n = n + 1
  441. ! storage problem ?
  442. if ( n > size(values) ) then
  443. write (gol,'("output array is too small:")'); call goErr
  444. write (gol,'(" input line : ",a )') trim(line); call goErr
  445. write (gol,'(" size(values) : ",i4)') size(values); call goErr
  446. TRACEBACK; status=1; return
  447. end if
  448. ! extract leading name:
  449. call goReadFromLine( line_curr, val, status, sep=the_sep )
  450. IF_NOTOK_RETURN(status=1)
  451. ! store value in output:
  452. values(n) = val
  453. end do
  454. ! ok
  455. status = 0
  456. end subroutine goSplitString_s
  457. ! *****************************************************
  458. subroutine goSplitString_r( line, n, values, status, sep )
  459. ! --- in/out --------------------------------
  460. character(len=*), intent(in) :: line
  461. integer, intent(out) :: n
  462. real, intent(out) :: values(:)
  463. integer, intent(out) :: status
  464. character(len=1), intent(in), optional :: sep
  465. ! --- const ----------------------------
  466. character(len=*), parameter :: rname = mname//'/goSplitString'
  467. ! --- local ---------------------------------
  468. character(len=1) :: the_sep
  469. character(len=len(line)) :: line_curr
  470. real :: val
  471. ! --- begin ---------------------------------
  472. ! seperation character:
  473. the_sep = ' '
  474. if ( present(sep) ) the_sep = sep
  475. ! copy input:
  476. line_curr = line
  477. ! no parts extracted yet:
  478. n = 0
  479. ! loop until all elements in line_curr are processed:
  480. do
  481. ! empty ? then finished:
  482. if ( len_trim(line_curr) == 0 ) exit
  483. ! next number:
  484. n = n + 1
  485. ! storage problem ?
  486. if ( n > size(values) ) then
  487. write (gol,'("output array is too small:")'); call goErr
  488. write (gol,'(" input line : ",a )') trim(line); call goErr
  489. write (gol,'(" size(values) : ",i4)') size(values); call goErr
  490. TRACEBACK; status=1; return
  491. end if
  492. ! extract leading name:
  493. call goReadFromLine( line_curr, val, status, sep=the_sep )
  494. IF_NOTOK_RETURN(status=1)
  495. ! store value in output:
  496. values(n) = val
  497. end do
  498. ! ok
  499. status = 0
  500. end subroutine goSplitString_r
  501. ! *******************************************************************
  502. subroutine MatchValue_s( val, list, ind, status, quiet )
  503. ! --- in/out --------------------------------
  504. character(len=*), intent(in) :: val
  505. character(len=*), intent(in) :: list(:)
  506. integer, intent(out) :: ind
  507. integer, intent(out) :: status
  508. logical, optional :: quiet
  509. ! --- const ----------------------------
  510. character(len=*), parameter :: rname = mname//'/MatchValue_s'
  511. ! --- local ---------------------------------
  512. integer :: nlist
  513. integer :: i
  514. logical :: verbose
  515. ! --- begin ---------------------------------
  516. ! shut up ?
  517. verbose = .true.
  518. if ( present(quiet) ) verbose = .not. quiet
  519. ! number of items in value list:
  520. nlist = size(list)
  521. ! search for this name in the global list:
  522. ind = -1
  523. do i = 1, nlist
  524. ! case indendent match ?
  525. if ( goUpCase(trim(val)) == goUpCase(trim(list(i))) ) then
  526. ! store index:
  527. ind = i
  528. ! do not search any further:
  529. exit
  530. end if
  531. end do
  532. ! not found ?
  533. if ( ind < 0 ) then
  534. if ( verbose ) then
  535. write (gol,'("name not supported:")'); call goErr
  536. write (gol,'(" value : ",a )') trim(val); call goErr
  537. write (gol,'(" possible values : ")'); call goErr
  538. do i = 1, nlist
  539. write (gol,'(" ",i4," ",a)') i, trim(list(i)); call goErr
  540. end do
  541. TRACEBACK
  542. end if
  543. status=-1; return
  544. end if
  545. ! ok
  546. status = 0
  547. end subroutine MatchValue_s
  548. ! ***
  549. subroutine MatchValues_s( line, list, &
  550. n, values, inds, &
  551. status, quiet )
  552. ! --- in/out --------------------------------
  553. character(len=*), intent(in) :: line
  554. character(len=*), intent(in) :: list(:)
  555. integer, intent(out) :: n
  556. character(len=*), intent(out) :: values(:)
  557. integer, intent(out) :: inds(:)
  558. integer, intent(out) :: status
  559. logical, optional :: quiet
  560. ! --- const ----------------------------
  561. character(len=*), parameter :: rname = mname//'/MatchValues_s'
  562. ! --- local ---------------------------------
  563. integer :: nlist
  564. character(len=len(line)) :: line_curr
  565. character(len=16) :: val
  566. integer :: ind
  567. logical :: verbose
  568. ! --- begin ---------------------------------
  569. ! shut up ?
  570. verbose = .true.
  571. if ( present(quiet) ) verbose = .not. quiet
  572. ! nuber of items in value list:
  573. nlist = size(list)
  574. ! copy input:
  575. line_curr = line
  576. ! no matching list yet:
  577. n = 0
  578. ! loop until all elements in line_curr are processed:
  579. do
  580. ! empty ? then finished:
  581. if ( len_trim(line_curr) == 0 ) exit
  582. ! next number:
  583. n = n + 1
  584. ! storage problem ?
  585. if ( (n > size(values)) .or. (n > size(inds)) ) then
  586. write (gol,'("output array is too small:")'); call goErr
  587. write (gol,'(" input line : ",a )') trim(line); call goErr
  588. write (gol,'(" size(values) : ",i4)') size(values); call goErr
  589. write (gol,'(" size(inds ) : ",i4)') size(inds ); call goErr
  590. TRACEBACK; status=1; return
  591. end if
  592. ! extract leading name:
  593. call goReadFromLine( line_curr, val, status, sep=' ' )
  594. IF_NOTOK_RETURN(status=1)
  595. ! store value in output:
  596. values(n) = val
  597. ! search for this name in the global list:
  598. call goMatchValue( val, list, ind, status, quiet )
  599. ! not found ?
  600. if ( status /= 0 ) then
  601. if ( verbose ) then
  602. write (gol,'("unable to match value with list:")'); call goErr
  603. write (gol,'(" line : ",a )') trim(line); call goErr
  604. write (gol,'(" line element : ",i3)') n; call goErr
  605. write (gol,'(" line value : ",a )') trim(val); call goErr
  606. TRACEBACK
  607. end if
  608. status=1; return
  609. end if
  610. ! store:
  611. inds(n) = ind
  612. end do
  613. ! empty ?
  614. if ( n < 1 ) then
  615. write (gol,'("no values extracted from line :")'); call goErr
  616. write (gol,'(" ",a)') trim(line); call goErr
  617. TRACEBACK; status=1; return
  618. end if
  619. ! ok
  620. status = 0
  621. end subroutine MatchValues_s
  622. ! ***
  623. subroutine MatchValues_i( line, i1, i2, &
  624. n, values, &
  625. status, quiet )
  626. ! --- in/out --------------------------------
  627. character(len=*), intent(in) :: line
  628. integer, intent(in) :: i1, i2
  629. integer, intent(out) :: n
  630. integer, intent(out) :: values(:)
  631. integer, intent(out) :: status
  632. logical, optional :: quiet
  633. ! --- const ----------------------------
  634. character(len=*), parameter :: rname = mname//'/MatchValues_i'
  635. ! --- local ---------------------------------
  636. character(len=len(line)) :: line_curr
  637. integer :: val
  638. logical :: verbose
  639. ! --- begin ---------------------------------
  640. ! shut up ?
  641. verbose = .true.
  642. if ( present(quiet) ) verbose = .not. quiet
  643. ! copy input:
  644. line_curr = line
  645. ! no matching list yet:
  646. n = 0
  647. ! loop until all elements in line_curr are processed:
  648. do
  649. ! empty ? then finished:
  650. if ( len_trim(line_curr) == 0 ) exit
  651. ! next number:
  652. n = n + 1
  653. ! storage problem ?
  654. if ( n > size(values) ) then
  655. write (gol,'("output arrays are too small:")'); call goErr
  656. write (gol,'(" input line : ",a )') trim(line); call goErr
  657. write (gol,'(" size(values) : ",i4)') size(values); call goErr
  658. TRACEBACK; status=1; return
  659. end if
  660. ! extract leading name:
  661. call goReadFromLine( line_curr, val, status, sep=' ' )
  662. IF_NOTOK_RETURN(status=1)
  663. ! store value in output:
  664. values(n) = val
  665. ! out of range ?
  666. if ( (val < i1) .or. (val > i2) ) then
  667. if ( verbose ) then
  668. write (gol,'("value not in range:")'); call goErr
  669. write (gol,'(" list : ",a )') trim(line); call goErr
  670. write (gol,'(" list element : ",i3)') n; call goErr
  671. write (gol,'(" list value : ",i3)') val; call goErr
  672. write (gol,'(" possible range : ",i3," .. ",i3)') i1, i2; call goErr
  673. TRACEBACK
  674. end if
  675. status=1; return
  676. end if
  677. end do
  678. ! empty ?
  679. if ( n < 1 ) then
  680. write (gol,'("no values extracted from line :")'); call goErr
  681. write (gol,'(" ",a)') trim(line); call goErr
  682. TRACEBACK; status=1; return
  683. end if
  684. ! ok
  685. status = 0
  686. end subroutine MatchValues_i
  687. ! *****************************************************
  688. !
  689. ! Read value from line:
  690. !
  691. ! bb = 'default'
  692. ! call goVarValue( 'aa=1;bb=xyz;cc=U123', ';', 'bb', '=', bb, status )
  693. !
  694. ! Return status:
  695. ! <0 : variable not found, val remains the same
  696. ! 0 : variable found, val reset;
  697. ! for multiple matches, last value is returned
  698. ! >0 : error
  699. !
  700. subroutine goVarValue_s( line, sep, var, is, val, status )
  701. use GO_Print, only : gol, goPr, goErr
  702. ! --- in/out ---------------------------------
  703. character(len=*), intent(in) :: line
  704. character(len=1), intent(in) :: sep
  705. character(len=*), intent(in) :: var
  706. character(len=1), intent(in) :: is
  707. character(len=*), intent(inout) :: val
  708. integer, intent(out) :: status
  709. ! --- const ------------------------------
  710. character(len=*), parameter :: rname = mname//'/goVarValue_s'
  711. ! --- local ----------------------------------
  712. character(len=len(line)) :: line2
  713. character(len=len(line)) :: varval
  714. character(len=16) :: var2
  715. character(len=256) :: val2
  716. ! --- begin ----------------------------------
  717. ! copy of input line:
  718. line2 = line
  719. ! default status: not found:
  720. status = -1
  721. ! loop over var=val keys :
  722. do
  723. ! no keys left ? then leave
  724. if ( len_trim(line2) == 0 ) exit
  725. ! remove leading var=value from line2 :
  726. call goReadFromLine( line2, varval, status, sep=sep )
  727. IF_ERROR_RETURN(status=1)
  728. ! split in var and value:
  729. call goSplitLine( varval, var2, is, val2, status )
  730. IF_ERROR_RETURN(status=1)
  731. ! keys match ?
  732. if ( trim(var2) == trim(var) ) then
  733. ! store in output (might overwrite previously stored value):
  734. val = trim(val2)
  735. ! set return status to 'found':
  736. status = 0
  737. end if
  738. end do
  739. ! ok, with status either -1 or 0 :
  740. return
  741. end subroutine goVarValue_s
  742. ! ***
  743. subroutine goVarValue_i( line, sep, var, is, val, status )
  744. use GO_Print, only : gol, goPr, goErr
  745. ! --- in/out ---------------------------------
  746. character(len=*), intent(in) :: line
  747. character(len=1), intent(in) :: sep
  748. character(len=*), intent(in) :: var
  749. character(len=1), intent(in) :: is
  750. integer, intent(inout) :: val
  751. integer, intent(out) :: status
  752. ! --- const ------------------------------
  753. character(len=*), parameter :: rname = mname//'/goVarValue_i'
  754. ! --- local ----------------------------------
  755. character(len=len(line)) :: line2
  756. character(len=len(line)) :: varval
  757. character(len=16) :: var2
  758. character(len=256) :: val2
  759. ! --- begin ----------------------------------
  760. ! copy of input line:
  761. line2 = line
  762. ! default status: not found:
  763. status = -1
  764. ! loop over var=val keys :
  765. do
  766. ! no keys left ? then leave
  767. if ( len_trim(line2) == 0 ) exit
  768. ! remove leading var=value from line2 :
  769. call goReadFromLine( line2, varval, status, sep=sep )
  770. IF_ERROR_RETURN(status=1)
  771. ! split in var and value:
  772. call goSplitLine( varval, var2, is, val2, status )
  773. IF_ERROR_RETURN(status=1)
  774. ! keys match ?
  775. if ( trim(var2) == trim(var) ) then
  776. ! store in output (might overwrite previously stored value):
  777. read (val2,'(i6)') val
  778. ! set return status to 'found':
  779. status = 0
  780. end if
  781. end do
  782. ! ok, with status either -1 or 0 :
  783. return
  784. end subroutine goVarValue_i
  785. ! ***
  786. subroutine goVarValue_r( line, sep, var, is, val, status )
  787. use GO_Print, only : gol, goPr, goErr
  788. ! --- in/out ---------------------------------
  789. character(len=*), intent(in) :: line
  790. character(len=1), intent(in) :: sep
  791. character(len=*), intent(in) :: var
  792. character(len=1), intent(in) :: is
  793. real, intent(inout) :: val
  794. integer, intent(out) :: status
  795. ! --- const ------------------------------
  796. character(len=*), parameter :: rname = mname//'/goVarValue_r'
  797. ! --- local ----------------------------------
  798. character(len=len(line)) :: line2
  799. character(len=len(line)) :: varval
  800. character(len=16) :: var2
  801. character(len=256) :: val2
  802. ! --- begin ----------------------------------
  803. ! copy of input line:
  804. line2 = line
  805. ! default status: not found:
  806. status = -1
  807. ! loop over var=val keys :
  808. do
  809. ! no keys left ? then leave
  810. if ( len_trim(line2) == 0 ) exit
  811. ! remove leading var=value from line2 :
  812. call goReadFromLine( line2, varval, status, sep=sep )
  813. IF_ERROR_RETURN(status=1)
  814. ! split in var and value:
  815. call goSplitLine( varval, var2, is, val2, status )
  816. IF_ERROR_RETURN(status=1)
  817. ! keys match ?
  818. if ( trim(var2) == trim(var) ) then
  819. ! store in output (might overwrite previously stored value):
  820. read (val2,*) val
  821. ! set return status to 'found':
  822. status = 0
  823. end if
  824. end do
  825. ! ok, with status either -1 or 0 :
  826. return
  827. end subroutine goVarValue_r
  828. ! ***
  829. subroutine goVarValue_l( line, sep, var, is, val, status )
  830. use GO_Print, only : gol, goPr, goErr
  831. ! --- in/out ---------------------------------
  832. character(len=*), intent(in) :: line
  833. character(len=1), intent(in) :: sep
  834. character(len=*), intent(in) :: var
  835. character(len=1), intent(in) :: is
  836. logical, intent(inout) :: val
  837. integer, intent(out) :: status
  838. ! --- const ------------------------------
  839. character(len=*), parameter :: rname = mname//'/goVarValue_l'
  840. ! --- local ----------------------------------
  841. character(len=len(line)) :: line2
  842. character(len=len(line)) :: varval
  843. character(len=16) :: var2
  844. character(len=256) :: val2
  845. ! --- begin ----------------------------------
  846. ! copy of input line:
  847. line2 = line
  848. ! default status: not found:
  849. status = -1
  850. ! loop over var=val keys :
  851. do
  852. ! no keys left ? then leave
  853. if ( len_trim(line2) == 0 ) exit
  854. ! remove leading var=value from line2 :
  855. call goReadFromLine( line2, varval, status, sep=sep )
  856. IF_ERROR_RETURN(status=1)
  857. ! split in var and value:
  858. call goSplitLine( varval, var2, is, val2, status )
  859. IF_ERROR_RETURN(status=1)
  860. ! keys match ?
  861. if ( trim(var2) == trim(var) ) then
  862. ! store in output (might overwrite previously stored value):
  863. read (val2,'(l1)') val
  864. ! set return status to 'found':
  865. status = 0
  866. end if
  867. end do
  868. ! ok, with status either -1 or 0 :
  869. return
  870. end subroutine goVarValue_l
  871. ! *****************************************************
  872. !---
  873. ! NAME
  874. ! gonum2str - prints number into character string
  875. !
  876. ! INTERFACE
  877. ! character(len=20) function gonum2str( x, fmt )
  878. ! integer [or real] , intent(in) :: x
  879. ! character(len=*), intent(in), optional :: fmt
  880. !
  881. ! ARGUMENTS
  882. ! x
  883. ! Number to be converted.
  884. ! fmt
  885. ! Optional format, following the formats provided
  886. ! to the 'write' command.
  887. ! Default values:
  888. !
  889. ! type x fmt example (- is space)
  890. ! ------------------ ---------- ---------------------
  891. ! integer '(i6)' 123---
  892. !
  893. ! CHANGES
  894. ! 01/09/1999 Arjo Segers
  895. !---
  896. character(len=6) function num2str_i( i, fmt )
  897. ! --- in/out ----------------------
  898. integer, intent(in) :: i
  899. character(len=*), intent(in), optional :: fmt
  900. ! --- local -----------------------
  901. character(len=6) :: s
  902. ! --- begin -----------------------
  903. if (present(fmt)) then
  904. write (s,fmt=fmt) i
  905. else
  906. write (s,'(i6)') i
  907. end if
  908. num2str_i=adjustl(s)
  909. end function num2str_i
  910. character(len=12) function num2str_r( r, fmt )
  911. ! --- in/out ----------------------
  912. real, intent(in) :: r
  913. character(len=*), intent(in), optional :: fmt
  914. ! --- local -----------------------
  915. character(len=12) :: s
  916. ! --- begin -----------------------
  917. if (present(fmt)) then
  918. write (s,fmt=fmt) r
  919. else
  920. write (s,'(g10.3)') r
  921. end if
  922. num2str_r=adjustl(s)
  923. end function num2str_r
  924. ! *** UpCase, LoCase ***
  925. function UpCase( s )
  926. ! --- in/out -----------------
  927. character(len=*), intent(in) :: s
  928. character(len=len(s)) :: UpCase
  929. ! --- local ------------------
  930. integer :: i
  931. ! --- begin ------------------
  932. do i = 1, len_trim(s)
  933. select case (s(i:i))
  934. case ('a') ; UpCase(i:i) = 'A'
  935. case ('b') ; UpCase(i:i) = 'B'
  936. case ('c') ; UpCase(i:i) = 'C'
  937. case ('d') ; UpCase(i:i) = 'D'
  938. case ('e') ; UpCase(i:i) = 'E'
  939. case ('f') ; UpCase(i:i) = 'F'
  940. case ('g') ; UpCase(i:i) = 'G'
  941. case ('h') ; UpCase(i:i) = 'H'
  942. case ('i') ; UpCase(i:i) = 'I'
  943. case ('j') ; UpCase(i:i) = 'J'
  944. case ('k') ; UpCase(i:i) = 'K'
  945. case ('l') ; UpCase(i:i) = 'L'
  946. case ('m') ; UpCase(i:i) = 'M'
  947. case ('n') ; UpCase(i:i) = 'N'
  948. case ('o') ; UpCase(i:i) = 'O'
  949. case ('p') ; UpCase(i:i) = 'P'
  950. case ('q') ; UpCase(i:i) = 'Q'
  951. case ('r') ; UpCase(i:i) = 'R'
  952. case ('s') ; UpCase(i:i) = 'S'
  953. case ('t') ; UpCase(i:i) = 'T'
  954. case ('u') ; UpCase(i:i) = 'U'
  955. case ('v') ; UpCase(i:i) = 'V'
  956. case ('w') ; UpCase(i:i) = 'W'
  957. case ('x') ; UpCase(i:i) = 'X'
  958. case ('y') ; UpCase(i:i) = 'Y'
  959. case ('z') ; UpCase(i:i) = 'Z'
  960. case default
  961. UpCase(i:i) = s(i:i)
  962. end select
  963. end do
  964. end function UpCase
  965. ! ***
  966. function LoCase( s )
  967. ! --- in/out -----------------
  968. character(len=*), intent(in) :: s
  969. character(len=len(s)) :: LoCase
  970. ! --- local ------------------
  971. integer :: i
  972. ! --- begin ------------------
  973. do i = 1, len_trim(s)
  974. select case (s(i:i))
  975. case ('A') ; LoCase(i:i) = 'a'
  976. case ('B') ; LoCase(i:i) = 'b'
  977. case ('C') ; LoCase(i:i) = 'c'
  978. case ('D') ; LoCase(i:i) = 'd'
  979. case ('E') ; LoCase(i:i) = 'e'
  980. case ('F') ; LoCase(i:i) = 'f'
  981. case ('G') ; LoCase(i:i) = 'g'
  982. case ('H') ; LoCase(i:i) = 'h'
  983. case ('I') ; LoCase(i:i) = 'i'
  984. case ('J') ; LoCase(i:i) = 'j'
  985. case ('K') ; LoCase(i:i) = 'k'
  986. case ('L') ; LoCase(i:i) = 'l'
  987. case ('M') ; LoCase(i:i) = 'm'
  988. case ('N') ; LoCase(i:i) = 'n'
  989. case ('O') ; LoCase(i:i) = 'o'
  990. case ('P') ; LoCase(i:i) = 'p'
  991. case ('Q') ; LoCase(i:i) = 'q'
  992. case ('R') ; LoCase(i:i) = 'r'
  993. case ('S') ; LoCase(i:i) = 's'
  994. case ('T') ; LoCase(i:i) = 't'
  995. case ('U') ; LoCase(i:i) = 'u'
  996. case ('V') ; LoCase(i:i) = 'v'
  997. case ('W') ; LoCase(i:i) = 'w'
  998. case ('X') ; LoCase(i:i) = 'x'
  999. case ('Y') ; LoCase(i:i) = 'y'
  1000. case ('Z') ; LoCase(i:i) = 'z'
  1001. case default
  1002. LoCase(i:i) = s(i:i)
  1003. end select
  1004. end do
  1005. end function LoCase
  1006. ! ***
  1007. subroutine WriteKeyNum( res, key, num )
  1008. ! --- in/out ------------------------------
  1009. character(len=*), intent(out) :: res
  1010. character(len=*), intent(in) :: key
  1011. integer, intent(in) :: num
  1012. ! --- local -------------------------------
  1013. integer :: anum
  1014. ! --- begin -------------------------------
  1015. anum = abs(num)
  1016. if ( anum <= 9 ) then
  1017. write (res,'(a,i1)') trim(key), anum
  1018. else if ( anum <= 99 ) then
  1019. write (res,'(a,i2)') trim(key), anum
  1020. else if ( anum <= 999 ) then
  1021. write (res,'(a,i3)') trim(key), anum
  1022. else if ( anum <= 9999 ) then
  1023. write (res,'(a,i4)') trim(key), anum
  1024. else if ( anum <= 99999 ) then
  1025. write (res,'(a,i5)') trim(key), anum
  1026. else
  1027. write (res,'(a,i6)') trim(key), anum
  1028. end if
  1029. end subroutine WriteKeyNum
  1030. ! ***
  1031. subroutine goTab2Space( s )
  1032. ! --- in/out -----------------
  1033. character(len=*), intent(inout) :: s
  1034. ! --- local ------------------
  1035. integer :: pos
  1036. ! --- begin ------------------
  1037. do
  1038. pos = scan(s,char(9))
  1039. if ( pos == 0 ) exit
  1040. s(pos:pos) = ' '
  1041. end do
  1042. end subroutine goTab2Space
  1043. ! ***
  1044. subroutine goReplace_s( s, key, repl, status )
  1045. ! --- in/out ---------------------------------
  1046. character(len=*), intent(inout) :: s
  1047. character(len=*), intent(in) :: key
  1048. character(len=*), intent(in) :: repl
  1049. integer, intent(out) :: status
  1050. ! --- const ----------------------------------
  1051. character(len=*), parameter :: rname = mname//'/goReplace_s'
  1052. ! --- local ----------------------------------
  1053. integer :: n_in, l_in
  1054. integer :: n_out
  1055. integer :: ind
  1056. character(len=len(s)) :: s_in
  1057. ! --- begin ----------------------------------
  1058. ! copy input:
  1059. s_in = s
  1060. ! empty target:
  1061. s = ''
  1062. n_out = 0
  1063. ! number of characters in s:
  1064. l_in = len_trim(s_in)
  1065. ! characters copied from s_in to s:
  1066. n_in = 0
  1067. ! loop over all matches of key:
  1068. do
  1069. !print *, '---- n_in, l_in : ',n_in, l_in
  1070. ! past end ?
  1071. if ( n_in > l_in ) exit
  1072. !print *, ' -- remaining : "'//s_in(n_in+1:l_in)//'" , key : "'//key//'"'
  1073. ! search key in remaining part of input :
  1074. if ( len(key) < 1 ) then
  1075. ind = 0
  1076. else
  1077. ind = index(s_in(n_in+1:l_in),key)
  1078. end if
  1079. !print *, ' -- index : ', ind
  1080. ! not found ?
  1081. if ( ind < 1 ) then
  1082. ! add remaining part:
  1083. s = s(1:n_out)//s_in(n_in+1:l_in)
  1084. n_out = n_out + l_in-n_in
  1085. ! leave:
  1086. exit
  1087. end if
  1088. ! add first part:
  1089. s = s(1:n_out)//s_in(n_in+1:n_in+ind-1)
  1090. n_out = n_out + ind-1
  1091. n_in = n_in + ind-1
  1092. !print *, ' -- out : ',n_out,'"'//s(1:n_out)//'"'
  1093. ! add replacement:
  1094. s = s(1:n_out)//repl
  1095. n_out = n_out + len(repl)
  1096. n_in = n_in + len(key)
  1097. !print *, ' -- out : ',n_out,'"'//s(1:n_out)//'"'
  1098. end do
  1099. ! ok
  1100. status = 0
  1101. end subroutine goReplace_s
  1102. ! ***
  1103. subroutine goReplace_i( s, key, fmt, i, status )
  1104. ! --- in/out ---------------------------------
  1105. character(len=*), intent(inout) :: s
  1106. character(len=*), intent(in) :: key
  1107. character(len=*), intent(in) :: fmt
  1108. integer, intent(in) :: i
  1109. integer, intent(out) :: status
  1110. ! --- const ----------------------------------
  1111. character(len=*), parameter :: rname = mname//'/goReplace_i'
  1112. ! --- local ----------------------------------
  1113. character(len=8) :: repl
  1114. ! --- begin ----------------------------------
  1115. ! fill replacement:
  1116. write (repl,fmt) i
  1117. ! replace value:
  1118. call goReplace( s, key, trim(repl), status )
  1119. IF_NOTOK_RETURN(status=1)
  1120. ! ok
  1121. status = 0
  1122. end subroutine goReplace_i
  1123. ! ***
  1124. ! replace in s all characters in 'chars' by the value in 'repl' .
  1125. subroutine goTranslate( s, chars, repl, status )
  1126. ! --- in/out ---------------------------------
  1127. character(len=*), intent(inout) :: s
  1128. character(len=*), intent(in) :: chars
  1129. character(len=*), intent(in) :: repl
  1130. integer, intent(out) :: status
  1131. ! --- const ----------------------------------
  1132. character(len=*), parameter :: rname = mname//'/goTranslate'
  1133. ! --- local ----------------------------------
  1134. integer :: i
  1135. ! --- begin ----------------------------------
  1136. ! loop over characters to be replaced:
  1137. do i = 1, len(chars)
  1138. ! replace character:
  1139. call goReplace( s, chars(i:i), repl, status )
  1140. IF_NOTOK_RETURN(status=1)
  1141. end do
  1142. ! ok
  1143. status = 0
  1144. end subroutine goTranslate
  1145. end module GO_String
  1146. ! ######################################################################
  1147. ! ###
  1148. ! ### test
  1149. ! ###
  1150. ! ######################################################################
  1151. !
  1152. !program test
  1153. !
  1154. ! use go_string
  1155. !
  1156. ! character(len=32) :: s
  1157. ! integer :: status
  1158. !
  1159. ! print *, 'not found ...'
  1160. ! s='abcd' ; call goReplace( s, 'q', 'x', status ) ; print *, '"'//trim(s)//'"'
  1161. !
  1162. ! print *, 'replace 1 character ...'
  1163. ! s='abcd' ; call goReplace( s, 'a', 'x', status ) ; print *, '"'//trim(s)//'"'
  1164. ! s='abcd' ; call goReplace( s, 'b', 'x', status ) ; print *, '"'//trim(s)//'"'
  1165. ! s='abcd' ; call goReplace( s, 'c', 'x', status ) ; print *, '"'//trim(s)//'"'
  1166. ! s='abcd' ; call goReplace( s, 'd', 'x', status ) ; print *, '"'//trim(s)//'"'
  1167. !
  1168. ! print *, 'empty arguments ...'
  1169. ! s='' ; call goReplace( s, 'a', 'x', status ) ; print *, '"'//trim(s)//'"'
  1170. ! s='abcd' ; call goReplace( s, '' , 'x', status ) ; print *, '"'//trim(s)//'"'
  1171. ! s='abcd' ; call goReplace( s, 'a', '' , status ) ; print *, '"'//trim(s)//'"'
  1172. !
  1173. ! print *, 'replace 1 by 2 characters ...'
  1174. ! s='abcd' ; call goReplace( s, 'a', 'XY', status ) ; print *, '"'//trim(s)//'"'
  1175. ! s='abcd' ; call goReplace( s, 'b', 'XY', status ) ; print *, '"'//trim(s)//'"'
  1176. ! s='abcd' ; call goReplace( s, 'd', 'XY', status ) ; print *, '"'//trim(s)//'"'
  1177. !
  1178. ! print *, 'replace 2 characters by 1 ...'
  1179. ! s='abcd' ; call goReplace( s, 'ab', 'x', status ) ; print *, '"'//trim(s)//'"'
  1180. ! s='abcd' ; call goReplace( s, 'bc', 'x', status ) ; print *, '"'//trim(s)//'"'
  1181. ! s='abcd' ; call goReplace( s, 'cd', 'x', status ) ; print *, '"'//trim(s)//'"'
  1182. !
  1183. ! print *, 'replace all ...'
  1184. ! s='abcdabcda' ; call goReplace( s, 'a', '_', status ) ; print *, '"'//trim(s)//'"'
  1185. ! s='abcdabcda' ; call goReplace( s, 'a', '' , status ) ; print *, '"'//trim(s)//'"'
  1186. !
  1187. !end program test
  1188. !
  1189. !