Changeset 1060 for trunk


Ignore:
Timestamp:
Jun 2, 2010, 3:56:35 AM (13 years ago)
Author:
Peter Johansson
Message:

refs #307

Splittin the Parameter class into two separate classes and a base
class holding the common parts. The output of '--help' is not sorted
as before otherwise everything should be the same. The sort will
require some ammendment in yat.

Location:
trunk
Files:
2 added
8 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/bin/Makefile.am

    r1055 r1060  
    2424bin_PROGRAMS = svndigest svncopyright
    2525
    26 svndigest_SOURCES = Parameter.cc svndigest.cc
    27 svncopyright_SOURCES = Parameter.cc svncopyright.cc
     26svndigest_SOURCES = Parameter.cc svndigestParameter.cc svndigest.cc
     27svncopyright_SOURCES = Parameter.cc svncopyrightParameter.cc svncopyright.cc
    2828
    29 noinst_HEADERS = Parameter.h
     29noinst_HEADERS = Parameter.h svncopyrightParameter.h svndigestParameter.h
    3030
    3131bin_SCRIPTS = svndigest-copy-cache
     
    3333
    3434LDADD = $(top_builddir)/lib/libsvndigest.a \
    35   $(top_builddir)/lib/yat/libyat.a $(SVN_LIBS) $(APR_LIBS) $(PLPLOT_LIBS)
    36 AM_LDFLAGS = $(APR_LDFLAGS) $(SVN_LDFLAGS) $(PLPLOT_LDFLAGS)
     35  $(top_builddir)/lib/yat/libyat.a $(SVN_LIBS) $(APR_LIBS)
     36AM_LDFLAGS = $(APR_LDFLAGS) $(SVN_LDFLAGS)
    3737
    3838AM_CPPFLAGS  = -I$(top_srcdir)/lib $(DEFAULT_CPPFLAGS) \
    39   $(APR_CPPFLAGS) $(SVN_CPPFLAGS) $(PLPLOT_CPPFLAGS)
     39  $(APR_CPPFLAGS) $(SVN_CPPFLAGS)
    4040AM_CXXFLAGS = $(DEFAULT_CXXFLAGS)
     41
     42svndigest_LDADD = $(LDADD) $(PLPLOT_LIBS)
     43svndigest_LDFLAGS = $(AM_LDFLAGS) $(PLPLOT_LDFLAGS)
     44svndigest_CPPFLAGS  = $(AM_CPPFLAGS) $(PLPLOT_CPPFLAGS)
    4145
    4246.as.in:
  • trunk/bin/Parameter.cc

    r1023 r1060  
    4848namespace svndigest {
    4949
    50   Parameter::Parameter( int argc, char *argv[])
     50  Parameter::Parameter(void)
    5151    : cmd_( std::string("Mandatory arguments to long options ") +
    5252            std::string("are mandatory for short options too.")),
    53       anchor_format_(cmd_,"anchor-format",
    54                      "override anchor image format defined in config file"),
    5553      config_file_(cmd_, "config-file",
    5654                   "configuration file [<ROOT>/.svndigest/config]"),
    57       copyright_(cmd_, "copyright", "update copyright statement"),
    5855      force_(cmd_, "f,force",
    5956             std::string("if sub-directory named <ROOT> exists in target dire")+
     
    6562                    std::string("ignore cache files and analyze ") +
    6663                    std::string("everything from repository")),
    67       format_(cmd_,"format", "override image format defined in config file"),
    68       report_(cmd_, "report", "create no HTML report", true),
    69       revisions_(cmd_, "revisions",
    70                  "use revision number as time scale instead of dates [dates]"),
    7164      root_(cmd_, "r,root",
    7265            "svn controlled directory to perform statistics on [.]"),
    73       target_(cmd_, "t,target", "output directory [.]"),
    7466      verbose_(cmd_, "v,verbose", "explain what is being done"),
    7567      version_(cmd_, "version", "print version information and exit", &verbose_)
     68  {
     69  }
     70
     71  void Parameter::parse(int argc, char* argv[])
    7672  {
    7773    init();
     
    8480    }
    8581
    86     // set default values
    87     if (!root_.present())
    88       root_.value(".");
    89 
    90     if (!target_.present())
    91       target_.value(".");
    92 
    93     if (!config_file_.present())
    94       config_file_.value(concatenate_path(root_.value(),".svndigest/config"));
     82    set_default();
    9583
    9684    // analyse arguments
     
    10189  Parameter::~Parameter(void)
    10290  {
    103   }
    104 
    105 
    106   const yat::utility::OptionArg<std::string>&
    107   Parameter::anchor_format(void) const
    108   {
    109     return anchor_format_;
    11091  }
    11192
     
    128109      chdir(save_wd.c_str());
    129110
    130       // check target (only if we write report)
    131       if (report()) {
    132         check_existence(target_.value());
    133         check_readable(target_.value());
    134         std::string base_root = file_name(root_.value());
    135         std::string path = concatenate_path(target_.value(),base_root);
    136         if (access_rights(target_.value().c_str(), "w")) {
    137           std::stringstream ss;
    138           ss << "svndigest: cannot create directory `" << path
    139              << "': " << strerror(errno);
    140           throw yat::utility::cmd_error(ss.str());
    141         }
    142         if (node_exist(path) && !force()) {
    143           std::stringstream ss;
    144           ss << "svndigest: cannot create directory `" << path << "' "
    145              << strerror(EEXIST);
    146           throw yat::utility::cmd_error(ss.str());
    147         }
    148         if (chdir(target_.value().c_str())) {
    149           std::stringstream ss;
    150           ss << "svndigest: cannot read `" << target_.value() << "': "
    151              << strerror(errno);
    152           throw yat::utility::cmd_error(ss.str());
    153         }
    154         target_.value(pwd());
    155         chdir(save_wd.c_str());
    156       }
    157111    }
    158112
     
    176130      }
    177131    }
     132    analyse2();
    178133  }
    179134
     
    205160
    206161
    207   bool Parameter::copyright(void) const
    208   {
    209     return copyright_.present();
    210   }
    211 
    212 
    213162  bool Parameter::force(void) const
    214163  {
     
    226175  {
    227176    return ignore_cache_.present();
    228   }
    229 
    230 
    231   const yat::utility::OptionArg<std::string>&
    232   Parameter::format(void) const
    233   {
    234     return format_;
    235177  }
    236178
     
    240182    // don't use argv[0] because user may rename the binary
    241183    cmd_.program_name() = PACKAGE_NAME;
    242     anchor_format_.print_arg("=FMT");
    243184    config_file_.print_arg("=FILE");
    244     format_.print_arg("=FMT");
    245185    root_.print_arg("=ROOT");
    246     target_.print_arg("=TARGET");
    247186    std::stringstream ss;
    248187    ss << "Report bugs to " << PACKAGE_BUGREPORT << ".\n"
    249188       << PACKAGE << " home page: <" << PACKAGE_URL << ">.\n";
    250189    help_.post_arguments() = ss.str();
    251     help_.synopsis() =
    252       "Generate statistical report for a subversion repository\n";
    253   }
    254 
    255 
    256   bool Parameter::report(void) const
    257   {
    258     return report_.value();
    259   }
    260 
    261 
    262   bool Parameter::revisions(void) const
    263   {
    264     return revisions_.present();
     190    init2();
    265191  }
    266192
     
    271197  }
    272198
    273  
    274   std::string Parameter::targetdir(void) const
    275   {
    276     return target_.value();
    277   }
    278 
    279  
     199  void Parameter::set_default(void)
     200  {
     201    if (!root_.present())
     202      root_.value(".");
     203
     204    if (!config_file_.present())
     205      config_file_.value(concatenate_path(root_.value(),".svndigest/config"));
     206
     207    set_default2();
     208  }
     209
     210
    280211  bool Parameter::verbose(void) const
    281212  {
  • trunk/bin/Parameter.h

    r1023 r1060  
    4747  class Parameter {
    4848  public:
    49     Parameter( int argc, char *argv[]);
     49    Parameter(void);
    5050    virtual ~Parameter(void);
    51     const yat::utility::OptionArg<std::string>& anchor_format(void) const;
     51    void parse( int argc, char *argv[]);
     52
    5253    std::string config_file(void) const;
    5354   
    54     bool copyright(void) const;
    5555    bool force(void) const;
    5656    bool generate_config(void) const ;
    5757    bool ignore_cache(void) const;
    58     const yat::utility::OptionArg<std::string>& format(void) const;
    59     bool report(void) const;
    60     bool revisions(void) const;
    6158    /// @return absolute path to root directory
    6259    std::string root(void) const;
    63     /// @return absolute path to target directory
    64     std::string targetdir(void) const;
    6560    bool verbose(void) const;
    6661
    67   private:
    68     void analyse(void);
     62  protected:
     63    yat::utility::CommandLine cmd_;
     64    yat::utility::OptionHelp help_;
     65
    6966    // throw cmd_error if path doesn't exist
    7067    void check_existence(std::string path) const;
     
    7471    void check_readable(std::string path) const;
    7572
     73  private:
     74    void analyse(void);
     75    virtual void analyse2(void)=0;
    7676    void init(void);
     77    // called at end of init(void)
     78    virtual void init2(void) = 0;
     79    void set_default(void);
     80    virtual void set_default2(void)=0;
    7781
    78     yat::utility::CommandLine cmd_;
    79     yat::utility::OptionArg<std::string> anchor_format_;
    8082    yat::utility::OptionArg<std::string> config_file_;
    81     yat::utility::OptionSwitch copyright_;
    8283    yat::utility::OptionSwitch force_;
    8384    yat::utility::OptionSwitch generate_config_;
    84     yat::utility::OptionHelp help_;
    8585    yat::utility::OptionSwitch ignore_cache_;
    86     yat::utility::OptionArg<std::string> format_;
    87     yat::utility::OptionSwitch report_;
    88     yat::utility::OptionSwitch revisions_;
    8986    yat::utility::OptionArg<std::string> root_;
    90     yat::utility::OptionArg<std::string> target_;
    9187    yat::utility::OptionSwitch verbose_;
     88  protected:
    9289    OptionVersion version_;
    9390
  • trunk/bin/svncopyright.cc

    r1055 r1060  
    2020*/
    2121
    22 #include "Parameter.h"
     22#include "svncopyrightParameter.h"
    2323
    2424#include <cassert>
     
    3232
    3333  // Reading commandline options
    34   Parameter* option=NULL;
     34  svncopyrightParameter option;
    3535  try {
    36     option = new Parameter(argc,argv);
    37     if (option->verbose())
     36    option.parse(argc, argv);
     37    if (option.verbose())
    3838      std::cout << "Done parsing parameters" << std::endl;
    3939  }
     
    4242    return EXIT_FAILURE;
    4343  }
    44   assert(option);
    45 
    4644  return EXIT_SUCCESS;        // normal exit
    4745}
  • trunk/bin/svndigest.cc

    r1041 r1060  
    2121*/
    2222
    23 #include "Parameter.h"
     23#include "svndigestParameter.h"
    2424
    2525#include "Configuration.h"
     
    5858
    5959  // Reading commandline options
    60   Parameter* option=NULL;
    61   try {
    62     option = new Parameter(argc,argv);
     60  svndigestParameter* option = new svndigestParameter;
     61  assert(option);
     62  try {
     63    option->parse(argc,argv);
    6364    if (option->verbose())
    6465      std::cout << "Done parsing parameters" << std::endl;
     
    6869    exit(EXIT_FAILURE);
    6970  }
    70   assert(option);
    7171
    7272  // Reading configuration file
  • trunk/bin/svndigestParameter.cc

    r1054 r1060  
    2323#include <config.h> // this header file is created by configure
    2424
    25 #include "Parameter.h"
     25#include "svndigestParameter.h"
    2626
    2727#include "OptionVersion.h"
    2828#include "../lib/utility.h" // to avoid inclusion of yat file
     29
     30#ifdef HAVE_PLPLOT
     31#include <plplot/plstream.h>
     32#endif
    2933
    3034#include "yat/ColumnStream.h"
     
    4852namespace svndigest {
    4953
    50   Parameter::Parameter( int argc, char *argv[])
    51     : cmd_( std::string("Mandatory arguments to long options ") +
    52             std::string("are mandatory for short options too.")),
     54  svndigestParameter::svndigestParameter(void)
     55    : Parameter(),
    5356      anchor_format_(cmd_,"anchor-format",
    5457                     "override anchor image format defined in config file"),
    55       config_file_(cmd_, "config-file",
    56                    "configuration file [<ROOT>/.svndigest/config]"),
    5758      copyright_(cmd_, "copyright", "update copyright statement"),
    58       force_(cmd_, "f,force",
    59              std::string("if sub-directory named <ROOT> exists in target dire")+
    60              std::string("ctory, remove sub-directory before writing results")),
    61       generate_config_(cmd_, "g,generate-config",
    62                        "write configuration to standard output"),
    63       help_(cmd_),
    64       ignore_cache_(cmd_, "ignore-cache",
    65                     std::string("ignore cache files and analyze ") +
    66                     std::string("everything from repository")),
    6759      format_(cmd_,"format", "override image format defined in config file"),
    6860      report_(cmd_, "report", "create no HTML report", true),
    6961      revisions_(cmd_, "revisions",
    7062                 "use revision number as time scale instead of dates [dates]"),
    71       root_(cmd_, "r,root",
    72             "svn controlled directory to perform statistics on [.]"),
    73       target_(cmd_, "t,target", "output directory [.]"),
    74       verbose_(cmd_, "v,verbose", "explain what is being done"),
    75       version_(cmd_, "version", "print version information and exit", &verbose_)
     63      target_(cmd_, "t,target", "output directory [.]")
    7664  {
    77     init();
    78     try {
    79       cmd_.parse(argc, argv);
    80     }
    81     catch (yat::utility::cmd_error& e) {
    82       std::cerr << e.what() << std::endl;
    83       exit (-1);
    84     }
    85 
    8665    // set default values
    87     if (!root_.present())
    88       root_.value(".");
    89 
     66    /*
    9067    if (!target_.present())
    9168      target_.value(".");
    92 
    93     if (!config_file_.present())
    94       config_file_.value(concatenate_path(root_.value(),".svndigest/config"));
    95 
    96     // analyse arguments
    97     analyse();
     69    */
    9870  }
    9971
    10072
    101   Parameter::~Parameter(void)
     73  svndigestParameter::~svndigestParameter(void)
    10274  {
    10375  }
     
    10577
    10678  const yat::utility::OptionArg<std::string>&
    107   Parameter::anchor_format(void) const
     79  svndigestParameter::anchor_format(void) const
    10880  {
    10981    return anchor_format_;
     
    11183
    11284
    113   void Parameter::analyse(void)
     85  void svndigestParameter::analyse2(void)
    11486  {
    11587    std::string save_wd = pwd();
     
    11789    // check root but not if -g option given
    11890    if (!generate_config()) {
    119       check_existence(root_.value());
    120       check_readable(root_.value());
    121       if (chdir(root_.value().c_str())) {
    122         std::stringstream ss;
    123         ss << "svndigest: cannot read `" << root_.value() << "': "
    124            << strerror(errno);
    125         throw yat::utility::cmd_error(ss.str());
    126       }
    127       root_.value(pwd());
    128       chdir(save_wd.c_str());
    129 
    13091      // check target (only if we write report)
    13192      if (report()) {
    13293        check_existence(target_.value());
    13394        check_readable(target_.value());
    134         std::string base_root = file_name(root_.value());
     95        std::string base_root = file_name(root());
    13596        std::string path = concatenate_path(target_.value(),base_root);
    13697        if (access_rights(target_.value().c_str(), "w")) {
     
    156117      }
    157118    }
    158 
    159     // check config file
    160     struct stat nodestat;
    161     // true also if there is a broken symlink named...
    162     bool config_exists = !lstat(config_file_.value().c_str(), &nodestat);
    163     // the latter case in order to catch broken symlink
    164     if (config_file_.present() || config_exists)
    165       // throws if file does not exists
    166       check_existence(config_file_.value());
    167     if (config_exists) {
    168       // throws if file is not readable
    169       check_readable(config_file_.value());
    170       stat(config_file_.value().c_str(), &nodestat);
    171       if (!S_ISREG(nodestat.st_mode)) {
    172         std::stringstream ss;
    173         ss << "svndigest: `" << config_file_.value()
    174            << "' is not a regular file";
    175         throw yat::utility::cmd_error(ss.str());
    176       }
    177     }
    178119  }
    179120
    180121
    181   void Parameter::check_existence(std::string path) const
    182   {
    183     if (node_exist(path))
    184       return;
    185     std::stringstream ss;
    186     ss << "svndigest: cannot stat `" << path << "': " << strerror(errno);
    187     throw yat::utility::cmd_error(ss.str());
    188   }
    189 
    190  
    191   void Parameter::check_readable(std::string path) const
    192   {
    193     if (!access_rights(path, "r"))
    194       return;
    195     std::stringstream ss;
    196     ss << "svndigest: cannot open `" << path << "': " << strerror(errno);
    197     throw yat::utility::cmd_error(ss.str());
    198   }
    199  
    200 
    201   std::string Parameter::config_file(void) const
    202   {
    203     return config_file_.value();
    204   }
    205 
    206 
    207   bool Parameter::copyright(void) const
     122  bool svndigestParameter::copyright(void) const
    208123  {
    209124    return copyright_.present();
     
    211126
    212127
    213   bool Parameter::force(void) const
    214   {
    215     return force_.present();
    216   }
    217 
    218 
    219   bool Parameter::generate_config(void) const
    220   {
    221     return generate_config_.present();
    222   }
    223 
    224 
    225   bool Parameter::ignore_cache(void) const
    226   {
    227     return ignore_cache_.present();
    228   }
    229 
    230 
    231128  const yat::utility::OptionArg<std::string>&
    232   Parameter::format(void) const
     129  svndigestParameter::format(void) const
    233130  {
    234131    return format_;
     
    236133
    237134
    238   void Parameter::init(void)
     135  void svndigestParameter::init2(void)
    239136  {
    240137    // don't use argv[0] because user may rename the binary
    241     cmd_.program_name() = PACKAGE_NAME;
     138    cmd_.program_name() = "svndigest";
    242139    anchor_format_.print_arg("=FMT");
    243     config_file_.print_arg("=FILE");
    244140    format_.print_arg("=FMT");
    245     root_.print_arg("=ROOT");
    246141    target_.print_arg("=TARGET");
    247     std::stringstream ss;
    248     ss << "Report bugs to " << PACKAGE_BUGREPORT << ".\n"
    249        << PACKAGE << " home page: <" << PACKAGE_URL << ">.\n";
    250     help_.post_arguments() = ss.str();
    251142    help_.synopsis() =
    252143      "Generate statistical report for a subversion repository\n";
     144
     145    std::stringstream ss;
     146#ifdef HAVE_PLPLOT
     147    ss << "using libplplot ";
     148    plstream pls;
     149    char* plplot_version = new char[32];
     150    pls.gver(plplot_version);
     151    ss << plplot_version << "\n";
     152    delete [] plplot_version;
     153#endif
     154    version_.extra(ss.str());
     155    version_.program_name("svndigest");
    253156  }
    254157
    255158
    256   bool Parameter::report(void) const
     159  bool svndigestParameter::report(void) const
    257160  {
    258161    return report_.value();
     
    260163
    261164
    262   bool Parameter::revisions(void) const
     165  bool svndigestParameter::revisions(void) const
    263166  {
    264167    return revisions_.present();
     
    266169
    267170
    268   std::string Parameter::root(void) const
     171  void svndigestParameter::set_default2(void)
    269172  {
    270     return root_.value();
     173
    271174  }
    272175
    273  
    274   std::string Parameter::targetdir(void) const
     176
     177  std::string svndigestParameter::targetdir(void) const
    275178  {
    276179    return target_.value();
    277180  }
    278181
    279  
    280   bool Parameter::verbose(void) const
    281   {
    282     return verbose_.present();
    283   }
    284 
    285 
    286182}} // of namespace svndigest and namespace theplu
  • trunk/bin/svndigestParameter.h

    r1054 r1060  
    1 #ifndef _theplu_svndigest_parameter_
    2 #define _theplu_svndigest_parameter_
     1#ifndef _theplu_svndigest_svndigest_parameter_
     2#define _theplu_svndigest_svndigest_parameter_
    33
    44// $Id$
     
    2424*/
    2525
     26#include "Parameter.h"
     27
    2628#include "OptionVersion.h"
    2729
     
    3739namespace yat {
    3840namespace utility {
    39   class OptionHelp;
    4041  class OptionSwitch;
    4142}}
    4243namespace svndigest {
    4344
    44   class OptionVersion;
    45 
    4645  // class for command line options.
    47   class Parameter {
     46  class svndigestParameter : public Parameter
     47  {
    4848  public:
    49     Parameter( int argc, char *argv[]);
    50     virtual ~Parameter(void);
     49    svndigestParameter(void);
     50    virtual ~svndigestParameter(void);
    5151    const yat::utility::OptionArg<std::string>& anchor_format(void) const;
    52     std::string config_file(void) const;
    5352   
    5453    bool copyright(void) const;
    55     bool force(void) const;
    56     bool generate_config(void) const ;
    57     bool ignore_cache(void) const;
    5854    const yat::utility::OptionArg<std::string>& format(void) const;
    5955    bool report(void) const;
    6056    bool revisions(void) const;
    6157    /// @return absolute path to root directory
    62     std::string root(void) const;
    63     /// @return absolute path to target directory
    6458    std::string targetdir(void) const;
    65     bool verbose(void) const;
    6659
    6760  private:
    68     void analyse(void);
    69     // throw cmd_error if path doesn't exist
    70     void check_existence(std::string path) const;
    71     // throw cmd_error if path is not dir
    72     void check_is_dir(std::string path) const;
    73     // throw cmd_error if path is not readable
    74     void check_readable(std::string path) const;
     61    void analyse2(void);
     62    void init2(void);
     63    void set_default2(void);
    7564
    76     void init(void);
    77 
    78     yat::utility::CommandLine cmd_;
    7965    yat::utility::OptionArg<std::string> anchor_format_;
    80     yat::utility::OptionArg<std::string> config_file_;
    8166    yat::utility::OptionSwitch copyright_;
    82     yat::utility::OptionSwitch force_;
    83     yat::utility::OptionSwitch generate_config_;
    84     yat::utility::OptionHelp help_;
    85     yat::utility::OptionSwitch ignore_cache_;
    8667    yat::utility::OptionArg<std::string> format_;
    8768    yat::utility::OptionSwitch report_;
    8869    yat::utility::OptionSwitch revisions_;
    89     yat::utility::OptionArg<std::string> root_;
    9070    yat::utility::OptionArg<std::string> target_;
    91     yat::utility::OptionSwitch verbose_;
    92     OptionVersion version_;
    93 
    9471  };
    9572
  • trunk/lib/OptionVersion.cc

    r1058 r1060  
    3333#include <apr_version.h>
    3434
    35 #ifdef HAVE_PLPLOT
    36 #include <plplot/plstream.h>
    37 #endif
    38 
    3935#include <cstdlib>
    4036#include <iostream>
     
    5753    yat::utility::ColumnStream cs(std::cout, 1);
    5854    cs.width(0)=79;
    59     cs << PACKAGE_NAME << " " << PACKAGE_VERSION;
     55    cs << prog_name_ << " " << PACKAGE_VERSION;
    6056    bool no_verbose = verbose_ && verbose_->present() && !verbose_->value();
    6157    if (!no_verbose) {
     
    8379      cs << apr_version_string();
    8480      cs << "\n";
    85 #ifdef HAVE_PLPLOT
    86       cs << "using libplplot ";
    87       plstream pls;
    88       char* plplot_version = new char[32];
    89       pls.gver(plplot_version);
    90       cs << plplot_version << "\n";
    91       delete [] plplot_version;
    92 #endif
     81      cs << extra_;
    9382    }
    9483    exit(EXIT_SUCCESS);
    9584  }
    9685
     86
     87  void OptionVersion::extra(const std::string& str)
     88  {
     89    extra_ = str;
     90  }
     91
     92
     93  void OptionVersion::program_name(const std::string& str)
     94  {
     95    prog_name_ = str;
     96  }
     97
    9798}} // of namespace svndigest and theplu
  • trunk/lib/OptionVersion.h

    r1059 r1060  
    5858
    5959    /**
     60       add extra string appended to output
     61     */
     62    void extra(const std::string&);
     63
     64    /**
     65       set program name
     66     */
     67    void program_name(const std::string&);
     68
     69    /**
    6070       \brief set version string
    6171    */
     
    6474  private:
    6575    OptionSwitch* const verbose_;
    66 
     76    std::string extra_;
     77    std::string prog_name_;
    6778
    6879    /**
  • trunk/test/svncopyright_test.sh

    r1055 r1060  
    3131done
    3232
     33../bin/svncopyright --version | head -n 1 | grep svncopyright || exit_fail
     34
    3335exit_success
Note: See TracChangeset for help on using the changeset viewer.