#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/* struct module properties of a single item */
#define MV_LITTLE_ENDIAN     0x001  /* byte order */
#define MV_NATIVE_SIZE       0x002  /* native or standard size */
#define MV_NATIVE_ALIGNMENT  0x004  /* native or no alignment */
int
format_type(const char **fmt)
{
    int native_le = 1;
    char *p = (char *) &native_le;
    /* assume big endian and standard size */
    int type = 0;

    native_le = (*p == 1);

    switch (**fmt) {
    case '=':
        type |= native_le;
        (*fmt)++;
        break;
    case '<':
        type |= MV_LITTLE_ENDIAN;
        (*fmt)++;
        break;
    case '>': case '!':
        (*fmt)++;
        break;
    case '@':
        (*fmt)++; /* fall through */
    default:
        type |= (native_le|MV_NATIVE_SIZE|MV_NATIVE_ALIGNMENT);
        break;
    }

    return type;
}

/* Return 0 for equal, nonzero otherwise */
int
fmtcmp(const char *p, const char *q)
{
    if (format_type(&p) != format_type(&q)) {
        return -1;
    }

    return strcmp(p, q);
}


const char *fmt[6] = {
  "@IhQ",
  "IhQ",
  "=IhQ",
  "<IhQ",
  ">IhQ",
  "!IhQ"
};

int expected_le[6][6] = {
  {0,   0, -1, -1, -1, -1},
  {0,   0, -1, -1, -1, -1},
  {-1, -1,  0,  0, -1, -1},
  {-1, -1,  0,  0, -1, -1},
  {-1, -1, -1, -1,  0,  0},
  {-1, -1, -1, -1,  0,  0}
};

int expected_be[6][6] = {
  {0,   0, -1, -1, -1, -1},
  {0,   0, -1, -1, -1, -1},
  {-1, -1,  0, -1,  0,  0},
  {-1, -1, -1,  0, -1, -1},
  {-1, -1,  0, -1,  0,  0},
  {-1, -1,  0, -1,  0,  0}
};



int
main(void)
{
    int x = 1;
    char *p = (char *) &x;
    const char *dfmt;
    const char *sfmt;
    int i, j;
    int (*expected)[6];

    if (*p == 1) {
        expected = expected_le;
        printf("native_le\n");
    }
    else {
        expected = expected_be;
        printf("native_be\n");
    }

    for (i = 0; i < 6; i++) {
        for (j = 0; j < 6; j++) {
            dfmt = fmt[i];
            sfmt = fmt[j];
            if (fmtcmp(dfmt, sfmt) != expected[i][j]) {
                printf("dfmt: %s  sfmt: %s\n", dfmt, sfmt);
                exit(1);
            }
        }
    }

    return 0;
}



