PageRenderTime 67ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/wrfv2_fire/external/io_grib1/MEL_grib1/ld_dec_lookup.c

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