cdo.c 47.3 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 <ctype.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
33
/*#include <malloc.h>*/ /* mallopt and malloc_stats */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
34
#include <sys/stat.h>
Uwe Schulzweida's avatar
Uwe Schulzweida committed
35
36
#if defined(HAVE_GETRLIMIT)
#if defined(HAVE_SYS_RESOURCE_H)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
37
38
#include <sys/time.h>       /* getrlimit */
#include <sys/resource.h>   /* getrlimit */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
39
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
40
#endif
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
41
#include <unistd.h>         /* sysconf, gethostname */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
42

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

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

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"
Uwe Schulzweida's avatar
Uwe Schulzweida committed
62

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

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

71
#define MAX_NUM_VARNAMES 256
72

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

83
void gridsearch_set_method(const char *methodstr);
84

Uwe Schulzweida's avatar
Uwe Schulzweida committed
85
86
#define PRINT_RLIMIT(resource) \
      { \
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
        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
103
104
      }

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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
124
static
125
int cdo_feenableexcept(int excepts)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
126
{
127
#if defined HAVE_FEENABLEEXCEPT
128
129
  int feenableexcept(int);
  int old_excepts = feenableexcept(excepts);
130
131
  return old_excepts;
#else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
132
  static fenv_t fenv;
133
134
  unsigned new_excepts = ((unsigned)excepts) & FE_ALL_EXCEPT;
  int old_excepts = -1;  // previous masks
Uwe Schulzweida's avatar
Uwe Schulzweida committed
135
136

  if ( fegetenv(&fenv) ) return -1;
137
138
#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
139

140
141
142
  // unmask
  fenv.__control &= ~new_excepts;
  fenv.__mxcsr   &= ~(new_excepts << 7);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
143
144
145
#endif

  return ( fesetenv(&fenv) ? -1 : (int)old_excepts );
146
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
147
148
149
150
151
152
153
154
155
156
157
158
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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
178
179
180
static
void cdo_version(void)
{
181
  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};
182
  const char* typenames[] = {        "srv",        "ext",        "ieg",       "grb1",        "grb2",       "nc1",        "nc2",        "nc4",        "nc4c"};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
183
184

  fprintf(stderr, "%s\n", CDO_Version);
185
#if defined(USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
186
  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n", USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
187
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
188
#if defined(COMPILER)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
189
190
  fprintf(stderr, "Compiler: %s\n", COMPILER);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
191
#if defined(COMP_VERSION)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
192
193
194
195
196
  fprintf(stderr, " version: %s\n", COMP_VERSION);
#endif

  printFeatures();
  printLibraries();
197

Uwe Schulzweida's avatar
Uwe Schulzweida committed
198
  fprintf(stderr, "Filetypes: ");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
199
  set_text_color(stderr, BRIGHT, GREEN);
200
201
  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
202
  reset_text_color(stderr);
203
204
  fprintf(stderr, "\n");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
205
206
207
208
  cdiPrintVersion();
  fprintf(stderr, "\n");
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
209
static
Uwe Schulzweida's avatar
Uwe Schulzweida committed
210
void cdo_usage(void)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
211
{
212
  const char *name;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
213
214
215

  /*  fprintf(stderr, "%s\n", CDO_Version);*/
  /*  fprintf(stderr, "\n");*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
216
  fprintf(stderr, "usage : cdo  [Options]  Operator1  [-Operator2  [-OperatorN]]\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
217
218
  fprintf(stderr, "\n");
  fprintf(stderr, "  Options:\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
219
  set_text_color(stderr, RESET, BLUE);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
220
  fprintf(stderr, "    -a             Generate an absolute time axis\n");
221
  fprintf(stderr, "    -b <nbits>     Set the number of bits for the output precision\n");
222
  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
223
  fprintf(stderr, "                   Add L or B to set the byteorder to Little or Big endian\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
224
225
  fprintf(stderr, "    --cmor         CMOR conform NetCDF output\n");
  fprintf(stderr, "    -C, --color    Colorized output messages\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
226
227
  fprintf(stderr, "    --enableexcept <except>\n");
  fprintf(stderr, "                   Set individual floating-point traps (DIVBYZERO, INEXACT, INVALID, OVERFLOW, UNDERFLOW, ALL_EXCEPT)\n");
228
  fprintf(stderr, "    -f, --format <format>\n");
229
  fprintf(stderr, "                   Format of the output file. (grb1/grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
230
  fprintf(stderr, "    -g <grid>      Set default grid name or file. Available grids: \n");
231
  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");
232
  fprintf(stderr, "    -h, --help     Help information for the operators\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
233
  fprintf(stderr, "    --history      Do not append to NetCDF \"history\" global attribute\n");
234
  fprintf(stderr, "    --netcdf_hdr_pad, --hdr_pad, --header_pad <nbr>\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
235
  fprintf(stderr, "                   Pad NetCDF output header with nbr bytes\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
236
237
238
  /*
  fprintf(stderr, "    -i <inst>      Institution name/file\n");
  fprintf(stderr, "                   Predefined instituts: ");
239
  for ( int id = 0; id < institutInqNumber; id++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
240
241
242
243
244
    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
245
246
  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
247
  fprintf(stderr, "    -M             Switch to indicate that the I/O streams have missing values\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
248
  fprintf(stderr, "    -m <missval>   Set the missing value of non NetCDF files (default: %g)\n", cdiInqMissval());
249
  fprintf(stderr, "    --no_warnings  Inhibit warning messages\n");
250
  fprintf(stderr, "    -O             Overwrite existing output file, if checked\n");
251
  fprintf(stderr, "    --operators    List of all operators\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
252
#if defined(_OPENMP)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
253
254
  fprintf(stderr, "    -P <nthreads>  Set number of OpenMP threads\n");
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
255
256
  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
257
  fprintf(stderr, "    --reduce_dim   Reduce NetCDF dimensions (module: TIMSTAT, FLDSTAT)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
258
  fprintf(stderr, "    -R, --regular  Convert GRIB1 data from reduced to regular grid (cgribex only)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
259
  fprintf(stderr, "    -r             Generate a relative time axis\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
260
261
  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
262
  fprintf(stderr, "    -s, --silent   Silent mode\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
263
  fprintf(stderr, "    --sort         Alphanumeric sorting of NetCDF parameter names\n");
264
  fprintf(stderr, "    -t <codetab>   Set GRIB1 default parameter code table name or file (cgribex only)\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
265
  fprintf(stderr, "                   Predefined tables: ");
266
  for ( int id = 0; id < tableInqNumber(); id++ )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
267
268
269
270
    if ( (name = tableInqNamePtr(id)) )
      fprintf(stderr, " %s", name);
  fprintf(stderr, "\n");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
271
272
  fprintf(stderr, "    --timestat_date <srcdate>\n");
  fprintf(stderr, "                   Target timestamp (time statistics): first, middle, midhigh or last source timestep.\n");
273
274
  fprintf(stderr, "    -V, --version  Print the version number\n");
  fprintf(stderr, "    -v, --verbose  Print extra details for some operators\n");
275
  fprintf(stderr, "    -W             Print extra warning messages\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
276
277
  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
278
  fprintf(stderr, "        zip[_1-9]  Deflate compression of NetCDF4 variables\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
279
  reset_text_color(stderr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
280
281
282
  fprintf(stderr, "\n");

  fprintf(stderr, "  Operators:\n");
283
284
  fprintf(stderr, "    Use option --operators for a list of all operators.\n");
  /*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
285
  set_text_color(stderr, RESET, GREEN);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
286
  operatorPrintAll();
Uwe Schulzweida's avatar
Uwe Schulzweida committed
287
  reset_text_color(stderr);
288
  */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
289
290

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
297
298
299
300
301
static
void cdo_init_is_tty(void)
{
  struct stat statbuf;
  fstat(0, &statbuf);
302
  if ( S_ISCHR(statbuf.st_mode) ) stdin_is_tty = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
303
  fstat(1, &statbuf);
304
  if ( S_ISCHR(statbuf.st_mode) ) stdout_is_tty = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
305
  fstat(2, &statbuf);
306
  if ( S_ISCHR(statbuf.st_mode) ) stderr_is_tty = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
307
308
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
309
static
310
void cdoPrintHelp(const char *phelp[]/*, char *xoperator*/)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
311
312
{
  if ( phelp == NULL )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
313
    fprintf(stderr, "No help available for this operator!\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
314
315
  else
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
316
      bool lprint;
317
      while ( *phelp )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
318
        {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
319
          lprint = !(*phelp[0] == '\0' && *(phelp+1) && *(phelp+1)[0] == ' ');
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
320
321
322
323
324
325
326
327
328
          
          if ( lprint )
            {
              if ( COLOR_STDOUT )
                {
                  if ( (strcmp(*phelp, "NAME")        == 0) ||
                       (strcmp(*phelp, "SYNOPSIS")    == 0) ||
                       (strcmp(*phelp, "DESCRIPTION") == 0) ||
                       (strcmp(*phelp, "OPERATORS")   == 0) ||
Uwe Schulzweida's avatar
Uwe Schulzweida committed
329
                       (strcmp(*phelp, "NAMELIST")    == 0) ||
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
330
                       (strcmp(*phelp, "PARAMETER")   == 0) ||
Uwe Schulzweida's avatar
Uwe Schulzweida committed
331
                       (strcmp(*phelp, "ENVIRONMENT") == 0) ||
Uwe Schulzweida's avatar
Uwe Schulzweida committed
332
                       (strcmp(*phelp, "NOTE")        == 0) ||
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
                       (strcmp(*phelp, "EXAMPLES")    == 0) )
                    {
                      set_text_color(stdout, BRIGHT, BLACK);
                      fprintf(stdout, "%s", *phelp);
                      reset_text_color(stdout);
                      fprintf(stdout, "\n");
                    }
                  else
                    fprintf(stdout, "%s\n", *phelp);
                }
              else
                {
                  fprintf(stdout, "%s\n", *phelp);
                }
            }

          phelp++;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
351
352
353
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
354
355
static
void cdoSetDebug(int level)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
{
  /*
    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
371
372
  if ( level == 1 || (level &  32) ) cdoDebug = 1;
  if ( level == 1 || (level &  64) ) pstreamDebug(1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
373
#if defined(HAVE_LIBPTHREAD)
Uwe Schulzweida's avatar
cleanup    
Uwe Schulzweida committed
374
375
  if ( level == 1 || (level & 128) ) pipeDebug(1);
  if ( level == 1 || (level & 256) ) Pthread_debug(1);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
376
377
378
379
380
381
#endif
}

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
382
static
383
void setDefaultDataType(const char *datatypestr)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
384
385
{
  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
386
  int nbits = -1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
387
  enum {D_UINT, D_INT, D_FLT, D_CPX};
Uwe Schulzweida's avatar
Uwe Schulzweida committed
388
389
  int dtype = -1;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
390
391
392
393
394
395
  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
396

397
398
  if ( isdigit((int) *datatypestr) )
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
399
      nbits = atoi(datatypestr);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
400
401
      datatypestr += 1;
      if ( nbits >= 10 ) datatypestr += 1;
402

Uwe Schulzweida's avatar
Uwe Schulzweida committed
403
      if ( dtype == -1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
404
405
406
407
        {
          if      ( nbits > 0 && nbits < 32 ) cdoDefaultDataType = nbits;
          else if ( nbits == 32 )
            {
408
              if ( cdoDefaultFileType == CDI_FILETYPE_GRB )
409
                cdoDefaultDataType = CDI_DATATYPE_PACK32;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
410
              else
411
                cdoDefaultDataType = CDI_DATATYPE_FLT32;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
412
            }
413
          else if ( nbits == 64 ) cdoDefaultDataType = CDI_DATATYPE_FLT64;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
414
415
416
          else
            {
              fprintf(stderr, "Unsupported number of bits %d!\n", nbits);
417
              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
418
419
420
              exit(EXIT_FAILURE);
            }
        }
421
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
422
423
424
        {
          if ( dtype == D_INT )
            {
425
426
427
              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
428
429
430
431
432
433
434
435
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype INT!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
          else if ( dtype == D_UINT )
            {
436
437
438
              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
439
440
441
442
443
444
445
446
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype UINT!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
          else if ( dtype == D_FLT )
            {
447
448
              if      ( nbits == 32 ) cdoDefaultDataType = CDI_DATATYPE_FLT32;
              else if ( nbits == 64 ) cdoDefaultDataType = CDI_DATATYPE_FLT64;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
449
450
451
452
453
454
455
456
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype FLT!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
          else if ( dtype == D_CPX )
            {
457
458
              if      ( nbits == 32 ) cdoDefaultDataType = CDI_DATATYPE_CPX32;
              else if ( nbits == 64 ) cdoDefaultDataType = CDI_DATATYPE_CPX64;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
459
460
461
462
463
464
465
              else
                {
                  fprintf(stderr, "Unsupported number of bits = %d for datatype CPX!\n", nbits);
                  exit(EXIT_FAILURE);
                }
            }
        }
466
467
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
468
  if ( *datatypestr != 0 )
469
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
470
      if ( *datatypestr == 'l' || *datatypestr == 'L' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
471
472
473
474
        {
          if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
          datatypestr++;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
475
      else if ( *datatypestr == 'b' || *datatypestr == 'B' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
476
477
478
479
        {
          if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
          datatypestr++;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
480
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
481
482
483
484
        {
          fprintf(stderr, "Unsupported character in number of bytes: >%s< !\n", datatypestr);
          exit(EXIT_FAILURE);
        }
485
486
    }
}
487
/*
Uwe Schulzweida's avatar
Uwe Schulzweida committed
488
489
static
void setDefaultDataTypeByte(char *datatypestr)
490
491
492
493
{
  static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
  int datatype = -1;

Uwe Schulzweida's avatar
Uwe Schulzweida committed
494
495
496
497
498
  if ( isdigit((int) *datatypestr) )
    {
      datatype = atoi(datatypestr);
      datatypestr++;

499
500
501
502
503
      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
504
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
505
506
        {
          fprintf(stderr, "Unsupported datatype %d!\n", datatype);
507
          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
508
509
          exit(EXIT_FAILURE);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
510
511
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
512
  if ( *datatypestr != 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
513
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
514
      if ( *datatypestr == 'l' || *datatypestr == 'L' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
515
516
        {
          if ( IsBigendian() ) cdoDefaultByteorder = CDI_LITTLEENDIAN;
517
          datatypestr++;setDefaultDataTypeByte
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
518
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
519
      else if ( *datatypestr == 'b' || *datatypestr == 'B' )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
520
521
522
523
        {
          if ( ! IsBigendian() ) cdoDefaultByteorder = CDI_BIGENDIAN;
          datatypestr++;
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
524
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
525
526
527
528
        {
          fprintf(stderr, "Unsupported character in number of bytes: %s!\n", datatypestr);
          exit(EXIT_FAILURE);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
529
530
    }
}
531
*/
Uwe Schulzweida's avatar
Uwe Schulzweida committed
532
static
533
void setDefaultFileType(const char *filetypestr, int labort)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
534
535
536
{
  if ( filetypestr )
    {
537
      const char *ftstr = filetypestr;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
538
539
      size_t len;

540
541
542
543
544
545
546
547
548
549
550
      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
551
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
552
553
554
555
        {
          if ( labort )
            {
              fprintf(stderr, "Unsupported filetype %s!\n", filetypestr);
556
              fprintf(stderr, "Available filetypes: grb1/grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg\n");
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
557
558
559
560
561
562
563
              exit(EXIT_FAILURE);
            }
          else
            {
              return;
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
564

565
      if ( cdoDefaultFileType != CDI_UNDEFID && *ftstr != 0 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
566
567
568
569
570
571
572
573
574
575
576
        {
          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");
577
578
              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
579
580
581
              exit(EXIT_FAILURE);
            }
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
582
583
584
    }
}

585
#define NTESTS 11
586
#include <inttypes.h>
587
588
589
590
591
592
593
594
595
596
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
597
  for ( int i = 0; i < NTESTS; ++i )
598
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
599
      ptr[i] = (double*) malloc(tsize[i]);
600
      iptr = (int64_t) ptr[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
601
      for ( int k = 0; k < 4; ++k ) if ( iptr%ma_check[k] ) ma_result[k] = 0; 
602
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
603
  for ( int i = 0; i < NTESTS; ++i ) free(ptr[i]);
604

Uwe Schulzweida's avatar
Uwe Schulzweida committed
605
  for ( int i = NTESTS-1; i >= 0; i-- )
606
    {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
607
      ptr[i] = (double*) malloc(tsize[i]+5);
608
      iptr = (int64_t) ptr[i];
Uwe Schulzweida's avatar
Uwe Schulzweida committed
609
      for ( int k = 0; k < 4; ++k ) if ( iptr%ma_check[k] ) ma_result[k] = 0; 
610
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
611
  for ( int i = 0; i < NTESTS; ++i ) free(ptr[i]);
612

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
615
  return ma;
616
617
}

618

Uwe Schulzweida's avatar
Uwe Schulzweida committed
619
static
620
621
622
623
void defineCompress(const char *arg)
{
  size_t len = strlen(arg);

Uwe Schulzweida's avatar
Uwe Schulzweida committed
624
  if      ( strncmp(arg, "szip", len) == 0 )
625
    {
626
      cdoCompType  = CDI_COMPRESS_SZIP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
627
      cdoCompLevel = 0;
628
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
629
  else if ( strncmp(arg, "jpeg", len) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
630
    {
631
      cdoCompType = CDI_COMPRESS_JPEG;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
632
      cdoCompLevel = 0;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
633
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
634
  else if ( strncmp(arg, "gzip", len) == 0 )
635
    {
636
      cdoCompType  = CDI_COMPRESS_GZIP;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
637
      cdoCompLevel = 6;
638
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
639
  else if ( strncmp(arg, "zip", 3) == 0 )
Uwe Schulzweida's avatar
Uwe Schulzweida committed
640
    {
641
      cdoCompType  = CDI_COMPRESS_ZIP;
642
      if ( len == 5 && arg[3] == '_' && isdigit(arg[4]) )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
643
        cdoCompLevel = atoi(&arg[4]);
644
      else
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
645
        cdoCompLevel = 1;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
646
    }
647
  else
Uwe Schulzweida's avatar
Uwe Schulzweida committed
648
649
650
651
652
653
654
655
656
    {
      fprintf(stderr, "Compression type '%s' unsupported!\n", arg);
      exit(EXIT_FAILURE);
    }
}

static
void defineChunktype(const char *arg)
{
657
658
659
  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
660
661
662
663
664
  else
    {
      fprintf(stderr, "Chunk type '%s' unsupported!\n", arg);
      exit(EXIT_FAILURE);
    }
665
666
}

667
668
669
670
671
672
673
674
675
676
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 )
677
    {      
678
      cdoVarnames = (char **) Malloc(MAX_NUM_VARNAMES*sizeof(char *));
679

680
      char *pbuf = strdup(arg+istart);
681
682
      cdoVarnames[cdoNumVarnames++] = pbuf;    

683
      char *commapos = pbuf;
684
      while ( (commapos = strchr(commapos, ',')) != NULL )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
685
686
687
688
689
690
691
692
693
694
        {
          *commapos++ = '\0';
          if ( strlen(commapos) )
            {
              if ( cdoNumVarnames >= MAX_NUM_VARNAMES )
                cdoAbort("Too many variable names (limit=%d)!", MAX_NUM_VARNAMES);

              cdoVarnames[cdoNumVarnames++] = commapos;
            }
        }
695
696
      /*
      for ( int i = 0; i < cdoNumVarnames; ++i )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
697
        printf("varname %d: %s\n", i+1, cdoVarnames[i]);
698
699
700
701
      */
    }
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
702
703
704
static
void get_env_vars(void)
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
705
706
707
708
709
710
711
  username = getenv("LOGNAME");
  if ( username == NULL )
    {
      username = getenv("USER");
      if ( username == NULL ) username = "unknown";
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
712
  char *envstr = getenv("CDO_GRID_SEARCH_DIR");
713
714
715
716
  if ( envstr )
    {
      size_t len = strlen(envstr);
      if ( len > 0 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
717
718
        {
          len += 2;
719
          cdoGridSearchDir = (char*) Malloc(len);
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
720
721
722
723
724
725
726
          memcpy(cdoGridSearchDir, envstr, len-1);
          if ( cdoGridSearchDir[len-3] != '/' )
            {
              cdoGridSearchDir[len-2] = '/';
              cdoGridSearchDir[len-1] = 0;
            }
        }
727
728
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
729
730
731
732
  envstr = getenv("CDO_LOG_OFF");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
733
734
735
736
737
        {
          cdoLogOff = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_LOG_OFF         = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
738
739
740
741
742
743
    }

  envstr = getenv("CDO_DISABLE_HISTORY");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
744
745
746
747
748
        {
          CDO_Reset_History = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_DISABLE_HISTORY = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
749
750
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
751
752
753
754
  envstr = getenv("CDO_RESET_HISTORY");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
755
756
757
758
759
        {
          CDO_Reset_History = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_RESET_HISTORY = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
760
761
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
762
763
764
765
766
767
768
769
770
771
772
773
  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
774
  CDO_File_Suffix[0] = 0;
775
776
777
778
779

  envstr = getenv("CDO_FILE_SUFFIX");
  if ( envstr )
    {
      if ( envstr[0] )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
780
781
782
783
784
        {
          strncat(CDO_File_Suffix, envstr, sizeof(CDO_File_Suffix)-1);
          if ( cdoVerbose )
            fprintf(stderr, "CDO_FILE_SUFFIX = %s\n", envstr);
        }
785
786
    }

Uwe Schulzweida's avatar
Uwe Schulzweida committed
787
788
789
790
  envstr = getenv("CDO_DISABLE_FILESUFFIX");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
791
792
793
794
795
        {
          strcat(CDO_File_Suffix, "NULL");
          if ( cdoVerbose )
            fprintf(stderr, "CDO_DISABLE_FILESUFFIX = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
796
797
798
799
800
801
    }

  envstr = getenv("CDO_DIAG");
  if ( envstr )
    {
      if ( atoi(envstr) == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
802
803
804
805
806
        {
          cdoDiag = TRUE;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_DIAG = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
807
    }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
808

809
810
811
812
813
  envstr = getenv("CDO_USE_FFTW");
  if ( envstr )
    {
      int ival = atoi(envstr);
      if ( ival == 0 || ival == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
814
815
816
817
818
        {
          CDO_Use_FFTW = ival;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_Use_FFTW = %s\n", envstr);
        }
819
820
    }

821
822
823
824
825
826
827
828
829
830
831
832
  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
833
834
835
  envstr = getenv("CDO_COLOR");
  if ( envstr )
    {
836
837
      int ival = atoi(envstr);
      if ( ival == 0 || ival == 1 )
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
838
839
840
841
842
        {
          CDO_Color = ival;
          if ( cdoVerbose )
            fprintf(stderr, "CDO_COLOR = %s\n", envstr);
        }
Uwe Schulzweida's avatar
Uwe Schulzweida committed
843
    }
844
  else if ( CDO_Color == FALSE && ITSME ) CDO_Color = TRUE;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
845
846
}

847
848
static
void print_system_info()
Uwe Schulzweida's avatar
Uwe Schulzweida committed
849
{
850
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
851
852
853
  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);
854
855
856
857
858
  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");
859

860
  const char *envstr;
861
862
863
864
865
866
867
868
869
  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
870

871
872
#if defined(_ARCH_PWR6)
  fprintf(stderr, "Predefined: _ARCH_PWR6\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
873
#elif defined(_ARCH_PWR7)
874
  fprintf(stderr, "Predefined: _ARCH_PWR7\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
875
876
877
878
879
#endif

#if defined(__AVX2__)
  fprintf(stderr, "Predefined: __AVX2__\n");
#elif defined(__AVX__)
880
  fprintf(stderr, "Predefined: __AVX__\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
881
882
883
884
885
886
887
888
#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");
889
890
#endif 
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
891

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

Uwe Schulzweida's avatar
Uwe Schulzweida committed
894
#if defined(HAVE_MMAP)
895
896
  fprintf(stderr, "HAVE_MMAP\n");
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
897
#if defined(HAVE_MEMORY_H)
898
899
900
  fprintf(stderr, "HAVE_MEMORY_H\n");
#endif
  fprintf(stderr, "\n");
901

Uwe Schulzweida's avatar
Uwe Schulzweida committed
902
#if defined(_OPENACC)
903
904
  fprintf(stderr, "OPENACC VERSION     = %d\n", _OPENACC);
#endif
905
906
  /* OPENMP 3:  201107 */
  /* OPENMP 4:  201307 gcc 4.9 */
Uwe Schulzweida's avatar
Uwe Schulzweida committed
907
#if defined(_OPENMP)
908
909
  fprintf(stderr, "OPENMP VERSION      = %d\n", _OPENMP);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
910
#if defined(__GNUC__)
911
912
  fprintf(stderr, "GNUC VERSION        = %d\n", __GNUC__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
913
#if defined(__GNUC_MINOR__)
Uwe Schulzweida's avatar
Uwe Schulzweida committed
914
915
  fprintf(stderr, "GNUC MINOR          = %d\n", __GNUC_MINOR__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
916
#if defined(__ICC)
917
918
  fprintf(stderr, "ICC VERSION         = %d\n", __ICC);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
919
#if defined(__STDC__)
920
921
  fprintf(stderr, "STD ANSI C          = %d\n", __STDC__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
922
#if defined(__STD_VERSION__)
923
924
  fprintf(stderr, "STD VERSION         = %ld\n", __STD_VERSION__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
925
#if defined(__STDC_VERSION__)
926
927
  fprintf(stderr, "STDC VERSION        = %ld\n", __STDC_VERSION__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
928
#if defined(__STD_HOSTED__)
929
930
  fprintf(stderr, "STD HOSTED          = %d\n", __STD_HOSTED__);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
931
#if defined(FLT_EVAL_METHOD)
932
933
  fprintf(stderr, "FLT_EVAL_METHOD     = %d\n", FLT_EVAL_METHOD);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
934
#if defined(FP_FAST_FMA)
935
  fprintf(stderr, "FP_FAST_FMA         = defined\n");
936
937
938
#endif
#if defined(__FAST_MATH__)
  fprintf(stderr, "__FAST_MATH__       = defined\n");
939
940
941
#endif
  fprintf(stderr, "\n");

Uwe Schulzweida's avatar
Uwe Schulzweida committed
942
#if defined(_SC_VERSION)
943
944
  fprintf(stderr, "POSIX.1 VERSION     = %ld\n", sysconf(_SC_VERSION));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
945
#if defined(_SC_ARG_MAX)
946
947
  fprintf(stderr, "POSIX.1 ARG_MAX     = %ld\n", sysconf(_SC_ARG_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
948
#if defined(_SC_CHILD_MAX)
949
950
  fprintf(stderr, "POSIX.1 CHILD_MAX   = %ld\n", sysconf(_SC_CHILD_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
951
#if defined(_SC_STREAM_MAX)
952
953
  fprintf(stderr, "POSIX.1 STREAM_MAX  = %ld\n", sysconf(_SC_STREAM_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
954
#if defined(_SC_OPEN_MAX)
955
956
  fprintf(stderr, "POSIX.1 OPEN_MAX    = %ld\n", sysconf(_SC_OPEN_MAX));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
957
#if defined(_SC_PAGESIZE)
958
959
  fprintf(stderr, "POSIX.1 PAGESIZE    = %ld\n", sysconf(_SC_PAGESIZE));
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
960

961
  fprintf(stderr, "\n");
Uwe Schulzweida's avatar
Uwe Schulzweida committed
962

Uwe Schulzweida's avatar
Uwe Schulzweida committed
963
964
#if defined(HAVE_GETRLIMIT)
#if defined(RLIMIT_FSIZE)
965
966
  PRINT_RLIMIT(RLIMIT_FSIZE);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
967
#if defined(RLIMIT_NOFILE)
968
969
  PRINT_RLIMIT(RLIMIT_NOFILE);
#endif
Uwe Schulzweida's avatar
Uwe Schulzweida committed
970
#if defined(RLIMIT_STACK)
971
972
973
974
975
976
  PRINT_RLIMIT(RLIMIT_STACK);
#endif
#endif
  fprintf(stderr, "\n");
}

977

978
979
980
static
void check_stacksize()
{
Uwe Schulzweida's avatar
Uwe Schulzweida committed
981
982
#if defined(HAVE_GETRLIMIT)
#if defined(RLIMIT_STACK)
983
984
  {
    struct rlimit rlim;
Uwe Schulzweida's avatar
Uwe Schulzweida committed
985
    int status = getrlimit(RLIMIT_STACK, &rlim);
986
987
988

    if ( status == 0 )
      {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
989
990
#define  MIN_STACK_SIZE  67108864L  /* 64MB */
        RLIM_T min_stack_size = MIN_STACK_SIZE;
Yvonne Kuestermann's avatar
Yvonne Kuestermann committed
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
        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, &rlim);
            if ( Debug )
              {
                if ( status == 0 )
                  {
                    fprintf(stderr, "Set stack size to %ld\n", (long) min_stack_size);
                    PRINT_RLIMIT(RLIMIT_STACK);
                  }
                else
                  fprintf(stderr, "Set stack size to %ld failed!\n", (long) min_stack_size);
              }
          }
1008
1009
1010
1011
1012
      }
  }
#endif
#endif
}
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1013

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1014
1015
1016
1017
1018
static
void cdo_set_options(void)
{
  if ( Debug )
    {
1019
      fprintf(stderr, "CDO_CMOR_Mode       = %d\n", CDO_CMOR_Mode);
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1020
1021
1022
1023
      fprintf(stderr, "CDO_netcdf_hdr_pad  = %d\n", CDO_netcdf_hdr_pad);
      fprintf(stderr, "\n");
    }
  
1024
  if ( CDO_CMOR_Mode )          cdiDefGlobal("CMOR_MODE", CDO_CMOR_Mode);
1025
  if ( CDO_netcdf_hdr_pad > 0 ) cdiDefGlobal("NETCDF_HDR_PAD", CDO_netcdf_hdr_pad);  
Uwe Schulzweida's avatar
Uwe Schulzweida committed
1026
1027
}

Uwe Schulzweida's avatar
Uwe Schulzweida committed
1028

1029
static