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