static bool parseCFG(HashedSet<HashedPtr<cfg_node> > &roots, std::map<const cfg_node *, _getStoreCFGs::cfgflavour_store_t> &flavours, const char *buf, const char **suffix) { std::map<named_string, cfg_node *> nodes; while (1) { if (!parseNodeDecl(nodes, flavours, buf, &buf)) break; } if (!parseEdgeDecl(nodes, buf, &buf)) return false; if (!parseThisString("Roots:\n", buf, &buf)) return false; while (!parseThisString("End of roots\n", buf, suffix)) { if (!*buf) return false; named_string key; if (!parseWord(&key, buf, &buf) || !parseThisChar('\n', buf, &buf)) return false; if (!nodes.count(key)) return false; roots.insert(nodes[key]); } return true; }
cbool parseSpaceAndComments( parse *p ) { while ( 1 ) { if ( parseThisChar( p, ' ' ) || parseThisChar( p, '\t' ) || parseThisChar( p, '\n' ) ) ; else if ( parseThisString( p, "/*" ) ) while ( !parseThisString( p, "*/" ) && parseAnyChar( p ) ); else if ( parseThisString( p, "//" ) ) while ( !parseThisChar( p, '\n' ) && parseAnyChar( p ) ); else break; } return true; }
static bool parseCfgFlavour(_getStoreCFGs::cfgflavour_store_t *out, const char *buf, const char **suffix) { if (parseThisString("true", buf, suffix)) { *out = _getStoreCFGs::cfgs_flavour_true; return true; } if (parseThisString("dupe", buf, suffix)) { *out = _getStoreCFGs::cfgs_flavour_dupe; return true; } if (parseThisString("ordinary", buf, suffix)) { *out = _getStoreCFGs::cfgs_flavour_ordinary; return true; } return false; }
static void read_cfg_and_depth(HashedSet<HashedPtr<cfg_node> > &roots, std::map<const cfg_node *, _getStoreCFGs::cfgflavour_store_t> &flavours, int *maxDepth, int fd) { char *buf = readfile(fd); const char *suffix; const char *p = buf; if (!parseThisString("depth = ", p, &p) || !parseDecimalInt(maxDepth, p, &p) || !parseThisChar('\n', p, &p) || !parseCFG(roots, flavours, p, &suffix)) errx(1, "cannot parse %s as test specification", buf); if (*suffix) warnx("trailing garbage after cfg: %s", suffix); free(buf); }
static bool parseEdgeDecl(std::map<named_string, cfg_node *> &nodes, const char *buf, const char **suffix) { while (1) { named_string start, end; const char *p; if (!parseWord(&start, buf, &p) || !parseThisString(" -> ", p, &p) || !parseWord(&end, p, &p) || !parseThisChar('\n', p, &buf)) break; cfg_node *s = nodes[start]; cfg_node *e = nodes[end]; if (!s || !e) return false; s->successors.push_back(cfg_node::successor_t::branch(e)); } *suffix = buf; return true; }
//example header line: //723815,"DAGGETT BARSTOW-DAGGETT AP",CA,-8.0,34.850,-116.800,586 int parseLocation(parse *p, Tmy3Location *loc){ return (parseStrExcept(p,",",loc->stationcode,100) && parseThisString(p,",\"") && parseStrExcept(p,"\"",loc->stationname,100) && parseThisString(p,"\",") && parseStrExcept(p,",",loc->state,100) && parseThisString(p,",") && parseDouble(p,&(loc->timezone)) && parseThisString(p,",") && parseDouble(p,&(loc->latitude)) && parseThisString(p,",") && parseDouble(p,&(loc->longitude)) && parseThisString(p,",") && parseDouble(p,&(loc->elevation)) && parseEOL(p) ) || parseError(p,"Error in header line (line 1)") ; }
/** Read a line of data and store in d. @return 0 on success */ int datareader_tmy3_data(DataReader *d){ //CONSOLE_DEBUG("Reading data, i = %d",d->i); unsigned year,month,day,hour,minute; Tmy3Point row; // in the following 'C' are char fiels, 'I' are integer fields; // the suffix 'e' means error/uncertainty and 's' means source of data. #define NUMFIELDS(C,I,X) I(3_EGHI) X I(4_EDNI) \ X I(5_GHI) X C(6_GHIs) X I(7_GHIe) \ X I(8_DNI) X C(9_DNIs) X I(10_DNIe) \ X I(11_DiffHI) X C(12_DiffHIs) X I(13_DiffHIe) \ X I(14_GHIll) X C(15_GHIlls) X I(16_GHIlle) \ X I(17_DNIll) X C(18_DNIlls) X I(19_DNIlle) \ X I(20_DiffHIll) X C(21_DiffHIlls) X I(22_DiffHIlle) \ X I(23_ZenLum) X C(24_ZenLums) X I(25_ZenLume) \ X I(26_TotCov) X C(27_TotCovs) X C(28_TotCove) \ X I(29_OpaqCov) X C(30_OpaqCovs) X C(31_OpenCove) \ X I(32_T) X C(33_Ts) X C(34_Te) \ X I(35_Tdew) X C(36_Tdews) X C(37_Tdewe) \ X I(38_RH) X C(39_RHs) X C(40_RHe) \ X I(41_P) X C(42_Ps) X C(43_Pe) \ X I(44_WD) X C(45_WDs) X C(46_WDe) \ X I(47_WS) X C(48_WSs) X C(49_WSe) \ X I(50_HViz) X C(51_HVizs) X C(52_HVize) \ X I(53_HViz) X C(54_HVizs) X C(55_HVize) \ X I(56_HViz) X C(57_HVizs) X C(58_HVize) \ X I(59_HViz) X C(60_HVizs) X C(61_HVize) \ X I(62_HViz) X C(63_HVizs) X C(64_HVize) \ X I(65_RainDepth) X I(66_RainDuration) X C(67_Rains) X C(68_Raine) #define CHARDECL(NAME) char tmy3_field_##NAME; #define NUMDECL(NAME) double tmy3_field_##NAME; #define NUTHIN_HERE NUMFIELDS(CHARDECL,NUMDECL,NUTHIN_HERE); #undef CHARDECL #undef NUMDECL #undef NUTHIN_HERE // TODO what to do with 'missing' values?? parse *p = DATA(d)->p; #define PARSEINT(NAME) parseDouble(p,&tmy3_field_##NAME) #define PARSECHAR(NAME) parseAChar(p,&tmy3_field_##NAME) #define ANDTHEN && parseThisString(p,",") && // example row: // 01/25/1988,12:00,821,1411,530,1,13,580,1,9,192,1,13,565,1,13,593,1,9,219,1,13,442,1,21,10,A,7,4,A,7,13.3,A,7,-8.9,A,7,21,A,7,960,A,7,60,A,7,3.6,A,7,80500,A,7,77777,A,7,0.5,E,8,0.030,F,8,-9900.000,?,0,-9900,-9900,?,0 if(!( (( /* parse the date and time first... */ parseNumber(p,&month) && parseThisString(p,"/") && parseNumber(p,&day) && parseThisString(p,"/") && parseNumber(p,&year) && parseThisString(p,",") && parseNumber(p,&hour) && parseThisString(p,":") && parseNumber(p,&minute) && parseThisString(p,",") /* then come the data fields */ && NUMFIELDS(PARSECHAR,PARSEINT,ANDTHEN) ) || parseError(p,"Missing/incorrect data field") ) && ( parseEOL(p) || parseError(p,"Expected end-of-line") ) )){ ERROR_REPORTER_HERE(ASC_PROG_ERROR,"Failed to parse E/E data file"); return 1; }; #undef ANDTHEN #undef PARSEINT #undef PARSECHAR /* TODO add check for data for Feb 29... just in case */ // ignore year, so that data sampled from a leap year isn't somehow offset. row.t = ((day_of_year(day,month) - 1)*24.0 + hour)*3600.0 + minute*60.; row.T = tmy3_field_32_T + 273.15 /* convert to K */; row.p = tmy3_field_41_P * 100.; row.rh = tmy3_field_38_RH * 0.01; row.DNI = tmy3_field_8_DNI * 1.; row.GHI = tmy3_field_5_GHI * 1.; row.v_wind = tmy3_field_47_WS * 1.; row.d_wind = tmy3_field_44_WD * 3.14159265358 / 180.; DATA(d)->rows[d->i] = row; //CONSOLE_DEBUG("Read i = %d, t = %f d, T = %.1f°C, rh = %.1f %",d->i,row.t / 3600. / 24., T, row.rh*100); d->i++; return 0; }
cbool parseLexThisString( parse *p, char *s ) { return ( parseSpaceAndComments( p ) && parseThisString( p, s ) ); }