/* { dg-do run } */ extern void abort (void); typedef int int32_t __attribute__ ((mode (SI))); typedef int int64_t __attribute__ ((mode (DI))); typedef __SIZE_TYPE__ size_t; struct slice { unsigned char *data; int64_t len; int64_t cap; }; void fail (int32_t) __attribute__ ((noinline)); void fail (int32_t c) { if (c != 0) abort (); } struct decode_rune_ret { int32_t r; int64_t width; }; struct decode_rune_ret decode_rune (struct slice) __attribute__ ((noinline)); struct decode_rune_ret decode_rune (struct slice s) { struct decode_rune_ret dr; dr.r = s.data[0]; dr.width = 1; return dr; } _Bool is_space (int32_t) __attribute__ ((noinline)); _Bool is_space (int32_t r) { return r == ' '; } struct ret { int64_t advance; struct slice token; }; struct ret scanwords (struct slice, _Bool) __attribute__ ((noinline)); struct ret scanwords (struct slice data, _Bool ateof) { int64_t advance; struct slice token; int64_t start = 0; { int64_t width; for (width = 0; start < data.len; start += width) { int32_t r = 0; struct slice s; if (start > data.cap || start < 0) fail (3); s.data = data.data + (size_t) start; s.len = data.len - start; s.cap = data.cap - start; struct decode_rune_ret dr = decode_rune (s); r = dr.r; width = dr.width; if (!is_space (r)) break; } } _Bool tmp = ateof; if (tmp != 0) goto L1; else goto L2; L1: tmp = data.len == 0; L2: if (tmp != 0) goto L11; else goto L12; L11: { struct ret r; advance = 0; token.data = 0; token.len = 0; token.cap = 0; r.advance = advance; r.token = token; return r; } L12:; int64_t width; int64_t i; for (width = 0, i = start; i < data.len; i += width) { int32_t r; struct slice s; if (i > data.cap || i < 0) fail (3); s.data = data.data + i; s.len = data.len - i; s.cap = data.cap - i; struct decode_rune_ret dr = decode_rune (s); r = dr.r; width = dr.width; if (is_space (r)) { if (i < start || i > data.cap || i < 0) fail (3); if (start > data.cap || start < 0) fail (3); struct ret r; advance = i + width; token.data = data.data + (size_t) start; token.len = i - start; token.cap = data.cap - start; r.advance = advance; r.token = token; return r; } } { struct ret r; advance = 0; token.data = 0; token.len = 0; token.cap = 0; r.advance = advance; r.token = token; return r; } } int main () { unsigned char buf[1000]; struct slice s; __builtin_memset (buf, 0, sizeof (buf)); buf[0] = ' '; buf[1] = 'a'; buf[2] = ' '; s.data = buf; s.len = 3; s.cap = sizeof (buf); struct ret r; r = scanwords (s, 1); if (r.advance != 3 || r.token.data[0] != 'a' || r.token.len != 1) abort (); return 0; }