// Hidden header style array. (2.10)
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// Utility.
#define MAX(a, b) \
({ __auto_type _x = (a); __auto_type _y = (b); \
(_y > _x) ? _y : _x; })
void *memfill(void *base, size_t n, size_t size, const void *fill)
{
if (n != 0 && size != 0)
{
size_t i = 1;
for (; i <= n/2; i *= 2)
memcpy((char*)base
+ i
*size
, base
, i
*size
); memcpy((char*)base
+ i
*size
, base
, (n
-i
)*size
); }
return base;
}
// Interface.
#define ar_init(a) ((a) = _ar_init())
#define ar_init_size(a, n, v) ((a) = _ar_init_size(n, (__typeof__(*(a))[]){v}, sizeof *(a)))
#define ar_init_copy(a, b) ((a) = _ar_init_copy(b, sizeof *(a)))
#define ar_free(a) (_ar_free(a), (a) = 0)
#define ar_reserve(a, n) ((a) = _ar_reserve(a, n, sizeof *(a)))
#define ar_resize(a, n, v) ((a) = _ar_resize(a, n, (__typeof__(*(a))[]){v}, sizeof *(a)))
#define ar_at(a, i) (ar_at_p(a, i)[0])
#define ar_at_c(a, i) (ar_at_c_p(a, i)[0])
#define ar_at_p(a, i) ((__typeof__(*(a))*)_ar_at(a, i, sizeof *(a)))
#define ar_at_c_p(a, i) ((const __typeof__(*(a))*)_ar_at_c(a, i, sizeof *(a)))
#define ar_remove(a, i, n) _ar_remove(a, i, n, sizeof *(a))
#define ar_insert(a, i, s, n) ((a) = _ar_insert(a, i, s, n, sizeof *(a)))
#define ar_push(a, v) ((a) = _ar_push(a, (__typeof__(*(a))[]){v}, sizeof *(a)))
#define ar_pop(a) _ar_pop(a)
#define ar_clear(a) _ar_clear(a)
#define ar_size(a) _ar_size(a)
#define ar_capacity(a) _ar_capacity(a)
void *_ar_reserve(void *p, size_t capacity, size_t itemsize);
void *_ar_resize(void *p, size_t size, const void *fill, size_t itemsize);
void _ar_free(void *p);
void *_ar_init(void);
void *_ar_init_size(size_t size, const void *fill, size_t itemsize);
void *_ar_init_copy(const void *p, size_t itemsize);
const void *_ar_at_c(const void *p, ptrdiff_t i, size_t itemsize);
void *_ar_at(void *p, ptrdiff_t i, size_t itemsize);
void _ar_remove(void *p, size_t i, size_t n, size_t itemsize);
void *_ar_insert(void *p, size_t i, const void *first, size_t n, size_t itemsize);
void *_ar_push(void *p, const void *item, size_t itemsize);
void _ar_pop(void *p);
void _ar_clear(void *p);
size_t _ar_size(const void *p);
size_t _ar_capacity(const void *p);
// Implementation.
typedef struct {
size_t size, capacity;
} _Header;
#define _PTR_TO_HDR(p) ((_Header*)((char*)p - sizeof(_Header)))
#define _HDR_TO_PTR(p) ((void*)((char*)p + sizeof(_Header)))
void *_ar_reserve(void *p, size_t capacity, size_t itemsize)
{
_Header *self = _PTR_TO_HDR(p);
if (capacity > self->capacity)
{
self
= realloc(self
, sizeof *self
+ capacity
*itemsize
); self->capacity = capacity;
}
return _HDR_TO_PTR(self);
}
void *_ar_resize(void *p, size_t size, const void *fill, size_t itemsize)
{
p = _ar_reserve(p, size, itemsize);
_Header *self = _PTR_TO_HDR(p);
size_t oldsize = self->size;
self->size = size;
if (fill != 0 && size > oldsize)
memfill(_ar_at(p, oldsize, itemsize), size - oldsize, itemsize, fill);
return p;
}
void _ar_free(void *p)
{
if (p != 0)
}
void *_ar_init(void)
{
_Header
*self
= malloc(sizeof *self
); self->size = 0;
self->capacity = 0;
return _HDR_TO_PTR(self);
}
void *_ar_init_size(size_t size, const void *fill, size_t itemsize)
{
return _ar_resize(_ar_init(), size, fill, itemsize);
}
void *_ar_init_copy(const void *p, size_t itemsize)
{
return _ar_insert(_ar_init(), 0, p, _PTR_TO_HDR(p)->size, itemsize);
}
const void *_ar_at_c(const void *p, ptrdiff_t i, size_t itemsize)
{
size_t size = _PTR_TO_HDR(p)->size;
size_t effective_i = (i < 0) ? i + size : (size_t)i;
return (const char*)p + effective_i*itemsize;
}
void *_ar_at(void *p, ptrdiff_t i, size_t itemsize)
{
return (void*)_ar_at_c(p, i, itemsize);
}
void _ar_remove(void *p, size_t i, size_t n, size_t itemsize)
{
_Header *self = _PTR_TO_HDR(p);
assert(self
->size
>= i
+ n
); // @bug (i + n) might overflow
if (n != 0)
{
size_t oldsize = self->size;
size_t j = i + n;
if (oldsize > j)
memmove(_ar_at
(p
, i
, itemsize
), _ar_at
(p
, j
, itemsize
), (oldsize
- j
)*itemsize
); self->size = oldsize - n;
}
}
void *_ar_insert(void *p, size_t i, const void *first, size_t n, size_t itemsize)
{
_Header *self = _PTR_TO_HDR(p);
if (n != 0)
{
size_t oldsize = self->size;
size_t newsize = oldsize + n;
if (newsize > self->capacity)
{
p = _ar_reserve(p, MAX(2*self->capacity, newsize), itemsize);
self = _PTR_TO_HDR(p);
}
self->size = newsize;
void *ip = _ar_at(p, i, itemsize);
if (oldsize > i)
memmove(_ar_at
(p
, i
+ n
, itemsize
), ip
, (oldsize
- i
)*itemsize
); memcpy(ip
, first
, n
*itemsize
); }
return p;
}
void *_ar_push(void *p, const void *item, size_t itemsize)
{
return _ar_insert(p, _PTR_TO_HDR(p)->size, item, 1, itemsize);
}
void _ar_pop(void *p)
{
_Header *self = _PTR_TO_HDR(p);
self->size--;
}
void _ar_clear(void *p)
{
_PTR_TO_HDR(p)->size = 0;
}
size_t _ar_size(const void *p)
{
return _PTR_TO_HDR(p)->size;
}
size_t _ar_capacity(const void *p)
{
return _PTR_TO_HDR(p)->capacity;
}
// Main.
void ar_print(const int *p)
{
printf("size/capacity: %zu/%zu [", ar_size
(p
), ar_capacity
(p
)); for (size_t i = 0; i < ar_size(p); i++)
{
printf(i
? ", %d" : "%d", p
[i
]); }
}
void test_init_free(void)
{
// Init.
int *p = 0;
ar_init(p);
ar_free(p);
// Init size.
ar_init_size(p, 3, 123);
for (size_t i = 0; i < 3; i++)
// Init copy.
int *q = 0;
ar_init_copy(q, p);
ar_free(p);
for (size_t i = 0; i < 3; i++)
ar_free(q);
printf("%s: Okay.\n", __func__
); }
void test_push_pop(void)
{
int *p = 0;
ar_init(p);
// Push (back).
for (int i = 0; i < 8; i++)
{
int cp2 = i ? 1<<(31 - __builtin_clz(2*i-1)) : 0;
assert(ar_capacity
(p
) == cp2
); ar_push(p, i);
}
// Pop (back).
for (int i = 7; i >= 0; i--)
{
ar_pop(p);
}
ar_free(p);
printf("%s: Okay.\n", __func__
); }
void test_insert_remove(void)
{
int *p = 0;
ar_init(p);
// Insert even (bulk).
ar_insert(p, 0, ((int[]){0, 2, 4}), 3);
for (int i = 0; i < 3; i++)
// Insert odd (single).
for (int i = 0; i < 3; i++)
ar_insert(p, 2*i+1, (int[]){2*i+1}, 1);
for (int i = 0; i < 6; i++)
// Remove even (single).
for (int i = 2; i >= 0; i--)
ar_remove(p, 2*i, 1);
for (int i = 0; i < 3; i++)
// Remove odd (bulk).
ar_remove(p, 0, 3);
ar_free(p);
printf("%s: Okay.\n", __func__
); }
int main(void)
{
test_init_free();
test_push_pop();
test_insert_remove();
int *p = 0;
ar_init(p);
int n = 5;
// Push/Pop (back).
for (int i = 0; i < n; i++)
{
ar_push(p, i);
ar_print(p);
}
while (ar_size(p) != 0)
{
ar_pop(p);
ar_print(p);
}
// Insert/Erase.
for (int i = 0; i < n; i++)
{
ar_insert(p, i, ((int[]){i+1, i+1+n}), 2);
ar_print(p);
}
for (int i = n-1; i >= 0; i--)
{
ar_remove(p, i, 2);
ar_print(p);
}
// Resize (fill).
for (int i = 1; i < n; i++)
{
ar_clear(p);
ar_resize(p, i, -i);
ar_print(p);
}
ar_free(p);
return 0;
}
Ly8gSGlkZGVuIGhlYWRlciBzdHlsZSBhcnJheS4gKDIuMTApCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKLy8gVXRpbGl0eS4KCiNkZWZpbmUgTUFYKGEsIGIpIFwKKHsgX19hdXRvX3R5cGUgX3ggPSAoYSk7IF9fYXV0b190eXBlIF95ID0gKGIpOyBcCiAgIChfeSA+IF94KSA/IF95IDogX3g7IH0pCgp2b2lkICptZW1maWxsKHZvaWQgKmJhc2UsIHNpemVfdCBuLCBzaXplX3Qgc2l6ZSwgY29uc3Qgdm9pZCAqZmlsbCkKewogICAgaWYgKG4gIT0gMCAmJiBzaXplICE9IDApCiAgICB7CiAgICAgICAgbWVtbW92ZShiYXNlLCBmaWxsLCBzaXplKTsKICAgICAgICBzaXplX3QgaSA9IDE7CiAgICAgICAgZm9yICg7IGkgPD0gbi8yOyBpICo9IDIpCiAgICAgICAgICAgIG1lbWNweSgoY2hhciopYmFzZSArIGkqc2l6ZSwgYmFzZSwgaSpzaXplKTsKICAgICAgICBtZW1jcHkoKGNoYXIqKWJhc2UgKyBpKnNpemUsIGJhc2UsIChuLWkpKnNpemUpOwogICAgfQogICAgcmV0dXJuIGJhc2U7Cn0KCi8vIEludGVyZmFjZS4KCiNkZWZpbmUgYXJfaW5pdChhKSAoKGEpID0gX2FyX2luaXQoKSkKI2RlZmluZSBhcl9pbml0X3NpemUoYSwgbiwgdikgKChhKSA9IF9hcl9pbml0X3NpemUobiwgKF9fdHlwZW9mX18oKihhKSlbXSl7dn0sIHNpemVvZiAqKGEpKSkKI2RlZmluZSBhcl9pbml0X2NvcHkoYSwgYikgKChhKSA9IF9hcl9pbml0X2NvcHkoYiwgc2l6ZW9mICooYSkpKQojZGVmaW5lIGFyX2ZyZWUoYSkgKF9hcl9mcmVlKGEpLCAoYSkgPSAwKQojZGVmaW5lIGFyX3Jlc2VydmUoYSwgbikgKChhKSA9IF9hcl9yZXNlcnZlKGEsIG4sIHNpemVvZiAqKGEpKSkKI2RlZmluZSBhcl9yZXNpemUoYSwgbiwgdikgKChhKSA9IF9hcl9yZXNpemUoYSwgbiwgKF9fdHlwZW9mX18oKihhKSlbXSl7dn0sIHNpemVvZiAqKGEpKSkKI2RlZmluZSBhcl9hdChhLCBpKSAoYXJfYXRfcChhLCBpKVswXSkKI2RlZmluZSBhcl9hdF9jKGEsIGkpIChhcl9hdF9jX3AoYSwgaSlbMF0pCiNkZWZpbmUgYXJfYXRfcChhLCBpKSAoKF9fdHlwZW9mX18oKihhKSkqKV9hcl9hdChhLCBpLCBzaXplb2YgKihhKSkpCiNkZWZpbmUgYXJfYXRfY19wKGEsIGkpICgoY29uc3QgX190eXBlb2ZfXygqKGEpKSopX2FyX2F0X2MoYSwgaSwgc2l6ZW9mICooYSkpKQojZGVmaW5lIGFyX3JlbW92ZShhLCBpLCBuKSBfYXJfcmVtb3ZlKGEsIGksIG4sIHNpemVvZiAqKGEpKQojZGVmaW5lIGFyX2luc2VydChhLCBpLCBzLCBuKSAoKGEpID0gX2FyX2luc2VydChhLCBpLCBzLCBuLCBzaXplb2YgKihhKSkpCiNkZWZpbmUgYXJfcHVzaChhLCB2KSAoKGEpID0gX2FyX3B1c2goYSwgKF9fdHlwZW9mX18oKihhKSlbXSl7dn0sIHNpemVvZiAqKGEpKSkKI2RlZmluZSBhcl9wb3AoYSkgX2FyX3BvcChhKQojZGVmaW5lIGFyX2NsZWFyKGEpIF9hcl9jbGVhcihhKQojZGVmaW5lIGFyX3NpemUoYSkgX2FyX3NpemUoYSkKI2RlZmluZSBhcl9jYXBhY2l0eShhKSBfYXJfY2FwYWNpdHkoYSkKCnZvaWQgKl9hcl9yZXNlcnZlKHZvaWQgKnAsIHNpemVfdCBjYXBhY2l0eSwgc2l6ZV90IGl0ZW1zaXplKTsKdm9pZCAqX2FyX3Jlc2l6ZSh2b2lkICpwLCBzaXplX3Qgc2l6ZSwgY29uc3Qgdm9pZCAqZmlsbCwgc2l6ZV90IGl0ZW1zaXplKTsKdm9pZCBfYXJfZnJlZSh2b2lkICpwKTsKdm9pZCAqX2FyX2luaXQodm9pZCk7CnZvaWQgKl9hcl9pbml0X3NpemUoc2l6ZV90IHNpemUsIGNvbnN0IHZvaWQgKmZpbGwsIHNpemVfdCBpdGVtc2l6ZSk7CnZvaWQgKl9hcl9pbml0X2NvcHkoY29uc3Qgdm9pZCAqcCwgc2l6ZV90IGl0ZW1zaXplKTsKY29uc3Qgdm9pZCAqX2FyX2F0X2MoY29uc3Qgdm9pZCAqcCwgcHRyZGlmZl90IGksIHNpemVfdCBpdGVtc2l6ZSk7CnZvaWQgKl9hcl9hdCh2b2lkICpwLCBwdHJkaWZmX3QgaSwgc2l6ZV90IGl0ZW1zaXplKTsKdm9pZCBfYXJfcmVtb3ZlKHZvaWQgKnAsIHNpemVfdCBpLCBzaXplX3Qgbiwgc2l6ZV90IGl0ZW1zaXplKTsKdm9pZCAqX2FyX2luc2VydCh2b2lkICpwLCBzaXplX3QgaSwgY29uc3Qgdm9pZCAqZmlyc3QsIHNpemVfdCBuLCBzaXplX3QgaXRlbXNpemUpOwp2b2lkICpfYXJfcHVzaCh2b2lkICpwLCBjb25zdCB2b2lkICppdGVtLCBzaXplX3QgaXRlbXNpemUpOwp2b2lkIF9hcl9wb3Aodm9pZCAqcCk7CnZvaWQgX2FyX2NsZWFyKHZvaWQgKnApOwpzaXplX3QgX2FyX3NpemUoY29uc3Qgdm9pZCAqcCk7CnNpemVfdCBfYXJfY2FwYWNpdHkoY29uc3Qgdm9pZCAqcCk7CgovLyBJbXBsZW1lbnRhdGlvbi4KCnR5cGVkZWYgc3RydWN0IHsKICAgIHNpemVfdCBzaXplLCBjYXBhY2l0eTsKfSBfSGVhZGVyOwoKI2RlZmluZSBfUFRSX1RPX0hEUihwKSAoKF9IZWFkZXIqKSgoY2hhciopcCAtIHNpemVvZihfSGVhZGVyKSkpCiNkZWZpbmUgX0hEUl9UT19QVFIocCkgKCh2b2lkKikoKGNoYXIqKXAgKyBzaXplb2YoX0hlYWRlcikpKQoKdm9pZCAqX2FyX3Jlc2VydmUodm9pZCAqcCwgc2l6ZV90IGNhcGFjaXR5LCBzaXplX3QgaXRlbXNpemUpCnsKICAgIGFzc2VydChwICE9IDApOwogICAgX0hlYWRlciAqc2VsZiA9IF9QVFJfVE9fSERSKHApOwoKICAgIGlmIChjYXBhY2l0eSA+IHNlbGYtPmNhcGFjaXR5KQogICAgewogICAgICAgIHNlbGYgPSByZWFsbG9jKHNlbGYsIHNpemVvZiAqc2VsZiArIGNhcGFjaXR5Kml0ZW1zaXplKTsKICAgICAgICBhc3NlcnQoc2VsZiAhPSAwKTsKICAgICAgICBzZWxmLT5jYXBhY2l0eSA9IGNhcGFjaXR5OwogICAgfQogICAgcmV0dXJuIF9IRFJfVE9fUFRSKHNlbGYpOwp9Cgp2b2lkICpfYXJfcmVzaXplKHZvaWQgKnAsIHNpemVfdCBzaXplLCBjb25zdCB2b2lkICpmaWxsLCBzaXplX3QgaXRlbXNpemUpCnsKICAgIGFzc2VydChwICE9IDApOwogICAgcCA9IF9hcl9yZXNlcnZlKHAsIHNpemUsIGl0ZW1zaXplKTsKCiAgICBfSGVhZGVyICpzZWxmID0gX1BUUl9UT19IRFIocCk7CiAgICBzaXplX3Qgb2xkc2l6ZSA9IHNlbGYtPnNpemU7CiAgICBzZWxmLT5zaXplID0gc2l6ZTsKCiAgICBpZiAoZmlsbCAhPSAwICYmIHNpemUgPiBvbGRzaXplKQogICAgICAgIG1lbWZpbGwoX2FyX2F0KHAsIG9sZHNpemUsIGl0ZW1zaXplKSwgc2l6ZSAtIG9sZHNpemUsIGl0ZW1zaXplLCBmaWxsKTsKICAgIHJldHVybiBwOwp9Cgp2b2lkIF9hcl9mcmVlKHZvaWQgKnApCnsKICAgIGlmIChwICE9IDApCiAgICAgICAgZnJlZShfUFRSX1RPX0hEUihwKSk7Cn0KCnZvaWQgKl9hcl9pbml0KHZvaWQpCnsKICAgIF9IZWFkZXIgKnNlbGYgPSBtYWxsb2Moc2l6ZW9mICpzZWxmKTsKICAgIGFzc2VydChzZWxmICE9IDApOwogICAgc2VsZi0+c2l6ZSA9IDA7CiAgICBzZWxmLT5jYXBhY2l0eSA9IDA7CiAgICByZXR1cm4gX0hEUl9UT19QVFIoc2VsZik7Cn0KCnZvaWQgKl9hcl9pbml0X3NpemUoc2l6ZV90IHNpemUsIGNvbnN0IHZvaWQgKmZpbGwsIHNpemVfdCBpdGVtc2l6ZSkKewogICAgcmV0dXJuIF9hcl9yZXNpemUoX2FyX2luaXQoKSwgc2l6ZSwgZmlsbCwgaXRlbXNpemUpOwp9Cgp2b2lkICpfYXJfaW5pdF9jb3B5KGNvbnN0IHZvaWQgKnAsIHNpemVfdCBpdGVtc2l6ZSkKewogICAgYXNzZXJ0KHAgIT0gMCk7CiAgICByZXR1cm4gX2FyX2luc2VydChfYXJfaW5pdCgpLCAwLCBwLCBfUFRSX1RPX0hEUihwKS0+c2l6ZSwgaXRlbXNpemUpOwp9Cgpjb25zdCB2b2lkICpfYXJfYXRfYyhjb25zdCB2b2lkICpwLCBwdHJkaWZmX3QgaSwgc2l6ZV90IGl0ZW1zaXplKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIHNpemVfdCBzaXplID0gX1BUUl9UT19IRFIocCktPnNpemU7CiAgICBzaXplX3QgZWZmZWN0aXZlX2kgPSAoaSA8IDApID8gaSArIHNpemUgOiAoc2l6ZV90KWk7CiAgICBhc3NlcnQoZWZmZWN0aXZlX2kgPCBzaXplKTsKICAgIHJldHVybiAoY29uc3QgY2hhciopcCArIGVmZmVjdGl2ZV9pKml0ZW1zaXplOwp9Cgp2b2lkICpfYXJfYXQodm9pZCAqcCwgcHRyZGlmZl90IGksIHNpemVfdCBpdGVtc2l6ZSkKewogICAgcmV0dXJuICh2b2lkKilfYXJfYXRfYyhwLCBpLCBpdGVtc2l6ZSk7Cn0KCnZvaWQgX2FyX3JlbW92ZSh2b2lkICpwLCBzaXplX3QgaSwgc2l6ZV90IG4sIHNpemVfdCBpdGVtc2l6ZSkKewogICAgYXNzZXJ0KHAgIT0gMCk7CiAgICBfSGVhZGVyICpzZWxmID0gX1BUUl9UT19IRFIocCk7CgogICAgYXNzZXJ0KHNlbGYtPnNpemUgPj0gaSk7CiAgICBhc3NlcnQoc2VsZi0+c2l6ZSA+PSBpICsgbik7IC8vIEBidWcgKGkgKyBuKSBtaWdodCBvdmVyZmxvdwoKICAgIGlmIChuICE9IDApCiAgICB7CiAgICAgICAgc2l6ZV90IG9sZHNpemUgPSBzZWxmLT5zaXplOwogICAgICAgIHNpemVfdCBqID0gaSArIG47CgogICAgICAgIGlmIChvbGRzaXplID4gaikKICAgICAgICAgICAgbWVtbW92ZShfYXJfYXQocCwgaSwgaXRlbXNpemUpLCBfYXJfYXQocCwgaiwgaXRlbXNpemUpLCAob2xkc2l6ZSAtIGopKml0ZW1zaXplKTsKICAgICAgICBzZWxmLT5zaXplID0gb2xkc2l6ZSAtIG47CiAgICB9Cn0KCnZvaWQgKl9hcl9pbnNlcnQodm9pZCAqcCwgc2l6ZV90IGksIGNvbnN0IHZvaWQgKmZpcnN0LCBzaXplX3Qgbiwgc2l6ZV90IGl0ZW1zaXplKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIF9IZWFkZXIgKnNlbGYgPSBfUFRSX1RPX0hEUihwKTsKCiAgICBhc3NlcnQoc2VsZi0+c2l6ZSA+PSBpKTsKCiAgICBpZiAobiAhPSAwKQogICAgewogICAgICAgIHNpemVfdCBvbGRzaXplID0gc2VsZi0+c2l6ZTsKICAgICAgICBzaXplX3QgbmV3c2l6ZSA9IG9sZHNpemUgKyBuOwoKICAgICAgICBpZiAobmV3c2l6ZSA+IHNlbGYtPmNhcGFjaXR5KQogICAgICAgIHsKICAgICAgICAgICAgcCA9IF9hcl9yZXNlcnZlKHAsIE1BWCgyKnNlbGYtPmNhcGFjaXR5LCBuZXdzaXplKSwgaXRlbXNpemUpOwogICAgICAgICAgICBzZWxmID0gX1BUUl9UT19IRFIocCk7CiAgICAgICAgfQogICAgICAgIHNlbGYtPnNpemUgPSBuZXdzaXplOwogICAgICAgIHZvaWQgKmlwID0gX2FyX2F0KHAsIGksIGl0ZW1zaXplKTsKCiAgICAgICAgaWYgKG9sZHNpemUgPiBpKQogICAgICAgICAgICBtZW1tb3ZlKF9hcl9hdChwLCBpICsgbiwgaXRlbXNpemUpLCBpcCwgKG9sZHNpemUgLSBpKSppdGVtc2l6ZSk7CiAgICAgICAgbWVtY3B5KGlwLCBmaXJzdCwgbippdGVtc2l6ZSk7CiAgICB9CiAgICByZXR1cm4gcDsKfQoKdm9pZCAqX2FyX3B1c2godm9pZCAqcCwgY29uc3Qgdm9pZCAqaXRlbSwgc2l6ZV90IGl0ZW1zaXplKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIHJldHVybiBfYXJfaW5zZXJ0KHAsIF9QVFJfVE9fSERSKHApLT5zaXplLCBpdGVtLCAxLCBpdGVtc2l6ZSk7Cn0KCnZvaWQgX2FyX3BvcCh2b2lkICpwKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIF9IZWFkZXIgKnNlbGYgPSBfUFRSX1RPX0hEUihwKTsKICAgIGFzc2VydChzZWxmLT5zaXplICE9IDApOwogICAgc2VsZi0+c2l6ZS0tOwp9Cgp2b2lkIF9hcl9jbGVhcih2b2lkICpwKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIF9QVFJfVE9fSERSKHApLT5zaXplID0gMDsKfQoKc2l6ZV90IF9hcl9zaXplKGNvbnN0IHZvaWQgKnApCnsKICAgIGFzc2VydChwICE9IDApOwogICAgcmV0dXJuIF9QVFJfVE9fSERSKHApLT5zaXplOwp9CgpzaXplX3QgX2FyX2NhcGFjaXR5KGNvbnN0IHZvaWQgKnApCnsKICAgIGFzc2VydChwICE9IDApOwogICAgcmV0dXJuIF9QVFJfVE9fSERSKHApLT5jYXBhY2l0eTsKfQoKLy8gTWFpbi4KCnZvaWQgYXJfcHJpbnQoY29uc3QgaW50ICpwKQp7CiAgICBwcmludGYoInNpemUvY2FwYWNpdHk6ICV6dS8lenUgWyIsIGFyX3NpemUocCksIGFyX2NhcGFjaXR5KHApKTsKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgYXJfc2l6ZShwKTsgaSsrKQogICAgewogICAgICAgIHByaW50ZihpID8gIiwgJWQiIDogIiVkIiwgcFtpXSk7CiAgICB9CiAgICBwdXRzKCJdIik7Cn0KCnZvaWQgdGVzdF9pbml0X2ZyZWUodm9pZCkKewogICAgLy8gSW5pdC4KCiAgICBpbnQgKnAgPSAwOwogICAgYXJfaW5pdChwKTsKICAgIGFzc2VydChhcl9zaXplKHApID09IDApOwogICAgYXJfZnJlZShwKTsKICAgIGFzc2VydChwID09IDApOwoKICAgIC8vIEluaXQgc2l6ZS4KCiAgICBhcl9pbml0X3NpemUocCwgMywgMTIzKTsKICAgIGFzc2VydChhcl9zaXplKHApID09IDMpOwogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCAzOyBpKyspCiAgICAgICAgYXNzZXJ0KGFyX2F0KHAsIGkpID09IDEyMyk7CgogICAgLy8gSW5pdCBjb3B5LgoKICAgIGludCAqcSA9IDA7CiAgICBhcl9pbml0X2NvcHkocSwgcCk7CiAgICBhcl9mcmVlKHApOwogICAgYXNzZXJ0KHAgPT0gMCk7CgogICAgYXNzZXJ0KGFyX3NpemUocSkgPT0gMyk7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBhc3NlcnQoYXJfYXQocSwgaSkgPT0gMTIzKTsKICAgIGFyX2ZyZWUocSk7CiAgICBhc3NlcnQocSA9PSAwKTsKCiAgICBwcmludGYoIiVzOiBPa2F5LlxuIiwgX19mdW5jX18pOwp9Cgp2b2lkIHRlc3RfcHVzaF9wb3Aodm9pZCkKewogICAgaW50ICpwID0gMDsKICAgIGFyX2luaXQocCk7CgogICAgLy8gUHVzaCAoYmFjaykuCgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspCiAgICB7CiAgICAgICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gaSk7CiAgICAgICAgaW50IGNwMiA9IGkgPyAxPDwoMzEgLSBfX2J1aWx0aW5fY2x6KDIqaS0xKSkgOiAwOwogICAgICAgIGFzc2VydChhcl9jYXBhY2l0eShwKSA9PSBjcDIpOwogICAgICAgIGFyX3B1c2gocCwgaSk7CiAgICAgICAgYXNzZXJ0KGFyX2F0KHAsIC0xKSA9PSBpKTsKICAgIH0KCiAgICAvLyBQb3AgKGJhY2spLgoKICAgIGZvciAoaW50IGkgPSA3OyBpID49IDA7IGktLSkKICAgIHsKICAgICAgICBhc3NlcnQoYXJfYXQocCwgLTEpID09IGkpOwogICAgICAgIGFyX3BvcChwKTsKICAgIH0KICAgIGFzc2VydChhcl9zaXplKHApID09IDApOwogICAgYXJfZnJlZShwKTsKCiAgICBwcmludGYoIiVzOiBPa2F5LlxuIiwgX19mdW5jX18pOwp9Cgp2b2lkIHRlc3RfaW5zZXJ0X3JlbW92ZSh2b2lkKQp7CiAgICBpbnQgKnAgPSAwOwogICAgYXJfaW5pdChwKTsKCiAgICAvLyBJbnNlcnQgZXZlbiAoYnVsaykuCgogICAgYXJfaW5zZXJ0KHAsIDAsICgoaW50W10pezAsIDIsIDR9KSwgMyk7CiAgICBhc3NlcnQoYXJfc2l6ZShwKSA9PSAzKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIGFzc2VydChhcl9hdChwLCBpKSA9PSAyKmkpOwoKICAgIC8vIEluc2VydCBvZGQgKHNpbmdsZSkuCgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspCiAgICAgICAgYXJfaW5zZXJ0KHAsIDIqaSsxLCAoaW50W10pezIqaSsxfSwgMSk7CiAgICBhc3NlcnQoYXJfc2l6ZShwKSA9PSA2KTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgNjsgaSsrKQogICAgICAgIGFzc2VydChhcl9hdChwLCBpKSA9PSBpKTsKCiAgICAvLyBSZW1vdmUgZXZlbiAoc2luZ2xlKS4KCiAgICBmb3IgKGludCBpID0gMjsgaSA+PSAwOyBpLS0pCiAgICAgICAgYXJfcmVtb3ZlKHAsIDIqaSwgMSk7CiAgICBhc3NlcnQoYXJfc2l6ZShwKSA9PSAzKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIGFzc2VydChhcl9hdChwLCBpKSA9PSAyKmkrMSk7CgogICAgLy8gUmVtb3ZlIG9kZCAoYnVsaykuCgogICAgYXJfcmVtb3ZlKHAsIDAsIDMpOwogICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gMCk7CiAgICBhcl9mcmVlKHApOwoKICAgIHByaW50ZigiJXM6IE9rYXkuXG4iLCBfX2Z1bmNfXyk7Cn0KCmludCBtYWluKHZvaWQpCnsKICAgIHRlc3RfaW5pdF9mcmVlKCk7CiAgICB0ZXN0X3B1c2hfcG9wKCk7CiAgICB0ZXN0X2luc2VydF9yZW1vdmUoKTsKCiAgICBpbnQgKnAgPSAwOwogICAgYXJfaW5pdChwKTsKCiAgICBpbnQgbiA9IDU7CgogICAgLy8gUHVzaC9Qb3AgKGJhY2spLgoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgewogICAgICAgIGFyX3B1c2gocCwgaSk7CiAgICAgICAgYXJfcHJpbnQocCk7CiAgICB9CiAgICB3aGlsZSAoYXJfc2l6ZShwKSAhPSAwKQogICAgewogICAgICAgIGFyX3BvcChwKTsKICAgICAgICBhcl9wcmludChwKTsKICAgIH0KCiAgICAvLyBJbnNlcnQvRXJhc2UuCgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCiAgICB7CiAgICAgICAgYXJfaW5zZXJ0KHAsIGksICgoaW50W10pe2krMSwgaSsxK259KSwgMik7CiAgICAgICAgYXJfcHJpbnQocCk7CiAgICB9CiAgICBmb3IgKGludCBpID0gbi0xOyBpID49IDA7IGktLSkKICAgIHsKICAgICAgICBhcl9yZW1vdmUocCwgaSwgMik7CiAgICAgICAgYXJfcHJpbnQocCk7CiAgICB9CgogICAgLy8gUmVzaXplIChmaWxsKS4KCiAgICBmb3IgKGludCBpID0gMTsgaSA8IG47IGkrKykKICAgIHsKICAgICAgICBhcl9jbGVhcihwKTsKICAgICAgICBhcl9yZXNpemUocCwgaSwgLWkpOwogICAgICAgIGFyX3ByaW50KHApOwogICAgfQoKICAgIGFyX2ZyZWUocCk7CiAgICByZXR1cm4gMDsKfQ==