
#ifndef _CFC_H_
#define _CFC_H_

/**
 * @file
 * @see cfc.c
 */

/***************************************************************************** 
 *                              Dependencies                                 * 
 *****************************************************************************/

#ifndef WIN32
#include <string.h>
#else
#include "win32.h"
#endif

/***************************************************************************** 
 *                          Macros & Definitions                             * 
 *****************************************************************************/

/** Symbols concatenation operator */
#ifndef name2
#define name2( x, y) x##y
#endif /* name2 */

#ifndef name3
#define name3( x, y, z) x##y##z
#endif /* name3 */

#ifdef WIN32

/** Manage Fortran API calling convention */
#ifdef WIN32_VS6 /* with Compaq Fortran under VisualStudio6 */
#define CFC_API __stdcall
#else
#define CFC_API
#endif

#ifdef WIN32_VS6 /* with Compaq Fortran under VisualStudio6 */
#define CFC_MIXED_STRING_LENGTH_ARG
#endif

#else /* WIN32 */

/** Manage Fortran API calling convention */
#define CFC_API

#endif /* WIN32 */

/** Manage function name decoration */
#if defined( underscore)
#define CFC_EXPORT_NAME( func) name2( func, _)
#else
#define CFC_EXPORT_NAME( func) func
#endif

/**
 * Definition of a Fortran string with space as padding character.
 */
#ifndef CFC_MIXED_STRING_LENGTH_ARG
typedef char* CFC_FString;
#else /* CFC_MIXED_STRING_LENGTH_ARG */
typedef struct {
	char* value;
	int length;
} CFC_FString;
#endif /* CFC_MIXED_STRING_LENGTH_ARG */

/**
 * Definition of Fortran string terminated by zero as used in C language. In
 * CFC_FzString name, "Fz" stands for [F]ortran string terminated by [Z]ero.
 */
typedef CFC_FString CFC_FzString;

/**
 * Macros to handle Fortran string length declaration and use.
 */
#ifdef CFC_MIXED_STRING_LENGTH_ARG
#define CFC_STRING_VALUE(var) (var.value)
#define CFC_STRING_LENGTH(var) (var.length)
#define CFC_DECLARE_STRING_LENGTH(var)
#define CFC_PASS_STRING_LENGTH(var)
#define CFC_DECLARE_LOCAL_STRING(var) CFC_FString var
#else
#define CFC_STRING_VALUE(var) var
#define CFC_STRING_LENGTH(var) name2(var,_length)
#define CFC_DECLARE_STRING_LENGTH(var) , long CFC_STRING_LENGTH(var)
#define CFC_PASS_STRING_LENGTH(var) , CFC_STRING_LENGTH(var)
#define CFC_DECLARE_LOCAL_STRING(var) CFC_FString var; long CFC_STRING_LENGTH(var)
#endif
#define CFC_STRING_LENGTH_MIN(var,max_length) (CFC_STRING_LENGTH(var) < max_length - 1 ? CFC_STRING_LENGTH(var) : max_length - 1)

/***************************************************************************** 
 *                           Function prototypes                             * 
 *****************************************************************************/

void CFC_padWithSpace( CFC_FString string, size_t length, size_t maxLength);
void CFC_suppressEndingSpaces( char* cString);
char* CFC_f2c_string( CFC_FString string);
char* CFC_fz2c_string( CFC_FzString string);
char* CFC_f2c_strcpy( char* cString, CFC_FString string, int length);
char* CFC_fz2c_strcpy( char* cString, CFC_FzString string);
char* CFC_c2f_strcpy( CFC_FString string, int maxLength, char* cString);
char* CFC_c2fz_strcpy( CFC_FzString string, char* cString);

#endif /* _CFC_H_ */

