/**
* @file array.002.c
* @ingroup experimental
* Dynamic array using hidden header.
* @date 08/13/2026
*/
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//
// Utility.
//
#define REF_T(T, ...) \
((T[]){__VA_ARGS__})
#define DEREF_T(T, p) \
(((T *)(void *)(p))[0])
#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*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;
}
//
// Array.
//
#define ar_size(a) _ar_size(a)
#define ar_itemsize(a) _ar_itemsize(a)
#define ar_capacity(a) _ar_capacity(a)
#define ar_putitem(a) _ar_putitem(a)
#define ar_set_putitem(a, f) _ar_set_putitem(a, f)
#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_reserve(a, n) ((a) = _ar_reserve(a, n))
#define ar_resize(a, n, v) ((a) = _ar_resize(a, n, (__typeof__(*(a))[]){v}))
#define ar_insert(a, i, s, n) ((a) = _ar_insert(a, i, s, n))
#define ar_remove(a, i, n) _ar_remove(a, i, 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_free(a) (_ar_free(a), (a) = 0)
#define ar_init(a, n) ((a) = _ar_init(sizeof *(a), n))
#define ar_init_size(a, n, v) ((a) = _ar_init_size(sizeof *(a), n, (__typeof__(*(a))[]){v}))
#define ar_init_copy(a, b, n) ((a) = (__typeof__(*(b)) *)_ar_init_copy(b, n))
#define ar_print(a) _ar_print(a, stdout)
#define ar_println(a) _ar_println(a, stdout)
// ..
#define _BASE_TO_SELF(p) ((_Header *)((char *)(p) - offsetof(_Header, _base)))
#define _SELF_TO_BASE(p) ((void *)((p)->_base))
typedef struct {
size_t size;
size_t itemsize;
size_t capacity;
void (*putitem)(const void *item, FILE *stream);
_Alignas(max_align_t) char _base[];
} _Header;
size_t _ar_size(const void *base)
{
return _BASE_TO_SELF(base)->size;
}
size_t _ar_itemsize(const void *base)
{
return _BASE_TO_SELF(base)->itemsize;
}
size_t _ar_capacity(const void *base)
{
return _BASE_TO_SELF(base)->capacity;
}
void (*_ar_putitem(const void *base))(const void *, FILE *)
{
return _BASE_TO_SELF(base)->putitem;
}
void _ar_set_putitem(void *base, void (*putitem)(const void *, FILE *))
{
_BASE_TO_SELF(base)->putitem = putitem;
}
const void *_ar_at_c(const void *base, ptrdiff_t i)
{
const _Header *self = _BASE_TO_SELF(base);
size_t size = self->size;
if (i < 0) i += size;
return (const char *)base + i*self->itemsize;
}
void *_ar_at(void *base, ptrdiff_t i)
{
return (void *)_ar_at_c(base, i);
}
void *_ar_reserve(void *base, size_t capacity)
{
// Ensure array has enough memory for capacity items.
_Header *self = _BASE_TO_SELF(base);
if (capacity > self->capacity)
{
self
= realloc(self
, sizeof *self
+ capacity
*self
->itemsize
); self->capacity = capacity;
}
return _SELF_TO_BASE(self);
}
void *_ar_resize(void *base, size_t size, const void *fill)
{
// Change array size and initialize newly revealed items to specified fill
// value. If fill is not provided, items are not initialized.
base = _ar_reserve(base, size);
_Header *self = _BASE_TO_SELF(base);
size_t oldsize = self->size;
self->size = size;
if (fill != 0 && size > oldsize)
memfill(_ar_at(base, oldsize), size - oldsize, self->itemsize, fill);
return base;
}
void *_ar_insert(void *base, size_t i, const void *first, size_t n)
{
// Insert n items starting at first into array at position i.
_Header *self = _BASE_TO_SELF(base);
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)
{
base = _ar_reserve(base, MAX(2*self->capacity, size));
self = _BASE_TO_SELF(base);
}
self->size = size;
void *ip = _ar_at(base, i);
if (oldsize > i)
memmove(_ar_at
(base
, i
+ n
), ip
, (oldsize
- i
)*self
->itemsize
); memcpy(ip
, first
, n
*self
->itemsize
); }
return base;
}
void _ar_remove(void *base, size_t i, size_t n)
{
// Remove n items from array starting at position i.
_Header *self = _BASE_TO_SELF(base);
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
(base
, i
), _ar_at
(base
, j
), (oldsize
- j
)*self
->itemsize
); self->size = oldsize - n;
}
}
void *_ar_push(void *base, const void *item)
{
return _ar_insert(base, _ar_size(base), item, 1);
}
void _ar_pop(void *base)
{
_ar_remove(base, _ar_size(base)-1, 1);
}
void _ar_clear(void *base)
{
_ar_resize(base, 0, 0);
}
void _ar_free(void *base)
{
if (base != 0)
free(_BASE_TO_SELF
(base
)); }
void *_ar_init(size_t itemsize, size_t capacity)
{
// Create array with enough memory for capacity items.
_Header
*self
= malloc(sizeof *self
+ capacity
*itemsize
); self->size = 0;
self->itemsize = itemsize;
self->capacity = capacity;
self->putitem = 0;
return _SELF_TO_BASE(self);
}
void *_ar_init_size(size_t itemsize, size_t size, const void *fill)
{
// Create array with size items and initialize with fill value.
return _ar_resize(_ar_init(itemsize, size), size, fill);
}
void *_ar_init_copy(const void *other_base, size_t capacity)
{
// Create copy of an array with at least capacity items reserved.
const _Header *other = _BASE_TO_SELF(other_base);
void *base = _ar_init(other->itemsize, MAX(other->size, capacity));
return _ar_insert(base, 0, other_base, other->size);
}
void _ar_print(const void *base, FILE *stream)
{
const _Header *self = _BASE_TO_SELF(base);
void (*putitem)(const void *, FILE *) = self->putitem;
size_t n = self->size;
if (n != 0)
{
for (size_t i = 0;;)
{
putitem(_ar_at_c(base, i), stream);
if (++i == n) break;
}
}
}
void _ar_println(const void *base, FILE *stream)
{
_ar_print
(base
, stream
); fputc('\n', stream
);}
//
// Main.
//
void test_init_free(void)
{
// Init.
int *a = 0;
ar_init(a, 0);
assert(ar_itemsize
(a
) == sizeof(*a
));
ar_free(a);
// Init (non-zero capacity).
ar_init(a, 8);
assert(ar_itemsize
(a
) == sizeof(*a
));
ar_free(a);
// Init size.
ar_init_size(a, 3, 123);
assert(ar_itemsize
(a
) == sizeof(*a
));
for (size_t i = 0; i < 3; i++)
// Init copy.
int *b = 0;
ar_init_copy(b, a, 0);
ar_free(a);
assert(ar_itemsize
(b
) == sizeof(*b
));
for (size_t i = 0; i < 3; i++)
// Init copy (non-zero capacity).
ar_init_copy(a, b, 8);
ar_free(b);
assert(ar_itemsize
(a
) == sizeof(*a
));
for (size_t i = 0; i < 3; i++)
ar_free(a);
}
void test_push_pop(void)
{
int *a = 0;
ar_init(a, 0);
// Push (back).
for (int i = 0; i < 8; i++)
{
ar_push(a, i);
assert(ar_size
(a
) == (size_t)i
+1); }
// Pop (back).
for (int i = 8-1; i >= 0; i--)
{
ar_pop(a);
assert(ar_size
(a
) == (size_t)i
); }
ar_free(a);
}
void test_insert_remove(void)
{
int *a = 0;
ar_init(a, 0);
// Insert even (bulk).
ar_insert(a, 0, REF_T(int, 0, 2, 4), 3);
for (int i = 0; i < 3; i++)
// Insert odd (single).
for (int i = 0; i < 3; i++)
ar_insert(a, 2*i+1, REF_T(int, 2*i+1), 1);
for (int i = 0; i < 6; i++)
// Remove even (single).
for (int i = 2; i >= 0; i--)
ar_remove(a, 2*i, 1);
for (int i = 0; i < 3; i++)
// Remove odd (bulk).
ar_remove(a, 0, 3);
ar_free(a);
}
void test_resize(void)
{
int *a = 0;
ar_init(a, 0);
// Resize (with clear).
for (int i = 0; i < 3; i++)
{
int n = i+1;
ar_resize(a, n, i);
assert(ar_size
(a
) == (size_t)n
); for (int j = 0; j < n; j++)
ar_clear(a);
}
// Resize (without clear).
for (int i = 0; i < 3; i++)
{
int n = i+1;
ar_resize(a, n, i);
assert(ar_size
(a
) == (size_t)n
); for (int j = 0; j < n; j++)
}
ar_free(a);
}
// ..
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
); }
int *iota(int n, int start, int step)
{
int *a = 0;
ar_init(a, MAX(n, 0));
ar_set_putitem(a, putitem_int);
for (int i = 0; i < n; i++)
ar_push(a, start + i*step);
return a;
}
void show_push_pop(void)
{
int *a = 0;
ar_init(a, 0);
ar_set_putitem(a, putitem_int);
int n = 4;
for (int i = 0; i < n; i++)
{
ar_push(a, i);
ar_println(a);
}
while (ar_size(a) != 0)
{
ar_pop(a);
ar_println(a);
}
ar_free(a);
}
void show_insert_remove(void)
{
int *a = 0;
ar_init(a, 0);
ar_set_putitem(a, putitem_int);
int n = 4;
for (int i = 0; i < n; i++)
{
ar_insert(a, i, REF_T(int, i+1, 2*n-i), 2);
ar_println(a);
}
for (int i = n-1; i >= 0; i--)
{
ar_remove(a, i, 2);
ar_println(a);
}
ar_free(a);
}
void show_resize(void)
{
int *a = 0;
ar_init(a, 0);
ar_set_putitem(a, putitem_int);
int n = 4;
for (int i = 1; i <= n; i++)
{
ar_resize(a, i, -i);
ar_println(a);
ar_clear(a);
}
for (int i = 1; i <= n; i++)
{
ar_resize(a, i, -i);
ar_println(a);
}
ar_free(a);
}
void show_array_of_array(void)
{
int **a = 0;
ar_init(a, 0);
ar_set_putitem(a, putitem_ar);
int n = 4;
for (int i = 0; i < n; i++)
{
int count = i+1;
int start = i*(i+1)/2+1;
ar_push(a, iota(count, start, 1));
ar_println(a);
}
for (size_t i = 0; i < ar_size(a); i++)
ar_free(a[i]);
ar_free(a);
}
int main(void)
{
test_init_free();
test_push_pop();
test_insert_remove();
test_resize();
show_push_pop();
show_insert_remove();
show_resize();
show_array_of_array();
return 0;
}
LyoqCiAqIEBmaWxlIGFycmF5LjAwMi5jCiAqIEBpbmdyb3VwIGV4cGVyaW1lbnRhbAogKiBEeW5hbWljIGFycmF5IHVzaW5nIGhpZGRlbiBoZWFkZXIuCiAqIEBkYXRlIDA4LzEzLzIwMjYKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKLy8KLy8gVXRpbGl0eS4KLy8KCiNkZWZpbmUgUkVGX1QoVCwgLi4uKSBcCiAgICAoKFRbXSl7X19WQV9BUkdTX199KQoKI2RlZmluZSBERVJFRl9UKFQsIHApIFwKICAgICgoKFQgKikodm9pZCAqKShwKSlbMF0pCgojZGVmaW5lIE1BWChhLCBiKSBcCih7IF9fYXV0b190eXBlIF94ID0gKGEpOyBfX2F1dG9fdHlwZSBfeSA9IChiKTsgXAogICAoX3kgPiBfeCkgPyBfeSA6IF94OyB9KQoKdm9pZCAqbWVtZmlsbCh2b2lkICpiYXNlLCBzaXplX3Qgbiwgc2l6ZV90IHNpemUsIGNvbnN0IHZvaWQgKmZpbGwpCnsKICAgIGlmIChuKnNpemUgIT0gMCkKICAgIHsKICAgICAgICBtZW1tb3ZlKGJhc2UsIGZpbGwsIHNpemUpOwogICAgICAgIHNpemVfdCBpID0gMTsKICAgICAgICBmb3IgKDsgaSA8PSBuLzI7IGkgKj0gMikKICAgICAgICAgICAgbWVtY3B5KChjaGFyICopYmFzZSArIGkqc2l6ZSwgYmFzZSwgaSpzaXplKTsKICAgICAgICBtZW1jcHkoKGNoYXIgKiliYXNlICsgaSpzaXplLCBiYXNlLCAobi1pKSpzaXplKTsKICAgIH0KICAgIHJldHVybiBiYXNlOwp9CgovLwovLyBBcnJheS4KLy8KCiNkZWZpbmUgYXJfc2l6ZShhKSBfYXJfc2l6ZShhKQojZGVmaW5lIGFyX2l0ZW1zaXplKGEpIF9hcl9pdGVtc2l6ZShhKQojZGVmaW5lIGFyX2NhcGFjaXR5KGEpIF9hcl9jYXBhY2l0eShhKQojZGVmaW5lIGFyX3B1dGl0ZW0oYSkgX2FyX3B1dGl0ZW0oYSkKI2RlZmluZSBhcl9zZXRfcHV0aXRlbShhLCBmKSBfYXJfc2V0X3B1dGl0ZW0oYSwgZikKI2RlZmluZSBhcl9hdChhLCBpKSAoKChfX3R5cGVvZl9fKCooYSkpICopX2FyX2F0KGEsIGkpKVswXSkKI2RlZmluZSBhcl9hdF9jKGEsIGkpICgoKGNvbnN0IF9fdHlwZW9mX18oKihhKSkgKilfYXJfYXRfYyhhLCBpKSlbMF0pCiNkZWZpbmUgYXJfcmVzZXJ2ZShhLCBuKSAoKGEpID0gX2FyX3Jlc2VydmUoYSwgbikpCiNkZWZpbmUgYXJfcmVzaXplKGEsIG4sIHYpICgoYSkgPSBfYXJfcmVzaXplKGEsIG4sIChfX3R5cGVvZl9fKCooYSkpW10pe3Z9KSkKI2RlZmluZSBhcl9pbnNlcnQoYSwgaSwgcywgbikgKChhKSA9IF9hcl9pbnNlcnQoYSwgaSwgcywgbikpCiNkZWZpbmUgYXJfcmVtb3ZlKGEsIGksIG4pIF9hcl9yZW1vdmUoYSwgaSwgbikKI2RlZmluZSBhcl9wdXNoKGEsIHYpICgoYSkgPSBfYXJfcHVzaChhLCAoX190eXBlb2ZfXygqKGEpKVtdKXt2fSkpCiNkZWZpbmUgYXJfcG9wKGEpIF9hcl9wb3AoYSkKI2RlZmluZSBhcl9jbGVhcihhKSBfYXJfY2xlYXIoYSkKI2RlZmluZSBhcl9mcmVlKGEpIChfYXJfZnJlZShhKSwgKGEpID0gMCkKI2RlZmluZSBhcl9pbml0KGEsIG4pICgoYSkgPSBfYXJfaW5pdChzaXplb2YgKihhKSwgbikpCiNkZWZpbmUgYXJfaW5pdF9zaXplKGEsIG4sIHYpICgoYSkgPSBfYXJfaW5pdF9zaXplKHNpemVvZiAqKGEpLCBuLCAoX190eXBlb2ZfXygqKGEpKVtdKXt2fSkpCiNkZWZpbmUgYXJfaW5pdF9jb3B5KGEsIGIsIG4pICgoYSkgPSAoX190eXBlb2ZfXygqKGIpKSAqKV9hcl9pbml0X2NvcHkoYiwgbikpCiNkZWZpbmUgYXJfcHJpbnQoYSkgX2FyX3ByaW50KGEsIHN0ZG91dCkKI2RlZmluZSBhcl9wcmludGxuKGEpIF9hcl9wcmludGxuKGEsIHN0ZG91dCkKCi8vIC4uCgojZGVmaW5lIF9CQVNFX1RPX1NFTEYocCkgKChfSGVhZGVyICopKChjaGFyICopKHApIC0gb2Zmc2V0b2YoX0hlYWRlciwgX2Jhc2UpKSkKI2RlZmluZSBfU0VMRl9UT19CQVNFKHApICgodm9pZCAqKSgocCktPl9iYXNlKSkKCnR5cGVkZWYgc3RydWN0IHsKICAgIHNpemVfdCBzaXplOwogICAgc2l6ZV90IGl0ZW1zaXplOwogICAgc2l6ZV90IGNhcGFjaXR5OwogICAgdm9pZCAoKnB1dGl0ZW0pKGNvbnN0IHZvaWQgKml0ZW0sIEZJTEUgKnN0cmVhbSk7CiAgICBfQWxpZ25hcyhtYXhfYWxpZ25fdCkgY2hhciBfYmFzZVtdOwp9IF9IZWFkZXI7CgpzaXplX3QgX2FyX3NpemUoY29uc3Qgdm9pZCAqYmFzZSkKewogICAgYXNzZXJ0KGJhc2UgIT0gMCk7CiAgICByZXR1cm4gX0JBU0VfVE9fU0VMRihiYXNlKS0+c2l6ZTsKfQoKc2l6ZV90IF9hcl9pdGVtc2l6ZShjb25zdCB2b2lkICpiYXNlKQp7CiAgICBhc3NlcnQoYmFzZSAhPSAwKTsKICAgIHJldHVybiBfQkFTRV9UT19TRUxGKGJhc2UpLT5pdGVtc2l6ZTsKfQoKc2l6ZV90IF9hcl9jYXBhY2l0eShjb25zdCB2b2lkICpiYXNlKQp7CiAgICBhc3NlcnQoYmFzZSAhPSAwKTsKICAgIHJldHVybiBfQkFTRV9UT19TRUxGKGJhc2UpLT5jYXBhY2l0eTsKfQoKdm9pZCAoKl9hcl9wdXRpdGVtKGNvbnN0IHZvaWQgKmJhc2UpKShjb25zdCB2b2lkICosIEZJTEUgKikKewogICAgYXNzZXJ0KGJhc2UgIT0gMCk7CiAgICByZXR1cm4gX0JBU0VfVE9fU0VMRihiYXNlKS0+cHV0aXRlbTsKfQoKdm9pZCBfYXJfc2V0X3B1dGl0ZW0odm9pZCAqYmFzZSwgdm9pZCAoKnB1dGl0ZW0pKGNvbnN0IHZvaWQgKiwgRklMRSAqKSkKewogICAgYXNzZXJ0KGJhc2UgIT0gMCk7CiAgICBfQkFTRV9UT19TRUxGKGJhc2UpLT5wdXRpdGVtID0gcHV0aXRlbTsKfQoKY29uc3Qgdm9pZCAqX2FyX2F0X2MoY29uc3Qgdm9pZCAqYmFzZSwgcHRyZGlmZl90IGkpCnsKICAgIGFzc2VydChiYXNlICE9IDApOwogICAgY29uc3QgX0hlYWRlciAqc2VsZiA9IF9CQVNFX1RPX1NFTEYoYmFzZSk7CgogICAgc2l6ZV90IHNpemUgPSBzZWxmLT5zaXplOwogICAgaWYgKGkgPCAwKSBpICs9IHNpemU7CiAgICBhc3NlcnQoKHNpemVfdClpIDwgc2l6ZSk7CiAgICByZXR1cm4gKGNvbnN0IGNoYXIgKiliYXNlICsgaSpzZWxmLT5pdGVtc2l6ZTsKfQoKdm9pZCAqX2FyX2F0KHZvaWQgKmJhc2UsIHB0cmRpZmZfdCBpKQp7CiAgICByZXR1cm4gKHZvaWQgKilfYXJfYXRfYyhiYXNlLCBpKTsKfQoKdm9pZCAqX2FyX3Jlc2VydmUodm9pZCAqYmFzZSwgc2l6ZV90IGNhcGFjaXR5KQp7CiAgICAvLyBFbnN1cmUgYXJyYXkgaGFzIGVub3VnaCBtZW1vcnkgZm9yIGNhcGFjaXR5IGl0ZW1zLgoKICAgIGFzc2VydChiYXNlICE9IDApOwogICAgX0hlYWRlciAqc2VsZiA9IF9CQVNFX1RPX1NFTEYoYmFzZSk7CgogICAgaWYgKGNhcGFjaXR5ID4gc2VsZi0+Y2FwYWNpdHkpCiAgICB7CiAgICAgICAgc2VsZiA9IHJlYWxsb2Moc2VsZiwgc2l6ZW9mICpzZWxmICsgY2FwYWNpdHkqc2VsZi0+aXRlbXNpemUpOwogICAgICAgIGFzc2VydChzZWxmICE9IDApOwogICAgICAgIHNlbGYtPmNhcGFjaXR5ID0gY2FwYWNpdHk7CiAgICB9CiAgICByZXR1cm4gX1NFTEZfVE9fQkFTRShzZWxmKTsKfQoKdm9pZCAqX2FyX3Jlc2l6ZSh2b2lkICpiYXNlLCBzaXplX3Qgc2l6ZSwgY29uc3Qgdm9pZCAqZmlsbCkKewogICAgLy8gQ2hhbmdlIGFycmF5IHNpemUgYW5kIGluaXRpYWxpemUgbmV3bHkgcmV2ZWFsZWQgaXRlbXMgdG8gc3BlY2lmaWVkIGZpbGwKICAgIC8vIHZhbHVlLiBJZiBmaWxsIGlzIG5vdCBwcm92aWRlZCwgaXRlbXMgYXJlIG5vdCBpbml0aWFsaXplZC4KCiAgICBhc3NlcnQoYmFzZSAhPSAwKTsKICAgIGJhc2UgPSBfYXJfcmVzZXJ2ZShiYXNlLCBzaXplKTsKCiAgICBfSGVhZGVyICpzZWxmID0gX0JBU0VfVE9fU0VMRihiYXNlKTsKICAgIHNpemVfdCBvbGRzaXplID0gc2VsZi0+c2l6ZTsKICAgIHNlbGYtPnNpemUgPSBzaXplOwoKICAgIGlmIChmaWxsICE9IDAgJiYgc2l6ZSA+IG9sZHNpemUpCiAgICAgICAgbWVtZmlsbChfYXJfYXQoYmFzZSwgb2xkc2l6ZSksIHNpemUgLSBvbGRzaXplLCBzZWxmLT5pdGVtc2l6ZSwgZmlsbCk7CiAgICByZXR1cm4gYmFzZTsKfQoKdm9pZCAqX2FyX2luc2VydCh2b2lkICpiYXNlLCBzaXplX3QgaSwgY29uc3Qgdm9pZCAqZmlyc3QsIHNpemVfdCBuKQp7CiAgICAvLyBJbnNlcnQgbiBpdGVtcyBzdGFydGluZyBhdCBmaXJzdCBpbnRvIGFycmF5IGF0IHBvc2l0aW9uIGkuCgogICAgYXNzZXJ0KGJhc2UgIT0gMCk7CiAgICBfSGVhZGVyICpzZWxmID0gX0JBU0VfVE9fU0VMRihiYXNlKTsKCiAgICBzaXplX3Qgb2xkc2l6ZSA9IHNlbGYtPnNpemU7CiAgICBhc3NlcnQob2xkc2l6ZSA+PSBpKTsKCiAgICBpZiAobiAhPSAwKQogICAgewogICAgICAgIHNpemVfdCBzaXplOwogICAgICAgIGlmIChfX2J1aWx0aW5fYWRkX292ZXJmbG93KG9sZHNpemUsIG4sICZzaXplKSkKICAgICAgICAgICAgYXNzZXJ0KDAgJiYgImludGVnZXIgb3ZlcmZsb3ciKTsKCiAgICAgICAgaWYgKHNpemUgPiBzZWxmLT5jYXBhY2l0eSkKICAgICAgICB7CiAgICAgICAgICAgIGJhc2UgPSBfYXJfcmVzZXJ2ZShiYXNlLCBNQVgoMipzZWxmLT5jYXBhY2l0eSwgc2l6ZSkpOwogICAgICAgICAgICBzZWxmID0gX0JBU0VfVE9fU0VMRihiYXNlKTsKICAgICAgICB9CiAgICAgICAgc2VsZi0+c2l6ZSA9IHNpemU7CiAgICAgICAgdm9pZCAqaXAgPSBfYXJfYXQoYmFzZSwgaSk7CgogICAgICAgIGlmIChvbGRzaXplID4gaSkKICAgICAgICAgICAgbWVtbW92ZShfYXJfYXQoYmFzZSwgaSArIG4pLCBpcCwgKG9sZHNpemUgLSBpKSpzZWxmLT5pdGVtc2l6ZSk7CiAgICAgICAgbWVtY3B5KGlwLCBmaXJzdCwgbipzZWxmLT5pdGVtc2l6ZSk7CiAgICB9CiAgICByZXR1cm4gYmFzZTsKfQoKdm9pZCBfYXJfcmVtb3ZlKHZvaWQgKmJhc2UsIHNpemVfdCBpLCBzaXplX3QgbikKewogICAgLy8gUmVtb3ZlIG4gaXRlbXMgZnJvbSBhcnJheSBzdGFydGluZyBhdCBwb3NpdGlvbiBpLgoKICAgIGFzc2VydChiYXNlICE9IDApOwogICAgX0hlYWRlciAqc2VsZiA9IF9CQVNFX1RPX1NFTEYoYmFzZSk7CgogICAgc2l6ZV90IG9sZHNpemUgPSBzZWxmLT5zaXplOwogICAgYXNzZXJ0KG9sZHNpemUgPj0gaSk7CgogICAgaWYgKG4gIT0gMCkKICAgIHsKICAgICAgICBzaXplX3QgajsKICAgICAgICBpZiAoX19idWlsdGluX2FkZF9vdmVyZmxvdyhpLCBuLCAmaikpCiAgICAgICAgICAgIGFzc2VydCgwICYmICJpbnRlZ2VyIG92ZXJmbG93Iik7CiAgICAgICAgYXNzZXJ0KG9sZHNpemUgPj0gaik7CgogICAgICAgIGlmIChvbGRzaXplID4gaikKICAgICAgICAgICAgbWVtbW92ZShfYXJfYXQoYmFzZSwgaSksIF9hcl9hdChiYXNlLCBqKSwgKG9sZHNpemUgLSBqKSpzZWxmLT5pdGVtc2l6ZSk7CiAgICAgICAgc2VsZi0+c2l6ZSA9IG9sZHNpemUgLSBuOwogICAgfQp9Cgp2b2lkICpfYXJfcHVzaCh2b2lkICpiYXNlLCBjb25zdCB2b2lkICppdGVtKQp7CiAgICByZXR1cm4gX2FyX2luc2VydChiYXNlLCBfYXJfc2l6ZShiYXNlKSwgaXRlbSwgMSk7Cn0KCnZvaWQgX2FyX3BvcCh2b2lkICpiYXNlKQp7CiAgICBfYXJfcmVtb3ZlKGJhc2UsIF9hcl9zaXplKGJhc2UpLTEsIDEpOwp9Cgp2b2lkIF9hcl9jbGVhcih2b2lkICpiYXNlKQp7CiAgICBfYXJfcmVzaXplKGJhc2UsIDAsIDApOwp9Cgp2b2lkIF9hcl9mcmVlKHZvaWQgKmJhc2UpCnsKICAgIGlmIChiYXNlICE9IDApCiAgICAgICAgZnJlZShfQkFTRV9UT19TRUxGKGJhc2UpKTsKfQoKdm9pZCAqX2FyX2luaXQoc2l6ZV90IGl0ZW1zaXplLCBzaXplX3QgY2FwYWNpdHkpCnsKICAgIC8vIENyZWF0ZSBhcnJheSB3aXRoIGVub3VnaCBtZW1vcnkgZm9yIGNhcGFjaXR5IGl0ZW1zLgoKICAgIF9IZWFkZXIgKnNlbGYgPSBtYWxsb2Moc2l6ZW9mICpzZWxmICsgY2FwYWNpdHkqaXRlbXNpemUpOwogICAgYXNzZXJ0KHNlbGYgIT0gMCk7CiAgICBzZWxmLT5zaXplID0gMDsKICAgIHNlbGYtPml0ZW1zaXplID0gaXRlbXNpemU7CiAgICBzZWxmLT5jYXBhY2l0eSA9IGNhcGFjaXR5OwogICAgc2VsZi0+cHV0aXRlbSA9IDA7CiAgICByZXR1cm4gX1NFTEZfVE9fQkFTRShzZWxmKTsKfQoKdm9pZCAqX2FyX2luaXRfc2l6ZShzaXplX3QgaXRlbXNpemUsIHNpemVfdCBzaXplLCBjb25zdCB2b2lkICpmaWxsKQp7CiAgICAvLyBDcmVhdGUgYXJyYXkgd2l0aCBzaXplIGl0ZW1zIGFuZCBpbml0aWFsaXplIHdpdGggZmlsbCB2YWx1ZS4KCiAgICByZXR1cm4gX2FyX3Jlc2l6ZShfYXJfaW5pdChpdGVtc2l6ZSwgc2l6ZSksIHNpemUsIGZpbGwpOwp9Cgp2b2lkICpfYXJfaW5pdF9jb3B5KGNvbnN0IHZvaWQgKm90aGVyX2Jhc2UsIHNpemVfdCBjYXBhY2l0eSkKewogICAgLy8gQ3JlYXRlIGNvcHkgb2YgYW4gYXJyYXkgd2l0aCBhdCBsZWFzdCBjYXBhY2l0eSBpdGVtcyByZXNlcnZlZC4KCiAgICBhc3NlcnQob3RoZXJfYmFzZSAhPSAwKTsKICAgIGNvbnN0IF9IZWFkZXIgKm90aGVyID0gX0JBU0VfVE9fU0VMRihvdGhlcl9iYXNlKTsKCiAgICB2b2lkICpiYXNlID0gX2FyX2luaXQob3RoZXItPml0ZW1zaXplLCBNQVgob3RoZXItPnNpemUsIGNhcGFjaXR5KSk7CiAgICByZXR1cm4gX2FyX2luc2VydChiYXNlLCAwLCBvdGhlcl9iYXNlLCBvdGhlci0+c2l6ZSk7Cn0KCnZvaWQgX2FyX3ByaW50KGNvbnN0IHZvaWQgKmJhc2UsIEZJTEUgKnN0cmVhbSkKewogICAgYXNzZXJ0KGJhc2UgIT0gMCk7CiAgICBjb25zdCBfSGVhZGVyICpzZWxmID0gX0JBU0VfVE9fU0VMRihiYXNlKTsKCiAgICB2b2lkICgqcHV0aXRlbSkoY29uc3Qgdm9pZCAqLCBGSUxFICopID0gc2VsZi0+cHV0aXRlbTsKICAgIGFzc2VydChwdXRpdGVtICE9IDApOwoKICAgIHNpemVfdCBuID0gc2VsZi0+c2l6ZTsKCiAgICBmcHV0YygneycsIHN0cmVhbSk7CiAgICBpZiAobiAhPSAwKQogICAgewogICAgICAgIGZvciAoc2l6ZV90IGkgPSAwOzspCiAgICAgICAgewogICAgICAgICAgICBwdXRpdGVtKF9hcl9hdF9jKGJhc2UsIGkpLCBzdHJlYW0pOwogICAgICAgICAgICBpZiAoKytpID09IG4pIGJyZWFrOwogICAgICAgICAgICBmcHV0cygiLCAiLCBzdHJlYW0pOwogICAgICAgIH0KICAgIH0KICAgIGZwdXRjKCd9Jywgc3RyZWFtKTsKfQoKdm9pZCBfYXJfcHJpbnRsbihjb25zdCB2b2lkICpiYXNlLCBGSUxFICpzdHJlYW0pCnsKICAgIF9hcl9wcmludChiYXNlLCBzdHJlYW0pOyBmcHV0YygnXG4nLCBzdHJlYW0pOwp9CgovLwovLyBNYWluLgovLwoKdm9pZCB0ZXN0X2luaXRfZnJlZSh2b2lkKQp7CiAgICBwcmludGYoIjwlcz5cbiIsIF9fZnVuY19fKTsKCiAgICAvLyBJbml0LgoKICAgIGludCAqYSA9IDA7CiAgICBhcl9pbml0KGEsIDApOwogICAgYXNzZXJ0KGFyX3NpemUoYSkgPT0gMCk7CiAgICBhc3NlcnQoYXJfaXRlbXNpemUoYSkgPT0gc2l6ZW9mKCphKSk7CiAgICBhc3NlcnQoYXJfY2FwYWNpdHkoYSkgPT0gMCk7CgogICAgYXJfZnJlZShhKTsKICAgIGFzc2VydChhID09IDApOwoKICAgIC8vIEluaXQgKG5vbi16ZXJvIGNhcGFjaXR5KS4KCiAgICBhcl9pbml0KGEsIDgpOwogICAgYXNzZXJ0KGFyX3NpemUoYSkgPT0gMCk7CiAgICBhc3NlcnQoYXJfaXRlbXNpemUoYSkgPT0gc2l6ZW9mKCphKSk7CiAgICBhc3NlcnQoYXJfY2FwYWNpdHkoYSkgPT0gOCk7CgogICAgYXJfZnJlZShhKTsKICAgIGFzc2VydChhID09IDApOwoKICAgIC8vIEluaXQgc2l6ZS4KCiAgICBhcl9pbml0X3NpemUoYSwgMywgMTIzKTsKICAgIGFzc2VydChhcl9zaXplKGEpID09IDMpOwogICAgYXNzZXJ0KGFyX2l0ZW1zaXplKGEpID09IHNpemVvZigqYSkpOwogICAgYXNzZXJ0KGFyX2NhcGFjaXR5KGEpID09IDMpOwoKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIGFzc2VydChhcl9hdChhLCBpKSA9PSAxMjMpOwoKICAgIC8vIEluaXQgY29weS4KCiAgICBpbnQgKmIgPSAwOwogICAgYXJfaW5pdF9jb3B5KGIsIGEsIDApOwoKICAgIGFyX2ZyZWUoYSk7CiAgICBhc3NlcnQoYSA9PSAwKTsKCiAgICBhc3NlcnQoYXJfc2l6ZShiKSA9PSAzKTsKICAgIGFzc2VydChhcl9pdGVtc2l6ZShiKSA9PSBzaXplb2YoKmIpKTsKICAgIGFzc2VydChhcl9jYXBhY2l0eShiKSA9PSAzKTsKCiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBhc3NlcnQoYXJfYXQoYiwgaSkgPT0gMTIzKTsKCiAgICAvLyBJbml0IGNvcHkgKG5vbi16ZXJvIGNhcGFjaXR5KS4KCiAgICBhcl9pbml0X2NvcHkoYSwgYiwgOCk7CgogICAgYXJfZnJlZShiKTsKICAgIGFzc2VydChiID09IDApOwoKICAgIGFzc2VydChhcl9zaXplKGEpID09IDMpOwogICAgYXNzZXJ0KGFyX2l0ZW1zaXplKGEpID09IHNpemVvZigqYSkpOwogICAgYXNzZXJ0KGFyX2NhcGFjaXR5KGEpID09IDgpOwoKICAgIGZvciAoc2l6ZV90IGkgPSAwOyBpIDwgMzsgaSsrKQogICAgICAgIGFzc2VydChhcl9hdChhLCBpKSA9PSAxMjMpOwogICAgYXJfZnJlZShhKTsKICAgIGFzc2VydChhID09IDApOwoKICAgIHB1dHMoIi4uT2theSIpOwp9Cgp2b2lkIHRlc3RfcHVzaF9wb3Aodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICphID0gMDsKICAgIGFyX2luaXQoYSwgMCk7CgogICAgLy8gUHVzaCAoYmFjaykuCgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspCiAgICB7CiAgICAgICAgYXJfcHVzaChhLCBpKTsKICAgICAgICBhc3NlcnQoYXJfc2l6ZShhKSA9PSAoc2l6ZV90KWkrMSk7CiAgICAgICAgYXNzZXJ0KGFyX2F0KGEsIC0xKSA9PSBpKTsKICAgIH0KCiAgICAvLyBQb3AgKGJhY2spLgoKICAgIGZvciAoaW50IGkgPSA4LTE7IGkgPj0gMDsgaS0tKQogICAgewogICAgICAgIGFzc2VydChhcl9hdChhLCAtMSkgPT0gaSk7CiAgICAgICAgYXJfcG9wKGEpOwogICAgICAgIGFzc2VydChhcl9zaXplKGEpID09IChzaXplX3QpaSk7CiAgICB9CgogICAgYXJfZnJlZShhKTsKCiAgICBwdXRzKCIuLk9rYXkiKTsKfQoKdm9pZCB0ZXN0X2luc2VydF9yZW1vdmUodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICphID0gMDsKICAgIGFyX2luaXQoYSwgMCk7CgogICAgLy8gSW5zZXJ0IGV2ZW4gKGJ1bGspLgoKICAgIGFyX2luc2VydChhLCAwLCBSRUZfVChpbnQsIDAsIDIsIDQpLCAzKTsKICAgIGFzc2VydChhcl9zaXplKGEpID09IDMpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspCiAgICAgICAgYXNzZXJ0KGFyX2F0KGEsIGkpID09IDIqaSk7CgogICAgLy8gSW5zZXJ0IG9kZCAoc2luZ2xlKS4KCiAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykKICAgICAgICBhcl9pbnNlcnQoYSwgMippKzEsIFJFRl9UKGludCwgMippKzEpLCAxKTsKICAgIGFzc2VydChhcl9zaXplKGEpID09IDYpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCA2OyBpKyspCiAgICAgICAgYXNzZXJ0KGFyX2F0KGEsIGkpID09IGkpOwoKICAgIC8vIFJlbW92ZSBldmVuIChzaW5nbGUpLgoKICAgIGZvciAoaW50IGkgPSAyOyBpID49IDA7IGktLSkKICAgICAgICBhcl9yZW1vdmUoYSwgMippLCAxKTsKICAgIGFzc2VydChhcl9zaXplKGEpID09IDMpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspCiAgICAgICAgYXNzZXJ0KGFyX2F0KGEsIGkpID09IDIqaSsxKTsKCiAgICAvLyBSZW1vdmUgb2RkIChidWxrKS4KCiAgICBhcl9yZW1vdmUoYSwgMCwgMyk7CiAgICBhc3NlcnQoYXJfc2l6ZShhKSA9PSAwKTsKICAgIGFyX2ZyZWUoYSk7CgogICAgcHV0cygiLi5Pa2F5Iik7Cn0KCnZvaWQgdGVzdF9yZXNpemUodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICphID0gMDsKICAgIGFyX2luaXQoYSwgMCk7CgogICAgLy8gUmVzaXplICh3aXRoIGNsZWFyKS4KCiAgICBmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykKICAgIHsKICAgICAgICBpbnQgbiA9IGkrMTsKICAgICAgICBhcl9yZXNpemUoYSwgbiwgaSk7CiAgICAgICAgYXNzZXJ0KGFyX3NpemUoYSkgPT0gKHNpemVfdCluKTsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG47IGorKykKICAgICAgICAgICAgYXNzZXJ0KGFyX2F0KGEsIGopID09IGkpOwogICAgICAgIGFyX2NsZWFyKGEpOwogICAgICAgIGFzc2VydChhcl9zaXplKGEpID09IDApOwogICAgfQoKICAgIC8vIFJlc2l6ZSAod2l0aG91dCBjbGVhcikuCgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAzOyBpKyspCiAgICB7CiAgICAgICAgaW50IG4gPSBpKzE7CiAgICAgICAgYXJfcmVzaXplKGEsIG4sIGkpOwogICAgICAgIGFzc2VydChhcl9zaXplKGEpID09IChzaXplX3Qpbik7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBuOyBqKyspCiAgICAgICAgICAgIGFzc2VydChhcl9hdChhLCBqKSA9PSBqKTsKICAgIH0KCiAgICBhcl9mcmVlKGEpOwoKICAgIHB1dHMoIi4uT2theSIpOwp9CgovLyAuLgoKdm9pZCBwdXRpdGVtX2FyKGNvbnN0IHZvaWQgKml0ZW0sIEZJTEUgKnN0cmVhbSkKewogICAgX2FyX3ByaW50KCooY29uc3Qgdm9pZCAqKilpdGVtLCBzdHJlYW0pOwp9Cgp2b2lkIHB1dGl0ZW1faW50KGNvbnN0IHZvaWQgKml0ZW0sIEZJTEUgKnN0cmVhbSkKewogICAgZnByaW50ZihzdHJlYW0sICIlZCIsICooY29uc3QgaW50ICopaXRlbSk7Cn0KCmludCAqaW90YShpbnQgbiwgaW50IHN0YXJ0LCBpbnQgc3RlcCkKewogICAgaW50ICphID0gMDsKICAgIGFyX2luaXQoYSwgTUFYKG4sIDApKTsKICAgIGFyX3NldF9wdXRpdGVtKGEsIHB1dGl0ZW1faW50KTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgICAgIGFyX3B1c2goYSwgc3RhcnQgKyBpKnN0ZXApOwogICAgcmV0dXJuIGE7Cn0KCnZvaWQgc2hvd19wdXNoX3BvcCh2b2lkKQp7CiAgICBwcmludGYoIjwlcz5cbiIsIF9fZnVuY19fKTsKCiAgICBpbnQgKmEgPSAwOwogICAgYXJfaW5pdChhLCAwKTsKICAgIGFyX3NldF9wdXRpdGVtKGEsIHB1dGl0ZW1faW50KTsKCiAgICBpbnQgbiA9IDQ7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCiAgICB7CiAgICAgICAgYXJfcHVzaChhLCBpKTsKICAgICAgICBhcl9wcmludGxuKGEpOwogICAgfQoKICAgIHdoaWxlIChhcl9zaXplKGEpICE9IDApCiAgICB7CiAgICAgICAgYXJfcG9wKGEpOwogICAgICAgIGFyX3ByaW50bG4oYSk7CiAgICB9CgogICAgYXJfZnJlZShhKTsKfQoKdm9pZCBzaG93X2luc2VydF9yZW1vdmUodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICphID0gMDsKICAgIGFyX2luaXQoYSwgMCk7CiAgICBhcl9zZXRfcHV0aXRlbShhLCBwdXRpdGVtX2ludCk7CgogICAgaW50IG4gPSA0OwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgewogICAgICAgIGFyX2luc2VydChhLCBpLCBSRUZfVChpbnQsIGkrMSwgMipuLWkpLCAyKTsKICAgICAgICBhcl9wcmludGxuKGEpOwogICAgfQoKICAgIGZvciAoaW50IGkgPSBuLTE7IGkgPj0gMDsgaS0tKQogICAgewogICAgICAgIGFyX3JlbW92ZShhLCBpLCAyKTsKICAgICAgICBhcl9wcmludGxuKGEpOwogICAgfQoKICAgIGFyX2ZyZWUoYSk7Cn0KCnZvaWQgc2hvd19yZXNpemUodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICphID0gMDsKICAgIGFyX2luaXQoYSwgMCk7CiAgICBhcl9zZXRfcHV0aXRlbShhLCBwdXRpdGVtX2ludCk7CgogICAgaW50IG4gPSA0OwoKICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IG47IGkrKykKICAgIHsKICAgICAgICBhcl9yZXNpemUoYSwgaSwgLWkpOwogICAgICAgIGFyX3ByaW50bG4oYSk7CiAgICAgICAgYXJfY2xlYXIoYSk7CiAgICB9CgogICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKQogICAgewogICAgICAgIGFyX3Jlc2l6ZShhLCBpLCAtaSk7CiAgICAgICAgYXJfcHJpbnRsbihhKTsKICAgIH0KCiAgICBhcl9mcmVlKGEpOwp9Cgp2b2lkIHNob3dfYXJyYXlfb2ZfYXJyYXkodm9pZCkKewogICAgcHJpbnRmKCI8JXM+XG4iLCBfX2Z1bmNfXyk7CgogICAgaW50ICoqYSA9IDA7CiAgICBhcl9pbml0KGEsIDApOwogICAgYXJfc2V0X3B1dGl0ZW0oYSwgcHV0aXRlbV9hcik7CgogICAgaW50IG4gPSA0OwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgewogICAgICAgIGludCBjb3VudCA9IGkrMTsKICAgICAgICBpbnQgc3RhcnQgPSBpKihpKzEpLzIrMTsKICAgICAgICBhcl9wdXNoKGEsIGlvdGEoY291bnQsIHN0YXJ0LCAxKSk7CiAgICAgICAgYXJfcHJpbnRsbihhKTsKICAgIH0KCiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IGFyX3NpemUoYSk7IGkrKykKICAgICAgICBhcl9mcmVlKGFbaV0pOwogICAgYXJfZnJlZShhKTsKfQoKaW50IG1haW4odm9pZCkKewogICAgdGVzdF9pbml0X2ZyZWUoKTsKICAgIHRlc3RfcHVzaF9wb3AoKTsKICAgIHRlc3RfaW5zZXJ0X3JlbW92ZSgpOwogICAgdGVzdF9yZXNpemUoKTsKCiAgICBzaG93X3B1c2hfcG9wKCk7CiAgICBzaG93X2luc2VydF9yZW1vdmUoKTsKICAgIHNob3dfcmVzaXplKCk7CiAgICBzaG93X2FycmF5X29mX2FycmF5KCk7CiAgICByZXR1cm4gMDsKfQ==