3416 lines
72 KiB
C
3416 lines
72 KiB
C
|
|
|
||
|
|
#include "file.h"
|
||
|
|
|
||
|
|
int globalClassIndex = 0;
|
||
|
|
|
||
|
|
struct file * file_new() {
|
||
|
|
|
||
|
|
struct file * fileInstance = malloc( sizeof( struct file ) );
|
||
|
|
|
||
|
|
return fileInstance;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_parseMacros( struct file * fileInstance, struct array * files ) {
|
||
|
|
|
||
|
|
file_removeComments( fileInstance );
|
||
|
|
|
||
|
|
char * filename = fileInstance->filename;
|
||
|
|
|
||
|
|
printf("parse Macros: %s \n\n", filename);
|
||
|
|
|
||
|
|
|
||
|
|
char * source = fileInstance->source;
|
||
|
|
|
||
|
|
printf("%s\n\n", source);
|
||
|
|
|
||
|
|
int includeCount = array_length( fileInstance->includes );
|
||
|
|
|
||
|
|
printf("add includes. %i \n", includeCount);
|
||
|
|
|
||
|
|
for ( int k = 0; k < includeCount; ++k )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct include * includeInstance = array_get( fileInstance->includes, k );
|
||
|
|
|
||
|
|
char * currentInclude = includeInstance->path;
|
||
|
|
|
||
|
|
char * includeFileName = file_getFileNameFromInclude( currentInclude );
|
||
|
|
|
||
|
|
char * includeFileBaseName = file_removeExtensionFromFileName( includeFileName );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct file * includedFileInstance = file_getFileByFileName( files, includeFileBaseName );
|
||
|
|
|
||
|
|
|
||
|
|
if( includedFileInstance != NULL ) {
|
||
|
|
|
||
|
|
printf("loaded %s.h \n\n", includedFileInstance->path );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text * filePath = text_new("/usr/include/");
|
||
|
|
|
||
|
|
text_append( filePath, includeFileName );
|
||
|
|
|
||
|
|
text_append( filePath, ".h" );
|
||
|
|
|
||
|
|
|
||
|
|
if( fileSystem_exists( filePath->value ) ) {
|
||
|
|
|
||
|
|
includedFileInstance = file_new();
|
||
|
|
|
||
|
|
|
||
|
|
includedFileInstance->filename = basename( text_copy( filePath->value ) );
|
||
|
|
|
||
|
|
includedFileInstance->dirname = dirname( text_copy( filePath->value ) );
|
||
|
|
|
||
|
|
includedFileInstance->path = filePath->value;
|
||
|
|
|
||
|
|
printf("Created new file: %s\n\n", includedFileInstance->path);
|
||
|
|
|
||
|
|
|
||
|
|
includedFileInstance->source = fileSystem_readFile( includedFileInstance->path );
|
||
|
|
|
||
|
|
|
||
|
|
//printf("%s\n\n", includedFileInstance->source);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
file_parseMacros( includedFileInstance, files );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_extendClasses( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
//printf( ANSI_COLOR_YELLOW "\n\n\n extend class.\n" ANSI_COLOR_RESET );
|
||
|
|
|
||
|
|
struct array * classes = fileInstance->classes;
|
||
|
|
|
||
|
|
int classesCount = array_length( classes );
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( classes, i );
|
||
|
|
|
||
|
|
classInstance->hasExtended = -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( classes, i );
|
||
|
|
|
||
|
|
class_extendClass( classInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_extractTemplates( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
struct array * classes = fileInstance->classes;
|
||
|
|
|
||
|
|
int classesCount = array_length( classes );
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( classes, i );
|
||
|
|
|
||
|
|
int methodCount = array_length( classInstance->methods );
|
||
|
|
|
||
|
|
for ( int k = 0; k < methodCount; ++k )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct method * methodInstance = array_get( classInstance->methods, k );
|
||
|
|
|
||
|
|
methodInstance->bodyOriginal = method_extractTemplates( methodInstance->bodyOriginal );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct array * functions = fileInstance->functions;
|
||
|
|
|
||
|
|
int functionCount = array_length( functions );
|
||
|
|
|
||
|
|
for (int i = 0; i < functionCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct functionLayout * functionInstance = array_get( functions, i );
|
||
|
|
|
||
|
|
functionInstance->bodyOriginal = method_extractTemplates( functionInstance->bodyOriginal );
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * class_createRegexSearchNeedle( char * name ) {
|
||
|
|
|
||
|
|
char * replaceFromRegex = "\\b";
|
||
|
|
|
||
|
|
replaceFromRegex = text_concatenate( replaceFromRegex, name );
|
||
|
|
|
||
|
|
replaceFromRegex = text_concatenate( replaceFromRegex, "\\b" );
|
||
|
|
|
||
|
|
return replaceFromRegex;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void class_copyMethod( struct class * classInstance,
|
||
|
|
struct method * methodInstance,
|
||
|
|
struct class * classCopy,
|
||
|
|
int * lineNumber,
|
||
|
|
char * classNameRegex,
|
||
|
|
char * templateAgumentRegex,
|
||
|
|
char * firstTemplateArgument,
|
||
|
|
char * firstTemplateArgumentValue ) {
|
||
|
|
|
||
|
|
|
||
|
|
struct method * methodCopy = malloc( sizeof( struct method ) );
|
||
|
|
|
||
|
|
methodCopy->methodName = methodInstance->methodName;
|
||
|
|
|
||
|
|
methodCopy->isSetter = methodInstance->isSetter;
|
||
|
|
|
||
|
|
methodCopy->isGetter = methodInstance->isGetter;
|
||
|
|
|
||
|
|
methodCopy->returnType = text_copy( methodInstance->returnType );
|
||
|
|
|
||
|
|
*lineNumber += text_countLineBreaks( methodInstance->bodyOriginal, -1 ) + 10;
|
||
|
|
|
||
|
|
methodCopy->lineNumber = *lineNumber;
|
||
|
|
|
||
|
|
methodCopy->arguments = array_new();
|
||
|
|
|
||
|
|
int argumentsCount = array_length( methodInstance->arguments );
|
||
|
|
|
||
|
|
for (int l = 0; l < argumentsCount; ++l)
|
||
|
|
{
|
||
|
|
char * currentArgument = array_get( methodInstance->arguments, l );
|
||
|
|
|
||
|
|
char * argumentCopy = text_copy( currentArgument );
|
||
|
|
|
||
|
|
if( l == 0 ) {
|
||
|
|
|
||
|
|
argumentCopy = text_regexReplaceAll( argumentCopy, classNameRegex, classInstance->className, classCopy->className );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
array_add( methodCopy->arguments, argumentCopy );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
methodCopy->variables = array_new();
|
||
|
|
|
||
|
|
method_addThisVariableToVariables( classCopy, methodCopy->variables );
|
||
|
|
|
||
|
|
methodCopy->bodyOriginal = text_regexReplaceAll( methodInstance->bodyOriginal, templateAgumentRegex, firstTemplateArgument, firstTemplateArgumentValue );//methodInstance->bodyOriginal;
|
||
|
|
|
||
|
|
|
||
|
|
for ( int h = 0; h < argumentsCount; ++h )
|
||
|
|
{
|
||
|
|
|
||
|
|
char * currentArgument = array_get( methodCopy->arguments, h );
|
||
|
|
|
||
|
|
currentArgument = text_regexReplaceAll( currentArgument, templateAgumentRegex, firstTemplateArgument, firstTemplateArgumentValue );
|
||
|
|
|
||
|
|
array_set( methodCopy->arguments, h, currentArgument );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
methodCopy->returnType = text_regexReplaceAll( methodCopy->returnType, templateAgumentRegex, firstTemplateArgument, firstTemplateArgumentValue );
|
||
|
|
|
||
|
|
array_add( classCopy->methods, methodCopy );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void class_copyMethods( struct class * classInstance, struct class * classCopy, char * firstTemplateArgument, char * firstTemplateArgumentValue, int * lineNumber ) {
|
||
|
|
|
||
|
|
char * templateAgumentRegex = class_createRegexSearchNeedle( firstTemplateArgument );
|
||
|
|
|
||
|
|
char * classNameRegex = class_createRegexSearchNeedle( classInstance->className ); // "\\b TT \\b"
|
||
|
|
|
||
|
|
|
||
|
|
int methodCount = array_length( classInstance->methods );
|
||
|
|
|
||
|
|
for (int k = 0; k < methodCount; ++k )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct method * methodInstance = array_get( classInstance->methods, k );
|
||
|
|
|
||
|
|
class_copyMethod( classInstance, methodInstance, classCopy, lineNumber, classNameRegex, templateAgumentRegex, firstTemplateArgument, firstTemplateArgumentValue );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void class_copyProperties( struct class * classInstance, struct class * classCopy, char * firstTemplateArgument, char * firstTemplateArgumentValue ) {
|
||
|
|
|
||
|
|
char * replaceFromRegex = class_createRegexSearchNeedle( firstTemplateArgument );
|
||
|
|
|
||
|
|
|
||
|
|
int propertyCount = array_length( classInstance->properties );
|
||
|
|
|
||
|
|
for (int k = 0; k < propertyCount; ++k )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct property * propertyInstance = array_get( classInstance->properties, k );
|
||
|
|
|
||
|
|
struct property * propertyCopy = malloc( sizeof( struct property ) );
|
||
|
|
|
||
|
|
propertyCopy->propertyName = text_copy( propertyInstance->propertyName );
|
||
|
|
|
||
|
|
propertyCopy->datatype = text_copy( propertyInstance->datatype );
|
||
|
|
|
||
|
|
propertyCopy->decleration = text_copy( propertyInstance->decleration );
|
||
|
|
|
||
|
|
propertyCopy->value = text_copy( propertyInstance->value );
|
||
|
|
|
||
|
|
propertyCopy->isPointer = propertyInstance->isPointer;
|
||
|
|
|
||
|
|
propertyCopy->type = text_copy( propertyInstance->type );
|
||
|
|
|
||
|
|
propertyCopy->hasValue = propertyInstance->hasValue;
|
||
|
|
|
||
|
|
propertyCopy->decleration = text_regexReplaceAll( propertyCopy->decleration, replaceFromRegex, firstTemplateArgument, firstTemplateArgumentValue );
|
||
|
|
|
||
|
|
propertyCopy->datatype = text_regexReplaceAll( propertyCopy->datatype, replaceFromRegex, firstTemplateArgument, firstTemplateArgumentValue );
|
||
|
|
|
||
|
|
|
||
|
|
array_add( classCopy->properties, propertyCopy );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void class_instantiateTemplates( struct file * fileInstance, struct class * classInstance, int * lineNumber ) {
|
||
|
|
|
||
|
|
struct template * currentTemplate = classInstance->template;
|
||
|
|
|
||
|
|
array * intances = currentTemplate->instances;
|
||
|
|
|
||
|
|
array * arguments = currentTemplate->arguments;
|
||
|
|
|
||
|
|
|
||
|
|
printf("\n\n\n\n Creating %i templates for %s\n\n\n\n\n", array_length( intances ), classInstance->className );
|
||
|
|
|
||
|
|
int intancesCount = array_length( intances );
|
||
|
|
|
||
|
|
for ( int j = 0; j < intancesCount; ++j )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct templateInstance * currentTemplateInstance = array_get( intances, j );
|
||
|
|
|
||
|
|
|
||
|
|
char * firstTemplateArgumentValue = array_get( currentTemplateInstance->argumentValues, 0 ); // array * <int>
|
||
|
|
|
||
|
|
char * firstTemplateArgument = array_get( arguments, 0 ); // template<T>
|
||
|
|
|
||
|
|
|
||
|
|
struct class * classCopy = class_new();
|
||
|
|
|
||
|
|
classCopy->methods = array_new();
|
||
|
|
|
||
|
|
classCopy->properties = array_new();
|
||
|
|
|
||
|
|
classCopy->extends = array_new();
|
||
|
|
|
||
|
|
classCopy->classIndex = classInstance->classIndex;
|
||
|
|
|
||
|
|
|
||
|
|
char * newClassName = text_copy( classInstance->className );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
newClassName = text_concatenate( newClassName, "_" );
|
||
|
|
|
||
|
|
newClassName = text_concatenate( newClassName, firstTemplateArgumentValue );
|
||
|
|
|
||
|
|
|
||
|
|
newClassName = text_replaceAll( newClassName, "*", "_pointer" );
|
||
|
|
|
||
|
|
newClassName = text_removeAllWhiteSpaces( newClassName );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
classCopy->className = newClassName;
|
||
|
|
|
||
|
|
|
||
|
|
class_copyMethods( classInstance, classCopy, firstTemplateArgument, firstTemplateArgumentValue, lineNumber );
|
||
|
|
|
||
|
|
class_copyProperties( classInstance, classCopy, firstTemplateArgument, firstTemplateArgumentValue );
|
||
|
|
|
||
|
|
|
||
|
|
classCopy->hasReflection = classInstance->hasReflection;
|
||
|
|
|
||
|
|
classCopy->usesTemplate = true;
|
||
|
|
|
||
|
|
|
||
|
|
array_add( fileInstance->classes, classCopy );
|
||
|
|
|
||
|
|
array_add( allClasses, classCopy );
|
||
|
|
|
||
|
|
// printf("replacing replaceFrom: %s namespace: %s\n\n", firstTemplateArgument, firstTemplateArgumentValue);
|
||
|
|
|
||
|
|
// printf("\n\n\n\n\n\n\nAdding class to allClasses: '%s'\n\n\n\n\n\n\n", classInstance->className);
|
||
|
|
|
||
|
|
// array_add( fileInstance->classes, classCopy );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_instanciateTemplates( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
int lineNumber = 0;
|
||
|
|
|
||
|
|
struct array * classes = fileInstance->classes;
|
||
|
|
|
||
|
|
int classesCount = array_length( classes );
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( classes, i );
|
||
|
|
|
||
|
|
if( classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
class_instantiateTemplates( fileInstance, classInstance, &lineNumber );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composeHeaderMacros( struct file * fileInstance, struct text * classHeader ) {
|
||
|
|
|
||
|
|
text_append( classHeader, "\n// Macros\n" );
|
||
|
|
|
||
|
|
int macroCount = array_length( fileInstance->macros );
|
||
|
|
|
||
|
|
for (int i = 0; i < macroCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * currentMacro = array_get( fileInstance->macros, i );
|
||
|
|
|
||
|
|
text_append( classHeader, "\n" );
|
||
|
|
|
||
|
|
text_append( classHeader, currentMacro );
|
||
|
|
|
||
|
|
text_append( classHeader, "\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( classHeader, "\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_compose( struct file * fileInstance, struct application * applicationInstance ) {
|
||
|
|
|
||
|
|
char * filename = fileInstance->filename;
|
||
|
|
|
||
|
|
struct text * classHeader = file_composeHeaderIncludes( fileInstance );
|
||
|
|
|
||
|
|
struct array * sourceArray = array_new();
|
||
|
|
|
||
|
|
struct array * classes = fileInstance->classes;
|
||
|
|
|
||
|
|
int classesCount = array_length( classes );
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( classes, i );
|
||
|
|
|
||
|
|
if( i == 0 ) {
|
||
|
|
|
||
|
|
if( classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
class_composeHeader( classInstance, classHeader, filename );
|
||
|
|
|
||
|
|
class_composeMethods( classInstance, classHeader, sourceArray );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
file_composeFunctions( fileInstance->functions, sourceArray, classHeader );
|
||
|
|
|
||
|
|
file_writeAll( sourceArray, classHeader, fileInstance->path, fileInstance->classes, fileInstance->globals, fileInstance->path, applicationInstance );
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_addIncludesToHeader( struct text * classHeader, struct file * currentFile ) {
|
||
|
|
|
||
|
|
text_append( classHeader, "\n" );
|
||
|
|
|
||
|
|
text_append( classHeader, "#include \"stdlib.h\"\n\n" );
|
||
|
|
|
||
|
|
//text_append( classHeader, "#include \"classConfiguration.h\"\n\n" );
|
||
|
|
|
||
|
|
text_append( classHeader, "extern char * __ClassNames[];\n\n" );
|
||
|
|
|
||
|
|
text_append( classHeader, "\n// Includes\n" );
|
||
|
|
|
||
|
|
int includesCount = array_length( currentFile->includes );
|
||
|
|
|
||
|
|
for (int i = 0; i < includesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct include * includeInstance = array_get( currentFile->includes, i );
|
||
|
|
|
||
|
|
char * currentInclude = includeInstance->path;
|
||
|
|
|
||
|
|
if( includeInstance->enabled ) {
|
||
|
|
|
||
|
|
text_append( classHeader, "\n" );
|
||
|
|
|
||
|
|
text_append( classHeader, currentInclude );
|
||
|
|
|
||
|
|
text_append( classHeader, "\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( classHeader, "\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_preventDoubleLoadingHeader( struct text * classHeader, char * filename ) {
|
||
|
|
|
||
|
|
// . with _
|
||
|
|
filename = text_replaceChar( filename, 46, 95 );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( classHeader, "#ifndef _" );
|
||
|
|
|
||
|
|
text_append( classHeader, filename );
|
||
|
|
|
||
|
|
text_append( classHeader, "\n\n#define _" );
|
||
|
|
|
||
|
|
text_append( classHeader, filename );
|
||
|
|
|
||
|
|
text_append( classHeader, "\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct text * file_composeHeaderIncludes( struct file * currentFile ) {
|
||
|
|
|
||
|
|
char * filename = ( currentFile->filename );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct text * classHeader = text_new("");
|
||
|
|
|
||
|
|
file_preventDoubleLoadingHeader( classHeader, filename );
|
||
|
|
|
||
|
|
file_composeHeaderMacros( currentFile, classHeader );
|
||
|
|
|
||
|
|
file_addIncludesToHeader( classHeader, currentFile );
|
||
|
|
|
||
|
|
return classHeader;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_extractMethodsAndProperties( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
char * source = fileInstance->source;
|
||
|
|
|
||
|
|
array * classesArray = array_new();
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
fileInstance->functions = array_new();
|
||
|
|
|
||
|
|
|
||
|
|
lexer_getTokens( currentLexer, source );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
int bodyCloseIndex = -1;
|
||
|
|
|
||
|
|
int depth = 0;
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( token, "{" ) == 0 ) {
|
||
|
|
|
||
|
|
depth++;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( depth == 0 ) {
|
||
|
|
|
||
|
|
if ( strcmp( token, "class" ) == 0 ) {
|
||
|
|
|
||
|
|
file_extractInnerClass( currentLexer, i, key, fileInstance, source, bodyCloseIndex );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "}" ) == 0 ) {
|
||
|
|
|
||
|
|
depth--;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_extractFunctions( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
char * source = fileInstance->source;
|
||
|
|
|
||
|
|
array * classesArray = array_new();
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
fileInstance->functions = array_new();
|
||
|
|
|
||
|
|
|
||
|
|
lexer_getTokens( currentLexer, source );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
int bodyCloseIndex = -1;
|
||
|
|
|
||
|
|
int depth = 0;
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( token, "{" ) == 0 ) {
|
||
|
|
|
||
|
|
depth++;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( depth == 0 ) {
|
||
|
|
|
||
|
|
if ( strcmp( token, "(" ) == 0 ) {
|
||
|
|
|
||
|
|
file_extractFunction( currentLexer, i, key, fileInstance, source, bodyCloseIndex, classesArray );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "}" ) == 0 ) {
|
||
|
|
|
||
|
|
depth--;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_parseClassBody( lexer * currentLexer,
|
||
|
|
int fromKey,
|
||
|
|
int toIndex,
|
||
|
|
char * source,
|
||
|
|
struct file * fileInstance,
|
||
|
|
struct class * classInstance ) {
|
||
|
|
|
||
|
|
|
||
|
|
int depth = -1;
|
||
|
|
|
||
|
|
int parsintMethod = -1;
|
||
|
|
|
||
|
|
printf(" class %s{\n\n", classInstance->className);
|
||
|
|
|
||
|
|
for (int i = fromKey; i < toIndex; ++i)
|
||
|
|
{
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
char * currentToken = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
if ( strcmp( currentToken, "{" ) == 0 ) {
|
||
|
|
|
||
|
|
depth++;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( depth == 0 ) {
|
||
|
|
|
||
|
|
//printf( "parseClassBody: %s : %i\n", currentToken, (int) key );
|
||
|
|
|
||
|
|
if ( strcmp( currentToken, ";" ) == 0 ) {
|
||
|
|
|
||
|
|
class_extractProperty( currentLexer, key, i, source, classInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( currentToken, "(" ) == 0 && parsintMethod == -1 ) {
|
||
|
|
|
||
|
|
int argumentCloseIndex = text_findArgumentCloseIndex( source, key );
|
||
|
|
|
||
|
|
int firstNextCharacter = text_findFirstNextCharacterNotWhiteSpace( source, argumentCloseIndex );
|
||
|
|
|
||
|
|
int beforePrevious = lexer_getKey( currentLexer, i - 2 );
|
||
|
|
|
||
|
|
char * methodDecleration = text_removeWhiteSpaces( text_slice( source, beforePrevious, firstNextCharacter ) );
|
||
|
|
|
||
|
|
|
||
|
|
// () {
|
||
|
|
if( source[firstNextCharacter] != 123 ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
class_extractMethod( currentLexer, source, i, classInstance, fileInstance->classes, fileInstance->functions );
|
||
|
|
|
||
|
|
parsintMethod = 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( currentToken, "}" ) == 0 ) {
|
||
|
|
|
||
|
|
depth--;
|
||
|
|
|
||
|
|
parsintMethod = -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("\n");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_extractInnerClass( lexer * currentLexer,
|
||
|
|
int i,
|
||
|
|
int key,
|
||
|
|
struct file * fileInstance,
|
||
|
|
char * source,
|
||
|
|
int bodyCloseIndex ) {
|
||
|
|
|
||
|
|
|
||
|
|
int bodyOpenIndex = lexer_findNextToken( currentLexer, i, "{" );
|
||
|
|
|
||
|
|
char * nextToken = lexer_getToken( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
char * className;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if( strcmp( nextToken, "extends" ) == 0 ) {
|
||
|
|
|
||
|
|
int nextKey = lexer_getKey( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
className = text_slice( source, key + 5, ( int ) nextKey - 1 );
|
||
|
|
|
||
|
|
bodyCloseIndex = lexer_findBodyCloseIndex( currentLexer, i + 2 );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
className = text_slice( source, key + 5, bodyOpenIndex - 1 );
|
||
|
|
|
||
|
|
bodyCloseIndex = lexer_findBodyCloseIndex( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
struct class * classInstance = application_getClassByClassName( fileInstance->classes, text_removeWhiteSpaces( className ) );
|
||
|
|
|
||
|
|
file_parseClassBody( currentLexer,
|
||
|
|
i + 1,
|
||
|
|
bodyCloseIndex,
|
||
|
|
source,
|
||
|
|
fileInstance,
|
||
|
|
classInstance );
|
||
|
|
|
||
|
|
|
||
|
|
printf(" }\n\n");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_extractFunctionDecleration( lexer * currentLexer, int i, int key, char * source ) {
|
||
|
|
|
||
|
|
int currentKey = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
int previousKey = lexer_getKey( currentLexer, i - 1 );
|
||
|
|
|
||
|
|
int fromPreviousKey = ( int ) previousKey + 1;
|
||
|
|
|
||
|
|
|
||
|
|
char * functionDeclaration = text_removeWhiteSpaces( text_slice( source, fromPreviousKey, key - 1 ) );
|
||
|
|
|
||
|
|
return functionDeclaration;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_extractFunction( lexer * currentLexer, int i, int key, struct file * fileInstance, char * source, int bodyCloseIndex, struct array * classesArray ) {
|
||
|
|
|
||
|
|
struct functionLayout * functionInstance = malloc( sizeof( struct functionLayout ) );
|
||
|
|
|
||
|
|
functionInstance->variables = array_new();
|
||
|
|
|
||
|
|
char * functionSource = class_extractBodyFromSource( currentLexer, i, source, bodyCloseIndex );
|
||
|
|
|
||
|
|
char * functionDeclaration = file_extractFunctionDecleration( currentLexer, i, key, source );
|
||
|
|
|
||
|
|
struct array * functionDeclarationParts = text_split( functionDeclaration, " \t" );
|
||
|
|
|
||
|
|
struct array * argumentsArray = method_getArguments_new( currentLexer, key, i, source, functionInstance->variables );
|
||
|
|
|
||
|
|
int declarationLength = array_length( functionDeclarationParts );
|
||
|
|
|
||
|
|
char * functionName = ( char * ) array_get( functionDeclarationParts, declarationLength - 1 );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
functionInstance->name = functionName;
|
||
|
|
|
||
|
|
functionInstance->declarationText = functionDeclaration;
|
||
|
|
|
||
|
|
functionInstance->bodyOriginal = functionSource;
|
||
|
|
|
||
|
|
functionInstance->arguments = argumentsArray;
|
||
|
|
|
||
|
|
functionInstance->isVariadic = method_methodIsVaradic( argumentsArray );
|
||
|
|
|
||
|
|
functionInstance->lineNumber = text_countLineBreaks( source, ( int ) key );
|
||
|
|
|
||
|
|
method_extractVariablesFromArguments( functionInstance->arguments, classesArray, functionInstance->variables );
|
||
|
|
|
||
|
|
|
||
|
|
array_add( allFunctions, functionInstance );
|
||
|
|
|
||
|
|
array_add( fileInstance->functions, functionInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_removeSingleLineComment_new( lexer * currentLexer, int i, char * source ) {
|
||
|
|
|
||
|
|
int nextLineIndex = lexer_findNextToken( currentLexer, i, "\n" );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
int numberOfCharacters = nextLineIndex - ( int ) key;
|
||
|
|
|
||
|
|
return text_replaceAt( ( int ) key, nextLineIndex, source, "" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_removeArrayTypeDefinitions( char * source ) {
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
//lexer_setSource( source );
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, "<");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, ">");
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
if ( strcmp( token, "<" ) == 0 ) {
|
||
|
|
|
||
|
|
|
||
|
|
int closeTypeDefinition = lexer_findNextToken( currentLexer, i, ">" );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
int previousKeyIndex = text_findFirstCharacterReverse( source, key );
|
||
|
|
|
||
|
|
char * wordBeforeKey = text_extractWordBeforeKey( source, key );
|
||
|
|
|
||
|
|
if ( strcmp( wordBeforeKey, "array" ) == 0 ) {
|
||
|
|
|
||
|
|
for (int i = key; i < closeTypeDefinition + 1; ++i)
|
||
|
|
{
|
||
|
|
source[i] = 32;
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("\n\n\n remove this array declaration: %s\n\n\n", wordBeforeKey);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * file_removeSingleLineComments( char * source ) {
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
//lexer_setSource( source );
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, "//");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, "\n");
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
if ( strcmp( token, "//" ) == 0 ) {
|
||
|
|
|
||
|
|
source = file_removeSingleLineComment_new( currentLexer, i, source );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_replaceMultiLineComment( lexer * currentLexer, int i, char * source ) {
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
int closeCommentIndex = lexer_findNextToken( currentLexer, i, "*/" ) + 2;
|
||
|
|
|
||
|
|
char * comment = text_slice( source, key, closeCommentIndex - 1 );
|
||
|
|
|
||
|
|
int numberOfLineBreaks = text_countLineBreaks( comment, -1 );
|
||
|
|
|
||
|
|
char * replacementText = malloc( numberOfLineBreaks + 1 );
|
||
|
|
|
||
|
|
replacementText[0] = 0;
|
||
|
|
|
||
|
|
for ( int j = 0; j < numberOfLineBreaks; ++j )
|
||
|
|
{
|
||
|
|
|
||
|
|
strcat( replacementText, "\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//printf("------------- open comment found: %s \n\n --%s-- \n\n %i \n", filename, comment, numberOfLineBreaks);
|
||
|
|
|
||
|
|
return text_replaceAt( ( int ) key, closeCommentIndex , source, replacementText );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_removeMultiLineComments( char * source ) {
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, "/*" );
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, "*/" );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
if ( strcmp( token, "/*" ) == 0 ) {
|
||
|
|
|
||
|
|
source = file_replaceMultiLineComment( currentLexer, i, source );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_removeComments( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
char * filename = fileInstance->path;
|
||
|
|
|
||
|
|
char * source = fileInstance->source;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//source = file_removeArrayTypeDefinitions( source );
|
||
|
|
|
||
|
|
source = file_removeSingleLineComments( source );
|
||
|
|
|
||
|
|
source = file_removeMultiLineComments( source );
|
||
|
|
|
||
|
|
|
||
|
|
fileInstance->source = source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_extractGlobalVariable( lexer * currentLexer, int key, int i, struct file * fileInstance, char * source ) {
|
||
|
|
|
||
|
|
int semicolonIndex = lexer_findPreviousKeyByToken( currentLexer, i, ";" );
|
||
|
|
|
||
|
|
void * previousToken = lexer_getToken( currentLexer, i - 1 );
|
||
|
|
|
||
|
|
int previousKey = lexer_getKey( currentLexer, i - 1 );
|
||
|
|
|
||
|
|
|
||
|
|
char * globalDeclaration = text_removeWhiteSpaces( text_slice( source, semicolonIndex + 1, key ) );
|
||
|
|
|
||
|
|
struct variable * variableInstance = variabe_new();
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct array * ISParts = text_split( globalDeclaration, "=" );
|
||
|
|
|
||
|
|
char * beforeIS = array_get( ISParts, 0 );
|
||
|
|
|
||
|
|
struct array * semicolonParts = text_split( globalDeclaration, ";" );
|
||
|
|
|
||
|
|
char * beforeSemocolon = array_get( semicolonParts, 0 );
|
||
|
|
|
||
|
|
|
||
|
|
struct array * defineParts = text_split( beforeSemocolon, " \t" );
|
||
|
|
|
||
|
|
char * variableName = array_get( defineParts, array_length( defineParts ) - 1 );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
variableInstance->variableName = variableName;
|
||
|
|
|
||
|
|
variableInstance->isPointer = variable_isPointer( defineParts );
|
||
|
|
|
||
|
|
variableInstance->declaration = globalDeclaration;
|
||
|
|
|
||
|
|
variableInstance->lineNumber = text_countLineBreaks( source, ( int ) key );
|
||
|
|
|
||
|
|
variableInstance->datatype = tools_findDatatype( defineParts );
|
||
|
|
|
||
|
|
|
||
|
|
array_add( fileInstance->globals, variableInstance );
|
||
|
|
|
||
|
|
//printf(" %i previous token: %s extract global: %s pointer: %i \n\n",semicolonIndex, previousToken, globalDeclaration, variableInstance->isPointer);
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_extractClasses( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
printf("Extract classes from file: '%s' \n\n", fileInstance->filename);
|
||
|
|
|
||
|
|
char * source = fileInstance->source;
|
||
|
|
|
||
|
|
array * classesArray = array_new();
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
|
||
|
|
lexer_getTokens( currentLexer, source );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
int bodyCloseIndex = 0;
|
||
|
|
|
||
|
|
int depth = 0;
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
if ( strcmp( token, "{" ) == 0 ) {
|
||
|
|
|
||
|
|
depth++;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "}" ) == 0 ) {
|
||
|
|
|
||
|
|
depth--;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( depth == 0 ) {
|
||
|
|
|
||
|
|
if ( strcmp( token, ";" ) == 0 ) {
|
||
|
|
|
||
|
|
file_extractGlobalVariable( currentLexer, key, i, fileInstance, source );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "class" ) == 0 ) {
|
||
|
|
|
||
|
|
if( depth == 0 ) {
|
||
|
|
|
||
|
|
file_extractClass( currentLexer, key, i, classesArray, depth, source );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
fileInstance->classes = classesArray;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_extractClass( lexer * currentLexer, int key, int i, struct array * classesArray, int depth, char * source ) {
|
||
|
|
|
||
|
|
|
||
|
|
char * previousToken = lexer_getToken( currentLexer, i - 1 );
|
||
|
|
|
||
|
|
char * nextToken = lexer_getToken( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
int bodyOpenIndex = lexer_findNextToken( currentLexer, i, "{" );
|
||
|
|
|
||
|
|
struct class * classInstance = class_new();
|
||
|
|
|
||
|
|
classInstance->hasReflection = false;
|
||
|
|
|
||
|
|
|
||
|
|
if( i > 0 ) {
|
||
|
|
|
||
|
|
if( strcmp( previousToken, "reflect" ) == 0 ) {
|
||
|
|
|
||
|
|
printf("this class is using reflection\n\n");
|
||
|
|
|
||
|
|
classInstance->hasReflection = true;
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( previousToken, ">" ) == 0 ) {
|
||
|
|
|
||
|
|
char * templateName = lexer_getToken( currentLexer, i - 3 );
|
||
|
|
|
||
|
|
|
||
|
|
if( strcmp( templateName, "template" ) == 0 ) {
|
||
|
|
|
||
|
|
int fromKey = lexer_getKey( currentLexer, i - 2 ) + 1;
|
||
|
|
|
||
|
|
int toKey = lexer_getKey( currentLexer, i - 1 ) - 1;
|
||
|
|
|
||
|
|
char * templateArguments = text_slice( source, fromKey, toKey );
|
||
|
|
|
||
|
|
|
||
|
|
classInstance->usesTemplate = true;
|
||
|
|
|
||
|
|
classInstance->template = template_new();
|
||
|
|
|
||
|
|
template_add_arguments( classInstance->template, templateArguments );
|
||
|
|
|
||
|
|
printf("this class has a template: %s \n\n", templateArguments);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//classInstance->hasReflection = true;
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if( strcmp( nextToken, "extends" ) == 0 ) {
|
||
|
|
|
||
|
|
int nextKey = lexer_getKey( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
|
||
|
|
char * className = text_slice( source, key + 5, nextKey - 1 );
|
||
|
|
|
||
|
|
classInstance->className = text_removeWhiteSpaces( className );
|
||
|
|
|
||
|
|
|
||
|
|
char * extendsText = text_slice( source, nextKey + 7, bodyOpenIndex - 1 );
|
||
|
|
|
||
|
|
char * extendsTextCopy = text_copy( extendsText );
|
||
|
|
|
||
|
|
classInstance->extends = text_split( extendsTextCopy, "," );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
classInstance->extends = array_new();
|
||
|
|
|
||
|
|
char * className = text_slice( source, key + 5, bodyOpenIndex - 1 );
|
||
|
|
|
||
|
|
classInstance->className = text_removeWhiteSpaces( className );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
classInstance->properties = array_new();
|
||
|
|
|
||
|
|
classInstance->methods = array_new();
|
||
|
|
|
||
|
|
classInstance->classIndex = globalClassIndex++;
|
||
|
|
|
||
|
|
|
||
|
|
printf( " class %s{}\n", classInstance->className );
|
||
|
|
|
||
|
|
array_add( classesArray, classInstance );
|
||
|
|
|
||
|
|
array_add( allClasses, classInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composeFunctionArguments( struct functionLayout * currentFunction, struct text * methodSource, struct text * classHeader ) {
|
||
|
|
|
||
|
|
struct array * arguments = currentFunction->arguments;
|
||
|
|
|
||
|
|
int argumentCount = array_length( arguments );
|
||
|
|
|
||
|
|
for (int j = 0; j < argumentCount; ++j)
|
||
|
|
{
|
||
|
|
char * argumentText = (char *) array_get( currentFunction->arguments, j );
|
||
|
|
|
||
|
|
text_append( methodSource, argumentText );
|
||
|
|
|
||
|
|
text_append( classHeader, text_copy( argumentText ) );
|
||
|
|
|
||
|
|
if( j != argumentCount-1 ) {
|
||
|
|
|
||
|
|
text_append( methodSource, ", " );
|
||
|
|
|
||
|
|
text_append( classHeader, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composeFunction( struct functionLayout * currentFunction, struct array * sourceArray, struct text * classHeader ) {
|
||
|
|
|
||
|
|
struct codeBundle * code = malloc( sizeof( struct codeBundle ) );
|
||
|
|
|
||
|
|
struct text * methodSource = text_new( "" );
|
||
|
|
|
||
|
|
text_append( methodSource, currentFunction->declarationText );
|
||
|
|
|
||
|
|
text_append( classHeader, currentFunction->declarationText );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( methodSource, "( ");
|
||
|
|
|
||
|
|
text_append( classHeader, "( ");
|
||
|
|
|
||
|
|
|
||
|
|
file_composeFunctionArguments( currentFunction, methodSource, classHeader );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( classHeader, " );\n\n" );
|
||
|
|
|
||
|
|
text_append( methodSource, " ) {" );
|
||
|
|
|
||
|
|
text_append( methodSource, currentFunction->body );
|
||
|
|
|
||
|
|
text_append( methodSource, "}" );
|
||
|
|
|
||
|
|
|
||
|
|
code->lineNumber = currentFunction->lineNumber;
|
||
|
|
|
||
|
|
code->sourceCode = methodSource->value;
|
||
|
|
|
||
|
|
array_add( sourceArray, code );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_composeFunctions( struct array * functions, struct array * sourceArray, struct text * classHeader ) {
|
||
|
|
|
||
|
|
int functionCount = array_length( functions );
|
||
|
|
|
||
|
|
for (int i = 0; i < functionCount; ++i)
|
||
|
|
{
|
||
|
|
struct functionLayout * currentFunction = array_get( functions, i );
|
||
|
|
|
||
|
|
file_composeFunction( currentFunction, sourceArray, classHeader );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int maxLineNumber = 0;
|
||
|
|
|
||
|
|
int sourceCount = array_length( sourceArray );
|
||
|
|
|
||
|
|
// align undefined line numbers for added function
|
||
|
|
|
||
|
|
for ( int i = 0; i < sourceCount; ++i )
|
||
|
|
{
|
||
|
|
struct codeBundle * code = array_get( sourceArray, i );
|
||
|
|
|
||
|
|
int afterBodyLineNumber = code->lineNumber + text_countLineBreaks( code->sourceCode, -1 );
|
||
|
|
|
||
|
|
if( afterBodyLineNumber > maxLineNumber ) {
|
||
|
|
|
||
|
|
maxLineNumber = afterBodyLineNumber;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
maxLineNumber += 2;
|
||
|
|
|
||
|
|
for (int i = 0; i < sourceCount; ++i)
|
||
|
|
{
|
||
|
|
struct codeBundle * code = array_get( sourceArray, i );
|
||
|
|
|
||
|
|
if( code->lineNumber == -1 ) {
|
||
|
|
|
||
|
|
code->lineNumber = maxLineNumber;
|
||
|
|
|
||
|
|
maxLineNumber += text_countLineBreaks( code->sourceCode, -1 );
|
||
|
|
|
||
|
|
maxLineNumber += 2;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
maxLineNumber += 12;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// this need to be in a separate file
|
||
|
|
|
||
|
|
void file_composeConfigInformation( struct array * files, struct application * applicationInstance ) {
|
||
|
|
|
||
|
|
int fileCount = array_length( files );
|
||
|
|
|
||
|
|
struct text * configurationHeader = text_new( "" );
|
||
|
|
|
||
|
|
struct text * configurationSource = text_new( "" );
|
||
|
|
|
||
|
|
|
||
|
|
int classesCount = array_length( allClasses );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationHeader, "#ifndef __" );
|
||
|
|
|
||
|
|
text_append( configurationHeader, "classConfiguration\n\n" );
|
||
|
|
|
||
|
|
text_append( configurationHeader, "#define __classConfiguration\n\n" );
|
||
|
|
|
||
|
|
text_append( configurationHeader, "#include <stddef.h>\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < fileCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct file * fileInstance = array_get( files, i );
|
||
|
|
|
||
|
|
char * path = fileInstance->path;
|
||
|
|
|
||
|
|
char * filename = fileInstance->filename;
|
||
|
|
|
||
|
|
if( array_length( fileInstance->classes ) > 0 ) {
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationHeader, "#include <" );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationHeader, path );
|
||
|
|
|
||
|
|
//text_append( configurationHeader, filename );
|
||
|
|
|
||
|
|
text_append( configurationHeader, ".h>\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationHeader, "#define TOTAL_CLASS_COUNT " );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationHeader, text_fromNumber(classesCount) );
|
||
|
|
|
||
|
|
text_append( configurationHeader, "\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "#include <classConfiguration.h>\n\n" );
|
||
|
|
|
||
|
|
text_append( configurationHeader, "extern char * __ClassNames[TOTAL_CLASS_COUNT];\n");
|
||
|
|
|
||
|
|
text_append( configurationHeader, "extern int __ClassPropertyCount[TOTAL_CLASS_COUNT];\n");
|
||
|
|
|
||
|
|
text_append( configurationHeader, "extern char * __ClassPropertyNames[TOTAL_CLASS_COUNT][30];\n");
|
||
|
|
|
||
|
|
text_append( configurationHeader, "extern int __ClassPropertyOffsets[TOTAL_CLASS_COUNT][30];\n");
|
||
|
|
|
||
|
|
text_append( configurationHeader, "extern int __ClassPropertyOffsets[TOTAL_CLASS_COUNT][30];\n");
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "char * __ClassNames[TOTAL_CLASS_COUNT] = { ");
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
if( i != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "\"" );
|
||
|
|
|
||
|
|
text_append( configurationSource, classInstance->className );
|
||
|
|
|
||
|
|
text_append( configurationSource, "\"" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " };\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "int __ClassMethodCount[TOTAL_CLASS_COUNT] = { ");
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
if( i != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( array_length( classInstance->methods ) ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " };\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "int __ClassPropertyCount[TOTAL_CLASS_COUNT] = { ");
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
if( i != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( array_length( classInstance->properties ) ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " };\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "char * __ClassPropertyNames[TOTAL_CLASS_COUNT][30] = {\n");
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
if( i != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", \n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct array * properties = classInstance->properties;
|
||
|
|
|
||
|
|
int propertyCount = array_length( properties );
|
||
|
|
|
||
|
|
text_append( configurationSource, "\t\t\t\t\t\t\t\t\t\t\t\t\t\t{");
|
||
|
|
|
||
|
|
if( propertyCount == 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int j = 0; j < propertyCount; ++j)
|
||
|
|
{
|
||
|
|
struct property * currentProperty = array_get( properties, j );
|
||
|
|
|
||
|
|
if( j != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " \"" );
|
||
|
|
|
||
|
|
text_append( configurationSource, currentProperty->propertyName );
|
||
|
|
|
||
|
|
text_append( configurationSource, "\" " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "}");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "\n\t\t\t\t\t\t\t\t\t\t\t\t\t};\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "char * __ClassMethodNames[TOTAL_CLASS_COUNT][30] = {\n");
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
if( i != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", \n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct array * methods = classInstance->methods;
|
||
|
|
|
||
|
|
int methodCount = array_length( methods );
|
||
|
|
|
||
|
|
text_append( configurationSource, "\t\t\t\t\t\t\t\t\t\t\t\t\t\t{");
|
||
|
|
|
||
|
|
if( methodCount == 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int j = 0; j < methodCount; ++j)
|
||
|
|
{
|
||
|
|
struct method * currentMethod = array_get( methods, j );
|
||
|
|
|
||
|
|
if( j != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " \"" );
|
||
|
|
|
||
|
|
text_append( configurationSource, currentMethod->methodName );
|
||
|
|
|
||
|
|
text_append( configurationSource, "\" " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "}");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "\n\t\t\t\t\t\t\t\t\t\t\t\t\t};\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "int __ClassPropertyOffsets[TOTAL_CLASS_COUNT][30] = {\n");
|
||
|
|
|
||
|
|
int index = 0;
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
if( classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
if( index != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", \n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
index++;
|
||
|
|
|
||
|
|
struct array * properties = classInstance->properties;
|
||
|
|
|
||
|
|
int propertyCount = array_length( properties );
|
||
|
|
|
||
|
|
text_append( configurationSource, "\t\t\t\t\t\t\t\t\t\t\t\t\t\t{");
|
||
|
|
|
||
|
|
if( propertyCount == 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int j = 0; j < propertyCount; ++j)
|
||
|
|
{
|
||
|
|
struct property * currentProperty = array_get( properties, j );
|
||
|
|
|
||
|
|
if( strcmp( currentProperty->type, "function" ) == 0 ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( j != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " offsetof( ");
|
||
|
|
|
||
|
|
text_append( configurationSource, className);
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
text_append( configurationSource, currentProperty->propertyName );
|
||
|
|
|
||
|
|
text_append( configurationSource, " )" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "}");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "\n\t\t\t\t\t\t\t\t\t\t\t\t\t};\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "int __ClassPropertyDatatypeIndices[TOTAL_CLASS_COUNT][30] = {\n");
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
if( i != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", \n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct array * properties = classInstance->properties;
|
||
|
|
|
||
|
|
int propertyCount = array_length( properties );
|
||
|
|
|
||
|
|
text_append( configurationSource, "\t\t\t\t\t\t\t\t\t\t\t\t\t\t{");
|
||
|
|
|
||
|
|
if( propertyCount == 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int j = 0; j < propertyCount; ++j)
|
||
|
|
{
|
||
|
|
struct property * currentProperty = array_get( properties, j );
|
||
|
|
|
||
|
|
if( j != 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//text_append( configurationSource, "\"");
|
||
|
|
|
||
|
|
/*
|
||
|
|
* char : -3
|
||
|
|
* char * : -2
|
||
|
|
* short : -4
|
||
|
|
* int : -5
|
||
|
|
* long : -6
|
||
|
|
*/
|
||
|
|
|
||
|
|
if( strcmp( currentProperty->datatype, "char" ) == 0 ) {
|
||
|
|
|
||
|
|
if( currentProperty->isPointer == 1 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( -3 ) );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( -2 ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
} else if( strcmp( currentProperty->datatype, "short" ) == 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( -4 ) );
|
||
|
|
|
||
|
|
} else if( strcmp( currentProperty->datatype, "int" ) == 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( -5 ) );
|
||
|
|
|
||
|
|
} else if( strcmp( currentProperty->datatype, "long" ) == 0 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( -6 ) );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
|
||
|
|
struct class * datatypeClass = application_getClassByClassName( allClasses, currentProperty->datatype );
|
||
|
|
|
||
|
|
if( datatypeClass != NULL ) {
|
||
|
|
|
||
|
|
//printf("-------------------------- classIndex: %i\n" ,datatypeClass->classIndex);
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( datatypeClass->classIndex ) );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( 1 ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//text_append( configurationSource, currentProperty->datatype );//text_fromNumber( datatypeClass->classIndex ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//text_append( configurationSource, "\"" );
|
||
|
|
|
||
|
|
//text_append( configurationSource, currentProperty->propertyName );
|
||
|
|
|
||
|
|
//text_append( configurationSource, " )" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "}");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, "\n\t\t\t\t\t\t\t\t\t\t\t\t\t};\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "void getArrayByClassIndex( int size, void * * voidArray, int * structByteSize, int classIndex ) {\n\n" );
|
||
|
|
|
||
|
|
//text_append( configurationSource, " struct user * array;\n\n" );
|
||
|
|
|
||
|
|
text_append( configurationSource, " switch( classIndex ) {\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
|
||
|
|
if( classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
if( strcmp( className, "char") == 0 ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( className, "int") == 0 ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int classIndex = classInstance->classIndex;
|
||
|
|
|
||
|
|
text_append( configurationSource, " case " );
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( classIndex ) );
|
||
|
|
|
||
|
|
text_append( configurationSource, ":\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " voidArray = ( void ** ) ( struct " );
|
||
|
|
|
||
|
|
text_append( configurationSource, className );
|
||
|
|
|
||
|
|
text_append( configurationSource, " * ) malloc( sizeof( struct " );
|
||
|
|
|
||
|
|
text_append( configurationSource, className );
|
||
|
|
|
||
|
|
text_append( configurationSource, " ) * size );\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " *structByteSize = sizeof( struct " );
|
||
|
|
|
||
|
|
text_append( configurationSource, className );
|
||
|
|
|
||
|
|
text_append( configurationSource, " );\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " break;\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " }\n\n" );
|
||
|
|
|
||
|
|
//text_append( configurationSource, " voidArray = ( void ** ) array;\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "}\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "void callMethodOfClass( int classIndex, int methodIndex, void * object ) {\n\n" );
|
||
|
|
|
||
|
|
//text_append( configurationSource, " struct user * array;\n\n" );
|
||
|
|
|
||
|
|
text_append( configurationSource, " switch( classIndex ) {\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( allClasses, i );
|
||
|
|
|
||
|
|
if( classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
if( strcmp( className, "char") == 0 ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( className, "int") == 0 ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int classIndex = classInstance->classIndex;
|
||
|
|
|
||
|
|
text_append( configurationSource, " case " );
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( classIndex ) );
|
||
|
|
|
||
|
|
text_append( configurationSource, ":\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " switch( methodIndex ) {\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
array * methods = classInstance->methods;
|
||
|
|
|
||
|
|
int methodsCount = array_length( methods );
|
||
|
|
|
||
|
|
|
||
|
|
if( methodsCount > 0 ) {
|
||
|
|
|
||
|
|
for (int methodIndex = 0; methodIndex < methodsCount; ++methodIndex)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct method * currentMethod = array_get( methods, methodIndex );
|
||
|
|
|
||
|
|
|
||
|
|
if( array_length( currentMethod->arguments ) == 1 ) {
|
||
|
|
|
||
|
|
text_append( configurationSource, " case " );
|
||
|
|
|
||
|
|
text_append( configurationSource, text_fromNumber( methodIndex ) );
|
||
|
|
|
||
|
|
text_append( configurationSource, ":\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " " );
|
||
|
|
|
||
|
|
text_append( configurationSource, className );
|
||
|
|
|
||
|
|
text_append( configurationSource, "_" );
|
||
|
|
|
||
|
|
text_append( configurationSource, currentMethod->methodName );
|
||
|
|
|
||
|
|
text_append( configurationSource, "( object );\n\n" );
|
||
|
|
|
||
|
|
text_append( configurationSource, " break;\n\n " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " }\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, " break;\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( configurationSource, " }\n\n" );
|
||
|
|
|
||
|
|
//text_append( configurationSource, " voidArray = ( void ** ) array;\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, "}\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
int __ClassPropertyCount[4] =
|
||
|
|
{
|
||
|
|
4, 6
|
||
|
|
};
|
||
|
|
*/
|
||
|
|
|
||
|
|
//text_append( configurationHeader, "int");
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < fileCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct file * fileInstance = array_get( files, i );
|
||
|
|
|
||
|
|
char * filename = fileInstance->filename;
|
||
|
|
|
||
|
|
char * source = fileInstance->source;
|
||
|
|
|
||
|
|
struct array * classesArray = fileInstance->classes;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * header = fileSystem_readFile( "../source/configuration.h" );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationHeader, header );
|
||
|
|
|
||
|
|
text_append( configurationHeader, "#endif\n" );
|
||
|
|
|
||
|
|
|
||
|
|
char * filePath = file_composePath( applicationInstance->output, "classConfiguration", "h" );
|
||
|
|
|
||
|
|
|
||
|
|
fileSystem_writeFile( filePath, configurationHeader->value );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * functions = fileSystem_readFile( "../source/configuration.c" );
|
||
|
|
|
||
|
|
|
||
|
|
filePath = file_composePath( applicationInstance->output, "classConfiguration", "c" );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( configurationSource, functions );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
fileSystem_writeFile( filePath, configurationSource->value );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// end
|
||
|
|
|
||
|
|
char * file_composePath( char * path, char * filename, char * extension ) {
|
||
|
|
|
||
|
|
char * filePath = malloc(1000);
|
||
|
|
|
||
|
|
filePath[0] = 0;
|
||
|
|
|
||
|
|
strcat( filePath, path );
|
||
|
|
|
||
|
|
strcat( filePath, filename );
|
||
|
|
|
||
|
|
strcat( filePath, "." );
|
||
|
|
|
||
|
|
strcat( filePath, extension );
|
||
|
|
|
||
|
|
return filePath;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composeNewPointerFunction( struct text * finalSourceCode, int hasConstructor, struct array * constructorArguments, struct class * classInstance ) {
|
||
|
|
|
||
|
|
//char * contructorArgumentsText = text_join( constructorArguments, "," );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, classInstance->className );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " * " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, classInstance->className );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "_newPointer(" );
|
||
|
|
|
||
|
|
//text_append( finalSourceCode, contructorArgumentsText );
|
||
|
|
|
||
|
|
int count = array_length( constructorArguments );
|
||
|
|
|
||
|
|
for (int i = 1; i < count; ++i)
|
||
|
|
{
|
||
|
|
char * argument = text_removeWhiteSpaces( array_get( constructorArguments, i ) );
|
||
|
|
|
||
|
|
if( i > 1 ) {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, argument );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ") {\n\n" );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " struct " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, classInstance->className );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " * pointer = malloc( sizeof ( struct " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, classInstance->className );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " ) );\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
file_composePropertieInitiations( finalSourceCode, 1, classInstance );
|
||
|
|
|
||
|
|
if( hasConstructor == 1 ) {
|
||
|
|
|
||
|
|
file_composeConstructorCall( finalSourceCode, classInstance->className, constructorArguments, -1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " return pointer;\n\n" );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "}\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_composeConstructorCall( struct text * finalSourceCode, char * className, struct array * constructorArguments, int usePointer ) {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, className );
|
||
|
|
|
||
|
|
if( usePointer == 1 ) {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "_constructor( &instance" );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "_constructor( pointer " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int argumentCount = array_length( constructorArguments );
|
||
|
|
|
||
|
|
for (int j = 1; j < argumentCount; ++j)
|
||
|
|
{
|
||
|
|
char * argumentText = ( char * ) array_get( constructorArguments, j );
|
||
|
|
|
||
|
|
struct array * argumentParts = text_split( argumentText, " \t" );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ", " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, array_get( argumentParts, array_length( argumentParts ) - 1 ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ");\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composePropertieInitiations( struct text * finalSourceCode, int usePointers, struct class * classInstance ) {
|
||
|
|
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
struct array * properties = classInstance->properties;
|
||
|
|
|
||
|
|
int classIndex = classInstance->classIndex;
|
||
|
|
|
||
|
|
int propertyLength = array_length( properties );
|
||
|
|
|
||
|
|
|
||
|
|
if( classInstance->hasReflection == true ) {
|
||
|
|
|
||
|
|
if( strcmp( className, "Hints" ) != 0 ) {
|
||
|
|
|
||
|
|
if( usePointers == 1 ) {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " pointer->__classIndex = " );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " instance.__classIndex = " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, text_fromNumber( classIndex ) );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ";\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < propertyLength; ++i)
|
||
|
|
{
|
||
|
|
struct property * currentProperty = array_get( properties, i );
|
||
|
|
|
||
|
|
if( currentProperty->hasValue == 1 ) {
|
||
|
|
|
||
|
|
char * propertyName = currentProperty->propertyName;
|
||
|
|
|
||
|
|
char * propertyValue = currentProperty->value;
|
||
|
|
|
||
|
|
if( usePointers == 1 ) {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " pointer->" );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " instance." );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, propertyName );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " = " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, currentProperty->value );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ";\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_composeNewFunction( struct text * finalSourceCode, int hasConstructor, struct array * constructorArguments, struct class * classInstance ) {
|
||
|
|
|
||
|
|
|
||
|
|
array * argumentsWithoutFirst = array_new();
|
||
|
|
|
||
|
|
int argumentCount = array_length( constructorArguments );
|
||
|
|
|
||
|
|
for (int i = 1; i < argumentCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * constructorArgument = array_get( constructorArguments, i );
|
||
|
|
|
||
|
|
array_add( argumentsWithoutFirst, constructorArgument );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * contructorArgumentsText = text_join( argumentsWithoutFirst, ", " );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( finalSourceCode, classInstance->className );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, classInstance->className );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "_new(" );
|
||
|
|
|
||
|
|
int count = array_length( constructorArguments );
|
||
|
|
|
||
|
|
for (int i = 1; i < count; ++i)
|
||
|
|
{
|
||
|
|
char * argument = text_removeWhiteSpaces( array_get( constructorArguments, i ) );
|
||
|
|
|
||
|
|
if( i > 1 ) {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, argument );
|
||
|
|
|
||
|
|
}
|
||
|
|
text_append( finalSourceCode, ") {\n\n" );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " " );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, classInstance->className );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " instance;\n\n" );
|
||
|
|
|
||
|
|
file_composePropertieInitiations( finalSourceCode, -1, classInstance );
|
||
|
|
|
||
|
|
if( hasConstructor == 1 ) {
|
||
|
|
|
||
|
|
file_composeConstructorCall( finalSourceCode, classInstance->className, constructorArguments, 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, " return instance;\n\n" );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "}\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composeNewFunctions( struct text * finalSourceCode, struct class * classInstance, int hasConstructor, struct array * constructorArguments ) {
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
struct array * properties = classInstance->properties;
|
||
|
|
|
||
|
|
int classIndex = classInstance->classIndex;
|
||
|
|
|
||
|
|
|
||
|
|
file_composeNewFunction( finalSourceCode, hasConstructor, constructorArguments, classInstance );
|
||
|
|
|
||
|
|
file_composeNewPointerFunction( finalSourceCode, hasConstructor, constructorArguments, classInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composeNewHeaderDeclerations( struct text * classHeader, char * className, struct array * contructorArguments ) {
|
||
|
|
|
||
|
|
text_append( classHeader, className );
|
||
|
|
|
||
|
|
text_append( classHeader, " " );
|
||
|
|
|
||
|
|
text_append( classHeader, className );
|
||
|
|
|
||
|
|
text_append( classHeader, "_new( " );
|
||
|
|
|
||
|
|
int count = array_length( contructorArguments );
|
||
|
|
|
||
|
|
for (int i = 1; i < count; ++i)
|
||
|
|
{
|
||
|
|
char * argument = text_removeWhiteSpaces( array_get( contructorArguments, i ) );
|
||
|
|
|
||
|
|
if( i > 1 ) {
|
||
|
|
|
||
|
|
text_append( classHeader, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( classHeader, argument );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//text_append( classHeader, ( contructorArgumentsText ) );
|
||
|
|
|
||
|
|
text_append( classHeader, " );\n\n" );
|
||
|
|
|
||
|
|
text_append( classHeader, className );
|
||
|
|
|
||
|
|
text_append( classHeader, " * " );
|
||
|
|
|
||
|
|
text_append( classHeader, className );
|
||
|
|
|
||
|
|
text_append( classHeader, "_newPointer( " );
|
||
|
|
|
||
|
|
for (int i = 1; i < count; ++i)
|
||
|
|
{
|
||
|
|
char * argument = text_removeWhiteSpaces( array_get( contructorArguments, i ) );
|
||
|
|
|
||
|
|
if( i > 1 ) {
|
||
|
|
|
||
|
|
text_append( classHeader, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( classHeader, argument );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//text_append( classHeader, text_copy( contructorArgumentsText ) );
|
||
|
|
|
||
|
|
text_append( classHeader, " );\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct array * file_getConstructorArguments( struct class * classInstance, int * hasConstructor ) {
|
||
|
|
|
||
|
|
struct array * constructorArguments = array_new();
|
||
|
|
|
||
|
|
int length = array_length( classInstance->methods );
|
||
|
|
|
||
|
|
for ( int j = 0; j < length; ++j )
|
||
|
|
{
|
||
|
|
struct method * currentMethod = ( struct method * ) array_get( classInstance->methods, j );
|
||
|
|
|
||
|
|
char * methodName = currentMethod->methodName;
|
||
|
|
|
||
|
|
if( strcmp( methodName, "constructor" ) == 0 ) {
|
||
|
|
|
||
|
|
constructorArguments = currentMethod->arguments;
|
||
|
|
|
||
|
|
*hasConstructor = 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return constructorArguments;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_composeClass( struct class * classInstance, struct text * classHeader, struct text * finalSourceCode ) {
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
int hasConstructor = -1;
|
||
|
|
|
||
|
|
int length = array_length( classInstance->methods );
|
||
|
|
|
||
|
|
struct array * constructorArguments = file_getConstructorArguments( classInstance, &hasConstructor );
|
||
|
|
|
||
|
|
//char * contructorArgumentsText = text_join( constructorArguments, "," );
|
||
|
|
|
||
|
|
//if( array_length( constructorArguments ) == 0 ) {
|
||
|
|
|
||
|
|
//contructorArgumentsText = " ";
|
||
|
|
|
||
|
|
//}
|
||
|
|
|
||
|
|
|
||
|
|
if( strcmp( className, "char" ) == 0 || strcmp( className, "int" ) == 0 ) {
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
file_composeNewHeaderDeclerations( classHeader, className, constructorArguments );
|
||
|
|
|
||
|
|
file_composeNewFunctions( finalSourceCode, classInstance, hasConstructor, constructorArguments );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_addLineBreaks( struct text * finalSourceCode, struct array * sourceArray ) {
|
||
|
|
|
||
|
|
int count = array_length( sourceArray );
|
||
|
|
|
||
|
|
for ( int i = 0; i < count; ++i )
|
||
|
|
{
|
||
|
|
struct codeBundle * code = array_get( sourceArray, i );
|
||
|
|
|
||
|
|
int currentLineBreaks = text_countLineBreaks( finalSourceCode->value, -1 );
|
||
|
|
|
||
|
|
int addingLinebreaks = code->lineNumber - currentLineBreaks;
|
||
|
|
|
||
|
|
//printf("adding linebreaks: %i\n", addingLinebreaks);
|
||
|
|
|
||
|
|
for (int j = 0; j < addingLinebreaks; ++j)
|
||
|
|
{
|
||
|
|
text_append( finalSourceCode, "\n" );
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, code->sourceCode );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_composeSourceHeader( struct text * finalSourceCode, char * filename ) {
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "/* \n * This file is automaticaly generated, Please dont edit this file! \n */\n" );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, "#include <" );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, filename );
|
||
|
|
|
||
|
|
text_append( finalSourceCode, ".h> \n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_writeAll( struct array * sourceArray, struct text * classHeader, char * filename, array * classesArray, array * globals, char * relativePath, struct application * applicationInstance ) {
|
||
|
|
|
||
|
|
|
||
|
|
struct text * finalSourceCode = text_new( "" );
|
||
|
|
|
||
|
|
int globalCount = array_length( globals );
|
||
|
|
|
||
|
|
for (int i = 0; i < globalCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct variable * variableInstance = array_get( globals, i );
|
||
|
|
|
||
|
|
struct array * sourceParts = text_split( text_copy( variableInstance->declaration ), " " );
|
||
|
|
|
||
|
|
struct text * declarationWithoutExtern = text_new( "" );
|
||
|
|
|
||
|
|
int sourcePartsLength = array_length( sourceParts );
|
||
|
|
|
||
|
|
for (int j = 0; j < sourcePartsLength; ++j)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * sourceCodePart = text_removeWhiteSpaces( ( char * ) array_get( sourceParts, j ) );
|
||
|
|
|
||
|
|
if( strcmp( sourceCodePart, "extern" ) != 0 ) {
|
||
|
|
|
||
|
|
text_append( declarationWithoutExtern, sourceCodePart );
|
||
|
|
|
||
|
|
text_append( declarationWithoutExtern, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct codeBundle * sourceCodeBundle = malloc( sizeof( struct codeBundle ) );
|
||
|
|
|
||
|
|
sourceCodeBundle->sourceCode = declarationWithoutExtern->value;
|
||
|
|
|
||
|
|
sourceCodeBundle->lineNumber = variableInstance->lineNumber;
|
||
|
|
|
||
|
|
array_add( sourceArray, sourceCodeBundle );
|
||
|
|
|
||
|
|
//struct text * declarationBeforeIS = text_new();
|
||
|
|
|
||
|
|
|
||
|
|
for (int j = 0; j < sourcePartsLength; ++j)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * sourceCodePart = text_removeWhiteSpaces( ( char * ) array_get( sourceParts, j ) );
|
||
|
|
|
||
|
|
if( strcmp( sourceCodePart, "=" ) == 0 ) {
|
||
|
|
|
||
|
|
text_append( classHeader, ";" );
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( classHeader, sourceCodePart );
|
||
|
|
|
||
|
|
text_append( classHeader, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( classHeader, "\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
method_sortLineNumbers( sourceArray );
|
||
|
|
|
||
|
|
file_composeSourceHeader( finalSourceCode, filename );
|
||
|
|
|
||
|
|
file_addLineBreaks( finalSourceCode, sourceArray );
|
||
|
|
|
||
|
|
|
||
|
|
int classesCount = array_length( classesArray );
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( classesArray, i );
|
||
|
|
|
||
|
|
if( i == 0 ) {
|
||
|
|
|
||
|
|
if( classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
file_composeClass( classInstance, classHeader, finalSourceCode );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( classHeader, "#endif\n" );
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct class * classInstance = array_get( classesArray, i );
|
||
|
|
|
||
|
|
char * className = classInstance->className;
|
||
|
|
|
||
|
|
if( strcmp( className, "char" ) != 0 && strcmp( className, "int" ) != 0 && strcmp( className, "void" ) != 0 ) {
|
||
|
|
|
||
|
|
class_composeTypedefStruct( classInstance, classHeader );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//char * path = "../application/target/";
|
||
|
|
|
||
|
|
char * filePath = file_composePath( applicationInstance->output, text_copy( relativePath ), "c" );
|
||
|
|
|
||
|
|
//printf("relativePath: '%s'\n", text_copy( filePath ));
|
||
|
|
|
||
|
|
fileSystem_ensureDirectory( text_copy( filePath ) );
|
||
|
|
|
||
|
|
fileSystem_writeFile( filePath, finalSourceCode->value );
|
||
|
|
|
||
|
|
printf(" writing source file: %s\n", filePath);
|
||
|
|
|
||
|
|
char * headerFilePath = file_composePath( applicationInstance->output, text_copy( relativePath ), "h" );
|
||
|
|
|
||
|
|
|
||
|
|
printf(" writing header file: %s\n\n", headerFilePath);
|
||
|
|
|
||
|
|
//classHeader->value[classHeader->length] = 0;
|
||
|
|
fileSystem_writeFile( headerFilePath, text_copy( classHeader->value ) );
|
||
|
|
|
||
|
|
text_free( classHeader );
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_parseFunctions( struct file * fileInstance, array * files ) {
|
||
|
|
|
||
|
|
struct array * functions = fileInstance->functions;
|
||
|
|
|
||
|
|
int functionsCount = array_length( functions );
|
||
|
|
|
||
|
|
for (int i = 0; i < functionsCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct functionLayout * functionInstance = array_get( functions, i );
|
||
|
|
|
||
|
|
printf(" %s() {\n\n", functionInstance->name);
|
||
|
|
|
||
|
|
|
||
|
|
int includeCount = array_length( fileInstance->includes );
|
||
|
|
|
||
|
|
for ( int k = 0; k < includeCount; ++k )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct include * includeInstance = array_get( fileInstance->includes, k );
|
||
|
|
|
||
|
|
char * currentInclude = includeInstance->path;
|
||
|
|
|
||
|
|
char * includeFileName = text_removeSlashFromStart( file_getFileNameFromInclude( currentInclude ) );
|
||
|
|
|
||
|
|
struct file * includedFile = file_getFileByFileName( files, includeFileName );
|
||
|
|
|
||
|
|
if( includedFile != NULL ) {
|
||
|
|
|
||
|
|
//printf(" ?? %s.c \n\n", includedFile->filename);
|
||
|
|
|
||
|
|
file_addVariablesFromFile( includedFile, functionInstance->variables );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int globalCount = array_length( fileInstance->globals );
|
||
|
|
|
||
|
|
for (int k = 0; k < globalCount; ++k)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct variable * globalVariableInstance = array_get( fileInstance->globals, k );
|
||
|
|
|
||
|
|
array_add( functionInstance->variables, globalVariableInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
functionInstance->body = method_parse( functionInstance->bodyOriginal, functionInstance->variables, fileInstance->functions );
|
||
|
|
|
||
|
|
printf(" }\n\n");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_parseMethods( struct file * fileInstance, array * files ) {
|
||
|
|
|
||
|
|
struct array * fileClasses = fileInstance->classes;
|
||
|
|
|
||
|
|
int classesCount = array_length( fileClasses );
|
||
|
|
|
||
|
|
for (int i = 0; i < classesCount; ++i)
|
||
|
|
{
|
||
|
|
struct class * classInstance = array_get( fileClasses, i );
|
||
|
|
|
||
|
|
printf(" class %s{\n\n", classInstance->className );
|
||
|
|
|
||
|
|
struct array * methods = classInstance->methods;
|
||
|
|
|
||
|
|
int methodsCount = array_length( methods );
|
||
|
|
|
||
|
|
for (int j = 0; j < methodsCount; ++j)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct method * methodInstance = array_get( methods, j );
|
||
|
|
|
||
|
|
printf(" %s() {\n\n", methodInstance->methodName);
|
||
|
|
|
||
|
|
int includeCount = array_length( fileInstance->includes );
|
||
|
|
|
||
|
|
for ( int k = 0; k < includeCount; ++k )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct include * includeInstance = array_get( fileInstance->includes, k );
|
||
|
|
|
||
|
|
char * currentInclude = includeInstance->path;
|
||
|
|
|
||
|
|
char * includeFileName = text_removeSlashFromStart( file_getFileNameFromInclude( currentInclude ) );
|
||
|
|
|
||
|
|
struct file * includedFile = file_getFileByFileName( files, includeFileName );
|
||
|
|
|
||
|
|
if( includedFile != NULL ) {
|
||
|
|
|
||
|
|
//printf(" %s.c \n\n", includedFile->filename);
|
||
|
|
|
||
|
|
file_addVariablesFromFile( includedFile, methodInstance->variables );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("\n\n");
|
||
|
|
|
||
|
|
file_addVariablesFromFile( fileInstance, methodInstance->variables );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//methodInstance->body = methodInstance->bodyOriginal;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//if( !classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
methodInstance->body = method_parse( methodInstance->bodyOriginal, methodInstance->variables, fileInstance->functions );
|
||
|
|
|
||
|
|
//}
|
||
|
|
|
||
|
|
printf(" }\n\n");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
printf(" }\n\n" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void file_addVariablesFromFile( struct file * fileInstance, struct array * variables ) {
|
||
|
|
|
||
|
|
int globalCount = array_length( fileInstance->globals );
|
||
|
|
|
||
|
|
//printf("add variables from file %i\n\n\n", globalCount);
|
||
|
|
|
||
|
|
for (int k = 0; k < globalCount; ++k)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct variable * globalVariableInstance = array_get( fileInstance->globals, k );
|
||
|
|
|
||
|
|
//printf(" - Adding variable from file: '%s' \n", globalVariableInstance->variableName );
|
||
|
|
|
||
|
|
array_add( variables, globalVariableInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_getBaseNameFromFileName( char * filename ) {
|
||
|
|
|
||
|
|
struct array * fileParts = text_split( filename, "." );
|
||
|
|
|
||
|
|
return array_get( fileParts, 0 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_getPathFrom( char * filename ) {
|
||
|
|
|
||
|
|
struct array * fileParts = text_split( filename, "." );
|
||
|
|
|
||
|
|
return array_get( fileParts, 0 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int libcFileCount = 293;
|
||
|
|
|
||
|
|
|
||
|
|
char * libcFileNames[293] = {"stdlib","stdlib","math","time","time","math","assert","math","math","stdlib","stdlib","stdlib","stdlib","nwchar","stdlib","nl_types","nl_types","nl_types","math","stdio","time","math","math","time","time","time","time","time","time","stdlib","math","io","math","stdlib","math","math","stdio","stdio","stdio","stdio","stdio","stdio","stdio","stdio","nwchar","nwchar","stdio","math","math","stdio","stdio","stdio","stdio","stdio","stdio","stdio","stdlib","stdio","math","stdio","stdio","stdio","stdio","nwchar","nwchar","stdio","nwchar","math","stdio","stdio","stdlib","stdio","nwchar","wchar","time","time","time","time","math","ctype","ctype","ctype","ctype","ctype","ctype","ctype","ctype","ctype","ctype","ctype","ctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","wctype","math","math","math","stdlib","math","stdlib","locale","time","time","time","time","math","math","setjmp","stdlib","stdlib","wchar","wchar","wchar","wchar","stdlib","stdlib","string","string","string","string","string","time","time","math","math","math","math","math","langinfo","stdio","math","stdio","stdio","stdio","stdlib","stdio","nwchar","wchar","stdlib","math","math","math","math","math","math","math","math","math","signal","stdlib","stdlib","stdlib","regex","regex","regex","regex","stdio","stdio","stdio","stdio","stdio","setjmp","locale","stdio","signal","math","math","stdio","stdio","math","stdlib","stdio","strings","string","string","string","string","string","string","string","wchar","time","string","strings","string","string","string","string","time","string","string","string","stdlib","stdlib","stdlib","stdlib","stdlib","string","string","stdlib","stdlib","stdlib","string","wchar","wchar","stdlib","math","math","time","time","stdio","stdio","ctype","ctype","ctype","wctype","wctype","wctype","stdio","stdio","stdarg","stdarg","stdarg","stdarg","stdio stdarg","stdio stdarg ","nwchar","stdio stdarg ","stdio stdarg","stdio stdarg ","stdio stdarg","stdio","stdio stdarg ","nwchar","stdio wchar ","nwchar","stdio wchar ","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","locale","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","stdlib","wchar","wchar","nwchar","stdlib","wctype","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","wchar","math","math","math"};
|
||
|
|
|
||
|
|
|
||
|
|
int file_isLibCFileName( char * baseName ) {
|
||
|
|
|
||
|
|
for (int i = 0; i < 293; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * libcFileName = libcFileNames[i] ;
|
||
|
|
|
||
|
|
char * libcBaseName = libcFileName;
|
||
|
|
|
||
|
|
if( strcmp( baseName, libcBaseName ) == 0 ) {
|
||
|
|
|
||
|
|
//printf("skip libc file: %s\n\n", libcBaseName);
|
||
|
|
|
||
|
|
return 1.0;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int file_hasLoadedFileName( char * fileName, struct array * loadedFileNames ) {
|
||
|
|
|
||
|
|
int loadedFileNamesCount = array_length( loadedFileNames );
|
||
|
|
|
||
|
|
for (int i = 0; i < loadedFileNamesCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * currentLoadedFileName = array_get( loadedFileNames, i );
|
||
|
|
|
||
|
|
if ( strcmp( currentLoadedFileName, fileName ) == 0 )
|
||
|
|
{
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * file_getFileNameFromInclude( char * include ) {
|
||
|
|
|
||
|
|
int openIndex = text_indexOff( include, "<", -1 );
|
||
|
|
|
||
|
|
int closeIndex = -1;
|
||
|
|
|
||
|
|
if( openIndex > 0 ) {
|
||
|
|
|
||
|
|
closeIndex = text_indexOff( include, ">", -1 );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
openIndex = text_indexOff( include, "\"", -1 );
|
||
|
|
|
||
|
|
closeIndex = text_indexOff( include, "\"", openIndex + 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * fileName = text_slice( include, openIndex + 1, closeIndex - 1 );
|
||
|
|
|
||
|
|
struct array * fileNameParts = text_split( text_copy( fileName ), "." );
|
||
|
|
|
||
|
|
|
||
|
|
return array_get( fileNameParts, 0 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct file * file_getFileByFileName( struct array * files, char * includeFileName ) {
|
||
|
|
|
||
|
|
int fileCount = array_length( files );
|
||
|
|
|
||
|
|
for (int i = 0; i < fileCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct file * fileInstance = array_get( files, i );
|
||
|
|
|
||
|
|
//printf("searching for file: %s \n\n", includeFileName);
|
||
|
|
|
||
|
|
if( strcmp( fileInstance->filename, includeFileName ) == 0 ) {
|
||
|
|
|
||
|
|
return fileInstance;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * file_extractInclude( struct file * fileInstance, char * source, lexer * currentLexer, int key, int i ) {
|
||
|
|
|
||
|
|
int nextKey = lexer_getKey( currentLexer, i + 2 );
|
||
|
|
|
||
|
|
int keyAfterWord = text_extractIndexAfterWord( source, key + 8 );
|
||
|
|
|
||
|
|
char * includeFileName = text_slice( source, key, keyAfterWord + 2);
|
||
|
|
|
||
|
|
|
||
|
|
struct include * includeInstance = include_new();
|
||
|
|
|
||
|
|
includeInstance->path = includeFileName;
|
||
|
|
|
||
|
|
includeInstance->enabled = true;
|
||
|
|
|
||
|
|
array_add( fileInstance->includes, includeInstance );
|
||
|
|
|
||
|
|
// printf("Add include: %s\n", includeInstance->path);
|
||
|
|
|
||
|
|
int numberOfCharacters = ( keyAfterWord + 2 ) - key;
|
||
|
|
|
||
|
|
|
||
|
|
struct text * includeReplacement = text_new( "" );
|
||
|
|
|
||
|
|
for ( int i = 0; i < numberOfCharacters + 1; ++i )
|
||
|
|
{
|
||
|
|
|
||
|
|
text_append( includeReplacement, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return text_replaceAt( key, keyAfterWord + 3, source, includeReplacement->value );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_eraseDefine( char * source, int key, int lineBreakIndex ) {
|
||
|
|
|
||
|
|
for (int i = key; i < lineBreakIndex; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
source[i] = ( char ) 32;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_extractDefine( struct file * fileInstance, char * source, int key, int i ) {
|
||
|
|
|
||
|
|
int lineBreakIndex = text_findNextLineBreak( source, key );
|
||
|
|
|
||
|
|
char * macro = text_slice( source, key, lineBreakIndex );
|
||
|
|
|
||
|
|
int numberOfCharacters = ( lineBreakIndex + 2 ) - key;
|
||
|
|
|
||
|
|
array_add( fileInstance->macros, macro );
|
||
|
|
|
||
|
|
|
||
|
|
source = file_eraseDefine( source, key, lineBreakIndex );
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_extractMacros( struct file * fileInstance ) {
|
||
|
|
|
||
|
|
char * source = fileInstance->source;
|
||
|
|
|
||
|
|
|
||
|
|
fileInstance->includes = array_new();
|
||
|
|
|
||
|
|
fileInstance->globals = array_new();
|
||
|
|
|
||
|
|
fileInstance->macros = array_new();
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
//printf("Source: %s\n", source);
|
||
|
|
|
||
|
|
|
||
|
|
lexer_getTokens( currentLexer, source );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
int bodyCloseIndex = -1;
|
||
|
|
|
||
|
|
int depth = 0;
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
//printf("Token: %s\n", token);
|
||
|
|
|
||
|
|
if ( strcmp( token, "{" ) == 0 ) {
|
||
|
|
|
||
|
|
depth++;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "}" ) == 0 ) {
|
||
|
|
|
||
|
|
depth--;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( depth == 0 ) {
|
||
|
|
|
||
|
|
if ( strcmp( token, "#" ) == 0 ) {
|
||
|
|
|
||
|
|
// #macroname
|
||
|
|
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( source, key );
|
||
|
|
|
||
|
|
char * macroName = text_removeWhiteSpaces( text_slice( source, (int) key +1 ,keyAfterMethod - 1) );
|
||
|
|
|
||
|
|
|
||
|
|
//printf( "%s: %i:", token, (int)key );
|
||
|
|
|
||
|
|
//printf("macro: %s \n", macroName);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( macroName, "include" ) == 0 ) {
|
||
|
|
|
||
|
|
source = file_extractInclude( fileInstance, source, currentLexer, key, i );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( macroName, "define" ) == 0 ) {
|
||
|
|
|
||
|
|
source = file_extractDefine( fileInstance, source, key, i );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
fileInstance->source = source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * file_getSource( char * filename ) {
|
||
|
|
|
||
|
|
char sourceFilePath[200] = "";
|
||
|
|
|
||
|
|
strcat( sourceFilePath, "../application/source/" );
|
||
|
|
|
||
|
|
strcat( sourceFilePath, filename);
|
||
|
|
|
||
|
|
strcat( sourceFilePath, ".c" );
|
||
|
|
|
||
|
|
char * source = fileSystem_readFile( sourceFilePath );
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * file_removeExtensionFromFileName( char * path ) {
|
||
|
|
/*
|
||
|
|
struct array * fileParts = text_split( text_copy( path ), "." );
|
||
|
|
|
||
|
|
int count = array_length( fileParts );
|
||
|
|
|
||
|
|
if( count > 1 ) {
|
||
|
|
|
||
|
|
array_delete( fileParts, count-1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
char * pathWithoutExtension = "";
|
||
|
|
|
||
|
|
char * base = basename( text_copy( path ) );
|
||
|
|
|
||
|
|
char * dir = dirname( text_copy( path ) );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
pathWithoutExtension = text_concatenate( pathWithoutExtension, dir );
|
||
|
|
|
||
|
|
pathWithoutExtension = text_concatenate( pathWithoutExtension, "/" );
|
||
|
|
|
||
|
|
pathWithoutExtension = text_concatenate( pathWithoutExtension, base );
|
||
|
|
|
||
|
|
if( pathWithoutExtension[0] == '.' && pathWithoutExtension[1] == '/' ) {
|
||
|
|
|
||
|
|
// shift pointer
|
||
|
|
pathWithoutExtension += 2;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int count = strlen( pathWithoutExtension );
|
||
|
|
|
||
|
|
for (int i = 0; i < count; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
if( pathWithoutExtension[count - i ] == 46 ) {
|
||
|
|
|
||
|
|
pathWithoutExtension[ count - i ] = 0;
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( pathWithoutExtension[count - i ] == 47 ) {
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return pathWithoutExtension;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * file_getFileNameFromIncludeFixed( char * include ) {
|
||
|
|
|
||
|
|
int openIndex = text_indexOff( include, "<", -1 );
|
||
|
|
|
||
|
|
int closeIndex = -1;
|
||
|
|
|
||
|
|
if( openIndex > 0 ) {
|
||
|
|
|
||
|
|
closeIndex = text_indexOff( include, ">", -1 );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
openIndex = text_indexOff( include, "\"", -1 );
|
||
|
|
|
||
|
|
closeIndex = text_indexOff( include, "\"", openIndex + 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * fileName = text_slice( include, openIndex + 1, closeIndex - 1 );
|
||
|
|
|
||
|
|
return fileName;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * resolve( char * path )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct array * pathParts = text_split( path, "/" );
|
||
|
|
|
||
|
|
int partsCount = array_length( pathParts );
|
||
|
|
|
||
|
|
array * validParts = array_new();
|
||
|
|
|
||
|
|
for (int i = 0; i < partsCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * currentPart = array_get( pathParts, i );
|
||
|
|
|
||
|
|
if( strcmp( currentPart, ".." ) == NULL ) {
|
||
|
|
|
||
|
|
array_pop( validParts );
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( currentPart, "." ) == NULL ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
array_add( validParts, currentPart );
|
||
|
|
|
||
|
|
//printf("currentPart: %s\n", currentPart);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * joinedText = text_join( validParts, "/" );
|
||
|
|
|
||
|
|
int lastCharacterIndex = strlen( path ) - 1;
|
||
|
|
|
||
|
|
text * finalPath = text_new("");
|
||
|
|
|
||
|
|
if( path[ 0 ] == 47 ) {
|
||
|
|
|
||
|
|
text_append( finalPath, "/" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( finalPath, joinedText );
|
||
|
|
|
||
|
|
if( path[ lastCharacterIndex ] == 47 ) {
|
||
|
|
|
||
|
|
text_append( finalPath, "/" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return finalPath->value;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void file_loadUnloadedFiles( struct array * unloadedFileNames, struct array * loadedFileNames, char * path ) {
|
||
|
|
|
||
|
|
|
||
|
|
char * parentPath = dirname( text_copy( path ) );
|
||
|
|
|
||
|
|
|
||
|
|
struct file * fileInstance = malloc( sizeof( struct file ) );
|
||
|
|
|
||
|
|
fileInstance->path = file_removeExtensionFromFileName( path );
|
||
|
|
|
||
|
|
fileInstance->source = file_getSource(fileInstance->path );
|
||
|
|
|
||
|
|
printf(":: %s\n", fileInstance->path );
|
||
|
|
|
||
|
|
|
||
|
|
if( array_length( loadedFileNames ) == 0 ) {
|
||
|
|
|
||
|
|
array_add( loadedFileNames, fileInstance->path );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
file_extractMacros( fileInstance );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int includeCount = array_length( fileInstance->includes );
|
||
|
|
|
||
|
|
|
||
|
|
//printf("include count: %i\n", includeCount);
|
||
|
|
|
||
|
|
for ( int k = 0; k < includeCount; ++k )
|
||
|
|
{
|
||
|
|
|
||
|
|
struct include * includeInstance = array_get( fileInstance->includes, k );
|
||
|
|
|
||
|
|
char * currentInclude = includeInstance->path;
|
||
|
|
|
||
|
|
char * includeFileName = file_getFileNameFromIncludeFixed( currentInclude );
|
||
|
|
|
||
|
|
char * includeFileBaseName = file_removeExtensionFromFileName( includeFileName );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if( file_isLibCFileName( includeFileBaseName ) ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int charCount = strlen( includeFileBaseName );
|
||
|
|
|
||
|
|
//printf("includeFileBaseName: %s\n", includeFileBaseName);
|
||
|
|
|
||
|
|
|
||
|
|
struct text * pathFromApplication = text_new( "" );
|
||
|
|
|
||
|
|
text_append( pathFromApplication, parentPath );
|
||
|
|
|
||
|
|
text_append( pathFromApplication, "/" );
|
||
|
|
|
||
|
|
text_append( pathFromApplication, includeFileBaseName );
|
||
|
|
|
||
|
|
|
||
|
|
struct text * relativeFilePath = text_new( "../application/source/" );
|
||
|
|
|
||
|
|
text_append( relativeFilePath, resolve( pathFromApplication->value ) );
|
||
|
|
|
||
|
|
text_append( relativeFilePath, ".c" );
|
||
|
|
|
||
|
|
char * absolutePath = realpath( relativeFilePath->value, NULL );
|
||
|
|
|
||
|
|
//printf("relativeFromWorkingDirectory: %s %s\n", absolutePath, relativeFilePath->value);
|
||
|
|
|
||
|
|
if( absolutePath == NULL ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * relativeFromWorkingDirectory = resolve( pathFromApplication->value );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if( file_hasLoadedFileName( relativeFromWorkingDirectory, loadedFileNames ) == 1 ) {
|
||
|
|
|
||
|
|
continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( fileSystem_exists( relativeFilePath->value ) ) {
|
||
|
|
|
||
|
|
array_add( loadedFileNames, relativeFromWorkingDirectory );
|
||
|
|
|
||
|
|
|
||
|
|
file_loadUnloadedFiles( unloadedFileNames, loadedFileNames, resolve( pathFromApplication->value ) );
|
||
|
|
|
||
|
|
//printf("file exists\n\n");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
struct text * testText = text_new( "../application/source/" );
|
||
|
|
|
||
|
|
char * relativePath = dirname( text_copy( includeFileBaseName ) );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( testText, ".c" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * absolutePath = realpath( "../application/source/", NULL );
|
||
|
|
|
||
|
|
|
||
|
|
struct text * test2 = text_new( "../application/source/" );
|
||
|
|
|
||
|
|
text_append( test2, parentPath );
|
||
|
|
|
||
|
|
text_append( test2, "/" );
|
||
|
|
|
||
|
|
//text_append( test2, relativePath );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * realTest = realpath( test2->value, NULL );
|
||
|
|
|
||
|
|
|
||
|
|
printf(" --- '%s' '%s' \n", text_copy( includeFileBaseName ),realTest);
|
||
|
|
|
||
|
|
|
||
|
|
if( fileSystem_exists( realTest ) ) {
|
||
|
|
|
||
|
|
struct text * currentFullFileName = text_new( realTest );
|
||
|
|
|
||
|
|
text_append( currentFullFileName, "/" );
|
||
|
|
|
||
|
|
text_append( currentFullFileName, includeFileBaseName );
|
||
|
|
|
||
|
|
text_append( currentFullFileName, ".c" );
|
||
|
|
|
||
|
|
char * goodAbsoluteFilePath = realpath( currentFullFileName->value, NULL );
|
||
|
|
|
||
|
|
printf(" currentFullFileName: %s \n", goodAbsoluteFilePath );
|
||
|
|
|
||
|
|
file_loadUnloadedFiles( unloadedFileNames, loadedFileNames, goodAbsoluteFilePath );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
printf("\nthis file does not exists %s\n\n", testText->value);
|
||
|
|
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|