CMOR.cc 199 KB
Newer Older
1
#include <cdi.h>
2
#include <signal.h>
3
4
5
6
7
#include "cdo.h"
#include "cdo_int.h"
#include "pstream.h"

#if defined(HAVE_LIBCMOR)
8
#include <unistd.h>
9
#include "uthash.h"
10
#include "util.h"
Fabian Wachsmann's avatar
Fabian Wachsmann committed
11
12
13
14

#ifdef __cplusplus
  extern "C" {
#endif
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
15
#include "cmor.h"
Fabian Wachsmann's avatar
Fabian Wachsmann committed
16
17
18
19
#ifdef __cplusplus
  }
#endif

20
#include "netcdf.h"
21
#include "pmlist.h"
22

23
24
#define CMOR_UNDEFID (CMOR_MAX_AXES + 1)

25
26
27
28
29
/* */
/* Read Mapping Table */
/* */
int stringToParam(const char *paramstr);

Fabian Wachsmann's avatar
Fabian Wachsmann committed
30
31
32
33
34
35
36
37
38
39
static char *kv_get_a_val(list_t *kvl, const char *key, const char *replacer)
{
  keyValues_t *kv = kvlist_search(kvl, key);
  if ( kv )
    return kv->values[0];
  if ( replacer )
    return (char *)replacer;
  else
    return NULL;
}
40

Fabian Wachsmann's avatar
Fabian Wachsmann committed
41
list_t *maptab_search_miptab(list_t *pmlist, const char *cmorname, const char *miptab, const char *key)
42
43
44
45
{
  if ( pmlist && cmorname && miptab )
    {
      listNode_t *node = pmlist->head;
46
      list_t *listlatest = NULL;
47
48
49
50
51
      while ( node )
        {
          if ( node->data )
            {
              list_t *kvlist = *(list_t **)node->data;
52
              keyValues_t *kvcn = kvlist_search(kvlist, key);
53
54
              if ( kvcn && kvcn->nvalues > 0 && *(kvcn->values[0]) == *cmorname && strcmp(kvcn->values[0], cmorname) == 0 )
                {
55
                  keyValues_t *kvmt = kvlist_search(kvlist, "project_mip_table");
56
57
                  if ( ( kvmt && kvmt->nvalues > 0 && *(kvmt->values[0]) == *miptab && strcmp(kvmt->values[0], miptab) == 0 ) || !kvmt )
                    return kvlist;
58
59
                  else
                    listlatest = kvlist;
60
61
62
63
                }
            }
          node = node->next;
        }
64
65
      if ( listlatest )
        {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
66
          if ( cdoVerbose )
67
            cdoPrint("No attribute 'project_mip_table' found in mapping table line for cmorname '%s'.\n          The latest line of the mapping table is used.", cmorname);
68
69
          return listlatest;
        }
70
71
72
73
74
    }

  return NULL;
}

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
static
char *readLineFromBuffer(char *buffer, size_t *buffersize, char *line, size_t len)
{
  int ichar;
  size_t ipos = 0;
  while ( *buffersize )
    {
      ichar = *buffer;
      (*buffersize)--;
      buffer++;
      if ( ichar == '\r' )
        {
          if ( *buffersize )
            {
              ichar = *buffer;
              if ( ichar == '\n' )
                {
                  (*buffersize)--;
                  buffer++;
                }
            }
          break;
        }
      if ( ichar == '\n' ) break;
      line[ipos++] = ichar;
      if ( ipos >= len )
        {
          fprintf(stderr, "readLineFromBuffer: end of line not found (maxlen = %ld)!\n", len);
          break;
        }
    }
  line[ipos] = 0;
  if ( *buffersize == 0 && ipos == 0 ) buffer = NULL;
  return buffer;
}

static
char *skipSeparator(char *pline)
{
  while ( isspace((int) *pline) ) pline++;
  if ( *pline == '=' || *pline == ':' ) pline++;
  while ( isspace((int) *pline) ) pline++;

  return pline;
}

121
static void handleError(list_t *kvl, int errnum, char *argument)
Fabian Wachsmann's avatar
Fabian Wachsmann committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
{
  char *filename = NULL;
  if ( kvl )
    filename = kv_get_a_val(kvl, "workfile4err", NULL);
  else 
    cdoAbort("In parsing the command line:\n          More than 100 values for a key are not supported.");
  if ( !filename )
    cdoAbort("In parsing file:\n          Cannot resolve recent working file.");
  switch ( errnum )
    {
    case ( 1 ): cdoAbort("In parsing file '%s':\n          Unexpected blank in line:\n          '%s'\n          Check syntax.", filename, argument);
    case ( 2 ): cdoAbort("In parsing file '%s':\n          Unexpected separator sign ',' in a key of line:\n          '%s'\n          Check syntax.", filename, argument);
    case ( 3 ): cdoAbort("In parsing file '%s':\n          More than 100 values for a key are not supported.", filename);
    case ( 4 ): cdoAbort("In parsing file '%s':\n          No values found for a keyword in line:\n          '%s'.\n          Check syntax.", filename, argument);
    case ( 5 ): cdoAbort("In parsing file '%s':\n          A value for a keyword begins with ',' in line:\n          '%s'.\n          Check syntax.", filename, argument);
    case ( 6 ): cdoAbort("In parsing file '%s':\n          A Value for a keyword has a start quote sign but no end quote sign in line:\n          '%s'.\n          Check syntax.",filename,  argument);
    case ( 7 ): cdoAbort("In parsing file '%s':\n          Unexpected separator sign '=' or ':' is found in values in line:\n          '%s'.", filename, argument);
    case ( 8 ): cdoAbort("In parsing file '%s':\n          Connected lines for one keyvalue contain more than the allowed 4096 characters.",filename);
    case ( 9 ): cdoAbort("In parsing file '%s':\n          A ',' is found at end of a line without information in next line.",filename);
    case ( 10): cdoAbort("In parsing file '%s':\n          A ',' is found at end of file.",filename);
    }
}

145
static
Fabian Wachsmann's avatar
Fabian Wachsmann committed
146
char *getElementName(char *pline, char *name, int *errh)
147
148
149
150
{
  while ( isspace((int) *pline) ) pline++;
  size_t len = strlen(pline);
  size_t pos = 0;
151
152
153
  while ( pos < len && *(pline+pos) != '=' )
    {
      if ( isspace((int) *(pline+pos)) )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
154
        { *errh=1; return pline; }
155
      if ( *(pline+pos) == ',' )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
156
        { *errh=2; return pline; }
157
      if ( *(pline+pos) == ':' )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
158
        cdoWarning("In parsing file:\n          Separator sign ':' is not supported. Use '=' instead.\n          ...'%s'...", pline);
159
160
161
      name[pos] = tolower(*(pline+pos));
      pos++;
    }
162
163
164
165
166
167
  name[pos] = 0;

  pline += pos;
  return pline;
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
168
static int copy_value(char *value, char **values, int *nvalues)
169
{
170
  if ( *nvalues > 100 )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
171
    return 3;
172
  values[*nvalues] = strdup(value);
173
  (*nvalues)++;
174
  values[*nvalues] = NULL;
Fabian Wachsmann's avatar
Fabian Wachsmann committed
175
  return 0;
176
177
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
178

179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
static void free_array(char **tofree)
{
  int i = 0;
  while ( tofree[i] )
    {
      free(tofree[i]);
      i++;
    }
  Free(tofree);
}

static void quote_replace(char **values, int nvalues, int i)
{
  char *source = values[nvalues];
  char *useful;
194
  source++;
195
196
197
198
199
  source[i-2] = 0;
  useful = strdup(source);
  free(values[nvalues]);
  values[nvalues] = strdup(useful);
  free(useful);
200
201
}

202
static
Fabian Wachsmann's avatar
Fabian Wachsmann committed
203
char *getElementValues(char *pline, char **values, int *nvalues, char *keyword, int *errh)
204
205
206
{
  while ( isspace((int) *pline) ) pline++;
  size_t len = strlen(pline);
207
208
209
  while ( isspace((int) *(pline+(int)len)) ) len--;
  *(pline+len) = 0;
  if ( (int)len == 0 )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
210
    {*errh=4; return keyword;}
211
212
213
214
215
216
  *nvalues = 0;
  int i = 0;
  while ( i < len && len )
    {
      if ( *(pline+i) == ',')
        {
217
          if ( i == 0 )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
218
219
220
221
222
223
224
            {
              *errh=5;
              return pline;
            }
          *errh = copy_value(pline, values, nvalues);
          if ( *errh > 0 )
            return pline;
225
226
227
228
          if ( *(values[*nvalues-1]+i-1) == '"' || *(values[*nvalues-1]+i-1) == '\'' )
            quote_replace(values, *nvalues-1,i);
          else
            *(values[*nvalues-1]+i) = 0;
229
230

          i++;
231
          pline+=i;
232
233
          len-=i;
          i=0;
234
235
236
237
238
239
240
241
        }
      else if ( *(pline+i) == '"' )
        {
          i++;
          while ( *(pline+i) != '"' )
            {
              i++;
              if ( *(pline+i) == 0 )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
242
                {*errh=6; return pline;}
243
244
245
246
            }
          i++;
        }
      else if ( isspace((int) *(pline+i)) )
247
        break;          
248
      else if ( *(pline+i) == '=' || *(pline+i) == ':' )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
249
250
251
252
        {
          *errh=7;
          return pline;
        }
253
254
255
      else
        i++;
    }
Fabian Wachsmann's avatar
Fabian Wachsmann committed
256
257
258
  *errh = copy_value(pline, values, nvalues);
  if ( *errh > 0 )
    return pline;
259
260
261
262
263
  if ( *(values[*nvalues-1]+i-1) == '"' )
    quote_replace(values, *nvalues-1, i);
  else
    *(values[*nvalues-1]+i) = 0;
  pline+=i;
264
265
266
  return pline;
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
267
static int parse_line_to_list(list_t *list, char *pline, const char *kvlname, int checkpml, int lowprior)
268
{
Fabian Wachsmann's avatar
Fabian Wachsmann committed
269
  int errh = 0;
270
271
272
273
274
275
276
277
278
279
  char name[256];
  int i = 0, nvalues;
  list_t *kvl = NULL;
  if ( checkpml )
    {
      kvl = list_new(sizeof(keyValues_t *), free_keyval, kvlname);
      list_append(list, &kvl);
    }
  while ( *pline != 0 )
    {
280
      char **values = (char **) Malloc( 100 * sizeof(char *) );
281
      
Fabian Wachsmann's avatar
Fabian Wachsmann committed
282
      pline = getElementName(pline, name, &errh);
283
284
      if ( strcmp(name, "conventions") == 0 )
        strcpy(name, "Conventions");
285
286
287
288
289
290
291
292
      if ( strcmp(name, "cn") == 0 )
        strcpy(name, "cmor_name");
      if ( strcmp(name, "c") == 0 )
        strcpy(name, "code");
      if ( strcmp(name, "n") == 0 )
        strcpy(name, "name");
      if ( strcmp(name, "pmt") == 0 )
        strcpy(name, "project_mip_table");
293
294
      if ( strcmp(name, "cordex_domain") == 0 )
        strcpy(name, "CORDEX_domain");
Fabian Wachsmann's avatar
Fabian Wachsmann committed
295
296
      if ( errh > 0 )
        return errh;
297
298
      if ( *pline == 0 )
        {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
299
          cdoPrint("In parsing a line of a file:\n          Could not find values for key: '%s'. Use correct 'key=value' syntax.", name);
300
301
          break;
        }
302
      pline = skipSeparator(pline);
303
304
      if ( *pline == 0 )
        {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
305
          cdoPrint("In parsing a line of a file:\n          Could not find values for: '%s'. Use correct 'key=value' syntax.", name);
306
307
          break;
        }
Fabian Wachsmann's avatar
Fabian Wachsmann committed
308
309
310
311
      pline = getElementValues(pline, values, &nvalues, name, &errh);
      if ( errh > 0 )
        return errh;

312
313
314
315
316
317
318
319
320
321
322
323
      if ( checkpml )
        kvlist_append(kvl, name, (const char **)values, nvalues);
      else
        {
          if ( lowprior )
            {
              keyValues_t *already = kvlist_search(list, name);
              if ( already )
                continue;
            }
          kvlist_append(list, name, (const char **)values, nvalues);
        }
324
      while ( isspace((int) *pline) ) pline++;
325
326
      if ( *pline == '/' )
        *pline = 0;
327
      free_array(values);
328
    }
Fabian Wachsmann's avatar
Fabian Wachsmann committed
329
  return 0;
330
}
331

332
333
static void remove_space_and_comms(char **pline, char *line)
{
334
  while ( isspace((int) *(*pline)) ) (*pline)++;
335
336
337
338
339
340
341
342
343
344
345
346
347
  char *tester = *pline;
  int i = 0;
  while ( *tester != 0 )
    {
      if ( *tester == '#' || *tester == '!' )
        {
          line[i] = '\0';
          break;
        }
      i++; tester++;
    }
}

348
static int add_lines_tester(char *line)
349
350
351
352
353
354
{
  char *tester = line;
  while ( *tester != 0 ) tester++;
  tester--;
  while ( isspace((int) *tester) ) tester--;
  if ( *tester == ',' )
355
356
357
358
    return 1;
  return 0;
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
359
static int add_lines(char *line, char **buffer, size_t *buffersize)
360
361
362
363
{
  int len = strlen(line);
  char nextline[4096];
  if ( (*buffer = readLineFromBuffer(*buffer, buffersize, nextline, sizeof(nextline))) )
364
    {
365
366
367
      char *nexttester = nextline;
      remove_space_and_comms(&nexttester, nextline);
      if ( *nexttester != '\0' && *nexttester != '&' )
368
        {
369
          if ( strlen(nexttester) + len > 4096 )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
370
            return 8;
371
          strcat(line, nextline);
372
          return 0;
373
374
        }
      else
Fabian Wachsmann's avatar
Fabian Wachsmann committed
375
        return 9;
376
377
    }
  else
Fabian Wachsmann's avatar
Fabian Wachsmann committed
378
    return 10;
379
}  
380

Fabian Wachsmann's avatar
Fabian Wachsmann committed
381
void parse_buffer_to_list(list_t *list, size_t buffersize, char *buffer, int checkpml, int lowprior, list_t *kvl)
382
383
384
385
{
  char line[4096];
  char name[256];
  char *pline;
Fabian Wachsmann's avatar
Fabian Wachsmann committed
386
  const char *listkeys[] = {"axis_entry:", "variable_entry:", "&parameter", NULL};
387
388
  int linenumber = 0;
  int listtype = 0;
Fabian Wachsmann's avatar
Fabian Wachsmann committed
389
  int errh = 0;
390
391
392
393
394

  while ( (buffer = readLineFromBuffer(buffer, &buffersize, line, sizeof(line))) )
    {
      linenumber++;
      pline = line;
395
396
      remove_space_and_comms(&pline, line);
      if ( *pline == '\0' ) continue;
397
      while ( add_lines_tester(line) )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
398
399
400
401
402
        {
          errh = add_lines(line, &buffer, &buffersize);
          if ( errh > 0 )
            handleError(kvl, errh, NULL);
        }
403
404
405
406
407
408
      //  len = (int) strlen(pline);
      if ( listtype == 0 && *pline == '&' ) listtype = 1;
/* MAXNVALUES*/
      int i = 0;
      while ( listkeys[i] )
        {
409
410
411
412
413
414
415
          if ( strlen(pline) > strlen(listkeys[i]) )
            if ( strncmp(pline, listkeys[i], strlen(listkeys[i])) == 0 )
              {
	        pline += strlen(listkeys[i]);
 	        listtype = 2;
                break;
	      }
416
417
          i++;
        }
418
      if ( listtype )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
419
        errh = parse_line_to_list(list, pline, listkeys[i], checkpml, lowprior);
420
      else
Fabian Wachsmann's avatar
Fabian Wachsmann committed
421
422
423
        errh = parse_line_to_list(list, pline, "keyvals", checkpml, lowprior);
      if ( errh > 0 )
        handleError(kvl, errh, pline);
424
425
    }
}
426

427
428
429
430
431
432
433

static void kv_insert_a_val(list_t *kvl, const char *key, char *value, int replace)
{
  if ( key )
    {
      keyValues_t *kv = kvlist_search(kvl, key);
      if ( !kv )
434
        {
435
436
437
438
439
          const char *apvalue[] = {value};
          kvlist_append(kvl, key, apvalue, 1);
        }
      else if ( replace )
        {
440
          Free(kv->values[0]);
441
442
443
444
445
          kv->values[0] = strdup((const char *) value);
        }
    }
}

446
447
448
449
450
451
452
453
static char **kv_get_vals(list_t *kvl, const char *key, int *numvals)
{
  keyValues_t *kv = kvlist_search(kvl, key);
  if ( kv )
    { *numvals = kv->nvalues; return kv->values; }
  return NULL;
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
454
list_t *cdo_parse_cmor_file(const char *filename, list_t *kvl)
455
456
457
458
459
460
{
  assert(filename != NULL);

  size_t filesize = fileSize(filename);
  if ( filesize == 0 )
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
461
      fprintf(stderr, "In reading the mapping table:\n          Empty table file: %s.", filename);
462
463
464
465
466
467
      return NULL;
    }

  FILE *fp = fopen(filename, "r");
  if ( fp == NULL )
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
468
      fprintf(stderr, "In reading the mapping table:\n          Open failed on %s: %s.", filename, strerror(errno));
469
470
471
472
473
474
475
476
477
478
      return NULL;
    }

  char *buffer = (char*) Malloc(filesize);
  size_t nitems = fread(buffer, 1, filesize, fp);

  fclose(fp);

  if ( nitems != filesize )
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
479
      fprintf(stderr, "In reading the mapping table:\n          Read failed on %s.", filename);
480
481
482
483
484
485
486
487
      return NULL;
    }
 
  list_t *pml = list_new(sizeof(list_t *), free_kvlist, filename);

/*  if ( buffer[0] == '{' )
    parse_json_buffer_to_pml(pml, filesize, buffer);
  else */
Fabian Wachsmann's avatar
Fabian Wachsmann committed
488
  parse_buffer_to_list(pml, filesize, buffer, 1, 0, kvl);
489

490
  if ( buffer ) Free(buffer);
491

492
493
494
  return pml;
}

495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
static void get_stringcode(int vlistID, int varID, char *varcodestring)
{
  int varcode;
  varcode = vlistInqVarCode(vlistID, varID);
  sprintf(varcodestring, "%03d", varcode);
}

static void get_ifilevalue(char *ifilevalue, const char *key, int vlistID, int varID)
{
  if ( strcmp(key, "name") == 0 )
    vlistInqVarName(vlistID, varID, ifilevalue);
  else if ( strcmp(key, "code") == 0 )
    {
      char varcodestring[CDI_MAX_NAME];
      get_stringcode(vlistID, varID, varcodestring);
      strcpy(ifilevalue, varcodestring);
    }
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
514
static int getVarIDToMap(int vlistID, int nvars, const char *key, const char *value)
515
516
517
518
519
520
521
522
523
524
525
{
  for ( int varID = 0; varID < nvars; varID++ )
    {
      char ifilevalue[CDI_MAX_NAME];
      get_ifilevalue(ifilevalue, key, vlistID, varID);
      if ( strcmp(ifilevalue, value) == 0 )
        return varID;
    }
  return CDI_UNDEFID;
}

526

Fabian Wachsmann's avatar
Fabian Wachsmann committed
527
static const char *check_short_key(char *key)
528
{
529
530
  const char *short_keys[]={"cn", "n", "c", "u", "cm", "vc", "p", "szc", "i", "ca", "za", "gi", "rtu", "mt", "om", "ms", "dr", "d", "lc", "dj", NULL};
  const char *long_keys[]={"cmor_name", "name", "code", "units", "cell_methods", "variable_comment", "positive", "scalar_z_coordinate", "info", "character_axis", "z_axis",  "grid_info", "required_time_units", "mapping_table", "output_mode", "max_size", "drs_root", "drs", "last_chunk", "dataset_json", NULL};
531
532
533
534
535
536
537
538
539
540
541
542
543
544

  for ( int i = 0; short_keys[i]; i++ )
    if ( strcmp(key, short_keys[i]) == 0 || strcmp(key, long_keys[i]) == 0 )
      return short_keys[i];
/*  if ( strcmp(key, "cmor_name") == 0 ) short_key = strdup("cn");
  else if ( strcmp(key, "name") == 0 ) short_key = strdup("n");
  else if ( strcmp(key, "code") == 0 ) short_key = strdup("c");
  else if ( strcmp(key, "units") == 0 ) short_key = strdup("u");
  else if ( strcmp(key, "cell_methods") == 0 ) short_key = strdup("cm");
  else if ( strcmp(key, "comment") == 0 ) short_key = strdup("k");
  else if ( strcmp(key, "positive") == 0 ) short_key = strdup("p");
  else if ( strcmp(key, "scalar_z_coordinate") == 0 ) short_key = strdup("szc");
  else if ( strcmp(key, "info") == 0 ) short_key = strdup("i");
  else if ( strcmp(key, "character_axis") == 0 ) short_key = strdup("ca");
545
  else if ( strcmp(key, "z_axis") == 0 ) short_key = strdup("za");
546
547
548
549
550
551
552
553
554
555
556
557
558
  else if ( strcmp(key, "grid_info") == 0 ) short_key = strdup("gi");
  else if ( strcmp(key, "required_time_units") == 0 ) short_key = strdup("rtu");
  else if ( strcmp(key, "mapping_table") == 0 ) short_key = strdup("mt");
  else if ( strcmp(key, "calendar") == 0 ) short_key = strdup("l");
  else if ( strcmp(key, "output_mode") == 0 ) short_key = strdup("om");
  else if ( strcmp(key, "max_size") == 0 ) short_key = strdup("ms");
  else if ( strcmp(key, "drs_root") == 0 ) short_key = strdup("dr");
  else if ( strcmp(key, "drs") == 0 ) short_key = strdup("d");
  else if ( strcmp(key, "last_chunk") == 0 ) short_key = strdup("lc"); 
  else if ( strcmp(key, "dataset_json") == 0 ) short_key = strdup("dj"); */
  return NULL;
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
559
static void map_it(list_t *kvl, int vlistID, int varID, char *var2map)
560
561
562
563
{
  for ( listNode_t *kvnode = kvl->head; kvnode; kvnode = kvnode->next )
    {
      keyValues_t *kv = *(keyValues_t **)kvnode->data;
Fabian Wachsmann's avatar
Fabian Wachsmann committed
564
      const char *key = ( check_short_key((char *)kv->key ) ) ? check_short_key((char *)kv->key) : NULL;
565
566
      if ( !key )
        {
567
          if ( strcmp(kv->key, "project_mip_table") != 0 )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
568
            cdoWarning("In variable mapping:\n           you try to assign '%s' to variable '%s'.\n          This mapping table keyword is skipped. Check allowed mapping table keywords.", kv->key, var2map);
569
570
          continue;
         }
571
      const char *value = kv->values[0];
572
573
/*      printf("'%s' = '%s'\n", key, value); */
      if ( !value ) continue;
574
/* Not necessary because cmor_name is what we use for renaming :
575
      else if ( STR_IS_EQ(key, "name")          ) vlistDefVarName(vlistID, varID, parameter2word(value));
576
*/
577
      else if ( STR_IS_EQ(key, "cn") )
578
579
580
581
582
583
584
        {
          char name[CDI_MAX_NAME];
          vlistInqVarName(vlistID, varID, name);
          if ( name[0] != 0 )
            cdiDefAttTxt(vlistID, varID, "original_name", (int) strlen(name), parameter2word(name));
          vlistDefVarName(vlistID, varID, parameter2word(value));
         }
585
586
587
      else if ( STR_IS_EQ(key, "u")        ) vlistDefVarUnits(vlistID, varID, value);
      else if ( STR_IS_EQ(key, "cm")  ) cdiDefAttTxt(vlistID, varID, "cell_methods", (int) strlen(value), value);
      else if ( STR_IS_EQ(key, "ca")  ) cdiDefAttTxt(vlistID, varID, "character_axis", (int) strlen(value), value);
588
      else if ( STR_IS_EQ(key, "za")  ) cdiDefAttTxt(vlistID, varID, "z_axis", (int) strlen(value), value);
589
/*      else if ( STR_IS_EQ(key, "factor")        ) {}
590
591
592
593
      else if ( STR_IS_EQ(key, "delete")        ) {}
      else if ( STR_IS_EQ(key, "long_name")     ) vlistDefVarLongname(vlistID, varID, value);
      else if ( STR_IS_EQ(key, "param")         ) vlistDefVarParam(vlistID, varID, stringToParam(parameter2word(value)));
      else if ( STR_IS_EQ(key, "out_param")     ) vlistDefVarParam(vlistID, varID, stringToParam(parameter2word(value)));
594
      else if ( STR_IS_EQ(key, "code")          ) {}
595
596
              // else if ( STR_IS_EQ(key, "code")          ) vlistDefVarParam(vlistID, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
              // else if ( STR_IS_EQ(key, "out_code")      ) vlistDefVarParam(vlistID, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
597
*/
598
      else if ( STR_IS_EQ(key, "vc")       ) cdiDefAttTxt(vlistID, varID, "comment", (int) strlen(value), value);
599
600
601
602
603
      else if ( STR_IS_EQ(key, "p")       )
        {
          if ( !isspace(value[0]) )
            cdiDefAttTxt(vlistID, varID, "positive", (int) strlen(value), value);
        }
604
/*      else if ( STR_IS_EQ(key, "cell_measures") ) cdiDefAttTxt(vlistID, varID, "cell_measures", (int) strlen(value), value);
605
606
607
608
609
610
      else if ( STR_IS_EQ(key, "convert")       ) {} 
      else if ( STR_IS_EQ(key, "missval")       )   {}  
      else if ( STR_IS_EQ(key, "valid_min")     ){}
      else if ( STR_IS_EQ(key, "valid_max")     ){}
      else if ( STR_IS_EQ(key, "ok_min_mean_abs") ) {}
      else if ( STR_IS_EQ(key, "ok_max_mean_abs") ){}
611
      else if ( STR_IS_EQ(key, "datatype") || STR_IS_EQ(key, "type") ) {} */
612
613
      else
        {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
614
          if ( cdoVerbose ) cdoPrint("In applying the mapping table:\n          Key: '%s' is ignored.", key);
615
616
617
618
619
        }
    }
}


620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
static int change_name_via_name(int vlistID, char *map_name, char *cmor_name)
{
  char name[CDI_MAX_NAME];
  for ( int varID = 0; varID < vlistNvars(vlistID); varID++ )
    {
      vlistInqVarName(vlistID, varID, name);
      if ( strcmp(name, map_name) == 0 )
        {
          vlistDefVarName(vlistID, varID, parameter2word((const char *) cmor_name));
          return 1;
        }
    }
  return 0;
}

static int change_name_via_code(int vlistID, char *map_code, char *cmor_name)
{
  int code;
  char codestring[4];
  for ( int varID = 0; varID < vlistNvars(vlistID); varID++ )
    {
      code = vlistInqVarCode(vlistID, varID);
      sprintf(codestring, "%03d", code);
      if ( strcmp(codestring, map_code) == 0 )
        {
          vlistDefVarName(vlistID, varID, parameter2word((const char *) cmor_name));
          return 1;
        }
    }
  return 0;
}


653
static int maptab_via_key(list_t *pml, int vlistID, int varID, int nventry, const char **ventry, const char *key, char *miptabfreq)
654
655
{
  char ifilevalue[CDI_MAX_NAME];
656
657
658
659
  if ( strcmp(key, "cmor_name") != 0 )
    get_ifilevalue(ifilevalue, key, vlistID, varID);
  else
    get_ifilevalue(ifilevalue, "name", vlistID, varID);
660

661
  if ( ifilevalue[0] )
662
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
663
      list_t *kvl = maptab_search_miptab(pml, ifilevalue, miptabfreq, key);
664
665
      if ( kvl )
        {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
666
667
668
          if ( cdoVerbose )
            cdoPrint("Start to map via '%s'.", key);
          map_it(kvl, vlistID, varID, ifilevalue);
669
670
          return 1;
        }
Fabian Wachsmann's avatar
Fabian Wachsmann committed
671
672
      if ( cdoVerbose )
        cdoPrint("In variable mapping:\n          Variable named '%s' with varID '%d' could not be mapped via '%s' because no corresponding key '%s' was found in mapping table file.", ifilevalue, varID, key, key);
673
      return 0;
674
675
676
    }
  else
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
677
678
      if ( cdoVerbose )
        cdoPrint("In variable mapping:\n          Variable with varID '%d' could not be mapped via '%s' because it does not possess a '%s' in infile.", varID, key, key);
679
680
681
682
      return 0;
    }
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
683
static int maptab_via_cn_and_key(list_t *kvl_oname, int vlistID, int nvars, const char *key)
684
685
{
  keyValues_t *kv = kvlist_search(kvl_oname, key);
Fabian Wachsmann's avatar
Fabian Wachsmann committed
686
  keyValues_t *kvcn = kvlist_search(kvl_oname, "cmor_name");
687
688
  if ( kv )
    {
689
      int varID = ( strcmp(key, "cmor_name") == 0 ) ? getVarIDToMap(vlistID, nvars, "name", kv->values[0]) : getVarIDToMap(vlistID, nvars, key, kv->values[0]);
690
      if ( varID != CDI_UNDEFID )
691
        {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
692
693
694
          if ( cdoVerbose )
            cdoPrint("Started mapping of variable via '%s'.", key);
          map_it(kvl_oname, vlistID, varID, kv->values[0]);
695
          return 1;
696
        }
Fabian Wachsmann's avatar
Fabian Wachsmann committed
697
      cdoPrint("In variable mapping:\n          Variable '%s' configured via cmor_name\n          could not be mapped via key '%s' because no infile variable '%s' equals '%s'.", kvcn->values[0], key, key, kv->values[0]);
698
699
    }
  else
Fabian Wachsmann's avatar
Fabian Wachsmann committed
700
701
    if ( cdoVerbose )
      cdoPrint("In variable mapping:\n          Variable '%s' configured via cmor_name\n          could not be mapped via key '%s' because it possesses no corresponding key '%s' in mapping file.", kvcn->values[0], key, key);
702
703
  return 0;
}
704

Fabian Wachsmann's avatar
Fabian Wachsmann committed
705
static void maptab_via_cmd(list_t *pml, const char *origValue, int vlistID, int nvars, const char *key, char *cmorName, char *miptabfreq)
706
{
707
708
  int varIDToMap = getVarIDToMap(vlistID, nvars, key, origValue);
  if ( varIDToMap == CDI_UNDEFID )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
709
    cdoAbort("In variable mapping:\n          Variable with '%s': '%s' configured via cmdline could not be found in infile '%s'.", key, origValue, cdoStreamName(0)->args);
710
  list_t *kvl_maptab = maptab_search_miptab(pml, cmorName, miptabfreq, "cmor_name");
711
  if ( !kvl_maptab )
712
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
713
      cdoWarning("In variable mapping:\n          The registered cmor_name '%s' via cmdline could not be found in mapping table.\n          No mapping table is applied.", cmorName);
714
      vlistDefVarName(vlistID, varIDToMap, parameter2word((const char *) cmorName));
715
    }
716
  else
717
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
718
719
720
      if ( cdoVerbose )
        cdoPrint("Started mapping of variable via '%s'.", key);
      map_it(kvl_maptab, vlistID, varIDToMap, cmorName);
721
    }
722
723
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
724
static void maptab_via_cn(list_t *pml, char **request, int vlistID, int nvars, int numvals, char *miptabfreq, int filetype)
725
{
726
  for ( int j = 0; j<numvals; j++)
727
    {
728
      list_t *kvl_oname = maptab_search_miptab(pml, request[j], miptabfreq, "cmor_name");
729
      if ( kvl_oname )
730
        {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
731
732
733
734
735
          if ( filetype == FILETYPE_GRB || filetype ==  FILETYPE_GRB2 )
            {
              if ( maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "code") )
                {
                  if ( cdoVerbose )
736
                    cdoPrint("Successfully mapped variable via code to cmor_name '%s'.", request[j]); 
Fabian Wachsmann's avatar
Fabian Wachsmann committed
737
738
739
                  continue;
                }
            }
740
741
          if ( maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "name") )
            {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
742
              if ( cdoVerbose )
743
                cdoPrint("Successfully mapped variable via name to cmor_name: '%s'.", request[j]); 
744
745
              continue;
            }
Fabian Wachsmann's avatar
Fabian Wachsmann committed
746
          else if ( ( filetype != FILETYPE_GRB && filetype != FILETYPE_GRB2 ) && maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "code") )
747
            {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
748
              if ( cdoVerbose )
749
                cdoPrint("Successfully mapped variable via code to cmor_name '%s'.", request[j]); 
750
751
              continue;
            }
752
753
          else
            {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
754
755
              if ( cdoVerbose )
                cdoPrint("In variable mapping:\n          Try to use cmor_name for selecting the infile variable.", request[j]);
756
              if ( maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "cmor_name") )
757
                {
758
                  cdoPrint("Successfully mapped variable via cmor_name to cmor_name '%s'.", request[j]); 
759
760
                  continue;
                }
761
              cdoWarning("In variable mapping:\n          Mapping table line of cmor_name '%s' could neither be mapped via 'name', 'code' nor 'cmor_name'.\n          No mapping for cmor_name: '%s'.", request[j],request[j]);
762
763
764
765
766
              continue;
            }
        }
      else
        {
767
          cdoWarning("In variable mapping:\n          Requested cmor_name: '%s' is not found in mapping table.\n          No mapping for cmor_name: '%s'", request[j],request[j]);
768
          continue;
769
770
        }
    }
771
}
772

773
774
775
/* */
/*... until here */
/* */
776

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
777
struct mapping
778
{
779
  int help_var;
780
781
  int cdi_varID;
  int cmor_varID;
782
  int zfactor_id;
783
  int charvars;
784
  char datatype;
785
  void *data;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
786
};
787

788
789
static struct mapping *construct_var_mapping(int streamID)
{
790
  int nvars_max = vlistNvars(pstreamInqVlist(streamID));
791
792
793
  struct mapping *vars =
    (struct mapping *) Malloc((nvars_max + 1) * sizeof(struct mapping));
  vars[0].cdi_varID = CDI_UNDEFID;
794
795
  vars[0].data = NULL;
  vars[0].charvars = 0;
796
797
798
799
800
801
802
803
804
805
  return vars;
}

static void destruct_var_mapping(struct mapping vars[])
{
  for ( int i = 0; vars[i].cdi_varID != CDI_UNDEFID; i++ )
    Free(vars[i].data);
  Free(vars);
}

806
static struct mapping *map_var(int cdi_varID, struct mapping vars[])
807
{
808
809
810
811
812
813
814
815
816
817
818
  for ( int i = 0; vars[i].cdi_varID != CDI_UNDEFID; i++ )
    if ( cdi_varID == vars[i].cdi_varID )
      return &vars[i];
  return NULL;
}

static struct mapping *new_var_mapping(struct mapping vars[])
{
  int i;
  for ( i = 0; vars[i].cdi_varID != CDI_UNDEFID; i++ );
  vars[i + 1].cdi_varID = CDI_UNDEFID;
819
820
  vars[i + 1].data = NULL;
  vars[i + 1].charvars = 0;
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
  return &vars[i];
}

static int *new_axis_id(int *axis_ids)
{
  int i;
  for ( i = 0; axis_ids[i] != CMOR_UNDEFID; i++ );
  axis_ids[i + 1] = CMOR_UNDEFID;
  return &axis_ids[i];
}

static int count_axis_ids(int *axis_ids)
{
  int i;
  for ( i = 0; axis_ids[i] != CMOR_UNDEFID; i++ );
  return i;
}
838

Fabian Wachsmann's avatar
Fabian Wachsmann committed
839
static void addcharvar(keyValues_t *charvars, int vlistID, const char *key, struct mapping vars[])
840
841
{
  if ( cdoVerbose )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
842
    cdoPrint("Start to merge variables to one character coordinate.");
843
844
845
846
847
848
  int varIDs[charvars->nvalues];
  int nvars = vlistNvars(vlistID);
  for ( int i = 0; i < charvars->nvalues; i++)
    {
      varIDs[i] = getVarIDToMap(vlistID, nvars, key, charvars->values[i]);
      if ( varIDs[i] == CDI_UNDEFID )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
849
        cdoAbort("In merging variables to a variable with a character coordinate:\n          Could not find '%s' in infile '%s' to build a variable with character coordinate.", charvars->values[i], cdoStreamName(0)->args);
850
851
852
853
854
855
856
857
858
859
860
    }

  int gridID = vlistInqVarGrid(vlistID, varIDs[0]);
  int subgridID;
  int zaxisID = vlistInqVarZaxis(vlistID, varIDs[0]);
  int subzaxisID;
  int ntsteps = vlistNtsteps(vlistID);

  if ( cdoStreamName(0)->args[0] == '-' )
    cdoAbort("No variables can be merged to one character axis since you piped several cdo operators.");

861
  int streamID2 = pstreamOpenRead(cdoStreamName(0));
862
863
864
865
  if ( ntsteps == -1 )
    {
      ntsteps = 0;
      int dummy;
866
      while ( ( dummy = pstreamInqTimestep(streamID2, ntsteps++) ) );
867
868
869
870
871
    }

  int axissize[3];
  double *xvals, *yvals, *zvals, *subsvals;

Fabian Wachsmann's avatar
Fabian Wachsmann committed
872
  subsvals = (double *) Malloc(charvars->nvalues * sizeof(double));
873
874
875
876
877
878
879
880
881
  for ( int i = 0; i < charvars->nvalues; i++ )
    subsvals[i] = i+1;

  axissize[0] = gridInqXsize(gridID);
  axissize[1] = gridInqYsize(gridID);
  axissize[2] = zaxisInqSize(zaxisID);


  if ( axissize[0] != 1 && axissize[1] != 1 && axissize[2] != 1 )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
882
    cdoAbort("In merging variables to a variable with a character coordinate:\n          No axis found to merge. One axis may not be allocated with more than one value.");
883
884
885
886
887
888
889
890
891

  int oldgridsize = axissize[0] * axissize[1];
  double *buffer_old = (double *)Malloc(oldgridsize * sizeof(double));

  for ( int i = 1; i < charvars->nvalues; i++)
    {
      gridID = vlistInqVarGrid(vlistID, varIDs[i]);  
      zaxisID = vlistInqVarZaxis(vlistID, varIDs[i]);
      if ( axissize[0] != gridInqXsize(gridID) )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
892
        cdoAbort("In merging variables to a variable with a character coordinate:\n          Size of x-axis: '%d' of variable '%s'\n          differ from x-axis size of variable '%s': '%d'.", gridInqXsize(gridID), charvars->values[i], charvars->values[0], axissize[0]);
893
      if ( axissize[1] != gridInqYsize(gridID) )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
894
        cdoAbort("In merging variables to a variable with a character coordinate:\n          Size of y-axis: '%d' of variable '%s'\n          differ from y-axis size of variable '%s': '%d'.", gridInqYsize(gridID), charvars->values[i], charvars->values[0], axissize[1]);
895
      if ( axissize[2] != zaxisInqSize(zaxisID) )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
896
        cdoAbort("In merging variables to a variable with a character coordinate:\n          Size of z-axis: '%d' of variable '%s'\n          differ from z-axis size of variable '%s': '%d'.", zaxisInqSize(zaxisID), charvars->values[i], charvars->values[0], axissize[2]);
897
898
899
900
901
    }

  if ( axissize[0] == 1 )
    {
      xvals = subsvals;
Fabian Wachsmann's avatar
Fabian Wachsmann committed
902
903
      yvals = (double *) Malloc(axissize[1] * sizeof(double));
      zvals = (double *) Malloc(axissize[2] * sizeof(double));
904
905
906
907
908
909
      gridInqYvals(gridID, yvals);
      zaxisInqLevels(zaxisID, zvals); 
      axissize[0] = charvars->nvalues;
    }
  else if ( axissize[1] == 1 )
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
910
      xvals = (double *) Malloc(axissize[0] * sizeof(double));
911
      yvals = subsvals;
Fabian Wachsmann's avatar
Fabian Wachsmann committed
912
      zvals = (double *) Malloc(axissize[2] * sizeof(double));
913
914
915
916
917
918
      gridInqXvals(gridID, xvals);
      zaxisInqLevels(zaxisID, zvals); 
      axissize[1] = charvars->nvalues;
    }
  else if ( axissize[2] == 1 )
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
919
920
      xvals = (double *) Malloc(axissize[0] * sizeof(double));
      yvals = (double *) Malloc(axissize[1] * sizeof(double));
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
      zvals = subsvals;
      gridInqXvals(gridID, xvals);
      gridInqYvals(gridID, yvals);
      axissize[2] = charvars->nvalues;
    }

  subgridID = gridCreate(GRID_GENERIC, axissize[0]*axissize[1]);
  subzaxisID = zaxisCreate(zaxisInqType(zaxisID), axissize[2]);

  gridDefXsize(subgridID, axissize[0]); 
  gridDefYsize(subgridID, axissize[1]); 
  gridDefXvals(subgridID, xvals); 
  gridDefYvals(subgridID, yvals); 
  zaxisDefLevels(subzaxisID, zvals); 

  struct mapping *var = new_var_mapping(vars);
937
  var->cdi_varID = vlistDefVar(vlistID, subgridID, subzaxisID,  TIME_VARYING);
938
939
940
941
942
943
944
945
946
947
948
  vlistDefVarName(vlistID, getVarIDToMap(vlistID, nvars+1, key, charvars->values[0]), "ChangedForMap");
  vlistDefVarName(vlistID, var->cdi_varID, charvars->values[0]);
  vlistDefVarDatatype(vlistID, var->cdi_varID,  DATATYPE_FLT64);
  vlistDefVarMissval(vlistID, var->cdi_varID, vlistInqVarMissval(vlistID, varIDs[0]));
  var->datatype = 'd';
  var->data = Malloc(ntsteps*axissize[0]*axissize[1]*axissize[2]*sizeof(double));

  int testzaxisID = vlistInqVarZaxis(vlistID, var->cdi_varID);

  int tsID = 0, nrecs = 0;

949
  while ( (nrecs = pstreamInqTimestep(streamID2, tsID)) )
950
951
952
    {
      while ( nrecs-- )
        {
Uwe Schulzweida's avatar
Uwe Schulzweida committed
953
954
          int varIDrw, levelIDrw;
          size_t nmiss;
955
          pstreamInqRecord(streamID2, &varIDrw, &levelIDrw);
956
957
958
          for ( int i = 0; i < charvars->nvalues; i++ )
            if ( varIDrw == varIDs[i] )
              {
959
                pstreamReadRecord(streamID2, buffer_old, &nmiss);
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
                int newIndex;
                for ( int j = 0; j < oldgridsize; j++ )
                  {
/* (lev x lat, basin ) 
            newIndex = j * levdim + levelID; */
                    if ( oldgridsize == axissize[0]*axissize[1] )
                      newIndex = tsID*axissize[2]*axissize[0]*axissize[1]+i*axissize[0]*axissize[1] + j;
                    else if ( axissize[0] == charvars->nvalues )
                      newIndex = tsID*axissize[2]*axissize[0]*axissize[1]+i*axissize[1]*axissize[2] + j*axissize[2] + levelIDrw;
                    else
                      newIndex = tsID*axissize[2]*axissize[0]*axissize[1]+levelIDrw*axissize[0]*axissize[1] + i*axissize[0]*axissize[1]/oldgridsize + j;
                    ((double *)var->data)[newIndex] = (double) buffer_old[j];
                  }
              }
        }
      tsID++;
    }
  var->charvars = 1;

979
  pstreamClose(streamID2);
980
981
982
  Free(buffer_old);

  if ( cdoVerbose )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
983
    cdoPrint("Successfully merged variables into one character axis. The final variable is called '%s' and has the ID: '%d'", charvars->values[0], var->cdi_varID);
984
985
}

Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
986
987
static char *trim(char *s)
{
988
  if (s == NULL) return s;
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
989
990
  while ( *s != '\0' && (isspace(*s) || *s == '"') )
    s++;
991
  int n = strlen(s);
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
992
993
994
995
996
997
  while ( n > 0 && (isspace(s[n - 1]) || s[n - 1] == '"') )
    n--;
  s[n] = '\0';
  return s;
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
998
static int file_exist(const char *tfilename, int force, const char *fileart)
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
999
{
Fabian Wachsmann's avatar
above    
Fabian Wachsmann committed
1000
1001
1002
  assert(tfilename != NULL);
  size_t filesize = fileSize(tfilename);
  if ( filesize == 0 && force)
Fabian Wachsmann's avatar
Fabian Wachsmann committed
1003
    cdoAbort("In checking wether a %s file exist:\n          Empty file: '%s'.", fileart, tfilename);
Fabian Wachsmann's avatar
above    
Fabian Wachsmann committed
1004
  else if ( filesize == 0 && !force )
1005
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
1006
      cdoPrint("In checking wether a %s file exist:\n          Empty file: '%s'.", fileart, tfilename);
Fabian Wachsmann's avatar
above    
Fabian Wachsmann committed
1007
      return 0;
1008
    }
1009
1010
  if ( strstr(tfilename, ".nc") || strstr(tfilename, ".grb") )
    return 1;
Fabian Wachsmann's avatar
above    
Fabian Wachsmann committed
1011
1012
  FILE *fp = fopen(tfilename, "r");
  if ( fp == NULL && force )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
1013
    cdoAbort("In checking wether a %s file exist:\n          Open failed on: '%s'.", fileart, tfilename);
Fabian Wachsmann's avatar
above    
Fabian Wachsmann committed
1014
  else if ( fp == NULL && !force )
1015
    {
Fabian Wachsmann's avatar
Fabian Wachsmann committed
1016
      cdoPrint("In checking wether a %s file exist::\n          Open failed on: '%s'.", fileart, tfilename);
1017
      return 0;
1018
    }
Fabian Wachsmann's avatar
above    
Fabian Wachsmann committed
1019
1020

  fclose(fp);
1021
1022
1023
  return 1;
}
  
1024
static int parse_kv_file(list_t *kvl, const char *filename)
1025
{
1026
1027
  if ( file_exist(filename, 0, "configuration") == 0 )
    return 0;
1028

1029
1030
1031
1032
1033
  FILE *fp = fopen(filename, "r");
  size_t filesize = fileSize(filename);
  char *buffer = (char*) Malloc(filesize);
  size_t nitems = fread(buffer, 1, filesize, fp);
  fclose(fp);
Mathis Rosenhauer's avatar
Mathis Rosenhauer committed
1034

Fabian Wachsmann's avatar
Fabian Wachsmann committed
1035
1036
  kv_insert_a_val(kvl, "workfile4err", (char *)filename, 1);
  parse_buffer_to_list(kvl, filesize, buffer, 0, 1, kvl);
1037
1038

  if ( buffer ) Free(buffer);
1039
  return 1;
1040
1041
}

Fabian Wachsmann's avatar
Fabian Wachsmann committed
1042
static void check_compare_set(char **finalset, char *attribute, const char *attname, const char *defaultstr)
1043
{
Fabian Wachsmann's avatar
Fabian Wachsmann committed
1044
  if ( !(*finalset) )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
1045
    {
1046
      if ( !attribute )
Fabian Wachsmann's avatar
Fabian Wachsmann committed
1047
        {
1048
1049
          if ( defaultstr )
            *finalset = strdup(defaultstr);
Fabian Wachsmann's avatar
Fabian Wachsmann committed