-
Notifications
You must be signed in to change notification settings - Fork 1
/
logmerge.cpp
141 lines (120 loc) · 3.19 KB
/
logmerge.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* Copyright (c) 2002 Dustin Sallings <dustin@spy.net>
*/
#include <iostream>
#include <string.h>
#include <unistd.h>
#ifdef USE_ASSERT
# include <assert.h>
#else
# undef assert
# define assert(a)
#endif
#include "logfiles.h"
#define STDOUT_BUF_SIZE 1024*1024
namespace logmerge {
static void initLogfiles(log_queue&, int, char **);
static void outputLogfiles(log_queue&);
static void initLogfile(log_queue&, const char*);
static void skipRecord(log_queue &queue);
}
/**
* Get rid of the first entry in the log list, and reinsert it somewhere
* that makes sense, or throw it away if it's no longer necessary.
*/
static void logmerge::skipRecord(log_queue &queue)
{
assert(!queue.empty());
LogFile *oldEntry=queue.top();
assert(oldEntry);
queue.pop();
/* If stuff comes back, reinsert the old entry */
if(oldEntry->nextLine()) {
queue.push(oldEntry);
} else {
delete oldEntry;
}
}
static void logmerge::initLogfile(log_queue& queue, const char *filename) {
try {
LogFile *lf=new LogFile(filename);
queue.push(lf);
} catch(LogfileError e) {
std::cerr << "*** Error initializing ``" << filename << "'': " << e.what()
<< std::endl;
}
}
/* Initialize all of the logfiles */
static void logmerge::initLogfiles(log_queue& queue, int argc, char **argv)
{
if(argc>1) {
for(int i=1; i<argc; i++) {
initLogfile(queue, argv[i]);
}
} else {
char buf[8192];
if (isatty(STDIN_FILENO)) {
std::cerr << "No logfiles given, accepting list from stdin"
<< std::endl;
}
while(fgets((char*)&buf, sizeof(buf)-1, stdin)) {
buf[strlen(buf)-1]=0x00;
initLogfile(queue, buf);
}
}
}
static void logmerge::outputLogfiles(log_queue& queue)
{
int entries=0;
while(!queue.empty()) {
entries++;
LogFile *lf=queue.top();
assert(lf);
lf->writeLine();
skipRecord(queue);
}
std::cerr << "Read " << entries << " entries" << std::endl;
}
#ifdef USE_ASSERT
static void testMonthParsing() {
const char *months[] = {
"Jan/", "Feb/", "Mar/", "Apr/", "May/", "Jun/",
"Jul/", "Aug/", "Sep/", "Oct/", "Nov/", "Dec/"
};
for(int i=0; i<12; i++) {
for(int j=0; j<10; j++) {
int rv=parseMonth(months[i]);
if(i != rv) {
std::cerr << "Expected " << i << " for "
<< months[i] << " got " << rv << std::endl;
abort();
}
}
}
for(int j=0; j<10; j++) {
for(int i=0; i<12; i++) {
int rv=parseMonth(months[i]);
if(i != rv) {
std::cerr << "Expected " << i << " for "
<< months[i] << " got " << rv << std::endl;
abort();
}
}
}
}
#else
static void testMonthParsing() {
}
#endif
/**
* The main.
*/
int main(int argc, char **argv)
{
log_queue queue;
testMonthParsing();
setvbuf(stdout, NULL, _IOFBF, STDOUT_BUF_SIZE);
logmerge::initLogfiles(queue, argc, argv);
logmerge::outputLogfiles(queue);
return(0);
}