File indexing completed on 2025-05-11 08:24:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
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
0061
0062
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
0087
0088 typedef struct {
0089
0090
0091
0092 int output[ 2 ];
0093
0094
0095
0096
0097 size_t output_count;
0098
0099
0100
0101
0102 char character;
0103
0104 struct {
0105
0106
0107
0108 size_t pcs[ 1 ];
0109
0110
0111
0112
0113 bool in_action_loop;
0114
0115
0116
0117
0118 size_t index;
0119
0120
0121
0122
0123 RtemsIoReqPutc_Entry entry;
0124
0125
0126
0127
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
0183
0184 ctx->character = '\n';
0185 break;
0186 }
0187
0188 case RtemsIoReqPutc_Pre_Char_Other: {
0189
0190
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
0210
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
0221
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
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