#include <stdio.h>
/*#include <malloc.h>*/
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef __STDC__
#include <stdlib.h>
#endif

/* zum Debbugen des Automaten sollte hier YYDEBUG definiert werden
 * mit #define YYDEBUG 1 */
#define YYDEBUG 1

/* Fuer Sun und Sparc Rechner wird hier die Funktion sscanf()
 * deklariert, da dies nicht im 'stdio.h' File geschieht:        */
#undef FLP_NEED_SSCANFDEF
#ifdef __sun__
#define FLP_NEED_SSCANFDEF 1
#else
#ifdef __sparc__
#define FLP_NEED_SSCANFDEF 1
#endif
#endif
#ifdef FLP_NEED_SSCANFDEF
/*   extern int sscanf( const char *, const char *, ... ); */
   extern int printf( const char *format, ... );
   extern int fprintf( FILE *file, const char *format, ...);
#endif


#define CPRINTF_BUFFER 8192
/* Auf dem cprintf-buffer wird bei der Auswertung von Zeilen
   und auswertung von Kommentaren gearbeitet. Speicher des
   Buffers wird mit der cprintf... Funktionen die im Modul
   "mit2mot.c" definiert sind, vergeben. Wegen des begrenzten
   Buffers werden sehr lange Kommentare bei Ueberlaufgefahr
   einfach brutal abgeschnitten. Das ist vertretbar, da sich
   die Semantik der Assemblerprogramme dadurch nicht aendert.
   Weiterhin kannn bei zu kleinem Buffer die Konvertierung von
   normalen Zeilen abgebrochen werden, wenn der Buffer
   ueberlaeuft. Die Belastung des Buffers wird bei jeder
   Konvertierung auf <stderr> ausgegeben.
   Gewaehler Wert bisher: 8192 (Rolf) */
#define CPRINTF_RESERVE 4096
/* Da die cprintf... Funktionen auf der Bibliotheksfunktion
   sprintf() aufsetzten, und diese Bibliothekfunktion keine
   Moeglichkeit zur Angabe der Groesse des Buffers bietet, wird
   an den cprintf-buffer eine Reserve angehaengt, um ein
   beschreiben in undefinierten Bereich zu vermeiden. Die
   Reserve soll mindestens so gross sein wie eine Komplette
   Zeile und muss unbedingt groesser als 512.
   Gewaehler Wert bisher: 4096 (Rolf) */
#define CPRINTF_REMARK_BUFFER 4000
/* Der Wert CPRINTF_REMARK_BUFFER bestimmt, wie weit der cprintf-
   Buffer fuer Kommentare im Assembler-Text benutzt werden darf.
   Der Wert sollte kleiner als CPRINTF_BUFFER gewaehlt werden,
   wenn folgende Bedingungen eintreten:
   1. Kommentare stehen nicht am Ende einer Zeile
   2. Kommentare die nicht am Ende einer Zeile stehen sind sehr sehr lang
   Da derzeit die bison(c) Regeln nur erlauben, Bemerkungen ans Ende
   einer Zeile zu setzen, ist es am guenstigsten, wenn gilt:
     CPRINTF_REMARK_BUFFER = CPRINTF_BUFFER
*/


/* Funktionen implementiert im Modul "mit2mot.c" */

void cprintfclear(void);
/* Loeschen des cprintf - Buffers */

char *cprintfappendinit();
/* Initialisierung fuer die cprintfappend-Routine */

#ifndef CPRINT_DEF

char *cprintf(const char *format, ...);
/* cprintf() ergibt eine Zeichenkette, die wie bei printf()
   erzeugt wird. Die Zeichenkette wird in einen internen buffer
   geschrieben. Der Zeiger auf den Buffer ist das Ergebnis.
   Aehnliche Funktion: cprintfappend();
*/

void cprintf_char( char zeich );
/* Haengt ein einzelnes Zeichen hinten an den cprintf_buffer.
   Diese Funktion ist nur sinnvoll in Kombination mit
   der Funktion cprintfappendinit. Es ist nicht garantiert, dass
   die Zeichenkette mit einem '\0' Character (0-Zeichen) endet.
   Daher muss die Konstrunktion von Zeichenketten mit
   der Funktion cprintf_char() wie folgt aussehen:
      zeichenkette=cprintfappendinit();
      cprintf_char( zeichen );
      ...
      cprintf_char( (char)0 );
   Laeuft der Buffer ueber, werden die letzten Zeichen einfach
   abgeschnitten (keine Fehlermeldung).
*/

void cprintfappend( const char *format, ...);
/* Arbeitet wie cprintf(), jedoch wird das 0 Character des letzten Strings
   ueberschrieben. So kann man ein "anhaengen" an die letzte Zeichenkette
   realisieren, ohne dass der Buffer superschnell ueberlaeuft.  Bei
   cprintfappend() sollte nicht auf den letzten von cprintf() erzeugten
   String zugegriffen werden, da die Routine sonst zu Fehlern fuehrt.
   Das Aufrufmuster zur benutzung von cprintfappend() sieht wie folgt aus:
        result=cprintfappendinit(); Initialisieren des Anfangs des Strings
        for (i=0; i<10; i++)        Die Schleife erzeugt eine Listen von
          cprintfappend("%d,");        Zahlen von 0 bis 9
        printf(result);             Gibt "0,1,2,3,4,5,6,7,8,9," aus.
*/

#endif

/* die Funktionen Setmc...()  setzen Flags wenn die
   verschiedenen Prozessortypen erkannt wurden */
   void Setmc68010( void );
   void Setmc68020( void );
   void Setmc68881( void );




/* Funktionen implementiert im Modul "mit2mot.y" */

struct t_wortkette { char *wort;
		     struct t_wortkette *naechstes; };
struct t_worte { struct t_wortkette *letztes;
		 struct t_wortkette *erstes; };

struct t_worte *create_wort( char *kette );
/* Aus einer Zeichenkette wird eine einelementige Wortliste */

struct t_worte *contact_wort(struct t_worte *w1,struct t_worte *w2);
/* Zwei Wortlisten w1 und w2 werden aneinandergehaengt */

char *cprintf_worte( struct t_worte *w );
/* Aus einer Wortliste wird ein String gemacht. Der Speicher
   fuer den String wird durch cprintf() alloziert. Der Speicher
      fuer die Wortliste wird freigegeben */

void SetDraussen( void );
/* Aendert die Konvertierung von den Adressen */




/* Funktionen implementiert im Modul "mit2mot.lex" */

void lexnextline(void);
  /* Loescht den Buffer, der durch das MACRO "Save" gefuellt wird
   - geschieht nach jeder Zeile, nur vom flex-Programm aus. */

char *lexline(void);
  /* ergibt die gebufferten Zeile */


#define LABELSIZE 64
  /* maximale Laenge eines Labels */

void PrintLabels(void);
  /* Gibt die nicht definierten Labels der Labelliste aus.
     Die Labelliste wird nur im flex-Modul erzeugt. */



/* Diese Funktionen sind implementiert in "floats.h": */

/* Aufzaehlungstyp fuer die drei unterstuetzen
 * Fliesskommagenauigkeiten                    */
typedef enum { FLP_SINGLE, FLP_DOUBLE, FLP_EXTENDED } t_precision;

/* Forward declaratios: */

int double2int( double );
void normalize_float( double, int, double *, int * );
void singlefloat2bytes( int, double, int, int * );
void doublefloat2bytes( int, double, int, int * );
void extendedfloat2bytes( int, double, int, int * );
char *float_transform( char *, t_precision );
