1 | /* FILENAME: ld_dec_lookup.c |
---|
2 | Revision logs: |
---|
3 | 16Jul97 /atn: clear Decoder section of structs only; chg warnings to Stdout; |
---|
4 | */ |
---|
5 | #include <stdio.h> |
---|
6 | #include <string.h> |
---|
7 | #include <stdlib.h> |
---|
8 | #include "grib_lookup.h" /* combined lookup structs */ |
---|
9 | #include "dprints.h" /* for dprints */ |
---|
10 | #include "gribfuncs.h" /* prototypes */ |
---|
11 | |
---|
12 | /* |
---|
13 | *..................................................... |
---|
14 | * ld_dec_lookup.c defines the following global vars: |
---|
15 | *..................................................... |
---|
16 | * PARM_DEFN db_parm_tbl[NPARM*MAX_PARM_TBLS] Parameter Conversion info |
---|
17 | * LVL_DEFN db_lvl_tbl[NLEV] Level Conversion info |
---|
18 | * MODEL_DEFN db_mdl_tbl[NMODEL] Model Conversion info |
---|
19 | * GEOM_DEFN db_geom_tbl[NGEOM] Geom Conversion info |
---|
20 | * |
---|
21 | */ |
---|
22 | PARM_DEFN db_parm_tbl [NPARM*MAX_PARM_TBLS];/* GLOBVAR parm conversion info*/ |
---|
23 | LVL_DEFN db_lvl_tbl [NLEV]; /* GLOBVAR level conversion info */ |
---|
24 | MODEL_DEFN db_mdl_tbl [NMODEL]; /* GLOBVAR model conversion info */ |
---|
25 | GEOM_DEFN db_geom_tbl [NGEOM]; /* GLOBVAR Geom conversion info */ |
---|
26 | |
---|
27 | /* |
---|
28 | ********************************************************************** |
---|
29 | * A. FUNCTION: ld_dec_lookup |
---|
30 | * This function reads in the information from an external Lookup |
---|
31 | * table (ie: g1tab_2.1). This info is used to convert |
---|
32 | * from the Database's parameter names to the GRIB Code Numbers. |
---|
33 | * |
---|
34 | * INTERFACE: |
---|
35 | * int ld_dec_lookup (lookup_fn, errmsg) |
---|
36 | * |
---|
37 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
38 | * (I) char *lookup_fn |
---|
39 | * Name of Lookup file to read from (ie: /abspath/g1tab_128_2.1) |
---|
40 | * (O) char *errmsg |
---|
41 | * empty array, returned filled if error occurred; |
---|
42 | * |
---|
43 | * RETURN CODE: |
---|
44 | * 0> successful, the 4 database tables Filled; |
---|
45 | * 1> file open error or got error/eof while reading; errmsg filled; |
---|
46 | ********************************************************************** |
---|
47 | * |
---|
48 | - REQUIREMENTS: *** do not use the TAB character !!! *** |
---|
49 | - Rules for creating Decoder Lookup file: |
---|
50 | - a) lines starting out with '#' is Comment lines & are skipped; |
---|
51 | - b) the tables within the file are defined in this order: |
---|
52 | - 'GRIB Table 2', |
---|
53 | - 'GRIB Table 2 - Sub A', |
---|
54 | - 'GRIB Table 2 - Sub B', |
---|
55 | - 'GRIB Table 2 - Sub C', |
---|
56 | - 'GRIB Table 2 - Sub D', |
---|
57 | - 'GRIB Table 2 - Sub E', |
---|
58 | - 'GRIB Table 3: Level Definitions', |
---|
59 | - 'GRIB Table - Generating Process Definitions (Octet 6 of PDS)', |
---|
60 | - 'GRIB Table - Pre-defined geometries (Octet 7 of PDS)' |
---|
61 | - c) Each Header section MUST start out with "GRIB Table"; |
---|
62 | - All Header Section except that of the LEVEL tbl MUST end with a line |
---|
63 | - containing atleast 4 consecutives '='; |
---|
64 | - e) Header lines are any number of lines before the '===' line which is |
---|
65 | - considered as a the last line of this section's Header; |
---|
66 | - f) the Parameter defn (Table 2 & subTables) must have at least 2 spaces |
---|
67 | - between the Field Parameter and Unit fields; |
---|
68 | - |
---|
69 | - While getting entries for current table, the program assumes it has |
---|
70 | - gotten to the end of current Table if Hdr SEction for next Table |
---|
71 | - (string "GRIB Table"). |
---|
72 | */ |
---|
73 | |
---|
74 | #if PROTOTYPE_NEEDED |
---|
75 | int ld_dec_lookup ( char *lookup_fn, char *errmsg) |
---|
76 | #else |
---|
77 | int ld_dec_lookup ( lookup_fn, errmsg) |
---|
78 | char *lookup_fn; |
---|
79 | char *errmsg; |
---|
80 | #endif |
---|
81 | { |
---|
82 | FILE *infile; |
---|
83 | char *func="ld_dec_lookup", line[200], temp[200], dummy; |
---|
84 | char *ptr2, *ptr, strGribCode[50], grib_dsc[150], grib_unit_dsc[150]; |
---|
85 | char strScale[50], strOffset[50], strDSF[50]; |
---|
86 | char lvl_name_1[150], lvl_name_2[150]; |
---|
87 | int LineRead, indx, sub, stat=1, num, cnt, iOctets; |
---|
88 | char strOctets[30]; |
---|
89 | int GribCode; |
---|
90 | PARM_DEFN *parmptr; /* ptr to cell w/in Parm array */ |
---|
91 | |
---|
92 | DPRINT1 ("Entering %s\n", func); |
---|
93 | /* |
---|
94 | * A.0 CLEAR out all the lookup arrays's decoder part |
---|
95 | */ |
---|
96 | for (num=0; num < NPARM ; num++) { |
---|
97 | db_parm_tbl[num].usParm_id= num; |
---|
98 | db_parm_tbl[num].usParm_sub= 0; /* not used for main tbl */ |
---|
99 | db_parm_tbl[num].grib_dsc[0] ='\0'; |
---|
100 | db_parm_tbl[num].grib_unit_dsc[0] ='\0'; |
---|
101 | } |
---|
102 | for (num=NPARM; num < NPARM * MAX_PARM_TBLS; num++) { /* for sub-tbls */ |
---|
103 | db_parm_tbl[num].usParm_id= 249 + num / NPARM; |
---|
104 | db_parm_tbl[num].usParm_sub= num % NPARM; |
---|
105 | db_parm_tbl[num].grib_dsc[0] ='\0'; |
---|
106 | db_parm_tbl[num].grib_unit_dsc[0] ='\0'; |
---|
107 | } |
---|
108 | |
---|
109 | for (num=0; num < NLEV; num++) { |
---|
110 | db_lvl_tbl[num].usLevel_id = num; |
---|
111 | db_lvl_tbl[num].grib_dsc[0] = '\0'; |
---|
112 | db_lvl_tbl[num].lvl_name_1[0] = '\0'; |
---|
113 | db_lvl_tbl[num].lvl_name_2[0] = '\0'; |
---|
114 | db_lvl_tbl[num].num_octets = 0; |
---|
115 | } |
---|
116 | |
---|
117 | for (num=0; num < NMODEL; num++) { |
---|
118 | db_mdl_tbl[num].usModel_id = num; |
---|
119 | db_mdl_tbl[num].grib_dsc[0] = '\0'; |
---|
120 | } |
---|
121 | |
---|
122 | for (num=0; num < NGEOM; num++) { |
---|
123 | db_geom_tbl[num].usGeom_id = num; |
---|
124 | db_geom_tbl[num].grib_dsc[0] = '\0'; |
---|
125 | } |
---|
126 | |
---|
127 | /* |
---|
128 | * |
---|
129 | * A.1 OPEN Lookup file for reading |
---|
130 | * RETURN 1 if fails; |
---|
131 | */ |
---|
132 | infile = fopen(lookup_fn, "r"); |
---|
133 | if (infile==NULL) { |
---|
134 | DPRINT2 ("%s: failed to open %s\n", func, lookup_fn); |
---|
135 | sprintf (errmsg ,"%s: failed to open %s\n", func, lookup_fn); |
---|
136 | goto BYE; |
---|
137 | } |
---|
138 | DPRINT1 ("Loading Decoder file= '%s'\n", lookup_fn); |
---|
139 | |
---|
140 | /**** PARM SECTION (TABLE 0/A/B/C/D/E) *** |
---|
141 | To be loaded continuously where Main tbl range is 0-255, B is 256-511, ... |
---|
142 | Sample: |
---|
143 | GRIB Table 2 |
---|
144 | Code Figure Field Parameter Unit |
---|
145 | =========== =============== ==== |
---|
146 | 000 Reserved * |
---|
147 | 001 Pressure Pa |
---|
148 | 002 Pressure reduced to MSL Pa |
---|
149 | 003 Pressure tendency Pa/s |
---|
150 | ##################################################################### |
---|
151 | GRIB Table 2 - Sub A |
---|
152 | Code Figure Field Parameter Unit |
---|
153 | =========== =============== ==== |
---|
154 | ###################################################################### |
---|
155 | GRIB Table 2 - Sub B |
---|
156 | Code Figure Field Parameter Unit |
---|
157 | =========== =============== ==== |
---|
158 | ###################################################################### |
---|
159 | GRIB Table 2 - Sub C |
---|
160 | Code Figure Field Parameter Unit |
---|
161 | =========== =============== ==== |
---|
162 | ###################################################################### |
---|
163 | GRIB Table 2 - Sub D |
---|
164 | Code Figure Field Parameter Unit |
---|
165 | =========== =============== ==== |
---|
166 | ###################################################################### |
---|
167 | |
---|
168 | * |
---|
169 | * *** Parameter Conversion info *** |
---|
170 | * A.2 FOR (each Parameter Table/subTable to load) DO |
---|
171 | */ |
---|
172 | LineRead = 0; |
---|
173 | for (sub=0; sub < 6; sub++) { /* 6 Parm tables altogether (0/A/B/C/D/E) */ |
---|
174 | /* |
---|
175 | * A.2.1 CALCULATE the index offset for this Table within the Parm array |
---|
176 | */ |
---|
177 | indx = sub * 256; |
---|
178 | |
---|
179 | /* |
---|
180 | * A.2.2 KEEP reading until end of comment line (line with '====') |
---|
181 | * RETURN error if fails |
---|
182 | */ |
---|
183 | /* Read until last of Header line */ |
---|
184 | for (line[0]='\0'; ! strstr(line,"====") ; ) |
---|
185 | { |
---|
186 | fgets(line, sizeof(line), infile); ++LineRead; |
---|
187 | if (feof(infile) || ferror(infile)) |
---|
188 | { sprintf(errmsg, |
---|
189 | "%s: got EOF/ERROR before PARM TABLE #%d info (Line %d in %s)\n", |
---|
190 | func, sub, LineRead, lookup_fn); |
---|
191 | goto BYE; |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | /* |
---|
196 | * A.2.3 FOR (successfully read a line from file) DO |
---|
197 | * LOOP if it's a comment line |
---|
198 | * BREAK out if already got to next Section (see "GRIB Table") |
---|
199 | * DROP line if it's a empty line |
---|
200 | */ |
---|
201 | DPRINT2("*** %s: Start reading Tbl2- sub#%d ***\n", func, sub); |
---|
202 | for (cnt=0 ; fgets(line, sizeof(line), infile)!=NULL; ) |
---|
203 | { |
---|
204 | ++LineRead; |
---|
205 | /* skip additional comments, Break if already got to next Table Defn, |
---|
206 | else replace tabs with spaces, newlines with null |
---|
207 | */ |
---|
208 | for (ptr=line; *ptr==' '; ptr++) ; if (*ptr == '#') continue; |
---|
209 | if (strstr(line, "GRIB Table ") != NULL) break; /* END OF CURR SECT */ |
---|
210 | while (ptr=strchr(line,'\t')) *ptr=' '; |
---|
211 | if (ptr=strchr(line,'\n')) *ptr='\0'; |
---|
212 | /* |
---|
213 | * EXTRACT line partially !Parmid, 1st word of Description |
---|
214 | * DROP line out if extraction fails; |
---|
215 | * DROP line if parmid is invalid or out or range |
---|
216 | * >> Note: valid parm id range is 0-255 for main table, |
---|
217 | * 1-255 for sub tables. |
---|
218 | */ |
---|
219 | /* DO a partial read, get parm_id and 1st word of Description */ |
---|
220 | if ((num=sscanf (line,"%s%s", strGribCode, temp )) !=2) { |
---|
221 | if (num>0) fprintf(stdout, |
---|
222 | "Warning: drop incomplete %s Line %d\n" ,lookup_fn, LineRead); |
---|
223 | continue; |
---|
224 | } |
---|
225 | |
---|
226 | /* Make sure Parmid field has a Number */ |
---|
227 | if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) { |
---|
228 | fprintf(stdout,"Warning: Invalid Parmid '%s', drop line#%d in %s\n", |
---|
229 | strGribCode, LineRead, lookup_fn); |
---|
230 | continue; } |
---|
231 | |
---|
232 | GribCode = atoi(strGribCode); |
---|
233 | /* check if id is out of range */ |
---|
234 | if (GribCode < 0 || GribCode >= NPARM) { |
---|
235 | fprintf(stdout, |
---|
236 | "Warning: Parm id '%d' out of range, drop %s:Line %d\n", |
---|
237 | GribCode, lookup_fn, LineRead); continue; } |
---|
238 | |
---|
239 | /* |
---|
240 | Can only have Parm code 0 in Main table; |
---|
241 | Donot load if parm is 0 and this is a Sub table; |
---|
242 | */ |
---|
243 | if (GribCode == 0 && sub!=0) { |
---|
244 | fprintf(stdout, |
---|
245 | "Warning: cannot have Gribcode 0 in Sub-tables, drop %s:Line %d\n", |
---|
246 | lookup_fn, LineRead); continue; |
---|
247 | } |
---|
248 | |
---|
249 | /* |
---|
250 | * EXTRACT Grib_Dsc & Grib_Unit_Dsc from line (both multi words) |
---|
251 | * !these 2 fields must be separated by atleast 2 spaces; |
---|
252 | * DROP line if cannot find Grib_Dsc/Unit; |
---|
253 | */ |
---|
254 | /* |
---|
255 | Now, get Grib_Desc and Grib_Unit_Dsc fields, both multi words... |
---|
256 | TEMP has 1st word of the Grib_Desc; This field ends when |
---|
257 | we see 2 consecutive spaces; |
---|
258 | locate Grib_Desc, move max of 75, then cap it where there are |
---|
259 | 4 consecutive spaces |
---|
260 | */ |
---|
261 | if (!(ptr= strstr (line, temp)) || !(ptr2= strstr (ptr, " "))) |
---|
262 | { fprintf(stdout, |
---|
263 | "Warning: cannot find Grib_Dsc, drop line#%d in %s\n", |
---|
264 | LineRead, lookup_fn); continue; |
---|
265 | } |
---|
266 | strncpy (grib_dsc, ptr, ptr2-ptr); /*sizeof(grib_dsc)-1); */ |
---|
267 | grib_dsc[ptr2 - ptr] = '\0'; |
---|
268 | |
---|
269 | /* Grib_Dsc now contains both "Desc & Unit", find where Unit begins |
---|
270 | (look for 2 consecutive spaces) then put null terminator to cap |
---|
271 | off Grib_Dsc |
---|
272 | if ((ptr= strstr (grib_dsc, " ")) == NULL) |
---|
273 | */ |
---|
274 | |
---|
275 | while (*ptr2==' ') ptr2++; |
---|
276 | if (! *ptr2) |
---|
277 | { fprintf(stdout, "Warning: cannot find Unit, drop Line %d in %s\n" , |
---|
278 | LineRead, lookup_fn); |
---|
279 | continue; |
---|
280 | } |
---|
281 | else strcpy (grib_unit_dsc, ptr2); |
---|
282 | for (ptr=grib_unit_dsc + strlen(grib_unit_dsc)-1; *ptr==' '; ptr--) |
---|
283 | *ptr='\0'; /* remove ending spaces */ |
---|
284 | |
---|
285 | /* |
---|
286 | *ptr= '\0'; /# cap off GribDsc, where delimitor begins #/ |
---|
287 | for (ptr= grib_unit_dsc+strlen(grib_unit_dsc) -1; |
---|
288 | *ptr=='\n' || *ptr == ' '; --ptr) |
---|
289 | *ptr='\0'; /# rm ending spaces in Unit #/ |
---|
290 | */ |
---|
291 | |
---|
292 | |
---|
293 | /* |
---|
294 | * DROP defn if this parmid is already defined; |
---|
295 | */ |
---|
296 | parmptr = db_parm_tbl + indx + GribCode; |
---|
297 | if (parmptr->grib_dsc[0] != '\0') { |
---|
298 | fprintf(stdout, |
---|
299 | "Warning: duplic Parm defn #%d (Index=%d), drop line %d in %s\n", |
---|
300 | GribCode, PARMTBL_INDX (parmptr->usParm_id, parmptr->usParm_sub), |
---|
301 | LineRead, lookup_fn); |
---|
302 | continue; |
---|
303 | } |
---|
304 | /* |
---|
305 | * STORE info in the array cell whose index is 'parm_id' |
---|
306 | * !undefined parm ids are all set to zero; |
---|
307 | */ |
---|
308 | /* depending on which Table Code it is, entry will be stored in |
---|
309 | its corresponding Parameter Range; |
---|
310 | >>> ENTRIES ARE STORED IN ARRAY CELL WHOSE INDEX IS 'PARM_ID' |
---|
311 | >>> UNDEFINED IDS WILL HAVE CELL WITH EMPTY DEFNS; |
---|
312 | */ |
---|
313 | /* Store entry just read in Parm Defn Array */ |
---|
314 | |
---|
315 | if (sub == 0) { /* Main Table only */ |
---|
316 | parmptr->usParm_id = (unsigned short)GribCode; |
---|
317 | parmptr->usParm_sub = 0; |
---|
318 | } |
---|
319 | else { /* for all Sub-Tables (non-zero sub) */ |
---|
320 | parmptr->usParm_id = sub + 249; /* range 250 to 254 only */ |
---|
321 | parmptr->usParm_sub = (unsigned short)GribCode; |
---|
322 | } |
---|
323 | strcpy (parmptr->grib_dsc, grib_dsc); |
---|
324 | strcpy (parmptr->grib_unit_dsc, grib_unit_dsc); |
---|
325 | |
---|
326 | DPRINT7( |
---|
327 | "(+D) T2-%d cd=%d: Parm=%d, ParmSub=%d, INDX=%d, Dscr='%s' Unit='%s'\n" |
---|
328 | ,sub, GribCode, |
---|
329 | parmptr->usParm_id, parmptr->usParm_sub, indx+GribCode, |
---|
330 | parmptr->grib_dsc, parmptr->grib_unit_dsc); |
---|
331 | |
---|
332 | ++cnt; /* keep track of #entries loaded */ |
---|
333 | /* |
---|
334 | * A.2.3 ENDFOR |
---|
335 | */ |
---|
336 | } |
---|
337 | DPRINT2 ("Parameter table#%d has %d entries\n", sub, cnt); |
---|
338 | |
---|
339 | /* |
---|
340 | * A.2 ENDFOR !load all 6 Parameter tables |
---|
341 | */ |
---|
342 | } /* load all 6 parm tables */ |
---|
343 | |
---|
344 | |
---|
345 | /******** GRIB's LEVEL TABLE ******* |
---|
346 | Sample: |
---|
347 | ###################################################################### |
---|
348 | GRIB Table 3: Level Definitions |
---|
349 | Line 1: Level ID | Number of Octets | Meaning |
---|
350 | Line 2: Contents of octet 11 (optional) |
---|
351 | Line 3: Contents of octet 12 (optional) |
---|
352 | 001 0 Ground or water surface |
---|
353 | 002 0 Cloud base level |
---|
354 | ... |
---|
355 | 100 2 Isobaric surface |
---|
356 | Pressure in hPa |
---|
357 | ... |
---|
358 | 101 1 Layer between two isobaric surfaces |
---|
359 | Pressure of top in kPa |
---|
360 | Pressure of bottom in kPa |
---|
361 | ###################################################################### |
---|
362 | |
---|
363 | * |
---|
364 | * *** Level Conversion info *** |
---|
365 | * A.3 LOOP until last line of comments ("Line3:" or "===="); |
---|
366 | * RETURN error if fails |
---|
367 | */ |
---|
368 | |
---|
369 | DPRINT1 ("*** %s: Start reading Level Defns ***\n", func); |
---|
370 | /* Read until the last line of Comments */ |
---|
371 | for (line[0]='\0'; ! strstr(line,"====") && ! strstr(line,"Line 3:") ; ) |
---|
372 | { |
---|
373 | fgets(line, sizeof(line), infile); |
---|
374 | ++LineRead; |
---|
375 | if (feof(infile) || ferror(infile)) |
---|
376 | { sprintf(errmsg, |
---|
377 | "%s: got EOF/ERROR before loading LEVEL info (Line %d in %s)\n", |
---|
378 | func, LineRead, lookup_fn); |
---|
379 | goto BYE; |
---|
380 | } |
---|
381 | } |
---|
382 | |
---|
383 | /* |
---|
384 | * A.4 LOOP (successfully read a line from file) DO |
---|
385 | * SKIP if comment line |
---|
386 | * BREAK out of loop if see next section "GRIB Table" |
---|
387 | */ |
---|
388 | for (cnt=0; fgets(line, sizeof(line), infile) != NULL; ) |
---|
389 | { |
---|
390 | ++LineRead; |
---|
391 | /* skip additional comments, Break if already got to next Table Defn, |
---|
392 | else replace tabs with spaces, newlines with null |
---|
393 | */ |
---|
394 | for (ptr=line; *ptr==' '; ptr++); if (*ptr == '#') continue; |
---|
395 | if (strstr(line, "GRIB Table ") != NULL) break; /* end of CURR SECT */ |
---|
396 | while (ptr=strchr(line,'\t')) *ptr=' '; |
---|
397 | if (ptr=strchr(line,'\n')) *ptr='\0'; |
---|
398 | |
---|
399 | /* |
---|
400 | * EXTRACT next GRIB's Level info into Level Array: |
---|
401 | * DROP line if extraction fails; |
---|
402 | * ! line 1 format: lvl id, #octets and Level_description |
---|
403 | * DROP line if level_id is invalid or out of range |
---|
404 | * DROP line if unable to extract level description |
---|
405 | */ |
---|
406 | /* --- Read Line 1 of Level: frmt= (Lvlid #octs Multiwords Dscr) --*/ |
---|
407 | if ((num= sscanf (line, "%s%s%s", strGribCode, strOctets, temp))!= 3) { |
---|
408 | if (num>0) fprintf(stdout, |
---|
409 | "Warning: dropping incomplete Level defn (%s:Line %d)\n", |
---|
410 | lookup_fn,LineRead); |
---|
411 | continue; |
---|
412 | } |
---|
413 | |
---|
414 | /* Make sure Parmid field has a Number, and is within Range */ |
---|
415 | if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) { |
---|
416 | fprintf(stdout,"Warning: Invalid Levelid '%s', drop Line=%d in %s\n", |
---|
417 | strGribCode, LineRead, lookup_fn); |
---|
418 | continue; } |
---|
419 | else GribCode = atoi(strGribCode); |
---|
420 | |
---|
421 | if (GribCode < 0 || GribCode >= NLEV) { |
---|
422 | fprintf(stdout, |
---|
423 | "Warning: Level Gribcode '%d' out of range, drop (Line %d in %s)", |
---|
424 | GribCode, LineRead, lookup_fn); |
---|
425 | continue; |
---|
426 | } |
---|
427 | |
---|
428 | /* Make sure #Octets field has a Number, and is within Range */ |
---|
429 | if (strspn (strOctets, "0123456789") != strlen(strOctets)) { |
---|
430 | fprintf(stdout, |
---|
431 | "Warning: Invalid NumOctets '%s' for Lvl %d, drop line#%d in %s\n", |
---|
432 | strOctets, GribCode, LineRead, lookup_fn); |
---|
433 | continue; |
---|
434 | } |
---|
435 | else iOctets = atoi(strOctets); |
---|
436 | if (iOctets < 0 || iOctets > 2) { |
---|
437 | fprintf(stdout, |
---|
438 | "Warning: Octets '%d' out of range (0-2 only), drop Line %d in %s\n", |
---|
439 | iOctets, LineRead, lookup_fn); |
---|
440 | continue; |
---|
441 | } |
---|
442 | |
---|
443 | /* TEMP here has 1st word of Lvl Descr, need to get rest of it */ |
---|
444 | if ((ptr= strstr (line, temp)) == NULL) |
---|
445 | { fprintf(stdout, |
---|
446 | "Warning: Cannot find Lvl_Dsc, drop line#%d in %s\n", |
---|
447 | LineRead, lookup_fn); |
---|
448 | continue; |
---|
449 | } |
---|
450 | |
---|
451 | strncpy (grib_dsc, ptr, sizeof(grib_dsc)-1); |
---|
452 | if (ptr=strstr(grib_dsc," ")) *ptr='\0'; /* rm trail blanks */ |
---|
453 | /* |
---|
454 | * IF (0 #octets) |
---|
455 | * SET lvl_name_1 and _2 to null; |
---|
456 | * ELSE if (1 #octets) |
---|
457 | * READ in 2 more lines !for lvl_name_1 & lvl_name_2 |
---|
458 | * ELSE !2 octets |
---|
459 | * READ in 1 more line !for lvl_name_1 |
---|
460 | * SET lvl_name_2 to null; |
---|
461 | * ENDIF |
---|
462 | */ |
---|
463 | /* --- Get Optional Lvl_1 and Lvl_2 lines, depneding on #octs */ |
---|
464 | switch (iOctets) { |
---|
465 | case 0: lvl_name_1[0]= '\0'; lvl_name_2[0]= '\0';break; |
---|
466 | case 1: if (!fgets(lvl_name_1, sizeof(lvl_name_1), infile) || |
---|
467 | !fgets(lvl_name_2, sizeof(lvl_name_2), infile)) { |
---|
468 | fprintf(stdout, |
---|
469 | "Warning: failed to get LvlName1/LvlName2; " |
---|
470 | "drop Level %d defn (Line#%d in %s)\n", |
---|
471 | GribCode, LineRead, lookup_fn); |
---|
472 | continue; |
---|
473 | } |
---|
474 | LineRead += 2; break; |
---|
475 | case 2: if (!fgets(lvl_name_1, sizeof(lvl_name_1), infile) ) |
---|
476 | { |
---|
477 | fprintf(stdout, |
---|
478 | "Warning: failed to get LvlName1; " |
---|
479 | "drop Level %d defn (Line#%d in %s)\n", |
---|
480 | GribCode, LineRead, lookup_fn); |
---|
481 | continue; |
---|
482 | } |
---|
483 | lvl_name_2[0]='\0'; ++LineRead; break; |
---|
484 | } |
---|
485 | |
---|
486 | /* replace tabs w/space, replace Newline with Null terminator, |
---|
487 | and rm trail blanks ; |
---|
488 | */ |
---|
489 | if (lvl_name_1[0]) { |
---|
490 | while (ptr=strchr(lvl_name_1,'\t')) *ptr=' '; |
---|
491 | if (ptr=strchr(lvl_name_1,'\n')) *ptr='\0'; |
---|
492 | if (ptr=strstr(lvl_name_1," ")) *ptr='\0'; |
---|
493 | } |
---|
494 | if (lvl_name_2[0]) { |
---|
495 | while (ptr=strchr(lvl_name_2,'\t')) *ptr=' '; |
---|
496 | if (ptr=strchr(lvl_name_2,'\n')) *ptr='\0'; |
---|
497 | if (ptr=strstr(lvl_name_2," ")) *ptr='\0'; |
---|
498 | } |
---|
499 | |
---|
500 | /* |
---|
501 | * DROP defn if this ID has already been defined; |
---|
502 | */ |
---|
503 | if (db_lvl_tbl[GribCode].grib_dsc[0] != '\0') { |
---|
504 | fprintf(stdout, |
---|
505 | "Warning: drop duplic Level %d defn, currently at line %d in %s\n", |
---|
506 | GribCode, LineRead, lookup_fn); |
---|
507 | continue; |
---|
508 | } |
---|
509 | |
---|
510 | /* |
---|
511 | * STORE all this info into Level Array cell whose index |
---|
512 | * equals the Level_id |
---|
513 | */ |
---|
514 | db_lvl_tbl[GribCode].usLevel_id = (unsigned short)GribCode; |
---|
515 | strncpy (db_lvl_tbl[GribCode].grib_dsc, grib_dsc, |
---|
516 | sizeof(db_lvl_tbl[GribCode].grib_dsc)-1); |
---|
517 | db_lvl_tbl[GribCode].num_octets = iOctets; |
---|
518 | strncpy (db_lvl_tbl[GribCode].lvl_name_1, lvl_name_1, |
---|
519 | sizeof(db_lvl_tbl[GribCode].lvl_name_1)-1); |
---|
520 | strncpy (db_lvl_tbl[GribCode].lvl_name_2, lvl_name_2, |
---|
521 | sizeof(db_lvl_tbl[GribCode].lvl_name_2)-1); |
---|
522 | |
---|
523 | /* |
---|
524 | * DEBUG print |
---|
525 | */ |
---|
526 | switch (iOctets) { |
---|
527 | case 0: |
---|
528 | DPRINT3("(+D) Lvl=%d Dsc='%s' %d octs\n", |
---|
529 | db_lvl_tbl[GribCode].usLevel_id, |
---|
530 | db_lvl_tbl[GribCode].grib_dsc, |
---|
531 | db_lvl_tbl[GribCode].num_octets);break; |
---|
532 | case 1: |
---|
533 | DPRINT5( |
---|
534 | "(+D) Lvl=%d Dsc='%s' %d octs\n Name1='%s'\n Name2='%s'\n", |
---|
535 | db_lvl_tbl[GribCode].usLevel_id, |
---|
536 | db_lvl_tbl[GribCode].grib_dsc, |
---|
537 | db_lvl_tbl[GribCode].num_octets, |
---|
538 | db_lvl_tbl[GribCode].lvl_name_1, |
---|
539 | db_lvl_tbl[GribCode].lvl_name_2);break; |
---|
540 | case 2: |
---|
541 | DPRINT4 ("(+D) Lvl=%d Dsc='%s' %d octs\n Name1='%s'\n", |
---|
542 | db_lvl_tbl[GribCode].usLevel_id, |
---|
543 | db_lvl_tbl[GribCode].grib_dsc, |
---|
544 | db_lvl_tbl[GribCode].num_octets, |
---|
545 | db_lvl_tbl[GribCode].lvl_name_1);break; |
---|
546 | } |
---|
547 | |
---|
548 | ++cnt; /* number loaded */ |
---|
549 | /* |
---|
550 | * A.4 ENDFOR !Level defns |
---|
551 | */ |
---|
552 | } |
---|
553 | DPRINT1 ("Level table has %d entries\n", cnt); |
---|
554 | |
---|
555 | |
---|
556 | /*** GRIB MODEL TABLE*** |
---|
557 | Sample: |
---|
558 | ###################################################################### |
---|
559 | GRIB Table - Generating Process Definitions (Octet 6 of PDS) |
---|
560 | Code Figure Model Name |
---|
561 | =========== ========== |
---|
562 | 001 NORAPS |
---|
563 | 002 COAMPS |
---|
564 | 003 NOGAPS |
---|
565 | * |
---|
566 | * *** Model Conversion info *** |
---|
567 | * A.5 WHILE (line is comment or header line) skip line; |
---|
568 | * RETURN error if fails |
---|
569 | */ |
---|
570 | DPRINT1 ("*** %s: Start reading Model Defns ***\n", func); |
---|
571 | /* Read until the last line of Comments */ |
---|
572 | for (line[0]='\0'; ! strstr(line,"====") ; ) |
---|
573 | { |
---|
574 | fgets(line, sizeof(line), infile); ++LineRead; |
---|
575 | if (feof(infile) || ferror(infile)) |
---|
576 | { sprintf(errmsg, |
---|
577 | "%s: got EOF/ERROR before loading MODEL info %s Line %d\n", |
---|
578 | func, lookup_fn, LineRead); |
---|
579 | goto BYE; |
---|
580 | } |
---|
581 | } |
---|
582 | |
---|
583 | /* |
---|
584 | * |
---|
585 | * A.6 FOR (successfully read a line from file) DO |
---|
586 | * DROP line if comment |
---|
587 | * BREAK out if see next section "GRIB Table" |
---|
588 | */ |
---|
589 | for (cnt=0; fgets(line, sizeof(line), infile)!=NULL; ) |
---|
590 | { |
---|
591 | ++LineRead; |
---|
592 | /* skip additional comments, Break if already got to next Table Defn, |
---|
593 | else replace tabs with spaces, newlines with null |
---|
594 | */ |
---|
595 | for (ptr=line; *ptr==' '; ptr++) ; if (*ptr == '#') continue; |
---|
596 | if (strstr(line, "GRIB Table ") != NULL) break; /* end of CURR SECT */ |
---|
597 | while (ptr=strchr(line,'\t')) *ptr=' '; |
---|
598 | if (ptr=strchr(line,'\n')) *ptr='\0'; |
---|
599 | /* |
---|
600 | * EXTRACT from line the GRIB's Model info ; |
---|
601 | * DROP line if extraction fails; |
---|
602 | * ! frmat: model_name model_id; |
---|
603 | * DROP line if modelid is invalid or out of range |
---|
604 | */ |
---|
605 | if ((num= sscanf (line, "%s%s", strGribCode, temp)) !=2) { |
---|
606 | if (num > 0) fprintf(stdout, |
---|
607 | "Warning: Drop incomplete Model line %d in %s\n", LineRead, lookup_fn); |
---|
608 | continue; |
---|
609 | } |
---|
610 | if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) { |
---|
611 | fprintf(stdout,"Warning: Invalid Level '%s', drop line=%d in %s\n", |
---|
612 | strGribCode, LineRead, lookup_fn); |
---|
613 | continue; |
---|
614 | } |
---|
615 | else GribCode = atoi(strGribCode); |
---|
616 | |
---|
617 | if (GribCode < 0 || GribCode >= NMODEL) { |
---|
618 | fprintf(stdout, |
---|
619 | "Warning: Model '%d' out of range, drop %s Line %d\n", |
---|
620 | GribCode, lookup_fn, LineRead); |
---|
621 | continue; |
---|
622 | } |
---|
623 | |
---|
624 | /* |
---|
625 | * DROP line if this model is already defined |
---|
626 | */ |
---|
627 | if (db_mdl_tbl[GribCode].grib_dsc[0] != '\0') { |
---|
628 | fprintf(stdout, |
---|
629 | "Warning: duplic Model#%d defn , drop (%s Line %d)\n", |
---|
630 | GribCode, lookup_fn, LineRead); |
---|
631 | continue; |
---|
632 | } |
---|
633 | /* |
---|
634 | * STORE model info into model array cell whose index |
---|
635 | * equals the model_id; |
---|
636 | */ |
---|
637 | db_mdl_tbl[GribCode].usModel_id = (unsigned short)GribCode; |
---|
638 | strncpy (db_mdl_tbl[GribCode].grib_dsc, |
---|
639 | line+(strstr(line,temp)-line), |
---|
640 | sizeof(db_mdl_tbl[GribCode].grib_dsc)-1); /* 1/more words */ |
---|
641 | DPRINT2 ("(+D) Mdl=%d, Gribdscr=%s\n", |
---|
642 | db_mdl_tbl[GribCode].usModel_id, db_mdl_tbl[GribCode].grib_dsc); |
---|
643 | ++cnt; /* number loaded */ |
---|
644 | /* |
---|
645 | * A.6 ENDFOR |
---|
646 | */ |
---|
647 | } |
---|
648 | DPRINT1 ("Model table has %d entries\n", cnt); |
---|
649 | |
---|
650 | |
---|
651 | /*** GRIB GEOMETRY TABLE*** |
---|
652 | Sample: |
---|
653 | ###################################################################### |
---|
654 | GRIB Table - Pre-defined geometries (Octet 7 of PDS) |
---|
655 | Code Figure Geometry Name |
---|
656 | =========== ============= |
---|
657 | 001 mediterranean_109x82 |
---|
658 | 002 persian_gulf_NORAPS_63x63 |
---|
659 | 003 global_144x288 |
---|
660 | 255 Undefined grid, description in GDS |
---|
661 | * |
---|
662 | * *** Geometry Conversion info *** |
---|
663 | * A.7 WHILE (line is comment or header line) skip line; |
---|
664 | * RETURN error if fails |
---|
665 | */ |
---|
666 | |
---|
667 | DPRINT1 ("*** %s: Start reading Geom Defns ***\n", func); |
---|
668 | /* Read until the last line of Comments */ |
---|
669 | for (line[0]='\0'; ! strstr(line,"====") ; ) { |
---|
670 | fgets(line, sizeof(line), infile); |
---|
671 | ++LineRead; |
---|
672 | if (feof(infile) || ferror(infile)) |
---|
673 | { sprintf(errmsg, |
---|
674 | "%s: got EOF/ERROR before loading GEOM info, %s Line %d\n", |
---|
675 | func, lookup_fn, LineRead); |
---|
676 | goto BYE; |
---|
677 | } |
---|
678 | } |
---|
679 | |
---|
680 | /* |
---|
681 | * A.8 FOR (successfully read a line from file) DO |
---|
682 | * DROP line if comment |
---|
683 | * BREAK out if see next section "GRIB Table" |
---|
684 | */ |
---|
685 | for (cnt=0; fgets(line, sizeof(line), infile)!=NULL; ) |
---|
686 | { |
---|
687 | ++LineRead; |
---|
688 | /* skip additional comments, Break if already got to next Table Defn, |
---|
689 | else replace tabs with spaces, newlines with null |
---|
690 | */ |
---|
691 | for (ptr=line; *ptr==' '; ptr++) ; if (*ptr == '#') continue; |
---|
692 | if (strstr(line, "GRIB Table ") != NULL) break; /* end of CURR SECT */ |
---|
693 | while (ptr=strchr(line,'\t')) *ptr=' '; |
---|
694 | if (ptr=strchr(line,'\n')) *ptr='\0'; |
---|
695 | |
---|
696 | /* |
---|
697 | * EXTRACT next GRIB's Geometry info into Geometry Array; |
---|
698 | * DROP line if extraction fails; |
---|
699 | * !format: geom_id geom_descr |
---|
700 | * DROP line if geom_id is invalid or out of range |
---|
701 | */ |
---|
702 | if ((num= sscanf (line, "%s%s", strGribCode, temp)) !=2) { |
---|
703 | if (num > 0) fprintf(stdout, |
---|
704 | "Warning: drop incomplete Geom line %d in %s\n", LineRead, lookup_fn); |
---|
705 | continue; |
---|
706 | } |
---|
707 | |
---|
708 | if (strspn (strGribCode, "0123456789") != strlen(strGribCode)) { |
---|
709 | fprintf(stdout,"Warning: Invalid Geom_id '%s', drop %s line=%d\n", |
---|
710 | strGribCode, lookup_fn, LineRead); |
---|
711 | continue; } |
---|
712 | else GribCode = atoi(strGribCode); |
---|
713 | |
---|
714 | if (GribCode < 0 || GribCode >= NGEOM) { |
---|
715 | fprintf(stdout, "Warning: Geomid '%d' out of range, drop %s Line %d\n", |
---|
716 | GribCode, lookup_fn, LineRead); |
---|
717 | continue; |
---|
718 | } |
---|
719 | |
---|
720 | /* |
---|
721 | * DROP line if geom_id is already defined |
---|
722 | */ |
---|
723 | if (db_geom_tbl[GribCode].grib_dsc[0] != '\0') { |
---|
724 | fprintf(stdout, "Warning: duplic GeomID=%d, drop %s line %d\n", |
---|
725 | GribCode, lookup_fn, LineRead); |
---|
726 | continue; |
---|
727 | } |
---|
728 | /* |
---|
729 | * STORE this geom info into array cell whose index |
---|
730 | * equals the geom_id; |
---|
731 | */ |
---|
732 | db_geom_tbl[GribCode].usGeom_id = (unsigned short)GribCode; |
---|
733 | strncpy (db_geom_tbl[GribCode].grib_dsc, |
---|
734 | line+(strstr(line,temp)-line), |
---|
735 | sizeof(db_geom_tbl[GribCode].grib_dsc)-1); /* 1/more words */ |
---|
736 | |
---|
737 | ++cnt; /* number loaded */ |
---|
738 | DPRINT2("(+D) Geom=%d, Gribdscr=%s\n", |
---|
739 | db_geom_tbl[GribCode].usGeom_id, db_geom_tbl[GribCode].grib_dsc); |
---|
740 | /* |
---|
741 | * A.8 ENDFOR |
---|
742 | */ |
---|
743 | } |
---|
744 | DPRINT1 ("Geometry table has %d entries\n", cnt); |
---|
745 | |
---|
746 | /* |
---|
747 | * |
---|
748 | * A.9 SET status to 0 !success |
---|
749 | */ |
---|
750 | stat=0; |
---|
751 | |
---|
752 | /* |
---|
753 | * |
---|
754 | * A.10 CLOSE Lookup file; |
---|
755 | */ |
---|
756 | BYE: |
---|
757 | if (infile) fclose(infile); |
---|
758 | DPRINT2 ("Leaving %s, stat=%d\n", func,stat); |
---|
759 | /* |
---|
760 | * |
---|
761 | * A.11 RETURN with status |
---|
762 | */ |
---|
763 | return (stat); |
---|
764 | /* |
---|
765 | * END OF FUNCTION |
---|
766 | * |
---|
767 | */ |
---|
768 | } |
---|