/* 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 #include #include #include #include #include #include /* * 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; }