1 #include "Local.h" /* standard header file */
2 #include "Metar.h" /* standard header file */
4 float fracPart( char * );
5 void DcdMTRmk( char **, Decoded_METAR * );
8 /********************************************************************/
10 /* Title: SaveTokenString */
11 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
12 /* Date: 14 Sep 1994 */
13 /* Programmer: CARL MCCALLA */
16 /* Abstract: SaveTokenString tokenizes the input character */
17 /* string based upon the delimeter set supplied */
18 /* by the calling routine. The elements tokenized */
19 /* from the input character string are saved in an */
20 /* array of pointers to characters. The address of */
21 /* this array is the output from this function. */
23 /* Input: string - a pointer to a character string. */
25 /* delimeters - a pointer to a string of 1 or more */
26 /* characters that are used for token- */
27 /* izing the input character string. */
29 /* Output: token - the address of a pointer to an array of */
30 /* pointers to character strings. The */
31 /* array of pointers are the addresses of */
32 /* the character strings that are token- */
33 /* ized from the input character string. */
36 /* Modification History: */
39 /********************************************************************/
41 static char **SaveTokenString ( char *string , char *delimeters )
44 /***************************/
45 /* DECLARE LOCAL VARIABLES */
46 /***************************/
49 static char *token[ MAXTOKENS ],
53 /*********************************/
54 /* BEGIN THE BODY OF THE ROUTINE */
55 /*********************************/
57 /******************************************/
58 /* TOKENIZE THE INPUT CHARACTER STRING */
59 /* AND SAVE THE TOKENS TO THE token ARRAY */
60 /******************************************/
63 TOKEN = strtok( string, delimeters);
68 token[NDEX] = (char *) malloc(sizeof(char)*(strlen(TOKEN)+1));
69 strcpy( token[ NDEX ], TOKEN );
72 while ( token[NDEX] != NULL )
75 TOKEN = strtok( NULL, delimeters );
79 token[NDEX] = (char *)
80 malloc(sizeof(char)*(strlen(TOKEN)+1));
81 strcpy( token[NDEX], TOKEN );
84 token[ NDEX ] = TOKEN;
92 /********************************************************************/
94 /* Title: freeTokens */
95 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
96 /* Date: 14 Sep 1994 */
97 /* Programmer: CARL MCCALLA */
100 /* Abstract: freeTokens frees the storage allocated for the */
101 /* character strings stored in the token array. */
103 /* Input: token - the address of a pointer to an array */
104 /* of string tokens. */
110 /* Modification History: */
113 /********************************************************************/
115 static void freeTokens( char **token )
120 while( *(token+NDEX) != NULL )
122 free( *(token+NDEX) );
127 /********************************************************************/
129 /* Title: InitDcdMETAR */
130 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
131 /* Date: 15 Sep 1994 */
132 /* Programmer: CARL MCCALLA */
133 /* Language: C/370 */
135 /* Abstract: InitDcdMETAR initializes every member of the */
136 /* structure addressed by the pointer Mptr. */
138 /* External Functions Called: */
141 /* Input: Mptr - ptr to a decoded_METAR structure. */
145 /* Modification History: */
148 /********************************************************************/
149 static void InitDcdMETAR( Decoded_METAR *Mptr )
152 /***************************/
153 /* DECLARE LOCAL VARIABLES */
154 /***************************/
162 /*************************/
163 /* START BODY OF ROUTINE */
164 /*************************/
166 memset(Mptr->TS_LOC,'\0',3);
167 memset(Mptr->TS_MOVMNT,'\0',3);
170 memset(Mptr->TornadicType,'\0',15);
171 memset(Mptr->TornadicLOC,'\0',10);
172 memset(Mptr->TornadicDIR,'\0',4);
173 memset(Mptr->TornadicMovDir,'\0',3);
174 Mptr->BTornadicHour = MAXINT;
175 Mptr->BTornadicMinute = MAXINT;
176 Mptr->ETornadicHour = MAXINT;
177 Mptr->ETornadicMinute = MAXINT;
178 Mptr->TornadicDistance = MAXINT;
180 memset( Mptr->autoIndicator,'\0', 5 );
184 Mptr->GR_Size = (float) MAXINT;
187 memset(Mptr->CHINO_LOC, '\0', 6);
190 memset(Mptr->VISNO_LOC, '\0', 6);
194 Mptr->FZRANO = FALSE;
196 Mptr->DollarSign = FALSE;
197 Mptr->hourlyPrecip = (float) MAXINT;
199 Mptr->ObscurAloftHgt = MAXINT;
200 memset(Mptr->ObscurAloft, '\0', 12);
201 memset(Mptr->ObscurAloftSkyCond, '\0', 12);
203 memset(Mptr->VrbSkyBelow, '\0', 4);
204 memset(Mptr->VrbSkyAbove, '\0', 4);
205 Mptr->VrbSkyLayerHgt = MAXINT;
207 Mptr->SectorVsby = (float) MAXINT;
208 memset( Mptr->SectorVsby_Dir, '\0', 3);
210 memset(Mptr->codeName, '\0', 6);
211 memset(Mptr->stnid, '\0', 5);
212 Mptr->ob_hour = MAXINT;
213 Mptr->ob_minute = MAXINT;
214 Mptr->ob_date = MAXINT;
216 memset(Mptr->synoptic_cloud_type, '\0', 6);
218 Mptr->CloudLow = '\0';
219 Mptr->CloudMedium = '\0';
220 Mptr->CloudHigh = '\0';
222 memset(Mptr->snow_depth_group, '\0', 6);
223 Mptr->snow_depth = MAXINT;
225 Mptr->Temp_2_tenths = (float) MAXINT;
226 Mptr->DP_Temp_2_tenths = (float) MAXINT;
228 Mptr->OCNL_LTG = FALSE;
229 Mptr->FRQ_LTG = FALSE;
230 Mptr->CNS_LTG = FALSE;
231 Mptr->CG_LTG = FALSE;
232 Mptr->IC_LTG = FALSE;
233 Mptr->CC_LTG = FALSE;
234 Mptr->CA_LTG = FALSE;
235 Mptr->AP_LTG = FALSE;
236 Mptr->OVHD_LTG = FALSE;
237 Mptr->DSNT_LTG = FALSE;
238 Mptr->VcyStn_LTG = FALSE;
239 Mptr->LightningVCTS = FALSE;
240 Mptr->LightningTS = FALSE;
242 memset( Mptr->LTG_DIR, '\0', 3);
245 for( i = 0; i < 3; i++)
247 memset(Mptr->ReWx[i].Recent_weather, '\0', 5);
249 Mptr->ReWx[i].Bhh = MAXINT;
250 Mptr->ReWx[i].Bmm = MAXINT;
252 Mptr->ReWx[i].Ehh = MAXINT;
253 Mptr->ReWx[i].Emm = MAXINT;
257 Mptr->NIL_rpt = FALSE;
261 Mptr->winData.windDir = MAXINT;
262 Mptr->winData.windSpeed = MAXINT;
263 Mptr->winData.windGust = MAXINT;
264 Mptr->winData.windVRB = FALSE;
265 memset(Mptr->winData.windUnits, '\0', 4);
267 Mptr->minWnDir = MAXINT;
268 Mptr->maxWnDir = MAXINT;
270 memset(Mptr->horiz_vsby, '\0', 5);
271 memset(Mptr->dir_min_horiz_vsby, '\0', 3);
273 Mptr->prevail_vsbySM = (float) MAXINT;
274 Mptr->prevail_vsbyM = (float) MAXINT;
275 Mptr->prevail_vsbyKM = (float) MAXINT;
277 memset(Mptr->vsby_Dir, '\0', 3);
281 for ( i = 0; i < 12; i++ )
283 memset(Mptr->RRVR[ i ].runway_designator,
286 Mptr->RRVR[ i ].visRange = MAXINT;
288 Mptr->RRVR[ i ].vrbl_visRange = FALSE;
289 Mptr->RRVR[ i ].below_min_RVR = FALSE;
290 Mptr->RRVR[ i ].above_max_RVR = FALSE;
293 Mptr->RRVR[ i ].Max_visRange = MAXINT;
294 Mptr->RRVR[ i ].Min_visRange = MAXINT;
297 Mptr->DVR.visRange = MAXINT;
298 Mptr->DVR.vrbl_visRange = FALSE;
299 Mptr->DVR.below_min_DVR = FALSE;
300 Mptr->DVR.above_max_DVR = FALSE;
301 Mptr->DVR.Max_visRange = MAXINT;
302 Mptr->DVR.Min_visRange = MAXINT;
304 for ( i = 0; i < 5; i++ )
306 for( j = 0; j < 8; j++ )
307 Mptr->WxObstruct[i][j] = '\0';
310 /***********************/
311 /* PARTIAL OBSCURATION */
312 /***********************/
314 memset( &(Mptr->PartialObscurationAmt[0][0]), '\0', 7 );
315 memset( &(Mptr->PartialObscurationPhenom[0][0]), '\0',12);
317 memset( &(Mptr->PartialObscurationAmt[1][0]), '\0', 7 );
318 memset( &(Mptr->PartialObscurationPhenom[1][0]), '\0',12);
321 /***************************************************/
322 /* CLOUD TYPE, CLOUD LEVEL, AND SIGNIFICANT CLOUDS */
323 /***************************************************/
326 for ( i = 0; i < 6; i++ )
328 memset(Mptr->cldTypHgt[ i ].cloud_type,
331 memset(Mptr->cldTypHgt[ i ].cloud_hgt_char,
334 Mptr->cldTypHgt[ i ].cloud_hgt_meters = MAXINT;
336 memset(Mptr->cldTypHgt[ i ].other_cld_phenom,
340 Mptr->VertVsby = MAXINT;
343 Mptr->dew_pt_temp = MAXINT;
347 Mptr->SLP = (float) MAXINT;
349 Mptr->A_altstng = FALSE;
350 Mptr->inches_altstng = (double) MAXINT;
352 Mptr->Q_altstng = FALSE;
353 Mptr->hectoPasc_altstng = MAXINT;
355 Mptr->char_prestndcy = MAXINT;
356 Mptr->prestndcy = (float) MAXINT;
358 Mptr->precip_amt = (float) MAXINT;
360 Mptr->precip_24_amt = (float) MAXINT;
361 Mptr->maxtemp = (float) MAXINT;
362 Mptr->mintemp = (float) MAXINT;
363 Mptr->max24temp = (float) MAXINT;
364 Mptr->min24temp = (float) MAXINT;
367 memset( Mptr->VIRGA_DIR, '\0', 3 );
369 Mptr->VOLCASH = FALSE;
371 Mptr->minCeiling = MAXINT;
372 Mptr->maxCeiling = MAXINT;
374 Mptr->CIG_2ndSite_Meters = MAXINT;
375 memset(Mptr->CIG_2ndSite_LOC, '\0', 10 );
377 Mptr->minVsby = (float) MAXINT;
378 Mptr->maxVsby = (float) MAXINT;
379 Mptr->VSBY_2ndSite = (float) MAXINT;
380 memset(Mptr->VSBY_2ndSite_LOC,'\0',10);
382 for( i = 0; i < 6; i++ )
383 memset (&(Mptr->SfcObscuration[i][0]), '\0', 10);
385 Mptr->Num8thsSkyObscured = MAXINT;
387 Mptr->Indeterminant3_6HrPrecip = FALSE;
389 Mptr->Ceiling = MAXINT;
390 Mptr->Estimated_Ceiling = MAXINT;
392 Mptr->NOSPECI = FALSE;
395 Mptr->SNINCR = MAXINT;
396 Mptr->SNINCR_TotalDepth = MAXINT;
398 Mptr->WaterEquivSnow = (float) MAXINT;
400 Mptr->SunshineDur = MAXINT;
401 Mptr->SunSensorOut = FALSE;
404 Mptr->WshfTime_hour = MAXINT;
405 Mptr->WshfTime_minute = MAXINT;
406 Mptr->Wshft_FROPA = FALSE;
407 Mptr->min_vrbl_wind_dir = MAXINT;
408 Mptr->max_vrbl_wind_dir = MAXINT;
410 Mptr->PRESRR = FALSE;
411 Mptr->PRESFR = FALSE;
413 Mptr->TWR_VSBY = (float) MAXINT;
414 Mptr->SFC_VSBY = (float) MAXINT;
416 Mptr->PKWND_dir = MAXINT;
417 Mptr->PKWND_speed = MAXINT;
418 Mptr->PKWND_hour = MAXINT;
419 Mptr->PKWND_minute = MAXINT;
424 /********************************************************************/
426 /* Title: ResetMETARGroup */
427 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
428 /* Date: 15 Sep 1994 */
429 /* Programmer: CARL MCCALLA */
430 /* Language: C/370 */
432 /* Abstract: ResetMETARGroup returns a METAR_obGroup enumerated */
433 /* variable that indicates which METAR reporting group */
434 /* might next appear in the METAR report and should be */
435 /* considered for decoding. */
437 /* External Functions Called: */
440 /* Input: StartGroup - a METAR_obGroup variable that */
441 /* indicates where or on what group */
442 /* METAR Decoding began. */
444 /* SaveStartGroup - a METAR_obGroup variable that */
445 /* indicates the reporting group */
446 /* in the METAR report that was */
447 /* successfully decoded. */
449 /* Output: A METAR_obGroup variable that indicates which */
450 /* reporting group in the METAR report should next */
451 /* be considered for decoding */
453 /* Modification History: */
456 /********************************************************************/
457 /*static int ResetMETARGroup( int StartGroup,
461 enum METAR_obGroup { codename, stnid, NIL1, COR1, obDateTime, NIL2,
462 AUTO, COR, windData, MinMaxWinDir,
464 RVR, presentWX, skyCond, tempGroup,
465 altimStng, NotIDed = 99};
467 if( StartGroup == NotIDed && SaveStartGroup == NotIDed )
469 else if( StartGroup == NotIDed && SaveStartGroup != NotIDed &&
470 SaveStartGroup != altimStng )
471 return (++SaveStartGroup);
473 return (++SaveStartGroup);
478 /********************************************************************/
480 /* Title: CodedHgt2Meters */
481 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
482 /* Date: 15 Sep 1994 */
483 /* Programmer: CARL MCCALLA */
484 /* Language: C/370 */
486 /* Abstract: CodedHgt2Meters converts a coded cloud height into */
489 /* External Functions Called: */
492 /* Input: token - a pointer to a METAR report group. */
493 /* Mptr - a pointer to a decoded_METAR structure. */
495 /* Output: Cloud height in meters */
497 /* Modification History: */
500 /********************************************************************/
502 static int CodedHgt2Meters( char *token, Decoded_METAR *Mptr )
505 static int maxhgt = 30000;
508 if( (hgt = atoi(token)) == 999 )
514 /********************************************************************/
516 /* Title: isPartObscur */
517 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
518 /* Date: 15 Sep 1994 */
519 /* Programmer: CARL MCCALLA */
520 /* Language: C/370 */
522 /* Abstract: isPartObscur determines whether or not the METAR */
523 /* report element that is passed to it is or is not */
524 /* a partial obscuration indicator for an amount of */
528 /* External Functions Called: */
531 /* Input: token - the address of a pointer to the group */
532 /* in the METAR report that isPartObscur */
533 /* determines is or is not a partial */
534 /* obscuration indicator. */
537 /* Mptr - a pointer to a decoded_METAR structure. */
539 /* Output: TRUE, if the group is a partial obscuration */
540 /* indicator and FALSE, if it is not. */
543 /* Modification History: */
546 /********************************************************************/
547 static bool isPartObscur( char **string, Decoded_METAR *Mptr,
551 if( *string == NULL )
554 if( strcmp( *string, "FEW///" ) == 0 ||
555 strcmp( *string, "SCT///" ) == 0 ||
556 strcmp( *string, "BKN///" ) == 0 ||
557 strcmp( *string, "FEW000" ) == 0 ||
558 strcmp( *string, "SCT000" ) == 0 ||
559 strcmp( *string, "BKN000" ) == 0 ) {
560 strcpy( &(Mptr->PartialObscurationAmt[0][0]), *string );
564 if( *string == NULL )
567 if( strcmp( (*string+3), "///") ) {
568 if( strcmp( *string, "FEW000" ) == 0 ||
569 strcmp( *string, "SCT000" ) == 0 ||
570 strcmp( *string, "BKN000" ) == 0 ) {
571 strcpy( &(Mptr->PartialObscurationAmt[1][0]), *string );
576 if( strcmp( *string, "FEW///" ) == 0 ||
577 strcmp( *string, "SCT///" ) == 0 ||
578 strcmp( *string, "BKN///" ) == 0 ) {
579 strcpy( &(Mptr->PartialObscurationAmt[1][0]), *string );
589 /********************************************************************/
591 /* Title: isCldLayer */
592 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
593 /* Date: 15 Sep 1994 */
594 /* Programmer: CARL MCCALLA */
595 /* Language: C/370 */
597 /* Abstract: isCldLayer determines whether or not the */
598 /* current group has a valid cloud layer */
602 /* External Functions Called: */
605 /* Input: token - pointer to a METAR report group. */
607 /* Output: TRUE, if the report group is a valid cloud */
608 /* layer indicator. */
610 /* FALSE, if the report group is not a valid cloud */
611 /* layer indicator. */
614 /* Modification History: */
617 /********************************************************************/
619 static bool isCldLayer( char *token )
624 if( strlen(token) < 6 )
627 return ((strncmp(token,"OVC",3) == 0 ||
628 strncmp(token,"SCT",3) == 0 ||
629 strncmp(token,"FEW",3) == 0 ||
630 strncmp(token,"BKN",3) == 0 ||
632 strncmp(token+1,"CU",2) == 0) ||
634 strncmp(token+1,"SC",2) == 0) ) &&
635 nisdigit((token+3),3)) ? TRUE:FALSE;
638 /********************************************************************/
641 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
642 /* Date: 09 May 1996 */
643 /* Programmer: CARL MCCALLA */
644 /* Language: C/370 */
646 /* Abstract: isCAVOK determines whether or not the current */
647 /* group is a valid CAVOK indicator. */
650 /* External Functions Called: */
653 /* Input: token - pointer to a METAR report group. */
655 /* Output: TRUE, if the input group is a valid CAVOK */
656 /* indicator. FALSE, otherwise. */
660 /* Modification History: */
663 /********************************************************************/
665 static bool isCAVOK( char *token, Decoded_METAR *Mptr, int *NDEX )
671 if( strcmp(token, "CAVOK") != 0 )
680 /********************************************************************/
682 /* Title: parseCldData */
683 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
684 /* Date: 15 Sep 1994 */
685 /* Programmer: CARL MCCALLA */
686 /* Language: C/370 */
690 /* External Functions Called: */
697 /* Modification History: */
700 /********************************************************************/
702 static void parseCldData( char *token, Decoded_METAR *Mptr, int next)
709 if( strlen(token) > 6 )
710 strncpy(Mptr->cldTypHgt[next].other_cld_phenom,token+6,
713 strncpy(Mptr->cldTypHgt[next].cloud_type,token,3);
715 strncpy(Mptr->cldTypHgt[next].cloud_hgt_char,token+3,3);
717 Mptr->cldTypHgt[next].cloud_hgt_meters =
718 CodedHgt2Meters( token+3, Mptr );
724 /********************************************************************/
726 /* Title: isSkyCond */
727 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
728 /* Date: 15 Sep 1994 */
729 /* Programmer: CARL MCCALLA */
730 /* Language: C/370 */
734 /* External Functions Called: */
741 /* Modification History: */
744 /********************************************************************/
745 static bool isSkyCond( char **skycond, Decoded_METAR *Mptr,
757 /********************************************************/
758 /* INTERROGATE skycond TO DETERMINE IF "CLR" IS PRESENT */
759 /********************************************************/
761 if( *skycond == NULL )
765 if( strcmp(*skycond,"CLR") == 0)
767 strcpy(Mptr->cldTypHgt[0].cloud_type,"CLR");
769 memset(Mptr->cldTypHgt[0].cloud_hgt_char,'\0',1);
770 memset(Mptr->cldTypHgt[0].other_cld_phenom,
777 /********************************************************/
778 /* INTERROGATE skycond TO DETERMINE IF "SKC" IS PRESENT */
779 /********************************************************/
781 else if( strcmp(*skycond,"SKC") == 0)
783 strcpy(Mptr->cldTypHgt[0].cloud_type,"SKC");
785 memset(Mptr->cldTypHgt[0].cloud_hgt_char,'\0',1);
786 memset(Mptr->cldTypHgt[0].other_cld_phenom,
793 /****************************************/
794 /* INTERROGATE skycond TO DETERMINE IF */
795 /* VERTICAL VISIBILITY IS PRESENT */
796 /****************************************/
798 else if( strncmp(*skycond,"VV",2) == 0
799 && strlen(*skycond) == 5 &&
800 nisdigit((*skycond+2),3) )
802 Mptr->VertVsby = CodedHgt2Meters( (*skycond+2), Mptr);
807 /****************************************/
808 /* INTERROGATE skycond TO DETERMINE IF */
809 /* CLOUD LAYER DATA IS PRESENT */
810 /****************************************/
812 else if( isCldLayer( *skycond ))
816 parseCldData( *skycond , Mptr, next );
821 if( *skycond == NULL )
824 second_layer = FALSE;
826 fourth_layer = FALSE;
831 if( isCldLayer( *skycond ) && first_layer )
833 parseCldData( *skycond, Mptr, next );
838 if( *skycond == NULL )
843 if( isCldLayer( *skycond ) && first_layer &&
846 parseCldData( *skycond , Mptr, next );
851 if( *skycond == NULL )
856 if( isCldLayer( *skycond ) && first_layer && second_layer &&
859 parseCldData( *skycond, Mptr, next );
864 if( *skycond == NULL )
869 if( isCldLayer( *skycond ) && first_layer && second_layer &&
870 third_layer && fourth_layer )
872 parseCldData( *skycond , Mptr, next );
877 if( *skycond == NULL )
882 if( isCldLayer( *skycond ) && first_layer && second_layer &&
883 third_layer && fourth_layer && fifth_layer )
885 parseCldData( *skycond , Mptr, next );
901 else if( fifth_layer )
910 else if( fourth_layer )
918 else if( third_layer )
925 else if( second_layer )
931 else if( first_layer )
943 /********************************************************************/
945 /* Title: prevailVSBY */
946 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
947 /* Date: 15 Sep 1994 */
948 /* Programmer: CARL MCCALLA */
949 /* Language: C/370 */
953 /* External Functions Called: */
960 /* Modification History: */
963 /********************************************************************/
964 static float prevailVSBY( char *visibility )
974 if( (SM_KM_ptr = strstr( visibility, "SM" )) == NULL )
975 SM_KM_ptr = strstr(visibility, "KM");
977 Slash_ptr = strchr( visibility, '/' );
979 if( Slash_ptr == NULL )
981 temp = (char *) malloc(sizeof(char) *
982 ((SM_KM_ptr - visibility)+1));
983 memset( temp, '\0', (SM_KM_ptr-visibility)+1);
984 strncpy( temp, visibility, (SM_KM_ptr-visibility) );
985 Miles_vsby = (float) (atoi(temp));
991 memset(numerator, '\0', 3);
992 memset(denominator, '\0', 3);
994 strncpy(numerator, visibility, (Slash_ptr - visibility));
996 /*>>>>>>>>>>>>>>>>>>>>>>
997 if( (SM_KM_ptr - (Slash_ptr+1)) == 0 )
998 strcpy(denominator, "4");
1000 <<<<<<<<<<<<<<<<<<<<<<*/
1002 strncpy(denominator,
1003 Slash_ptr+1, (SM_KM_ptr - Slash_ptr));
1005 return ( ((float)(atoi(numerator)))/
1006 ((float)(atoi(denominator))) );
1011 /********************************************************************/
1013 /* Title: isVisibility */
1014 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1015 /* Date: 15 Sep 1994 */
1016 /* Programmer: CARL MCCALLA */
1017 /* Language: C/370 */
1021 /* External Functions Called: */
1028 /* Modification History: */
1031 /********************************************************************/
1034 static bool isVisibility( char **visblty, Decoded_METAR *Mptr,
1042 /****************************************/
1043 /* CHECK FOR VISIBILITY MEASURED <1/4SM */
1044 /****************************************/
1046 if( *visblty == NULL )
1050 if( strcmp(*visblty,"M1/4SM") == 0 ||
1051 strcmp(*visblty,"<1/4SM") == 0 ) {
1052 Mptr->prevail_vsbySM = 0.0;
1057 /***********************************************/
1058 /* CHECK FOR VISIBILITY MEASURED IN KILOMETERS */
1059 /***********************************************/
1061 if( (achar = strstr(*visblty, "KM")) != NULL )
1063 if( nisdigit(*visblty,(achar - *visblty)) &&
1064 (achar - *visblty) > 0 )
1066 Mptr->prevail_vsbyKM = prevailVSBY( *visblty );
1074 /***********************************/
1075 /* CHECK FOR VISIBILITY MEASURED */
1076 /* IN A FRACTION OF A STATUTE MILE */
1077 /***********************************/
1079 else if( (achar = strchr( *visblty, '/' )) !=
1081 (astring = strstr( *visblty, "SM")) != NULL )
1083 if( nisdigit(*visblty,(achar - *visblty))
1085 (achar - *visblty) > 0 &&
1086 (astring - (achar+1)) > 0 &&
1087 nisdigit(achar+1, (astring - (achar+1))) )
1089 Mptr->prevail_vsbySM = prevailVSBY (*visblty);
1097 /***********************************/
1098 /* CHECK FOR VISIBILITY MEASURED */
1099 /* IN WHOLE STATUTE MILES */
1100 /***********************************/
1102 else if( (astring = strstr(*visblty,"SM") ) != NULL )
1104 if( nisdigit(*visblty,(astring - *visblty)) &&
1105 (astring- *visblty) > 0 )
1107 Mptr->prevail_vsbySM = prevailVSBY (*visblty);
1115 /***********************************/
1116 /* CHECK FOR VISIBILITY MEASURED */
1117 /* IN WHOLE AND FRACTIONAL STATUTE */
1119 /***********************************/
1121 else if( nisdigit( *visblty,
1122 strlen(*visblty)) &&
1123 strlen(*visblty) < 4 )
1125 save_token = (char *) malloc(sizeof(char)*
1126 (strlen(*visblty)+1));
1127 strcpy(save_token,*visblty);
1128 if( *(++visblty) == NULL)
1134 if( (achar = strchr( *visblty, '/' ) ) != NULL &&
1135 (astring = strstr( *visblty, "SM") ) != NULL )
1137 if( nisdigit(*visblty,
1138 (achar - *visblty)) &&
1139 (achar - *visblty) > 0 &&
1140 (astring - (achar+1)) > 0 &&
1141 nisdigit(achar+1, (astring - (achar+1))) )
1143 Mptr->prevail_vsbySM = prevailVSBY (*visblty);
1144 Mptr->prevail_vsbySM +=
1145 (float) (atoi(save_token));
1162 /***********************************/
1163 /* CHECK FOR VISIBILITY MEASURED */
1164 /* IN METERS WITH OR WITHOUT DI- */
1165 /* RECTION OF OBSERVATION */
1166 /***********************************/
1168 else if( nisdigit(*visblty,4) &&
1169 strlen(*visblty) >= 4)
1171 if( strcmp(*visblty+4,"NE") == 0 )
1173 memset(Mptr->vsby_Dir,'\0',3);
1174 strcpy(Mptr->vsby_Dir,*visblty+4);
1176 if( strcmp(*visblty+4,"NW") == 0 )
1178 memset(Mptr->vsby_Dir,'\0',3);
1179 strcpy(Mptr->vsby_Dir,*visblty+4);
1181 if( strcmp(*visblty+4,"SE") == 0 )
1183 memset(Mptr->vsby_Dir,'\0',3);
1184 strcpy(Mptr->vsby_Dir,*visblty+4);
1186 if( strcmp(*visblty+4,"SW") == 0 )
1188 memset(Mptr->vsby_Dir,'\0',3);
1189 strcpy(Mptr->vsby_Dir,*visblty+4);
1191 if( strcmp(*visblty+4,"N") == 0 )
1193 memset(Mptr->vsby_Dir,'\0',3);
1194 strcpy(Mptr->vsby_Dir,*visblty+4);
1196 if( strcmp(*visblty+4,"S") == 0 )
1198 memset(Mptr->vsby_Dir,'\0',3);
1199 strcpy(Mptr->vsby_Dir,*visblty+4);
1201 if( strcmp(*visblty+4,"E") == 0 )
1203 memset(Mptr->vsby_Dir,'\0',3);
1204 strcpy(Mptr->vsby_Dir,*visblty+4);
1206 if( strcmp(*visblty+4,"W") == 0 )
1208 memset(Mptr->vsby_Dir,'\0',3);
1209 strcpy(Mptr->vsby_Dir,*visblty+4);
1213 strlen(*visblty)) >= 50 &&
1215 strlen(*visblty)) <= 500 &&
1217 strlen(*visblty)) % 50) == 0 )
1219 Mptr->prevail_vsbyM =
1220 (float) (antoi(*visblty,
1225 else if( antoi(*visblty,
1226 strlen(*visblty)) >= 500 &&
1228 strlen(*visblty)) <= 3000 &&
1230 strlen(*visblty)) % 100) == 0 )
1232 Mptr->prevail_vsbyM =
1233 (float) (antoi(*visblty,
1238 else if( antoi(*visblty,
1239 strlen(*visblty)) >= 3000 &&
1241 strlen(*visblty)) <= 5000 &&
1243 strlen(*visblty)) % 500) == 0 )
1245 Mptr->prevail_vsbyM =
1246 (float) (antoi(*visblty,
1251 else if( antoi(*visblty,
1252 strlen(*visblty)) >= 5000 &&
1254 strlen(*visblty)) <= 9999 &&
1256 strlen(*visblty)) % 500) == 0 ||
1258 strlen(*visblty)) == 9999 )
1260 Mptr->prevail_vsbyM =
1261 (float) (antoi(*visblty,
1275 /********************************************************************/
1277 /* Title: vrblVsby */
1278 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1279 /* Date: 15 Sep 1994 */
1280 /* Programmer: CARL MCCALLA */
1281 /* Language: C/370 */
1285 /* External Functions Called: */
1292 /* Modification History: */
1295 /********************************************************************/
1296 static bool vrblVsby( char *string1, char *string2,
1297 Decoded_METAR *Mptr, int *NDEX )
1306 if( string1 == NULL )
1309 V_char = strchr(string1,'V');
1310 slash = strchr(string1,'/');
1314 if(nisdigit(string1,V_char-string1))
1316 memset(buf, '\0', 6);
1317 strncpy(buf, string1, V_char-string1);
1319 if( Mptr->minVsby != (float) MAXINT )
1320 Mptr->minVsby += (float) atoi(buf);
1322 Mptr->minVsby = (float) atoi(buf);
1324 memset(buf, '\0', 6);
1325 strncpy(buf, V_char+1, 5);
1326 Mptr->maxVsby = (float) atoi(buf);
1334 temp = (char *) malloc(sizeof(char)*((V_char-string1)+1));
1335 memset(temp, '\0', (V_char-string1) +1);
1336 strncpy(temp, string1, V_char-string1);
1337 if( Mptr->minVsby != MAXINT )
1338 Mptr->minVsby += fracPart(temp);
1340 Mptr->minVsby = fracPart(temp);
1344 if( strchr(V_char+1,'/') != NULL)
1345 Mptr->maxVsby = fracPart(V_char+1);
1347 Mptr->maxVsby = (float) atoi(V_char+1);
1350 if( string2 == NULL )
1354 slash = strchr( string2, '/' );
1360 if( nisdigit(string2,slash-string2) &&
1361 nisdigit(slash+1,strlen(slash+1)) )
1363 Mptr->maxVsby += fracPart(string2);
1373 /********************************************************************/
1375 /* Title: isMinMaxWinDir */
1376 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1377 /* Date: 15 Sep 1994 */
1378 /* Programmer: CARL MCCALLA */
1379 /* Language: C/370 */
1383 /* External Functions Called: */
1390 /* Modification History: */
1393 /********************************************************************/
1394 static bool isMinMaxWinDir( char *string, Decoded_METAR *Mptr,
1398 char buf[ buf_len ];
1401 if( string == NULL )
1404 if( (V_char = strchr(string,'V')) == NULL )
1408 if( nisdigit(string,(V_char - string)) &&
1409 nisdigit(V_char+1,3) )
1411 memset( buf, '\0', buf_len);
1412 strncpy( buf, string, V_char - string);
1413 Mptr->minWnDir = atoi( buf );
1415 memset( buf, '\0', buf_len);
1416 strcpy( buf, V_char+1 );
1417 Mptr->maxWnDir = atoi( buf );
1426 /********************************************************************/
1429 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1430 /* Date: 15 Sep 1994 */
1431 /* Programmer: CARL MCCALLA */
1432 /* Language: C/370 */
1436 /* External Functions Called: */
1443 /* Modification History: */
1446 /********************************************************************/
1448 static bool isRVR( char *token, Decoded_METAR *Mptr, int *NDEX,
1451 char *slashPtr, *FT_ptr;
1458 if( *token != 'R' || (length = strlen(token)) < 7 ||
1459 (slashPtr = strchr(token,'/')) == NULL ||
1460 nisdigit(token+1,2) == FALSE )
1463 if( (slashPtr - (token+3)) > 0 )
1464 if( !nisalpha(token+3,(slashPtr - (token+3))) )
1467 if( strcmp(token+(strlen(token)-2),"FT") != 0 )
1470 FT_ptr = token + (strlen(token)-2);
1472 if( strchr(slashPtr+1, 'P' ) != NULL )
1473 Mptr->RRVR[ndex].above_max_RVR = TRUE;
1475 if( strchr(slashPtr+1, 'M' ) != NULL )
1476 Mptr->RRVR[ndex].below_min_RVR = TRUE;
1479 strncpy(Mptr->RRVR[ndex].runway_designator, token+1,
1480 (slashPtr-(token+1)));
1482 if( (vPtr = strchr(slashPtr, 'V' )) != NULL )
1484 Mptr->RRVR[ndex].vrbl_visRange = TRUE;
1485 Mptr->RRVR[ndex].Min_visRange = antoi(slashPtr+1,
1486 (vPtr-(slashPtr+1)) );
1487 Mptr->RRVR[ndex].Max_visRange = antoi(vPtr+1,
1488 (FT_ptr - (vPtr+1)) );
1494 if( Mptr->RRVR[ndex].below_min_RVR ||
1495 Mptr->RRVR[ndex].above_max_RVR )
1496 Mptr->RRVR[ndex].visRange = antoi(slashPtr+2,
1497 (FT_ptr - (slashPtr+2)) );
1499 Mptr->RRVR[ndex].visRange = antoi(slashPtr+1,
1500 (FT_ptr - (slashPtr+1)) );
1509 /********************************************************************/
1511 /* Title: isAltimStng */
1512 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1513 /* Date: 15 Sep 1994 */
1514 /* Programmer: CARL MCCALLA */
1515 /* Language: C/370 */
1519 /* External Functions Called: */
1526 /* Modification History: */
1529 /********************************************************************/
1531 static bool isAltimStng( char *token, Decoded_METAR *Mptr, int *NDEX )
1539 if( strlen(token) < 5 )
1543 Mptr->A_altstng = FALSE;
1544 Mptr->Q_altstng = FALSE;
1546 if( (*token == 'A' || *token == 'Q') &&
1547 (nisdigit(token+1, strlen(token)-1) ||
1548 nisdigit(token+1,strlen(token)-3)) )
1552 Mptr->A_altstng = TRUE;
1553 Mptr->inches_altstng = atof(token+1) * 0.01;
1557 Mptr->Q_altstng = TRUE;
1559 if( strchr(token,'.') != NULL)
1561 memset(dummy, '\0', 6);
1562 strncpy(dummy,token+1,4);
1563 Mptr->hectoPasc_altstng = atoi(dummy);
1566 Mptr->hectoPasc_altstng = atoi(token+1);
1578 /********************************************************************/
1580 /* Title: isTempGroup */
1581 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1582 /* Date: 15 Sep 1994 */
1583 /* Programmer: CARL MCCALLA */
1584 /* Language: C/370 */
1588 /* External Functions Called: */
1595 /* Modification History: */
1598 /********************************************************************/
1600 static bool isTempGroup( char *token, Decoded_METAR *Mptr, int *NDEX)
1603 /***************************/
1604 /* DECLARE LOCAL VARIABLES */
1605 /***************************/
1612 if( (slash = strchr(token,'/')) == NULL)
1616 if( charcmp(token,"aa'/'dd") ) {
1617 Mptr->dew_pt_temp = atoi(slash+1);
1621 else if( charcmp(token,"aa'/''M'dd") ) {
1622 Mptr->dew_pt_temp = atoi(slash+2) * -1;
1626 else if( charcmp(token,"dd'/'aa") ) {
1627 Mptr->temp = antoi(token,(slash-token));
1631 else if( charcmp(token,"'M'dd'/'aa") ) {
1632 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1636 else if( nisdigit(token,(slash-token)) &&
1637 nisdigit(slash+1,strlen(slash+1)) )
1639 Mptr->temp = antoi(token,(slash-token));
1640 Mptr->dew_pt_temp = atoi(slash+1);
1644 else if( *token == 'M' && nisdigit(token+1,(slash-(token+1)))
1645 && *(slash+1) != '\0' &&
1646 *(slash+1) == 'M' && nisdigit(slash+2,strlen(slash+2)) )
1648 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1649 Mptr->dew_pt_temp = atoi(slash+2) * -1;
1653 else if( *token == 'M' && nisdigit(token+1,(slash-(token+1)))
1654 && *(slash+1) != '\0' &&
1655 nisdigit(slash+1,strlen(slash+1)) )
1657 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1658 Mptr->dew_pt_temp = atoi(slash+1);
1662 else if( nisdigit(token,(slash - token)) &&
1663 *(slash+1) != '\0' &&
1664 nisdigit(slash+2,strlen(slash+2)) )
1666 Mptr->temp = antoi(token,(slash-token));
1667 Mptr->dew_pt_temp = atoi(slash+2) * -1;
1671 else if( nisdigit(token,(slash-token)) &&
1674 Mptr->temp = antoi(token,(slash-token));
1678 else if( *token == 'M' &&
1679 nisdigit(token+1,(slash-(token+1))) &&
1682 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1694 /********************************************************************/
1696 /* Title: isWxToken */
1697 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1698 /* Date: 15 Sep 1994 */
1699 /* Programmer: CARL MCCALLA */
1700 /* Language: C/370 */
1704 /* External Functions Called: */
1711 /* Modification History: */
1714 /********************************************************************/
1716 /*static bool isWxToken( char *token )
1722 for( i = 0; i < (int)strlen(token); i++ )
1724 if( !(isalpha(*(token+i)) || *(token+i) == '+' ||
1725 *(token+i) == '-' ) )
1732 /********************************************************************/
1734 /* Title: isPresentWX */
1735 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1736 /* Date: 15 Sep 1994 */
1737 /* Programmer: CARL MCCALLA */
1738 /* Language: C/370 */
1742 /* External Functions Called: */
1749 /* Modification History: */
1752 /********************************************************************/
1754 static bool isPresentWX( char *token, Decoded_METAR *Mptr,
1755 int *NDEX, int *next )
1758 static char *WxSymbols[] = {"BCFG", "BLDU", "BLSA", "BLPY",
1759 "DRDU", "DRSA", "DRSN", "DZ", "DS", "FZFG", "FZDZ", "FZRA",
1760 "FG", "FC", "FU", "GS", "GR", "HZ", "IC", "MIFG",
1761 "PE", "PO", "RA", "SHRA", "SHSN", "SHPE", "SHGS",
1762 "SHGR", "SN", "SG", "SQ", "SA", "SS", "TSRA",
1763 "TSSN", "TSPE", "TSGS", "TSGR", "TS", "VA", "VCFG", "VCFC",
1764 "VCSH", "VCPO", "VCBLDU", "VCBLSA", "VCBLSN", NULL};
1766 static char *WxSymbols[] = {"BCFG", "BLDU", "BLSA", "BLPY",
1767 "BR", "FZBR", "VCBR",
1768 "DRDU", "DRSA", "DRSN", "DZ", "DS", "FZFG", "FZDZ", "FZRA",
1769 "FG", "FC", "FU", "GS", "GR", "HZ", "IC", "MIFG",
1770 "PE", "PO", "RA", "SHRA", "SHSN", "SHPE", "SHGS",
1771 "SHGR", "SN", "SG", "SQ", "SA", "SS", "TS",
1772 "VA", "VCFG", "VCFC",
1773 "VCSH", "VCPO", "VCBLDU", "VCBLSA", "VCBLSN", NULL};
1783 temp_token_orig = temp_token =
1784 (char *) malloc(sizeof(char)*(strlen(token)+1));
1785 strcpy(temp_token, token);
1786 while( temp_token != NULL && (*next) < MAXWXSYMBOLS )
1791 if( *temp_token == '+' || *temp_token == '-' )
1793 save_token = temp_token;
1797 while( WxSymbols[i] != NULL )
1798 if( strncmp(temp_token, WxSymbols[i],
1799 strlen(WxSymbols[i])) != 0 )
1804 if( WxSymbols[i] == NULL ) {
1805 free( temp_token_orig );
1811 if( save_token != NULL )
1813 strncpy( Mptr->WxObstruct[*next], save_token, 1);
1814 strcpy( (Mptr->WxObstruct[*next])+1,
1820 strcpy( Mptr->WxObstruct[*next], WxSymbols[i]);
1825 if( strcmp(temp_token, WxSymbols[i]) != 0)
1827 ptr = strstr(temp_token, WxSymbols[i]);
1828 temp_token = ptr + strlen(WxSymbols[i]);
1832 free( temp_token_orig );
1842 free( temp_token_orig );
1847 /********************************************************************/
1849 /* Title: isStnID */
1850 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1851 /* Date: 15 Sep 1994 */
1852 /* Programmer: CARL MCCALLA */
1853 /* Language: C/370 */
1857 /* External Functions Called: */
1864 /* Modification History: */
1867 /********************************************************************/
1869 static bool isStnId( char *stnID, Decoded_METAR *Mptr, int *NDEX)
1875 if( strlen(stnID) == 4 )
1877 if( nisalpha(stnID,1) && nisalnum(stnID+1,3) ) {
1878 strcpy(Mptr->stnid,stnID);
1890 /********************************************************************/
1892 /* Title: isCodeName */
1893 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1894 /* Date: 15 Sep 1994 */
1895 /* Programmer: CARL MCCALLA */
1896 /* Language: C/370 */
1900 /* External Functions Called: */
1907 /* Modification History: */
1910 /********************************************************************/
1912 static bool isCodeName( char *codename, Decoded_METAR *Mptr, int *NDEX)
1914 if( codename == NULL )
1917 if( strcmp(codename,"METAR") == 0 ||
1918 strcmp(codename,"SPECI") == 0 )
1920 strcpy(Mptr->codeName, codename );
1930 /********************************************************************/
1933 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1934 /* Date: 15 Sep 1994 */
1935 /* Programmer: CARL MCCALLA */
1936 /* Language: C/370 */
1940 /* External Functions Called: */
1947 /* Modification History: */
1950 /********************************************************************/
1952 static bool isNIL( char *token, Decoded_METAR *Mptr, int *NDEX)
1958 if( strcmp(token, "NIL") == 0 )
1960 Mptr->NIL_rpt = TRUE;
1969 /********************************************************************/
1972 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1973 /* Date: 15 Sep 1994 */
1974 /* Programmer: CARL MCCALLA */
1975 /* Language: C/370 */
1979 /* External Functions Called: */
1986 /* Modification History: */
1989 /********************************************************************/
1991 static bool isAUTO( char *token, Decoded_METAR *Mptr, int *NDEX)
1997 if( strcmp(token, "AUTO") == 0 )
2008 /********************************************************************/
2011 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2012 /* Date: 24 Apr 1996 */
2013 /* Programmer: CARL MCCALLA */
2014 /* Language: C/370 */
2018 /* External Functions Called: */
2025 /* Modification History: */
2028 /********************************************************************/
2030 static bool isCOR ( char *token, Decoded_METAR *Mptr, int *NDEX)
2036 if( strcmp(token, "COR") == 0 )
2047 /********************************************************************/
2049 /* Title: isTimeUTC */
2050 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2051 /* Date: 15 Sep 1994 */
2052 /* Programmer: CARL MCCALLA */
2053 /* Language: C/370 */
2057 /* External Functions Called: */
2064 /* Modification History: */
2067 /********************************************************************/
2069 static bool isTimeUTC( char *UTC, Decoded_METAR *Mptr, int *NDEX )
2075 if( strlen( UTC ) == 4 ) {
2076 if(nisdigit(UTC,4) ) {
2077 Mptr->ob_hour = antoi(UTC,2);
2078 Mptr->ob_minute = antoi(UTC+2,2);
2085 else if( strlen( UTC ) == 6 ) {
2086 if(nisdigit(UTC,6) ) {
2087 Mptr->ob_date = antoi(UTC,2);
2088 Mptr->ob_hour = antoi(UTC+2,2);
2089 Mptr->ob_minute = antoi(UTC+4,2);
2096 if( strlen( UTC ) == 5 ) {
2097 if(nisdigit(UTC,4) && (*(UTC+4) == 'Z') ) {
2098 Mptr->ob_hour = antoi(UTC,2);
2099 Mptr->ob_minute = antoi(UTC+2,2);
2106 else if( strlen( UTC ) == 7 ) {
2107 if(nisdigit(UTC,6) && (*(UTC+6) == 'Z') ) {
2108 Mptr->ob_date = antoi(UTC,2);
2109 Mptr->ob_hour = antoi(UTC+2, 2);
2110 Mptr->ob_minute = antoi(UTC+4, 2 );
2122 /********************************************************************/
2124 /* Title: isWindData */
2125 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2126 /* Date: 15 Sep 1994 */
2127 /* Programmer: CARL MCCALLA */
2128 /* Language: C/370 */
2132 /* External Functions Called: */
2139 /* Modification History: */
2142 /********************************************************************/
2144 static bool isWindData( char *wind, Decoded_METAR *Mptr, int *NDEX )
2154 if( strlen(wind) < 7 )
2157 memset(dummy,'\0',8);
2159 if( ( unitsPtr = strstr( wind, "KMH" ) ) != NULL )
2160 strcpy( dummy, "KMH" );
2161 else if( (unitsPtr = strstr( wind, "KT") ) != NULL )
2162 strcpy( dummy, "KT" );
2163 else if( (unitsPtr = strstr( wind, "MPS") ) != NULL )
2164 strcpy( dummy, "MPS" );
2168 if( (GustPtr = strchr( wind, 'G' )) != NULL )
2170 if( (nisdigit(wind,(GustPtr-wind)) ||
2171 (strncmp(wind,"VRB",3) == 0 &&
2172 nisdigit(wind+3,(GustPtr-(wind+3))))) &&
2173 nisdigit(GustPtr+1,(unitsPtr-(GustPtr+1))) &&
2174 ((GustPtr-wind) >= 5 && (GustPtr-wind) <= 6) &&
2175 ((unitsPtr-(GustPtr+1)) >= 2 &&
2176 (unitsPtr-(GustPtr+1)) <= 3) )
2178 if( strncmp(wind,"VRB",3) == 0 )
2179 Mptr->winData.windVRB = TRUE;
2181 Mptr->winData.windDir = antoi(wind,3);
2183 Mptr->winData.windSpeed = antoi(wind+3, (GustPtr-(wind+3)));
2184 Mptr->winData.windGust = antoi(GustPtr+1,(unitsPtr-
2187 strcpy( Mptr->winData.windUnits, dummy );
2193 else if( nisdigit(wind,(unitsPtr-wind)) ||
2194 (strncmp(wind,"VRB",3) == 0 &&
2195 nisdigit(wind+3,(unitsPtr-(wind+3)))) &&
2196 ((unitsPtr-wind) >= 5 && (unitsPtr-wind) <= 6) )
2198 if( strncmp(wind,"VRB",3) == 0 )
2199 Mptr->winData.windVRB = TRUE;
2201 Mptr->winData.windDir = antoi(wind, 3);
2203 Mptr->winData.windSpeed = antoi(wind+3,(unitsPtr-(wind+3)));
2205 strcpy( Mptr->winData.windUnits, dummy );
2212 /********************************************************************/
2214 /* Title: DcdMETAR */
2215 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2216 /* Date: 14 Sep 1994 */
2217 /* Programmer: CARL MCCALLA */
2218 /* Language: C/370 */
2220 /* Abstract: DcdMETAR takes a pointer to a METAR report char- */
2221 /* acter string as input, decodes the report, and */
2222 /* puts the individual decoded/parsed groups into */
2223 /* a structure that has the variable type */
2224 /* Decoded_METAR. */
2226 /* Input: string - a pointer to a METAR report character */
2229 /* Output: Mptr - a pointer to a structure that has the */
2230 /* variable type Decoded_METAR. */
2232 /* Modification History: */
2235 /********************************************************************/
2238 int DcdMETAR( char *string , Decoded_METAR *Mptr )
2241 /***************************/
2242 /* DECLARE LOCAL VARIABLES */
2243 /***************************/
2246 enum METAR_obGroup { codename, stnid, NIL1, COR1, obDateTime, NIL2,
2247 AUTO, COR, windData, MinMaxWinDir,
2249 RVR, presentWX, PartialObscur,
2251 altimStng, NotIDed = 99 }
2252 StartGroup, SaveStartGroup, MetarGroup;
2254 // WindStruct *WinDataPtr;
2262 *delimeters = {" "};
2266 /*********************************/
2267 /* BEGIN THE BODY OF THE ROUTINE */
2268 /*********************************/
2270 /********************************************************/
2271 /* ONLY PARSE OR DECOCODE NON-NULL METAR REPORT STRINGS */
2272 /********************************************************/
2274 if( string == NULL )
2278 /*****************************************/
2279 /* INITIALIZE STRUCTURE THAT HAS THE */
2280 /* VARIABLE TYPE Decoded_METAR */
2281 /*****************************************/
2283 InitDcdMETAR( Mptr );
2286 printf("DcdMETAR: Returned from InitDcdMETAR\n");
2290 /****************************************************/
2291 /* TOKENIZE AND STORE THE INPUT METAR REPORT STRING */
2292 /****************************************************/
2294 printf("DcdMETAR: Before start of tokenizing, string = %s\n",
2298 token = SaveTokenString( string, delimeters );
2302 /*********************************************************/
2303 /* DECODE THE METAR REPORT (POSITIONAL ORDER PRECEDENCE) */
2304 /*********************************************************/
2307 MetarGroup = codename;
2311 printf("DcdMETAR: token[0] = %s\n",token[0]);
2314 while( token[NDEX] != NULL && IS_NOT_RMKS ) {
2317 if( strcmp(token[0],"OPKC") == 0 || strcmp(token[0],"MDSD") == 0 )
2318 printf("DcdMETAR: token[%d] = %s\n",NDEX,token[NDEX]);
2322 printf("DcdMETAR: Token[%d] = %s\n",NDEX,token[NDEX]);
2325 printf("DcdMETAR: MetarGroup = %d\n",MetarGroup);
2328 if( strcmp( token[NDEX], "RMK" ) != 0 ) {
2330 StartGroup = NotIDed;
2333 printf("DcdMETAR: StartGroup = %d\n",StartGroup);
2334 printf("DcdMETAR: SaveStartGroup = %d\n",SaveStartGroup);
2337 /**********************************************/
2338 /* SET ID_break_CODE TO ITS DEFAULT VALUE OF */
2339 /* 99, WHICH MEANS THAT NO SUCCESSFUL ATTEMPT */
2340 /* WAS MADE TO DECODE ANY METAR CODED GROUP */
2341 /* FOR THIS PASS THROUGH THE DECODING LOOP */
2342 /**********************************************/
2343 switch( MetarGroup ) {
2345 if( isCodeName( token[NDEX], Mptr, &NDEX ) )
2346 SaveStartGroup = StartGroup = codename;
2350 if( isStnId( token[NDEX], Mptr, &NDEX ) ) {
2351 SaveStartGroup = StartGroup = stnid;
2356 printf("DcdMETAR: token[%d] = %s\n",NDEX,token[NDEX]);
2358 freeTokens( token );
2363 if( isNIL( token[NDEX], Mptr, &NDEX ) )
2364 SaveStartGroup = StartGroup = NIL1;
2368 if( isCOR( token[NDEX], Mptr, &NDEX ) )
2369 SaveStartGroup = StartGroup = COR1;
2370 MetarGroup = obDateTime;
2374 if( isTimeUTC( token[NDEX], Mptr, &NDEX ) ) {
2375 SaveStartGroup = StartGroup = obDateTime;
2379 freeTokens( token );
2384 if( isTimeUTC( token[NDEX], Mptr, &NDEX ) )
2385 SaveStartGroup = StartGroup = obDateTime;
2389 if( isNIL( token[NDEX], Mptr, &NDEX ) )
2390 SaveStartGroup = StartGroup = NIL2;
2394 if( isAUTO( token[NDEX], Mptr, &NDEX ) )
2395 SaveStartGroup = StartGroup = AUTO;
2399 if( isCOR( token[NDEX], Mptr, &NDEX ) )
2400 SaveStartGroup = StartGroup = COR;
2401 MetarGroup = windData;
2404 if( isWindData( token[NDEX], Mptr, &NDEX ) )
2405 SaveStartGroup = StartGroup = windData;
2406 MetarGroup = MinMaxWinDir;
2408 case( MinMaxWinDir ):
2409 if( isMinMaxWinDir( token[NDEX], Mptr, &NDEX ) )
2410 SaveStartGroup = StartGroup = MinMaxWinDir;
2414 if( isCAVOK( token[NDEX], Mptr, &NDEX ) )
2415 SaveStartGroup = StartGroup = CAVOK;
2416 MetarGroup = visibility;
2419 if( isVisibility( &(token[NDEX]), Mptr, &NDEX ) )
2420 SaveStartGroup = StartGroup = visibility;
2425 MetarGroup = presentWX;
2427 while (isRVR( token[NDEX], Mptr, &NDEX, ndex ) &&
2430 SaveStartGroup = StartGroup = RVR;
2431 MetarGroup = presentWX;
2436 MetarGroup = skyCond;
2438 while( isPresentWX( token[NDEX], Mptr, &NDEX,
2439 &ndex ) && ndex < MAXWXSYMBOLS) {
2440 SaveStartGroup = StartGroup = presentWX;
2441 MetarGroup = PartialObscur;
2444 case( PartialObscur ):
2445 if( isPartObscur( &(token[NDEX]), Mptr, &NDEX ) )
2446 SaveStartGroup = StartGroup = PartialObscur;
2447 MetarGroup = skyCond;
2450 if( isSkyCond( &(token[NDEX]), Mptr, &NDEX ) )
2451 SaveStartGroup = StartGroup = skyCond;
2452 MetarGroup = tempGroup;
2455 if( isTempGroup( token[NDEX], Mptr, &NDEX ) )
2456 SaveStartGroup = StartGroup = tempGroup;
2457 MetarGroup = altimStng;
2460 if( isAltimStng( token[NDEX], Mptr, &NDEX ) )
2461 SaveStartGroup = StartGroup = altimStng;
2462 MetarGroup = NotIDed;
2466 MetarGroup = SaveStartGroup;
2467 /* MetarGroup = ResetMETARGroup( StartGroup,
2468 SaveStartGroup ); */
2473 IS_NOT_RMKS = FALSE;
2479 printf("DcdMETAR: while loop exited, Token[%d] = %s\n",
2482 /******************************/
2483 /* DECODE GROUPS FOUND IN THE */
2484 /* REMARKS SECTION OF THE */
2486 /******************************/
2488 if( token[NDEX] != NULL )
2489 if( strcmp( token[NDEX], "RMK" ) == 0 )
2490 DcdMTRmk( token, Mptr );
2492 /****************************************/
2493 freeTokens( token ); /* FREE THE STORAGE ALLOCATED FOR THE */
2494 /* ARRAY USED TO HOLD THE METAR REPORT */
2496 /****************************************/