Tidy: modernize-use-nullptr
[alexxy/gromacs.git] / src / gromacs / commandline / filenm.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014,2015,2016,2017, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 #include "gmxpre.h"
38
39 #include "filenm.h"
40
41 #include <cstdio>
42 #include <cstring>
43
44 #include "gromacs/fileio/filetypes.h"
45 #include "gromacs/utility/basedefinitions.h"
46 #include "gromacs/utility/cstringutil.h"
47 #include "gromacs/utility/smalloc.h"
48
49 /* Use bitflag ... */
50 #define IS_SET(fn) ((fn.flag &ffSET) != 0)
51 #define IS_OPT(fn) ((fn.flag &ffOPT) != 0)
52
53 const t_filenm *getFilenm(const char *opt, int nfile, const t_filenm fnm[])
54 {
55     int i;
56
57     for (i = 0; (i < nfile); i++)
58     {
59         if (strcmp(opt, fnm[i].opt) == 0)
60         {
61             return &fnm[i];
62         }
63     }
64
65     return nullptr;
66 }
67
68 const char *opt2fn(const char *opt, int nfile, const t_filenm fnm[])
69 {
70     int i;
71
72     for (i = 0; (i < nfile); i++)
73     {
74         if (std::strcmp(opt, fnm[i].opt) == 0)
75         {
76             return fnm[i].fns[0];
77         }
78     }
79
80     fprintf(stderr, "No option %s\n", opt);
81
82     return nullptr;
83 }
84
85 int opt2fns(char **fns[], const char *opt, int nfile, const t_filenm fnm[])
86 {
87     int i;
88
89     for (i = 0; (i < nfile); i++)
90     {
91         if (strcmp(opt, fnm[i].opt) == 0)
92         {
93             *fns = fnm[i].fns;
94             return fnm[i].nfiles;
95         }
96     }
97
98     fprintf(stderr, "No option %s\n", opt);
99     return 0;
100 }
101
102 const char *ftp2fn(int ftp, int nfile, const t_filenm fnm[])
103 {
104     int i;
105
106     for (i = 0; (i < nfile); i++)
107     {
108         if (ftp == fnm[i].ftp)
109         {
110             return fnm[i].fns[0];
111         }
112     }
113
114     fprintf(stderr, "ftp2fn: No filetype %s\n", ftp2ext_with_dot(ftp));
115     return nullptr;
116 }
117
118 int ftp2fns(char **fns[], int ftp, int nfile, const t_filenm fnm[])
119 {
120     int i;
121
122     for (i = 0; (i < nfile); i++)
123     {
124         if (ftp == fnm[i].ftp)
125         {
126             *fns = fnm[i].fns;
127             return fnm[i].nfiles;
128         }
129     }
130
131     fprintf(stderr, "ftp2fn: No filetype %s\n", ftp2ext_with_dot(ftp));
132     return 0;
133 }
134
135 gmx_bool ftp2bSet(int ftp, int nfile, const t_filenm fnm[])
136 {
137     int i;
138
139     for (i = 0; (i < nfile); i++)
140     {
141         if (ftp == fnm[i].ftp)
142         {
143             return (gmx_bool) IS_SET(fnm[i]);
144         }
145     }
146
147     fprintf(stderr, "ftp2fn: No filetype %s\n", ftp2ext_with_dot(ftp));
148
149     return FALSE;
150 }
151
152 gmx_bool opt2bSet(const char *opt, int nfile, const t_filenm fnm[])
153 {
154     int i;
155
156     for (i = 0; (i < nfile); i++)
157     {
158         if (std::strcmp(opt, fnm[i].opt) == 0)
159         {
160             return (gmx_bool) IS_SET(fnm[i]);
161         }
162     }
163
164     fprintf(stderr, "No option %s\n", opt);
165
166     return FALSE;
167 }
168
169 const char *opt2fn_null(const char *opt, int nfile, const t_filenm fnm[])
170 {
171     int i;
172
173     for (i = 0; (i < nfile); i++)
174     {
175         if (std::strcmp(opt, fnm[i].opt) == 0)
176         {
177             if (IS_OPT(fnm[i]) && !IS_SET(fnm[i]))
178             {
179                 return nullptr;
180             }
181             else
182             {
183                 return fnm[i].fns[0];
184             }
185         }
186     }
187     fprintf(stderr, "No option %s\n", opt);
188     return nullptr;
189 }
190
191 const char *ftp2fn_null(int ftp, int nfile, const t_filenm fnm[])
192 {
193     int i;
194
195     for (i = 0; (i < nfile); i++)
196     {
197         if (ftp == fnm[i].ftp)
198         {
199             if (IS_OPT(fnm[i]) && !IS_SET(fnm[i]))
200             {
201                 return nullptr;
202             }
203             else
204             {
205                 return fnm[i].fns[0];
206             }
207         }
208     }
209     fprintf(stderr, "ftp2fn: No filetype %s\n", ftp2ext_with_dot(ftp));
210     return nullptr;
211 }
212
213 gmx_bool is_optional(const t_filenm *fnm)
214 {
215     return ((fnm->flag & ffOPT) == ffOPT);
216 }
217
218 gmx_bool is_output(const t_filenm *fnm)
219 {
220     return ((fnm->flag & ffWRITE) == ffWRITE);
221 }
222
223 gmx_bool is_set(const t_filenm *fnm)
224 {
225     return ((fnm->flag & ffSET) == ffSET);
226 }
227
228 int add_suffix_to_output_names(t_filenm *fnm, int nfile, const char *suffix)
229 {
230     int   i, j;
231     char  buf[STRLEN], newname[STRLEN];
232     char *extpos;
233
234     for (i = 0; i < nfile; i++)
235     {
236         if (is_output(&fnm[i]) && fnm[i].ftp != efCPT)
237         {
238             /* We never use multiple _outputs_, but we might as well check
239                for it, just in case... */
240             for (j = 0; j < fnm[i].nfiles; j++)
241             {
242                 std::strncpy(buf, fnm[i].fns[j], STRLEN - 1);
243                 extpos  = strrchr(buf, '.');
244                 *extpos = '\0';
245                 sprintf(newname, "%s%s.%s", buf, suffix, extpos + 1);
246                 sfree(fnm[i].fns[j]);
247                 fnm[i].fns[j] = gmx_strdup(newname);
248             }
249         }
250     }
251     return 0;
252 }
253
254 t_filenm *dup_tfn(int nf, const t_filenm tfn[])
255 {
256     int       i, j;
257     t_filenm *ret;
258
259     snew(ret, nf);
260     for (i = 0; i < nf; i++)
261     {
262         ret[i] = tfn[i]; /* just directly copy all non-string fields */
263         if (tfn[i].opt)
264         {
265             ret[i].opt = gmx_strdup(tfn[i].opt);
266         }
267         else
268         {
269             ret[i].opt = nullptr;
270         }
271
272         if (tfn[i].fn)
273         {
274             ret[i].fn = gmx_strdup(tfn[i].fn);
275         }
276         else
277         {
278             ret[i].fn = nullptr;
279         }
280
281         if (tfn[i].nfiles > 0)
282         {
283             snew(ret[i].fns, tfn[i].nfiles);
284             for (j = 0; j < tfn[i].nfiles; j++)
285             {
286                 ret[i].fns[j] = gmx_strdup(tfn[i].fns[j]);
287             }
288         }
289     }
290     return ret;
291 }
292
293 void done_filenms(int nf, t_filenm fnm[])
294 {
295     int i, j;
296
297     for (i = 0; i < nf; ++i)
298     {
299         for (j = 0; j < fnm[i].nfiles; ++j)
300         {
301             sfree(fnm[i].fns[j]);
302         }
303         sfree(fnm[i].fns);
304         fnm[i].fns = nullptr;
305     }
306 }