/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*\
\                                                                          /
/   Header file for                   Copyright (c)  Dmitry A. Kazakov     \
\   Common declarations                              St.Petersburg         /
/                                                    Autumn, 1993          \
\                                                                          /
/   (C, ANSI C)                                                            \
\                                     Last revision :  15:59 22 Jan 2000   /
/                                                                          \
\   This library is free software; you can redistribute it and/or modify   /
/   it  under  the  terms  of  the GNU Library General Public License as   \
\   published  by  the Free Software Foundation; either version 2 of the   /
/   License, or (at your option) any later version.                        \
\                                                                          /
/   As a special exception, if other  files  instantiate  generics  from   \
\   this unit, or you link this unit with  other  files  to  produce  an   /
/   executable, this  unit  does  not  by  itself  cause  the  resulting   \
\   executable  to  be  covered  by the GNU General Public License. This   /
/   exception  does  not  however  invalidate  any other reasons why the   \
\   executable file might be covered by the GNU Public License.            /
/                                                                          \
\   This library is distributed in the hope that it will be useful,  but   /
/   WITHOUT   ANY   WARRANTY;  without  even  the  implied  warranty  of   \
\   MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE.  See  the  GNU   /
/   Library General Public License for more details.                       \
\                                                                          /
/   You  should  have  received a copy of the GNU Library General Public   \
\   License  along with this library; if not, write to the Free Software   /
/   Foundation,   Inc.,   59  Temple  Place  -  Suite  330,  Boston,  MA   \
\   02111-1307, USA                                                        /
/                                                                          \
\*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/

#ifndef    Common_h
#define    Common_h
/*>

   This file should contain the machine specifics:

<*/
#include	"sizeof.h"

#define         BACK_SLASH      '\\'
#define         CIRCUMFLEX      '^'
#define         CR              '\r'
#define         LF              '\n'
#define         SPACE           ' '
#define         TAB             '\t'
/*>

   Next we will define some machine dependet types. Of course, the C  is
   completely fool, so we cannot define exactly what  we  need.  But  we 
   will try ...

   HARDWARE     hardware magic cookie (initializator for char [4])
   byte         one byte without sign expansion
   halfword     half of machine's word
   word         machine's word (is long enough for an address)

<*/
#ifndef HARDWARE
#define         HARDWARE        { 'u', 'n', 'k', 'n' }
#endif  /*> HARDWARE <*/

#if BitsPerWord == 16
typedef unsigned char   byte;
typedef unsigned short  halfword;
typedef unsigned long   word;
typedef unsigned long   longword;
#endif	/*> BitsPerWord == 16 <*/

#if BitsPerWord == 32
typedef unsigned char   byte;
typedef unsigned short  halfword;
typedef unsigned int    word;
typedef unsigned long   longword;
#endif	/*> BitsPerWord == 32 <*/

#if BitsPerWord == 64
typedef unsigned char   byte;
typedef unsigned short  halfword;
typedef unsigned int    word;
typedef unsigned long   longword;
#endif	/*> BitsPerWord == 64 <*/

#ifdef  NON_ANSI
#define         const
#endif  /*> NON_ANSI <*/
/*>

   MvBytes -- Raw memory copy (by bytes)
   MvWords -- Raw memory copy (by words)

        Dest    - Pointer to the memory block (to copy to)
        Source  - Pointer to the memory block (to copy from)
        Length  - Memory block length (in bytes)

   Raw memory  copy.  The  source  and  destination  memory  blocks  can
   overlap.  It must be as fast as possible. There are two possibilities 
   for implementation of these functions:

        memmove - (which  may  incorrectly work or be absent). For using
                  memmove the USE_MEMMOVE symbol must be defined.

        macro   - default

   Effects :

        None, even if both memory blocks do overlap.

<*/
#ifndef USE_MEMMOVE

#define         MvGeneric(type, Dest, Source, Length)           \
                {                                               \
                   type *       From  = (type *) (Source);      \
                   type *       To    = (type *) (Dest);        \
                   int          Count = (Length);               \
                                                                \
                   if (From > To)                               \
                   {                                            \
                      for (; Count > 0; Count -= sizeof (type)) \
                         *To++ = *From++;                       \
                   }                                            \
                   else                                         \
                   {                                            \
                      From = (type *) ((char *) From + Count);  \
                      To   = (type *) ((char *) To   + Count);  \
                      for (; Count > 0; Count -= sizeof (type)) \
                         *--To = *--From;                       \
                }  }

#define         MvWords(Dest, Source, Length)                   \
                MvGeneric (word, (Dest), (Source), (Length))

#define         MvBytes(Dest, Source, Length)                   \
                MvGeneric (char, (Dest), (Source), (Length))

#else   /*> ifdef USE_MEMMOVE <*/

#ifndef NON_ANSI
#include        <string.h>	/* Prototype for memmove	*/
#endif  /*> NON_ANSI <*/

#define         MvBytes(Dest, Source, Length)                   \
                memmove ((void *) Dest, (void *) Source, Length)

#define         MvWords(Dest, Source, Length)                   \
                memmove ((void *) Dest, (void *) Source, Length)

#endif  /*> USE_MEMMOVE <*/
/*>

   Memory control. By  default  this  file  automatically  includes  the
   `mem.h'  file  to  control  the  memory  allocation.  To disable this
   feature, just define the `NO_MEM_CTL' symbol.

<*/
#ifndef NO_MEM_CTL
#include        "mem.h"
#else	/*> ifndef NON_MEM_CTL <*/
#define	ACCESS(aType,aPointer,aMode)	aType *	aPointer
#define	ATTACH(aPointer,aCtxNo,aSegNo)
#define	MAP(aMode)
#define	MAP_(aMode)
#endif  /*> NON_MEM_CTL <*/
/*>

   as -- Use data as specified ...

        Type    - Desired type

   This pretty kludge allows you to use a data specified by pointer  and
   offset  as  the entity of the type you want. For example, if you have
   charater array `Buffer' and offset `Offs' within it you may use char-
   acters  beginning  with  the offset as a long number just specifying:
   as(long) Buffer [Offs]. Of course, all problems  with  alignment  are
   your own.

<*/
#define         as(Type)        *(Type *)&
/*>

   bits  -- Converting a word size to the size in bits
   chars -- Converting a word size to the size in bytes
   rof   -- Rounded `sizeof'
   round -- Alignment to a word boundary
   wof   -- Same as `sizeof' but tells size in words
   bytes -- Converting a bit size to the size in bytes
   words -- Converting a byte size to the size in words

<*/
#define         WORD_MASK       (sizeof (word) - 1)
#define         WORD_BITS                                       \
                (  sizeof (word) == 4                           \
                ?  2                                            \
                :  (  sizeof (word) == 8                        \
                   ?  3                                         \
                   :  4                                         \
                )  )

#define         bits(Size)      ((Size) << (WORD_BITS + 3))

#define         bytes(Size)	(((Size) + 7) >> 3)

#define         chars(Size)     ((Size) << WORD_BITS)

#define         words(Size)                                     \
                (  ((word) (Size) + WORD_MASK) >> WORD_BITS  )

#define         wof(Object)     (words (sizeof (Object)))
#define         rof(Object)     (round (sizeof (Object)))

#define         round(Number)                                   \
                (  ((word) (Number) + WORD_MASK)                \
                & ~(word) WORD_MASK                             \
                )
/*>

   Inverse -- String inversion

	String	- Points to the character string to be inversed
	Length	- The string length (may be 0)

   This  function inverses the String, i.e. swaps the first and the last
   bytes, the second and the last before the last byte and so on. 

<*/
#ifndef NON_ANSI
void	Inverse
(
   char	     *	String,
   int		Length
);
#else
void    Inverse ();
#endif  /*> NON_ANSI <*/

#endif  /*> Common_h <*/
