// Join items on output stream. (3.03)
#include <stdio.h>
void ostream_join(
const void *base, size_t nitems, size_t itemsize,
void (*putitem)(const void *item, FILE *stream),
const char *separator, FILE *stream, _Bool reverse)
{
const char *first = base;
const char *last = first + nitems*itemsize;
if (first != last)
{
for (;;) {
if (reverse)
{
last -= itemsize;
putitem(last, stream);
}
else
{
putitem(first, stream);
first += itemsize;
}
if (first == last)
break;
fputs(separator
, stream
); }
}
}
// Specialize.
#define DEFINE_PRINTER(name, proc, type) \
void name(const type *a, size_t n, int end, _Bool reverse) \
{ \
putchar('['); \
ostream_join(a, n, sizeof *a, proc, ", ", stdout, reverse); \
putchar(']'); \
if (end != 0) \
putchar(end); \
}
struct point {
int x, y;
};
static void putpoint_(const void *item, FILE *stream)
{
const struct point *p = item;
fprintf(stream
, "(%d, %d)", p
->x
, p
->y
); }
DEFINE_PRINTER(print_points, putpoint_, struct point)
int main(void)
{
struct point a[] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
print_points(a, sizeof a / sizeof *a, '\n', 0);
print_points(a, sizeof a / sizeof *a, '\n', 1);
return 0;
}
Ly8gSm9pbiBpdGVtcyBvbiBvdXRwdXQgc3RyZWFtLiAoMy4wMykKCiNpbmNsdWRlIDxzdGRpby5oPgoKdm9pZCBvc3RyZWFtX2pvaW4oCiAgICBjb25zdCB2b2lkICpiYXNlLCBzaXplX3Qgbml0ZW1zLCBzaXplX3QgaXRlbXNpemUsCiAgICB2b2lkICgqcHV0aXRlbSkoY29uc3Qgdm9pZCAqaXRlbSwgRklMRSAqc3RyZWFtKSwKICAgIGNvbnN0IGNoYXIgKnNlcGFyYXRvciwgRklMRSAqc3RyZWFtLCBfQm9vbCByZXZlcnNlKQp7CiAgICBjb25zdCBjaGFyICpmaXJzdCA9IGJhc2U7CiAgICBjb25zdCBjaGFyICpsYXN0ID0gZmlyc3QgKyBuaXRlbXMqaXRlbXNpemU7CgogICAgaWYgKGZpcnN0ICE9IGxhc3QpCiAgICB7CiAgICAgICAgZm9yICg7OykgewogICAgICAgICAgICBpZiAocmV2ZXJzZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbGFzdCAtPSBpdGVtc2l6ZTsKICAgICAgICAgICAgICAgIHB1dGl0ZW0obGFzdCwgc3RyZWFtKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHB1dGl0ZW0oZmlyc3QsIHN0cmVhbSk7CiAgICAgICAgICAgICAgICBmaXJzdCArPSBpdGVtc2l6ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoZmlyc3QgPT0gbGFzdCkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBmcHV0cyhzZXBhcmF0b3IsIHN0cmVhbSk7CiAgICAgICAgfQogICAgfQp9CgovLyBTcGVjaWFsaXplLgoKI2RlZmluZSBERUZJTkVfUFJJTlRFUihuYW1lLCBwcm9jLCB0eXBlKSAgICAgICAgICAgICAgICAgICAgICAgIFwKdm9pZCBuYW1lKGNvbnN0IHR5cGUgKmEsIHNpemVfdCBuLCBpbnQgZW5kLCBfQm9vbCByZXZlcnNlKSAgICAgIFwKeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHB1dGNoYXIoJ1snKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIG9zdHJlYW1fam9pbihhLCBuLCBzaXplb2YgKmEsIHByb2MsICIsICIsIHN0ZG91dCwgcmV2ZXJzZSk7IFwKICAgIHB1dGNoYXIoJ10nKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGlmIChlbmQgIT0gMCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICBwdXRjaGFyKGVuZCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKfQoKc3RydWN0IHBvaW50IHsKICAgIGludCB4LCB5Owp9OwoKc3RhdGljIHZvaWQgcHV0cG9pbnRfKGNvbnN0IHZvaWQgKml0ZW0sIEZJTEUgKnN0cmVhbSkKewogICAgY29uc3Qgc3RydWN0IHBvaW50ICpwID0gaXRlbTsKICAgIGZwcmludGYoc3RyZWFtLCAiKCVkLCAlZCkiLCBwLT54LCBwLT55KTsKfQoKREVGSU5FX1BSSU5URVIocHJpbnRfcG9pbnRzLCBwdXRwb2ludF8sIHN0cnVjdCBwb2ludCkKCmludCBtYWluKHZvaWQpCnsKICAgIHN0cnVjdCBwb2ludCBhW10gPSB7ezEsIDJ9LCB7MywgNH0sIHs1LCA2fSwgezcsIDh9fTsKICAgIHByaW50X3BvaW50cyhhLCBzaXplb2YgYSAvIHNpemVvZiAqYSwgJ1xuJywgMCk7CiAgICBwcmludF9wb2ludHMoYSwgc2l6ZW9mIGEgLyBzaXplb2YgKmEsICdcbicsIDEpOwogICAgcmV0dXJuIDA7Cn0=