├── .github └── workflows │ ├── Valgrind.yml │ ├── c-build.yml │ ├── cppcheck.yml │ └── unit-test.yml ├── .gitignore ├── Doxygen_document.md ├── Example_Programs ├── Challenges │ └── Colored_box │ │ └── README.md ├── Factorial │ ├── Factorial.cbp │ ├── Makefile │ ├── documentation │ │ ├── Doxyfile │ │ └── Makefile │ ├── inc │ │ ├── documentation_main.md │ │ └── factorial.h │ ├── main.c │ ├── src │ │ └── factorial.c │ ├── test │ │ ├── test_factorial.c │ │ └── test_factorial.h │ └── unity │ │ ├── unity.c │ │ ├── unity.h │ │ └── unity_internals.h ├── PhoneBook │ ├── Makefile │ ├── doc │ │ └── documentation.md │ ├── inc │ │ ├── add_contact.h │ │ ├── contact.h │ │ ├── delete_contact.h │ │ ├── display_contact.h │ │ ├── modify_contact.h │ │ ├── phone_book.h │ │ ├── search_contact.h │ │ └── utility.h │ ├── phone_book.c │ ├── src │ │ ├── add_contact.c │ │ ├── delete_contact.c │ │ ├── display_contact.c │ │ ├── modify_contact.c │ │ ├── search_contact.c │ │ └── utility.c │ ├── test │ │ └── phone_book_test.c │ └── unity │ │ ├── unity.c │ │ ├── unity.h │ │ └── unity_internals.h └── programming_concpets │ ├── Basics │ ├── 0_helloworld.c │ ├── 1_memory_map.c │ ├── 2_lazy_evaluation.c │ ├── 3_sequence_points.c │ ├── 4_pre_processors.c │ ├── 5_recursion.c │ ├── 6_inline_functions.c │ ├── 7_min_array.c │ └── Makefile │ ├── Questions_2a │ ├── README.md │ └── data.csv │ ├── array_of_structures │ ├── Array_of_boxes.c │ └── Makefile │ ├── calculator │ ├── Makefile │ ├── calculator.c │ ├── calculator.h │ ├── test_calculator.c │ └── unity │ │ ├── unity.c │ │ ├── unity.h │ │ └── unity_internals.h │ ├── calculator_complex │ ├── Makefile │ ├── README.md │ ├── doc │ │ ├── Complex_Calc_Doxyfile │ │ ├── Makefile │ │ └── doc_main.md │ ├── inc │ │ └── complex_calculator.h │ ├── main.c │ ├── src │ │ └── complex_calculator.c │ ├── test │ │ └── test_complex_calculator.c │ └── unity │ │ ├── unity.c │ │ ├── unity.h │ │ └── unity_internals.h │ ├── functions_pointers │ ├── 1_array_passing.c │ ├── 2a_function_ptr.c │ ├── 2b_function_ptr_typedef.c │ └── 2c_function_ptr_array.c │ ├── multi_file │ ├── Makefile │ ├── inc │ │ └── fun.h │ ├── src │ │ ├── sqr.c │ │ └── sum.c │ └── test.c │ ├── pointer_operations │ ├── 1a_pointer_arithmetic.c │ ├── 1b_const_with_pointesr.c │ ├── 1c_precedence_associativity_pointers.c │ └── demo.c │ └── tools_examples │ ├── gdb-examples │ ├── example1.c │ ├── example2.c │ ├── example3.c │ ├── example4.c │ └── example5.c │ ├── make-examples │ ├── tuto1 │ │ ├── fun.h │ │ ├── sqr.c │ │ ├── sum.c │ │ └── test.c │ ├── tuto2 │ │ ├── Makefile │ │ ├── README.md │ │ ├── fun.h │ │ ├── sqr.c │ │ ├── sum.c │ │ └── test.c │ ├── tuto3 │ │ ├── Makefile │ │ ├── README.md │ │ ├── fun.h │ │ ├── sqr.c │ │ ├── sum.c │ │ └── test.c │ ├── tuto4 │ │ ├── Makefile │ │ ├── README.md │ │ ├── fun.h │ │ ├── sqr.c │ │ ├── sum.c │ │ └── test.c │ ├── tuto5 │ │ ├── Makefile │ │ ├── README.md │ │ ├── include │ │ │ └── fun.h │ │ ├── src │ │ │ ├── sqr.c │ │ │ └── sum.c │ │ └── test.c │ └── tuto6 │ │ ├── Makefile │ │ ├── README.md │ │ ├── include │ │ └── fun.h │ │ ├── src │ │ ├── sqr.c │ │ └── sum.c │ │ └── test.c │ └── valgrind-examples │ ├── README.md │ ├── example1.c │ ├── example2.c │ ├── example3.c │ ├── example4.c │ └── example5.c ├── GitHub_Workflow.md ├── GitSetup.md ├── HOWTO.md ├── LICENSE ├── Linux_Setup.md ├── MiniProject_C ├── 0_Certificates │ └── README.md ├── 1_Requirements │ ├── README.md │ └── Simple Gantt Chart.xlsx ├── 2_Architecture │ ├── README.md │ ├── behavior Diagrams │ │ └── README.md │ └── structure Diagrams │ │ └── README.md ├── 3_Implementation │ ├── Makefile │ ├── documentation │ │ ├── Calculator_Doxyfile │ │ ├── Doxyfile │ │ └── Makefile │ ├── inc │ │ ├── calculator_operations.h │ │ └── documentation_main.md │ ├── project_main.c │ ├── src │ │ └── calculator_operations.c │ ├── test │ │ └── test_calculator_operations.c │ └── unity │ │ ├── unity.c │ │ ├── unity.h │ │ └── unity_internals.h ├── 4_TestPlanAndOutput │ └── README.md ├── 5_Report │ └── README.md ├── 6_ImagesAndVideos │ └── README.md ├── 7_Other │ ├── README.md │ └── data-set │ │ └── README.md └── README.md ├── Multifile_Programming.md ├── README.md ├── SETUP.md ├── Windows_Setup.md ├── azure-pipelines.yml └── images ├── CodeMetrics.png ├── Doxygen1.png ├── Linux_doxygen1.png ├── Linux_doxygen2.png ├── Linux_doxygen3.png ├── Linux_doxygen4.png ├── Linux_doxygen5.png ├── Linux_doxygen6.png ├── Linux_doxygen7.png ├── Linux_doxygen8.png ├── New_repo.png ├── New_repo2.png ├── New_repo3.png ├── Workflow_create.png ├── Workflow_create0.png ├── Workflow_create2.png ├── Workflow_create3.png ├── Workflow_create4.png ├── Workflow_create5.png ├── Workflow_create6.png ├── Workflow_create7.png ├── Workflow_create8.png ├── Workflow_create9.png ├── clone1.png ├── clone2.png ├── clone3.png ├── clone4.png ├── clone5.png ├── clone6.png ├── commit1.png ├── commit2.png ├── commit3.png ├── commit4.png ├── commit5.png ├── doxywizard.png └── doxywizard1.png /.github/workflows/Valgrind.yml: -------------------------------------------------------------------------------- 1 | name: Valgrind 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: apt install dependency 17 | run: | 18 | sudo apt-get -y install valgrind 19 | sudo apt-get -y install libcunit1 libcunit1-doc libcunit1-dev 20 | - name: make test 21 | run: | 22 | make test -C MiniProject_C/3_Implementation/ 23 | valgrind ./MiniProject_C/3_Implementation/build/Test_Calculator.out 24 | -------------------------------------------------------------------------------- /.github/workflows/c-build.yml: -------------------------------------------------------------------------------- 1 | name: C/C++ CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - name: make all 18 | run: make all -C MiniProject_C/3_Implementation/ 19 | -------------------------------------------------------------------------------- /.github/workflows/cppcheck.yml: -------------------------------------------------------------------------------- 1 | 2 | name: cppcheck-action 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | name: cppcheck 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | 12 | - name: Install cppcheck 13 | run: sudo apt-get -y install cppcheck 14 | - name: Cppcheck code 15 | run: cppcheck MiniProject_C/3_Implementation -------------------------------------------------------------------------------- /.github/workflows/unit-test.yml: -------------------------------------------------------------------------------- 1 | name: Unit testing 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Install Cunit 17 | run: sudo apt-get -y install libcunit1 libcunit1-doc libcunit1-dev 18 | - name: make test 19 | run: make test -C MiniProject_C/3_Implementation/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gcda 2 | *.gcno 3 | *.gcov 4 | .vscode 5 | # Doxygen Ouput 6 | *html 7 | # Prerequisites 8 | *.d 9 | 10 | # Object files 11 | *.o 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Linker output 17 | *.ilk 18 | *.map 19 | *.exp 20 | 21 | # Precompiled Headers 22 | *.gch 23 | *.pch 24 | 25 | # Libraries 26 | *.lib 27 | *.a 28 | *.la 29 | *.lo 30 | 31 | # Shared objects (inc. Windows DLLs) 32 | *.dll 33 | *.so 34 | *.so.* 35 | *.dylib 36 | 37 | # Executables 38 | *.exe 39 | *.out 40 | *.app 41 | *.i*86 42 | *.x86_64 43 | *.hex 44 | 45 | # Debug files 46 | *.dSYM/ 47 | *.su 48 | *.idb 49 | *.pdb 50 | 51 | # Kernel Module Compile Results 52 | *.mod* 53 | *.cmd 54 | .tmp_versions/ 55 | modules.order 56 | Module.symvers 57 | Mkfile.old 58 | dkms.conf 59 | -------------------------------------------------------------------------------- /Doxygen_document.md: -------------------------------------------------------------------------------- 1 | # Code Documentation using Doxygen based comments 2 | ## Step-1: Create files 3 | * Create a two new folders **documentation** and **inc** under your project 4 | * Create a file named **documentation_main.md** inside **inc** folder 5 | ``` 6 | @mainpage Calculator Application by "Your name" 7 | @subpage calculator_operations.h 8 | ``` 9 | 10 | * Create **calculator_operations.h** file with below content under **inc** folder 11 | ``` 12 | /** 13 | * @file calculator_operations.h 14 | * @author Your Name 15 | * @brief Header file for Calculator application with Arithmetic operations 16 | * 17 | */ 18 | 19 | #ifndef __CALCULATOR_OPERATIONS_H__ 20 | #define __CALCULATOR_OPERATIONS_H__ 21 | 22 | #include 23 | #include 24 | 25 | /** 26 | * @brief Adds the operand1 and operand2 and returns the result 27 | * @param[in] operand1 28 | * @param[in] operand2 29 | * @return Result of operand1 + operand2 30 | */ 31 | int add(int operand1, int operand2); 32 | 33 | /** 34 | * @brief Subtracts the operand1, operand2 and returns the result 35 | * @param[in] operand1 36 | * @param[in] operand2 37 | * @return Result of operand1 - operand2 38 | */ 39 | int subtract(int operand1, int operand2); 40 | 41 | /** 42 | * @brief Multiply the operand1, operand2 and returns the result 43 | * @param[in] operand1 44 | * @param[in] operand2 45 | * @return Result of operand1 * operand2 46 | */ 47 | int multiply(int operand1, int operand2); 48 | 49 | /** 50 | * @brief Divides the operand1 by operand2 and returns the result 51 | * @param[in] operand1 52 | * @param[in] operand2 53 | * @return integer value of the operand1 / operand2 54 | * @note returns 0 for divide by 0 error 55 | */ 56 | int divide(int operand1, int operand2); 57 | 58 | #endif /* #define __CALCULATOR_OPERATIONS_H__ */ 59 | ``` 60 | ## Step-2: Create Doxyfile 61 | ### Launch Doxywizard 62 | * If not already installed Doxygen, install based on your OS: [Windows](https://github.com/stepin654321/MiniProject_Template/wiki/Windows_Setup#documentation), [Linux](https://github.com/stepin654321/MiniProject_Template/wiki/Linux_Setup#documentation) 63 | 64 | #### Windows OS 65 | |Step-1|Step-2| 66 | |:--:|:--:| 67 | |![Doxywizard](images/doxywizard.png)|![Doxywizard](images/doxywizard1.png)| 68 | 69 | #### Linux OS 70 | * Type the below command 71 | ``` 72 | doxywizard 73 | ``` 74 | |Step-1| 75 | |:--:| 76 | |![Doxywizard](images/Linux_doxygen1.png)| 77 | 78 | ### Creating Doxygen file 79 | * Change the Project name to "Calculator". 80 | * Save the file as **Calculator_Doxyfile** under your project's **documentation** folder 81 | ``` 82 | File -> Save -> Path 83 | ``` 84 | * Folder structure should now look like this 85 | ``` 86 | Project 87 | documentation 88 | Calculator_Doxfile 89 | inc 90 | calculator_operations.h 91 | documentation_main.md 92 | ``` 93 | ## Step-3: Configure the Doxyfile 94 | ### Setup Paths 95 | * Specify **Source code directory**. Select the folder where header files with doxygen comments are placed. 96 | * We placed the header file in **inc** 97 | * Select the option **Scan recursively** 98 | * To include any sub folders for documentation 99 | * Select the **Destination directory** where all the documents must be placed. In our case it is the current folder where Doxyfile is placed. 100 | * **Save** and click on **Next** 101 | 102 | |Setup Paths| 103 | |:--:| 104 | |![Doxywizard](images/Linux_doxygen2.png)| 105 | 106 | ### Setup Mode 107 | * Change the Optimization method to C 108 | * **Save** and click on **Next** 109 | 110 | |Setup Mode| 111 | |:--:| 112 | |![Doxywizard](images/Linux_doxygen3.png)| 113 | 114 | ### Setup Output 115 | * Select the mode as **HTML** only 116 | * And click on **Next** 117 | 118 | |Setup Output| 119 | |:--:| 120 | |![Doxywizard](images/Linux_doxygen4.png)| 121 | 122 | ### Setup Diagrams 123 | * Select **No Diagrams** 124 | * **Save** and click on **Next** 125 | 126 | |Setup Diagrams| 127 | |:--:| 128 | |![Doxywizard](images/Linux_doxygen5.png)| 129 | 130 | ## Step-4: Generate Documents 131 | * Click **Run doxygen** and check that it is finished without errors. 132 | * **Save** the changes done sar far 133 | ``` 134 | File -> Save 135 | ``` 136 | 137 | |Generate Documents| 138 | |:--:| 139 | |![Doxywizard](images/Linux_doxygen6.png)| 140 | 141 | ## Step-5: View Generated Documents 142 | * Click **Show HTML Output** to view genrated files in browser. 143 | * All the files generated by Doxygen are placed under **documentation/html** folder. 144 | * To view the documentation, one can open **index.html** file. 145 | 146 | * Click on **calculator_operations.h** to view docuemnts for functions. 147 | 148 | |Main Page|Subpage| 149 | |:--:|:--:| 150 | |![Doxywizard](images/Linux_doxygen7.png)|![Doxywizard](images/Linux_doxygen8.png)| 151 | 152 | ## Step-6: Learning more about Doxygen 153 | * To understand each option of Doxygen Follow this [Tutorial1](https://embeddedinventor.com/guide-to-configure-doxygen-to-document-c-source-code-for-beginners/) and [Tutorial2](https://os.mbed.com/media/uploads/defiantgti/doxygentutorial.pdf) 154 | 155 | # Notes 156 | * For generating the cdocuemnts after some changes or additions, we can reuse the generated **Calculator_Doxyfile** by opening it from Doxywizard application 157 | ``` 158 | File-> Open 159 | ``` 160 | -------------------------------------------------------------------------------- /Example_Programs/Challenges/Colored_box/README.md: -------------------------------------------------------------------------------- 1 | # A weighted colored Box 2 | A Box is associated with following attributes: 3 | ``` 4 | unique id 5 | length 6 | breadth 7 | height 8 | color 9 | weight 10 | ``` 11 | ### Write seperate functions to perform the following operations: 12 | * Create an collection(array or linked list) of boxes using dynamic memory 13 | * Add a box at end of the collection 14 | * Display the state of all boxes 15 | * Find the box with given id 16 | * Count all boxes with specified color 17 | * Find average volume of all boxes 18 | * Find the difference between box with min volume and box with max volume 19 | * Find the box which has maximum height 20 | * Update weight of box having a given id 21 | * Remove the Box with given id 22 | * Create a structure to define Weighted Colored Box as encapsulated unit (Single structure with pointer to data and pointer to functions) 23 | 24 | ## Guidelines 25 | * Use dynamic memory allocation for arrays and structures. 26 | * Return appropriate results from all the functions instead of printing. 27 | * Follow Modular programming and multifile approach 28 | * Create Makefile with targets for compiling and testing, analysis and coverage. 29 | * Follow best practices while writing the code. 30 | 31 | ## Solutions 32 | * By [Arnob Chowdhury](https://github.com/arc-arnob/LnT-Assignments/tree/master/Colored_box) 33 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/Factorial.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 48 | 49 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/Makefile: -------------------------------------------------------------------------------- 1 | SRC = unity/unity.c\ 2 | src/factorial.c\ 3 | test/test_factorial.c\ 4 | main.c 5 | 6 | INC = -Iunity\ 7 | -Iinc\ 8 | -Itest 9 | 10 | PROJECT_NAME = FACTORIAL.exe 11 | 12 | $(PROJECT_NAME): $(SRC) 13 | gcc $(SRC) $(INC) -o $(PROJECT_NAME) 14 | 15 | run:$(PROJECT_NAME) 16 | ./${PROJECT_NAME} 17 | doc: 18 | make -C documentation 19 | 20 | clean: 21 | rm -rf $(PROJECT_NAME) documentation/html 22 | 23 | coverage:${PROJECT_NAME} 24 | gcc -fprofile-arcs -ftest-coverage $(SRC) $(INC) -o $(PROJECT_NAME) 25 | ./${PROJECT_NAME} 26 | gcov -a src/factorial.c main.c -------------------------------------------------------------------------------- /Example_Programs/Factorial/documentation/Makefile: -------------------------------------------------------------------------------- 1 | # Document the code using Doxygen 2 | 3 | doc: Doxyfile 4 | doxygen ./Doxyfile -------------------------------------------------------------------------------- /Example_Programs/Factorial/inc/documentation_main.md: -------------------------------------------------------------------------------- 1 | @mainpage Factorial Application by Bharath G 2 | @subpage factorial.h 3 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/inc/factorial.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file factorial.h 3 | * 4 | */ 5 | #ifndef __FACTORIAL_H__ 6 | #define __FACTORIAL_H__ 7 | 8 | /** 9 | * Calculates the factorial of integer number 10 | * @param[in] number for which factorial has to be found 11 | * @return Factorial of the number 12 | * @note Returns -1 for negative values 13 | */ 14 | int factorial(int number); 15 | 16 | #endif /* #ifndef __FACTORIAL_H__ */ 17 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/main.c: -------------------------------------------------------------------------------- 1 | #include "test_factorial.h" 2 | 3 | int main(void) 4 | { 5 | test_main(); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/src/factorial.c: -------------------------------------------------------------------------------- 1 | #include "factorial.h" 2 | 3 | int factorial(int number) 4 | { 5 | /* Return -1 for negative numbers */ 6 | if(number < 0) 7 | return -1; 8 | 9 | /* Return 1 for 0 */ 10 | if(number == 0) 11 | return 1; 12 | 13 | /* Recursively calculate Factorial of the number */ 14 | return number * factorial(number-1); 15 | } 16 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/test/test_factorial.c: -------------------------------------------------------------------------------- 1 | #include "unity.h" 2 | #include "factorial.h" 3 | /* Required by the unity test framework */ 4 | void setUp(){} 5 | /* Required by the unity test framework */ 6 | void tearDown(){} 7 | 8 | void test_factorial(void) 9 | { 10 | TEST_ASSERT_EQUAL(120, factorial(5)); 11 | TEST_ASSERT_EQUAL(720, factorial(6)); 12 | } 13 | void test_zero_one(void) 14 | { 15 | TEST_ASSERT_EQUAL(1, factorial(0)); 16 | TEST_ASSERT_EQUAL(1, factorial(1)); 17 | } 18 | void test_negative(void) 19 | { 20 | TEST_ASSERT_EQUAL(-1, factorial(-5)); 21 | TEST_ASSERT_EQUAL(-1, factorial(-10)); 22 | } 23 | 24 | int test_main(void) 25 | { 26 | /* Initiate the Unity Test Framework */ 27 | UNITY_BEGIN(); 28 | 29 | /* Run Test functions */ 30 | RUN_TEST(test_factorial); 31 | RUN_TEST(test_zero_one); 32 | RUN_TEST(test_negative); 33 | 34 | /* Close the Unity Test Framework */ 35 | return UNITY_END(); 36 | } 37 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/test/test_factorial.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEST_FACTORIAL_H__ 2 | #define __TEST_FACTORIAL_H__ 3 | 4 | int test_main(void); 5 | 6 | #endif /* #ifndef __TEST_FACTORIAL_H__ */ 7 | -------------------------------------------------------------------------------- /Example_Programs/Factorial/unity/unity.c: -------------------------------------------------------------------------------- 1 | /* ========================================================================= 2 | Unity Project - A Test Framework for C 3 | Copyright (c) 2007-19 Mike Karlesky, Mark VanderVoord, Greg Williams 4 | [Released under MIT License. Please refer to license.txt for details] 5 | ============================================================================ */ 6 | 7 | #include "unity.h" 8 | #include 9 | 10 | #ifdef AVR 11 | #include 12 | #else 13 | #define PROGMEM 14 | #endif 15 | 16 | /* If omitted from header, declare overrideable prototypes here so they're ready for use */ 17 | #ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION 18 | void UNITY_OUTPUT_CHAR(int); 19 | #endif 20 | 21 | /* Helpful macros for us to use here in Assert functions */ 22 | #define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } 23 | #define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; UNITY_OUTPUT_FLUSH(); TEST_ABORT(); } 24 | #define RETURN_IF_FAIL_OR_IGNORE if (Unity.CurrentTestFailed || Unity.CurrentTestIgnored) TEST_ABORT() 25 | 26 | struct UNITY_STORAGE_T Unity; 27 | 28 | #ifdef UNITY_OUTPUT_COLOR 29 | const char PROGMEM UnityStrOk[] = "\033[42mOK\033[00m"; 30 | const char PROGMEM UnityStrPass[] = "\033[42mPASS\033[00m"; 31 | const char PROGMEM UnityStrFail[] = "\033[41mFAIL\033[00m"; 32 | const char PROGMEM UnityStrIgnore[] = "\033[43mIGNORE\033[00m"; 33 | #else 34 | const char PROGMEM UnityStrOk[] = "OK"; 35 | const char PROGMEM UnityStrPass[] = "PASS"; 36 | const char PROGMEM UnityStrFail[] = "FAIL"; 37 | const char PROGMEM UnityStrIgnore[] = "IGNORE"; 38 | #endif 39 | static const char PROGMEM UnityStrNull[] = "NULL"; 40 | static const char PROGMEM UnityStrSpacer[] = ". "; 41 | static const char PROGMEM UnityStrExpected[] = " Expected "; 42 | static const char PROGMEM UnityStrWas[] = " Was "; 43 | static const char PROGMEM UnityStrGt[] = " to be greater than "; 44 | static const char PROGMEM UnityStrLt[] = " to be less than "; 45 | static const char PROGMEM UnityStrOrEqual[] = "or equal to "; 46 | static const char PROGMEM UnityStrNotEqual[] = " to be not equal to "; 47 | static const char PROGMEM UnityStrElement[] = " Element "; 48 | static const char PROGMEM UnityStrByte[] = " Byte "; 49 | static const char PROGMEM UnityStrMemory[] = " Memory Mismatch."; 50 | static const char PROGMEM UnityStrDelta[] = " Values Not Within Delta "; 51 | static const char PROGMEM UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; 52 | static const char PROGMEM UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; 53 | static const char PROGMEM UnityStrNullPointerForActual[] = " Actual pointer was NULL"; 54 | #ifndef UNITY_EXCLUDE_FLOAT 55 | static const char PROGMEM UnityStrNot[] = "Not "; 56 | static const char PROGMEM UnityStrInf[] = "Infinity"; 57 | static const char PROGMEM UnityStrNegInf[] = "Negative Infinity"; 58 | static const char PROGMEM UnityStrNaN[] = "NaN"; 59 | static const char PROGMEM UnityStrDet[] = "Determinate"; 60 | static const char PROGMEM UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; 61 | #endif 62 | const char PROGMEM UnityStrErrShorthand[] = "Unity Shorthand Support Disabled"; 63 | const char PROGMEM UnityStrErrFloat[] = "Unity Floating Point Disabled"; 64 | const char PROGMEM UnityStrErrDouble[] = "Unity Double Precision Disabled"; 65 | const char PROGMEM UnityStrErr64[] = "Unity 64-bit Support Disabled"; 66 | static const char PROGMEM UnityStrBreaker[] = "-----------------------"; 67 | static const char PROGMEM UnityStrResultsTests[] = " Tests "; 68 | static const char PROGMEM UnityStrResultsFailures[] = " Failures "; 69 | static const char PROGMEM UnityStrResultsIgnored[] = " Ignored "; 70 | static const char PROGMEM UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; 71 | static const char PROGMEM UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; 72 | 73 | /*----------------------------------------------- 74 | * Pretty Printers & Test Result Output Handlers 75 | *-----------------------------------------------*/ 76 | 77 | /*-----------------------------------------------*/ 78 | /* Local helper function to print characters. */ 79 | static void UnityPrintChar(const char* pch) 80 | { 81 | /* printable characters plus CR & LF are printed */ 82 | if ((*pch <= 126) && (*pch >= 32)) 83 | { 84 | UNITY_OUTPUT_CHAR(*pch); 85 | } 86 | /* write escaped carriage returns */ 87 | else if (*pch == 13) 88 | { 89 | UNITY_OUTPUT_CHAR('\\'); 90 | UNITY_OUTPUT_CHAR('r'); 91 | } 92 | /* write escaped line feeds */ 93 | else if (*pch == 10) 94 | { 95 | UNITY_OUTPUT_CHAR('\\'); 96 | UNITY_OUTPUT_CHAR('n'); 97 | } 98 | /* unprintable characters are shown as codes */ 99 | else 100 | { 101 | UNITY_OUTPUT_CHAR('\\'); 102 | UNITY_OUTPUT_CHAR('x'); 103 | UnityPrintNumberHex((UNITY_UINT)*pch, 2); 104 | } 105 | } 106 | 107 | /*-----------------------------------------------*/ 108 | /* Local helper function to print ANSI escape strings e.g. "\033[42m". */ 109 | #ifdef UNITY_OUTPUT_COLOR 110 | static UNITY_UINT UnityPrintAnsiEscapeString(const char* string) 111 | { 112 | const char* pch = string; 113 | UNITY_UINT count = 0; 114 | 115 | while (*pch && (*pch != 'm')) 116 | { 117 | UNITY_OUTPUT_CHAR(*pch); 118 | pch++; 119 | count++; 120 | } 121 | UNITY_OUTPUT_CHAR('m'); 122 | count++; 123 | 124 | return count; 125 | } 126 | #endif 127 | 128 | /*-----------------------------------------------*/ 129 | void UnityPrint(const char* string) 130 | { 131 | const char* pch = string; 132 | 133 | if (pch != NULL) 134 | { 135 | while (*pch) 136 | { 137 | #ifdef UNITY_OUTPUT_COLOR 138 | /* print ANSI escape code */ 139 | if ((*pch == 27) && (*(pch + 1) == '[')) 140 | { 141 | pch += UnityPrintAnsiEscapeString(pch); 142 | continue; 143 | } 144 | #endif 145 | UnityPrintChar(pch); 146 | pch++; 147 | } 148 | } 149 | } 150 | /*-----------------------------------------------*/ 151 | void UnityPrintLen(const char* string, const UNITY_UINT32 length) 152 | { 153 | const char* pch = string; 154 | 155 | if (pch != NULL) 156 | { 157 | while (*pch && ((UNITY_UINT32)(pch - string) < length)) 158 | { 159 | /* printable characters plus CR & LF are printed */ 160 | if ((*pch <= 126) && (*pch >= 32)) 161 | { 162 | UNITY_OUTPUT_CHAR(*pch); 163 | } 164 | /* write escaped carriage returns */ 165 | else if (*pch == 13) 166 | { 167 | UNITY_OUTPUT_CHAR('\\'); 168 | UNITY_OUTPUT_CHAR('r'); 169 | } 170 | /* write escaped line feeds */ 171 | else if (*pch == 10) 172 | { 173 | UNITY_OUTPUT_CHAR('\\'); 174 | UNITY_OUTPUT_CHAR('n'); 175 | } 176 | /* unprintable characters are shown as codes */ 177 | else 178 | { 179 | UNITY_OUTPUT_CHAR('\\'); 180 | UNITY_OUTPUT_CHAR('x'); 181 | UnityPrintNumberHex((UNITY_UINT)*pch, 2); 182 | } 183 | pch++; 184 | } 185 | } 186 | } 187 | 188 | /*-----------------------------------------------*/ 189 | void UnityPrintNumberByStyle(const UNITY_INT number, const UNITY_DISPLAY_STYLE_T style) 190 | { 191 | if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 192 | { 193 | if (style == UNITY_DISPLAY_STYLE_CHAR) 194 | { 195 | /* printable characters plus CR & LF are printed */ 196 | UNITY_OUTPUT_CHAR('\''); 197 | if ((number <= 126) && (number >= 32)) 198 | { 199 | UNITY_OUTPUT_CHAR((int)number); 200 | } 201 | /* write escaped carriage returns */ 202 | else if (number == 13) 203 | { 204 | UNITY_OUTPUT_CHAR('\\'); 205 | UNITY_OUTPUT_CHAR('r'); 206 | } 207 | /* write escaped line feeds */ 208 | else if (number == 10) 209 | { 210 | UNITY_OUTPUT_CHAR('\\'); 211 | UNITY_OUTPUT_CHAR('n'); 212 | } 213 | /* unprintable characters are shown as codes */ 214 | else 215 | { 216 | UNITY_OUTPUT_CHAR('\\'); 217 | UNITY_OUTPUT_CHAR('x'); 218 | UnityPrintNumberHex((UNITY_UINT)number, 2); 219 | } 220 | UNITY_OUTPUT_CHAR('\''); 221 | } 222 | else 223 | { 224 | UnityPrintNumber(number); 225 | } 226 | } 227 | else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) 228 | { 229 | UnityPrintNumberUnsigned((UNITY_UINT)number); 230 | } 231 | else 232 | { 233 | UNITY_OUTPUT_CHAR('0'); 234 | UNITY_OUTPUT_CHAR('x'); 235 | UnityPrintNumberHex((UNITY_UINT)number, (char)((style & 0xF) * 2)); 236 | } 237 | } 238 | 239 | /*-----------------------------------------------*/ 240 | void UnityPrintNumber(const UNITY_INT number_to_print) 241 | { 242 | UNITY_UINT number = (UNITY_UINT)number_to_print; 243 | 244 | if (number_to_print < 0) 245 | { 246 | /* A negative number, including MIN negative */ 247 | UNITY_OUTPUT_CHAR('-'); 248 | number = (~number) + 1; 249 | } 250 | UnityPrintNumberUnsigned(number); 251 | } 252 | 253 | /*----------------------------------------------- 254 | * basically do an itoa using as little ram as possible */ 255 | void UnityPrintNumberUnsigned(const UNITY_UINT number) 256 | { 257 | UNITY_UINT divisor = 1; 258 | 259 | /* figure out initial divisor */ 260 | while (number / divisor > 9) 261 | { 262 | divisor *= 10; 263 | } 264 | 265 | /* now mod and print, then divide divisor */ 266 | do 267 | { 268 | UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); 269 | divisor /= 10; 270 | } while (divisor > 0); 271 | } 272 | 273 | /*-----------------------------------------------*/ 274 | void UnityPrintNumberHex(const UNITY_UINT number, const char nibbles_to_print) 275 | { 276 | int nibble; 277 | char nibbles = nibbles_to_print; 278 | 279 | if ((unsigned)nibbles > UNITY_MAX_NIBBLES) 280 | { 281 | nibbles = UNITY_MAX_NIBBLES; 282 | } 283 | 284 | while (nibbles > 0) 285 | { 286 | nibbles--; 287 | nibble = (int)(number >> (nibbles * 4)) & 0x0F; 288 | if (nibble <= 9) 289 | { 290 | UNITY_OUTPUT_CHAR((char)('0' + nibble)); 291 | } 292 | else 293 | { 294 | UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); 295 | } 296 | } 297 | } 298 | 299 | /*-----------------------------------------------*/ 300 | void UnityPrintMask(const UNITY_UINT mask, const UNITY_UINT number) 301 | { 302 | UNITY_UINT current_bit = (UNITY_UINT)1 << (UNITY_INT_WIDTH - 1); 303 | UNITY_INT32 i; 304 | 305 | for (i = 0; i < UNITY_INT_WIDTH; i++) 306 | { 307 | if (current_bit & mask) 308 | { 309 | if (current_bit & number) 310 | { 311 | UNITY_OUTPUT_CHAR('1'); 312 | } 313 | else 314 | { 315 | UNITY_OUTPUT_CHAR('0'); 316 | } 317 | } 318 | else 319 | { 320 | UNITY_OUTPUT_CHAR('X'); 321 | } 322 | current_bit = current_bit >> 1; 323 | } 324 | } 325 | 326 | /*-----------------------------------------------*/ 327 | #ifndef UNITY_EXCLUDE_FLOAT_PRINT 328 | /* 329 | * This function prints a floating-point value in a format similar to 330 | * printf("%.7g") on a single-precision machine or printf("%.9g") on a 331 | * double-precision machine. The 7th digit won't always be totally correct 332 | * in single-precision operation (for that level of accuracy, a more 333 | * complicated algorithm would be needed). 334 | */ 335 | void UnityPrintFloat(const UNITY_DOUBLE input_number) 336 | { 337 | #ifdef UNITY_INCLUDE_DOUBLE 338 | static const int sig_digits = 9; 339 | static const UNITY_INT32 min_scaled = 100000000; 340 | static const UNITY_INT32 max_scaled = 1000000000; 341 | #else 342 | static const int sig_digits = 7; 343 | static const UNITY_INT32 min_scaled = 1000000; 344 | static const UNITY_INT32 max_scaled = 10000000; 345 | #endif 346 | 347 | UNITY_DOUBLE number = input_number; 348 | 349 | /* print minus sign (does not handle negative zero) */ 350 | if (number < 0.0f) 351 | { 352 | UNITY_OUTPUT_CHAR('-'); 353 | number = -number; 354 | } 355 | 356 | /* handle zero, NaN, and +/- infinity */ 357 | if (number == 0.0f) 358 | { 359 | UnityPrint("0"); 360 | } 361 | else if (isnan(number)) 362 | { 363 | UnityPrint("nan"); 364 | } 365 | else if (isinf(number)) 366 | { 367 | UnityPrint("inf"); 368 | } 369 | else 370 | { 371 | UNITY_INT32 n_int = 0, n; 372 | int exponent = 0; 373 | int decimals, digits; 374 | char buf[16] = {0}; 375 | 376 | /* 377 | * Scale up or down by powers of 10. To minimize rounding error, 378 | * start with a factor/divisor of 10^10, which is the largest 379 | * power of 10 that can be represented exactly. Finally, compute 380 | * (exactly) the remaining power of 10 and perform one more 381 | * multiplication or division. 382 | */ 383 | if (number < 1.0f) 384 | { 385 | UNITY_DOUBLE factor = 1.0f; 386 | 387 | while (number < (UNITY_DOUBLE)max_scaled / 1e10f) { number *= 1e10f; exponent -= 10; } 388 | while (number * factor < (UNITY_DOUBLE)min_scaled) { factor *= 10.0f; exponent--; } 389 | 390 | number *= factor; 391 | } 392 | else if (number > (UNITY_DOUBLE)max_scaled) 393 | { 394 | UNITY_DOUBLE divisor = 1.0f; 395 | 396 | while (number > (UNITY_DOUBLE)min_scaled * 1e10f) { number /= 1e10f; exponent += 10; } 397 | while (number / divisor > (UNITY_DOUBLE)max_scaled) { divisor *= 10.0f; exponent++; } 398 | 399 | number /= divisor; 400 | } 401 | else 402 | { 403 | /* 404 | * In this range, we can split off the integer part before 405 | * doing any multiplications. This reduces rounding error by 406 | * freeing up significant bits in the fractional part. 407 | */ 408 | UNITY_DOUBLE factor = 1.0f; 409 | n_int = (UNITY_INT32)number; 410 | number -= (UNITY_DOUBLE)n_int; 411 | 412 | while (n_int < min_scaled) { n_int *= 10; factor *= 10.0f; exponent--; } 413 | 414 | number *= factor; 415 | } 416 | 417 | /* round to nearest integer */ 418 | n = ((UNITY_INT32)(number + number) + 1) / 2; 419 | 420 | #ifndef UNITY_ROUND_TIES_AWAY_FROM_ZERO 421 | /* round to even if exactly between two integers */ 422 | if ((n & 1) && (((UNITY_DOUBLE)n - number) == 0.5f)) 423 | n--; 424 | #endif 425 | 426 | n += n_int; 427 | 428 | if (n >= max_scaled) 429 | { 430 | n = min_scaled; 431 | exponent++; 432 | } 433 | 434 | /* determine where to place decimal point */ 435 | decimals = ((exponent <= 0) && (exponent >= -(sig_digits + 3))) ? (-exponent) : (sig_digits - 1); 436 | exponent += decimals; 437 | 438 | /* truncate trailing zeroes after decimal point */ 439 | while ((decimals > 0) && ((n % 10) == 0)) 440 | { 441 | n /= 10; 442 | decimals--; 443 | } 444 | 445 | /* build up buffer in reverse order */ 446 | digits = 0; 447 | while ((n != 0) || (digits < (decimals + 1))) 448 | { 449 | buf[digits++] = (char)('0' + n % 10); 450 | n /= 10; 451 | } 452 | while (digits > 0) 453 | { 454 | if (digits == decimals) { UNITY_OUTPUT_CHAR('.'); } 455 | UNITY_OUTPUT_CHAR(buf[--digits]); 456 | } 457 | 458 | /* print exponent if needed */ 459 | if (exponent != 0) 460 | { 461 | UNITY_OUTPUT_CHAR('e'); 462 | 463 | if (exponent < 0) 464 | { 465 | UNITY_OUTPUT_CHAR('-'); 466 | exponent = -exponent; 467 | } 468 | else 469 | { 470 | UNITY_OUTPUT_CHAR('+'); 471 | } 472 | 473 | digits = 0; 474 | while ((exponent != 0) || (digits < 2)) 475 | { 476 | buf[digits++] = (char)('0' + exponent % 10); 477 | exponent /= 10; 478 | } 479 | while (digits > 0) 480 | { 481 | UNITY_OUTPUT_CHAR(buf[--digits]); 482 | } 483 | } 484 | } 485 | } 486 | #endif /* ! UNITY_EXCLUDE_FLOAT_PRINT */ 487 | 488 | /*-----------------------------------------------*/ 489 | static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) 490 | { 491 | #ifdef UNITY_OUTPUT_FOR_ECLIPSE 492 | UNITY_OUTPUT_CHAR('('); 493 | UnityPrint(file); 494 | UNITY_OUTPUT_CHAR(':'); 495 | UnityPrintNumber((UNITY_INT)line); 496 | UNITY_OUTPUT_CHAR(')'); 497 | UNITY_OUTPUT_CHAR(' '); 498 | UnityPrint(Unity.CurrentTestName); 499 | UNITY_OUTPUT_CHAR(':'); 500 | #else 501 | #ifdef UNITY_OUTPUT_FOR_IAR_WORKBENCH 502 | UnityPrint("'); 508 | UnityPrint(Unity.CurrentTestName); 509 | UnityPrint(" "); 510 | #else 511 | #ifdef UNITY_OUTPUT_FOR_QT_CREATOR 512 | UnityPrint("file://"); 513 | UnityPrint(file); 514 | UNITY_OUTPUT_CHAR(':'); 515 | UnityPrintNumber((UNITY_INT)line); 516 | UNITY_OUTPUT_CHAR(' '); 517 | UnityPrint(Unity.CurrentTestName); 518 | UNITY_OUTPUT_CHAR(':'); 519 | #else 520 | UnityPrint(file); 521 | UNITY_OUTPUT_CHAR(':'); 522 | UnityPrintNumber((UNITY_INT)line); 523 | UNITY_OUTPUT_CHAR(':'); 524 | UnityPrint(Unity.CurrentTestName); 525 | UNITY_OUTPUT_CHAR(':'); 526 | #endif 527 | #endif 528 | #endif 529 | } 530 | 531 | /*-----------------------------------------------*/ 532 | static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) 533 | { 534 | UnityTestResultsBegin(Unity.TestFile, line); 535 | UnityPrint(UnityStrFail); 536 | UNITY_OUTPUT_CHAR(':'); 537 | } 538 | 539 | /*-----------------------------------------------*/ 540 | void UnityConcludeTest(void) 541 | { 542 | if (Unity.CurrentTestIgnored) 543 | { 544 | Unity.TestIgnores++; 545 | } 546 | else if (!Unity.CurrentTestFailed) 547 | { 548 | UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); 549 | UnityPrint(UnityStrPass); 550 | } 551 | else 552 | { 553 | Unity.TestFailures++; 554 | } 555 | 556 | Unity.CurrentTestFailed = 0; 557 | Unity.CurrentTestIgnored = 0; 558 | UNITY_PRINT_EXEC_TIME(); 559 | UNITY_PRINT_EOL(); 560 | UNITY_FLUSH_CALL(); 561 | } 562 | 563 | /*-----------------------------------------------*/ 564 | static void UnityAddMsgIfSpecified(const char* msg) 565 | { 566 | if (msg) 567 | { 568 | UnityPrint(UnityStrSpacer); 569 | 570 | #ifdef UNITY_PRINT_TEST_CONTEXT 571 | UNITY_PRINT_TEST_CONTEXT(); 572 | #endif 573 | #ifndef UNITY_EXCLUDE_DETAILS 574 | if (Unity.CurrentDetail1) 575 | { 576 | UnityPrint(UnityStrDetail1Name); 577 | UnityPrint(Unity.CurrentDetail1); 578 | if (Unity.CurrentDetail2) 579 | { 580 | UnityPrint(UnityStrDetail2Name); 581 | UnityPrint(Unity.CurrentDetail2); 582 | } 583 | UnityPrint(UnityStrSpacer); 584 | } 585 | #endif 586 | UnityPrint(msg); 587 | } 588 | } 589 | 590 | /*-----------------------------------------------*/ 591 | static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) 592 | { 593 | UnityPrint(UnityStrExpected); 594 | if (expected != NULL) 595 | { 596 | UNITY_OUTPUT_CHAR('\''); 597 | UnityPrint(expected); 598 | UNITY_OUTPUT_CHAR('\''); 599 | } 600 | else 601 | { 602 | UnityPrint(UnityStrNull); 603 | } 604 | UnityPrint(UnityStrWas); 605 | if (actual != NULL) 606 | { 607 | UNITY_OUTPUT_CHAR('\''); 608 | UnityPrint(actual); 609 | UNITY_OUTPUT_CHAR('\''); 610 | } 611 | else 612 | { 613 | UnityPrint(UnityStrNull); 614 | } 615 | } 616 | 617 | /*-----------------------------------------------*/ 618 | static void UnityPrintExpectedAndActualStringsLen(const char* expected, 619 | const char* actual, 620 | const UNITY_UINT32 length) 621 | { 622 | UnityPrint(UnityStrExpected); 623 | if (expected != NULL) 624 | { 625 | UNITY_OUTPUT_CHAR('\''); 626 | UnityPrintLen(expected, length); 627 | UNITY_OUTPUT_CHAR('\''); 628 | } 629 | else 630 | { 631 | UnityPrint(UnityStrNull); 632 | } 633 | UnityPrint(UnityStrWas); 634 | if (actual != NULL) 635 | { 636 | UNITY_OUTPUT_CHAR('\''); 637 | UnityPrintLen(actual, length); 638 | UNITY_OUTPUT_CHAR('\''); 639 | } 640 | else 641 | { 642 | UnityPrint(UnityStrNull); 643 | } 644 | } 645 | 646 | /*----------------------------------------------- 647 | * Assertion & Control Helpers 648 | *-----------------------------------------------*/ 649 | 650 | /*-----------------------------------------------*/ 651 | static int UnityIsOneArrayNull(UNITY_INTERNAL_PTR expected, 652 | UNITY_INTERNAL_PTR actual, 653 | const UNITY_LINE_TYPE lineNumber, 654 | const char* msg) 655 | { 656 | /* Both are NULL or same pointer */ 657 | if (expected == actual) { return 0; } 658 | 659 | /* print and return true if just expected is NULL */ 660 | if (expected == NULL) 661 | { 662 | UnityTestResultsFailBegin(lineNumber); 663 | UnityPrint(UnityStrNullPointerForExpected); 664 | UnityAddMsgIfSpecified(msg); 665 | return 1; 666 | } 667 | 668 | /* print and return true if just actual is NULL */ 669 | if (actual == NULL) 670 | { 671 | UnityTestResultsFailBegin(lineNumber); 672 | UnityPrint(UnityStrNullPointerForActual); 673 | UnityAddMsgIfSpecified(msg); 674 | return 1; 675 | } 676 | 677 | return 0; /* return false if neither is NULL */ 678 | } 679 | 680 | /*----------------------------------------------- 681 | * Assertion Functions 682 | *-----------------------------------------------*/ 683 | 684 | /*-----------------------------------------------*/ 685 | void UnityAssertBits(const UNITY_INT mask, 686 | const UNITY_INT expected, 687 | const UNITY_INT actual, 688 | const char* msg, 689 | const UNITY_LINE_TYPE lineNumber) 690 | { 691 | RETURN_IF_FAIL_OR_IGNORE; 692 | 693 | if ((mask & expected) != (mask & actual)) 694 | { 695 | UnityTestResultsFailBegin(lineNumber); 696 | UnityPrint(UnityStrExpected); 697 | UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)expected); 698 | UnityPrint(UnityStrWas); 699 | UnityPrintMask((UNITY_UINT)mask, (UNITY_UINT)actual); 700 | UnityAddMsgIfSpecified(msg); 701 | UNITY_FAIL_AND_BAIL; 702 | } 703 | } 704 | 705 | /*-----------------------------------------------*/ 706 | void UnityAssertEqualNumber(const UNITY_INT expected, 707 | const UNITY_INT actual, 708 | const char* msg, 709 | const UNITY_LINE_TYPE lineNumber, 710 | const UNITY_DISPLAY_STYLE_T style) 711 | { 712 | RETURN_IF_FAIL_OR_IGNORE; 713 | 714 | if (expected != actual) 715 | { 716 | UnityTestResultsFailBegin(lineNumber); 717 | UnityPrint(UnityStrExpected); 718 | UnityPrintNumberByStyle(expected, style); 719 | UnityPrint(UnityStrWas); 720 | UnityPrintNumberByStyle(actual, style); 721 | UnityAddMsgIfSpecified(msg); 722 | UNITY_FAIL_AND_BAIL; 723 | } 724 | } 725 | 726 | /*-----------------------------------------------*/ 727 | void UnityAssertGreaterOrLessOrEqualNumber(const UNITY_INT threshold, 728 | const UNITY_INT actual, 729 | const UNITY_COMPARISON_T compare, 730 | const char *msg, 731 | const UNITY_LINE_TYPE lineNumber, 732 | const UNITY_DISPLAY_STYLE_T style) 733 | { 734 | int failed = 0; 735 | RETURN_IF_FAIL_OR_IGNORE; 736 | 737 | if ((threshold == actual) && (compare & UNITY_EQUAL_TO)) { return; } 738 | if ((threshold == actual)) { failed = 1; } 739 | 740 | if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 741 | { 742 | if ((actual > threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } 743 | if ((actual < threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } 744 | } 745 | else /* UINT or HEX */ 746 | { 747 | if (((UNITY_UINT)actual > (UNITY_UINT)threshold) && (compare & UNITY_SMALLER_THAN)) { failed = 1; } 748 | if (((UNITY_UINT)actual < (UNITY_UINT)threshold) && (compare & UNITY_GREATER_THAN)) { failed = 1; } 749 | } 750 | 751 | if (failed) 752 | { 753 | UnityTestResultsFailBegin(lineNumber); 754 | UnityPrint(UnityStrExpected); 755 | UnityPrintNumberByStyle(actual, style); 756 | if (compare & UNITY_GREATER_THAN) { UnityPrint(UnityStrGt); } 757 | if (compare & UNITY_SMALLER_THAN) { UnityPrint(UnityStrLt); } 758 | if (compare & UNITY_EQUAL_TO) { UnityPrint(UnityStrOrEqual); } 759 | if (compare == UNITY_NOT_EQUAL) { UnityPrint(UnityStrNotEqual); } 760 | UnityPrintNumberByStyle(threshold, style); 761 | UnityAddMsgIfSpecified(msg); 762 | UNITY_FAIL_AND_BAIL; 763 | } 764 | } 765 | 766 | #define UnityPrintPointlessAndBail() \ 767 | { \ 768 | UnityTestResultsFailBegin(lineNumber); \ 769 | UnityPrint(UnityStrPointless); \ 770 | UnityAddMsgIfSpecified(msg); \ 771 | UNITY_FAIL_AND_BAIL; } 772 | 773 | /*-----------------------------------------------*/ 774 | void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, 775 | UNITY_INTERNAL_PTR actual, 776 | const UNITY_UINT32 num_elements, 777 | const char* msg, 778 | const UNITY_LINE_TYPE lineNumber, 779 | const UNITY_DISPLAY_STYLE_T style, 780 | const UNITY_FLAGS_T flags) 781 | { 782 | UNITY_UINT32 elements = num_elements; 783 | unsigned int length = style & 0xF; 784 | unsigned int increment = 0; 785 | 786 | RETURN_IF_FAIL_OR_IGNORE; 787 | 788 | if (num_elements == 0) 789 | { 790 | UnityPrintPointlessAndBail(); 791 | } 792 | 793 | if (expected == actual) 794 | { 795 | return; /* Both are NULL or same pointer */ 796 | } 797 | 798 | if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 799 | { 800 | UNITY_FAIL_AND_BAIL; 801 | } 802 | 803 | while ((elements > 0) && (elements--)) 804 | { 805 | UNITY_INT expect_val; 806 | UNITY_INT actual_val; 807 | 808 | switch (length) 809 | { 810 | case 1: 811 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; 812 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; 813 | increment = sizeof(UNITY_INT8); 814 | break; 815 | 816 | case 2: 817 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; 818 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; 819 | increment = sizeof(UNITY_INT16); 820 | break; 821 | 822 | #ifdef UNITY_SUPPORT_64 823 | case 8: 824 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; 825 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; 826 | increment = sizeof(UNITY_INT64); 827 | break; 828 | #endif 829 | 830 | default: /* default is length 4 bytes */ 831 | case 4: 832 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; 833 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; 834 | increment = sizeof(UNITY_INT32); 835 | length = 4; 836 | break; 837 | } 838 | 839 | if (expect_val != actual_val) 840 | { 841 | if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) 842 | { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ 843 | UNITY_INT mask = 1; 844 | mask = (mask << 8 * length) - 1; 845 | expect_val &= mask; 846 | actual_val &= mask; 847 | } 848 | UnityTestResultsFailBegin(lineNumber); 849 | UnityPrint(UnityStrElement); 850 | UnityPrintNumberUnsigned(num_elements - elements - 1); 851 | UnityPrint(UnityStrExpected); 852 | UnityPrintNumberByStyle(expect_val, style); 853 | UnityPrint(UnityStrWas); 854 | UnityPrintNumberByStyle(actual_val, style); 855 | UnityAddMsgIfSpecified(msg); 856 | UNITY_FAIL_AND_BAIL; 857 | } 858 | /* Walk through array by incrementing the pointers */ 859 | if (flags == UNITY_ARRAY_TO_ARRAY) 860 | { 861 | expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); 862 | } 863 | actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); 864 | } 865 | } 866 | 867 | /*-----------------------------------------------*/ 868 | #ifndef UNITY_EXCLUDE_FLOAT 869 | /* Wrap this define in a function with variable types as float or double */ 870 | #define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \ 871 | if (isinf(expected) && isinf(actual) && (((expected) < 0) == ((actual) < 0))) return 1; \ 872 | if (UNITY_NAN_CHECK) return 1; \ 873 | (diff) = (actual) - (expected); \ 874 | if ((diff) < 0) (diff) = -(diff); \ 875 | if ((delta) < 0) (delta) = -(delta); \ 876 | return !(isnan(diff) || isinf(diff) || ((diff) > (delta))) 877 | /* This first part of this condition will catch any NaN or Infinite values */ 878 | #ifndef UNITY_NAN_NOT_EQUAL_NAN 879 | #define UNITY_NAN_CHECK isnan(expected) && isnan(actual) 880 | #else 881 | #define UNITY_NAN_CHECK 0 882 | #endif 883 | 884 | #ifndef UNITY_EXCLUDE_FLOAT_PRINT 885 | #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ 886 | { \ 887 | UnityPrint(UnityStrExpected); \ 888 | UnityPrintFloat(expected); \ 889 | UnityPrint(UnityStrWas); \ 890 | UnityPrintFloat(actual); } 891 | #else 892 | #define UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual) \ 893 | UnityPrint(UnityStrDelta) 894 | #endif /* UNITY_EXCLUDE_FLOAT_PRINT */ 895 | 896 | /*-----------------------------------------------*/ 897 | static int UnityFloatsWithin(UNITY_FLOAT delta, UNITY_FLOAT expected, UNITY_FLOAT actual) 898 | { 899 | UNITY_FLOAT diff; 900 | UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); 901 | } 902 | 903 | /*-----------------------------------------------*/ 904 | void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* expected, 905 | UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* actual, 906 | const UNITY_UINT32 num_elements, 907 | const char* msg, 908 | const UNITY_LINE_TYPE lineNumber, 909 | const UNITY_FLAGS_T flags) 910 | { 911 | UNITY_UINT32 elements = num_elements; 912 | UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_expected = expected; 913 | UNITY_PTR_ATTRIBUTE const UNITY_FLOAT* ptr_actual = actual; 914 | 915 | RETURN_IF_FAIL_OR_IGNORE; 916 | 917 | if (elements == 0) 918 | { 919 | UnityPrintPointlessAndBail(); 920 | } 921 | 922 | if (expected == actual) 923 | { 924 | return; /* Both are NULL or same pointer */ 925 | } 926 | 927 | if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 928 | { 929 | UNITY_FAIL_AND_BAIL; 930 | } 931 | 932 | while (elements--) 933 | { 934 | if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual)) 935 | { 936 | UnityTestResultsFailBegin(lineNumber); 937 | UnityPrint(UnityStrElement); 938 | UnityPrintNumberUnsigned(num_elements - elements - 1); 939 | UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)*ptr_expected, (UNITY_DOUBLE)*ptr_actual); 940 | UnityAddMsgIfSpecified(msg); 941 | UNITY_FAIL_AND_BAIL; 942 | } 943 | if (flags == UNITY_ARRAY_TO_ARRAY) 944 | { 945 | ptr_expected++; 946 | } 947 | ptr_actual++; 948 | } 949 | } 950 | 951 | /*-----------------------------------------------*/ 952 | void UnityAssertFloatsWithin(const UNITY_FLOAT delta, 953 | const UNITY_FLOAT expected, 954 | const UNITY_FLOAT actual, 955 | const char* msg, 956 | const UNITY_LINE_TYPE lineNumber) 957 | { 958 | RETURN_IF_FAIL_OR_IGNORE; 959 | 960 | 961 | if (!UnityFloatsWithin(delta, expected, actual)) 962 | { 963 | UnityTestResultsFailBegin(lineNumber); 964 | UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT((UNITY_DOUBLE)expected, (UNITY_DOUBLE)actual); 965 | UnityAddMsgIfSpecified(msg); 966 | UNITY_FAIL_AND_BAIL; 967 | } 968 | } 969 | 970 | /*-----------------------------------------------*/ 971 | void UnityAssertFloatSpecial(const UNITY_FLOAT actual, 972 | const char* msg, 973 | const UNITY_LINE_TYPE lineNumber, 974 | const UNITY_FLOAT_TRAIT_T style) 975 | { 976 | const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; 977 | UNITY_INT should_be_trait = ((UNITY_INT)style & 1); 978 | UNITY_INT is_trait = !should_be_trait; 979 | UNITY_INT trait_index = (UNITY_INT)(style >> 1); 980 | 981 | RETURN_IF_FAIL_OR_IGNORE; 982 | 983 | switch (style) 984 | { 985 | case UNITY_FLOAT_IS_INF: 986 | case UNITY_FLOAT_IS_NOT_INF: 987 | is_trait = isinf(actual) && (actual > 0); 988 | break; 989 | case UNITY_FLOAT_IS_NEG_INF: 990 | case UNITY_FLOAT_IS_NOT_NEG_INF: 991 | is_trait = isinf(actual) && (actual < 0); 992 | break; 993 | 994 | case UNITY_FLOAT_IS_NAN: 995 | case UNITY_FLOAT_IS_NOT_NAN: 996 | is_trait = isnan(actual) ? 1 : 0; 997 | break; 998 | 999 | case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ 1000 | case UNITY_FLOAT_IS_NOT_DET: 1001 | is_trait = !isinf(actual) && !isnan(actual); 1002 | break; 1003 | 1004 | case UNITY_FLOAT_INVALID_TRAIT: 1005 | default: 1006 | trait_index = 0; 1007 | trait_names[0] = UnityStrInvalidFloatTrait; 1008 | break; 1009 | } 1010 | 1011 | if (is_trait != should_be_trait) 1012 | { 1013 | UnityTestResultsFailBegin(lineNumber); 1014 | UnityPrint(UnityStrExpected); 1015 | if (!should_be_trait) 1016 | { 1017 | UnityPrint(UnityStrNot); 1018 | } 1019 | UnityPrint(trait_names[trait_index]); 1020 | UnityPrint(UnityStrWas); 1021 | #ifndef UNITY_EXCLUDE_FLOAT_PRINT 1022 | UnityPrintFloat((UNITY_DOUBLE)actual); 1023 | #else 1024 | if (should_be_trait) 1025 | { 1026 | UnityPrint(UnityStrNot); 1027 | } 1028 | UnityPrint(trait_names[trait_index]); 1029 | #endif 1030 | UnityAddMsgIfSpecified(msg); 1031 | UNITY_FAIL_AND_BAIL; 1032 | } 1033 | } 1034 | 1035 | #endif /* not UNITY_EXCLUDE_FLOAT */ 1036 | 1037 | /*-----------------------------------------------*/ 1038 | #ifndef UNITY_EXCLUDE_DOUBLE 1039 | static int UnityDoublesWithin(UNITY_DOUBLE delta, UNITY_DOUBLE expected, UNITY_DOUBLE actual) 1040 | { 1041 | UNITY_DOUBLE diff; 1042 | UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); 1043 | } 1044 | 1045 | /*-----------------------------------------------*/ 1046 | void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* expected, 1047 | UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* actual, 1048 | const UNITY_UINT32 num_elements, 1049 | const char* msg, 1050 | const UNITY_LINE_TYPE lineNumber, 1051 | const UNITY_FLAGS_T flags) 1052 | { 1053 | UNITY_UINT32 elements = num_elements; 1054 | UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_expected = expected; 1055 | UNITY_PTR_ATTRIBUTE const UNITY_DOUBLE* ptr_actual = actual; 1056 | 1057 | RETURN_IF_FAIL_OR_IGNORE; 1058 | 1059 | if (elements == 0) 1060 | { 1061 | UnityPrintPointlessAndBail(); 1062 | } 1063 | 1064 | if (expected == actual) 1065 | { 1066 | return; /* Both are NULL or same pointer */ 1067 | } 1068 | 1069 | if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 1070 | { 1071 | UNITY_FAIL_AND_BAIL; 1072 | } 1073 | 1074 | while (elements--) 1075 | { 1076 | if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual)) 1077 | { 1078 | UnityTestResultsFailBegin(lineNumber); 1079 | UnityPrint(UnityStrElement); 1080 | UnityPrintNumberUnsigned(num_elements - elements - 1); 1081 | UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(*ptr_expected, *ptr_actual); 1082 | UnityAddMsgIfSpecified(msg); 1083 | UNITY_FAIL_AND_BAIL; 1084 | } 1085 | if (flags == UNITY_ARRAY_TO_ARRAY) 1086 | { 1087 | ptr_expected++; 1088 | } 1089 | ptr_actual++; 1090 | } 1091 | } 1092 | 1093 | /*-----------------------------------------------*/ 1094 | void UnityAssertDoublesWithin(const UNITY_DOUBLE delta, 1095 | const UNITY_DOUBLE expected, 1096 | const UNITY_DOUBLE actual, 1097 | const char* msg, 1098 | const UNITY_LINE_TYPE lineNumber) 1099 | { 1100 | RETURN_IF_FAIL_OR_IGNORE; 1101 | 1102 | if (!UnityDoublesWithin(delta, expected, actual)) 1103 | { 1104 | UnityTestResultsFailBegin(lineNumber); 1105 | UNITY_PRINT_EXPECTED_AND_ACTUAL_FLOAT(expected, actual); 1106 | UnityAddMsgIfSpecified(msg); 1107 | UNITY_FAIL_AND_BAIL; 1108 | } 1109 | } 1110 | 1111 | /*-----------------------------------------------*/ 1112 | void UnityAssertDoubleSpecial(const UNITY_DOUBLE actual, 1113 | const char* msg, 1114 | const UNITY_LINE_TYPE lineNumber, 1115 | const UNITY_FLOAT_TRAIT_T style) 1116 | { 1117 | const char* trait_names[] = {UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet}; 1118 | UNITY_INT should_be_trait = ((UNITY_INT)style & 1); 1119 | UNITY_INT is_trait = !should_be_trait; 1120 | UNITY_INT trait_index = (UNITY_INT)(style >> 1); 1121 | 1122 | RETURN_IF_FAIL_OR_IGNORE; 1123 | 1124 | switch (style) 1125 | { 1126 | case UNITY_FLOAT_IS_INF: 1127 | case UNITY_FLOAT_IS_NOT_INF: 1128 | is_trait = isinf(actual) && (actual > 0); 1129 | break; 1130 | case UNITY_FLOAT_IS_NEG_INF: 1131 | case UNITY_FLOAT_IS_NOT_NEG_INF: 1132 | is_trait = isinf(actual) && (actual < 0); 1133 | break; 1134 | 1135 | case UNITY_FLOAT_IS_NAN: 1136 | case UNITY_FLOAT_IS_NOT_NAN: 1137 | is_trait = isnan(actual) ? 1 : 0; 1138 | break; 1139 | 1140 | case UNITY_FLOAT_IS_DET: /* A determinate number is non infinite and not NaN. */ 1141 | case UNITY_FLOAT_IS_NOT_DET: 1142 | is_trait = !isinf(actual) && !isnan(actual); 1143 | break; 1144 | 1145 | case UNITY_FLOAT_INVALID_TRAIT: 1146 | default: 1147 | trait_index = 0; 1148 | trait_names[0] = UnityStrInvalidFloatTrait; 1149 | break; 1150 | } 1151 | 1152 | if (is_trait != should_be_trait) 1153 | { 1154 | UnityTestResultsFailBegin(lineNumber); 1155 | UnityPrint(UnityStrExpected); 1156 | if (!should_be_trait) 1157 | { 1158 | UnityPrint(UnityStrNot); 1159 | } 1160 | UnityPrint(trait_names[trait_index]); 1161 | UnityPrint(UnityStrWas); 1162 | #ifndef UNITY_EXCLUDE_FLOAT_PRINT 1163 | UnityPrintFloat(actual); 1164 | #else 1165 | if (should_be_trait) 1166 | { 1167 | UnityPrint(UnityStrNot); 1168 | } 1169 | UnityPrint(trait_names[trait_index]); 1170 | #endif 1171 | UnityAddMsgIfSpecified(msg); 1172 | UNITY_FAIL_AND_BAIL; 1173 | } 1174 | } 1175 | 1176 | #endif /* not UNITY_EXCLUDE_DOUBLE */ 1177 | 1178 | /*-----------------------------------------------*/ 1179 | void UnityAssertNumbersWithin(const UNITY_UINT delta, 1180 | const UNITY_INT expected, 1181 | const UNITY_INT actual, 1182 | const char* msg, 1183 | const UNITY_LINE_TYPE lineNumber, 1184 | const UNITY_DISPLAY_STYLE_T style) 1185 | { 1186 | RETURN_IF_FAIL_OR_IGNORE; 1187 | 1188 | if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 1189 | { 1190 | if (actual > expected) 1191 | { 1192 | Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); 1193 | } 1194 | else 1195 | { 1196 | Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); 1197 | } 1198 | } 1199 | else 1200 | { 1201 | if ((UNITY_UINT)actual > (UNITY_UINT)expected) 1202 | { 1203 | Unity.CurrentTestFailed = (((UNITY_UINT)actual - (UNITY_UINT)expected) > delta); 1204 | } 1205 | else 1206 | { 1207 | Unity.CurrentTestFailed = (((UNITY_UINT)expected - (UNITY_UINT)actual) > delta); 1208 | } 1209 | } 1210 | 1211 | if (Unity.CurrentTestFailed) 1212 | { 1213 | UnityTestResultsFailBegin(lineNumber); 1214 | UnityPrint(UnityStrDelta); 1215 | UnityPrintNumberByStyle((UNITY_INT)delta, style); 1216 | UnityPrint(UnityStrExpected); 1217 | UnityPrintNumberByStyle(expected, style); 1218 | UnityPrint(UnityStrWas); 1219 | UnityPrintNumberByStyle(actual, style); 1220 | UnityAddMsgIfSpecified(msg); 1221 | UNITY_FAIL_AND_BAIL; 1222 | } 1223 | } 1224 | 1225 | /*-----------------------------------------------*/ 1226 | void UnityAssertNumbersArrayWithin(const UNITY_UINT delta, 1227 | UNITY_INTERNAL_PTR expected, 1228 | UNITY_INTERNAL_PTR actual, 1229 | const UNITY_UINT32 num_elements, 1230 | const char* msg, 1231 | const UNITY_LINE_TYPE lineNumber, 1232 | const UNITY_DISPLAY_STYLE_T style, 1233 | const UNITY_FLAGS_T flags) 1234 | { 1235 | UNITY_UINT32 elements = num_elements; 1236 | unsigned int length = style & 0xF; 1237 | unsigned int increment = 0; 1238 | 1239 | RETURN_IF_FAIL_OR_IGNORE; 1240 | 1241 | if (num_elements == 0) 1242 | { 1243 | UnityPrintPointlessAndBail(); 1244 | } 1245 | 1246 | if (expected == actual) 1247 | { 1248 | return; /* Both are NULL or same pointer */ 1249 | } 1250 | 1251 | if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 1252 | { 1253 | UNITY_FAIL_AND_BAIL; 1254 | } 1255 | 1256 | while ((elements > 0) && (elements--)) 1257 | { 1258 | UNITY_INT expect_val; 1259 | UNITY_INT actual_val; 1260 | 1261 | switch (length) 1262 | { 1263 | case 1: 1264 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)expected; 1265 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT8*)actual; 1266 | increment = sizeof(UNITY_INT8); 1267 | break; 1268 | 1269 | case 2: 1270 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)expected; 1271 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT16*)actual; 1272 | increment = sizeof(UNITY_INT16); 1273 | break; 1274 | 1275 | #ifdef UNITY_SUPPORT_64 1276 | case 8: 1277 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)expected; 1278 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT64*)actual; 1279 | increment = sizeof(UNITY_INT64); 1280 | break; 1281 | #endif 1282 | 1283 | default: /* default is length 4 bytes */ 1284 | case 4: 1285 | expect_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)expected; 1286 | actual_val = *(UNITY_PTR_ATTRIBUTE const UNITY_INT32*)actual; 1287 | increment = sizeof(UNITY_INT32); 1288 | length = 4; 1289 | break; 1290 | } 1291 | 1292 | if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) 1293 | { 1294 | if (actual_val > expect_val) 1295 | { 1296 | Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); 1297 | } 1298 | else 1299 | { 1300 | Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); 1301 | } 1302 | } 1303 | else 1304 | { 1305 | if ((UNITY_UINT)actual_val > (UNITY_UINT)expect_val) 1306 | { 1307 | Unity.CurrentTestFailed = (((UNITY_UINT)actual_val - (UNITY_UINT)expect_val) > delta); 1308 | } 1309 | else 1310 | { 1311 | Unity.CurrentTestFailed = (((UNITY_UINT)expect_val - (UNITY_UINT)actual_val) > delta); 1312 | } 1313 | } 1314 | 1315 | if (Unity.CurrentTestFailed) 1316 | { 1317 | if ((style & UNITY_DISPLAY_RANGE_UINT) && (length < (UNITY_INT_WIDTH / 8))) 1318 | { /* For UINT, remove sign extension (padding 1's) from signed type casts above */ 1319 | UNITY_INT mask = 1; 1320 | mask = (mask << 8 * length) - 1; 1321 | expect_val &= mask; 1322 | actual_val &= mask; 1323 | } 1324 | UnityTestResultsFailBegin(lineNumber); 1325 | UnityPrint(UnityStrDelta); 1326 | UnityPrintNumberByStyle((UNITY_INT)delta, style); 1327 | UnityPrint(UnityStrElement); 1328 | UnityPrintNumberUnsigned(num_elements - elements - 1); 1329 | UnityPrint(UnityStrExpected); 1330 | UnityPrintNumberByStyle(expect_val, style); 1331 | UnityPrint(UnityStrWas); 1332 | UnityPrintNumberByStyle(actual_val, style); 1333 | UnityAddMsgIfSpecified(msg); 1334 | UNITY_FAIL_AND_BAIL; 1335 | } 1336 | /* Walk through array by incrementing the pointers */ 1337 | if (flags == UNITY_ARRAY_TO_ARRAY) 1338 | { 1339 | expected = (UNITY_INTERNAL_PTR)((const char*)expected + increment); 1340 | } 1341 | actual = (UNITY_INTERNAL_PTR)((const char*)actual + increment); 1342 | } 1343 | } 1344 | 1345 | /*-----------------------------------------------*/ 1346 | void UnityAssertEqualString(const char* expected, 1347 | const char* actual, 1348 | const char* msg, 1349 | const UNITY_LINE_TYPE lineNumber) 1350 | { 1351 | UNITY_UINT32 i; 1352 | 1353 | RETURN_IF_FAIL_OR_IGNORE; 1354 | 1355 | /* if both pointers not null compare the strings */ 1356 | if (expected && actual) 1357 | { 1358 | for (i = 0; expected[i] || actual[i]; i++) 1359 | { 1360 | if (expected[i] != actual[i]) 1361 | { 1362 | Unity.CurrentTestFailed = 1; 1363 | break; 1364 | } 1365 | } 1366 | } 1367 | else 1368 | { /* handle case of one pointers being null (if both null, test should pass) */ 1369 | if (expected != actual) 1370 | { 1371 | Unity.CurrentTestFailed = 1; 1372 | } 1373 | } 1374 | 1375 | if (Unity.CurrentTestFailed) 1376 | { 1377 | UnityTestResultsFailBegin(lineNumber); 1378 | UnityPrintExpectedAndActualStrings(expected, actual); 1379 | UnityAddMsgIfSpecified(msg); 1380 | UNITY_FAIL_AND_BAIL; 1381 | } 1382 | } 1383 | 1384 | /*-----------------------------------------------*/ 1385 | void UnityAssertEqualStringLen(const char* expected, 1386 | const char* actual, 1387 | const UNITY_UINT32 length, 1388 | const char* msg, 1389 | const UNITY_LINE_TYPE lineNumber) 1390 | { 1391 | UNITY_UINT32 i; 1392 | 1393 | RETURN_IF_FAIL_OR_IGNORE; 1394 | 1395 | /* if both pointers not null compare the strings */ 1396 | if (expected && actual) 1397 | { 1398 | for (i = 0; (i < length) && (expected[i] || actual[i]); i++) 1399 | { 1400 | if (expected[i] != actual[i]) 1401 | { 1402 | Unity.CurrentTestFailed = 1; 1403 | break; 1404 | } 1405 | } 1406 | } 1407 | else 1408 | { /* handle case of one pointers being null (if both null, test should pass) */ 1409 | if (expected != actual) 1410 | { 1411 | Unity.CurrentTestFailed = 1; 1412 | } 1413 | } 1414 | 1415 | if (Unity.CurrentTestFailed) 1416 | { 1417 | UnityTestResultsFailBegin(lineNumber); 1418 | UnityPrintExpectedAndActualStringsLen(expected, actual, length); 1419 | UnityAddMsgIfSpecified(msg); 1420 | UNITY_FAIL_AND_BAIL; 1421 | } 1422 | } 1423 | 1424 | /*-----------------------------------------------*/ 1425 | void UnityAssertEqualStringArray(UNITY_INTERNAL_PTR expected, 1426 | const char** actual, 1427 | const UNITY_UINT32 num_elements, 1428 | const char* msg, 1429 | const UNITY_LINE_TYPE lineNumber, 1430 | const UNITY_FLAGS_T flags) 1431 | { 1432 | UNITY_UINT32 i = 0; 1433 | UNITY_UINT32 j = 0; 1434 | const char* expd = NULL; 1435 | const char* act = NULL; 1436 | 1437 | RETURN_IF_FAIL_OR_IGNORE; 1438 | 1439 | /* if no elements, it's an error */ 1440 | if (num_elements == 0) 1441 | { 1442 | UnityPrintPointlessAndBail(); 1443 | } 1444 | 1445 | if ((const void*)expected == (const void*)actual) 1446 | { 1447 | return; /* Both are NULL or same pointer */ 1448 | } 1449 | 1450 | if (UnityIsOneArrayNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg)) 1451 | { 1452 | UNITY_FAIL_AND_BAIL; 1453 | } 1454 | 1455 | if (flags != UNITY_ARRAY_TO_ARRAY) 1456 | { 1457 | expd = (const char*)expected; 1458 | } 1459 | 1460 | do 1461 | { 1462 | act = actual[j]; 1463 | if (flags == UNITY_ARRAY_TO_ARRAY) 1464 | { 1465 | expd = ((const char* const*)expected)[j]; 1466 | } 1467 | 1468 | /* if both pointers not null compare the strings */ 1469 | if (expd && act) 1470 | { 1471 | for (i = 0; expd[i] || act[i]; i++) 1472 | { 1473 | if (expd[i] != act[i]) 1474 | { 1475 | Unity.CurrentTestFailed = 1; 1476 | break; 1477 | } 1478 | } 1479 | } 1480 | else 1481 | { /* handle case of one pointers being null (if both null, test should pass) */ 1482 | if (expd != act) 1483 | { 1484 | Unity.CurrentTestFailed = 1; 1485 | } 1486 | } 1487 | 1488 | if (Unity.CurrentTestFailed) 1489 | { 1490 | UnityTestResultsFailBegin(lineNumber); 1491 | if (num_elements > 1) 1492 | { 1493 | UnityPrint(UnityStrElement); 1494 | UnityPrintNumberUnsigned(j); 1495 | } 1496 | UnityPrintExpectedAndActualStrings(expd, act); 1497 | UnityAddMsgIfSpecified(msg); 1498 | UNITY_FAIL_AND_BAIL; 1499 | } 1500 | } while (++j < num_elements); 1501 | } 1502 | 1503 | /*-----------------------------------------------*/ 1504 | void UnityAssertEqualMemory(UNITY_INTERNAL_PTR expected, 1505 | UNITY_INTERNAL_PTR actual, 1506 | const UNITY_UINT32 length, 1507 | const UNITY_UINT32 num_elements, 1508 | const char* msg, 1509 | const UNITY_LINE_TYPE lineNumber, 1510 | const UNITY_FLAGS_T flags) 1511 | { 1512 | UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; 1513 | UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; 1514 | UNITY_UINT32 elements = num_elements; 1515 | UNITY_UINT32 bytes; 1516 | 1517 | RETURN_IF_FAIL_OR_IGNORE; 1518 | 1519 | if ((elements == 0) || (length == 0)) 1520 | { 1521 | UnityPrintPointlessAndBail(); 1522 | } 1523 | 1524 | if (expected == actual) 1525 | { 1526 | return; /* Both are NULL or same pointer */ 1527 | } 1528 | 1529 | if (UnityIsOneArrayNull(expected, actual, lineNumber, msg)) 1530 | { 1531 | UNITY_FAIL_AND_BAIL; 1532 | } 1533 | 1534 | while (elements--) 1535 | { 1536 | bytes = length; 1537 | while (bytes--) 1538 | { 1539 | if (*ptr_exp != *ptr_act) 1540 | { 1541 | UnityTestResultsFailBegin(lineNumber); 1542 | UnityPrint(UnityStrMemory); 1543 | if (num_elements > 1) 1544 | { 1545 | UnityPrint(UnityStrElement); 1546 | UnityPrintNumberUnsigned(num_elements - elements - 1); 1547 | } 1548 | UnityPrint(UnityStrByte); 1549 | UnityPrintNumberUnsigned(length - bytes - 1); 1550 | UnityPrint(UnityStrExpected); 1551 | UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); 1552 | UnityPrint(UnityStrWas); 1553 | UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); 1554 | UnityAddMsgIfSpecified(msg); 1555 | UNITY_FAIL_AND_BAIL; 1556 | } 1557 | ptr_exp++; 1558 | ptr_act++; 1559 | } 1560 | if (flags == UNITY_ARRAY_TO_VAL) 1561 | { 1562 | ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; 1563 | } 1564 | } 1565 | } 1566 | 1567 | /*-----------------------------------------------*/ 1568 | 1569 | static union 1570 | { 1571 | UNITY_INT8 i8; 1572 | UNITY_INT16 i16; 1573 | UNITY_INT32 i32; 1574 | #ifdef UNITY_SUPPORT_64 1575 | UNITY_INT64 i64; 1576 | #endif 1577 | #ifndef UNITY_EXCLUDE_FLOAT 1578 | float f; 1579 | #endif 1580 | #ifndef UNITY_EXCLUDE_DOUBLE 1581 | double d; 1582 | #endif 1583 | } UnityQuickCompare; 1584 | 1585 | UNITY_INTERNAL_PTR UnityNumToPtr(const UNITY_INT num, const UNITY_UINT8 size) 1586 | { 1587 | switch(size) 1588 | { 1589 | case 1: 1590 | UnityQuickCompare.i8 = (UNITY_INT8)num; 1591 | return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i8); 1592 | 1593 | case 2: 1594 | UnityQuickCompare.i16 = (UNITY_INT16)num; 1595 | return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i16); 1596 | 1597 | #ifdef UNITY_SUPPORT_64 1598 | case 8: 1599 | UnityQuickCompare.i64 = (UNITY_INT64)num; 1600 | return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i64); 1601 | #endif 1602 | 1603 | default: /* 4 bytes */ 1604 | UnityQuickCompare.i32 = (UNITY_INT32)num; 1605 | return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.i32); 1606 | } 1607 | } 1608 | 1609 | #ifndef UNITY_EXCLUDE_FLOAT 1610 | /*-----------------------------------------------*/ 1611 | UNITY_INTERNAL_PTR UnityFloatToPtr(const float num) 1612 | { 1613 | UnityQuickCompare.f = num; 1614 | return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.f); 1615 | } 1616 | #endif 1617 | 1618 | #ifndef UNITY_EXCLUDE_DOUBLE 1619 | /*-----------------------------------------------*/ 1620 | UNITY_INTERNAL_PTR UnityDoubleToPtr(const double num) 1621 | { 1622 | UnityQuickCompare.d = num; 1623 | return (UNITY_INTERNAL_PTR)(&UnityQuickCompare.d); 1624 | } 1625 | #endif 1626 | 1627 | /*----------------------------------------------- 1628 | * printf helper function 1629 | *-----------------------------------------------*/ 1630 | #ifdef UNITY_INCLUDE_PRINT_FORMATTED 1631 | static void UnityPrintFVA(const char* format, va_list va) 1632 | { 1633 | const char* pch = format; 1634 | if (pch != NULL) 1635 | { 1636 | while (*pch) 1637 | { 1638 | /* format identification character */ 1639 | if (*pch == '%') 1640 | { 1641 | pch++; 1642 | 1643 | if (pch != NULL) 1644 | { 1645 | switch (*pch) 1646 | { 1647 | case 'd': 1648 | case 'i': 1649 | { 1650 | const int number = va_arg(va, int); 1651 | UnityPrintNumber((UNITY_INT)number); 1652 | break; 1653 | } 1654 | #ifndef UNITY_EXCLUDE_FLOAT_PRINT 1655 | case 'f': 1656 | case 'g': 1657 | { 1658 | const double number = va_arg(va, double); 1659 | UnityPrintFloat((UNITY_DOUBLE)number); 1660 | break; 1661 | } 1662 | #endif 1663 | case 'u': 1664 | { 1665 | const unsigned int number = va_arg(va, unsigned int); 1666 | UnityPrintNumberUnsigned((UNITY_UINT)number); 1667 | break; 1668 | } 1669 | case 'b': 1670 | { 1671 | const unsigned int number = va_arg(va, unsigned int); 1672 | const UNITY_UINT mask = (UNITY_UINT)0 - (UNITY_UINT)1; 1673 | UNITY_OUTPUT_CHAR('0'); 1674 | UNITY_OUTPUT_CHAR('b'); 1675 | UnityPrintMask(mask, (UNITY_UINT)number); 1676 | break; 1677 | } 1678 | case 'x': 1679 | case 'X': 1680 | case 'p': 1681 | { 1682 | const unsigned int number = va_arg(va, unsigned int); 1683 | UNITY_OUTPUT_CHAR('0'); 1684 | UNITY_OUTPUT_CHAR('x'); 1685 | UnityPrintNumberHex((UNITY_UINT)number, 8); 1686 | break; 1687 | } 1688 | case 'c': 1689 | { 1690 | const int ch = va_arg(va, int); 1691 | UnityPrintChar((const char *)&ch); 1692 | break; 1693 | } 1694 | case 's': 1695 | { 1696 | const char * string = va_arg(va, const char *); 1697 | UnityPrint(string); 1698 | break; 1699 | } 1700 | case '%': 1701 | { 1702 | UnityPrintChar(pch); 1703 | break; 1704 | } 1705 | default: 1706 | { 1707 | /* print the unknown format character */ 1708 | UNITY_OUTPUT_CHAR('%'); 1709 | UnityPrintChar(pch); 1710 | break; 1711 | } 1712 | } 1713 | } 1714 | } 1715 | #ifdef UNITY_OUTPUT_COLOR 1716 | /* print ANSI escape code */ 1717 | else if ((*pch == 27) && (*(pch + 1) == '[')) 1718 | { 1719 | pch += UnityPrintAnsiEscapeString(pch); 1720 | continue; 1721 | } 1722 | #endif 1723 | else if (*pch == '\n') 1724 | { 1725 | UNITY_PRINT_EOL(); 1726 | } 1727 | else 1728 | { 1729 | UnityPrintChar(pch); 1730 | } 1731 | 1732 | pch++; 1733 | } 1734 | } 1735 | } 1736 | 1737 | void UnityPrintF(const UNITY_LINE_TYPE line, const char* format, ...) 1738 | { 1739 | UnityTestResultsBegin(Unity.TestFile, line); 1740 | UnityPrint("INFO"); 1741 | if(format != NULL) 1742 | { 1743 | UnityPrint(": "); 1744 | va_list va; 1745 | va_start(va, format); 1746 | UnityPrintFVA(format, va); 1747 | va_end(va); 1748 | } 1749 | UNITY_PRINT_EOL(); 1750 | } 1751 | #endif /* ! UNITY_INCLUDE_PRINT_FORMATTED */ 1752 | 1753 | 1754 | /*----------------------------------------------- 1755 | * Control Functions 1756 | *-----------------------------------------------*/ 1757 | 1758 | /*-----------------------------------------------*/ 1759 | void UnityFail(const char* msg, const UNITY_LINE_TYPE line) 1760 | { 1761 | RETURN_IF_FAIL_OR_IGNORE; 1762 | 1763 | UnityTestResultsBegin(Unity.TestFile, line); 1764 | UnityPrint(UnityStrFail); 1765 | if (msg != NULL) 1766 | { 1767 | UNITY_OUTPUT_CHAR(':'); 1768 | 1769 | #ifdef UNITY_PRINT_TEST_CONTEXT 1770 | UNITY_PRINT_TEST_CONTEXT(); 1771 | #endif 1772 | #ifndef UNITY_EXCLUDE_DETAILS 1773 | if (Unity.CurrentDetail1) 1774 | { 1775 | UnityPrint(UnityStrDetail1Name); 1776 | UnityPrint(Unity.CurrentDetail1); 1777 | if (Unity.CurrentDetail2) 1778 | { 1779 | UnityPrint(UnityStrDetail2Name); 1780 | UnityPrint(Unity.CurrentDetail2); 1781 | } 1782 | UnityPrint(UnityStrSpacer); 1783 | } 1784 | #endif 1785 | if (msg[0] != ' ') 1786 | { 1787 | UNITY_OUTPUT_CHAR(' '); 1788 | } 1789 | UnityPrint(msg); 1790 | } 1791 | 1792 | UNITY_FAIL_AND_BAIL; 1793 | } 1794 | 1795 | /*-----------------------------------------------*/ 1796 | void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) 1797 | { 1798 | RETURN_IF_FAIL_OR_IGNORE; 1799 | 1800 | UnityTestResultsBegin(Unity.TestFile, line); 1801 | UnityPrint(UnityStrIgnore); 1802 | if (msg != NULL) 1803 | { 1804 | UNITY_OUTPUT_CHAR(':'); 1805 | UNITY_OUTPUT_CHAR(' '); 1806 | UnityPrint(msg); 1807 | } 1808 | UNITY_IGNORE_AND_BAIL; 1809 | } 1810 | 1811 | /*-----------------------------------------------*/ 1812 | void UnityMessage(const char* msg, const UNITY_LINE_TYPE line) 1813 | { 1814 | UnityTestResultsBegin(Unity.TestFile, line); 1815 | UnityPrint("INFO"); 1816 | if (msg != NULL) 1817 | { 1818 | UNITY_OUTPUT_CHAR(':'); 1819 | UNITY_OUTPUT_CHAR(' '); 1820 | UnityPrint(msg); 1821 | } 1822 | UNITY_PRINT_EOL(); 1823 | } 1824 | 1825 | /*-----------------------------------------------*/ 1826 | /* If we have not defined our own test runner, then include our default test runner to make life easier */ 1827 | #ifndef UNITY_SKIP_DEFAULT_RUNNER 1828 | void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) 1829 | { 1830 | Unity.CurrentTestName = FuncName; 1831 | Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; 1832 | Unity.NumberOfTests++; 1833 | UNITY_CLR_DETAILS(); 1834 | UNITY_EXEC_TIME_START(); 1835 | if (TEST_PROTECT()) 1836 | { 1837 | setUp(); 1838 | Func(); 1839 | } 1840 | if (TEST_PROTECT()) 1841 | { 1842 | tearDown(); 1843 | } 1844 | UNITY_EXEC_TIME_STOP(); 1845 | UnityConcludeTest(); 1846 | } 1847 | #endif 1848 | 1849 | /*-----------------------------------------------*/ 1850 | void UnitySetTestFile(const char* filename) 1851 | { 1852 | Unity.TestFile = filename; 1853 | } 1854 | 1855 | /*-----------------------------------------------*/ 1856 | void UnityBegin(const char* filename) 1857 | { 1858 | Unity.TestFile = filename; 1859 | Unity.CurrentTestName = NULL; 1860 | Unity.CurrentTestLineNumber = 0; 1861 | Unity.NumberOfTests = 0; 1862 | Unity.TestFailures = 0; 1863 | Unity.TestIgnores = 0; 1864 | Unity.CurrentTestFailed = 0; 1865 | Unity.CurrentTestIgnored = 0; 1866 | 1867 | UNITY_CLR_DETAILS(); 1868 | UNITY_OUTPUT_START(); 1869 | } 1870 | 1871 | /*-----------------------------------------------*/ 1872 | int UnityEnd(void) 1873 | { 1874 | UNITY_PRINT_EOL(); 1875 | UnityPrint(UnityStrBreaker); 1876 | UNITY_PRINT_EOL(); 1877 | UnityPrintNumber((UNITY_INT)(Unity.NumberOfTests)); 1878 | UnityPrint(UnityStrResultsTests); 1879 | UnityPrintNumber((UNITY_INT)(Unity.TestFailures)); 1880 | UnityPrint(UnityStrResultsFailures); 1881 | UnityPrintNumber((UNITY_INT)(Unity.TestIgnores)); 1882 | UnityPrint(UnityStrResultsIgnored); 1883 | UNITY_PRINT_EOL(); 1884 | if (Unity.TestFailures == 0U) 1885 | { 1886 | UnityPrint(UnityStrOk); 1887 | } 1888 | else 1889 | { 1890 | UnityPrint(UnityStrFail); 1891 | #ifdef UNITY_DIFFERENTIATE_FINAL_FAIL 1892 | UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); 1893 | #endif 1894 | } 1895 | UNITY_PRINT_EOL(); 1896 | UNITY_FLUSH_CALL(); 1897 | UNITY_OUTPUT_COMPLETE(); 1898 | return (int)(Unity.TestFailures); 1899 | } 1900 | 1901 | /*----------------------------------------------- 1902 | * Command Line Argument Support 1903 | *-----------------------------------------------*/ 1904 | #ifdef UNITY_USE_COMMAND_LINE_ARGS 1905 | 1906 | char* UnityOptionIncludeNamed = NULL; 1907 | char* UnityOptionExcludeNamed = NULL; 1908 | int UnityVerbosity = 1; 1909 | 1910 | /*-----------------------------------------------*/ 1911 | int UnityParseOptions(int argc, char** argv) 1912 | { 1913 | int i; 1914 | UnityOptionIncludeNamed = NULL; 1915 | UnityOptionExcludeNamed = NULL; 1916 | 1917 | for (i = 1; i < argc; i++) 1918 | { 1919 | if (argv[i][0] == '-') 1920 | { 1921 | switch (argv[i][1]) 1922 | { 1923 | case 'l': /* list tests */ 1924 | return -1; 1925 | case 'n': /* include tests with name including this string */ 1926 | case 'f': /* an alias for -n */ 1927 | if (argv[i][2] == '=') 1928 | { 1929 | UnityOptionIncludeNamed = &argv[i][3]; 1930 | } 1931 | else if (++i < argc) 1932 | { 1933 | UnityOptionIncludeNamed = argv[i]; 1934 | } 1935 | else 1936 | { 1937 | UnityPrint("ERROR: No Test String to Include Matches For"); 1938 | UNITY_PRINT_EOL(); 1939 | return 1; 1940 | } 1941 | break; 1942 | case 'q': /* quiet */ 1943 | UnityVerbosity = 0; 1944 | break; 1945 | case 'v': /* verbose */ 1946 | UnityVerbosity = 2; 1947 | break; 1948 | case 'x': /* exclude tests with name including this string */ 1949 | if (argv[i][2] == '=') 1950 | { 1951 | UnityOptionExcludeNamed = &argv[i][3]; 1952 | } 1953 | else if (++i < argc) 1954 | { 1955 | UnityOptionExcludeNamed = argv[i]; 1956 | } 1957 | else 1958 | { 1959 | UnityPrint("ERROR: No Test String to Exclude Matches For"); 1960 | UNITY_PRINT_EOL(); 1961 | return 1; 1962 | } 1963 | break; 1964 | default: 1965 | UnityPrint("ERROR: Unknown Option "); 1966 | UNITY_OUTPUT_CHAR(argv[i][1]); 1967 | UNITY_PRINT_EOL(); 1968 | return 1; 1969 | } 1970 | } 1971 | } 1972 | 1973 | return 0; 1974 | } 1975 | 1976 | /*-----------------------------------------------*/ 1977 | int IsStringInBiggerString(const char* longstring, const char* shortstring) 1978 | { 1979 | const char* lptr = longstring; 1980 | const char* sptr = shortstring; 1981 | const char* lnext = lptr; 1982 | 1983 | if (*sptr == '*') 1984 | { 1985 | return 1; 1986 | } 1987 | 1988 | while (*lptr) 1989 | { 1990 | lnext = lptr + 1; 1991 | 1992 | /* If they current bytes match, go on to the next bytes */ 1993 | while (*lptr && *sptr && (*lptr == *sptr)) 1994 | { 1995 | lptr++; 1996 | sptr++; 1997 | 1998 | /* We're done if we match the entire string or up to a wildcard */ 1999 | if (*sptr == '*') 2000 | return 1; 2001 | if (*sptr == ',') 2002 | return 1; 2003 | if (*sptr == '"') 2004 | return 1; 2005 | if (*sptr == '\'') 2006 | return 1; 2007 | if (*sptr == ':') 2008 | return 2; 2009 | if (*sptr == 0) 2010 | return 1; 2011 | } 2012 | 2013 | /* Otherwise we start in the long pointer 1 character further and try again */ 2014 | lptr = lnext; 2015 | sptr = shortstring; 2016 | } 2017 | 2018 | return 0; 2019 | } 2020 | 2021 | /*-----------------------------------------------*/ 2022 | int UnityStringArgumentMatches(const char* str) 2023 | { 2024 | int retval; 2025 | const char* ptr1; 2026 | const char* ptr2; 2027 | const char* ptrf; 2028 | 2029 | /* Go through the options and get the substrings for matching one at a time */ 2030 | ptr1 = str; 2031 | while (ptr1[0] != 0) 2032 | { 2033 | if ((ptr1[0] == '"') || (ptr1[0] == '\'')) 2034 | { 2035 | ptr1++; 2036 | } 2037 | 2038 | /* look for the start of the next partial */ 2039 | ptr2 = ptr1; 2040 | ptrf = 0; 2041 | do 2042 | { 2043 | ptr2++; 2044 | if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) 2045 | { 2046 | ptrf = &ptr2[1]; 2047 | } 2048 | } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); 2049 | 2050 | while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) 2051 | { 2052 | ptr2++; 2053 | } 2054 | 2055 | /* done if complete filename match */ 2056 | retval = IsStringInBiggerString(Unity.TestFile, ptr1); 2057 | if (retval == 1) 2058 | { 2059 | return retval; 2060 | } 2061 | 2062 | /* done if testname match after filename partial match */ 2063 | if ((retval == 2) && (ptrf != 0)) 2064 | { 2065 | if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) 2066 | { 2067 | return 1; 2068 | } 2069 | } 2070 | 2071 | /* done if complete testname match */ 2072 | if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) 2073 | { 2074 | return 1; 2075 | } 2076 | 2077 | ptr1 = ptr2; 2078 | } 2079 | 2080 | /* we couldn't find a match for any substrings */ 2081 | return 0; 2082 | } 2083 | 2084 | /*-----------------------------------------------*/ 2085 | int UnityTestMatches(void) 2086 | { 2087 | /* Check if this test name matches the included test pattern */ 2088 | int retval; 2089 | if (UnityOptionIncludeNamed) 2090 | { 2091 | retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); 2092 | } 2093 | else 2094 | { 2095 | retval = 1; 2096 | } 2097 | 2098 | /* Check if this test name matches the excluded test pattern */ 2099 | if (UnityOptionExcludeNamed) 2100 | { 2101 | if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) 2102 | { 2103 | retval = 0; 2104 | } 2105 | } 2106 | 2107 | return retval; 2108 | } 2109 | 2110 | #endif /* UNITY_USE_COMMAND_LINE_ARGS */ 2111 | /*-----------------------------------------------*/ 2112 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/Makefile: -------------------------------------------------------------------------------- 1 | # Name of the project 2 | PROJECT_NAME = PhoneBook 3 | 4 | # Output directory 5 | BUILD = build 6 | 7 | # All source code files 8 | SRC = src/add_contact.c\ 9 | src/delete_contact.c\ 10 | src/display_contact.c\ 11 | src/modify_contact.c\ 12 | src/search_contact.c\ 13 | src/utility.c\ 14 | 15 | # All test source files 16 | TEST_SRC = ${SRC}\ 17 | test/phone_book_test.c\ 18 | unity/unity.c\ 19 | 20 | TEST_OUTPUT = $(BUILD)/Test_$(PROJECT_NAME).out 21 | 22 | # All include folders with header files 23 | INC = -Iinc\ 24 | -Iunity\ 25 | 26 | #Library Inlcudes 27 | INCLUDE_LIBS = 28 | 29 | # Project Output name 30 | PROJECT_OUTPUT = $(BUILD)/$(PROJECT_NAME).out 31 | 32 | # Document files 33 | DOCUMENTATION_OUTPUT = documentation/html 34 | 35 | # Default target built 36 | $(PROJECT_NAME):all 37 | 38 | # Run the target even if the matching name exists 39 | .PHONY: run clean test doc all 40 | 41 | all: $(SRC) $(BUILD) 42 | gcc phone_book.c $(SRC) $(INC) -o $(PROJECT_OUTPUT).out 43 | 44 | # Call `make run` to run the application 45 | run:$(PROJECT_NAME) 46 | ./$(PROJECT_OUTPUT).out 47 | 48 | # Document the code using Doxygen 49 | doc: 50 | make -C ./documentation 51 | 52 | # Build and run the unit tests 53 | test:$(BUILD) 54 | gcc $(TEST_SRC) $(INC) -o $(TEST_OUTPUT) $(INCLUDE_LIBS) 55 | ./$(TEST_OUTPUT) 56 | 57 | # Remove all the built files, invoke by `make clean` 58 | clean: 59 | rm -rf $(BUILD) $(DOCUMENTATION_OUTPUT) contacts.bin 60 | 61 | # Create new build folder if not present 62 | $(BUILD): 63 | mkdir build -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/doc/documentation.md: -------------------------------------------------------------------------------- 1 | @mainpage Phone Book 2 | 3 | This is a Phoone book application 4 | 5 | #TO-DO 6 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/add_contact.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file add_contact.h 3 | * 4 | */ 5 | 6 | #ifndef __ADD_CONTACT_H__ 7 | #define __ADD_CONTACT_H__ 8 | 9 | #include "contact.h" 10 | 11 | int add_contact(contact_t *contact); 12 | 13 | void create_new_contact(contact_t *contact); 14 | 15 | #endif //__ADD_CONTACT_H__ 16 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/contact.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file contact.h 3 | * 4 | */ 5 | #ifndef __CONTACT_H__ 6 | #define __CONTACT_H__ 7 | 8 | enum max_lengths { 9 | MAX_NAME_LEN = 32, 10 | MAX_PHONE_NUMBER_LEN = 15, 11 | MAX_EMAIL_ID_LEN = 100 12 | }; 13 | 14 | typedef struct contact_t{ 15 | char name[MAX_NAME_LEN]; 16 | char ph_number[MAX_PHONE_NUMBER_LEN]; 17 | char email_id[MAX_EMAIL_ID_LEN]; 18 | }contact_t; 19 | 20 | #endif //__CONTACT_H__ 21 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/delete_contact.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file delete_contact.h 3 | * 4 | */ 5 | 6 | #ifndef __DELETE_CONTACT_H__ 7 | #define __DELETE_CONTACT_H__ 8 | 9 | #include "contact.h" 10 | 11 | int delete_contact(const char* name); 12 | 13 | #endif //__DELETE_CONTACT_H__ 14 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/display_contact.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file display_contact.h 3 | * 4 | */ 5 | 6 | #ifndef __DISPLAY_CONTACT_H__ 7 | #define __DISPLAY_CONTACT_H__ 8 | 9 | #include "contact.h" 10 | 11 | int display_contact(void); 12 | 13 | #endif //__DISPLAY_CONTACT_H__ 14 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/modify_contact.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file modify_contact.h 3 | * 4 | */ 5 | 6 | #ifndef __MODIFY_CONTACT_H__ 7 | #define __MODIFY_CONTACT_H__ 8 | 9 | #include "contact.h" 10 | 11 | int modify_contact(char *name, contact_t* update_contact); 12 | 13 | #endif //__MODIFY_CONTACT_H__ 14 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/phone_book.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file phone_book.h 3 | * 4 | */ 5 | 6 | #ifndef __PHONE_BOOK_H__ 7 | #define __PHONE_BOOK_H__ 8 | 9 | #include "utility.h" 10 | #include "contact.h" 11 | #include "add_contact.h" 12 | #include "delete_contact.h" 13 | #include "modify_contact.h" 14 | #include "search_contact.h" 15 | #include "display_contact.h" 16 | 17 | #endif //__PHONE_BOOK_H__ 18 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/search_contact.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file search_contact.h 3 | * 4 | */ 5 | 6 | #ifndef __SEARCH_CONTACT_H__ 7 | #define __SEARCH_CONTACT_H__ 8 | 9 | #include "contact.h" 10 | 11 | int search_contact(const char* name); 12 | 13 | #endif //__SEARCH_CONTACT_H__ 14 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/inc/utility.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file utility.h 3 | * 4 | */ 5 | #ifndef __UTILITY_H__ 6 | #define __UTILITY_H__ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "contact.h" 14 | 15 | void get_data(char *name); 16 | void get_contact_details(contact_t *contact); 17 | 18 | #endif //__UTILITY_H__ 19 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/phone_book.c: -------------------------------------------------------------------------------- 1 | #include "phone_book.h" 2 | 3 | typedef enum options { 4 | NONE, 5 | ADD_CONTACT, 6 | MODIFY_CONTACT, 7 | DELETE_CONTACT, 8 | DISPLAY_CONTACTS, 9 | SEARCH_CONTACTS, 10 | EXIT 11 | } options_t; 12 | 13 | int main() { 14 | int choice = NONE; 15 | 16 | printf("\n\t****Welcome to Phone book application****\n"); 17 | for (;;) { 18 | 19 | printf("\nSelect your choice: \n"); 20 | printf("1.Add Contact \n2.Modify Contact \n3.Delete Contact \ 21 | \n4.Display all Contacts \n5.Search for a contact\n6.Exit\n"); 22 | 23 | printf("Enter your choice: "); 24 | __fpurge(stdin); 25 | scanf("%d", &choice); 26 | 27 | switch (choice) { 28 | case ADD_CONTACT: { 29 | contact_t *new_contact = (contact_t *)calloc(1, sizeof(contact_t)); 30 | 31 | get_contact_details(new_contact); 32 | switch (add_contact(new_contact)) { 33 | case 0: 34 | printf("\n\t Add contact successful"); 35 | break; 36 | default: 37 | printf("\n\t***Error in adding contact***"); 38 | } 39 | free(new_contact); 40 | break; 41 | } 42 | case DELETE_CONTACT: { 43 | int contact_count = display_contact(); 44 | if (0 < contact_count) { 45 | char name[MAX_NAME_LEN] = ""; 46 | 47 | printf("Enter Contact'S Name from above list:"); 48 | get_data(name); 49 | 50 | switch (delete_contact(name)) { 51 | case -1: 52 | printf("\n\t***No Matching contact found***\n"); 53 | break; 54 | case -2: 55 | printf("\n\t***No contact found***\n"); 56 | break; 57 | case 0: 58 | printf("\n\t***Contact record deleted successfuly***\n"); 59 | break; 60 | default: 61 | printf("\n\t***Error in Delete contact***"); 62 | } 63 | } else if (contact_count == 0) { 64 | printf("\n\t***No contact found***\n"); 65 | } 66 | break; 67 | } 68 | case MODIFY_CONTACT: { 69 | int contact_count = display_contact(); 70 | if (0 < contact_count) { 71 | char name[MAX_NAME_LEN] = ""; 72 | contact_t *new_contact = (contact_t *)calloc(1, sizeof(contact_t)); 73 | 74 | printf("Enter Contact'S Name from above list:"); 75 | 76 | get_data(name); 77 | get_contact_details(new_contact); 78 | 79 | switch (modify_contact(name, new_contact)) { 80 | case -1: 81 | printf("\n\t***No Matching contact found***\n"); 82 | break; 83 | case -2: 84 | printf("\n\t***No contact found***\n"); 85 | break; 86 | case 0: 87 | printf("\n\t***Contact record Modify successfuly***\n"); 88 | break; 89 | default: 90 | printf("\n\t***Error in Modify contact***"); 91 | } 92 | free(new_contact); 93 | } else if (contact_count == 0) { 94 | printf("\n\t***No contact found***\n"); 95 | } 96 | break; 97 | } 98 | case DISPLAY_CONTACTS: 99 | switch (display_contact()) { 100 | case -2: 101 | printf("\n\t***No Contacts found***\n\n"); 102 | break; 103 | case 0: 104 | printf("\n\t***No Contacts found***\n\n"); 105 | break; 106 | default: 107 | printf("\n\t***Display contacts record successfuly***\n"); 108 | } 109 | break; 110 | 111 | case SEARCH_CONTACTS: { 112 | int contact_count = display_contact(); 113 | if (0 < contact_count) { 114 | char name[MAX_NAME_LEN] = ""; 115 | 116 | printf("\nEnter name of person to search\n"); 117 | __fpurge(stdin); 118 | get_data(name); 119 | 120 | switch (search_contact(name)) { 121 | case -1: 122 | printf("\n\t***No Matching contact found***\n"); 123 | break; 124 | case -2: 125 | printf("\n\t***No Contacts found***\n\n"); 126 | break; 127 | case 0: 128 | printf("\n\t***Search Successful***\n"); 129 | break; 130 | default: 131 | printf("\n\t***Error in Search contact***"); 132 | } 133 | } 134 | 135 | else if (contact_count == 0) { 136 | printf("\n\t***No contact found***\n"); 137 | } 138 | break; 139 | } 140 | case EXIT: 141 | printf("\n\t****Exiting application****\n"); 142 | exit(0); 143 | break; 144 | 145 | default: 146 | printf("\n\t***Selected option not available***"); 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/src/add_contact.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "add_contact.h" 6 | #include "utility.h" 7 | 8 | int add_contact(contact_t *contact) { 9 | 10 | FILE *fptr; 11 | if ((fptr = fopen("contacts.bin", "ab+")) == NULL) { 12 | return -1; 13 | } 14 | fwrite(contact, sizeof(contact_t), 1, fptr); 15 | 16 | __fpurge(stdin); 17 | fclose(fptr); 18 | 19 | return 0; 20 | } 21 | /* 22 | void create_new_contact(contact_t *contact) { 23 | printf("\nEnter name: "); 24 | get_data(contact->name); 25 | 26 | printf("\nEnter the Phone number: "); 27 | get_data(contact->ph_number); 28 | 29 | printf("\nEnter Email ID: "); 30 | get_data(contact->email_id); 31 | } 32 | */ -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/src/delete_contact.c: -------------------------------------------------------------------------------- 1 | #include "delete_contact.h" 2 | #include "utility.h" 3 | 4 | int delete_contact(const char *name) { 5 | contact_t contact; 6 | FILE *f, *ft; 7 | int flag, result; 8 | 9 | f = fopen("contacts.bin", "rb"); 10 | if (f == NULL) { 11 | return -2; 12 | } else { 13 | ft = fopen("temp.bin", "wb+"); 14 | if (ft == NULL) { 15 | result = -3; 16 | } else { 17 | 18 | while (fread(&contact, sizeof(contact_t), 1, f) == 1) { 19 | if (strcmp(contact.name, name) != 0) 20 | fwrite(&contact, sizeof(contact_t), 1, ft); 21 | if (strcmp(contact.name, name) == 0) 22 | flag = 1; 23 | } 24 | fclose(f); 25 | f = NULL; 26 | fclose(ft); 27 | 28 | if (flag != 1) { 29 | remove("temp.bin"); 30 | result = -1; 31 | } else { 32 | remove("contacts.bin"); 33 | rename("temp.bin", "contacts.bin"); 34 | result = 0; 35 | } 36 | } 37 | } 38 | if (NULL != f) 39 | fclose(f); 40 | 41 | return result; 42 | } 43 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/src/display_contact.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "display_contact.h" 5 | 6 | int display_contact(void) { 7 | contact_t contact; 8 | FILE *fptr; 9 | int count = 0; 10 | if ((fptr = fopen("contacts.bin", "rb")) == NULL) { 11 | return -2; 12 | } 13 | 14 | printf("\n### Phone book contacts ###\n"); 15 | while (fread(&contact, sizeof(contact), 1, fptr) == 1) { 16 | printf("Name = %s\nPhone Number = %s\nEmail ID = %s\n\n", contact.name, 17 | contact.ph_number, contact.email_id); 18 | count++; 19 | } 20 | printf("### Phone book contacts ###\n\n"); 21 | fclose(fptr); 22 | return count; 23 | } 24 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/src/modify_contact.c: -------------------------------------------------------------------------------- 1 | #include "modify_contact.h" 2 | #include "utility.h" 3 | 4 | int modify_contact(char *name, contact_t *update_contact) { 5 | int result = 0; 6 | FILE *fptr; 7 | int flag = 0; 8 | contact_t old_contact; 9 | 10 | fptr = fopen("contacts.bin", "rb+"); 11 | 12 | if (fptr == NULL) { 13 | return -2; 14 | } else { 15 | 16 | while (fread(&old_contact, sizeof(contact_t), 1, fptr) == 1) { 17 | if (strcmp(name, old_contact.name) == 0) { 18 | fseek(fptr, -sizeof(contact_t), SEEK_CUR); 19 | fwrite(update_contact, sizeof(contact_t), 1, fptr); 20 | flag = 1; 21 | break; 22 | } 23 | } 24 | if (flag == 1) { 25 | result = 0; 26 | } else { 27 | result = -1; 28 | } 29 | fclose(fptr); 30 | } 31 | return result; 32 | } 33 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/src/search_contact.c: -------------------------------------------------------------------------------- 1 | #include "search_contact.h" 2 | #include "utility.h" 3 | 4 | int search_contact(const char *name) { 5 | contact_t contact; 6 | FILE *f; 7 | 8 | f = fopen("contacts.bin", "rb"); 9 | if (f == NULL) { 10 | return -2; 11 | } 12 | 13 | while (fread(&contact, sizeof(contact_t), 1, f) == 1) { 14 | if (strcmp(contact.name, name) == 0) { 15 | printf("\nContact details for %s:\n", name); 16 | printf("Name = %s\nPhone Number = %s\nEmail ID = %s\n\n", contact.name, 17 | contact.ph_number, contact.email_id); 18 | fclose(f); 19 | return 0; 20 | } 21 | } 22 | fclose(f); 23 | return -1; 24 | } 25 | -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/src/utility.c: -------------------------------------------------------------------------------- 1 | #include "utility.h" 2 | #include "contact.h" 3 | 4 | void get_data(char *name) { 5 | 6 | int i = 0, j; 7 | char c, ch; 8 | __fpurge(stdin); 9 | do { 10 | c = getchar(); 11 | if (c != '\n') { 12 | *(name + i) = c; 13 | putchar(c); 14 | i++; 15 | } 16 | if (c == 8) { 17 | if (i > 0) { 18 | i--; 19 | } 20 | for (j = 0; j < i; j++) { 21 | ch = *(name + j); 22 | putchar(ch); 23 | } 24 | } 25 | } while (c != '\n'); 26 | *(name + i) = '\0'; 27 | } 28 | 29 | void get_contact_details(contact_t *contact) { 30 | printf("\nEnter name: "); 31 | __fpurge(stdin); 32 | get_data(contact->name); 33 | 34 | printf("\nEnter the Phone number: "); 35 | __fpurge(stdin); 36 | get_data(contact->ph_number); 37 | 38 | printf("\nEnter Email ID: "); 39 | __fpurge(stdin); 40 | get_data(contact->email_id); 41 | } -------------------------------------------------------------------------------- /Example_Programs/PhoneBook/test/phone_book_test.c: -------------------------------------------------------------------------------- 1 | #include "unity.h" 2 | #include "phone_book.h" 3 | 4 | /* Required by the unity test framework */ 5 | void setUp(){} 6 | /* Required by the unity test framework */ 7 | void tearDown(){} 8 | 9 | void test_add_contact(void) { 10 | contact_t new_contact = {"Add_user", "12345", "user1@email.com"}; 11 | TEST_ASSERT_EQUAL(0, add_contact(&new_contact)); 12 | } 13 | 14 | void test_delete_contact(void) { 15 | contact_t new_contact = {"Delete_user", "12345", "user1@email.com"}; 16 | TEST_ASSERT_EQUAL(0, add_contact(&new_contact)); 17 | TEST_ASSERT_EQUAL(0, delete_contact(new_contact.name)); 18 | } 19 | 20 | void test_modify_contact(void) { 21 | contact_t new_contact = {"Modify_User", "12345", "user1@email.com"}; 22 | contact_t new_contact1 = {"Modified_User", "345", "new@email.com"}; 23 | TEST_ASSERT_EQUAL(0, add_contact(&new_contact)); 24 | TEST_ASSERT_EQUAL(0, modify_contact(new_contact.name, &new_contact1)); 25 | TEST_ASSERT_EQUAL(0, delete_contact(new_contact1.name)); 26 | } 27 | void test_search_contact(void) { 28 | contact_t new_contact = {"Search_User", "345", "new@email.com"}; 29 | TEST_ASSERT_EQUAL(0, add_contact(&new_contact)); 30 | TEST_ASSERT_EQUAL(0 , search_contact(new_contact.name)); 31 | TEST_ASSERT_EQUAL(0 , delete_contact(new_contact.name)); 32 | } 33 | void test_display_contact(void) 34 | { 35 | TEST_ASSERT_EQUAL(1, display_contact()>0); 36 | } 37 | 38 | int main(void) 39 | { 40 | /* Initiate the Unity Test Framework */ 41 | UNITY_BEGIN(); 42 | 43 | /* Run Test functions */ 44 | RUN_TEST(test_add_contact); 45 | RUN_TEST(test_delete_contact); 46 | RUN_TEST(test_modify_contact); 47 | RUN_TEST(test_search_contact); 48 | RUN_TEST(test_display_contact); 49 | 50 | /* Close the Unity Test Framework */ 51 | return UNITY_END(); 52 | } 53 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/0_helloworld.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 0_helloworld.c 3 | * @author Bharath G 4 | * @brief First program 5 | * @version 0.1 6 | * @date 2021-03-16 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | */ 11 | #include 12 | /** 13 | * @brief Print message 14 | * 15 | * @return int 16 | */ 17 | int main() 18 | { 19 | int a = 10; 20 | 21 | int sum =20; 22 | printf("Welcome to STEPin\n"); 23 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/1_memory_map.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 1_mmeory_map.c 3 | * @author Bharath G 4 | * @brief Program to show in which section of the memory map each variable is stored. 5 | * Adding qualifiers like const and static change the sections. 6 | * Initialized and Uninitialized variables are stored in different sections. 7 | * 8 | * To check the memory map or the symbols created, run below commands 9 | * gcc -c memory_map.c 10 | * nm memory_map.o 11 | * @version 0.1 12 | * @date 2021-03-16 13 | * 14 | * @copyright Copyright (c) 2021 15 | * 16 | */ 17 | 18 | int global_initialized_variable = 10; 19 | int global_uninitialized_variable; 20 | 21 | static int global_static_initialized_variable = 10; 22 | static int global_static_initialized_variable; 23 | 24 | const int global_const_initialized_variable = 10; 25 | 26 | static const int global_static_const_initialized_variable = 10; 27 | static const int global_static_const_uninitialized_variable; 28 | 29 | /* Function prototype */ 30 | int referenced_function(int,int); 31 | 32 | void normal_function() 33 | { 34 | // Function body 35 | } 36 | 37 | static void static_function() 38 | { 39 | // Function body 40 | } 41 | 42 | int main() 43 | { 44 | int x, y, z; 45 | 46 | const int local_const_initialized_variable = 10; 47 | const int local_const_uninitialized_variable; 48 | 49 | static int local_static_initialized_variable = 1000; 50 | static int local_static_uninitialized_variable; 51 | 52 | 53 | static const int local_static_const_initialized_variable = 2000; 54 | static const int local_static_const_uninitialized_variable; 55 | 56 | /* Definition is not provided in this file, hence compilation will fail. 57 | So use " -c " option in gcc to stop after object file generation */ 58 | z = referenced_function(x, y); 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/2_lazy_evaluation.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 2_lazy_evaluation.c 3 | * @author Bharath G 4 | * @brief Example to show the lazy evaluation or short circuit behaviour of logical expressions 5 | * @version 0.1 6 | * @date 2021-03-16 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | */ 11 | 12 | #include 13 | 14 | int main(void) { 15 | int a = 20; 16 | int b = -5; 17 | 18 | if (a != 20 && b++) 19 | printf("Inside 1st if condition, b = %d\n", b); 20 | 21 | printf("After 1st if condition, b = %d\n", b); 22 | 23 | if (a == 20 || b++) 24 | printf("Inside 2nd if condition, b = %d\n", b); 25 | 26 | printf("After 2nd if condition, b = %d\n", b); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/3_sequence_points.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @brief Example to show the sequence points 3 | * Since compilers have option to implement the sequence points, every compiler implements in thier own way. 4 | * The same can be seen from this website: https://godbolt.org/ 5 | */ 6 | 7 | unsigned counter = 0; 8 | 9 | unsigned account(void) { 10 | return counter++; 11 | } 12 | 13 | int main() 14 | { 15 | int i = 0; 16 | int a[10] ={}; 17 | 18 | /* Expressions with no Sequnece points */ 19 | a[i++] = i; 20 | a[i] = i++; 21 | 22 | f() + g(); 23 | 24 | i++ * i++; 25 | 26 | i++ & i++; 27 | f(x++, x++); /* the ',' in a function call is *not* the same as the comma operator */ 28 | i++ * i++; 29 | 30 | printf("the order is %u %u\n", account(), account()); 31 | } 32 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/4_pre_processors.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 4_pre_processors.c 3 | * @author Bharath G 4 | * @brief Preprocessor directives in C 5 | * @version 0.1 6 | * @date 2021-03-16 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | # Checklist 11 | * Role of preprocessor 12 | * Special constants &directives 13 | * Macro examples,side effects 14 | * Conditional inclusion directives 15 | #include 16 | #define 17 | #undef 18 | #ifdef 19 | #ifndef 20 | #if 21 | #else 22 | #elif 23 | #endif 24 | #error 25 | #pragma 26 | defined 27 | 28 | * Header guard technique - include once only : #ifndef vs #pragma once 29 | * Special constants: __FILE__,__LINE__, __FUNCTION__, __DATE__,__TIME__ 30 | * Special directives : #line 31 | * Special operators :##, # 32 | */ -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/5_recursion.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 5_recursion.c 3 | * @author Bharath G 4 | * @brief Example to understand recursive functions 5 | * @version 0.1 6 | * @date 2021-03-16 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | * @note Visualizer: https://www.cs.usfca.edu/~galles/visualization/RecFact.html 11 | */ 12 | 13 | #include 14 | unsigned long int factorial(unsigned int i) { 15 | 16 | /* Termination condition */ 17 | if(i <= 1) { 18 | return 1; 19 | } 20 | return i * factorial(i - 1); 21 | } 22 | 23 | int main() 24 | { 25 | int i = 12; 26 | printf("Factorial of %d is %d\n", i, factorial(i)); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/6_inline_functions.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @brief Example to understand the difference between Inline functions and Macro functions 4 | * 5 | */ 6 | #include 7 | #define GREATER(a, b) ((a < b) ? b : a) 8 | 9 | // Inline function 10 | static inline int Maximum(int a, int b) 11 | { 12 | return (a > b) ? a : b; 13 | } 14 | int main( void) 15 | { 16 | printf("Greater of 10 and 20 is %d\n", GREATER(20, 10) ); 17 | printf("Maximum of 10 and 20 is %d\n", Maximum(20, 10) ); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/Basics/7_min_array.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 7_min_array.c 3 | * @author Bharath G 4 | * @brief Function to find Minimum value in unsigned integer array 5 | * @version 0.1 6 | * @date 2021-03-16 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | */ 11 | #include "stdio.h" 12 | #include "time.h" 13 | #include "stdlib.h" 14 | 15 | #define ARRAY_SIZE (10) 16 | /* Two methods to access the array values */ 17 | #define INDEX_BASED (1) 18 | #define POINTER_BASED (2) 19 | 20 | /* Change this to above options to change the method of access */ 21 | #define ARRAY_ACCESS_METHOD (POINTER_BASED) 22 | 23 | /** 24 | * Function to find Minimum value in unsigned integer array 25 | * Param1 - Pointer to unsigned integer Array 26 | * Param2 - Size of the Array 27 | * Return - -1 if the Array pointer is NULL, minimum value otherwise 28 | */ 29 | 30 | /** 31 | * @brief 32 | * 33 | * @param ptr_arr 34 | * @param arr_size 35 | * @return int 36 | */ 37 | int min_value_in_array(const unsigned int *ptr_arr, const size_t arr_size) 38 | { 39 | /* If array is not pointing to anything, return a error */ 40 | if(NULL == ptr_arr) 41 | return -1; 42 | 43 | /* Initialize the minimum value with the first value in array */ 44 | unsigned int min_val = ptr_arr[0]; 45 | 46 | /* Loop through the array till the minimum value is found */ 47 | for(unsigned int index = 0; index < arr_size; ++index) 48 | { 49 | /* Index based accesing */ 50 | #if (ARRAY_ACCESS_METHOD == INDEX_BASED) 51 | if(ptr_arr[index] < min_val) 52 | { 53 | min_val = ptr_arr[index]; 54 | } 55 | #else 56 | /* Pointer based accesing */ 57 | if(*ptr_arr< min_val) 58 | { 59 | min_val = *ptr_arr; 60 | } 61 | ptr_arr++; 62 | #endif 63 | } 64 | 65 | return min_val; 66 | } 67 | 68 | int main() { 69 | 70 | /* Test the function with Known data */ 71 | unsigned int arr1[ARRAY_SIZE] = {107,350,125,104,156,650,47,80,49,707}; 72 | printf("Minimum in Array = %d",min_value_in_array(arr1, ARRAY_SIZE)); 73 | 74 | /* Test the function with random data */ 75 | unsigned int arr2[ARRAY_SIZE] = {}; 76 | /* Seed value for Random number generator */ 77 | srand(time(0)); 78 | /* Fill the array with random values */ 79 | for(unsigned int index = 0; index 16 | #include 17 | #include 18 | #include 19 | 20 | /** @enum error_t 21 | * @brief This enum is a definition of errors 22 | */ 23 | typedef enum error_t 24 | { 25 | SUCCESS = 0, /**< Success */ 26 | MEMORY_FAILURE, /**< Memory Allocation failure Full */ 27 | ARRAY_FULL, /**< Array is full */ 28 | NULL_PTR, /**< Error Code for Failure */ 29 | 30 | } error_t; 31 | 32 | /** @enum color_t 33 | * @brief This enum is a definition of colours 34 | */ 35 | typedef enum color_t 36 | { 37 | RED = 0xFF, /**< Colour Code for RED */ 38 | BLUE, /**< Colour Code for BLUE */ 39 | GREEN /**< Colour Code for GREEN */ 40 | } color_t; 41 | 42 | /** @struct box_t 43 | * @brief This structure is a definition of box and its attributes 44 | */ 45 | typedef struct box_t 46 | { 47 | uint8_t id; /**< ID of the Box */ 48 | float length; /**< Length of the Box */ 49 | float breadth; /**< Breadth of the Box */ 50 | float height; /**< Height of the Box */ 51 | float weight; /**< Weight of the Box */ 52 | color_t color; /**< Colour of the Box */ 53 | } box_t; 54 | 55 | /** 56 | * @brief Creates an Array of box dynamically 57 | * @param[in] box_ptr Pointer to the array of Boxes 58 | * @param[in] number_of_boxes Number of Boxes in Array 59 | * @return Pointer to the newly created Box Array 60 | */ 61 | box_t *create_array_of_box(const size_t number_of_boxes) 62 | { 63 | return calloc(number_of_boxes, sizeof(box_t)); 64 | } 65 | 66 | /** 67 | * @brief Adds a box to the end of the current array where ID is NULL 68 | * @param[in] box_ptr Pointer to the array of Boxes 69 | * @param[in] array_size Size of the array 70 | * @param[in] new_box New box to be added at the end of the array 71 | * @return Success if the New box is added. Error code otherwise 72 | */ 73 | error_t add_box_at_end(box_t *box_ptr, const size_t array_size, const box_t *new_box) 74 | { 75 | if (NULL == box_ptr) 76 | { 77 | return NULL_PTR; 78 | } 79 | for (int index = 0; index < array_size; index++) 80 | { 81 | if (0 != (box_ptr + index)->id) 82 | { 83 | continue; 84 | } 85 | else 86 | { 87 | memcpy((box_ptr + index), new_box, sizeof(box_t)); 88 | return SUCCESS; 89 | } 90 | } 91 | return ARRAY_FULL; 92 | } 93 | 94 | /** 95 | * @brief Displays attributes of all boxes in the passed array. 96 | * @param[in] Box_array Pointer to the array of Boxes 97 | * @param[in] array_size Size of the array 98 | * @return Success if passed array is not NULL 99 | */ 100 | error_t display_all(const box_t *Box_array, const size_t array_size) 101 | { 102 | if (NULL == Box_array) 103 | { 104 | return NULL_PTR; 105 | } 106 | for (int index = 0; index < array_size && (0 != (Box_array + index)->id); index++) 107 | { 108 | printf("ID = %d \nLength = %f \nBreadth = %f \nHeight=%f \nWeight = %f \n", 109 | (Box_array + index)->id, 110 | (Box_array + index)->length, 111 | (Box_array + index)->breadth, 112 | (Box_array + index)->height, 113 | (Box_array + index)->weight); 114 | switch ((Box_array + index)->color) 115 | { 116 | case RED: 117 | printf("Color = RED\n\n"); 118 | break; 119 | case BLUE: 120 | printf("Color = BLUE\n\n"); 121 | break; 122 | case GREEN: 123 | printf("Color = BLUE\n\n"); 124 | break; 125 | default: 126 | printf("Color = DEFAULT\n\n"); 127 | } 128 | } 129 | return SUCCESS; 130 | } 131 | 132 | /** 133 | * Code to test the above functions 134 | */ 135 | size_t ARRAY_SIZE = 3; 136 | 137 | // If not assigned with NULL, it becomes a wild pointer 138 | box_t *box_ptr = NULL; 139 | 140 | // Initialize two box variables 141 | box_t box1 = {1, 10.2, 10.3, 22.566, 23.7777, RED}; 142 | box_t box2 = {2, .breadth = 99.99, .color = GREEN}; 143 | box_t box3 = {2, .breadth = 99.99, .color = GREEN}; 144 | 145 | int main() 146 | { 147 | // Allocate memory to hold the boxes 148 | box_ptr = create_array_of_box(ARRAY_SIZE); 149 | 150 | /** Add a box to the array */ 151 | add_box_at_end(box_ptr, ARRAY_SIZE, &box1); 152 | add_box_at_end(box_ptr, ARRAY_SIZE, &box2); 153 | 154 | /** Display all the added boxes */ 155 | display_all(box_ptr, ARRAY_SIZE); 156 | 157 | // release the dynamically allocated memory 158 | //free(box_ptr); 159 | box_ptr = NULL; 160 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/array_of_structures/Makefile: -------------------------------------------------------------------------------- 1 | # Written considering Linux OS only 2 | PROJ_NAME = BOX_ARRAY.out 3 | BUILD_DIR = Build 4 | 5 | SRC = Array_of_boxes.c 6 | 7 | all:$(SRC) 8 | gcc $^ -o $(PROJ_NAME) 9 | 10 | run: all 11 | ./$(PROJ_NAME) 12 | 13 | analyze: all memcheck staticcheck coverage codesize sanitize_check 14 | 15 | staticcheck: 16 | cppcheck --enable=all . 17 | 18 | memcheck: 19 | valgrind ./$(PROJ_NAME) 20 | 21 | sanitize_check: 22 | gcc -fsanitize=address -fno-omit-frame-pointer $(SRC) -o $(PROJ_NAME) 23 | ./$(PROJ_NAME) 24 | 25 | coverage:$(SRC) 26 | gcc -fprofile-arcs -ftest-coverage $< -o $(PROJ_NAME) 27 | ./$(PROJ_NAME) 28 | gcov -a $(SRC) 29 | 30 | codesize:$(PROJ_NAME) 31 | size $^ 32 | 33 | clean: 34 | rm -rf $(PROJ_NAME) *.gcov *.gcda *.gcno 35 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = Calculator 2 | SRC = calculator.c\ 3 | test_calculator.c 4 | 5 | INC = unity 6 | 7 | TEST = unity/unity.c 8 | 9 | $(PROJECT_NAME).exe : $(SRC) $(TEST) 10 | gcc -I $(INC) $(SRC) $(TEST) -o $(PROJECT_NAME).exe 11 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator/calculator.c: -------------------------------------------------------------------------------- 1 | int div(int num1, int num2) 2 | { 3 | if(num2 == 0) 4 | return 0; 5 | return num1/num2; 6 | } 7 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator/calculator.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file calculator.h 3 | * @author your name (you@domain.com) 4 | * @brief 5 | * @version 0.1 6 | * @date 2021-03-19 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | */ 11 | 12 | #ifndef __CALCULATOR_H__ 13 | #define __CALCULATOR_H__ 14 | /** 15 | * @brief 16 | * 17 | * @param num1 18 | * @param num2 19 | * @return int 20 | */ 21 | int div(int num1, int num2); 22 | #endif -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator/test_calculator.c: -------------------------------------------------------------------------------- 1 | #include "unity.h" 2 | #include "calculator.h" 3 | 4 | /* Required by the unity test framework */ 5 | void setUp(){} 6 | /* Required by the unity test framework */ 7 | void tearDown(){} 8 | 9 | 10 | void test_div(void) 11 | { 12 | TEST_ASSERT_EQUAL(1, div(10, 10)); 13 | TEST_ASSERT_EQUAL(0, div(10, 0)); 14 | } 15 | 16 | int main() 17 | { 18 | /* Initiate the Unity Test Framework */ 19 | UNITY_BEGIN(); 20 | 21 | /* Run Test functions */ 22 | RUN_TEST(test_div); 23 | 24 | /* Close the Unity Test Framework */ 25 | return UNITY_END(); 26 | } 27 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/Makefile: -------------------------------------------------------------------------------- 1 | PROJ_NAME = Complex_Calculator 2 | TEST_PROJ_NAME = Test_$(PROJ_NAME) 3 | 4 | BUILD_DIR = Build 5 | 6 | SRC = src/complex_calculator.c 7 | 8 | TEST_SRC = test/test_complex_calculator.c\ 9 | unity/unity.c 10 | 11 | INC = -Iinc\ 12 | -Iunity 13 | 14 | #To check if the OS is Windows or Linux and set the executable file extension and delete command accordingly 15 | ifdef OS 16 | RM = del /q 17 | FixPath = $(subst /,\,$1) 18 | EXEC = exe 19 | else 20 | ifeq ($(shell uname), Linux) 21 | RM = rm -rf 22 | FixPath = $1 23 | EXEC = out 24 | endif 25 | endif 26 | 27 | # Makefile will not run target command if the name with file already exists. To override, use .PHONY 28 | .PHONY : all test coverage run clean doc 29 | 30 | all:$(BUILD_DIR) 31 | gcc main.c $(SRC) $(INC) -o $(call FixPath,$(BUILD_DIR)/$(PROJ_NAME).$(EXEC)) 32 | 33 | run: all 34 | $(call FixPath,$(BUILD_DIR)/$(PROJ_NAME).$(EXEC)) 35 | 36 | test: $(SRC) $(TEST_SRC) 37 | gcc $^ $(INC) -o $(call FixPath,$(BUILD_DIR)/$(TEST_PROJ_NAME).$(EXEC)) 38 | $(call FixPath,$(BUILD_DIR)/$(TEST_PROJ_NAME).$(EXEC)) 39 | 40 | coverage:${PROJECT_NAME} 41 | gcc -fprofile-arcs -ftest-coverage $(SRC) $(TEST_SRC) $(INC) -o $(call FixPath,$(BUILD_DIR)/$(TEST_PROJ_NAME).$(EXEC)) 42 | $(call FixPath,$(BUILD_DIR)/$(TEST_PROJ_NAME).$(EXEC)) 43 | gcov -a $(SRC) 44 | 45 | doc: 46 | make -C doc 47 | $(BUILD_DIR): 48 | mkdir $(BUILD_DIR) 49 | 50 | clean: 51 | $(RM) $(call FixPath,$(BUILD_DIR)/*) 52 | make clean -C doc 53 | rmdir $(BUILD_DIR) doc/html -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/README.md: -------------------------------------------------------------------------------- 1 | # Time to code 2 | ## Problem Statement 3 | * Write functions to compute **Sum**, **Difference**, **Product** and **Division** of two **Complex numbers** of the below structure. 4 | ``` 5 | typedef struct complex_t { 6 | float real; 7 | float imaginary; 8 | } complex_t; 9 | ``` 10 | 11 | ## Guidelines: 12 | ### Programming 13 | * **Do not use scanf functions**. Assume test values for arguments to functions. 14 | * Implement different functions for each operation instead of writing everything under main function. 15 | * Create a **header file**, **source code file** and **test file**. 16 | * Use **Dynamic memory** wherever possible. 17 | 18 | ### Tool usage 19 | * Write **Unit test** cases for each function. 20 | * **Makefile** for **compilation**, **running test** cases and additional targets. 21 | * Create **Documentation** using **Doxygen**. 22 | * Use **cppcheck** and **Valgrind** tools to analyze the code. 23 | 24 | ## Resources: 25 | * [Structure in C: you should know in depth](https://aticleworld.com/structure-in-c/) 26 | 27 | ## Solutions 28 | * By [Arnob Chowdhury](https://github.com/arc-arnob/MiniProject_Template/tree/master/Example_Programs/calculator_complex) 29 | * By [Shravya K N](https://github.com/28-shravya/MiniProject_Template/tree/master/Example_Programs/programming_concpets/calculator_complex) 30 | * By [Govind bansal](https://github.com/govindbansal1309/MiniProject_Template/tree/master/Example_Programs/programming_concpets/calculator_complex) 31 | * By [258009](https://github.com/bgvmysore/Complex_calculator) 32 | * By [Hemanth A - 256889](https://github.com/hemanth-asapu/demoproj1/tree/main/complex_calculator) 33 | * By [Rohan Gupta](https://github.com/256018/Implementing_Calculator) 34 | * By [Ayushman 255949](https://github.com/255949/Complex_calaculator) 35 | * By [Jay Singh](https://github.com/codemonk-007/LnT-Stepin-Projects/edit/main/calculator_complex) 36 | * By [258331](https://github.com/Aranshu/MiniProject_Template/tree/master/Example_Programs/programming_concpets/calculator_complex) 37 | * By [Sobin Rajan](https://github.com/sobinrajan1999/Qestions1a-ltts-) 38 | * By [Shivani Singh](https://github.com/shivani-11318/MiniProject_Template/tree/master/Example_Programs/programming_concpets/calculator_complex) 39 | * By [Roopesh Verma](https://github.com/Roopesh16/Complex_Calculator.git) 40 | * By [K Satyadev - 260902](https://github.com/satyadevkalakonda/Solution_1A) 41 | * By [Syed Basit Ahmad](https://github.com/syedbasitahmad/Complex_caclulator) 42 | * By [Sarthak Naithani](https://github.com/sarthaknaithani/260757_complex_calculator) 43 | * By [255919 Gobikumaar-Sivagnanam](https://github.com/Gobikumaar-Sivagnanam/Learnings-Week-2) 44 | * By [258070](https://github.com/PramodhMahadeshKM/Complex_Calculator) 45 | * By [Sagar Paryani](https://github.com/ParyaniSagar/Complex_Calculator) 46 | * By [Shubham Kalihari](https://github.com/shubhamk09/STEPin-programms/tree/master/Complex_cal) 47 | * By [256182](https://github.com/256182/Complex_Calc) 48 | * By [Khushbu Majithia-261406](https://github.com/Khushbu-Majithia-261406/STEP_IN_PROGRAMS) 49 | * By [Indiya B Henly](https://github.com/indiya77/complex_calculator.git) 50 | * By [Nikhil Pothu](https://github.com/PothuNikhil/255906-Calculator.git) 51 | * By [Annarose K](https://github.com/AnnaroseK/SFID-255976complex_calculator) 52 | * By [Jeevak Raj](https://github.com/JeevakRaj/LTTS_Stepin_Exercises/tree/main/Question_1a_Complex_Calculator) 53 | * By [Vivek Valagadri](https://github.com/vivekvalagadri/Stepin.git) 54 | * BY [Himanshu Kaushish 257170](https://github.com/Himanshu257170/Complex_Calcuator.git) 55 | * By [Milan Apegaonkar 255934](https://github.com/255934/Question1/tree/master/complex_calculator) 56 | * By [p.s.v.n.k.mani gupta 256316](https://github.com/pydimanigupta256316/ltts-problems/tree/main/complex_calculator) 57 | * By [Hrishikesh Kholamkar 267236](https://github.com/hrishik16/Assignments_LTTS.git) 58 | * By [Priyadharshni N](https://github.com/Priyadharshni05/Complex-Calculator.git) 59 | * By [Shriya Naik](https://github.com/Shriya-265054/linux/tree/master/complex_calculator) -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/doc/Makefile: -------------------------------------------------------------------------------- 1 | # Document the code using Doxygen 2 | PROJECT_DOXY_FILE = Complex_Calc_Doxyfile 3 | 4 | doc: $(PROJECT_DOXY_FILE) 5 | doxygen ./$^ 6 | 7 | clean: 8 | rm -rf html* -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/doc/doc_main.md: -------------------------------------------------------------------------------- 1 | @mainpage Complex calculator Application by Bharath G 2 | @subpage complex_calculator.h 3 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/inc/complex_calculator.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file complex_calculator.h 3 | * @author your name (you@domain.com) 4 | * @brief Functions to perform Sum, Difference, Division and Multiplication on complex Varibales of \ref complex_t 5 | * @version 0.1 6 | * @date 2021-03-22 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | */ 11 | 12 | /** 13 | * @brief Error values for calculator operations 14 | * 15 | */ 16 | typedef enum error_t { 17 | ERROR_DIV_BY_ZERO = -2, /**< Division by 0 error */ 18 | ERROR_NULL_PTR = -1, /**< Null pointer dereferncing error */ 19 | SUCCESS = 0 /**< Compute operation is successful */ 20 | }error_t; 21 | 22 | /** 23 | * @brief Structure for Complex number 24 | * 25 | */ 26 | typedef struct complex_t { 27 | float real; /**< real part of the complex number */ 28 | float imaginary; /**< real part of the complex number */ 29 | } complex_t; 30 | 31 | 32 | /** 33 | * @brief computes sum of the two complex numbers 34 | * 35 | * @param[in] cnum1 Pointer to complex number1 36 | * @param[in] cnum2 Pointer to complex number2 37 | * @param[out] csum Pointer to store the computed result 38 | * @return error_t SUCCESS if operation is completed successfully. Error value otherwise. 39 | */ 40 | error_t complex_sum(complex_t* cnum1, complex_t* cnum2, complex_t* csum); 41 | 42 | 43 | /** 44 | * @brief TODO Add the remaining functions 45 | * 46 | */ -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "complex_calculator.h" 3 | int main() 4 | { 5 | //TODO Write all the logic for Calculator app 6 | printf("Complex calculator "); 7 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/src/complex_calculator.c: -------------------------------------------------------------------------------- 1 | #include "stdlib.h" 2 | #include "complex_calculator.h" 3 | 4 | error_t complex_sum(complex_t* cnum1, complex_t* cnum2, complex_t* csum) 5 | { 6 | if(NULL == cnum1 || NULL == cnum2) 7 | return ERROR_NULL_PTR; 8 | 9 | 10 | csum->real = cnum1->real + cnum2->real; 11 | csum->imaginary = cnum1->imaginary + cnum2->imaginary; 12 | 13 | return SUCCESS; 14 | 15 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/calculator_complex/test/test_complex_calculator.c: -------------------------------------------------------------------------------- 1 | #include "complex_calculator.h" 2 | #include "unity.h" 3 | 4 | static complex_t c1 = {0, 0}; 5 | static complex_t c2 = {0, 0}; 6 | static complex_t result = {0, 0}; 7 | /* Required by the unity test framework */ 8 | void setUp() 9 | { 10 | } 11 | /* Required by the unity test framework */ 12 | void tearDown() 13 | { 14 | } 15 | 16 | void test_zero(void) 17 | { 18 | // Can ommi the below intialization as it is done at the declaration time 19 | c1.real = 0; 20 | c1.imaginary = 0; 21 | 22 | c2.real = 0; 23 | c2.imaginary = 0; 24 | 25 | TEST_ASSERT_EQUAL(SUCCESS, complex_sum(&c1, &c2, &result)); 26 | TEST_ASSERT_EQUAL(0, result.real); 27 | TEST_ASSERT_EQUAL(0, result.imaginary); 28 | } 29 | void test_positive(void) 30 | { 31 | c1.real = 25; 32 | c1.imaginary = 15; 33 | 34 | c2.real = 75; 35 | c2.imaginary = 95; 36 | 37 | TEST_ASSERT_EQUAL(SUCCESS, complex_sum(&c1, &c2, &result)); 38 | TEST_ASSERT_EQUAL(100, result.real); 39 | TEST_ASSERT_EQUAL(110, result.imaginary); 40 | } 41 | 42 | void test_negative(void) 43 | { 44 | c1.real = -25; 45 | c1.imaginary = -15; 46 | 47 | c2.real = 75; 48 | c2.imaginary = 95; 49 | 50 | TEST_ASSERT_EQUAL(SUCCESS, complex_sum(&c1, &c2, &result)); 51 | TEST_ASSERT_EQUAL(50, result.real); 52 | TEST_ASSERT_EQUAL(80, result.imaginary); 53 | 54 | c1.real = -25; 55 | c1.imaginary = -15; 56 | 57 | c2.real = -75; 58 | c2.imaginary = -95; 59 | 60 | TEST_ASSERT_EQUAL(SUCCESS, complex_sum(&c1, &c2, &result)); 61 | TEST_ASSERT_EQUAL(-100, result.real); 62 | TEST_ASSERT_EQUAL(-110, result.imaginary); 63 | 64 | } 65 | 66 | int main(void) 67 | { 68 | /* Initiate the Unity Test Framework */ 69 | UNITY_BEGIN(); 70 | 71 | /* Run Test functions */ 72 | RUN_TEST(test_zero); 73 | RUN_TEST(test_positive); 74 | RUN_TEST(test_negative); 75 | 76 | /* Close the Unity Test Framework */ 77 | return UNITY_END(); 78 | } 79 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/functions_pointers/1_array_passing.c: -------------------------------------------------------------------------------- 1 | /* Passing arrays */ 2 | 3 | /** 4 | * Arrays are passed by reference(base address) 5 | * Whole array is never passed 6 | */ 7 | #include 8 | #include 9 | #include 10 | void fill(int[], int); // void fill(int*,int); 11 | void aprint(const int[], int); // void aprint(int*,int); 12 | void compute(const int *, int); // void compute(int[],int); 13 | 14 | int main() { 15 | int arr[10]; 16 | 17 | fill(arr, 10); // arr is equivalent to &arr[0] 18 | aprint(arr, 8); 19 | compute(arr, 10); 20 | return 0; 21 | } 22 | 23 | void fill(int arr[], int n) { // void fill(int* arr,int n) 24 | // sizeof(arr) 25 | srand(time(0)); 26 | int i; 27 | for (i = 0; i < n; i++) 28 | arr[i] = rand() % 100; //*(arr+i)=rand()%100; 29 | } 30 | 31 | void aprint(const int arr[], int n) { // void aprint(int *arr,int n) 32 | // sizeof(arr) 33 | int i; 34 | for (i = 0; i < n; i++) 35 | printf("%d\n", arr[i]); // printf("%d\n", *arr++); 36 | } 37 | 38 | void compute(const int *parr, int n) { 39 | // sizeof(parr) 40 | int i, sum = 0; 41 | for (i = 0; i < n; i++) 42 | sum += *parr++; // sum += parr[i] 43 | } 44 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/functions_pointers/2a_function_ptr.c: -------------------------------------------------------------------------------- 1 | /* Function Pointers */ 2 | 3 | /** 4 | * function name acts like it's address 5 | * Binding pointers and functions 6 | * invoking functions through pointers 7 | */ 8 | 9 | #include 10 | 11 | int sum(int, int); 12 | int (*ptr_sum)(int, int); 13 | 14 | int prod(int, int); 15 | 16 | int main() { 17 | 18 | int a = 10, b = 20, c, d; 19 | int *ptr_a = &a; 20 | 21 | int (*fp)(int, int) = NULL; 22 | 23 | fp = sum; // same as *fp = &sum 24 | sum(a, b); 25 | c = fp(a, b); 26 | 27 | fp = prod; 28 | d = fp(a, b); // same as (*fp)(a,b) 29 | 30 | return 0; 31 | } 32 | 33 | int sum(int x, int y) { return x + y; } 34 | 35 | int prod(int x, int y) { return x * y; } 36 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/functions_pointers/2b_function_ptr_typedef.c: -------------------------------------------------------------------------------- 1 | /* Passing functions to other functions */ 2 | 3 | /** 4 | * passing function names vs function calls 5 | * parameters representing function pointers 6 | * Hint - basis for callback functions 7 | */ 8 | #include 9 | 10 | typedef int (*fptr_t)(int, int); 11 | 12 | int sum(int, int); 13 | int prod(int, int); 14 | void acompute(int, int, int (*)(int, int)); 15 | void acompute_t(int x, int y, fptr_t fnptr); 16 | 17 | int sum(int x, int y) { return x + y; } 18 | int prod(int x, int y) { return x * y; } 19 | int main() { 20 | int a = 10, b = 20, c, d; 21 | 22 | acompute(a, b, sum); 23 | acompute_t(a, b, prod); 24 | return 0; 25 | } 26 | 27 | void acompute(int x, int y, int (*fptr)(int, int)) { 28 | int z; 29 | z = fptr(x, y); 30 | printf("Res = %d\n", z); 31 | } 32 | 33 | void acompute_t(int x, int y, fptr_t fnptr) { 34 | int z; 35 | z = fnptr(x, y); 36 | printf("Res = %d\n", z); 37 | } 38 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/functions_pointers/2c_function_ptr_array.c: -------------------------------------------------------------------------------- 1 | /* Array of function pointers */ 2 | #include 3 | 4 | int add(int x, int y) { return x + y; } 5 | int subtract(int x, int y) { return x - y; } 6 | int divide(int x, int y) { return x / y; } 7 | 8 | int multiply(int x, int y) { return x * y; } 9 | 10 | int main() { 11 | int (*fparr[5])(int, int); 12 | 13 | fparr[0] = add; 14 | fparr[1] = subtract; 15 | fparr[2] = multiply; 16 | fparr[3] = divide; 17 | fparr[4] = NULL; 18 | 19 | int a = 10, b = 20, c; 20 | int i = 3; 21 | 22 | (fparr[0])(10, 20); 23 | 24 | c = (fparr[i])(a, b); // i can be 0,1,2,3 25 | // what if i==4 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/multi_file/Makefile: -------------------------------------------------------------------------------- 1 | # comments 2 | 3 | #Target : dependency 4 | #Command 5 | 6 | PROJECT_NAME = all.exe 7 | SRC = test.c\ 8 | src\sum.c\ 9 | src\sqr.c 10 | 11 | INC = inc 12 | 13 | $(PROJECT_NAME): $(SRC) 14 | gcc -I $(INC) $(SRC) -o all.exe 15 | 16 | run: $(PROJECT_NAME) 17 | $(PROJECT_NAME) 18 | 19 | clean: 20 | del /q *.exe -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/multi_file/inc/fun.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file fun.h 3 | * @author Bharath G 4 | * @brief Header file for sum and square functions 5 | * @version 0.1 6 | * @date 2021-03-16 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | */ 11 | 12 | #ifndef __FUN_H__ 13 | #define __FUN_H__ 14 | /** 15 | * @brief Funtion to find the sum of two integer numbers 16 | * 17 | * @param[in] number1 18 | * @param[in] number2 19 | * @return int result of the sum operation 20 | */ 21 | int sum(int number1, int number2); 22 | 23 | /** 24 | * @brief Function to find square of a integer number 25 | * 26 | * @param[in] number Number for which the square has to be found 27 | * @return int Result of the square operation 28 | */ 29 | int square(int number); 30 | 31 | #endif /* __FUN_H__ */ -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/multi_file/src/sqr.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | //#include 3 | 4 | int square(int number) 5 | { 6 | return number * number; 7 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/multi_file/src/sum.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | 3 | int sum(int number1, int number2) 4 | { 5 | return number1 + number2 + 10 ; 6 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/multi_file/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //#include "fun.h" 4 | 5 | int main() { 6 | int num1 = 10, num2=20, num3, num4; 7 | num1 = 10; 8 | num2 = 20; 9 | num3 = sum(num1, num2); 10 | num4 = square(num1); 11 | 12 | printf("Sum = %d \t Square = %d \n", num3, num4); 13 | return 0; 14 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/pointer_operations/1a_pointer_arithmetic.c: -------------------------------------------------------------------------------- 1 | /* Pointer arithmetic */ 2 | 3 | /** 4 | * Allowed pointer arithmetic (p1, p2 are pointers, t is a scalar) 5 | * pointer + scalar, p1 + t, ++p1 6 | * pointer - scalar, p1 - t, --p2 7 | * difference between pointers p1 - p2 8 | * derefernce *p1 9 | */ 10 | 11 | #include 12 | 13 | int main() { 14 | int val=100; 15 | int *ptr; 16 | ptr=&val; //Make a note of value 17 | 18 | int *p1, *p2, t; 19 | p1 = ptr + 5; 20 | //print p1 21 | p2 = ptr - 10; 22 | //print p2 23 | ++p1; 24 | //print p1 25 | --p2; 26 | //print p2 27 | t = p1 - p2; 28 | //print the difference 29 | 30 | //TODO: try these operations on other types like double*, char* 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/pointer_operations/1b_const_with_pointesr.c: -------------------------------------------------------------------------------- 1 | /* const keyword usage */ 2 | 3 | /** 4 | * const keyword usage with pointers 5 | * pointer to const 6 | * constant pointer 7 | * violation of const commitment 8 | */ 9 | #include 10 | const int global_var = 10; // data (read only) 11 | int main() { 12 | 13 | // Pointer to a constant integer 14 | const int a1 = 10; // stack 15 | 16 | int* pa1 = &a; 17 | 18 | const int* ptr1 = &a1; 19 | *ptr1 = 5; // wrong 20 | ptr1++; // right 21 | 22 | 23 | // Constant Pointer to an integer 24 | int a2 = 10; 25 | int *const ptr2 = &a2; 26 | *ptr2 = 5; // right 27 | ptr2++; // wrong 28 | 29 | // Constant Pointer to a constant integer 30 | int a2 = 10; 31 | const int *const ptr2 = &a2; 32 | *ptr2 = 5; // wrong 33 | ptr2++; // wrong 34 | 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/pointer_operations/1c_precedence_associativity_pointers.c: -------------------------------------------------------------------------------- 1 | /* Precedence & associativity */ 2 | 3 | /** 4 | * Combinations of dereference, increment/decrement operations 5 | * *ptr++, (*ptr)++, *(ptr++), ++*ptr, ++(*ptr), *++ptr, *(++ptr) 6 | */ 7 | #include 8 | 9 | int main() { 10 | int arr[10]={10,20,30,40,50, 60, 70, 80, 90, 100}; 11 | int *ptr=&arr[2]; //ptr=arr+2 12 | int val; 13 | 14 | val=*ptr++; //A, val=*ptr, ptr=ptr+1 15 | printf("val = %d, *ptr = %d\n", val, *ptr); 16 | 17 | val=*(ptr++); //B, same as above 18 | printf("val = %d, *ptr = %d\n", val, *ptr); 19 | 20 | val=(*ptr)++; //C, val=*ptr, *ptr=*ptr+1 21 | printf("val = %d, *ptr = %d\n", val, *ptr); 22 | 23 | val=++*ptr; //D, *ptr=*ptr+1, val=*ptr 24 | printf("val = %d, *ptr = %d\n", val, *ptr); 25 | 26 | val=++(*ptr); //E, same as above 27 | printf("val = %d, *ptr = %d\n", val, *ptr); 28 | 29 | val=*++ptr; //F, ptr=ptr+1, val=*ptr 30 | printf("val = %d, *ptr = %d\n", val, *ptr); 31 | 32 | val=*(++ptr); //G, same as above 33 | printf("val = %d, *ptr = %d\n", val, *ptr); 34 | 35 | //TODO: analyze *ptr--, (*ptr)--, --*ptr, *--ptr 36 | 37 | return 0; 38 | } 39 | 40 | 41 | a = b * c + d; 42 | 43 | //unsequenced 44 | a = *ptr++ + ++*ptr -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/pointer_operations/demo.c: -------------------------------------------------------------------------------- 1 | /* function pointer */ //function pointer as arguments int ArithMaticOperation(int iData1,int iData2, pfunctPtr Calculation) { int iRet =0; iRet = Calculation(iData1,iData2); return iRet; } /*function add two number*/ int AddTwoNumber(int iData1,int iData2) { return (iData1 + iData2); } /*function subtract two number*/ int SubTwoNumber(int iData1,int iData2) { return (iData1 - iData2); } /*function multiply two number*/ int MulTwoNumber(int iData1,int iData2) { return (iData1 * iData2); } int main() { int iData1 = 10; int iData2 = 20; int iChoice = 1; int Result = 0; printf("Enter two Integer Data \n\n"); //scanf("%d%d",&iData1,&iData2); printf("Enter 1 for Addition \n\n"); printf("Enter 2 for Subtraction \n\n"); printf("Enter 3 for Multiplication \n\n"); printf("User choice :"); //scanf("%d",&iChoice); switch(iChoice)17:14 2 | #include 3 | typedef int (*pfunctPtr)(int, int); 4 | { 5 | case 1: 6 | Result = ArithMaticOperation(iData1, iData2, AddTwoNumber); 7 | break; 8 | case 2: 9 | Result = ArithMaticOperation(iData1, iData2, SubTwoNumber); 10 | break; 11 | case 3: 12 | Result = ArithMaticOperation(iData1, iData2, MulTwoNumber); 13 | break; 14 | default: 15 | printf("Enter Wrong Choice\n\n"); 16 | } 17 | printf("\n\nResult = %d\n\n", Result); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/gdb-examples/example1.c: -------------------------------------------------------------------------------- 1 | int main() { 2 | int i; 3 | double sum=0; 4 | for(i=1;i<=10;i++) 5 | sum += 1.0 / (i-5); 6 | printf("sum is %d\n",sum); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/gdb-examples/example2.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const int cval = 100; 4 | 5 | int main(int argc, char* argv[]) { 6 | int *ptr; 7 | ptr=&cval; //error or warning? 8 | *ptr=200; 9 | printf("Thank You\n"); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/gdb-examples/example3.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int *fetch() { 4 | int val=100; 5 | return &val; 6 | } 7 | 8 | int main(int argc, char* argv[]) { 9 | int *ptr; 10 | ptr=fetch(); 11 | printf("Ret val=%d\n",*ptr); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/gdb-examples/example4.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int isVowel(char ch) { 4 | return ch=='a' || ch=='e' || ch == 'i' || ch == 'o' || ch == 'u'; 5 | } 6 | 7 | int main(int argc, char* argv[]) { 8 | char *ps = "black"; 9 | int len=strlen(ps); 10 | for(int i=0;i 2 | 3 | int mystrlen(const char* pstr); 4 | void test(char* pstr); 5 | 6 | int main(int argc, char* argv[]) { 7 | int len=5; 8 | char *pstable[5] = { "sunday", "monday", "tuesday"}; 9 | char *ps; 10 | for(int i=0;i 3 | int main() { 4 | int a, b, c, d; 5 | a = 10; 6 | b = 20; 7 | c = sum(a, b); 8 | d = square(a); 9 | printf("c=%d,d=%d\n",c,d); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto2/Makefile: -------------------------------------------------------------------------------- 1 | all:all.out 2 | 3 | all.out:test.o sum.o sqr.o 4 | gcc $^ -o $@ 5 | 6 | clean: 7 | rm -rf *.o all.out 8 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto2/README.md: -------------------------------------------------------------------------------- 1 | # Hands-on & Discussion 2 | * Meaning of special variables $@, $^, $< 3 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto2/fun.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUN_H 2 | #define __FUN_H 3 | int sum(int x, int y); 4 | int square(int x); 5 | #endif -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto2/sqr.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int square(int x) { 3 | return x * x; 4 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto2/sum.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int sum(int x, int y) { 3 | return x + y; 4 | } 5 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto2/test.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | #include 3 | int main() { 4 | int a, b, c, d; 5 | a = 10; 6 | b = 20; 7 | c = sum(a, b); 8 | d = square(a); 9 | printf("c=%d,d=%d\n",c,d); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto3/Makefile: -------------------------------------------------------------------------------- 1 | all:all.out 2 | 3 | #CC=clang 4 | #CXX=clang 5 | #LD=g++ 6 | #AS 7 | #CPP 8 | 9 | #CFLAGS=-v 10 | #LDFLAGS=-static 11 | #CXXFLAGS 12 | #ASFLAGS 13 | 14 | all.out:test.o sum.o sqr.o 15 | gcc $^ -o $@ 16 | clean: 17 | rm -rf *.o all.out 18 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto3/README.md: -------------------------------------------------------------------------------- 1 | # Hands-on & Discussion 2 | * Implicit rules 3 | * Built-in variables : CC, CXX, LD, AS 4 | * Built-in flag vars : CFLAGS, CXXFLAGS, LDFLAGS, ASFLAGS 5 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto3/fun.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUN_H 2 | #define __FUN_H 3 | int sum(int x, int y); 4 | int square(int x); 5 | #endif -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto3/sqr.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int square(int x) { 3 | return x * x; 4 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto3/sum.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int sum(int x, int y) { 3 | return x + y; 4 | } 5 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto3/test.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | #include 3 | int main() { 4 | int a, b, c, d; 5 | a = 10; 6 | b = 20; 7 | c = sum(a, b); 8 | d = square(a); 9 | printf("c=%d,d=%d\n",c,d); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto4/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=hall.out 2 | OBJS=test.o sum.o sqr.o 3 | 4 | all:${TARGET} 5 | 6 | $(TARGET):${OBJS} 7 | gcc $^ -o $@ 8 | %.o:%.c fun.h # pattern based rule 9 | gcc $< -c -g 10 | clean: 11 | rm -rf *.o ${TARGET} 12 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto4/README.md: -------------------------------------------------------------------------------- 1 | # Hands-on & Discussion 2 | * Pattern based rules 3 | * User variables 4 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto4/fun.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUN_H 2 | #define __FUN_H 3 | int sum(int x, int y); 4 | int square(int x); 5 | #endif -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto4/sqr.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int square(int x) { 3 | return x * x; 4 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto4/sum.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int sum(int x, int y) { 3 | return x + y; 4 | } 5 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto4/test.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | #include 3 | int main() { 4 | int a, b, c, d; 5 | a = 10; 6 | b = 20; 7 | c = sum(a, b); 8 | d = square(a); 9 | printf("c=%d,d=%d\n",c,d); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto5/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=hall.out 2 | OBJS=test.o src/sum.o src/sqr.o 3 | TOPDIR=${PWD} 4 | 5 | CFLAGS=-I${TOPDIR}/include 6 | 7 | all:$(TARGET) 8 | 9 | $(TARGET):$(OBJS) 10 | gcc $^ -o $@ 11 | 12 | %.o:src/%.c 13 | 14 | test.o:test.c 15 | 16 | clean: 17 | rm -rf ${OBJS} ${TARGET} 18 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto5/README.md: -------------------------------------------------------------------------------- 1 | # Hands-on & Discussion 2 | * Pattern based rules 3 | * User variables 4 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto5/include/fun.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUN_H 2 | #define __FUN_H 3 | int sum(int x, int y); 4 | int square(int x); 5 | #endif -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto5/src/sqr.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int square(int x) { 3 | return x * x; 4 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto5/src/sum.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int sum(int x, int y) { 3 | return x + y; 4 | } 5 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto5/test.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | #include 3 | int main() { 4 | int a, b, c, d; 5 | a = 10; 6 | b = 20; 7 | c = sum(a, b); 8 | d = square(a); 9 | printf("c=%d,d=%d\n",c,d); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto6/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=sall.out 2 | OBJS=test.o src/sum.o src/sqr.o 3 | 4 | TOPDIR=${PWD} 5 | CFLAGS=-I${TOPDIR}/include 6 | LDFLAGS=-lsimple 7 | 8 | #User created variable 9 | LIBPATH=${PWD} 10 | 11 | all:sall.out 12 | 13 | sall.out:test.o libsimple.a 14 | gcc -L${LIBPATH} $< -o $@ 15 | libsimple.a:src/sum.o src/sqr.o 16 | ar rc $@ $^ 17 | %.o:src/%.c include/fun.h 18 | 19 | test.o: test.c include/fun.h 20 | 21 | clean: 22 | rm -rf *.a *.o src/*.o ${TARGET} 23 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto6/README.md: -------------------------------------------------------------------------------- 1 | # Hands-on & Discussion 2 | * Pattern based rules 3 | * User variables 4 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto6/include/fun.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUN_H 2 | #define __FUN_H 3 | int sum(int x, int y); 4 | int square(int x); 5 | #endif -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto6/src/sqr.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int square(int x) { 3 | return x * x; 4 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto6/src/sum.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | int sum(int x, int y) { 3 | return x + y; 4 | } 5 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/make-examples/tuto6/test.c: -------------------------------------------------------------------------------- 1 | #include "fun.h" 2 | #include 3 | int main() { 4 | int a, b, c, d; 5 | a = 10; 6 | b = 20; 7 | c = sum(a, b); 8 | d = square(a); 9 | printf("c=%d,d=%d\n",c,d); 10 | return 0; 11 | } -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/valgrind-examples/README.md: -------------------------------------------------------------------------------- 1 | # Outline 2 | 3 | ## Install valgrind 4 | * If valgrind is not installed, install thru package manager 5 | ``` 6 | sudo apt install valgrind 7 | ``` 8 | 9 | ## Simple Usage 10 | ``` 11 | gcc example1.c -o ex1.out 12 | valgrind ./ex1.out 13 | 14 | gcc example3.c -o ex3.out -g 15 | valgrind ./ex3.out 16 | ``` 17 | 18 | ## Memory Leaks & Heap Analysis 19 | * Memory leak 20 | * Read/write after free 21 | * Read/write beyond heap block size 22 | * Mismatch between malloc/new, free/delete 23 | * Modified/Invalid base address to free 24 | * Double free problem 25 | * Direct vs Indirect memory leaks 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Example_Programs/programming_concpets/tools_examples/valgrind-examples/example1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "string.h" 3 | #include "stdint.h" 4 | #include "stdlib.h" 5 | #include "time.h" 6 | int arr[10] ={}; 7 | int main(int argc, char* argv[]) { 8 | int *parr; 9 | int len=10, sum; 10 | if(argc > 1) 11 | len = strtoul(argv[1],NULL,10); 12 | 13 | parr = malloc(len * sizeof(int)); 14 | 15 | srand(time(0)); 16 | 17 | for(int i=0;i 2 | #include "string.h" 3 | #include "stdint.h" 4 | #include "stdlib.h" 5 | #include "time.h" 6 | 7 | int main(int argc, char* argv[]) { 8 | int *parr; 9 | int len=10,sum; 10 | if(argc > 1) 11 | len = strtoul(argv[1],NULL,10); 12 | 13 | parr = malloc(len * sizeof(int)); 14 | srand(time(0)); 15 | 16 | for(int i=0;i 2 | 3 | int main(int argc, char* argv[]) { 4 | int *parr; 5 | int len=10,sum=0; 6 | parr = malloc(len * sizeof(int)); 7 | srand(time(0)); 8 | for(int i=0;i 2 | #include "string.h" 3 | #include "stdint.h" 4 | #include "stdlib.h" 5 | #include "time.h" 6 | int main(int argc, char* argv[]) { 7 | int *parr; 8 | int len=10, sum; 9 | parr = malloc(len * sizeof(int)); 10 | srand(time(0)); 11 | 12 | for(int i=0;i 2 | 3 | int main(int argc, char* argv[]) { 4 | int *parr; 5 | int len=10, sum; 6 | parr = malloc(len * sizeof(int)); 7 | srand(time(0)); 8 | for(int i=0;i 6 | int main() 7 | { 8 | printf("Welcome to Github Actions.\n********* Its Working*******\n"); 9 | return 0; 10 | } 11 | ``` 12 | 13 | |Preparation| 14 | |:--:| 15 | |![Workflow0](images/Workflow_create0.png)| 16 | 17 | 18 | * In the repository, click on **Actions** tab and create a new workflow either from existing or a new workflow. 19 | 20 | |Create actions| 21 | |:--:| 22 | |![Workflow1](images/Workflow_create.png)| 23 | 24 | ## Build action for Linux OS 25 | 26 | * Add the below content into the **.yml** file and commit to repository 27 | ``` 28 | name: Linux C/C++ CI 29 | 30 | on: 31 | push: 32 | branches: [ master ] 33 | pull_request: 34 | branches: [ master ] 35 | 36 | jobs: 37 | build: 38 | 39 | runs-on: ubuntu-latest 40 | 41 | steps: 42 | - uses: actions/checkout@v2 43 | - name: build 44 | run: gcc hello.c -o hello.exe 45 | - name: Run 46 | run: ./hello.exe 47 | ``` 48 | 49 | |Work flow for Linux| 50 | |:--:| 51 | |![Workflow2](images/Workflow_create2.png)| 52 | 53 | ## Build action for Windows OS 54 | * Add the below content into the **.yml** file and commit to repository 55 | ``` 56 | name: Windows C/C++ CI 57 | 58 | on: 59 | push: 60 | branches: [ master ] 61 | pull_request: 62 | branches: [ master ] 63 | 64 | jobs: 65 | build: 66 | 67 | runs-on: windows-latest 68 | 69 | steps: 70 | - uses: actions/checkout@v2 71 | - name: build 72 | run: gcc hello.c -o hello.exe 73 | - name: Run 74 | run: .\hello.exe 75 | ``` 76 | 77 | |Work flow for Windows| 78 | |:--:| 79 | |![Workflow3](images/Workflow_create3.png)| 80 | 81 | 82 | * Verify that the files you created are under the path **your_repo_name**/.github/workflows 83 | * Also click on **Actions** tab and verify that the newly added actions are present. 84 | 85 | |Verification|| 86 | |:--:|:--:| 87 | |![Workflow4](images/Workflow_create4.png)|![Workflow5](images/Workflow_create5.png)| 88 | 89 | * Make a small change to the **hello.c** file and **commit** changes to trigger the build actions. 90 | ``` 91 | #include 92 | int main() 93 | { 94 | printf("Welcome to Github Actions\n"); 95 | printf("\n******Hurry, It works******\n"); 96 | return 0; 97 | } 98 | 99 | ``` 100 | 101 | |Triggering Workflow| 102 | |:--:| 103 | |![Workflow6](images/Workflow_create6.png)| 104 | 105 | ### Verify that the actions are triggered and build is successful 106 | * Under **Actions** tab, check that the build works are triggered and wait for them to complete. 107 | * When color changes to **Green** (Build is successful) or **Red** (Build is failing) its complete. 108 | * Now open any one action and verify if you got the expected outputunder the **Run** command. 109 | * Click on any Workflow, and select **build** on the left side and expand teh **Run** command and check that the output is printed. 110 | 111 | |Workflow in action|| 112 | |:--:|:--:| 113 | |![Workflow7](images/Workflow_create7.png)|![Workflow8](images/Workflow_create8.png)| 114 | 115 | |Workflow Output| 116 | |:--:| 117 | |![Workflow9](images/Workflow_create9.png)| 118 | 119 | 120 | * The build and run commands can be replaced with Makefile commands to setup the build actions for projects with Makefiles 121 | -------------------------------------------------------------------------------- /GitSetup.md: -------------------------------------------------------------------------------- 1 | # Setup VS code to Clone and Push from Github Repositories 2 | ## Step-1 3 | * Create an Account on Github if you don't have an account already. 4 | 5 | ## Step-2 6 | * If you already have a repository created, jump to [Step-3](#step-3) 7 | * Create a new repository 8 | * Use available and meaningful name for your repository 9 | * Select appropriate visibility for your repository. Public to make it visible for everyone on the internet. Private to make it visible only for you and contributors you add to your repository. 10 | * Add the **README .md** and **.gitignore** files 11 | * Verify that the files are visible under your repository. 12 | 13 | |Step1|Step2| 14 | |:--:|:--:| 15 | |![New_repo](images/New_repo.png)|![New_repo2](images/New_repo2.png)| 16 | 17 | |Step3| 18 | |:--:| 19 | |![New_repo3](images/New_repo3.png)| 20 | 21 | ## Step-3 22 | * Clone your Repository to your local machine through VS Code 23 | * Copy the Https link of your github repository 24 | * Use **CTRL + SHIFT + P** to open command pallette and type **clone** and select **Clone from GitHub** 25 | * Paste the copied Https link and click Enter 26 | * Select a location where the repository should be saved on the machine 27 | * Select **Open** option to open the Cloned Repository in VS Code 28 | * Check that the contents of the repository are shown in the VS Code 29 | 30 | |Step1|Step2|Step3| 31 | |:--:|:--:|:--:| 32 | |![Clone1](images/clone2.png)|![Clone2](images/clone1.png)|![Clone3](images/clone3.png)| 33 | 34 | |Step4|Step5|Step6| 35 | |:--:|:--:|:--:| 36 | |![Clone4](images/clone4.png)|![Clone5](images/clone5.png)|![Clone6](images/clone6.png)| 37 | 38 | ## Step-4 39 | * Create a new file under the VS Code 40 | * Select the Source control Menu on the Left 41 | * Add your new files to the [**staging area**](https://git-scm.com/about/staging-area#:~:text=Staging%20Area%20Unlike%20the%20other%20systems%2C%20Git%20has,be%20formatted%20and%20reviewed%20before%20completing%20the%20commit.) by clicking on **+** icon 42 | * Add a meaningful commit message according to the changes made and add to repository by clicking on **☑** 43 | * From the dropdown, select push to push your local changes to the Github repository. 44 | * On completion, refresh the explorer and verify the added files are visible. 45 | 46 | |Step1|Step2|Step3| 47 | |:--:|:--:|:--:| 48 | |![Commit1](images/commit1.png)|![Commit2](images/commit2.png)|![Commit1](images/commit3.png)| 49 | 50 | 51 | |Step4|Step5| 52 | |:--:|:--:| 53 | |![Commit4](images/commit4.png)|![Commit5](images/commit5.png)| 54 | -------------------------------------------------------------------------------- /HOWTO.md: -------------------------------------------------------------------------------- 1 | # HOW TO ?? 2 | 3 | ## STEP1 - Create new C Project in Codeblocks 4 | * [New C Project in Codeblocks](https://www.youtube.com/watch?v=c9WT8revSJY) 5 | * From file explorer, Naviagete to Location of your Project and Create a folder named "src", "inc". 6 | * Under "src" folder, create a new file named "sum.c" and add the below code 7 | ``` 8 | int sum(int number1, int number2) 9 | { 10 | return number1 + number2; 11 | } 12 | ``` 13 | * Under "inc" folder, create a new file "sum.h" and add the below code 14 | ``` 15 | #ifndef __SUM_H__ 16 | #define __SUM_H__ 17 | 18 | int sum(int number1, int number2); 19 | 20 | #endif 21 | ``` 22 | * Now call your sum function inside the main.c file. 23 | ``` 24 | #include 25 | #include 26 | #include "sum.h" /* Add include file*/ 27 | int main() 28 | { 29 | printf("Hello world!\n"); 30 | 31 | int my_sum = sum(10, 20); /* Add function call */ 32 | printf("Sum = %d", my_sum); 33 | 34 | return 0; 35 | } 36 | ``` 37 | * After this step you should have the below folders and files under your project folder 38 | ``` 39 | ProjectFolder 40 | projectname.cbp 41 | main.c 42 | src 43 | sum.c 44 | inc 45 | sum.h 46 | ``` 47 | * Compiling the project now will give a error at this stage as the sum function is not defined in our project and is not visible to compiler. 48 | 49 | ## STEP2 - Add Files, Paths and Compile your Project 50 | * Add sum.c file to your project in Code Blocks. 51 | ``` 52 | Click on Project --> Add Files --> Navigate to your Project Location --> src --> sum.c 53 | ``` 54 | * Add include path of header file 55 | ``` 56 | Click on Project -> Build options... -> Search directories -> Compiler 57 | Click on Add Button and Select Navigate and navigate to project folder and select "inc" folder. 58 | Click on Select Folder. 59 | Pop up will appear asking to keep this as relative path. Select "Yes" followed by "OK". 60 | Select OK to Close the Project Build options window. 61 | ``` 62 | * Compiling your code now shoul dnot give you any error. If there is a error, try to redo the STE2. 63 | * Run the code to confirm your project is configured correctly. 64 | 65 | ## STEP3 - Add Unity Test framework to Codeblocks 66 | * In file explorer, create new folders "unity" and "test" under your Project folder. 67 | * After this step you should have the below folders and files under your project folder 68 | ``` 69 | ProjectFolder 70 | projectname.cbp 71 | main.c 72 | src 73 | sum.c 74 | inc 75 | sum.h 76 | unity 77 | test 78 | ``` 79 | * [Download](https://github.com/ThrowTheSwitch/Unity/archive/master.zip) or clone the content from [Unity Thow Swicth](https://github.com/ThrowTheSwitch/Unity) 80 | * Only 3 files are required and are placed inside "src" folder of the downloaded content: 81 | * unity.c 82 | * unity.h 83 | * unity_internals.h 84 | * Copy those files to a folder named "unity" under your project folder which is created in the previous step. 85 | 86 | * Under "test" folder, create a new file "test_sum.c" and add the below code 87 | ``` 88 | #include "unity.h" 89 | #include "factorial.h" 90 | 91 | void setUp() 92 | { } 93 | void tearDown() 94 | { } 95 | 96 | void test_sum(void) 97 | { 98 | TEST_ASSERT_EQUAL(30, sum(10, 20)); 99 | TEST_ASSERT_EQUAL(-30, sum(-50, 20)); 100 | } 101 | 102 | int test_main(void) 103 | { 104 | UNITY_BEGIN(); 105 | 106 | RUN_TEST(test_sum); 107 | 108 | return UNITY_END(); 109 | } 110 | ``` 111 | * Under "test" folder, create a new file "test_sum.h" and add the below code 112 | ``` 113 | #ifndef __TEST_SUM_H__ 114 | #define __TEST_SUM_H__ 115 | 116 | int test_main(void); 117 | 118 | #endif 119 | ``` 120 | * Follow STEP2 again to add the "test_sum.c" file to project and "test" folder for including the test folder. 121 | * Add the below code to your "main.c" file 122 | ``` 123 | #include 124 | #include 125 | #include "sum.h" /* Add include file*/ 126 | #include "test_sum.h" /* Add include file*/ 127 | int main() 128 | { 129 | printf("Hello world!\n"); 130 | 131 | int my_sum = sum(10, 20); /* Add function call */ 132 | printf("Sum = %d", my_sum); 133 | 134 | /* Calling test main*/ 135 | test_main(); /* Add function call */ 136 | 137 | return 0; 138 | } 139 | ``` 140 | * Compile the code to make sure you have added files and path correctly. If the compilation is giving an error, follow STEP3 again. 141 | * Run the compiled code now to see the output 142 | ``` 143 | test/test_sum.c:10:test_Factorial:PASS 144 | ``` 145 | * The line number might vary depending on the code. But observe that our code is passing the test case. 146 | * Now add more test cases to test your sum function and observe the output. 147 | * Try generating a dummy FAIL case by expecting a wrong result from sum function. 148 | 149 | * If you have correctly got the ouput so far, you have learnt how to use Unit test framework for C Programming. 150 | * To write and test other projects or programs, you have to change contents from "src", "inc" and "test" folders. 151 | * The content of unity folder will remain same for all projects. 152 | 153 | ## STEP4 - Generate Documents for projects using Doxygen 154 | * Let us re-use the same project file from the "factorail example" for Doxygen. 155 | * Create a new folder "documentation" under your project, and copy the "Doxyfile" from factorial example. 156 | * Copy files from the Factorial example 157 | ``` 158 | Copy "Factorial --> documentation --> Doxyfile" to "YourProject --> documentation" 159 | Copy "Factorial --> inc --> documentation_main.md" to "YourProject --> inc" 160 | ``` 161 | * Change the Content of documentation_main.md to match your project 162 | ``` 163 | @mainpage Sum Application by "Your name" 164 | @subpage sum.h 165 | ``` 166 | 167 | * Change the content of "sum.h" file to the below 168 | ``` 169 | /** 170 | * @file sum.h 171 | */ 172 | #ifndef __SUM_H__ 173 | #define __SUM_H__ 174 | 175 | /** 176 | * Calculates the sum of two integer numbers 177 | * @param[in] number1 first integer 178 | * @param[in] number2 seconf integer 179 | * @return Sum of number1 & number1 180 | * @note Any note for the function 181 | */ 182 | int sum(int number1, int number2); 183 | 184 | #endif 185 | ``` 186 | 187 | 188 | * Launch Doxywizard from launch menu 189 | 190 | |Step-1|Step-2| 191 | |:--:|:--:| 192 | |![Doxywizard](images/doxywizard.png)|![Doxywizard](images/doxywizard1.png)| 193 | 194 | * Open the Doxyfile in the Doxywizard application 195 | ``` 196 | Click on File --> Open --> Navigate to your project --> documentation --> Doxyfile 197 | ``` 198 | * Change the Project name to "SUM". 199 | * Since all the configuration is already present, you can genearet the document by clicking on Run 200 | ``` 201 | Click on Run --> Run doxygen 202 | ``` 203 | * The above action should genearet a folder name html under you Project directory. 204 | * You can Navigate to the folder and launch "index.html" fiel to see the Documentation for your project. 205 | 206 | * To understand each option of Doxygen Follow this [Tutorial1](https://embeddedinventor.com/guide-to-configure-doxygen-to-document-c-source-code-for-beginners/) and [Tutorial2](https://os.mbed.com/media/uploads/defiantgti/doxygentutorial.pdf) 207 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Linux_Setup.md: -------------------------------------------------------------------------------- 1 | # Software Setup on Linux OS for C Programming 2 | ## IDE 3 | * [Visula Studio Code](https://code.visualstudio.com/docs/cpp/config-linux) for compiling and debuggin the code. 4 | * Compiling and running without IDE 5 | ``` 6 | sudo apt-get update 7 | sudo apt-get upgrade 8 | sudo apt-get install build-essential 9 | ``` 10 | * Compiling and running 11 | ``` 12 | gcc filename.c -o outputname.out 13 | ./outputname.out 14 | ``` 15 | 16 | ### Build tools 17 | * Make for automating the build 18 | ``` 19 | sudo apt-get install cmake 20 | ``` 21 | 22 | ### Code Analysis 23 | * [cppcheck](http://cppcheck.sourceforge.net/) for Static Analysis 24 | * Valgrind for Heap analysis. Check usage [here](http://cs.ecs.baylor.edu/~donahoo/tools/valgrind/) 25 | ``` 26 | sudo apt-get install valgrind 27 | ``` 28 | * [Memory Sanitization](https://lemire.me/blog/2016/04/20/no-more-leaks-with-sanitize-flags-in-gcc-and-clang/) using gcc and -fsanitize option 29 | 30 | ### Source code Management 31 | * [git](https://git-scm.com/downloads) 32 | 33 | ### Test Framework 34 | * [Unit test](http://www.throwtheswitch.org/unity) 35 | 36 | ### Documentation 37 | * [Doxygen](https://www.doxygen.nl/download.html) 38 | -------------------------------------------------------------------------------- /MiniProject_C/0_Certificates/README.md: -------------------------------------------------------------------------------- 1 | Add the certificates in this folder 2 | * Sololearn Certificate for [Basics of C Programming](https://www.sololearn.com/learning/1089). 3 | * [Cisco NDG](https://www.netacad.com/courses/os-it/ndg-linux-unhatched) to Understand Linux OS and Command Line Interface. 4 | * **Screenshot** of [Github Learning](https://lab.github.com/githubtraining/first-day-on-github) to understand the github usage. 5 | -------------------------------------------------------------------------------- /MiniProject_C/1_Requirements/README.md: -------------------------------------------------------------------------------- 1 | # Requirements 2 | 3 | * Capture all the requirements wrt system, module, interface, integration, testing, Functional and Non-functional 4 | * Captures Basic Planning of the project through - Sample Gantt Chart attached 5 | 6 | * Tools: MS Excel, MS word or Similar 7 | 8 | -------------------------------------------------------------------------------- /MiniProject_C/1_Requirements/Simple Gantt Chart.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/MiniProject_C/1_Requirements/Simple Gantt Chart.xlsx -------------------------------------------------------------------------------- /MiniProject_C/2_Architecture/README.md: -------------------------------------------------------------------------------- 1 | # Architecture 2 | 3 | * Add UML Diagrams 4 | * For information about UML Diagrams refer: [UML Diagrams](https://www.uml-diagrams.org/uml-25-diagrams.html) 5 | ## Tools 6 | * [Draw.io](https://app.diagrams.net/) 7 | * [Creately](https://app.creately.com/diagram/create) 8 | * or any other free tools 9 | -------------------------------------------------------------------------------- /MiniProject_C/2_Architecture/behavior Diagrams/README.md: -------------------------------------------------------------------------------- 1 | # Behavior Diagrams 2 | 3 | ## Add all the Behavior diagrams implememted 4 | 5 | -------------------------------------------------------------------------------- /MiniProject_C/2_Architecture/structure Diagrams/README.md: -------------------------------------------------------------------------------- 1 | # Structure Diagrams 2 | 3 | ## Add all the Structure Diagrams implemented 4 | -------------------------------------------------------------------------------- /MiniProject_C/3_Implementation/Makefile: -------------------------------------------------------------------------------- 1 | # Name of the project 2 | PROJECT_NAME = Calculator 3 | 4 | # Output directory 5 | BUILD = build 6 | 7 | # All source code files 8 | SRC = project_main.c\ 9 | src/calculator_operations.c 10 | 11 | # All test source files 12 | TEST_SRC = src/calculator_operations.c\ 13 | test/test_calculator_operations.c\ 14 | unity/unity.c\ 15 | 16 | TEST_OUTPUT = $(BUILD)/Test_$(PROJECT_NAME).out 17 | 18 | # All include folders with header files 19 | INC = -Iinc\ 20 | -Iunity\ 21 | 22 | #Library Inlcudes 23 | #INCLUDE_LIBS = 24 | INCLUDE_LIBS = -lcunit 25 | 26 | # Project Output name 27 | PROJECT_OUTPUT = $(BUILD)/$(PROJECT_NAME).out 28 | 29 | # Document files 30 | DOCUMENTATION_OUTPUT = documentation/html 31 | 32 | # Default target built 33 | $(PROJECT_NAME):all 34 | 35 | # Run the target even if the matching name exists 36 | .PHONY: run clean test doc all 37 | 38 | all: $(SRC) $(BUILD) 39 | gcc $(SRC) $(INC) -o $(PROJECT_OUTPUT).out 40 | 41 | # Call `make run` to run the application 42 | run:$(PROJECT_NAME) 43 | ./$(PROJECT_OUTPUT).out 44 | 45 | # Document the code using Doxygen 46 | doc: 47 | make -C ./documentation 48 | 49 | # Build and run the unit tests 50 | test:$(BUILD) 51 | gcc $(TEST_SRC) $(INC) -o $(TEST_OUTPUT) $(INCLUDE_LIBS) 52 | ./$(TEST_OUTPUT) 53 | 54 | analyze: test memcheck staticcheck coverage sanitize_check 55 | 56 | staticcheck: 57 | cppcheck --enable=all -iunity . 58 | 59 | memcheck: 60 | valgrind ./$(TEST_OUTPUT) 61 | 62 | sanitize_check: 63 | gcc -fsanitize=address -fno-omit-frame-pointer $(TEST_SRC) $(INC) -o $(TEST_OUTPUT) $(INCLUDE_LIBS) 64 | ./$(TEST_OUTPUT) 65 | 66 | coverage:$(TEST_SRC) 67 | gcc -fprofile-arcs -ftest-coverage $(TEST_SRC) $(INC) -o $(TEST_OUTPUT) $(INCLUDE_LIBS) 68 | ./$(TEST_OUTPUT) 69 | gcov -a calculator_operations.c 70 | 71 | # Remove all the built files, invoke by `make clean` 72 | clean: 73 | rm -rf $(BUILD) $(DOCUMENTATION_OUTPUT) *.gcda *.gcno *.gcov 74 | 75 | # Create new build folder if not present 76 | $(BUILD): 77 | mkdir build 78 | -------------------------------------------------------------------------------- /MiniProject_C/3_Implementation/documentation/Makefile: -------------------------------------------------------------------------------- 1 | # Document the code using Doxygen 2 | 3 | doc: Doxyfile 4 | doxygen ./Doxyfile -------------------------------------------------------------------------------- /MiniProject_C/3_Implementation/inc/calculator_operations.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file calculator_operations.h 3 | * @author Bharath.G () 4 | * @brief Calculator application with 4 mathematical operations 5 | * @version 0.1 6 | * @date 2021-12-30 7 | * 8 | * @copyright Copyright (c) 2021 9 | * 10 | */ 11 | #ifndef __CALCULATOR_OPERATIONS_H__ 12 | #define __CALCULATOR_OPERATIONS_H__ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | /** 19 | * adds the operand1 and operand2 and returns the result 20 | * @param[in] operand1 21 | * @param[in] operand2 22 | * @return Result of operand1 + operand2 23 | */ 24 | int add(int operand1, int operand2); 25 | 26 | /** 27 | * subtracts the operand1, operand2 and returns the result 28 | * @param[in] operand1 29 | * @param[in] operand2 30 | * @return Result of operand1 - operand2 31 | */ 32 | int subtract(int operand1, int operand2); 33 | 34 | /** 35 | * multiply the operand1, operand2 and returns the result 36 | * @param[in] operand1 37 | * @param[in] operand2 38 | * @return Result of operand1 * operand2 39 | */ 40 | int multiply(int operand1, int operand2); 41 | 42 | 43 | /** 44 | * divides the operand1 by operand2 and returns the result 45 | * @param[in] operand1 46 | * @param[in] operand2 47 | * @return integer value of the operand1 / operand2 48 | * @note returns 0 for divide by 0 error 49 | */ 50 | int divide(int operand1, int operand2); 51 | 52 | #endif /* #define __CALCULATOR_OPERATIONS_H__ */ -------------------------------------------------------------------------------- /MiniProject_C/3_Implementation/inc/documentation_main.md: -------------------------------------------------------------------------------- 1 | @mainpage Calculator Application by Bharath G 2 | @subpage calculator_operations.h -------------------------------------------------------------------------------- /MiniProject_C/3_Implementation/project_main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /* Status of the operation requested */ 4 | #define VALID (1) 5 | #define INVALID (0) 6 | 7 | /* Calculator operation requested by user*/ 8 | unsigned int calculator_operation = 0; 9 | 10 | /* Operands on which calculation is performed */ 11 | int calculator_operand1 = 0; 12 | int calculator_operand2 = 0; 13 | 14 | /* Valid operations */ 15 | enum operations{ ADD=1, SUBTRACT, MULTIPLY, DIVIDE, EXIT }; 16 | 17 | /* Display the menu of operations supported */ 18 | void calculator_menu(void); 19 | /* Verifies the requested operations validity */ 20 | int valid_operation(int operation); 21 | 22 | 23 | /* Start of the application */ 24 | int main(int argc, char *argv[]) 25 | { 26 | printf("\n****Calculator****\n"); 27 | while(1) 28 | { 29 | calculator_menu(); 30 | } 31 | } 32 | 33 | void calculator_menu(void) 34 | { 35 | printf("\nAvailable Operations\n"); 36 | printf("\n1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Exit"); 37 | printf("\n\tEnter your choice\n"); 38 | 39 | __fpurge(stdin); 40 | scanf("%d", &calculator_operation); 41 | 42 | if(EXIT == calculator_operation) 43 | { 44 | printf("\nThank you. Exiting the Application\n"); 45 | exit(0); 46 | } 47 | 48 | if(INVALID != valid_operation(calculator_operation)) 49 | { 50 | printf("\n\tEnter your Numbers with space between them\n"); 51 | __fpurge(stdin); 52 | scanf("%d %d", &calculator_operand1, &calculator_operand2); 53 | } 54 | else 55 | { 56 | printf("\n\t---Wrong choice---\nEnter to continue\n"); 57 | __fpurge(stdin); 58 | getchar(); 59 | return; 60 | 61 | } 62 | switch(calculator_operation) 63 | { 64 | case ADD: 65 | printf("\n\t%d + %d = %d\nEnter to continue", 66 | calculator_operand1, 67 | calculator_operand2, 68 | add(calculator_operand1, calculator_operand2)); 69 | 70 | __fpurge(stdin); 71 | getchar(); 72 | break; 73 | case SUBTRACT: 74 | printf("\n\t%d - %d = %d\nEnter to continue", 75 | calculator_operand1, 76 | calculator_operand2, 77 | subtract(calculator_operand1, calculator_operand2)); 78 | 79 | __fpurge(stdin); 80 | getchar(); 81 | break; 82 | case MULTIPLY: 83 | printf("\n\t%d * %d = %d\nEnter to continue", 84 | calculator_operand1, 85 | calculator_operand2, 86 | multiply(calculator_operand1, calculator_operand2)); 87 | 88 | __fpurge(stdin); 89 | getchar(); 90 | break; 91 | case DIVIDE: 92 | printf("\n\t%d / %d = %d\nEnter to continue", 93 | calculator_operand1, 94 | calculator_operand2, 95 | divide(calculator_operand1, calculator_operand2)); 96 | 97 | __fpurge(stdin); 98 | getchar(); 99 | break; 100 | case 5: 101 | exit(0); 102 | break; 103 | default: 104 | printf("\n\t---It should never come here---\n"); 105 | } 106 | } 107 | 108 | int valid_operation(int operation) 109 | { 110 | /* Check if the operation is a valid operation */ 111 | return ((ADD <= operation) && (EXIT >= operation)) ? VALID: INVALID; 112 | } -------------------------------------------------------------------------------- /MiniProject_C/3_Implementation/src/calculator_operations.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int add(int operand1, int operand2) 4 | { 5 | return operand1 + operand2; 6 | } 7 | 8 | int subtract(int operand1, int operand2) 9 | { 10 | return operand1 - operand2; 11 | } 12 | 13 | int multiply(int operand1, int operand2) 14 | { 15 | return operand1 * operand2; 16 | } 17 | 18 | int divide(int operand1, int operand2) 19 | { 20 | if(0 == operand2) 21 | return 0; 22 | else 23 | return operand1 / operand2; 24 | } -------------------------------------------------------------------------------- /MiniProject_C/3_Implementation/test/test_calculator_operations.c: -------------------------------------------------------------------------------- 1 | #include "unity.h" 2 | #include 3 | 4 | /* Modify these two lines according to the project */ 5 | #include 6 | #define PROJECT_NAME "Calculator" 7 | 8 | /* Prototypes for all the test functions */ 9 | void test_add(void); 10 | void test_subtract(void); 11 | void test_multiply(void); 12 | void test_divide(void); 13 | 14 | /* Required by the unity test framework */ 15 | void setUp(){} 16 | /* Required by the unity test framework */ 17 | void tearDown(){} 18 | 19 | /* Start of the application test */ 20 | int main() 21 | { 22 | /* Initiate the Unity Test Framework */ 23 | UNITY_BEGIN(); 24 | 25 | /* Run Test functions */ 26 | RUN_TEST(test_add); 27 | RUN_TEST(test_subtract); 28 | RUN_TEST(test_multiply); 29 | RUN_TEST(test_divide); 30 | 31 | /* Close the Unity Test Framework */ 32 | return UNITY_END(); 33 | } 34 | 35 | /* Write all the test functions */ 36 | void test_add(void) { 37 | TEST_ASSERT_EQUAL(30, add(10, 20)); 38 | 39 | /* Dummy fail*/ 40 | TEST_ASSERT_EQUAL(15000, add(7500, 7500)); 41 | } 42 | 43 | void test_subtract(void) { 44 | TEST_ASSERT_EQUAL(-3, subtract(0, 3)); 45 | 46 | /* Dummy fail*/ 47 | TEST_ASSERT_EQUAL(100, subtract(1000, 900)); 48 | } 49 | 50 | void test_multiply(void) { 51 | TEST_ASSERT_EQUAL(0, multiply(1, 0)); 52 | 53 | /* Dummy fail*/ 54 | TEST_ASSERT_EQUAL(10, multiply(2, 5)); 55 | } 56 | 57 | void test_divide(void) { 58 | TEST_ASSERT_EQUAL(0, divide(1, 0)); 59 | 60 | /* Dummy fail*/ 61 | TEST_ASSERT_EQUAL(1, divide(2, 2)); 62 | } 63 | -------------------------------------------------------------------------------- /MiniProject_C/4_TestPlanAndOutput/README.md: -------------------------------------------------------------------------------- 1 | # test plan and test ouput 2 | 3 | * Add all the test paln and test output related files under thsi folder -------------------------------------------------------------------------------- /MiniProject_C/5_Report/README.md: -------------------------------------------------------------------------------- 1 | Report document 2 | -------------------------------------------------------------------------------- /MiniProject_C/6_ImagesAndVideos/README.md: -------------------------------------------------------------------------------- 1 | # images and videos 2 | 3 | * Add any images or Videos related to the implemented project -------------------------------------------------------------------------------- /MiniProject_C/7_Other/README.md: -------------------------------------------------------------------------------- 1 | # other 2 | 3 | * Add any other folders or files which are created for the project 4 | 5 | -------------------------------------------------------------------------------- /MiniProject_C/7_Other/data-set/README.md: -------------------------------------------------------------------------------- 1 | # data set 2 | 3 | -------------------------------------------------------------------------------- /MiniProject_C/README.md: -------------------------------------------------------------------------------- 1 | # Project Information 2 | 3 | * Add a brief discription about the project 4 | * Add the information about extra folders or files added -------------------------------------------------------------------------------- /Multifile_Programming.md: -------------------------------------------------------------------------------- 1 | # Multifile Programming 2 | * Industry projects opten have 5000 to 5 millions of Source lines of Code. And writing everything under one sinlge file is not reader frindly and also it is easy to get lost. 3 | * A simple solution is to divide the code into multiple files. 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # STEPin MiniProject_Template Sample 2 | 3 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/3b20c7c3ec7f4734b42cc0d04dcf3fb2)](https://app.codacy.com/manual/stepin654321/MiniProject_Template?utm_source=github.com&utm_medium=referral&utm_content=stepin654321/MiniProject_Template&utm_campaign=Badge_Grade_Dashboard) 4 | 5 | 6 | |Build|Unit Test|cppcheck|Valgrind|Codacy| 7 | |:--:|:--:|:--:|:--:|:--:| 8 | |![C/C++ CI](https://github.com/stepin654321/MiniProject_Template/workflows/C/C++%20CI/badge.svg)|![Unit testing](https://github.com/stepin654321/MiniProject_Template/workflows/Unit%20testing/badge.svg)|![cppcheck-action](https://github.com/stepin654321/MiniProject_Template/workflows/cppcheck-action/badge.svg)|![Valgrind](https://github.com/stepin654321/MiniProject_Template/workflows/Valgrind/badge.svg)|[![Codacy Badge](https://app.codacy.com/project/badge/Grade/3ac7e2a959a24fa4b5d1b9c1c886ff75)](https://www.codacy.com/manual/stepin654321/MiniProject_Template?utm_source=github.com&utm_medium=referral&utm_content=stepin654321/MiniProject_Template&utm_campaign=Badge_Grade)| 9 | 10 | ## Integrated Tools to GitHub 11 | * [Codacy](https://www.codacy.com/) 12 | 13 | ## GitHub Actions 14 | * Build using Make for CI 15 | * Unit tests with Cunit 16 | * Static code analysis using cppcheck 17 | * Dynamic Code analysis using Valgrind 18 | 19 | ## Learning Resources 20 | * [How to write Makefile](https://github.com/riuandg5/learn-makefile) by Rishu Anand 21 | -------------------------------------------------------------------------------- /SETUP.md: -------------------------------------------------------------------------------- 1 | # Software tools for C Programming 2 | 3 | * [WINDOWS OS](Windows_Setup.md) 4 | * [LINUX OS](Linux_Setup.md) -------------------------------------------------------------------------------- /Windows_Setup.md: -------------------------------------------------------------------------------- 1 | # Software Setup on Windows OS for C Programming 2 | 3 | ## IDE 4 | [Visula Studio Code](https://code.visualstudio.com/docs/cpp/config-mingw) for compiling and debuggin the code. 5 | 6 | ### Build tools 7 | * [Make Installer](http://gnuwin32.sourceforge.net/downlinks/make.php) from [GNUWin32](http://gnuwin32.sourceforge.net/packages/make.htm) for automating the build without usign IDE 8 | 9 | ### Code Analysis 10 | * [cppcheck](http://cppcheck.sourceforge.net/) for Static Analysis 11 | * [Dr. Memory](https://github.com/DynamoRIO/drmemory/wiki/Downloads) for Heap analysis 12 | * [Memory Sanitization](https://lemire.me/blog/2016/04/20/no-more-leaks-with-sanitize-flags-in-gcc-and-clang/) using gcc and -fsanitize option 13 | 14 | ### Source code Management 15 | * [git](https://git-scm.com/downloads) 16 | 17 | ### Test Framework 18 | * [Unit test](http://www.throwtheswitch.org/unity) 19 | 20 | ### Documentation 21 | * [Doxygen](https://www.doxygen.nl/download.html) 22 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # C/C++ with GCC 2 | # Build your C/C++ project with GCC using make. 3 | # Add steps that publish test results, save build artifacts, deploy, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/c-cpp/gcc 5 | 6 | trigger: 7 | - master 8 | 9 | pool: 10 | vmImage: ubuntu-latest 11 | 12 | steps: 13 | - script: | 14 | make 15 | displayName: 'make' 16 | -------------------------------------------------------------------------------- /images/CodeMetrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/CodeMetrics.png -------------------------------------------------------------------------------- /images/Doxygen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Doxygen1.png -------------------------------------------------------------------------------- /images/Linux_doxygen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen1.png -------------------------------------------------------------------------------- /images/Linux_doxygen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen2.png -------------------------------------------------------------------------------- /images/Linux_doxygen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen3.png -------------------------------------------------------------------------------- /images/Linux_doxygen4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen4.png -------------------------------------------------------------------------------- /images/Linux_doxygen5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen5.png -------------------------------------------------------------------------------- /images/Linux_doxygen6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen6.png -------------------------------------------------------------------------------- /images/Linux_doxygen7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen7.png -------------------------------------------------------------------------------- /images/Linux_doxygen8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Linux_doxygen8.png -------------------------------------------------------------------------------- /images/New_repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/New_repo.png -------------------------------------------------------------------------------- /images/New_repo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/New_repo2.png -------------------------------------------------------------------------------- /images/New_repo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/New_repo3.png -------------------------------------------------------------------------------- /images/Workflow_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create.png -------------------------------------------------------------------------------- /images/Workflow_create0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create0.png -------------------------------------------------------------------------------- /images/Workflow_create2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create2.png -------------------------------------------------------------------------------- /images/Workflow_create3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create3.png -------------------------------------------------------------------------------- /images/Workflow_create4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create4.png -------------------------------------------------------------------------------- /images/Workflow_create5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create5.png -------------------------------------------------------------------------------- /images/Workflow_create6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create6.png -------------------------------------------------------------------------------- /images/Workflow_create7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create7.png -------------------------------------------------------------------------------- /images/Workflow_create8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create8.png -------------------------------------------------------------------------------- /images/Workflow_create9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/Workflow_create9.png -------------------------------------------------------------------------------- /images/clone1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/clone1.png -------------------------------------------------------------------------------- /images/clone2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/clone2.png -------------------------------------------------------------------------------- /images/clone3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/clone3.png -------------------------------------------------------------------------------- /images/clone4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/clone4.png -------------------------------------------------------------------------------- /images/clone5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/clone5.png -------------------------------------------------------------------------------- /images/clone6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/clone6.png -------------------------------------------------------------------------------- /images/commit1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/commit1.png -------------------------------------------------------------------------------- /images/commit2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/commit2.png -------------------------------------------------------------------------------- /images/commit3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/commit3.png -------------------------------------------------------------------------------- /images/commit4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/commit4.png -------------------------------------------------------------------------------- /images/commit5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/commit5.png -------------------------------------------------------------------------------- /images/doxywizard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/doxywizard.png -------------------------------------------------------------------------------- /images/doxywizard1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stepin654321/MiniProject_Template/abf9c8a1c2246639ddc877c4a9fe499928631cb3/images/doxywizard1.png --------------------------------------------------------------------------------