// Hidden header style array. (3.00)
#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_size(a) _ar_size(a)
#define ar_capacity(a) _ar_capacity(a)
#define ar_itemsize(a) _ar_itemsize(a)
#define ar_putitem(a) _ar_putitem(a)
#define ar_set_putitem(a, f) _ar_set_putitem(a, f)
#define ar_reserve(a, n) ((a) = _ar_reserve(a, n))
#define ar_resize(a, n, v) ((a) = _ar_resize(a, n, (__typeof__(*(a))[]){v}))
#define ar_free(a) (_ar_free(a), (a) = 0)
#define ar_init(a) ((a) = _ar_init(sizeof *(a)))
#define ar_init_size(a, n, v) ((a) = _ar_init_size(n, (__typeof__(*(a))[]){v}, sizeof *(a)))
#define ar_init_copy(a, b) ((a) = (__typeof__(*(b))*)_ar_init_copy(b, sizeof *(a)))
#define ar_at(a, i) (((__typeof__(*(a))*)_ar_at(a, i))[0])
#define ar_at_c(a, i) (((const __typeof__(*(a))*)_ar_at_c(a, i))[0])
#define ar_remove(a, i, n) _ar_remove(a, i, n)
#define ar_insert(a, i, s, n) ((a) = _ar_insert(a, i, s, n))
#define ar_push(a, v) ((a) = _ar_push(a, (__typeof__(*(a))[]){v}))
#define ar_pop(a) _ar_pop(a)
#define ar_clear(a) _ar_clear(a)
#define ar_print(a) _ar_print(a, stdout)
#define ar_println(a) _ar_println(a, stdout)
size_t _ar_size(const void *p);
size_t _ar_capacity(const void *p);
size_t _ar_itemsize(const void *p);
void (*_ar_putitem(const void *p))(const void *, FILE *);
void _ar_set_putitem(void *p, void (*putitem)(const void *, FILE *));
void *_ar_reserve(void *p, size_t capacity);
void *_ar_resize(void *p, size_t size, const void *fill);
void _ar_free(void *p);
void *_ar_init(size_t itemsize);
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);
void *_ar_at(void *p, ptrdiff_t i);
void _ar_remove(void *p, size_t i, size_t n);
void *_ar_insert(void *p, size_t i, const void *first, size_t n);
void *_ar_push(void *p, const void *item);
void _ar_pop(void *p);
void _ar_clear(void *p);
void _ar_print(const void *p, FILE *stream);
void _ar_println(const void *p, FILE *stream);
// Implementation.
typedef struct {
size_t size;
size_t capacity;
size_t itemsize;
void (*putitem)(const void *item, FILE *stream);
} _Header;
#define _PTR_TO_HDR(p) ((_Header*)((char*)p - sizeof(_Header)))
#define _HDR_TO_PTR(p) ((void*)((char*)p + sizeof(_Header)))
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;
}
size_t _ar_itemsize(const void *p)
{
return _PTR_TO_HDR(p)->itemsize;
}
void (*_ar_putitem(const void *p))(const void *, FILE *)
{
return _PTR_TO_HDR(p)->putitem;
}
void _ar_set_putitem(void *p, void (*putitem)(const void *, FILE *))
{
_PTR_TO_HDR(p)->putitem = putitem;
}
void *_ar_reserve(void *p, size_t capacity)
{
_Header *self = _PTR_TO_HDR(p);
if (capacity > self->capacity)
{
self
= realloc(self
, sizeof *self
+ capacity
*self
->itemsize
); self->capacity = capacity;
}
return _HDR_TO_PTR(self);
}
void *_ar_resize(void *p, size_t size, const void *fill)
{
p = _ar_reserve(p, size);
_Header *self = _PTR_TO_HDR(p);
size_t oldsize = self->size;
self->size = size;
if (fill != 0 && size > oldsize)
memfill(_ar_at(p, oldsize), size - oldsize, self->itemsize, fill);
return p;
}
void _ar_free(void *p)
{
if (p != 0)
}
void *_ar_init(size_t itemsize)
{
_Header
*self
= malloc(sizeof *self
); self->size = 0;
self->capacity = 0;
self->itemsize = itemsize;
self->putitem = 0;
return _HDR_TO_PTR(self);
}
void *_ar_init_size(size_t size, const void *fill, size_t itemsize)
{
return _ar_resize(_ar_init(itemsize), size, fill);
}
void *_ar_init_copy(const void *p, size_t itemsize)
{
const _Header *other = _PTR_TO_HDR(p);
assert(itemsize
== other
->itemsize
); return _ar_insert(_ar_init(itemsize), 0, p, other->size);
}
const void *_ar_at_c(const void *p, ptrdiff_t i)
{
const _Header *self = _PTR_TO_HDR(p);
size_t size = self->size;
size_t j = (i < 0) ? i + size : (size_t)i;
return (const char*)p + j*self->itemsize;
}
void *_ar_at(void *p, ptrdiff_t i)
{
return (void*)_ar_at_c(p, i);
}
void _ar_remove(void *p, size_t i, size_t n)
{
_Header *self = _PTR_TO_HDR(p);
size_t oldsize = self->size;
if (n != 0)
{
size_t j;
if (__builtin_add_overflow(i, n, &j))
assert(0 && "integer overflow");
if (oldsize > j)
memmove(_ar_at
(p
, i
), _ar_at
(p
, j
), (oldsize
- j
)*self
->itemsize
); self->size = oldsize - n;
}
}
void *_ar_insert(void *p, size_t i, const void *first, size_t n)
{
_Header *self = _PTR_TO_HDR(p);
size_t oldsize = self->size;
if (n != 0)
{
size_t size;
if (__builtin_add_overflow(oldsize, n, &size))
assert(0 && "integer overflow");
if (size > self->capacity)
{
p = _ar_reserve(p, MAX(2*self->capacity, size));
self = _PTR_TO_HDR(p);
}
self->size = size;
void *ip = _ar_at(p, i);
if (oldsize > i)
memmove(_ar_at
(p
, i
+ n
), ip
, (oldsize
- i
)*self
->itemsize
); memcpy(ip
, first
, n
*self
->itemsize
); }
return p;
}
void *_ar_push(void *p, const void *item)
{
return _ar_insert(p, _ar_size(p), item, 1);
}
void _ar_pop(void *p)
{
_ar_remove(p, _ar_size(p)-1, 1);
}
void _ar_clear(void *p)
{
_ar_resize(p, 0, 0);
}
void _ar_print(const void *p, FILE *stream)
{
const _Header *self = _PTR_TO_HDR(p);
size_t n = self->size;
if (n != 0)
{
for (size_t i = 0;;)
{
self->putitem(_ar_at_c(p, i), stream);
if (++i == n) break;
}
}
}
void _ar_println(const void *p, FILE *stream)
{
_ar_print
(p
, stream
); fputc('\n', stream
);}
// Putitem callback.
void putitem_ar(const void *item, FILE *stream)
{
_ar_print(*(const void **)item, stream);
}
void putitem_int(const void *item, FILE *stream)
{
fprintf(stream
, "%d", *(const int *)item
); }
// Test.
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);
}
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);
}
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);
}
// Show.
void show_push_pop(void)
{
int *p = 0;
ar_init(p);
ar_set_putitem(p, putitem_int);
int n = 4;
for (int i = 0; i < n; i++)
{
ar_push(p, i);
ar_println(p);
}
while (ar_size(p) != 0)
{
ar_pop(p);
ar_println(p);
}
ar_free(p);
}
void show_insert_remove(void)
{
int *p = 0;
ar_init(p);
ar_set_putitem(p, putitem_int);
int n = 4;
for (int i = 0; i < n; i++)
{
ar_insert(p, i, ((int[]){i+1, i+1+n}), 2);
ar_println(p);
}
for (int i = n-1; i >= 0; i--)
{
ar_remove(p, i, 2);
ar_println(p);
}
ar_free(p);
}
void show_resize(void)
{
int *p = 0;
ar_init(p);
ar_set_putitem(p, putitem_int);
int n = 5;
for (int i = 1; i < n; i++)
{
ar_resize(p, i, -i);
ar_println(p);
ar_clear(p);
}
ar_free(p);
}
void show_array_of_array(void)
{
int **p = 0;
ar_init(p);
ar_set_putitem(p, putitem_ar);
int n = 4;
int v = 1;
for (int i = 0; i < n; i++)
{
int *q = 0;
ar_init(q);
ar_set_putitem(q, putitem_int);
for (int j = 0; j < i+1; j++)
ar_push(q, v++);
ar_push(p, q);
ar_println(p);
}
while (ar_size(p) != 0)
{
int *q = ar_at(p, -1);
ar_free(q);
ar_pop(p);
}
ar_free(p);
}
int main(void)
{
test_init_free();
test_push_pop();
test_insert_remove();
show_push_pop();
show_insert_remove();
show_resize();
show_array_of_array();
return 0;
}
Ly8gSGlkZGVuIGhlYWRlciBzdHlsZSBhcnJheS4gKDMuMDApCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKLy8gVXRpbGl0eS4KCiNkZWZpbmUgTUFYKGEsIGIpIFwKKHsgX19hdXRvX3R5cGUgX3ggPSAoYSk7IF9fYXV0b190eXBlIF95ID0gKGIpOyBcCiAgIChfeSA+IF94KSA/IF95IDogX3g7IH0pCgp2b2lkICptZW1maWxsKHZvaWQgKmJhc2UsIHNpemVfdCBuLCBzaXplX3Qgc2l6ZSwgY29uc3Qgdm9pZCAqZmlsbCkKewogICAgaWYgKG4gIT0gMCAmJiBzaXplICE9IDApCiAgICB7CiAgICAgICAgbWVtbW92ZShiYXNlLCBmaWxsLCBzaXplKTsKICAgICAgICBzaXplX3QgaSA9IDE7CiAgICAgICAgZm9yICg7IGkgPD0gbi8yOyBpICo9IDIpCiAgICAgICAgICAgIG1lbWNweSgoY2hhciopYmFzZSArIGkqc2l6ZSwgYmFzZSwgaSpzaXplKTsKICAgICAgICBtZW1jcHkoKGNoYXIqKWJhc2UgKyBpKnNpemUsIGJhc2UsIChuLWkpKnNpemUpOwogICAgfQogICAgcmV0dXJuIGJhc2U7Cn0KCi8vIEludGVyZmFjZS4KCiNkZWZpbmUgYXJfc2l6ZShhKSBfYXJfc2l6ZShhKQojZGVmaW5lIGFyX2NhcGFjaXR5KGEpIF9hcl9jYXBhY2l0eShhKQojZGVmaW5lIGFyX2l0ZW1zaXplKGEpIF9hcl9pdGVtc2l6ZShhKQojZGVmaW5lIGFyX3B1dGl0ZW0oYSkgX2FyX3B1dGl0ZW0oYSkKI2RlZmluZSBhcl9zZXRfcHV0aXRlbShhLCBmKSBfYXJfc2V0X3B1dGl0ZW0oYSwgZikKI2RlZmluZSBhcl9yZXNlcnZlKGEsIG4pICgoYSkgPSBfYXJfcmVzZXJ2ZShhLCBuKSkKI2RlZmluZSBhcl9yZXNpemUoYSwgbiwgdikgKChhKSA9IF9hcl9yZXNpemUoYSwgbiwgKF9fdHlwZW9mX18oKihhKSlbXSl7dn0pKQojZGVmaW5lIGFyX2ZyZWUoYSkgKF9hcl9mcmVlKGEpLCAoYSkgPSAwKQojZGVmaW5lIGFyX2luaXQoYSkgKChhKSA9IF9hcl9pbml0KHNpemVvZiAqKGEpKSkKI2RlZmluZSBhcl9pbml0X3NpemUoYSwgbiwgdikgKChhKSA9IF9hcl9pbml0X3NpemUobiwgKF9fdHlwZW9mX18oKihhKSlbXSl7dn0sIHNpemVvZiAqKGEpKSkKI2RlZmluZSBhcl9pbml0X2NvcHkoYSwgYikgKChhKSA9IChfX3R5cGVvZl9fKCooYikpKilfYXJfaW5pdF9jb3B5KGIsIHNpemVvZiAqKGEpKSkKI2RlZmluZSBhcl9hdChhLCBpKSAoKChfX3R5cGVvZl9fKCooYSkpKilfYXJfYXQoYSwgaSkpWzBdKQojZGVmaW5lIGFyX2F0X2MoYSwgaSkgKCgoY29uc3QgX190eXBlb2ZfXygqKGEpKSopX2FyX2F0X2MoYSwgaSkpWzBdKQojZGVmaW5lIGFyX3JlbW92ZShhLCBpLCBuKSBfYXJfcmVtb3ZlKGEsIGksIG4pCiNkZWZpbmUgYXJfaW5zZXJ0KGEsIGksIHMsIG4pICgoYSkgPSBfYXJfaW5zZXJ0KGEsIGksIHMsIG4pKQojZGVmaW5lIGFyX3B1c2goYSwgdikgKChhKSA9IF9hcl9wdXNoKGEsIChfX3R5cGVvZl9fKCooYSkpW10pe3Z9KSkKI2RlZmluZSBhcl9wb3AoYSkgX2FyX3BvcChhKQojZGVmaW5lIGFyX2NsZWFyKGEpIF9hcl9jbGVhcihhKQojZGVmaW5lIGFyX3ByaW50KGEpIF9hcl9wcmludChhLCBzdGRvdXQpCiNkZWZpbmUgYXJfcHJpbnRsbihhKSBfYXJfcHJpbnRsbihhLCBzdGRvdXQpCgpzaXplX3QgX2FyX3NpemUoY29uc3Qgdm9pZCAqcCk7CnNpemVfdCBfYXJfY2FwYWNpdHkoY29uc3Qgdm9pZCAqcCk7CnNpemVfdCBfYXJfaXRlbXNpemUoY29uc3Qgdm9pZCAqcCk7CnZvaWQgKCpfYXJfcHV0aXRlbShjb25zdCB2b2lkICpwKSkoY29uc3Qgdm9pZCAqLCBGSUxFICopOwp2b2lkIF9hcl9zZXRfcHV0aXRlbSh2b2lkICpwLCB2b2lkICgqcHV0aXRlbSkoY29uc3Qgdm9pZCAqLCBGSUxFICopKTsKdm9pZCAqX2FyX3Jlc2VydmUodm9pZCAqcCwgc2l6ZV90IGNhcGFjaXR5KTsKdm9pZCAqX2FyX3Jlc2l6ZSh2b2lkICpwLCBzaXplX3Qgc2l6ZSwgY29uc3Qgdm9pZCAqZmlsbCk7CnZvaWQgX2FyX2ZyZWUodm9pZCAqcCk7CnZvaWQgKl9hcl9pbml0KHNpemVfdCBpdGVtc2l6ZSk7CnZvaWQgKl9hcl9pbml0X3NpemUoc2l6ZV90IHNpemUsIGNvbnN0IHZvaWQgKmZpbGwsIHNpemVfdCBpdGVtc2l6ZSk7CnZvaWQgKl9hcl9pbml0X2NvcHkoY29uc3Qgdm9pZCAqcCwgc2l6ZV90IGl0ZW1zaXplKTsKY29uc3Qgdm9pZCAqX2FyX2F0X2MoY29uc3Qgdm9pZCAqcCwgcHRyZGlmZl90IGkpOwp2b2lkICpfYXJfYXQodm9pZCAqcCwgcHRyZGlmZl90IGkpOwp2b2lkIF9hcl9yZW1vdmUodm9pZCAqcCwgc2l6ZV90IGksIHNpemVfdCBuKTsKdm9pZCAqX2FyX2luc2VydCh2b2lkICpwLCBzaXplX3QgaSwgY29uc3Qgdm9pZCAqZmlyc3QsIHNpemVfdCBuKTsKdm9pZCAqX2FyX3B1c2godm9pZCAqcCwgY29uc3Qgdm9pZCAqaXRlbSk7CnZvaWQgX2FyX3BvcCh2b2lkICpwKTsKdm9pZCBfYXJfY2xlYXIodm9pZCAqcCk7CnZvaWQgX2FyX3ByaW50KGNvbnN0IHZvaWQgKnAsIEZJTEUgKnN0cmVhbSk7CnZvaWQgX2FyX3ByaW50bG4oY29uc3Qgdm9pZCAqcCwgRklMRSAqc3RyZWFtKTsKCi8vIEltcGxlbWVudGF0aW9uLgoKdHlwZWRlZiBzdHJ1Y3QgewogICAgc2l6ZV90IHNpemU7CiAgICBzaXplX3QgY2FwYWNpdHk7CiAgICBzaXplX3QgaXRlbXNpemU7CiAgICB2b2lkICgqcHV0aXRlbSkoY29uc3Qgdm9pZCAqaXRlbSwgRklMRSAqc3RyZWFtKTsKfSBfSGVhZGVyOwoKI2RlZmluZSBfUFRSX1RPX0hEUihwKSAoKF9IZWFkZXIqKSgoY2hhciopcCAtIHNpemVvZihfSGVhZGVyKSkpCiNkZWZpbmUgX0hEUl9UT19QVFIocCkgKCh2b2lkKikoKGNoYXIqKXAgKyBzaXplb2YoX0hlYWRlcikpKQoKc2l6ZV90IF9hcl9zaXplKGNvbnN0IHZvaWQgKnApCnsKICAgIGFzc2VydChwICE9IDApOwogICAgcmV0dXJuIF9QVFJfVE9fSERSKHApLT5zaXplOwp9CgpzaXplX3QgX2FyX2NhcGFjaXR5KGNvbnN0IHZvaWQgKnApCnsKICAgIGFzc2VydChwICE9IDApOwogICAgcmV0dXJuIF9QVFJfVE9fSERSKHApLT5jYXBhY2l0eTsKfQoKc2l6ZV90IF9hcl9pdGVtc2l6ZShjb25zdCB2b2lkICpwKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIHJldHVybiBfUFRSX1RPX0hEUihwKS0+aXRlbXNpemU7Cn0KCnZvaWQgKCpfYXJfcHV0aXRlbShjb25zdCB2b2lkICpwKSkoY29uc3Qgdm9pZCAqLCBGSUxFICopCnsKICAgIGFzc2VydChwICE9IDApOwogICAgcmV0dXJuIF9QVFJfVE9fSERSKHApLT5wdXRpdGVtOwp9Cgp2b2lkIF9hcl9zZXRfcHV0aXRlbSh2b2lkICpwLCB2b2lkICgqcHV0aXRlbSkoY29uc3Qgdm9pZCAqLCBGSUxFICopKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIF9QVFJfVE9fSERSKHApLT5wdXRpdGVtID0gcHV0aXRlbTsKfQoKdm9pZCAqX2FyX3Jlc2VydmUodm9pZCAqcCwgc2l6ZV90IGNhcGFjaXR5KQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIF9IZWFkZXIgKnNlbGYgPSBfUFRSX1RPX0hEUihwKTsKCiAgICBpZiAoY2FwYWNpdHkgPiBzZWxmLT5jYXBhY2l0eSkKICAgIHsKICAgICAgICBzZWxmID0gcmVhbGxvYyhzZWxmLCBzaXplb2YgKnNlbGYgKyBjYXBhY2l0eSpzZWxmLT5pdGVtc2l6ZSk7CiAgICAgICAgYXNzZXJ0KHNlbGYgIT0gMCk7CiAgICAgICAgc2VsZi0+Y2FwYWNpdHkgPSBjYXBhY2l0eTsKICAgIH0KICAgIHJldHVybiBfSERSX1RPX1BUUihzZWxmKTsKfQoKdm9pZCAqX2FyX3Jlc2l6ZSh2b2lkICpwLCBzaXplX3Qgc2l6ZSwgY29uc3Qgdm9pZCAqZmlsbCkKewogICAgYXNzZXJ0KHAgIT0gMCk7CiAgICBwID0gX2FyX3Jlc2VydmUocCwgc2l6ZSk7CgogICAgX0hlYWRlciAqc2VsZiA9IF9QVFJfVE9fSERSKHApOwogICAgc2l6ZV90IG9sZHNpemUgPSBzZWxmLT5zaXplOwogICAgc2VsZi0+c2l6ZSA9IHNpemU7CgogICAgaWYgKGZpbGwgIT0gMCAmJiBzaXplID4gb2xkc2l6ZSkKICAgICAgICBtZW1maWxsKF9hcl9hdChwLCBvbGRzaXplKSwgc2l6ZSAtIG9sZHNpemUsIHNlbGYtPml0ZW1zaXplLCBmaWxsKTsKICAgIHJldHVybiBwOwp9Cgp2b2lkIF9hcl9mcmVlKHZvaWQgKnApCnsKICAgIGlmIChwICE9IDApCiAgICAgICAgZnJlZShfUFRSX1RPX0hEUihwKSk7Cn0KCnZvaWQgKl9hcl9pbml0KHNpemVfdCBpdGVtc2l6ZSkKewogICAgX0hlYWRlciAqc2VsZiA9IG1hbGxvYyhzaXplb2YgKnNlbGYpOwogICAgYXNzZXJ0KHNlbGYgIT0gMCk7CiAgICBzZWxmLT5zaXplID0gMDsKICAgIHNlbGYtPmNhcGFjaXR5ID0gMDsKICAgIHNlbGYtPml0ZW1zaXplID0gaXRlbXNpemU7CiAgICBzZWxmLT5wdXRpdGVtID0gMDsKICAgIHJldHVybiBfSERSX1RPX1BUUihzZWxmKTsKfQoKdm9pZCAqX2FyX2luaXRfc2l6ZShzaXplX3Qgc2l6ZSwgY29uc3Qgdm9pZCAqZmlsbCwgc2l6ZV90IGl0ZW1zaXplKQp7CiAgICByZXR1cm4gX2FyX3Jlc2l6ZShfYXJfaW5pdChpdGVtc2l6ZSksIHNpemUsIGZpbGwpOwp9Cgp2b2lkICpfYXJfaW5pdF9jb3B5KGNvbnN0IHZvaWQgKnAsIHNpemVfdCBpdGVtc2l6ZSkKewogICAgYXNzZXJ0KHAgIT0gMCk7CiAgICBjb25zdCBfSGVhZGVyICpvdGhlciA9IF9QVFJfVE9fSERSKHApOwoKICAgIGFzc2VydChpdGVtc2l6ZSA9PSBvdGhlci0+aXRlbXNpemUpOwogICAgcmV0dXJuIF9hcl9pbnNlcnQoX2FyX2luaXQoaXRlbXNpemUpLCAwLCBwLCBvdGhlci0+c2l6ZSk7Cn0KCmNvbnN0IHZvaWQgKl9hcl9hdF9jKGNvbnN0IHZvaWQgKnAsIHB0cmRpZmZfdCBpKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIGNvbnN0IF9IZWFkZXIgKnNlbGYgPSBfUFRSX1RPX0hEUihwKTsKCiAgICBzaXplX3Qgc2l6ZSA9IHNlbGYtPnNpemU7CiAgICBzaXplX3QgaiA9IChpIDwgMCkgPyBpICsgc2l6ZSA6IChzaXplX3QpaTsKICAgIGFzc2VydChqIDwgc2l6ZSk7CiAgICByZXR1cm4gKGNvbnN0IGNoYXIqKXAgKyBqKnNlbGYtPml0ZW1zaXplOwp9Cgp2b2lkICpfYXJfYXQodm9pZCAqcCwgcHRyZGlmZl90IGkpCnsKICAgIHJldHVybiAodm9pZCopX2FyX2F0X2MocCwgaSk7Cn0KCnZvaWQgX2FyX3JlbW92ZSh2b2lkICpwLCBzaXplX3QgaSwgc2l6ZV90IG4pCnsKICAgIGFzc2VydChwICE9IDApOwogICAgX0hlYWRlciAqc2VsZiA9IF9QVFJfVE9fSERSKHApOwoKICAgIHNpemVfdCBvbGRzaXplID0gc2VsZi0+c2l6ZTsKICAgIGFzc2VydChvbGRzaXplID49IGkpOwoKICAgIGlmIChuICE9IDApCiAgICB7CiAgICAgICAgc2l6ZV90IGo7CiAgICAgICAgaWYgKF9fYnVpbHRpbl9hZGRfb3ZlcmZsb3coaSwgbiwgJmopKQogICAgICAgICAgICBhc3NlcnQoMCAmJiAiaW50ZWdlciBvdmVyZmxvdyIpOwogICAgICAgIGFzc2VydChvbGRzaXplID49IGopOwoKICAgICAgICBpZiAob2xkc2l6ZSA+IGopCiAgICAgICAgICAgIG1lbW1vdmUoX2FyX2F0KHAsIGkpLCBfYXJfYXQocCwgaiksIChvbGRzaXplIC0gaikqc2VsZi0+aXRlbXNpemUpOwogICAgICAgIHNlbGYtPnNpemUgPSBvbGRzaXplIC0gbjsKICAgIH0KfQoKdm9pZCAqX2FyX2luc2VydCh2b2lkICpwLCBzaXplX3QgaSwgY29uc3Qgdm9pZCAqZmlyc3QsIHNpemVfdCBuKQp7CiAgICBhc3NlcnQocCAhPSAwKTsKICAgIF9IZWFkZXIgKnNlbGYgPSBfUFRSX1RPX0hEUihwKTsKCiAgICBzaXplX3Qgb2xkc2l6ZSA9IHNlbGYtPnNpemU7CiAgICBhc3NlcnQob2xkc2l6ZSA+PSBpKTsKCiAgICBpZiAobiAhPSAwKQogICAgewogICAgICAgIHNpemVfdCBzaXplOwogICAgICAgIGlmIChfX2J1aWx0aW5fYWRkX292ZXJmbG93KG9sZHNpemUsIG4sICZzaXplKSkKICAgICAgICAgICAgYXNzZXJ0KDAgJiYgImludGVnZXIgb3ZlcmZsb3ciKTsKCiAgICAgICAgaWYgKHNpemUgPiBzZWxmLT5jYXBhY2l0eSkKICAgICAgICB7CiAgICAgICAgICAgIHAgPSBfYXJfcmVzZXJ2ZShwLCBNQVgoMipzZWxmLT5jYXBhY2l0eSwgc2l6ZSkpOwogICAgICAgICAgICBzZWxmID0gX1BUUl9UT19IRFIocCk7CiAgICAgICAgfQogICAgICAgIHNlbGYtPnNpemUgPSBzaXplOwogICAgICAgIHZvaWQgKmlwID0gX2FyX2F0KHAsIGkpOwoKICAgICAgICBpZiAob2xkc2l6ZSA+IGkpCiAgICAgICAgICAgIG1lbW1vdmUoX2FyX2F0KHAsIGkgKyBuKSwgaXAsIChvbGRzaXplIC0gaSkqc2VsZi0+aXRlbXNpemUpOwogICAgICAgIG1lbWNweShpcCwgZmlyc3QsIG4qc2VsZi0+aXRlbXNpemUpOwogICAgfQogICAgcmV0dXJuIHA7Cn0KCnZvaWQgKl9hcl9wdXNoKHZvaWQgKnAsIGNvbnN0IHZvaWQgKml0ZW0pCnsKICAgIHJldHVybiBfYXJfaW5zZXJ0KHAsIF9hcl9zaXplKHApLCBpdGVtLCAxKTsKfQoKdm9pZCBfYXJfcG9wKHZvaWQgKnApCnsKICAgIF9hcl9yZW1vdmUocCwgX2FyX3NpemUocCktMSwgMSk7Cn0KCnZvaWQgX2FyX2NsZWFyKHZvaWQgKnApCnsKICAgIF9hcl9yZXNpemUocCwgMCwgMCk7Cn0KCnZvaWQgX2FyX3ByaW50KGNvbnN0IHZvaWQgKnAsIEZJTEUgKnN0cmVhbSkKewogICAgYXNzZXJ0KHAgIT0gMCk7CiAgICBjb25zdCBfSGVhZGVyICpzZWxmID0gX1BUUl9UT19IRFIocCk7CgogICAgYXNzZXJ0KHNlbGYtPnB1dGl0ZW0gIT0gMCk7CiAgICBzaXplX3QgbiA9IHNlbGYtPnNpemU7CgogICAgZnB1dGMoJ3snLCBzdHJlYW0pOwogICAgaWYgKG4gIT0gMCkKICAgIHsKICAgICAgICBmb3IgKHNpemVfdCBpID0gMDs7KQogICAgICAgIHsKICAgICAgICAgICAgc2VsZi0+cHV0aXRlbShfYXJfYXRfYyhwLCBpKSwgc3RyZWFtKTsKICAgICAgICAgICAgaWYgKCsraSA9PSBuKSBicmVhazsKICAgICAgICAgICAgZnB1dHMoIiwgIiwgc3RyZWFtKTsKICAgICAgICB9CiAgICB9CiAgICBmcHV0YygnfScsIHN0cmVhbSk7Cn0KCnZvaWQgX2FyX3ByaW50bG4oY29uc3Qgdm9pZCAqcCwgRklMRSAqc3RyZWFtKQp7CiAgICBfYXJfcHJpbnQocCwgc3RyZWFtKTsgZnB1dGMoJ1xuJywgc3RyZWFtKTsKfQoKLy8gUHV0aXRlbSBjYWxsYmFjay4KCnZvaWQgcHV0aXRlbV9hcihjb25zdCB2b2lkICppdGVtLCBGSUxFICpzdHJlYW0pCnsKICAgIF9hcl9wcmludCgqKGNvbnN0IHZvaWQgKiopaXRlbSwgc3RyZWFtKTsKfQoKdm9pZCBwdXRpdGVtX2ludChjb25zdCB2b2lkICppdGVtLCBGSUxFICpzdHJlYW0pCnsKICAgIGZwcmludGYoc3RyZWFtLCAiJWQiLCAqKGNvbnN0IGludCAqKWl0ZW0pOwp9CgovLyBUZXN0LgoKdm9pZCB0ZXN0X2luaXRfZnJlZSh2b2lkKQp7CiAgICBwcmludGYoIjwlcz5cbiIsIF9fZnVuY19fKTsKCiAgICAvLyBJbml0LgoKICAgIGludCAqcCA9IDA7CiAgICBhcl9pbml0KHApOwogICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gMCk7CiAgICBhcl9mcmVlKHApOwogICAgYXNzZXJ0KHAgPT0gMCk7CgogICAgLy8gSW5pdCBzaXplLgoKICAgIGFyX2luaXRfc2l6ZShwLCAzLCAxMjMpOwogICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gMyk7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBhc3NlcnQoYXJfYXQocCwgaSkgPT0gMTIzKTsKCiAgICAvLyBJbml0IGNvcHkuCgogICAgaW50ICpxID0gMDsKICAgIGFyX2luaXRfY29weShxLCBwKTsKICAgIGFyX2ZyZWUocCk7CiAgICBhc3NlcnQocCA9PSAwKTsKCiAgICBhc3NlcnQoYXJfc2l6ZShxKSA9PSAzKTsKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIGFzc2VydChhcl9hdChxLCBpKSA9PSAxMjMpOwogICAgYXJfZnJlZShxKTsKICAgIGFzc2VydChxID09IDApOwoKICAgIHB1dHMoIi4uT2theSIpOwp9Cgp2b2lkIHRlc3RfcHVzaF9wb3Aodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICpwID0gMDsKICAgIGFyX2luaXQocCk7CgogICAgLy8gUHVzaCAoYmFjaykuCgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspCiAgICB7CiAgICAgICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gaSk7CiAgICAgICAgaW50IGNwMiA9IGkgPyAxPDwoMzEgLSBfX2J1aWx0aW5fY2x6KDIqaS0xKSkgOiAwOwogICAgICAgIGFzc2VydChhcl9jYXBhY2l0eShwKSA9PSBjcDIpOwogICAgICAgIGFyX3B1c2gocCwgaSk7CiAgICAgICAgYXNzZXJ0KGFyX2F0KHAsIC0xKSA9PSBpKTsKICAgIH0KCiAgICAvLyBQb3AgKGJhY2spLgoKICAgIGZvciAoaW50IGkgPSA3OyBpID49IDA7IGktLSkKICAgIHsKICAgICAgICBhc3NlcnQoYXJfYXQocCwgLTEpID09IGkpOwogICAgICAgIGFyX3BvcChwKTsKICAgIH0KICAgIGFzc2VydChhcl9zaXplKHApID09IDApOwogICAgYXJfZnJlZShwKTsKCiAgICBwdXRzKCIuLk9rYXkiKTsKfQoKdm9pZCB0ZXN0X2luc2VydF9yZW1vdmUodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICpwID0gMDsKICAgIGFyX2luaXQocCk7CgogICAgLy8gSW5zZXJ0IGV2ZW4gKGJ1bGspLgoKICAgIGFyX2luc2VydChwLCAwLCAoKGludFtdKXswLCAyLCA0fSksIDMpOwogICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gMyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBhc3NlcnQoYXJfYXQocCwgaSkgPT0gMippKTsKCiAgICAvLyBJbnNlcnQgb2RkIChzaW5nbGUpLgoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIGFyX2luc2VydChwLCAyKmkrMSwgKGludFtdKXsyKmkrMX0sIDEpOwogICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gNik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IDY7IGkrKykKICAgICAgICBhc3NlcnQoYXJfYXQocCwgaSkgPT0gaSk7CgogICAgLy8gUmVtb3ZlIGV2ZW4gKHNpbmdsZSkuCgogICAgZm9yIChpbnQgaSA9IDI7IGkgPj0gMDsgaS0tKQogICAgICAgIGFyX3JlbW92ZShwLCAyKmksIDEpOwogICAgYXNzZXJ0KGFyX3NpemUocCkgPT0gMyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBhc3NlcnQoYXJfYXQocCwgaSkgPT0gMippKzEpOwoKICAgIC8vIFJlbW92ZSBvZGQgKGJ1bGspLgoKICAgIGFyX3JlbW92ZShwLCAwLCAzKTsKICAgIGFzc2VydChhcl9zaXplKHApID09IDApOwogICAgYXJfZnJlZShwKTsKCiAgICBwdXRzKCIuLk9rYXkiKTsKfQoKLy8gU2hvdy4KCnZvaWQgc2hvd19wdXNoX3BvcCh2b2lkKQp7CiAgICBwcmludGYoIjwlcz5cbiIsIF9fZnVuY19fKTsKCiAgICBpbnQgKnAgPSAwOwogICAgYXJfaW5pdChwKTsKICAgIGFyX3NldF9wdXRpdGVtKHAsIHB1dGl0ZW1faW50KTsKCiAgICBpbnQgbiA9IDQ7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCiAgICB7CiAgICAgICAgYXJfcHVzaChwLCBpKTsKICAgICAgICBhcl9wcmludGxuKHApOwogICAgfQoKICAgIHdoaWxlIChhcl9zaXplKHApICE9IDApCiAgICB7CiAgICAgICAgYXJfcG9wKHApOwogICAgICAgIGFyX3ByaW50bG4ocCk7CiAgICB9CgogICAgYXJfZnJlZShwKTsKfQoKdm9pZCBzaG93X2luc2VydF9yZW1vdmUodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICpwID0gMDsKICAgIGFyX2luaXQocCk7CiAgICBhcl9zZXRfcHV0aXRlbShwLCBwdXRpdGVtX2ludCk7CgogICAgaW50IG4gPSA0OwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgewogICAgICAgIGFyX2luc2VydChwLCBpLCAoKGludFtdKXtpKzEsIGkrMStufSksIDIpOwogICAgICAgIGFyX3ByaW50bG4ocCk7CiAgICB9CgogICAgZm9yIChpbnQgaSA9IG4tMTsgaSA+PSAwOyBpLS0pCiAgICB7CiAgICAgICAgYXJfcmVtb3ZlKHAsIGksIDIpOwogICAgICAgIGFyX3ByaW50bG4ocCk7CiAgICB9CgogICAgYXJfZnJlZShwKTsKfQoKdm9pZCBzaG93X3Jlc2l6ZSh2b2lkKQp7CiAgICBwcmludGYoIjwlcz5cbiIsIF9fZnVuY19fKTsKCiAgICBpbnQgKnAgPSAwOwogICAgYXJfaW5pdChwKTsKICAgIGFyX3NldF9wdXRpdGVtKHAsIHB1dGl0ZW1faW50KTsKCiAgICBpbnQgbiA9IDU7CgogICAgZm9yIChpbnQgaSA9IDE7IGkgPCBuOyBpKyspCiAgICB7CiAgICAgICAgYXJfcmVzaXplKHAsIGksIC1pKTsKICAgICAgICBhcl9wcmludGxuKHApOwogICAgICAgIGFyX2NsZWFyKHApOwogICAgfQoKICAgIGFyX2ZyZWUocCk7Cn0KCnZvaWQgc2hvd19hcnJheV9vZl9hcnJheSh2b2lkKQp7CiAgICBwcmludGYoIjwlcz5cbiIsIF9fZnVuY19fKTsKCiAgICBpbnQgKipwID0gMDsKICAgIGFyX2luaXQocCk7CiAgICBhcl9zZXRfcHV0aXRlbShwLCBwdXRpdGVtX2FyKTsKCiAgICBpbnQgbiA9IDQ7CiAgICBpbnQgdiA9IDE7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCiAgICB7CiAgICAgICAgaW50ICpxID0gMDsKICAgICAgICBhcl9pbml0KHEpOwogICAgICAgIGFyX3NldF9wdXRpdGVtKHEsIHB1dGl0ZW1faW50KTsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGkrMTsgaisrKQogICAgICAgICAgICBhcl9wdXNoKHEsIHYrKyk7CiAgICAgICAgYXJfcHVzaChwLCBxKTsKICAgICAgICBhcl9wcmludGxuKHApOwogICAgfQoKICAgIHdoaWxlIChhcl9zaXplKHApICE9IDApCiAgICB7CiAgICAgICAgaW50ICpxID0gYXJfYXQocCwgLTEpOwogICAgICAgIGFyX2ZyZWUocSk7CiAgICAgICAgYXJfcG9wKHApOwogICAgfQoKICAgIGFyX2ZyZWUocCk7Cn0KCmludCBtYWluKHZvaWQpCnsKICAgIHRlc3RfaW5pdF9mcmVlKCk7CiAgICB0ZXN0X3B1c2hfcG9wKCk7CiAgICB0ZXN0X2luc2VydF9yZW1vdmUoKTsKCiAgICBzaG93X3B1c2hfcG9wKCk7CiAgICBzaG93X2luc2VydF9yZW1vdmUoKTsKICAgIHNob3dfcmVzaXplKCk7CiAgICBzaG93X2FycmF5X29mX2FycmF5KCk7CiAgICByZXR1cm4gMDsKfQ==