source: lmdz_wrf/WRFV3/external/io_grib1/MEL_grib1/gribputpds.c @ 1

Last change on this file since 1 was 1, checked in by lfita, 10 years ago
  • -- --- Opening of the WRF+LMDZ coupling repository --- -- -

WRF: version v3.3
LMDZ: version v1818

More details in:

File size: 18.2 KB
Line 
1/* FILENAME:   gribputpds.c */
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <stdlib.h>
6#ifdef XT3_Catamount
7#include <features.h>
8#elif defined(_WIN32)
9#include <Winsock2.h>
10#else
11#include <netinet/in.h>
12#endif
13#include "dprints.h"            /* for dprints */
14#include "gribfuncs.h"          /* prototypes */
15
16/*
17*
18****************************************************************************
19* A.  FUNCTION:  gribputpds
20*       Use the information provided to create a Product Defn Section of
21*       the GRIB format and store it in the GRIB_HDR structure;
22*
23*    INTERFACE:
24*       int gribputpds (Data_Input, User_Input, pPDS_Input, ppgrib_hdr, errmsg)
25*
26*    ARGUMENTS (I=input, O=output, I&O=input and output):
27*      (I)  DATA_INPUT Data_Input;
28*           Structure containing info of this field (ids used in the Sections)
29*      (I)  USER_INPUT User_Input;
30*           Structure containing encoder configuration data
31*      (O)  PDS_INPUT  *pPDS_Input;
32*           points to an empty Structure;   to be filled with PDS info
33*           retrieved from  Data_Input and User_Input.
34*     (I&O) GRIB_HDR **ppgrib_hdr;
35*           points to Grib Header Structure;  May already have 1 or more
36*           GRIB sections in it;  Will have PDS appended to its 'entire_msg',
37*           'pds_ptr', 'pds_len' and 'mesg_len' updated also.
38*      (O)  char *errmsg;
39*           empty array, returned filled if error occurred
40*
41*    RETURN CODE:
42*       0>  no errors;
43*           Grib Header structure now has PDS newly appended to its
44*           entire_msg buffer, its sections length, message length,
45*           and section pointers are updated.
46*       1>  error, errmsg filled;
47*           failed to make storage for PDS_GRIB, or
48*           failed to enlarge 'entire_msg' to hold new PDS block;
49*      99>  error in create_inpPDS() or inp2grib_PDS(); errmsg filled;
50****************************************************************************/
51
52#if PROTOTYPE_NEEDED
53int gribputpds ( DATA_INPUT     Data_Input,
54                USER_INPUT      User_Input,
55                PDS_INPUT       *pPDS_Input,
56                GRIB_HDR        **ppgrib_hdr,
57                char            *errmsg)
58#else
59int gribputpds ( Data_Input, User_Input, pPDS_Input, ppgrib_hdr, errmsg)
60                DATA_INPUT      Data_Input;
61                USER_INPUT      User_Input;
62                PDS_INPUT       *pPDS_Input;
63                GRIB_HDR        **ppgrib_hdr;
64                char            *errmsg;
65#endif
66{
67   PDS_GRIB  *pPDS_Grib=0; /* true GRIB format for pds */
68   GRIB_HDR  *gh;          /* working var */
69   int       stat= 0;      /* status */
70   long      newsize=0L;   /* size of msg after adding PDS block */
71   /*void      create_inpPDS ();
72   int       inp2grib_PDS ();*/
73   char      *func= "GribPutPDS";
74
75  DPRINT1("\nEntering %s()......\n", func);
76/*
77*
78* A.1       FUNCTION create_inpPDS              !void
79*           !create internal struct PDS_INPUT from DATA_INPUT & USER_INPUT
80*/
81   create_inpPDS (Data_Input, User_Input, pPDS_Input);
82
83/*
84*
85* A.2       MALLOC local struct PDS_GRIB, clear it out;
86*           IF (fails) THEN
87*               SET bad stat
88*               RETURN
89*           ELSE
90*               CLEAR out the struct
91*           ENDIF
92*/
93  if ( !(pPDS_Grib= (PDS_GRIB *)malloc(sizeof(PDS_GRIB))) )
94    {   
95     sprintf(errmsg,"%s:  failed storage for PDS_GRIB\n",func);
96     stat=1; goto BYE; 
97    }
98   else memset ((void *)pPDS_Grib, '\0', sizeof(PDS_GRIB));
99
100/*
101*
102* A.3       FUNCTION inp2grib_PDS   
103*           !convert internal PDS_INPUT to true Grib format PDS_GRIB
104*           IF (error) THEN
105*               SAVE error from func in stat
106*               RETURN
107*           ENDIF
108*/
109   if (stat = inp2grib_PDS (pPDS_Input, &pPDS_Grib, errmsg))
110         { upd_child_errmsg (func, errmsg);
111           goto BYE; 
112         }
113/*
114*
115* A.4       CALCULATE new msg length after adding new PDS
116*/
117  DPRINT0("putting Pds into Grib Hdr struct\n");
118
119  gh= *ppgrib_hdr;
120  newsize= gh->msg_length + sizeof(PDS_GRIB);
121
122/*
123*
124* A.5       IF gribhdr's buffer is too small AND
125*               FUCTION Expand_gribhdr failed
126*           THEN
127*               SET stat = 1
128*               RETURN with error   !errmsg filled
129*           ENDIF
130*/
131     if (newsize > gh->abs_size
132        && Expand_gribhdr (gh, newsize, errmsg) !=0)
133        {
134        stat = 1;
135        upd_child_errmsg (func, errmsg);
136        goto BYE;
137        }
138
139/*
140*
141* A.6       COPY Pds and its info into Grib Header
142*           !copy PDS_GRIB struct to the end of Entire_msg array;
143*           !store pds pointer and length
144*           !update msg length
145*/
146   gh->pds_ptr= gh->entire_msg + gh->msg_length;
147   memcpy ((void *) gh->pds_ptr, (void *) pPDS_Grib, sizeof (PDS_GRIB));
148   gh->pds_len    = sizeof(PDS_GRIB);
149   gh->msg_length += gh->pds_len;
150
151   DPRINT1 ("copied PDS_GRIB(%ld) bytes from pPDS_Grib to PDS_PTR\n",
152        sizeof(PDS_GRIB));
153
154/*
155*
156* A.7       FREE up local struct PDS_GRIB
157*
158* A.8       RETURN to caller with stat
159*/
160BYE:
161   if (pPDS_Grib!=NULL) free (pPDS_Grib);
162   DPRINT2 ("Leaving %s(), stat=%d\n", func,stat);
163   return stat;
164/*
165*
166* END OF FUNCTION
167*
168*
169*/
170}
171
172/*
173*
174*********************************************************************
175* B. FUNCTION:  create_inpPDS
176*        Fill the internal Product Defn Section structure with info
177*        retrieved from the 2 input structures DATA_INPUT and USER_INPUT.
178*
179*    INTERFACE:
180*        void  create_inpPDS (Data_Input, User_Input, pPDS_Input)
181*
182*    ARGUMENTS (I=input, O=output, I&O=input and output):
183*      (I)  DATA_INPUT Data_Input;   holds ids to be used in Sections
184*      (I)  USER_INPUT User_Input;   holds encoder configuration info
185*      (O)  PDS_INPUT *pPDS_Input;   pre-allocated structure to be filled;
186*
187*    RETURN CODE:   none;
188**********************************************************************
189*/
190#if PROTOTYPE_NEEDED
191void  create_inpPDS ( DATA_INPUT Data_Input, USER_INPUT User_Input,
192                        PDS_INPUT *pPDS_Input)
193#else
194void  create_inpPDS ( Data_Input, User_Input, pPDS_Input)
195                        DATA_INPUT Data_Input; 
196                        USER_INPUT User_Input;
197                        PDS_INPUT *pPDS_Input;
198#endif
199{
200int i;
201
202   DPRINT0 ( "Entering create_inpPDS ()\n" );
203/*
204*
205* B.1       LOAD info from struct USER_INPUT into struct PDS_INPUT
206*/
207
208/* assigns the values from USER_INPUT to PDS_Input */
209   pPDS_Input->usEd_num = (unsigned short) 1; /* GRIB Edition num */
210   pPDS_Input->usParm_tbl = User_Input.usParm_tbl; /* GRIB TblVersion num */
211   pPDS_Input->usSub_tbl = User_Input.usSub_tbl; /* Local TblVersion num */
212   pPDS_Input->usCenter_id = User_Input.usCenter_id; /* Originating Ctr-Tbl0*/
213   pPDS_Input->usProc_id = Data_Input.usProc_id; /* Model id */
214   pPDS_Input->usGrid_id = Data_Input.usGrid_id; /* Grid id num */
215   pPDS_Input->usGds_bms_id = User_Input.usGds_bms_id; /* GDS/BMS flag-Tbl1 */
216   pPDS_Input->usParm_id = Data_Input.usParm_id; /* Parameter& Units id -Tbl2 */
217   pPDS_Input->usParm_sub = Data_Input.usParm_sub_id;/* Sub-Tblentry for Tbl2 */
218   pPDS_Input->usLevel_id = Data_Input.usLevel_id; /* Type of level/layer-Tbl3*/ /* Height, pressure of level 1  and 2 */ 
219   pPDS_Input->usHeight1 =(unsigned short)Data_Input.nLvl_1 ; 
220   pPDS_Input->usHeight2 =(unsigned short)Data_Input.nLvl_2 ; 
221   pPDS_Input->usYear =(unsigned short)( Data_Input.nYear % 100 ); /* Year */
222   pPDS_Input->usMonth =(unsigned short)Data_Input.nMonth; /* Month */
223   pPDS_Input->usDay =(unsigned short)Data_Input.nDay;/* Day of month */
224   pPDS_Input->usHour =(unsigned short)Data_Input.nHour; /* Hour of day */
225   pPDS_Input->usMinute =(unsigned short)Data_Input.nMinute; /* Minute of hour*/
226   pPDS_Input->usSecond =(unsigned short)Data_Input.nSecond; /* Secs of Min */
227   pPDS_Input->usFcst_unit_id = Data_Input.usFcst_id; /*ForecastTime unit-Tbl4*/
228   /* Period of time (tau)- 0 for analysis */
229   pPDS_Input->usP1 = Data_Input.usFcst_per1;
230   /* Period of time between analyses */
231   pPDS_Input->usP2 = Data_Input.usFcst_per2;
232   /* Time range indicator-Tbl5 */
233   pPDS_Input->usTime_range = Data_Input.usTime_range_id;
234   /* Num in average */
235   pPDS_Input->usTime_range_avg = Data_Input.usTime_range_avg;
236   /* Num missing from average */
237   pPDS_Input->usTime_range_mis = Data_Input.usTime_range_mis; 
238
239   /* Century of reference time */
240   if (Data_Input.nYear % 100 == 0) {
241     pPDS_Input->usCentury = (unsigned short)( Data_Input.nYear / 100 );
242     pPDS_Input->usYear += 100;
243   } else {
244     pPDS_Input->usCentury =(unsigned short)( Data_Input.nYear / 100 + 1);
245   }
246
247   /* Decimal scale factor */
248   pPDS_Input->sDec_sc_fctr = (short) Data_Input.nDec_sc_fctr;
249   /* reserved bytes */
250   for ( i=0 ; i< 12 ; i++)pPDS_Input->ausZero[i] = 0; /* Reserved- Set to 0 */
251   /* Oct-26 was reserved, now holds Sub-Center Id */
252   pPDS_Input->usCenter_sub =  User_Input.usCenter_sub;
253   /* Oct-41:  show that Grib Extensions are used */
254   pPDS_Input->usExt_flag = (unsigned short)EXTENSION_FLAG; 
255   /* Tracking ID for data set */
256   pPDS_Input->usTrack_num = User_Input.usTrack_num; 
257
258   /* WSI Extended PDS section: Used for extended and higher resolution time periods */
259   pPDS_Input->PDS_41 = Data_Input.PDS_41;
260   pPDS_Input->PDS_42 = Data_Input.PDS_42;
261   pPDS_Input->PDS_46 = Data_Input.PDS_46;
262   pPDS_Input->PDS_47 = Data_Input.PDS_47;
263   pPDS_Input->PDS_51 = Data_Input.PDS_51;
264   pPDS_Input->PDS_52 = Data_Input.PDS_52;
265
266/*
267*
268* B.2       ASSIGN size of PDS_GRIB into uslength of struct PDS_INPUT
269            ** If encoding MEL GRIB messages, Pds Length should be 46 and
270            Octet 41 should equal the Extension Flag.
271*/
272   pPDS_Input->uslength = sizeof(PDS_GRIB);
273
274/*
275*
276* B.3       DEBUG Print
277*/
278   DPRINT1("\t create_inpPDS:  uslength = %u (Size of PDS_GRIB)\n",
279   pPDS_Input->uslength );
280   DPRINT1("\t create_inpPDS:  usEd_num = %u\n", pPDS_Input->usEd_num );
281   DPRINT1("\t create_inpPDS:  usParm_tbl = %u\n", pPDS_Input->usParm_tbl );
282   DPRINT1("\t create_inpPDS:  usSub_tbl = %u\n", pPDS_Input->usSub_tbl);
283   DPRINT1("\t create_inpPDS:  usCenter_id = %u\n", pPDS_Input->usCenter_id );
284   DPRINT2("\t create_inpPDS:  usCenter_sub Oct26=%u, usExt_flag Oct41=%u\n", 
285        pPDS_Input->usCenter_sub, pPDS_Input->usExt_flag);
286   DPRINT1("\t create_inpPDS:  usProc_id = %u\n", pPDS_Input->usProc_id );
287   DPRINT1("\t create_inpPDS:  usGrid_id = %u\n", pPDS_Input->usGrid_id );
288   DPRINT1("\t create_inpPDS:  usGds_bms_id = %u\n", pPDS_Input->usGds_bms_id);
289   DPRINT1("\t create_inpPDS:  usParm_id = %u\n", pPDS_Input->usParm_id );
290   DPRINT1("\t create_inpPDS:  usParm_sub = %u\n", pPDS_Input->usParm_sub);
291   DPRINT1("\t create_inpPDS:  usLevel_id = %u\n", pPDS_Input->usLevel_id );
292   DPRINT1("\t create_inpPDS:  usHeight1 = %u\n", pPDS_Input->usHeight1 );
293   DPRINT1("\t create_inpPDS:  usHeight2 = %u\n", pPDS_Input->usHeight2 );
294   DPRINT1("\t create_inpPDS:  usCentury = %u\n", pPDS_Input->usCentury );
295   DPRINT1("\t create_inpPDS:  usYear = %u\n", pPDS_Input->usYear );
296   DPRINT1("\t create_inpPDS:  usDay = %u\n", pPDS_Input->usDay );
297   DPRINT1("\t create_inpPDS:  usHour = %u\n", pPDS_Input->usHour );
298   DPRINT1("\t create_inpPDS:  usMinute = %u\n", pPDS_Input->usMinute );
299   DPRINT1("\t create_inpPDS:  usSecond = %u\n", pPDS_Input->usSecond );
300   DPRINT1("\t create_inpPDS:  usP1 = %u\n", pPDS_Input->usP1);
301   DPRINT1("\t create_inpPDS:  sDec_sc_fctr  = %d\n", pPDS_Input->sDec_sc_fctr);
302   DPRINT1("\t create_inpPDS:  usTrack_num = %u\n", pPDS_Input->usTrack_num);
303   DPRINT0("\t create_inpPDS:  WSI Extended PDS Section: \n");
304   DPRINT1("\t create_inpPDS:  PDS_41 (Forecast time 1 unit id): %u\n",pPDS_Input->PDS_41);
305   DPRINT1("\t create_inpPDS:  PDS_42 (Forecast time 1): %u\n",pPDS_Input->PDS_42);
306   DPRINT1("\t create_inpPDS:  PDS_46 (Forecast time 2 unit id): %u\n",pPDS_Input->PDS_46);
307   DPRINT1("\t create_inpPDS:  PDS_47 (Forecast time 2 unit id): %u\n",pPDS_Input->PDS_47);
308   DPRINT1("\t create_inpPDS:  PDS_51 (Time range indicator): %u\n",pPDS_Input->PDS_51);
309   DPRINT1("\t create_inpPDS:  PDS_52 (Top of atm): %u\n",pPDS_Input->PDS_52);
310
311   
312/*
313*
314* B.4       RETURN w/nothing
315*/
316   DPRINT0 ("Exiting create_inpPDS with no errors;\n"); 
317
318/*
319*
320* END OF FUNCTION
321*
322*
323*/
324}
325
326/*
327*
328****************************************************************************
329* C. FUNCTION:  inp2grib_PDS
330*      Use the data from the internal structure to fill the Product
331*      Definition Section structure.
332*
333*    INTERFACE:
334*      int inp2grib_PDS ( pPDS_Input, ppPDS_Grib, errmsg)
335*
336*    ARGUMENTS (I=input, O=output, I&O=input and output):
337*      (I)  PDS_INPUT *pPDS_Input;
338*           internal PDS structure, used for input
339*      (O)  PDS_GRIB  **ppPDS_GRIB ;
340*           pre-allocated structure to be filled;
341*      (O)  char *errmsg;
342*           empty array, returned filled if error occured;
343*
344*   RETURN CODE:
345*      0> no errors;  PDS_GRIB filled;
346*     99> unexpected null pointers, Errmsg filled;
347****************************************************************************/
348
349#if PROTOTYPE_NEEDED
350int inp2grib_PDS ( PDS_INPUT    *pPDS_Input,
351                PDS_GRIB        **ppPDS_Grib,
352                char            *errmsg)
353#else
354int inp2grib_PDS ( pPDS_Input, ppPDS_Grib, errmsg)
355                PDS_INPUT       *pPDS_Input;
356                PDS_GRIB        **ppPDS_Grib;
357                char            *errmsg;
358#endif
359{
360   char             *func= "inp2grib_PDS";
361   unsigned char    ach3bytes[3];
362   unsigned long    ulPDS_length = 0;
363   short            sDec_sc_fctr = 0;
364   int              nStatus = 0;
365   int              i;          /* loop counter */
366   long             lTemp;      /* working var */
367   PDS_GRIB         *tpds;      /* true grib pds, working var */
368   short            tmp_byte2;  /* working var */
369   long             tmp_byte4;  /* working var */
370
371   DPRINT0  ( "Entering inp2grib_PDS......\n" );
372
373/*
374*
375* C.1       IF (either Internal PDS_INPUT or True Grib PDS_GRIB is null) THEN
376*              SET status = 99;
377*              RETURN
378*           ENDIF
379*/
380      if ( !ppPDS_Grib  || !pPDS_Input) {
381           sprintf(errmsg,
382           "%s: either PDS_GRIB /PDS_INPUT/or both are Null\n",func);
383           nStatus= 99;
384           goto BYE;
385        }
386
387/*
388*
389* C.2       ASSIGN local ptr to point to PDS_GRIB struct;
390*/
391      tpds = *ppPDS_Grib;
392
393/*
394*
395* C.3       CREATE true Grib struct PDS_GRIB from internal PDS_INPUT
396*/
397      tpds->chParm_tbl =  ( unsigned char ) pPDS_Input->usParm_tbl;
398
399      /* Commented out by Todd Hutchinson, WSI, when Extended PDS was replaced */
400      /* tpds->chSub_tbl =  ( unsigned char ) pPDS_Input->usSub_tbl; */
401
402      tpds->chCenter_id = ( unsigned char ) pPDS_Input->usCenter_id;
403      tpds->chProc_id = ( unsigned char ) pPDS_Input->usProc_id;
404      tpds->chGrid_id = ( unsigned char ) pPDS_Input->usGrid_id;
405      tpds->chGds_bms_id = ( unsigned char ) pPDS_Input->usGds_bms_id;
406      tpds->chParm_id = ( unsigned char ) pPDS_Input->usParm_id;
407
408      /* Commented out by Todd Hutchinson, WSI, when Extended PDS was replaced */
409      /* tpds->chParm_sub= (unsigned char )  pPDS_Input->usParm_sub; */
410
411      tpds->chLevel_id = ( unsigned char ) pPDS_Input->usLevel_id;
412
413      switch(pPDS_Input->usLevel_id){
414        case   1:  /* surface(of the Earth, includes sea surface) level  */
415        case   2:  /* cloud base level  */
416        case   3:  /* cloud top level  */
417        case   4:  /* 0 deg C isotherm level */
418        case   5:  /* adiabatic condensation level  */
419        case   6:  /* maximum wind speed level  */
420        case   7:  /* tropopause level  */
421        case   8:  /* nominal top of atmosphere level  */
422        case   9:  /* sea bottom level  */
423        case 100:  /* isobaric level            */
424        case 103:  /* fixed height level        */
425        case 105:  /* fixed height above ground */
426        case 107:  /* sigma level               */
427        case 111:  /* depth below land surface  */
428        case 113:  /* isentropic (theta) level  */
429        case 115:  /* sigma-z level  */
430        case 119:  /* Eta Level */
431        case 125:  /* height level above ground (high precision) */
432        case 160:  /* depth below sea level     */
433        case 200:  /* entire atmosphere considered as a single layer */
434        case 201:  /* entire ocean considered as a single layer */
435        case 212:  /* low cloud bottom level */
436        case 213:  /* low cloud top level */
437        case 222:  /* middle cloud bottom level */
438        case 223:  /* middle cloud top level */
439        case 232:  /* high cloud bottom level */
440        case 233:  /* high cloud top level */
441          set_bytes(pPDS_Input->usHeight1, 2, tpds->achHeight);
442          break;
443        default:
444          set_bytes(pPDS_Input->usHeight2, 1, (tpds->achHeight));
445          set_bytes(pPDS_Input->usHeight1, 1, (tpds->achHeight)+1);
446          break;
447      }
448
449      tpds->chYear = ( unsigned char ) pPDS_Input->usYear;
450      tpds->chMonth = ( unsigned char ) pPDS_Input->usMonth;
451      tpds->chDay = ( unsigned char ) pPDS_Input->usDay;
452      tpds->chHour = ( unsigned char ) pPDS_Input->usHour;
453      tpds->chMinute = ( unsigned char ) pPDS_Input->usMinute;
454      tpds->chFcst_unit_id = ( unsigned char ) pPDS_Input->usFcst_unit_id;
455      tpds->chP1 = ( unsigned char ) pPDS_Input->usP1;
456      tpds->chP2 = ( unsigned char ) pPDS_Input->usP2;
457      tpds->chTime_range = ( unsigned char ) pPDS_Input->usTime_range;
458
459      set_bytes(pPDS_Input->usTime_range_avg,2,tpds->achTime_range_avg);
460
461      tpds->chTime_range_mis = ( unsigned char ) pPDS_Input->usTime_range_mis;
462      tpds->chCentury = ( unsigned char ) pPDS_Input->usCentury;
463      tpds->chCenter_sub = ( unsigned char ) pPDS_Input->usCenter_sub;
464      DPRINT1("Octet-26:  tpds->usCenter_sub= %d\n", (int)tpds->chCenter_sub);
465
466      set_bytes(pPDS_Input->sDec_sc_fctr,2,tpds->achDec_sc_fctr);
467
468      for(i=0;i<12;++i)
469        tpds->achZero[i]= ( unsigned char ) pPDS_Input->ausZero[i];
470
471      /* Commented out by Todd Hutchinson, WSI, when Extended PDS was replaced */
472      /*
473      tpds->chExt_flag = (unsigned char) pPDS_Input->usExt_flag;
474      DPRINT1("Octet41:   tpds->chExt_flag= %d\n", (int)tpds->chExt_flag);
475
476      tpds->chSecond = ( unsigned char ) pPDS_Input->usSecond;
477      memcpy((void *)tpds->chTrack_num,
478                (void *)&(pPDS_Input->usTrack_num), 2);
479      */
480     
481      /* Added by Todd Hutchinson, WSI.  Extended WSI PDS section */
482
483      tpds->PDS_41 = (unsigned char)pPDS_Input->PDS_41;
484
485      set_bytes(pPDS_Input->PDS_42,4,tpds->PDS_42);
486
487      tpds->PDS_46 = (unsigned char)pPDS_Input->PDS_46;
488
489      set_bytes(pPDS_Input->PDS_47,4,tpds->PDS_47);
490
491      tpds->PDS_51 = (unsigned char)pPDS_Input->PDS_51;
492
493      set_bytes(pPDS_Input->PDS_52,2,tpds->PDS_52);
494
495      ulPDS_length= sizeof (PDS_GRIB);
496      DPRINT1 ( "\t length of PDS_GRIB is %d\n", ulPDS_length );
497
498      set_bytes(ulPDS_length, 3, tpds->achPDS_length);
499
500     HDR_PRINT("encoded PDS", (unsigned char*)tpds, (int)ulPDS_length); 
501/*
502*
503* C.4       RETURN with Status
504*/
505BYE:
506      DPRINT1 ( "Exiting inp2grib_PDS(), stat=%d\n", nStatus);
507      return ( nStatus );
508/*
509*
510* END OF FUNCTION
511*
512*/ 
513}
Note: See TracBrowser for help on using the repository browser.