1 #include <ncbi_pch.hpp>
2 
3 #include <string.h>
4 #include <time.h>
5 #include <sstream>
6 
7 #include <corelib/ncbiapp.hpp>
8 #include <corelib/ncbifile.hpp>
9 
10 #include "flatfile_message_reporter.hpp"
11 #include "ftaerr.hpp"
12 
13 #ifdef THIS_FILE
14 #    undef THIS_FILE
15 #endif
16 #define THIS_FILE "ftaerr.cpp"
17 
18 #define MESSAGE_DIR "/am/ncbiapdata/errmsg"
19 
20 
21 BEGIN_NCBI_SCOPE
22 USING_SCOPE(objects);
23 
24 typedef struct fta_err_context {
25     const char *module;
26     const char *fname;
27     int  line;
28 } FtaErrCode;
29 
30 typedef struct bsv_msg_mod_tag_ctx {
31     char                       *strsubtag;
32     int                        intsubtag;
33     int                        intseverity;
34     struct bsv_msg_mod_tag_ctx *next;
35 } FtaMsgModTagCtx;
36 
37 typedef struct bsv_msg_mod_tag {
38     char                   *strtag;
39     int                    inttag;
40     FtaMsgModTagCtx        *bmctx;
41     struct bsv_msg_mod_tag *next;
42 } FtaMsgModTag;
43 
44 typedef struct bsv_msg_mod_files {
45     char                     *modname;      /* NCBI_MODULE or THIS_MODULE
46                                                value */
47     char                     *filename;     /* Name with full path of .msg
48                                                file */
49     FtaMsgModTag             *bmmt;
50     struct bsv_msg_mod_files *next;
51 } FtaMsgModFiles;
52 
53 //typedef struct bsv_msg_post {
54 struct FtaMsgPost {
55     FILE               *lfd;            /* Opened logfile */
56     char               *logfile;        /* Logfile full name */
57     std::string         appname;
58     char               *prefix_accession;
59     char               *prefix_locus;
60     char               *prefix_feature;
61     bool               to_stderr;
62     bool               show_msg_codeline;
63     bool               show_log_codeline;
64     bool               show_msg_codes;
65     bool               show_log_codes;
66     bool               hook_only;
67     ErrSev             msglevel;        /* Filter out messages displaying on
68                                            stderr only: ignode those with
69                                            severity lower than msglevel */
70     ErrSev             loglevel;        /* Filter out messages displaying in
71                                            logfile only: ignode those with
72                                            severity lower than msglevel */
73     FtaMsgModFiles     *bmmf;
74 
FtaMsgPostFtaMsgPost75     FtaMsgPost() :
76         lfd(NULL),
77         logfile(NULL),
78         prefix_accession(NULL),
79         prefix_locus(NULL),
80         prefix_feature(NULL),
81         to_stderr(true),
82         show_msg_codeline(false),
83         show_log_codeline(false),
84         show_msg_codes(false),
85         show_log_codes(false),
86         hook_only(false),
87         msglevel(SEV_NONE),
88         loglevel(SEV_NONE),
89         bmmf(NULL)
90     {}
91 
~FtaMsgPostFtaMsgPost92     virtual ~FtaMsgPost() {
93         if (lfd) {
94             fclose(lfd);
95         }
96         if (logfile) {
97             free(logfile);
98         }
99         if (prefix_locus) {
100             free(prefix_locus);
101         }
102         if (prefix_accession) {
103             free(prefix_accession);
104         }
105         if (prefix_feature) {
106             free(prefix_feature);
107         }
108     };
109 };
110 //} FtaMsgPost;
111 
112 typedef struct fta_post_info {
113     const char *module;
114     char *severity;
115     char *strcode;
116     char *strsubcode;
117     char *buffer;
118     const char *fname;
119     int  sevcode;
120     int  intcode;
121     int  intsubcode;
122     int  line;
123 } FtaPostInfo;
124 
125 const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
126                         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
127 
128 FtaPostInfo fpi;
129 thread_local unique_ptr<FtaMsgPost>  bmp;
130 FtaErrCode  fec;
131 
132 /**********************************************************/
FtaStrSevToIntSev(char * strsevcode)133 static int FtaStrSevToIntSev(char *strsevcode)
134 {
135     if(!strsevcode)
136         return(-1);
137 
138     if(!strcmp(strsevcode, "SEV_INFO"))
139         return(1);
140     if(!strcmp(strsevcode, "SEV_WARNING"))
141         return(2);
142     if(!strcmp(strsevcode, "SEV_ERROR"))
143         return(3);
144     if(!strcmp(strsevcode, "SEV_REJECT"))
145         return(4);
146     if(!strcmp(strsevcode, "SEV_FATAL"))
147         return(5);
148     return(-1);
149 }
150 
151 /**********************************************************/
FtaErrGetMsgCodes(const char * module,int code,int subcode,char ** strcode,char ** strsubcode,int * sevcode)152 void FtaErrGetMsgCodes(const char *module, int code, int subcode,
153                        char **strcode, char **strsubcode,
154                        int *sevcode)
155 {
156     FtaMsgModTagCtx *bmctxp;
157     FtaMsgModFiles  *bmmfp;
158     FtaMsgModTag    *bmmtp;
159     FILE            *fd;
160     char            *val1;
161     char            *val3;
162     char            *buf;
163     char            *p;
164     char            *q;
165     char            s[2048];
166     char            ch;
167     bool            got_mod;
168     int             val2;
169 
170     if(!bmp)
171         FtaErrInit();
172 
173     for(got_mod = false, bmmfp = bmp->bmmf; bmmfp; bmmfp = bmmfp->next)
174     {
175         if(strcmp(bmmfp->modname, module))
176             continue;
177 
178         got_mod = true;
179         for(bmmtp = bmmfp->bmmt; bmmtp; bmmtp = bmmtp->next)
180         {
181             if(bmmtp->inttag != code)
182                 continue;
183 
184             *strcode = bmmtp->strtag;
185             for(bmctxp = bmmtp->bmctx; bmctxp; bmctxp = bmctxp->next)
186             {
187                 if(bmctxp->intsubtag != subcode)
188                     continue;
189 
190                 *strsubcode = bmctxp->strsubtag;
191                 *sevcode = bmctxp->intseverity;
192                 break;
193             }
194             break;
195         }
196         break;
197     }
198 
199     if(got_mod)
200         return;
201 
202     string curdir = CDir::GetCwd();
203 
204     buf = (char *) malloc(curdir.size() + strlen(module) + 6);
205     sprintf(buf, "%s/%s.msg", curdir.c_str(), module);
206 
207     fd = fopen(buf, "r");
208     if(!fd)
209     {
210         free(buf);
211         buf = (char *)malloc(strlen(MESSAGE_DIR) + strlen(module) + 6);
212         sprintf(buf, "%s/%s.msg", MESSAGE_DIR, module);
213 
214         fd = fopen(buf, "r");
215         if (!fd)
216         {
217             free(buf);
218             return;
219         }
220     }
221 
222     bmmfp = (FtaMsgModFiles *) calloc(1, sizeof(FtaMsgModFiles));
223     bmmfp->modname = (char *) malloc(strlen(module) + 1);
224     strcpy(bmmfp->modname, module);
225     bmmfp->filename = (char *) malloc(strlen(buf) + 1);
226     strcpy(bmmfp->filename, buf);
227     free(buf);
228 
229     if(bmp->bmmf)
230         bmmfp->next = bmp->bmmf;
231     bmp->bmmf = bmmfp;
232 
233     val2 = 0;
234     val1 = NULL;
235     val3 = NULL;
236     bmmtp = NULL;
237     while(fgets(s, 2047, fd))
238     {
239         if(s[0] != '$' || (s[1] != '^' && s[1] != '$'))
240             continue;
241 
242         val2 = 0;
243         val1 = NULL;
244         val3 = NULL;
245 
246         for(p = s + 2; *p == ' ' || *p == '\t'; p++);
247         for(q = p; *p && *p != ','; p++);
248         if(*p != ',')
249             continue;
250 
251         *p = '\0';
252         val1 = (char *) malloc(strlen(q) + 1);
253         strcpy(val1, q);
254 
255         for(*p++ = ','; *p == ' ' || *p == '\t'; p++);
256         for(q = p; *p >= '0' && *p <= '9'; p++);
257 
258         if(q == p)
259         {
260             free(val1);
261             continue;
262         }
263 
264         ch = *p;
265         *p = '\0';
266         val2 = atoi(q);
267         *p = ch;
268 
269         if(val2 < 1)
270         {
271             free(val1);
272             continue;
273         }
274 
275         if(s[1] == '^' && ch == ',')
276         {
277             for(p++; *p == ' ' || *p == '\t'; p++);
278             for(q = p;
279                 *p && *p != ' ' && *p != '\t' && *p != '\n' && *p != ','; p++);
280             if(p > q)
281             {
282                 ch = *p;
283                 *p = '\0';
284                 if(!strcmp(q, "SEV_INFO") || !strcmp(q, "SEV_WARNING") ||
285                    !strcmp(q, "SEV_ERROR") || !strcmp(q, "SEV_REJECT") ||
286                    !strcmp(q, "SEV_FATAL"))
287                 {
288                     val3 = (char *) malloc(strlen(q) + 1);
289                     strcpy(val3, q);
290                 }
291                 *p = ch;
292             }
293         }
294 
295         if(s[1] == '$')
296         {
297             bmmtp = (FtaMsgModTag *) calloc(1, sizeof(FtaMsgModTag));
298 
299             if(bmmfp->bmmt)
300                 bmmtp->next = bmmfp->bmmt;
301             bmmfp->bmmt = bmmtp;
302 
303             bmmtp->strtag = val1;
304             bmmtp->inttag = val2;
305             if(val2 == code && *strcode == NULL)
306                 *strcode = val1;
307 
308             if(val3)
309             {
310                 free(val3);
311                 val3 = NULL;
312             }
313 
314             continue;
315         }
316 
317         if(!bmmfp->bmmt || !bmmtp)
318         {
319             if(val1)
320                 free(val1);
321             if(val3)
322                 free(val3);
323             val2 = 0;
324             continue;
325         }
326 
327         bmctxp = (FtaMsgModTagCtx *) calloc(1, sizeof(FtaMsgModTagCtx));
328 
329         if(bmmtp->bmctx)
330             bmctxp->next = bmmtp->bmctx;
331         bmmtp->bmctx = bmctxp;
332 
333         bmctxp->strsubtag = val1;
334         bmctxp->intsubtag = val2;
335         bmctxp->intseverity = FtaStrSevToIntSev(val3);
336 
337         if(val3)
338         {
339             free(val3);
340             val3 = NULL;
341         }
342 
343         if(val2 == subcode && *strsubcode == NULL && *strcode != NULL)
344         {
345             *strsubcode = val1;
346             if(*sevcode < 0)
347                 *sevcode = bmctxp->intseverity;
348         }
349     }
350 
351     fclose(fd);
352 }
353 
354 /**********************************************************/
FtaIntSevToStrSev(int sevcode)355 static const char *FtaIntSevToStrSev(int sevcode)
356 {
357     if(sevcode < 1 || sevcode > 5)
358         return(NULL);
359 
360     if(sevcode == 1)
361         return("NOTE");
362     if(sevcode == 2)
363         return("WARNING");
364     if(sevcode == 3)
365         return("ERROR");
366     if(sevcode == 4)
367         return("REJECT");
368     return("FATAL ERROR");
369 }
370 
371 /**********************************************************/
FtaPostMessage(void)372 static void FtaPostMessage(void)
373 {
374     if(bmp->lfd && fpi.sevcode >= bmp->loglevel)
375     {
376         fprintf(bmp->lfd, "%s: ", fpi.severity);
377         if(bmp->show_log_codes)
378         {
379             if(fpi.module)
380                 fprintf(bmp->lfd, "%s ", fpi.module);
381             if(fpi.strcode)
382             {
383                 fprintf(bmp->lfd, "[%s", fpi.strcode);
384                 if(fpi.strsubcode)
385                     fprintf(bmp->lfd, ".%s] ", fpi.strsubcode);
386                 else
387                     fprintf(bmp->lfd, "] ");
388             }
389             else
390                 fprintf(bmp->lfd, "[%03d.%03d] ", fpi.intcode, fpi.intsubcode);
391         }
392 
393         if(bmp->show_log_codeline)
394             fprintf(bmp->lfd, "{%s, line %d} ", fpi.fname, fpi.line);
395         if(bmp->prefix_locus != NULL)
396             fprintf(bmp->lfd, "%s: ", bmp->prefix_locus);
397         if(bmp->prefix_accession != NULL)
398             fprintf(bmp->lfd, "%s: ", bmp->prefix_accession);
399         if(bmp->prefix_feature != NULL)
400             fprintf(bmp->lfd, "%s ", bmp->prefix_feature);
401         fprintf(bmp->lfd, "%s\n", fpi.buffer);
402     }
403 
404     if(bmp->to_stderr && fpi.sevcode >= bmp->msglevel)
405     {
406         fprintf(stderr, "[%s] %s: ", bmp->appname.c_str(), fpi.severity);
407         if(bmp->show_msg_codes)
408         {
409             if(fpi.module)
410                 fprintf(stderr, "%s ", fpi.module);
411             if(fpi.strcode)
412             {
413                 fprintf(stderr, "[%s", fpi.strcode);
414                 if(fpi.strsubcode)
415                     fprintf(stderr, ".%s] ", fpi.strsubcode);
416                 else
417                     fprintf(stderr, "] ");
418             }
419             else
420                 fprintf(stderr, "[%03d.%03d] ", fpi.intcode, fpi.intsubcode);
421         }
422 
423         if(bmp->show_msg_codeline)
424             fprintf(stderr, "{%s, line %d} ", fpi.fname, fpi.line);
425         else                            // Bug, just to match C Toolkit output:
426             fprintf(stderr, " ");
427         if(bmp->prefix_locus != NULL)
428             fprintf(stderr, "%s: ", bmp->prefix_locus);
429         if(bmp->prefix_accession != NULL)
430             fprintf(stderr, "%s: ", bmp->prefix_accession);
431         if(bmp->prefix_feature != NULL)
432             fprintf(stderr, "%s ", bmp->prefix_feature);
433         fprintf(stderr, "%s\n", fpi.buffer);
434     }
435 }
436 
437 /**********************************************************/
FtaErrInit()438 void FtaErrInit()
439 {
440     if(bmp)
441         return;
442 
443     bmp.reset(new FtaMsgPost());
444     bmp->appname = CNcbiApplication::GetAppName();
445 
446     fec.module = NULL;
447     fec.fname = NULL;
448     bmp->hook_only = false;
449     fec.line = -1;
450 }
451 
452 /**********************************************************/
FtaErrFini(void)453 void FtaErrFini(void)
454 {
455     if (bmp) {
456         bmp.reset();
457     }
458 }
459 
460 
461 /**********************************************************/
FtaInstallPrefix(int prefix,const char * name,const char * location)462 void FtaInstallPrefix(int prefix, const char *name, const char *location)
463 {
464     if(name == NULL || *name == '\0')
465         return;
466 
467     if((prefix & PREFIX_ACCESSION) == PREFIX_ACCESSION)
468     {
469         if(bmp->prefix_accession != NULL)
470            free(bmp->prefix_accession);
471         bmp->prefix_accession = (char *) malloc(strlen(name) + 1);
472         strcpy(bmp->prefix_accession, name);
473     }
474     if((prefix & PREFIX_LOCUS) == PREFIX_LOCUS)
475     {
476         if(bmp->prefix_locus != NULL)
477            free(bmp->prefix_locus);
478         bmp->prefix_locus = (char *) malloc(strlen(name) + 1);
479         strcpy(bmp->prefix_locus, name);
480     }
481     if((prefix & PREFIX_FEATURE) == PREFIX_FEATURE)
482     {
483         if(bmp->prefix_feature != NULL)
484            free(bmp->prefix_feature);
485         bmp->prefix_feature = (char *) malloc(160);
486         strcpy(bmp->prefix_feature, "FEAT=");
487         strncat(bmp->prefix_feature, name, 20);
488         bmp->prefix_feature[24] = '\0';
489         strcat(bmp->prefix_feature, "[");
490         strncat(bmp->prefix_feature, location, 127);
491         bmp->prefix_feature[152] = '\0';
492         strcat(bmp->prefix_feature, "]");
493     }
494 }
495 
496 /**********************************************************/
FtaDeletePrefix(int prefix)497 void FtaDeletePrefix(int prefix)
498 {
499     if((prefix & PREFIX_ACCESSION) == PREFIX_ACCESSION)
500     {
501         if(bmp->prefix_accession != NULL)
502            free(bmp->prefix_accession);
503         bmp->prefix_accession = NULL;
504     }
505     if((prefix & PREFIX_LOCUS) == PREFIX_LOCUS)
506     {
507         if(bmp->prefix_locus != NULL)
508            free(bmp->prefix_locus);
509         bmp->prefix_locus = NULL;
510     }
511     if((prefix & PREFIX_FEATURE) == PREFIX_FEATURE)
512     {
513         if(bmp->prefix_feature != NULL)
514            free(bmp->prefix_feature);
515         bmp->prefix_feature = NULL;
516     }
517 }
518 
519 /**********************************************************/
ErrSetLog(const char * logfile)520 bool ErrSetLog(const char *logfile)
521 {
522     struct tm *tm;
523     time_t    now;
524     int       i;
525 
526     if(!logfile || !*logfile)
527         return(false);
528 
529     if(!bmp)
530         FtaErrInit();
531 
532     if(!bmp->logfile)
533     {
534         bmp->logfile = (char *) malloc(strlen(logfile) + 1);
535         strcpy(bmp->logfile, logfile);
536     }
537 
538     if(!bmp->lfd && bmp->logfile)
539     {
540         time(&now);
541         tm = localtime(&now);
542         i = tm->tm_hour % 12;
543         if(!i)
544             i = 12;
545 
546         bmp->lfd = fopen(bmp->logfile, "a");
547         fprintf(bmp->lfd,
548                 "\n========================[ %s %d, %d %2d:%02d %s ]========================\n",
549                 months[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900,
550                 i, tm->tm_min, (tm->tm_hour >= 12) ? "PM" : "AM");
551     }
552 
553     return(true);
554 }
555 
556 /**********************************************************/
ErrSetFatalLevel(ErrSev sev)557 void ErrSetFatalLevel(ErrSev sev)
558 {
559 }
560 
561 /**********************************************************/
ErrSetOptFlags(int flags)562 void ErrSetOptFlags(int flags)
563 {
564     if(!bmp)
565         FtaErrInit();
566 
567     if((flags & EO_MSG_CODES) == EO_MSG_CODES)
568         bmp->show_msg_codes = true;
569     if((flags & EO_LOG_CODES) == EO_LOG_CODES)
570         bmp->show_log_codes = true;
571     if((flags & EO_MSG_FILELINE) == EO_MSG_FILELINE)
572         bmp->show_msg_codeline = true;
573     if((flags & EO_LOG_FILELINE) == EO_LOG_FILELINE)
574         bmp->show_log_codeline = true;
575 }
576 
577 /**********************************************************/
ErrClear(void)578 void ErrClear(void)
579 {
580 }
581 
582 /**********************************************************/
ErrLogPrintStr(const char * str)583 void ErrLogPrintStr(const char *str)
584 {
585     if(str == NULL || str[0] == '\0')
586         return;
587 
588     if(!bmp)
589         FtaErrInit();
590 
591     fprintf(bmp->lfd, "%s", str);
592 }
593 
594 /**********************************************************/
ErrSetLogLevel(ErrSev sev)595 ErrSev ErrSetLogLevel(ErrSev sev)
596 {
597     ErrSev prev;
598 
599     if(!bmp)
600         FtaErrInit();
601 
602     prev = bmp->loglevel;
603     bmp->loglevel = sev;
604     return(prev);
605 }
606 
607 /**********************************************************/
ErrSetMessageLevel(ErrSev sev)608 ErrSev ErrSetMessageLevel(ErrSev sev)
609 {
610     ErrSev prev;
611 
612     if(!bmp)
613         FtaErrInit();
614 
615     prev = bmp->msglevel;
616     bmp->msglevel = sev;
617     return(prev);
618 }
619 
620 /**********************************************************/
Nlm_ErrSetContext(const char * module,const char * fname,int line)621 int Nlm_ErrSetContext(const char *module, const char *fname, int line)
622 {
623     if(!bmp)
624         FtaErrInit();
625 
626     fec.module = module;
627     fec.fname = fname;
628     fec.line = line;
629     return(0);
630 }
631 
632 /**********************************************************/
ErrCToCxxSeverity(int c_severity)633 EDiagSev ErrCToCxxSeverity(int c_severity)
634 {
635     EDiagSev cxx_severity;
636 
637     switch(c_severity)
638     {
639     case SEV_NONE:
640         cxx_severity = eDiag_Trace;
641         break;
642     case SEV_INFO:
643         cxx_severity = eDiag_Info;
644         break;
645     case SEV_WARNING:
646         cxx_severity = eDiag_Warning;
647         break;
648     case SEV_ERROR:
649         cxx_severity = eDiag_Error;
650         break;
651     case SEV_REJECT:
652         cxx_severity = eDiag_Critical;
653         break;
654     case SEV_FATAL:
655     default:
656         cxx_severity = eDiag_Fatal;
657         break;
658     }
659     return(cxx_severity);
660 }
661 
662 /**********************************************************/
FtaErrHandler(void)663 static void FtaErrHandler(void)
664 {
665     try
666     {
667         CNcbiDiag diag(ErrCToCxxSeverity(fpi.sevcode));
668 
669         if(fpi.fname)
670             diag.SetFile(fpi.fname);
671         if(fpi.line)
672             diag.SetLine(fpi.line);
673         if(fpi.module)
674             diag.SetModule(fpi.module);
675         diag.SetErrorCode(fpi.intcode, fpi.intsubcode);
676 
677         if(fpi.strcode)
678         {
679             diag << fpi.strcode;
680             if(fpi.strsubcode)
681             {
682                 diag << '.';
683                 diag << fpi.strsubcode;
684             }
685         }
686 
687         if(bmp->prefix_accession)
688         {
689             diag << ' ';
690             diag << bmp->prefix_accession;
691         }
692         if(bmp->prefix_locus)
693         {
694             diag << ' ';
695             diag << bmp->prefix_locus;
696         }
697         if(bmp->prefix_feature)
698         {
699             diag << ' ';
700             diag << bmp->prefix_feature;
701         }
702 
703         if(fpi.buffer)
704         {
705             diag << ' ';
706             diag << fpi.buffer;
707         }
708 
709         diag << Endm;
710     }
711     catch(...)
712     {
713         _ASSERT(0);
714     }
715 }
716 
717 /**********************************************************/
Nlm_ErrPostEx(ErrSev sev,int lev1,int lev2,const char * fmt,...)718 void Nlm_ErrPostEx(ErrSev sev, int lev1, int lev2, const char *fmt, ...)
719 {
720 
721     if(!bmp)
722         FtaErrInit();
723 
724 
725     if(fec.fname == NULL || fec.line < 0)
726     {
727         fec.module = NULL;
728         fec.fname = NULL;
729         fec.line = -1;
730         return;
731     }
732 
733     va_list args;
734     char    buffer[1024];
735     va_start(args, fmt);
736     vsnprintf(buffer, 1024, fmt, args);
737     va_end(args);
738 
739     fpi.buffer = buffer;
740     fpi.sevcode = -1;
741     fpi.strcode = NULL;
742     fpi.strsubcode = NULL;
743 
744     fpi.intcode = lev1;
745     fpi.intsubcode = lev2;
746 
747     fpi.line = fec.line;
748     fpi.fname = fec.fname;
749     fpi.module = fec.module;
750 
751     fec.module = NULL;
752     fec.fname = NULL;
753     fec.line = -1;
754 
755     if(fpi.module && *fpi.module)
756         FtaErrGetMsgCodes(fpi.module, fpi.intcode, fpi.intsubcode,
757                           &fpi.strcode, &fpi.strsubcode, &fpi.sevcode);
758     else
759         fpi.module = NULL;
760 
761     if(fpi.sevcode < 0)
762         fpi.sevcode = (int) sev;
763     fpi.severity = (char *) FtaIntSevToStrSev(fpi.sevcode);
764 
765     if(bmp->appname.empty())
766         bmp->appname = CNcbiApplication::GetAppName();
767 /*
768     if(bmp->hook_only)
769         FtaErrHandler();
770     else
771         FtaPostMessage();
772 */
773     stringstream textStream;
774     if (fpi.strcode) {
775         textStream << "[" << fpi.strcode;
776         if (fpi.strsubcode) {
777             textStream << "." << fpi.strsubcode;
778         }
779         textStream << "] ";
780     }
781 
782     if (bmp->show_log_codeline) {
783         textStream << "{" << fpi.fname << ", line " << fpi.line;
784     }
785     if (bmp->prefix_locus) {
786         textStream << bmp->prefix_locus << ": ";
787     }
788     if (bmp->prefix_accession) {
789         textStream << bmp->prefix_accession << ": ";
790     }
791     if (bmp->prefix_feature) {
792         textStream << bmp->prefix_feature << " ";
793     }
794     textStream << fpi.buffer;
795 
796     static const map<ErrSev, EDiagSev> sSeverityMap
797        =  {{SEV_NONE , eDiag_Trace},
798           {SEV_INFO , eDiag_Info},
799           {SEV_WARNING , eDiag_Warning},
800           {SEV_ERROR , eDiag_Error},
801           {SEV_REJECT , eDiag_Critical},
802           {SEV_FATAL , eDiag_Fatal}};
803 
804     CFlatFileMessageReporter::GetInstance()
805         .Report(fpi.module ? fpi.module : "",
806                 sSeverityMap.at(static_cast<ErrSev>(fpi.sevcode)),
807                 lev1, lev2, textStream.str());
808 }
809 
810 /**********************************************************/
Nlm_ErrPostStr(ErrSev sev,int lev1,int lev2,const char * str)811 void Nlm_ErrPostStr(ErrSev sev, int lev1, int lev2, const char *str)
812 {
813     Nlm_ErrPostEx(sev, lev1, lev2, str);
814 }
815 
816 /**********************************************************/
817 
818 END_NCBI_SCOPE
819