00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <stdarg.h>
00040
00041 #include "statusMessageReporting.h"
00042
00043 #if defined __cplusplus
00044 namespace GIDI {
00045 using namespace GIDI;
00046 #endif
00047
00048 static const char smr_mallocFailed[] = "statusMessageReporting could not allocate memory for message";
00049
00050 static int smr_setAllocationFailure( statusMessageReporting *smr, const char *fmt, va_list *args );
00051 static int smr_setMessage( statusMessageReporting *smr, void *userInterface, const char *file, int line, int code,
00052 enum smr_status status, const char *fmt, va_list *args );
00053 static char *smr_getFullMessage2( char const *fmt, ... );
00054
00055
00056
00057 int smr_initialize( statusMessageReporting *smr ) {
00058
00059 smr->status = smr_status_Ok;
00060 smr->packageName[0] = 0;
00061 smr->line= -1;
00062 smr->code = 0;
00063 smr->message = NULL;
00064 return( 0 );
00065 }
00066
00067
00068
00069 int smr_release( statusMessageReporting *smr ) {
00070
00071 if( smr->message != NULL ) {
00072 if( smr->message != smr_mallocFailed ) free( smr->message );
00073 }
00074 return( smr_initialize( smr ) );
00075 }
00076
00077
00078
00079 int smr_setMessageInfo( statusMessageReporting *smr, void *userInterface, const char *file, int line, int code, const char *fmt, ... ) {
00080
00081 int status;
00082 va_list args;
00083
00084 va_start( args, fmt );
00085 status = smr_setMessage( smr, userInterface, file, line, code, smr_status_Info, fmt, &args );
00086 va_end( args );
00087 return( status );
00088 }
00089
00090
00091
00092 int smr_vsetMessageInfo( statusMessageReporting *smr, void *userInterface, const char *file, int line, int code, const char *fmt, va_list *args ) {
00093
00094 int status = smr_setMessage( smr, userInterface, file, line, code, smr_status_Info, fmt, args );
00095 return( status );
00096 }
00097
00098
00099
00100 int smr_setMessageError( statusMessageReporting *smr, void *userInterface, const char *file, int line, int code, const char *fmt, ... ) {
00101
00102 int status;
00103 va_list args;
00104
00105 va_start( args, fmt );
00106 status = smr_setMessage( smr, userInterface, file, line, code, smr_status_Error, fmt, &args );
00107 va_end( args );
00108 return( status );
00109 }
00110
00111
00112
00113 int smr_vsetMessageError( statusMessageReporting *smr, void *userInterface, const char *file, int line, int code, const char *fmt, va_list *args ) {
00114
00115 int status = smr_setMessage( smr, userInterface, file, line, code, smr_status_Error, fmt, args );
00116 return( status );
00117 }
00118
00119
00120
00121 char *smr_allocateFormatMessage( const char *fmt, ... ) {
00122
00123 char *s;
00124 va_list args;
00125
00126 va_start( args, fmt );
00127 s = smr_vallocateFormatMessage( fmt, &args );
00128 va_end( args );
00129 return( s );
00130 }
00131
00132
00133
00134 char *smr_vallocateFormatMessage( const char *fmt, va_list *args ) {
00135
00136 int n, size = 128;
00137 char *message = NULL;
00138 va_list args_;
00139
00140 while( 1 ) {
00141 if( ( message = (char *) realloc( message, size ) ) == NULL ) return( NULL );
00142
00143 #if defined WIN32
00144 args_ = *args;
00145 #elif defined __IBMCPP__
00146 va_copy( args_, *args );
00147 #else
00148 __va_copy( args_, *args );
00149 #endif
00150 n = vsnprintf( message, size, fmt, args_ );
00151 va_end( args_ );
00152 if( ( n > -1 ) && ( n < size ) ) break;
00153 if( n > -1 ) {
00154 size = n + 3; }
00155 else {
00156 size += 128;
00157 }
00158 }
00159 return( message );
00160 }
00161
00162
00163
00164 static int smr_setMessage( statusMessageReporting *smr, void *userInterface, const char *file, int line, int code,
00165 enum smr_status status, const char *fmt, va_list *args ) {
00166
00167 char *userMsg = NULL;
00168 int userSize;
00169
00170 if( smr == NULL ) return( 0 );
00171 smr_release( smr );
00172 smr->status = status;
00173 if( file != NULL ) strncpy( smr->packageName, file, smr_maximumPackageNameSize );
00174 smr->packageName[smr_maximumPackageNameSize-1] = 0;
00175 smr->line= line;
00176 smr->code = code;
00177
00178 if( ( smr->message = smr_vallocateFormatMessage( fmt, args ) ) == NULL ) return( smr_setAllocationFailure( smr, fmt, args ) );
00179 if( userInterface != NULL ) {
00180 if( ( userSize = (*(smr_userInterface *) userInterface)( (void *) userInterface, NULL ) ) > 0 ) {
00181
00182 if( (smr->message = (char*) realloc(smr->message, strlen( smr->message ) + userSize + 2)) == NULL ) return( smr_setAllocationFailure( smr, fmt, args ) );
00183 strcat( smr->message, "\n" );
00184 userSize = (*(smr_userInterface *) userInterface)( (void *) userInterface, &userMsg );
00185 if( userSize < 0 ) return( smr_setAllocationFailure( smr, fmt, args ) );
00186 if( userSize > 0 ) {
00187 strcat( smr->message, userMsg );
00188 free( userMsg );
00189 }
00190 }
00191 }
00192 return( 0 );
00193 }
00194
00195
00196
00197 static int smr_setAllocationFailure( statusMessageReporting *smr, const char *fmt, va_list *args ) {
00198
00199 vfprintf( stderr, fmt, *args );
00200 fprintf( stderr, "\nAt line %d of %s\n", smr->line, smr->packageName );
00201 smr->status = smr_status_Fatal;
00202 smr->message = (char *) smr_mallocFailed;
00203 return( 1 );
00204 }
00205
00206
00207
00208 int smr_isOk( statusMessageReporting *smr ) {
00209
00210 if( smr == NULL ) return( 1 );
00211 return( smr->status == smr_status_Ok );
00212 }
00213
00214
00215
00216 int smr_isInfo( statusMessageReporting *smr ) {
00217
00218 if( smr == NULL ) return( 1 );
00219 return( smr->status == smr_status_Info );
00220 }
00221
00222
00223
00224 int smr_isError( statusMessageReporting *smr ) {
00225
00226 if( smr == NULL ) return( 1 );
00227 return( ( smr->status == smr_status_Error ) || ( smr->status == smr_status_Fatal ) );
00228 }
00229
00230
00231
00232 int smr_isFatal( statusMessageReporting *smr ) {
00233
00234 if( smr == NULL ) return( 1 );
00235 return( smr->status == smr_status_Fatal );
00236 }
00237
00238
00239
00240 const char *smr_getMessage( statusMessageReporting *smr ) {
00241
00242 return( smr->message );
00243 }
00244
00245
00246
00247 char *smr_getFullMessage( statusMessageReporting *smr ) {
00248
00249 return( smr_getFullMessage2( "%s\nAt line %d of %s", smr->message, smr->line, smr->packageName ) );
00250 }
00251
00252
00253
00254 static char *smr_getFullMessage2( char const *fmt, ... ) {
00255
00256 va_list args;
00257 char *message;
00258
00259 va_start( args, fmt );
00260 message = smr_vallocateFormatMessage( fmt, &args );
00261 va_end( args );
00262 return( message );
00263 }
00264
00265
00266
00267 void smr_print( statusMessageReporting *smr, FILE *f, int clear ) {
00268
00269 if( smr->message != NULL ) fprintf( f, "%s\nAt line %d of %s\n", smr->message, smr->line, smr->packageName );
00270 if( clear ) smr_release( smr );
00271 }
00272
00273 #if defined __cplusplus
00274 }
00275 #endif