<commit_before>#include "condor_common.h"
#include "condor_config.h"
#include "condor_debug.h"

#include "sysapi.h"
#include "sysapi_externs.h"

const char * sysapi_processor_flags_raw( void ) {
    sysapi_internal_reconfig();
    
    if( _sysapi_processor_flags_raw != NULL ) {
        return _sysapi_processor_flags_raw;
    }
    
    /* You can adapt this to ncpus.cpp's _SysapiProceCpuinfo for debugging. */
    FILE * fp = safe_fopen_wrapper_follow( "/proc/cpuinfo", "r", 0644 );
    dprintf( D_LOAD, "Reading from /proc/cpuinfo\n" );
    if( fp ) {
        /* See comment in npcus.cpp for an explanation of this constant. */
        char buffer[1024];
        while( fgets( buffer, sizeof( buffer ) - sizeof(char), fp ) ) {
            char * colon = strchr( buffer, ':' );
            
            char * value = NULL;
            char * attribute = NULL;
            if( colon != NULL ) {
                if( *(colon + 1) != '\0' ) {
                    value = colon + 2;
                }
                
                char * tmp = colon;
                while( isspace( *tmp ) || (*tmp == ':' ) ) {
                    *tmp = '\0';
                    --tmp;
                }
                attribute = buffer;
                
                if( strcmp( attribute, "flags" ) == 0 ) {
                    /* This is where we assume flags into buffer. */
                    _sysapi_processor_flags_raw = strdup( value );
                    if( _sysapi_processor_flags_raw == NULL ) {
                        EXCEPT( "Failed to allocate memory for the raw processor flags." );
                    }
                    break;
                }
            }
        }
        
        fclose( fp );
    } else {
        _sysapi_processor_flags_raw = "";
    }
    
    return _sysapi_processor_flags_raw;
}

const char * sysapi_processor_flags( void ) {
    sysapi_internal_reconfig();
    
    if( _sysapi_processor_flags != NULL ) {
        return _sysapi_processor_flags;
    }
    
    if( _sysapi_processor_flags_raw == NULL ) {
        sysapi_processor_flags_raw();
        ASSERT(_sysapi_processor_flags_raw != NULL);
    }

    /* Which flags do we care about?  You MUST terminate this list with NULL. */
    static const char * const flagNames[] = { "ssse3", "sse4_1", "sse4_2", NULL };

    /* Do some memory-allocation math. */
    int numFlags = 0;
    int maxFlagLength = 0;
    for( int i = 0; flagNames[i] != NULL; ++i ) {
        ++numFlags;
        int curFlagLength = strlen( flagNames[i] );
        if( curFlagLength > maxFlagLength ) { maxFlagLength = curFlagLength; }
    }

    char * currentFlag = (char *)malloc( maxFlagLength * sizeof( char ) );
    if( currentFlag == NULL ) {
        EXCEPT( "Failed to allocate memory for current processor flag." );
    }        
    currentFlag[0] = '\0';

    /* If we track which flags we have, we can make sure the order we
       print them is the same regardless of the raw flags order. */
    const char ** flags = (const char **)malloc( sizeof( const  char * ) * numFlags );
    if( flags == NULL ) {
        EXCEPT( "Failed to allocate memory for processor flags." );
    }
    for( int i = 0; i < numFlags; ++i ) { flags[i] = ""; }<commit_msg>(Coverity)  Allocate room for the trailing NUL, too.<commit_after>#include "condor_common.h"
#include "condor_config.h"
#include "condor_debug.h"

#include "sysapi.h"
#include "sysapi_externs.h"

/*
 * See GitTrac #3544 for an explanation of why we care about processor flags
 * (short answer: because glibc does, and breaks standard universe as a 
 * result).  To determine which flags glibc cares about, examine the glibc
 * sources; in 2.12-2, the file sysdeps/x86_64/multiarch/init-arch.h #defines
 * [bit|index]_[SSE2|SSSE3|SSE4_1|SSE4_2].  I confirmed (by checking with
 * Wikipedia's CPUID article) that glibc was using the same names for those
 * processor flags as everyone else (using the value of the shift in the bit_*
 * macros, combined with CPUID_E[C|D]X_OFFSET).  Thus, SSSE3 really does have
 * three 'S's.
 *
 * We ignore what glibc is doing in init-arch.c because it's strictly for
 * performance -- see the ticket for details.
 *
 * We're ignoring SSE2 because every processor built in the last 10 years
 * supports it.
 */

const char * sysapi_processor_flags_raw( void ) {
    sysapi_internal_reconfig();
    
    if( _sysapi_processor_flags_raw != NULL ) {
        return _sysapi_processor_flags_raw;
    }
    
    /* You can adapt this to ncpus.cpp's _SysapiProceCpuinfo for debugging. */
    FILE * fp = safe_fopen_wrapper_follow( "/proc/cpuinfo", "r", 0644 );
    dprintf( D_LOAD, "Reading from /proc/cpuinfo\n" );
    if( fp ) {
        /* See comment in npcus.cpp for an explanation of this constant. */
        char buffer[1024];
        while( fgets( buffer, sizeof( buffer ) - sizeof(char), fp ) ) {
            char * colon = strchr( buffer, ':' );
            
            char * value = NULL;
            char * attribute = NULL;
            if( colon != NULL ) {
                if( *(colon + 1) != '\0' ) {
                    value = colon + 2;
                }
                
                char * tmp = colon;
                while( isspace( *tmp ) || (*tmp == ':' ) ) {
                    *tmp = '\0';
                    --tmp;
                }
                attribute = buffer;
                
                if( strcmp( attribute, "flags" ) == 0 ) {
                    /* This is where we assume flags into buffer. */
                    _sysapi_processor_flags_raw = strdup( value );
                    if( _sysapi_processor_flags_raw == NULL ) {
                        EXCEPT( "Failed to allocate memory for the raw processor flags." );
                    }
                    break;
                }
            }
        }
        
        fclose( fp );
    } else {
        _sysapi_processor_flags_raw = "";
    }
    
    return _sysapi_processor_flags_raw;
}

const char * sysapi_processor_flags( void ) {
    sysapi_internal_reconfig();
    
    if( _sysapi_processor_flags != NULL ) {
        return _sysapi_processor_flags;
    }
    
    if( _sysapi_processor_flags_raw == NULL ) {
        sysapi_processor_flags_raw();
        ASSERT(_sysapi_processor_flags_raw != NULL);
    }

    /* Which flags do we care about?  You MUST terminate this list with NULL. */
    static const char * const flagNames[] = { "ssse3", "sse4_1", "sse4_2", NULL };

    /* Do some memory-allocation math. */
    int numFlags = 0;
    int maxFlagLength = 0;
    for( int i = 0; flagNames[i] != NULL; ++i ) {
        ++numFlags;
        int curFlagLength = strlen( flagNames[i] );
        if( curFlagLength > maxFlagLength ) { maxFlagLength = curFlagLength; }
    }

    char * currentFlag = (char *)malloc( (1 + maxFlagLength) * sizeof( char ) );
    if( currentFlag == NULL ) {
        EXCEPT( "Failed to allocate memory for current processor flag." );
    }        
    currentFlag[0] = '\0';

    /* If we track which flags we have, we can make sure the order we
       print them is the same regardless of the raw flags order. */
    const char ** flags = (const char **)malloc( sizeof( const  char * ) * numFlags );
    if( flags == NULL ) {
        EXCEPT( "Failed to allocate memory for processor flags." );
    }
    for( int i = 0; i < numFlags; ++i ) { flags[i] = ""; }
{'fraction_non_alphanumeric': 0.11097527845694105, 'fraction_numerical': 0.009644118446074436, 'mean_word_length': 1.916039603960396, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3614231', 'n_tokens_mistral': 2260, 'n_tokens_neox': 2158, 'n_words': 663}