SURFEX v8.1
General documentation of Surfex
lfi_grok.c
Go to the documentation of this file.
1 /**** *lfi_grok.c* - Find out the kind of an LFI file
2  *
3  * Author.
4  * -------
5  * Philippe Marguinaud *METEO-FRANCE*
6  * Original : 12-08-2013
7  * Modified : 08-12-2014 Portability on Mac OSX
8  *
9  */
10 #include <stdio.h>
11 #include <ctype.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #if defined(DARWIN)
15 #include <limits.h>
16 #define MAXINT INT_MAX
17 #define MAXLONG LONG_MAX
18 #elif defined(MACOSX)
19 #include <limits.h>
20 #define MAXINT INT_MAX
21 #else
22 #include <values.h>
23 #endif
24 #include <errno.h>
25 
26 #include "lfi_grok.h"
27 #include "lfi_type.h"
28 #include "lfi_misc.h"
29 #include "lfi_abor.h"
30 
31 
32 #define YYYYMMDD_chk(x) (((x) >= 19000000) && ((x) <= 21000000))
33 #define HHmmss_chk(x) ((x) <= 999999)
34 
35 /* Open a LFI file and try to guess its type */
36 lfi_grok_t lfi_grok (const character * file, character_len file_len)
37 {
38  FILE * fp;
39  char f[file_len+1];
40  integer64 isect1[22];
41  char cmagic[8];
42  lfi_grok_t lg;
43  int nr;
44  int i;
45 
46  memcpy (f, file, file_len);
47  f[file_len] = '\0';
48  for (i = file_len-1; i >= 0; i--)
49  if (f[i] == ' ')
50  f[i] = '\0';
51  else
52  break;
53 
54  fp = fopen (f, "r");
55 
56  if (fp == NULL)
57  goto lfi_none;
58 
59  nr = fread (isect1, sizeof (integer64), 22, fp);
60 
61  if (nr != 22)
62  goto lfi_altm;
63 
64  if (isect1[3] != 22)
65  {
66  int t = 8, n = 22;
67  jswap_ (isect1, isect1, &t, &n);
68  }
69 
70  if (isect1[3] != 22)
71  goto lfi_altm;
72 
73  if (isect1[1] != 16)
74  goto lfi_altm;
75 
76  if (! YYYYMMDD_chk (isect1[13]))
77  goto lfi_altm;
78 
79  if (! HHmmss_chk (isect1[14]))
80  goto lfi_altm;
81 
82  lg = LFI_PURE;
83  goto done;
84 
85 lfi_altm:
86 
87  fseek (fp, 0, SEEK_SET);
88  nr = fread (cmagic, 1, 8, fp);
89  if (nr != 8)
90  goto lfi_unkn;
91  if (memcmp ("LFI_ALTM", cmagic, 8))
92  goto lfi_unkn;
93  lg = LFI_ALTM;
94 
95  goto done;
96 
97 lfi_none:
98 
99  lg = LFI_NONE;
100  goto done;
101 
102 lfi_unkn:
103 
104  lg = LFI_UNKN;
105  goto done;
106 
107 done:
108 
109  if (fp != NULL)
110  fclose (fp);
111 
112  errno = 0;
113 
114  return lg;
115 }
116 
117 
118 static int iscan (const char ** str, int * val)
119 {
120  int j, k = 1;
121  const char * s = *str;
122 
123  if (*s == '+')
124  s++;
125  if (*s == '-')
126  {
127  s++;
128  k = -1;
129  }
130  if (! isdigit (*s))
131  return 0;
132 
133  j = 0;
134  for ( ; isdigit (*s); s++)
135  j = 10 * j + (*s - '0');
136 
137  *str = s;
138  *val = k * j;
139 
140  return 1;
141 }
142 
143 /* Find the LFI library to use to open a given LFI unit (KNUMER)
144  * we use the variable LFI_HNDL_SPEC to do that
145  */
147 {
148  int unit = *KNUMER;
149  const char * str = (const char *)getenv ("LFI_HNDL_SPEC");
150  int unum = 0;
151 
152  if (str == NULL)
153  return 0;
154 
155  while (1)
156  {
157  int umin = -MAXINT;
158  int umax = +MAXINT;
159  int u;
160  int rmin = iscan (&str, &umin);
161 
162  if (strncmp (str, "..", 2) == 0)
163  {
164  str += 2;
165  iscan (&str, &umax);
166  }
167  else if (rmin)
168  {
169  umax = umin;
170  }
171 
172  if (strncmp (str, ":", 1) != 0)
173  goto error;
174  str++;
175 
176  iscan (&str, &u);
177 
178  if ((umin <= unit) && (unit <= umax))
179  {
180  unum = u;
181  break;
182  }
183 
184 
185  if (str[0] == '\0')
186  break;
187 
188  if (str[0] != ',')
189  goto error;
190 
191  str++;
192 
193  }
194 
195  return unum;
196 
197 error:
198 
199  lfi_abor ("Could not parse LFI_HNDL_SPEC =`%s'", str);
200 
201  return -1;
202 }
203 
204 
205 
206 
FILE * fp
Definition: opfla_perfmon.c:24
long long int integer64
Definition: lfi_type.h:15
int character_len
Definition: lfi_type.h:17
lfi_grok_t lfi_grok(const character *file, character_len file_len)
Definition: lfi_grok.c:36
char character
Definition: lfi_type.h:18
void lfi_abor(const char *fmt,...)
Definition: lfi_abor.c:21
int lfi_unum(integer64 *KNUMER)
Definition: lfi_grok.c:146
ERROR in n
Definition: ecsort_shared.h:90
static int iscan(const char **str, int *val)
Definition: lfi_grok.c:118
INTERFACE SUBROUTINE FACILO KNUMER
Definition: facilo.h:4
void jswap_(void *, const void *, const int *, const int *)
subroutine t(CDPREF, CDSUFF, KCODPA, LDNIVA, PMULTI)
Definition: faicor.F90:567
lfi_grok_t
Definition: lfi_grok.h:14