Skip to content

Instantly share code, notes, and snippets.

@vurtun
Created August 13, 2018 19:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vurtun/0b350b3efc4cc66e511f2735402b7f1a to your computer and use it in GitHub Desktop.
Save vurtun/0b350b3efc4cc66e511f2735402b7f1a to your computer and use it in GitHub Desktop.
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;
}
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;
}
#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