#include "ta_pragma.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#if !defined(__WIN32__) && !defined(__MSDOS__) && !defined(WIN32)
#include <unistd.h>
#endif
#if defined (WIN32)
#include <windows.h>
#endif
#include "ta_common.h"
#include "ta_abstract.h"
#include "ta_memory.h"
#if defined(__WIN32__) || defined(WIN32)
# define TA_FS_SLASH "\\"
# define TA_MCPP_EXE "..\\src\\tools\\gen_code\\mcpp.exe"
#else
# define TA_FS_SLASH "/"
# define TA_MCPP_EXE "/usr/bin/mcpp"
#endif
static char *ta_fs_path(int count, ...) {
char *path = (char *)malloc(16000);
char *p;
va_list argp;
int j;
va_start(argp, count);
p = path;
for (j = 0; j < count; j++) {
int i;
char *part;
part = va_arg(argp, char *);
i = strlen(part);
memmove(p, part, i);
p += i;
memmove(p, TA_FS_SLASH, 1);
p++;
}
*--p = '\0';
va_end(argp);
return path;
}
extern int mcpp_main( int argc, char ** argv);
#define BUFFER_SIZE 16000
#define FILE_WRITE 0
#define WRITE_ON_CHANGE_ONLY 0
#define FILE_READ 0x00000001
#define WRITE_ALWAYS 0x00000002
#ifndef min
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef max
#define max(a, b) (((a) > (b)) ? (a) : (b))
#endif
typedef struct
{
FILE *file;
FILE *fileTarget;
FILE *templateFile;
char f1_name[BUFFER_SIZE];
char f2_name[BUFFER_SIZE];
int flags;
} FileHandle;
FileHandle *gOutFunc_H;
FileHandle *gOutFrame_H;
FileHandle *gOutFrame_C;
FileHandle *gOutGroupIdx_C;
FileHandle *gOutFunc_C;
FileHandle *gOutRetCode_C;
FileHandle *gOutRetCode_CSV;
FileHandle *gOutFuncList_TXT;
FileHandle *gOutDefs_H;
FileHandle *gOutFunc_SWG;
FileHandle *gOutFunc_XML;
FileHandle *gOutFuncAPI_C;
FileHandle *gOutMakefile_AM;
FileHandle *gOutCore_Java;
FileHandle *gOutJavaDefs_H;
FileHandle *gOutFunc_Annotation;
#ifdef _MSC_VER
FileHandle *gOutDotNet_H;
FileHandle *gOutProjFile;
FileHandle *gOutMSVCProjFile;
FileHandle *gOutVS2005ProjFile;
FileHandle *gOutVS2008ProjFile;
#ifdef TA_LIB_PRO
#endif
FileHandle *gOutExcelGlue_C;
static void printExcelGlueCode( FILE *out, const TA_FuncInfo *funcInfo );
#endif
static void genJavaCodePhase1( const TA_FuncInfo *funcInfo );
static void genJavaCodePhase2( const TA_FuncInfo *funcInfo );
static void printJavaFunctionAnnotation(const TA_FuncInfo *funcInfo);
typedef void (*TA_ForEachGroup)( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
);
static unsigned int forEachGroup( TA_ForEachGroup forEachGroupfunc,
void *opaqueData );
static void doForEachFunctionPhase1( const TA_FuncInfo *funcInfo,
void *opaqueData );
static void doForEachFunctionPhase2( const TA_FuncInfo *funcInfo,
void *opaqueData );
static void doForEachFunctionXml( const TA_FuncInfo *funcInfo,
void *opaqueData );
static void doForEachUnstableFunction( const TA_FuncInfo *funcInfo,
void *opaqueData );
#ifdef TA_LIB_PRO
#endif
static void doDefsFile( void );
static int gen_retcode( void );
static void printIndent( FILE *out, unsigned int indent );
static void printFunc( FILE *out,
const char *prefix,
const TA_FuncInfo *funcInfo,
unsigned int prototype,
unsigned int frame,
unsigned int semiColonNeeded,
unsigned int validationCode,
unsigned int lookbackSignature,
unsigned int managedCPPCode,
unsigned int managedCPPDeclaration,
unsigned int inputIsSinglePrecision,
unsigned int outputForSWIG,
unsigned int outputForJava,
unsigned int lookbackValidationCode,
unsigned int useSubArrayObject,
unsigned int arrayToSubArrayCnvt
);
static void printCallFrame ( FILE *out, const TA_FuncInfo *funcInfo );
static void printFrameHeader( FILE *out, const TA_FuncInfo *funcInfo, unsigned int lookbackSignature );
static void printExternReferenceForEachFunction( const TA_FuncInfo *info,
void *opaqueData );
static void printFunctionAddress( const TA_FuncInfo *info,
void *opaqueData );
static void printPerGroupList( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
);
static void printGroupListAddress( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
);
static void printGroupSize( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
);
static void printGroupSizeAddition( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
);
static int addUnstablePeriodEnum( FILE *out );
static int createTemplate( FileHandle *in, FileHandle *out );
static int generateFuncAPI_C( void );
#ifdef _MSC_VER
static int createProjTemplate( FileHandle *in, FileHandle *out );
static int createMSVCProjTemplate( FileHandle *in, FileHandle *out );
static int createVS2005ProjTemplate( FileHandle *in, FileHandle *out );
static void printVS2005FileNode( FILE *out, const char *name );
#ifdef TA_LIB_PRO
#endif
#endif
static void writeFuncFile( const TA_FuncInfo *funcInfo );
static void doFuncFile( const TA_FuncInfo *funcInfo );
static void printOptInputValidation( FILE *out,
const char *name,
const TA_OptInputParameterInfo *optInputParamInfo,
int lookbackValidationCode );
static int skipToGenCode( const char *dstName, FILE *out, FILE *templateFile );
static void printDefines( FILE *out, const TA_FuncInfo *funcInfo );
static void printFuncHeaderDoc( FILE *out,
const TA_FuncInfo *funcInfo,
const char *prefix );
static void extractTALogic( FILE *inFile, FILE *outFile );
static void cnvtToUpperCase( char *str );
static void cnvtChar( char *str, char from, char to );
static char *trimWhitespace( char *str );
static int copyFile( const char *src, const char *dest );
static int areFileSame( const char *file1, const char *file2 );
static void fileDelete( const char *fileToDelete );
static void appendToFunc( FILE *out );
static void convertFileToCArray( FILE *in, FILE *out );
static void ReplaceReservedXmlCharacters(const char *input, char *output );
char gToOpen[BUFFER_SIZE];
char gTempBuf[BUFFER_SIZE];
char gTempBuf2[BUFFER_SIZE];
char gTempBuf3[BUFFER_SIZE];
char gTempBufForPrint[BUFFER_SIZE];
char gTempDoubleToStr[200];
const char *doubleToStr( double value );
const char *gCurrentGroupName;
static int genCode(int argc, char* argv[]);
extern const TA_OptInputParameterInfo TA_DEF_UI_MA_Method;
int genPrefix = 0;
void print( FILE *out, const char *text, ... )
{
va_list arglist;
memset(gTempBufForPrint,0,sizeof(gTempBufForPrint));
va_start(arglist,text);
vsprintf(gTempBufForPrint,text,arglist);
va_end(arglist);
if( strlen(gTempBufForPrint) >= BUFFER_SIZE-strlen("/* Generated */ ") )
{
printf( "Lines length exceed internal buffers (%lu,%lu)\n",
(unsigned long)strlen(gTempBufForPrint),
(unsigned long)(BUFFER_SIZE-strlen("/* Generated */ ")) );
exit(-1);
}
if( genPrefix )
fprintf( out, "/* Generated */ %s", gTempBufForPrint );
else
fprintf( out, "%s", gTempBufForPrint );
}
static void printIndent( FILE *out, unsigned int indent )
{
unsigned int i;
if( genPrefix )
fprintf( out, "/* Generated */ " );
for( i=0; i < indent; i++ )
{
fprintf( out, " " );
}
}
int main(int argc, char* argv[])
{
int retValue;
TA_RetCode retCode;
if( argc > 1 )
{
printf( "\n" );
printf( "gen_code V%s - Updates many TA-Lib source files\n", TA_GetVersionString() );
printf( "\n" );
printf( "Usage: gen_code\n");
printf( "\n" );
printf( " No parameter needed.\n" );
printf( "\n" );
printf( " This utility is useful only for developers adding new TA\n" );
printf( " functions to TA-Lib.\n" );
printf( "\n" );
printf( " The interface definitions in c/src/ta_abstract/tables\n" );
printf( " are used to generate code, documentation and some more.\n" );
printf( "\n" );
printf( " The following files are updated or regenerated:\n" );
printf( " 1) ta-lib/c/include/ta_func.h\n" );
printf( " 2) ta-lib/c/include/ta_defs.h\n" );
printf( " 3) ta-lib/ta_func_list.txt\n" );
printf( " 4) ta-lib/c/src/ta_common/ta_retcode.*\n" );
printf( " 5) ta-lib/c/src/ta_abstract/ta_group_idx.c\n");
printf( " 6) ta-lib/c/src/ta_abstract/frames/*.*\n");
printf( " 7) ta-lib/swig/src/interface/ta_func.swg\n" );
printf( " 8) ta-lib/dotnet/src/Core/TA-Lib-Core.vcproj (Win32 only)\n" );
printf( " 9) ta-lib/dotnet/src/Core/TA-Lib-Core.h (Win32 only)\n" );
printf( " 10) ta-lib/c/src/ta_abstract/excel_glue.c (Win32 only)\n" );
printf( " 11) ta-lib/c/src/ta_abstract/java_defs.h (Win32 only)\n" );
printf( " 12) ta-lib/c/ide/msvc/lib_proj/ta_func/ta_func.dsp (Win32 only)\n" );
printf( " 13) ta-lib/java/src/com/tictactec/ta/lib/Core.java (Win32 only)\n" );
printf( " 14) ta-lib/java/src/com/tictactec/ta/lib/CoreAnnotated.java (Win32 only)\n" );
printf( " 15) ta-lib/ta_func_api.xml\n" );
printf( " 16) ta-lib/c/src/ta_abstract/ta_func_api.c\n" );
printf( " 17) ... and more ...");
printf( "\n" );
printf( " The function header, parameters and validation code of all TA\n" );
printf( " function in c/src/ta_func are also updated.\n" );
printf( "\n" );
printf( "** Must be directly run from the 'bin' directory.\n" );
exit(-1);
}
printf( "gen_code V%s\n", TA_GetVersionString() );
retCode = TA_Initialize();
if( retCode != TA_SUCCESS )
{
printf( "\nCannot initialize the library\n");
return -1;
}
printf( "Now updating source code...\n" );
retValue = genCode( argc, argv );
retCode = TA_Shutdown();
if( retCode != TA_SUCCESS )
{
printf( "Shutdown failed (%d)\n", retCode );
}
return retValue;
}
static void init_gToOpen( const char *filePath, const char *suffix )
{
strcpy( gToOpen, filePath );
if( suffix )
strcat( gToOpen, suffix );
}
static FileHandle *fileOpen( const char *fileToOpen,
const char *templateFile,
int flags )
{
FileHandle *retValue;
if( (fileToOpen == NULL) ||
((flags&FILE_READ) && (templateFile != NULL)) )
{
printf( "Internal error line %d", __LINE__ );
return (FileHandle *)NULL;
}
retValue = TA_Malloc( sizeof(FileHandle) );
if( !retValue )
{
printf( "Memory alloc error line %d", __LINE__ );
return (FileHandle *)NULL;
}
memset( retValue, 0, sizeof(FileHandle) );
retValue->flags = flags;
init_gToOpen( fileToOpen, NULL );
strcpy( retValue->f1_name, gToOpen );
if( flags&FILE_READ )
{
retValue->file = fopen( gToOpen, "r" );
if( retValue->file == NULL )
{
memset( retValue, 0, sizeof(FileHandle) );
TA_Free( retValue );
return (FileHandle *)NULL;
}
}
else if( flags&WRITE_ALWAYS )
{
retValue->file = fopen( gToOpen, "w" );
if( retValue->file == NULL )
{
memset( retValue, 0, sizeof(FileHandle) );
TA_Free( retValue );
return (FileHandle *)NULL;
}
}
else
{
retValue->file = fopen( gToOpen, "r" );
if( retValue->file )
{
retValue->fileTarget = retValue->file;
init_gToOpen( fileToOpen, ".tmp" );
strcpy( retValue->f2_name, gToOpen );
retValue->file = fopen( gToOpen, "w" );
if( !retValue->file )
{
fclose( retValue->fileTarget );
memset( retValue, 0, sizeof(FileHandle) );
TA_Free( retValue );
return (FileHandle *)NULL;
}
}
else
{
retValue->fileTarget = NULL;
retValue->file = fopen( gToOpen, "w" );
if( retValue->file == NULL )
{
memset( retValue, 0, sizeof(FileHandle) );
TA_Free( retValue );
return (FileHandle *)NULL;
}
}
}
if( !(flags&FILE_READ) )
{
if( templateFile )
{
init_gToOpen( templateFile, NULL );
retValue->templateFile = fopen( gToOpen, "r" );
if( retValue->templateFile == NULL )
{
if(retValue->fileTarget) fclose( retValue->fileTarget );
if(retValue->file) fclose( retValue->file );
if(retValue->templateFile) fclose( retValue->templateFile );
memset( retValue, 0, sizeof(FileHandle) );
TA_Free( retValue );
printf( "\nCannot open template [%s]\n", gToOpen );
return (FileHandle *)NULL;
}
if( skipToGenCode( fileToOpen, retValue->file, retValue->templateFile ) != 0 )
{
if(retValue->fileTarget) fclose( retValue->fileTarget );
if(retValue->file) fclose( retValue->file );
if(retValue->templateFile) fclose( retValue->templateFile );
memset( retValue, 0, sizeof(FileHandle) );
TA_Free( retValue );
return (FileHandle *)NULL;
}
}
}
return retValue;
}
static void fileClose( FileHandle *handle )
{
if( !handle ) return;
if( handle->templateFile && handle->file )
{
while( fgets( gTempBuf, BUFFER_SIZE, handle->templateFile ) != NULL )
{
if( fputs( gTempBuf, handle->file ) == EOF )
{
printf( "Cannot write to output file! Disk Full? " );
break;
}
}
#if 0 #endif
}
if(handle->fileTarget) fclose( handle->fileTarget );
if(handle->templateFile) fclose( handle->templateFile );
if(handle->file) fclose( handle->file );
if( !(handle->flags&FILE_READ) && !(handle->flags&WRITE_ALWAYS) && (handle->fileTarget != NULL))
{
if( !areFileSame( handle->f1_name, handle->f2_name ) )
copyFile( handle->f2_name, handle->f1_name );
fileDelete( handle->f2_name );
}
memset( handle, 0, sizeof(FileHandle) );
TA_Free( handle );
}
static void fileDelete( const char *fileToDelete )
{
init_gToOpen( fileToDelete, NULL );
#if defined (WIN32)
DeleteFile (fileToDelete);
#else
unlink (fileToDelete);
#endif
}
static int genCode(int argc, char* argv[])
{
TA_RetCode retCode;
unsigned int nbGroup;
FileHandle *tempFile;
FileHandle *tempFileOut;
(void)argc;
(void)argv;
#ifdef _MSC_VER
#define FILE_NET_PROJ ta_fs_path(6, "..", "..", "dotnet", "src", "Core", "TA-Lib-Core.vcproj")
#define FILE_NET_PROJ_TMP ta_fs_path(3, "..", "temp", "dotnetproj.tmp")
gOutProjFile = fileOpen( FILE_NET_PROJ, NULL, FILE_READ );
if( gOutProjFile == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
tempFile = fileOpen( FILE_NET_PROJ_TMP, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile == NULL )
{
printf( "Cannot create temporary .NET project file!\n" );
return -1;
}
if( createProjTemplate( gOutProjFile, tempFile ) != 0 )
{
printf( "Failed to parse and write the temporary .NET project file!\n" );
return -1;
}
fileClose(gOutProjFile);
fileClose(tempFile);
#define FILE_MSVC_PROJ ta_fs_path(8, "..", "..", "c", "ide", "msvc", "lib_proj", "ta_func", "ta_func.dsp")
#define FILE_MSVC_PROJ_TMP ta_fs_path(3, "..", "temp", "ta_func_dsp.tmp")
gOutMSVCProjFile = fileOpen( FILE_MSVC_PROJ, NULL, FILE_READ );
if( gOutMSVCProjFile == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
tempFile = fileOpen( FILE_MSVC_PROJ_TMP, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile == NULL )
{
printf( "Cannot create temporary MSVC project file!\n" );
return -1;
}
if( createMSVCProjTemplate( gOutMSVCProjFile, tempFile ) != 0 )
{
printf( "Failed to parse and write the temporary MSVC project file!\n" );
return -1;
}
fileClose(gOutMSVCProjFile);
fileClose(tempFile);
#define FILE_VS2005_PROJ ta_fs_path(8, "..", "..", "c", "ide", "vs2005", "lib_proj", "ta_func", "ta_func.vcproj")
#define FILE_VS2005_PROJ_TMP ta_fs_path(3, "..", "temp", "ta_func_vcproj05.tmp")
gOutVS2005ProjFile = fileOpen( FILE_VS2005_PROJ, NULL, FILE_READ );
if( gOutVS2005ProjFile == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
tempFile = fileOpen( FILE_VS2005_PROJ_TMP, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile == NULL )
{
printf( "Cannot create temporary VS2005 project file!\n" );
return -1;
}
if( createVS2005ProjTemplate( gOutVS2005ProjFile, tempFile ) != 0 )
{
printf( "Failed to parse and write the temporary VS2005 project file!\n" );
return -1;
}
fileClose(gOutVS2005ProjFile);
fileClose(tempFile);
#define FILE_VS2008_PROJ ta_fs_path(8, "..", "..", "c", "ide", "vs2008", "lib_proj", "ta_func", "ta_func.vcproj")
#define FILE_VS2008_PROJ_TMP ta_fs_path(3, "..", "temp", "ta_func_vcproj08.tmp")
gOutVS2008ProjFile = fileOpen( FILE_VS2008_PROJ, NULL, FILE_READ );
if( gOutVS2008ProjFile == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
tempFile = fileOpen( FILE_VS2008_PROJ_TMP, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile == NULL )
{
printf( "Cannot create temporary VS2008 project file!\n" );
return -1;
}
if( createVS2005ProjTemplate( gOutVS2008ProjFile, tempFile ) != 0 )
{
printf( "Failed to parse and write the temporary VS2008 project file!\n" );
return -1;
}
fileClose(gOutVS2008ProjFile);
fileClose(tempFile);
#ifdef TA_LIB_PRO
#endif
#endif
#define FILE_CORE_JAVA ta_fs_path(9, "..", "..", "java", "src", "com", "tictactec", "ta", "lib", "Core.java")
#define FILE_CORE_JAVA_TMP ta_fs_path(3, "..", "temp", "CoreJava.tmp")
#define FILE_CORE_JAVA_UNF ta_fs_path(3, "..", "temp", "CoreJavaUnformated.tmp")
gOutCore_Java = fileOpen( FILE_CORE_JAVA, NULL, FILE_READ );
if( gOutCore_Java == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
tempFile = fileOpen( FILE_CORE_JAVA_TMP, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile == NULL )
{
printf( "Cannot create temporary Core.java project file!\n" );
return -1;
}
if( createTemplate( gOutCore_Java, tempFile ) != 0 )
{
printf( "Failed to parse and write the temporary Core.java project file!\n" );
return -1;
}
fileClose(gOutCore_Java);
fileClose(tempFile);
#ifdef _MSC_VER
#define FILE_NET_HEADER ta_fs_path(6, "..", "..", "dotnet", "src", "Core", "TA-Lib-Core.h")
#define FILE_NET_HEADER_TMP ta_fs_path(3, "..", "temp", "dotneth.tmp")
gOutDotNet_H = fileOpen( FILE_NET_HEADER, NULL, FILE_READ );
if( gOutDotNet_H == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
tempFile = fileOpen( FILE_NET_HEADER_TMP, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile == NULL )
{
printf( "Cannot create temporary .NET header file!\n" );
return -1;
}
if( createTemplate( gOutDotNet_H, tempFile ) != 0 )
{
printf( "Failed to parse and write the temporary .NET header file!\n" );
return -1;
}
fileClose(gOutDotNet_H);
fileClose(tempFile);
#endif
if( gen_retcode() != 0 )
{
printf( "\nCannot generate src/ta_common/ta_retcode.c\n" );
return -1;
}
gOutFunc_H = fileOpen( ta_fs_path(3, "..", "include", "ta_func.h"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_func.h.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutFunc_H == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutFunc_XML = fileOpen( ta_fs_path(3, "..", "..", "ta_func_api.xml"), NULL, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if(gOutFunc_XML == NULL)
{
printf( "\nCannot access ta_func_api.xml" );
}
gOutFunc_SWG = fileOpen( ta_fs_path(6, "..", "..", "swig", "src", "interface", "ta_func.swg"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_func.swg.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutFunc_SWG == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutFuncList_TXT = fileOpen( ta_fs_path(3, "..", "..", "ta_func_list.txt"),
NULL,
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutFuncList_TXT == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutFrame_H = fileOpen( ta_fs_path(5, "..", "src", "ta_abstract", "frames", "ta_frame.h"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_frame.h.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutFrame_H == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutFrame_C = fileOpen( ta_fs_path(5, "..", "src", "ta_abstract", "frames", "ta_frame.c"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_frame.c.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutFrame_C == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutMakefile_AM = fileOpen( ta_fs_path(4, "..", "src", "ta_func", "Makefile.am"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "Makefile.am.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutMakefile_AM == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutJavaDefs_H = fileOpen( ta_fs_path(4, "..", "src", "ta_abstract", "ta_java_defs.h"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_java_defs.h.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutJavaDefs_H == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
#ifdef _MSC_VER
gOutExcelGlue_C = fileOpen( ta_fs_path(4, "..", "src", "ta_abstract", "excel_glue.c"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "excel_glue.c.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutExcelGlue_C == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutProjFile = fileOpen( FILE_NET_PROJ, FILE_NET_PROJ_TMP, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutProjFile == NULL )
{
printf( "Cannot update [%s]\n", FILE_NET_PROJ );
return -1;
}
gOutMSVCProjFile = fileOpen( FILE_MSVC_PROJ, FILE_MSVC_PROJ_TMP, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutMSVCProjFile == NULL )
{
printf( "Cannot update [%s]\n", FILE_MSVC_PROJ );
return -1;
}
gOutVS2005ProjFile = fileOpen( FILE_VS2005_PROJ, FILE_VS2005_PROJ_TMP, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutVS2005ProjFile == NULL )
{
printf( "Cannot update [%s]\n", FILE_VS2005_PROJ );
return -1;
}
gOutVS2008ProjFile = fileOpen( FILE_VS2008_PROJ, FILE_VS2008_PROJ_TMP, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutVS2008ProjFile == NULL )
{
printf( "Cannot update [%s]\n", FILE_VS2008_PROJ );
return -1;
}
#ifdef TA_LIB_PRO
#endif
#endif
gOutFunc_Annotation = fileOpen( ta_fs_path(9, "..", "..", "java", "src", "com", "tictactec", "ta", "lib", "CoreAnnotated.java"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "CoreAnnotated.java.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if(gOutFunc_Annotation == NULL)
{
printf( "\nCannot access CoreAnnotated.java" );
}
gOutCore_Java = fileOpen( FILE_CORE_JAVA_UNF, FILE_CORE_JAVA_TMP, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutCore_Java == NULL )
{
printf( "Cannot update [%s]\n", FILE_CORE_JAVA_UNF );
return -1;
}
#ifdef _MSC_VER
gOutDotNet_H = fileOpen( FILE_NET_HEADER, FILE_NET_HEADER_TMP, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutDotNet_H == NULL )
{
printf( "Cannot update [%s]\n", FILE_NET_HEADER );
return -1;
}
#endif
TA_ForEachFunc( doForEachFunctionPhase1, NULL );
TA_ForEachFunc( doForEachFunctionPhase2, NULL );
fprintf( gOutMakefile_AM->file, "\n" );
fprintf(gOutFunc_XML->file, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
fprintf(gOutFunc_XML->file, "<FinancialFunctions>\n");
retCode = TA_ForEachFunc( doForEachFunctionXml, NULL );
fprintf(gOutFunc_XML->file, "</FinancialFunctions>\n");
appendToFunc( gOutFunc_H->file );
appendToFunc( gOutFunc_SWG->file );
#ifdef TA_LIB_PRO
#endif
fileClose( gOutFuncList_TXT );
fileClose( gOutFunc_H );
fileClose( gOutFunc_SWG );
fileClose( gOutFrame_H );
fileClose( gOutFrame_C );
fileClose( gOutFunc_XML );
fileClose( gOutMakefile_AM );
fileClose( gOutCore_Java );
fileClose( gOutJavaDefs_H );
fileClose( gOutFunc_Annotation );
fileDelete( FILE_CORE_JAVA_TMP );
#ifdef _MSC_VER
fileClose( gOutDotNet_H );
fileClose( gOutVS2005ProjFile );
fileClose( gOutVS2008ProjFile );
fileClose( gOutProjFile );
fileClose( gOutMSVCProjFile );
fileClose( gOutExcelGlue_C );
#ifdef TA_LIB_PRO
#endif
#endif
if( retCode != TA_SUCCESS )
{
printf( "Failed [%d]\n", retCode );
return -1;
}
genPrefix = 1;
gOutGroupIdx_C = fileOpen( ta_fs_path(4, "..", "src", "ta_abstract", "ta_group_idx.c"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_group_idx.c.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutGroupIdx_C == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
retCode = TA_ForEachFunc( printExternReferenceForEachFunction, NULL );
if( retCode != TA_SUCCESS )
{
fileClose( gOutGroupIdx_C );
return -1;
}
nbGroup = forEachGroup( printPerGroupList, NULL );
print( gOutGroupIdx_C->file, "const TA_FuncDef **TA_PerGroupFuncDef[%d] = {\n", nbGroup );
forEachGroup( printGroupListAddress, NULL );
print( gOutGroupIdx_C->file, "};\n\n" );
print( gOutGroupIdx_C->file, "const unsigned int TA_PerGroupSize[%d] = {\n", nbGroup );
forEachGroup( printGroupSize, NULL );
print( gOutGroupIdx_C->file, "};\n\n" );
print( gOutGroupIdx_C->file, "const unsigned int TA_TotalNbFunction =\n" );
forEachGroup( printGroupSizeAddition, NULL );
fileClose( gOutGroupIdx_C );
genPrefix = 0;
doDefsFile();
if( generateFuncAPI_C() != 1 )
{
return -1;
}
printf( "\nPost-Processing Java Code\n" );
# define JAVA_SUCCESS_FILE ta_fs_path(3, "..", "temp", "java_success")
#define JAVA_PRETTY_TEMP_FILE ta_fs_path(3, "..", "temp", "CoreJavaPretty.tmp")
fileDelete( JAVA_SUCCESS_FILE );
#ifdef _MSC_VER
system( "javac -cp . -d . \".." TA_FS_SLASH "src" TA_FS_SLASH "tools" TA_FS_SLASH "gen_code" TA_FS_SLASH "java" TA_FS_SLASH "PrettyCode.java" );
system( "javac -cp . -d . \".." TA_FS_SLASH "src" TA_FS_SLASH "tools" TA_FS_SLASH "gen_code" TA_FS_SLASH "java" TA_FS_SLASH "Main.java" );
#else
system( "javac -cp . -d . .." TA_FS_SLASH "src" TA_FS_SLASH "tools" TA_FS_SLASH "gen_code" TA_FS_SLASH "java" TA_FS_SLASH "PrettyCode.java" );
system( "javac -cp . -d . .." TA_FS_SLASH "src" TA_FS_SLASH "tools" TA_FS_SLASH "gen_code" TA_FS_SLASH "java" TA_FS_SLASH "Main.java" );
#endif
system( "java -cp . Main" );
tempFile = fileOpen(JAVA_SUCCESS_FILE,NULL,FILE_READ );
fileDelete( FILE_CORE_JAVA_UNF );
if( tempFile == NULL )
{
printf( "\nWarning: Java code NOT updated.\n" );
}
else
{
fileClose( tempFile );
tempFile = fileOpen( JAVA_PRETTY_TEMP_FILE, NULL, FILE_READ );
tempFileOut = fileOpen( FILE_CORE_JAVA, NULL,
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( (tempFile == NULL) || (tempFileOut == NULL) )
{
printf( "\nError: Java code update failed.\n" );
return -1;
}
else
{
while( fgets( gTempBuf, BUFFER_SIZE, tempFile->file ) )
fputs(gTempBuf,tempFileOut->file);
fileClose(tempFile);
fileClose(tempFileOut);
}
}
fileDelete( JAVA_SUCCESS_FILE );
fileDelete( JAVA_PRETTY_TEMP_FILE );
#ifdef _MSC_VER
fileDelete( FILE_NET_PROJ_TMP );
fileDelete( FILE_MSVC_PROJ_TMP );
fileDelete( FILE_NET_HEADER_TMP );
#endif
printf( "\n** Update completed with success **\n");
return 0;
}
static unsigned int forEachGroup( TA_ForEachGroup forEachGroupFunc,
void *opaqueData )
{
TA_RetCode retCode;
TA_StringTable *table;
unsigned int i;
(void)opaqueData;
retCode = TA_GroupTableAlloc( &table );
if( retCode != TA_SUCCESS )
return 0;
for( i=0; i < table->size; i++ )
{
forEachGroupFunc( table->string[i],
i,
i==0? 1:0,
i==(table->size-1)? 1:0 );
}
retCode = TA_GroupTableFree( table );
if( retCode != TA_SUCCESS )
return 0;
return i;
}
static void ReplaceReservedXmlCharacters(const char *input, char *output )
{
char *currentPosition;
char tempString[8*1024];
if((input == NULL) || (output == NULL))
{
return;
}
strcpy(output, input);
currentPosition = output;
while((currentPosition = strchr(currentPosition, '&')) != NULL)
{
tempString[0] = '\0';
if(strlen(currentPosition) > 1)
{
strcpy(tempString, currentPosition+1);
}
sprintf(currentPosition, "&%s", tempString);
}
currentPosition = output;
while((currentPosition = strchr(currentPosition, '<')) != NULL)
{
tempString[0] = '\0';
if(strlen(currentPosition) > 1)
{
strcpy(tempString, currentPosition+1);
}
sprintf(currentPosition, "<%s", tempString);
}
currentPosition = output;
while((currentPosition = strchr(currentPosition, '>')) != NULL)
{
tempString[0] = '\0';
if(strlen(currentPosition) > 1)
{
strcpy(tempString, currentPosition+1);
}
sprintf(currentPosition, ">%s", tempString);
}
currentPosition = output;
while((currentPosition = strchr(currentPosition, '\'')) != NULL)
{
tempString[0] = '\0';
if(strlen(currentPosition) > 1)
{
strcpy(tempString, currentPosition+1);
}
sprintf(currentPosition, "'%s", tempString);
}
currentPosition = output;
while((currentPosition = strchr(currentPosition, '"')) != NULL)
{
tempString[0] = '\0';
if(strlen(currentPosition) > 1)
{
strcpy(tempString, currentPosition+1);
}
sprintf(currentPosition, ""%s", tempString);
}
}
static void doForEachFunctionXml(const TA_FuncInfo *funcInfo,
void *opaqueData)
{
TA_RetCode retCode;
const TA_InputParameterInfo *inputInfo;
const TA_OptInputParameterInfo *optInputInfo;
const TA_OutputParameterInfo *outputInfo;
char tempString[8*1024];
unsigned int i;
(void)opaqueData;
fprintf(gOutFunc_XML->file, " <!-- %s -->\n", funcInfo->name);
fprintf(gOutFunc_XML->file, " <FinancialFunction>\n");
fprintf(gOutFunc_XML->file, " <Abbreviation>%s</Abbreviation>\n", (funcInfo->name == NULL)? "" : funcInfo->name);
fprintf(gOutFunc_XML->file, " <CamelCaseName>%s</CamelCaseName>\n", (funcInfo->camelCaseName == NULL)? "" : funcInfo->camelCaseName);
ReplaceReservedXmlCharacters(funcInfo->hint, tempString);
fprintf(gOutFunc_XML->file, " <ShortDescription>%s</ShortDescription>\n", (funcInfo->hint == NULL)? "" : tempString);
fprintf(gOutFunc_XML->file, " <GroupId>%s</GroupId>\n", funcInfo->group);
if(funcInfo->flags & (TA_FUNC_FLG_OVERLAP | TA_FUNC_FLG_VOLUME | TA_FUNC_FLG_CANDLESTICK | TA_FUNC_FLG_UNST_PER))
{
fprintf(gOutFunc_XML->file, " <Flags>\n");
if(funcInfo->flags & TA_FUNC_FLG_OVERLAP)
{
fprintf(gOutFunc_XML->file, " <Flag>Overlap</Flag>\n");
}
if(funcInfo->flags & TA_FUNC_FLG_VOLUME)
{
fprintf(gOutFunc_XML->file, " <Flag>Volume</Flag>\n");
}
if(funcInfo->flags & TA_FUNC_FLG_CANDLESTICK)
{
fprintf(gOutFunc_XML->file, " <Flag>Candlestick</Flag>\n");
}
if(funcInfo->flags & TA_FUNC_FLG_UNST_PER)
{
fprintf(gOutFunc_XML->file, " <Flag>Unstable Period</Flag>\n");
}
fprintf(gOutFunc_XML->file, " </Flags>\n");
}
fprintf(gOutFunc_XML->file, " <RequiredInputArguments>\n");
for(i=0; i<funcInfo->nbInput; i++)
{
retCode = TA_GetInputParameterInfo( funcInfo->handle, i, &inputInfo);
if(inputInfo->type == TA_Input_Price)
{
if(inputInfo->flags & TA_IN_PRICE_OPEN)
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Type>Open</Type>\n");
fprintf(gOutFunc_XML->file, " <Name>Open</Name>\n");
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
if(inputInfo->flags & TA_IN_PRICE_HIGH)
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Type>High</Type>\n");
fprintf(gOutFunc_XML->file, " <Name>High</Name>\n");
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
if(inputInfo->flags & TA_IN_PRICE_LOW)
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Type>Low</Type>\n");
fprintf(gOutFunc_XML->file, " <Name>Low</Name>\n");
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
if(inputInfo->flags & TA_IN_PRICE_CLOSE)
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Type>Close</Type>\n");
fprintf(gOutFunc_XML->file, " <Name>Close</Name>\n");
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
if(inputInfo->flags & TA_IN_PRICE_VOLUME)
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Type>Volume</Type>\n");
fprintf(gOutFunc_XML->file, " <Name>Volume</Name>\n");
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
if(inputInfo->flags & TA_IN_PRICE_OPENINTEREST)
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Type>Open Interest</Type>\n");
fprintf(gOutFunc_XML->file, " <Name>Open Interest</Name>\n");
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
if(inputInfo->flags & TA_IN_PRICE_TIMESTAMP)
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Type>Timestamp</Type>\n");
fprintf(gOutFunc_XML->file, " <Name>Timestamp</Name>\n");
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
}
else
{
fprintf(gOutFunc_XML->file, " <RequiredInputArgument>\n");
if(inputInfo->type == TA_Input_Real)
{
fprintf(gOutFunc_XML->file, " <Type>Double Array</Type>\n");
}
else if(inputInfo->type == TA_Input_Integer)
{
fprintf(gOutFunc_XML->file, " <Type>Integer Array</Type>\n");
}
else
{
printf("Unknown input type detected.\n");
}
fprintf(gOutFunc_XML->file, " <Name>%s</Name>\n", inputInfo->paramName);
fprintf(gOutFunc_XML->file, " </RequiredInputArgument>\n");
}
}
fprintf(gOutFunc_XML->file, " </RequiredInputArguments>\n");
if(funcInfo->nbOptInput > 0)
{
fprintf(gOutFunc_XML->file, " <OptionalInputArguments>\n");
for(i=0; i<funcInfo->nbOptInput; i++)
{
retCode = TA_GetOptInputParameterInfo( funcInfo->handle, i, &optInputInfo );
fprintf(gOutFunc_XML->file, " <OptionalInputArgument>\n");
fprintf(gOutFunc_XML->file, " <Name>%s</Name>\n", optInputInfo->displayName);
ReplaceReservedXmlCharacters(optInputInfo->hint, tempString);
fprintf(gOutFunc_XML->file, " <ShortDescription>%s</ShortDescription>\n", (optInputInfo->hint == NULL)? "" : tempString);
if(optInputInfo->flags != 0)
{
fprintf(gOutFunc_XML->file, " <Flags>\n");
if(optInputInfo->flags & TA_OPTIN_IS_PERCENT)
{
fprintf(gOutFunc_XML->file, " <Flag>Percent</Flag>\n");
}
if(optInputInfo->flags & TA_OPTIN_IS_DEGREE)
{
fprintf(gOutFunc_XML->file, " <Flag>Degree</Flag>\n");
}
if(optInputInfo->flags & TA_OPTIN_IS_CURRENCY)
{
fprintf(gOutFunc_XML->file, " <Flag>Currency</Flag>\n");
}
if(optInputInfo->flags & TA_OPTIN_ADVANCED)
{
fprintf(gOutFunc_XML->file, " <Flag>Advanced</Flag>\n");
}
fprintf(gOutFunc_XML->file, " </Flags>\n");
}
if(optInputInfo->type == TA_OptInput_RealRange)
{
TA_RealRange *doubleRange;
doubleRange= (TA_RealRange*)optInputInfo->dataSet;
fprintf(gOutFunc_XML->file, " <Type>Double</Type>\n");
fprintf(gOutFunc_XML->file, " <Range>\n");
fprintf(gOutFunc_XML->file, " <Minimum>%s</Minimum>\n", doubleToStr(doubleRange->min));
fprintf(gOutFunc_XML->file, " <Maximum>%s</Maximum>\n", doubleToStr(doubleRange->max));
fprintf(gOutFunc_XML->file, " <Precision>%d</Precision>\n", doubleRange->precision);
fprintf(gOutFunc_XML->file, " <SuggestedStart>%s</SuggestedStart>\n", doubleToStr(doubleRange->suggested_start));
fprintf(gOutFunc_XML->file, " <SuggestedEnd>%s</SuggestedEnd>\n", doubleToStr(doubleRange->suggested_end));
fprintf(gOutFunc_XML->file, " <SuggestedIncrement>%s</SuggestedIncrement>\n", doubleToStr(doubleRange->suggested_increment));
fprintf(gOutFunc_XML->file, " </Range>\n");
fprintf(gOutFunc_XML->file, " <DefaultValue>%s</DefaultValue>\n", doubleToStr(optInputInfo->defaultValue));
}
else if(optInputInfo->type == TA_OptInput_IntegerRange)
{
TA_IntegerRange *integerRange;
integerRange = (TA_IntegerRange*)optInputInfo->dataSet;
fprintf(gOutFunc_XML->file, " <Type>Integer</Type>\n");
fprintf(gOutFunc_XML->file, " <Range>\n");
fprintf(gOutFunc_XML->file, " <Minimum>%d</Minimum>\n", integerRange->min);
fprintf(gOutFunc_XML->file, " <Maximum>%d</Maximum>\n", integerRange->max);
fprintf(gOutFunc_XML->file, " <SuggestedStart>%d</SuggestedStart>\n", integerRange->max);
fprintf(gOutFunc_XML->file, " <SuggestedEnd>%d</SuggestedEnd>\n", integerRange->max);
fprintf(gOutFunc_XML->file, " <SuggestedIncrement>%d</SuggestedIncrement>\n", integerRange->max);
fprintf(gOutFunc_XML->file, " </Range>\n");
fprintf(gOutFunc_XML->file, " <DefaultValue>%d</DefaultValue>\n", (int)optInputInfo->defaultValue);
}
else if(optInputInfo->type == TA_OptInput_IntegerList)
{
TA_IntegerList *intList;
intList = (TA_IntegerList*) optInputInfo->dataSet;
fprintf(gOutFunc_XML->file, " <Type>MA Type</Type>\n");
fprintf(gOutFunc_XML->file, " <DefaultValue>%d</DefaultValue>\n", (int)optInputInfo->defaultValue);
if( intList != (TA_IntegerList*) TA_DEF_UI_MA_Method.dataSet )
{
printf("Integer lists are not supported.\n");
}
}
else
{
printf("Unknown optional input type detected.\n");
}
fprintf(gOutFunc_XML->file, " </OptionalInputArgument>\n");
}
fprintf(gOutFunc_XML->file, " </OptionalInputArguments>\n");
}
fprintf(gOutFunc_XML->file, " <OutputArguments>\n");
for(i=0; i<funcInfo->nbOutput; i++)
{
retCode = TA_GetOutputParameterInfo( funcInfo->handle, i, &outputInfo );
fprintf(gOutFunc_XML->file, " <OutputArgument>\n");
if(outputInfo->type == TA_Output_Integer)
{
fprintf(gOutFunc_XML->file, " <Type>Integer Array</Type>\n");
}
else if(outputInfo->type == TA_Output_Real)
{
fprintf(gOutFunc_XML->file, " <Type>Double Array</Type>\n");
}
else
{
printf("Unknown output type detected.\n");
}
fprintf(gOutFunc_XML->file, " <Name>%s</Name>\n", outputInfo->paramName);
if(outputInfo->flags != 0)
{
fprintf(gOutFunc_XML->file, " <Flags>\n");
if(outputInfo->flags & TA_OUT_LINE)
{
fprintf(gOutFunc_XML->file, " <Flag>Line</Flag>\n");
}
if(outputInfo->flags & TA_OUT_DOT_LINE)
{
fprintf(gOutFunc_XML->file, " <Flag>Dotted Line</Flag>\n");
}
if(outputInfo->flags & TA_OUT_DASH_LINE)
{
fprintf(gOutFunc_XML->file, " <Flag>Dashed Line</Flag>\n");
}
if(outputInfo->flags & TA_OUT_DOT)
{
fprintf(gOutFunc_XML->file, " <Flag>Dots</Flag>\n");
}
if(outputInfo->flags & TA_OUT_HISTO)
{
fprintf(gOutFunc_XML->file, " <Flag>Histogram</Flag>\n");
}
if(outputInfo->flags & TA_OUT_PATTERN_BOOL)
{
fprintf(gOutFunc_XML->file, " <Flag>Pattern Bool</Flag>\n");
}
if(outputInfo->flags & TA_OUT_PATTERN_BULL_BEAR)
{
fprintf(gOutFunc_XML->file, " <Flag>Pattern Bull Bear</Flag>\n");
}
if(outputInfo->flags & TA_OUT_PATTERN_STRENGTH)
{
fprintf(gOutFunc_XML->file, " <Flag>Pattern Strength</Flag>\n");
}
if(outputInfo->flags & TA_OUT_POSITIVE)
{
fprintf(gOutFunc_XML->file, " <Flag>Positive</Flag>\n");
}
if(outputInfo->flags & TA_OUT_NEGATIVE)
{
fprintf(gOutFunc_XML->file, " <Flag>Negative</Flag>\n");
}
if(outputInfo->flags & TA_OUT_ZERO)
{
fprintf(gOutFunc_XML->file, " <Flag>Zero</Flag>\n");
}
if(outputInfo->flags & TA_OUT_UPPER_LIMIT)
{
fprintf(gOutFunc_XML->file, " <Flag>Upper Limit</Flag>\n");
}
if(outputInfo->flags & TA_OUT_LOWER_LIMIT)
{
fprintf(gOutFunc_XML->file, " <Flag>Lower Limit</Flag>\n");
}
fprintf(gOutFunc_XML->file, " </Flags>\n");
}
fprintf(gOutFunc_XML->file, " </OutputArgument>\n");
}
fprintf(gOutFunc_XML->file, " </OutputArguments>\n");
fprintf(gOutFunc_XML->file, " </FinancialFunction>\n");
fprintf(gOutFunc_XML->file, "\n");
fprintf(gOutFunc_XML->file, "\n");
}
static void doForEachFunctionPhase1( const TA_FuncInfo *funcInfo,
void *opaqueData )
{
(void)opaqueData;
genJavaCodePhase1( funcInfo );
}
static void doForEachFunctionPhase2( const TA_FuncInfo *funcInfo,
void *opaqueData )
{
static int firstTime = 1;
(void)opaqueData;
genPrefix = 0;
fprintf( gOutFuncList_TXT->file, "%-20s%s\n", funcInfo->name, funcInfo->hint );
fprintf( gOutFunc_H->file, "\n" );
fprintf( gOutFunc_SWG->file, "\n" );
printf( "Processing [TA_%s]\n", funcInfo->name );
fprintf( gOutFunc_H->file, "/*\n" );
printFuncHeaderDoc( gOutFunc_H->file, funcInfo, " * " );
fprintf( gOutFunc_H->file, " */\n" );
fprintf( gOutFunc_SWG->file, "/*\n" );
printFuncHeaderDoc( gOutFunc_SWG->file, funcInfo, " * " );
fprintf( gOutFunc_SWG->file, " */\n" );
printDefines( gOutFunc_H->file, funcInfo );
printDefines( gOutFunc_SWG->file, funcInfo );
printFunc( gOutFunc_H->file, "TA_LIB_API ", funcInfo, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
fprintf( gOutFunc_H->file, "\n" );
printFunc( gOutFunc_H->file, "TA_LIB_API ", funcInfo, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 );
fprintf( gOutFunc_H->file, "\n" );
printFunc( gOutFunc_SWG->file, NULL, funcInfo, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 );
fprintf( gOutFunc_SWG->file, "\n" );
printFunc( gOutFunc_H->file, "TA_LIB_API ", funcInfo, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 );
printFunc( gOutFunc_SWG->file, NULL, funcInfo, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 );
genPrefix = 1;
printFrameHeader( gOutFrame_H->file, funcInfo, 0 );
fprintf( gOutFrame_H->file, ";\n" );
printFrameHeader( gOutFrame_H->file, funcInfo, 1 );
fprintf( gOutFrame_H->file, ";\n\n" );
printCallFrame( gOutFrame_C->file, funcInfo );
if( firstTime )
fprintf( gOutMakefile_AM->file, "\tta_%s.c", funcInfo->name );
else
fprintf( gOutMakefile_AM->file, " " TA_FS_SLASH "\n\tta_%s.c", funcInfo->name );
#ifdef _MSC_VER
fprintf( gOutProjFile->file, " <File\n" );
fprintf( gOutProjFile->file, " RelativePath=\".." TA_FS_SLASH ".." TA_FS_SLASH ".." TA_FS_SLASH "c" TA_FS_SLASH "src" TA_FS_SLASH "ta_func" TA_FS_SLASH "ta_%s.c\">\n", funcInfo->name );
fprintf( gOutProjFile->file, " <FileConfiguration\n" );
fprintf( gOutProjFile->file, " Name=\"Debug|Win32\">\n" );
fprintf( gOutProjFile->file, " <Tool\n" );
fprintf( gOutProjFile->file, " Name=\"VCCLCompilerTool\"\n" );
fprintf( gOutProjFile->file, " AdditionalIncludeDirectories=\"\"\n" );
fprintf( gOutProjFile->file, " UsePrecompiledHeader=\"0\"\n" );
fprintf( gOutProjFile->file, " CompileAs=\"2\"/>\n" );
fprintf( gOutProjFile->file, " </FileConfiguration>\n" );
fprintf( gOutProjFile->file, " <FileConfiguration\n" );
fprintf( gOutProjFile->file, " Name=\"Release|Win32\">\n" );
fprintf( gOutProjFile->file, " <Tool\n" );
fprintf( gOutProjFile->file, " Name=\"VCCLCompilerTool\"\n" );
fprintf( gOutProjFile->file, " AdditionalIncludeDirectories=\"\"\n" );
fprintf( gOutProjFile->file, " UsePrecompiledHeader=\"0\"\n" );
fprintf( gOutProjFile->file, " CompileAs=\"2\"/>\n" );
fprintf( gOutProjFile->file, " </FileConfiguration>\n" );
fprintf( gOutProjFile->file, " <FileConfiguration\n" );
fprintf( gOutProjFile->file, " Name=\"Debug SubArray|Win32\">\n" );
fprintf( gOutProjFile->file, " <Tool\n" );
fprintf( gOutProjFile->file, " Name=\"VCCLCompilerTool\"\n" );
fprintf( gOutProjFile->file, " AdditionalIncludeDirectories=\"\"\n" );
fprintf( gOutProjFile->file, " UsePrecompiledHeader=\"0\"\n" );
fprintf( gOutProjFile->file, " CompileAs=\"2\"/>\n" );
fprintf( gOutProjFile->file, " </FileConfiguration>\n" );
fprintf( gOutProjFile->file, " <FileConfiguration\n" );
fprintf( gOutProjFile->file, " Name=\"Release SubArray|Win32\">\n" );
fprintf( gOutProjFile->file, " <Tool\n" );
fprintf( gOutProjFile->file, " Name=\"VCCLCompilerTool\"\n" );
fprintf( gOutProjFile->file, " AdditionalIncludeDirectories=\"\"\n" );
fprintf( gOutProjFile->file, " UsePrecompiledHeader=\"0\"\n" );
fprintf( gOutProjFile->file, " CompileAs=\"2\"/>\n" );
fprintf( gOutProjFile->file, " </FileConfiguration>\n" );
fprintf( gOutProjFile->file, " </File>\n" );
fprintf( gOutMSVCProjFile->file, "# Begin Source File\n" );
fprintf( gOutMSVCProjFile->file, "\n" );
fprintf( gOutMSVCProjFile->file, "SOURCE=.." TA_FS_SLASH ".." TA_FS_SLASH ".." TA_FS_SLASH ".." TA_FS_SLASH "src" TA_FS_SLASH "ta_func" TA_FS_SLASH "ta_%s.c\n", funcInfo->name );
fprintf( gOutMSVCProjFile->file, "# End Source File\n" );
printVS2005FileNode( gOutVS2005ProjFile->file, funcInfo->name );
printVS2005FileNode( gOutVS2008ProjFile->file, funcInfo->name );
#ifdef TA_LIB_PRO
#endif
printExcelGlueCode( gOutExcelGlue_C->file, funcInfo );
#endif
printJavaFunctionAnnotation( funcInfo );
#ifdef _MSC_VER
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 );
fprintf( gOutDotNet_H->file, " #if defined( _MANAGED ) && defined( USE_SUBARRAY )\n" );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0 );
fprintf( gOutDotNet_H->file, "\n" );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0 );
fprintf( gOutDotNet_H->file, "\n" );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 );
fprintf( gOutDotNet_H->file, " { return " );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1 );
fprintf( gOutDotNet_H->file, " }\n" );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 );
fprintf( gOutDotNet_H->file, " { return " );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1 );
fprintf( gOutDotNet_H->file, " }\n" );
fprintf( gOutDotNet_H->file, " #elif defined( _MANAGED )\n" );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 );
printFunc( gOutDotNet_H->file, NULL, funcInfo, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 );
fprintf( gOutDotNet_H->file, " #endif\n" );
fprintf( gOutDotNet_H->file, "\n" );
fprintf( gOutDotNet_H->file, " #define TA_%s Core::%s\n", funcInfo->name, funcInfo->camelCaseName );
fprintf( gOutDotNet_H->file, " #define TA_%s_Lookback Core::%sLookback\n\n", funcInfo->name, funcInfo->camelCaseName );
#endif
doFuncFile( funcInfo );
genJavaCodePhase2( funcInfo );
firstTime = 0;
}
static void doForEachUnstableFunction( const TA_FuncInfo *funcInfo,
void *opaqueData )
{
unsigned int *i;
i = (unsigned int *)opaqueData;
if( funcInfo->flags & TA_FUNC_FLG_UNST_PER )
{
print( gOutDefs_H->file, " /* %03d */ ENUM_DEFINE( TA_FUNC_UNST_%s, %s),\n", *i, funcInfo->name, funcInfo->camelCaseName );
(*i)++;
}
}
static void printDefines( FILE *out, const TA_FuncInfo *funcInfo )
{
TA_RetCode retCode;
const TA_OptInputParameterInfo *optInputParamInfo;
unsigned int i, j;
unsigned int paramNb;
const char *paramName;
const char *defaultParamName;
TA_IntegerList *intList;
TA_RealList *realList;
paramNb = 0;
for( i=0; i < funcInfo->nbOptInput; i++ )
{
retCode = TA_GetOptInputParameterInfo( funcInfo->handle,
i, &optInputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'optional input' information\n", funcInfo->name );
return;
}
paramName = optInputParamInfo->paramName;
switch( optInputParamInfo->type )
{
case TA_OptInput_RealList:
defaultParamName = "optInReal";
break;
case TA_OptInput_IntegerList:
defaultParamName = "optInInteger";
break;
default:
paramNb++;
continue;
}
if( !paramName )
paramName = defaultParamName;
switch( optInputParamInfo->type )
{
case TA_OptInput_IntegerList:
intList = (TA_IntegerList *)optInputParamInfo->dataSet;
if( intList != (TA_IntegerList *)TA_DEF_UI_MA_Method.dataSet )
{
fprintf( out, "\n/* TA_%s: Optional Parameter %s */\n",
funcInfo->name, paramName );
for( j=0; j < intList->nbElement; j++ )
{
strcpy( gTempBuf, intList->data[j].string );
cnvtChar( gTempBuf, ' ', '_' );
trimWhitespace( gTempBuf );
cnvtToUpperCase( gTempBuf );
fprintf( out, "#define TA_%s_%s %d\n",
funcInfo->name,
gTempBuf,
intList->data[j].value );
}
fprintf( out, "\n" );
}
break;
case TA_OptInput_RealList:
fprintf( out, "\n/* TA_%s: Optional Parameter %s */\n",
funcInfo->name, paramName );
realList = (TA_RealList *)optInputParamInfo->dataSet;
for( j=0; j < realList->nbElement; j++ )
{
strcpy( gTempBuf, realList->data[j].string );
cnvtChar( gTempBuf, ' ', '_' );
trimWhitespace( gTempBuf );
cnvtToUpperCase( gTempBuf );
fprintf( out, "#define TA_%s_%s %s\n",
funcInfo->name,
gTempBuf,
doubleToStr(realList->data[j].value) );
}
fprintf( out, "\n" );
break;
default:
break;
}
paramNb++;
}
}
static void printFunc( FILE *out,
const char *prefix,
const TA_FuncInfo *funcInfo,
unsigned int prototype,
unsigned int frame,
unsigned int semiColonNeeded,
unsigned int validationCode,
unsigned int lookbackSignature,
unsigned int managedCPPCode,
unsigned int managedCPPDeclaration,
unsigned int inputIsSinglePrecision,
unsigned int outputForSWIG,
unsigned int outputForJava,
unsigned int lookbackValidationCode,
unsigned int useSubArrayObject,
unsigned int arrayToSubArrayCnvt
)
{
TA_RetCode retCode;
unsigned int i, j, k, lastParam;
int indent;
unsigned int paramNb;
const char *paramName;
const char *defaultParamName;
const TA_InputParameterInfo *inputParamInfo;
const TA_OptInputParameterInfo *optInputParamInfo;
const TA_OutputParameterInfo *outputParamInfo;
const char *typeString;
const char *inputDoubleArrayType;
const char *inputIntArrayType;
const char *outputDoubleArrayType;
const char *outputIntArrayType;
const char *outputIntParam;
const char *arrayBracket;
const char *funcName;
int excludeFromManaged;
int isMAType;
const char *startIdxString;
const char *endIdxString;
const char *outNbElementString;
const char *outBegIdxString;
char funcNameBuffer[1024];
if( arrayToSubArrayCnvt )
{
inputIntArrayType = "int";
if( inputIsSinglePrecision )
{
inputDoubleArrayType = "float";
}
else
{
inputDoubleArrayType = "double";
}
outputDoubleArrayType = "double";
outputIntArrayType = "int";
outputIntParam = " ";
arrayBracket = " ";
startIdxString = "startIdx";
endIdxString = "endIdx";
outNbElementString = "outNBElement";
outBegIdxString = "outBegIdx";
funcName = funcInfo->camelCaseName;
}
else if( managedCPPCode )
{
if( inputIsSinglePrecision )
{
inputDoubleArrayType = useSubArrayObject? "SubArray<float>^":"cli::array<float>^";
}
else
{
inputDoubleArrayType = useSubArrayObject? "SubArray<double>^":"cli::array<double>^";
}
inputIntArrayType = useSubArrayObject? "SubArray<int>^" : "cli::array<int>^";
outputDoubleArrayType = useSubArrayObject? "SubArray<double>^": "cli::array<double>^";
outputIntArrayType = useSubArrayObject? "SubArray<int>^" : "cli::array<int>^";
outputIntParam = "[Out]int%";
arrayBracket = "";
startIdxString = "startIdx";
endIdxString = "endIdx";
outNbElementString = "outNBElement";
outBegIdxString = "outBegIdx";
funcName = funcInfo->camelCaseName;
}
else if( outputForSWIG )
{
if( inputIsSinglePrecision )
inputDoubleArrayType = "const float *";
else
inputDoubleArrayType = "const double *";
inputIntArrayType = "const int *";
outputIntArrayType = "int";
outputDoubleArrayType = "double";
outputIntParam = "int";
arrayBracket = "";
startIdxString = " START_IDX";
endIdxString = " END_IDX";
outNbElementString = "OUT_SIZE";
outBegIdxString = "BEG_IDX";
funcName = funcInfo->name;
}
else if( outputForJava )
{
if( inputIsSinglePrecision )
inputDoubleArrayType = "float";
else
inputDoubleArrayType = "double";
inputIntArrayType = "int";
outputDoubleArrayType = "double";
outputIntArrayType = "int";
outputIntParam = "MInteger";
arrayBracket = "[]";
startIdxString = "startIdx";
endIdxString = "endIdx";
outNbElementString = "outNBElement";
outBegIdxString = "outBegIdx";
funcName = funcNameBuffer;
strcpy( funcNameBuffer, funcInfo->camelCaseName );
funcNameBuffer[0] = tolower(funcNameBuffer[0]);
}
else
{
if( inputIsSinglePrecision )
inputDoubleArrayType = "const float";
else
inputDoubleArrayType = "const double";
inputIntArrayType = "const int";
outputDoubleArrayType = "double";
outputIntArrayType = "int";
outputIntParam = "int";
arrayBracket = "[]";
startIdxString = "startIdx";
endIdxString = "endIdx";
outNbElementString = "outNBElement";
outBegIdxString = "outBegIdx";
funcName = funcInfo->name;
}
typeString = "";
defaultParamName = "";
if( prototype )
{
if( lookbackSignature )
{
if( managedCPPCode )
{
sprintf( gTempBuf, "%s%sint %s%sLookback( ",
prefix? prefix:"",
managedCPPDeclaration? " static ":"",
managedCPPDeclaration? "":"Core::",
funcName );
}
else if( outputForJava )
{
sprintf( gTempBuf, "%spublic int %sLookback( ",
prefix? prefix:"",
funcName );
}
else
{
sprintf( gTempBuf, "%sint TA_%s_Lookback( ",
prefix? prefix:"",
funcName );
}
print( out, gTempBuf );
indent = (unsigned int)strlen(gTempBuf) - 2;
}
else
{
if( arrayToSubArrayCnvt )
{
sprintf( gTempBuf, "%s%s( %s, ", prefix? prefix:"", funcName, startIdxString );
}
else if( managedCPPCode )
{
sprintf( gTempBuf, "%s%senum class %sRetCode %s%s( int %s,\n",
prefix? prefix:"",
managedCPPDeclaration? " static ":"",
managedCPPDeclaration? "":"Core::",
managedCPPDeclaration? "":"Core::",
funcName,
startIdxString );
}
else if( outputForJava )
{
sprintf( gTempBuf, "%spublic RetCode %s( int %s,\n",
prefix? prefix:"",
funcName,
startIdxString );
}
else
{
if( inputIsSinglePrecision )
sprintf( gTempBuf, "%sTA_RetCode TA_S_%s( int %s,\n",
prefix? prefix:"",
funcName,
startIdxString );
else
sprintf( gTempBuf, "%sTA_RetCode TA_%s( int %s,\n",
prefix? prefix:"",
funcName,
startIdxString );
}
print( out, gTempBuf );
indent = (unsigned int)strlen(gTempBuf);
if( outputForSWIG )
indent -= 25;
else
indent -= 17;
if( indent < 0 ) indent = 0;
printIndent( out, indent );
if( arrayToSubArrayCnvt )
fprintf( out, "%s,\n", endIdxString );
else
fprintf( out, "int %s,\n", endIdxString );
}
}
else if( frame )
{
indent = (unsigned int)strlen(funcName);
if( lookbackSignature )
{
print( out, "%sTA_%s_Lookback(", prefix == NULL? "" : prefix, funcName );
indent += 12;
}
else
{
print( out, "%sTA_%s(\n", prefix == NULL? "" : prefix, funcName );
indent += 4;
}
}
else if( validationCode )
{
indent = 3;
}
else
{
printf( "printFunc has nothing to do?\n" );
return;
}
if( prefix )
indent += (unsigned int)strlen(prefix);
if( frame )
indent -= 5;
if( frame && !lookbackSignature )
{
printIndent( out, indent );
fprintf( out, "%s,\n", startIdxString );
printIndent( out, indent );
fprintf( out, "%s,\n", endIdxString );
}
if( !lookbackSignature && !lookbackValidationCode )
{
if( validationCode )
{
printIndent( out, indent );
fprintf( out, "#if !defined(_JAVA)\n" );
}
paramNb = 0;
for( i=0; i < funcInfo->nbInput; i++ )
{
retCode = TA_GetInputParameterInfo( funcInfo->handle,
i, &inputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'input' information (%d,%d)\n", funcName, i, paramNb );
return;
}
paramName = inputParamInfo->paramName;
switch( inputParamInfo->type )
{
case TA_Input_Price:
j = 0;
if( inputParamInfo->flags & TA_IN_PRICE_TIMESTAMP )
j++;
if( inputParamInfo->flags & TA_IN_PRICE_OPEN )
j++;
if( inputParamInfo->flags & TA_IN_PRICE_HIGH )
j++;
if( inputParamInfo->flags & TA_IN_PRICE_LOW )
j++;
if( inputParamInfo->flags & TA_IN_PRICE_CLOSE )
j++;
if( inputParamInfo->flags & TA_IN_PRICE_VOLUME )
j++;
if( inputParamInfo->flags & TA_IN_PRICE_OPENINTEREST )
j++;
if( j == 0 )
{
printf( "[%s] invalid 'price input' information (%d,%d)\n", funcName, i, paramNb );
return;
}
if( validationCode )
{
printIndent( out, indent );
fprintf( out, "/* Verify required price component. */\n" );
printIndent( out, indent );
fprintf( out, "if(" );
k = 0;
if( inputParamInfo->flags & TA_IN_PRICE_TIMESTAMP )
{
k++;
fprintf( out, "!inTimestamp%s", k != j? "||":")");
}
if( inputParamInfo->flags & TA_IN_PRICE_OPEN )
{
k++;
fprintf( out, "!inOpen%s", k != j? "||":")");
}
if( inputParamInfo->flags & TA_IN_PRICE_HIGH )
{
k++;
fprintf( out, "!inHigh%s", k != j? "||":")");
}
if( inputParamInfo->flags & TA_IN_PRICE_LOW )
{
k++;
fprintf( out, "!inLow%s", k != j? "||":")");
}
if( inputParamInfo->flags & TA_IN_PRICE_CLOSE )
{
k++;
fprintf( out, "!inClose%s", k != j? "||":")");
}
if( inputParamInfo->flags & TA_IN_PRICE_VOLUME )
{
k++;
fprintf( out, "!inVolume%s", k != j? "||":")");
}
if( inputParamInfo->flags & TA_IN_PRICE_OPENINTEREST )
{
k++;
fprintf( out, "!inOpenInterest%s", k != j? "||":")");
}
fprintf( out, "\n" );
printIndent( out, indent );
fprintf( out, " return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);\n" );
print( out, "\n" );
}
else
{
if( inputParamInfo->flags & TA_IN_PRICE_OPEN )
{
printIndent( out, indent );
if( frame )
fprintf( out, "params->in[%d].data.inPrice.open, /*", paramNb );
if( arrayToSubArrayCnvt )
{
fprintf( out, " gcnew SubArrayFrom1D<%s>(inOpen,0)", inputDoubleArrayType );
}
else
{
fprintf( out, "%-*s%s%s%s",
prototype? 12 : 0,
prototype? inputDoubleArrayType : "",
outputForSWIG?"":" ",
outputForSWIG? "IN_ARRAY /* inOpen */": "inOpen",
prototype? arrayBracket : "" );
}
fprintf( out, "%s\n", frame? " */":"," );
}
if( inputParamInfo->flags & TA_IN_PRICE_HIGH )
{
printIndent( out, indent );
if( frame )
fprintf( out, "params->in[%d].data.inPrice.high, /*", paramNb );
if( arrayToSubArrayCnvt )
{
fprintf( out, " gcnew SubArrayFrom1D<%s>(inHigh,0)", inputDoubleArrayType );
}
else
{
fprintf( out, "%-*s%s%s%s",
prototype? 12 : 0,
prototype? inputDoubleArrayType : "",
outputForSWIG?"":" ",
outputForSWIG? "IN_ARRAY /* inHigh */":"inHigh",
prototype? arrayBracket : "" );
}
fprintf( out, "%s\n", frame? " */":"," );
}
if( inputParamInfo->flags & TA_IN_PRICE_LOW )
{
printIndent( out, indent );
if( frame )
fprintf( out, "params->in[%d].data.inPrice.low, /*", paramNb );
if( arrayToSubArrayCnvt )
{
fprintf( out, " gcnew SubArrayFrom1D<%s>(inLow,0)", inputDoubleArrayType );
}
else
{
fprintf( out, "%-*s%s%s%s",
prototype? 12 : 0,
prototype? inputDoubleArrayType : "",
outputForSWIG?"":" ",
outputForSWIG? "IN_ARRAY /* inLow */": "inLow",
prototype? arrayBracket : "" );
}
fprintf( out, "%s\n", frame? " */":"," );
}
if( inputParamInfo->flags & TA_IN_PRICE_CLOSE )
{
printIndent( out, indent );
if( frame )
fprintf( out, "params->in[%d].data.inPrice.close, /*", paramNb );
if( arrayToSubArrayCnvt )
{
fprintf( out, " gcnew SubArrayFrom1D<%s>(inClose,0)", inputDoubleArrayType );
}
else
{
fprintf( out, "%-*s%s%s%s",
prototype? 12 : 0,
prototype? inputDoubleArrayType : "",
outputForSWIG?"":" ",
outputForSWIG? "IN_ARRAY /* inClose */": "inClose",
prototype? arrayBracket : "" );
}
fprintf( out, "%s\n", frame? " */":"," );
}
if( inputParamInfo->flags & TA_IN_PRICE_VOLUME )
{
printIndent( out, indent );
if( frame )
fprintf( out, "params->in[%d].data.inPrice.volume, /*", paramNb );
if( arrayToSubArrayCnvt )
{
fprintf( out, " gcnew SubArrayFrom1D<%s>(inVolume,0)", inputDoubleArrayType );
}
else
{
fprintf( out, "%-*s%s%s%s",
prototype? 12 : 0,
prototype? inputDoubleArrayType : "",
outputForSWIG?"":" ",
outputForSWIG? "IN_ARRAY /* inVolume */": "inVolume",
prototype? arrayBracket : "" );
}
fprintf( out, "%s\n", frame? " */":"," );
}
if( inputParamInfo->flags & TA_IN_PRICE_OPENINTEREST )
{
printIndent( out, indent );
if( frame )
fprintf( out, "params->in[%d].data.inPrice.openInterest, /*", paramNb );
if( arrayToSubArrayCnvt )
{
fprintf( out, " gcnew SubArrayFrom1D<%s>(inOpenInterest,0)", inputDoubleArrayType );
}
else
{
fprintf( out, "%-*s%s%s%s",
prototype? 12 : 0,
prototype? inputDoubleArrayType : "",
outputForSWIG?"":" ",
outputForSWIG? "IN_ARRAY /* inOpenInterest */": "inOpenInterest",
prototype? arrayBracket : "" );
}
fprintf( out, "%s\n", frame? " */":"," );
}
}
break;
case TA_Input_Real:
typeString = inputDoubleArrayType;
defaultParamName = outputForSWIG? "IN_ARRAY":"inReal";
break;
case TA_Input_Integer:
typeString = inputIntArrayType;
defaultParamName = outputForSWIG? "IN_ARRAY":"inInteger";
break;
default:
if( !paramName )
paramName = "inParam";
printf( "[%s,%s,%d] invalid 'input' type(%d)\n",
funcName, paramName, paramNb,
inputParamInfo->type );
return;
}
if( inputParamInfo->type != TA_Input_Price )
{
printIndent( out, indent );
if( validationCode )
fprintf( out, "if( !%s ) return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);\n", inputParamInfo->paramName );
else
{
if( frame )
fprintf( out, "params->in[%d].data.%s, /*", paramNb, defaultParamName );
if( outputForSWIG )
fprintf( out, "%-*s%s%s /* %s */",
prototype? 12 : 0,
prototype? typeString : "",
defaultParamName,
prototype? arrayBracket : "",
inputParamInfo->paramName );
else
{
if( arrayToSubArrayCnvt )
{
fprintf( out, " %-*sgcnew SubArrayFrom1D<%s>(%s,0)",
prototype? 12 : 0, "",
typeString,
inputParamInfo->paramName );
}
else
{
fprintf( out, "%-*s %s%s",
prototype? 12 : 0,
prototype? typeString : "",
inputParamInfo->paramName,
prototype? arrayBracket : "" );
}
}
fprintf( out, "%s\n", frame? " */":"," );
}
}
paramNb++;
}
if( validationCode )
{
printIndent( out, indent );
fprintf( out, "#endif /* !defined(_JAVA)*/\n" );
}
}
paramNb = 0;
lastParam = 0;
for( i=0; i < funcInfo->nbOptInput; i++ )
{
excludeFromManaged = 0;
if( (i == (funcInfo->nbOptInput-1)) && lookbackSignature )
lastParam = 1;
retCode = TA_GetOptInputParameterInfo( funcInfo->handle,
i, &optInputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'optional input' information\n", funcName );
return;
}
paramName = optInputParamInfo->paramName;
if( optInputParamInfo->dataSet == TA_DEF_UI_MA_Method.dataSet )
isMAType = 1;
else
isMAType = 0;
switch( optInputParamInfo->type )
{
case TA_OptInput_RealRange:
case TA_OptInput_RealList:
typeString = "double";
defaultParamName = outputForSWIG? "OPT_REAL":"optInReal";
break;
case TA_OptInput_IntegerRange:
typeString = "int";
defaultParamName = outputForSWIG? "OPT_INT":"optInInteger";
break;
case TA_OptInput_IntegerList:
if( isMAType && !frame )
{
typeString = managedCPPCode||outputForJava? "MAType":"TA_MAType";
defaultParamName = outputForSWIG? "OPT_MATYPE":"optInMAType";
excludeFromManaged = 1;
}
else
{
typeString = "int";
defaultParamName = outputForSWIG? "OPT_INT":"optInInteger";
}
break;
default:
if( !paramName )
paramName = "optInParam";
printf( "[%s,%s,%d] invalid 'optional input' type(%d)\n",
funcName, paramName, paramNb,
optInputParamInfo->type );
return;
}
if( arrayToSubArrayCnvt )
typeString = "";
if( !paramName )
paramName = defaultParamName;
if( validationCode )
{
if( excludeFromManaged )
{
printIndent( out, indent );
fprintf( out, "#if !defined(_MANAGED) && !defined(_JAVA)\n" );
}
printOptInputValidation( out, paramName, optInputParamInfo, lookbackValidationCode );
if( excludeFromManaged )
{
printIndent( out, indent );
fprintf( out, "#endif /* !defined(_MANAGED) && !defined(_JAVA)*/\n" );
}
}
else
{
if( !(lookbackSignature && (i == 0 )) )
printIndent( out, indent );
if( frame )
{
fprintf( out, "%sparams->optIn[%d].data.%s%s /*",
isMAType?"(TA_MAType)":"",
paramNb, defaultParamName,
lookbackSignature&&lastParam?"":"," );
}
if( outputForSWIG )
fprintf( out, "%-*s %s /* %s */",
prototype? 13 : 0,
prototype? typeString : "",
defaultParamName, paramName );
else
fprintf( out, "%-*s %s",
prototype? 13 : 0,
prototype? typeString : "",
paramName );
if( frame )
{
if( lookbackSignature && lastParam )
fprintf( out, "*/ )%s\n", semiColonNeeded? ";":"" );
else
fprintf( out, "*/\n" );
}
else
{
switch( optInputParamInfo->type )
{
case TA_OptInput_RealRange:
if( lookbackSignature && lastParam )
fprintf( out, " )%s ", semiColonNeeded? ";":"" );
else
fprintf( out, "," );
if( ((TA_RealRange *)(optInputParamInfo->dataSet))->min == TA_REAL_MIN )
fprintf( out, " /* From TA_REAL_MIN" );
else
fprintf( out, " /* From %.*g",
((TA_RealRange *)(optInputParamInfo->dataSet))->precision,
((TA_RealRange *)(optInputParamInfo->dataSet))->min );
if( ((TA_RealRange *)(optInputParamInfo->dataSet))->max == TA_REAL_MAX )
fprintf( out, " to TA_REAL_MAX */\n" );
else
{
fprintf( out, " to %.*g%s */\n",
((TA_RealRange *)(optInputParamInfo->dataSet))->precision,
((TA_RealRange *)(optInputParamInfo->dataSet))->max,
optInputParamInfo->flags & TA_OPTIN_IS_PERCENT? " %":"" );
}
break;
case TA_OptInput_IntegerRange:
if( lookbackSignature && lastParam )
fprintf( out, " )%s ", semiColonNeeded? ";":"" );
else
fprintf( out, "," );
if( ((TA_IntegerRange *)(optInputParamInfo->dataSet))->min == TA_INTEGER_MIN )
fprintf( out, " /* From TA_INTEGER_MIN" );
else
{
fprintf( out, " /* From %d",
((TA_IntegerRange *)(optInputParamInfo->dataSet))->min );
}
if( ((TA_IntegerRange *)(optInputParamInfo->dataSet))->max == TA_INTEGER_MAX )
fprintf( out, " to TA_INTEGER_MAX */\n" );
else
{
fprintf( out, " to %d */\n",
((TA_IntegerRange *)(optInputParamInfo->dataSet))->max );
}
break;
default:
if( lookbackSignature && lastParam )
fprintf( out, " )%s ", semiColonNeeded? ";":"" );
else
fprintf( out, ",\n" );
}
}
}
paramNb++;
}
if( lookbackSignature && (funcInfo->nbOptInput == 0) )
{
if( frame || outputForJava )
fprintf( out, " )%s\n", semiColonNeeded? ";":"" );
else
fprintf( out, "void )%s\n", semiColonNeeded? ";":"" );
}
if( lookbackSignature )
{
if( !frame )
print( out, "\n" );
}
else if( !lookbackValidationCode )
{
paramNb = 0;
lastParam = 0;
if( !validationCode )
{
printIndent( out, indent );
if( frame )
fprintf( out, "%s, ", outBegIdxString );
else
fprintf( out, "%-*s %s%s",
prototype? 12 : 0,
prototype? outputIntParam : "",
prototype&&!managedCPPCode&&!outputForJava? "*" : "",
outBegIdxString );
fprintf( out, "%s\n", frame? "":"," );
printIndent( out, indent );
if( frame )
fprintf( out, "%s, ", outNbElementString );
else
fprintf( out, "%-*s %s%s",
prototype? 12 : 0,
prototype? outputIntParam : "",
prototype&&!managedCPPCode&&!outputForJava? "*" : "",
outNbElementString );
fprintf( out, "%s\n", frame? "":"," );
}
if( validationCode )
{
printIndent( out, indent );
fprintf( out, "#if !defined(_JAVA)\n" );
}
for( i=0; i < funcInfo->nbOutput; i++ )
{
if( i == (funcInfo->nbOutput-1) )
lastParam = 1;
retCode = TA_GetOutputParameterInfo( funcInfo->handle,
i, &outputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'output' information\n", funcName );
return;
}
paramName = outputParamInfo->paramName;
switch( outputParamInfo->type )
{
case TA_Output_Real:
typeString = outputDoubleArrayType;
defaultParamName = outputForSWIG? "OUT_ARRAY":"outReal";
break;
case TA_Output_Integer:
typeString = outputIntArrayType;;
defaultParamName = outputForSWIG? "OUT_ARRAY":"outInteger";
break;
default:
if( !paramName )
paramName = "outParam";
printf( "[%s,%s,%d] invalid 'output' type(%d)\n",
funcName, paramName, paramNb,
outputParamInfo->type );
return;
}
if( !paramName )
paramName = defaultParamName;
if( validationCode )
{
print( out, " if( !%s )\n", paramName );
print( out, " return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);\n" );
print( out, "\n" );
}
else
{
printIndent( out, indent );
if( frame )
fprintf( out, "params->out[%d].data.%s%s /*",
paramNb, defaultParamName,
lastParam? "":"," );
if( outputForSWIG )
fprintf( out, "%-*s *%s%s /* %s */",
prototype? 12 : 0,
prototype? typeString : "",
defaultParamName,
prototype? arrayBracket : "",
paramName );
else if( arrayToSubArrayCnvt )
{
fprintf( out, " gcnew SubArrayFrom1D<%s>(%s,0)", typeString, paramName );
}
else
{
fprintf( out, "%-*s %s%s",
prototype? 12 : 0,
prototype? typeString : "",
paramName,
prototype? arrayBracket : "" );
}
if( !lastParam )
fprintf( out, "%s\n", frame? " */":"," );
else
{
fprintf( out, "%s )%s\n",
frame? " */":"",
semiColonNeeded? ";":"" );
}
}
paramNb++;
}
if( validationCode )
{
printIndent( out, indent );
fprintf( out, "#endif /* !defined(_JAVA) */\n" );
}
}
}
static void printCallFrame( FILE *out, const TA_FuncInfo *funcInfo )
{
genPrefix = 1;
printFrameHeader( out, funcInfo, 0 );
print( out, "{\n" );
printFunc( out, " return ", funcInfo, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
print( out, "}\n" );
printFrameHeader( out, funcInfo, 1 );
print( out, "{\n" );
if( funcInfo->nbOptInput == 0 )
print( out, " (void)params;\n" );
printFunc( out, " return ", funcInfo, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 );
print( out, "}\n" );
genPrefix = 0;
}
static void printFrameHeader( FILE *out, const TA_FuncInfo *funcInfo, unsigned int lookbackSignature )
{
if( lookbackSignature )
{
print( out, "unsigned int TA_%s_FramePPLB( const TA_ParamHolderPriv *params )\n", funcInfo->name );
}
else
{
print( out, "TA_RetCode TA_%s_FramePP( const TA_ParamHolderPriv *params,\n", funcInfo->name );
print( out, " int startIdx,\n" );
print( out, " int endIdx,\n" );
print( out, " int *outBegIdx,\n" );
print( out, " int *outNBElement )\n" );
}
}
static void printExternReferenceForEachFunction( const TA_FuncInfo *info,
void *opaqueData )
{
(void)opaqueData;
fprintf( gOutGroupIdx_C->file, "extern const TA_FuncDef TA_DEF_%s;\n", info->name );
}
static void printPerGroupList( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
)
{
(void)isLast;
(void)isFirst;
fprintf( gOutGroupIdx_C->file,
"\nconst TA_FuncDef *TA_PerGroupFunc_%d[] = {\n", index );
gCurrentGroupName = groupName;
TA_ForEachFunc( printFunctionAddress, NULL );
fprintf( gOutGroupIdx_C->file, "NULL };\n" );
fprintf( gOutGroupIdx_C->file,
"#define SIZE_GROUP_%d ((sizeof(TA_PerGroupFunc_%d)/sizeof(const TA_FuncDef *))-1)\n",
index, index );
}
static void printFunctionAddress( const TA_FuncInfo *info,
void *opaqueData )
{
(void)opaqueData;
if( strcmp( info->group, gCurrentGroupName ) == 0 )
fprintf( gOutGroupIdx_C->file, "&TA_DEF_%s,\n", info->name );
}
static void printGroupListAddress( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
)
{
(void)isFirst;
if( groupName == NULL )
fprintf( gOutGroupIdx_C->file, "NULL%s", isLast? "" : "," );
else fprintf( gOutGroupIdx_C->file, "&TA_PerGroupFunc_%d[0]%s\n",
index, isLast? "" : "," );
}
static void printGroupSize( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
)
{
(void)isFirst;
(void)groupName;
fprintf( gOutGroupIdx_C->file, "SIZE_GROUP_%d%s\n",
index, isLast? "" : "," );
}
static void printGroupSizeAddition( const char *groupName,
unsigned int index,
unsigned int isFirst,
unsigned int isLast
)
{
(void)isFirst;
(void)groupName;
fprintf( gOutGroupIdx_C->file, "SIZE_GROUP_%d%s",
index, isLast? ";" : "+\n" );
}
static void doFuncFile( const TA_FuncInfo *funcInfo )
{
FileHandle *tempFile1;
unsigned int useTempFile;
FILE *logicIn;
FILE *logicTmp;
char localBuf1[500];
#define TEMPLATE_PASS1 ".." TA_FS_SLASH "temp" TA_FS_SLASH "pass1.tmp"
#define TEMPLATE_PASS2 ".." TA_FS_SLASH "temp" TA_FS_SLASH "pass2.tmp"
#define TEMPLATE_DEFAULT ".." TA_FS_SLASH "src" TA_FS_SLASH "ta_abstract" TA_FS_SLASH "templates" TA_FS_SLASH "ta_x.c.template"
#define LOGIC_TEMP ".." TA_FS_SLASH "temp" TA_FS_SLASH "logic.tmp"
sprintf( localBuf1, ".." TA_FS_SLASH "src" TA_FS_SLASH "ta_func" TA_FS_SLASH "ta_%s.c", funcInfo->name );
gOutFunc_C = fileOpen( localBuf1, NULL, FILE_READ);
if( gOutFunc_C == NULL )
useTempFile = 0;
else
{
useTempFile = 1;
tempFile1 = fileOpen( TEMPLATE_PASS1, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile1 == NULL )
{
printf( "Cannot create temporary file!\n" );
return;
}
createTemplate( gOutFunc_C, tempFile1 );
fileClose( tempFile1 );
fileClose( gOutFunc_C );
}
if( useTempFile )
gOutFunc_C = fileOpen( TEMPLATE_PASS2, TEMPLATE_PASS1, FILE_WRITE|WRITE_ALWAYS );
else
gOutFunc_C = fileOpen( TEMPLATE_PASS2, TEMPLATE_DEFAULT, FILE_WRITE|WRITE_ALWAYS );
if( gOutFunc_C == NULL )
{
printf( "Cannot create [%s]\n", localBuf1 );
return;
}
writeFuncFile( funcInfo );
fileClose( gOutFunc_C );
if( !useTempFile )
{
if( !copyFile( TEMPLATE_PASS2, localBuf1 ) )
{
printf( "Cannot copy %s to %s\n", TEMPLATE_PASS2, localBuf1 );
return;
}
}
init_gToOpen( localBuf1, NULL );
logicIn = fopen( gToOpen, "r" );
if( !logicIn )
{
printf( "Cannot open [%s] for extracting TA logic\n", localBuf1 );
return;
}
init_gToOpen( LOGIC_TEMP, NULL );
logicTmp = fopen( gToOpen, "w" );
if( !logicTmp )
{
fclose(logicIn);
printf( "Cannot open logic.tmp\n" );
return;
}
extractTALogic( logicIn, logicTmp );
fclose(logicIn);
fclose(logicTmp);
gOutFunc_C = fileOpen( localBuf1, TEMPLATE_PASS2, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutFunc_C == NULL )
{
printf( "Cannot complete 2nd pass with [%s]\n", localBuf1 );
return;
}
print( gOutFunc_C->file, "\n" );
print( gOutFunc_C->file, "#define USE_SINGLE_PRECISION_INPUT\n" );
print( gOutFunc_C->file, "#undef TA_LIB_PRO\n" );
print( gOutFunc_C->file, "#if !defined( _MANAGED ) && !defined( _JAVA )\n" );
print( gOutFunc_C->file, " #undef TA_PREFIX\n" );
print( gOutFunc_C->file, " #define TA_PREFIX(x) TA_S_##x\n" );
print( gOutFunc_C->file, "#endif\n" );
print( gOutFunc_C->file, "#undef INPUT_TYPE\n" );
print( gOutFunc_C->file, "#define INPUT_TYPE float\n" );
print( gOutFunc_C->file, "#if defined( _MANAGED ) && defined( USE_SUBARRAY )\n" );
printFunc( gOutFunc_C->file, NULL, funcInfo, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0 );
print( gOutFunc_C->file, "#elif defined( _MANAGED )\n" );
printFunc( gOutFunc_C->file, NULL, funcInfo, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 );
print( gOutFunc_C->file, "#elif defined( _JAVA )\n" );
printFunc( gOutFunc_C->file, NULL, funcInfo, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0 );
print( gOutFunc_C->file, "#else\n" );
printFunc( gOutFunc_C->file, NULL, funcInfo, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 );
print( gOutFunc_C->file, "#endif\n" );
init_gToOpen( LOGIC_TEMP, NULL );
logicTmp = fopen( gToOpen, "r" );
if( !logicTmp )
{
fileClose( gOutFunc_C );
printf( "Cannot read open logic.tmp\n" );
return;
}
while( fgets(gTempBuf,BUFFER_SIZE,logicTmp) )
fputs( gTempBuf, gOutFunc_C->file );
fclose(logicTmp);
print( gOutFunc_C->file, "\n" );
print( gOutFunc_C->file, "#if defined( _MANAGED )\n" );
print( gOutFunc_C->file, "}}} // Close namespace TicTacTec.TA.Lib\n" );
print( gOutFunc_C->file, "#endif\n" );
fileClose( gOutFunc_C );
fileDelete( LOGIC_TEMP );
fileDelete( TEMPLATE_PASS1 );
fileDelete( TEMPLATE_PASS2 );
}
static void doDefsFile( void )
{
FileHandle *tempFile;
FILE *out;
#define FILE_TA_DEFS_H ".." TA_FS_SLASH "include" TA_FS_SLASH "ta_defs.h"
#define FILE_TA_DEFS_TMP ".." TA_FS_SLASH "temp" TA_FS_SLASH "ta_defs.tmp"
gOutDefs_H = fileOpen( FILE_TA_DEFS_H, NULL, FILE_READ );
if( gOutDefs_H == NULL )
{
printf( "ta_defs.h must exist for being updated!\n" );
exit(-1);
}
tempFile = fileOpen( FILE_TA_DEFS_TMP, NULL, FILE_WRITE|WRITE_ALWAYS );
if( tempFile == NULL )
{
printf( "Cannot create temporary file!\n" );
exit(-1);
}
createTemplate( gOutDefs_H, tempFile );
fileClose( tempFile );
fileClose( gOutDefs_H );
gOutDefs_H = fileOpen( FILE_TA_DEFS_H, FILE_TA_DEFS_TMP, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutDefs_H == NULL )
{
printf( "Cannot create ta_defs.h\n" );
exit(-1);
}
out = gOutDefs_H->file;
genPrefix = 1;
addUnstablePeriodEnum( out );
print( out, "\n" );
genPrefix = 0;
fileClose( gOutDefs_H );
fileDelete( FILE_TA_DEFS_TMP );
#undef FILE_TA_DEFS_H
#undef FILE_TA_DEFS_TMP
}
#ifdef _MSC_VER
static int createProjTemplate( FileHandle *in, FileHandle *out )
{
FILE *inFile;
FILE *outFile;
unsigned int skipSection;
unsigned int sectionDone;
unsigned int step;
inFile = in->file;
outFile = out->file;
skipSection = 0;
sectionDone = 0;
step = 0;
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
if( !skipSection )
{
fputs( gTempBuf, outFile );
if( !strstr( gTempBuf, "<Filter" ) )
continue;
if( !fgets( gTempBuf2, BUFFER_SIZE, inFile ) )
{
printf( "Unexpected end-of-file\n" );
return -1;
}
fputs( gTempBuf2, outFile );
if( !strstr( gTempBuf2, "Name=\"ta_func\"" ) )
continue;
if( !fgets( gTempBuf3, BUFFER_SIZE, inFile ) )
{
printf( "Unexpected end-of-file\n" );
return -1;
}
fputs( gTempBuf3, outFile );
if( !strstr( gTempBuf3, ">" ) )
continue;
skipSection = 1;
fputs( "%%%GENCODE%%%\n", outFile );
}
else if( strstr( gTempBuf, "</Filter>" ) )
{
skipSection = 0;
fputs( gTempBuf, outFile );
sectionDone++;
}
}
return 0;
}
static int createMSVCProjTemplate( FileHandle *in, FileHandle *out )
{
FILE *inFile;
FILE *outFile;
unsigned int skipSection;
inFile = in->file;
outFile = out->file;
skipSection = 0;
while( !skipSection && fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
if( strstr( gTempBuf, "# Begin Source File") )
skipSection = 1;
else
fputs( gTempBuf, outFile );
}
if( !skipSection )
{
printf( "Unexpected end-of-file\n" );
return -1;
}
fputs( "%%%GENCODE%%%\n", outFile );
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
if( strstr( gTempBuf, "# End Group" ) )
{
fprintf( outFile, "# Begin Source File\n");
fprintf( outFile, "\n");
fprintf( outFile, "SOURCE=.." TA_FS_SLASH ".." TA_FS_SLASH ".." TA_FS_SLASH ".." TA_FS_SLASH "src" TA_FS_SLASH "ta_func" TA_FS_SLASH "ta_utility.c\n");
fprintf( outFile, "# End Source File\n");
fprintf( outFile, "# End Group\n");
break;
}
}
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
fputs( gTempBuf, outFile );
return 0;
}
#ifdef TA_LIB_PRO
#endif
static int createVS2005ProjTemplate( FileHandle *in, FileHandle *out )
{
FILE *inFile;
FILE *outFile;
unsigned int skipSection;
inFile = in->file;
outFile = out->file;
skipSection = 0;
while( !skipSection && fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
if( strstr( gTempBuf, "<Files>") )
skipSection = 1;
else
fputs( gTempBuf, outFile );
}
if( !skipSection )
{
printf( "Unexpected end-of-file. Missing \"<Files>\"\n" );
return -1;
}
fputs( gTempBuf, outFile );
skipSection = 0;
while( !skipSection && fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
if( strstr( gTempBuf, "<File") )
skipSection = 1;
else
fputs( gTempBuf, outFile );
}
if( !skipSection )
{
printf( "Unexpected end-of-file. Missing \"<File\"\n" );
return -1;
}
fputs( "%%%GENCODE%%%\n", outFile );
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
if( strstr( gTempBuf, "</Filter>" ) )
{
printVS2005FileNode( outFile, "utility" );
fprintf( outFile, " </Filter>\n");
break;
}
}
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
fputs( gTempBuf, outFile );
return 0;
}
static void printVS2005FileNode( FILE *out, const char *name )
{
fprintf( out, " <File\n" );
fprintf( out, " RelativePath=\".." TA_FS_SLASH ".." TA_FS_SLASH ".." TA_FS_SLASH ".." TA_FS_SLASH "src" TA_FS_SLASH "ta_func" TA_FS_SLASH "ta_%s.c\"\n", name );
fprintf( out, " >\n" );
fprintf( out, " </File>\n" );
}
#endif
static int createTemplate( FileHandle *in, FileHandle *out )
{
FILE *inFile;
FILE *outFile;
char *inTheLinePtr;
unsigned int skipSection;
unsigned int sectionDone;
inFile = in->file;
outFile = out->file;
skipSection = 0;
sectionDone = 0;
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
inTheLinePtr = gTempBuf;
while( isspace(*inTheLinePtr) ) inTheLinePtr++;
if( strncmp( inTheLinePtr, "/**** START GENCODE SECTION", 27 ) == 0 )
{
skipSection = 1;
fputs( gTempBuf, outFile );
fputs( "%%%GENCODE%%%\n", outFile );
}
else if( strncmp( inTheLinePtr, "/**** END GENCODE SECTION", 25 ) == 0 )
{
if( skipSection )
{
skipSection = 0;
sectionDone++;
}
}
if( !skipSection )
{
if( fputs( gTempBuf, outFile ) == EOF )
{
printf( "Cannot write tmp file\n" );
return -1;
}
}
}
return 0;
}
static void writeFuncFile( const TA_FuncInfo *funcInfo )
{
FILE *out;
out = gOutFunc_C->file;
fprintf( out, "/* All code within this section is automatically\n" );
fprintf( out, " * generated by gen_code. Any modification will be lost\n" );
fprintf( out, " * next time gen_code is run.\n" );
fprintf( out, " */\n" );
genPrefix = 1;
print( out, "\n" );
print( out, "#if defined( _MANAGED )\n" );
print( out, " #include \"TA-Lib-Core.h\"\n" );
print( out, " #define TA_INTERNAL_ERROR(Id) (RetCode::InternalError)\n" );
print( out, " namespace TicTacTec { namespace TA { namespace Library {\n" );
print( out, "#elif defined( _JAVA )\n" );
print( out, " #include \"ta_defs.h\"\n" );
print( out, " #include \"ta_java_defs.h\"\n" );
print( out, " #define TA_INTERNAL_ERROR(Id) (RetCode.InternalError)\n" );
print( out, "#else\n" );
print( out, " #include <string.h>\n" );
print( out, " #include <math.h>\n" );
print( out, " #include \"ta_func.h\"\n" );
print( out, "#endif\n" );
print( out, "\n" );
print( out, "#ifndef TA_UTILITY_H\n" );
print( out, " #include \"ta_utility.h\"\n" );
print( out, "#endif\n" );
print( out, "\n" );
print( out, "#ifndef TA_MEMORY_H\n" );
print( out, " #include \"ta_memory.h\"\n" );
print( out, "#endif\n" );
print( out, "\n" );
print( out, "#define TA_PREFIX(x) TA_##x\n" );
print( out, "#define INPUT_TYPE double\n" );
print( out, "\n" );
print( out, "#if defined( _MANAGED )\n" );
printFunc( out, NULL, funcInfo, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 );
print( out, "#elif defined( _JAVA )\n" );
printFunc( out, NULL, funcInfo, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0 );
print( out, "#else\n" );
printFunc( out, "TA_LIB_API ", funcInfo, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 );
print( out, "#endif\n" );
genPrefix = 0;
skipToGenCode( funcInfo->name, gOutFunc_C->file, gOutFunc_C->templateFile );
genPrefix = 1;
if( funcInfo->nbOptInput != 0 )
print( out, "#ifndef TA_FUNC_NO_RANGE_CHECK\n" );
printFunc( out, NULL, funcInfo, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 );
if( funcInfo->nbOptInput != 0 )
print( out, "#endif /* TA_FUNC_NO_RANGE_CHECK */\n" );
else
print( out, "/* No parameters to validate. */\n" );
genPrefix = 0;
skipToGenCode( funcInfo->name, gOutFunc_C->file, gOutFunc_C->templateFile );
genPrefix = 1;
fprintf( out, "/*\n" );
printFuncHeaderDoc( out, funcInfo, " * " );
fprintf( out, " */\n" );
print( out, "\n" );
print( out, "#if defined( _MANAGED ) && defined( USE_SUBARRAY )\n" );
printFunc( out, NULL, funcInfo, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 );
print( out, "#elif defined( _MANAGED )\n" );
printFunc( out, NULL, funcInfo, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 );
print( out, "#elif defined( _JAVA )\n" );
if( strcmp( funcInfo->camelCaseName, "Min" ) == 0 ) {
print( out, "#undef min\n" );
} else if( strcmp( funcInfo->camelCaseName, "Max" ) == 0 ) {
print( out, "#undef max\n" );
}
printFunc( out, NULL, funcInfo, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 );
print( out, "#else\n" );
printFunc( out, "TA_LIB_API ", funcInfo, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
print( out, "#endif\n" );
genPrefix = 0;
skipToGenCode( funcInfo->name, gOutFunc_C->file, gOutFunc_C->templateFile );
genPrefix = 1;
print( out, "\n" );
print( out, "#ifndef TA_FUNC_NO_RANGE_CHECK\n" );
print( out, "\n" );
print( out, " /* Validate the requested output range. */\n" );
print( out, " if( startIdx < 0 )\n" );
print( out, " return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_START_INDEX,OutOfRangeStartIndex);\n" );
print( out, " if( (endIdx < 0) || (endIdx < startIdx))\n" );
print( out, " return ENUM_VALUE(RetCode,TA_OUT_OF_RANGE_END_INDEX,OutOfRangeEndIndex);\n" );
print( out, "\n" );
printFunc( out, NULL, funcInfo, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
print( out, "#endif /* TA_FUNC_NO_RANGE_CHECK */\n" );
print( out, "\n" );
skipToGenCode( funcInfo->name, gOutFunc_C->file, gOutFunc_C->templateFile );
fprintf( out, "%%%%%%GENCODE%%%%%%\n" );
}
static void printOptInputValidation( FILE *out,
const char *name,
const TA_OptInputParameterInfo *optInputParamInfo,
int lookbackValidationCode )
{
int minInt, maxInt;
double minReal, maxReal;
unsigned int i;
int isMAType;
const TA_RealList *realList;
const TA_IntegerList *integerList;
const TA_RealRange *realRange;
const TA_IntegerRange *integerRange;
minInt = maxInt = (int)0;
minReal = maxReal = (double)0.0;
switch( optInputParamInfo->type )
{
case TA_OptInput_RealRange:
realRange = (const TA_RealRange *)optInputParamInfo->dataSet;
minReal = realRange->min;
maxReal = realRange->max;
break;
case TA_OptInput_IntegerRange:
integerRange = (const TA_IntegerRange *)optInputParamInfo->dataSet;
minInt = integerRange->min;
maxInt = integerRange->max;
break;
case TA_OptInput_RealList:
realList = (const TA_RealList *)optInputParamInfo->dataSet;
minReal = realList->data[0].value;
maxReal = realList->data[0].value;
for( i=0; i < realList->nbElement; i++ )
{
minReal = min( realList->data[i].value, minReal );
maxReal = max( realList->data[i].value, maxReal );
}
break;
case TA_OptInput_IntegerList:
integerList = (const TA_IntegerList *)optInputParamInfo->dataSet;
minInt = integerList->data[0].value;
maxInt = integerList->data[0].value;
for( i=0; i < integerList->nbElement; i++ )
{
minInt = min( integerList->data[i].value, minInt );
maxInt = max( integerList->data[i].value, maxInt );
}
break;
}
if( optInputParamInfo->dataSet == TA_DEF_UI_MA_Method.dataSet )
isMAType = 1;
else
isMAType = 0;
switch( optInputParamInfo->type )
{
case TA_OptInput_RealList:
print( out, " /* min/max are checked for %s. */\n", name );
case TA_OptInput_RealRange:
print( out, " if( %s == TA_REAL_DEFAULT )\n", name );
print( out, " %s = %s;\n", name, doubleToStr(optInputParamInfo->defaultValue) );
print( out, " else if( (%s < %s) ||", name, doubleToStr(minReal) );
print( out, " (%s > %s) )\n", name, doubleToStr(maxReal) );
break;
case TA_OptInput_IntegerRange:
print( out, " /* min/max are checked for %s. */\n", name );
case TA_OptInput_IntegerList:
print( out, " if( (int)%s == TA_INTEGER_DEFAULT )\n", name );
print( out, " %s = %s%d;\n", name, isMAType?"(TA_MAType)":"", (int)optInputParamInfo->defaultValue );
print( out, " else if( ((int)%s < %d) || ((int)%s > %d) )\n",
name, minInt,
name, maxInt );
break;
}
if( lookbackValidationCode )
print( out, " return -1;\n" );
else
print( out, " return ENUM_VALUE(RetCode,TA_BAD_PARAM,BadParam);\n" );
print( out, "\n" );
}
static int skipToGenCode( const char *dstName, FILE *out, FILE *templateFile )
{
unsigned int headerWritten = 0;
while( fgets( gTempBuf, BUFFER_SIZE, templateFile ) )
{
if( strncmp( gTempBuf, "%%%GENCODE%%%", 13 ) == 0 )
{
headerWritten = 1;
break;
}
if( out && (fputs( gTempBuf, out ) == EOF) )
{
printf( "Cannot write to [%s]\n", dstName );
return -1;
}
}
if( !headerWritten )
{
printf( "Line with string %%%%%%GENCODE%%%%%% Missing in [%s]", dstName );
return -1;
}
return 0;
}
static void printFuncHeaderDoc( FILE *out,
const TA_FuncInfo *funcInfo,
const char *prefix )
{
TA_RetCode retCode;
unsigned int paramNb;
const char *paramName;
const char *defaultParamName;
const TA_InputParameterInfo *inputParamInfo;
const TA_OptInputParameterInfo *optInputParamInfo;
const TA_OutputParameterInfo *outputParamInfo;
int first;
fprintf( out, "%sTA_%s - %s\n", prefix, funcInfo->name, funcInfo->hint );
fprintf( out, prefix );
fprintf( out, "\n" );
fprintf( out, "%sInput = ", prefix );
for( paramNb=0; paramNb < funcInfo->nbInput; paramNb++ )
{
retCode = TA_GetInputParameterInfo( funcInfo->handle,
paramNb, &inputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'input' information\n", funcInfo->name );
return;
}
switch( inputParamInfo->type )
{
case TA_Input_Price:
first = 1;
#define PRICE_PARAM(upperParam,lowerParam) \
{ \
if( inputParamInfo->flags & TA_IN_PRICE_##upperParam ) \
{ \
if( !first ) fprintf( out, ", " ); \
fprintf( out, lowerParam ); \
first = 0; \
} \
}
PRICE_PARAM( OPEN, "Open" );
PRICE_PARAM( HIGH, "High" );
PRICE_PARAM( LOW, "Low" );
PRICE_PARAM( CLOSE, "Close" );
PRICE_PARAM( VOLUME, "Volume" );
PRICE_PARAM( OPENINTEREST, "OpenInterest" );
PRICE_PARAM( TIMESTAMP, "Timestamp" );
#undef PRICE_PARAM
break;
case TA_Input_Integer:
fprintf( out, "int" );
break;
case TA_Input_Real:
fprintf( out, "double" );
break;
}
if( paramNb+1 == funcInfo->nbInput )
fprintf( out, "\n" );
else
fprintf( out, ", " );
}
fprintf( out, "%sOutput = ", prefix );
for( paramNb=0; paramNb < funcInfo->nbOutput; paramNb++ )
{
retCode = TA_GetOutputParameterInfo( funcInfo->handle,
paramNb, &outputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'output' information\n", funcInfo->name );
return;
}
switch( outputParamInfo->type )
{
case TA_Output_Real:
fprintf( out, "double" );
break;
case TA_Output_Integer:
fprintf( out, "int" );
break;
}
if( paramNb+1 == funcInfo->nbOutput )
fprintf( out, "\n" );
else
fprintf( out, ", " );
}
if( funcInfo->nbOptInput != 0 )
{
fprintf( out, "%s\n", prefix );
fprintf( out, "%sOptional Parameters\n", prefix );
fprintf( out, "%s-------------------\n", prefix );
for( paramNb=0; paramNb < funcInfo->nbOptInput; paramNb++ )
{
retCode = TA_GetOptInputParameterInfo( funcInfo->handle,
paramNb, &optInputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'optional input' information\n", funcInfo->name );
return;
}
paramName = optInputParamInfo->paramName;
switch( optInputParamInfo->type )
{
case TA_OptInput_RealRange:
case TA_OptInput_RealList:
defaultParamName = "optInReal";
break;
case TA_OptInput_IntegerRange:
case TA_OptInput_IntegerList:
defaultParamName = "optInInteger";
break;
default:
if( !paramName )
paramName = "optInParam";
printf( "[%s,%s,%d] invalid 'optional input' type(%d)\n",
funcInfo->name, paramName, paramNb,
optInputParamInfo->type );
return;
}
if( !paramName )
paramName = defaultParamName;
fprintf( out, "%s%s:", prefix, paramName );
switch( optInputParamInfo->type )
{
case TA_OptInput_RealRange:
if( ((TA_RealRange *)(optInputParamInfo->dataSet))->min == TA_REAL_MIN )
fprintf( out, "(From TA_REAL_MIN" );
else
{
fprintf( out, "(From %.*g",
((TA_RealRange *)(optInputParamInfo->dataSet))->precision,
((TA_RealRange *)(optInputParamInfo->dataSet))->min );
}
if( ((TA_RealRange *)(optInputParamInfo->dataSet))->max == TA_REAL_MAX )
fprintf( out, " to TA_REAL_MAX)\n" );
else
{
fprintf( out, " to %.*g%s)\n",
((TA_RealRange *)(optInputParamInfo->dataSet))->precision,
((TA_RealRange *)(optInputParamInfo->dataSet))->max,
optInputParamInfo->flags & TA_OPTIN_IS_PERCENT? " %":"" );
}
break;
case TA_OptInput_IntegerRange:
if( ((TA_IntegerRange *)(optInputParamInfo->dataSet))->min == TA_INTEGER_MIN )
fprintf( out, "(From TA_INTEGER_MIN" );
else
{
fprintf( out, "(From %d",
((TA_IntegerRange *)(optInputParamInfo->dataSet))->min );
}
if( ((TA_IntegerRange *)(optInputParamInfo->dataSet))->max == TA_INTEGER_MAX )
fprintf( out, " to TA_INTEGER_MAX)\n" );
else
{
fprintf( out, " to %d)\n",
((TA_IntegerRange *)(optInputParamInfo->dataSet))->max );
}
break;
default:
fprintf( out, "\n" );
}
fprintf( out, "%s %s\n", prefix, optInputParamInfo->hint );
fprintf( out, "%s\n", prefix );
}
}
fprintf( out, "%s\n", prefix );
}
static int addUnstablePeriodEnum( FILE *out )
{
TA_RetCode retCode;
unsigned int id;
print( out, "\n" );
print( out, "ENUM_BEGIN( FuncUnstId )\n");
id = 0;
retCode = TA_ForEachFunc( doForEachUnstableFunction, &id );
print( out, " ENUM_DEFINE( TA_FUNC_UNST_ALL, FuncUnstAll),\n");
print( out, " ENUM_DEFINE( TA_FUNC_UNST_NONE, FuncUnstNone) = -1\n" );
print( out, "ENUM_END( FuncUnstId )\n");
if( retCode != TA_SUCCESS )
return -1;
return 0;
}
static int gen_retcode( void )
{
FileHandle *inHdr;
char *ptr1, *ptr2;
int step1Done;
int retValue;
TA_RetCode retCodeValue;
char *retCodeEnum, *retCodeInfo;
retValue = -1;
gOutRetCode_C = fileOpen( ta_fs_path(4, "..", "src", "ta_common", "ta_retcode.c"),
ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_retcode.c.template"),
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutRetCode_C == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutRetCode_CSV = fileOpen( ta_fs_path(4, "..", "src", "ta_common", "ta_retcode.csv"),
NULL,
FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutRetCode_CSV == NULL )
{
fileClose( gOutRetCode_C );
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
inHdr = fileOpen( ta_fs_path(3, "..", "include", "ta_defs.h"),
NULL,
FILE_READ );
if( inHdr == NULL )
{
fileClose( gOutRetCode_C );
fileClose( gOutRetCode_CSV );
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
step1Done = 0;
while( fgets( gTempBuf, sizeof( gTempBuf ), inHdr->file ) )
{
if( !step1Done )
{
if( strstr( gTempBuf, "ENUM_BEGIN( RetCode )" ) != NULL )
step1Done = 1;
}
else
{
if( strstr( gTempBuf, "TA_UNKNOWN_ERR" ) != NULL )
{
retValue = 0;
goto gen_retcode_exit;
}
ptr1 = strstr( gTempBuf, "/*" );
ptr2 = strstr( gTempBuf, "/***" );
if( ptr1 && !ptr2 )
{
ptr1 += 2;
retCodeValue = (TA_RetCode)atoi(ptr1);
ptr1 = strstr( ptr1, "TA_" );
if( !ptr1 )
{
printf( "Can't find TA_" );
goto gen_retcode_exit;
}
retCodeEnum = ptr1;
retCodeInfo = NULL;
while( isdigit(*ptr1) || isalpha(*ptr1) || *ptr1 == '_' )
ptr1++;
if( *ptr1 != '\0' )
{
*ptr1 = '\0';
ptr1++;
if( *ptr1 != '\0' )
{
retCodeInfo = strstr( ptr1, "/* " );
if( retCodeInfo )
{
retCodeInfo += 3;
ptr1 = strstr( retCodeInfo, "*/" );
if( ptr1 == NULL )
retCodeInfo = NULL;
else
*ptr1 = '\0';
}
}
}
if( !retCodeInfo )
retCodeInfo = "No Info";
strcpy( gTempBuf, retCodeEnum );
ptr1 = trimWhitespace( gTempBuf );
fprintf( gOutRetCode_C->file, " {(TA_RetCode)%d,\"%s\",", retCodeValue, ptr1 );
fprintf( gOutRetCode_CSV->file, "%d,%s", retCodeValue, ptr1 );
strcpy( gTempBuf, retCodeInfo );
ptr1 = trimWhitespace( gTempBuf );
fprintf( gOutRetCode_C->file, "\"%s\"},\n", ptr1 );
fprintf( gOutRetCode_CSV->file, ",%s\n", ptr1 );
}
}
}
gen_retcode_exit:
fileClose( inHdr );
fileClose( gOutRetCode_C );
fileClose( gOutRetCode_CSV );
return retValue;
}
const char *doubleToStr( double value )
{
int length;
int i, outIdx;
sprintf( gTempDoubleToStr, "%e", value );
length = (int)strlen( gTempDoubleToStr );
outIdx = 0;
for( i=0; i < length; i++ )
{
if( (i >= 2) &&
(toupper(gTempDoubleToStr[i-2]) == 'E') &&
((gTempDoubleToStr[i-1] == '+')||(gTempDoubleToStr[i-1] == '-')) &&
(gTempDoubleToStr[i] == '0') &&
(gTempDoubleToStr[i+1] == '0') &&
(isdigit(gTempDoubleToStr[i+2])) )
{
i++;
continue;
}
if( (i >= 2) &&
(toupper(gTempDoubleToStr[i-2]) == 'E') &&
((gTempDoubleToStr[i-1] == '+')||(gTempDoubleToStr[i-1] == '-')) &&
(gTempDoubleToStr[i] == '0') &&
(isdigit(gTempDoubleToStr[i+1])))
{
continue;
}
gTempDoubleToStr[outIdx++] = gTempDoubleToStr[i];
}
gTempDoubleToStr[outIdx] = '\0';
return gTempDoubleToStr;
}
static void cnvtToUpperCase( char *str )
{
char c;
if( !str ) return;
c = *str;
while( c != '\0' )
{
*str = (char)toupper(c);
str++;
c = *str;
}
}
static char *trimWhitespace( char *str )
{
int i;
if( !str ) return str;
while( isspace(*str) ) str++;
if( *str == '\0' ) return str;
for( i=(int)strlen(str)-1; i >= 0; i-- )
{
if( !isspace(str[i]) )
return str;
str[i] = '\0';
}
return str;
}
static void cnvtChar( char *str, char from, char to )
{
char c;
if( !str ) return;
c = *str;
while( c != '\0' )
{
if( c == from ) *str = to;
str++;
c = *str;
}
}
#ifdef _MSC_VER
static void printExcelGlueCode( FILE *out, const TA_FuncInfo *funcInfo )
{
int nbParam;
unsigned int i;
TA_RetCode retCode;
const TA_InputParameterInfo *inputParamInfo;
nbParam = funcInfo->nbOptInput;
for( i=0; i < funcInfo->nbInput; i++ )
{
retCode = TA_GetInputParameterInfo( funcInfo->handle,
i, &inputParamInfo );
if( retCode != TA_SUCCESS )
{
printf( "[%s] invalid 'input' information (%d,%d)\n", funcInfo->name, i, nbParam );
return;
}
if( inputParamInfo->type != TA_Input_Price )
nbParam++;
else
{
if( inputParamInfo->flags & TA_IN_PRICE_TIMESTAMP )
nbParam++;
if( inputParamInfo->flags & TA_IN_PRICE_OPEN )
nbParam++;
if( inputParamInfo->flags & TA_IN_PRICE_HIGH )
nbParam++;
if( inputParamInfo->flags & TA_IN_PRICE_LOW )
nbParam++;
if( inputParamInfo->flags & TA_IN_PRICE_CLOSE )
nbParam++;
if( inputParamInfo->flags & TA_IN_PRICE_VOLUME )
nbParam++;
if( inputParamInfo->flags & TA_IN_PRICE_OPENINTEREST )
nbParam++;
}
}
fprintf( out, "EXCEL_GLUE_CODE_WITH_%d_PARAM(%s)\n",
nbParam,
funcInfo->name );
}
#endif
static void extractTALogic( FILE *inFile, FILE *outFile )
{
int i, length, nbCodeChar;
int commentBlock, commentFirstCharFound, outIdx;
#define START_DELIMITATOR "/**** END GENCODE SECTION 3"
#define STOP_DELIMITATOR "/**** START GENCODE SECTION 5"
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
length = (int)strlen(gTempBuf);
if( length > BUFFER_SIZE )
return;
if( strncmp( gTempBuf, START_DELIMITATOR, strlen(START_DELIMITATOR) ) == 0)
break;
}
commentBlock = 0;
commentFirstCharFound = 0;
while( fgets( gTempBuf, BUFFER_SIZE, inFile ) )
{
length = (int)strlen(gTempBuf);
if( length > BUFFER_SIZE )
return;
if( strncmp( gTempBuf, STOP_DELIMITATOR, strlen(STOP_DELIMITATOR) ) == 0)
break;
outIdx = 0;
nbCodeChar = 0;
for( i=0; i < length; i++ )
{
if( !commentBlock )
{
if( !commentFirstCharFound )
{
if( gTempBuf[i] == '/' )
commentFirstCharFound = 1;
else
{
gTempBuf2[outIdx++] = gTempBuf[i];
if( !isspace(gTempBuf[i]) )
nbCodeChar++;
}
}
else
{
commentFirstCharFound = 0;
if( gTempBuf[i] == '*' )
commentBlock = 1;
else
{
gTempBuf2[outIdx++] = '/';
nbCodeChar++;
if( gTempBuf[i] == '/' )
commentFirstCharFound = 1;
else
{
gTempBuf2[outIdx++] = gTempBuf[i];
if( !isspace(gTempBuf[i]) )
nbCodeChar++;
}
}
}
}
else
{
if( !commentFirstCharFound )
{
if( gTempBuf[i] == '*' )
commentFirstCharFound = 1;
}
else
{
commentFirstCharFound = 0;
if( gTempBuf[i] == '/' )
commentBlock = 0;
else if( gTempBuf[i] == '*' )
commentFirstCharFound = 1;
}
}
}
#define BEG_PROP_MARKER "* Begin Proprietary *"
#define END_PROP_MARKER "* End Proprietary *"
if( strstr( gTempBuf, BEG_PROP_MARKER ) )
{
fputs( "/* Generated */ /", outFile );
fputs( BEG_PROP_MARKER, outFile );
fputs( "/\n", outFile );
}
else if( strstr( gTempBuf, END_PROP_MARKER ) )
{
fputs( "/* Generated */ /", outFile );
fputs( END_PROP_MARKER, outFile );
fputs( "/\n", outFile );
}
else if( nbCodeChar != 0 )
{
gTempBuf2[outIdx] = '\0';
fputs( "/* Generated */ ", outFile );
fputs( gTempBuf2, outFile );
}
}
}
static int copyFile( const char *src, const char *dest )
{
FILE *in;
FILE *out;
init_gToOpen( src, NULL );
in = fopen( gToOpen, "rb" );
if( !in )
return 0;
init_gToOpen( dest, NULL );
out = fopen( gToOpen, "wb" );
if( !out )
{
fclose( in );
return 0;
}
while( fgets( gTempBuf, BUFFER_SIZE, in ) )
{
fputs(gTempBuf,out);
}
fclose(in);
fclose(out);
return 1;
}
static int areFileSame( const char *file1, const char *file2 )
{
unsigned int i;
FILE *f1;
FILE *f2;
init_gToOpen( file1, NULL );
f1 = fopen( gToOpen, "r" );
if( !f1 )
return 0;
init_gToOpen( file2, NULL );
f2 = fopen( gToOpen, "r" );
if( !f2 )
{
fclose( f1 );
return 0;
}
memset( gTempBuf, 0, sizeof(gTempBuf ) );
memset( gTempBuf2, 0, sizeof(gTempBuf2) );
while( fgets( gTempBuf, BUFFER_SIZE, f1 ) )
{
if( !fgets( gTempBuf2, BUFFER_SIZE, f2 ) )
{
fclose(f1);
fclose(f2);
return 0;
}
for( i=0; i < sizeof(gTempBuf); i++ )
{
if( gTempBuf[i] != gTempBuf2[i] )
{
fclose(f1);
fclose(f2);
return 0;
}
if( gTempBuf[i] == '\0' )
i = sizeof(gTempBuf);
}
memset( gTempBuf, 0, sizeof(gTempBuf ) );
memset( gTempBuf2, 0, sizeof(gTempBuf2) );
}
if( fgets( gTempBuf2, BUFFER_SIZE, f2 ) )
{
fclose(f1);
fclose(f2);
return 0;
}
fclose(f1);
fclose(f2);
return 1;
}
static void appendToFunc( FILE *out )
{
fprintf( out, "\n" );
fprintf( out, "/* Some TA functions takes a certain amount of input data\n" );
fprintf( out, " * before stabilizing and outputing meaningful data. This is\n" );
fprintf( out, " * a behavior pertaining to the algo of some TA functions and\n" );
fprintf( out, " * is not particular to the TA-Lib implementation.\n" );
fprintf( out, " * TA-Lib allows you to automatically strip off these unstabl\n" );
fprintf( out, " * data from your output and from any internal processing.\n" );
fprintf( out, " * (See documentation for more info)\n" );
fprintf( out, " *\n" );
fprintf( out, " * Examples:\n" );
fprintf( out, " * TA_SetUnstablePeriod( TA_FUNC_UNST_EMA, 30 );\n" );
fprintf( out, " * Always strip off 30 price bar for the TA_EMA function.\n" );
fprintf( out, " *\n" );
fprintf( out, " * TA_SetUnstablePeriod( TA_FUNC_UNST_ALL, 30 );\n" );
fprintf( out, " * Always strip off 30 price bar from ALL functions\n" );
fprintf( out, " * having an unstable period.\n" );
fprintf( out, " *\n" );
fprintf( out, " * See ta_defs.h for the enumeration TA_FuncUnstId\n" );
fprintf( out, " */\n" );
fprintf( out, "\n" );
fprintf( out, "TA_RetCode TA_SetUnstablePeriod( TA_FuncUnstId id,\n" );
fprintf( out, " unsigned int unstablePeriod );\n" );
fprintf( out, "\n" );
fprintf( out, "unsigned int TA_GetUnstablePeriod( TA_FuncUnstId id );\n" );
fprintf( out, "\n" );
fprintf( out, "/* You can change slightly the behavior of the TA functions\n" );
fprintf( out, " * by requesting compatibiliy with some existing software.\n" );
fprintf( out, " *\n" );
fprintf( out, " * By default, the behavior is as close as the original \n" );
fprintf( out, " * author of the TA functions intend it to be.\n" );
fprintf( out, " *\n" );
fprintf( out, " * See ta_defs.h for the enumeration TA_Compatibility.\n" );
fprintf( out, " */\n" );
fprintf( out, "TA_RetCode TA_SetCompatibility( TA_Compatibility value );\n" );
fprintf( out, "TA_Compatibility TA_GetCompatibility( void );\n" );
fprintf( out, "\n" );
fprintf( out, "/* Candlesticks struct and functions\n" );
fprintf( out, " * Because candlestick patterns are subjective, it is necessary \n" );
fprintf( out, " * to allow the user to specify what should be the meaning of \n" );
fprintf( out, " * 'long body', 'short shadows', etc.\n" );
fprintf( out, " */\n" );
fprintf( out, "\n" );
fprintf( out, "/* Call TA_SetCandleSettings to set that when comparing a candle \n" );
fprintf( out, " * basing on settingType it must be compared with the average \n" );
fprintf( out, " * of the last avgPeriod candles' rangeType multiplied by factor.\n" );
fprintf( out, " * This setting is valid until TA_RestoreCandleDefaultSettings is called\n" );
fprintf( out, " */\n" );
fprintf( out, "TA_RetCode TA_SetCandleSettings( TA_CandleSettingType settingType, \n" );
fprintf( out, " TA_RangeType rangeType, \n" );
fprintf( out, " int avgPeriod, \n" );
fprintf( out, " double factor );\n" );
fprintf( out, "\n" );
fprintf( out, "/* Call TA_RestoreCandleDefaultSettings after using custom settings \n" );
fprintf( out, " * to restore the default settings for the specified settingType\n" );
fprintf( out, " */\n" );
fprintf( out, "TA_RetCode TA_RestoreCandleDefaultSettings( TA_CandleSettingType settingType );\n" );
}
void genJavaCodePhase1( const TA_FuncInfo *funcInfo )
{
fprintf( gOutJavaDefs_H->file, "#define TA_%s_Lookback %c%sLookback\n", funcInfo->name, tolower(funcInfo->camelCaseName[0]), &funcInfo->camelCaseName[1] );
fprintf( gOutJavaDefs_H->file, "#define TA_%s %c%s\n", funcInfo->name, tolower(funcInfo->camelCaseName[0]), &funcInfo->camelCaseName[1] );
}
void genJavaCodePhase2( const TA_FuncInfo *funcInfo )
{
FILE *logicTmp;
char buffer[500];
int idx, again;
static int firstTime = 1;
if( firstTime == 1 )
{
fileDelete( ta_fs_path(3, "..", "temp", "CoreJavaCode1.tmp") );
fileDelete( ta_fs_path(3, "..", "temp", "CoreJavaCode2.tmp") );
firstTime = 0;
}
init_gToOpen(ta_fs_path(3, "..", "temp", "CoreJavaCode1.tmp"), NULL );
logicTmp = fopen( gToOpen, "w" );
if( !logicTmp )
{
printf( "Cannot open CoreJavaCode1.tmp\n" );
return;
}
fprintf( logicTmp, "#include \"ta_java_defs.h\"\n" );
fclose(logicTmp);
#ifdef _MSC_VER
sprintf( buffer, TA_MCPP_EXE " -c -+ -z -P -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_common -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_abstract -I.." TA_FS_SLASH "include -D _JAVA .." TA_FS_SLASH "src" TA_FS_SLASH "ta_func" TA_FS_SLASH "TA_%s.c >>.." TA_FS_SLASH "temp" TA_FS_SLASH "CoreJavaCode1.tmp ", funcInfo->name);
system( buffer );
sprintf( buffer, TA_MCPP_EXE " -c -+ -z -P -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_common -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_abstract -I.." TA_FS_SLASH "include -D _JAVA .." TA_FS_SLASH "temp" TA_FS_SLASH "CoreJavaCode1.tmp >.." TA_FS_SLASH "temp" TA_FS_SLASH "CoreJavaCode2.tmp " );
system( buffer );
#else
sprintf( buffer, TA_MCPP_EXE " -@compat -+ -z -P -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_common -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_abstract -I.." TA_FS_SLASH "include -D _JAVA .." TA_FS_SLASH "src" TA_FS_SLASH "ta_func" TA_FS_SLASH "ta_%s.c | sed '/^#include/d' >> .." TA_FS_SLASH "temp" TA_FS_SLASH "CoreJavaCode1.tmp ", funcInfo->name);
system( buffer );
sprintf( buffer, TA_MCPP_EXE " -@compat -+ -z -P -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_common -I.." TA_FS_SLASH "src" TA_FS_SLASH "ta_abstract -I.." TA_FS_SLASH "include -D _JAVA .." TA_FS_SLASH "temp" TA_FS_SLASH "CoreJavaCode1.tmp | sed '/^#include/d' > .." TA_FS_SLASH "temp" TA_FS_SLASH "CoreJavaCode2.tmp " );
system( buffer );
#endif
init_gToOpen( ta_fs_path(3, "..", "temp", "CoreJavaCode2.tmp"), NULL );
logicTmp = fopen( gToOpen, "r" );
if( !logicTmp )
{
printf( "Cannot open CoreJavaCode2.tmp\n" );
return;
}
while( fgets(gTempBuf,BUFFER_SIZE,logicTmp) )
{
idx = 0;
again = 1;
while( again && gTempBuf[idx] != '\0' )
{
if( !isspace(gTempBuf[idx]) && !(gTempBuf[idx] == ';') )
again = 0;
idx++;
}
if( (again == 0) && (idx > 0) )
fputs( gTempBuf, gOutCore_Java->file );
}
fclose(logicTmp);
print( gOutCore_Java->file, "\n" );
fileDelete( ta_fs_path(3, "..", "temp", "CoreJavaCode1.tmp") );
fileDelete( ta_fs_path(3, "..", "temp", "CoreJavaCode2.tmp") );
}
static int generateFuncAPI_C()
{
FileHandle *inFile;
FILE *out;
FILE *in;
#define FILE_INPUT ta_fs_path(3, "..", "..", "ta_func_api.xml")
#define FILE_OUTPUT ta_fs_path(4, "..", "src", "ta_abstract", "ta_func_api.c")
#define FILE_OUTPUT_TEMPLATE ta_fs_path(5, "..", "src", "ta_abstract", "templates", "ta_func_api.c.template")
inFile = fileOpen( FILE_INPUT, NULL, FILE_READ );
if( inFile == NULL )
{
printf( "\nCannot access [%s]\n", gToOpen );
return -1;
}
gOutFuncAPI_C = fileOpen( FILE_OUTPUT, FILE_OUTPUT_TEMPLATE, FILE_WRITE|WRITE_ON_CHANGE_ONLY );
if( gOutFuncAPI_C == NULL )
{
printf( "\nCannot write to [%s]\n", gToOpen );
return -1;
}
out = gOutFuncAPI_C->file;
in = inFile->file;
convertFileToCArray(in, out);
fileClose(gOutFuncAPI_C);
fileClose(inFile);
return 1;
}
static void convertFileToCArray( FILE *in, FILE *out )
{
int c;
int position;
position = 0;
c = getc(in);
while( c != EOF )
{
if( position == 0 )
fprintf( out, "0x%02X", (char)c );
else
{
fprintf( out, ",0x%02X", (char)c );
if( (position % 20) == 0 )
fprintf( out, "\n" );
}
position++;
c = getc(in);
}
}
static void printJavaFunctionAnnotation(const TA_FuncInfo *funcInfo)
{
TA_RetCode retCode;
TA_InputParameterInfo *inputInfo;
TA_OptInputParameterInfo *optInputInfo;
TA_OutputParameterInfo *outputInfo;
TA_RealRange *doubleRange;
TA_IntegerRange *integerRange;
TA_IntegerList *intList;
unsigned int i, j;
#define FUNCNAME_SIZE 100
char funcName[FUNCNAME_SIZE];
memset(funcName, 0, FUNCNAME_SIZE);
if( strlen(funcInfo->name) > (FUNCNAME_SIZE-1) )
{
printf( "\n*** Error buffer size exceeded (printJavaFunctionAnnotation)\n" );
strcpy( funcName, "1A2");
}
else
{
if (funcInfo->camelCaseName==NULL) {
strcpy(funcName, funcInfo->name);
for (i=0; funcName[i]; i++) {
funcName[i] = tolower(funcName[i]);
}
} else {
strcpy(funcName, funcInfo->camelCaseName);
funcName[0] = tolower(funcName[0]);
}
}
fprintf(gOutFunc_Annotation->file, "public int %sLookback(\n", funcName);
for(i=0; i<funcInfo->nbOptInput; i++)
{
retCode = TA_GetOptInputParameterInfo( funcInfo->handle, i, (void*)&optInputInfo );
if(optInputInfo->type == TA_OptInput_RealRange)
{
fprintf(gOutFunc_Annotation->file, " double %s", optInputInfo->paramName);
}
else if(optInputInfo->type == TA_OptInput_IntegerRange)
{
fprintf(gOutFunc_Annotation->file, " int %s", optInputInfo->paramName);
}
else if(optInputInfo->type == TA_OptInput_IntegerList)
{
fprintf(gOutFunc_Annotation->file, " MAType %s", optInputInfo->paramName);
}
else
{
printf( "Unexpected error 1 (doForEachFunctionAnnotation)\n");
}
if (i<funcInfo->nbOptInput-1) fprintf(gOutFunc_Annotation->file, ",\n");
}
fprintf(gOutFunc_Annotation->file, ") {\n");
fprintf(gOutFunc_Annotation->file, " return super.%sLookback(\n", funcName);
for(i=0; i<funcInfo->nbOptInput; i++)
{
retCode = TA_GetOptInputParameterInfo( funcInfo->handle, i, (void*)&optInputInfo );
fprintf(gOutFunc_Annotation->file, " %s", optInputInfo->paramName);
if (i<funcInfo->nbOptInput-1) fprintf(gOutFunc_Annotation->file, ",\n");
}
fprintf(gOutFunc_Annotation->file, "); }\n\n");
fprintf(gOutFunc_Annotation->file, "@FuncInfo(\n");
fprintf(gOutFunc_Annotation->file, " name = \"%s\",\n", funcInfo->name);
fprintf(gOutFunc_Annotation->file, " group = \"%s\",\n", funcInfo->group);
fprintf(gOutFunc_Annotation->file, " flags = %d,\n", funcInfo->flags);
fprintf(gOutFunc_Annotation->file, " nbInput = %d,\n", funcInfo->nbInput);
fprintf(gOutFunc_Annotation->file, " nbOptInput = %d,\n", funcInfo->nbOptInput);
fprintf(gOutFunc_Annotation->file, " nbOutput = %d\n", funcInfo->nbOutput);
fprintf(gOutFunc_Annotation->file, ")\n");
fprintf(gOutFunc_Annotation->file, "public RetCode %s(\n", funcName);
fprintf(gOutFunc_Annotation->file, " int startIdx,\n");
fprintf(gOutFunc_Annotation->file, " int endIdx,\n");
for(i=0; i<funcInfo->nbInput; i++)
{
char idx = ' ';
retCode = TA_GetInputParameterInfo( funcInfo->handle, i, (void*)&inputInfo);
if(inputInfo->type == TA_Input_Price)
{
fprintf(gOutFunc_Annotation->file, " @InputParameterInfo(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", inputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " flags = %d,\n", inputInfo->flags);
fprintf(gOutFunc_Annotation->file, " type = InputParameterType.TA_Input_Price\n");
fprintf(gOutFunc_Annotation->file, " )\n");
if(inputInfo->flags & TA_IN_PRICE_OPEN)
{
fprintf(gOutFunc_Annotation->file, " double inOpen%c[],\n",idx);
}
if(inputInfo->flags & TA_IN_PRICE_HIGH)
{
fprintf(gOutFunc_Annotation->file, " double inHigh%c[],\n",idx);
}
if(inputInfo->flags & TA_IN_PRICE_LOW)
{
fprintf(gOutFunc_Annotation->file, " double inLow%c[],\n",idx);
}
if(inputInfo->flags & TA_IN_PRICE_CLOSE)
{
fprintf(gOutFunc_Annotation->file, " double inClose%c[],\n",idx);
}
if(inputInfo->flags & TA_IN_PRICE_VOLUME)
{
fprintf(gOutFunc_Annotation->file, " double inVolume%c[],\n",idx);
}
if(inputInfo->flags & TA_IN_PRICE_OPENINTEREST)
{
fprintf(gOutFunc_Annotation->file, " double inOpenInterest%c[],\n",idx);
}
if(inputInfo->flags & TA_IN_PRICE_TIMESTAMP)
{
fprintf(gOutFunc_Annotation->file, " long inTimestamp%c[],\n",idx);
}
}
else
{
if(inputInfo->type == TA_Input_Real)
{
fprintf(gOutFunc_Annotation->file, " @InputParameterInfo(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", inputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " flags = %d,\n", inputInfo->flags);
fprintf(gOutFunc_Annotation->file, " type = InputParameterType.TA_Input_Real\n");
fprintf(gOutFunc_Annotation->file, " )\n");
fprintf(gOutFunc_Annotation->file, " double %s[],\n", inputInfo->paramName);
}
else if(inputInfo->type == TA_Input_Integer)
{
fprintf(gOutFunc_Annotation->file, " @InputParameterInfo(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", inputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " flags = %d,\n", inputInfo->flags);
fprintf(gOutFunc_Annotation->file, " type = InputParameterType.TA_Input_Integer\n");
fprintf(gOutFunc_Annotation->file, " )\n");
fprintf(gOutFunc_Annotation->file, " int %s[],\n", inputInfo->paramName);
}
else
{
printf( "Unexpected error 2(doForEachFunctionAnnotation)\n");
}
}
}
for(i=0; i<funcInfo->nbOptInput; i++)
{
retCode = TA_GetOptInputParameterInfo( funcInfo->handle, i, (void*)&optInputInfo );
fprintf(gOutFunc_Annotation->file, " @OptInputParameterInfo(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", optInputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " displayName = \"%s\",\n", optInputInfo->displayName);
fprintf(gOutFunc_Annotation->file, " flags = %d,\n", optInputInfo->flags);
if(optInputInfo->type == TA_OptInput_RealRange)
{
fprintf(gOutFunc_Annotation->file, " type = OptInputParameterType.TA_OptInput_RealRange,\n");
fprintf(gOutFunc_Annotation->file, " dataSet = com.tictactec.ta.lib.meta.annotation.RealRange.class\n");
fprintf(gOutFunc_Annotation->file, " )\n");
doubleRange= (TA_RealRange*)optInputInfo->dataSet;
fprintf(gOutFunc_Annotation->file, " @RealRange(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", optInputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " defaultValue = %.5f,\n", (double)optInputInfo->defaultValue);
fprintf(gOutFunc_Annotation->file, " min = %.5f,\n", doubleRange->min);
fprintf(gOutFunc_Annotation->file, " max = %.5f,\n", doubleRange->max);
fprintf(gOutFunc_Annotation->file, " precision = %d,\n", doubleRange->precision);
fprintf(gOutFunc_Annotation->file, " suggested_start = %.5f,\n", doubleRange->suggested_start);
fprintf(gOutFunc_Annotation->file, " suggested_end = %.5f,\n", doubleRange->suggested_end);
fprintf(gOutFunc_Annotation->file, " suggested_increment = %.5f\n", doubleRange->suggested_increment);
fprintf(gOutFunc_Annotation->file, " )\n");
fprintf(gOutFunc_Annotation->file, " double %s,\n", optInputInfo->paramName);
}
else if(optInputInfo->type == TA_OptInput_IntegerRange)
{
fprintf(gOutFunc_Annotation->file, " type = OptInputParameterType.TA_OptInput_IntegerRange,\n");
fprintf(gOutFunc_Annotation->file, " dataSet = com.tictactec.ta.lib.meta.annotation.IntegerRange.class\n");
fprintf(gOutFunc_Annotation->file, " )\n");
integerRange= (TA_IntegerRange*)optInputInfo->dataSet;
fprintf(gOutFunc_Annotation->file, " @IntegerRange(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", optInputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " defaultValue = %d,\n", (int)optInputInfo->defaultValue);
fprintf(gOutFunc_Annotation->file, " min = %d,\n", integerRange->min);
fprintf(gOutFunc_Annotation->file, " max = %d,\n", integerRange->max);
fprintf(gOutFunc_Annotation->file, " suggested_start = %d,\n", integerRange->suggested_start);
fprintf(gOutFunc_Annotation->file, " suggested_end = %d,\n", integerRange->suggested_end);
fprintf(gOutFunc_Annotation->file, " suggested_increment = %d\n", integerRange->suggested_increment);
fprintf(gOutFunc_Annotation->file, " )\n");
fprintf(gOutFunc_Annotation->file, " int %s,\n", optInputInfo->paramName);
}
else if(optInputInfo->type == TA_OptInput_IntegerList)
{
fprintf(gOutFunc_Annotation->file, " type = OptInputParameterType.TA_OptInput_IntegerList,\n");
fprintf(gOutFunc_Annotation->file, " dataSet = com.tictactec.ta.lib.meta.annotation.IntegerList.class\n");
fprintf(gOutFunc_Annotation->file, " )\n");
intList = (TA_IntegerList*) optInputInfo->dataSet;
fprintf(gOutFunc_Annotation->file, " @IntegerList(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", optInputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " defaultValue = %d,\n", (int)optInputInfo->defaultValue);
if (intList->nbElement>0) {
fprintf(gOutFunc_Annotation->file, " value = { ");
for (j=0; j<intList->nbElement-1; j++) {
fprintf(gOutFunc_Annotation->file, "%d, ", intList->data[j].value);
}
fprintf(gOutFunc_Annotation->file, "%d },\n", intList->data[intList->nbElement-1].value);
fprintf(gOutFunc_Annotation->file, " string = { ");
for (j=0; j<intList->nbElement-1; j++) {
fprintf(gOutFunc_Annotation->file, "\"%s\", ", intList->data[j].string);
}
fprintf(gOutFunc_Annotation->file, "\"%s\" }\n", intList->data[intList->nbElement-1].string);
}
fprintf(gOutFunc_Annotation->file, " )\n");
fprintf(gOutFunc_Annotation->file, " MAType %s,\n", optInputInfo->paramName);
}
else
{
printf( "Unexpected error 2(doForEachFunctionAnnotation)\n");
}
}
fprintf(gOutFunc_Annotation->file, " MInteger outBegIdx,\n");
fprintf(gOutFunc_Annotation->file, " MInteger outNBElement,\n");
for(i=0; i<funcInfo->nbOutput; i++)
{
retCode = TA_GetOutputParameterInfo( funcInfo->handle, i, (void*)&outputInfo );
if(outputInfo->type == TA_Output_Integer)
{
fprintf(gOutFunc_Annotation->file, " @OutputParameterInfo(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", outputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " flags = %d,\n", outputInfo->flags);
fprintf(gOutFunc_Annotation->file, " type = OutputParameterType.TA_Output_Integer\n");
fprintf(gOutFunc_Annotation->file, " )\n");
fprintf(gOutFunc_Annotation->file, " int %s[]\n", outputInfo->paramName);
}
else if(outputInfo->type == TA_Output_Real)
{
fprintf(gOutFunc_Annotation->file, " @OutputParameterInfo(\n");
fprintf(gOutFunc_Annotation->file, " paramName = \"%s\",\n", outputInfo->paramName);
fprintf(gOutFunc_Annotation->file, " flags = %d,\n", outputInfo->flags);
fprintf(gOutFunc_Annotation->file, " type = OutputParameterType.TA_Output_Real\n");
fprintf(gOutFunc_Annotation->file, " )\n");
fprintf(gOutFunc_Annotation->file, " double %s[]", outputInfo->paramName);
}
else
{
printf( "Unexpected error 3(doForEachFunctionAnnotation)\n");
}
if (i<funcInfo->nbOutput-1) {
fprintf(gOutFunc_Annotation->file, ",");
}
fprintf(gOutFunc_Annotation->file, "\n");
}
fprintf(gOutFunc_Annotation->file, ") {\n");
fprintf(gOutFunc_Annotation->file, " return super.%s (\n", funcName);
fprintf(gOutFunc_Annotation->file, " startIdx,\n");
fprintf(gOutFunc_Annotation->file, " endIdx,\n");
for(i=0; i<funcInfo->nbInput; i++)
{
retCode = TA_GetInputParameterInfo(funcInfo->handle, i, (void*)&inputInfo);
if(inputInfo->type == TA_Input_Price)
{
char idx = ' ';
if(inputInfo->flags & TA_IN_PRICE_OPEN)
{
fprintf(gOutFunc_Annotation->file, " inOpen%c,\n", idx);
}
if(inputInfo->flags & TA_IN_PRICE_HIGH)
{
fprintf(gOutFunc_Annotation->file, " inHigh%c,\n", idx);
}
if(inputInfo->flags & TA_IN_PRICE_LOW)
{
fprintf(gOutFunc_Annotation->file, " inLow%c,\n", idx);
}
if(inputInfo->flags & TA_IN_PRICE_CLOSE)
{
fprintf(gOutFunc_Annotation->file, " inClose%c,\n", idx);
}
if(inputInfo->flags & TA_IN_PRICE_VOLUME)
{
fprintf(gOutFunc_Annotation->file, " inVolume%c,\n", idx);
}
if(inputInfo->flags & TA_IN_PRICE_OPENINTEREST)
{
fprintf(gOutFunc_Annotation->file, " inOpenInterest%c,\n", idx);
}
if(inputInfo->flags & TA_IN_PRICE_TIMESTAMP)
{
fprintf(gOutFunc_Annotation->file, " inTimestamp%c,\n", idx);
}
} else {
fprintf(gOutFunc_Annotation->file, " %s,\n", inputInfo->paramName);
}
}
for(i=0; i<funcInfo->nbOptInput; i++)
{
retCode = TA_GetOptInputParameterInfo(funcInfo->handle, i, (void*)&optInputInfo);
fprintf(gOutFunc_Annotation->file, " %s,\n", optInputInfo->paramName);
}
fprintf(gOutFunc_Annotation->file, " outBegIdx,\n");
fprintf(gOutFunc_Annotation->file, " outNBElement,\n");
for(i=0; i<funcInfo->nbOutput-1; i++)
{
retCode = TA_GetOutputParameterInfo(funcInfo->handle, i, (void*)&outputInfo);
fprintf(gOutFunc_Annotation->file, " %s,\n", outputInfo->paramName);
}
retCode = TA_GetOutputParameterInfo(funcInfo->handle, funcInfo->nbOutput-1, (void*)&outputInfo);
fprintf(gOutFunc_Annotation->file, " %s\n", outputInfo->paramName);
fprintf(gOutFunc_Annotation->file, "); }\n\n\n");
}
#ifdef TA_LIB_PRO
#endif