source: trunk/lib/Configuration.cc @ 514

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

Fixing #230

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.3 KB
Line 
1// $Id: Configuration.cc 514 2007-12-09 01:51:07Z peter $
2
3/*
4  Copyright (C) 2007 Peter Johansson
5
6  This file is part of svndigest, http://trac.thep.lu.se/trac/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 2 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 this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "Configuration.h"
25
26#include "Functor.h"
27
28#include <cassert>
29#include <fstream>
30#include <map>
31#include <string>
32#include <sstream>
33#include <stdexcept>
34#include <utility>
35
36namespace theplu{
37namespace svndigest{
38
39  Configuration* Configuration::instance_=NULL;
40
41
42  Configuration::Configuration(void)
43  {
44  }
45
46
47  void Configuration::add_codon(std::string key, std::string start, 
48                                std::string end)
49  {
50    std::pair<std::string, std::string> p(start,end);
51    String2Codons::iterator iter = string2codons_.end();
52    for (String2Codons::iterator i=string2codons_.begin();
53         i!=string2codons_.end(); ++i)
54      if (i->first == key)
55        iter = i;
56   
57    if (iter==string2codons_.end())
58      string2codons_.push_back(std::make_pair(key, codons(1,p)));
59    else
60      iter->second.push_back(p);
61  }
62
63
64  const std::vector<std::pair<std::string, std::string> >* 
65  Configuration::codon(std::string file_name) const 
66  {
67    for (String2Codons::const_iterator i(string2codons_.begin());
68         i!=string2codons_.end(); ++i) {
69      if (svndigest::equal(file_name.begin(), file_name.end(), 
70                           i->first.begin(), i->first.end()) ) {
71        return &i->second;
72      }
73    }
74    return NULL;
75  }
76
77
78  const std::map<std::string,Alias>& Configuration::copyright_alias(void) const
79  {
80    return copyright_alias_;
81  }
82
83
84  bool Configuration::equal_false(const std::string& str) const
85  {
86    return str=="false" || str=="False" || str=="FALSE" ||
87      str=="no" || str=="No" || str=="NO";
88  }
89
90
91  bool Configuration::equal_true(const std::string& str) const
92  {
93    return str=="true" || str=="True" || str=="TRUE" ||
94      str=="yes" || str=="Yes" || str=="YES";
95  }
96
97
98  void Configuration::load(void)
99  {
100    set_default();
101  }
102
103
104  void Configuration::load(std::istream& is)
105  {
106    assert(is.good());
107    set_default();
108
109    bool parsing_found=false;
110    std::string line;
111    std::string section;
112    std::string tmp;
113    while (getline(is, line)) {
114      line = ltrim(line);
115      if (line.empty() || line[0]=='#')
116        continue;
117      std::stringstream ss(line);
118      if (line[0] == '[') {
119        getline(ss, tmp, '[');
120        getline(ss, section, ']');
121        continue;
122      }
123      getline(ss, tmp, '=');
124      std::string lhs = trim(tmp);
125      getline(ss, tmp);
126      std::string rhs = trim(tmp);
127      if (rhs.empty()){
128        std::stringstream mess;
129        mess << "svndigest: invalid config file: "
130             << "line: `" << line << "' is invalid.";
131        throw std::runtime_error(mess.str());
132      }
133      if (section == "copyright-alias"){
134        std::map<std::string,Alias>::iterator iter = 
135          copyright_alias_.lower_bound(lhs);
136        if (iter!=copyright_alias_.end() && iter->first==lhs){
137          std::stringstream mess;
138          mess << "svndigest: invalid config file: "
139               << "in copright-alias section " << lhs << " defined twice.";
140          throw std::runtime_error(mess.str());
141        }
142       
143        // insert alias
144        copyright_alias_.insert(iter,std::make_pair(lhs, Alias(rhs,copyright_alias_.size())));
145      }
146      else if (section == "trac"){
147        if (lhs=="trac-root")
148          trac_root_=rhs;
149        else {
150          std::stringstream mess;
151          mess << "svndigest: invalid config file: "
152               << "in trac section" << lhs + " is invalid option.";
153          throw std::runtime_error(mess.str());
154        }
155      }
156      else if (section == "copyright") {
157        if (lhs=="missing-copyright-warning")
158          if (equal_false(rhs))
159            missing_copyright_warning_ = false;
160          else if (equal_true(rhs))
161            missing_copyright_warning_ = true;
162          else {
163            std::stringstream mess;
164            mess << "svndigest: invalid config file: "
165                 << "line: `" << line << "' is invalid.";
166            throw std::runtime_error(mess.str());
167          }
168      }
169      else if (section == "parsing-codons") {
170        if (!parsing_found) {
171          parsing_found=true;
172          // clearing the default setting
173          string2codons_.clear();
174        }
175       
176        if (codon(lhs)) {
177          std::stringstream mess;
178          mess << "svndigest: invalid config file\n"
179               << "line: `" << line << "' is invalid.\n"
180               << "clashes with previous given file-name-pattern: ";
181          // find previous file-name-pattern
182          for (String2Codons::const_iterator i(string2codons_.begin());
183               i!=string2codons_.end(); ++i) {
184            if (svndigest::equal(lhs.begin(), lhs.end(), 
185                                 i->first.begin(), i->first.end()) ) {
186              mess << "`" << i->first << "'";
187              break;
188            }
189          }
190          throw std::runtime_error(mess.str());
191        }
192        std::stringstream ss(rhs);
193        std::string start;
194        while (getline(ss, start, ':')) {
195          start = trim(start);
196          std::string end;
197          getline(ss, end, ';');
198          end = trim(end);
199          if (!start.empty() && !end.empty()) {
200            replace(start, "<NEWLINE>", "\n");
201            replace(end, "<NEWLINE>", "\n");
202            add_codon(lhs, start, end);
203          }
204          else if (!start.empty() || !end.empty()) {
205            std::stringstream mess;
206            mess << "svndigest: invalid config file\n"
207                 << "line: `" << line << "' is invalid.\n";
208            throw std::runtime_error(mess.str());
209          }
210        }
211      } 
212    }
213  }
214
215
216  Configuration& Configuration::instance(void)
217  {
218    if (!instance_)
219      instance_ = new Configuration;
220    return *instance_;
221  }
222
223
224  bool Configuration::missing_copyright_warning(void) const
225  {
226    return missing_copyright_warning_;
227  }
228
229
230  std::string trans_end_code(std::string str)
231  {
232    if (str.size()>0 && str[str.size()-1]=='\n')
233      return str.substr(0, str.size()-1) + std::string("<NEWLINE>");
234    return str;
235  }
236
237
238  std::string trans_beg_code(std::string str)
239  {
240    if (str.size()>0 && str[0]=='\n')
241      return std::string("<NEWLINE>") + str.substr(1); 
242    return str;
243  }
244
245
246  void Configuration::set_default(void)
247  {
248    copyright_alias_.clear();
249    missing_copyright_warning_=false;
250    trac_root_ = "";
251
252    add_codon("*.ac", "#", "\n");
253    add_codon("*.ac", "dnl", "\n");
254    add_codon("*.am", "#", "\n");
255    add_codon("*.am", "dnl", "\n");
256    add_codon("*.m4", "#", "\n");
257    add_codon("*.m4", "dnl", "\n");
258    add_codon("*.c", "//", "\n");
259    add_codon("*.c", "/*", "*/");
260    add_codon("*.cc", "//", "\n");
261    add_codon("*.cc", "/*", "*/");
262    add_codon("*.cpp", "//", "\n");
263    add_codon("*.cpp", "/*", "*/");
264    add_codon("*.cxx", "//", "\n");
265    add_codon("*.cxx", "/*", "*/");
266    add_codon("*.h", "//", "\n");
267    add_codon("*.h", "/*", "*/");
268    add_codon("*.hh", "//", "\n");
269    add_codon("*.hh", "/*", "*/");
270    add_codon("*.hpp", "//", "\n");
271    add_codon("*.hpp", "/*", "*/");
272    add_codon("*.java", "//", "\n");
273    add_codon("*.java", "/*", "*/");
274    add_codon("*.pl", "#", "\n");
275    add_codon("*.pm", "#", "\n");
276    add_codon("*.sh", "#", "\n");
277    add_codon("*config", "#", "\n");
278    add_codon("bootstrap", "#", "\n");
279    add_codon("Makefile", "#", "\n");
280    add_codon("*.tex", "%", "\n");
281    add_codon("*.m", "%", "\n");
282    add_codon("*.jsp", "<!--", "-->");
283    add_codon("*.html", "<%--", "--%>");
284    add_codon("*.xml", "<!--", "-->");
285    add_codon("*.xsl", "<!--", "-->");
286    add_codon("*.xsd", "<!--", "-->");
287    add_codon("*.xhtml", "<!--", "-->");
288    add_codon("*.shtml", "<!--", "-->");
289    add_codon("*.xml", "<!--", "-->");
290    add_codon("*.css", "<!--", "-->");
291    add_codon("*.rss", "<!--", "-->");
292    add_codon("*.sgml", "<!--", "-->");
293    add_codon("*.bat", "\nREM", "\n");
294    add_codon("*.bat", "\nrem", "\n");
295  }
296
297
298  std::string Configuration::trac_root(void) const
299  {
300    return trac_root_;
301  }
302
303
304  std::ostream& operator<<(std::ostream& os, const Configuration& conf)
305  {
306    os << "### This file configures various behaviors for svndigest\n"
307       << "### The commented-out below are intended to demonstrate how to use\n"
308       << "### this file.\n"
309       << "\n"
310       << "### Section for setting behaviour of copyright update\n"
311       << "[copyright]\n"
312       << "# if true svndigest will warn if file has no copyright statement.\n"
313       << "missing-copyright-warning = ";
314   
315    if (conf.missing_copyright_warning())
316      os << "yes\n";
317    else
318      os << "no\n";
319
320    os << "\n"
321       << "### Section for setting aliases used in copyright update\n"
322       << "[copyright-alias]\n"
323       << "# jdoe = John Doe\n";
324
325    typedef std::vector<std::pair<std::string, Alias> > vector;
326    vector vec;
327    std::back_insert_iterator<vector> back_insert_iterator(vec);
328    vec.reserve(conf.copyright_alias().size());
329    std::copy(conf.copyright_alias().begin(), conf.copyright_alias().end(),
330              back_insert_iterator);
331    // sort with respect to Alias.id
332    IdCompare id;
333    PairSecondCompare<const std::string, Alias, IdCompare> comp(id);
334    std::sort(vec.begin(),vec.end(), comp);
335             
336
337    for (vector::const_iterator i(vec.begin()); i!=vec.end(); ++i) {
338      os << i->first << " = " << i->second.name() << " \n";
339    }
340
341    os << "\n"
342       << "### Section for setting trac environment\n"
343       << "[trac]\n"
344       << "# If trac-root is set, svndigest will create anchors to "
345       << "the Trac page.\n"
346       << "# trac-root = http://trac.thep.lu.se/trac/svndigest/\n";
347    if (!conf.trac_root().empty())
348      os << "trac-root = " << conf.trac_root() << "\n";
349
350    if (!conf.string2codons_.empty()) {
351      os << "\n"
352         << "### Section for setting parsing modes\n"
353         << "### The format of the entries is:\n"
354         << "###   file-name-pattern = start-code : end-code\n"
355         << "### The file-name-pattern may contain wildcards (such as '*' "
356         << "and '?').\n"
357         << "### String \"<NEWLINE>\" can be used for codons containing newline"
358         << "\n### character: '\\n'\n"
359         << "[parsing-codons]\n";
360      for (size_t i=0; i<conf.string2codons_.size(); ++i) {
361        os << conf.string2codons_[i].first << " = "; 
362        for (size_t j=0; j<conf.string2codons_[i].second.size(); ++j) {
363          if (j)
364            os << "  ;  ";
365          os << trans_beg_code(conf.string2codons_[i].second[j].first) 
366             << " : " 
367             << trans_end_code(conf.string2codons_[i].second[j].second); 
368        }
369        os << "\n";
370      }
371    }
372    return os;
373  }
374
375
376}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.