std::set SysInfo::str_to_cpu_set()

in src/sys_info.cc [28:97]


	std::set<unsigned int> SysInfo::str_to_cpu_set(const char * s) {

		std::set<unsigned int> ret;

		if (!s) return ret;

		// pointer into the string
		const char * ptr = const_cast<char*>(s);

		// fields for denoting a range of cpus
		unsigned int curr, next;

		char * endptr;

		// we'll loop as long as there are fields left denoting active cpus (comma separated)
		while (1) {

			// stop if we reach an invalid field
			if (*ptr < '0' || *ptr > '9') break;

			// get an integer
			curr = strtoul(ptr, &endptr, 10);

			// check for strtoul error
			if (curr == std::numeric_limits<unsigned int>::max()) {
				fprintf(stderr, "Invalid cpu set \"%s\"", s);
				exit(1);
			}

			// advance past this number
			ptr = endptr;

			// if there's a dash, it means this field specifies a range of cpus
			if (*ptr == '-') {
				// get the next number after the '-' and advance past it
				++ptr;

				// stop if we reach an invalid field
				if (*ptr < '0' || *ptr > '9') break;

				next = strtoul(ptr, &endptr, 10);

				// check for strtoul error
				if (next == std::numeric_limits<unsigned int>::max()) {
					fprintf(stderr, "Invalid cpu set \"%s\"", s);
					exit(1);
				}

				// advance past this number
				ptr = endptr;

			// otherwise, only one cpu in this field
			} else {
				next = curr;
			}

			// insert the range of cpu numbers [curr,next] into the set
			for (int i = curr; i <= next; ++i) {
				ret.insert(i);
			}

			// we're done if there are no more number fields (which are ',' separated)
			if (*ptr != ',') break;

			// otherwise increment the pointer past the comma to the next field
			++ptr;
		}

		return ret;
	}