libsim  Versione8.0.0
log4fortran.F90
1 ! Copyright (C) 2010 ARPA-SIM <urpsim@smr.arpa.emr.it>
2 ! authors:
3 ! Davide Cesari <dcesari@arpa.emr.it>
4 ! Paolo Patruno <ppatruno@arpa.emr.it>
5 
6 ! This program is free software; you can redistribute it and/or
7 ! modify it under the terms of the GNU General Public License as
8 ! published by the Free Software Foundation; either version 2 of
9 ! the License, or (at your option) any later version.
10 
11 ! This program is distributed in the hope that it will be useful,
12 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ! GNU General Public License for more details.
15 
16 ! You should have received a copy of the GNU General Public License
17 ! along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "config.h"
19 
23 
113 MODULE log4fortran
114 USE iso_c_binding
115 IMPLICIT NONE
116 
117 INTEGER(kind=c_int),PARAMETER :: L4F_FATAL = 000
118 INTEGER(kind=c_int),PARAMETER :: L4F_ALERT = 100
119 INTEGER(kind=c_int),PARAMETER :: L4F_CRIT = 200
120 INTEGER(kind=c_int),PARAMETER :: L4F_ERROR = 300
121 INTEGER(kind=c_int),PARAMETER :: L4F_WARN = 400
122 INTEGER(kind=c_int),PARAMETER :: L4F_NOTICE = 500
123 INTEGER(kind=c_int),PARAMETER :: L4F_INFO = 600
124 INTEGER(kind=c_int),PARAMETER :: L4F_DEBUG = 700
125 INTEGER(kind=c_int),PARAMETER :: L4F_TRACE = 800
126 INTEGER(kind=c_int),PARAMETER :: L4F_NOTSET = 900
127 INTEGER(kind=c_int),PARAMETER :: L4F_UNKNOWN = 1000
128 
132 INTEGER(kind=c_int),PUBLIC :: l4f_priority=l4f_notice
133 
134 #ifdef HAVE_LIBLOG4C
135 
139 TYPE,BIND(C) :: l4f_handle
140  PRIVATE
141  TYPE(c_ptr) :: ptr = c_null_ptr
142 END TYPE l4f_handle
143 
144 
145 TYPE(l4f_handle),SAVE :: l4f_global_default
146 
147 #undef ARRAYOF_ORIGEQ
148 #undef ARRAYOF_ORIGTYPE
149 #undef ARRAYOF_TYPE
150 #define ARRAYOF_ORIGTYPE TYPE(l4f_handle)
151 #define ARRAYOF_TYPE arrayof_l4f_handle
152 #include "arrayof_pre_nodoc.F90"
153 
154 TYPE(arrayof_l4f_handle) :: l4f_global_ptr
155 
157 INTERFACE
158  FUNCTION l4f_init() bind(C,name='log4c_init')
159  import
160  INTEGER(kind=c_int) :: l4f_init
161  END FUNCTION l4f_init
162 END INTERFACE
163 
164 ! Internal C interface not to be used by user Fortran code
165 INTERFACE
166  FUNCTION l4f_category_get_c(a_name) bind(C,name='log4c_category_get')
167  import
168  CHARACTER(kind=c_char),INTENT(in) :: a_name(*)
169  TYPE(l4f_handle) :: l4f_category_get_c
170  END FUNCTION l4f_category_get_c
171 END INTERFACE
172 
173 ! Internal C interface not to be used by user Fortran code
174 ! this function has been disabled because after deleting a category
175 ! the following log4c_fini fails with a double free, we must
176 ! understand the log4c docs
177 INTERFACE
178  SUBROUTINE l4f_category_delete_c(a_category) bind(C,name='log4c_category_delete')
179  import
180  TYPE(l4f_handle),VALUE :: a_category
181  END SUBROUTINE l4f_category_delete_c
182 END INTERFACE
183 
184 !! Delete a logging category. It can receive a l4f_handle pointer or a
185 !! legacy integer value.
186 INTERFACE l4f_category_delete
187  MODULE PROCEDURE l4f_category_delete_legacy, l4f_category_delete_f
188 END INTERFACE
189 
190 ! Internal C interface not to be used by user Fortran code
191 INTERFACE
192  SUBROUTINE l4f_category_log_c(a_category, a_priority, a_format) bind(C,name='log4c_category_log_c')
193  import
194  TYPE(l4f_handle),VALUE :: a_category
195  INTEGER(kind=c_int),VALUE :: a_priority
196 ! TYPE(c_ptr),VALUE :: locinfo !< not used
197  CHARACTER(kind=c_char),INTENT(in) :: a_format(*)
198  ! TYPE(c_ptr),VALUE :: a_args
199  END SUBROUTINE l4f_category_log_c
200 END INTERFACE
201 
204 INTERFACE l4f_category_log
205  MODULE PROCEDURE l4f_category_log_f, l4f_category_log_legacy
206 END INTERFACE l4f_category_log
207 
209 INTERFACE l4f_category_exist
210  MODULE PROCEDURE l4f_category_exist_f, l4f_category_exist_legacy
211 END INTERFACE l4f_category_exist
212 
214 INTERFACE
215  FUNCTION l4f_fini() bind(C,name='log4c_fini')
216  import
217  INTEGER(kind=c_int) :: l4f_fini
218  END FUNCTION l4f_fini
219 END INTERFACE
220 
222 !interface
223 !CHARACTER(len=12) FUNCTION l4f_msg(a_priority)
224 !integer,intent(in):: a_priority !< category name
225 !end function l4f_msg
226 !end interface
227 
228 #else
229 
230 CHARACTER(len=510),PRIVATE:: dummy_a_name
231 
233 TYPE :: l4f_handle
234  PRIVATE
235  INTEGER :: ptr = 0
236 END TYPE l4f_handle
237 
238 #endif
239 
240 PRIVATE
241 PUBLIC l4f_fatal, l4f_alert, l4f_crit, l4f_error, l4f_warn, l4f_notice, &
242  l4f_info, l4f_debug, l4f_trace, l4f_notset, l4f_unknown
243 PUBLIC l4f_handle, l4f_init, l4f_category_get_handle, l4f_category_get, l4f_category_delete, l4f_category_log, &
244  l4f_log, l4f_category_exist, l4f_fini
245 PUBLIC l4f_launcher
246 
247 CONTAINS
248 
253 SUBROUTINE l4f_launcher(a_name, a_name_force, a_name_append)
254 CHARACTER(len=*),INTENT(out) :: a_name
255 CHARACTER(len=*),INTENT(in),OPTIONAL :: a_name_force
256 CHARACTER(len=*),INTENT(in),OPTIONAL :: a_name_append
257 
258 INTEGER :: tarray(8)
259 CHARACTER(len=255) :: LOG4_APPLICATION_NAME,LOG4_APPLICATION_ID,arg
260 CHARACTER(len=255),SAVE :: a_name_save=""
261 
262 IF (PRESENT(a_name_force))THEN
263  a_name=a_name_force
264 ELSE IF (a_name_save /= "")THEN
265  a_name=a_name_save
266 ELSE
267 
268  CALL date_and_time(values=tarray)
269  CALL getarg(0, arg)
270  CALL getenv("LOG4_APPLICATION_NAME", log4_application_name)
271  CALL getenv("LOG4_APPLICATION_ID", log4_application_id)
272 
273  IF (log4_application_name == "" .AND. log4_application_id == "") THEN
274  WRITE(a_name,"(a,a,8i5,a)")trim(arg),"[",tarray,"]"
275  ELSE
276  a_name = trim(log4_application_name)//"["//trim(log4_application_id)//"]"
277  END IF
278 
279 END IF
280 
281 a_name_save=a_name
282 
283 IF (PRESENT(a_name_append)) THEN
284  a_name=trim(a_name)//"."//trim(a_name_append)
285 END IF
286 
287 END SUBROUTINE l4f_launcher
288 
289 #ifndef HAVE_LIBLOG4C
290 ! define dummy function to replace log4c interface
291 
293 INTEGER FUNCTION l4f_init()
294 CHARACTER(len=10) :: priority
295 INTEGER :: iostat
296 
297 CALL getenv("LOG4C_PRIORITY",priority)
298 IF (priority=="") THEN
299  l4f_priority = l4f_notice
300 ELSE
301  READ(priority,*,iostat=iostat)l4f_priority
302 END IF
303 
304 IF (iostat /= 0) THEN
305  l4f_priority = l4f_notice
306 END IF
307 
308 l4f_init = 0
309 
310 END FUNCTION l4f_init
312 
314 FUNCTION l4f_category_get(a_name) RESULT(handle)
315 CHARACTER(len=*),INTENT(in) :: a_name
317 TYPE(l4f_handle) :: handle
319 handle%ptr = 1
320 dummy_a_name = a_name
322 END FUNCTION l4f_category_get
326 SUBROUTINE l4f_category_delete(a_category)
327 TYPE(l4f_handle),INTENT(in) :: a_category
328 
329 a_category%ptr = 0
330 dummy_a_name = ""
331 
332 END SUBROUTINE l4f_category_delete
333 
334 
336 SUBROUTINE l4f_category_log(a_category,a_priority,a_format)
337 TYPE(l4f_handle),INTENT(in) :: a_category
338 INTEGER,INTENT(in):: a_priority
339 CHARACTER(len=*),INTENT(in):: a_format
340 
341 IF (a_category%ptr == 1 .AND. a_priority <= l4f_priority) THEN
342  WRITE(*,*)"[dummy] ",l4f_msg(a_priority),trim(dummy_a_name)," - ",trim(a_format)
343 ENDIF
344 
345 END SUBROUTINE l4f_category_log
346 
347 
349 SUBROUTINE l4f_log(a_priority,a_format)
350 INTEGER,INTENT(in):: a_priority
351 CHARACTER(len=*),INTENT(in):: a_format
352 
353 IF (a_priority <= l4f_priority) THEN
354  WRITE(*,*)"[_default] ",l4f_msg(a_priority),trim(dummy_a_name)," - ",trim(a_format)
355 ENDIF
356 
357 END SUBROUTINE l4f_log
358 
359 
361 LOGICAL FUNCTION l4f_category_exist(a_category)
362 TYPE(l4f_handle),INTENT(in) :: a_category
363 
364 l4f_category_exist = a_category%ptr == 1
365 
366 END FUNCTION l4f_category_exist
367 
368 
370 INTEGER FUNCTION l4f_fini()
371 
372 l4f_fini= 0
373 
374 END FUNCTION l4f_fini
375 
377 CHARACTER(len=12) FUNCTION l4f_msg(a_priority)
378 INTEGER,INTENT(in):: a_priority
379 
380 write(l4f_msg,*)a_priority
381 
382 if (a_priority == l4f_fatal) l4f_msg="FATAL"
383 if (a_priority == l4f_alert) l4f_msg="ALERT"
384 if (a_priority == l4f_crit) l4f_msg="CRIT"
385 if (a_priority == l4f_error) l4f_msg="ERROR"
386 if (a_priority == l4f_warn) l4f_msg="WARN"
387 if (a_priority == l4f_notice) l4f_msg="NOTICE"
388 if (a_priority == l4f_info) l4f_msg="INFO"
389 if (a_priority == l4f_debug) l4f_msg="DEBUG"
390 if (a_priority == l4f_trace) l4f_msg="TRACE"
391 if (a_priority == l4f_notset) l4f_msg="NOTSET"
392 if (a_priority == l4f_unknown) l4f_msg="UNKNOWN"
393 
394 END FUNCTION l4f_msg
395 
396 #else
397 
398 #include "arrayof_post_nodoc.F90"
399 
403 FUNCTION l4f_category_get(a_name) RESULT(handle)
404 CHARACTER(kind=c_char,len=*),INTENT(in) :: a_name
405 INTEGER :: handle
406 
407 handle = append(l4f_global_ptr, l4f_category_get_c(trim(a_name)//char(0)))
408 
409 END FUNCTION l4f_category_get
410 
411 
415 FUNCTION l4f_category_get_handle(a_name) RESULT(handle)
416 CHARACTER(kind=c_char,len=*),INTENT(in) :: a_name
417 TYPE(l4f_handle) :: handle
418 
419 handle = l4f_category_get_c(trim(a_name)//char(0))
420 
421 END FUNCTION l4f_category_get_handle
422 
423 
425 SUBROUTINE l4f_category_delete_legacy(a_category)
426 INTEGER,INTENT(in) :: a_category
427 
428 IF (a_category <= 0 .OR. a_category > l4f_global_ptr%arraysize) RETURN
429 CALL remove(l4f_global_ptr, pos=a_category)
430 
431 END SUBROUTINE l4f_category_delete_legacy
432 
433 
435 SUBROUTINE l4f_category_delete_f(a_category)
436 TYPE(l4f_handle),INTENT(inout) :: a_category
437 
438 ! hee the C function should be called, see comment above
439 ! CALL l4f_category_delete_c(a_category)
440 a_category%ptr = c_null_ptr
441 
442 END SUBROUTINE l4f_category_delete_f
443 
444 
447 SUBROUTINE l4f_category_log_f(a_category, a_priority, a_format)
448 TYPE(l4f_handle),INTENT(in) :: a_category
449 INTEGER(kind=c_int),INTENT(in) :: a_priority
450 CHARACTER(len=*),INTENT(in) :: a_format
451 
452 CALL l4f_category_log_c(a_category, a_priority, trim(a_format)//char(0))
453 
454 END SUBROUTINE l4f_category_log_f
455 
456 
460 SUBROUTINE l4f_category_log_legacy(a_category, a_priority, a_format)
461 INTEGER(kind=c_int),INTENT(in) :: a_category
462 INTEGER(kind=c_int),INTENT(in) :: a_priority
463 CHARACTER(len=*),INTENT(in) :: a_format
464 
465 CALL l4f_category_log_c(l4f_global_ptr%array(a_category), l4f_warn, &
466  'You are using the legacy log4fortran interface!'//char(0))
467 CALL l4f_category_log_c(l4f_global_ptr%array(a_category), l4f_warn, &
468  'Please, upgrade your code by defining category as `TYPE(l4f_handle)`'//char(0))
469 CALL l4f_category_log_c(l4f_global_ptr%array(a_category), l4f_warn, &
470  'and replacing `l4f_category_get` with `l4f_category_get_handle`'//char(0))
471 CALL l4f_category_log_c(l4f_global_ptr%array(a_category), a_priority, trim(a_format)//char(0))
472 
473 END SUBROUTINE l4f_category_log_legacy
474 
475 
478 SUBROUTINE l4f_log(a_priority, a_format)
479 INTEGER(kind=c_int),INTENT(in) :: a_priority
480 CHARACTER(len=*),INTENT(in) :: a_format
481 
482 INTEGER :: i
483 
484 IF (.NOT.l4f_category_exist(l4f_global_default)) THEN
485  i = l4f_init()
486  l4f_global_default = l4f_category_get_handle('_default')
487 ENDIF
488 CALL l4f_category_log(l4f_global_default, a_priority, a_format)
489 
490 END SUBROUTINE l4f_log
491 
492 
495 FUNCTION l4f_category_exist_f(a_category) RESULT(exist)
496 TYPE(l4f_handle),INTENT(in) :: a_category
497 LOGICAL :: exist
498 
499 exist = c_associated(a_category%ptr)
500 
501 END FUNCTION l4f_category_exist_f
502 
507 FUNCTION l4f_category_exist_legacy(a_category) RESULT(exist)
508 INTEGER,INTENT(in):: a_category
509 LOGICAL :: exist
510 
511 IF (a_category <= 0 .OR. a_category > l4f_global_ptr%arraysize) THEN
512  exist = .false.
513 ELSE
514  exist = l4f_category_exist(l4f_global_ptr%array(a_category))
515 ENDIF
516 
517 END FUNCTION l4f_category_exist_legacy
518 
519 #endif
520 
521 END MODULE log4fortran
Return true if the corresponding category handle exists.
Global log4fortran destructor.
classe per la gestione del logging
Global log4fortran constructor.
Emit log message for a category with specific priority.

Generated with Doxygen.