6 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
7 * Copyright (C) 2009, MinGW Project
10 * Implementation of the diagnostic message handling subsystem.
13 * This is free software. Permission is granted to copy, modify and
14 * redistribute this software, under the provisions of the GNU General
15 * Public License, Version 3, (or, at your option, any later version),
16 * as published by the Free Software Foundation; see the file COPYING
17 * for licensing details.
19 * Note, in particular, that this software is provided "as is", in the
20 * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
21 * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
22 * PARTICULAR PURPOSE. Under no circumstances will the author, or the
23 * MinGW Project, accept liability for any damages, however caused,
24 * arising from the use of this software.
35 /* Abstract base class, from which message handlers are derived.
38 dmhTypeGeneric( const char* );
39 virtual uint16_t control( const uint16_t, const uint16_t ) = 0;
40 virtual int notify( const dmh_severity, const char*, va_list ) = 0;
41 virtual int printf( const char*, va_list ) = 0;
47 class dmhTypeTTY : public dmhTypeGeneric
49 /* Diagnostic message handler for use in console applications.
52 dmhTypeTTY( const char *progname );
53 virtual uint16_t control( const uint16_t, const uint16_t );
54 virtual int notify( const dmh_severity, const char*, va_list );
55 virtual int printf( const char*, va_list );
58 class dmhTypeGUI : public dmhTypeGeneric
60 /* Diagnostic message handler for use in window applications.
63 dmhTypeGUI( const char *progname );
64 virtual uint16_t control( const uint16_t, const uint16_t );
65 virtual int notify( const dmh_severity, const char*, va_list );
66 virtual int printf( const char*, va_list );
69 dmh_exception::dmh_exception() throw()
70 : message("Unspecified error")
73 dmh_exception::dmh_exception::dmh_exception(const char * msg) throw()
74 : message("Unspecified error")
80 dmh_exception::~dmh_exception() throw()
83 const char * dmh_exception::what() const throw()
88 /* Constructors serve to initialise the message handler,
89 * simply creating the class instance, and storing the specified
90 * program name within it.
92 dmhTypeGeneric::dmhTypeGeneric( const char* name ):progname( name ){}
93 dmhTypeTTY::dmhTypeTTY( const char* name ):dmhTypeGeneric( name ){}
94 dmhTypeGUI::dmhTypeGUI( const char* name ):dmhTypeGeneric( name ){}
96 /* This pointer stores the address of the message handler
97 * class instance, after initialisation.
99 static dmhTypeGeneric *dmh = NULL;
101 EXTERN_C void dmh_init( const dmh_class subsystem, const char *progname )
103 /* Public entry point for message handler initialisation...
105 * We only do it once, silently ignoring any attempt to
106 * establish a second handler.
110 /* No message handler has yet been initialised;
111 * passing the specified program name, select...
113 if( subsystem == DMH_SUBSYSTEM_GUI )
115 * ...a GUI class handler on demand...
117 dmh = new dmhTypeGUI( progname );
120 /* ...otherwise, a console class handler by default.
122 dmh = new dmhTypeTTY( progname );
127 int abort_if_fatal( const dmh_severity code, int status )
129 /* Helper function to abort an application, on notification
130 * of a DMH_FATAL exception.
132 if( code == DMH_FATAL )
133 throw dmh_exception("Fatal error occured");
135 /* If the exception wasn't DMH_FATAL, then fall through to
136 * return the specified status code.
141 uint16_t dmhTypeGUI::control( const uint16_t request, const uint16_t mask )
143 /* Select optional features of the GUI class message handler.
145 * FIXME: this is a stub; implementation to be provided.
150 int dmhTypeGUI::notify( const dmh_severity code, const char *fmt, va_list argv )
152 /* Message dispatcher for GUI applications.
154 * FIXME: this is a stub; implementation to be provided.
157 fprintf( stderr, "%s: *** ERROR *** DMH_SUBSYSTEM_GUI not yet implemented\n", progname );
160 int dmhTypeGUI::printf( const char *fmt, va_list argv )
162 /* Display arbitrary text messages via the diagnostic message handler.
164 * FIXME: this is a stub; implementation to be provided.
166 return notify( DMH_ERROR, fmt, argv );
169 uint16_t dmhTypeTTY::control( const uint16_t request, const uint16_t mask )
171 /* Select optional features of the console class message handler.
172 * This message handler provides no optional features; we make this
178 int dmhTypeTTY::notify( const dmh_severity code, const char *fmt, va_list argv )
180 /* Message dispatcher for console class applications.
182 static const char *severity[] =
184 /* Labels to identify message severity...
186 "INFO", /* DMH_INFO */
187 "WARNING", /* DMH_WARNING */
188 "ERROR", /* DMH_ERROR */
189 "FATAL" /* DMH_FATAL */
192 /* Dispatch the message to standard error, terminate application
193 * if DMH_FATAL, else continue, returning the message length.
195 int retcode = fprintf( stderr, "%s: *** %s *** ", progname, severity[code] );
196 return abort_if_fatal( code, retcode + vfprintf( stderr, fmt, argv ) );
199 int dmhTypeTTY::printf( const char *fmt, va_list argv )
201 /* Display arbitrary text messages via the diagnostic message handler;
202 * for the TTY subsystem, this is equivalent to printf() on stderr.
204 return vfprintf( stderr, fmt, argv );
207 EXTERN_C uint16_t dmh_control( const uint16_t request, const uint16_t mask )
209 return dmh->control( request, mask );
212 EXTERN_C int dmh_notify( const dmh_severity code, const char *fmt, ... )
214 /* Public entry point for diagnostic message dispatcher.
218 /* The message handler has been called before initialising it;
219 * this is an internal program error -- treat it as fatal!
221 dmh_init( DMH_SUBSYSTEM_TTY, "dmh" );
222 dmh_notify( DMH_FATAL, "message handler was not initialised\n" );
225 /* Normal operation; pass the message on to the active handler.
228 va_start( argv, fmt );
229 int retcode = dmh->notify( code, fmt, argv );
234 EXTERN_C int dmh_printf( const char *fmt, ... )
236 /* Simulate standard printf() function calls, redirecting the display
237 * of formatted output through the diagnostic message handler.
240 va_start( argv, fmt );
241 int retcode = dmh->printf( fmt, argv );
246 /* $RCSfile$: end of file */