#include <avr/pgmspace.h>

#define SerialPrintf(fmt, ...) _SerialPrintf(PSTR(fmt), ##__VA_ARGS__)
#define printf SerialPrintf
#define MASK(x) ((unsigned char) (1 << (x))) 

extern "C" {
  int serialputc(char c, FILE *fp)
  {
    if (c == '\n')
      Serial.write('\r');
    Serial.write(c);
  }
}

void _SerialPrintf(const char *fmt, ...)
{
  FILE stdiostr;
  va_list ap;

  fdev_setup_stream(&stdiostr, serialputc, NULL, _FDEV_SETUP_WRITE);

  va_start(ap, fmt);
  vfprintf_P(&stdiostr, fmt, ap);
  va_end(ap);
}

struct {
  unsigned int age : 3;
} Age;

typedef union {
  struct {
    unsigned sunday : 1;
    unsigned monday : 1;
    unsigned tuesday : 1;
    unsigned wednesday : 1;
    unsigned thursday : 1;
    unsigned friday : 1;
    unsigned saturday : 1;
  } days;
  uint8_t byte_sized;
} weekdays;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  DDRD |= MASK(5);

  Age.age = 4;
  printf("Sizeof(Age) : %d\n", sizeof(Age));

  printf("Age.age : %d\n", Age.age);

  Age.age = 7;
  printf("Age.age : %d\n", Age.age);

  Age.age = 8;
  printf("Age.age : %d\n", Age.age);

  weekdays active_days;
  active_days.days.sunday = true;
  active_days.days.friday = true;
  printf("Days: %d\n", active_days.byte_sized);
}

void loop() {
  PORTD |= MASK(5);
  delay(500);
  PORTD &= ~MASK(5);
  delay(500);
}