1 /* Copyright (C) 2021 J.F.Dockes
2  *
3  * License: GPL 2.1
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2.1 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the
17  * Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include "autoconfig.h"
22 
23 #include <stdio.h>
24 #include <mutex>
25 
26 #include "idxdiags.h"
27 
28 static std::mutex diagmutex;
29 
30 class IdxDiags::Internal {
31 public:
~Internal()32     ~Internal() {
33         if (fp) {
34             fclose(fp);
35         }
36     }
37     FILE *fp{nullptr};
38 };
39 
IdxDiags()40 IdxDiags::IdxDiags()
41 {
42     m = new Internal;
43 }
44 
~IdxDiags()45 IdxDiags::~IdxDiags()
46 {
47     delete m;
48 }
49 
flush()50 bool IdxDiags::flush()
51 {
52     std::unique_lock<std::mutex> lock(diagmutex);
53     if (m && m->fp) {
54         return fflush(m->fp) ? false : true;
55     }
56     return true;
57 }
58 
59 static IdxDiags *theInstance;
60 
theDiags()61 IdxDiags& IdxDiags::theDiags()
62 {
63     if (nullptr == theInstance) {
64         theInstance = new IdxDiags;
65     }
66     return *theInstance;
67 }
68 
init(const std::string & outpath)69 bool IdxDiags::init(const std::string& outpath)
70 {
71     m->fp = fopen(outpath.c_str(), "w");
72     if (nullptr == m->fp) {
73         return false;
74     }
75     return true;
76 }
77 
record(DiagKind diag,const std::string & path,const std::string & detail)78 bool IdxDiags::record(DiagKind diag, const std::string& path, const std::string& detail)
79 {
80     if (nullptr == m || nullptr == m->fp || (path.empty() && detail.empty())) {
81         return true;
82     }
83     const char *skind = "Unknown";
84     switch (diag) {
85     case Ok: skind = "Ok";break;
86     case Skipped: skind = "Skipped";break;
87     case NoContentSuffix: skind = "NoContentSuffix";break;
88     case MissingHelper: skind = "MissingHelper";break;
89     case Error: skind = "Error";break;
90     case NoHandler: skind = "NoHandler";break;
91     case ExcludedMime: skind = "ExcludedMime";break;
92     case NotIncludedMime: skind = "NotIncludedMime";break;
93     }
94 
95     std::unique_lock<std::mutex> lock(diagmutex);
96     fprintf(m->fp, "%s %s | %s\n", skind, path.c_str(), detail.c_str());
97     return true;
98 }
99