cdo.cc 50.6 KB
Newer Older
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1
/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
2
  This file is part of CDO. CDO is a collection of Operators to
Uwe Schulzweida's avatar
Uwe Schulzweida committed
3
4
  manipulate and analyse Climate model Data.

Uwe Schulzweida's avatar
Uwe Schulzweida committed
5
  Copyright (C) 2003-2017 Uwe Schulzweida, <uwe.schulzweida AT mpimet.mpg.de>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
6
7
8
9
10
11
12
13
14
15
16
17
  See COPYING file for copying and redistribution conditions.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; version 2 of the License.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
*/

Uwe Schulzweida's avatar
Uwe Schulzweida committed
18
#if defined(HAVE_CONFIG_H)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
19
20
21
#  include "config.h"
#endif

22
#ifndef _XOPEN_SOURCE
Uwe Schulzweida's avatar
Uwe Schulzweida committed
23
//#define _XOPEN_SOURCE 600 /* gethostname */
24
25
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
26
27
28
29
#if defined (HAVE_EXECINFO_H)
#include <execinfo.h>
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
30
31
#include <signal.h>
#include <fenv.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
32
/*#include <malloc.h>*/ /* mallopt and malloc_stats */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
#include <sys/stat.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
35
#if defined(HAVE_GETRLIMIT)
#if defined(HAVE_SYS_RESOURCE_H)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
36
37
#include <sys/time.h>       /* getrlimit */
#include <sys/resource.h>   /* getrlimit */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
38
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
#endif
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
40
#include <unistd.h>         /* sysconf, gethostname */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
41

Uwe Schulzweida's avatar
Uwe Schulzweida committed
42
#if defined(SX)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
43
44
45
46
47
#define RLIM_T  long long
#else
#define RLIM_T  rlim_t
#endif

Ralf Mueller's avatar
Ralf Mueller committed
48
#include <cdi.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
49
50
#include "cdo.h"
#include "cdo_int.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
51
#include "cdo_task.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
52

Uwe Schulzweida's avatar
Uwe Schulzweida committed
53
#include "cdo_getopt.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
54

Uwe Schulzweida's avatar
Uwe Schulzweida committed
55
#if defined(HAVE_LIBPTHREAD)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
56
57
58
59
60
#include "pstream_int.h"
#include "pthread_debug.h"
#endif

#include "modules.h"
61
#include "error.h"
62
#include "grid_proj.h"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
63

Uwe Schulzweida's avatar
Uwe Schulzweida committed
64
#if defined(_OPENMP)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
65
66
67
#  include <omp.h>
#endif

Uwe Schulzweida's avatar
Uwe Schulzweida committed
68
#if ! defined(VERSION)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
69
70
71
#  define  VERSION  "0.0.1"
#endif

72
#define MAX_NUM_VARNAMES 256
73

74
75
#include <string>

76
77
78
79
80
static int Debug = 0;
static int Version = 0;
static int Help = 0;
static int DebugLevel = 0;
static int numThreads = 0;
81
static int timer_total;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
82
83
static int CDO_netcdf_hdr_pad = 0;
static int CDO_Rusage = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
84
static const char *username;
85

86
87
88
89
90
91
92
93
#ifdef __cplusplus
extern "C" {
#endif
void streamGrbDefDataScanningMode(int scanmode);
#if defined (__cplusplus)
}
#endif

94
void gridsearch_set_method(const char *methodstr);
95

Uwe Schulzweida's avatar
Uwe Schulzweida committed
96
97
#define PRINT_RLIMIT(resource) \
      { \
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
        int status; \
        struct rlimit rlim; \
        status = getrlimit(resource, &rlim); \
        if ( status == 0 ) \
          { \
            if ( sizeof(RLIM_T) > sizeof(long) ) \
              { \
                fprintf(stderr, "CUR %-15s = %llu\n", #resource, (long long) rlim.rlim_cur); \
                fprintf(stderr, "MAX %-15s = %llu\n", #resource, (long long) rlim.rlim_max); \
              } \
            else \
              { \
                fprintf(stderr, "CUR %-15s = %lu\n", #resource, (long) rlim.rlim_cur); \
                fprintf(stderr, "MAX %-15s = %lu\n", #resource, (long) rlim.rlim_max); \
              } \
          } \
Uwe Schulzweida's avatar
Uwe Schulzweida committed
114
115
      }

116
#define ITSME  (strcmp(username, "\x6d\x32\x31\x34\x30\x30\x33") == 0)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
117

Uwe Schulzweida's avatar
Uwe Schulzweida committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
static
void cdo_stackframe(void)
{
#if defined HAVE_EXECINFO_H && defined HAVE_BACKTRACE
  void *callstack[32];
  int frames = backtrace(callstack, 32);
  char **messages = backtrace_symbols(callstack, frames);

  fprintf(stderr, "[bt] Execution path:\n");
  if ( messages ) {
    for ( int i = 0; i < frames; ++i )
      fprintf(stderr, "[bt] %s\n", messages[i]);
    free(messages);
  }
#endif
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
135
static
136
int cdo_feenableexcept(int excepts)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
137
{
138
#if defined HAVE_FEENABLEEXCEPT
139
140
  int feenableexcept(int);
  int old_excepts = feenableexcept(excepts);
141
142
  return old_excepts;
#else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
143
  static fenv_t fenv;
144
145
  unsigned new_excepts = ((unsigned)excepts) & FE_ALL_EXCEPT;
  int old_excepts = -1;  // previous masks
Uwe Schulzweida's avatar
Uwe Schulzweida committed
146
147

  if ( fegetenv(&fenv) ) return -1;
148
149
#if defined(HAVE_FENV_T___CONTROL) && defined(HAVE_FENV_T___MXCSR)
  old_excepts = (int) (fenv.__control & FE_ALL_EXCEPT);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
150

151
152
153
  // unmask
  fenv.__control &= ~new_excepts;
  fenv.__mxcsr   &= ~(new_excepts << 7);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
154
155
156
#endif

  return ( fesetenv(&fenv) ? -1 : (int)old_excepts );
157
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
158
159
160
161
162
163
164
165
166
167
168
169
}

static
void cdo_sig_handler(int signo)
{
  if ( signo == SIGFPE )
    {
      cdo_stackframe();
      cdoAbort("floating-point exception!");
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
static
void cdo_set_digits(const char *optarg)
{
  char *ptr1 = 0;
  if ( optarg != 0 && (int) strlen(optarg) > 0 && optarg[0] != ',' )
    CDO_flt_digits = (int)strtol(optarg, &ptr1, 10);

  if ( CDO_flt_digits < 1 || CDO_flt_digits > 20 )
    cdoAbort("Unreasonable value for float significant digits: %d", CDO_flt_digits);

  if ( ptr1 && *ptr1 == ',' )
    {
      char *ptr2 = 0;
      CDO_dbl_digits = (int)strtol(ptr1+1, &ptr2, 10);
      if  ( ptr2 == ptr1+1 || CDO_dbl_digits < 1 || CDO_dbl_digits > 20 )
        cdoAbort("Unreasonable value for double significant digits: %d", CDO_dbl_digits);
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
190
191
static
void cdo_version(void)
{
192
  const int   filetypes[] = {CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C};
193
  const char* typenames[] = {        "srv",        "ext",        "ieg",       "grb1",        "grb2",       "nc1",        "nc2",        "nc4",        "nc4c"};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
194
195

  fprintf(stderr, "%s\n", CDO_Version);
196
#if defined(USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
197
  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n", USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
198
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
199
#if defined(COMPILER)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
200
201
  fprintf(stderr, "Compiler: %s\n", COMPILER);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
202
#if defined(COMP_VERSION)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
203
204
205
206
207
  fprintf(stderr, " version: %s\n", COMP_VERSION);
#endif

  printFeatures();
  printLibraries();
208

Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
  fprintf(stderr, "Filetypes: ");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
210
  set_text_color(stderr, BRIGHT, GREEN);
211
212
  for ( size_t i = 0; i < sizeof(filetypes)/sizeof(int); ++i )
    if ( cdiHaveFiletype(filetypes[i]) ) fprintf(stderr, "%s ", typenames[i]);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213
  reset_text_color(stderr);
214
215
  fprintf(stderr, "\n");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
217
218
219
  cdiPrintVersion();
  fprintf(stderr, "\n");
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
221
void cdo_usage(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
222
{
223
  const char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
225
226

  /*  fprintf(stderr, "%s\n", CDO_Version);*/
  /*  fprintf(stderr, "\n");*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
227
  fprintf(stderr, "usage : cdo  [Options]  Operator1  [-Operator2  [-OperatorN]]\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
228
229
  fprintf(stderr, "\n");
  fprintf(stderr, "  Options:\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
230
  set_text_color(stderr, RESET, BLUE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
231
  fprintf(stderr, "    -a             Generate an absolute time axis\n");
232
  fprintf(stderr, "    -b <nbits>     Set the number of bits for the output precision\n");
233
  fprintf(stderr, "                   (I8/I16/I32/F32/F64 for nc1/nc2/nc4/nc4c; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb1/grb2)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
234
  fprintf(stderr, "                   Add L or B to set the byteorder to Little or Big endian\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
235
236
  fprintf(stderr, "    --cmor         CMOR conform NetCDF output\n");
  fprintf(stderr, "    -C, --color    Colorized output messages\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
237
238
  fprintf(stderr, "    --enableexcept <except>\n");
  fprintf(stderr, "                   Set individual floating-point traps (DIVBYZERO, INEXACT, INVALID, OVERFLOW, UNDERFLOW, ALL_EXCEPT)\n");
239
  fprintf(stderr, "    -f, --format <format>\n");
240
  fprintf(stderr, "                   Format of the output file. (grb1/grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
241
  fprintf(stderr, "    -g <grid>      Set default grid name or file. Available grids: \n");
242
  fprintf(stderr, "                   n<N>, t<RES>, tl<RES>, global_<DXY>, r<NX>x<NY>, g<NX>x<NY>, gme<NI>, lon=<LON>/lat=<LAT>\n");
243
  fprintf(stderr, "    -h, --help     Help information for the operators\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
244
  fprintf(stderr, "    --history      Do not append to NetCDF \"history\" global attribute\n");
245
  fprintf(stderr, "    --netcdf_hdr_pad, --hdr_pad, --header_pad <nbr>\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
246
  fprintf(stderr, "                   Pad NetCDF output header with nbr bytes\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
247
248
249
  /*
  fprintf(stderr, "    -i <inst>      Institution name/file\n");
  fprintf(stderr, "                   Predefined instituts: ");
250
  for ( int id = 0; id < institutInqNumber; id++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
251
252
253
254
255
    if ( (name = institutInqNamePtr(id)) )
      fprintf(stderr, " %s", name);
  fprintf(stderr, "\n");
  */
  /* fprintf(stderr, "    -l <level>     Level file\n"); */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
256
257
  fprintf(stderr, "    -k <chunktype> NetCDF4 chunk type: auto, grid or lines\n");
  fprintf(stderr, "    -L             Lock IO (sequential access)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
  fprintf(stderr, "    -M             Switch to indicate that the I/O streams have missing values\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
  fprintf(stderr, "    -m <missval>   Set the missing value of non NetCDF files (default: %g)\n", cdiInqMissval());
260
  fprintf(stderr, "    --no_warnings  Inhibit warning messages\n");
261
  fprintf(stderr, "    -O             Overwrite existing output file, if checked\n");
262
  fprintf(stderr, "    --operators    List of all operators\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263
#if defined(_OPENMP)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
264
265
  fprintf(stderr, "    -P <nthreads>  Set number of OpenMP threads\n");
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
266
267
  fprintf(stderr, "    --percentile <method>\n");
  fprintf(stderr, "                   Percentile method: nrank, nist, numpy, numpy_lower, numpy_higher, numpy_nearest\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
268
269
  fprintf(stderr, "    --precision <float_digits[,double_digits]>\n");
  fprintf(stderr, "                   Precision to use in displaying floating-point data (default: 7,15)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
270
  fprintf(stderr, "    --reduce_dim   Reduce NetCDF dimensions (module: TIMSTAT, FLDSTAT)\n");
271
272
  if ( ITSME )
    fprintf(stderr, "    --remap_genweights\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
273
  fprintf(stderr, "    -R, --regular  Convert GRIB1 data from reduced to regular grid (cgribex only)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
274
  fprintf(stderr, "    -r             Generate a relative time axis\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
275
276
  fprintf(stderr, "    -S             Create an extra output stream for the module TIMSTAT. This stream\n");
  fprintf(stderr, "                   contains the number of non missing values for each output period.\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
277
  fprintf(stderr, "    -s, --silent   Silent mode\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
278
  fprintf(stderr, "    --sort         Alphanumeric sorting of NetCDF parameter names\n");
279
  fprintf(stderr, "    -t <codetab>   Set GRIB1 default parameter code table name or file (cgribex only)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
280
  fprintf(stderr, "                   Predefined tables: ");
281
  for ( int id = 0; id < tableInqNumber(); id++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
282
283
284
285
    if ( (name = tableInqNamePtr(id)) )
      fprintf(stderr, " %s", name);
  fprintf(stderr, "\n");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
286
287
  fprintf(stderr, "    --timestat_date <srcdate>\n");
  fprintf(stderr, "                   Target timestamp (time statistics): first, middle, midhigh or last source timestep.\n");
288
289
  fprintf(stderr, "    -V, --version  Print the version number\n");
  fprintf(stderr, "    -v, --verbose  Print extra details for some operators\n");
290
  fprintf(stderr, "    -W             Print extra warning messages\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
291
292
  fprintf(stderr, "    -z szip        SZIP compression of GRIB1 records\n");
  fprintf(stderr, "       jpeg        JPEG compression of GRIB2 records\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
293
  fprintf(stderr, "        zip[_1-9]  Deflate compression of NetCDF4 variables\n");
294
295
296
297
#ifdef HIRLAM_EXTENSIONS
  fprintf(stderr, "    --Dkext <debLev>   Setting debugLevel for extensions\n");
  fprintf(stderr, "    --outputGribDataScanningMode <mode>   Setting grib scanning mode for data in output file <0, 64, 96>; Default is 64\n");
#endif // HIRLAM_EXTENSIONS
Uwe Schulzweida's avatar
Uwe Schulzweida committed
298
  reset_text_color(stderr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
299
300
301
  fprintf(stderr, "\n");

  fprintf(stderr, "  Operators:\n");
302
303
  fprintf(stderr, "    Use option --operators for a list of all operators.\n");
  /*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
304
  set_text_color(stderr, RESET, GREEN);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305
  operatorPrintAll();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
306
  reset_text_color(stderr);
307
  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
308
309

  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
310
  fprintf(stderr, "  CDO version %s, Copyright (C) 2003-2017 Uwe Schulzweida\n", VERSION);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
  //  fprintf(stderr, "  Available from <http://mpimet.mpg.de/cdo>\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
312
  fprintf(stderr, "  This is free software and comes with ABSOLUTELY NO WARRANTY\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
  fprintf(stderr, "  Report bugs to <http://mpimet.mpg.de/cdo>\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
315
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
316
317
318
319
320
static
void cdo_init_is_tty(void)
{
  struct stat statbuf;
  fstat(0, &statbuf);
321
  if ( S_ISCHR(statbuf.st_mode) ) stdin_is_tty = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
322
  fstat(1, &statbuf);
323
  if ( S_ISCHR(statbuf.st_mode) ) stdout_is_tty = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
324
  fstat(2, &statbuf);
325
  if ( S_ISCHR(statbuf.st_mode) ) stderr_is_tty = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
326
327
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
328
static
329
void cdoPrintHelp(std::vector<std::string> help/*, char *xoperator*/)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
330
{
331
  if (help.empty())
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332
    fprintf(stderr, "No help available for this operator!\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
333
334
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
335
      bool lprint;
336
      for(unsigned long i =  0; i < help.size(); i++)
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
337
        {
338
          lprint = !(help[i][0] == '\0'  && help[i+1][0] == ' ');
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
339
340
341
342
343
          
          if ( lprint )
            {
              if ( COLOR_STDOUT )
                {
344
345
346
347
348
349
350
351
352
                  if ( (help[i].compare( "NAME")        == 0) ||
                       (help[i].compare( "SYNOPSIS")    == 0) ||
                       (help[i].compare( "DESCRIPTION") == 0) ||
                       (help[i].compare( "OPERATORS")   == 0) ||
                       (help[i].compare( "NAMELIST")    == 0) ||
                       (help[i].compare( "PARAMETER")   == 0) ||
                       (help[i].compare( "ENVIRONMENT") == 0) ||
                       (help[i].compare( "NOTE")        == 0) ||
                       (help[i].compare( "EXAMPLES")    == 0) )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
353
354
                    {
                      set_text_color(stdout, BRIGHT, BLACK);
355
                      fprintf(stdout, "%s", help[i].c_str());
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
356
357
358
359
                      reset_text_color(stdout);
                      fprintf(stdout, "\n");
                    }
                  else
360
                    fprintf(stdout, "%s\n", help[i].c_str());
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
361
362
363
                }
              else
                {
364
                  fprintf(stdout, "%s\n", help[i].c_str());
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
365
366
367
                }
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
368
369
    }
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
370
371
static
void cdoSetDebug(int level)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
{
  /*
    level   0: off
    level   1: on
    level   2: cdi
    level   4: memory
    level   8: file
    level  16: format
    level  32: cdo
    level  64: stream
    level 128: pipe
    level 256: pthread
   */
  cdiDebug(level);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
387
388
  if ( level == 1 || (level &  32) ) cdoDebug = 1;
  if ( level == 1 || (level &  64) ) pstreamDebug(1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
389
#if defined(HAVE_LIBPTHREAD)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
390
391
  if ( level == 1 || (level & 128) ) pipeDebug(1);
  if ( level == 1 || (level & 256) ) Pthread_debug(1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
392
393
394
395
396
397
#endif
}

#undef  IsBigendian
#define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )

Uwe Schulzweida's avatar
Uwe Schulzweida committed
398
static
399
void setDefaultDataType(const char *datatypestr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
400
401
{
  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
402
  int nbits = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
  enum {D_UINT, D_INT, D_FLT, D_CPX};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
404
405
  int dtype = -1;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
406
407
408
409
410
411
  int datatype = tolower(*datatypestr);
  if      ( datatype == 'i' ) { dtype = D_INT;  datatypestr++; }
  else if ( datatype == 'u' ) { dtype = D_UINT; datatypestr++; }
  else if ( datatype == 'f' ) { dtype = D_FLT;  datatypestr++; }
  else if ( datatype == 'c' ) { dtype = D_CPX;  datatypestr++; }
  else if ( datatype == 'p' ) { datatypestr++; }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
412

413
414
  if ( isdigit((int) *datatypestr) )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
415
      nbits = atoi(datatypestr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
416
417
      datatypestr += 1;
      if ( nbits >= 10 ) datatypestr += 1;
418

Uwe Schulzweida's avatar
Uwe Schulzweida committed
419
      if ( dtype == -1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
420
421
422
423
        {
          if      ( nbits > 0 && nbits < 32 ) cdoDefaultDataType = nbits;
          else if ( nbits == 32 )
            {
424
              if ( cdoDefaultFileType == CDI_FILETYPE_GRB )
425
                cdoDefaultDataType = CDI_DATATYPE_PACK32;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
426
              else
427
                cdoDefaultDataType = CDI_DATATYPE_FLT32;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
428
            }
429
          else if ( nbits == 64 ) cdoDefaultDataType = CDI_DATATYPE_FLT64;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
430
431
432
          else
            {
              fprintf(stderr, "Unsupported number of bits %d!\n", nbits);
433
              fprintf(stderr, "Use I8/I16/I32/F32/F64 for nc1/nc2/nc4/nc4c; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb1/grb2.\n");
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
434
435
436
              exit(EXIT_FAILURE);
            }
        }
437
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
438
439
440
        {
          if ( dtype == D_INT )
            {
441
442
443
              if      ( nbits ==  8 ) cdoDefaultDataType = CDI_DATATYPE_INT8;
              else if ( nbits == 16 ) cdoDefaultDataType = CDI_DATATYPE_INT16;
              else if ( nbits == 32 ) cdoDefaultDataType = CDI_DATATYPE_INT32;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
444
445
446
447
448
449
450
451
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype INT!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
          else if ( dtype == D_UINT )
            {
452
453
454
              if      ( nbits ==  8 ) cdoDefaultDataType = CDI_DATATYPE_UINT8;
              else if ( nbits == 16 ) cdoDefaultDataType = CDI_DATATYPE_UINT16;
              else if ( nbits == 32 ) cdoDefaultDataType = CDI_DATATYPE_UINT32;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
455
456
457
458
459
460
461
462
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype UINT!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
          else if ( dtype == D_FLT )
            {
463
464
              if      ( nbits == 32 ) cdoDefaultDataType = CDI_DATATYPE_FLT32;
              else if ( nbits == 64 ) cdoDefaultDataType = CDI_DATATYPE_FLT64;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
465
466
467
468
469
470
471
472
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype FLT!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
          else if ( dtype == D_CPX )
            {
473
474
              if      ( nbits == 32 ) cdoDefaultDataType = CDI_DATATYPE_CPX32;
              else if ( nbits == 64 ) cdoDefaultDataType = CDI_DATATYPE_CPX64;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
475
476
477
478
479
480
481
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype CPX!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
        }
482
483
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
484
  if ( *datatypestr != 0 )
485
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
486
      if ( *datatypestr == 'l' || *datatypestr == 'L' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
487
488
489
490
        {
          if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
          datatypestr++;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
491
      else if ( *datatypestr == 'b' || *datatypestr == 'B' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
492
493
494
495
        {
          if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
          datatypestr++;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
496
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
497
498
499
500
        {
          fprintf(stderr, "Unsupported character in number of bytes: >%s< !\n", datatypestr);
          exit(EXIT_FAILURE);
        }
501
502
    }
}
503
/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
504
505
static
void setDefaultDataTypeByte(char *datatypestr)
506
507
508
509
{
  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
  int datatype = -1;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
511
512
513
514
  if ( isdigit((int) *datatypestr) )
    {
      datatype = atoi(datatypestr);
      datatypestr++;

515
516
517
518
519
      if      ( datatype == 1 ) cdoDefaultDataType = CDI_DATATYPE_PACK8;
      else if ( datatype == 2 ) cdoDefaultDataType = CDI_DATATYPE_PACK16;
      else if ( datatype == 3 ) cdoDefaultDataType = CDI_DATATYPE_PACK24;
      else if ( datatype == 4 ) cdoDefaultDataType = CDI_DATATYPE_FLT32;
      else if ( datatype == 8 ) cdoDefaultDataType = CDI_DATATYPE_FLT64;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
520
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
521
522
        {
          fprintf(stderr, "Unsupported datatype %d!\n", datatype);
523
          fprintf(stderr, "Use 4/8 for filetype nc/srv/ext/ieg and 1/2/3 for grb1/grb2.\n");
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
524
525
          exit(EXIT_FAILURE);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
526
527
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
528
  if ( *datatypestr != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
530
      if ( *datatypestr == 'l' || *datatypestr == 'L' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
531
532
        {
          if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
533
          datatypestr++;setDefaultDataTypeByte
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
534
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
535
      else if ( *datatypestr == 'b' || *datatypestr == 'B' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
536
537
538
539
        {
          if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
          datatypestr++;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
540
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
541
542
543
544
        {
          fprintf(stderr, "Unsupported character in number of bytes: %s!\n", datatypestr);
          exit(EXIT_FAILURE);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
545
546
    }
}
547
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
548
static
549
void setDefaultFileType(const char *filetypestr, int labort)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
550
551
552
{
  if ( filetypestr )
    {
553
      const char *ftstr = filetypestr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
554
555
      size_t len;

556
557
558
559
560
561
562
563
564
565
566
      if      ( cmpstrlen(filetypestr, "grb2", len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_GRB2;}
      else if ( cmpstrlen(filetypestr, "grb1", len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_GRB; }
      else if ( cmpstrlen(filetypestr, "grb",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_GRB; }
      else if ( cmpstrlen(filetypestr, "nc2",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC2; }
      else if ( cmpstrlen(filetypestr, "nc4c", len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC4C;}
      else if ( cmpstrlen(filetypestr, "nc4",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC4; }
      else if ( cmpstrlen(filetypestr, "nc1",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC;  }
      else if ( cmpstrlen(filetypestr, "nc",   len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC2; }
      else if ( cmpstrlen(filetypestr, "srv",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_SRV; }
      else if ( cmpstrlen(filetypestr, "ext",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_EXT; }
      else if ( cmpstrlen(filetypestr, "ieg",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_IEG; }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
567
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
568
569
570
571
        {
          if ( labort )
            {
              fprintf(stderr, "Unsupported filetype %s!\n", filetypestr);
572
              fprintf(stderr, "Available filetypes: grb1/grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg\n");
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
573
574
575
576
577
578
579
              exit(EXIT_FAILURE);
            }
          else
            {
              return;
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
580

581
      if ( cdoDefaultFileType != CDI_UNDEFID && *ftstr != 0 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
582
583
584
585
586
587
588
589
590
591
592
        {
          if ( *ftstr == '_' )
            {
              ftstr++;

              setDefaultDataType(ftstr);
            }
          else
            {
              fprintf(stderr, "Unexpected character >%c< in file type >%s<!\n", *ftstr, filetypestr);
              fprintf(stderr, "Use format[_nbits] with:\n");
593
594
              fprintf(stderr, "    format = grb1, grb2, nc1, nc2, nc4, nc4c, srv, ext or ieg\n");
              fprintf(stderr, "    nbits  = 32/64 for grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg; 1 - 24 for grb1/grb2\n");
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
595
596
597
              exit(EXIT_FAILURE);
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
598
599
600
    }
}

601
#define NTESTS 11
602
#include <inttypes.h>
603
604
605
606
607
608
609
610
611
612
static
int getMemAlignment(void)
{
  int ma = -1;
  double *ptr[NTESTS];
  int64_t iptr;
  size_t tsize[NTESTS] = {1, 3, 5, 9, 17, 33, 69, 121, 251, 510, 1025};
  size_t ma_check[4] = {8, 16, 32, 64};
  int ma_result[4] = {1, 1, 1, 1};

Uwe Schulzweida's avatar
Uwe Schulzweida committed
613
  for ( int i = 0; i < NTESTS; ++i )
614
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
615
      ptr[i] = (double*) malloc(tsize[i]);
616
      iptr = (int64_t) ptr[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
617
      for ( int k = 0; k < 4; ++k ) if ( iptr%ma_check[k] ) ma_result[k] = 0; 
618
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
619
  for ( int i = 0; i < NTESTS; ++i ) free(ptr[i]);
620

Uwe Schulzweida's avatar
Uwe Schulzweida committed
621
  for ( int i = NTESTS-1; i >= 0; i-- )
622
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
623
      ptr[i] = (double*) malloc(tsize[i]+5);
624
      iptr = (int64_t) ptr[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
625
      for ( int k = 0; k < 4; ++k ) if ( iptr%ma_check[k] ) ma_result[k] = 0; 
626
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
  for ( int i = 0; i < NTESTS; ++i ) free(ptr[i]);
628

Uwe Schulzweida's avatar
Uwe Schulzweida committed
629
  for ( int k = 0; k < 4; ++k ) if ( ma_result[k] ) ma = ma_check[k];
630

Uwe Schulzweida's avatar
Uwe Schulzweida committed
631
  return ma;
632
633
}

634

Uwe Schulzweida's avatar
Uwe Schulzweida committed
635
static
636
637
638
639
void defineCompress(const char *arg)
{
  size_t len = strlen(arg);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
  if      ( strncmp(arg, "szip", len) == 0 )
641
    {
642
      cdoCompType  = CDI_COMPRESS_SZIP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
643
      cdoCompLevel = 0;
644
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
645
  else if ( strncmp(arg, "jpeg", len) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
    {
647
      cdoCompType = CDI_COMPRESS_JPEG;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
      cdoCompLevel = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
649
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
650
  else if ( strncmp(arg, "gzip", len) == 0 )
651
    {
652
      cdoCompType  = CDI_COMPRESS_GZIP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
653
      cdoCompLevel = 6;
654
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
655
  else if ( strncmp(arg, "zip", 3) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
656
    {
657
      cdoCompType  = CDI_COMPRESS_ZIP;
658
      if ( len == 5 && arg[3] == '_' && isdigit(arg[4]) )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
659
        cdoCompLevel = atoi(&arg[4]);
660
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
661
        cdoCompLevel = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
662
    }
663
  else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
664
665
666
667
668
669
670
671
672
    {
      fprintf(stderr, "Compression type '%s' unsupported!\n", arg);
      exit(EXIT_FAILURE);
    }
}

static
void defineChunktype(const char *arg)
{
673
674
675
  if      ( strcmp("auto",  arg)   == 0 ) cdoChunkType = CDI_CHUNK_AUTO;
  else if ( strcmp("grid",  arg)   == 0 ) cdoChunkType = CDI_CHUNK_GRID;
  else if ( strcmp("lines", arg)   == 0 ) cdoChunkType = CDI_CHUNK_LINES;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
676
677
678
679
680
  else
    {
      fprintf(stderr, "Chunk type '%s' unsupported!\n", arg);
      exit(EXIT_FAILURE);
    }
681
682
}

683
684
685
686
687
688
689
690
691
692
static
void defineVarnames(const char *arg)
{
  size_t len = strlen(arg);
  size_t istart = 0;
  while ( istart < len && (arg[istart] == ' ' || arg[istart] == ',') ) istart++;

  len -= istart;

  if ( len )
693
    {      
694
      cdoVarnames = (char **) Malloc(MAX_NUM_VARNAMES*sizeof(char *));
695

696
      char *pbuf = strdup(arg+istart);
697
698
      cdoVarnames[cdoNumVarnames++] = pbuf;    

699
      char *commapos = pbuf;
700
      while ( (commapos = strchr(commapos, ',')) != NULL )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
701
702
703
704
705
706
707
708
709
710
        {
          *commapos++ = '\0';
          if ( strlen(commapos) )
            {
              if ( cdoNumVarnames >= MAX_NUM_VARNAMES )
                cdoAbort("Too many variable names (limit=%d)!", MAX_NUM_VARNAMES);

              cdoVarnames[cdoNumVarnames++] = commapos;
            }
        }
711
712
      /*
      for ( int i = 0; i < cdoNumVarnames; ++i )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
713
        printf("varname %d: %s\n", i+1, cdoVarnames[i]);
714
715
716
717
      */
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
718
719
720
static
void get_env_vars(void)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
721
722
723
724
725
726
727
  username = getenv("LOGNAME");
  if ( username == NULL )
    {
      username = getenv("USER");
      if ( username == NULL ) username = "unknown";
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
728
  char *envstr = getenv("CDO_GRID_SEARCH_DIR");
729
730
731
732
  if ( envstr )
    {
      size_t len = strlen(envstr);
      if ( len > 0 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
733
734
        {
          len += 2;
735
          cdoGridSearchDir = (char*) Malloc(len);
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
736
737
738
739
740
741
742
          memcpy(cdoGridSearchDir, envstr, len-1);
          if ( cdoGridSearchDir[len-3] != '/' )
            {
              cdoGridSearchDir[len-2] = '/';
              cdoGridSearchDir[len-1] = 0;
            }
        }
743
744
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
745
746
747
748
  envstr = getenv("CDO_LOG_OFF");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
749
750
751
752
753
        {
          cdoLogOff = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_LOG_OFF         = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
754
755
756
757
758
759
    }

  envstr = getenv("CDO_DISABLE_HISTORY");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
760
761
762
763
764
        {
          CDO_Reset_History = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_DISABLE_HISTORY = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
765
766
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
767
768
769
770
  envstr = getenv("CDO_RESET_HISTORY");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
771
772
773
774
775
        {
          CDO_Reset_History = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_RESET_HISTORY = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
776
777
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
778
779
780
781
782
783
784
785
786
787
788
789
  envstr = getenv("CDO_HISTORY_INFO");
  if ( envstr )
    {
      int ival = atoi(envstr);
      if ( ival == 0 || ival == 1 )
        {
          CDO_Append_History = ival;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_HISTORY_INFO = %s\n", envstr);
        }
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
790
  CDO_File_Suffix[0] = 0;
791
792
793
794
795

  envstr = getenv("CDO_FILE_SUFFIX");
  if ( envstr )
    {
      if ( envstr[0] )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
796
797
798
799
800
        {
          strncat(CDO_File_Suffix, envstr, sizeof(CDO_File_Suffix)-1);
          if ( cdoVerbose )
            fprintf(stderr, "CDO_FILE_SUFFIX = %s\n", envstr);
        }
801
802
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
803
804
805
806
  envstr = getenv("CDO_DISABLE_FILESUFFIX");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
807
808
809
810
811
        {
          strcat(CDO_File_Suffix, "NULL");
          if ( cdoVerbose )
            fprintf(stderr, "CDO_DISABLE_FILESUFFIX = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
812
813
814
815
816
817
    }

  envstr = getenv("CDO_DIAG");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
818
819
820
821
822
        {
          cdoDiag = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_DIAG = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
823
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
824

825
826
827
828
829
  envstr = getenv("CDO_USE_FFTW");
  if ( envstr )
    {
      int ival = atoi(envstr);
      if ( ival == 0 || ival == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
830
831
832
833
834
        {
          CDO_Use_FFTW = ival;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_Use_FFTW = %s\n", envstr);
        }
835
836
    }

837
838
839
840
841
842
843
844
845
846
847
848
  envstr = getenv("CDO_VERSION_INFO");
  if ( envstr )
    {
      int ival = atoi(envstr);
      if ( ival == 0 || ival == 1 )
        {
          CDO_Version_Info = ival;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_Version_Info = %s\n", envstr);
        }
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
850
851
  envstr = getenv("CDO_COLOR");
  if ( envstr )
    {
852
853
      int ival = atoi(envstr);
      if ( ival == 0 || ival == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
854
855
856
857
858
        {
          CDO_Color = ival;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_COLOR = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
859
    }
860
  else if ( CDO_Color == FALSE && ITSME ) CDO_Color = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
861
862
}

863
864
static
void print_system_info()
Uwe Schulzweida's avatar
Uwe Schulzweida committed
865
{
866
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
867
868
869
  fprintf(stderr, "CDO_Color           = %d\n", CDO_Color);
  fprintf(stderr, "CDO_Reset_History   = %d\n", CDO_Reset_History);
  fprintf(stderr, "CDO_File_Suffix     = %s\n", CDO_File_Suffix);
870
871
872
873
874
  fprintf(stderr, "cdoDefaultFileType  = %d\n", cdoDefaultFileType);
  fprintf(stderr, "cdoDefaultDataType  = %d\n", cdoDefaultDataType);
  fprintf(stderr, "cdoDefaultByteorder = %d\n", cdoDefaultByteorder);
  fprintf(stderr, "cdoDefaultTableID   = %d\n", cdoDefaultTableID);
  fprintf(stderr, "\n");
875

876
  const char *envstr;
877
878
879
880
881
882
883
884
885
  envstr = getenv("HOSTTYPE");
  if ( envstr ) fprintf(stderr, "HOSTTYPE            = %s\n", envstr);
  envstr = getenv("VENDOR");
  if ( envstr ) fprintf(stderr, "VENDOR              = %s\n", envstr);
  envstr = getenv("OSTYPE");
  if ( envstr ) fprintf(stderr, "OSTYPE              = %s\n", envstr);
  envstr = getenv("MACHTYPE");
  if ( envstr ) fprintf(stderr, "MACHTYPE            = %s\n", envstr);
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
886

887
888
#if defined(_ARCH_PWR6)
  fprintf(stderr, "Predefined: _ARCH_PWR6\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
889
#elif defined(_ARCH_PWR7)
890
  fprintf(stderr, "Predefined: _ARCH_PWR7\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
891
892
893
894
895
#endif

#if defined(__AVX2__)
  fprintf(stderr, "Predefined: __AVX2__\n");
#elif defined(__AVX__)
896
  fprintf(stderr, "Predefined: __AVX__\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897
898
899
900
901
902
903
904
#elif defined(__SSE4_2__)
  fprintf(stderr, "Predefined: __SSE4_2__\n");
#elif defined(__SSE4_1__)
  fprintf(stderr, "Predefined: __SSE4_1__\n");
#elif defined(__SSE3__)
  fprintf(stderr, "Predefined: __SSE3__\n");
#elif defined(__SSE2__)
  fprintf(stderr, "Predefined: __SSE2__\n");
905
906
#endif 
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907

908
  fprintf(stderr, "mem alignment       = %d\n\n", getMemAlignment());
Uwe Schulzweida's avatar
Uwe Schulzweida committed
909

Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
#if defined(HAVE_MMAP)
911
912
  fprintf(stderr, "HAVE_MMAP\n");
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
913
#if defined(HAVE_MEMORY_H)
914
915
916
  fprintf(stderr, "HAVE_MEMORY_H\n");
#endif
  fprintf(stderr, "\n");
917

Uwe Schulzweida's avatar
Uwe Schulzweida committed
918
#if defined(_OPENACC)
919
920
  fprintf(stderr, "OPENACC VERSION     = %d\n", _OPENACC);
#endif
921
922
  /* OPENMP 3:  201107 */
  /* OPENMP 4:  201307 gcc 4.9 */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
923
#if defined(_OPENMP)
924
925
  fprintf(stderr, "OPENMP VERSION      = %d\n", _OPENMP);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
926
#if defined(__GNUC__)
927
928
  fprintf(stderr, "GNUC VERSION        = %d\n", __GNUC__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
929
#if defined(__GNUC_MINOR__)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
930
931
  fprintf(stderr, "GNUC MINOR          = %d\n", __GNUC_MINOR__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
932
#if defined(__ICC)
933
934
  fprintf(stderr, "ICC VERSION         = %d\n", __ICC);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
935
#if defined(__STDC__)
936
937
  fprintf(stderr, "STD ANSI C          = %d\n", __STDC__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
938
#if defined(__STD_VERSION__)
939
940
  fprintf(stderr, "STD VERSION         = %ld\n", __STD_VERSION__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
941
#if defined(__STDC_VERSION__)
942
943
  fprintf(stderr, "STDC VERSION        = %ld\n", __STDC_VERSION__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
944
#if defined(__STD_HOSTED__)
945
946
  fprintf(stderr, "STD HOSTED          = %d\n", __STD_HOSTED__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
947
#if defined(FLT_EVAL_METHOD)
948
949
  fprintf(stderr, "FLT_EVAL_METHOD     = %d\n", FLT_EVAL_METHOD);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
950
#if defined(FP_FAST_FMA)
951
  fprintf(stderr, "FP_FAST_FMA         = defined\n");
952
953
954
#endif
#if defined(__FAST_MATH__)
  fprintf(stderr, "__FAST_MATH__       = defined\n");
955
956
957
#endif
  fprintf(stderr, "\n");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
958
#if defined(_SC_VERSION)
959
960
  fprintf(stderr, "POSIX.1 VERSION     = %ld\n", sysconf(_SC_VERSION));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
961
#if defined(_SC_ARG_MAX)
962
963
  fprintf(stderr, "POSIX.1 ARG_MAX     = %ld\n", sysconf(_SC_ARG_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
964
#if defined(_SC_CHILD_MAX)
965
966
  fprintf(stderr, "POSIX.1 CHILD_MAX   = %ld\n", sysconf(_SC_CHILD_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
967
#if defined(_SC_STREAM_MAX)
968
969
  fprintf(stderr, "POSIX.1 STREAM_MAX  = %ld\n", sysconf(_SC_STREAM_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
#if defined(_SC_OPEN_MAX)
971
972
  fprintf(stderr, "POSIX.1 OPEN_MAX    = %ld\n", sysconf(_SC_OPEN_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
973
#if defined(_SC_PAGESIZE)
974
975
  fprintf(stderr, "POSIX.1 PAGESIZE    = %ld\n", sysconf(_SC_PAGESIZE));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
976

977
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
978

Uwe Schulzweida's avatar
Uwe Schulzweida committed
979
980
#if defined(HAVE_GETRLIMIT)
#if defined(RLIMIT_FSIZE)
981
982
  PRINT_RLIMIT(RLIMIT_FSIZE);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
983
#if defined(RLIMIT_NOFILE)
984
985
  PRINT_RLIMIT(RLIMIT_NOFILE);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
986
#if defined(RLIMIT_STACK)
987
988
989
990
991
992
  PRINT_RLIMIT(RLIMIT_STACK);
#endif
#endif
  fprintf(stderr, "\n");
}

993

994
995
996
static
void check_stacksize()
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
997
998
#if defined(HAVE_GETRLIMIT)
#if defined(RLIMIT_STACK)
999
1000
  {
    struct rlimit rlim;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1001
    int status = getrlimit(RLIMIT_STACK, &rlim);
1002
1003
1004

    if ( status == 0 )
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1005
1006
#define  MIN_STACK_SIZE  67108864L  /* 64MB */
        RLIM_T min_stack_size = MIN_STACK_SIZE;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
        if ( min_stack_size > rlim.rlim_max ) min_stack_size = rlim.rlim_max;
        if ( rlim.rlim_cur < min_stack_size )
          {
            rlim.rlim_cur = min_stack_size;

            status = setrlimit(RLIMIT_STACK