/*
   fichier machine.c
   version 22 janvier 2007 par whygee@f-cpu.org

   Ce petit programme est un remplaçant d'autoconf qui détecte
   les paramètres critiques du système sur lequel il tourne.
   Il génère le fichier machine.h qui est utilisé par def64.h,
   mais il peut être modifié pour correspondre à d'autres
   architectures cibles.

   Note : les variables sont prévues pour supporter
   "au moins" le nombre de bits voulu, mon code de CRC16
   semble s'en accomoder.
 */

#include <stdio.h>

unsigned long long int i[2]={0x3837363534333231,
  0}; /* pour le zero terminal */
  
int main(int argc, char *argv[]) {
  char *c=(char *)&i,
    *endian="#error UNDEFINED ENDIAN",
    *u32="#error UNDEFINED U32";
  int j;
  int ssi, si, sli;

  if (sizeof(char)!=1) {
    printf("#error sizeof(char) = %i != 1\n",
       (int)sizeof(char));
  }

  if (sizeof(short int) < 2) {
    printf("#error sizeof(short int) = %i < 2\n",
       (int)sizeof(short int));
  }

  ssi = sizeof(short int);
   si = sizeof(int);
  sli = sizeof(long int);

  if (sizeof(int)>=4) {
    u32="int";
  } 
  else {
    if (sizeof(long int)>=4) {
      u32="long int";
    }
    else {
      printf("#error incapable de trouver le nom d'un type 32 bits\n");
      printf("#error sizeof(int) = %i, sizeof(long int) = %i\n",
       (int)sizeof(int), (int)sizeof(long int));
    }
  }

  if (sizeof(long long int)!=8) {
    printf("#error sizeof(long long int) = %i != 8 */\n",
       (int)sizeof(long long int));
  } 

  if ((c[0]=='8') && (c[1]=='7') && (c[2]=='6') && (c[3]=='5')
   && (c[4]=='4') && (c[5]=='3') && (c[6]=='2') && (c[7]=='1')
   && (c[8]==0)) {
    endian="#define WORDS_BIGENDIAN";
  }
  else {
    if ((c[0]=='1') && (c[1]=='2') && (c[2]=='3') && (c[3]=='4')
     && (c[4]=='5') && (c[5]=='6') && (c[6]=='7') && (c[7]=='8')
     && (c[8]==0)) {
      endian="/* Little Endian detected, #undef WORDS_BIGENDIAN */";
    }
    else {
      printf("#error Endian=%s ???\n",c);
    }
  }

  printf("\
/* fichier machine.h\n\
 Attention ! ce fichier a ete genere par machine.c");

  if (argc>1) {
    printf("\n tag : ");
    for (j=1; j<argc; j++)
      printf("%s ",argv[j]);
  }

  printf("\n*/\n\
\n\
#ifndef __MACHINE_H__\n\
#define __MACHINE_H__\n\
\n\
/* sizeof(short int)=%d\n\
   sizeof(      int)=%d\n\
   sizeof(long  int)=%d */\n\
", ssi, si, sli);

  printf("\n\
#define U8    unsigned char\n\
#define S8      signed char\n\
\n\
#define U16   unsigned short int\n\
#define S16     signed short int\n\
\n\
#define U32   unsigned %s\n\
#define S32     signed %s\n\
\n\
#define U64   unsigned long long int\n\
#define S64     signed long long int\n\
\n\
/* Endian : */\n\
#define ENDIAN64 %s\n\
%s\n\
\n\
#endif\n\
", u32, u32, c, endian);

  return 0;
}
