diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/sam2p/error.cpp |
Initial commit
Diffstat (limited to 'graphics/sam2p/error.cpp')
-rw-r--r-- | graphics/sam2p/error.cpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/graphics/sam2p/error.cpp b/graphics/sam2p/error.cpp new file mode 100644 index 0000000000..c5da52d517 --- /dev/null +++ b/graphics/sam2p/error.cpp @@ -0,0 +1,198 @@ +/* + * error.cpp + * by pts@fazekas.hu at Fri Mar 1 11:46:27 CET 2002 + * added policies at Sat Sep 7 18:28:30 CEST 2002 + */ + +#ifdef __GNUC__ +#ifndef __clang__ +#pragma implementation +#endif +#endif + +#include "error.hpp" +#include "gensio.hpp" +#include <stdio.h> +#include <stdlib.h> /* exit() */ +#include <string.h> /* strlen() */ +#if _MSC_VER > 1000 +# include "windows.h" /* ExitThread() */ +#endif + +char const* Error::argv0=(char const*)NULLP; +char const* Error::long_argv0=(char const*)NULLP; +char const* Error::banner0=(char const*)NULLP; +char const* Error::tmpargv0=(char const*)"pRg_tMp"; + +static Filter::NullE devNull; +Files::FILEW serr_default(stderr); +GenBuffer::Writable * Error::serr = &serr_default; +static Error::Policy defaultPolicy={ + (SimBuffer::B*)NULLP, /* record */ + (Error::level_t)-9999, /* topSecret */ + (Error::level_t)-9999, /* topRecorded */ + (Error::level_t)0, /* killer (level>=0) */ + (Error::level_t)-99, /* printed */ + (Error::level_t)-199, /* recorded */ + Error::serr, /* err */ + (Error::Policy*)NULLP, /* prev */ + (Error::Policy*)NULLP, /* next */ + (Error::level_t)-9999, /* curlev */ +}; +Error::Policy *Error::policy_top=&defaultPolicy, *Error::policy_bottom=&defaultPolicy; + +char const*Error::level2str(level_t level) { + return level==ASSERT ? "failed_assertion" : /* Imp: make assert() produce this */ + level==FATAL ? "Fatal Error" : + level==ERROR_CONT ? "Error" : + level==EERROR ? "Error" : + level==WARNING_DEFER ? "Warning" : + level==WARNING ? "Warning" : + level==NOTICE ? "Notice" : + level==NOTICE_DEFER ? "Notice" : + level==INFO ? "Info" : + level==DEBUG ? "DEBUG" : + "??level" ; +} + +GenBuffer::Writable& Error::sev(level_t level) { + /* So they are trying to make an error? Let's see whether they can. */ + GenBuffer::Writable *err=policy_top->err; + // printf("curlev=%d\n", policy_top->curlev); + assert(policy_top->curlev==-9999 && "nested error/ unfinished prev err"); + policy_top->curlev=level; + /* printf("level=%d\n", level); */ + if (level>=policy_top->printed) { /* printed or killer */ + #if 0 /* Disables printing of "using template: " */ + /* vvv Delay printing this message after all recorded messages */ + if (policy_top->record!=NULLP) err=policy_top->record; + #endif + } else if (level>=policy_top->recorded) { /* recorded */ + if (NULLP==(err=policy_top->record)) err=policy_top->record=new SimBuffer::B(); + if (level>policy_top->topRecorded) policy_top->topRecorded=level; + } else { /* secret */ + if (level>policy_top->topSecret) policy_top->topSecret=level; + return devNull; + } + return *err << (argv0==(char const*)NULLP?"??argv0":argv0) << ": " << level2str(level) << ": "; + /* Processing will continue soon by GenBuffer::Writable& operator <<(GenBuffer::Writable& gb,Error*) */ +} + +GenBuffer::Writable& operator <<(GenBuffer::Writable& err,Error*) { + err << '\n'; + Error::level_t level=Error::policy_top->curlev; + if (level>=Error::policy_top->killer) { /* killer */ + /* Also print recorded messages throughout the the policy stack */ + Error::Policy *p=Error::policy_bottom; + while (p!=NULLP) { + if (NULLP!=p->record) Error::policy_top->err->vi_write(p->record->begin_(), p->record->getLength()); + p=p->next; + } + // if (level>=Error::policy_top->killer) + Error::cexit(level); + } + /* Note that the order of error messages might be scrambled, i.e `printed' + * is printed before `recorded'. + */ + Error::policy_top->curlev=(Error::level_t)-9999; /* pedantic but useless because of nesting */ + return err; +} + +void Error::pushPolicy(level_t killer_, level_t printed_, level_t recorded_, GenBuffer::Writable *err) { + Policy *p=new Policy(); + p->record=(SimBuffer::B*)NULLP; + p->topSecret=p->topRecorded=(Error::level_t)-9999; + p->killer=killer_; + p->printed=printed_; + p->recorded=recorded_; + p->err=(err==NULLP) ? policy_top->err : err; + p->prev=policy_top; + p->next=(Policy*)NULLP; + policy_top=p->prev->next=p; + p->curlev=(Error::level_t)-9999; /* pedantic but useless because of nesting */ +} + +SimBuffer::B *Error::getRecorded() { + SimBuffer::B *ret=policy_top->record; + policy_top->record=(SimBuffer::B*)NULLP; + return ret; +} + +void Error::setTopPrinted(level_t printed_) { + policy_top->printed=printed_; +} + +Error::level_t Error::getTopPrinted() { return policy_top->printed; } + +void Error::popPolicy() { + if (policy_top==policy_bottom) { + Error::sev(Error::ASSERT) << "popPolicy: underflow" << (Error*)0; + } else { + if (NULLP!=policy_top->record) { + (*Error::policy_top->err) << "-- recorded messages:\n"; + Error::policy_top->err->vi_write(policy_top->record->begin_(), policy_top->record->getLength()); + delete policy_top->record; + } + policy_top=policy_top->prev; + delete policy_top->next; + policy_top->next=(Policy*)NULLP; + } +} + +/* --- */ + +Error::Cleanup *Error::first_cleanup=(Error::Cleanup*)NULLP; + +int Error::runCleanups(int exitCode) { + /* Flush buffered messages and revert to the default policy so subsequent + * errors can be logged. + */ + while (policy_top != policy_bottom) + popPolicy(); + + Cleanup *next; + int exit2; + while (first_cleanup!=NULLP) { + // fprintf(stderr, "hand %p\n", first_cleanup); + if (exitCode<(exit2=first_cleanup->handler(first_cleanup))) exitCode=exit2; + next=first_cleanup->next; + /* Allocated from as an array of char (to make space for + * first_cleanup->getBuf()), but has no destructors. + */ + delete [] (char*)first_cleanup; + first_cleanup=next; + } + return exitCode; +} + +void Error::cexit(int exitCode) { + #if _MSC_VER > 1000 + ExitThread(exitCode); + #else + exit(exitCode); /* <stdlib.h> */ + #endif +} + +Error::Cleanup* Error::newCleanup(Error::Cleanup::handler_t handler, void *data, slen_t bufSize) { + param_assert(handler!=0); + // slen_t num_packets=(bufSize+sizeof(Cleanup)-1)/sizeof(Cleanup); + Cleanup *new_=(Cleanup*)new char[bufSize+sizeof(Cleanup)]; /* new Cleanup[1+num_packets]; */ + /* ^^^ should be a new Cleanup + new char[bufSize]; now we can avoid alignment + * problems + */ + new_->handler=handler; + new_->bufSize=bufSize; + new_->data=data; + new_->next=first_cleanup; + first_cleanup=new_; + return new_; +} + +Error::Cleanup* Error::newCleanup(Error::Cleanup::handler_t handler, void *data, char const*bufCstr) { + const slen_t bufSize=strlen(bufCstr)+1; + Cleanup *new_=newCleanup(handler, data, bufSize); + memcpy(new_->getBuf(), bufCstr, bufSize); + return new_; +} + +/* __END__ */ |