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