summaryrefslogblamecommitdiffstats
path: root/testsuites/support/include/buffer_test_io.h
blob: dff312d132ebcfd7c3f947edd0c22ea97581f64c (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                                        




                          
                        

                       



                  
  

                                                    





                                                               




                                                             


                                                          
                                                             

                                                         


      



                               
                        



























                                                                             
 
                                





                                  
       




                                  
        
 





                                 
 


                      
     



                     


                                                                      
                                       
 
                                                            


                                                                       



                                

                       




                             
                                                        



                         

                                        













                                                  




























                                                                               



                                                       
                                                     
     













                                                                               

     










                                                                                        
 

                                 
                                    
                                    
                                    
     
 
        
 
      

                  
  


      
/*
 *  Support for running the test output through a buffer
 */

#ifndef __BUFFER_TEST_IO_h
#define __BUFFER_TEST_IO_h

#include <rtems/bspIo.h>
#include <rtems/test.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Test states. No state string is an expected pass.
 */
#if (TEST_STATE_EXPECTED_FAIL && TEST_STATE_USER_INPUT) || \
    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_INDETERMINATE) || \
    (TEST_STATE_EXPECTED_FAIL && TEST_STATE_BENCHMARK) || \
    (TEST_STATE_USER_INPUT    && TEST_STATE_INDETERMINATE) || \
    (TEST_STATE_USER_INPUT    && TEST_STATE_BENCHMARK) || \
    (TEST_STATE_INDETERMINATE && TEST_STATE_BENCHMARK)
  #error Test states must be unique
#endif

#if TEST_STATE_EXPECTED_FAIL
  #define TEST_STATE_STRING "*** TEST STATE: EXPECTED-FAIL\n"
#elif TEST_STATE_USER_INPUT
  #define TEST_STATE_STRING "*** TEST STATE: USER_INPUT\n"
#elif TEST_STATE_INDETERMINATE
  #define TEST_STATE_STRING "*** TEST STATE: INDETERMINATE\n"
#elif TEST_STATE_BENCHMARK
  #define TEST_STATE_STRING "*** TEST STATE: BENCHMARK\n"
#endif

/*
 *  USE PRINTK TO MINIMIZE SIZE
 */
#if defined(TESTS_USE_PRINTK)

#include <rtems/print.h>

  #undef printf
  #define printf(...) \
    do { \
       printk( __VA_ARGS__); \
    } while (0)

  #undef puts
  #define puts(_s) \
    do { \
       printk( "%s\n", _s); \
    } while (0)

  #undef putchar
  #define putchar(_c) \
    do { \
       printk( "%c", _c ); \
    } while (0)

  /* Do not call exit() since it closes stdin, etc and pulls in stdio code */
  #define rtems_test_exit(_s) \
    do { \
      rtems_shutdown_executive(0); \
    } while (0)

  #define FLUSH_OUTPUT() \
    do { \
    } while (0)

  #if defined(TEST_STATE_STRING)
    #define TEST_BEGIN() \
    do { \
      printk("\n"); \
      printk(TEST_BEGIN_STRING); \
      printk(TEST_STATE_STRING); \
    } while (0)
  #else
    #define TEST_BEGIN() \
    do { \
      printk("\n"); \
      printk(TEST_BEGIN_STRING); \
    } while (0)
  #endif

  #define TEST_END() \
    do { \
       printk( "\n" ); \
       printk(TEST_END_STRING); \
       printk( "\n" ); \
    } while (0)

/*
 *  BUFFER TEST OUTPUT
 */
#else

  #include <stdio.h>
  #include <stdlib.h>

  #define TEST_PRINT__FORMAT(_fmtpos, _appos) \
              __attribute__((__format__(__printf__, _fmtpos, _appos)))

  #define _TEST_OUTPUT_BUFFER_SIZE 2048

  extern char _test_output_buffer[_TEST_OUTPUT_BUFFER_SIZE];

  void _test_output_printf(const char *, ...) TEST_PRINT__FORMAT(1, 2);
  void _test_output_append(const char *);
  void _test_output_flush(void);

  #define rtems_test_exit(_s) \
    do { \
      fflush(stdout); \
      fflush(stderr); \
      _test_output_flush(); \
      exit(_s); \
    } while (0)

  #undef printf
  #define printf(...) _test_output_printf( __VA_ARGS__ )

  #undef puts
  #define puts(_string) \
    do { \
       _test_output_append( _string ); \
       _test_output_append( "\n" ); \
    } while (0)

  #undef putchar
  #define putchar(_c) \
    do { \
       char _buffer[2]; \
       _buffer[0] = _c; \
       _buffer[1] = '\0'; \
       _test_output_append( _buffer ); \
    } while (0)

  /* we write to stderr when there is a pause() */
  #define FLUSH_OUTPUT() _test_output_flush()

  #if defined(TEST_STATE_STRING)
    #define TEST_BEGIN() \
    do { \
       _test_output_append( "\n" ); \
       _test_output_printf(TEST_BEGIN_STRING); \
       _test_output_append(TEST_STATE_STRING); \
       _test_output_append( "\n" ); \
    } while (0)
  #else
    #define TEST_BEGIN() \
      do { \
         _test_output_append( "\n" ); \
         _test_output_printf(TEST_BEGIN_STRING); \
         _test_output_append( "\n" ); \
      } while (0)
  #endif

  #define TEST_END() \
    do { \
       _test_output_append( "\n" ); \
       _test_output_printf(TEST_END_STRING); \
       _test_output_append( "\n" ); \
    } while (0)

  /*
   * Inline the tests this way because adding the code to the support directory
   * requires all the makefile files to changed.
   */
  #if defined(TEST_INIT)

    char _test_output_buffer[_TEST_OUTPUT_BUFFER_SIZE];
    int _test_output_buffer_index = 0;

    void _test_output_printf(const char* format, ...)
    {
      va_list args;
      char*   in;
      size_t  size;
      bool    lf;
      va_start(args, format);
      in = _test_output_buffer + _test_output_buffer_index;
      size = vsniprintf(in,
                        _TEST_OUTPUT_BUFFER_SIZE - _test_output_buffer_index,
                        format, args);
      lf = memchr(in, '\n', size);
      _test_output_buffer_index += size;
      if ( lf || _test_output_buffer_index >= (_TEST_OUTPUT_BUFFER_SIZE - 80) )
        _test_output_flush();
      va_end(args);
    }

    void _test_output_append(const char *_buffer)
    {
      char*  in;
      size_t size;
      bool   lf;
      in = _test_output_buffer + _test_output_buffer_index;
      size = strlcpy(in, _buffer, _TEST_OUTPUT_BUFFER_SIZE - _test_output_buffer_index);
      lf = memchr(in, '\n', size);
      if ( lf || _test_output_buffer_index >= (_TEST_OUTPUT_BUFFER_SIZE - 80) )
        _test_output_flush();
    }

    void _test_output_flush(void)
    {
      printk( _test_output_buffer );
      _test_output_buffer_index = 0;
      _test_output_buffer[0] = '\0';
    }

  #endif

#endif

#ifdef __cplusplus
};
#endif

#endif