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 /********************************************************************/
1297 static bool vrblVsby( char *string1, char *string2,
1298 Decoded_METAR *Mptr, int *NDEX )
1307 if( string1 == NULL )
1310 V_char = strchr(string1,'V');
1311 slash = strchr(string1,'/');
1315 if(nisdigit(string1,V_char-string1))
1317 memset(buf, '\0', 6);
1318 strncpy(buf, string1, V_char-string1);
1320 if( Mptr->minVsby != (float) MAXINT )
1321 Mptr->minVsby += (float) atoi(buf);
1323 Mptr->minVsby = (float) atoi(buf);
1325 memset(buf, '\0', 6);
1326 strncpy(buf, V_char+1, 5);
1327 Mptr->maxVsby = (float) atoi(buf);
1335 temp = (char *) malloc(sizeof(char)*((V_char-string1)+1));
1336 memset(temp, '\0', (V_char-string1) +1);
1337 strncpy(temp, string1, V_char-string1);
1338 if( Mptr->minVsby != MAXINT )
1339 Mptr->minVsby += fracPart(temp);
1341 Mptr->minVsby = fracPart(temp);
1345 if( strchr(V_char+1,'/') != NULL)
1346 Mptr->maxVsby = fracPart(V_char+1);
1348 Mptr->maxVsby = (float) atoi(V_char+1);
1351 if( string2 == NULL )
1355 slash = strchr( string2, '/' );
1361 if( nisdigit(string2,slash-string2) &&
1362 nisdigit(slash+1,strlen(slash+1)) )
1364 Mptr->maxVsby += fracPart(string2);
1375 /********************************************************************/
1377 /* Title: isMinMaxWinDir */
1378 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1379 /* Date: 15 Sep 1994 */
1380 /* Programmer: CARL MCCALLA */
1381 /* Language: C/370 */
1385 /* External Functions Called: */
1392 /* Modification History: */
1395 /********************************************************************/
1396 static bool isMinMaxWinDir( char *string, Decoded_METAR *Mptr,
1400 char buf[ buf_len ];
1403 if( string == NULL )
1406 if( (V_char = strchr(string,'V')) == NULL )
1410 if( nisdigit(string,(V_char - string)) &&
1411 nisdigit(V_char+1,3) )
1413 memset( buf, '\0', buf_len);
1414 strncpy( buf, string, V_char - string);
1415 Mptr->minWnDir = atoi( buf );
1417 memset( buf, '\0', buf_len);
1418 strcpy( buf, V_char+1 );
1419 Mptr->maxWnDir = atoi( buf );
1428 /********************************************************************/
1431 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1432 /* Date: 15 Sep 1994 */
1433 /* Programmer: CARL MCCALLA */
1434 /* Language: C/370 */
1438 /* External Functions Called: */
1445 /* Modification History: */
1448 /********************************************************************/
1450 static bool isRVR( char *token, Decoded_METAR *Mptr, int *NDEX,
1453 char *slashPtr, *FT_ptr;
1460 if( *token != 'R' || (length = strlen(token)) < 7 ||
1461 (slashPtr = strchr(token,'/')) == NULL ||
1462 nisdigit(token+1,2) == FALSE )
1465 if( (slashPtr - (token+3)) > 0 )
1466 if( !nisalpha(token+3,(slashPtr - (token+3))) )
1469 if( strcmp(token+(strlen(token)-2),"FT") != 0 )
1472 FT_ptr = token + (strlen(token)-2);
1474 if( strchr(slashPtr+1, 'P' ) != NULL )
1475 Mptr->RRVR[ndex].above_max_RVR = TRUE;
1477 if( strchr(slashPtr+1, 'M' ) != NULL )
1478 Mptr->RRVR[ndex].below_min_RVR = TRUE;
1481 strncpy(Mptr->RRVR[ndex].runway_designator, token+1,
1482 (slashPtr-(token+1)));
1484 if( (vPtr = strchr(slashPtr, 'V' )) != NULL )
1486 Mptr->RRVR[ndex].vrbl_visRange = TRUE;
1487 Mptr->RRVR[ndex].Min_visRange = antoi(slashPtr+1,
1488 (vPtr-(slashPtr+1)) );
1489 Mptr->RRVR[ndex].Max_visRange = antoi(vPtr+1,
1490 (FT_ptr - (vPtr+1)) );
1496 if( Mptr->RRVR[ndex].below_min_RVR ||
1497 Mptr->RRVR[ndex].above_max_RVR )
1498 Mptr->RRVR[ndex].visRange = antoi(slashPtr+2,
1499 (FT_ptr - (slashPtr+2)) );
1501 Mptr->RRVR[ndex].visRange = antoi(slashPtr+1,
1502 (FT_ptr - (slashPtr+1)) );
1511 /********************************************************************/
1513 /* Title: isAltimStng */
1514 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1515 /* Date: 15 Sep 1994 */
1516 /* Programmer: CARL MCCALLA */
1517 /* Language: C/370 */
1521 /* External Functions Called: */
1528 /* Modification History: */
1531 /********************************************************************/
1533 static bool isAltimStng( char *token, Decoded_METAR *Mptr, int *NDEX )
1541 if( strlen(token) < 5 )
1545 Mptr->A_altstng = FALSE;
1546 Mptr->Q_altstng = FALSE;
1548 if( (*token == 'A' || *token == 'Q') &&
1549 (nisdigit(token+1, strlen(token)-1) ||
1550 nisdigit(token+1,strlen(token)-3)) )
1554 Mptr->A_altstng = TRUE;
1555 Mptr->inches_altstng = atof(token+1) * 0.01;
1559 Mptr->Q_altstng = TRUE;
1561 if( strchr(token,'.') != NULL)
1563 memset(dummy, '\0', 6);
1564 strncpy(dummy,token+1,4);
1565 Mptr->hectoPasc_altstng = atoi(dummy);
1568 Mptr->hectoPasc_altstng = atoi(token+1);
1580 /********************************************************************/
1582 /* Title: isTempGroup */
1583 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1584 /* Date: 15 Sep 1994 */
1585 /* Programmer: CARL MCCALLA */
1586 /* Language: C/370 */
1590 /* External Functions Called: */
1597 /* Modification History: */
1600 /********************************************************************/
1602 static bool isTempGroup( char *token, Decoded_METAR *Mptr, int *NDEX)
1605 /***************************/
1606 /* DECLARE LOCAL VARIABLES */
1607 /***************************/
1614 if( (slash = strchr(token,'/')) == NULL)
1618 if( charcmp(token,"aa'/'dd") ) {
1619 Mptr->dew_pt_temp = atoi(slash+1);
1623 else if( charcmp(token,"aa'/''M'dd") ) {
1624 Mptr->dew_pt_temp = atoi(slash+2) * -1;
1628 else if( charcmp(token,"dd'/'aa") ) {
1629 Mptr->temp = antoi(token,(slash-token));
1633 else if( charcmp(token,"'M'dd'/'aa") ) {
1634 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1638 else if( nisdigit(token,(slash-token)) &&
1639 nisdigit(slash+1,strlen(slash+1)) )
1641 Mptr->temp = antoi(token,(slash-token));
1642 Mptr->dew_pt_temp = atoi(slash+1);
1646 else if( *token == 'M' && nisdigit(token+1,(slash-(token+1)))
1647 && *(slash+1) != '\0' &&
1648 *(slash+1) == 'M' && nisdigit(slash+2,strlen(slash+2)) )
1650 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1651 Mptr->dew_pt_temp = atoi(slash+2) * -1;
1655 else if( *token == 'M' && nisdigit(token+1,(slash-(token+1)))
1656 && *(slash+1) != '\0' &&
1657 nisdigit(slash+1,strlen(slash+1)) )
1659 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1660 Mptr->dew_pt_temp = atoi(slash+1);
1664 else if( nisdigit(token,(slash - token)) &&
1665 *(slash+1) != '\0' &&
1666 nisdigit(slash+2,strlen(slash+2)) )
1668 Mptr->temp = antoi(token,(slash-token));
1669 Mptr->dew_pt_temp = atoi(slash+2) * -1;
1673 else if( nisdigit(token,(slash-token)) &&
1676 Mptr->temp = antoi(token,(slash-token));
1680 else if( *token == 'M' &&
1681 nisdigit(token+1,(slash-(token+1))) &&
1684 Mptr->temp = antoi(token+1,(slash-(token+1))) * -1;
1696 /********************************************************************/
1698 /* Title: isWxToken */
1699 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1700 /* Date: 15 Sep 1994 */
1701 /* Programmer: CARL MCCALLA */
1702 /* Language: C/370 */
1706 /* External Functions Called: */
1713 /* Modification History: */
1716 /********************************************************************/
1718 /*static bool isWxToken( char *token )
1724 for( i = 0; i < (int)strlen(token); i++ )
1726 if( !(isalpha(*(token+i)) || *(token+i) == '+' ||
1727 *(token+i) == '-' ) )
1734 /********************************************************************/
1736 /* Title: isPresentWX */
1737 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1738 /* Date: 15 Sep 1994 */
1739 /* Programmer: CARL MCCALLA */
1740 /* Language: C/370 */
1744 /* External Functions Called: */
1751 /* Modification History: */
1754 /********************************************************************/
1756 static bool isPresentWX( char *token, Decoded_METAR *Mptr,
1757 int *NDEX, int *next )
1760 static char *WxSymbols[] = {"BCFG", "BLDU", "BLSA", "BLPY",
1761 "DRDU", "DRSA", "DRSN", "DZ", "DS", "FZFG", "FZDZ", "FZRA",
1762 "FG", "FC", "FU", "GS", "GR", "HZ", "IC", "MIFG",
1763 "PE", "PO", "RA", "SHRA", "SHSN", "SHPE", "SHGS",
1764 "SHGR", "SN", "SG", "SQ", "SA", "SS", "TSRA",
1765 "TSSN", "TSPE", "TSGS", "TSGR", "TS", "VA", "VCFG", "VCFC",
1766 "VCSH", "VCPO", "VCBLDU", "VCBLSA", "VCBLSN", NULL};
1768 static char *WxSymbols[] = {"BCFG", "BLDU", "BLSA", "BLPY",
1769 "BR", "FZBR", "VCBR",
1770 "DRDU", "DRSA", "DRSN", "DZ", "DS", "FZFG", "FZDZ", "FZRA",
1771 "FG", "FC", "FU", "GS", "GR", "HZ", "IC", "MIFG",
1772 "PE", "PO", "RA", "SHRA", "SHSN", "SHPE", "SHGS",
1773 "SHGR", "SN", "SG", "SQ", "SA", "SS", "TS",
1774 "VA", "VCFG", "VCFC",
1775 "VCSH", "VCPO", "VCBLDU", "VCBLSA", "VCBLSN", NULL};
1785 temp_token_orig = temp_token =
1786 (char *) malloc(sizeof(char)*(strlen(token)+1));
1787 strcpy(temp_token, token);
1788 while( temp_token != NULL && (*next) < MAXWXSYMBOLS )
1793 if( *temp_token == '+' || *temp_token == '-' )
1795 save_token = temp_token;
1799 while( WxSymbols[i] != NULL )
1800 if( strncmp(temp_token, WxSymbols[i],
1801 strlen(WxSymbols[i])) != 0 )
1806 if( WxSymbols[i] == NULL ) {
1807 free( temp_token_orig );
1813 if( save_token != NULL )
1815 strncpy( Mptr->WxObstruct[*next], save_token, 1);
1816 strcpy( (Mptr->WxObstruct[*next])+1,
1822 strcpy( Mptr->WxObstruct[*next], WxSymbols[i]);
1827 if( strcmp(temp_token, WxSymbols[i]) != 0)
1829 ptr = strstr(temp_token, WxSymbols[i]);
1830 temp_token = ptr + strlen(WxSymbols[i]);
1834 free( temp_token_orig );
1844 free( temp_token_orig );
1849 /********************************************************************/
1851 /* Title: isStnID */
1852 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1853 /* Date: 15 Sep 1994 */
1854 /* Programmer: CARL MCCALLA */
1855 /* Language: C/370 */
1859 /* External Functions Called: */
1866 /* Modification History: */
1869 /********************************************************************/
1871 static bool isStnId( char *stnID, Decoded_METAR *Mptr, int *NDEX)
1877 if( strlen(stnID) == 4 )
1879 if( nisalpha(stnID,1) && nisalnum(stnID+1,3) ) {
1880 strcpy(Mptr->stnid,stnID);
1892 /********************************************************************/
1894 /* Title: isCodeName */
1895 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1896 /* Date: 15 Sep 1994 */
1897 /* Programmer: CARL MCCALLA */
1898 /* Language: C/370 */
1902 /* External Functions Called: */
1909 /* Modification History: */
1912 /********************************************************************/
1914 static bool isCodeName( char *codename, Decoded_METAR *Mptr, int *NDEX)
1916 if( codename == NULL )
1919 if( strcmp(codename,"METAR") == 0 ||
1920 strcmp(codename,"SPECI") == 0 )
1922 strcpy(Mptr->codeName, codename );
1932 /********************************************************************/
1935 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1936 /* Date: 15 Sep 1994 */
1937 /* Programmer: CARL MCCALLA */
1938 /* Language: C/370 */
1942 /* External Functions Called: */
1949 /* Modification History: */
1952 /********************************************************************/
1954 static bool isNIL( char *token, Decoded_METAR *Mptr, int *NDEX)
1960 if( strcmp(token, "NIL") == 0 )
1962 Mptr->NIL_rpt = TRUE;
1971 /********************************************************************/
1974 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
1975 /* Date: 15 Sep 1994 */
1976 /* Programmer: CARL MCCALLA */
1977 /* Language: C/370 */
1981 /* External Functions Called: */
1988 /* Modification History: */
1991 /********************************************************************/
1993 static bool isAUTO( char *token, Decoded_METAR *Mptr, int *NDEX)
1999 if( strcmp(token, "AUTO") == 0 )
2010 /********************************************************************/
2013 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2014 /* Date: 24 Apr 1996 */
2015 /* Programmer: CARL MCCALLA */
2016 /* Language: C/370 */
2020 /* External Functions Called: */
2027 /* Modification History: */
2030 /********************************************************************/
2032 static bool isCOR ( char *token, Decoded_METAR *Mptr, int *NDEX)
2038 if( strcmp(token, "COR") == 0 )
2049 /********************************************************************/
2051 /* Title: isTimeUTC */
2052 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2053 /* Date: 15 Sep 1994 */
2054 /* Programmer: CARL MCCALLA */
2055 /* Language: C/370 */
2059 /* External Functions Called: */
2066 /* Modification History: */
2069 /********************************************************************/
2071 static bool isTimeUTC( char *UTC, Decoded_METAR *Mptr, int *NDEX )
2077 if( strlen( UTC ) == 4 ) {
2078 if(nisdigit(UTC,4) ) {
2079 Mptr->ob_hour = antoi(UTC,2);
2080 Mptr->ob_minute = antoi(UTC+2,2);
2087 else if( strlen( UTC ) == 6 ) {
2088 if(nisdigit(UTC,6) ) {
2089 Mptr->ob_date = antoi(UTC,2);
2090 Mptr->ob_hour = antoi(UTC+2,2);
2091 Mptr->ob_minute = antoi(UTC+4,2);
2098 if( strlen( UTC ) == 5 ) {
2099 if(nisdigit(UTC,4) && (*(UTC+4) == 'Z') ) {
2100 Mptr->ob_hour = antoi(UTC,2);
2101 Mptr->ob_minute = antoi(UTC+2,2);
2108 else if( strlen( UTC ) == 7 ) {
2109 if(nisdigit(UTC,6) && (*(UTC+6) == 'Z') ) {
2110 Mptr->ob_date = antoi(UTC,2);
2111 Mptr->ob_hour = antoi(UTC+2, 2);
2112 Mptr->ob_minute = antoi(UTC+4, 2 );
2124 /********************************************************************/
2126 /* Title: isWindData */
2127 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2128 /* Date: 15 Sep 1994 */
2129 /* Programmer: CARL MCCALLA */
2130 /* Language: C/370 */
2134 /* External Functions Called: */
2141 /* Modification History: */
2144 /********************************************************************/
2146 static bool isWindData( char *wind, Decoded_METAR *Mptr, int *NDEX )
2156 if( strlen(wind) < 7 )
2159 memset(dummy,'\0',8);
2161 if( ( unitsPtr = strstr( wind, "KMH" ) ) != NULL )
2162 strcpy( dummy, "KMH" );
2163 else if( (unitsPtr = strstr( wind, "KT") ) != NULL )
2164 strcpy( dummy, "KT" );
2165 else if( (unitsPtr = strstr( wind, "MPS") ) != NULL )
2166 strcpy( dummy, "MPS" );
2170 if( (GustPtr = strchr( wind, 'G' )) != NULL )
2172 if( (nisdigit(wind,(GustPtr-wind)) ||
2173 (strncmp(wind,"VRB",3) == 0 &&
2174 nisdigit(wind+3,(GustPtr-(wind+3))))) &&
2175 nisdigit(GustPtr+1,(unitsPtr-(GustPtr+1))) &&
2176 ((GustPtr-wind) >= 5 && (GustPtr-wind) <= 6) &&
2177 ((unitsPtr-(GustPtr+1)) >= 2 &&
2178 (unitsPtr-(GustPtr+1)) <= 3) )
2180 if( strncmp(wind,"VRB",3) == 0 )
2181 Mptr->winData.windVRB = TRUE;
2183 Mptr->winData.windDir = antoi(wind,3);
2185 Mptr->winData.windSpeed = antoi(wind+3, (GustPtr-(wind+3)));
2186 Mptr->winData.windGust = antoi(GustPtr+1,(unitsPtr-
2189 strcpy( Mptr->winData.windUnits, dummy );
2195 else if( nisdigit(wind,(unitsPtr-wind)) ||
2196 (strncmp(wind,"VRB",3) == 0 &&
2197 nisdigit(wind+3,(unitsPtr-(wind+3)))) &&
2198 ((unitsPtr-wind) >= 5 && (unitsPtr-wind) <= 6) )
2200 if( strncmp(wind,"VRB",3) == 0 )
2201 Mptr->winData.windVRB = TRUE;
2203 Mptr->winData.windDir = antoi(wind, 3);
2205 Mptr->winData.windSpeed = antoi(wind+3,(unitsPtr-(wind+3)));
2207 strcpy( Mptr->winData.windUnits, dummy );
2214 /********************************************************************/
2216 /* Title: DcdMETAR */
2217 /* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
2218 /* Date: 14 Sep 1994 */
2219 /* Programmer: CARL MCCALLA */
2220 /* Language: C/370 */
2222 /* Abstract: DcdMETAR takes a pointer to a METAR report char- */
2223 /* acter string as input, decodes the report, and */
2224 /* puts the individual decoded/parsed groups into */
2225 /* a structure that has the variable type */
2226 /* Decoded_METAR. */
2228 /* Input: string - a pointer to a METAR report character */
2231 /* Output: Mptr - a pointer to a structure that has the */
2232 /* variable type Decoded_METAR. */
2234 /* Modification History: */
2237 /********************************************************************/
2240 int DcdMETAR( char *string , Decoded_METAR *Mptr )
2243 /***************************/
2244 /* DECLARE LOCAL VARIABLES */
2245 /***************************/
2248 enum METAR_obGroup { codename, stnid, NIL1, COR1, obDateTime, NIL2,
2249 AUTO, COR, windData, MinMaxWinDir,
2251 RVR, presentWX, PartialObscur,
2253 altimStng, NotIDed = 99 }
2254 StartGroup, SaveStartGroup, MetarGroup;
2256 // WindStruct *WinDataPtr;
2264 *delimeters = {" "};
2268 /*********************************/
2269 /* BEGIN THE BODY OF THE ROUTINE */
2270 /*********************************/
2272 /********************************************************/
2273 /* ONLY PARSE OR DECOCODE NON-NULL METAR REPORT STRINGS */
2274 /********************************************************/
2276 if( string == NULL )
2280 /*****************************************/
2281 /* INITIALIZE STRUCTURE THAT HAS THE */
2282 /* VARIABLE TYPE Decoded_METAR */
2283 /*****************************************/
2285 InitDcdMETAR( Mptr );
2288 printf("DcdMETAR: Returned from InitDcdMETAR\n");
2292 /****************************************************/
2293 /* TOKENIZE AND STORE THE INPUT METAR REPORT STRING */
2294 /****************************************************/
2296 printf("DcdMETAR: Before start of tokenizing, string = %s\n",
2300 token = SaveTokenString( string, delimeters );
2304 /*********************************************************/
2305 /* DECODE THE METAR REPORT (POSITIONAL ORDER PRECEDENCE) */
2306 /*********************************************************/
2309 MetarGroup = codename;
2313 printf("DcdMETAR: token[0] = %s\n",token[0]);
2316 while( token[NDEX] != NULL && IS_NOT_RMKS ) {
2319 if( strcmp(token[0],"OPKC") == 0 || strcmp(token[0],"MDSD") == 0 )
2320 printf("DcdMETAR: token[%d] = %s\n",NDEX,token[NDEX]);
2324 printf("DcdMETAR: Token[%d] = %s\n",NDEX,token[NDEX]);
2327 printf("DcdMETAR: MetarGroup = %d\n",MetarGroup);
2330 if( strcmp( token[NDEX], "RMK" ) != 0 ) {
2332 StartGroup = NotIDed;
2335 printf("DcdMETAR: StartGroup = %d\n",StartGroup);
2336 printf("DcdMETAR: SaveStartGroup = %d\n",SaveStartGroup);
2339 /**********************************************/
2340 /* SET ID_break_CODE TO ITS DEFAULT VALUE OF */
2341 /* 99, WHICH MEANS THAT NO SUCCESSFUL ATTEMPT */
2342 /* WAS MADE TO DECODE ANY METAR CODED GROUP */
2343 /* FOR THIS PASS THROUGH THE DECODING LOOP */
2344 /**********************************************/
2345 switch( MetarGroup ) {
2347 if( isCodeName( token[NDEX], Mptr, &NDEX ) )
2348 SaveStartGroup = StartGroup = codename;
2352 if( isStnId( token[NDEX], Mptr, &NDEX ) ) {
2353 SaveStartGroup = StartGroup = stnid;
2358 printf("DcdMETAR: token[%d] = %s\n",NDEX,token[NDEX]);
2360 freeTokens( token );
2365 if( isNIL( token[NDEX], Mptr, &NDEX ) )
2366 SaveStartGroup = StartGroup = NIL1;
2370 if( isCOR( token[NDEX], Mptr, &NDEX ) )
2371 SaveStartGroup = StartGroup = COR1;
2372 MetarGroup = obDateTime;
2376 if( isTimeUTC( token[NDEX], Mptr, &NDEX ) ) {
2377 SaveStartGroup = StartGroup = obDateTime;
2381 freeTokens( token );
2386 if( isTimeUTC( token[NDEX], Mptr, &NDEX ) )
2387 SaveStartGroup = StartGroup = obDateTime;
2391 if( isNIL( token[NDEX], Mptr, &NDEX ) )
2392 SaveStartGroup = StartGroup = NIL2;
2396 if( isAUTO( token[NDEX], Mptr, &NDEX ) )
2397 SaveStartGroup = StartGroup = AUTO;
2401 if( isCOR( token[NDEX], Mptr, &NDEX ) )
2402 SaveStartGroup = StartGroup = COR;
2403 MetarGroup = windData;
2406 if( isWindData( token[NDEX], Mptr, &NDEX ) )
2407 SaveStartGroup = StartGroup = windData;
2408 MetarGroup = MinMaxWinDir;
2410 case( MinMaxWinDir ):
2411 if( isMinMaxWinDir( token[NDEX], Mptr, &NDEX ) )
2412 SaveStartGroup = StartGroup = MinMaxWinDir;
2416 if( isCAVOK( token[NDEX], Mptr, &NDEX ) )
2417 SaveStartGroup = StartGroup = CAVOK;
2418 MetarGroup = visibility;
2421 if( isVisibility( &(token[NDEX]), Mptr, &NDEX ) )
2422 SaveStartGroup = StartGroup = visibility;
2427 MetarGroup = presentWX;
2429 while (isRVR( token[NDEX], Mptr, &NDEX, ndex ) &&
2432 SaveStartGroup = StartGroup = RVR;
2433 MetarGroup = presentWX;
2438 MetarGroup = skyCond;
2440 while( isPresentWX( token[NDEX], Mptr, &NDEX,
2441 &ndex ) && ndex < MAXWXSYMBOLS) {
2442 SaveStartGroup = StartGroup = presentWX;
2443 MetarGroup = PartialObscur;
2446 case( PartialObscur ):
2447 if( isPartObscur( &(token[NDEX]), Mptr, &NDEX ) )
2448 SaveStartGroup = StartGroup = PartialObscur;
2449 MetarGroup = skyCond;
2452 if( isSkyCond( &(token[NDEX]), Mptr, &NDEX ) )
2453 SaveStartGroup = StartGroup = skyCond;
2454 MetarGroup = tempGroup;
2457 if( isTempGroup( token[NDEX], Mptr, &NDEX ) )
2458 SaveStartGroup = StartGroup = tempGroup;
2459 MetarGroup = altimStng;
2462 if( isAltimStng( token[NDEX], Mptr, &NDEX ) )
2463 SaveStartGroup = StartGroup = altimStng;
2464 MetarGroup = NotIDed;
2468 MetarGroup = SaveStartGroup;
2469 /* MetarGroup = ResetMETARGroup( StartGroup,
2470 SaveStartGroup ); */
2475 IS_NOT_RMKS = FALSE;
2481 printf("DcdMETAR: while loop exited, Token[%d] = %s\n",
2484 /******************************/
2485 /* DECODE GROUPS FOUND IN THE */
2486 /* REMARKS SECTION OF THE */
2488 /******************************/
2490 if( token[NDEX] != NULL )
2491 if( strcmp( token[NDEX], "RMK" ) == 0 )
2492 DcdMTRmk( token, Mptr );
2494 /****************************************/
2495 freeTokens( token ); /* FREE THE STORAGE ALLOCATED FOR THE */
2496 /* ARRAY USED TO HOLD THE METAR REPORT */
2498 /****************************************/