source: branches/0.7-stable/lib/LineTypeParser.cc @ 927

Last change on this file since 927 was 927, checked in by Peter Johansson, 14 years ago

Fixes #417.

File name in parsing rules are matched against the file name and not
the entire path. This has no influence on most files because the name
starts with a wild card (*) but for files not doing so (default
bootstrap and Makefile) the correct parsing rule will be used. It is
recommended to remove the cache of such files before running
svndigest.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 3.8 KB
Line 
1// $Id: LineTypeParser.cc 927 2009-12-02 04:55:28Z peter $
2
3/*
4  Copyright (C) 2006, 2007, 2008 Jari Häkkinen, Peter Johansson
5
6  This file is part of svndigest, http://dev.thep.lu.se/svndigest
7
8  svndigest is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12
13  svndigest is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "LineTypeParser.h"
23#include "Configuration.h"
24#include "utility.h"
25
26#include <algorithm>
27#include <cassert>
28#include <functional>
29#include <fstream>
30#include <iostream>
31#include <string>
32#include <utility>
33#include <vector>
34
35namespace theplu{
36namespace svndigest{
37
38
39  LineTypeParser::LineTypeParser(std::string path)
40    : mode_(0), post_copyright_(false), copyright_found_(false)
41  {
42    codon_ = Configuration::instance().codon(file_name(path)); 
43  }
44
45
46  LineTypeParser::line_type LineTypeParser::parse(std::string line)
47  {
48    if (!post_copyright_) {
49      if (copyright_found_) {
50        // check if line is end of copyright statement, i.e. contains
51        // no alphanumerical character (except in copyright_prefix).
52        post_copyright_ = true;
53        for (size_t i=0; i<line.size()&&post_copyright_; ++i)
54          if (isalnum(line[i]) && 
55              !(i<copyright_prefix_.size() && copyright_prefix_[i]==line[i])){
56            post_copyright_ = false;
57            block_ += line + "\n";
58          }
59        if (post_copyright_)
60          end_line_ = type_.size()+1;
61      }
62      else {
63        // check whether copyright starts on this line
64        std::string::iterator i=search(line.begin(),line.end(),"Copyright (C)");
65        if (i!=line.end()) {
66          start_line_ = type_.size()+1;
67          copyright_prefix_ = line.substr(0, distance(line.begin(), i));
68          copyright_found_ = true;
69          block_ = line+"\n";
70        }
71      }
72    }
73    // we are in copyright block
74    if (copyright_found_ && !post_copyright_)
75      type_.push_back(LineTypeParser::copyright);
76
77    else if (codon_)
78      type_.push_back(code_mode(line));
79    else
80      type_.push_back(text_mode(line));
81    return type_.back();
82                     
83  }
84
85
86  LineTypeParser::line_type LineTypeParser::code_mode(const std::string& str)
87  {
88    // mode zero means we are currently not in a comment
89    // if mode!=0 comment is closed by codon[mode-1].second -> mode=0
90    // if codon[x-1].start is found and x >= mode -> mode=x
91    line_type lt=other;
92    {
93      for (std::string::const_iterator iter=str.begin();iter!=str.end();++iter){
94        for (size_t i=mode_; i<codon_->size(); ++i) {
95          if ( iter==str.begin() && (*codon_)[i].first[0] == '\n' && 
96               match_begin(iter, str.end(), (*codon_)[i].first.substr(1)) ) {
97            iter += (*codon_)[i].first.size()-1;
98            mode_ = i+1;
99            break;
100          }
101          if (match_begin(iter, str.end(), (*codon_)[i].first)) {
102            iter += (*codon_)[i].first.size();
103            mode_ = i+1;
104            break;
105          }
106        }
107        if (iter==str.end())
108          break;
109        assert(mode_==0 || mode_-1<(*codon_).size());
110        if (mode_ && match_begin(iter,str.end(), (*codon_)[mode_-1].second)){
111          iter += (*codon_)[mode_-1].second.size();
112          mode_=0;
113          if (iter==str.end())
114            break;
115        }
116        else if (!mode_ && isgraph(*iter))
117          lt=code;
118        else if (mode_ && lt!=code && isalnum(*iter))
119          lt=comment;
120      }
121      if (mode_ && (*codon_)[mode_-1].second==std::string("\n"))
122        mode_=0;
123    }
124    return lt;
125  }
126
127
128  LineTypeParser::line_type LineTypeParser::text_mode(const std::string& str)
129  {
130    for (std::string::const_iterator iter=str.begin(); iter!=str.end(); ++iter)
131      if (isalnum(*iter))
132        return comment;
133    return other;
134  }
135
136
137}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.