]> git.mxchange.org Git - simgear.git/blob - simgear/metar/Dcdmetar.cpp
Tidy up the autoconf/automake configuration a bit.
[simgear.git] / simgear / metar / Dcdmetar.cpp
1 #include "Local.h"     /* standard header file */
2 #include "Metar.h"     /* standard header file */
3  
4 float fracPart( char * );
5 void DcdMTRmk( char **, Decoded_METAR * );
6  
7  
8 /********************************************************************/
9 /*                                                                  */
10 /*  Title:         SaveTokenString                                  */
11 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
12 /*  Date:          14 Sep 1994                                      */
13 /*  Programmer:    CARL MCCALLA                                     */
14 /*  Language:      C/370                                            */
15 /*                                                                  */
16 /*  Abstract:      SaveTokenString tokenizes the input character    */
17 /*                 string based upon the delimeter set supplied     */
18 /*                 by the calling routine.  The elements tokenized  */
19 /*                 from the input character string are saved in an  */
20 /*                 array of pointers to characters.  The address of */
21 /*                 this array is the output from this function.     */
22 /*                                                                  */
23 /*  Input:         string - a pointer to a character string.        */
24 /*                                                                  */
25 /*                 delimeters - a pointer to a string of 1 or more  */
26 /*                              characters that are used for token- */
27 /*                              izing the input character string.   */
28 /*                                                                  */
29 /*  Output:        token  - the address of a pointer to an array of */
30 /*                          pointers to character strings.  The     */
31 /*                          array of pointers are the addresses of  */
32 /*                          the character strings that are token-   */
33 /*                          ized from the input character string.   */
34 /*                                                                  */
35 /*                                                                  */
36 /*  Modification History:                                           */
37 /*                 None.                                            */
38 /*                                                                  */
39 /********************************************************************/
40  
41 static char **SaveTokenString ( char *string , char *delimeters )
42 {
43  
44    /***************************/
45    /* DECLARE LOCAL VARIABLES */
46    /***************************/
47  
48    int NDEX;
49    static char *token[ MAXTOKENS ],
50         *TOKEN;
51  
52  
53    /*********************************/
54    /* BEGIN THE BODY OF THE ROUTINE */
55    /*********************************/
56  
57    /******************************************/
58    /* TOKENIZE THE INPUT CHARACTER STRING    */
59    /* AND SAVE THE TOKENS TO THE token ARRAY */
60    /******************************************/
61  
62    NDEX = 0;
63    TOKEN = strtok( string, delimeters);
64  
65    if( TOKEN == NULL )
66       return NULL;
67  
68    token[NDEX] = (char *) malloc(sizeof(char)*(strlen(TOKEN)+1));
69    strcpy( token[ NDEX ], TOKEN );
70  
71  
72    while ( token[NDEX] != NULL )
73    {
74       NDEX++;
75       TOKEN = strtok( NULL, delimeters );
76  
77       if( TOKEN != NULL )
78       {
79          token[NDEX] = (char *)
80                               malloc(sizeof(char)*(strlen(TOKEN)+1));
81          strcpy( token[NDEX], TOKEN );
82       }
83       else
84          token[ NDEX ] = TOKEN;
85  
86    }
87  
88  
89    return token;
90  
91 }
92 /********************************************************************/
93 /*                                                                  */
94 /*  Title:         freeTokens                                       */
95 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
96 /*  Date:          14 Sep 1994                                      */
97 /*  Programmer:    CARL MCCALLA                                     */
98 /*  Language:      C/370                                            */
99 /*                                                                  */
100 /*  Abstract:      freeTokens frees the storage allocated for the   */
101 /*                 character strings stored in the token array.     */
102 /*                                                                  */
103 /*  Input:         token  - the address of a pointer to an array    */
104 /*                          of string tokens.                       */
105 /*                                                                  */
106 /*                                                                  */
107 /*  Output:        None.                                            */
108 /*                                                                  */
109 /*                                                                  */
110 /*  Modification History:                                           */
111 /*                 None.                                            */
112 /*                                                                  */
113 /********************************************************************/
114  
115 static void freeTokens( char **token )
116 {
117    int NDEX;
118  
119    NDEX = 0;
120    while( *(token+NDEX) != NULL )
121    {
122       free( *(token+NDEX) );
123       NDEX++;
124    }
125    return;
126 }
127 /********************************************************************/
128 /*                                                                  */
129 /*  Title:         InitDcdMETAR                                     */
130 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
131 /*  Date:          15 Sep 1994                                      */
132 /*  Programmer:    CARL MCCALLA                                     */
133 /*  Language:      C/370                                            */
134 /*                                                                  */
135 /*  Abstract:  InitDcdMETAR initializes every member of the         */
136 /*             structure addressed by the pointer Mptr.             */
137 /*                                                                  */
138 /*  External Functions Called:                                      */
139 /*                 None.                                            */
140 /*                                                                  */
141 /*  Input:         Mptr - ptr to a decoded_METAR structure.         */
142 /*                                                                  */
143 /*  Output:        NONE                                             */
144 /*                                                                  */
145 /*  Modification History:                                           */
146 /*                 None.                                            */
147 /*                                                                  */
148 /********************************************************************/
149 static void InitDcdMETAR( Decoded_METAR *Mptr )
150 {
151  
152    /***************************/
153    /* DECLARE LOCAL VARIABLES */
154    /***************************/
155  
156  
157    int i,
158        j;
159  
160  
161  
162    /*************************/
163    /* START BODY OF ROUTINE */
164    /*************************/
165  
166    memset(Mptr->TS_LOC,'\0',3);
167    memset(Mptr->TS_MOVMNT,'\0',3);
168  
169  
170    memset(Mptr->TornadicType,'\0',15);
171    memset(Mptr->TornadicLOC,'\0',10);
172    memset(Mptr->TornadicDIR,'\0',4);
173    memset(Mptr->TornadicMovDir,'\0',3);
174    Mptr->BTornadicHour = MAXINT;
175    Mptr->BTornadicMinute = MAXINT;
176    Mptr->ETornadicHour = MAXINT;
177    Mptr->ETornadicMinute = MAXINT;
178    Mptr->TornadicDistance = MAXINT;
179  
180    memset( Mptr->autoIndicator,'\0', 5 );
181  
182    Mptr->RVRNO = FALSE;
183    Mptr->GR = FALSE;
184    Mptr->GR_Size = (float) MAXINT;
185  
186    Mptr->CHINO = FALSE;
187    memset(Mptr->CHINO_LOC, '\0', 6);
188  
189    Mptr->VISNO = FALSE;
190    memset(Mptr->VISNO_LOC, '\0', 6);
191  
192    Mptr->PNO = FALSE;
193    Mptr->PWINO = FALSE;
194    Mptr->FZRANO  = FALSE;
195    Mptr->TSNO   = FALSE;
196    Mptr->DollarSign  = FALSE;
197    Mptr->hourlyPrecip = (float) MAXINT;
198  
199    Mptr->ObscurAloftHgt = MAXINT;
200    memset(Mptr->ObscurAloft, '\0', 12);
201    memset(Mptr->ObscurAloftSkyCond, '\0', 12);
202  
203    memset(Mptr->VrbSkyBelow, '\0', 4);
204    memset(Mptr->VrbSkyAbove, '\0', 4);
205    Mptr->VrbSkyLayerHgt = MAXINT;
206  
207    Mptr->SectorVsby = (float) MAXINT;
208    memset( Mptr->SectorVsby_Dir, '\0', 3);
209  
210    memset(Mptr->codeName, '\0', 6);
211    memset(Mptr->stnid, '\0', 5);
212    Mptr->ob_hour   = MAXINT;
213    Mptr->ob_minute = MAXINT;
214    Mptr->ob_date   = MAXINT;
215  
216    memset(Mptr->synoptic_cloud_type, '\0', 6);
217  
218    Mptr->CloudLow    = '\0';
219    Mptr->CloudMedium = '\0';
220    Mptr->CloudHigh   = '\0';
221  
222    memset(Mptr->snow_depth_group, '\0', 6);
223    Mptr->snow_depth = MAXINT;
224  
225    Mptr->Temp_2_tenths    = (float) MAXINT;
226    Mptr->DP_Temp_2_tenths = (float) MAXINT;
227  
228    Mptr->OCNL_LTG      = FALSE;
229    Mptr->FRQ_LTG       = FALSE;
230    Mptr->CNS_LTG       = FALSE;
231    Mptr->CG_LTG        = FALSE;
232    Mptr->IC_LTG        = FALSE;
233    Mptr->CC_LTG        = FALSE;
234    Mptr->CA_LTG        = FALSE;
235    Mptr->AP_LTG        = FALSE;
236    Mptr->OVHD_LTG      = FALSE;
237    Mptr->DSNT_LTG      = FALSE;
238    Mptr->VcyStn_LTG    = FALSE;
239    Mptr->LightningVCTS = FALSE;
240    Mptr->LightningTS   = FALSE;
241  
242    memset( Mptr->LTG_DIR, '\0', 3);
243  
244  
245    for( i = 0; i < 3; i++)
246    {
247       memset(Mptr->ReWx[i].Recent_weather, '\0', 5);
248  
249       Mptr->ReWx[i].Bhh = MAXINT;
250       Mptr->ReWx[i].Bmm = MAXINT;
251  
252       Mptr->ReWx[i].Ehh = MAXINT;
253       Mptr->ReWx[i].Emm = MAXINT;
254  
255    }
256  
257    Mptr->NIL_rpt = FALSE;
258    Mptr->AUTO = FALSE;
259    Mptr->COR  = FALSE;
260  
261    Mptr->winData.windDir = MAXINT;
262    Mptr->winData.windSpeed = MAXINT;
263    Mptr->winData.windGust = MAXINT;
264    Mptr->winData.windVRB  = FALSE;
265    memset(Mptr->winData.windUnits, '\0', 4);
266  
267    Mptr->minWnDir = MAXINT;
268    Mptr->maxWnDir = MAXINT;
269  
270    memset(Mptr->horiz_vsby, '\0', 5);
271    memset(Mptr->dir_min_horiz_vsby, '\0', 3);
272  
273    Mptr->prevail_vsbySM = (float) MAXINT;
274    Mptr->prevail_vsbyM  = (float) MAXINT;
275    Mptr->prevail_vsbyKM = (float) MAXINT;
276  
277    memset(Mptr->vsby_Dir, '\0', 3);
278  
279    Mptr->CAVOK = FALSE;
280  
281    for ( i = 0; i < 12; i++ )
282    {
283       memset(Mptr->RRVR[ i ].runway_designator,
284               '\0', 6);
285  
286       Mptr->RRVR[ i ].visRange = MAXINT;
287  
288       Mptr->RRVR[ i ].vrbl_visRange = FALSE;
289       Mptr->RRVR[ i ].below_min_RVR = FALSE;
290       Mptr->RRVR[ i ].above_max_RVR = FALSE;
291  
292  
293       Mptr->RRVR[ i ].Max_visRange = MAXINT;
294       Mptr->RRVR[ i ].Min_visRange = MAXINT;
295    }
296  
297    Mptr->DVR.visRange = MAXINT;
298    Mptr->DVR.vrbl_visRange = FALSE;
299    Mptr->DVR.below_min_DVR = FALSE;
300    Mptr->DVR.above_max_DVR = FALSE;
301    Mptr->DVR.Max_visRange = MAXINT;
302    Mptr->DVR.Min_visRange = MAXINT;
303  
304    for ( i = 0; i < 5; i++ )
305    {
306       for( j = 0; j < 8; j++ )
307          Mptr->WxObstruct[i][j] = '\0';
308    }
309  
310    /***********************/
311    /* PARTIAL OBSCURATION */
312    /***********************/
313  
314    memset( &(Mptr->PartialObscurationAmt[0][0]), '\0', 7 );
315    memset( &(Mptr->PartialObscurationPhenom[0][0]), '\0',12);
316  
317    memset( &(Mptr->PartialObscurationAmt[1][0]), '\0', 7 );
318    memset( &(Mptr->PartialObscurationPhenom[1][0]), '\0',12);
319  
320  
321    /***************************************************/
322    /* CLOUD TYPE, CLOUD LEVEL, AND SIGNIFICANT CLOUDS */
323    /***************************************************/
324  
325  
326    for ( i = 0; i < 6; i++ )
327    {
328       memset(Mptr->cldTypHgt[ i ].cloud_type,
329               '\0', 5);
330  
331       memset(Mptr->cldTypHgt[ i ].cloud_hgt_char,
332               '\0', 4);
333  
334       Mptr->cldTypHgt[ i ].cloud_hgt_meters = MAXINT;
335  
336       memset(Mptr->cldTypHgt[ i ].other_cld_phenom,
337               '\0', 4);
338    }
339  
340    Mptr->VertVsby = MAXINT;
341  
342    Mptr->temp = MAXINT;
343    Mptr->dew_pt_temp = MAXINT;
344    Mptr->QFE = MAXINT;
345  
346    Mptr->SLPNO = FALSE;
347    Mptr->SLP = (float) MAXINT;
348  
349    Mptr->A_altstng = FALSE;
350    Mptr->inches_altstng = (double) MAXINT;
351  
352    Mptr->Q_altstng = FALSE;
353    Mptr->hectoPasc_altstng = MAXINT;
354  
355    Mptr->char_prestndcy = MAXINT;
356    Mptr->prestndcy = (float) MAXINT;
357  
358    Mptr->precip_amt = (float) MAXINT;
359  
360    Mptr->precip_24_amt = (float) MAXINT;
361    Mptr->maxtemp       = (float) MAXINT;
362    Mptr->mintemp       = (float) MAXINT;
363    Mptr->max24temp     = (float) MAXINT;
364    Mptr->min24temp     = (float) MAXINT;
365  
366    Mptr->VIRGA         = FALSE;
367    memset( Mptr->VIRGA_DIR, '\0', 3 );
368  
369    Mptr->VOLCASH       = FALSE;
370  
371    Mptr->minCeiling    = MAXINT;
372    Mptr->maxCeiling    = MAXINT;
373  
374    Mptr->CIG_2ndSite_Meters = MAXINT;
375    memset(Mptr->CIG_2ndSite_LOC, '\0', 10 );
376  
377    Mptr->minVsby = (float) MAXINT;
378    Mptr->maxVsby = (float) MAXINT;
379    Mptr->VSBY_2ndSite = (float) MAXINT;
380    memset(Mptr->VSBY_2ndSite_LOC,'\0',10);
381  
382    for( i = 0; i < 6; i++ )
383       memset (&(Mptr->SfcObscuration[i][0]), '\0', 10);
384  
385    Mptr->Num8thsSkyObscured = MAXINT;
386  
387    Mptr->Indeterminant3_6HrPrecip = FALSE;
388    Mptr->CIGNO = FALSE;
389    Mptr->Ceiling = MAXINT;
390    Mptr->Estimated_Ceiling = MAXINT;
391  
392    Mptr->NOSPECI = FALSE;
393    Mptr->LAST    = FALSE;
394  
395    Mptr->SNINCR = MAXINT;
396    Mptr->SNINCR_TotalDepth = MAXINT;
397  
398    Mptr->WaterEquivSnow = (float) MAXINT;
399  
400    Mptr->SunshineDur = MAXINT;
401    Mptr->SunSensorOut = FALSE;
402  
403  
404    Mptr->WshfTime_hour = MAXINT;
405    Mptr->WshfTime_minute = MAXINT;
406    Mptr->Wshft_FROPA     = FALSE;
407    Mptr->min_vrbl_wind_dir = MAXINT;
408    Mptr->max_vrbl_wind_dir = MAXINT;
409  
410    Mptr->PRESRR        = FALSE;
411    Mptr->PRESFR        = FALSE;
412  
413    Mptr->TWR_VSBY = (float) MAXINT;
414    Mptr->SFC_VSBY = (float) MAXINT;
415  
416    Mptr->PKWND_dir = MAXINT;
417    Mptr->PKWND_speed = MAXINT;
418    Mptr->PKWND_hour = MAXINT;
419    Mptr->PKWND_minute = MAXINT;
420  
421    return;
422  
423 }
424 /********************************************************************/
425 /*                                                                  */
426 /*  Title:         ResetMETARGroup                                  */
427 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
428 /*  Date:          15 Sep 1994                                      */
429 /*  Programmer:    CARL MCCALLA                                     */
430 /*  Language:      C/370                                            */
431 /*                                                                  */
432 /*  Abstract:  ResetMETARGroup returns a METAR_obGroup enumerated   */
433 /*             variable that indicates which METAR reporting group  */
434 /*             might next appear in the METAR report and should be  */
435 /*             considered for decoding.                             */
436 /*                                                                  */
437 /*  External Functions Called:                                      */
438 /*                 None.                                            */
439 /*                                                                  */
440 /*  Input:         StartGroup - a METAR_obGroup variable that       */
441 /*                              indicates where or on what group    */
442 /*                              METAR Decoding began.               */
443 /*                                                                  */
444 /*                 SaveStartGroup - a METAR_obGroup variable that   */
445 /*                                  indicates the reporting group   */
446 /*                                  in the METAR report that was    */
447 /*                                  successfully decoded.           */
448 /*                                                                  */
449 /*  Output:        A METAR_obGroup variable that indicates which    */
450 /*                 reporting group in the METAR report should next  */
451 /*                 be considered for decoding                       */
452 /*                                                                  */
453 /*  Modification History:                                           */
454 /*                 None.                                            */
455 /*                                                                  */
456 /********************************************************************/
457 /*static int ResetMETARGroup( int StartGroup,
458                             int SaveStartGroup )
459 {
460  
461    enum METAR_obGroup { codename, stnid, NIL1, COR1, obDateTime, NIL2,
462                         AUTO, COR, windData, MinMaxWinDir,
463                         CAVOK, visibility,
464                         RVR, presentWX, skyCond, tempGroup,
465                         altimStng, NotIDed = 99};
466  
467    if( StartGroup == NotIDed && SaveStartGroup == NotIDed )
468       return NotIDed;
469    else if( StartGroup == NotIDed && SaveStartGroup != NotIDed &&
470             SaveStartGroup != altimStng )
471       return (++SaveStartGroup);
472    else
473       return (++SaveStartGroup);
474  
475 }
476 */
477  
478 /********************************************************************/
479 /*                                                                  */
480 /*  Title:         CodedHgt2Meters                                  */
481 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
482 /*  Date:          15 Sep 1994                                      */
483 /*  Programmer:    CARL MCCALLA                                     */
484 /*  Language:      C/370                                            */
485 /*                                                                  */
486 /*  Abstract:  CodedHgt2Meters converts a coded cloud height into   */
487 /*             meters.                                              */
488 /*                                                                  */
489 /*  External Functions Called:                                      */
490 /*                 None.                                            */
491 /*                                                                  */
492 /*  Input:         token - a pointer to a METAR report group.       */
493 /*                 Mptr - a pointer to a decoded_METAR structure.   */
494 /*                                                                  */
495 /*  Output:        Cloud height in meters                           */
496 /*                                                                  */
497 /*  Modification History:                                           */
498 /*                 None.                                            */
499 /*                                                                  */
500 /********************************************************************/
501  
502 static int CodedHgt2Meters( char *token, Decoded_METAR *Mptr )
503 {
504    int hgt;
505    static int maxhgt = 30000;
506  
507  
508    if( (hgt = atoi(token)) == 999 )
509       return maxhgt;
510    else
511       return (hgt*30);
512 }
513  
514 /********************************************************************/
515 /*                                                                  */
516 /*  Title:         isPartObscur                                     */
517 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
518 /*  Date:          15 Sep 1994                                      */
519 /*  Programmer:    CARL MCCALLA                                     */
520 /*  Language:      C/370                                            */
521 /*                                                                  */
522 /*  Abstract:  isPartObscur determines whether or not the METAR     */
523 /*             report element that is passed to it is or is not     */
524 /*             a partial obscuration indicator for an amount of     */
525 /*             obscuration.                                         */
526 /*                                                                  */
527 /*                                                                  */
528 /*  External Functions Called:                                      */
529 /*                 None.                                            */
530 /*                                                                  */
531 /*  Input:         token - the address of a pointer to the group    */
532 /*                         in the METAR report that isPartObscur    */
533 /*                         determines is or is not a partial        */
534 /*                         obscuration indicator.                   */
535 /*                                                                  */
536 /*                                                                  */
537 /*                 Mptr - a pointer to a decoded_METAR structure.   */
538 /*                                                                  */
539 /*  Output:        TRUE, if the group is a partial obscuration      */
540 /*                 indicator and FALSE, if it is not.               */
541 /*                                                                  */
542 /*                                                                  */
543 /*  Modification History:                                           */
544 /*                 None.                                            */
545 /*                                                                  */
546 /********************************************************************/
547 static bool isPartObscur( char **string, Decoded_METAR *Mptr,
548                           int *NDEX )
549 {
550  
551    if( *string == NULL )
552       return FALSE;
553  
554    if( strcmp( *string, "FEW///" ) == 0 ||
555        strcmp( *string, "SCT///" ) == 0 ||
556        strcmp( *string, "BKN///" ) == 0 ||
557        strcmp( *string, "FEW000" ) == 0 ||
558        strcmp( *string, "SCT000" ) == 0 ||
559        strcmp( *string, "BKN000" ) == 0    ) {
560       strcpy( &(Mptr->PartialObscurationAmt[0][0]), *string );
561       (*NDEX)++;
562       string++;
563  
564       if( *string == NULL )
565          return TRUE;
566  
567       if( strcmp( (*string+3), "///") ) {
568           if( strcmp( *string, "FEW000" ) == 0 ||
569               strcmp( *string, "SCT000" ) == 0 ||
570               strcmp( *string, "BKN000" ) == 0    ) {
571             strcpy( &(Mptr->PartialObscurationAmt[1][0]), *string );
572             (*NDEX)++;
573          }
574       }
575       else {
576          if( strcmp( *string, "FEW///" ) == 0 ||
577              strcmp( *string, "SCT///" ) == 0 ||
578              strcmp( *string, "BKN///" ) == 0 ) {
579             strcpy( &(Mptr->PartialObscurationAmt[1][0]), *string );
580             (*NDEX)++;
581          }
582       }
583       return TRUE;
584    }
585    else
586       return FALSE;
587 }
588  
589 /********************************************************************/
590 /*                                                                  */
591 /*  Title:         isCldLayer                                       */
592 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
593 /*  Date:          15 Sep 1994                                      */
594 /*  Programmer:    CARL MCCALLA                                     */
595 /*  Language:      C/370                                            */
596 /*                                                                  */
597 /*  Abstract:      isCldLayer determines whether or not the         */
598 /*                 current group has a valid cloud layer            */
599 /*                 identifier.                                      */
600 /*                                                                  */
601 /*                                                                  */
602 /*  External Functions Called:                                      */
603 /*                 None.                                            */
604 /*                                                                  */
605 /*  Input:         token - pointer to a METAR report group.         */
606 /*                                                                  */
607 /*  Output:        TRUE, if the report group is a valid cloud       */
608 /*                 layer indicator.                                 */
609 /*                                                                  */
610 /*                 FALSE, if the report group is not a valid cloud  */
611 /*                 layer indicator.                                 */
612 /*                                                                  */
613 /*                                                                  */
614 /*  Modification History:                                           */
615 /*                 None.                                            */
616 /*                                                                  */
617 /********************************************************************/
618  
619 static bool isCldLayer( char *token )
620 {
621    if( token == NULL )
622       return FALSE;
623  
624    if( strlen(token) < 6 )
625       return FALSE;
626    else
627       return ((strncmp(token,"OVC",3) == 0 ||
628                strncmp(token,"SCT",3) == 0 ||
629                strncmp(token,"FEW",3) == 0 ||
630                strncmp(token,"BKN",3) == 0 ||
631                (isdigit(*token) &&
632                 strncmp(token+1,"CU",2) == 0) ||
633                (isdigit(*token) &&
634                 strncmp(token+1,"SC",2) == 0) ) &&
635                nisdigit((token+3),3)) ? TRUE:FALSE;
636 }
637  
638 /********************************************************************/
639 /*                                                                  */
640 /*  Title:         isCAVOK                                          */
641 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
642 /*  Date:          09 May 1996                                      */
643 /*  Programmer:    CARL MCCALLA                                     */
644 /*  Language:      C/370                                            */
645 /*                                                                  */
646 /*  Abstract:      isCAVOK determines whether or not the current    */
647 /*                 group is a valid CAVOK indicator.                */
648 /*                                                                  */
649 /*                                                                  */
650 /*  External Functions Called:                                      */
651 /*                 None.                                            */
652 /*                                                                  */
653 /*  Input:         token - pointer to a METAR report group.         */
654 /*                                                                  */
655 /*  Output:        TRUE, if the input group is a valid CAVOK        */
656 /*                 indicator.  FALSE, otherwise.                    */
657 /*                                                                  */
658 /*                                                                  */
659 /*                                                                  */
660 /*  Modification History:                                           */
661 /*                 None.                                            */
662 /*                                                                  */
663 /********************************************************************/
664  
665 static bool isCAVOK( char *token, Decoded_METAR *Mptr, int *NDEX )
666 {
667  
668    if( token == NULL )
669       return FALSE;
670  
671    if( strcmp(token, "CAVOK") != 0 )
672       return FALSE;
673    else {
674       (*NDEX)++;
675       Mptr->CAVOK = TRUE;
676       return TRUE;
677    }
678 }
679  
680 /********************************************************************/
681 /*                                                                  */
682 /*  Title:         parseCldData                                     */
683 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
684 /*  Date:          15 Sep 1994                                      */
685 /*  Programmer:    CARL MCCALLA                                     */
686 /*  Language:      C/370                                            */
687 /*                                                                  */
688 /*  Abstract:                                                       */
689 /*                                                                  */
690 /*  External Functions Called:                                      */
691 /*                 None.                                            */
692 /*                                                                  */
693 /*  Input:         x                                                */
694 /*                                                                  */
695 /*  Output:        x                                                */
696 /*                                                                  */
697 /*  Modification History:                                           */
698 /*                 None.                                            */
699 /*                                                                  */
700 /********************************************************************/
701  
702 static void parseCldData( char *token, Decoded_METAR *Mptr, int next)
703 {
704  
705  
706    if( token == NULL )
707       return;
708  
709    if( strlen(token) > 6 )
710       strncpy(Mptr->cldTypHgt[next].other_cld_phenom,token+6,
711               (strlen(token)-6));
712  
713    strncpy(Mptr->cldTypHgt[next].cloud_type,token,3);
714  
715    strncpy(Mptr->cldTypHgt[next].cloud_hgt_char,token+3,3);
716  
717    Mptr->cldTypHgt[next].cloud_hgt_meters =
718                                CodedHgt2Meters( token+3, Mptr );
719  
720    return;
721 }
722  
723  
724 /********************************************************************/
725 /*                                                                  */
726 /*  Title:         isSkyCond                                        */
727 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
728 /*  Date:          15 Sep 1994                                      */
729 /*  Programmer:    CARL MCCALLA                                     */
730 /*  Language:      C/370                                            */
731 /*                                                                  */
732 /*  Abstract:                                                       */
733 /*                                                                  */
734 /*  External Functions Called:                                      */
735 /*                 None.                                            */
736 /*                                                                  */
737 /*  Input:         x                                                */
738 /*                                                                  */
739 /*  Output:        x                                                */
740 /*                                                                  */
741 /*  Modification History:                                           */
742 /*                 None.                                            */
743 /*                                                                  */
744 /********************************************************************/
745 static bool isSkyCond( char **skycond, Decoded_METAR *Mptr,
746                         int *NDEX )
747 {
748  
749    bool first_layer,
750         second_layer,
751         third_layer,
752         fourth_layer,
753         fifth_layer,
754         sixth_layer;
755    int next;
756  
757       /********************************************************/
758       /* INTERROGATE skycond TO DETERMINE IF "CLR" IS PRESENT */
759       /********************************************************/
760  
761    if( *skycond == NULL )
762       return FALSE;
763  
764  
765    if( strcmp(*skycond,"CLR") == 0)
766    {
767       strcpy(Mptr->cldTypHgt[0].cloud_type,"CLR");
768 /*
769       memset(Mptr->cldTypHgt[0].cloud_hgt_char,'\0',1);
770       memset(Mptr->cldTypHgt[0].other_cld_phenom,
771               '\0', 1);
772 */
773       (*NDEX)++;
774       return TRUE;
775    }
776  
777       /********************************************************/
778       /* INTERROGATE skycond TO DETERMINE IF "SKC" IS PRESENT */
779       /********************************************************/
780  
781    else if( strcmp(*skycond,"SKC") == 0)
782    {
783       strcpy(Mptr->cldTypHgt[0].cloud_type,"SKC");
784 /*
785       memset(Mptr->cldTypHgt[0].cloud_hgt_char,'\0',1);
786       memset(Mptr->cldTypHgt[0].other_cld_phenom,
787               '\0', 1);
788 */
789       (*NDEX)++;
790       return TRUE;
791    }
792  
793       /****************************************/
794       /* INTERROGATE skycond TO DETERMINE IF  */
795       /*    VERTICAL VISIBILITY IS PRESENT    */
796       /****************************************/
797  
798    else if( strncmp(*skycond,"VV",2) == 0
799              && strlen(*skycond) == 5 &&
800                   nisdigit((*skycond+2),3) )
801    {
802       Mptr->VertVsby = CodedHgt2Meters( (*skycond+2), Mptr);
803       (*NDEX)++;
804       return TRUE;
805    }
806  
807       /****************************************/
808       /* INTERROGATE skycond TO DETERMINE IF  */
809       /*    CLOUD LAYER DATA IS PRESENT       */
810       /****************************************/
811  
812    else if( isCldLayer( *skycond ))
813    {
814       next = 0;
815  
816       parseCldData( *skycond , Mptr, next );
817       first_layer = TRUE;
818       next++;
819       (++skycond);
820  
821       if( *skycond == NULL )
822          return TRUE;
823  
824       second_layer = FALSE;
825       third_layer = FALSE;
826       fourth_layer = FALSE;
827       fifth_layer = FALSE;
828       sixth_layer = FALSE;
829  
830  
831       if( isCldLayer( *skycond ) && first_layer )
832       {
833          parseCldData( *skycond, Mptr, next );
834          second_layer = TRUE;
835          next++;
836          (++skycond);
837  
838          if( *skycond == NULL )
839             return TRUE;
840  
841       }
842  
843       if( isCldLayer( *skycond ) && first_layer &&
844           second_layer )
845       {
846          parseCldData( *skycond , Mptr, next );
847          third_layer = TRUE;
848          next++;
849          (++skycond);
850  
851          if( *skycond == NULL )
852             return TRUE;
853  
854       }
855  
856       if( isCldLayer( *skycond ) && first_layer && second_layer &&
857                       third_layer )
858       {
859          parseCldData( *skycond, Mptr, next );
860          fourth_layer = TRUE;
861          next++;
862          (++skycond);
863  
864          if( *skycond == NULL )
865             return TRUE;
866  
867       }
868  
869       if( isCldLayer( *skycond ) && first_layer && second_layer &&
870           third_layer && fourth_layer )
871       {
872          parseCldData( *skycond , Mptr, next );
873          fifth_layer = TRUE;
874          next++;
875          (++skycond);
876  
877          if( *skycond == NULL )
878             return TRUE;
879  
880       }
881  
882       if( isCldLayer( *skycond ) && first_layer && second_layer &&
883           third_layer && fourth_layer && fifth_layer )
884       {
885          parseCldData( *skycond , Mptr, next );
886          sixth_layer = TRUE;
887       }
888  
889  
890  
891       if( sixth_layer )
892       {
893          (*NDEX)++;
894          (*NDEX)++;
895          (*NDEX)++;
896          (*NDEX)++;
897          (*NDEX)++;
898          (*NDEX)++;
899          return TRUE;
900       }
901       else if( fifth_layer )
902       {
903          (*NDEX)++;
904          (*NDEX)++;
905          (*NDEX)++;
906          (*NDEX)++;
907          (*NDEX)++;
908          return TRUE;
909       }
910       else if( fourth_layer )
911       {
912          (*NDEX)++;
913          (*NDEX)++;
914          (*NDEX)++;
915          (*NDEX)++;
916          return TRUE;
917       }
918       else if( third_layer )
919       {
920          (*NDEX)++;
921          (*NDEX)++;
922          (*NDEX)++;
923          return TRUE;
924       }
925       else if( second_layer )
926       {
927          (*NDEX)++;
928          (*NDEX)++;
929          return TRUE;
930       }
931       else if( first_layer )
932       {
933          (*NDEX)++;
934          return TRUE;
935       }
936       else
937          return FALSE;
938  
939    }
940    else
941       return FALSE;
942 }
943 /********************************************************************/
944 /*                                                                  */
945 /*  Title:         prevailVSBY                                      */
946 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
947 /*  Date:          15 Sep 1994                                      */
948 /*  Programmer:    CARL MCCALLA                                     */
949 /*  Language:      C/370                                            */
950 /*                                                                  */
951 /*  Abstract:                                                       */
952 /*                                                                  */
953 /*  External Functions Called:                                      */
954 /*                 None.                                            */
955 /*                                                                  */
956 /*  Input:         x                                                */
957 /*                                                                  */
958 /*  Output:        x                                                */
959 /*                                                                  */
960 /*  Modification History:                                           */
961 /*                 None.                                            */
962 /*                                                                  */
963 /********************************************************************/
964 static float prevailVSBY( char *visibility )
965 {
966    float Miles_vsby;
967    char *temp,
968         *Slash_ptr,
969         *SM_KM_ptr;
970    char numerator[3],
971         denominator[3];
972  
973  
974    if( (SM_KM_ptr = strstr( visibility, "SM" )) == NULL )
975       SM_KM_ptr = strstr(visibility, "KM");
976  
977    Slash_ptr = strchr( visibility, '/' );
978  
979    if( Slash_ptr == NULL )
980    {
981       temp = (char *) malloc(sizeof(char) *
982                           ((SM_KM_ptr - visibility)+1));
983       memset( temp, '\0', (SM_KM_ptr-visibility)+1);
984       strncpy( temp, visibility, (SM_KM_ptr-visibility) );
985       Miles_vsby = (float) (atoi(temp));
986       free( temp );
987       return Miles_vsby;
988    }
989    else
990    {
991       memset(numerator,   '\0', 3);
992       memset(denominator, '\0', 3);
993  
994       strncpy(numerator, visibility, (Slash_ptr - visibility));
995  
996 /*>>>>>>>>>>>>>>>>>>>>>>
997       if( (SM_KM_ptr - (Slash_ptr+1)) == 0 )
998          strcpy(denominator, "4");
999       else
1000 <<<<<<<<<<<<<<<<<<<<<<*/
1001  
1002       strncpy(denominator,
1003               Slash_ptr+1, (SM_KM_ptr - Slash_ptr));
1004  
1005       return ( ((float)(atoi(numerator)))/
1006                ((float)(atoi(denominator))) );
1007    }
1008  
1009 }
1010  
1011 /********************************************************************/
1012 /*                                                                  */
1013 /*  Title:         isVisibility                                     */
1014 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1015 /*  Date:          15 Sep 1994                                      */
1016 /*  Programmer:    CARL MCCALLA                                     */
1017 /*  Language:      C/370                                            */
1018 /*                                                                  */
1019 /*  Abstract:                                                       */
1020 /*                                                                  */
1021 /*  External Functions Called:                                      */
1022 /*                 None.                                            */
1023 /*                                                                  */
1024 /*  Input:         x                                                */
1025 /*                                                                  */
1026 /*  Output:        x                                                */
1027 /*                                                                  */
1028 /*  Modification History:                                           */
1029 /*                 None.                                            */
1030 /*                                                                  */
1031 /********************************************************************/
1032  
1033  
1034 static bool isVisibility( char **visblty, Decoded_METAR *Mptr,
1035                           int *NDEX )
1036 {
1037    char *achar,
1038         *astring,
1039         *save_token;
1040  
1041  
1042    /****************************************/
1043    /* CHECK FOR VISIBILITY MEASURED <1/4SM */
1044    /****************************************/
1045  
1046    if( *visblty == NULL )
1047       return FALSE;
1048  
1049  
1050    if( strcmp(*visblty,"M1/4SM") == 0 ||
1051        strcmp(*visblty,"<1/4SM") == 0 ) {
1052       Mptr->prevail_vsbySM = 0.0;
1053       (*NDEX)++;
1054       return TRUE;
1055    }
1056  
1057    /***********************************************/
1058    /* CHECK FOR VISIBILITY MEASURED IN KILOMETERS */
1059    /***********************************************/
1060  
1061    if( (achar = strstr(*visblty, "KM")) != NULL )
1062    {
1063       if( nisdigit(*visblty,(achar - *visblty)) &&
1064                         (achar - *visblty) > 0 )
1065       {
1066          Mptr->prevail_vsbyKM = prevailVSBY( *visblty );
1067          (*NDEX)++;
1068          return TRUE;
1069       }
1070       else
1071          return FALSE;
1072    }
1073  
1074    /***********************************/
1075    /* CHECK FOR VISIBILITY MEASURED   */
1076    /* IN A FRACTION OF A STATUTE MILE */
1077    /***********************************/
1078  
1079    else if( (achar = strchr( *visblty, '/' )) !=
1080                     NULL &&
1081        (astring = strstr( *visblty, "SM")) != NULL )
1082    {
1083       if( nisdigit(*visblty,(achar - *visblty))
1084                      &&
1085                (achar - *visblty) > 0 &&
1086                (astring - (achar+1)) > 0 &&
1087                 nisdigit(achar+1, (astring - (achar+1))) )
1088       {
1089          Mptr->prevail_vsbySM = prevailVSBY (*visblty);
1090          (*NDEX)++;
1091          return TRUE;
1092       }
1093       else
1094          return FALSE;
1095    }
1096  
1097    /***********************************/
1098    /* CHECK FOR VISIBILITY MEASURED   */
1099    /*     IN WHOLE STATUTE MILES      */
1100    /***********************************/
1101  
1102    else if( (astring = strstr(*visblty,"SM") ) != NULL )
1103    {
1104       if( nisdigit(*visblty,(astring - *visblty)) &&
1105                        (astring- *visblty) > 0 )
1106       {
1107          Mptr->prevail_vsbySM = prevailVSBY (*visblty);
1108          (*NDEX)++;
1109          return TRUE;
1110       }
1111       else
1112          return FALSE;
1113    }
1114  
1115    /***********************************/
1116    /* CHECK FOR VISIBILITY MEASURED   */
1117    /* IN WHOLE AND FRACTIONAL STATUTE */
1118    /*             MILES               */
1119    /***********************************/
1120  
1121    else if( nisdigit( *visblty,
1122                strlen(*visblty)) &&
1123                             strlen(*visblty) < 4 )
1124    {
1125       save_token = (char *) malloc(sizeof(char)*
1126                               (strlen(*visblty)+1));
1127       strcpy(save_token,*visblty);
1128       if( *(++visblty) == NULL)
1129       {
1130          free( save_token );
1131          return FALSE;
1132       }
1133  
1134       if( (achar = strchr( *visblty, '/' ) ) != NULL &&
1135           (astring = strstr( *visblty, "SM") ) != NULL  )
1136       {
1137          if( nisdigit(*visblty,
1138                  (achar - *visblty)) &&
1139                  (achar - *visblty) > 0 &&
1140                  (astring - (achar+1)) > 0 &&
1141              nisdigit(achar+1, (astring - (achar+1))) )
1142          {
1143             Mptr->prevail_vsbySM = prevailVSBY (*visblty);
1144             Mptr->prevail_vsbySM +=
1145                                  (float) (atoi(save_token));
1146             free( save_token);
1147  
1148             (*NDEX)++;
1149             (*NDEX)++;
1150  
1151             return TRUE;
1152  
1153          }
1154          else
1155             return FALSE;
1156       }
1157       else
1158          return FALSE;
1159  
1160    }
1161  
1162    /***********************************/
1163    /* CHECK FOR VISIBILITY MEASURED   */
1164    /* IN METERS WITH OR WITHOUT DI-   */
1165    /*     RECTION OF OBSERVATION      */
1166    /***********************************/
1167  
1168    else if( nisdigit(*visblty,4) &&
1169                 strlen(*visblty) >= 4)
1170    {
1171       if( strcmp(*visblty+4,"NE") == 0 )
1172       {
1173          memset(Mptr->vsby_Dir,'\0',3);
1174          strcpy(Mptr->vsby_Dir,*visblty+4);
1175       }
1176       if( strcmp(*visblty+4,"NW") == 0 )
1177       {
1178          memset(Mptr->vsby_Dir,'\0',3);
1179          strcpy(Mptr->vsby_Dir,*visblty+4);
1180       }
1181       if( strcmp(*visblty+4,"SE") == 0 )
1182       {
1183          memset(Mptr->vsby_Dir,'\0',3);
1184          strcpy(Mptr->vsby_Dir,*visblty+4);
1185       }
1186       if( strcmp(*visblty+4,"SW") == 0 )
1187       {
1188          memset(Mptr->vsby_Dir,'\0',3);
1189          strcpy(Mptr->vsby_Dir,*visblty+4);
1190       }
1191       if( strcmp(*visblty+4,"N") == 0 )
1192       {
1193          memset(Mptr->vsby_Dir,'\0',3);
1194          strcpy(Mptr->vsby_Dir,*visblty+4);
1195       }
1196       if( strcmp(*visblty+4,"S") == 0 )
1197       {
1198          memset(Mptr->vsby_Dir,'\0',3);
1199          strcpy(Mptr->vsby_Dir,*visblty+4);
1200       }
1201       if( strcmp(*visblty+4,"E") == 0 )
1202       {
1203          memset(Mptr->vsby_Dir,'\0',3);
1204          strcpy(Mptr->vsby_Dir,*visblty+4);
1205       }
1206       if( strcmp(*visblty+4,"W") == 0 )
1207       {
1208          memset(Mptr->vsby_Dir,'\0',3);
1209          strcpy(Mptr->vsby_Dir,*visblty+4);
1210       }
1211  
1212       if( antoi(*visblty,
1213                   strlen(*visblty)) >= 50 &&
1214                antoi(*visblty,
1215                   strlen(*visblty)) <= 500 &&
1216               (antoi(*visblty,
1217                   strlen(*visblty)) % 50) == 0 )
1218       {
1219          Mptr->prevail_vsbyM =
1220            (float) (antoi(*visblty,
1221                        strlen(*visblty)));
1222          (*NDEX)++;
1223          return TRUE;
1224       }
1225       else if( antoi(*visblty,
1226                  strlen(*visblty)) >= 500 &&
1227            antoi(*visblty,
1228                  strlen(*visblty)) <= 3000 &&
1229           (antoi(*visblty,
1230                  strlen(*visblty)) % 100) == 0 )
1231       {
1232          Mptr->prevail_vsbyM =
1233             (float) (antoi(*visblty,
1234                       strlen(*visblty)));
1235          (*NDEX)++;
1236          return TRUE;
1237       }
1238       else if( antoi(*visblty,
1239               strlen(*visblty)) >= 3000 &&
1240           antoi(*visblty,
1241               strlen(*visblty)) <= 5000 &&
1242           (antoi(*visblty,
1243                   strlen(*visblty)) % 500) == 0 )
1244       {
1245          Mptr->prevail_vsbyM =
1246                (float) (antoi(*visblty,
1247                     strlen(*visblty)));
1248          (*NDEX)++;
1249          return TRUE;
1250       }
1251       else if( antoi(*visblty,
1252             strlen(*visblty)) >= 5000 &&
1253           antoi(*visblty,
1254             strlen(*visblty)) <= 9999 &&
1255           (antoi(*visblty,
1256             strlen(*visblty)) % 500) == 0 ||
1257            antoi(*visblty,
1258             strlen(*visblty)) == 9999 )
1259       {
1260          Mptr->prevail_vsbyM =
1261                 (float) (antoi(*visblty,
1262                      strlen(*visblty)));
1263          (*NDEX)++;
1264          return TRUE;
1265       }
1266       else
1267          return FALSE;
1268  
1269    }
1270    else
1271       return FALSE;
1272  
1273 }
1274  
1275 /********************************************************************/
1276 /*                                                                  */
1277 /*  Title:         vrblVsby                                         */
1278 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1279 /*  Date:          15 Sep 1994                                      */
1280 /*  Programmer:    CARL MCCALLA                                     */
1281 /*  Language:      C/370                                            */
1282 /*                                                                  */
1283 /*  Abstract:                                                       */
1284 /*                                                                  */
1285 /*  External Functions Called:                                      */
1286 /*                 None.                                            */
1287 /*                                                                  */
1288 /*  Input:         x                                                */
1289 /*                                                                  */
1290 /*  Output:        x                                                */
1291 /*                                                                  */
1292 /*  Modification History:                                           */
1293 /*                 None.                                            */
1294 /*                                                                  */
1295 /********************************************************************/
1296 #if 0
1297 static bool vrblVsby( char *string1, char *string2,
1298                       Decoded_METAR *Mptr, int *NDEX )
1299 {
1300    char buf[ 6 ];
1301    /* int numerator,
1302        denominator; */
1303    char *slash,
1304         *V_char,
1305         *temp;
1306  
1307    if( string1 == NULL )
1308       return FALSE;
1309  
1310    V_char = strchr(string1,'V');
1311    slash =  strchr(string1,'/');
1312  
1313    if(slash == NULL)
1314    {
1315       if(nisdigit(string1,V_char-string1))
1316       {
1317          memset(buf, '\0', 6);
1318          strncpy(buf, string1, V_char-string1);
1319  
1320          if( Mptr->minVsby != (float) MAXINT )
1321             Mptr->minVsby += (float) atoi(buf);
1322          else
1323             Mptr->minVsby  = (float) atoi(buf);
1324  
1325          memset(buf, '\0', 6);
1326          strncpy(buf, V_char+1, 5);
1327          Mptr->maxVsby = (float) atoi(buf);
1328  
1329       }
1330       else
1331          return FALSE;
1332    }
1333    else
1334    {
1335       temp = (char *) malloc(sizeof(char)*((V_char-string1)+1));
1336       memset(temp, '\0', (V_char-string1) +1);
1337       strncpy(temp, string1, V_char-string1);
1338       if( Mptr->minVsby != MAXINT )
1339          Mptr->minVsby += fracPart(temp);
1340       else
1341          Mptr->minVsby = fracPart(temp);
1342  
1343       free( temp );
1344  
1345       if( strchr(V_char+1,'/') != NULL)
1346          Mptr->maxVsby = fracPart(V_char+1);
1347       else
1348          Mptr->maxVsby = (float) atoi(V_char+1);
1349    }
1350  
1351    if( string2 == NULL )
1352       return TRUE;
1353    else
1354    {
1355       slash = strchr( string2, '/' );
1356  
1357       if( slash == NULL )
1358          return TRUE;
1359       else
1360       {
1361          if( nisdigit(string2,slash-string2) &&
1362              nisdigit(slash+1,strlen(slash+1)) )
1363          {
1364             Mptr->maxVsby += fracPart(string2);
1365             (*NDEX)++;
1366          }
1367          return TRUE;
1368       }
1369    }
1370  
1371 }
1372 #endif
1373  
1374  
1375 /********************************************************************/
1376 /*                                                                  */
1377 /*  Title:         isMinMaxWinDir                                   */
1378 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1379 /*  Date:          15 Sep 1994                                      */
1380 /*  Programmer:    CARL MCCALLA                                     */
1381 /*  Language:      C/370                                            */
1382 /*                                                                  */
1383 /*  Abstract:                                                       */
1384 /*                                                                  */
1385 /*  External Functions Called:                                      */
1386 /*                 None.                                            */
1387 /*                                                                  */
1388 /*  Input:         x                                                */
1389 /*                                                                  */
1390 /*  Output:        x                                                */
1391 /*                                                                  */
1392 /*  Modification History:                                           */
1393 /*                 None.                                            */
1394 /*                                                                  */
1395 /********************************************************************/
1396 static bool isMinMaxWinDir( char *string, Decoded_METAR *Mptr,
1397      int *NDEX )
1398 {
1399 #define buf_len 50
1400    char buf[ buf_len ];
1401    char *V_char;
1402  
1403    if( string == NULL )
1404       return FALSE;
1405  
1406    if( (V_char = strchr(string,'V')) == NULL )
1407       return FALSE;
1408    else
1409    {
1410       if( nisdigit(string,(V_char - string)) &&
1411                nisdigit(V_char+1,3) )
1412       {
1413          memset( buf, '\0', buf_len);
1414          strncpy( buf, string, V_char - string);
1415          Mptr->minWnDir = atoi( buf );
1416  
1417          memset( buf, '\0', buf_len);
1418          strcpy( buf, V_char+1 );
1419          Mptr->maxWnDir = atoi( buf );
1420  
1421          (*NDEX)++;
1422          return TRUE;
1423       }
1424       else
1425          return FALSE;
1426    }
1427 }
1428 /********************************************************************/
1429 /*                                                                  */
1430 /*  Title:         isRVR                                            */
1431 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1432 /*  Date:          15 Sep 1994                                      */
1433 /*  Programmer:    CARL MCCALLA                                     */
1434 /*  Language:      C/370                                            */
1435 /*                                                                  */
1436 /*  Abstract:                                                       */
1437 /*                                                                  */
1438 /*  External Functions Called:                                      */
1439 /*                 None.                                            */
1440 /*                                                                  */
1441 /*  Input:         x                                                */
1442 /*                                                                  */
1443 /*  Output:        x                                                */
1444 /*                                                                  */
1445 /*  Modification History:                                           */
1446 /*                 None.                                            */
1447 /*                                                                  */
1448 /********************************************************************/
1449  
1450 static bool isRVR( char *token, Decoded_METAR *Mptr, int *NDEX,
1451                      int ndex )
1452 {
1453    char *slashPtr, *FT_ptr;
1454    char *vPtr;
1455    int length;
1456  
1457    if( token == NULL )
1458       return FALSE;
1459  
1460    if( *token != 'R' || (length = strlen(token)) < 7 ||
1461         (slashPtr = strchr(token,'/')) == NULL ||
1462         nisdigit(token+1,2) == FALSE )
1463       return FALSE;
1464  
1465    if( (slashPtr - (token+3)) > 0 )
1466       if( !nisalpha(token+3,(slashPtr - (token+3))) )
1467          return FALSE;
1468  
1469    if( strcmp(token+(strlen(token)-2),"FT") != 0 )
1470       return FALSE;
1471    else
1472       FT_ptr = token + (strlen(token)-2);
1473  
1474    if( strchr(slashPtr+1, 'P' ) != NULL )
1475       Mptr->RRVR[ndex].above_max_RVR = TRUE;
1476  
1477    if( strchr(slashPtr+1, 'M' ) != NULL )
1478       Mptr->RRVR[ndex].below_min_RVR = TRUE;
1479  
1480  
1481    strncpy(Mptr->RRVR[ndex].runway_designator, token+1,
1482            (slashPtr-(token+1)));
1483  
1484    if( (vPtr = strchr(slashPtr, 'V' )) != NULL )
1485    {
1486       Mptr->RRVR[ndex].vrbl_visRange = TRUE;
1487       Mptr->RRVR[ndex].Min_visRange = antoi(slashPtr+1,
1488                               (vPtr-(slashPtr+1)) );
1489       Mptr->RRVR[ndex].Max_visRange = antoi(vPtr+1,
1490                               (FT_ptr - (vPtr+1)) );
1491       (*NDEX)++;
1492       return TRUE;
1493    }
1494    else
1495    {
1496       if( Mptr->RRVR[ndex].below_min_RVR ||
1497           Mptr->RRVR[ndex].above_max_RVR    )
1498          Mptr->RRVR[ndex].visRange = antoi(slashPtr+2,
1499                            (FT_ptr - (slashPtr+2)) );
1500       else
1501          Mptr->RRVR[ndex].visRange = antoi(slashPtr+1,
1502                            (FT_ptr - (slashPtr+1)) );
1503  
1504       (*NDEX)++;
1505       return TRUE;
1506    }
1507  
1508 }
1509  
1510  
1511 /********************************************************************/
1512 /*                                                                  */
1513 /*  Title:         isAltimStng                                      */
1514 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1515 /*  Date:          15 Sep 1994                                      */
1516 /*  Programmer:    CARL MCCALLA                                     */
1517 /*  Language:      C/370                                            */
1518 /*                                                                  */
1519 /*  Abstract:                                                       */
1520 /*                                                                  */
1521 /*  External Functions Called:                                      */
1522 /*                 None.                                            */
1523 /*                                                                  */
1524 /*  Input:         x                                                */
1525 /*                                                                  */
1526 /*  Output:        x                                                */
1527 /*                                                                  */
1528 /*  Modification History:                                           */
1529 /*                 None.                                            */
1530 /*                                                                  */
1531 /********************************************************************/
1532  
1533 static bool isAltimStng( char *token, Decoded_METAR *Mptr, int *NDEX )
1534 {
1535    char dummy[6];
1536  
1537  
1538    if( token == NULL )
1539       return FALSE;
1540  
1541    if( strlen(token) < 5 )
1542       return FALSE;
1543    else
1544    {
1545       Mptr->A_altstng = FALSE;
1546       Mptr->Q_altstng = FALSE;
1547  
1548       if( (*token == 'A' || *token == 'Q') &&
1549            (nisdigit(token+1, strlen(token)-1) ||
1550             nisdigit(token+1,strlen(token)-3)) )
1551       {
1552          if( *token == 'A' )
1553          {
1554             Mptr->A_altstng = TRUE;
1555             Mptr->inches_altstng = atof(token+1) * 0.01;
1556          }
1557          else
1558          {
1559             Mptr->Q_altstng = TRUE;
1560  
1561             if( strchr(token,'.') != NULL)
1562             {
1563                memset(dummy, '\0', 6);
1564                strncpy(dummy,token+1,4);
1565                Mptr->hectoPasc_altstng = atoi(dummy);
1566             }
1567             else
1568                Mptr->hectoPasc_altstng = atoi(token+1);
1569          }
1570  
1571          (*NDEX)++;
1572          return TRUE;
1573  
1574       }
1575       return FALSE;
1576    }
1577 }
1578  
1579  
1580 /********************************************************************/
1581 /*                                                                  */
1582 /*  Title:         isTempGroup                                      */
1583 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1584 /*  Date:          15 Sep 1994                                      */
1585 /*  Programmer:    CARL MCCALLA                                     */
1586 /*  Language:      C/370                                            */
1587 /*                                                                  */
1588 /*  Abstract:                                                       */
1589 /*                                                                  */
1590 /*  External Functions Called:                                      */
1591 /*                 None.                                            */
1592 /*                                                                  */
1593 /*  Input:         x                                                */
1594 /*                                                                  */
1595 /*  Output:        x                                                */
1596 /*                                                                  */
1597 /*  Modification History:                                           */
1598 /*                 None.                                            */
1599 /*                                                                  */
1600 /********************************************************************/
1601  
1602 static bool isTempGroup( char *token, Decoded_METAR *Mptr, int *NDEX)
1603 {
1604  
1605    /***************************/
1606    /* DECLARE LOCAL VARIABLES */
1607    /***************************/
1608  
1609    char *slash;
1610  
1611    if( token == NULL )
1612       return FALSE;
1613  
1614    if( (slash = strchr(token,'/')) == NULL)
1615       return FALSE;
1616    else
1617    {
1618       if( charcmp(token,"aa'/'dd") ) {
1619          Mptr->dew_pt_temp = atoi(slash+1);
1620          (*NDEX)++;
1621          return TRUE;
1622       }
1623       else if( charcmp(token,"aa'/''M'dd") ) {
1624          Mptr->dew_pt_temp = atoi(slash+2) * -1;
1625          (*NDEX)++;
1626          return TRUE;
1627       }
1628       else if( charcmp(token,"dd'/'aa") ) {
1629          Mptr->temp = antoi(token,(slash-token));
1630          (*NDEX)++;
1631          return TRUE;
1632       }
1633       else if( charcmp(token,"'M'dd'/'aa") ) {
1634          Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1635          (*NDEX)++;
1636          return TRUE;
1637       }
1638       else if( nisdigit(token,(slash-token)) &&
1639            nisdigit(slash+1,strlen(slash+1)) )
1640       {
1641          Mptr->temp = antoi(token,(slash-token));
1642          Mptr->dew_pt_temp = atoi(slash+1);
1643          (*NDEX)++;
1644          return TRUE;
1645       }
1646       else if( *token == 'M' && nisdigit(token+1,(slash-(token+1)))
1647                 && *(slash+1) != '\0' &&
1648             *(slash+1) == 'M' && nisdigit(slash+2,strlen(slash+2)) )
1649       {
1650          Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1651          Mptr->dew_pt_temp = atoi(slash+2) * -1;
1652          (*NDEX)++;
1653          return TRUE;
1654       }
1655       else if( *token == 'M' && nisdigit(token+1,(slash-(token+1)))
1656                  && *(slash+1) != '\0' &&
1657                nisdigit(slash+1,strlen(slash+1)) )
1658       {
1659          Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1660          Mptr->dew_pt_temp = atoi(slash+1);
1661          (*NDEX)++;
1662          return TRUE;
1663       }
1664       else if( nisdigit(token,(slash - token)) &&
1665                     *(slash+1) != '\0' &&
1666                     nisdigit(slash+2,strlen(slash+2)) )
1667       {
1668          Mptr->temp = antoi(token,(slash-token));
1669          Mptr->dew_pt_temp = atoi(slash+2) * -1;
1670          (*NDEX)++;
1671          return TRUE;
1672       }
1673       else if( nisdigit(token,(slash-token)) &&
1674            strlen(token) <= 3)
1675       {
1676          Mptr->temp = antoi(token,(slash-token));
1677          (*NDEX)++;
1678          return TRUE;
1679       }
1680       else if( *token == 'M' &&
1681                    nisdigit(token+1,(slash-(token+1))) &&
1682                    strlen(token) <= 4)
1683       {
1684          Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1685          (*NDEX)++;
1686          return TRUE;
1687       }
1688       else
1689          return FALSE;
1690    }
1691  
1692 }
1693  
1694  
1695  
1696 /********************************************************************/
1697 /*                                                                  */
1698 /*  Title:         isWxToken                                        */
1699 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1700 /*  Date:          15 Sep 1994                                      */
1701 /*  Programmer:    CARL MCCALLA                                     */
1702 /*  Language:      C/370                                            */
1703 /*                                                                  */
1704 /*  Abstract:                                                       */
1705 /*                                                                  */
1706 /*  External Functions Called:                                      */
1707 /*                 None.                                            */
1708 /*                                                                  */
1709 /*  Input:         x                                                */
1710 /*                                                                  */
1711 /*  Output:        x                                                */
1712 /*                                                                  */
1713 /*  Modification History:                                           */
1714 /*                 None.                                            */
1715 /*                                                                  */
1716 /********************************************************************/
1717  
1718 /*static bool isWxToken( char *token )
1719 {
1720    int i;
1721  
1722    if( token == NULL )
1723       return FALSE;
1724    for( i = 0; i < (int)strlen(token); i++ )
1725    {
1726       if( !(isalpha(*(token+i)) || *(token+i) == '+' ||
1727                                    *(token+i) == '-'   ) )
1728          return FALSE;
1729    }
1730    return TRUE;
1731 }*/
1732  
1733  
1734 /********************************************************************/
1735 /*                                                                  */
1736 /*  Title:         isPresentWX                                      */
1737 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1738 /*  Date:          15 Sep 1994                                      */
1739 /*  Programmer:    CARL MCCALLA                                     */
1740 /*  Language:      C/370                                            */
1741 /*                                                                  */
1742 /*  Abstract:                                                       */
1743 /*                                                                  */
1744 /*  External Functions Called:                                      */
1745 /*                 None.                                            */
1746 /*                                                                  */
1747 /*  Input:         x                                                */
1748 /*                                                                  */
1749 /*  Output:        x                                                */
1750 /*                                                                  */
1751 /*  Modification History:                                           */
1752 /*                 None.                                            */
1753 /*                                                                  */
1754 /********************************************************************/
1755  
1756 static bool isPresentWX( char *token, Decoded_METAR *Mptr,
1757                         int *NDEX, int *next )
1758 {
1759 /*
1760    static char *WxSymbols[] = {"BCFG", "BLDU", "BLSA", "BLPY",
1761           "DRDU", "DRSA", "DRSN", "DZ", "DS", "FZFG", "FZDZ", "FZRA",
1762           "FG", "FC", "FU", "GS", "GR", "HZ", "IC", "MIFG",
1763           "PE", "PO", "RA", "SHRA", "SHSN", "SHPE", "SHGS",
1764           "SHGR", "SN", "SG", "SQ", "SA", "SS", "TSRA",
1765           "TSSN", "TSPE", "TSGS", "TSGR", "TS", "VA", "VCFG", "VCFC",
1766           "VCSH", "VCPO", "VCBLDU", "VCBLSA", "VCBLSN", NULL};
1767 */
1768    static char *WxSymbols[] = {"BCFG", "BLDU", "BLSA", "BLPY",
1769           "BR", "FZBR", "VCBR",
1770           "DRDU", "DRSA", "DRSN", "DZ", "DS", "FZFG", "FZDZ", "FZRA",
1771           "FG", "FC", "FU", "GS", "GR", "HZ", "IC", "MIFG",
1772           "PE", "PO", "RA", "SHRA", "SHSN", "SHPE", "SHGS",
1773           "SHGR", "SN", "SG", "SQ", "SA", "SS", "TS",
1774           "VA", "VCFG", "VCFC",
1775           "VCSH", "VCPO", "VCBLDU", "VCBLSA", "VCBLSN", NULL};
1776    int i;
1777    char *ptr,
1778         *temp_token,
1779         *save_token,
1780         *temp_token_orig;
1781  
1782    if( token == NULL)
1783       return FALSE;
1784  
1785    temp_token_orig = temp_token =
1786         (char *) malloc(sizeof(char)*(strlen(token)+1));
1787    strcpy(temp_token, token);
1788    while( temp_token != NULL && (*next) < MAXWXSYMBOLS )
1789    {
1790       i = 0;
1791       save_token = NULL;
1792  
1793       if( *temp_token == '+' || *temp_token == '-' )
1794       {
1795          save_token = temp_token;
1796          temp_token++;
1797       }
1798  
1799       while( WxSymbols[i] != NULL )
1800          if( strncmp(temp_token, WxSymbols[i],
1801                       strlen(WxSymbols[i])) != 0 )
1802             i++;
1803          else
1804             break;
1805  
1806       if( WxSymbols[i] == NULL ) {
1807          free( temp_token_orig );
1808          return FALSE;
1809       }
1810       else
1811       {
1812  
1813          if( save_token != NULL )
1814          {
1815             strncpy( Mptr->WxObstruct[*next], save_token, 1);
1816             strcpy( (Mptr->WxObstruct[*next])+1,
1817                               WxSymbols[i]);
1818             (*next)++;
1819          }
1820          else
1821          {
1822             strcpy( Mptr->WxObstruct[*next], WxSymbols[i]);
1823             (*next)++;
1824          }
1825  
1826  
1827          if( strcmp(temp_token, WxSymbols[i]) != 0)
1828          {
1829             ptr = strstr(temp_token, WxSymbols[i]);
1830             temp_token = ptr + strlen(WxSymbols[i]);
1831          }
1832          else
1833          {
1834             free( temp_token_orig );
1835             temp_token = NULL;
1836             (*NDEX)++;
1837             return TRUE;
1838          }
1839  
1840       }
1841  
1842    }
1843  
1844    free( temp_token_orig );
1845    return FALSE;
1846  
1847 }
1848  
1849 /********************************************************************/
1850 /*                                                                  */
1851 /*  Title:         isStnID                                          */
1852 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1853 /*  Date:          15 Sep 1994                                      */
1854 /*  Programmer:    CARL MCCALLA                                     */
1855 /*  Language:      C/370                                            */
1856 /*                                                                  */
1857 /*  Abstract:                                                       */
1858 /*                                                                  */
1859 /*  External Functions Called:                                      */
1860 /*                 None.                                            */
1861 /*                                                                  */
1862 /*  Input:         x                                                */
1863 /*                                                                  */
1864 /*  Output:        x                                                */
1865 /*                                                                  */
1866 /*  Modification History:                                           */
1867 /*                 None.                                            */
1868 /*                                                                  */
1869 /********************************************************************/
1870  
1871 static bool isStnId( char *stnID, Decoded_METAR *Mptr, int *NDEX)
1872 {
1873  
1874    if( stnID == NULL )
1875       return FALSE;
1876  
1877    if( strlen(stnID) == 4 )
1878    {
1879       if( nisalpha(stnID,1) && nisalnum(stnID+1,3) ) {
1880          strcpy(Mptr->stnid,stnID);
1881          (*NDEX)++;
1882          return TRUE;
1883       }
1884       else
1885          return FALSE;
1886    }
1887    else
1888       return FALSE;
1889  
1890 }
1891  
1892 /********************************************************************/
1893 /*                                                                  */
1894 /*  Title:         isCodeName                                       */
1895 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1896 /*  Date:          15 Sep 1994                                      */
1897 /*  Programmer:    CARL MCCALLA                                     */
1898 /*  Language:      C/370                                            */
1899 /*                                                                  */
1900 /*  Abstract:                                                       */
1901 /*                                                                  */
1902 /*  External Functions Called:                                      */
1903 /*                 None.                                            */
1904 /*                                                                  */
1905 /*  Input:         x                                                */
1906 /*                                                                  */
1907 /*  Output:        x                                                */
1908 /*                                                                  */
1909 /*  Modification History:                                           */
1910 /*                 None.                                            */
1911 /*                                                                  */
1912 /********************************************************************/
1913  
1914 static bool isCodeName( char *codename, Decoded_METAR *Mptr, int *NDEX)
1915 {
1916    if( codename == NULL )
1917       return FALSE;
1918  
1919    if( strcmp(codename,"METAR") == 0 ||
1920        strcmp(codename,"SPECI") == 0   )
1921    {
1922       strcpy(Mptr->codeName, codename );
1923       (*NDEX)++;
1924       return TRUE;
1925    }
1926    else
1927       return FALSE;
1928  
1929 }
1930  
1931  
1932 /********************************************************************/
1933 /*                                                                  */
1934 /*  Title:         isNIL                                            */
1935 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1936 /*  Date:          15 Sep 1994                                      */
1937 /*  Programmer:    CARL MCCALLA                                     */
1938 /*  Language:      C/370                                            */
1939 /*                                                                  */
1940 /*  Abstract:                                                       */
1941 /*                                                                  */
1942 /*  External Functions Called:                                      */
1943 /*                 None.                                            */
1944 /*                                                                  */
1945 /*  Input:         x                                                */
1946 /*                                                                  */
1947 /*  Output:        x                                                */
1948 /*                                                                  */
1949 /*  Modification History:                                           */
1950 /*                 None.                                            */
1951 /*                                                                  */
1952 /********************************************************************/
1953  
1954 static bool isNIL( char *token, Decoded_METAR *Mptr, int *NDEX)
1955 {
1956  
1957    if( token == NULL )
1958       return FALSE;
1959  
1960    if( strcmp(token, "NIL") == 0 )
1961    {
1962       Mptr->NIL_rpt = TRUE;
1963       (*NDEX)++;
1964       return TRUE;
1965    }
1966    else
1967       return FALSE;
1968  
1969 }
1970  
1971 /********************************************************************/
1972 /*                                                                  */
1973 /*  Title:         isAUTO                                           */
1974 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
1975 /*  Date:          15 Sep 1994                                      */
1976 /*  Programmer:    CARL MCCALLA                                     */
1977 /*  Language:      C/370                                            */
1978 /*                                                                  */
1979 /*  Abstract:                                                       */
1980 /*                                                                  */
1981 /*  External Functions Called:                                      */
1982 /*                 None.                                            */
1983 /*                                                                  */
1984 /*  Input:         x                                                */
1985 /*                                                                  */
1986 /*  Output:        x                                                */
1987 /*                                                                  */
1988 /*  Modification History:                                           */
1989 /*                 None.                                            */
1990 /*                                                                  */
1991 /********************************************************************/
1992  
1993 static bool isAUTO( char *token, Decoded_METAR *Mptr, int *NDEX)
1994 {
1995  
1996    if( token == NULL )
1997       return FALSE;
1998  
1999    if( strcmp(token, "AUTO") == 0 )
2000    {
2001       Mptr->AUTO = TRUE;
2002       (*NDEX)++;
2003       return TRUE;
2004    }
2005    else
2006       return FALSE;
2007  
2008 }
2009  
2010 /********************************************************************/
2011 /*                                                                  */
2012 /*  Title:         isCOR                                            */
2013 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
2014 /*  Date:          24 Apr 1996                                      */
2015 /*  Programmer:    CARL MCCALLA                                     */
2016 /*  Language:      C/370                                            */
2017 /*                                                                  */
2018 /*  Abstract:                                                       */
2019 /*                                                                  */
2020 /*  External Functions Called:                                      */
2021 /*                 None.                                            */
2022 /*                                                                  */
2023 /*  Input:         x                                                */
2024 /*                                                                  */
2025 /*  Output:        x                                                */
2026 /*                                                                  */
2027 /*  Modification History:                                           */
2028 /*                 None.                                            */
2029 /*                                                                  */
2030 /********************************************************************/
2031  
2032 static bool isCOR ( char *token, Decoded_METAR *Mptr, int *NDEX)
2033 {
2034  
2035    if( token == NULL )
2036       return FALSE;
2037  
2038    if( strcmp(token, "COR") == 0 )
2039    {
2040       Mptr->COR  = TRUE;
2041       (*NDEX)++;
2042       return TRUE;
2043    }
2044    else
2045       return FALSE;
2046  
2047 }
2048  
2049 /********************************************************************/
2050 /*                                                                  */
2051 /*  Title:         isTimeUTC                                        */
2052 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
2053 /*  Date:          15 Sep 1994                                      */
2054 /*  Programmer:    CARL MCCALLA                                     */
2055 /*  Language:      C/370                                            */
2056 /*                                                                  */
2057 /*  Abstract:                                                       */
2058 /*                                                                  */
2059 /*  External Functions Called:                                      */
2060 /*                 None.                                            */
2061 /*                                                                  */
2062 /*  Input:         x                                                */
2063 /*                                                                  */
2064 /*  Output:        x                                                */
2065 /*                                                                  */
2066 /*  Modification History:                                           */
2067 /*                 None.                                            */
2068 /*                                                                  */
2069 /********************************************************************/
2070  
2071 static bool isTimeUTC( char *UTC, Decoded_METAR *Mptr, int *NDEX )
2072 {
2073  
2074    if( UTC == NULL )
2075       return FALSE;
2076  
2077    if( strlen( UTC ) == 4 ) {
2078       if(nisdigit(UTC,4) ) {
2079          Mptr->ob_hour = antoi(UTC,2);
2080          Mptr->ob_minute = antoi(UTC+2,2);
2081          (*NDEX)++;
2082          return TRUE;
2083       }
2084       else
2085          return FALSE;
2086    }
2087    else if( strlen( UTC ) == 6 ) {
2088       if(nisdigit(UTC,6) ) {
2089          Mptr->ob_date = antoi(UTC,2);
2090          Mptr->ob_hour = antoi(UTC+2,2);
2091          Mptr->ob_minute = antoi(UTC+4,2);
2092          (*NDEX)++;
2093          return TRUE;
2094       }
2095       else
2096          return FALSE;
2097    }
2098    if( strlen( UTC ) == 5 ) {
2099       if(nisdigit(UTC,4) && (*(UTC+4) == 'Z') ) {
2100          Mptr->ob_hour = antoi(UTC,2);
2101          Mptr->ob_minute = antoi(UTC+2,2);
2102          (*NDEX)++;
2103          return TRUE;
2104       }
2105       else
2106          return FALSE;
2107    }
2108    else if( strlen( UTC ) == 7 ) {
2109       if(nisdigit(UTC,6) && (*(UTC+6) == 'Z') ) {
2110          Mptr->ob_date = antoi(UTC,2);
2111          Mptr->ob_hour = antoi(UTC+2, 2);
2112          Mptr->ob_minute = antoi(UTC+4, 2 );
2113          (*NDEX)++;
2114          return TRUE;
2115       }
2116       else
2117          return FALSE;
2118    }
2119    else
2120       return FALSE;
2121 }
2122  
2123  
2124 /********************************************************************/
2125 /*                                                                  */
2126 /*  Title:         isWindData                                       */
2127 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
2128 /*  Date:          15 Sep 1994                                      */
2129 /*  Programmer:    CARL MCCALLA                                     */
2130 /*  Language:      C/370                                            */
2131 /*                                                                  */
2132 /*  Abstract:                                                       */
2133 /*                                                                  */
2134 /*  External Functions Called:                                      */
2135 /*                 None.                                            */
2136 /*                                                                  */
2137 /*  Input:         x                                                */
2138 /*                                                                  */
2139 /*  Output:        x                                                */
2140 /*                                                                  */
2141 /*  Modification History:                                           */
2142 /*                 None.                                            */
2143 /*                                                                  */
2144 /********************************************************************/
2145  
2146 static bool isWindData( char *wind, Decoded_METAR *Mptr, int *NDEX )
2147 {
2148  
2149    char *GustPtr,
2150         *unitsPtr;
2151    char dummy[8];
2152  
2153    if( wind == NULL )
2154       return FALSE;
2155  
2156    if( strlen(wind) < 7 )
2157       return FALSE;
2158  
2159    memset(dummy,'\0',8);
2160  
2161    if( ( unitsPtr = strstr( wind, "KMH" ) ) != NULL )
2162       strcpy( dummy, "KMH" );
2163    else if( (unitsPtr = strstr( wind, "KT") ) != NULL )
2164       strcpy( dummy, "KT" );
2165    else if( (unitsPtr = strstr( wind, "MPS") ) != NULL )
2166       strcpy( dummy, "MPS" );
2167    else
2168       return FALSE;
2169  
2170    if( (GustPtr = strchr( wind, 'G' )) != NULL )
2171    {
2172       if( (nisdigit(wind,(GustPtr-wind)) ||
2173             (strncmp(wind,"VRB",3) == 0 &&
2174               nisdigit(wind+3,(GustPtr-(wind+3))))) &&
2175             nisdigit(GustPtr+1,(unitsPtr-(GustPtr+1))) &&
2176             ((GustPtr-wind) >= 5 && (GustPtr-wind) <= 6) &&
2177             ((unitsPtr-(GustPtr+1)) >= 2 &&
2178              (unitsPtr-(GustPtr+1)) <= 3) )
2179       {
2180          if( strncmp(wind,"VRB",3) == 0 )
2181             Mptr->winData.windVRB = TRUE;
2182          else
2183             Mptr->winData.windDir = antoi(wind,3);
2184  
2185          Mptr->winData.windSpeed = antoi(wind+3, (GustPtr-(wind+3)));
2186          Mptr->winData.windGust = antoi(GustPtr+1,(unitsPtr-
2187                                                     (GustPtr+1)));
2188          (*NDEX)++;
2189          strcpy( Mptr->winData.windUnits, dummy );
2190          return TRUE;
2191       }
2192       else
2193          return FALSE;
2194    }
2195    else if( nisdigit(wind,(unitsPtr-wind)) ||
2196                 (strncmp(wind,"VRB",3) == 0 &&
2197                   nisdigit(wind+3,(unitsPtr-(wind+3)))) &&
2198             ((unitsPtr-wind) >= 5 && (unitsPtr-wind) <= 6) )
2199    {
2200       if( strncmp(wind,"VRB",3) == 0 )
2201          Mptr->winData.windVRB = TRUE;
2202       else
2203          Mptr->winData.windDir = antoi(wind, 3);
2204  
2205       Mptr->winData.windSpeed = antoi(wind+3,(unitsPtr-(wind+3)));
2206       (*NDEX)++;
2207       strcpy( Mptr->winData.windUnits, dummy );
2208       return TRUE;
2209    }
2210    else
2211       return FALSE;
2212  
2213 }
2214 /********************************************************************/
2215 /*                                                                  */
2216 /*  Title:         DcdMETAR                                         */
2217 /*  Organization:  W/OSO242 - GRAPHICS AND DISPLAY SECTION          */
2218 /*  Date:          14 Sep 1994                                      */
2219 /*  Programmer:    CARL MCCALLA                                     */
2220 /*  Language:      C/370                                            */
2221 /*                                                                  */
2222 /*  Abstract:      DcdMETAR takes a pointer to a METAR report char- */
2223 /*                 acter string as input, decodes the report, and   */
2224 /*                 puts the individual decoded/parsed groups into   */
2225 /*                 a structure that has the variable type           */
2226 /*                 Decoded_METAR.                                   */
2227 /*                                                                  */
2228 /*  Input:         string - a pointer to a METAR report character   */
2229 /*                          string.                                 */
2230 /*                                                                  */
2231 /*  Output:        Mptr   - a pointer to a structure that has the   */
2232 /*                          variable type Decoded_METAR.            */
2233 /*                                                                  */
2234 /*  Modification History:                                           */
2235 /*                 None.                                            */
2236 /*                                                                  */
2237 /********************************************************************/
2238  
2239  
2240 int DcdMETAR( char *string , Decoded_METAR *Mptr )
2241 {
2242  
2243    /***************************/
2244    /* DECLARE LOCAL VARIABLES */
2245    /***************************/
2246  
2247  
2248    enum METAR_obGroup { codename, stnid, NIL1, COR1, obDateTime, NIL2,
2249                         AUTO, COR, windData, MinMaxWinDir,
2250                         CAVOK, visibility,
2251                         RVR, presentWX, PartialObscur,
2252                         skyCond, tempGroup,
2253                         altimStng, NotIDed = 99 }
2254    StartGroup, SaveStartGroup, MetarGroup;
2255  
2256    // WindStruct *WinDataPtr;
2257  
2258    int ndex;
2259    int NDEX;
2260    // int i, jkj, j;
2261  
2262  
2263    char   **token,
2264           *delimeters = {" "};
2265  
2266    bool IS_NOT_RMKS;
2267  
2268 /*********************************/
2269 /* BEGIN THE BODY OF THE ROUTINE */
2270 /*********************************/
2271  
2272    /********************************************************/
2273    /* ONLY PARSE OR DECOCODE NON-NULL METAR REPORT STRINGS */
2274    /********************************************************/
2275  
2276    if( string == NULL )
2277       return 8;
2278  
2279  
2280    /*****************************************/
2281    /*   INITIALIZE STRUCTURE THAT HAS THE   */
2282    /*      VARIABLE TYPE Decoded_METAR      */
2283    /*****************************************/
2284  
2285    InitDcdMETAR( Mptr );
2286  
2287 #ifdef DEBUGZZ
2288    printf("DcdMETAR: Returned from InitDcdMETAR\n");
2289 #endif
2290  
2291  
2292    /****************************************************/
2293    /* TOKENIZE AND STORE THE INPUT METAR REPORT STRING */
2294    /****************************************************/
2295 #ifdef DEBUGZZ
2296    printf("DcdMETAR: Before start of tokenizing, string = %s\n",
2297              string);
2298 #endif
2299  
2300    token = SaveTokenString( string, delimeters );
2301  
2302  
2303  
2304    /*********************************************************/
2305    /* DECODE THE METAR REPORT (POSITIONAL ORDER PRECEDENCE) */
2306    /*********************************************************/
2307  
2308    NDEX = 0;
2309    MetarGroup = codename;
2310    IS_NOT_RMKS = TRUE;
2311  
2312 #ifdef DEBUGZZ
2313 printf("DcdMETAR: token[0] = %s\n",token[0]);
2314 #endif
2315  
2316    while( token[NDEX] != NULL && IS_NOT_RMKS ) {
2317  
2318 #ifdef DEBUGZZ
2319 if( strcmp(token[0],"OPKC") == 0 || strcmp(token[0],"MDSD") == 0 )
2320    printf("DcdMETAR:  token[%d] = %s\n",NDEX,token[NDEX]);
2321 #endif
2322  
2323 #ifdef DEBUGZZ
2324    printf("DcdMETAR: Token[%d] = %s\n",NDEX,token[NDEX]);
2325 #endif
2326 #ifdef DEBUGZZ
2327    printf("DcdMETAR: MetarGroup = %d\n",MetarGroup);
2328 #endif
2329  
2330     if( strcmp( token[NDEX], "RMK" ) != 0 ) {
2331  
2332       StartGroup = NotIDed;
2333  
2334 #ifdef DEBUGZZ
2335    printf("DcdMETAR: StartGroup = %d\n",StartGroup);
2336    printf("DcdMETAR: SaveStartGroup = %d\n",SaveStartGroup);
2337 #endif
2338  
2339       /**********************************************/
2340       /* SET ID_break_CODE TO ITS DEFAULT VALUE OF  */
2341       /* 99, WHICH MEANS THAT NO SUCCESSFUL ATTEMPT */
2342       /* WAS MADE TO DECODE ANY METAR CODED GROUP   */
2343       /* FOR THIS PASS THROUGH THE DECODING LOOP    */
2344       /**********************************************/
2345       switch( MetarGroup ) {
2346          case( codename ):
2347             if( isCodeName( token[NDEX], Mptr, &NDEX ) )
2348                SaveStartGroup = StartGroup = codename;
2349             MetarGroup = stnid;
2350             break;
2351          case( stnid ):
2352             if( isStnId( token[NDEX], Mptr, &NDEX ) ) {
2353                SaveStartGroup = StartGroup = stnid;
2354                MetarGroup = NIL1;
2355             }
2356             else {
2357 #ifdef DEBUGZZ
2358 printf("DcdMETAR:  token[%d] = %s\n",NDEX,token[NDEX]);
2359 #endif
2360                freeTokens( token );
2361                return 12;
2362             }
2363             break;
2364          case( NIL1 ):
2365             if( isNIL( token[NDEX], Mptr, &NDEX ) )
2366                SaveStartGroup = StartGroup = NIL1;
2367             MetarGroup = COR1;
2368             break;
2369          case( COR1 ):
2370             if( isCOR( token[NDEX], Mptr, &NDEX ) )
2371                SaveStartGroup = StartGroup = COR1;
2372             MetarGroup = obDateTime;
2373             break;
2374          case( obDateTime ):
2375 /*
2376             if( isTimeUTC( token[NDEX], Mptr, &NDEX ) ) {
2377                SaveStartGroup = StartGroup = obDateTime;
2378                MetarGroup = NIL2;
2379             }
2380             else {
2381                freeTokens( token );
2382                return 12;
2383             }
2384             break;
2385 */
2386             if( isTimeUTC( token[NDEX], Mptr, &NDEX ) )
2387                SaveStartGroup = StartGroup = obDateTime;
2388             MetarGroup = NIL2;
2389             break;
2390          case( NIL2 ):
2391             if( isNIL( token[NDEX], Mptr, &NDEX ) )
2392                SaveStartGroup = StartGroup = NIL2;
2393             MetarGroup = AUTO;
2394             break;
2395          case( AUTO ):
2396             if( isAUTO( token[NDEX], Mptr, &NDEX ) )
2397                SaveStartGroup = StartGroup = AUTO;
2398             MetarGroup = COR;
2399             break;
2400          case( COR ):
2401             if( isCOR( token[NDEX], Mptr, &NDEX ) )
2402                SaveStartGroup = StartGroup = COR;
2403             MetarGroup = windData;
2404             break;
2405          case( windData ):
2406             if( isWindData( token[NDEX], Mptr, &NDEX ) )
2407                SaveStartGroup = StartGroup = windData;
2408             MetarGroup = MinMaxWinDir;
2409             break;
2410          case( MinMaxWinDir ):
2411             if( isMinMaxWinDir( token[NDEX], Mptr, &NDEX ) )
2412                SaveStartGroup = StartGroup = MinMaxWinDir;
2413             MetarGroup = CAVOK;
2414             break;
2415          case( CAVOK ):
2416             if( isCAVOK( token[NDEX], Mptr, &NDEX ) )
2417                SaveStartGroup = StartGroup = CAVOK;
2418             MetarGroup = visibility;
2419             break;
2420          case( visibility ):
2421             if( isVisibility( &(token[NDEX]), Mptr, &NDEX ) )
2422                SaveStartGroup = StartGroup = visibility;
2423             MetarGroup = RVR;
2424             break;
2425          case( RVR ):
2426             ndex = 0;
2427             MetarGroup = presentWX;
2428  
2429             while (isRVR( token[NDEX], Mptr, &NDEX, ndex ) &&
2430                                ndex < 12 ) {
2431                ndex++;
2432                SaveStartGroup = StartGroup = RVR;
2433                MetarGroup = presentWX;
2434             }
2435             break;
2436          case( presentWX ):
2437             ndex = 0;
2438             MetarGroup = skyCond;
2439  
2440             while( isPresentWX( token[NDEX], Mptr, &NDEX,
2441                           &ndex ) && ndex < MAXWXSYMBOLS) {
2442                SaveStartGroup = StartGroup = presentWX;
2443                MetarGroup = PartialObscur;
2444             }
2445             break;
2446          case( PartialObscur ):
2447             if( isPartObscur( &(token[NDEX]), Mptr, &NDEX ) )
2448                SaveStartGroup = StartGroup = PartialObscur;
2449             MetarGroup = skyCond;
2450             break;
2451          case( skyCond ):
2452             if( isSkyCond( &(token[NDEX]), Mptr, &NDEX ) )
2453                SaveStartGroup = StartGroup = skyCond;
2454             MetarGroup = tempGroup;
2455             break;
2456          case( tempGroup ):
2457             if( isTempGroup( token[NDEX], Mptr, &NDEX ) )
2458                SaveStartGroup = StartGroup = tempGroup;
2459             MetarGroup = altimStng;
2460             break;
2461          case( altimStng ):
2462             if( isAltimStng( token[NDEX], Mptr, &NDEX ) )
2463                SaveStartGroup = StartGroup = altimStng;
2464             MetarGroup = NotIDed;
2465             break;
2466          default:
2467             NDEX++;
2468             MetarGroup = SaveStartGroup;
2469 /*          MetarGroup = ResetMETARGroup( StartGroup,
2470                                           SaveStartGroup );  */
2471             break;
2472       }
2473     }
2474     else
2475       IS_NOT_RMKS = FALSE;
2476  
2477    }
2478  
2479  
2480 #ifdef DEBUGZZ
2481    printf("DcdMETAR:  while loop exited, Token[%d] = %s\n",
2482                   NDEX,token[NDEX]);
2483 #endif
2484                                      /******************************/
2485                                      /* DECODE GROUPS FOUND IN THE */
2486                                      /*  REMARKS SECTION OF THE    */
2487                                      /*       METAR REPORT         */
2488                                      /******************************/
2489  
2490    if( token[NDEX] != NULL )
2491       if( strcmp( token[NDEX], "RMK" ) == 0 )
2492          DcdMTRmk( token, Mptr );
2493  
2494                            /****************************************/
2495    freeTokens( token );    /* FREE THE STORAGE ALLOCATED FOR THE   */
2496                            /* ARRAY USED TO HOLD THE METAR REPORT  */
2497                            /*                GROUPS                */
2498                            /****************************************/
2499    return 0;
2500  
2501 }