Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:51

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsIoReqPutc
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /*
0035  * This file is part of the RTEMS quality process and was automatically
0036  * generated.  If you find something that needs to be fixed or
0037  * worded better please post a report or patch to an RTEMS mailing list
0038  * or raise a bug report:
0039  *
0040  * https://www.rtems.org/bugs.html
0041  *
0042  * For information on updating and regenerating please refer to the How-To
0043  * section in the Software Requirements Engineering chapter of the
0044  * RTEMS Software Engineering manual.  The manual is provided as a part of
0045  * a release.  For development sources please refer to the online
0046  * documentation at:
0047  *
0048  * https://docs.rtems.org
0049  */
0050 
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054 
0055 #include <rtems/bspIo.h>
0056 
0057 #include <rtems/test.h>
0058 
0059 /**
0060  * @defgroup RtemsIoReqPutc spec:/rtems/io/req/putc
0061  *
0062  * @ingroup TestsuitesValidationNoClock0
0063  *
0064  * @{
0065  */
0066 
0067 typedef enum {
0068   RtemsIoReqPutc_Pre_Char_Nl,
0069   RtemsIoReqPutc_Pre_Char_Other,
0070   RtemsIoReqPutc_Pre_Char_NA
0071 } RtemsIoReqPutc_Pre_Char;
0072 
0073 typedef enum {
0074   RtemsIoReqPutc_Post_Output_CrNl,
0075   RtemsIoReqPutc_Post_Output_Other,
0076   RtemsIoReqPutc_Post_Output_NA
0077 } RtemsIoReqPutc_Post_Output;
0078 
0079 typedef struct {
0080   uint8_t Skip : 1;
0081   uint8_t Pre_Char_NA : 1;
0082   uint8_t Post_Output : 2;
0083 } RtemsIoReqPutc_Entry;
0084 
0085 /**
0086  * @brief Test context for spec:/rtems/io/req/putc test case.
0087  */
0088 typedef struct {
0089   /**
0090    * @brief This member contains the character output.
0091    */
0092   int output[ 2 ];
0093 
0094   /**
0095    * @brief This member contains the character output count.
0096    */
0097   size_t output_count;
0098 
0099   /**
0100    * @brief This member specifies if the ``c`` parameter value.
0101    */
0102   char character;
0103 
0104   struct {
0105     /**
0106      * @brief This member defines the pre-condition states for the next action.
0107      */
0108     size_t pcs[ 1 ];
0109 
0110     /**
0111      * @brief If this member is true, then the test action loop is executed.
0112      */
0113     bool in_action_loop;
0114 
0115     /**
0116      * @brief This member contains the next transition map index.
0117      */
0118     size_t index;
0119 
0120     /**
0121      * @brief This member contains the current transition map entry.
0122      */
0123     RtemsIoReqPutc_Entry entry;
0124 
0125     /**
0126      * @brief If this member is true, then the current transition variant
0127      *   should be skipped.
0128      */
0129     bool skip;
0130   } Map;
0131 } RtemsIoReqPutc_Context;
0132 
0133 static RtemsIoReqPutc_Context
0134   RtemsIoReqPutc_Instance;
0135 
0136 static const char * const RtemsIoReqPutc_PreDesc_Char[] = {
0137   "Nl",
0138   "Other",
0139   "NA"
0140 };
0141 
0142 static const char * const * const RtemsIoReqPutc_PreDesc[] = {
0143   RtemsIoReqPutc_PreDesc_Char,
0144   NULL
0145 };
0146 
0147 typedef RtemsIoReqPutc_Context Context;
0148 
0149 static void Output( int value )
0150 {
0151   Context *ctx;
0152 
0153   ctx = T_fixture_context();
0154 
0155   if ( ctx->output_count < RTEMS_ARRAY_SIZE( ctx->output ) ) {
0156     ctx->output[ ctx->output_count ] = value;
0157   }
0158 
0159   ++ctx->output_count;
0160 }
0161 
0162 static void WrongOutput( char c )
0163 {
0164   (void) c;
0165   Output( -1 );
0166 }
0167 
0168 static void OutputChar( char c )
0169 {
0170   BSP_output_char = WrongOutput;
0171   Output( (unsigned char) c );
0172 }
0173 
0174 static void RtemsIoReqPutc_Pre_Char_Prepare(
0175   RtemsIoReqPutc_Context *ctx,
0176   RtemsIoReqPutc_Pre_Char state
0177 )
0178 {
0179   switch ( state ) {
0180     case RtemsIoReqPutc_Pre_Char_Nl: {
0181       /*
0182        * While the ``c`` parameter is equal to ``NL``.
0183        */
0184       ctx->character = '\n';
0185       break;
0186     }
0187 
0188     case RtemsIoReqPutc_Pre_Char_Other: {
0189       /*
0190        * While the ``c`` parameter is not equal to ``NL``.
0191        */
0192       ctx->character = (char) 0xff;
0193       break;
0194     }
0195 
0196     case RtemsIoReqPutc_Pre_Char_NA:
0197       break;
0198   }
0199 }
0200 
0201 static void RtemsIoReqPutc_Post_Output_Check(
0202   RtemsIoReqPutc_Context    *ctx,
0203   RtemsIoReqPutc_Post_Output state
0204 )
0205 {
0206   switch ( state ) {
0207     case RtemsIoReqPutc_Post_Output_CrNl: {
0208       /*
0209        * The function referenced by BSP_output_char shall be called with a
0210        * ``CR`` character followed by a call with a ``NL`` character.
0211        */
0212       T_eq_int( ctx->output[ 0 ], (unsigned char) '\r' );
0213       T_eq_int( ctx->output[ 1 ], (unsigned char) '\n' );
0214       T_eq_sz( ctx->output_count, 2 );
0215       break;
0216     }
0217 
0218     case RtemsIoReqPutc_Post_Output_Other: {
0219       /*
0220        * The function referenced by BSP_output_char shall be called with the
0221        * character specified by ``c``.
0222        */
0223       T_eq_int( ctx->output[ 0 ], 0xff );
0224       T_eq_sz( ctx->output_count, 1 );
0225       break;
0226     }
0227 
0228     case RtemsIoReqPutc_Post_Output_NA:
0229       break;
0230   }
0231 }
0232 
0233 static void RtemsIoReqPutc_Action( RtemsIoReqPutc_Context *ctx )
0234 {
0235   BSP_output_char_function_type output_char;
0236 
0237   ctx->output[ 0 ] = -1;
0238   ctx->output[ 1 ] = -1;
0239   ctx->output_count = 0;
0240   output_char = BSP_output_char;
0241   BSP_output_char = OutputChar;
0242   rtems_putc( ctx->character );
0243   BSP_output_char = output_char;
0244 }
0245 
0246 static const RtemsIoReqPutc_Entry
0247 RtemsIoReqPutc_Entries[] = {
0248   { 0, 0, RtemsIoReqPutc_Post_Output_CrNl },
0249   { 0, 0, RtemsIoReqPutc_Post_Output_Other }
0250 };
0251 
0252 static const uint8_t
0253 RtemsIoReqPutc_Map[] = {
0254   0, 1
0255 };
0256 
0257 static size_t RtemsIoReqPutc_Scope( void *arg, char *buf, size_t n )
0258 {
0259   RtemsIoReqPutc_Context *ctx;
0260 
0261   ctx = arg;
0262 
0263   if ( ctx->Map.in_action_loop ) {
0264     return T_get_scope( RtemsIoReqPutc_PreDesc, buf, n, ctx->Map.pcs );
0265   }
0266 
0267   return 0;
0268 }
0269 
0270 static T_fixture RtemsIoReqPutc_Fixture = {
0271   .setup = NULL,
0272   .stop = NULL,
0273   .teardown = NULL,
0274   .scope = RtemsIoReqPutc_Scope,
0275   .initial_context = &RtemsIoReqPutc_Instance
0276 };
0277 
0278 static inline RtemsIoReqPutc_Entry RtemsIoReqPutc_PopEntry(
0279   RtemsIoReqPutc_Context *ctx
0280 )
0281 {
0282   size_t index;
0283 
0284   index = ctx->Map.index;
0285   ctx->Map.index = index + 1;
0286   return RtemsIoReqPutc_Entries[
0287     RtemsIoReqPutc_Map[ index ]
0288   ];
0289 }
0290 
0291 static void RtemsIoReqPutc_TestVariant( RtemsIoReqPutc_Context *ctx )
0292 {
0293   RtemsIoReqPutc_Pre_Char_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0294   RtemsIoReqPutc_Action( ctx );
0295   RtemsIoReqPutc_Post_Output_Check( ctx, ctx->Map.entry.Post_Output );
0296 }
0297 
0298 /**
0299  * @fn void T_case_body_RtemsIoReqPutc( void )
0300  */
0301 T_TEST_CASE_FIXTURE( RtemsIoReqPutc, &RtemsIoReqPutc_Fixture )
0302 {
0303   RtemsIoReqPutc_Context *ctx;
0304 
0305   ctx = T_fixture_context();
0306   ctx->Map.in_action_loop = true;
0307   ctx->Map.index = 0;
0308 
0309   for (
0310     ctx->Map.pcs[ 0 ] = RtemsIoReqPutc_Pre_Char_Nl;
0311     ctx->Map.pcs[ 0 ] < RtemsIoReqPutc_Pre_Char_NA;
0312     ++ctx->Map.pcs[ 0 ]
0313   ) {
0314     ctx->Map.entry = RtemsIoReqPutc_PopEntry( ctx );
0315     RtemsIoReqPutc_TestVariant( ctx );
0316   }
0317 }
0318 
0319 /** @} */