├── .astylerc ├── .gitignore ├── CMakeLists.txt ├── IMPORTANT ├── LICENSE.txt ├── Makefile ├── README.md ├── build └── .gitignore ├── configure-gh-pages ├── link_git_modules ├── new_source ├── src ├── d_string.c ├── d_string.h └── main.c ├── templates ├── README.md.in ├── doxygen.conf.in ├── template.c.in ├── template.h.in └── version.h.in ├── test ├── CuTest.c ├── CuTest.h └── make-tests.sh ├── tools ├── Toolchain-MinGW-w64-32bit.cmake ├── Toolchain-MinGW-w64-64bit.cmake └── Toolchain-mingw32.cmake └── update_git_modules /.astylerc: -------------------------------------------------------------------------------- 1 | # astyle configuration file 2 | # http://astyle.sourceforge.net/astyle.html 3 | 4 | 5 | # Brace style 6 | --style=java 7 | 8 | 9 | # Indents 10 | --indent=force-tab=4 11 | 12 | 13 | # Switch statements 14 | --indent-switches 15 | 16 | 17 | # Break long conditionals 18 | --break-after-logical 19 | 20 | 21 | # Indent pre-processor directives 22 | --indent-preproc-block 23 | --indent-preproc-define 24 | --indent-preproc-cond 25 | 26 | 27 | # Line endings 28 | --lineend=linux 29 | 30 | 31 | # Add brackets to one-liners 32 | --add-brackets 33 | 34 | 35 | # Pad with blank lines 36 | --break-blocks 37 | 38 | 39 | # Pad with spaces 40 | --pad-oper 41 | --pad-header 42 | 43 | 44 | # Pointers/References 45 | --align-reference=name 46 | 47 | 48 | # Excludes 49 | --exclude="src/critic.c" 50 | --exclude="src/smartenter.c" 51 | --exclude="src/smartenter_parser.c" 52 | 53 | --ignore-exclude-errors 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | CHANGELOG-UNRELEASED 3 | documentation 4 | 5 | # Developer Tools 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | *.xcworkspace 15 | !default.xcworkspace 16 | xcuserdata 17 | profile 18 | *.moved-aside 19 | DerivedData 20 | .idea/ 21 | 22 | build-xcode 23 | build-xcode-debug 24 | 25 | *.xcuserstate 26 | *.xcbkptlist 27 | 28 | *.orig 29 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.6) 2 | 3 | 4 | # ================== 5 | # Define Our Project 6 | # ================== 7 | 8 | set (My_Project_Title "C-Template") 9 | set (My_Project_Description "Boilerplate c project with cmake support, CuTest unit testing, and more.") 10 | set (My_Project_Author "Fletcher T. Penney") 11 | set (My_Project_Revised_Date "2019-01-16") 12 | set (My_Project_Version_Major 1) 13 | set (My_Project_Version_Minor 0) 14 | set (My_Project_Version_Patch 9) 15 | 16 | set (My_Project_Version "${My_Project_Version_Major}.${My_Project_Version_Minor}.${My_Project_Version_Patch}") 17 | 18 | set (My_Project_Copyright_Date "2015-2019") 19 | set (My_Project_Copyright "Copyright © ${My_Project_Copyright_Date} ${My_Project_Author}.") 20 | 21 | string(TOUPPER ${My_Project_Title} My_Project_Title_Caps ) 22 | string(REGEX REPLACE " " "_" My_Project_Title_Caps ${My_Project_Title_Caps} ) 23 | 24 | project (${My_Project_Title}) 25 | 26 | 27 | # ========================= 28 | # Build Submodules (if any) 29 | # ========================= 30 | 31 | # add_subdirectory(submodules/foo) 32 | 33 | 34 | # ================= 35 | # Configure Project 36 | # ================= 37 | 38 | # Search for included files here 39 | include_directories( ${PROJECT_SOURCE_DIR}/src ) 40 | include_directories( ${PROJECT_SOURCE_DIR}/test ) 41 | include_directories(${PROJECT_BINARY_DIR}) 42 | 43 | 44 | # ================= 45 | # Macro Definitions 46 | # ================= 47 | 48 | MACRO(ADD_PUBLIC_HEADER target filename) 49 | # Add filename to public_header_files list, flag it as 50 | # public header for libraries and OS X Frameworks 51 | 52 | # This will work for creating one library/framework with public headers 53 | # per project. If you need more than one, you will need to customize 54 | # the workflow as appropriate, since there is only one 55 | # public_header_files list. 56 | 57 | # SET_TARGET_PROPERTIES(${target} PROPERTIES PUBLIC_HEADER ${filename}) 58 | 59 | LIST(APPEND public_header_files ${filename}) 60 | 61 | SET_SOURCE_FILES_PROPERTIES( 62 | ${filename} 63 | PROPERTIES 64 | MACOSX_PACKAGE_LOCATION 65 | include/\${PRODUCT_NAME} 66 | ) 67 | 68 | # Set Xcode project to configure public header location to allow 69 | # use when this project is used in another workspace. 70 | # NOTE: You must manually add a "Headers" build phase and add 71 | # the desired public headers to that list for Xcode to use them. 72 | # 73 | # TODO: If anyone knows how to automate that in Cmake, I would be very 74 | # grateful!! 75 | 76 | SET_TARGET_PROPERTIES(${target} PROPERTIES 77 | XCODE_ATTRIBUTE_PUBLIC_HEADERS_FOLDER_PATH 78 | "include/$(TARGET_NAME)" 79 | ) 80 | 81 | SET_TARGET_PROPERTIES(${target} PROPERTIES 82 | XCODE_ATTRIBUTE_PRIVATE_HEADERS_FOLDER_PATH 83 | "$(PUBLIC_HEADERS_FOLDER_PATH)/Private" 84 | ) 85 | 86 | # Set Xcode target to include settings for OS X and iOS 87 | 88 | SET_TARGET_PROPERTIES(${target} PROPERTIES 89 | XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS 90 | "macos iphonesimulator iphoneos" 91 | ) 92 | 93 | SET_TARGET_PROPERTIES(${target} PROPERTIES 94 | XCODE_ATTRIBUTE_VALID_ARCHITECTURES 95 | "x86_64 i386 armv6 armv7 armv7s arm64" 96 | ) 97 | 98 | ENDMACRO(ADD_PUBLIC_HEADER) 99 | 100 | 101 | # The target should be an OS X Bundle with a PList 102 | 103 | MACRO(MAKE_TARGET_BUNDLE targetname) 104 | 105 | set_target_properties( 106 | ${targetname} 107 | PROPERTIES 108 | MACOSX_BUNDLE_INFO_PLIST 109 | ${PROJECT_SOURCE_DIR}/templates/plist.in 110 | ) 111 | 112 | ENDMACRO(MAKE_TARGET_BUNDLE) 113 | 114 | 115 | MACRO(ADD_LINKED_FRAMEWORK frame) 116 | 117 | SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGES} -framework ${frame}") 118 | 119 | ENDMACRO(ADD_LINKED_FRAMEWORK) 120 | 121 | 122 | # ====================== 123 | # Process Template Files 124 | # ====================== 125 | 126 | file(READ ${PROJECT_SOURCE_DIR}/LICENSE.txt My_Project_License) 127 | 128 | string(REGEX REPLACE "\n" "\n\t" My_Project_License_Indented ${My_Project_License}) 129 | 130 | string(REGEX REPLACE "\"" "\\\\\"" My_Project_License_Escaped ${My_Project_License_Indented}) 131 | 132 | string(REGEX REPLACE "\n" "\\\\n\"\\\\\n\"" My_Project_License_Literal ${My_Project_License_Escaped}) 133 | 134 | 135 | configure_file ( 136 | "${PROJECT_SOURCE_DIR}/templates/template.c.in" 137 | "${PROJECT_BINARY_DIR}/template.c" 138 | ) 139 | 140 | configure_file ( 141 | "${PROJECT_SOURCE_DIR}/templates/template.h.in" 142 | "${PROJECT_BINARY_DIR}/template.h" 143 | ) 144 | 145 | # Update the project README, to pull in new version #, etc. 146 | configure_file ( 147 | "${PROJECT_SOURCE_DIR}/templates/README.md.in" 148 | "${CMAKE_CURRENT_LIST_DIR}/README.md" 149 | ) 150 | 151 | configure_file ( 152 | "${PROJECT_SOURCE_DIR}/templates/version.h.in" 153 | "${PROJECT_BINARY_DIR}/version.h" 154 | ) 155 | 156 | 157 | # ============ 158 | # Source Files 159 | # ============ 160 | 161 | # src_files are the primary files, and will be included in doxygen documentation 162 | set(src_files 163 | # src/foo.c 164 | ) 165 | 166 | # Primary header files, also for doxygen documentation 167 | set(header_files 168 | ) 169 | 170 | # Public headers, will be installed in 'include' 171 | # Do not manually add files here, use the ADD_PUBLIC_HEADER() macro 172 | set(public_header_files 173 | ) 174 | 175 | # Utility source files will not be included in doxygen 176 | set(src_utility_files 177 | # src/d_string.c 178 | ) 179 | 180 | set(header_utility_files 181 | # src/d_string.h 182 | ${PROJECT_BINARY_DIR}/version.h 183 | ) 184 | 185 | # Generate doxygen configuration file 186 | string(REPLACE ";" " " doxygen_src_files "${src_files}" ) 187 | string(REPLACE ";" " " doxygen_header_files "${header_files}" ) 188 | 189 | configure_file ( 190 | "${PROJECT_SOURCE_DIR}/templates/doxygen.conf.in" 191 | "${PROJECT_BINARY_DIR}/doxygen.conf" 192 | ) 193 | 194 | 195 | # =========================================== 196 | # Build Test Suite with CuTest (unit testing) 197 | # =========================================== 198 | 199 | # from http://stackoverflow.com/questions/25199677/how-to-detect-if-current-scope-has-a-parent-in-cmake 200 | get_directory_property(hasParent PARENT_DIRECTORY) 201 | 202 | if(hasParent) 203 | # Don't create "run_tests" when we're a sub-project for something else 204 | else() 205 | set(test_files 206 | test/CuTest.c 207 | test/CuTest.h 208 | ${PROJECT_BINARY_DIR}/AllTests.c 209 | ) 210 | 211 | if (DEFINED TEST) 212 | add_definitions(-DTEST) 213 | 214 | add_executable(run_tests 215 | ${test_files} 216 | ${src_files} 217 | ${header_files} 218 | ${src_utility_files} 219 | ${header_utility_files} 220 | ) 221 | 222 | # Process source files to look for tests to run 223 | add_custom_command ( 224 | OUTPUT ${PROJECT_BINARY_DIR}/AllTests.c 225 | COMMAND bash ${PROJECT_SOURCE_DIR}/test/make-tests.sh ${PROJECT_SOURCE_DIR}/src/*.c > ${PROJECT_BINARY_DIR}/AllTests.c 226 | ) 227 | 228 | enable_testing() 229 | 230 | add_test( test ${PROJECT_BINARY_DIR}/run_tests) 231 | 232 | # valgrind memory testing 233 | find_program (MEMORYCHECK_COMMAND valgrind) 234 | SET (MEMORYCHECK_COMMAND_OPTIONS --leak-check=full --error-exitcode=1) 235 | 236 | add_test( memory_test ${MEMORYCHECK_COMMAND} ${MEMORYCHECK_COMMAND_OPTIONS} ${PROJECT_BINARY_DIR}/run_tests) 237 | 238 | endif() 239 | endif() 240 | 241 | 242 | # ======================= 243 | # Configure for Target OS 244 | # ======================= 245 | 246 | # OS X Builds 247 | if (APPLE) 248 | 249 | # Configure backwards-compatible support (if your project allows it) 250 | SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.4" CACHE STRING "Deployment target for OSX" FORCE) 251 | SET(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "10.0" CACHE STRING "Deployment target for iOS" FORCE) 252 | 253 | # Compile for x86_64 and i386. ppc no longer supported 254 | if(CMAKE_BUILD_TYPE MATCHES "Release") 255 | SET (CMAKE_OSX_ARCHITECTURES x86_64;i386) 256 | endif(CMAKE_BUILD_TYPE MATCHES "Release") 257 | 258 | # Use PackageMaker for installers? 259 | if (DEFINED ZIP) 260 | set (CPACK_GENERATOR ZIP) 261 | else (DEFINED ZIP) 262 | set (CPACK_GENERATOR PackageMaker) 263 | endif (DEFINED ZIP) 264 | 265 | endif (APPLE) 266 | 267 | # Windows Builds 268 | if (WIN32) 269 | 270 | # Use NSIS to generate installers? 271 | if (DEFINED ZIP) 272 | set (CPACK_GENERATOR ZIP) 273 | else (DEFINED ZIP) 274 | set (CPACK_GENERATOR NSIS) 275 | endif (DEFINED ZIP) 276 | 277 | # Linux Builds (not cross-compiling for Windows) 278 | elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") 279 | 280 | # Create zip archive 281 | set (CPACK_GENERATOR ZIP) 282 | 283 | # Statically link libraries -- might make the binary slightly more 284 | # compatible across Linux distributions, for example 285 | # 286 | # You may wish to disable this. 287 | # 288 | 289 | set (CMAKE_FIND_LIBRARY_SUFFIXES ".a") 290 | set (BUILD_SHARED_LIBRARIES OFF) 291 | set (CMAKE_EXE_LINKER_FLAGS "-static") 292 | 293 | # Some libraries need to be linked on some Linux builds 294 | if (DEFINED TEST) 295 | # target_link_libraries(run_tests m) 296 | endif (DEFINED TEST) 297 | 298 | endif (WIN32) 299 | 300 | 301 | # ============== 302 | # Define targets 303 | # ============== 304 | 305 | # Create a library? 306 | add_library(libFOO STATIC 307 | ${src_files} 308 | ${src_utility_files} 309 | ${header_files} 310 | ${header_utility_files} 311 | ) 312 | 313 | # remove the extra "lib" from "liblibFOO" 314 | SET_TARGET_PROPERTIES(libFOO PROPERTIES 315 | PREFIX "" 316 | FRAMEWORK TRUE 317 | FRAMEWORK_VERSION A 318 | MACOSX_FRAMEWORK_IDENTIFIER net.fletcherpenney.c-template 319 | ) 320 | 321 | # Create a command-line app? 322 | # if (NOT DEFINED TEST) 323 | # add_executable(main 324 | # src/main.c 325 | # src/d_string.c 326 | # src/d_string.h 327 | # ${header_files} 328 | # ) 329 | # 330 | # Link the library to the app? 331 | # target_link_libraries(main libFOO) 332 | # endif() 333 | 334 | # Xcode settings for fat binaries 335 | # set_target_properties(libFOO PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO") 336 | # set_target_properties(main PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO") 337 | 338 | 339 | # ========================== 340 | # Build Installer with CPack 341 | # ========================== 342 | 343 | # You're largely on your own here 344 | 345 | # install (FILES ${CMAKE_CURRENT_LIST_DIR}/README.md ${PROJECT_SOURCE_DIR}/LICENSE.txt 346 | # DESTINATION . 347 | # ) 348 | 349 | # Use something like this to install public header files (after adding them 350 | # with the ADD_PUBLIC_HEADER() macro) 351 | 352 | # install (FILES ${public_header_files} DESTINATION local/include/libFoo) 353 | 354 | set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "${My_Project_Description}") 355 | set (CPACK_PACKAGE_VENDOR "${My_Project_Author}") 356 | set (CPACK_PACKAGE_VERSION "${My_Project_Version_Major}.${My_Project_Version_Minor}.${My_Project_Version_Patch}") 357 | set (CPACK_PACKAGE_VERSION_MAJOR "${My_Project_Version_Major}") 358 | set (CPACK_PACKAGE_VERSION_MINOR "${My_Project_Version_Minor}") 359 | set (CPACK_PACKAGE_VERSION_PATCH "My_Project_Version_Patch") 360 | 361 | set (CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE.txt") 362 | 363 | if (APPLE) 364 | set (CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-Mac-${CPACK_PACKAGE_VERSION}") 365 | else (APPLE) 366 | set (CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CMAKE_SYSTEM_NAME}-${CPACK_PACKAGE_VERSION}") 367 | endif (APPLE) 368 | 369 | # Use some default install locations (if appropriate) 370 | set(CPACK_SET_DESTDIR true) 371 | if (WIN32) 372 | set (CPACK_INSTALL_PREFIX "") 373 | set (CPACK_NSIS_MODIFY_PATH ON) 374 | else (WIN32) 375 | set (CPACK_INSTALL_PREFIX /usr/local) 376 | endif (WIN32) 377 | 378 | set (CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT}) 379 | 380 | include (CPack) 381 | -------------------------------------------------------------------------------- /IMPORTANT: -------------------------------------------------------------------------------- 1 | This project is designed for use with cmake. 2 | 3 | The Makefile controls the overall build: 4 | 5 | make 6 | make release 7 | 8 | Build a version optimized for performance. 9 | 10 | make debug 11 | 12 | Faster compile, but not as high performance. Enables test suite support. 13 | 14 | make xcode 15 | 16 | Create an Xcode project for use on OS X. 17 | 18 | make windows 19 | 20 | Used for cross-compiling for Windows using MinGW. 21 | 22 | make documentation 23 | 24 | Setup a `doxygen` configuration file based on project information, and then 25 | generate HTML and LaTeX documentation. 26 | 27 | make clean 28 | 29 | Clean up the `build` directory. 30 | 31 | These commands control the `build` directory. Everything in this directory is 32 | auto-generated. You should not manually change these files or put anything 33 | else in there. 34 | 35 | 36 | The setup is designed to support unit testing with CuTest. Functions along 37 | the lines of `void Test*` will be located automatically and used to create the 38 | test suite, which is run by: 39 | 40 | ./run_tests 41 | 42 | Or 43 | 44 | make test 45 | 46 | (The `run_tests` approach will probably give more useful feedback if a test fails.) 47 | 48 | 49 | Integration testing must be handled separately. 50 | 51 | You can configure the `CMakeLists.txt` to support creating installers. 52 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The `c-template` project is released under the MIT License. 2 | 3 | GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project: 4 | 5 | https://github.com/fletcher/MultiMarkdown-4/ 6 | 7 | MMD 4 is released under both the MIT License and GPL. 8 | 9 | 10 | CuTest is released under the zlib/libpng license. See CuTest.c for the text 11 | of the license. 12 | 13 | 14 | ## The MIT License ## 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy 17 | of this software and associated documentation files (the "Software"), to deal 18 | in the Software without restriction, including without limitation the rights 19 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 | copies of the Software, and to permit persons to whom the Software is 21 | furnished to do so, subject to the following conditions: 22 | 23 | The above copyright notice and this permission notice shall be included in 24 | all copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 32 | THE SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BUILD_DIR = build 2 | XCODE_BUILD_DIR = build-xcode 3 | XCODE_DEBUG_BUILD_DIR = build-xcode-debug 4 | 5 | # The release target will perform additional optimization 6 | .PHONY : release 7 | release: $(BUILD_DIR) 8 | cd $(BUILD_DIR); \ 9 | cmake -DCMAKE_BUILD_TYPE=Release .. 10 | 11 | # Build zip file package 12 | .PHONY : zip 13 | zip: $(BUILD_DIR) 14 | cd $(BUILD_DIR); touch README.html; \ 15 | cmake -DCMAKE_BUILD_TYPE=Release -DZIP=1 .. 16 | 17 | # debug target enables CuTest unit testing 18 | .PHONY : debug 19 | debug: $(BUILD_DIR) 20 | cd $(BUILD_DIR); \ 21 | cmake -DTEST=1 .. 22 | 23 | # analyze target enables use of clang's scan-build (if installed) 24 | # will then need to run 'scan-build make' to compile and analyze 25 | # 'scan-build -V make' will show the results graphically in your 26 | # web browser 27 | .PHONY : analyze 28 | analyze: $(BUILD_DIR) 29 | cd $(BUILD_DIR); \ 30 | scan-build cmake -DTEST=1 .. 31 | 32 | # Create xcode project 33 | # You can then build within XCode, or using the commands: 34 | # xcodebuild -configuration Debug 35 | # xcodebuild -configuration Release 36 | .PHONY : xcode 37 | xcode: $(XCODE_BUILD_DIR) 38 | cd $(XCODE_BUILD_DIR); \ 39 | cmake -G Xcode .. 40 | 41 | .PHONY : xcode-debug 42 | xcode-debug: $(XCODE_DEBUG_BUILD_DIR) 43 | cd $(XCODE_DEBUG_BUILD_DIR); \ 44 | cmake -G Xcode -DTEST=1 .. 45 | 46 | # Cross-compile for Windows using MinGW on *nix 47 | .PHONY : windows 48 | windows: $(BUILD_DIR) 49 | cd $(BUILD_DIR); touch README.html; \ 50 | cmake -DCMAKE_TOOLCHAIN_FILE=../tools/Toolchain-MinGW-w64-64bit.cmake -DCMAKE_BUILD_TYPE=Release .. 51 | 52 | # Build Windows zip file using MinGW on *nix 53 | .PHONY : windows-zip 54 | windows-zip: $(BUILD_DIR) 55 | cd $(BUILD_DIR); touch README.html; \ 56 | cmake -DCMAKE_TOOLCHAIN_FILE=../tools/Toolchain-MinGW-w64-64bit.cmake -DCMAKE_BUILD_TYPE=Release -DZIP=1 .. 57 | 58 | # Cross-compile for Windows using MinGW on *nix (32-bit) 59 | .PHONY : windows-32 60 | windows-32: $(BUILD_DIR) 61 | cd $(BUILD_DIR); touch README.html; \ 62 | cmake -DCMAKE_TOOLCHAIN_FILE=../tools/Toolchain-MinGW-w64-32bit.cmake -DCMAKE_BUILD_TYPE=Release .. 63 | 64 | # Build Windows zip file using MinGW on *nix (32-bit) 65 | .PHONY : windows-zip-32 66 | windows-zip-32: $(BUILD_DIR) 67 | cd $(BUILD_DIR); touch README.html; \ 68 | cmake -DCMAKE_TOOLCHAIN_FILE=../tools/Toolchain-mingw32.cmake -DCMAKE_BUILD_TYPE=Release -DZIP=1 .. 69 | 70 | # Build the documentation using doxygen 71 | .PHONY : documentation 72 | documentation: $(BUILD_DIR) 73 | cd $(BUILD_DIR); \ 74 | cmake -DDOCUMENTATION=1 ..; cd ..; \ 75 | doxygen build/doxygen.conf 76 | 77 | .PHONY : gh-pages 78 | gh-pages: documentation 79 | cp -r $(BUILD_DIR)/documentation/html/* documentation/ 80 | 81 | # Clean out the build directory 82 | .PHONY : clean 83 | clean: 84 | rm -rf $(BUILD_DIR)/* 85 | 86 | # Create build directory if it doesn't exist 87 | $(BUILD_DIR): CHANGELOG 88 | -mkdir $(BUILD_DIR) 2>/dev/null 89 | -cd $(BUILD_DIR); rm -rf * 90 | 91 | # Build xcode directories if they don't exist 92 | $(XCODE_BUILD_DIR): 93 | -mkdir $(XCODE_BUILD_DIR) 2>/dev/null 94 | -cd $(XCODE_BUILD_DIR); rm -rf * 95 | 96 | $(XCODE_DEBUG_BUILD_DIR): 97 | -mkdir $(XCODE_DEBUG_BUILD_DIR) 2>/dev/null 98 | -cd $(XCODE_DEBUG_BUILD_DIR); rm -rf * 99 | 100 | # Generate a list of changes since last commit to 'master' branch 101 | .PHONY : CHANGELOG 102 | CHANGELOG: 103 | git log master..develop --format="* %s" | sort | uniq > CHANGELOG-UNRELEASED 104 | 105 | # Use astyle 106 | .PHONY : astyle 107 | astyle: 108 | astyle --options=.astylerc "src/*.c" "src/*.h" 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## About ## 2 | 3 | | | | 4 | | ---------- | ------------------------- | 5 | | Title: | C-Template | 6 | | Author: | Fletcher T. Penney | 7 | | Date: | 2019-01-16 | 8 | | Copyright: | Copyright © 2015-2019 Fletcher T. Penney. | 9 | | Version: | 1.0.9 | 10 | 11 | 12 | ## Introduction ## 13 | 14 | This template was created out of a desire to simplify some of the setup and 15 | configuration that I was doing over and over each time I started a new project. 16 | Additionally, I wanted to try to start encouraging some "better practices" 17 | (though not necessarily "best practices"): 18 | 19 | 1. [Test-driven development][tdd] -- My development of MultiMarkdown 20 | focused on integration testing, but really had no unit testing to 21 | speak of. Some newer projects I began working on were a bit math- 22 | heavy, and ensuring that each piece works properly became even more 23 | important. It was also nice to be able to actually develop code that 24 | could do *something* (via the test suite), even though the project as 25 | a whole was nowhere near complete.) To accomplish this, I include the 26 | [CuTest] project to support writing tests for your code. 27 | 28 | 2. Use of the [cmake] build system. `cmake` is not perfect by any 29 | means, but it does offer some very useful features and a means for 30 | better integrating the compilation and packaging/installation aspects 31 | of development. Rather than reinventing the wheel each time, this 32 | setup incorporates basic `cmake` functionality to make it easy to 33 | control how your project is compiled, and includes automated generation 34 | of the test command. 35 | 36 | 3. Templates -- `cmake` has a reasonable templating system, so that you 37 | can define basic variables (e.g. author, project name, etc.) and allow 38 | `cmake` to combine those elements to ensure consistency across source 39 | code and README files. 40 | 41 | 4. Documentation -- some default setup to allow for [Doxygen]-generated 42 | documentation. The generated `README.md` file is used as the main 43 | page, and the source c/header files are included. Naturally, Doxygen 44 | is a complex system, so you're responsible for figuring out how to 45 | properly document your code. 46 | 47 | 5. Simplify `git` a touch -- In my larger projects, I make heavy use of 48 | git modules. One project may make use of 20-30 modules, which are 49 | designed to be re-usable across other projects. I found that I was 50 | spending too much time making sure that I had the latest version 51 | of a module checked out, so I created two scripts to help me keep 52 | my modules in line: `link_git_modules` and `update_git_modules`. 53 | You run the `link` script once to ensure that your modules are properly 54 | set up, and can then run the `update` script at any time to be sure 55 | you've pulled the latest version. One advantage of this is that your 56 | modules are set to a branch, rather than just a detached commit. It 57 | may or may not work for your needs, but it saves me a bunch of time 58 | and headache. 59 | 60 | 61 | [tdd]: https://en.wikipedia.org/wiki/Test-driven_development 62 | [cmake]: http://www.cmake.org/ 63 | [CuTest]: http://cutest.sourceforge.net 64 | [Doxygen]: http://www.stack.nl/~dimitri/doxygen/ 65 | 66 | 67 | ## How do I use it? ## 68 | 69 | You can download the source from [github] and get to work. The file "IMPORTANT" 70 | contains instructions on the various build commands you can use. 71 | 72 | 73 | I recommend using the following script to automatically create a new git repo, 74 | pull in the default project template, and configure git-flow. You simply have 75 | to rename your project directory from `new-project` to whatever you desire: 76 | 77 | 78 | #!/bin/sh 79 | 80 | git init new-project 81 | 82 | cd new-project 83 | 84 | git remote add "template" https://github.com/fletcher/c-template.git 85 | 86 | git pull template master 87 | 88 | git flow init -d 89 | 90 | git checkout develop 91 | 92 | 93 | Using this approach, you can define your own `origin` remote if you like, but 94 | the `template` remote can be used to update the core project files should any 95 | improvements come about: 96 | 97 | git checkout develop 98 | git merge template master 99 | 100 | **NOTE**: `cmake` is a complex suite of utilities, and if you have trouble you 101 | will need to get support elsewhere. If you find errors in this template, by 102 | all means I want to hear about them and fix them, but this is just a basic 103 | framework to get you started. In all likelihood, all but the most basic 104 | projects will need some customization. 105 | 106 | 107 | [github]: https://github.com/fletcher/c-template 108 | 109 | 110 | ## Configuration ## 111 | 112 | 113 | ### CMakeLists.txt File ### 114 | 115 | First, you should update the project information under the "Define Our Project" 116 | section, including the title, description, etc. This information will be used 117 | to update the README, as well as to create the `version.h` file so that the 118 | project can have access to its own version number. 119 | 120 | You will then need to update the various groups in the "Source Files" section 121 | so that Cmake will be able to determine which files are used to build your 122 | project. For reasons that will become clear later, try to follow the 123 | suggestions for the different groups of files. 124 | 125 | You then need to define your targets, such as a library, or executable, etc. 126 | Obviously, this will depend on the needs of your project. You can also add 127 | custom steps based on the Target OS (OS X, Windows, *nix, etc.). 128 | 129 | You can use CPack to generate installers for your software. This can be 130 | complex, and you will need to modify this section heavily. 131 | 132 | CuTest is used by default to provide unit testing (see below), but you 133 | can also use CMake/CTest to provide integration testing. Again, this will 134 | be up to you to configure. 135 | 136 | 137 | ### CuTest ### 138 | 139 | [CuTest] provides a means to integrate unit testing with your C source code. 140 | Once you get the hang of it, it's easy to use. 141 | 142 | 143 | ### Doxygen ### 144 | 145 | [Doxygen] is used to generate documentation from the source code itself. 146 | Properly configuring your source for this is up to you. You can modify the 147 | `doxygen.conf.in` template with your desired settings as desired, but most 148 | of the basics are handled for you based on your CMake configuration. 149 | 150 | 151 | ### GitHub Pages Support ### 152 | 153 | The `configure-gh-pages` script sets up a `documentation` directory that is 154 | linked to a `gh-pages` branch of the project. You can then run `make gh-pages` 155 | to update the documentation in this directory. Commit and push to your origin, 156 | and your projects gh-page is updated. 157 | 158 | 159 | ### Makefile ### 160 | 161 | The overall build process is controlled by the master `Makefile`. It provides 162 | the following commands: 163 | 164 | make 165 | make release 166 | 167 | Generate the CMake build files for use or distribution. Once complete you will 168 | need to change to the `build` directory and run `make`, `make test`, and 169 | `cpack` as desired. 170 | 171 | make zip 172 | 173 | Direct CPack to create a zip installer rather than a graphical installer. 174 | 175 | make debug 176 | 177 | Generate build files for [CuTest] unit testing. In the `build` directory, 178 | run `make`, then `make test`. 179 | 180 | make analyze 181 | 182 | If you have `clang` installed, this will generate debug build files with the 183 | `scan-build` command. In the `build` directory, run `scan-build -V make` 184 | to compile the software and view the static analysis results. 185 | 186 | make xcode 187 | 188 | Build a project file for Xcode on OS X. 189 | 190 | make windows 191 | make windows-zip 192 | make windows-32 193 | make windows-zip-32 194 | 195 | Use the MinGW software to cross-compile for Windows on a *nix machine. You can 196 | specify the 32 bit option, and also the zip option as indicated. 197 | 198 | make documentation 199 | 200 | Build the [Doxygen]-generated documentation. 201 | 202 | make clean 203 | 204 | Clean out the `build` directory. Be sure to run this before running another 205 | command. 206 | 207 | 208 | ## Git Submodules ## 209 | 210 | Apparently, submodules are a rather controversial feature in git. For me, 211 | however, they have proven invaluable. My most active projects depend on each 212 | other, and the submodule feature allows me to easily keep everything up to 213 | date. That said, however, I quickly realized that submodules don't work very 214 | well using default commands. 215 | 216 | The problem is that I want to always use the latest version of my submodules. 217 | This is more easily accomplished when the submodule is set to the `master` 218 | branch of the original repository, rather than a detached commit as happens 219 | by default. In order to easily keep all submodules updated, there are two 220 | scripts: 221 | 222 | 1. `link_git_modules` -- this script is generally only run when the master 223 | repository is first cloned, but can also be run after a new submodule is 224 | added. It causes the submodules to automatically track the master branch. 225 | If you need to modify this, there are instructions in the script itself 226 | explaining how to modify it on a per submodule basis. Running this script 227 | more than one time will not hurt anything. 228 | 229 | 2. `update_git_modules` -- this script simply causes each submodule to be 230 | updated to the latest commit in the original repository. Again, running it 231 | multiple times doesn't hurt anything. 232 | 233 | 234 | ## Source File Templates ## 235 | 236 | In the `templates` directory are two files, `template.c.in` and 237 | `template.h.in`. These are used to create default source files that include 238 | the project title, copyright, license, etc. They are also set up to include 239 | some example information for [Doxygen] and [CuTest]. 240 | 241 | 242 | ## License ## 243 | 244 | The `c-template` project is released under the MIT License. 245 | 246 | GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project: 247 | 248 | https://github.com/fletcher/MultiMarkdown-4/ 249 | 250 | MMD 4 is released under both the MIT License and GPL. 251 | 252 | 253 | CuTest is released under the zlib/libpng license. See CuTest.c for the text 254 | of the license. 255 | 256 | 257 | ## The MIT License ## 258 | 259 | Permission is hereby granted, free of charge, to any person obtaining a copy 260 | of this software and associated documentation files (the "Software"), to deal 261 | in the Software without restriction, including without limitation the rights 262 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 263 | copies of the Software, and to permit persons to whom the Software is 264 | furnished to do so, subject to the following conditions: 265 | 266 | The above copyright notice and this permission notice shall be included in 267 | all copies or substantial portions of the Software. 268 | 269 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 270 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 271 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 272 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 273 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 274 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 275 | THE SOFTWARE. 276 | -------------------------------------------------------------------------------- /build/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /configure-gh-pages: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir documentation 4 | 5 | cd documentation 6 | 7 | git clone .. . 8 | 9 | git checkout --orphan gh-pages 10 | 11 | git rm -rf . 12 | -------------------------------------------------------------------------------- /link_git_modules: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This command sets up any git submodules in the project. 4 | # Generally, this only needs to be run once on a freshly cloned 5 | # project, but won't harm anything if run later, provided 6 | # you modify it to accomodate any submodules that should *NOT* 7 | # be on the `master` branch. 8 | 9 | git submodule init 10 | 11 | git submodule update 12 | 13 | git submodule foreach git branch --set-upstream master origin/master 14 | 15 | git submodule foreach git checkout master 16 | 17 | # If one module needs to follow a different branch: 18 | # cd some_module 19 | # git branch --set-upstream our-branch origin/some-branch 20 | # git checkout our-branch 21 | # cd .. 22 | -------------------------------------------------------------------------------- /new_source: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | FILE=$1 4 | 5 | 6 | cp build/template.c src/$FILE.c 7 | 8 | perl -pi -e "s/file\.c/$FILE\.c/;" -e "s/file\.h/$FILE\.h/;" src/$FILE.c 9 | 10 | 11 | cp build/template.h src/$FILE.h 12 | 13 | perl -pi -e "s/file\.c/$FILE\.c/;" -e "s/file\.h/$FILE\.h/;" -e "s/FILE\_/\U$FILE\_/;" src/$FILE.h 14 | -------------------------------------------------------------------------------- /src/d_string.c: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Dynamic string -- Lightweight dynamic string implementation. 4 | 5 | @file d_string.c 6 | 7 | @brief Dynamic string -- refactoring of old GLibFacade from MultiMarkdown. 8 | Provides a string "object" that can grow to accomodate any size content 9 | that is appended. 10 | 11 | 12 | @author Daniel Jalkut, modified by Fletcher T. Penney and Dan Lowe 13 | 14 | @bug 15 | 16 | **/ 17 | 18 | /* 19 | 20 | Copyright © 2011 Daniel Jalkut. 21 | Modifications by Fletcher T. Penney, Copyright © 2011-2018 Fletcher T. Penney. 22 | Modifications by Dan Lowe, Copyright © 2011 Dan Lowe. 23 | 24 | 25 | The `MultiMarkdown 6` project is released under the MIT License.. 26 | 27 | GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project: 28 | 29 | https://github.com/fletcher/MultiMarkdown-4/ 30 | 31 | MMD 4 is released under both the MIT License and GPL. 32 | 33 | 34 | CuTest is released under the zlib/libpng license. See CuTest.c for the text 35 | of the license. 36 | 37 | 38 | ## The MIT License ## 39 | 40 | Permission is hereby granted, free of charge, to any person obtaining a copy 41 | of this software and associated documentation files (the "Software"), to deal 42 | in the Software without restriction, including without limitation the rights 43 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 44 | copies of the Software, and to permit persons to whom the Software is 45 | furnished to do so, subject to the following conditions: 46 | 47 | The above copyright notice and this permission notice shall be included in 48 | all copies or substantial portions of the Software. 49 | 50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 52 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 53 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 54 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 55 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 56 | THE SOFTWARE. 57 | 58 | */ 59 | 60 | 61 | #include 62 | #include 63 | #include 64 | #include 65 | 66 | #include "d_string.h" 67 | 68 | #ifdef TEST 69 | #include "CuTest.h" 70 | #endif 71 | 72 | 73 | /* 74 | * The following section came from: 75 | * 76 | * http://lists-archives.org/mingw-users/12649-asprintf-missing-vsnprintf- 77 | * behaving-differently-and-_vsncprintf-undefined.html 78 | * 79 | * and 80 | * 81 | * http://groups.google.com/group/jansson-users/browse_thread/thread/ 82 | * 76a88d63d9519978/041a7d0570de2d48?lnk=raot 83 | */ 84 | 85 | // Some operating systems do not supply vasprintf() -- standardize on this 86 | // replacement from: 87 | // https://github.com/esp8266/Arduino/issues/1954 88 | int vasprintf(char** strp, const char* fmt, va_list ap) { 89 | va_list ap2; 90 | va_copy(ap2, ap); 91 | 92 | #if (defined(_WIN32) || defined(__WIN32__)) 93 | char *tmp = NULL; 94 | int size = vsnprintf(tmp, 0, fmt, ap2); 95 | #else 96 | char tmp[1]; 97 | int size = vsnprintf(tmp, 1, fmt, ap2); 98 | #endif 99 | 100 | if (size <= 0) { 101 | return size; 102 | } 103 | 104 | va_end(ap2); 105 | size += 1; 106 | *strp = (char*)malloc(size * sizeof(char)); 107 | return vsnprintf(*strp, size, fmt, ap); 108 | } 109 | 110 | 111 | /* DString */ 112 | 113 | #define kStringBufferStartingSize 1024 //!< Default size of string buffer capacity 114 | #define kStringBufferGrowthMultiplier 2 //!< Multiply capacity by this factor when more space is needed 115 | #define kStringBufferMaxIncrement 1024 * 1024 * 100 //!< Maximum growth increment when resizing (to limit exponential growth) 116 | 117 | 118 | /// Create a new dynamic string 119 | DString* d_string_new(const char * startingString) { 120 | DString* newString = malloc(sizeof(DString)); 121 | 122 | if (!newString) { 123 | return NULL; 124 | } 125 | 126 | if (startingString == NULL) { 127 | startingString = ""; 128 | } 129 | 130 | size_t startingBufferSize = kStringBufferStartingSize; 131 | size_t startingStringSize = strlen(startingString); 132 | 133 | while (startingBufferSize < (startingStringSize + 1)) { 134 | startingBufferSize *= kStringBufferGrowthMultiplier; 135 | } 136 | 137 | newString->str = malloc(startingBufferSize); 138 | 139 | if (!newString->str) { 140 | free(newString); 141 | return NULL; 142 | } 143 | 144 | newString->currentStringBufferSize = startingBufferSize; 145 | strncpy(newString->str, startingString, startingStringSize); 146 | newString->str[startingStringSize] = '\0'; 147 | newString->currentStringLength = startingStringSize; 148 | 149 | return newString; 150 | } 151 | 152 | 153 | #ifdef TEST 154 | void Test_d_string_new(CuTest* tc) { 155 | char * test = "foo"; 156 | 157 | DString * result = d_string_new(test); 158 | 159 | CuAssertIntEquals(tc, 3, result->currentStringLength); 160 | CuAssertIntEquals(tc, kStringBufferStartingSize, result->currentStringBufferSize); 161 | CuAssertStrEquals(tc, test, result->str); 162 | CuAssertIntEquals(tc, '\0', result->str[strlen(test)]); 163 | 164 | d_string_free(result, true); 165 | 166 | result = d_string_new(NULL); 167 | 168 | CuAssertIntEquals(tc, 0, result->currentStringLength); 169 | CuAssertIntEquals(tc, kStringBufferStartingSize, result->currentStringBufferSize); 170 | CuAssertStrEquals(tc, "", result->str); 171 | CuAssertIntEquals(tc, '\0', 0); 172 | 173 | d_string_free(result, true); 174 | } 175 | #endif 176 | 177 | 178 | /// Free dynamic string 179 | char* d_string_free(DString * ripString, bool freeCharacterData) { 180 | if (ripString == NULL) { 181 | return NULL; 182 | } 183 | 184 | char* returnedString = ripString->str; 185 | 186 | if (freeCharacterData) { 187 | if (ripString->str != NULL) { 188 | free(ripString->str); 189 | } 190 | 191 | returnedString = NULL; 192 | } 193 | 194 | free(ripString); 195 | 196 | return returnedString; 197 | } 198 | 199 | 200 | /// Ensure that dynamic string has specified capacity 201 | static void ensureStringBufferCanHold(DString * baseString, size_t newStringSize) { 202 | if (baseString) { 203 | size_t newBufferSizeNeeded = newStringSize + 1; 204 | 205 | if (newBufferSizeNeeded > baseString->currentStringBufferSize) { 206 | size_t newBufferSize = baseString->currentStringBufferSize; 207 | 208 | while (newBufferSizeNeeded > newBufferSize) { 209 | if (newBufferSize > kStringBufferMaxIncrement) { 210 | newBufferSize += kStringBufferMaxIncrement; 211 | } else { 212 | newBufferSize *= kStringBufferGrowthMultiplier; 213 | } 214 | } 215 | 216 | char *temp; 217 | temp = realloc(baseString->str, newBufferSize); 218 | 219 | if (temp == NULL) { 220 | /* realloc failed */ 221 | fprintf(stderr, "Error reallocating memory for d_string. Current buffer size %lu.\n", baseString->currentStringBufferSize); 222 | 223 | exit(1); 224 | } 225 | 226 | baseString->str = temp; 227 | baseString->currentStringBufferSize = newBufferSize; 228 | } 229 | } 230 | } 231 | 232 | 233 | #ifdef TEST 234 | void Test_ensureStringBufferCanHold(CuTest* tc) { 235 | char * test = "foo"; 236 | 237 | DString * result = d_string_new(test); 238 | 239 | ensureStringBufferCanHold(result, 1024); 240 | CuAssertIntEquals(tc, 2048, result->currentStringBufferSize); 241 | 242 | ensureStringBufferCanHold(result, 1024); 243 | CuAssertIntEquals(tc, 2048, result->currentStringBufferSize); 244 | 245 | /* This becomes 0 after we add 1 for the '\0' */ 246 | ensureStringBufferCanHold(result, -1); 247 | CuAssertIntEquals(tc, 2048, result->currentStringBufferSize); 248 | 249 | ensureStringBufferCanHold(result, 1024 * 1024 - 1); 250 | CuAssertIntEquals(tc, 1024 * 1024, result->currentStringBufferSize); 251 | 252 | ensureStringBufferCanHold(result, 1024 * 1024 - 1); 253 | CuAssertIntEquals(tc, 1024 * 1024, result->currentStringBufferSize); 254 | 255 | ensureStringBufferCanHold(NULL, 1024); 256 | 257 | d_string_free(result, true); 258 | } 259 | #endif 260 | 261 | 262 | /// Append null-terminated string to end of dynamic string 263 | void d_string_append(DString * baseString, const char * appendedString) { 264 | if (baseString && appendedString) { 265 | size_t appendedStringLength = strlen(appendedString); 266 | 267 | if (appendedStringLength > 0) { 268 | size_t newStringLength = baseString->currentStringLength + appendedStringLength; 269 | ensureStringBufferCanHold(baseString, newStringLength); 270 | 271 | /* We already know where the current string ends, so pass that as the starting address for strncat */ 272 | strncat(baseString->str + baseString->currentStringLength, appendedString, appendedStringLength); 273 | baseString->currentStringLength = newStringLength; 274 | } 275 | } 276 | } 277 | 278 | 279 | #ifdef TEST 280 | void Test_d_string_append(CuTest* tc) { 281 | char * test = "foo"; 282 | 283 | DString * result = d_string_new(test); 284 | 285 | d_string_append(result, "bar"); 286 | CuAssertStrEquals(tc, "foobar", result->str); 287 | 288 | d_string_append(result, ""); 289 | CuAssertStrEquals(tc, "foobar", result->str); 290 | 291 | d_string_append(result, NULL); 292 | CuAssertStrEquals(tc, "foobar", result->str); 293 | 294 | d_string_append(NULL, "foo"); 295 | 296 | d_string_free(result, true); 297 | } 298 | #endif 299 | 300 | 301 | /// Append single character to end of dynamic string 302 | void d_string_append_c(DString * baseString, char appendedCharacter) { 303 | if (baseString && appendedCharacter) { 304 | size_t newSizeNeeded = baseString->currentStringLength + 1; 305 | ensureStringBufferCanHold(baseString, newSizeNeeded); 306 | 307 | baseString->str[baseString->currentStringLength] = appendedCharacter; 308 | baseString->currentStringLength++; 309 | baseString->str[baseString->currentStringLength] = '\0'; 310 | } 311 | } 312 | 313 | 314 | #ifdef TEST 315 | void Test_d_string_append_c(CuTest* tc) { 316 | char * test = "foo"; 317 | 318 | DString * result = d_string_new(test); 319 | 320 | d_string_append_c(result, 'z'); 321 | CuAssertStrEquals(tc, "fooz", result->str); 322 | CuAssertIntEquals(tc, 4, result->currentStringLength); 323 | 324 | d_string_append_c(result, 0); 325 | CuAssertStrEquals(tc, "fooz", result->str); 326 | CuAssertIntEquals(tc, 4, result->currentStringLength); 327 | 328 | d_string_append_c(NULL, 'f'); 329 | 330 | d_string_free(result, true); 331 | } 332 | #endif 333 | 334 | 335 | /// Append array of characters to end of dynamic string 336 | void d_string_append_c_array(DString * baseString, const char * appendedChars, size_t bytes) { 337 | if (baseString && appendedChars) { 338 | if (bytes == -1) { 339 | // This is the same as regular append 340 | d_string_append(baseString, appendedChars); 341 | } else { 342 | if (appendedChars) { 343 | size_t newSizeNeeded = baseString->currentStringLength + bytes; 344 | ensureStringBufferCanHold(baseString, newSizeNeeded); 345 | 346 | memcpy((void*)baseString->str + baseString->currentStringLength, appendedChars, bytes); 347 | 348 | baseString->currentStringLength = newSizeNeeded; 349 | baseString->str[newSizeNeeded] = '\0'; 350 | } 351 | } 352 | } 353 | } 354 | 355 | 356 | #ifdef TEST 357 | void Test_d_string_append_c_array(CuTest* tc) { 358 | char * test = "foo"; 359 | 360 | DString * result = d_string_new(test); 361 | 362 | d_string_append_c_array(result, "bar", 3); 363 | CuAssertStrEquals(tc, "foobar", result->str); 364 | CuAssertIntEquals(tc, 6, result->currentStringLength); 365 | 366 | d_string_append_c_array(result, "baz", -1); 367 | CuAssertStrEquals(tc, "foobarbaz", result->str); 368 | CuAssertIntEquals(tc, 9, result->currentStringLength); 369 | 370 | d_string_append_c_array(result, NULL, 0); 371 | CuAssertStrEquals(tc, "foobarbaz", result->str); 372 | CuAssertIntEquals(tc, 9, result->currentStringLength); 373 | 374 | d_string_append_c_array(result, NULL, -1); 375 | CuAssertStrEquals(tc, "foobarbaz", result->str); 376 | CuAssertIntEquals(tc, 9, result->currentStringLength); 377 | 378 | d_string_append_c_array(NULL, "foo", -1); 379 | 380 | d_string_free(result, true); 381 | } 382 | #endif 383 | 384 | 385 | /// Append to end of dynamic string using format specifier 386 | void d_string_append_printf(DString * baseString, const char * format, ...) { 387 | if (baseString && format) { 388 | va_list args; 389 | va_start(args, format); 390 | 391 | char* formattedString = NULL; 392 | vasprintf(&formattedString, format, args); 393 | 394 | if (formattedString != NULL) { 395 | d_string_append(baseString, formattedString); 396 | free(formattedString); 397 | } 398 | 399 | va_end(args); 400 | } 401 | } 402 | 403 | 404 | #ifdef TEST 405 | void Test_d_string_append_printf(CuTest* tc) { 406 | char * test = "foo"; 407 | 408 | DString * result = d_string_new(test); 409 | 410 | d_string_append_printf(result, "%dbar%d", 5, 7); 411 | CuAssertStrEquals(tc, "foo5bar7", result->str); 412 | CuAssertIntEquals(tc, 8, result->currentStringLength); 413 | 414 | d_string_append_printf(result, NULL); 415 | CuAssertStrEquals(tc, "foo5bar7", result->str); 416 | CuAssertIntEquals(tc, 8, result->currentStringLength); 417 | 418 | d_string_append_printf(result, NULL, 5, 7); 419 | CuAssertStrEquals(tc, "foo5bar7", result->str); 420 | CuAssertIntEquals(tc, 8, result->currentStringLength); 421 | 422 | d_string_append_printf(NULL, "foo"); 423 | 424 | d_string_free(result, true); 425 | } 426 | #endif 427 | 428 | 429 | /// Prepend null-terminated string to end of dynamic string 430 | void d_string_prepend(DString * baseString, const char * prependedString) { 431 | if (baseString && prependedString) { 432 | size_t prependedStringLength = strlen(prependedString); 433 | 434 | if (prependedStringLength > 0) { 435 | size_t newStringLength = baseString->currentStringLength + prependedStringLength; 436 | ensureStringBufferCanHold(baseString, newStringLength); 437 | 438 | memmove(baseString->str + prependedStringLength, baseString->str, baseString->currentStringLength); 439 | strncpy(baseString->str, prependedString, prependedStringLength); 440 | baseString->currentStringLength = newStringLength; 441 | baseString->str[baseString->currentStringLength] = '\0'; 442 | } 443 | } 444 | } 445 | 446 | 447 | #ifdef TEST 448 | void Test_d_string_prepend(CuTest* tc) { 449 | char * test = "foo"; 450 | 451 | DString * result = d_string_new(test); 452 | 453 | d_string_prepend(result, "bar"); 454 | CuAssertStrEquals(tc, "barfoo", result->str); 455 | CuAssertIntEquals(tc, 6, result->currentStringLength); 456 | 457 | d_string_prepend(result, NULL); 458 | CuAssertStrEquals(tc, "barfoo", result->str); 459 | CuAssertIntEquals(tc, 6, result->currentStringLength); 460 | 461 | d_string_prepend(NULL, "bar"); 462 | 463 | d_string_free(result, true); 464 | } 465 | #endif 466 | 467 | 468 | /// Insert null-terminated string inside dynamic string 469 | void d_string_insert(DString * baseString, size_t pos, const char * insertedString) { 470 | if (baseString && insertedString) { 471 | size_t insertedStringLength = strlen(insertedString); 472 | 473 | if (insertedStringLength > 0) { 474 | if (pos > baseString->currentStringLength) { 475 | pos = baseString->currentStringLength; 476 | } 477 | 478 | size_t newStringLength = baseString->currentStringLength + insertedStringLength; 479 | ensureStringBufferCanHold(baseString, newStringLength); 480 | 481 | /* Shift following string to 'right' */ 482 | memmove(baseString->str + pos + insertedStringLength, baseString->str + pos, baseString->currentStringLength - pos); 483 | strncpy(baseString->str + pos, insertedString, insertedStringLength); 484 | baseString->currentStringLength = newStringLength; 485 | baseString->str[baseString->currentStringLength] = '\0'; 486 | } 487 | } 488 | } 489 | 490 | 491 | #ifdef TEST 492 | void Test_d_string_insert(CuTest* tc) { 493 | char * test = "foo"; 494 | 495 | DString * result = d_string_new(test); 496 | 497 | d_string_insert(result, 2, "bar"); 498 | CuAssertStrEquals(tc, "fobaro", result->str); 499 | CuAssertIntEquals(tc, 6, result->currentStringLength); 500 | 501 | d_string_insert(result, -1, "bar"); 502 | CuAssertStrEquals(tc, "fobarobar", result->str); 503 | CuAssertIntEquals(tc, 9, result->currentStringLength); 504 | 505 | d_string_insert(result, -1, NULL); 506 | CuAssertStrEquals(tc, "fobarobar", result->str); 507 | CuAssertIntEquals(tc, 9, result->currentStringLength); 508 | 509 | d_string_insert(NULL, 0, NULL); 510 | 511 | d_string_free(result, true); 512 | } 513 | #endif 514 | 515 | 516 | /// Insert single character inside dynamic string 517 | void d_string_insert_c(DString * baseString, size_t pos, char insertedCharacter) { 518 | if (baseString && insertedCharacter) { 519 | if (pos > baseString->currentStringLength) { 520 | pos = baseString->currentStringLength; 521 | } 522 | 523 | size_t newSizeNeeded = baseString->currentStringLength + 1; 524 | ensureStringBufferCanHold(baseString, newSizeNeeded); 525 | 526 | /* Shift following string to 'right' */ 527 | memmove(baseString->str + pos + 1, baseString->str + pos, baseString->currentStringLength - pos); 528 | 529 | baseString->str[pos] = insertedCharacter; 530 | baseString->currentStringLength++; 531 | baseString->str[baseString->currentStringLength] = '\0'; 532 | } 533 | } 534 | 535 | 536 | #ifdef TEST 537 | void Test_d_string_insert_c(CuTest* tc) { 538 | char * test = "foo"; 539 | 540 | DString * result = d_string_new(test); 541 | 542 | d_string_insert_c(result, 2, 'b'); 543 | CuAssertStrEquals(tc, "fobo", result->str); 544 | CuAssertIntEquals(tc, 4, result->currentStringLength); 545 | 546 | d_string_insert_c(result, -1, 'z'); 547 | CuAssertStrEquals(tc, "foboz", result->str); 548 | CuAssertIntEquals(tc, 5, result->currentStringLength); 549 | 550 | d_string_insert_c(result, 3, 0); 551 | CuAssertStrEquals(tc, "foboz", result->str); 552 | CuAssertIntEquals(tc, 5, result->currentStringLength); 553 | 554 | d_string_insert_c(NULL, 0, 0); 555 | 556 | d_string_free(result, true); 557 | } 558 | #endif 559 | 560 | 561 | /// Insert inside dynamic string using format specifier 562 | void d_string_insert_printf(DString * baseString, size_t pos, const char * format, ...) { 563 | if (baseString && format) { 564 | va_list args; 565 | va_start(args, format); 566 | 567 | char* formattedString = NULL; 568 | vasprintf(&formattedString, format, args); 569 | 570 | if (formattedString != NULL) { 571 | d_string_insert(baseString, pos, formattedString); 572 | free(formattedString); 573 | } 574 | 575 | va_end(args); 576 | } 577 | } 578 | 579 | 580 | #ifdef TEST 581 | void Test_d_string_insert_printf(CuTest* tc) { 582 | char * test = "foo"; 583 | 584 | DString * result = d_string_new(test); 585 | 586 | d_string_insert_printf(result, 2, "%dbar%d", 5, 7); 587 | CuAssertStrEquals(tc, "fo5bar7o", result->str); 588 | CuAssertIntEquals(tc, 8, result->currentStringLength); 589 | 590 | d_string_insert_printf(result, -1, "z", 5, 7); 591 | CuAssertStrEquals(tc, "fo5bar7oz", result->str); 592 | CuAssertIntEquals(tc, 9, result->currentStringLength); 593 | 594 | d_string_insert_printf(NULL, 0, NULL); 595 | 596 | d_string_free(result, true); 597 | } 598 | #endif 599 | 600 | 601 | /// Erase portion of dynamic string 602 | void d_string_erase(DString * baseString, size_t pos, size_t len) { 603 | if (baseString) { 604 | if ((pos > baseString->currentStringLength) || (len <= 0)) { 605 | return; 606 | } 607 | 608 | if ((pos + len) >= baseString->currentStringLength) { 609 | len = -1; 610 | } 611 | 612 | if (len == -1) { 613 | baseString->currentStringLength = pos; 614 | } else { 615 | memmove(baseString->str + pos, baseString->str + pos + len, baseString->currentStringLength - pos - len); 616 | baseString->currentStringLength -= len; 617 | } 618 | 619 | baseString->str[baseString->currentStringLength] = '\0'; 620 | } 621 | } 622 | 623 | 624 | #ifdef TEST 625 | void Test_d_string_erase(CuTest* tc) { 626 | char * test = "foobar"; 627 | 628 | DString * result = d_string_new(test); 629 | 630 | d_string_erase(result, 2, 1); 631 | CuAssertStrEquals(tc, "fobar", result->str); 632 | CuAssertIntEquals(tc, 5, result->currentStringLength); 633 | 634 | d_string_erase(result, -1, -1); 635 | CuAssertStrEquals(tc, "fobar", result->str); 636 | CuAssertIntEquals(tc, 5, result->currentStringLength); 637 | 638 | d_string_erase(result, 2, -1); 639 | CuAssertStrEquals(tc, "fo", result->str); 640 | CuAssertIntEquals(tc, 2, result->currentStringLength); 641 | 642 | d_string_erase(NULL, 0, 0); 643 | 644 | d_string_free(result, true); 645 | } 646 | #endif 647 | 648 | 649 | /// Copy a portion of dynamic string 650 | char * d_string_copy_substring(DString * d, size_t start, size_t len) { 651 | if (d) { 652 | char * result; 653 | 654 | if (len == -1) { 655 | if (start <= d->currentStringLength) { 656 | len = d->currentStringLength - start; 657 | } else { 658 | len = 0; 659 | } 660 | } 661 | 662 | if (start + len > d->currentStringLength) { 663 | fprintf(stderr, "d_string: Asked to copy invalid substring range.\n"); 664 | fprintf(stderr, "start: %lu len: %lu string: %lu\n", start, len, 665 | d->currentStringLength); 666 | return NULL; 667 | } 668 | 669 | result = malloc(len + 1); 670 | strncpy(result, &d->str[start], len); 671 | result[len] = '\0'; 672 | 673 | return result; 674 | } else { 675 | return NULL; 676 | } 677 | } 678 | 679 | 680 | #ifdef TEST 681 | void Test_d_string_copy_substring(CuTest* tc) { 682 | char * test = "foobar"; 683 | 684 | DString * result = d_string_new(test); 685 | 686 | test = d_string_copy_substring(result, 0, -1); 687 | CuAssertStrEquals(tc, "foobar", test); 688 | free(test); 689 | 690 | test = d_string_copy_substring(result, 2, 3); 691 | CuAssertStrEquals(tc, "oba", test); 692 | free(test); 693 | 694 | test = d_string_copy_substring(result, 8, 2); 695 | CuAssertStrEquals(tc, NULL, test); 696 | free(test); 697 | 698 | test = d_string_copy_substring(result, -1, -1); 699 | CuAssertStrEquals(tc, NULL, test); 700 | free(test); 701 | 702 | test = d_string_copy_substring(NULL, -1, -1); 703 | CuAssertStrEquals(tc, NULL, test); 704 | 705 | d_string_free(result, true); 706 | } 707 | #endif 708 | 709 | 710 | /// Replace occurences of "original" with "replace" inside the specified range 711 | /// Returns the change in overall length 712 | long d_string_replace_text_in_range(DString * d, size_t pos, size_t len, const char * original, const char * replace) { 713 | if (d && original && replace) { 714 | long delta = 0; // Overall change in length 715 | 716 | long len_o = strlen(original); 717 | long len_r = strlen(replace); 718 | long change = len_r - len_o; // Change in length for each replacement 719 | 720 | size_t stop; 721 | 722 | if (len == -1) { 723 | stop = d->currentStringLength; 724 | } else { 725 | stop = pos + len; 726 | 727 | if (stop > d->currentStringLength) { 728 | stop = d->currentStringLength; 729 | } 730 | } 731 | 732 | char * match = strstr(&(d->str[pos]), original); 733 | 734 | while (match && (match - d->str < stop)) { 735 | pos = match - d->str; 736 | d_string_erase(d, match - d->str, len_o); 737 | d_string_insert(d, match - d->str, replace); 738 | 739 | delta += change; 740 | stop += change; 741 | match = strstr(d->str + pos + len_r, original); 742 | } 743 | 744 | return delta; 745 | } else { 746 | return 0; 747 | } 748 | } 749 | 750 | 751 | #ifdef TEST 752 | void Test_d_string_replace_text_in_range(CuTest* tc) { 753 | char * test = "foobarfoobarfoo"; 754 | long delta = 0; 755 | 756 | DString * result = d_string_new(test); 757 | 758 | delta = d_string_replace_text_in_range(result, 100, 3, "foo", "zapz"); 759 | CuAssertIntEquals(tc, 15, result->currentStringLength); 760 | CuAssertStrEquals(tc, "foobarfoobarfoo", result->str); 761 | CuAssertIntEquals(tc, delta, 0); 762 | 763 | delta = d_string_replace_text_in_range(result, 0, 3, "foo", "zapz"); 764 | CuAssertIntEquals(tc, 16, result->currentStringLength); 765 | CuAssertStrEquals(tc, "zapzbarfoobarfoo", result->str); 766 | CuAssertIntEquals(tc, delta, 1); 767 | 768 | delta = d_string_replace_text_in_range(result, 0, 100, "foo", "zapz"); 769 | CuAssertIntEquals(tc, 18, result->currentStringLength); 770 | CuAssertStrEquals(tc, "zapzbarzapzbarzapz", result->str); 771 | CuAssertIntEquals(tc, delta, 2); 772 | 773 | delta = d_string_replace_text_in_range(result, 0, -1, NULL, "zap"); 774 | CuAssertIntEquals(tc, 18, result->currentStringLength); 775 | CuAssertStrEquals(tc, "zapzbarzapzbarzapz", result->str); 776 | CuAssertIntEquals(tc, delta, 0); 777 | 778 | d_string_replace_text_in_range(result, 0, -1, "foo", NULL); 779 | CuAssertIntEquals(tc, 18, result->currentStringLength); 780 | CuAssertStrEquals(tc, "zapzbarzapzbarzapz", result->str); 781 | 782 | d_string_replace_text_in_range(NULL, 0, -1, "foo", NULL); 783 | 784 | d_string_free(result, true); 785 | } 786 | #endif 787 | 788 | -------------------------------------------------------------------------------- /src/d_string.h: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | Dynamic string -- Lightweight dynamic string implementation. 4 | 5 | @file d_string.h 6 | 7 | @brief Dynamic string -- refactoring of old GLibFacade from MultiMarkdown. 8 | Provides a string "object" that can grow to accomodate any size content 9 | that is appended. 10 | 11 | 12 | @author Daniel Jalkut, modified by Fletcher T. Penney and Dan Lowe 13 | 14 | @bug 15 | 16 | **/ 17 | 18 | /* 19 | 20 | Copyright © 2011 Daniel Jalkut. 21 | Modifications by Fletcher T. Penney, Copyright © 2011-2018 Fletcher T. Penney. 22 | Modifications by Dan Lowe, Copyright © 2011 Dan Lowe. 23 | 24 | 25 | The `MultiMarkdown 6` project is released under the MIT License.. 26 | 27 | GLibFacade.c and GLibFacade.h are from the MultiMarkdown v4 project: 28 | 29 | https://github.com/fletcher/MultiMarkdown-4/ 30 | 31 | MMD 4 is released under both the MIT License and GPL. 32 | 33 | 34 | CuTest is released under the zlib/libpng license. See CuTest.c for the text 35 | of the license. 36 | 37 | 38 | ## The MIT License ## 39 | 40 | Permission is hereby granted, free of charge, to any person obtaining a copy 41 | of this software and associated documentation files (the "Software"), to deal 42 | in the Software without restriction, including without limitation the rights 43 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 44 | copies of the Software, and to permit persons to whom the Software is 45 | furnished to do so, subject to the following conditions: 46 | 47 | The above copyright notice and this permission notice shall be included in 48 | all copies or substantial portions of the Software. 49 | 50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 52 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 53 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 54 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 55 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 56 | THE SOFTWARE. 57 | 58 | */ 59 | 60 | 61 | #ifndef D_STRING_SMART_STRING_H 62 | #define D_STRING_SMART_STRING_H 63 | 64 | #include 65 | #include 66 | 67 | /* WE implement minimal mirror implementations of GLib's GString 68 | * sufficient to cover the functionality required by MultiMarkdown. 69 | * 70 | * NOTE: THese are 100% clean, from-scratch implementations using only the 71 | * GLib function prototype as guide for behavior. 72 | */ 73 | 74 | 75 | /// Structure for dynamic string 76 | struct DString { 77 | char * str; //!< Pointer to UTF-8 byte stream for string 78 | unsigned long currentStringBufferSize; //!< Size of buffer currently allocated 79 | unsigned long currentStringLength; //!< Size of current string 80 | }; 81 | 82 | typedef struct DString DString; 83 | 84 | 85 | /// Create a new dynamic string 86 | DString * d_string_new( 87 | const char * startingString //!< Initial contents for string 88 | ); 89 | 90 | 91 | /// Free dynamic string 92 | char * d_string_free( 93 | DString * ripString, //!< DString to be freed 94 | bool freeCharacterData //!< Should the underlying str be freed as well? 95 | ); 96 | 97 | 98 | /// Append null-terminated string to end of dynamic string 99 | void d_string_append( 100 | DString * baseString, //!< DString to be appended 101 | const char * appendedString //!< String to be appended 102 | ); 103 | 104 | 105 | /// Append single character to end of dynamic string 106 | void d_string_append_c( 107 | DString * baseString, //!< DString to be appended 108 | char appendedCharacter //!< Character to append 109 | ); 110 | 111 | 112 | /// Append array of characters to end of dynamic string 113 | void d_string_append_c_array( 114 | DString * baseString, //!< DString to be appended 115 | const char * appendedChars, //!< String to be appended 116 | size_t bytes //!< Number of bytes to append 117 | ); 118 | 119 | 120 | /// Append to end of dynamic string using format specifier 121 | void d_string_append_printf( 122 | DString * baseString, //!< DString to be appended 123 | const char * format, //!< Format specifier for appending 124 | ... //!< Arguments for format specifier 125 | ); 126 | 127 | 128 | /// Prepend null-terminated string to end of dynamic string 129 | void d_string_prepend( 130 | DString * baseString, //!< DString to be appended 131 | const char * prependedString //!< String to be prepended 132 | ); 133 | 134 | 135 | /// Insert null-terminated string inside dynamic string 136 | void d_string_insert( 137 | DString * baseString, //!< DString to be appended 138 | size_t pos, //!< Offset at which to insert string 139 | const char * insertedString //!< String to be inserted 140 | ); 141 | 142 | 143 | /// Insert single character inside dynamic string 144 | void d_string_insert_c( 145 | DString * baseString, //!< DString to be appended 146 | size_t pos, //!< Offset at which to insert string 147 | char insertedCharacter //!< Character to insert 148 | ); 149 | 150 | 151 | /// Insert inside dynamic string using format specifier 152 | void d_string_insert_printf( 153 | DString * baseString, //!< DString to be appended 154 | size_t pos, //!< Offset at which to insert string 155 | const char * format, //!< Format specifier for appending 156 | ... //!< Arguments for format specifier 157 | ); 158 | 159 | 160 | /// Erase portion of dynamic string 161 | void d_string_erase( 162 | DString * baseString, //!< DString to be appended 163 | size_t pos, //!< Offset at which to erase portion of string 164 | size_t len //!< Character to append 165 | ); 166 | 167 | /// Copy a portion of dynamic string 168 | char * d_string_copy_substring( 169 | DString * d, //!< DString to copy 170 | size_t start, //!< Start position for copy 171 | size_t len //!< How many characters(bytes) to copy 172 | ); 173 | 174 | /// Replace occurences of "original" with "replace" inside the specified range 175 | /// Returns the change in overall length 176 | long d_string_replace_text_in_range( 177 | DString * d, 178 | size_t pos, 179 | size_t len, 180 | const char * original, 181 | const char * replace 182 | ); 183 | 184 | #endif 185 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | main.c -- Template main() 4 | 5 | Copyright © 2015-2016 Fletcher T. Penney. 6 | 7 | 8 | This program is free software you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation either version 2 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | #include "d_string.h" 28 | 29 | #define kBUFFERSIZE 4096 // How many bytes to read at a time 30 | 31 | DString * stdin_buffer() { 32 | /* Read from stdin and return a GString * 33 | `buffer` will need to be freed elsewhere */ 34 | 35 | char chunk[kBUFFERSIZE]; 36 | size_t bytes; 37 | 38 | DString * buffer = d_string_new(""); 39 | 40 | while ((bytes = fread(chunk, 1, kBUFFERSIZE, stdin)) > 0) { 41 | d_string_append_c_array(buffer, chunk, bytes); 42 | } 43 | 44 | fclose(stdin); 45 | 46 | return buffer; 47 | } 48 | 49 | DString * scan_file(char * fname) { 50 | /* Read from stdin and return a GString * 51 | `buffer` will need to be freed elsewhere */ 52 | 53 | char chunk[kBUFFERSIZE]; 54 | size_t bytes; 55 | 56 | FILE * file; 57 | 58 | if ((file = fopen(fname, "r")) == NULL ) { 59 | return NULL; 60 | } 61 | 62 | DString * buffer = d_string_new(""); 63 | 64 | while ((bytes = fread(chunk, 1, kBUFFERSIZE, file)) > 0) { 65 | d_string_append_c_array(buffer, chunk, bytes); 66 | } 67 | 68 | fclose(file); 69 | 70 | return buffer; 71 | } 72 | 73 | int main( int argc, char** argv ) { 74 | /* Make your program do whatever you want */ 75 | } 76 | -------------------------------------------------------------------------------- /templates/README.md.in: -------------------------------------------------------------------------------- 1 | ## About ## 2 | 3 | | | | 4 | | ---------- | ------------------------- | 5 | | Title: | @My_Project_Title@ | 6 | | Author: | @My_Project_Author@ | 7 | | Date: | @My_Project_Revised_Date@ | 8 | | Copyright: | @My_Project_Copyright@ | 9 | | Version: | @My_Project_Version@ | 10 | 11 | 12 | ## Introduction ## 13 | 14 | This template was created out of a desire to simplify some of the setup and 15 | configuration that I was doing over and over each time I started a new project. 16 | Additionally, I wanted to try to start encouraging some "better practices" 17 | (though not necessarily "best practices"): 18 | 19 | 1. [Test-driven development][tdd] -- My development of MultiMarkdown 20 | focused on integration testing, but really had no unit testing to 21 | speak of. Some newer projects I began working on were a bit math- 22 | heavy, and ensuring that each piece works properly became even more 23 | important. It was also nice to be able to actually develop code that 24 | could do *something* (via the test suite), even though the project as 25 | a whole was nowhere near complete.) To accomplish this, I include the 26 | [CuTest] project to support writing tests for your code. 27 | 28 | 2. Use of the [cmake] build system. `cmake` is not perfect by any 29 | means, but it does offer some very useful features and a means for 30 | better integrating the compilation and packaging/installation aspects 31 | of development. Rather than reinventing the wheel each time, this 32 | setup incorporates basic `cmake` functionality to make it easy to 33 | control how your project is compiled, and includes automated generation 34 | of the test command. 35 | 36 | 3. Templates -- `cmake` has a reasonable templating system, so that you 37 | can define basic variables (e.g. author, project name, etc.) and allow 38 | `cmake` to combine those elements to ensure consistency across source 39 | code and README files. 40 | 41 | 4. Documentation -- some default setup to allow for [Doxygen]-generated 42 | documentation. The generated `README.md` file is used as the main 43 | page, and the source c/header files are included. Naturally, Doxygen 44 | is a complex system, so you're responsible for figuring out how to 45 | properly document your code. 46 | 47 | 5. Simplify `git` a touch -- In my larger projects, I make heavy use of 48 | git modules. One project may make use of 20-30 modules, which are 49 | designed to be re-usable across other projects. I found that I was 50 | spending too much time making sure that I had the latest version 51 | of a module checked out, so I created two scripts to help me keep 52 | my modules in line: `link_git_modules` and `update_git_modules`. 53 | You run the `link` script once to ensure that your modules are properly 54 | set up, and can then run the `update` script at any time to be sure 55 | you've pulled the latest version. One advantage of this is that your 56 | modules are set to a branch, rather than just a detached commit. It 57 | may or may not work for your needs, but it saves me a bunch of time 58 | and headache. 59 | 60 | 61 | [tdd]: https://en.wikipedia.org/wiki/Test-driven_development 62 | [cmake]: http://www.cmake.org/ 63 | [CuTest]: http://cutest.sourceforge.net 64 | [Doxygen]: http://www.stack.nl/~dimitri/doxygen/ 65 | 66 | 67 | ## How do I use it? ## 68 | 69 | You can download the source from [github] and get to work. The file "IMPORTANT" 70 | contains instructions on the various build commands you can use. 71 | 72 | 73 | I recommend using the following script to automatically create a new git repo, 74 | pull in the default project template, and configure git-flow. You simply have 75 | to rename your project directory from `new-project` to whatever you desire: 76 | 77 | 78 | #!/bin/sh 79 | 80 | git init new-project 81 | 82 | cd new-project 83 | 84 | git remote add "template" https://github.com/fletcher/c-template.git 85 | 86 | git pull template master 87 | 88 | git flow init -d 89 | 90 | git checkout develop 91 | 92 | 93 | Using this approach, you can define your own `origin` remote if you like, but 94 | the `template` remote can be used to update the core project files should any 95 | improvements come about: 96 | 97 | git checkout develop 98 | git merge template master 99 | 100 | **NOTE**: `cmake` is a complex suite of utilities, and if you have trouble you 101 | will need to get support elsewhere. If you find errors in this template, by 102 | all means I want to hear about them and fix them, but this is just a basic 103 | framework to get you started. In all likelihood, all but the most basic 104 | projects will need some customization. 105 | 106 | 107 | [github]: https://github.com/fletcher/c-template 108 | 109 | 110 | ## Configuration ## 111 | 112 | 113 | ### CMakeLists.txt File ### 114 | 115 | First, you should update the project information under the "Define Our Project" 116 | section, including the title, description, etc. This information will be used 117 | to update the README, as well as to create the `version.h` file so that the 118 | project can have access to its own version number. 119 | 120 | You will then need to update the various groups in the "Source Files" section 121 | so that Cmake will be able to determine which files are used to build your 122 | project. For reasons that will become clear later, try to follow the 123 | suggestions for the different groups of files. 124 | 125 | You then need to define your targets, such as a library, or executable, etc. 126 | Obviously, this will depend on the needs of your project. You can also add 127 | custom steps based on the Target OS (OS X, Windows, *nix, etc.). 128 | 129 | You can use CPack to generate installers for your software. This can be 130 | complex, and you will need to modify this section heavily. 131 | 132 | CuTest is used by default to provide unit testing (see below), but you 133 | can also use CMake/CTest to provide integration testing. Again, this will 134 | be up to you to configure. 135 | 136 | 137 | ### CuTest ### 138 | 139 | [CuTest] provides a means to integrate unit testing with your C source code. 140 | Once you get the hang of it, it's easy to use. 141 | 142 | 143 | ### Doxygen ### 144 | 145 | [Doxygen] is used to generate documentation from the source code itself. 146 | Properly configuring your source for this is up to you. You can modify the 147 | `doxygen.conf.in` template with your desired settings as desired, but most 148 | of the basics are handled for you based on your CMake configuration. 149 | 150 | 151 | ### GitHub Pages Support ### 152 | 153 | The `configure-gh-pages` script sets up a `documentation` directory that is 154 | linked to a `gh-pages` branch of the project. You can then run `make gh-pages` 155 | to update the documentation in this directory. Commit and push to your origin, 156 | and your projects gh-page is updated. 157 | 158 | 159 | ### Makefile ### 160 | 161 | The overall build process is controlled by the master `Makefile`. It provides 162 | the following commands: 163 | 164 | make 165 | make release 166 | 167 | Generate the CMake build files for use or distribution. Once complete you will 168 | need to change to the `build` directory and run `make`, `make test`, and 169 | `cpack` as desired. 170 | 171 | make zip 172 | 173 | Direct CPack to create a zip installer rather than a graphical installer. 174 | 175 | make debug 176 | 177 | Generate build files for [CuTest] unit testing. In the `build` directory, 178 | run `make`, then `make test`. 179 | 180 | make analyze 181 | 182 | If you have `clang` installed, this will generate debug build files with the 183 | `scan-build` command. In the `build` directory, run `scan-build -V make` 184 | to compile the software and view the static analysis results. 185 | 186 | make xcode 187 | 188 | Build a project file for Xcode on OS X. 189 | 190 | make windows 191 | make windows-zip 192 | make windows-32 193 | make windows-zip-32 194 | 195 | Use the MinGW software to cross-compile for Windows on a *nix machine. You can 196 | specify the 32 bit option, and also the zip option as indicated. 197 | 198 | make documentation 199 | 200 | Build the [Doxygen]-generated documentation. 201 | 202 | make clean 203 | 204 | Clean out the `build` directory. Be sure to run this before running another 205 | command. 206 | 207 | 208 | ## Git Submodules ## 209 | 210 | Apparently, submodules are a rather controversial feature in git. For me, 211 | however, they have proven invaluable. My most active projects depend on each 212 | other, and the submodule feature allows me to easily keep everything up to 213 | date. That said, however, I quickly realized that submodules don't work very 214 | well using default commands. 215 | 216 | The problem is that I want to always use the latest version of my submodules. 217 | This is more easily accomplished when the submodule is set to the `master` 218 | branch of the original repository, rather than a detached commit as happens 219 | by default. In order to easily keep all submodules updated, there are two 220 | scripts: 221 | 222 | 1. `link_git_modules` -- this script is generally only run when the master 223 | repository is first cloned, but can also be run after a new submodule is 224 | added. It causes the submodules to automatically track the master branch. 225 | If you need to modify this, there are instructions in the script itself 226 | explaining how to modify it on a per submodule basis. Running this script 227 | more than one time will not hurt anything. 228 | 229 | 2. `update_git_modules` -- this script simply causes each submodule to be 230 | updated to the latest commit in the original repository. Again, running it 231 | multiple times doesn't hurt anything. 232 | 233 | 234 | ## Source File Templates ## 235 | 236 | In the `templates` directory are two files, `template.c.in` and 237 | `template.h.in`. These are used to create default source files that include 238 | the project title, copyright, license, etc. They are also set up to include 239 | some example information for [Doxygen] and [CuTest]. 240 | 241 | 242 | ## License ## 243 | 244 | @My_Project_License@ 245 | -------------------------------------------------------------------------------- /templates/doxygen.conf.in: -------------------------------------------------------------------------------- 1 | # Doxyfile 1.8.4 2 | 3 | # This file describes the settings to be used by the documentation system 4 | # doxygen (www.doxygen.org) for a project. 5 | # 6 | # All text after a double hash (##) is considered a comment and is placed 7 | # in front of the TAG it is preceding . 8 | # All text after a hash (#) is considered a comment and will be ignored. 9 | # The format is: 10 | # TAG = value [value, ...] 11 | # For lists items can also be appended using: 12 | # TAG += value [value, ...] 13 | # Values that contain spaces should be placed between quotes (" "). 14 | 15 | #--------------------------------------------------------------------------- 16 | # Project related configuration options 17 | #--------------------------------------------------------------------------- 18 | 19 | # This tag specifies the encoding used for all characters in the config file 20 | # that follow. The default is UTF-8 which is also the encoding used for all 21 | # text before the first occurrence of this tag. Doxygen uses libiconv (or the 22 | # iconv built into libc) for the transcoding. See 23 | # http://www.gnu.org/software/libiconv for the list of possible encodings. 24 | 25 | DOXYFILE_ENCODING = UTF-8 26 | 27 | # The PROJECT_NAME tag is a single word (or sequence of words) that should 28 | # identify the project. Note that if you do not use Doxywizard you need 29 | # to put quotes around the project name if it contains spaces. 30 | 31 | PROJECT_NAME = "@My_Project_Title@" 32 | 33 | # The PROJECT_NUMBER tag can be used to enter a project or revision number. 34 | # This could be handy for archiving the generated documentation or 35 | # if some version control system is used. 36 | 37 | PROJECT_NUMBER = @My_Project_Version@ 38 | 39 | # Using the PROJECT_BRIEF tag one can provide an optional one line description 40 | # for a project that appears at the top of each page and should give viewer 41 | # a quick idea about the purpose of the project. Keep the description short. 42 | 43 | PROJECT_BRIEF = "@My_Project_Description@" 44 | 45 | # With the PROJECT_LOGO tag one can specify an logo or icon that is 46 | # included in the documentation. The maximum height of the logo should not 47 | # exceed 55 pixels and the maximum width should not exceed 200 pixels. 48 | # Doxygen will copy the logo to the output directory. 49 | 50 | PROJECT_LOGO = 51 | 52 | # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 53 | # base path where the generated documentation will be put. 54 | # If a relative path is entered, it will be relative to the location 55 | # where doxygen was started. If left blank the current directory will be used. 56 | 57 | OUTPUT_DIRECTORY = "@PROJECT_BINARY_DIR@/documentation" 58 | 59 | # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 60 | # 4096 sub-directories (in 2 levels) under the output directory of each output 61 | # format and will distribute the generated files over these directories. 62 | # Enabling this option can be useful when feeding doxygen a huge amount of 63 | # source files, where putting all generated files in the same directory would 64 | # otherwise cause performance problems for the file system. 65 | 66 | CREATE_SUBDIRS = NO 67 | 68 | # The OUTPUT_LANGUAGE tag is used to specify the language in which all 69 | # documentation generated by doxygen is written. Doxygen will use this 70 | # information to generate all constant output in the proper language. 71 | # The default language is English, other supported languages are: 72 | # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 73 | # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 74 | # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 75 | # messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, 76 | # Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, 77 | # Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. 78 | 79 | OUTPUT_LANGUAGE = English 80 | 81 | # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 82 | # include brief member descriptions after the members that are listed in 83 | # the file and class documentation (similar to JavaDoc). 84 | # Set to NO to disable this. 85 | 86 | BRIEF_MEMBER_DESC = YES 87 | 88 | # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 89 | # the brief description of a member or function before the detailed description. 90 | # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 91 | # brief descriptions will be completely suppressed. 92 | 93 | REPEAT_BRIEF = YES 94 | 95 | # This tag implements a quasi-intelligent brief description abbreviator 96 | # that is used to form the text in various listings. Each string 97 | # in this list, if found as the leading text of the brief description, will be 98 | # stripped from the text and the result after processing the whole list, is 99 | # used as the annotated text. Otherwise, the brief description is used as-is. 100 | # If left blank, the following values are used ("$name" is automatically 101 | # replaced with the name of the entity): "The $name class" "The $name widget" 102 | # "The $name file" "is" "provides" "specifies" "contains" 103 | # "represents" "a" "an" "the" 104 | 105 | ABBREVIATE_BRIEF = 106 | 107 | # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 108 | # Doxygen will generate a detailed section even if there is only a brief 109 | # description. 110 | 111 | ALWAYS_DETAILED_SEC = NO 112 | 113 | # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 114 | # inherited members of a class in the documentation of that class as if those 115 | # members were ordinary class members. Constructors, destructors and assignment 116 | # operators of the base classes will not be shown. 117 | 118 | INLINE_INHERITED_MEMB = NO 119 | 120 | # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 121 | # path before files name in the file list and in the header files. If set 122 | # to NO the shortest path that makes the file name unique will be used. 123 | 124 | FULL_PATH_NAMES = YES 125 | 126 | # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 127 | # can be used to strip a user-defined part of the path. Stripping is 128 | # only done if one of the specified strings matches the left-hand part of 129 | # the path. The tag can be used to show relative paths in the file list. 130 | # If left blank the directory from which doxygen is run is used as the 131 | # path to strip. Note that you specify absolute paths here, but also 132 | # relative paths, which will be relative from the directory where doxygen is 133 | # started. 134 | 135 | STRIP_FROM_PATH = 136 | 137 | # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 138 | # the path mentioned in the documentation of a class, which tells 139 | # the reader which header file to include in order to use a class. 140 | # If left blank only the name of the header file containing the class 141 | # definition is used. Otherwise one should specify the include paths that 142 | # are normally passed to the compiler using the -I flag. 143 | 144 | STRIP_FROM_INC_PATH = 145 | 146 | # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 147 | # (but less readable) file names. This can be useful if your file system 148 | # doesn't support long names like on DOS, Mac, or CD-ROM. 149 | 150 | SHORT_NAMES = NO 151 | 152 | # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 153 | # will interpret the first line (until the first dot) of a JavaDoc-style 154 | # comment as the brief description. If set to NO, the JavaDoc 155 | # comments will behave just like regular Qt-style comments 156 | # (thus requiring an explicit @brief command for a brief description.) 157 | 158 | JAVADOC_AUTOBRIEF = NO 159 | 160 | # If the QT_AUTOBRIEF tag is set to YES then Doxygen will 161 | # interpret the first line (until the first dot) of a Qt-style 162 | # comment as the brief description. If set to NO, the comments 163 | # will behave just like regular Qt-style comments (thus requiring 164 | # an explicit \brief command for a brief description.) 165 | 166 | QT_AUTOBRIEF = NO 167 | 168 | # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 169 | # treat a multi-line C++ special comment block (i.e. a block of //! or /// 170 | # comments) as a brief description. This used to be the default behaviour. 171 | # The new default is to treat a multi-line C++ comment block as a detailed 172 | # description. Set this tag to YES if you prefer the old behaviour instead. 173 | 174 | MULTILINE_CPP_IS_BRIEF = NO 175 | 176 | # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 177 | # member inherits the documentation from any documented member that it 178 | # re-implements. 179 | 180 | INHERIT_DOCS = YES 181 | 182 | # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 183 | # a new page for each member. If set to NO, the documentation of a member will 184 | # be part of the file/class/namespace that contains it. 185 | 186 | SEPARATE_MEMBER_PAGES = NO 187 | 188 | # The TAB_SIZE tag can be used to set the number of spaces in a tab. 189 | # Doxygen uses this value to replace tabs by spaces in code fragments. 190 | 191 | TAB_SIZE = 4 192 | 193 | # This tag can be used to specify a number of aliases that acts 194 | # as commands in the documentation. An alias has the form "name=value". 195 | # For example adding "sideeffect=\par Side Effects:\n" will allow you to 196 | # put the command \sideeffect (or @sideeffect) in the documentation, which 197 | # will result in a user-defined paragraph with heading "Side Effects:". 198 | # You can put \n's in the value part of an alias to insert newlines. 199 | 200 | ALIASES = 201 | 202 | # This tag can be used to specify a number of word-keyword mappings (TCL only). 203 | # A mapping has the form "name=value". For example adding 204 | # "class=itcl::class" will allow you to use the command class in the 205 | # itcl::class meaning. 206 | 207 | TCL_SUBST = 208 | 209 | # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 210 | # sources only. Doxygen will then generate output that is more tailored for C. 211 | # For instance, some of the names that are used will be different. The list 212 | # of all members will be omitted, etc. 213 | 214 | OPTIMIZE_OUTPUT_FOR_C = NO 215 | 216 | # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 217 | # sources only. Doxygen will then generate output that is more tailored for 218 | # Java. For instance, namespaces will be presented as packages, qualified 219 | # scopes will look different, etc. 220 | 221 | OPTIMIZE_OUTPUT_JAVA = NO 222 | 223 | # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 224 | # sources only. Doxygen will then generate output that is more tailored for 225 | # Fortran. 226 | 227 | OPTIMIZE_FOR_FORTRAN = NO 228 | 229 | # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 230 | # sources. Doxygen will then generate output that is tailored for 231 | # VHDL. 232 | 233 | OPTIMIZE_OUTPUT_VHDL = NO 234 | 235 | # Doxygen selects the parser to use depending on the extension of the files it 236 | # parses. With this tag you can assign which parser to use for a given 237 | # extension. Doxygen has a built-in mapping, but you can override or extend it 238 | # using this tag. The format is ext=language, where ext is a file extension, 239 | # and language is one of the parsers supported by doxygen: IDL, Java, 240 | # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, 241 | # C++. For instance to make doxygen treat .inc files as Fortran files (default 242 | # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note 243 | # that for custom extensions you also need to set FILE_PATTERNS otherwise the 244 | # files are not read by doxygen. 245 | 246 | EXTENSION_MAPPING = 247 | 248 | # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all 249 | # comments according to the Markdown format, which allows for more readable 250 | # documentation. See http://daringfireball.net/projects/markdown/ for details. 251 | # The output of markdown processing is further processed by doxygen, so you 252 | # can mix doxygen, HTML, and XML commands with Markdown formatting. 253 | # Disable only in case of backward compatibilities issues. 254 | 255 | MARKDOWN_SUPPORT = YES 256 | 257 | # When enabled doxygen tries to link words that correspond to documented 258 | # classes, or namespaces to their corresponding documentation. Such a link can 259 | # be prevented in individual cases by by putting a % sign in front of the word 260 | # or globally by setting AUTOLINK_SUPPORT to NO. 261 | 262 | AUTOLINK_SUPPORT = YES 263 | 264 | # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 265 | # to include (a tag file for) the STL sources as input, then you should 266 | # set this tag to YES in order to let doxygen match functions declarations and 267 | # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 268 | # func(std::string) {}). This also makes the inheritance and collaboration 269 | # diagrams that involve STL classes more complete and accurate. 270 | 271 | BUILTIN_STL_SUPPORT = NO 272 | 273 | # If you use Microsoft's C++/CLI language, you should set this option to YES to 274 | # enable parsing support. 275 | 276 | CPP_CLI_SUPPORT = NO 277 | 278 | # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 279 | # Doxygen will parse them like normal C++ but will assume all classes use public 280 | # instead of private inheritance when no explicit protection keyword is present. 281 | 282 | SIP_SUPPORT = NO 283 | 284 | # For Microsoft's IDL there are propget and propput attributes to indicate 285 | # getter and setter methods for a property. Setting this option to YES (the 286 | # default) will make doxygen replace the get and set methods by a property in 287 | # the documentation. This will only work if the methods are indeed getting or 288 | # setting a simple type. If this is not the case, or you want to show the 289 | # methods anyway, you should set this option to NO. 290 | 291 | IDL_PROPERTY_SUPPORT = YES 292 | 293 | # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 294 | # tag is set to YES, then doxygen will reuse the documentation of the first 295 | # member in the group (if any) for the other members of the group. By default 296 | # all members of a group must be documented explicitly. 297 | 298 | DISTRIBUTE_GROUP_DOC = NO 299 | 300 | # Set the SUBGROUPING tag to YES (the default) to allow class member groups of 301 | # the same type (for instance a group of public functions) to be put as a 302 | # subgroup of that type (e.g. under the Public Functions section). Set it to 303 | # NO to prevent subgrouping. Alternatively, this can be done per class using 304 | # the \nosubgrouping command. 305 | 306 | SUBGROUPING = YES 307 | 308 | # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 309 | # unions are shown inside the group in which they are included (e.g. using 310 | # @ingroup) instead of on a separate page (for HTML and Man pages) or 311 | # section (for LaTeX and RTF). 312 | 313 | INLINE_GROUPED_CLASSES = NO 314 | 315 | # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 316 | # unions with only public data fields or simple typedef fields will be shown 317 | # inline in the documentation of the scope in which they are defined (i.e. file, 318 | # namespace, or group documentation), provided this scope is documented. If set 319 | # to NO (the default), structs, classes, and unions are shown on a separate 320 | # page (for HTML and Man pages) or section (for LaTeX and RTF). 321 | 322 | INLINE_SIMPLE_STRUCTS = NO 323 | 324 | # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 325 | # is documented as struct, union, or enum with the name of the typedef. So 326 | # typedef struct TypeS {} TypeT, will appear in the documentation as a struct 327 | # with name TypeT. When disabled the typedef will appear as a member of a file, 328 | # namespace, or class. And the struct will be named TypeS. This can typically 329 | # be useful for C code in case the coding convention dictates that all compound 330 | # types are typedef'ed and only the typedef is referenced, never the tag name. 331 | 332 | TYPEDEF_HIDES_STRUCT = NO 333 | 334 | # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This 335 | # cache is used to resolve symbols given their name and scope. Since this can 336 | # be an expensive process and often the same symbol appear multiple times in 337 | # the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too 338 | # small doxygen will become slower. If the cache is too large, memory is wasted. 339 | # The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid 340 | # range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 341 | # symbols. 342 | 343 | LOOKUP_CACHE_SIZE = 0 344 | 345 | #--------------------------------------------------------------------------- 346 | # Build related configuration options 347 | #--------------------------------------------------------------------------- 348 | 349 | # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 350 | # documentation are documented, even if no documentation was available. 351 | # Private class members and static file members will be hidden unless 352 | # the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES 353 | 354 | EXTRACT_ALL = NO 355 | 356 | # If the EXTRACT_PRIVATE tag is set to YES all private members of a class 357 | # will be included in the documentation. 358 | 359 | EXTRACT_PRIVATE = NO 360 | 361 | # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal 362 | # scope will be included in the documentation. 363 | 364 | EXTRACT_PACKAGE = NO 365 | 366 | # If the EXTRACT_STATIC tag is set to YES all static members of a file 367 | # will be included in the documentation. 368 | 369 | EXTRACT_STATIC = NO 370 | 371 | # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 372 | # defined locally in source files will be included in the documentation. 373 | # If set to NO only classes defined in header files are included. 374 | 375 | EXTRACT_LOCAL_CLASSES = YES 376 | 377 | # This flag is only useful for Objective-C code. When set to YES local 378 | # methods, which are defined in the implementation section but not in 379 | # the interface are included in the documentation. 380 | # If set to NO (the default) only methods in the interface are included. 381 | 382 | EXTRACT_LOCAL_METHODS = NO 383 | 384 | # If this flag is set to YES, the members of anonymous namespaces will be 385 | # extracted and appear in the documentation as a namespace called 386 | # 'anonymous_namespace{file}', where file will be replaced with the base 387 | # name of the file that contains the anonymous namespace. By default 388 | # anonymous namespaces are hidden. 389 | 390 | EXTRACT_ANON_NSPACES = NO 391 | 392 | # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 393 | # undocumented members of documented classes, files or namespaces. 394 | # If set to NO (the default) these members will be included in the 395 | # various overviews, but no documentation section is generated. 396 | # This option has no effect if EXTRACT_ALL is enabled. 397 | 398 | HIDE_UNDOC_MEMBERS = NO 399 | 400 | # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 401 | # undocumented classes that are normally visible in the class hierarchy. 402 | # If set to NO (the default) these classes will be included in the various 403 | # overviews. This option has no effect if EXTRACT_ALL is enabled. 404 | 405 | HIDE_UNDOC_CLASSES = NO 406 | 407 | # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 408 | # friend (class|struct|union) declarations. 409 | # If set to NO (the default) these declarations will be included in the 410 | # documentation. 411 | 412 | HIDE_FRIEND_COMPOUNDS = NO 413 | 414 | # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 415 | # documentation blocks found inside the body of a function. 416 | # If set to NO (the default) these blocks will be appended to the 417 | # function's detailed documentation block. 418 | 419 | HIDE_IN_BODY_DOCS = NO 420 | 421 | # The INTERNAL_DOCS tag determines if documentation 422 | # that is typed after a \internal command is included. If the tag is set 423 | # to NO (the default) then the documentation will be excluded. 424 | # Set it to YES to include the internal documentation. 425 | 426 | INTERNAL_DOCS = NO 427 | 428 | # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 429 | # file names in lower-case letters. If set to YES upper-case letters are also 430 | # allowed. This is useful if you have classes or files whose names only differ 431 | # in case and if your file system supports case sensitive file names. Windows 432 | # and Mac users are advised to set this option to NO. 433 | 434 | CASE_SENSE_NAMES = NO 435 | 436 | # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 437 | # will show members with their full class and namespace scopes in the 438 | # documentation. If set to YES the scope will be hidden. 439 | 440 | HIDE_SCOPE_NAMES = NO 441 | 442 | # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 443 | # will put a list of the files that are included by a file in the documentation 444 | # of that file. 445 | 446 | SHOW_INCLUDE_FILES = YES 447 | 448 | # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 449 | # will list include files with double quotes in the documentation 450 | # rather than with sharp brackets. 451 | 452 | FORCE_LOCAL_INCLUDES = NO 453 | 454 | # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 455 | # is inserted in the documentation for inline members. 456 | 457 | INLINE_INFO = YES 458 | 459 | # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 460 | # will sort the (detailed) documentation of file and class members 461 | # alphabetically by member name. If set to NO the members will appear in 462 | # declaration order. 463 | 464 | SORT_MEMBER_DOCS = YES 465 | 466 | # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 467 | # brief documentation of file, namespace and class members alphabetically 468 | # by member name. If set to NO (the default) the members will appear in 469 | # declaration order. 470 | 471 | SORT_BRIEF_DOCS = NO 472 | 473 | # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 474 | # will sort the (brief and detailed) documentation of class members so that 475 | # constructors and destructors are listed first. If set to NO (the default) 476 | # the constructors will appear in the respective orders defined by 477 | # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 478 | # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 479 | # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. 480 | 481 | SORT_MEMBERS_CTORS_1ST = NO 482 | 483 | # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 484 | # hierarchy of group names into alphabetical order. If set to NO (the default) 485 | # the group names will appear in their defined order. 486 | 487 | SORT_GROUP_NAMES = NO 488 | 489 | # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 490 | # sorted by fully-qualified names, including namespaces. If set to 491 | # NO (the default), the class list will be sorted only by class name, 492 | # not including the namespace part. 493 | # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 494 | # Note: This option applies only to the class list, not to the 495 | # alphabetical list. 496 | 497 | SORT_BY_SCOPE_NAME = NO 498 | 499 | # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 500 | # do proper type resolution of all parameters of a function it will reject a 501 | # match between the prototype and the implementation of a member function even 502 | # if there is only one candidate or it is obvious which candidate to choose 503 | # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 504 | # will still accept a match between prototype and implementation in such cases. 505 | 506 | STRICT_PROTO_MATCHING = NO 507 | 508 | # The GENERATE_TODOLIST tag can be used to enable (YES) or 509 | # disable (NO) the todo list. This list is created by putting \todo 510 | # commands in the documentation. 511 | 512 | GENERATE_TODOLIST = YES 513 | 514 | # The GENERATE_TESTLIST tag can be used to enable (YES) or 515 | # disable (NO) the test list. This list is created by putting \test 516 | # commands in the documentation. 517 | 518 | GENERATE_TESTLIST = YES 519 | 520 | # The GENERATE_BUGLIST tag can be used to enable (YES) or 521 | # disable (NO) the bug list. This list is created by putting \bug 522 | # commands in the documentation. 523 | 524 | GENERATE_BUGLIST = YES 525 | 526 | # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 527 | # disable (NO) the deprecated list. This list is created by putting 528 | # \deprecated commands in the documentation. 529 | 530 | GENERATE_DEPRECATEDLIST= YES 531 | 532 | # The ENABLED_SECTIONS tag can be used to enable conditional 533 | # documentation sections, marked by \if section-label ... \endif 534 | # and \cond section-label ... \endcond blocks. 535 | 536 | ENABLED_SECTIONS = 537 | 538 | # The MAX_INITIALIZER_LINES tag determines the maximum number of lines 539 | # the initial value of a variable or macro consists of for it to appear in 540 | # the documentation. If the initializer consists of more lines than specified 541 | # here it will be hidden. Use a value of 0 to hide initializers completely. 542 | # The appearance of the initializer of individual variables and macros in the 543 | # documentation can be controlled using \showinitializer or \hideinitializer 544 | # command in the documentation regardless of this setting. 545 | 546 | MAX_INITIALIZER_LINES = 30 547 | 548 | # Set the SHOW_USED_FILES tag to NO to disable the list of files generated 549 | # at the bottom of the documentation of classes and structs. If set to YES the 550 | # list will mention the files that were used to generate the documentation. 551 | 552 | SHOW_USED_FILES = YES 553 | 554 | # Set the SHOW_FILES tag to NO to disable the generation of the Files page. 555 | # This will remove the Files entry from the Quick Index and from the 556 | # Folder Tree View (if specified). The default is YES. 557 | 558 | SHOW_FILES = YES 559 | 560 | # Set the SHOW_NAMESPACES tag to NO to disable the generation of the 561 | # Namespaces page. 562 | # This will remove the Namespaces entry from the Quick Index 563 | # and from the Folder Tree View (if specified). The default is YES. 564 | 565 | SHOW_NAMESPACES = YES 566 | 567 | # The FILE_VERSION_FILTER tag can be used to specify a program or script that 568 | # doxygen should invoke to get the current version for each file (typically from 569 | # the version control system). Doxygen will invoke the program by executing (via 570 | # popen()) the command , where is the value of 571 | # the FILE_VERSION_FILTER tag, and is the name of an input file 572 | # provided by doxygen. Whatever the program writes to standard output 573 | # is used as the file version. See the manual for examples. 574 | 575 | FILE_VERSION_FILTER = 576 | 577 | # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 578 | # by doxygen. The layout file controls the global structure of the generated 579 | # output files in an output format independent way. To create the layout file 580 | # that represents doxygen's defaults, run doxygen with the -l option. 581 | # You can optionally specify a file name after the option, if omitted 582 | # DoxygenLayout.xml will be used as the name of the layout file. 583 | 584 | LAYOUT_FILE = 585 | 586 | # The CITE_BIB_FILES tag can be used to specify one or more bib files 587 | # containing the references data. This must be a list of .bib files. The 588 | # .bib extension is automatically appended if omitted. Using this command 589 | # requires the bibtex tool to be installed. See also 590 | # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 591 | # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 592 | # feature you need bibtex and perl available in the search path. Do not use 593 | # file names with spaces, bibtex cannot handle them. 594 | 595 | CITE_BIB_FILES = 596 | 597 | #--------------------------------------------------------------------------- 598 | # configuration options related to warning and progress messages 599 | #--------------------------------------------------------------------------- 600 | 601 | # The QUIET tag can be used to turn on/off the messages that are generated 602 | # by doxygen. Possible values are YES and NO. If left blank NO is used. 603 | 604 | QUIET = NO 605 | 606 | # The WARNINGS tag can be used to turn on/off the warning messages that are 607 | # generated by doxygen. Possible values are YES and NO. If left blank 608 | # NO is used. 609 | 610 | WARNINGS = YES 611 | 612 | # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 613 | # for undocumented members. If EXTRACT_ALL is set to YES then this flag will 614 | # automatically be disabled. 615 | 616 | WARN_IF_UNDOCUMENTED = YES 617 | 618 | # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 619 | # potential errors in the documentation, such as not documenting some 620 | # parameters in a documented function, or documenting parameters that 621 | # don't exist or using markup commands wrongly. 622 | 623 | WARN_IF_DOC_ERROR = YES 624 | 625 | # The WARN_NO_PARAMDOC option can be enabled to get warnings for 626 | # functions that are documented, but have no documentation for their parameters 627 | # or return value. If set to NO (the default) doxygen will only warn about 628 | # wrong or incomplete parameter documentation, but not about the absence of 629 | # documentation. 630 | 631 | WARN_NO_PARAMDOC = NO 632 | 633 | # The WARN_FORMAT tag determines the format of the warning messages that 634 | # doxygen can produce. The string should contain the $file, $line, and $text 635 | # tags, which will be replaced by the file and line number from which the 636 | # warning originated and the warning text. Optionally the format may contain 637 | # $version, which will be replaced by the version of the file (if it could 638 | # be obtained via FILE_VERSION_FILTER) 639 | 640 | WARN_FORMAT = "$file:$line: $text" 641 | 642 | # The WARN_LOGFILE tag can be used to specify a file to which warning 643 | # and error messages should be written. If left blank the output is written 644 | # to stderr. 645 | 646 | WARN_LOGFILE = 647 | 648 | #--------------------------------------------------------------------------- 649 | # configuration options related to the input files 650 | #--------------------------------------------------------------------------- 651 | 652 | # The INPUT tag can be used to specify the files and/or directories that contain 653 | # documented source files. You may enter file names like "myfile.cpp" or 654 | # directories like "/usr/src/myproject". Separate the files or directories 655 | # with spaces. 656 | 657 | INPUT = "@CMAKE_CURRENT_LIST_DIR@/README.md" @doxygen_src_files@ @doxygen_header_files@ 658 | 659 | # This tag can be used to specify the character encoding of the source files 660 | # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 661 | # also the default input encoding. Doxygen uses libiconv (or the iconv built 662 | # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 663 | # the list of possible encodings. 664 | 665 | INPUT_ENCODING = UTF-8 666 | 667 | # If the value of the INPUT tag contains directories, you can use the 668 | # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 669 | # and *.h) to filter out the source-files in the directories. If left 670 | # blank the following patterns are tested: 671 | # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 672 | # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 673 | # *.f90 *.f *.for *.vhd *.vhdl 674 | 675 | FILE_PATTERNS = 676 | 677 | # The RECURSIVE tag can be used to turn specify whether or not subdirectories 678 | # should be searched for input files as well. Possible values are YES and NO. 679 | # If left blank NO is used. 680 | 681 | RECURSIVE = NO 682 | 683 | # The EXCLUDE tag can be used to specify files and/or directories that should be 684 | # excluded from the INPUT source files. This way you can easily exclude a 685 | # subdirectory from a directory tree whose root is specified with the INPUT tag. 686 | # Note that relative paths are relative to the directory from which doxygen is 687 | # run. 688 | 689 | EXCLUDE = 690 | 691 | # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 692 | # directories that are symbolic links (a Unix file system feature) are excluded 693 | # from the input. 694 | 695 | EXCLUDE_SYMLINKS = NO 696 | 697 | # If the value of the INPUT tag contains directories, you can use the 698 | # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 699 | # certain files from those directories. Note that the wildcards are matched 700 | # against the file with absolute path, so to exclude all test directories 701 | # for example use the pattern */test/* 702 | 703 | EXCLUDE_PATTERNS = 704 | 705 | # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 706 | # (namespaces, classes, functions, etc.) that should be excluded from the 707 | # output. The symbol name can be a fully qualified name, a word, or if the 708 | # wildcard * is used, a substring. Examples: ANamespace, AClass, 709 | # AClass::ANamespace, ANamespace::*Test 710 | 711 | EXCLUDE_SYMBOLS = 712 | 713 | # The EXAMPLE_PATH tag can be used to specify one or more files or 714 | # directories that contain example code fragments that are included (see 715 | # the \include command). 716 | 717 | EXAMPLE_PATH = 718 | 719 | # If the value of the EXAMPLE_PATH tag contains directories, you can use the 720 | # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 721 | # and *.h) to filter out the source-files in the directories. If left 722 | # blank all files are included. 723 | 724 | EXAMPLE_PATTERNS = 725 | 726 | # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 727 | # searched for input files to be used with the \include or \dontinclude 728 | # commands irrespective of the value of the RECURSIVE tag. 729 | # Possible values are YES and NO. If left blank NO is used. 730 | 731 | EXAMPLE_RECURSIVE = NO 732 | 733 | # The IMAGE_PATH tag can be used to specify one or more files or 734 | # directories that contain image that are included in the documentation (see 735 | # the \image command). 736 | 737 | IMAGE_PATH = 738 | 739 | # The INPUT_FILTER tag can be used to specify a program that doxygen should 740 | # invoke to filter for each input file. Doxygen will invoke the filter program 741 | # by executing (via popen()) the command , where 742 | # is the value of the INPUT_FILTER tag, and is the name of an 743 | # input file. Doxygen will then use the output that the filter program writes 744 | # to standard output. 745 | # If FILTER_PATTERNS is specified, this tag will be ignored. 746 | # Note that the filter must not add or remove lines; it is applied before the 747 | # code is scanned, but not when the output code is generated. If lines are added 748 | # or removed, the anchors will not be placed correctly. 749 | 750 | INPUT_FILTER = 751 | 752 | # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 753 | # basis. 754 | # Doxygen will compare the file name with each pattern and apply the 755 | # filter if there is a match. 756 | # The filters are a list of the form: 757 | # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 758 | # info on how filters are used. If FILTER_PATTERNS is empty or if 759 | # non of the patterns match the file name, INPUT_FILTER is applied. 760 | 761 | FILTER_PATTERNS = 762 | 763 | # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 764 | # INPUT_FILTER) will be used to filter the input files when producing source 765 | # files to browse (i.e. when SOURCE_BROWSER is set to YES). 766 | 767 | FILTER_SOURCE_FILES = NO 768 | 769 | # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 770 | # pattern. A pattern will override the setting for FILTER_PATTERN (if any) 771 | # and it is also possible to disable source filtering for a specific pattern 772 | # using *.ext= (so without naming a filter). This option only has effect when 773 | # FILTER_SOURCE_FILES is enabled. 774 | 775 | FILTER_SOURCE_PATTERNS = 776 | 777 | # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that 778 | # is part of the input, its contents will be placed on the main page 779 | # (index.html). This can be useful if you have a project on for instance GitHub 780 | # and want reuse the introduction page also for the doxygen output. 781 | 782 | USE_MDFILE_AS_MAINPAGE = README.md 783 | 784 | #--------------------------------------------------------------------------- 785 | # configuration options related to source browsing 786 | #--------------------------------------------------------------------------- 787 | 788 | # If the SOURCE_BROWSER tag is set to YES then a list of source files will 789 | # be generated. Documented entities will be cross-referenced with these sources. 790 | # Note: To get rid of all source code in the generated output, make sure also 791 | # VERBATIM_HEADERS is set to NO. 792 | 793 | SOURCE_BROWSER = YES 794 | 795 | # Setting the INLINE_SOURCES tag to YES will include the body 796 | # of functions and classes directly in the documentation. 797 | 798 | INLINE_SOURCES = NO 799 | 800 | # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 801 | # doxygen to hide any special comment blocks from generated source code 802 | # fragments. Normal C, C++ and Fortran comments will always remain visible. 803 | 804 | STRIP_CODE_COMMENTS = YES 805 | 806 | # If the REFERENCED_BY_RELATION tag is set to YES 807 | # then for each documented function all documented 808 | # functions referencing it will be listed. 809 | 810 | REFERENCED_BY_RELATION = NO 811 | 812 | # If the REFERENCES_RELATION tag is set to YES 813 | # then for each documented function all documented entities 814 | # called/used by that function will be listed. 815 | 816 | REFERENCES_RELATION = NO 817 | 818 | # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 819 | # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 820 | # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 821 | # link to the source code. 822 | # Otherwise they will link to the documentation. 823 | 824 | REFERENCES_LINK_SOURCE = YES 825 | 826 | # If the USE_HTAGS tag is set to YES then the references to source code 827 | # will point to the HTML generated by the htags(1) tool instead of doxygen 828 | # built-in source browser. The htags tool is part of GNU's global source 829 | # tagging system (see http://www.gnu.org/software/global/global.html). You 830 | # will need version 4.8.6 or higher. 831 | 832 | USE_HTAGS = NO 833 | 834 | # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 835 | # will generate a verbatim copy of the header file for each class for 836 | # which an include is specified. Set to NO to disable this. 837 | 838 | VERBATIM_HEADERS = YES 839 | 840 | #--------------------------------------------------------------------------- 841 | # configuration options related to the alphabetical class index 842 | #--------------------------------------------------------------------------- 843 | 844 | # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 845 | # of all compounds will be generated. Enable this if the project 846 | # contains a lot of classes, structs, unions or interfaces. 847 | 848 | ALPHABETICAL_INDEX = YES 849 | 850 | # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 851 | # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 852 | # in which this list will be split (can be a number in the range [1..20]) 853 | 854 | COLS_IN_ALPHA_INDEX = 5 855 | 856 | # In case all classes in a project start with a common prefix, all 857 | # classes will be put under the same header in the alphabetical index. 858 | # The IGNORE_PREFIX tag can be used to specify one or more prefixes that 859 | # should be ignored while generating the index headers. 860 | 861 | IGNORE_PREFIX = 862 | 863 | #--------------------------------------------------------------------------- 864 | # configuration options related to the HTML output 865 | #--------------------------------------------------------------------------- 866 | 867 | # If the GENERATE_HTML tag is set to YES (the default) Doxygen will 868 | # generate HTML output. 869 | 870 | GENERATE_HTML = YES 871 | 872 | # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 873 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 874 | # put in front of it. If left blank `html' will be used as the default path. 875 | 876 | HTML_OUTPUT = html 877 | 878 | # The HTML_FILE_EXTENSION tag can be used to specify the file extension for 879 | # each generated HTML page (for example: .htm,.php,.asp). If it is left blank 880 | # doxygen will generate files with .html extension. 881 | 882 | HTML_FILE_EXTENSION = .html 883 | 884 | # The HTML_HEADER tag can be used to specify a personal HTML header for 885 | # each generated HTML page. If it is left blank doxygen will generate a 886 | # standard header. Note that when using a custom header you are responsible 887 | # for the proper inclusion of any scripts and style sheets that doxygen 888 | # needs, which is dependent on the configuration options used. 889 | # It is advised to generate a default header using "doxygen -w html 890 | # header.html footer.html stylesheet.css YourConfigFile" and then modify 891 | # that header. Note that the header is subject to change so you typically 892 | # have to redo this when upgrading to a newer version of doxygen or when 893 | # changing the value of configuration settings such as GENERATE_TREEVIEW! 894 | 895 | HTML_HEADER = 896 | 897 | # The HTML_FOOTER tag can be used to specify a personal HTML footer for 898 | # each generated HTML page. If it is left blank doxygen will generate a 899 | # standard footer. 900 | 901 | HTML_FOOTER = 902 | 903 | # The HTML_STYLESHEET tag can be used to specify a user-defined cascading 904 | # style sheet that is used by each HTML page. It can be used to 905 | # fine-tune the look of the HTML output. If left blank doxygen will 906 | # generate a default style sheet. Note that it is recommended to use 907 | # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this 908 | # tag will in the future become obsolete. 909 | 910 | HTML_STYLESHEET = 911 | 912 | # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional 913 | # user-defined cascading style sheet that is included after the standard 914 | # style sheets created by doxygen. Using this option one can overrule 915 | # certain style aspects. This is preferred over using HTML_STYLESHEET 916 | # since it does not replace the standard style sheet and is therefor more 917 | # robust against future updates. Doxygen will copy the style sheet file to 918 | # the output directory. 919 | 920 | HTML_EXTRA_STYLESHEET = 921 | 922 | # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 923 | # other source files which should be copied to the HTML output directory. Note 924 | # that these files will be copied to the base HTML output directory. Use the 925 | # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 926 | # files. In the HTML_STYLESHEET file, use the file name only. Also note that 927 | # the files will be copied as-is; there are no commands or markers available. 928 | 929 | HTML_EXTRA_FILES = 930 | 931 | # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 932 | # Doxygen will adjust the colors in the style sheet and background images 933 | # according to this color. Hue is specified as an angle on a colorwheel, 934 | # see http://en.wikipedia.org/wiki/Hue for more information. 935 | # For instance the value 0 represents red, 60 is yellow, 120 is green, 936 | # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 937 | # The allowed range is 0 to 359. 938 | 939 | HTML_COLORSTYLE_HUE = 220 940 | 941 | # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 942 | # the colors in the HTML output. For a value of 0 the output will use 943 | # grayscales only. A value of 255 will produce the most vivid colors. 944 | 945 | HTML_COLORSTYLE_SAT = 100 946 | 947 | # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 948 | # the luminance component of the colors in the HTML output. Values below 949 | # 100 gradually make the output lighter, whereas values above 100 make 950 | # the output darker. The value divided by 100 is the actual gamma applied, 951 | # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 952 | # and 100 does not change the gamma. 953 | 954 | HTML_COLORSTYLE_GAMMA = 80 955 | 956 | # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 957 | # page will contain the date and time when the page was generated. Setting 958 | # this to NO can help when comparing the output of multiple runs. 959 | 960 | HTML_TIMESTAMP = YES 961 | 962 | # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 963 | # documentation will contain sections that can be hidden and shown after the 964 | # page has loaded. 965 | 966 | HTML_DYNAMIC_SECTIONS = NO 967 | 968 | # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of 969 | # entries shown in the various tree structured indices initially; the user 970 | # can expand and collapse entries dynamically later on. Doxygen will expand 971 | # the tree to such a level that at most the specified number of entries are 972 | # visible (unless a fully collapsed tree already exceeds this amount). 973 | # So setting the number of entries 1 will produce a full collapsed tree by 974 | # default. 0 is a special value representing an infinite number of entries 975 | # and will result in a full expanded tree by default. 976 | 977 | HTML_INDEX_NUM_ENTRIES = 100 978 | 979 | # If the GENERATE_DOCSET tag is set to YES, additional index files 980 | # will be generated that can be used as input for Apple's Xcode 3 981 | # integrated development environment, introduced with OSX 10.5 (Leopard). 982 | # To create a documentation set, doxygen will generate a Makefile in the 983 | # HTML output directory. Running make will produce the docset in that 984 | # directory and running "make install" will install the docset in 985 | # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 986 | # it at startup. 987 | # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 988 | # for more information. 989 | 990 | GENERATE_DOCSET = NO 991 | 992 | # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 993 | # feed. A documentation feed provides an umbrella under which multiple 994 | # documentation sets from a single provider (such as a company or product suite) 995 | # can be grouped. 996 | 997 | DOCSET_FEEDNAME = "Doxygen generated docs" 998 | 999 | # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 1000 | # should uniquely identify the documentation set bundle. This should be a 1001 | # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 1002 | # will append .docset to the name. 1003 | 1004 | DOCSET_BUNDLE_ID = org.doxygen.Project 1005 | 1006 | # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely 1007 | # identify the documentation publisher. This should be a reverse domain-name 1008 | # style string, e.g. com.mycompany.MyDocSet.documentation. 1009 | 1010 | DOCSET_PUBLISHER_ID = org.doxygen.Publisher 1011 | 1012 | # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. 1013 | 1014 | DOCSET_PUBLISHER_NAME = Publisher 1015 | 1016 | # If the GENERATE_HTMLHELP tag is set to YES, additional index files 1017 | # will be generated that can be used as input for tools like the 1018 | # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 1019 | # of the generated HTML documentation. 1020 | 1021 | GENERATE_HTMLHELP = NO 1022 | 1023 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 1024 | # be used to specify the file name of the resulting .chm file. You 1025 | # can add a path in front of the file if the result should not be 1026 | # written to the html output directory. 1027 | 1028 | CHM_FILE = 1029 | 1030 | # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 1031 | # be used to specify the location (absolute path including file name) of 1032 | # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 1033 | # the HTML help compiler on the generated index.hhp. 1034 | 1035 | HHC_LOCATION = 1036 | 1037 | # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 1038 | # controls if a separate .chi index file is generated (YES) or that 1039 | # it should be included in the master .chm file (NO). 1040 | 1041 | GENERATE_CHI = NO 1042 | 1043 | # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 1044 | # is used to encode HtmlHelp index (hhk), content (hhc) and project file 1045 | # content. 1046 | 1047 | CHM_INDEX_ENCODING = 1048 | 1049 | # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 1050 | # controls whether a binary table of contents is generated (YES) or a 1051 | # normal table of contents (NO) in the .chm file. 1052 | 1053 | BINARY_TOC = NO 1054 | 1055 | # The TOC_EXPAND flag can be set to YES to add extra items for group members 1056 | # to the contents of the HTML help documentation and to the tree view. 1057 | 1058 | TOC_EXPAND = NO 1059 | 1060 | # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 1061 | # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 1062 | # that can be used as input for Qt's qhelpgenerator to generate a 1063 | # Qt Compressed Help (.qch) of the generated HTML documentation. 1064 | 1065 | GENERATE_QHP = NO 1066 | 1067 | # If the QHG_LOCATION tag is specified, the QCH_FILE tag can 1068 | # be used to specify the file name of the resulting .qch file. 1069 | # The path specified is relative to the HTML output folder. 1070 | 1071 | QCH_FILE = 1072 | 1073 | # The QHP_NAMESPACE tag specifies the namespace to use when generating 1074 | # Qt Help Project output. For more information please see 1075 | # http://doc.trolltech.com/qthelpproject.html#namespace 1076 | 1077 | QHP_NAMESPACE = org.doxygen.Project 1078 | 1079 | # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 1080 | # Qt Help Project output. For more information please see 1081 | # http://doc.trolltech.com/qthelpproject.html#virtual-folders 1082 | 1083 | QHP_VIRTUAL_FOLDER = doc 1084 | 1085 | # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 1086 | # add. For more information please see 1087 | # http://doc.trolltech.com/qthelpproject.html#custom-filters 1088 | 1089 | QHP_CUST_FILTER_NAME = 1090 | 1091 | # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 1092 | # custom filter to add. For more information please see 1093 | # 1094 | # Qt Help Project / Custom Filters. 1095 | 1096 | QHP_CUST_FILTER_ATTRS = 1097 | 1098 | # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 1099 | # project's 1100 | # filter section matches. 1101 | # 1102 | # Qt Help Project / Filter Attributes. 1103 | 1104 | QHP_SECT_FILTER_ATTRS = 1105 | 1106 | # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 1107 | # be used to specify the location of Qt's qhelpgenerator. 1108 | # If non-empty doxygen will try to run qhelpgenerator on the generated 1109 | # .qhp file. 1110 | 1111 | QHG_LOCATION = 1112 | 1113 | # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files 1114 | # will be generated, which together with the HTML files, form an Eclipse help 1115 | # plugin. To install this plugin and make it available under the help contents 1116 | # menu in Eclipse, the contents of the directory containing the HTML and XML 1117 | # files needs to be copied into the plugins directory of eclipse. The name of 1118 | # the directory within the plugins directory should be the same as 1119 | # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 1120 | # the help appears. 1121 | 1122 | GENERATE_ECLIPSEHELP = NO 1123 | 1124 | # A unique identifier for the eclipse help plugin. When installing the plugin 1125 | # the directory name containing the HTML and XML files should also have 1126 | # this name. 1127 | 1128 | ECLIPSE_DOC_ID = org.doxygen.Project 1129 | 1130 | # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 1131 | # at top of each HTML page. The value NO (the default) enables the index and 1132 | # the value YES disables it. Since the tabs have the same information as the 1133 | # navigation tree you can set this option to NO if you already set 1134 | # GENERATE_TREEVIEW to YES. 1135 | 1136 | DISABLE_INDEX = NO 1137 | 1138 | # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 1139 | # structure should be generated to display hierarchical information. 1140 | # If the tag value is set to YES, a side panel will be generated 1141 | # containing a tree-like index structure (just like the one that 1142 | # is generated for HTML Help). For this to work a browser that supports 1143 | # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 1144 | # Windows users are probably better off using the HTML help feature. 1145 | # Since the tree basically has the same information as the tab index you 1146 | # could consider to set DISABLE_INDEX to NO when enabling this option. 1147 | 1148 | GENERATE_TREEVIEW = NO 1149 | 1150 | # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 1151 | # (range [0,1..20]) that doxygen will group on one line in the generated HTML 1152 | # documentation. Note that a value of 0 will completely suppress the enum 1153 | # values from appearing in the overview section. 1154 | 1155 | ENUM_VALUES_PER_LINE = 4 1156 | 1157 | # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 1158 | # used to set the initial width (in pixels) of the frame in which the tree 1159 | # is shown. 1160 | 1161 | TREEVIEW_WIDTH = 250 1162 | 1163 | # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 1164 | # links to external symbols imported via tag files in a separate window. 1165 | 1166 | EXT_LINKS_IN_WINDOW = NO 1167 | 1168 | # Use this tag to change the font size of Latex formulas included 1169 | # as images in the HTML documentation. The default is 10. Note that 1170 | # when you change the font size after a successful doxygen run you need 1171 | # to manually remove any form_*.png images from the HTML output directory 1172 | # to force them to be regenerated. 1173 | 1174 | FORMULA_FONTSIZE = 10 1175 | 1176 | # Use the FORMULA_TRANPARENT tag to determine whether or not the images 1177 | # generated for formulas are transparent PNGs. Transparent PNGs are 1178 | # not supported properly for IE 6.0, but are supported on all modern browsers. 1179 | # Note that when changing this option you need to delete any form_*.png files 1180 | # in the HTML output before the changes have effect. 1181 | 1182 | FORMULA_TRANSPARENT = YES 1183 | 1184 | # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 1185 | # (see http://www.mathjax.org) which uses client side Javascript for the 1186 | # rendering instead of using prerendered bitmaps. Use this if you do not 1187 | # have LaTeX installed or if you want to formulas look prettier in the HTML 1188 | # output. When enabled you may also need to install MathJax separately and 1189 | # configure the path to it using the MATHJAX_RELPATH option. 1190 | 1191 | USE_MATHJAX = NO 1192 | 1193 | # When MathJax is enabled you can set the default output format to be used for 1194 | # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and 1195 | # SVG. The default value is HTML-CSS, which is slower, but has the best 1196 | # compatibility. 1197 | 1198 | MATHJAX_FORMAT = HTML-CSS 1199 | 1200 | # When MathJax is enabled you need to specify the location relative to the 1201 | # HTML output directory using the MATHJAX_RELPATH option. The destination 1202 | # directory should contain the MathJax.js script. For instance, if the mathjax 1203 | # directory is located at the same level as the HTML output directory, then 1204 | # MATHJAX_RELPATH should be ../mathjax. The default value points to 1205 | # the MathJax Content Delivery Network so you can quickly see the result without 1206 | # installing MathJax. 1207 | # However, it is strongly recommended to install a local 1208 | # copy of MathJax from http://www.mathjax.org before deployment. 1209 | 1210 | MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest 1211 | 1212 | # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 1213 | # names that should be enabled during MathJax rendering. 1214 | 1215 | MATHJAX_EXTENSIONS = 1216 | 1217 | # The MATHJAX_CODEFILE tag can be used to specify a file with javascript 1218 | # pieces of code that will be used on startup of the MathJax code. 1219 | 1220 | MATHJAX_CODEFILE = 1221 | 1222 | # When the SEARCHENGINE tag is enabled doxygen will generate a search box 1223 | # for the HTML output. The underlying search engine uses javascript 1224 | # and DHTML and should work on any modern browser. Note that when using 1225 | # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 1226 | # (GENERATE_DOCSET) there is already a search function so this one should 1227 | # typically be disabled. For large projects the javascript based search engine 1228 | # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. 1229 | 1230 | SEARCHENGINE = YES 1231 | 1232 | # When the SERVER_BASED_SEARCH tag is enabled the search engine will be 1233 | # implemented using a web server instead of a web client using Javascript. 1234 | # There are two flavours of web server based search depending on the 1235 | # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for 1236 | # searching and an index file used by the script. When EXTERNAL_SEARCH is 1237 | # enabled the indexing and searching needs to be provided by external tools. 1238 | # See the manual for details. 1239 | 1240 | SERVER_BASED_SEARCH = NO 1241 | 1242 | # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP 1243 | # script for searching. Instead the search results are written to an XML file 1244 | # which needs to be processed by an external indexer. Doxygen will invoke an 1245 | # external search engine pointed to by the SEARCHENGINE_URL option to obtain 1246 | # the search results. Doxygen ships with an example indexer (doxyindexer) and 1247 | # search engine (doxysearch.cgi) which are based on the open source search 1248 | # engine library Xapian. See the manual for configuration details. 1249 | 1250 | EXTERNAL_SEARCH = NO 1251 | 1252 | # The SEARCHENGINE_URL should point to a search engine hosted by a web server 1253 | # which will returned the search results when EXTERNAL_SEARCH is enabled. 1254 | # Doxygen ships with an example search engine (doxysearch) which is based on 1255 | # the open source search engine library Xapian. See the manual for configuration 1256 | # details. 1257 | 1258 | SEARCHENGINE_URL = 1259 | 1260 | # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed 1261 | # search data is written to a file for indexing by an external tool. With the 1262 | # SEARCHDATA_FILE tag the name of this file can be specified. 1263 | 1264 | SEARCHDATA_FILE = searchdata.xml 1265 | 1266 | # When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the 1267 | # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is 1268 | # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple 1269 | # projects and redirect the results back to the right project. 1270 | 1271 | EXTERNAL_SEARCH_ID = 1272 | 1273 | # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen 1274 | # projects other than the one defined by this configuration file, but that are 1275 | # all added to the same external search index. Each project needs to have a 1276 | # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id 1277 | # of to a relative location where the documentation can be found. 1278 | # The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... 1279 | 1280 | EXTRA_SEARCH_MAPPINGS = 1281 | 1282 | #--------------------------------------------------------------------------- 1283 | # configuration options related to the LaTeX output 1284 | #--------------------------------------------------------------------------- 1285 | 1286 | # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 1287 | # generate Latex output. 1288 | 1289 | GENERATE_LATEX = YES 1290 | 1291 | # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 1292 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1293 | # put in front of it. If left blank `latex' will be used as the default path. 1294 | 1295 | LATEX_OUTPUT = latex 1296 | 1297 | # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 1298 | # invoked. If left blank `latex' will be used as the default command name. 1299 | # Note that when enabling USE_PDFLATEX this option is only used for 1300 | # generating bitmaps for formulas in the HTML output, but not in the 1301 | # Makefile that is written to the output directory. 1302 | 1303 | LATEX_CMD_NAME = latex 1304 | 1305 | # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 1306 | # generate index for LaTeX. If left blank `makeindex' will be used as the 1307 | # default command name. 1308 | 1309 | MAKEINDEX_CMD_NAME = makeindex 1310 | 1311 | # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 1312 | # LaTeX documents. This may be useful for small projects and may help to 1313 | # save some trees in general. 1314 | 1315 | COMPACT_LATEX = NO 1316 | 1317 | # The PAPER_TYPE tag can be used to set the paper type that is used 1318 | # by the printer. Possible values are: a4, letter, legal and 1319 | # executive. If left blank a4 will be used. 1320 | 1321 | PAPER_TYPE = a4 1322 | 1323 | # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 1324 | # packages that should be included in the LaTeX output. 1325 | 1326 | EXTRA_PACKAGES = 1327 | 1328 | # The LATEX_HEADER tag can be used to specify a personal LaTeX header for 1329 | # the generated latex document. The header should contain everything until 1330 | # the first chapter. If it is left blank doxygen will generate a 1331 | # standard header. Notice: only use this tag if you know what you are doing! 1332 | 1333 | LATEX_HEADER = 1334 | 1335 | # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 1336 | # the generated latex document. The footer should contain everything after 1337 | # the last chapter. If it is left blank doxygen will generate a 1338 | # standard footer. Notice: only use this tag if you know what you are doing! 1339 | 1340 | LATEX_FOOTER = 1341 | 1342 | # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images 1343 | # or other source files which should be copied to the LaTeX output directory. 1344 | # Note that the files will be copied as-is; there are no commands or markers 1345 | # available. 1346 | 1347 | LATEX_EXTRA_FILES = 1348 | 1349 | # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 1350 | # is prepared for conversion to pdf (using ps2pdf). The pdf file will 1351 | # contain links (just like the HTML output) instead of page references 1352 | # This makes the output suitable for online browsing using a pdf viewer. 1353 | 1354 | PDF_HYPERLINKS = YES 1355 | 1356 | # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 1357 | # plain latex in the generated Makefile. Set this option to YES to get a 1358 | # higher quality PDF documentation. 1359 | 1360 | USE_PDFLATEX = YES 1361 | 1362 | # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 1363 | # command to the generated LaTeX files. This will instruct LaTeX to keep 1364 | # running if errors occur, instead of asking the user for help. 1365 | # This option is also used when generating formulas in HTML. 1366 | 1367 | LATEX_BATCHMODE = NO 1368 | 1369 | # If LATEX_HIDE_INDICES is set to YES then doxygen will not 1370 | # include the index chapters (such as File Index, Compound Index, etc.) 1371 | # in the output. 1372 | 1373 | LATEX_HIDE_INDICES = NO 1374 | 1375 | # If LATEX_SOURCE_CODE is set to YES then doxygen will include 1376 | # source code with syntax highlighting in the LaTeX output. 1377 | # Note that which sources are shown also depends on other settings 1378 | # such as SOURCE_BROWSER. 1379 | 1380 | LATEX_SOURCE_CODE = YES 1381 | 1382 | # The LATEX_BIB_STYLE tag can be used to specify the style to use for the 1383 | # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 1384 | # http://en.wikipedia.org/wiki/BibTeX for more info. 1385 | 1386 | LATEX_BIB_STYLE = plain 1387 | 1388 | #--------------------------------------------------------------------------- 1389 | # configuration options related to the RTF output 1390 | #--------------------------------------------------------------------------- 1391 | 1392 | # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 1393 | # The RTF output is optimized for Word 97 and may not look very pretty with 1394 | # other RTF readers or editors. 1395 | 1396 | GENERATE_RTF = NO 1397 | 1398 | # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 1399 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1400 | # put in front of it. If left blank `rtf' will be used as the default path. 1401 | 1402 | RTF_OUTPUT = rtf 1403 | 1404 | # If the COMPACT_RTF tag is set to YES Doxygen generates more compact 1405 | # RTF documents. This may be useful for small projects and may help to 1406 | # save some trees in general. 1407 | 1408 | COMPACT_RTF = NO 1409 | 1410 | # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 1411 | # will contain hyperlink fields. The RTF file will 1412 | # contain links (just like the HTML output) instead of page references. 1413 | # This makes the output suitable for online browsing using WORD or other 1414 | # programs which support those fields. 1415 | # Note: wordpad (write) and others do not support links. 1416 | 1417 | RTF_HYPERLINKS = NO 1418 | 1419 | # Load style sheet definitions from file. Syntax is similar to doxygen's 1420 | # config file, i.e. a series of assignments. You only have to provide 1421 | # replacements, missing definitions are set to their default value. 1422 | 1423 | RTF_STYLESHEET_FILE = 1424 | 1425 | # Set optional variables used in the generation of an rtf document. 1426 | # Syntax is similar to doxygen's config file. 1427 | 1428 | RTF_EXTENSIONS_FILE = 1429 | 1430 | #--------------------------------------------------------------------------- 1431 | # configuration options related to the man page output 1432 | #--------------------------------------------------------------------------- 1433 | 1434 | # If the GENERATE_MAN tag is set to YES (the default) Doxygen will 1435 | # generate man pages 1436 | 1437 | GENERATE_MAN = NO 1438 | 1439 | # The MAN_OUTPUT tag is used to specify where the man pages will be put. 1440 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1441 | # put in front of it. If left blank `man' will be used as the default path. 1442 | 1443 | MAN_OUTPUT = man 1444 | 1445 | # The MAN_EXTENSION tag determines the extension that is added to 1446 | # the generated man pages (default is the subroutine's section .3) 1447 | 1448 | MAN_EXTENSION = .3 1449 | 1450 | # If the MAN_LINKS tag is set to YES and Doxygen generates man output, 1451 | # then it will generate one additional man file for each entity 1452 | # documented in the real man page(s). These additional files 1453 | # only source the real man page, but without them the man command 1454 | # would be unable to find the correct page. The default is NO. 1455 | 1456 | MAN_LINKS = NO 1457 | 1458 | #--------------------------------------------------------------------------- 1459 | # configuration options related to the XML output 1460 | #--------------------------------------------------------------------------- 1461 | 1462 | # If the GENERATE_XML tag is set to YES Doxygen will 1463 | # generate an XML file that captures the structure of 1464 | # the code including all documentation. 1465 | 1466 | GENERATE_XML = NO 1467 | 1468 | # The XML_OUTPUT tag is used to specify where the XML pages will be put. 1469 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be 1470 | # put in front of it. If left blank `xml' will be used as the default path. 1471 | 1472 | XML_OUTPUT = xml 1473 | 1474 | # The XML_SCHEMA tag can be used to specify an XML schema, 1475 | # which can be used by a validating XML parser to check the 1476 | # syntax of the XML files. 1477 | 1478 | XML_SCHEMA = 1479 | 1480 | # The XML_DTD tag can be used to specify an XML DTD, 1481 | # which can be used by a validating XML parser to check the 1482 | # syntax of the XML files. 1483 | 1484 | XML_DTD = 1485 | 1486 | # If the XML_PROGRAMLISTING tag is set to YES Doxygen will 1487 | # dump the program listings (including syntax highlighting 1488 | # and cross-referencing information) to the XML output. Note that 1489 | # enabling this will significantly increase the size of the XML output. 1490 | 1491 | XML_PROGRAMLISTING = YES 1492 | 1493 | #--------------------------------------------------------------------------- 1494 | # configuration options related to the DOCBOOK output 1495 | #--------------------------------------------------------------------------- 1496 | 1497 | # If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files 1498 | # that can be used to generate PDF. 1499 | 1500 | GENERATE_DOCBOOK = NO 1501 | 1502 | # The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. 1503 | # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in 1504 | # front of it. If left blank docbook will be used as the default path. 1505 | 1506 | DOCBOOK_OUTPUT = docbook 1507 | 1508 | #--------------------------------------------------------------------------- 1509 | # configuration options for the AutoGen Definitions output 1510 | #--------------------------------------------------------------------------- 1511 | 1512 | # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 1513 | # generate an AutoGen Definitions (see autogen.sf.net) file 1514 | # that captures the structure of the code including all 1515 | # documentation. Note that this feature is still experimental 1516 | # and incomplete at the moment. 1517 | 1518 | GENERATE_AUTOGEN_DEF = NO 1519 | 1520 | #--------------------------------------------------------------------------- 1521 | # configuration options related to the Perl module output 1522 | #--------------------------------------------------------------------------- 1523 | 1524 | # If the GENERATE_PERLMOD tag is set to YES Doxygen will 1525 | # generate a Perl module file that captures the structure of 1526 | # the code including all documentation. Note that this 1527 | # feature is still experimental and incomplete at the 1528 | # moment. 1529 | 1530 | GENERATE_PERLMOD = NO 1531 | 1532 | # If the PERLMOD_LATEX tag is set to YES Doxygen will generate 1533 | # the necessary Makefile rules, Perl scripts and LaTeX code to be able 1534 | # to generate PDF and DVI output from the Perl module output. 1535 | 1536 | PERLMOD_LATEX = NO 1537 | 1538 | # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 1539 | # nicely formatted so it can be parsed by a human reader. 1540 | # This is useful 1541 | # if you want to understand what is going on. 1542 | # On the other hand, if this 1543 | # tag is set to NO the size of the Perl module output will be much smaller 1544 | # and Perl will parse it just the same. 1545 | 1546 | PERLMOD_PRETTY = YES 1547 | 1548 | # The names of the make variables in the generated doxyrules.make file 1549 | # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 1550 | # This is useful so different doxyrules.make files included by the same 1551 | # Makefile don't overwrite each other's variables. 1552 | 1553 | PERLMOD_MAKEVAR_PREFIX = 1554 | 1555 | #--------------------------------------------------------------------------- 1556 | # Configuration options related to the preprocessor 1557 | #--------------------------------------------------------------------------- 1558 | 1559 | # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 1560 | # evaluate all C-preprocessor directives found in the sources and include 1561 | # files. 1562 | 1563 | ENABLE_PREPROCESSING = YES 1564 | 1565 | # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 1566 | # names in the source code. If set to NO (the default) only conditional 1567 | # compilation will be performed. Macro expansion can be done in a controlled 1568 | # way by setting EXPAND_ONLY_PREDEF to YES. 1569 | 1570 | MACRO_EXPANSION = NO 1571 | 1572 | # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 1573 | # then the macro expansion is limited to the macros specified with the 1574 | # PREDEFINED and EXPAND_AS_DEFINED tags. 1575 | 1576 | EXPAND_ONLY_PREDEF = NO 1577 | 1578 | # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 1579 | # pointed to by INCLUDE_PATH will be searched when a #include is found. 1580 | 1581 | SEARCH_INCLUDES = YES 1582 | 1583 | # The INCLUDE_PATH tag can be used to specify one or more directories that 1584 | # contain include files that are not input files but should be processed by 1585 | # the preprocessor. 1586 | 1587 | INCLUDE_PATH = 1588 | 1589 | # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 1590 | # patterns (like *.h and *.hpp) to filter out the header-files in the 1591 | # directories. If left blank, the patterns specified with FILE_PATTERNS will 1592 | # be used. 1593 | 1594 | INCLUDE_FILE_PATTERNS = 1595 | 1596 | # The PREDEFINED tag can be used to specify one or more macro names that 1597 | # are defined before the preprocessor is started (similar to the -D option of 1598 | # gcc). The argument of the tag is a list of macros of the form: name 1599 | # or name=definition (no spaces). If the definition and the = are 1600 | # omitted =1 is assumed. To prevent a macro definition from being 1601 | # undefined via #undef or recursively expanded use the := operator 1602 | # instead of the = operator. 1603 | 1604 | PREDEFINED = 1605 | 1606 | # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 1607 | # this tag can be used to specify a list of macro names that should be expanded. 1608 | # The macro definition that is found in the sources will be used. 1609 | # Use the PREDEFINED tag if you want to use a different macro definition that 1610 | # overrules the definition found in the source code. 1611 | 1612 | EXPAND_AS_DEFINED = 1613 | 1614 | # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 1615 | # doxygen's preprocessor will remove all references to function-like macros 1616 | # that are alone on a line, have an all uppercase name, and do not end with a 1617 | # semicolon, because these will confuse the parser if not removed. 1618 | 1619 | SKIP_FUNCTION_MACROS = YES 1620 | 1621 | #--------------------------------------------------------------------------- 1622 | # Configuration::additions related to external references 1623 | #--------------------------------------------------------------------------- 1624 | 1625 | # The TAGFILES option can be used to specify one or more tagfiles. For each 1626 | # tag file the location of the external documentation should be added. The 1627 | # format of a tag file without this location is as follows: 1628 | # 1629 | # TAGFILES = file1 file2 ... 1630 | # Adding location for the tag files is done as follows: 1631 | # 1632 | # TAGFILES = file1=loc1 "file2 = loc2" ... 1633 | # where "loc1" and "loc2" can be relative or absolute paths 1634 | # or URLs. Note that each tag file must have a unique name (where the name does 1635 | # NOT include the path). If a tag file is not located in the directory in which 1636 | # doxygen is run, you must also specify the path to the tagfile here. 1637 | 1638 | TAGFILES = 1639 | 1640 | # When a file name is specified after GENERATE_TAGFILE, doxygen will create 1641 | # a tag file that is based on the input files it reads. 1642 | 1643 | GENERATE_TAGFILE = 1644 | 1645 | # If the ALLEXTERNALS tag is set to YES all external classes will be listed 1646 | # in the class index. If set to NO only the inherited external classes 1647 | # will be listed. 1648 | 1649 | ALLEXTERNALS = NO 1650 | 1651 | # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 1652 | # in the modules index. If set to NO, only the current project's groups will 1653 | # be listed. 1654 | 1655 | EXTERNAL_GROUPS = YES 1656 | 1657 | # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed 1658 | # in the related pages index. If set to NO, only the current project's 1659 | # pages will be listed. 1660 | 1661 | EXTERNAL_PAGES = YES 1662 | 1663 | # The PERL_PATH should be the absolute path and name of the perl script 1664 | # interpreter (i.e. the result of `which perl'). 1665 | 1666 | PERL_PATH = /usr/bin/perl 1667 | 1668 | #--------------------------------------------------------------------------- 1669 | # Configuration options related to the dot tool 1670 | #--------------------------------------------------------------------------- 1671 | 1672 | # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 1673 | # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 1674 | # or super classes. Setting the tag to NO turns the diagrams off. Note that 1675 | # this option also works with HAVE_DOT disabled, but it is recommended to 1676 | # install and use dot, since it yields more powerful graphs. 1677 | 1678 | CLASS_DIAGRAMS = YES 1679 | 1680 | # You can define message sequence charts within doxygen comments using the \msc 1681 | # command. Doxygen will then run the mscgen tool (see 1682 | # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 1683 | # documentation. The MSCGEN_PATH tag allows you to specify the directory where 1684 | # the mscgen tool resides. If left empty the tool is assumed to be found in the 1685 | # default search path. 1686 | 1687 | MSCGEN_PATH = 1688 | 1689 | # If set to YES, the inheritance and collaboration graphs will hide 1690 | # inheritance and usage relations if the target is undocumented 1691 | # or is not a class. 1692 | 1693 | HIDE_UNDOC_RELATIONS = YES 1694 | 1695 | # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 1696 | # available from the path. This tool is part of Graphviz, a graph visualization 1697 | # toolkit from AT&T and Lucent Bell Labs. The other options in this section 1698 | # have no effect if this option is set to NO (the default) 1699 | 1700 | HAVE_DOT = NO 1701 | 1702 | # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 1703 | # allowed to run in parallel. When set to 0 (the default) doxygen will 1704 | # base this on the number of processors available in the system. You can set it 1705 | # explicitly to a value larger than 0 to get control over the balance 1706 | # between CPU load and processing speed. 1707 | 1708 | DOT_NUM_THREADS = 0 1709 | 1710 | # By default doxygen will use the Helvetica font for all dot files that 1711 | # doxygen generates. When you want a differently looking font you can specify 1712 | # the font name using DOT_FONTNAME. You need to make sure dot is able to find 1713 | # the font, which can be done by putting it in a standard location or by setting 1714 | # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 1715 | # directory containing the font. 1716 | 1717 | DOT_FONTNAME = Helvetica 1718 | 1719 | # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 1720 | # The default size is 10pt. 1721 | 1722 | DOT_FONTSIZE = 10 1723 | 1724 | # By default doxygen will tell dot to use the Helvetica font. 1725 | # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 1726 | # set the path where dot can find it. 1727 | 1728 | DOT_FONTPATH = 1729 | 1730 | # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 1731 | # will generate a graph for each documented class showing the direct and 1732 | # indirect inheritance relations. Setting this tag to YES will force the 1733 | # CLASS_DIAGRAMS tag to NO. 1734 | 1735 | CLASS_GRAPH = YES 1736 | 1737 | # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 1738 | # will generate a graph for each documented class showing the direct and 1739 | # indirect implementation dependencies (inheritance, containment, and 1740 | # class references variables) of the class with other documented classes. 1741 | 1742 | COLLABORATION_GRAPH = YES 1743 | 1744 | # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 1745 | # will generate a graph for groups, showing the direct groups dependencies 1746 | 1747 | GROUP_GRAPHS = YES 1748 | 1749 | # If the UML_LOOK tag is set to YES doxygen will generate inheritance and 1750 | # collaboration diagrams in a style similar to the OMG's Unified Modeling 1751 | # Language. 1752 | 1753 | UML_LOOK = NO 1754 | 1755 | # If the UML_LOOK tag is enabled, the fields and methods are shown inside 1756 | # the class node. If there are many fields or methods and many nodes the 1757 | # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS 1758 | # threshold limits the number of items for each type to make the size more 1759 | # manageable. Set this to 0 for no limit. Note that the threshold may be 1760 | # exceeded by 50% before the limit is enforced. 1761 | 1762 | UML_LIMIT_NUM_FIELDS = 10 1763 | 1764 | # If set to YES, the inheritance and collaboration graphs will show the 1765 | # relations between templates and their instances. 1766 | 1767 | TEMPLATE_RELATIONS = NO 1768 | 1769 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 1770 | # tags are set to YES then doxygen will generate a graph for each documented 1771 | # file showing the direct and indirect include dependencies of the file with 1772 | # other documented files. 1773 | 1774 | INCLUDE_GRAPH = YES 1775 | 1776 | # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 1777 | # HAVE_DOT tags are set to YES then doxygen will generate a graph for each 1778 | # documented header file showing the documented files that directly or 1779 | # indirectly include this file. 1780 | 1781 | INCLUDED_BY_GRAPH = YES 1782 | 1783 | # If the CALL_GRAPH and HAVE_DOT options are set to YES then 1784 | # doxygen will generate a call dependency graph for every global function 1785 | # or class method. Note that enabling this option will significantly increase 1786 | # the time of a run. So in most cases it will be better to enable call graphs 1787 | # for selected functions only using the \callgraph command. 1788 | 1789 | CALL_GRAPH = NO 1790 | 1791 | # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 1792 | # doxygen will generate a caller dependency graph for every global function 1793 | # or class method. Note that enabling this option will significantly increase 1794 | # the time of a run. So in most cases it will be better to enable caller 1795 | # graphs for selected functions only using the \callergraph command. 1796 | 1797 | CALLER_GRAPH = NO 1798 | 1799 | # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 1800 | # will generate a graphical hierarchy of all classes instead of a textual one. 1801 | 1802 | GRAPHICAL_HIERARCHY = YES 1803 | 1804 | # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES 1805 | # then doxygen will show the dependencies a directory has on other directories 1806 | # in a graphical way. The dependency relations are determined by the #include 1807 | # relations between the files in the directories. 1808 | 1809 | DIRECTORY_GRAPH = YES 1810 | 1811 | # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 1812 | # generated by dot. Possible values are svg, png, jpg, or gif. 1813 | # If left blank png will be used. If you choose svg you need to set 1814 | # HTML_FILE_EXTENSION to xhtml in order to make the SVG files 1815 | # visible in IE 9+ (other browsers do not have this requirement). 1816 | 1817 | DOT_IMAGE_FORMAT = png 1818 | 1819 | # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 1820 | # enable generation of interactive SVG images that allow zooming and panning. 1821 | # Note that this requires a modern browser other than Internet Explorer. 1822 | # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 1823 | # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 1824 | # visible. Older versions of IE do not have SVG support. 1825 | 1826 | INTERACTIVE_SVG = NO 1827 | 1828 | # The tag DOT_PATH can be used to specify the path where the dot tool can be 1829 | # found. If left blank, it is assumed the dot tool can be found in the path. 1830 | 1831 | DOT_PATH = 1832 | 1833 | # The DOTFILE_DIRS tag can be used to specify one or more directories that 1834 | # contain dot files that are included in the documentation (see the 1835 | # \dotfile command). 1836 | 1837 | DOTFILE_DIRS = 1838 | 1839 | # The MSCFILE_DIRS tag can be used to specify one or more directories that 1840 | # contain msc files that are included in the documentation (see the 1841 | # \mscfile command). 1842 | 1843 | MSCFILE_DIRS = 1844 | 1845 | # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 1846 | # nodes that will be shown in the graph. If the number of nodes in a graph 1847 | # becomes larger than this value, doxygen will truncate the graph, which is 1848 | # visualized by representing a node as a red box. Note that doxygen if the 1849 | # number of direct children of the root node in a graph is already larger than 1850 | # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 1851 | # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. 1852 | 1853 | DOT_GRAPH_MAX_NODES = 50 1854 | 1855 | # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 1856 | # graphs generated by dot. A depth value of 3 means that only nodes reachable 1857 | # from the root by following a path via at most 3 edges will be shown. Nodes 1858 | # that lay further from the root node will be omitted. Note that setting this 1859 | # option to 1 or 2 may greatly reduce the computation time needed for large 1860 | # code bases. Also note that the size of a graph can be further restricted by 1861 | # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. 1862 | 1863 | MAX_DOT_GRAPH_DEPTH = 0 1864 | 1865 | # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 1866 | # background. This is disabled by default, because dot on Windows does not 1867 | # seem to support this out of the box. Warning: Depending on the platform used, 1868 | # enabling this option may lead to badly anti-aliased labels on the edges of 1869 | # a graph (i.e. they become hard to read). 1870 | 1871 | DOT_TRANSPARENT = NO 1872 | 1873 | # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 1874 | # files in one run (i.e. multiple -o and -T options on the command line). This 1875 | # makes dot run faster, but since only newer versions of dot (>1.8.10) 1876 | # support this, this feature is disabled by default. 1877 | 1878 | DOT_MULTI_TARGETS = NO 1879 | 1880 | # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 1881 | # generate a legend page explaining the meaning of the various boxes and 1882 | # arrows in the dot generated graphs. 1883 | 1884 | GENERATE_LEGEND = YES 1885 | 1886 | # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 1887 | # remove the intermediate dot files that are used to generate 1888 | # the various graphs. 1889 | 1890 | DOT_CLEANUP = YES 1891 | -------------------------------------------------------------------------------- /templates/template.c.in: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | @My_Project_Title@ -- @My_Project_Description@ 4 | 5 | @file file.c 6 | 7 | @brief 8 | 9 | 10 | @author @My_Project_Author@ 11 | @bug 12 | 13 | **/ 14 | 15 | /* 16 | 17 | @My_Project_Copyright@ 18 | 19 | 20 | @My_Project_License_Indented@ 21 | 22 | */ 23 | 24 | 25 | #include "file.h" 26 | 27 | static int void_function(void) { 28 | return 0; 29 | } 30 | 31 | #ifdef TEST 32 | static void Test_void_function(CuTest* tc) { 33 | int test = void_function(); 34 | 35 | CuAssertIntEquals(tc, 0, test); 36 | } 37 | #endif 38 | -------------------------------------------------------------------------------- /templates/template.h.in: -------------------------------------------------------------------------------- 1 | /** 2 | 3 | @My_Project_Title@ -- @My_Project_Description@ 4 | 5 | @file file.h 6 | 7 | @brief 8 | 9 | 10 | @author @My_Project_Author@ 11 | @bug 12 | 13 | **/ 14 | 15 | /* 16 | 17 | @My_Project_Copyright@ 18 | 19 | 20 | @My_Project_License_Indented@ 21 | 22 | */ 23 | 24 | 25 | #ifndef FILE_@My_Project_Title_Caps@_H 26 | #define FILE_@My_Project_Title_Caps@_H 27 | 28 | #ifdef TEST 29 | #include "CuTest.h" 30 | #endif 31 | 32 | 33 | /// This is a sample function with a doxygen description. 34 | // void void_f(void); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /templates/version.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | version.h -- @My_Project_Title@ 4 | 5 | @My_Project_Copyright@ 6 | 7 | 8 | @My_Project_License_Indent@ 9 | 10 | */ 11 | 12 | /** 13 | 14 | @file 15 | 16 | @brief @My_Project_Description@ - project version header 17 | 18 | **/ 19 | 20 | 21 | #ifndef FILE_@My_Project_Title_Caps@_H 22 | #define FILE_@My_Project_Title_Caps@_H 23 | 24 | #define @My_Project_Title_Caps@_NAME "@My_Project_Title@" 25 | 26 | #define @My_Project_Title_Caps@_VERSION "@My_Project_Version@" 27 | #define @My_Project_Title_Caps@_COPYRIGHT "@My_Project_Copyright@" 28 | 29 | #define @My_Project_Title_Caps@_LICENSE "\t@My_Project_License_Literal@" 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /test/CuTest.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | CuTest 4 | 5 | http://cutest.sourceforge.net/ 6 | 7 | NOTE 8 | 9 | The license is based on the zlib/libpng license. For more details see 10 | http://www.opensource.org/licenses/zlib-license.html. The intent of the 11 | license is to: 12 | 13 | - keep the license as simple as possible 14 | - encourage the use of CuTest in both free and commercial applications 15 | and libraries 16 | - keep the source code together 17 | - give credit to the CuTest contributors for their work 18 | 19 | If you ship CuTest in source form with your source distribution, the 20 | following license document must be included with it in unaltered form. 21 | If you find CuTest useful we would like to hear about it. 22 | 23 | LICENSE 24 | 25 | Copyright (c) 2003 Asim Jalis 26 | 27 | This software is provided 'as-is', without any express or implied 28 | warranty. In no event will the authors be held liable for any damages 29 | arising from the use of this software. 30 | 31 | Permission is granted to anyone to use this software for any purpose, 32 | including commercial applications, and to alter it and redistribute it 33 | freely, subject to the following restrictions: 34 | 35 | 1. The origin of this software must not be misrepresented; you must not 36 | claim that you wrote the original software. If you use this software in 37 | a product, an acknowledgment in the product documentation would be 38 | appreciated but is not required. 39 | 40 | 2. Altered source versions must be plainly marked as such, and must not 41 | be misrepresented as being the original software. 42 | 43 | 3. This notice may not be removed or altered from any source 44 | distribution. 45 | 46 | */ 47 | 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | 55 | #include "CuTest.h" 56 | 57 | /*-------------------------------------------------------------------------* 58 | * CuStr 59 | *-------------------------------------------------------------------------*/ 60 | 61 | char* CuStrAlloc(int size) 62 | { 63 | char* newStr = (char*) malloc( sizeof(char) * (size) ); 64 | return newStr; 65 | } 66 | 67 | char* CuStrCopy(const char* old) 68 | { 69 | int len = (int) strlen(old); 70 | char* newStr = CuStrAlloc(len + 1); 71 | strcpy(newStr, old); 72 | return newStr; 73 | } 74 | 75 | /*-------------------------------------------------------------------------* 76 | * CuString 77 | *-------------------------------------------------------------------------*/ 78 | 79 | void CuStringInit(CuString* str) 80 | { 81 | str->length = 0; 82 | str->size = STRING_MAX; 83 | str->buffer = (char*) malloc(sizeof(char) * str->size); 84 | str->buffer[0] = '\0'; 85 | } 86 | 87 | CuString* CuStringNew(void) 88 | { 89 | CuString* str = (CuString*) malloc(sizeof(CuString)); 90 | str->length = 0; 91 | str->size = STRING_MAX; 92 | str->buffer = (char*) malloc(sizeof(char) * str->size); 93 | str->buffer[0] = '\0'; 94 | return str; 95 | } 96 | 97 | void CuStringDelete(CuString *str) 98 | { 99 | if (!str) return; 100 | free(str->buffer); 101 | free(str); 102 | } 103 | 104 | void CuStringResize(CuString* str, int newSize) 105 | { 106 | str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize); 107 | str->size = newSize; 108 | } 109 | 110 | void CuStringAppend(CuString* str, const char* text) 111 | { 112 | int length; 113 | 114 | if (text == NULL) { 115 | text = "NULL"; 116 | } 117 | 118 | length = (int) strlen(text); 119 | if (str->length + length + 1 >= str->size) 120 | CuStringResize(str, str->length + length + 1 + STRING_INC); 121 | str->length += length; 122 | strcat(str->buffer, text); 123 | } 124 | 125 | void CuStringAppendChar(CuString* str, char ch) 126 | { 127 | char text[2]; 128 | text[0] = ch; 129 | text[1] = '\0'; 130 | CuStringAppend(str, text); 131 | } 132 | 133 | void CuStringAppendFormat(CuString* str, const char* format, ...) 134 | { 135 | va_list argp; 136 | char buf[HUGE_STRING_LEN]; 137 | va_start(argp, format); 138 | vsprintf(buf, format, argp); 139 | va_end(argp); 140 | CuStringAppend(str, buf); 141 | } 142 | 143 | void CuStringInsert(CuString* str, const char* text, int pos) 144 | { 145 | int length = (int) strlen(text); 146 | if (pos > str->length) 147 | pos = str->length; 148 | if (str->length + length + 1 >= str->size) 149 | CuStringResize(str, str->length + length + 1 + STRING_INC); 150 | memmove(str->buffer + pos + length, str->buffer + pos, (str->length - pos) + 1); 151 | str->length += length; 152 | memcpy(str->buffer + pos, text, length); 153 | } 154 | 155 | /*-------------------------------------------------------------------------* 156 | * CuTest 157 | *-------------------------------------------------------------------------*/ 158 | 159 | void CuTestInit(CuTest* t, const char* name, TestFunction function) 160 | { 161 | t->name = CuStrCopy(name); 162 | t->failed = 0; 163 | t->ran = 0; 164 | t->message = NULL; 165 | t->function = function; 166 | t->jumpBuf = NULL; 167 | } 168 | 169 | CuTest* CuTestNew(const char* name, TestFunction function) 170 | { 171 | CuTest* tc = CU_ALLOC(CuTest); 172 | CuTestInit(tc, name, function); 173 | return tc; 174 | } 175 | 176 | void CuTestDelete(CuTest *t) 177 | { 178 | if (!t) return; 179 | free(t->name); 180 | free(t); 181 | } 182 | 183 | void CuTestRun(CuTest* tc) 184 | { 185 | jmp_buf buf; 186 | tc->jumpBuf = &buf; 187 | if (setjmp(buf) == 0) 188 | { 189 | tc->ran = 1; 190 | (tc->function)(tc); 191 | } 192 | tc->jumpBuf = 0; 193 | } 194 | 195 | static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string) 196 | { 197 | char buf[HUGE_STRING_LEN]; 198 | 199 | sprintf(buf, "%s:%d: ", file, line); 200 | CuStringInsert(string, buf, 0); 201 | 202 | tc->failed = 1; 203 | tc->message = string->buffer; 204 | if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0); 205 | } 206 | 207 | void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message) 208 | { 209 | CuString string; 210 | 211 | CuStringInit(&string); 212 | if (message2 != NULL) 213 | { 214 | CuStringAppend(&string, message2); 215 | CuStringAppend(&string, ": "); 216 | } 217 | CuStringAppend(&string, message); 218 | CuFailInternal(tc, file, line, &string); 219 | } 220 | 221 | void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition) 222 | { 223 | if (condition) return; 224 | CuFail_Line(tc, file, line, NULL, message); 225 | } 226 | 227 | void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 228 | const char* expected, const char* actual) 229 | { 230 | CuString string; 231 | if ((expected == NULL && actual == NULL) || 232 | (expected != NULL && actual != NULL && 233 | strcmp(expected, actual) == 0)) 234 | { 235 | return; 236 | } 237 | 238 | CuStringInit(&string); 239 | if (message != NULL) 240 | { 241 | CuStringAppend(&string, message); 242 | CuStringAppend(&string, ": "); 243 | } 244 | CuStringAppend(&string, "expected <"); 245 | CuStringAppend(&string, expected); 246 | CuStringAppend(&string, "> but was <"); 247 | CuStringAppend(&string, actual); 248 | CuStringAppend(&string, ">"); 249 | CuFailInternal(tc, file, line, &string); 250 | } 251 | 252 | void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 253 | int expected, int actual) 254 | { 255 | char buf[STRING_MAX]; 256 | if (expected == actual) return; 257 | sprintf(buf, "expected <%d> but was <%d>", expected, actual); 258 | CuFail_Line(tc, file, line, message, buf); 259 | } 260 | 261 | void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 262 | double expected, double actual, double delta) 263 | { 264 | char buf[STRING_MAX]; 265 | if (fabs(expected - actual) <= delta) return; 266 | sprintf(buf, "expected <%f> but was <%f>", expected, actual); 267 | 268 | CuFail_Line(tc, file, line, message, buf); 269 | } 270 | 271 | void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 272 | void* expected, void* actual) 273 | { 274 | char buf[STRING_MAX]; 275 | if (expected == actual) return; 276 | sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual); 277 | CuFail_Line(tc, file, line, message, buf); 278 | } 279 | 280 | 281 | /*-------------------------------------------------------------------------* 282 | * CuSuite 283 | *-------------------------------------------------------------------------*/ 284 | 285 | void CuSuiteInit(CuSuite* testSuite) 286 | { 287 | testSuite->count = 0; 288 | testSuite->failCount = 0; 289 | memset(testSuite->list, 0, sizeof(testSuite->list)); 290 | } 291 | 292 | CuSuite* CuSuiteNew(void) 293 | { 294 | CuSuite* testSuite = CU_ALLOC(CuSuite); 295 | CuSuiteInit(testSuite); 296 | return testSuite; 297 | } 298 | 299 | void CuSuiteDelete(CuSuite *testSuite) 300 | { 301 | unsigned int n; 302 | for (n=0; n < MAX_TEST_CASES; n++) 303 | { 304 | if (testSuite->list[n]) 305 | { 306 | CuTestDelete(testSuite->list[n]); 307 | } 308 | } 309 | free(testSuite); 310 | 311 | } 312 | 313 | void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) 314 | { 315 | assert(testSuite->count < MAX_TEST_CASES); 316 | testSuite->list[testSuite->count] = testCase; 317 | testSuite->count++; 318 | } 319 | 320 | void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2) 321 | { 322 | int i; 323 | for (i = 0 ; i < testSuite2->count ; ++i) 324 | { 325 | CuTest* testCase = testSuite2->list[i]; 326 | CuSuiteAdd(testSuite, testCase); 327 | } 328 | } 329 | 330 | void CuSuiteRun(CuSuite* testSuite) 331 | { 332 | int i; 333 | for (i = 0 ; i < testSuite->count ; ++i) 334 | { 335 | CuTest* testCase = testSuite->list[i]; 336 | CuTestRun(testCase); 337 | if (testCase->failed) { testSuite->failCount += 1; } 338 | } 339 | } 340 | 341 | void CuSuiteSummary(CuSuite* testSuite, CuString* summary) 342 | { 343 | int i; 344 | for (i = 0 ; i < testSuite->count ; ++i) 345 | { 346 | CuTest* testCase = testSuite->list[i]; 347 | CuStringAppend(summary, testCase->failed ? "F" : "."); 348 | } 349 | CuStringAppend(summary, "\n\n"); 350 | } 351 | 352 | void CuSuiteDetails(CuSuite* testSuite, CuString* details) 353 | { 354 | int i; 355 | int failCount = 0; 356 | 357 | if (testSuite->failCount == 0) 358 | { 359 | int passCount = testSuite->count - testSuite->failCount; 360 | const char* testWord = passCount == 1 ? "test" : "tests"; 361 | CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord); 362 | } 363 | else 364 | { 365 | if (testSuite->failCount == 1) 366 | CuStringAppend(details, "There was 1 failure:\n"); 367 | else 368 | CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount); 369 | 370 | for (i = 0 ; i < testSuite->count ; ++i) 371 | { 372 | CuTest* testCase = testSuite->list[i]; 373 | if (testCase->failed) 374 | { 375 | failCount++; 376 | CuStringAppendFormat(details, "%d) %s: %s\n", 377 | failCount, testCase->name, testCase->message); 378 | } 379 | } 380 | CuStringAppend(details, "\n!!!FAILURES!!!\n"); 381 | 382 | CuStringAppendFormat(details, "Runs: %d ", testSuite->count); 383 | CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount); 384 | CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount); 385 | } 386 | } 387 | -------------------------------------------------------------------------------- /test/CuTest.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | CuTest 4 | 5 | http://cutest.sourceforge.net/ 6 | 7 | NOTE 8 | 9 | The license is based on the zlib/libpng license. For more details see 10 | http://www.opensource.org/licenses/zlib-license.html. The intent of the 11 | license is to: 12 | 13 | - keep the license as simple as possible 14 | - encourage the use of CuTest in both free and commercial applications 15 | and libraries 16 | - keep the source code together 17 | - give credit to the CuTest contributors for their work 18 | 19 | If you ship CuTest in source form with your source distribution, the 20 | following license document must be included with it in unaltered form. 21 | If you find CuTest useful we would like to hear about it. 22 | 23 | LICENSE 24 | 25 | Copyright (c) 2003 Asim Jalis 26 | 27 | This software is provided 'as-is', without any express or implied 28 | warranty. In no event will the authors be held liable for any damages 29 | arising from the use of this software. 30 | 31 | Permission is granted to anyone to use this software for any purpose, 32 | including commercial applications, and to alter it and redistribute it 33 | freely, subject to the following restrictions: 34 | 35 | 1. The origin of this software must not be misrepresented; you must not 36 | claim that you wrote the original software. If you use this software in 37 | a product, an acknowledgment in the product documentation would be 38 | appreciated but is not required. 39 | 40 | 2. Altered source versions must be plainly marked as such, and must not 41 | be misrepresented as being the original software. 42 | 43 | 3. This notice may not be removed or altered from any source 44 | distribution. 45 | 46 | */ 47 | 48 | #ifndef CU_TEST_H 49 | #define CU_TEST_H 50 | 51 | #include 52 | #include 53 | 54 | #define CUTEST_VERSION "CuTest 1.5" 55 | 56 | /* CuString */ 57 | 58 | char* CuStrAlloc(int size); 59 | char* CuStrCopy(const char* old); 60 | 61 | #define CU_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE))) 62 | 63 | #define HUGE_STRING_LEN 8192 64 | #define STRING_MAX 256 65 | #define STRING_INC 256 66 | 67 | typedef struct 68 | { 69 | int length; 70 | int size; 71 | char* buffer; 72 | } CuString; 73 | 74 | void CuStringInit(CuString* str); 75 | CuString* CuStringNew(void); 76 | void CuStringRead(CuString* str, const char* path); 77 | void CuStringAppend(CuString* str, const char* text); 78 | void CuStringAppendChar(CuString* str, char ch); 79 | void CuStringAppendFormat(CuString* str, const char* format, ...); 80 | void CuStringInsert(CuString* str, const char* text, int pos); 81 | void CuStringResize(CuString* str, int newSize); 82 | void CuStringDelete(CuString* str); 83 | 84 | /* CuTest */ 85 | 86 | typedef struct CuTest CuTest; 87 | 88 | typedef void (*TestFunction)(CuTest *); 89 | 90 | struct CuTest 91 | { 92 | char* name; 93 | TestFunction function; 94 | int failed; 95 | int ran; 96 | const char* message; 97 | jmp_buf *jumpBuf; 98 | }; 99 | 100 | void CuTestInit(CuTest* t, const char* name, TestFunction function); 101 | CuTest* CuTestNew(const char* name, TestFunction function); 102 | void CuTestRun(CuTest* tc); 103 | void CuTestDelete(CuTest *t); 104 | 105 | /* Internal versions of assert functions -- use the public versions */ 106 | void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message); 107 | void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition); 108 | void CuAssertStrEquals_LineMsg(CuTest* tc, 109 | const char* file, int line, const char* message, 110 | const char* expected, const char* actual); 111 | void CuAssertIntEquals_LineMsg(CuTest* tc, 112 | const char* file, int line, const char* message, 113 | int expected, int actual); 114 | void CuAssertDblEquals_LineMsg(CuTest* tc, 115 | const char* file, int line, const char* message, 116 | double expected, double actual, double delta); 117 | void CuAssertPtrEquals_LineMsg(CuTest* tc, 118 | const char* file, int line, const char* message, 119 | void* expected, void* actual); 120 | 121 | /* public assert functions */ 122 | 123 | #define CuFail(tc, ms) CuFail_Line( (tc), __FILE__, __LINE__, NULL, (ms)) 124 | #define CuAssert(tc, ms, cond) CuAssert_Line((tc), __FILE__, __LINE__, (ms), (cond)) 125 | #define CuAssertTrue(tc, cond) CuAssert_Line((tc), __FILE__, __LINE__, "assert failed", (cond)) 126 | 127 | #define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) 128 | #define CuAssertStrEquals_Msg(tc,ms,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) 129 | #define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) 130 | #define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) 131 | #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) 132 | #define CuAssertDblEquals_Msg(tc,ms,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac),(dl)) 133 | #define CuAssertPtrEquals(tc,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) 134 | #define CuAssertPtrEquals_Msg(tc,ms,ex,ac) CuAssertPtrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) 135 | 136 | #define CuAssertPtrNotNull(tc,p) CuAssert_Line((tc),__FILE__,__LINE__,"null pointer unexpected",(p != NULL)) 137 | #define CuAssertPtrNotNullMsg(tc,msg,p) CuAssert_Line((tc),__FILE__,__LINE__,(msg),(p != NULL)) 138 | 139 | /* CuSuite */ 140 | 141 | #define MAX_TEST_CASES 1024 142 | 143 | #define SUITE_ADD_TEST(SUITE,TEST) CuSuiteAdd(SUITE, CuTestNew(#TEST, TEST)) 144 | 145 | typedef struct 146 | { 147 | int count; 148 | CuTest* list[MAX_TEST_CASES]; 149 | int failCount; 150 | 151 | } CuSuite; 152 | 153 | 154 | void CuSuiteInit(CuSuite* testSuite); 155 | CuSuite* CuSuiteNew(void); 156 | void CuSuiteDelete(CuSuite *testSuite); 157 | void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase); 158 | void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2); 159 | void CuSuiteRun(CuSuite* testSuite); 160 | void CuSuiteSummary(CuSuite* testSuite, CuString* summary); 161 | void CuSuiteDetails(CuSuite* testSuite, CuString* details); 162 | 163 | #endif /* CU_TEST_H */ 164 | -------------------------------------------------------------------------------- /test/make-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Auto generate single AllTests file for CuTest. 4 | # Searches through all *.c files in the current directory. 5 | # Prints to stdout. 6 | # Author: Asim Jalis 7 | # Date: 01/08/2003 8 | # 9 | # Modified by Fletcher T. Penney for proper error codes 10 | # Modified by Fletcher T. Penney to handle spaces in path names 11 | 12 | if test $# -eq 0 ; then FILES=("*.c") ; else FILES=("$@") ; fi 13 | 14 | echo ' 15 | 16 | /* This is auto-generated code. Edit at your own peril. */ 17 | #include 18 | #include 19 | 20 | #include "CuTest.h" 21 | 22 | ' 23 | 24 | cat "${FILES[@]}" | grep '^void Test' | 25 | sed -e 's/(.*$//' \ 26 | -e 's/$/(CuTest*);/' \ 27 | -e 's/^/extern /' 28 | 29 | echo \ 30 | ' 31 | 32 | void RunAllTests(void) 33 | { 34 | CuString *output = CuStringNew(); 35 | CuSuite* suite = CuSuiteNew(); 36 | int failCount = 0; 37 | 38 | ' 39 | cat "${FILES[@]}" | grep '^void Test' | 40 | sed -e 's/^void //' \ 41 | -e 's/(.*$//' \ 42 | -e 's/^/ SUITE_ADD_TEST(suite, /' \ 43 | -e 's/$/);/' 44 | 45 | echo \ 46 | ' 47 | CuSuiteRun(suite); 48 | CuSuiteSummary(suite, output); 49 | CuSuiteDetails(suite, output); 50 | printf("%s\\n", output->buffer); 51 | CuStringDelete(output); 52 | 53 | failCount = suite->failCount; 54 | CuSuiteDelete(suite); 55 | 56 | if (failCount != 0) 57 | exit(EXIT_FAILURE); 58 | 59 | exit(EXIT_SUCCESS); 60 | } 61 | 62 | int main(void) 63 | { 64 | RunAllTests(); 65 | } 66 | ' 67 | -------------------------------------------------------------------------------- /tools/Toolchain-MinGW-w64-32bit.cmake: -------------------------------------------------------------------------------- 1 | # Settings for compiling for Windows 32-bit machines using MinGW-w64 2 | 3 | set (IS_CROSSCOMPILING "YES") 4 | set (IS_32_BIT "32-") 5 | 6 | set (CMAKE_SYSTEM_NAME Windows) 7 | 8 | set (CMAKE_C_COMPILER i686-w64-mingw32-gcc) 9 | set (CMAKE_CXX_COMPILER i686-w64-mingw32-g++) 10 | set (CMAKE_RC_COMPILER i686-w64-mingw32-windres) 11 | 12 | set (CMAKE_FIND_ROOT_PATH /usr/bin) 13 | -------------------------------------------------------------------------------- /tools/Toolchain-MinGW-w64-64bit.cmake: -------------------------------------------------------------------------------- 1 | # Settings for compiling for Windows 64-bit machines using MinGW-w64 2 | 3 | set (IS_CROSSCOMPILING "YES") 4 | 5 | set (CMAKE_SYSTEM_NAME Windows) 6 | 7 | set (CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) 8 | set (CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) 9 | set (CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) 10 | 11 | set (CMAKE_FIND_ROOT_PATH /usr/bin) 12 | -------------------------------------------------------------------------------- /tools/Toolchain-mingw32.cmake: -------------------------------------------------------------------------------- 1 | # Settings for compiling for Windows 32-bit machines 2 | 3 | set (IS_CROSSCOMPILING "YES") 4 | set (IS_32_BIT "32-") 5 | 6 | set (CMAKE_SYSTEM_NAME Windows) 7 | 8 | set (CMAKE_C_COMPILER i586-mingw32msvc-gcc) 9 | set (CMAKE_CXX_COMPILER i586-mingw32msvc-g++) 10 | set (CMAKE_RC_COMPILER i586-mingw32msvc-windres) 11 | 12 | set (CMAKE_FIND_ROOT_PATH /usr/bin) 13 | -------------------------------------------------------------------------------- /update_git_modules: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This command can be run any time to ensure that all submodules are on 4 | # the most recent commit for the configured branch, as set up 5 | # in the `link_git_modules` script. 6 | 7 | git submodule foreach git pull origin 8 | --------------------------------------------------------------------------------