Created
August 13, 2018 19:12
-
-
Save vurtun/0b350b3efc4cc66e511f2735402b7f1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct path_iter { | |
const char *begin; | |
const char *end; | |
/* internal */ | |
const char *next; | |
const char *eof; | |
}; | |
static void | |
path_begin(struct path_iter *it, const char *str, const char *end) | |
{ | |
memset(it, 0, sizeof(*it)); | |
it->eof = (!end) ? str + strlen(str): end; | |
it->next = str; | |
} | |
static int | |
path_next(struct path_iter *it) | |
{ | |
struct utf8_iter iter; | |
if (it->next >= it->eof) return 0; | |
it->begin = it->next; | |
it->end = it->begin; | |
for (utf8_begin(&iter, it->end, it->eof); utf8_next(&iter); ) { | |
if (iter.rune == '/') break; | |
it->end = iter.rune_end; | |
} | |
if (it->begin == it->end) | |
it->next = it->end = it->begin + 1; | |
else it->next = (it->end < it->eof) ? it->end + 1: it->eof; | |
return 1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct str_iter { | |
const char *begin; | |
const char *end; | |
/* internal */ | |
const char *next; | |
const char *eof; | |
}; | |
static void | |
str_iter(struct str_iter *si, const char *str, const char *end) | |
{ | |
memset(si, 0, sizeof(*si)); | |
si->eof = (!end) ? str + strlen(str): end; | |
si->next = str; | |
} | |
static int | |
str_next_sep(struct str_iter *si, uint32 sep) | |
{ | |
if (si->next >= si->eof) return 0; | |
si->begin = si->next; | |
struct utf8_iter iter = {0}; | |
for (utf8_begin(&iter, si->next, si->eof); utf8_next(&iter); ) { | |
if (iter.rune != sep) break; | |
si->begin = iter.rune_end; | |
} | |
si->end = si->begin; | |
for (utf8_begin(&iter, si->end, si->eof); utf8_next(&iter); ) { | |
if (iter.rune == sep) break; | |
si->end = iter.rune_end; | |
} | |
if (si->begin == si->end) return 0; | |
si->next = (si->end >= si->eof) ? si->eof: si->end; | |
return 1; | |
} | |
static int | |
str_next_tok(struct str_iter *si, const char *delims) | |
{ | |
struct utf8_iter iter = {0}; | |
if (si->next >= si->eof) return 0; | |
si->begin = si->next; | |
for (utf8_begin(&iter, si->begin, si->eof); utf8_next(&iter); ) { | |
if (!utf8_has(delims, iter.rune)) break; | |
si->begin = iter.rune_end; | |
} | |
si->end = si->begin; | |
for (utf8_begin(&iter, si->end, si->eof); utf8_next(&iter); ) { | |
if (utf8_has(delims, iter.rune)) break; | |
si->end = iter.rune_end; | |
} | |
if (si->begin == si->end) return 0; | |
si->next = (si->end < si->eof) ? si->end: si->eof; | |
return 1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if 0 | |
struct utf8_iter iter = {0}; | |
for (utf8_begin(&iter, str_begin, str_end); utf8_next(&iter); ) { | |
printf("%d\n", iter.rune); | |
} | |
#endif | |
struct utf8_iter { | |
int error; | |
long rune; | |
int rune_len; | |
const char *rune_begin; | |
const char *rune_end; | |
/* internal */ | |
const char *next; | |
const char *prev; | |
const char *eof; | |
}; | |
static void | |
utf8_begin(struct utf8_iter *it, const char *str, const char *end) | |
{ | |
it->error = 0; | |
it->eof = end ? end: str + strlen(str); | |
it->prev = it->eof; | |
it->next = str; | |
} | |
static int | |
utf8_next(struct utf8_iter *it) | |
{ | |
if (it->next >= it->eof) return 0; | |
it->rune_begin = it->next; | |
it->rune_len = utf8_decode(it->rune_begin, &it->rune, (int)(it->eof - it->rune_begin)); | |
it->rune_end = it->rune_begin + it->rune_len; | |
it->next = (it->rune_end >= it->eof) ? it->eof: it->rune_end; | |
if (it->rune == UTF_INVALID) { | |
it->error = UTF_INVALID; | |
return 0; | |
} else return 1; | |
} | |
static int | |
utf8_prev(struct utf8_iter *it) | |
{ | |
if (it->prev <= it->next) return 0; | |
it->rune_begin = utf8_dec(it->next, it->prev); | |
if (!it->rune_begin) return 0; | |
it->rune_len = utf8_decode(it->rune_begin, &it->rune, (int)(it->eof - it->rune_begin)); | |
it->rune_end = it->rune_begin + it->rune_len; | |
it->prev = it->rune_begin; | |
if (it->rune == UTF_INVALID) { | |
it->error = UTF_INVALID; | |
return 0; | |
} else return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment