// -*-C++-*- 

/*  inc/platform/Platform.hpp  */

/*
 * Author: Philogelos A. <Philogelos@yahoo.com>
 * Maintainer: Philogelos A.
 * Keywords: C++, library, containers
 *
 * Copyright (C) 1998 Philogelos A.
 *
 * This file is part of Quercus Robusta.
 *
 * Quercus Robusta 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, or (at your option)
 * any later version.
 *
 * This software 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 software; see the file COPYING.LIB.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */



#ifndef __PLATFORM_HPP__
#define __PLATFORM_HPP__

/* $Id$ */

#include "Top.hpp"
#include "defines.h"

#include <stdarg.h>

#define PLAF Platform::getInstance()

/**
   Class name of default Platofrm used by application.
   This class must be not abstract.

   Can be one of: POSIXPlatform, MinimalPlatform or Win32Platform.
*/
#define PLATFORM POSIXPlatform /* */
/* #define PLATFORM MinimalPlatform */
/* #define PLATFORM Win32Platform */

/**
   If this defined, library provides default implementation
   of system-dependent application entry-point (main, WinMain etc).
   This entry point does some initialisation and calls user-provided
   QRMain.

   @see QRMain
*/
#define WRAP_MAIN

#if defined( WANT_PLATFORM )
#if defined( PLATFORM )
#undef PLATFORM
#endif
#define PLATFORM WANT_PLATFORM
#endif

#if defined( WANT_WRAP_MAIN )
#define WRAP_MAIN
#elif defined( UNWANT_WRAP_MAIN )
#if defined( WRAP_MAIN )
#undef WRAP_MAIN
#endif
#endif


/**
   Interface to platform-dependent functions.

   @author Philogelos
   @created
*/
interface Platform : public virtual Top
{
 public: virtual void sprintf( char *s, const char * format, /* args */ ... ) 
		   PRINTF_ALIKE( 3, 4 ) = 0;
 public: virtual void vsprintf( char *s, const char *format, va_list raw ) = 0;

 public: virtual Index printfLength( const char * format, /* args */ ... ) 
		   PRINTF_ALIKE( 2, 3 ) = 0;
 public: virtual Index vprintfLength( const char * format, va_list raw ) = 0;
 
 public: virtual void rawErrorPrintf( const char * format, /* args */ ... ) 
		   PRINTF_ALIKE( 2, 3 ) = 0;

 public: virtual void rawErrorVPrintf( const char * format, va_list raw ) = 0;

 public: virtual char *getErrorDescription( int errCode ) = 0;

 public: virtual void exitImmediate( long status ) = 0;

 public: virtual void suicide() NORETURN = 0;

 public: virtual void attachDebugger() = 0;

 public: virtual void setImageName( const char *aName ) = 0;
 public: virtual const char *getImageName() const = 0;
 
 public: virtual char *getNL() const = 0;

 /**
	Returns string identifying current instant in time. 
	Should not be freed.
 */
 public: virtual char *getTimeStampString() = 0;

 public: virtual char  *strcpy( char *dst, const char *src ) = 0;
 public: virtual int    strcmp( const char *s1, const char *s2 ) = 0;
 public: virtual Index  strlen( const char *s ) = 0;
 public: virtual char  *strcat( char *dst, const char *src ) = 0;
 public: virtual char  *strchr( const char *s, int c ) = 0;

 /**
	Interface to strtol(3C). Throws InvalidArgument
	if value is too big (ERANGE), conversion failed (EINVAL) or
	endptr is not NULL and there are non-numeric characters 
	in the string.
 */
 public: virtual long   strtol( const char *str, char **endptr, int base ) = 0;

 public: virtual int   memcmp( void *s1, const void *s2, Index n ) = 0;
 public: virtual void *memchr( const void *s, int c, Index n ) = 0;
 public: virtual void *memcpy( void *s1, const void *s2, Index n ) = 0;
 public: virtual void *memset( void *s, int c, Index n ) = 0;

 public: virtual void *allocateMemory( Index aSize ) = 0;
 public: virtual void  deallocateMemory( void *aPointer ) = 0;


 public: static void *allocateMemoryBootstrap( Index aSize );
 public: static void  deallocateMemoryBootstrap( void *aPointer );


 public: static Platform *getInstance();
 public: static Platform *getInstanceNow();
 
 protected: static Platform *instance;
};

#if defined( WRAP_MAIN )
class List;

extern int QRMain( List *anArgs );
#endif

/* $Log$ */

/* __PLATFORM_HPP__ */
#endif
