blob: e27b9cac5b39ab635a28a0468558d1c2cadd26a0 [file] [log] [blame]
/* { 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;
}