Merge release-4-6 into master
[alexxy/gromacs.git] / src / testutils / cmdlinetest.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Implements gmx::test::CommandLine.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_testutils
37  */
38 #include "cmdlinetest.h"
39
40 #include <cstdlib>
41 #include <cstring>
42
43 #include <new>
44 #include <vector>
45
46 #include "gromacs/utility/programinfo.h"
47
48 namespace gmx
49 {
50 namespace test
51 {
52
53 /********************************************************************
54  * CommandLine::Impl
55  */
56
57 class CommandLine::Impl
58 {
59     public:
60         Impl(const char *const cmdline[], size_t count);
61         ~Impl();
62
63         std::vector<char *>     args_;
64         std::vector<char *>     argv_;
65         int                     argc_;
66 };
67
68 CommandLine::Impl::Impl(const char *const cmdline[], size_t count)
69 {
70     args_.reserve(count);
71     argv_.reserve(count);
72     argc_ = static_cast<int>(count);
73     for (size_t i = 0; i < count; ++i)
74     {
75         char *arg = strdup(cmdline[i]);
76         if (arg == NULL)
77         {
78             throw std::bad_alloc();
79         }
80         args_.push_back(arg);
81         argv_.push_back(arg);
82     }
83 }
84
85 CommandLine::Impl::~Impl()
86 {
87     for (size_t i = 0; i < args_.size(); ++i)
88     {
89         std::free(args_[i]);
90     }
91 }
92
93 /********************************************************************
94  * CommandLine
95  */
96
97 CommandLine::CommandLine()
98     : impl_(new Impl(NULL, 0))
99 {
100 }
101
102 CommandLine::CommandLine(const char *const cmdline[], size_t count)
103     : impl_(new Impl(cmdline, count))
104 {
105 }
106
107 CommandLine::CommandLine(const CommandLine &other)
108     : impl_(new Impl(other.argv(), other.argc()))
109 {
110 }
111
112 CommandLine::~CommandLine()
113 {
114 }
115
116 void CommandLine::append(const char *arg)
117 {
118     size_t newSize = impl_->args_.size() + 1;
119     impl_->args_.reserve(newSize);
120     impl_->argv_.reserve(newSize);
121     char *newArg = strdup(arg);
122     if (newArg == NULL)
123     {
124         throw std::bad_alloc();
125     }
126     impl_->args_.push_back(newArg);
127     impl_->argv_.push_back(newArg);
128     impl_->argc_ = static_cast<int>(newSize);
129 }
130
131 int &CommandLine::argc()
132 {
133     return impl_->argc_;
134 }
135 char **CommandLine::argv()
136 {
137     return &impl_->argv_[0];
138 }
139 int CommandLine::argc() const
140 {
141     return impl_->argc_;
142 }
143 const char *const *CommandLine::argv() const
144 {
145     return &impl_->argv_[0];
146 }
147 const char *CommandLine::arg(int i) const
148 {
149     return impl_->argv_[i];
150 }
151
152 std::string CommandLine::toString() const
153 {
154     return ProgramInfo(argc(), argv()).commandLine();
155 }
156
157 } // namespace test
158 } // namespace gmx