go_print.F90 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. !
  2. ! go print : tools for standard output
  3. !
  4. ! Example:
  5. !
  6. ! ! messages printed by root only:
  7. ! call GO_Print_Init( status, apply=myid==root, &
  8. ! prompt_pe=npes>1, pe=myid, &
  9. ! trace=.false. )
  10. ! if (status/=0) stop
  11. !
  12. ! ! set routine label:
  13. ! call goLabel( 'mymod/myroutine' )
  14. !
  15. ! ! write single message (including processor prompt?) :
  16. ! ! [00] This is number 3
  17. ! write (gol,'("This is number ",i2)') 3; call goPr
  18. !
  19. ! ! write error message and traceback using the
  20. ! ! previous defined routine label:
  21. ! ! [00] ERROR - Something wrong.
  22. ! ! [00] ERROR in mymod/myroutine
  23. ! write (gol,'("Something wrong.")'); call goErr
  24. ! call goErr
  25. !
  26. ! ! close label
  27. ! call goLabel()
  28. !
  29. ! ! done
  30. ! call GO_Print_Done( status )
  31. ! if (status/=0) stop
  32. !
  33. ! Nedit macro's:
  34. !
  35. ! o change error traceback:
  36. ! write (*,'("ERROR in ",a)') rname
  37. ! call goErr
  38. !
  39. ! o change error traceback:
  40. ! write (*,'("ERROR in ",a)') rname
  41. ! write (gol,'("in ",a)') rname; call goErr
  42. !
  43. ! o change error message:
  44. ! write \(\*,'\("ERROR - (.*$)
  45. ! write (gol,'("\1; call goErr
  46. !
  47. ! o change other message:
  48. ! write \(\*,(.*$)
  49. ! write (gol,\1; call goPr
  50. !
  51. ! o change error time messages:
  52. ! (goprdt.*ERROR.*$)
  53. ! \1; call goErr
  54. !
  55. ! o change time messages:
  56. ! printdate2
  57. ! wrtgol
  58. ! call printdate2\( 'ERROR - (.*$)
  59. ! call wrtgol( '\1; call goErr
  60. ! printdate
  61. ! wrtgol
  62. ! call printdate\( 'ERROR - (.*$)
  63. ! call wrtgol( '\1; call goErr
  64. !
  65. !
  66. !
  67. ! o change error messages:
  68. ! (ERROR.*; call )goPr
  69. ! \1goErr
  70. !
  71. ! o change time messages:
  72. ! (call goprdt.*$)
  73. ! \1; call goPr
  74. !
  75. module GO_Print
  76. implicit none
  77. ! --- in/out ---------------------------------
  78. private
  79. public :: gol
  80. public :: GO_Print_Init, GO_Print_Done
  81. public :: goPr, goErr, goBug
  82. public :: goLabel
  83. ! --- const ---------------------------------
  84. character(len=*), parameter :: mname = 'GO_Print'
  85. ! --- var ------------------------------------
  86. ! buffer for standard output
  87. character(len=1024) :: gol
  88. ! stack with labels:
  89. integer, parameter :: mstack = 400
  90. character(len=64) :: labels(0:mstack)
  91. integer :: istack = 0
  92. ! initialized ?
  93. ! some errors might be printed before initialization ...
  94. logical :: pr_initialized = .false.
  95. ! destination file unit:
  96. integer :: pr_fu
  97. ! flags etc
  98. logical :: pr_apply
  99. logical :: pr_trace
  100. ! processor prompt
  101. logical :: pr_prompt_pe
  102. integer :: pr_pe
  103. ! white space for indents:
  104. integer, parameter :: dindent = 2
  105. integer :: indent = 0
  106. ! writ to file ?
  107. logical :: pr_file
  108. character(len=256) :: pr_file_name
  109. contains
  110. ! ***************************************************************************
  111. ! ***
  112. ! *** module init/done
  113. ! ***
  114. ! ***************************************************************************
  115. subroutine GO_Print_Init( status, apply, prompt_pe, pe, trace, file, file_name )
  116. use go_fu, only : goStdOut
  117. ! --- in/out ----------------------------
  118. integer, intent(out) :: status
  119. logical, intent(in), optional :: apply
  120. logical, intent(in), optional :: prompt_pe
  121. integer, intent(in), optional :: pe
  122. logical, intent(in), optional :: trace
  123. logical, intent(in), optional :: file
  124. character(len=*), intent(in), optional :: file_name
  125. ! --- const ----------------------------
  126. character(len=*), parameter :: rname = mname//'/GO_Print_Init'
  127. ! --- local -----------------------------
  128. logical :: opened
  129. ! --- begin -----------------------------
  130. ! print or not ?
  131. pr_apply = .true.
  132. if ( present(apply) ) pr_apply = apply
  133. ! processor number
  134. pr_pe = 0
  135. if ( present(pe) ) pr_pe = pe
  136. ! prompt processor number ?
  137. pr_prompt_pe = .false.
  138. if ( present(prompt_pe) ) pr_prompt_pe = prompt_pe
  139. ! trace labels ?
  140. pr_trace = .false.
  141. if ( present(trace) ) pr_trace = trace
  142. ! write to file ?
  143. pr_file = .false.
  144. if ( present(file) ) pr_file = file
  145. pr_file_name = 'go.out'
  146. if ( present(file_name) ) pr_file_name = file_name
  147. ! init label stack:
  148. labels(0) = '<no-label>'
  149. istack = 0
  150. ! no indent yet
  151. indent = 0
  152. if ( .not. pr_trace ) indent = -2
  153. ! write messages to file ?
  154. if ( pr_file ) then
  155. ! select free file unit:
  156. pr_fu = 10
  157. do
  158. inquire( pr_fu, opened=opened )
  159. if ( .not. opened ) exit
  160. pr_fu = pr_fu + 1
  161. end do
  162. ! open requested output file:
  163. open( unit=pr_fu, file=pr_file_name, status='replace', iostat=status )
  164. if ( status/=0 ) then
  165. write (*,'("ERROR - opening file for output:")')
  166. write (*,'("ERROR - unit : ",i6)') pr_fu
  167. write (*,'("ERROR - file : ",a)') trim(pr_file_name)
  168. write (*,'("ERROR in ",a)') rname; status=1; return
  169. end if
  170. else
  171. ! write to standard output:
  172. pr_fu = goStdOut
  173. end if
  174. ! now the module is initialized ...
  175. pr_initialized = .true.
  176. ! ok
  177. status = 0
  178. end subroutine GO_Print_Init
  179. ! ***
  180. subroutine GO_Print_Done( status )
  181. ! --- in/out ----------------------------
  182. integer, intent(out) :: status
  183. ! --- const ----------------------------
  184. character(len=*), parameter :: rname = mname//'/GO_Print_Done'
  185. ! --- begin -----------------------------
  186. ! output to file ?
  187. if ( pr_file ) then
  188. ! close file:
  189. close( pr_fu, iostat=status )
  190. if ( status/=0 ) then
  191. write (*,'("ERROR - closing output file:")')
  192. write (*,'("ERROR - unit : ",i6)') pr_fu
  193. write (*,'("ERROR - file : ",a)') trim(pr_file_name)
  194. write (*,'("ERROR in ",a)') rname; status=1; return
  195. end if
  196. end if
  197. ! ok
  198. status = 0
  199. end subroutine GO_Print_Done
  200. ! ***************************************************************************
  201. ! ***
  202. ! *** printing
  203. ! ***
  204. ! ***************************************************************************
  205. subroutine goPr
  206. ! --- local --------------------------------
  207. character(len=16) :: prompt, s
  208. integer :: nind
  209. ! --- const ----------------------------
  210. character(len=*), parameter :: rname = mname//'/goPr'
  211. ! --- begin --------------------------------
  212. ! not initialized yet ? then print to standard output:
  213. if ( .not. pr_initialized ) then
  214. write (*,'(a)') trim(gol)
  215. gol = ''
  216. return
  217. end if
  218. ! print go line ?
  219. if ( pr_apply ) then
  220. ! number of spaces to indent:
  221. nind = max( 0, indent )
  222. ! processor prompt ?
  223. if ( pr_prompt_pe ) then
  224. write (prompt,'("[",i2.2,"]")') pr_pe
  225. nind = nind + 1
  226. else
  227. prompt = ''
  228. end if
  229. ! write prompt, indention, go line:
  230. if ( nind > 0 ) then
  231. write (pr_fu,'(a,a,a)') trim(prompt), repeat(' ',nind), trim(gol)
  232. else
  233. write (pr_fu,'(a,a)') trim(prompt), trim(gol)
  234. end if
  235. end if
  236. ! call Flush( pr_fu )
  237. ! clear output line:
  238. gol = ''
  239. end subroutine goPr
  240. ! ***
  241. ! Print error message.
  242. ! Now printed to standard output, in future to standard error ?
  243. ! Make gol empty before leaving.
  244. ! If still empty in next call, this is a trace back
  245. ! (print error label, one label back)
  246. subroutine goErr
  247. ! --- local -------------------------------
  248. integer :: ilab
  249. ! --- const ----------------------------
  250. character(len=*), parameter :: rname = mname//'/goErr'
  251. ! --- local ----------------------------
  252. logical :: save_pr_apply
  253. character(len=len(gol)) :: gol2
  254. ! --- begin --------------------------------
  255. ! store original apply flag:
  256. save_pr_apply = pr_apply
  257. ! always print error messages:
  258. pr_apply = .true.
  259. ! message in buffer ?
  260. if ( len_trim(gol) > 0 ) then
  261. ! error message;
  262. ! make a copy of the message to avoid problems with
  263. ! re-writing a character string that occures on some machines:
  264. gol2 = trim(gol)
  265. write (gol,'("ERROR - ",a)') trim(gol2); call goPr
  266. else
  267. ! label index:
  268. ilab = min( istack, mstack )
  269. ! write error message:
  270. write (gol,'("ERROR in ",a)') trim(labels(ilab)); call goPr
  271. ! one level back:
  272. call goLabel()
  273. end if
  274. ! restore apply flag:
  275. pr_apply = save_pr_apply
  276. end subroutine goErr
  277. ! ***
  278. subroutine goBug
  279. ! --- local ----------------------------
  280. logical :: save_pr_apply
  281. ! --- begin --------------------------------
  282. ! store original apply flag:
  283. save_pr_apply = pr_apply
  284. ! always print bug messages:
  285. pr_apply = .true.
  286. ! write message
  287. write (gol,'("BUG - ",a)') trim(gol); call goPr
  288. ! restore apply flag:
  289. pr_apply = save_pr_apply
  290. end subroutine goBug
  291. ! ***************************************************************************
  292. ! ***
  293. ! *** routine labels
  294. ! ***
  295. ! ***************************************************************************
  296. subroutine goLabel( label )
  297. ! --- in/out -------------------------------
  298. character(len=*), intent(in), optional :: label
  299. ! --- const ----------------------------
  300. character(len=*), parameter :: rname = mname//'/goLabel'
  301. ! --- begin --------------------------------
  302. ! add new label to stack ?
  303. if ( present(label) ) then
  304. istack = istack + 1
  305. if ( istack > mstack ) then
  306. write (gol,'("BUG - stack too small; please increase mstack in go_print")'); call goPr
  307. else
  308. labels(istack) = label
  309. end if
  310. if (pr_trace) then
  311. write (gol,'("<",a,">")') trim(labels(istack)); call goPr
  312. end if
  313. indent = indent + dindent
  314. else
  315. indent = indent - dindent
  316. if (pr_trace) then
  317. write (gol,'("(",a,")")') trim(labels(istack)); call goPr
  318. end if
  319. istack = max( 0, istack - 1 )
  320. end if
  321. end subroutine goLabel
  322. end module go_print
  323. ! #############################################################################
  324. ! ###
  325. ! ### test program
  326. ! ###
  327. ! #############################################################################
  328. !
  329. !
  330. !module testmod
  331. !
  332. ! implicit none
  333. !
  334. ! public
  335. !
  336. !contains
  337. !
  338. ! subroutine subr( i, status )
  339. !
  340. ! use go_print, only : goLabel, gol, goPr, goErr
  341. !
  342. ! ! --- in/out ----------------------------------------
  343. !
  344. ! integer, intent(in) :: i
  345. ! integer, intent(out) :: status
  346. !
  347. ! ! --- begin -----------------------------------------
  348. !
  349. ! call goLabel( 'subr' )
  350. !
  351. ! write (gol,'("welcome to subr !")'); call goPr
  352. !
  353. ! select case ( i )
  354. !
  355. ! case ( 0 )
  356. ! write (gol,'("testing i : ",i2)') i; call goPr
  357. !
  358. ! case ( 1 )
  359. ! call subr2( 0, status )
  360. ! if (status/=0) then; call goErr; status=1; return; end if
  361. !
  362. ! case ( 2 )
  363. ! call subr2( 1, status )
  364. ! if (status/=0) then; call goErr; status=1; return; end if
  365. !
  366. ! case default
  367. ! write (gol,'("unsupported i : ",i2)') i; call goErr
  368. ! call goErr; status=1; return
  369. !
  370. ! end select
  371. !
  372. ! call goLabel(); status=0
  373. !
  374. ! end subroutine subr
  375. !
  376. !
  377. ! ! ***
  378. !
  379. !
  380. ! subroutine subr2( i, status )
  381. !
  382. ! use go_print, only : goLabel, gol, goPr, goErr
  383. !
  384. ! ! --- in/out ----------------------------------------
  385. !
  386. ! integer, intent(in) :: i
  387. ! integer, intent(out) :: status
  388. !
  389. ! ! --- begin -----------------------------------------
  390. !
  391. ! call goLabel('subr2')
  392. !
  393. ! write (gol,'("testing subr2")'); call goPr
  394. !
  395. ! select case ( i )
  396. ! case ( 0 )
  397. ! case default
  398. ! write (gol,'("wrong i : ",i2)') i; call goErr
  399. ! call goErr; status=1; return
  400. ! end select
  401. !
  402. ! call goLabel; status=0
  403. !
  404. ! end subroutine subr2
  405. !
  406. !
  407. !
  408. !end module testmod
  409. !
  410. !
  411. ! ################################################################
  412. !
  413. !
  414. !program test
  415. !
  416. ! use go_print
  417. ! use testmod
  418. !
  419. ! ! --- local -----------------------------------------
  420. !
  421. ! integer :: status
  422. !
  423. ! ! --- begin ------------------------------------------
  424. !
  425. ! call GO_Print_Init( status, trace=.false. )
  426. ! call goLabel('test prog')
  427. !
  428. ! write (gol,'("begin of program")'); call goPr
  429. !
  430. ! call Subr( 2, status )
  431. ! if (status/=0) then; call goErr; call exit(1); end if
  432. !
  433. ! write (gol,'("end of program")'); call goPr
  434. !
  435. ! call goLabel()
  436. ! call GO_Print_Done( status )
  437. !
  438. !end program test
  439. !