Lhogho  0.0.027
Data Structures | Defines | Typedefs | Variables
internal.h File Reference

Data Structures

struct  test_case_info_tag

Defines

#define __INTERNAL_H_8DED3586_3931_4BD5_A578_3B8B6082391C_INCLUDED

Typedefs

typedef RESULT(* parse_config_attribute_function )(const TCHAR *parameter_name, const TCHAR *parameter_optipons, test_case_info *test_case_params)

Variables

int g_first

Basic definitions

These macros are used to define basic constants in the code.

#define LOGO_NAME   "lhogho"
#define TARGET_FILE_EXTENSION   "lgo"
#define SHELL_FILE_EXTENSION   "sh"
#define EXPECTED_RESULTS_EXT   "expected"
#define REAL_RESULTS_EXT   "real"
#define ERROR_RESULTS_EXT   "stderr"
#define LTEMP_EXT   "ltemp"
#define MAX_LINE_LENGTH   2048
#define MAX_NAME_LEN   1024
#define EXPECTED_MEMORY   TEXT("{MEM#0:0}")
#define MEMORY_CHECK_OPTION   "-Zm"
#define PARAM_SET_SYMBOL   TEXT('=')
#define SPACE_ESC_SYMBOL   TEXT('\"')
#define COMMENT_SYMBOL   TEXT(';')

Config file data types

These struct contains data from parameters written into test case file.

typedef struct test_case_info_tag test_case_info

String functions prototypes

See source code for details

int m_strcmp (const TCHAR *str1, const TCHAR *str2)
 compares two strings
TCHAR * m_strcpy (TCHAR *dest, const TCHAR *src)
 copy string
BOOL m_isspace (TCHAR chr)
 test if char is space
RESULT m_strdup (TCHAR **dest_ptr, const TCHAR *src)
 duplicate string. Allocate memory for destination
RESULT m_strndup (TCHAR **dest_ptr, const TCHAR *src, size_t num_chars)
 duplicate string, but no more than num_chars symbols
size_t m_strlen (const TCHAR *str)
 calculates string length
TCHAR * m_fgets (FILE *file, TCHAR *buffer, size_t buffer_size, size_t *out_size_ptr)
 Read a line from file.
void m_fputs (FILE *file, const TCHAR *buffer)
 prints a line to file
void m_fputs_ascii (FILE *file, const char *buffer)
 prints a line to file, convert it to UNICODE if needed
void m_fputc (FILE *file, TCHAR tchar)
 prints a symbol to file

Internal tester helper functions prototypes

See source code for details

RESULT parse_line (FILE *input_file, TCHAR **parameter_name, TCHAR **parameter_optipons)
 Parse a comment line in the test case file.
RESULT extract_args (FILE *input_file, test_case_info *test_info)
 Extracts all argument pairs from test case file.
RESULT extract_expected_results (FILE *input_file, const char *file_name)
 Extract value for expected results from test case file.
RESULT execute_test (const char *file_name, test_case_info test_info)
 Execute a test case.
RESULT compile_test (const char *file_name, test_case_info test_info)
 Compile test case file to executable.
RESULT check_results (const char *file_name, test_case_info test_info, UINT32 exec_result)
 Check results from test case execution.
RESULT import_results (const char *file_name, test_case_info test_info)
 Import results from test execution into test case file.
void clean_up (const char *file_name)
 Clean up any temporary data from test execution.
void print_file (const char *file_name, FILE *output)
 prints a file to the end of another one
RESULT file_compare (const char *test_file_name, test_case_info test_info)
 Compare result file with one expected.
RESULT exec_shell (const char *file_name)
 Execute a shell script with name same as test file name.

Define Documentation

#define LOGO_NAME   "lhogho"
#define TARGET_FILE_EXTENSION   "lgo"
#define SHELL_FILE_EXTENSION   "sh"
#define EXPECTED_RESULTS_EXT   "expected"
#define REAL_RESULTS_EXT   "real"
#define ERROR_RESULTS_EXT   "stderr"
#define LTEMP_EXT   "ltemp"
#define MAX_LINE_LENGTH   2048
#define MAX_NAME_LEN   1024
#define EXPECTED_MEMORY   TEXT("{MEM#0:0}")
#define MEMORY_CHECK_OPTION   "-Zm"
#define PARAM_SET_SYMBOL   TEXT('=')
#define SPACE_ESC_SYMBOL   TEXT('\"')
#define COMMENT_SYMBOL   TEXT(';')

Typedef Documentation

typedef RESULT(* parse_config_attribute_function)(const TCHAR *parameter_name, const TCHAR *parameter_optipons, test_case_info *test_case_params)

Function Documentation

int m_strcmp ( const TCHAR *  str1,
const TCHAR *  str2 
)
Parameters:
str1first string
str2second string
Returns:
comparison result similar to standart strcmp result

Comare two strings. Return negative value if first is less than second positive value if first is great than second and zero if strings are equal

{
    while (*str1 && *str1 == *str2)
    {
        ++str1;
        ++str2;
    }
    return *str1 - *str2;
}
TCHAR * m_strcpy ( TCHAR *  dest,
const TCHAR *  src 
)
Parameters:
destdestination string
srcsource string
Returns:
pointer to destination

Copy string value to given pointer. User must supply enought memory

{
    TCHAR * mem = dest;
    while (*src)
    {
        *dest++ = *src++;
    }
    *dest = 0;
    return mem;
}
BOOL m_isspace ( TCHAR  chr)
Parameters:
chrchar to test
Returns:
result of the test

Test if symbol is space symbol (Space, new line or tab)

{
    return (chr == TEXT(' ')  || chr == TEXT('\t') || 
        chr == TEXT('\r') || chr == TEXT('\n'));
}
RESULT m_strdup ( TCHAR **  dest_ptr,
const TCHAR *  src 
)
Parameters:
dest_ptrpointer to destination string
srcsource string
Returns:
RESULT value. Error on memory problems

Duplicate string. Allocate memory for destination. If memory problems occured return error.

{
    size_t len = m_strlen(src);
    return m_strndup(dest_ptr, src, len);
}
RESULT m_strndup ( TCHAR **  dest_ptr,
const TCHAR *  src,
size_t  num_chars 
)
Parameters:
dest_ptrpointer to destination string
srcsource string
num_charsnumber of characters to copy.
Returns:
RESULT value. Error on memory problems

Copy string value to given pointer, byt no more than num_chars symbols. Allocates memory for destination. Not copy the 0 byte if source is longer than wanted length

{
    *dest_ptr = (TCHAR *)malloc((num_chars + 1) * sizeof(TCHAR));
    if (!*dest_ptr)
    {
        return ERR_MEMORY;
    }
    memcpy(*dest_ptr, src, num_chars * sizeof(TCHAR));
    (*dest_ptr)[num_chars] = 0;
    return SUCCESS_FULL;
}
size_t m_strlen ( const TCHAR *  str)
Parameters:
strthe string
Returns:
length of the string in symbols

Calculates string length in symbols. Works with char and w_char

{
    const TCHAR * start = str;
    while (*str) ++str;
    return str - start;
}
TCHAR * m_fgets ( FILE *  file,
TCHAR *  buffer,
size_t  buffer_size,
size_t *  out_size_ptr 
)
Parameters:
filefile to read from
bufferbuffer to read in
buffer_sizesize of space in the buffer
out_size_ptrsize of line readed
Returns:
pointer to readed string or NULL if error

Read characters from given open file until new line symbol is reached or input buffer is full. Returns the count of really readed symbols in parameter and pointer to the buffer. If error occured during read process returns NULL

{
    TCHAR c = 0;
    size_t pos = 0;
    if (!file || !buffer || !buffer_size || !out_size_ptr)
    {
        LOG_ERROR("Invalid args supplied to m_fgets");
        if (out_size_ptr)
        {
            *out_size_ptr = 0;
        }
        return NULL;
    }

    while (pos < buffer_size - 1)
    {
        if (!fread(&c, sizeof(TCHAR), 1, file))   
        {
            break;
        }
        buffer[pos++] = c;

        if (c == TEXT('\r') || c == TEXT('\n'))
        {
            TCHAR c1;
            size_t readed;
            if ((readed = fread(&c1, sizeof(TCHAR), 1, file)) &&
                (c1 == TEXT('\r') || c1 == TEXT('\n')) && c1 != c)
            {
                buffer[pos++] = c1;
            }
            else
            {
                if (readed)
                {
                    fseek(file, -1l, SEEK_CUR);
                }
            }
            break;
        }
    }

    buffer[pos] = 0;
    *out_size_ptr = pos;
    return pos ? buffer : NULL;
}
void m_fputs ( FILE *  file,
const TCHAR *  buffer 
)
Parameters:
filefile to write in
bufferstring to write

Writes a line to the file. Buffer must be a valid nul-terminated string

{
    size_t len = m_strlen(buffer);
    fwrite(buffer, sizeof(TCHAR), len, file);
}
void m_fputs_ascii ( FILE *  file,
const char *  buffer 
)
Parameters:
filefile to write in
bufferstring to write

Writes a line to the file. If program works in unicode mode the string is converted from ASCII to unicode.

{
    char * buf = (char *)buffer;
    size_t len = strlen(buffer) * sizeof(TCHAR);
    
#if defined(UNICODE)
     buf = (char*)malloc(len);
     while (*buffer) *buf++ = *buffer++, *buf++ = 0;
#endif
    fwrite(buf, sizeof(TCHAR), len, file);

#if defined(UNICODE)
    free(buf);
#endif
}
void m_fputc ( FILE *  file,
TCHAR  tchar 
)
Parameters:
filefile to write in
tcharsymbol to write

Writes a symbol to file.

{
#if defined (UNICODE)
    putwc(tchar, file);
#else
    putc(tchar, file);
#endif
}
RESULT parse_line ( FILE *  input_file,
TCHAR **  parameter_name,
TCHAR **  parameter_optipons 
)
Parameters:
input_filefile to read from
parameter_namename of the parameter readed
parameter_optiponspointer to data assigned to the parameter
Returns:
RESULT value. See error.h for details

Read a comment line from test case file. If line describes valid parameter-value pair assignes name of parameter to parameter_name and option value to parameter_optipons Allocates memory for them. If line is empty return SUCCESS_EMPTY value If other error occurs return some error value.

{
    TCHAR buffer[MAX_LINE_LENGTH];
    TCHAR * str, *start, *end;
    size_t read_size;

    m_fgets(input_file, buffer, MAX_LINE_LENGTH, &read_size);
    if (!read_size)
    {
        return SUCCESS_EMPTY;
    }
    str = buffer;
    while (*str && m_isspace(*str))
    {
        ++str;
    }
    if (!*str)
    {
        return SUCCESS_EMPTY;
    }

    // Skiping shell comments
    if (str[0] == '#' && str[1] == '!' && g_first)
    {
        g_first = 0;
        return parse_line(input_file, parameter_name, parameter_optipons);
    }

    if (*str != COMMENT_SYMBOL)
    {
        LOG_ERROR("parse_line - no comment line");
        return ERR_GENERIC;
    }

    while (*str == COMMENT_SYMBOL || m_isspace(*str))
    {
        ++str;
    }

    start = str;
    while (*str && *str != PARAM_SET_SYMBOL)
    {
        ++str;
    }
    if (*str)
    {
        end = str;
        --str;
        while(str > start && m_isspace(*str))
            --str;
        if (str == start)
        {
            LOG_ERROR("parse_line - no param name");
            return ERR_GENERIC;
        }
        if (*str != PARAM_SET_SYMBOL)
            ++str;

        *parameter_name = (TCHAR*)malloc((str - start + 1) * sizeof(TCHAR));
        str[0] = 0;
        m_strcpy(*parameter_name, start);
    }
    else
    {
        LOG_ERROR("parse_line - no value specified");
        return SUCCESS_EMPTY;
    }

    str = end+1;
    while (*str && m_isspace(*str))
    {
        ++str;
    }
    m_strdup(parameter_optipons, str);
    return SUCCESS_FULL;
}
RESULT extract_args ( FILE *  input_file,
test_case_info test_info 
)
Parameters:
input_filefile to read from
test_infostruct in which data from parameters will be writen
Returns:
RESULT value. See error.h for details

Reads comment lines from the source file until empty is found For each extracts data and call all registered parsers. Each of them is responsible to process parameter or return ERR_INVALID_ARG if doesn't recognise the param name

{
    TCHAR * test_name = NULL;
    TCHAR * test_options = NULL;
    RESULT res;
    int i;

    g_first = 1;

    while ((res = parse_line(input_file, &test_name, &test_options)) != SUCCESS_EMPTY)
    {
        if (IS_ERROR(res))
        {
            LOG_ERROR("Couldn't read parameter from input file");
            break;
        }
        for (i = 0; i < PARSERS_COUNT; ++i)
        {
            if (g_parsers[i])
            {
                res = g_parsers[i](test_name, test_options, test_info);
                if (IS_ERROR(res) && res != ERR_INVALID_ARG)
                {
                    break;
                }
            }
        }
        free (test_name);
        free (test_options);

        res = SUCCESS_FULL;
    }

    return IS_ERROR(res) ? res : SUCCESS_FULL;
}
RESULT extract_expected_results ( FILE *  input_file,
const char *  file_name 
)
Parameters:
input_fileTest case file
file_namename of the file
Returns:
RESULT value. See error.h for details

Read lines with expected results from test case file until empty found. Write them after corresponding processment to the file with name similar to file_name but with specified suffix.

{
    TCHAR   buffer [MAX_LINE_LENGTH];
    TCHAR * str;
    size_t  real_read_size;
    RESULT  res = SUCCESS_FULL;
    char    new_file_name [MAX_LINE_LENGTH];
    FILE  * test_file = NULL;

    strcpy(new_file_name, file_name);
    strcat(new_file_name, "."EXPECTED_RESULTS_EXT);

    if (!(test_file = fopen(new_file_name, "wb")))
    {
        return ERR_FILE;
    }

    do
    {
        str = m_fgets(input_file, buffer, MAX_LINE_LENGTH, &real_read_size);

        while (str && *str && m_isspace(*str))
        {
            ++str;
        }
        res = write_one_line_result(str, test_file);
    }while (res == SUCCESS_FULL);

    fclose(test_file);
   return IS_ERROR(res) ? res : SUCCESS_FULL;
}
RESULT execute_test ( const char *  file_name,
test_case_info  test_info 
)
Parameters:
file_nameTest case file name
test_infoOptions for execution
Returns:
execution code as RESULT value

Prepare shell comand line calling tested application and execute it. Depending on testing mode could perform different actions. Collect stdout output and return execution success code as SUCCESS result

{
    char cmd_buffer[MAX_LINE_LENGTH] = "";
    int ret;

#if defined(__WIN32__) && defined (__GNUC__)
   // If executed in Cygwin there is problem with system primitive
   // 'cause system is calling 'cmd' , not 'bash'
   strcpy(cmd_buffer, "bash -c \"");
#endif

    if ((g_parameters.tester_mode & MODE_TEST) ||
        (g_parameters.tester_mode & MODE_BUILD) )
    {
        /* will compile a source */
        if (g_parameters.compiler_name)
        {
            strcat(cmd_buffer, g_parameters.compiler_name);
        }
        else
        {
            strcat(cmd_buffer, LOGO_NAME);
        }
        strcat(cmd_buffer, " ");
    }
    else
    {
        /* will execute precompiled program */
        char * end = (char *)strrchr(file_name, '.');
        if (end) *end = '\0';
        strcpy(cmd_buffer, file_name);
        if (end) *end = '.';
    }


    if ((g_parameters.tester_mode & MODE_TEST) || (g_parameters.tester_mode & MODE_EXECUTE))
    {
        strcat(cmd_buffer, MEMORY_CHECK_OPTION);
        strcat(cmd_buffer, " ");
    }

    if (g_parameters.global_params)
    {
        strcat(cmd_buffer, g_parameters.global_params);
        strcat(cmd_buffer, " ");
    }

    if (test_info.command_line_param)
    {
        strcat(cmd_buffer, test_info.command_line_param);
        strcat(cmd_buffer, " ");
    }
    
    if ((g_parameters.tester_mode & MODE_TEST) ||
        (g_parameters.tester_mode & MODE_BUILD) )
    {
        strcat(cmd_buffer, file_name);
    }

    strcat(cmd_buffer, " 1> ");
    strcat(cmd_buffer, file_name);
    strcat(cmd_buffer, "."REAL_RESULTS_EXT);
    strcat(cmd_buffer, " 2> ");
    strcat(cmd_buffer, file_name);
    strcat(cmd_buffer, "."ERROR_RESULTS_EXT);

#if defined(__WIN32__) && defined (__GNUC__)
   strcat(cmd_buffer, "\"");
#endif

   ret = system(cmd_buffer);
   if (ret == -1)
    {
        LOG_ERROR("execution failed");
        return ERR_GENERIC;
    }
    return MAKE_SUCCESS(ret);
}
RESULT compile_test ( const char *  file_name,
test_case_info  test_info 
)
Parameters:
file_nameTest case file name
test_infoOptions for execution
Returns:
RESULT value. See error.h for details

Calls external compiler to compile test file.

{
    char cmd_buffer[MAX_LINE_LENGTH];
    int ret;

    if (g_parameters.compiler_name)
    {
        strcpy(cmd_buffer, g_parameters.compiler_name);
    }
    else
    {
        strcpy(cmd_buffer, LOGO_NAME);
    }
    strcat(cmd_buffer, " -x ");

    if (g_parameters.global_params)
    {
        strcat(cmd_buffer, g_parameters.global_params);
        strcat(cmd_buffer, " ");
    }

    if (test_info.command_line_param)
    {
        strcat(cmd_buffer, test_info.command_line_param);
        strcat(cmd_buffer, " ");
    }
    
    strcat(cmd_buffer, file_name);

    if ((ret = system(cmd_buffer)) == -1)
    {
        LOG_ERROR("execution failed");
        return ERR_GENERIC;
    }
    return MAKE_SUCCESS(ret);
}
RESULT check_results ( const char *  file_name,
test_case_info  test_info,
UINT32  exec_result 
)
Parameters:
file_namename of tested file
test_infooptions for execution
exec_resultreturn value from execution
Returns:
RESULT value. See error.h for details

Checks results from test execution and compare them with expected.

{
    BOOL    is_success = TRUE;
    UINT64  size;
    RESULT  res;
    char    par_name[MAX_NAME_LEN];
    size_t  file_name_len;

    file_name_len = m_strlen(file_name);
    strcpy(par_name, file_name);

    if (0 && exec_result)   // No exit code tests now!
    {
        if (g_parameters.verbose_flag)
        {
            fprintf(g_parameters.output_file, "Error executing test :");
            m_fputs(g_parameters.output_file, test_info.test_name ? test_info.test_name : file_name);
            fprintf(g_parameters.output_file, "Exit code : %u\n", exec_result);
        }
        return MAKE_SUCCESS(exec_result);
    }

    strcpy(par_name + file_name_len, "."ERROR_RESULTS_EXT);
    res = get_file_size(par_name, &size);
    if (IS_ERROR(res))
    {
        LOG_ERROR("get_file_size failed");
        return res;
    }
    if (size)
    {
        if (g_parameters.verbose_flag)
        {
            fprintf(g_parameters.output_file, "Executing test ");
            m_fputs(g_parameters.output_file, test_info.test_name ? test_info.test_name : file_name);
            fprintf(g_parameters.output_file, " causet output to stderr\n");
            print_file(par_name, g_parameters.output_file);
        }
        return MAKE_SUCCESS((UINT32)size);
    }

    if (res = file_compare(file_name, test_info))
    {
        return res;
    }

    if (g_parameters.verbose_flag)
    {
        fprintf(g_parameters.output_file, "Executing test ");
        m_fputs(g_parameters.output_file, test_info.test_name ? test_info.test_name : file_name);
        fprintf(g_parameters.output_file, " success!\n");
    }

    return SUCCESS_FULL;
}
RESULT import_results ( const char *  file_name,
test_case_info  test_info 
)
Parameters:
file_namename of tested file
test_infooptions for execution
Returns:
RESULT value. See error.h for details

Import results from test execution into test case file.

{
    TCHAR   line[MAX_LINE_LENGTH];
    size_t  real_size; 

    char    exp_name[MAX_NAME_LEN];
    char    temp_name[MAX_NAME_LEN];

    FILE  * expected_file;
    FILE  * source_file;
    FILE  * temp_file;


    strcpy(exp_name, file_name);
    strcat(exp_name, "."REAL_RESULTS_EXT);
    expected_file = fopen(exp_name, "rb");
    if (!expected_file)
    {
        LOG_ERROR("Can't open expected file");
        return ERR_FILE;
    }

    strcpy(temp_name, file_name);
    strcat(temp_name, "."LTEMP_EXT);
    temp_file = fopen(temp_name, "wb");
    if (!temp_file)
    {
        LOG_ERROR("Can't open temp file");
        return ERR_FILE;
    }

    source_file = fopen(file_name, "rb");
    if (!source_file)
    {
        LOG_ERROR("Can't open source file");
        return ERR_FILE;
    }

    fprintf(temp_file, "\n");

    while (m_fgets(expected_file, line, MAX_LINE_LENGTH, &real_size))
    {
        if (real_size && real_size < MAX_LINE_LENGTH)
        {
            m_fputc(temp_file, COMMENT_SYMBOL);
        }
        m_fputs(temp_file, line);
    }

    fprintf(temp_file, "\n");
    fclose(expected_file);
    unlink(exp_name);

    while (m_fgets(source_file, line, MAX_LINE_LENGTH, &real_size))
    {
        m_fputs(temp_file, line);
    }
    fclose(temp_file);
    fclose(source_file);
    unlink(file_name);
    return rename(temp_name, file_name) == 0 ? SUCCESS_FULL : ERR_FILE;
}
void clean_up ( const char *  file_name)
Parameters:
file_namename of tested file

Remove any temporary files produced from test execution process

{
    char name[MAX_NAME_LEN];
    size_t  file_name_len;

    file_name_len = m_strlen(file_name);
    strcpy(name, file_name);

    strcpy(name + file_name_len, "."EXPECTED_RESULTS_EXT);
    unlink(name);

    strcpy(name + file_name_len, "."REAL_RESULTS_EXT);
    unlink(name);

    strcpy(name + file_name_len, "."ERROR_RESULTS_EXT);
    unlink(name);
}
void print_file ( const char *  file_name,
FILE *  output_file 
)
Parameters:
file_namename of file to be printed
output_filefile where data will be appended

Appends contet of input file into end of destination file

{
    TCHAR   buffer[MAX_LINE_LENGTH];
    size_t  size;

    FILE * f = fopen(file_name, "rb");
    if (!f)
    {
        LOG_ERROR("Open file to print failed");
        return;
    }
    while(m_fgets(f, buffer, MAX_LINE_LENGTH, &size))
    {
        m_fputs(output_file, buffer);
    }
    fclose(f);
}
RESULT file_compare ( const char *  test_file_name,
test_case_info  test_info 
)
Parameters:
test_file_namename of tested file
test_infoparameters for test execution
Returns:
RESULT value. See error.h for details

Compare file containing produced from tester data with file containing expected data Returns success value if lines are "equual" and error if tey are not

{
    TCHAR   expected[MAX_LINE_LENGTH];
    TCHAR   expected_mem[] = EXPECTED_MEMORY;
    TCHAR   real[MAX_LINE_LENGTH];
    size_t  real_size, exp_size;
    char    name[MAX_NAME_LEN];
    RESULT  res = SUCCESS_FULL;
    int     mem_checked = 0;

    FILE * expected_file;
    FILE * real_file;

    strcpy(name, test_file_name);
    strcat(name, "."EXPECTED_RESULTS_EXT);
    expected_file = fopen(name, "rb");
    if (!expected_file)
    {
        LOG_ERROR("Can't open expected file");
        return ERR_FILE;
    }

    strcpy(name, test_file_name);
    strcat(name, "."REAL_RESULTS_EXT);
    real_file = fopen(name, "rb");
    if (!real_file)
    {
        LOG_ERROR("Can't open real file");
        return ERR_FILE;
    }

    while (m_fgets(real_file, real, MAX_LINE_LENGTH, &real_size))
    {
        if (!m_fgets(expected_file, expected, MAX_LINE_LENGTH, &exp_size))
        {
            if (!mem_checked)
            {
                mem_checked = 1;
                if (SUCCESS_FULL == compare_strings_output(real, expected_mem))
                {
                    continue;
                }
            }
            
            if (g_parameters.verbose_flag)
            {
                fprintf(g_parameters.output_file, "Test %s failed. Extra line in output: \n%s\n", 
               test_info.test_name ? test_info.test_name : test_file_name, real);
            }
            else
            {
                fprintf(g_parameters.output_file, "Test failed\n");
            }
            res = ERR_GENERIC;
            break;
        }
        if (IS_ERROR(compare_strings_output(real, expected)))
        {
            if (g_parameters.verbose_flag)
            {
                fprintf(g_parameters.output_file, "Test %s failed. Unexpected line in output: \n\"%s\"\n"
               "\tExpected\n\"%s\"\n", 
               test_info.test_name ? test_info.test_name : test_file_name, real, expected);
            }
            else
            {
                fprintf(g_parameters.output_file, "Test failed\n");
            }
            res = ERR_GENERIC;
            break;
        }
    }

    if (m_fgets(expected_file, expected, MAX_LINE_LENGTH, &exp_size))
    {
        int i = 0;
        if (expected[i])
        {
            if (g_parameters.verbose_flag)
            {
                fprintf(g_parameters.output_file, "Test %s failed. Extra line in output: \n%s\n", 
                    test_info.test_name ? test_info.test_name : test_file_name, real);
            }
            else
            {
                fprintf(g_parameters.output_file, "Test failed\n");
            }
            res = ERR_GENERIC;
        }
    }

    if (!mem_checked)
    {
        if (g_parameters.verbose_flag)
        {
            fprintf(g_parameters.output_file, "Test %s failed. No memory check performed!\n", 
                test_info.test_name ? test_info.test_name : test_file_name);
        }
        else
        {
            fprintf(g_parameters.output_file, "Test failed\n");
        }
        res = ERR_GENERIC;
    }

    fclose(real_file);
    fclose(expected_file);

   return res;
}
RESULT exec_shell ( const char *  file_name)
Parameters:
file_namename of tested file
Returns:
RESULT value. Execuion status

Try to execute shell script with name same as input file if any. If no script exist return SUCCESS_FILE else return SUCESS_FULL on successfull execution of ERR_GENERIC on error.

{
    RESULT res = SUCCESS_FILE;
    FILE * test_file;
    char sh_name[512];
    char command[512] = "bash -c ";
    size_t len;
    int ret_code;
    char * dot_pos = strrchr(file_name, '.');
    
    // Prepare shell file name
    if (dot_pos && dot_pos != file_name)
    {
        len = dot_pos - file_name;
    }
    else
    {
        len = strlen(file_name);
    }

    strncpy(sh_name, file_name, len);
    sh_name[len++] = '.';
    strcpy(sh_name+len, SHELL_FILE_EXTENSION);

    // Try to open file
    test_file = fopen(sh_name, "r");
    if (!test_file)
    {
        return SUCCESS_FILE;
    }
    fclose(test_file);
    ret_code = system(strcat(command, sh_name));
    if (g_parameters.verbose_flag)
    {
        fprintf(stderr, "execution:%s-> %d\n", sh_name, ret_code);
    }
    if (ret_code == -1) // execution failed!
    {
        LOG_ERROR("execution failed");
        return SUCCESS_FILE;
    }
    if (ret_code == 0)
    {
        ++g_parameters.num_passed;
        return SUCCESS_FULL;
    }

    ++g_parameters.num_failed;
    return ERR_GENERIC;
}

Variable Documentation

int g_first

[ HOME | INDEX | ATOMS | VARS | REFERENCE ]
Lhogho Developer's Documentation
Tue Feb 7 2012