
/**
 * @file
 * C to Fortran and Fortran to C Conversion utilities and function naming
 * conventions. The main goal of this API is to suppress specific C code
 * dealing with various Fortran compiler.
 * The more tedious problem is dealing with Fortran strings. Fortran compilers
 * pass string length either directly after string argument either after last
 * argument. Two new types have been defined, @b CFC_FString and @b
 * CFC_FzString.
 * @b CFC_FString stands for standard Fortran string and @b CFC_FzString stands
 * for Fortran string terminated with null character as C string.
 * The macro @b CFC_EXPORT_NAME has also been defined to deal with function
 * name decorations.
 * Finally the macro @b CFC_API is used to deal with calling conventions (ie
 * __stdall with Windows compilers).
 */

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

#include "cfc.h"

/***************************************************************************** 
 *                             Function bodies                               * 
 *****************************************************************************/

/**
 * Pad a Fortran string with space character.
 *
 * @param[out] string is the Fortran string.
 * @param[in] length is the actual length of @e string.
 * @param[in] maxLength is the allocated size of @e string.
 */
void CFC_padWithSpace( CFC_FString string, size_t length, size_t maxLength)
{
	size_t i;
	char* s = CFC_f2c_string( string);
	for (i = length; i < maxLength; i++) {
		s[i] = ' ';
	}
}

/**
 * Suppress ending spaces from a string.
 *
 * @param[in,out] cString is the string.
 */
void CFC_suppressEndingSpaces( char* cString)
{
	size_t l = strlen( cString);
	while (l > 0 && cString[l - 1] == ' ') {
		l--;
	}
	cString[l] = '\0';
}

/**
 * Returns the C pointer of a Fortran string.
 *
 * @param[in] string is the Fortran string.
 * @return the C pointer.
 */
char* CFC_f2c_string( CFC_FString string)
{
	return CFC_STRING_VALUE( string);
}

/**
 * Returns the C pointer of a zero terminated Fortran string.
 *
 * @param[in] string is the zero terminated Fortran string.
 * @return the C pointer.
 */
char* CFC_fz2c_string( CFC_FzString string)
{
	return CFC_STRING_VALUE( string);
}

/**
 * Copy a Fortran string to a C string.
 *
 * @param[out] cString is the C destination string.
 * @param[in] string is the Fortran source string.
 * @param[in] length is the actual length of @e string.
 * @return @e cString.
 */
char* CFC_f2c_strcpy( char* cString, CFC_FString string, int length)
{
	if (cString == NULL)
		return NULL;

	strncpy( cString, CFC_f2c_string( string), length);
	cString[length] = '\0';
	CFC_suppressEndingSpaces( cString);

	return cString;
}

/**
 * Copy a zero terminated Fortran string to a C string.
 *
 * @param[out] cString is the C destination string.
 * @param[in] string is the zero terminated Fortran source string.
 * @return @e cString.
 */
char* CFC_fz2c_strcpy( char* cString, CFC_FzString string)
{
	if (cString == NULL)
		return NULL;
	return strcpy( cString, CFC_fz2c_string( string));
}

/**
 * Copy a C string to a Fortran string.
 *
 * @param[out] string is the Fortran destination string.
 * @param[in] maxLength is the allocated size of @e string.
 * @param[in] cString is the C source string.
 * @return the C pointer of @e string.
 */
char* CFC_c2f_strcpy( CFC_FString string, int maxLength, char* cString)
{
	if (cString == NULL)
		cString = "";
	strncpy( CFC_f2c_string( string), cString, maxLength);
	CFC_padWithSpace( string, strlen( cString), maxLength);
	return CFC_f2c_string( string);
}

/**
 * Copy a C string to a zero terminated Fortran string.
 *
 * @param[out] string is the zero terminated Fortran destination string.
 * @param[in] cString is the C source string.
 * @return the C pointer of @e string.
 */
char* CFC_c2fz_strcpy( CFC_FzString string, char* cString)
{
	if (cString == NULL)
		cString = "";
	return strcpy( CFC_fz2c_string( string), cString);
}

