void debugDumpAstSubTreeToFile()

in agent/native/ext/AST_debug.cpp [704:772]


void debugDumpAstSubTreeToFile( StringView compiledFileFullPath, zend_ast* ast, bool isBeforeProcess )
{
    ResultCode resultCode;
    StringBuffer debugDumpFileFullPath = ELASTIC_APM_EMPTY_STRING_BUFFER;
    FILE* debugDumpFile = NULL;
    int errnoValue = 0;
    char txtOutStreamBuf[ELASTIC_APM_TEXT_OUTPUT_STREAM_ON_STACK_BUFFER_SIZE];
    TextOutputStream txtOutStream = ELASTIC_APM_TEXT_OUTPUT_STREAM_FROM_STATIC_BUFFER( txtOutStreamBuf );

    DebugDumpAstPrintToFileCtx ctx;
    DebugDumpAstPrinter printer;


    ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "compiledFileFullPath: %s", compiledFileFullPath.begin );

    StringView pathPrefix = stringBufferToView( g_astProcessDebugDumpForPathPrefix );
    if ( ! isFileSystemPathPrefix( compiledFileFullPath, pathPrefix ) )
    {
        ELASTIC_APM_LOG_DEBUG_FUNCTION_ENTRY_MSG( "Skipping this file because it does not have required prefix: %s", pathPrefix.begin );
        return;
    }

    StringView compiledFileRelativePath = subStringView( compiledFileFullPath, pathPrefix.length );
    StringView isBeforeProcessSuffix = isBeforeProcess ? ELASTIC_APM_STRING_LITERAL_TO_VIEW( ".before_AST_process" ) : ELASTIC_APM_STRING_LITERAL_TO_VIEW( ".after_AST_process" );
    StringView debugDumpFileExtensionSuffix = ELASTIC_APM_STRING_LITERAL_TO_VIEW( ".txt" );
    StringView debugDumpFileFullPathParts[] = {
        stringBufferToView( g_astProcessDebugDumpOutDir ),
        compiledFileRelativePath,
        isBeforeProcessSuffix,
        debugDumpFileExtensionSuffix
    };
    ELASTIC_APM_CALL_IF_FAILED_GOTO( buildFileFullPath( ELASTIC_APM_MAKE_ARRAY_VIEW_FROM_STATIC( StringViewArrayView, debugDumpFileFullPathParts ), /* out */ &debugDumpFileFullPath ) );

    ELASTIC_APM_CALL_IF_FAILED_GOTO( ensureDirectoriesExist( stringBufferToView( debugDumpFileFullPath ) ) );

    errnoValue = openFile( debugDumpFileFullPath.begin, "w", /* out */ &debugDumpFile );
    if ( errnoValue != 0 )
    {
        ELASTIC_APM_LOG_ERROR( "Failed to open file; debugDumpFileFullPath: %s; errno: %d (%s)", debugDumpFileFullPath.begin, errnoValue, streamErrNo( errnoValue, &txtOutStream ) );
        ELASTIC_APM_SET_RESULT_CODE_AND_GOTO_FAILURE();
    }

    ELASTIC_APM_LOG_INFO( "Printing AST debug dump of %s to %s ...", compiledFileFullPath.begin, debugDumpFileFullPath.begin );
    ctx = (DebugDumpAstPrintToFileCtx){ .outFile = debugDumpFile };
    printer = (DebugDumpAstPrinter){ .printLine = &debugDumpAstPrintLineToFile, .ctx = &ctx };
    debugDumpAst( &printer, ast, /* nestingDepth */ 0 );
    ELASTIC_APM_LOG_INFO( "Printed AST debug dump of %s to %s", compiledFileFullPath.begin, debugDumpFileFullPath.begin );

    if ( g_astProcessDebugDumpConvertedBackToSource )
    {
        debugDumpAstSubTreeConvertedBackToSource( compiledFileFullPath, compiledFileRelativePath, ast, isBeforeProcessSuffix, &txtOutStream );
    }

    resultCode = resultSuccess;
    finally:
    ELASTIC_APM_LOG_DEBUG_RESULT_CODE_FUNCTION_EXIT_MSG();
    if ( debugDumpFile != NULL )
    {
        fclose( debugDumpFile );
        debugDumpFile = NULL;
    }
    ELASTIC_APM_FREE_STRING_BUFFER_AND_SET_TO_NULL( /* in,out */ debugDumpFileFullPath );

    ELASTIC_APM_UNUSED( resultCode );
    return;

    failure:
    goto finally;
}