ARTS  2.3.1285(git:92a29ea9-dirty)
parameters.cc
Go to the documentation of this file.
1 /* Copyright (C) 2000-2012 Stefan Buehler <sbuehler@ltu.se>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
28 #include <cstdio>
29 #include <cstdlib>
30 #include <iostream>
31 #include "arts.h"
32 #ifdef HAVE_GETOPT_H
33 #include <getopt.h>
34 #else
35 #include <arts_getopt.h>
36 #endif
37 #include "file.h"
38 #include "parameters.h"
39 
42 
44 
54  char *envval = getenv(envvar.c_str());
55  if (envval) {
56  String pathstring(envval);
57 
58  // Skip delimiters at beginning.
59  String::size_type lastPos = pathstring.find_first_not_of(":", 0);
60  // Find first "non-delimiter".
61  String::size_type pos = pathstring.find_first_of(":", lastPos);
62 
63  while (String::npos != pos || String::npos != lastPos) {
64  paths.push_back(pathstring.substr(lastPos, pos - lastPos));
65  lastPos = pathstring.find_first_not_of(":", pos);
66  pos = pathstring.find_first_of(":", lastPos);
67  }
68  }
69 }
70 
71 bool get_parameters(int argc, char **argv) {
72  /*
73  The header file getopt.h declares some external variables:
74 
75  extern char *optarg; (argument value for options that take an argument)
76  extern int optind; (index in ARGV of the next element to be scanned.)
77  extern int opterr; (we don�t use this)
78  extern int optopt; (set to an option caracter that was recoginized)
79  */
80 
81  /*
82  From the GNU documentation:
83 
84  Describe the long-named options requested by the application.
85  The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
86  of `struct option' terminated by an element containing a name which is
87  zero.
88 
89  The field `has_arg' is:
90  no_argument (or 0) if the option does not take an argument,
91  required_argument (or 1) if the option requires an argument,
92  optional_argument (or 2) if the option takes an optional argument.
93 
94  If the field `flag' is not NULL, it points to a variable that is set
95  to the value given in the field `val' when the option is found, but
96  left unchanged if the option is not found.
97 
98  To have a long-named option do something other than set an `int' to
99  a compiled-in constant, such as set a value from `optarg', set the
100  option's `flag' field to zero and its `val' field to a nonzero
101  value (the equivalent single-letter option character, if there is
102  one). For long options that have a zero `flag' field, `getopt'
103  returns the contents of the `val' field.
104 
105  struct option
106  {
107  #if defined (__STDC__) && __STDC__
108  const char *name;
109  #else
110  char *name;
111  #endif
112  int has_arg;
113  int *flag;
114  int val;
115  };
116  */
117  struct option longopts[] = {
118  {"basename", required_argument, NULL, 'b'},
119 #ifdef ENABLE_DOCSERVER
120  {"check-docs", no_argument, NULL, 'C'},
121 #endif
122  {"describe", required_argument, NULL, 'd'},
123  {"groups", no_argument, NULL, 'g'},
124  {"help", no_argument, NULL, 'h'},
125  {"includepath", required_argument, NULL, 'I'},
126  {"datapath", required_argument, NULL, 'D'},
127  {"input", required_argument, NULL, 'i'},
128  {"methods", required_argument, NULL, 'm'},
129  {"numthreads", required_argument, NULL, 'n'},
130  {"outdir", required_argument, NULL, 'o'},
131  {"plain", no_argument, NULL, 'p'},
132  {"reporting", required_argument, NULL, 'r'},
133 #ifdef ENABLE_DOCSERVER
134  {"docserver", optional_argument, NULL, 's'},
135  {"docdaemon", optional_argument, NULL, 'S'},
136  {"baseurl", required_argument, NULL, 'U'},
137 #endif
138  {"workspacevariables", required_argument, NULL, 'w'},
139  {"version", no_argument, NULL, 'v'},
140  {NULL, no_argument, NULL, 0}};
141 
142  parameters.usage =
143  "Usage: arts [-bBdghimnrsSvw]\n"
144  " [--basename <name>]\n"
145  " [--describe <method or variable>]\n"
146  " [--groups]\n"
147  " [--help]\n"
148  " [--includepath <path>]\n"
149  " [--datapath <path>]\n"
150  " [--input <variable>]\n"
151  " [--methods all|<variable>]\n"
152  " [--numthreads <#>\n"
153  " [--outdir <name>]\n"
154  " [--plain]\n"
155  " [--reporting <xyz>]\n"
156 #ifdef ENABLE_DOCSERVER
157  " [--docserver[=<port>] --baseurl=BASEURL]\n"
158  " [--docdaemon[=<port>] --baseurl=BASEURL]\n"
159 #endif
160  " [--workspacevariables all|<method>]\n"
161  " file1.arts file2.arts ...";
162 
163  parameters.helptext =
164  "The Atmospheric Radiative Transfer Simulator.\n\n"
165  "-b, --basename Set the basename for the report\n"
166  " file and for other output files.\n"
167  "-d, --describe Print the description String of the given\n"
168  " workspace variable or method.\n"
169  "-g --groups List all workspace variable groups.\n"
170  "-h, --help Print this message.\n"
171  "-i, --input This is complementary to the --methods switch.\n"
172  " It must be given the name of a variable (or group).\n"
173  " Then it lists all methods that take this variable\n"
174  " (or group) as input.\n"
175  "-I --includepath Search path for include files. Can be given more\n"
176  " than once to add several paths.\n"
177  " Include paths can also be added by setting the\n"
178  " environment variable ARTS_INCLUDE_PATH. Multiple\n"
179  " paths have to be separated by colons.\n"
180  " Paths specified on the commandline have precedence\n"
181  " over the environment variable and will be searched\n"
182  " first.\n"
183  "-D --datapath Additional search path for data files. Directories\n"
184  " specified here will be searched after the includepath.\n"
185  " Data paths can also be added by setting the\n"
186  " environment variable ARTS_DATA_PATH.\n"
187  "-m, --methods If this is given the argument 'all',\n"
188  " it simply prints a list of all methods.\n"
189  " If it is given the name of a variable\n"
190  " (or variable group), it prints all\n"
191  " methods that produce this\n"
192  " variable (or group) as output.\n"
193  "-n, --numthreads If arts was compiled with OpenMP support this option\n"
194  " can be used to set the maximum number of threads.\n"
195  " By default OpenMP uses all processors/cores.\n"
196  "-o, --outdir Set the output directory for the report\n"
197  " file and for other output files with relative paths.\n"
198  " Default is the current directory.\n"
199  "-p --plain Generate plain help output suitable for\n"
200  " script processing.\n"
201  "-r, --reporting Three digit integer. Sets the reporting\n"
202  " level for agenda calls (first digit),\n"
203  " screen (second digit) and file (third \n"
204  " digit). All reporting levels can reach from 0\n"
205  " (only error messages) to 3 (everything).\n"
206  " The agenda setting applies in addition to both\n"
207  " screen and file output.\n"
208  " Default is 010.\n"
209 #ifdef ENABLE_DOCSERVER
210  "-s, --docserver Start documentation server. Optionally, specify\n"
211  " the port number the server should listen on,\n"
212  " e.g. arts -s9999 or arts --docserver=9999.\n"
213  " Default is 9000.\n"
214  "-S, --docdaemon Start documentation server in the background.\n"
215  "-U, --baseurl Base URL for the documentation server.\n"
216 #endif
217  "-v, --version Show version information.\n"
218  "-w, --workspacevariables If this is given the argument 'all',\n"
219  " it simply prints a list of all variables.\n"
220  " If it is given the name of a method, it\n"
221  " prints all variables needed by this method.\n"
222 #ifdef ENABLE_DOCSERVER
223  "\nDEVELOPER ONLY:\n\n"
224  "-C, --check-docs Check for broken links in built-in docs.\n"
225 #endif
226  ;
227 
228  // Set the short options automatically from the last columns of
229  // longopts.
230  //
231  // Watch out! We also have to put in colons after options that take
232  // an argument, and a double colon for options with optional
233  // arguments. (Watch out, optional arguments only work with GNU
234  // getopt. But since the GNU getopt source code is included with
235  // ARTS, why not use this feature?)
236  //
237  String shortopts;
238  {
239  int i = 0;
240  while (NULL != longopts[i].name) {
241  char c = (char)longopts[i].val;
242  shortopts += c;
243  // cout << "name = " << longopts[i].name << "\n";
244  // cout << "val = " << longopts[i].val << "\n";
245 
246  // Check if we need to insert a colon
247  if (required_argument == longopts[i].has_arg) {
248  shortopts += ":";
249  }
250 
251  // Or a double colon maybe?
252  if (optional_argument == longopts[i].has_arg) {
253  shortopts += "::";
254  }
255 
256  ++i;
257  }
258  shortopts += '\0';
259  }
260  // cout << "shortopts: " << shortopts << '\n';
261 
262  int optc;
263 
264  while (EOF != (optc = getopt_long(
265  argc, argv, shortopts.c_str(), longopts, (int *)0))) {
266  // cout << "optc = " << optc << '\n';
267  switch (optc) {
268  case 'h':
269  parameters.help = true;
270  break;
271  case 'C':
272  parameters.check_docs = true;
273  break;
274  case 'b':
275  parameters.basename = optarg;
276  break;
277  case 'd':
278  parameters.describe = optarg;
279  break;
280  case 'g':
281  parameters.groups = true;
282  break;
283  case 'G':
284  parameters.gui = true;
285  break;
286  case 'i':
287  parameters.input = optarg;
288  break;
289  case 'I':
290  parameters.includepath.push_back(optarg);
291  break;
292  case 'D':
293  parameters.datapath.push_back(optarg);
294  break;
295  case 'm':
296  parameters.methods = optarg;
297  break;
298  case 'n': {
299  istringstream iss(optarg);
300  iss >> std::dec >> parameters.numthreads;
301  if (iss.bad() || !iss.eof()) {
302  cerr << "Argument to --numthreads (-n) must be an integer!\n";
303  arts_exit();
304  }
305  break;
306  }
307  case 'o':
308  parameters.outdir = optarg;
309  break;
310  case 'p':
311  parameters.plain = true;
312  break;
313  case 'r': {
314  // cout << "optarg = " << optarg << endl;
315  istringstream iss(optarg);
316  iss >> parameters.reporting;
317  ws(iss);
318  // This if statement should cover all cases: If there is
319  // no integer at all, is becomes bad (first condition). If
320  // there is something else behind the integer, ws does not
321  // reach the end of is (second condition).
322  if (iss.bad() || !iss.eof()) {
323  cerr << "Argument to --reporting (-r) must be an integer!\n";
324  arts_exit();
325  }
326  break;
327  }
328  case 's': {
329  if (optarg) {
330  istringstream iss(optarg);
331  iss >> std::dec >> parameters.docserver;
332  if (iss.bad() || !iss.eof()) {
333  cerr << "Argument to --docserver (-s) must be an integer!\n";
334  arts_exit();
335  }
336  } else
337  parameters.docserver = -1;
338  break;
339  }
340  case 'S': {
341  if (optarg) {
342  istringstream iss(optarg);
343  iss >> std::dec >> parameters.docserver;
344  if (iss.bad() || !iss.eof()) {
345  cerr << "Argument to --docdaemon (-S) must be an integer!\n";
346  arts_exit();
347  }
348  } else
349  parameters.docserver = -1;
350 
351  parameters.daemon = true;
352  break;
353  }
354  case 'U':
355  parameters.baseurl = optarg;
356  break;
357  case 'v':
358  parameters.version = true;
359  break;
360  case 'w':
361  parameters.workspacevariables = optarg;
362  break;
363  default:
364  // There were strange options.
365  return (1);
366  break;
367  }
368  }
369 
370  // Remaining things on the command line must be control file names.
371  // Get them one by one.
372  while (optind < argc) {
373  String dummy = argv[optind];
374  if (dummy.nelem()) parameters.controlfiles.push_back(dummy);
375  optind++;
376  }
377 
378  // Look for include paths in the ARTS_INCLUDE_PATH environment variable and
379  // append them to parameters.includepath
380 
381  parse_path_from_environment(String("ARTS_INCLUDE_PATH"),
382  parameters.includepath);
383  parse_path_from_environment(String("ARTS_DATA_PATH"), parameters.datapath);
384 
385 #ifdef ARTS_DEFAULT_INCLUDE_DIR
386  String arts_default_include_path(ARTS_DEFAULT_INCLUDE_DIR);
387  if (arts_default_include_path != "" && !parameters.includepath.nelem()) {
388  // Skip delimiters at beginning.
389  String::size_type lastPos =
390  arts_default_include_path.find_first_not_of(":", 0);
391  // Find first "non-delimiter".
392  String::size_type pos =
393  arts_default_include_path.find_first_of(":", lastPos);
394 
395  while (String::npos != pos || String::npos != lastPos) {
396  parameters.includepath.push_back(
397  arts_default_include_path.substr(lastPos, pos - lastPos));
398  lastPos = arts_default_include_path.find_first_not_of(":", pos);
399  pos = arts_default_include_path.find_first_of(":", lastPos);
400  }
401  }
402 #endif
403 
404  parameters.includepath.insert(parameters.includepath.begin(), ".");
405  parameters.datapath.insert(parameters.datapath.begin(), ".");
406 
407  if (parameters.outdir.nelem())
408  parameters.datapath.insert(parameters.datapath.begin(), parameters.outdir);
409 
410  if (parameters.controlfiles.nelem()) {
411  String cfdirname;
412  get_dirname(cfdirname, parameters.controlfiles[0]);
413  if (cfdirname.nelem()) parameters.includepath.push_back(cfdirname);
414  }
415 
416  return false;
417 }
bool daemon
Flag to run the docserver in the background.
Definition: parameters.h:129
ArrayOfString controlfiles
The filenames of the controlfiles.
Definition: parameters.h:90
Parameters parameters
Holds the command line parameters.
Definition: parameters.cc:41
#define no_argument
Definition: arts_getopt.h:96
int val
Definition: arts_getopt.h:91
Index nelem() const
Number of elements.
Definition: array.h:195
void arts_exit(int status)
This is the exit function of ARTS.
Definition: arts.cc:42
String baseurl
Baseurl for the docserver.
Definition: parameters.h:127
bool check_docs
Flag to check built-in documentation.
Definition: parameters.h:133
String basename
If this is specified (with the -b –basename option), it is used as the base name for the report file...
Definition: parameters.h:82
char * name
Definition: arts_getopt.h:85
bool groups
Print a list of all workspace variable groups.
Definition: parameters.h:121
void get_dirname(String &dirname, const String &path)
Return the parent directory of a path.
Definition: file.cc:519
This file contains basic functions to handle ASCII files.
Structure to hold all command line Parameters.
Definition: parameters.h:42
String methods
If this is given the argument `all&#39;, it simply prints a list of all methods.
Definition: parameters.h:102
void parse_path_from_environment(String envvar, ArrayOfString &paths)
Parse path environment variable.
Definition: parameters.cc:53
String input
This is complementary to the methods switch.
Definition: parameters.h:112
ArrayOfString includepath
List of paths to search for include files.
Definition: parameters.h:106
int optind
ArrayOfString datapath
List of paths to search for data files.
Definition: parameters.h:108
String outdir
If this is specified (with the -o –outdir option), it is used as the base directory for the report f...
Definition: parameters.h:87
Index numthreads
The maximum number of threads to use.
Definition: parameters.h:104
The global header file for ARTS.
bool help
Only display the help text.
Definition: parameters.h:76
Index reporting
This should be a two digit integer.
Definition: parameters.h:98
Index docserver
Port to use for the docserver.
Definition: parameters.h:125
Index nelem() const
Number of elements.
Definition: mystring.h:246
String usage
Short message how to call the program.
Definition: parameters.h:72
bool gui
Flag to run with graphical user interface.
Definition: parameters.h:131
This can be used to make arrays out of anything.
Definition: array.h:40
#define optional_argument
Definition: arts_getopt.h:98
int getopt_long()
#define ARTS_DEFAULT_INCLUDE_DIR
Definition: config.h:13
bool get_parameters(int argc, char **argv)
Get the command line parameters.
Definition: parameters.cc:71
String workspacevariables
If this is given the argument `all&#39;, it simply prints a list of all workspace variables.
Definition: parameters.h:116
bool version
Display version information.
Definition: parameters.h:78
char * optarg
static const Index npos
Define npos:
Definition: mystring.h:106
int has_arg
Definition: arts_getopt.h:89
This file contains header information for the dealing with command line parameters.
bool plain
Generate plain help out suitable for script processing.
Definition: parameters.h:123
#define required_argument
Definition: arts_getopt.h:97
my_basic_string< char > String
The String type for ARTS.
Definition: mystring.h:280
String describe
Print the description String of the given workspace variable or method.
Definition: parameters.h:119
String helptext
Longer message explaining the options.
Definition: parameters.h:74