Re: Request for Comment: Callable CRM114 Classifiers (libcrm114) --> OOBC
"Ger Hobbelt" <[email protected]>
| Newsgroups | gmane.mail.spam.crm114 |
|---|---|
| Message-ID | <[email protected]> |
On Sat, Oct 4, 2008 at 10:11 PM, Eugene Crosser <[email protected]> wrote: > Ger Hobbelt wrote: > >> Verbosity cannot be done through 'printf()' et al > ... >> --> error reporting hooks are required elements of the interface. > > Openssl style stack of error messages maybe? > > I'd suggest not to over-engineer debugging (/trace) interface for now. I > have an impression that it could divert effort from more important things. Nothing overengineered: the code is currently littered with stuff like this: ---------------------------- if (internal_trace) fprintf(stderr, "executing a LEARN\n"); ---------------------------- which I'd rather see turn into this: ---------------------------- this->trace_callback(this, CRM_DBG_INTERNAL, "executing a LEARN\n"); ---------------------------- so that all std I/O gets thrown to the wolves *outside* libcrm114 on a /purpose/ basis (tracing, error reporting, etc.): you don't have stdout/stderr in GUI and embedded environs anyway. The above would then be completed with an interface bit a la: ---------------------------- typedef void crm_trace_callback_t(crm_config_t *obj, int level, const char *fmt_msg, ...); ---------------------------- (which, incidentally, you can augment in GCC (without hurting portability to other compilers) to tell GCC he should check this callback interface as if it were a regular printf() style formatted vararg, so you'd get nice warnings when screwing up your %d, %s, etc. elements) plus the extra hook in the crm class object: ---------------------------- typedef struct { crm_trace_callback_t *trace_callback; } crm_config_t; ---------------------------- and a /user defined/ function for a console app: ---------------------------- void my_crm_trace(crm_config_t *obj, int level, const char *fmt, ...) { va_list args; my_own_custom_state_object_t *cfg; va_start(args, fmt); // get my own state object back (functor!) cfg = (my_own_custom_state_object_t *)obj->propagator; if ((cfg->internal_trace && level == CRM_DBG_INTERNAL) || (cfg->internal_trace && level == CRM_DBG_INTERNAL)) { vfprintf(stderr, fmt, args); } va_end(args); } ---------------------------- (Note: GUI app writers and embedded folk would copy&paste that, but replace the vfprintf() with a GUI message or syslog() call or other. Given this callback architecture, that's finally doable!) plus 'registration' code somewhere at the start of your run: ---------------------------- crm_config_t *obj = ...; .... obj->trace_callback = my_crm_trace; ... // call libcrm114 methods: result = obj->learn(.......); .... /// and more using libcrm114... -------------------------------- Which is nothing spectacular, just basic stuff for professional software engineers. ;-) And a direct replacement, no frills, for the current code (as shown at top). Folks might recognize this as a Visitor Pattern (Gamma et al) done in 'C'. (Who said you couldn't do OO in 'C', eh? cfront did it. So can we. ... I might be joking. ;-) ) EXTRA: --------- The only thing in there that I'd like to see 'improved' regarding the trace stuff is an 'improved' use of that 'level' argument there, which can be easily done using a few platinum blonde macros, so that one can filter messages not only at USER vs. INTERNAL, but per function/code section within libcrm114: this would mean I'd introduce a 'code section' ID code and mix that in with the 'severity level' INTERNAL/USER/... so things would look like this in Bill's: ---------------------------- this->trace_callback(this, CRM_TRACE_LEVEL(CRM_DBG_INTERNAL, CRM_S_LEARN_SETUP), "executing a LEARN\n"); ---------------------------- which would of course be shortened to (with help of a little wrap macro): ---------------------------- this->trace_callback(this, CRM_TRACE_INTERNAL(CRM_S_LEARN_SETUP), "executing a LEARN\n"); ---------------------------- where you'd have definitions like these to go with that in your .h: ---------------------------- // trace 'severity' levels: #define CRM_DBG_USER 1 #define CRM_DBG_INTERNAL 2 // code section ID's ... #define CRM_S_LEARN_SETUP 42 #define CRM_S_VT_CORE 43 #define CRM_S_LEARN_FEATURES 44 #define CRM_S_LEARN_FINALIZE 45 ... // and here's the macro stuff to go with that: #define CRM_TRACE_LEVEL(severity, section) (((severity) << 24) || ((section) & 0xFFF)) #define CRM_GET_TRACE_SECTION(code) ((code) & 0xFFF) #define CRM_GET_TRACE_SEVERITY(code) ((code) >> 24) ---------------------------- Error Handlers in libcrm114: ----------------------------------------- For error handlers, I had the idea to do exactly the same for them, using an error_callback hook + VMS severity levels a la the above, but your suggestion for using a OpenSSL-like error /stack/ is much nicer and does not preclude that: right now, nonfatalerror()+fatalerror()s get obscured by subsequent ones within the same statement, and using an error /stack/ would resolve that. C# and other folks would recognize that stuff as a stack trace / exception trace equivalent, which is _very_ handy for diagnosing trouble. However, I'd be OK with it if I had to 'do' that error stack 'on the outside': what I want for bare metal minimum is an error/warning/fatal abort-retry-panic callback like the above. Besides, talking about resources: I'd rather [help to] create this code then having to pick up some well meaning but sad code all over again, you know. (And yes, I still have to start work on that libcrm114 demo I was talking about last week, thanks to delays due to spurious failures -- well, you've probably seen my trails on the general and dev ML the last week; I moved off to dev because I felt it was really getting out of hand for 'general') -- Met vriendelijke groeten / Best regards, Ger Hobbelt -------------------------------------------------- web: http://www.hobbelt.com/ http://www.hebbut.net/ mail: [email protected] mobile: +31-6-11 120 978 -------------------------------------------------- ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/