]> cygwin.com Git - cygwin-apps/setup.git/blame - LogFile.cc
2002-05-12 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / LogFile.cc
CommitLineData
9f4a0c62
RC
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
19static 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>
74617327 32#include <string>
9f4a0c62
RC
33
34/* private helper class */
35class filedef
36{
37public:
38 int level;
39 String key;
40 bool append;
41};
42
43/* another */
44struct LogEnt
45{
46 LogEnt *next;
47 enum log_level level;
48 time_t when;
49 String msg;
50};
51
52static LogEnt *first_logent = 0;
53static LogEnt **next_logent = &first_logent;
54static LogEnt *currEnt = 0;
55int exit_msg = 0;
56
57static list<filedef, String, String::casecompare> files;
58static ostrstream *theStream;
59
60LogFile::LogFile()
61{
62 theStream = new ostrstream;
63 rdbuf (theStream->rdbuf());
64}
65LogFile::~LogFile(){}
66
67void
68LogFile::clearFiles ()
69{
70 while (files.number())
71 {
72 filedef *f = files.removebyindex(1);
73 delete f;
74 }
75}
76
77void
78LogFile::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
91void
92LogFile::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
120void
121LogFile::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
154ostream &
155LogFile::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
168void
169LogFile::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 }
74617327
RC
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());
9f4a0c62
RC
193 theStream->freeze(0);
194 delete theStream;
195 /* reset for next use */
196 theStream = new ostrstream;
197 rdbuf (theStream->rdbuf());
74617327 198 init (theStream->rdbuf());
9f4a0c62 199}
This page took 0.040258 seconds and 5 git commands to generate.