~ubuntu-branches/debian/wheezy/gource/wheezy

« back to all changes in this revision

Viewing changes to src/commitlog.cpp

  • Committer: Package Import Robot
  • Author(s): Andrew Caudwell
  • Date: 2012-04-24 11:25:45 UTC
  • mfrom: (1.2.13)
  • Revision ID: package-import@ubuntu.com-20120424112545-18fbnycu9xrsl4s5
Tags: 0.38-1
* New upstream release (closes: #667189)
* New build dependencies on libglm-dev and libboost-filesystem-dev. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    Copyright (C) 2009 Andrew Caudwell (acaudwell@gmail.com)
3
 
 
4
 
    This program is free software; you can redistribute it and/or
5
 
    modify it under the terms of the GNU General Public License
6
 
    as published by the Free Software Foundation; either version
7
 
    3 of the License, or (at your option) any later version.
8
 
 
9
 
    This program is distributed in the hope that it will be useful,
10
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
    GNU General Public License for more details.
13
 
 
14
 
    You should have received a copy of the GNU General Public License
15
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 
*/
17
 
 
18
 
#include "commitlog.h"
19
 
 
20
 
std::string munge_utf8(const std::string& str) {
21
 
 
22
 
    std::string munged;
23
 
    try {
24
 
        utf8::replace_invalid(str.begin(), str.end(), back_inserter(munged), '?');
25
 
    }
26
 
    catch(...) {
27
 
        munged = "???";
28
 
    }
29
 
 
30
 
    return munged;
31
 
}
32
 
 
33
 
//RCommitLog
34
 
 
35
 
RCommitLog::RCommitLog(const std::string& logfile, int firstChar) {
36
 
 
37
 
    logf     = 0;
38
 
    seekable = false;
39
 
    success  = false;
40
 
    is_dir   = false;
41
 
    buffered = false;
42
 
 
43
 
    if(logfile == "-") {
44
 
 
45
 
        //check first char
46
 
        if(checkFirstChar(firstChar, std::cin)) {
47
 
            logf     = new StreamLog();
48
 
            is_dir   = false;
49
 
            seekable = false;
50
 
            success  = true;
51
 
        }
52
 
 
53
 
        return;
54
 
    }
55
 
 
56
 
    struct stat fileinfo;
57
 
    int rc = stat(logfile.c_str(), &fileinfo);
58
 
 
59
 
    if(rc==0) {
60
 
        is_dir = (fileinfo.st_mode & S_IFDIR) ? true : false;
61
 
 
62
 
        if(!is_dir) {
63
 
 
64
 
            //check first char
65
 
            std::ifstream testf(logfile.c_str());
66
 
 
67
 
            bool firstOK = checkFirstChar(firstChar, testf);
68
 
 
69
 
            testf.close();
70
 
 
71
 
            if(firstOK) {
72
 
                logf = new SeekLog(logfile);
73
 
                seekable = true;
74
 
                success = true;
75
 
            }
76
 
        }
77
 
    }
78
 
}
79
 
 
80
 
RCommitLog::~RCommitLog() {
81
 
    if(logf!=0) delete logf;
82
 
 
83
 
    if(!temp_file.empty()) {
84
 
        remove(temp_file.c_str());
85
 
    }
86
 
}
87
 
 
88
 
//check firstChar of stream is as expected. if no firstChar defined just returns true.
89
 
bool RCommitLog::checkFirstChar(int firstChar, std::istream& stream) {
90
 
 
91
 
    //cant check this
92
 
    if(firstChar == -1) return true;
93
 
 
94
 
    int c = stream.peek();
95
 
 
96
 
    if(firstChar == c) return true;
97
 
 
98
 
    return false;
99
 
}
100
 
 
101
 
bool RCommitLog::checkFormat() {
102
 
 
103
 
    if(!success) return false;
104
 
 
105
 
    //read a commit to see if the log is in the correct format
106
 
    if(nextCommit(lastCommit)) {
107
 
 
108
 
        if(seekable) {
109
 
            //if the log is seekable, go back to the start
110
 
            ((SeekLog*)logf)->seekTo(0.0);
111
 
        } else {
112
 
            //otherwise set the buffered flag as we have bufferd one commit
113
 
            buffered = true;
114
 
        }
115
 
 
116
 
        return true;
117
 
    }
118
 
 
119
 
    return false;
120
 
}
121
 
 
122
 
std::string RCommitLog::getLogCommand() {
123
 
    return log_command;
124
 
}
125
 
 
126
 
bool RCommitLog::isSeekable() {
127
 
    return seekable;
128
 
}
129
 
 
130
 
bool RCommitLog::getCommitAt(float percent, RCommit& commit) {
131
 
    if(!seekable) return false;
132
 
 
133
 
    SeekLog* seeklog = ((SeekLog*)logf);
134
 
 
135
 
    //save settings
136
 
    long currpointer = seeklog->getPointer();
137
 
    std::string currlastline = lastline;
138
 
 
139
 
    seekTo(percent);
140
 
    bool success = findNextCommit(commit,500);
141
 
 
142
 
    //restore settings
143
 
    seeklog->setPointer(currpointer);
144
 
    lastline = currlastline;
145
 
 
146
 
    return success;
147
 
}
148
 
 
149
 
bool RCommitLog::getNextLine(std::string& line) {
150
 
    if(!lastline.empty()) {
151
 
        line = lastline;
152
 
        lastline = std::string("");
153
 
        return true;
154
 
    }
155
 
 
156
 
    return logf->getNextLine(line);
157
 
}
158
 
 
159
 
 
160
 
void RCommitLog::seekTo(float percent) {
161
 
    if(!seekable) return;
162
 
 
163
 
    lastline = "";
164
 
 
165
 
    ((SeekLog*)logf)->seekTo(percent);
166
 
}
167
 
 
168
 
float RCommitLog::getPercent() {
169
 
    if(seekable) return ((SeekLog*)logf)->getPercent();
170
 
 
171
 
    return 0.0;
172
 
}
173
 
 
174
 
bool RCommitLog::findNextCommit(RCommit& commit, int attempts) {
175
 
 
176
 
    for(int i=0;i<attempts;i++) {
177
 
        RCommit c;
178
 
 
179
 
        if(nextCommit(c)) {
180
 
            commit = c;
181
 
            return true;
182
 
        }
183
 
    }
184
 
 
185
 
    return false;
186
 
}
187
 
 
188
 
bool RCommitLog::nextCommit(RCommit& commit) {
189
 
 
190
 
    if(buffered) {
191
 
        commit = lastCommit;
192
 
        buffered = false;
193
 
        return true;
194
 
    }
195
 
 
196
 
    bool success = parseCommit(commit);
197
 
 
198
 
    if(!success) return false;
199
 
 
200
 
    return commit.isValid();
201
 
}
202
 
 
203
 
bool RCommitLog::isFinished() {
204
 
    if(seekable && logf->isFinished()) return true;
205
 
 
206
 
    return false;
207
 
}
208
 
 
209
 
//create temp file
210
 
void RCommitLog::createTempLog() {
211
 
 
212
 
    std::string tempdir;
213
 
 
214
 
#ifdef _WIN32
215
 
    DWORD tmplen = GetTempPath(0, "");
216
 
 
217
 
    if(tmplen == 0) return;
218
 
 
219
 
    std::vector<TCHAR> temp(tmplen+1);
220
 
 
221
 
    tmplen = GetTempPath(static_cast<DWORD>(temp.size()), &temp[0]);
222
 
 
223
 
    if(tmplen == 0 || tmplen >= temp.size()) return;
224
 
 
225
 
    tempdir = std::string(temp.begin(), temp.begin() + static_cast<std::size_t>(tmplen));
226
 
    tempdir += "\\";
227
 
#else
228
 
    tempdir = "/tmp/";
229
 
#endif
230
 
 
231
 
    char tmplate[1024];
232
 
    snprintf(tmplate, 1024, "%sgource-XXXXXX", tempdir.c_str());
233
 
 
234
 
#ifdef _WIN32
235
 
    if(mktemp(tmplate) < 0) return;
236
 
#else
237
 
    if(mkstemp(tmplate) < 0) return;
238
 
#endif
239
 
 
240
 
    temp_file = std::string(tmplate);
241
 
}
242
 
 
243
 
// RCommitFile
244
 
 
245
 
RCommitFile::RCommitFile(const std::string& filename, const std::string& action, vec3f colour) {
246
 
 
247
 
    this->filename = munge_utf8(filename);
248
 
 
249
 
    //prepend a root slash
250
 
    if(this->filename[0] != '/') {
251
 
        this->filename.insert(0, 1, '/');
252
 
    }
253
 
 
254
 
    this->action   = action;
255
 
    this->colour   = colour;
256
 
}
257
 
 
258
 
RCommit::RCommit() {
259
 
    timestamp = 0;
260
 
}
261
 
 
262
 
vec3f RCommit::fileColour(const std::string& filename) {
263
 
 
264
 
    size_t slash = filename.rfind('/');
265
 
    size_t dot   = filename.rfind('.');
266
 
 
267
 
    if(dot != std::string::npos && dot+1<filename.size() && (slash == std::string::npos || slash < dot)) {
268
 
        std::string file_ext = filename.substr(dot+1);
269
 
 
270
 
        return colourHash(file_ext);
271
 
    } else {
272
 
        return vec3f(1.0, 1.0, 1.0);
273
 
    }
274
 
}
275
 
 
276
 
void RCommit::addFile(const std::string& filename, const std::string& action) {
277
 
    files.push_back(RCommitFile(filename, action, fileColour(filename)));
278
 
}
279
 
 
280
 
void RCommit::addFile(const std::string& filename, const  std::string& action, vec3f colour) {
281
 
    files.push_back(RCommitFile(filename, action, colour));
282
 
}
283
 
 
284
 
bool RCommit::isValid() {
285
 
 
286
 
    username = munge_utf8(username);
287
 
 
288
 
    return true;
289
 
}
290
 
 
291
 
void RCommit::debug() {
292
 
    debugLog("files:\n");
293
 
 
294
 
    for(std::list<RCommitFile>::iterator it = files.begin(); it != files.end(); it++) {
295
 
        RCommitFile f = *it;
296
 
        debugLog("%s %s\n", f.action.c_str(), f.filename.c_str());
297
 
    }
298
 
}