]> cygwin.com Git - cygwin-apps/setup.git/blob - LogFile.cc
2002-05-12 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / LogFile.cc
1 /*
2 * Copyright (c) 2002, Robert Collins.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16 /* Log to one or more files. */
17
18 #if 0
19 static const char *cvsid =
20 "\n%%% $Id$\n";
21 #endif
22
23 #include "LogFile.h"
24 #include "io_stream.h"
25 #include "win32.h"
26 #include "list.h"
27 #include "msg.h"
28 #include "resource.h"
29 #include <iostream>
30 #include <strstream>
31 #include <time.h>
32 #include <string>
33
34 /* private helper class */
35 class filedef
36 {
37 public:
38 int level;
39 String key;
40 bool append;
41 };
42
43 /* another */
44 struct LogEnt
45 {
46 LogEnt *next;
47 enum log_level level;
48 time_t when;
49 String msg;
50 };
51
52 static LogEnt *first_logent = 0;
53 static LogEnt **next_logent = &first_logent;
54 static LogEnt *currEnt = 0;
55 int exit_msg = 0;
56
57 static list<filedef, String, String::casecompare> files;
58 static ostrstream *theStream;
59
60 LogFile::LogFile()
61 {
62 theStream = new ostrstream;
63 rdbuf (theStream->rdbuf());
64 }
65 LogFile::~LogFile(){}
66
67 void
68 LogFile::clearFiles ()
69 {
70 while (files.number())
71 {
72 filedef *f = files.removebyindex(1);
73 delete f;
74 }
75 }
76
77 void
78 LogFile::setFile (int minlevel, String const &path, bool append)
79 {
80 filedef *f = files.getbykey (path);
81 if (!f)
82 {
83 f = new filedef;
84 f->key = path;
85 files.registerbyobject (*f);
86 }
87 f->level = minlevel;
88 f->append = append;
89 }
90
91 void
92 LogFile::exit (int const exit_code)
93 {
94 static int been_here = 0;
95 if (been_here)
96 #ifndef _CYGWIN_
97 ExitProcess (1);
98 #else
99 exit (1);
100 #endif
101 been_here = 1;
102
103 if (exit_msg)
104 note (NULL, exit_msg);
105
106 log (LOG_TIMESTAMP) << "Ending cygwin install" << endLog;
107
108 for (unsigned int i = 1; i <= files.number(); ++i)
109 {
110 filedef *f = files[i];
111 log_save (f->level, f->key, f->append);
112 }
113 #ifndef _CYGWIN_
114 ExitProcess (exit_code);
115 #else
116 exit (1);
117 #endif
118 }
119
120 void
121 LogFile::log_save (int babble, String const &filename, bool append)
122 {
123 static int been_here = 0;
124 if (been_here)
125 return;
126 been_here = 1;
127
128 io_stream::mkpath_p (PATH_TO_FILE, String("file://") + filename);
129
130 io_stream *f = io_stream::open(String("file://") + filename, append ? "at" : "wt");
131 if (!f)
132 {
133 fatal (NULL, IDS_NOLOGFILE, filename.cstr_oneuse());
134 return;
135 }
136
137 LogEnt *l;
138
139 for (l = first_logent; l; l = l->next)
140 {
141 if (babble || !(l->level == LOG_BABBLE))
142 {
143 char *tstr = l->msg.cstr();
144 f->write (tstr, strlen (tstr));
145 if (tstr[strlen (tstr) - 1] != '\n')
146 f->write ("\n", 1);
147 }
148 }
149
150 delete f;
151 been_here = 0;
152 }
153
154 ostream &
155 LogFile::operator() (log_level theLevel)
156 {
157 if (theLevel < 1 || theLevel > 2)
158 throw "barfoo";
159 if (!theStream)
160 theStream = new ostrstream;
161 rdbuf (theStream->rdbuf());
162 currEnt = new LogEnt;
163 currEnt->next = 0;
164 currEnt->level = theLevel;
165 return *this;
166 }
167
168 void
169 LogFile::endEntry()
170 {
171 if (!currEnt)
172 {
173 /* get a default LogEnt */
174 currEnt = new LogEnt;
175 currEnt->next = 0;
176 currEnt->level = LOG_PLAIN;
177 }
178 *next_logent = currEnt;
179 next_logent = &(currEnt->next);
180 time (&(currEnt->when));
181 if (currEnt->level == LOG_TIMESTAMP)
182 {
183 char b[100];
184 struct tm *tm = localtime (&(currEnt->when));
185 strftime (b, 1000, "%Y/%m/%d %H:%M:%S ", tm);
186 currEnt->msg = b;
187 }
188 /* What follows is a hack to get around an (apparent) bug in libg++-3 with
189 * non-0 memory on alloc
190 */
191 currEnt->msg += string(theStream->str()).substr(0,theStream->pcount()).c_str();
192 msg ("LOG: %d %s", currEnt->level, string(theStream->str()).substr(0,theStream->rdbuf()->pcount()).c_str());
193 theStream->freeze(0);
194 delete theStream;
195 /* reset for next use */
196 theStream = new ostrstream;
197 rdbuf (theStream->rdbuf());
198 init (theStream->rdbuf());
199 }
This page took 0.098477 seconds and 5 git commands to generate.