blob: 406e993b7517af37009f529cdf1dc2e3b53b497e [file] [log] [blame]
Ed Tanous50c50c22017-05-12 16:58:06 -07001/** ==========================================================================
2 * 2013 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
3 * with no warranties. This code is yours to share, use and modify with no
4 * strings attached and no restrictions or obligations.
5 *
6 * For more information see g3log/LICENSE or refer refer to http://unlicense.org
7 * ============================================================================*/
8
9#pragma once
10
11
12#include <memory>
13#include <string>
14#include <algorithm>
15#include <iostream>
16#include <fstream>
17#include <sstream>
18#include <string>
19
20
21namespace g3 {
22 namespace internal {
23 static const std::string file_name_time_formatted = "%Y%m%d-%H%M%S";
24
25 // check for filename validity - filename should not be part of PATH
26 bool isValidFilename(const std::string &prefix_filename) {
27 std::string illegal_characters("/,|<>:#$%{}[]\'\"^!?+* ");
28 size_t pos = prefix_filename.find_first_of(illegal_characters, 0);
29 if (pos != std::string::npos) {
30 std::cerr << "Illegal character [" << prefix_filename.at(pos) << "] in logname prefix: " << "[" << prefix_filename << "]" << std::endl;
31 return false;
32 } else if (prefix_filename.empty()) {
33 std::cerr << "Empty filename prefix is not allowed" << std::endl;
34 return false;
35 }
36
37 return true;
38 }
39
40 std::string prefixSanityFix(std::string prefix) {
41 prefix.erase(std::remove_if(prefix.begin(), prefix.end(), ::isspace), prefix.end());
42 prefix.erase(std::remove(prefix.begin(), prefix.end(), '/'), prefix.end());
43 prefix.erase(std::remove(prefix.begin(), prefix.end(), '\\'), prefix.end());
44 prefix.erase(std::remove(prefix.begin(), prefix.end(), '.'), prefix.end());
45 prefix.erase(std::remove(prefix.begin(), prefix.end(), ':'), prefix.end());
46 if (!isValidFilename(prefix)) {
47 return
48 {
49 };
50 }
51 return prefix;
52 }
53
54 std::string pathSanityFix(std::string path, std::string file_name) {
55 // Unify the delimeters,. maybe sketchy solution but it seems to work
56 // on at least win7 + ubuntu. All bets are off for older windows
57 std::replace(path.begin(), path.end(), '\\', '/');
58
59 // clean up in case of multiples
60 auto contains_end = [&](std::string & in) -> bool {
61 size_t size = in.size();
62 if (!size) return false;
63 char end = in[size - 1];
64 return (end == '/' || end == ' ');
65 };
66
67 while (contains_end(path)) {
68 path.erase(path.size() - 1);
69 }
70
71 if (!path.empty()) {
72 path.insert(path.end(), '/');
73 }
74
75 path.insert(path.size(), file_name);
76 return path;
77 }
78
79 std::string header() {
80 std::ostringstream ss_entry;
81 // Day Month Date Time Year: is written as "%a %b %d %H:%M:%S %Y" and formatted output as : Wed Sep 19 08:28:16 2012
82 ss_entry << "\t\tg3log created log at: " << g3::localtime_formatted(g3::systemtime_now(), "%a %b %d %H:%M:%S %Y") << "\n";
83 ss_entry << "\t\tLOG format: [YYYY/MM/DD hh:mm:ss uuu* LEVEL FILE->FUNCTION:LINE] message";
84 ss_entry << "\t\t(uuu*: microseconds fractions of the seconds value)\n\n";
85 return ss_entry.str();
86 }
87
88 std::string createLogFileName(const std::string &verified_prefix, const std::string &logger_id) {
89 std::stringstream oss_name;
90 oss_name << verified_prefix << ".";
91 if( logger_id != "" ) oss_name << logger_id << ".";
92 oss_name << g3::localtime_formatted(g3::systemtime_now(), file_name_time_formatted);
93 oss_name << ".log";
94 return oss_name.str();
95 }
96
97 bool openLogFile(const std::string &complete_file_with_path, std::ofstream &outstream) {
98 std::ios_base::openmode mode = std::ios_base::out; // for clarity: it's really overkill since it's an ofstream
99 mode |= std::ios_base::trunc;
100 outstream.open(complete_file_with_path, mode);
101 if (!outstream.is_open()) {
102 std::ostringstream ss_error;
103 ss_error << "FILE ERROR: could not open log file:[" << complete_file_with_path << "]";
104 ss_error << "\n\t\t std::ios_base state = " << outstream.rdstate();
105 std::cerr << ss_error.str().c_str() << std::endl;
106 outstream.close();
107 return false;
108 }
109 return true;
110 }
111
112 std::unique_ptr<std::ofstream> createLogFile(const std::string &file_with_full_path) {
113 std::unique_ptr<std::ofstream> out(new std::ofstream);
114 std::ofstream &stream(*(out.get()));
115 bool success_with_open_file = openLogFile(file_with_full_path, stream);
116 if (false == success_with_open_file) {
117 out.release();
118 }
119 return out;
120 }
121
122
123 }
124}