ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
statusMessageReporting.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file statusMessageReporting.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdarg.h>
5 
6 #ifdef WIN32
7 /*#define va_copy(dst, src) ((dst) = (src))*/
8 #endif
9 
10 #include "statusMessageReporting.h"
11 
12 #if defined __cplusplus
13 namespace GIDI {
14 using namespace GIDI;
15 #endif
16 
17 #define SMR_InitialMessageSize 1024
18 #define SMR_IncrementMessageSize 1024
19 
20 static int smrIsSetup = 0;
21 static char smr_mallocFailed[] = "statusMessageReporting could not allocate memory for message";
22 static char statusStringOk[] = "Ok", statusStringInfo[] = "Info",
23  statusStringWarning[] = "Warning", statusStringError[] = "Error", statusStringInvalid[] = "Invalid";
24 
26 static char unknownLibrary[] = "unknownID";
27 static char tooManyLibrary[] = "tooManyIDs";
28 static char invalidLibrary[] = "invalidID";
29 static char errnoLibrary[] = "errnoID";
30 static char smrLibrary[] = "statusMessageReporting";
32 
33 static statusMessageReport *smr_reportNew( void );
34 static int smr_reportInitialize( statusMessageReport *report );
35 static void smr_reportRelease( statusMessageReport *report );
36 static int smr_setReport( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code,
37  enum smr_status status, char const *fmt, va_list *args );
38 static int smr_setAllocationFailure( statusMessageReport *report, char const *file, int line, char const *function, char const *fmt, va_list *args );
39 /*
40 ============================================================
41 */
42 int smr_setup( void ) {
43 
44  int i;
45 
46  if( smrIsSetup ) return( 0 );
47  smrIsSetup = 1;
48  for( i = 0; i < smr_maximumNumberOfRegisteredLibraries; ++i ) registeredLibraries[i] = NULL;
59  return( 1 );
60 }
61 /*
62 ============================================================
63 */
64 int smr_cleanup( void ) {
65 
66  int i;
67 
68  if( smrIsSetup == 0 ) return( 0 );
69  for( i = smr_smrID + 1; i < numberOfRegisteredLibraries; ++i ) smr_freeMemory( (void **) &(registeredLibraries[i]) );
70  numberOfRegisteredLibraries = 0;
71  smrIsSetup = 0;
72 
73  return( 0 );
74 }
75 /*
76 ============================================================
77 */
78 int smr_registerLibrary( char const *libraryName ) {
79 
80  int i;
81 
82  if( smrIsSetup == 0 ) return( -1 );
84  for( i = 0; i < numberOfRegisteredLibraries; ++i ) { /* Check if name is already registered. */
85  if( strcmp( libraryName, registeredLibraries[i] ) == 0 ) return( i );
86  }
87  if( ( registeredLibraries[numberOfRegisteredLibraries] = strdup( libraryName ) ) == NULL ) return( -2 );
89  return( numberOfRegisteredLibraries - 1 );
90 }
91 /*
92 ============================================================
93 */
95 
97 }
98 /*
99 ============================================================
100 */
101 char const *smr_getRegisteredLibrariesName( int ID ) {
102 
103  if( ( ID < 0 ) || ( ID >= smr_maximumNumberOfRegisteredLibraries ) ) return( NULL );
104  return( registeredLibraries[ID] );
105 }
106 /*
107 ============================================================
108 */
109 statusMessageReporting *smr_new( statusMessageReporting *smr, enum smr_status verbosity, int append ) {
110 
111  statusMessageReporting *new_SMR;
112 
113  if( ( new_SMR = (statusMessageReporting *) smr_malloc2( smr, sizeof( statusMessageReporting ), 0, "new_SMR" ) ) == NULL ) return( NULL );
114  smr_initialize( new_SMR, verbosity, append );
115  return( new_SMR );
116 }
117 /*
118 ============================================================
119 */
120 int smr_initialize( statusMessageReporting *smr, enum smr_status verbosity, int append ) {
121 
122  if( smr == NULL ) return( 0 );
123  smr->verbosity = verbosity;
124  smr->append = append;
125  smr_reportInitialize( &(smr->report) );
126  return( 0 );
127 }
128 /*
129 ============================================================
130 */
132 
133  if( smr == NULL ) return( NULL );
134  return( smr_new( NULL, smr->verbosity, smr->append ) );
135 }
136 /*
137 ============================================================
138 */
140 
141  statusMessageReport *current, *next, *first = smr_firstReport( smr );
142 
143  if( smr == NULL ) return;
144  for( current = first; current != NULL; current = next ) {
145  next = smr_nextReport( current );
146  smr_reportRelease( current );
147  if( current != first ) smr_freeMemory( (void **) &current );
148  }
149  smr_initialize( smr, smr->verbosity, smr->append );
150 }
151 /*
152 ============================================================
153 */
155 
156  if( smr == NULL ) return( NULL );
157  if( *smr != NULL ) {
158  smr_release( *smr );
159  smr_freeMemory( (void **) smr );
160  }
161  return( *smr );
162 }
163 /*
164 ============================================================
165 */
167 
168  statusMessageReport *report;
169 
170  if( ( report = (statusMessageReport *) smr_malloc2( NULL, sizeof( statusMessageReport ), 0, "report" ) ) == NULL ) return( NULL );
171  smr_reportInitialize( report );
172  return( report );
173 }
174 /*
175 ============================================================
176 */
178 
179  report->next = NULL;
180  report->status = smr_status_Ok;
181  report->libraryID = smr_unknownID;
182  report->code = smr_codeNULL;
183  report->line = -1;
184  report->fileName[0] = 0;
185  report->function[0] = 0;
186  report->message = NULL;
187  return( 0 );
188 }
189 /*
190 ============================================================
191 */
192 static void smr_reportRelease( statusMessageReport *report ) {
193 
194  if( report->message != NULL ) {
195  if( report->message != smr_mallocFailed ) smr_freeMemory( (void **) &(report->message) );
196  }
197  smr_reportInitialize( report );
198 }
199 /*
200 ============================================================
201 */
202 static int smr_setReport( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code,
203  enum smr_status status, char const *fmt, va_list *args ) {
204 
205  char *userMsg;
206  statusMessageReport *report, *next;
207 
208  if( smr == NULL ) return( 0 );
209  if( (int) status < (int) smr->verbosity ) return( 0 );
210  if( status == smr_status_Ok ) return( 0 );
211  if( ( smr->report.status != smr_status_Ok ) && smr->append ) {
212  if( ( report = smr_reportNew( ) ) == NULL ) return( smr_setAllocationFailure( NULL, file, line, function, fmt, args ) );
213  for( next = smr_firstReport( smr ); next->next != NULL; next = next->next ) ;
214  next->next = report; }
215  else {
216  if( status <= smr->report.status ) return( 0 );
217  smr_release( smr );
218  report = &(smr->report);
219  }
220  report->status = status;
221  if( ( libraryID < 0 ) || ( libraryID >= numberOfRegisteredLibraries ) ) libraryID = smr_invalidID;
222  report->libraryID = libraryID;
223  report->code = code;
224  report->line = line;
225  if( file != NULL ) strncpy( report->fileName, file, smr_maximumFileNameSize );
226  report->fileName[smr_maximumFileNameSize] = 0;
227  if( function != NULL ) strncpy( report->function, function, smr_maximumFileNameSize );
228  report->function[smr_maximumFileNameSize] = 0;
229 
230  if( ( report->message = smr_vallocateFormatMessage( fmt, args ) ) == NULL ) return( smr_setAllocationFailure( report, file, line, function, fmt, args ) );
231  if( userInterface != NULL ) {
232  if( ( userMsg = (*(smr_userInterface *) userInterface)( (void *) userInterface ) ) != NULL ) {
233  int userSize = (int) strlen( userMsg );
234  if( ( report->message = (char *) smr_realloc2( NULL, report->message, strlen( report->message ) + userSize + 2, "report->message" ) ) == NULL ) {
235  free( userMsg );
236  return( smr_setAllocationFailure( report, file, line, function, fmt, args ) );
237  }
238  strcat( report->message, userMsg );
239  free( userMsg );
240  }
241  }
242  return( 0 );
243 }
244 /*
245 ============================================================
246 */
247 static int smr_setAllocationFailure( statusMessageReport *report, char const *file, int line, char const *function, char const *fmt, va_list *args ) {
248 
249  vfprintf( stderr, fmt, *args );
250  va_end( *args );
251  fprintf( stderr, "\nAt line %d of %s in function %s\n", line, file, function );
252  if( report != NULL ) {
253  report->status = smr_status_Error;
254  report->message = (char *) smr_mallocFailed;
255  return( 1 );
256  }
257  return( -1 );
258 }
259 /*
260 ============================================================
261 */
262 int smr_setReportInfo( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code, char const *fmt, ... ) {
263 
264  int status;
265  va_list args;
266 
267  va_start( args, fmt );
268  status = smr_setReport( smr, userInterface, file, line, function, libraryID, code, smr_status_Info, fmt, &args );
269  va_end( args );
270  return( status );
271 }
272 /*
273 ============================================================
274 */
275 int smr_vsetReportInfo( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code, char const *fmt, va_list *args ) {
276 
277  return( smr_setReport( smr, userInterface, file, line, function, libraryID, code, smr_status_Info, fmt, args ) );
278 }
279 /*
280 ============================================================
281 */
282 int smr_setReportWarning( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code, char const *fmt, ... ) {
283 
284  int status;
285  va_list args;
286 
287  va_start( args, fmt );
288  status = smr_setReport( smr, userInterface, file, line, function, libraryID, code, smr_status_Warning, fmt, &args );
289  va_end( args );
290  return( status );
291 }
292 /*
293 ============================================================
294 */
295 int smr_vsetReportWarning( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code, char const *fmt, va_list *args ) {
296 
297  return( smr_setReport( smr, userInterface, file, line, function, libraryID, code, smr_status_Warning, fmt, args ) );
298 }
299 /*
300 ============================================================
301 */
302 int smr_setReportError( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code, char const *fmt, ... ) {
303 
304  int status;
305  va_list args;
306 
307  va_start( args, fmt );
308  status = smr_setReport( smr, userInterface, file, line, function, libraryID, code, smr_status_Error, fmt, &args );
309  va_end( args );
310  return( status );
311 }
312 /*
313 ============================================================
314 */
315 int smr_vsetReportError( statusMessageReporting *smr, void *userInterface, char const *file, int line, char const *function, int libraryID, int code, char const *fmt, va_list *args ) {
316 
317  return( smr_setReport( smr, userInterface, file, line, function, libraryID, code, smr_status_Error, fmt, args ) );
318 }
319 /*
320 ============================================================
321 */
323 
324  enum smr_status status = smr_status_Ok;
325  statusMessageReport *report;
326 
327  if( smr == NULL ) return( smr_status_Ok );
328  for( report = smr_firstReport( smr ); report != NULL; report = smr_nextReport( report ) ) if( report->status > status ) status = report->status;
329  return( status );
330 }
331 /*
332 ============================================================
333 */
335 
336  return( smr_highestStatus( smr ) == smr_status_Ok );
337 }
338 /*
339 ============================================================
340 */
342 
343  return( smr_highestStatus( smr ) == smr_status_Info );
344 }
345 /*
346 ============================================================
347 */
349 
350  return( smr_highestStatus( smr ) == smr_status_Warning );
351 }
352 /*
353 ============================================================
354 */
356 
357  return( smr_highestStatus( smr ) == smr_status_Error );
358 }
359 /*
360 ============================================================
361 */
363 
364  enum smr_status status = smr_highestStatus( smr );
365 
366  return( ( status == smr_status_Warning ) || ( status == smr_status_Error ) );
367 }
368 /*
369 ============================================================
370 */
372 
373  if( report == NULL ) return( 0 );
374  return( report->status == smr_status_Ok );
375 }
376 /*
377 ============================================================
378 */
380 
381  if( report == NULL ) return( 0 );
382  return( report->status == smr_status_Info );
383 }
384 /*
385 ============================================================
386 */
388 
389  if( report == NULL ) return( 0 );
390  return( report->status == smr_status_Warning );
391 }
392 /*
393 ============================================================
394 */
396 
397  if( report == NULL ) return( 0 );
398  return( report->status == smr_status_Error );
399 }
400 /*
401 ============================================================
402 */
404 
405  if( report == NULL ) return( 0 );
406  return( ( report->status == smr_status_Warning ) || ( report->status == smr_status_Error ) );
407 }
408 /*
409 ============================================================
410 */
412 
413  int n = 0;
414  statusMessageReport *report;
415 
416  if( smr == NULL ) return( 0 );
417  if( smr->report.status == smr_status_Ok ) return( 0 );
418  for( report = smr_firstReport( smr ); report != NULL; report = smr_nextReport( report ) ) ++n;
419  return( n );
420 }
421 /*
422 ============================================================
423 */
425 
426  if( smr == NULL ) return( NULL );
427  if( smr->report.status == smr_status_Ok ) return( NULL );
428  return( &(smr->report) );
429 }
430 /*
431 ============================================================
432 */
434 
435  if( report == NULL ) return( NULL );
436  return( report->next );
437 }
438 /*
439 ============================================================
440 */
442 
443  if( smr == NULL ) return( smr_status_Ok );
444  return( smr->verbosity );
445 }
446 /*
447 ============================================================
448 */
450 
451  if( smr == NULL ) return( 0 );
452  return( smr->append );
453 }
454 /*
455 ============================================================
456 */
458 
459  if( report == NULL ) return( 0 );
460  return( report->libraryID );
461 }
462 /*
463 ============================================================
464 */
466 
467  if( report == NULL ) return( -1 );
468  return( report->code );
469 }
470 /*
471 ============================================================
472 */
474 
475  if( report == NULL ) return( -1 );
476  return( report->line );
477 }
478 /*
479 ============================================================
480 */
481 char const *smr_getFile( statusMessageReport *report ) {
482 
483  if( report == NULL ) return( NULL );
484  return( report->fileName );
485 }
486 /*
487 ============================================================
488 */
489 char const *smr_getFunction( statusMessageReport *report ) {
490 
491  if( report == NULL ) return( NULL );
492  return( report->function );
493 }
494 /*
495 ============================================================
496 */
497 char const *smr_getMessage( statusMessageReport *report ) {
498 
499  if( report == NULL ) return( NULL );
500  return( report->message );
501 }
502 /*
503 ============================================================
504 */
506 
507  if( report == NULL ) return( NULL );
508  if( report->status == smr_status_Ok ) return( NULL );
509  return( smr_allocateFormatMessage( report->message ) );
510 }
511 /*
512 ============================================================
513 */
515 
516  if( report == NULL ) return( NULL );
517  if( report->status == smr_status_Ok ) return( NULL );
518  return( smr_allocateFormatMessage( "%s\nAt line %d of %s in function %s", report->message, report->line, report->fileName, report->function ) );
519 }
520 /*
521 ============================================================
522 */
524 
525  smr_write( smr, stdout, clear );
526 }
527 /*
528 ============================================================
529 */
530 void smr_write( statusMessageReporting *smr, FILE *f, int clear ) {
531 
532  statusMessageReport *report;
533 
534  if( smr == NULL ) return;
535  for( report = smr_firstReport( smr ); report != NULL; report = smr_nextReport( report ) ) smr_reportWrite( report, f );
536  if( clear ) smr_release( smr );
537 }
538 /*
539 ============================================================
540 */
542 
543  smr_reportWrite( report, stderr );
544 }
545 /*
546 ============================================================
547 */
548 void smr_reportWrite( statusMessageReport *report, FILE *f ) {
549 
550  if( report->message != NULL ) fprintf( f, "%s\nAt line %d of %s in function %s\n", report->message, report->line, report->fileName, report->function );
551 }
552 /*
553 ============================================================
554 */
555 char const *smr_statusToString( enum smr_status status ) {
556 
557  switch( status ) {
558  case smr_status_Ok : return( statusStringOk );
559  case smr_status_Info : return( statusStringInfo );
560  case smr_status_Warning : return( statusStringWarning );
561  case smr_status_Error : return( statusStringError );
562  }
563  return( statusStringInvalid );
564 }
565 /*
566 ============================================================
567 */
568 char *smr_allocateFormatMessage( char const *fmt, ... ) {
569 
570  char *s;
571  va_list args;
572 
573  va_start( args, fmt );
574  s = smr_vallocateFormatMessage( fmt, &args );
575  va_end( args );
576  return( s );
577 }
578 /*
579 ============================================================
580 */
581 char *smr_vallocateFormatMessage( char const *fmt, va_list *args ) {
582 
583  int n, size = SMR_InitialMessageSize;
585  va_list args_;
586 
587  while( 1 ) {
588  va_copy( args_, *args );
589  n = vsnprintf( message, size, fmt, args_ );
590  va_end( args_ );
591  if( ( n > -1 ) && ( n < size ) ) break;
592  if( n > -1 ) { /* glibc 2.1 */
593  size = n + 3; }
594  else { /* glibc 2.0 */
595  size += SMR_IncrementMessageSize;
596  }
597  if( message == buffer ) message = NULL;
598  if( ( message = (char *) realloc( message, size ) ) == NULL ) return( NULL );
599  } // Loop checking, 11.06.2015, T. Koi
600  if( message == buffer ) {
601  if( ( message = (char *) malloc( n + 1 ) ) == NULL ) return( NULL );
602  strcpy( message, buffer ); }
603  else {
604  if( ( message = (char *) realloc( message, n + 1 ) ) == NULL ) return( NULL );
605  }
606  return( message );
607 }
608 /*
609 ============================================================
610 */
611 void *smr_malloc( statusMessageReporting *smr, size_t size, int zero, char const *forItem, char const *file, int line, char const *function ) {
612 
613  void *p = smr_realloc( smr, NULL, size, forItem, file, line, function );
614  size_t i;
615  char *c;
616  long long *l;
617 
618  if( ( p != NULL ) && zero ) {
619  for( i = 0, l = (long long *) p; i < size / sizeof( long long ); i++, l++ ) *l = 0;
620  for( i *= sizeof( long long ), c = (char *) l; i < size; i++, c++ ) *c = 0;
621  }
622 
623  return( p );
624 }
625 /*
626 ============================================================
627 */
628 void *smr_realloc( statusMessageReporting *smr, void *pOld, size_t size, char const *forItem, char const *file, int line, char const *function ) {
629 
630  void *p = realloc( pOld, size );
631 
632  if( ( p == NULL ) && ( smr != NULL ) ) {
633  smr_setReportError( smr, NULL, file, line, function, smr_smrID, -1, " smr_realloc: failed to realloc size = %z for variable %s\n", size, forItem );
634  }
635  return( p );
636 }
637 /*
638 ============================================================
639 */
640 void *smr_freeMemory( void **p ) {
641 
642  if( p == NULL ) return( NULL );
643  if( *p != NULL ) {
644  free( *p );
645  *p = NULL;
646  }
647  return( *p );
648 }
649 /*
650 ============================================================
651 */
652 char *smr_allocateCopyString( statusMessageReporting *smr, char const *s, char const *forItem, char const *file, int line, char const *function ) {
653 /*
654 * User must free returned string.
655 */
656  char *c = strdup( s );
657 
658  if( c == NULL ) smr_setReportError( smr, NULL, file, line, function, smr_smrID, -1, " smr_allocateCopyString: strdup failed for strlen( s ) = %z for variable %s",
659  strlen( s ), forItem );
660  return( c );
661 }
662 /*
663 ============================================================
664 */
665 char *smr_allocateCopyStringN( statusMessageReporting *smr, char const *s, size_t n, char const *forItem, char const *file, int line, char const *function ) {
666 /*
667 * User must free returned string.
668 */
669  size_t l = strlen( s );
670  char *c;
671 
672  if( l > n ) l = n;
673  if( ( c = (char *) smr_malloc( smr, l + 1, 0, forItem, file, line, function ) ) != NULL ) {
674  strncpy( c, s, n );
675  c[l] = 0;
676  }
677 /*
678  c = strndup( s, l ); # Not standard on enough systems.
679  if( c != NULL ) {
680  c[l] = 0; }
681  else {
682  smr_setReportError( smr, NULL, file, line, function, smr_smrID, -1, " smr_allocateCopyStringN: strndup failed for strlen( s ) = %z for variable %s",
683  strlen( s ), forItem );
684  }
685 */
686  return( c );
687 }
688 
689 #if defined __cplusplus
690 }
691 #endif