source: trunk/lib/Configuration.cc @ 515

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

adding dictionary variable in Configuration. Reading and usage of the variable needs to be implemented

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.2 KB
Line 
1// $Id: Configuration.cc 515 2007-12-09 02:38:34Z 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, VectorPair(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    dictionary_ = VectorPair(1, std::make_pair("*.in", "$1"));
297  }
298
299
300  std::string Configuration::trac_root(void) const
301  {
302    return trac_root_;
303  }
304
305
306  std::ostream& operator<<(std::ostream& os, const Configuration& conf)
307  {
308    os << "### This file configures various behaviors for svndigest\n"
309       << "### The commented-out below are intended to demonstrate how to use\n"
310       << "### this file.\n"
311       << "\n"
312       << "### Section for setting behaviour of copyright update\n"
313       << "[copyright]\n"
314       << "# if true svndigest will warn if file has no copyright statement.\n"
315       << "missing-copyright-warning = ";
316   
317    if (conf.missing_copyright_warning())
318      os << "yes\n";
319    else
320      os << "no\n";
321
322    os << "\n"
323       << "### Section for setting aliases used in copyright update\n"
324       << "[copyright-alias]\n"
325       << "# jdoe = John Doe\n";
326
327    typedef std::vector<std::pair<std::string, Alias> > vector;
328    vector vec;
329    std::back_insert_iterator<vector> back_insert_iterator(vec);
330    vec.reserve(conf.copyright_alias().size());
331    std::copy(conf.copyright_alias().begin(), conf.copyright_alias().end(),
332              back_insert_iterator);
333    // sort with respect to Alias.id
334    IdCompare id;
335    PairSecondCompare<const std::string, Alias, IdCompare> comp(id);
336    std::sort(vec.begin(),vec.end(), comp);
337             
338
339    for (vector::const_iterator i(vec.begin()); i!=vec.end(); ++i) {
340      os << i->first << " = " << i->second.name() << " \n";
341    }
342
343    os << "\n"
344       << "### Section for setting trac environment\n"
345       << "[trac]\n"
346       << "# If trac-root is set, svndigest will create anchors to "
347       << "the Trac page.\n"
348       << "# trac-root = http://trac.thep.lu.se/trac/svndigest/\n";
349    if (!conf.trac_root().empty())
350      os << "trac-root = " << conf.trac_root() << "\n";
351
352    if (!conf.dictionary_.empty()) {
353      os << "\n"
354         << "### Section for setting dictionary for file names.\n"
355         << "### Prior looking for file name pattern in section [codon],\n"
356         << "### the file name may be translated according to the rules \n"
357         << "### in this section. In default setting there is, for example,\n"
358         << "### a rule to translate `<FILENAME>.in' to `<FILENAME>'.\n"
359         << "### The format of the entries is:\n"
360         << "###    file-name-pattern = new-name\n"
361         << "### Left hand side may contain wildcards (such as '*' and '?').\n"
362         << "### Right hand side may contain \"$i\", which will be replaced \n"
363         << "### with the ith wild card in lhs string.\n"
364         << "[file-name-dictionary]\n";
365      for (size_t i=0; i<conf.dictionary_.size(); ++i)
366        os << conf.dictionary_[i].first << " = " 
367           << conf.dictionary_[i].second << "\n"; 
368    }
369    if (!conf.string2codons_.empty()) {
370      os << "\n"
371         << "### Section for setting parsing modes\n"
372         << "### The format of the entries is:\n"
373         << "###   file-name-pattern = start-code : end-code\n"
374         << "### The file-name-pattern may contain wildcards (such as '*' "
375         << "and '?').\n"
376         << "### String \"<NEWLINE>\" can be used for codons containing newline"
377         << "\n### character: '\\n'\n"
378         << "[parsing-codons]\n";
379      for (size_t i=0; i<conf.string2codons_.size(); ++i) {
380        os << conf.string2codons_[i].first << " = "; 
381        for (size_t j=0; j<conf.string2codons_[i].second.size(); ++j) {
382          if (j)
383            os << "  ;  ";
384          os << trans_beg_code(conf.string2codons_[i].second[j].first) 
385             << " : " 
386             << trans_end_code(conf.string2codons_[i].second[j].second); 
387        }
388        os << "\n";
389      }
390    }
391    return os;
392  }
393
394
395}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.