| /* libraries.c - test access to the minimal C libraries */ |
| |
| /* |
| * Copyright (c) 2014 Wind River Systems, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| DESCRIPTION |
| This module verifies that the various minimal C libraries can be used. |
| |
| IMPORTANT: The module only ensures that each supported library is present, |
| and that a bare minimum of its functionality is operating correctly. It does |
| NOT guarantee that ALL standards-defined functionality is present, nor does |
| it guarantee that ALL functionality provided is working correctly. |
| */ |
| |
| #include <zephyr.h> |
| #include <tc_util.h> |
| |
| #include <limits.h> |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <string.h> |
| |
| /* |
| * variables used during limits library testing; must be marked as "volatile" |
| * to prevent compiler from computing results at compile time |
| */ |
| |
| volatile long longMax = LONG_MAX; |
| volatile long longOne = 1L; |
| |
| /** |
| * |
| * @brief Test implementation-defined constants library |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int limitsTest(void) |
| { |
| TC_PRINT("Testing limits.h library ...\n"); |
| |
| if (longMax + longOne != LONG_MIN) { |
| return TC_FAIL; |
| } |
| |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test boolean types and values library |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int stdboolTest(void) |
| { |
| TC_PRINT("Testing stdbool.h library ...\n"); |
| |
| if ((true != 1) || (false != 0)) { |
| return TC_FAIL; |
| } |
| |
| return TC_PASS; |
| } |
| |
| /* |
| * variables used during stddef library testing; must be marked as "volatile" |
| * to prevent compiler from computing results at compile time |
| */ |
| |
| volatile long longVariable; |
| volatile size_t sizeOfLongVariable = sizeof(longVariable); |
| |
| /** |
| * |
| * @brief Test standard type definitions library |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int stddefTest(void) |
| { |
| TC_PRINT("Testing stddef.h library ...\n"); |
| |
| if (sizeOfLongVariable != 4) { |
| return TC_FAIL; |
| } |
| |
| return TC_PASS; |
| } |
| |
| /* |
| * variables used during stdint library testing; must be marked as "volatile" |
| * to prevent compiler from computing results at compile time |
| */ |
| |
| volatile uint8_t unsignedByte = 0xff; |
| volatile uint32_t unsignedInt = 0xffffff00; |
| |
| /** |
| * |
| * @brief Test integer types library |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int stdintTest(void) |
| { |
| TC_PRINT("Testing stdint.h library ...\n"); |
| |
| if (unsignedInt + unsignedByte + 1u != 0) { |
| return TC_FAIL; |
| } |
| |
| return TC_PASS; |
| } |
| |
| /* |
| * variables used during string library testing |
| */ |
| |
| #define BUFSIZE 10 |
| |
| char buffer[BUFSIZE]; |
| |
| /** |
| * |
| * @brief Test string memset |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int memset_test(void) |
| { |
| TC_PRINT("\tmemset ...\t"); |
| |
| memset(buffer, 'a', BUFSIZE); |
| if (buffer[0] != 'a' || buffer[BUFSIZE-1] != 'a') { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| TC_PRINT("passed\n"); |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test string length function |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int strlen_test(void) |
| { |
| TC_PRINT("\tstrlen ...\t"); |
| |
| memset(buffer, '\0', BUFSIZE); |
| memset(buffer, 'b', 5); /* 5 is BUFSIZE / 2 */ |
| if (strlen(buffer) != 5) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| TC_PRINT("passed\n"); |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test string compare function |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int strcmp_test(void) |
| { |
| strcpy(buffer, "eeeee"); |
| |
| TC_PRINT("\tstrcmp less ...\t"); |
| if (strcmp(buffer, "fffff") >= 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } else { |
| TC_PRINT("passed\n"); |
| } |
| |
| TC_PRINT("\tstrcmp equal ...\t"); |
| if (strcmp(buffer, "eeeee") != 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } else { |
| TC_PRINT("passed\n"); |
| } |
| |
| TC_PRINT("\tstrcmp greater ...\t"); |
| if (strcmp(buffer, "ddddd") <= 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } else { |
| TC_PRINT("passed\n"); |
| } |
| |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test string N compare function |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int strncmp_test(void) |
| { |
| strncpy(buffer, "eeeeeeeeeeee", BUFSIZE); |
| |
| TC_PRINT("\tstrncmp 0 ...\t"); |
| if (strncmp(buffer, "fffff", 0) != 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } else { |
| TC_PRINT("passed\n"); |
| } |
| |
| TC_PRINT("\tstrncmp 3 ...\t"); |
| if (strncmp(buffer, "eeeff", 3) != 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } else { |
| TC_PRINT("passed\n"); |
| } |
| |
| TC_PRINT("\tstrncmp 10 ...\t"); |
| if (strncmp(buffer, "eeeeeeeeeeeff", BUFSIZE) != 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } else { |
| TC_PRINT("passed\n"); |
| } |
| |
| return TC_PASS; |
| } |
| |
| |
| /** |
| * |
| * @brief Test string copy function |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int strcpy_test(void) |
| { |
| TC_PRINT("\tstrcpy ...\t"); |
| |
| memset(buffer, '\0', BUFSIZE); |
| strcpy(buffer, "10 chars!!\0"); |
| |
| if (strcmp(buffer, "10 chars!!\0") != 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| TC_PRINT("passed\n"); |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test string N copy function |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int strncpy_test(void) |
| { |
| TC_PRINT("\tstrncpy ...\t"); |
| |
| memset(buffer, '\0', BUFSIZE); |
| strncpy(buffer, "This is over 10 characters", BUFSIZE); |
| |
| /* Purposely different values */ |
| if (strncmp(buffer, "This is over 20 characters", BUFSIZE) != 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| TC_PRINT("passed\n"); |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test string scanning function |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int strchr_test(void) |
| { |
| char *rs = NULL; |
| TC_PRINT("\tstrchr ...\t"); |
| |
| memset(buffer, '\0', BUFSIZE); |
| strncpy(buffer, "Copy 10", BUFSIZE); |
| |
| rs = strchr(buffer, '1'); |
| |
| if (!rs) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| if (strncmp(rs, "10", 2) != 0) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| TC_PRINT("passed\n"); |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test memory comparison function |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int memcmp_test(void) |
| { |
| unsigned char m1[5] = { 1, 2, 3, 4, 5 }; |
| unsigned char m2[5] = { 1, 2, 3, 4, 6 }; |
| |
| TC_PRINT("\tmemcmp ...\t"); |
| |
| if (memcmp(m1, m2, 4)) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| if (!memcmp(m1, m2, 5)) { |
| TC_PRINT("failed\n"); |
| return TC_FAIL; |
| } |
| |
| TC_PRINT("passed\n"); |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Test string operations library |
| * * @return TC_PASS or TC_FAIL |
| */ |
| |
| int stringTest(void) |
| { |
| TC_PRINT("Testing string.h library ...\n"); |
| |
| if (memset_test() || strlen_test() || strcmp_test() || strcpy_test() || |
| strncpy_test() || strncmp_test() || strchr_test() || |
| memcmp_test()) { |
| return TC_FAIL; |
| } |
| |
| return TC_PASS; |
| } |
| |
| /** |
| * |
| * @brief Main task in the test suite |
| * |
| * This is the entry point to the main task used by the standard libraries test |
| * suite. It tests each library in turn until a failure is detected or all |
| * libraries have been tested successfully. |
| * |
| * @return TC_PASS or TC_FAIL |
| */ |
| |
| int RegressionTask(void) |
| { |
| TC_PRINT("Validating access to supported libraries\n"); |
| |
| if (limitsTest() || stdboolTest() || stddefTest() || |
| stdintTest() || stringTest()) { |
| TC_PRINT("Library validation failed\n"); |
| return TC_FAIL; |
| } |
| |
| TC_PRINT("Validation complete\n"); |
| return TC_PASS; |
| } |