#include #include #include coroutine RangeParser { const char * text; int com; }; void ?{}(RangeParser & this, const char * text) { this.text = text; } static inline void push(RangeParser & this, int val) { this.com = val; suspend; } static inline int next(RangeParser & this) { return resume(this).com; } void main(RangeParser & this) { for() { int start = -1, stop = -1; int start_len = -1, stop_len = -1; int ret = sscanf(this.text, "%u%n-%u%n", &start, &start_len, &stop, &stop_len); switch(ret) { case 0: // Not a range, maybe a comma? if(this.text[0] == ',') { this.text ++; continue; } serr | "Error: unexpected character in next range: '" | this.text |"'"; exit(2); case 1: // Only one value, push it! push(this, start); this.text += start_len; break; case 2: if(start > stop) { serr | "Error: next range out of order '" | this.text |"'"; exit(2); } for(int i = start; i <= stop; i++) { push(this, i); } this.text += stop_len; break; default: serr | "Error reading next block: '" | this.text |"', returned" | ret; exit(2); } if(this.text[0] == '\0') break; } this.com = -1; } int main(int argc, char * argv[]) { if(argc != 2) { serr | "Usage:" | argv[0] | "range"; return 1; } RangeParser rp = { argv[1] }; for() { int i = next(rp); if(i < 0) break; sout | i | nonl; } sout | nl; }