period_type get_period(stream_itr_type& sitr, stream_itr_type& stream_end, std::ios_base& a_ios, const period_type& p, const duration_type& dur_unit, const facet_type& facet) const { // skip leading whitespace while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } typedef typename period_type::point_type point_type; point_type p1(not_a_date_time), p2(not_a_date_time); consume_delim(sitr, stream_end, delimiters[START]); // start delim facet.get(sitr, stream_end, a_ios, p1); // first point consume_delim(sitr, stream_end, delimiters[SEPARATOR]); // separator facet.get(sitr, stream_end, a_ios, p2); // second point // period construction parameters are always open range [begin, end) if (m_range_option == AS_CLOSED_RANGE) { consume_delim(sitr, stream_end, delimiters[CLOSED_END]);// end delim // add 1 duration unit to p2 to make range open p2 += dur_unit; } else { consume_delim(sitr, stream_end, delimiters[OPEN_END]); // end delim } return period_type(p1, p2); }
static int read_cache_file(int fd, struct cache_entry **cache_entries, size_t *num_cache_entries) { struct stat st; int rc; char const *cfg = NULL; char const *ptr; char const *end_ptr; bool in_comment = false; enum { ST_MAJOR, ST_MINOR, ST_ALIAS, ST_SYSFS, ST_IDX } state = ST_MAJOR; struct cache_entry *entry = NULL; size_t alloc_entries = 0; *cache_entries = NULL; *num_cache_entries = 0; if (fstat(fd, &st) < 0) { perror("fstat()"); rc = -EX_OSERR; goto err; } cfg = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (!cfg) { perror("mmap()"); rc = -EX_OSERR; goto err; }; ptr = cfg; end_ptr = cfg + st.st_size; while (ptr < cfg + st.st_size) { if (alloc_entries <= *num_cache_entries) { struct cache_entry *tmp; alloc_entries = alloc_entries * 3/2 + 10; tmp = realloc(*cache_entries, sizeof *tmp * alloc_entries); if (!tmp) { perror("realloc(<cache_entries>)"); rc = -EX_OSERR; goto err; } *cache_entries = tmp; entry = (void *)0xdeadbeaf; } if (in_comment) { if (*ptr == '\n') in_comment = false; ++ptr; } else if (*ptr == '#') { in_comment = true; ++ptr; } else { unsigned int dummy; switch (state) { case ST_MAJOR: entry = &(*cache_entries)[*num_cache_entries]; entry->have_stats = 0; if (memchr(ptr, '\n', end_ptr - ptr) == NULL) { fprintf(stderr, "invalid cache entry"); rc = -EX_SOFTWARE; goto err; } rc = consume_uint(&dummy, &ptr, "major"); break; case ST_MINOR: rc = consume_uint(&dummy, &ptr, "minor"); break; case ST_IDX: rc = consume_uint(&entry->idx, &ptr, "idx"); break; case ST_ALIAS: rc = consume_str(&entry->alias, &ptr, end_ptr, "alias"); break; case ST_SYSFS: rc = consume_str(&entry->sysfs, &ptr, end_ptr, "sysfs"); break; default: abort(); } if (rc >= 0) rc = consume_delim(&ptr, (state == ST_IDX) ? '\n' : ' '); if (rc < 0) goto err; else if (state == ST_IDX) { state = ST_MAJOR; ++*num_cache_entries; } else ++state; } } if (state != ST_MAJOR) { fprintf(stderr, "incomplete cache entry\n"); rc = -EX_SOFTWARE; goto err; } munmap((void *)cfg, st.st_size); qsort(*cache_entries, *num_cache_entries, sizeof (*cache_entries)[0], cache_entry_cmp); return 0; err: free(*cache_entries); if (cfg) munmap((void *)cfg, st.st_size); return rc; }