├── .github └── workflows │ └── test.yml ├── .gitignore ├── .run └── st_utest.run.xml ├── Dockerfile.cov ├── Dockerfile.test ├── LICENSE ├── Makefile ├── README ├── README.md ├── auto ├── codecov.sh ├── coverage.sh └── fast.sh ├── common.h ├── docs ├── fig.gif ├── notes.html ├── reference.html ├── st.html └── timeout_heap.txt ├── event.c ├── ide └── st_clion │ └── CMakeLists.txt ├── io.c ├── key.c ├── libst.def ├── md.h ├── md_cygwin64.S ├── md_darwin.S ├── md_linux.S ├── md_linux2.S ├── osguess.sh ├── public.h ├── sched.c ├── st.pc.in ├── st.spec ├── stk.c ├── sync.c ├── tools ├── backtrace │ ├── .gitignore │ ├── Makefile │ └── backtrace.c ├── helloworld │ ├── .gitignore │ ├── Makefile │ └── helloworld.c ├── jmpbuf │ ├── .gitignore │ ├── Makefile │ └── jmpbuf.c ├── pcs │ ├── .gitignore │ ├── Makefile │ └── pcs.c ├── porting │ ├── .gitignore │ ├── Makefile │ └── porting.c ├── stack │ ├── .gitignore │ ├── Makefile │ └── stack.c └── verify │ ├── .gitignore │ ├── Makefile │ └── verify.c └── utest ├── Makefile ├── gtest-fit ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── googlemock │ ├── CMakeLists.txt │ ├── README.md │ ├── cmake │ │ ├── gmock.pc.in │ │ └── gmock_main.pc.in │ ├── include │ │ └── gmock │ │ │ ├── gmock-actions.h │ │ │ ├── gmock-cardinalities.h │ │ │ ├── gmock-function-mocker.h │ │ │ ├── gmock-matchers.h │ │ │ ├── gmock-more-actions.h │ │ │ ├── gmock-more-matchers.h │ │ │ ├── gmock-nice-strict.h │ │ │ ├── gmock-spec-builders.h │ │ │ ├── gmock.h │ │ │ └── internal │ │ │ ├── custom │ │ │ ├── README.md │ │ │ ├── gmock-generated-actions.h │ │ │ ├── gmock-matchers.h │ │ │ └── gmock-port.h │ │ │ ├── gmock-internal-utils.h │ │ │ ├── gmock-port.h │ │ │ └── gmock-pp.h │ └── src │ │ ├── gmock-all.cc │ │ ├── gmock-cardinalities.cc │ │ ├── gmock-internal-utils.cc │ │ ├── gmock-matchers.cc │ │ ├── gmock-spec-builders.cc │ │ ├── gmock.cc │ │ └── gmock_main.cc └── googletest │ ├── CMakeLists.txt │ ├── README.md │ ├── cmake │ ├── Config.cmake.in │ ├── gtest.pc.in │ ├── gtest_main.pc.in │ ├── internal_utils.cmake │ └── libgtest.la.in │ ├── include │ └── gtest │ │ ├── gtest-death-test.h │ │ ├── gtest-matchers.h │ │ ├── gtest-message.h │ │ ├── gtest-param-test.h │ │ ├── gtest-printers.h │ │ ├── gtest-spi.h │ │ ├── gtest-test-part.h │ │ ├── gtest-typed-test.h │ │ ├── gtest.h │ │ ├── gtest_pred_impl.h │ │ ├── gtest_prod.h │ │ └── internal │ │ ├── custom │ │ ├── README.md │ │ ├── gtest-port.h │ │ ├── gtest-printers.h │ │ └── gtest.h │ │ ├── gtest-death-test-internal.h │ │ ├── gtest-filepath.h │ │ ├── gtest-internal.h │ │ ├── gtest-param-util.h │ │ ├── gtest-port-arch.h │ │ ├── gtest-port.h │ │ ├── gtest-string.h │ │ └── gtest-type-util.h │ └── src │ ├── gtest-all.cc │ ├── gtest-death-test.cc │ ├── gtest-filepath.cc │ ├── gtest-internal-inl.h │ ├── gtest-matchers.cc │ ├── gtest-port.cc │ ├── gtest-printers.cc │ ├── gtest-test-part.cc │ ├── gtest-typed-test.cc │ ├── gtest.cc │ └── gtest_main.cc ├── st_utest.cpp ├── st_utest.hpp ├── st_utest_coroutines.cpp └── st_utest_tcp.cpp /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: "Test" 2 | 3 | # @see https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#onpushpull_requestbranchestags 4 | on: [push, pull_request] 5 | 6 | jobs: 7 | utest: 8 | name: actions-test-utest 9 | runs-on: ubuntu-20.04 10 | 11 | steps: 12 | - name: Checkout repository 13 | uses: actions/checkout@v2 14 | 15 | ################################################################ 16 | # Tests 17 | - name: Build test image 18 | run: docker build --tag st:test -f Dockerfile.test . 19 | # For utest 20 | - name: Run ST utest 21 | run: docker run --rm st:test bash -c 'make linux-debug-utest && ./obj/st_utest' 22 | 23 | coverage: 24 | name: actions-test-coverage 25 | runs-on: ubuntu-20.04 26 | 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v2 30 | 31 | ################################################################ 32 | # Tests 33 | - name: Build coverage image 34 | run: docker build --tag st:cov -f Dockerfile.cov . 35 | # For coverage, only allow push to branch(refs/heads/4.0release) or pull requests(refs/pull/2536/merge). 36 | - name: Run ST covergae 37 | if: ${{ startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/pull/') }} 38 | env: 39 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 40 | run: | 41 | # The hash of commit. 42 | ST_SHA=${{ github.sha }} 43 | # Note that the root of ST, must contains .git, for report fixing. 44 | ST_PROJECT=/st 45 | # The github.ref is, for example, refs/heads/4.0release 46 | ST_BRANCH=$(echo ${{ github.ref }}| awk -F 'refs/heads/' '{print $2}'| awk -F '/' '{print $1}') 47 | # The github.ref is, for example, refs/pull/2536/merge 48 | ST_PR=$(echo ${{ github.ref }}| awk -F 'refs/pull/' '{print $2}'| awk -F '/' '{print $1}') 49 | # 50 | echo "For github.ref=${{ github.ref }}, github.sha=${{ github.sha }}" 51 | echo "ST_BRANCH=$ST_BRANCH, ST_PR=$ST_PR, ST_SHA=$ST_SHA, ST_PROJECT=$ST_PROJECT" 52 | docker run --rm --env CODECOV_TOKEN=$CODECOV_TOKEN \ 53 | --env ST_BRANCH=$ST_BRANCH --env ST_PR=$ST_PR --env ST_SHA=$ST_SHA --env ST_PROJECT=$ST_PROJECT \ 54 | st:cov bash -c 'make linux-debug-gcov && ./obj/st_utest && bash auto/codecov.sh' 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | DARWIN_*_DBG 2 | LINUX_*_DBG 3 | CYGWIN64_*_DBG 4 | obj 5 | st.pc 6 | .idea 7 | 8 | gtest* 9 | googletest-* 10 | *.gcda 11 | *.gcno 12 | coverage 13 | codecov 14 | *.dSYM 15 | 16 | srs 17 | cmake-build-debug 18 | /ide/st_clion/CMakeCache.txt 19 | /ide/st_clion/CMakeFiles 20 | /ide/st_clion/Makefile 21 | /ide/st_clion/cmake_install.cmake 22 | /ide/st_clion/st 23 | /ide/st_clion/Testing/ 24 | .DS_Store 25 | 26 | -------------------------------------------------------------------------------- /.run/st_utest.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /Dockerfile.cov: -------------------------------------------------------------------------------- 1 | FROM ossrs/srs:dev-gcc7 2 | 3 | # Install depends tools. 4 | RUN yum install -y gcc make gcc-c++ patch unzip perl git 5 | 6 | # Build and install SRS. 7 | COPY . /st 8 | WORKDIR /st 9 | 10 | # Note that we must enable the gcc7 or link failed. 11 | RUN scl enable devtoolset-7 -- make linux-debug-gcov 12 | 13 | -------------------------------------------------------------------------------- /Dockerfile.test: -------------------------------------------------------------------------------- 1 | FROM ossrs/srs:dev-gcc7 2 | 3 | # Install depends tools. 4 | RUN yum install -y gcc make gcc-c++ patch unzip perl git 5 | 6 | # Build and install SRS. 7 | COPY . /st 8 | WORKDIR /st 9 | 10 | # Note that we must enable the gcc7 or link failed. 11 | RUN scl enable devtoolset-7 -- make linux-debug-utest 12 | 13 | # Run utest 14 | RUN ./obj/st_utest 15 | 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The state-threads is provided under the terms of the MPL-1.1 or the 2 | GPL-2.0-or-later. For more information about these licenses, please see 3 | https://spdx.org/licenses/MPL-1.1.html and 4 | https://spdx.org/licenses/GPL-2.0-or-later.html 5 | 6 | Individual files contain the following tag instead of the full license text. 7 | 8 | SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later 9 | 10 | New source code and all source code in the "tools" and "utest" directory 11 | is distributed under the MIT style license. 12 | 13 | SPDX-License-Identifier: MIT 14 | 15 | This enables machine processing of license information based on the SPDX 16 | License Identifiers that are here available: http://spdx.org/licenses/ 17 | 18 | --------------------------------------------------------------------------- 19 | Note: https://github.com/ossrs/state-threads/blob/srs/README#L68 20 | 21 | The State Threads library is a derivative of the Netscape Portable 22 | Runtime library (NSPR). All source code in this directory is 23 | distributed under the terms of the Mozilla Public License (MPL) version 24 | 1.1 or the GNU General Public License (GPL) version 2 or later. For 25 | more information about these licenses please see 26 | http://www.mozilla.org/MPL/ and http://www.gnu.org/copyleft/. 27 | 28 | All source code in the "examples" directory is distributed under the BSD 29 | style license. 30 | 31 | -------------------------------------------------------------------------------- /auto/codecov.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Workdir is obj/coverage. 4 | workdir=`pwd`/coverage 5 | 6 | # Create trunk under workdir. 7 | mkdir -p $workdir && cd $workdir 8 | ret=$?; if [[ $ret -ne 0 ]]; then echo "Enter workdir failed, ret=$ret"; exit $ret; fi 9 | 10 | CODECOV_ARGS="" 11 | if [[ $ST_PROJECT != '' ]]; then 12 | # -R root dir Used when not in git/hg project to identify project root directory 13 | # -p dir Project root directory. Also used when preparing gcov 14 | CODECOV_ARGS="$CODECOV_ARGS -R $ST_PROJECT -p $ST_PROJECT" 15 | fi 16 | if [[ $ST_BRANCH != '' ]]; then 17 | # -B branch Specify the branch name 18 | CODECOV_ARGS="$CODECOV_ARGS -B $ST_BRANCH" 19 | fi 20 | if [[ $ST_SHA != '' ]]; then 21 | # -C sha Specify the commit sha 22 | CODECOV_ARGS="$CODECOV_ARGS -C $ST_SHA" 23 | fi 24 | if [[ $ST_PR != '' ]]; then 25 | # -P pr Specify the pull request number 26 | CODECOV_ARGS="$CODECOV_ARGS -P $ST_PR" 27 | fi 28 | 29 | # Upload report with *.gcov 30 | # Remark: The file codecov.yml is not neccessary. It literally depends on git. 31 | # Note: The right path is like: 32 | # https://app.codecov.io/gh/ossrs/state-threads/blob/srs/sched.c 33 | # https://app.codecov.io/gh/ossrs/state-threads/blob/593cf748f055ca383867003e409a423efd8f8f86/sched.c 34 | cd $workdir && 35 | export CODECOV_TOKEN="$CODECOV_TOKEN" && 36 | bash <(curl -s https://codecov.io/bash) $CODECOV_ARGS -f '!*gtest*' -f '!*c++*' && 37 | echo "Done" && exit 0 38 | 39 | -------------------------------------------------------------------------------- /auto/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ ! -f utest/gtest-fit/googletest/include/gtest/gtest.h ]]; then 4 | echo "No utest/gtest, please download from https://github.com/google/googletest/releases/tag/release-1.11.0" 5 | exit -1 6 | else 7 | echo "Check utest/gtest ok" 8 | fi 9 | 10 | if [[ $(gcovr --version >/dev/null && echo yes) != yes ]]; then 11 | echo "Please install gcovr" 12 | exit -1 13 | fi 14 | 15 | IS_LINUX=yes 16 | uname -s|grep Darwin >/dev/null && IS_DARWIN=yes && IS_LINUX=no 17 | echo "IS_LINUX: $IS_LINUX, IS_DARWIN: $IS_DARWIN" 18 | 19 | echo "Build and run utest" 20 | if [[ $IS_DARWIN == yes ]]; then 21 | make clean && make darwin-debug-gcov && ./obj/st_utest 22 | else 23 | make clean && make linux-debug-gcov && ./obj/st_utest 24 | fi 25 | 26 | echo "Generating coverage" 27 | mkdir -p coverage && 28 | (cd obj && rm -f gtest-all.gcda gtest-all.gcno) && 29 | (cd obj && rm -f *.c *.cpp gtest-fit && ln -sf ../*.c . && ln -sf ../utest/*.cpp && ln -sf ../utest/gtest-fit .) && 30 | (cd obj && gcovr --gcov-exclude gtest --html --html-details -o ../coverage/st.html) && 31 | (cd obj && rm -f *.c *.cpp gtest-fit) && 32 | echo "Coverage report at coverage/st.html" && 33 | open coverage/st.html 34 | -------------------------------------------------------------------------------- /auto/fast.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PWD=$(cd `dirname $0`/.. && pwd) 4 | 5 | pushd $PWD 6 | echo "Run UTest in $(pwd)" 7 | 8 | IS_LINUX=yes 9 | uname -s|grep Darwin >/dev/null && IS_DARWIN=yes && IS_LINUX=no 10 | echo "IS_LINUX: $IS_LINUX, IS_DARWIN: $IS_DARWIN" 11 | 12 | echo "Clean gcda files" 13 | rm -f ./obj/*.gcda 14 | 15 | echo "Build and run utest" 16 | if [[ $IS_DARWIN == yes ]]; then 17 | make darwin-debug-gcov && ./obj/st_utest 18 | else 19 | make linux-debug-gcov && ./obj/st_utest 20 | fi 21 | ret=$?; if [[ 0 -ne $ret ]]; then echo "Make ST utest fail, ret=$ret"; exit $ret; fi 22 | 23 | echo "Generating coverage" 24 | mkdir -p coverage && 25 | (cd obj && rm -f gtest-all.gcda gtest-all.gcno) && 26 | (cd obj && rm -f *.c *.cpp gtest-fit && ln -sf ../*.c . && ln -sf ../utest/*.cpp && ln -sf ../utest/gtest-fit .) && 27 | (cd obj && gcovr --gcov-exclude gtest --html --html-details -o ../coverage/st.html) && 28 | (cd obj && rm -f *.c *.cpp gtest-fit) && 29 | echo "Coverage report at coverage/st.html" && 30 | open coverage/st.html 31 | 32 | popd 33 | echo "UTest done, restore $(pwd)" -------------------------------------------------------------------------------- /docs/fig.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ossrs/state-threads/b01986064cf01de86cea7b24a2f95e7114ba3d75/docs/fig.gif -------------------------------------------------------------------------------- /docs/timeout_heap.txt: -------------------------------------------------------------------------------- 1 | How the timeout heap works 2 | 3 | As of version 1.5, the State Threads Library represents the queue of 4 | sleeping threads using a heap data structure rather than a sorted 5 | linked list. This improves performance when there is a large number 6 | of sleeping threads, since insertion into a heap takes O(log N) time 7 | while insertion into a sorted list takes O(N) time. For example, in 8 | one test 1000 threads were created, each thread called st_usleep() 9 | with a random time interval, and then all the threads where 10 | immediately interrupted and joined before the sleeps had a chance to 11 | finish. The whole process was repeated 1000 times, for a total of a 12 | million sleep queue insertions and removals. With the old list-based 13 | sleep queue, this test took 100 seconds; now it takes only 12 seconds. 14 | 15 | Heap data structures are typically based on dynamically resized 16 | arrays. However, since the existing ST code base was very nicely 17 | structured around linking the thread objects into pointer-based lists 18 | without the need for any auxiliary data structures, implementing the 19 | heap using a similar nodes-and-pointers based approach seemed more 20 | appropriate for ST than introducing a separate array. 21 | 22 | Thus, the new ST timeout heap works by organizing the existing 23 | _st_thread_t objects in a balanced binary tree, just as they were 24 | previously organized into a doubly-linked, sorted list. The global 25 | _ST_SLEEPQ variable, formerly a linked list head, is now simply a 26 | pointer to the root of this tree, and the root node of the tree is the 27 | thread with the earliest timeout. Each thread object has two child 28 | pointers, "left" and "right", pointing to threads with later timeouts. 29 | 30 | Each node in the tree is numbered with an integer index, corresponding 31 | to the array index in an array-based heap, and the tree is kept fully 32 | balanced and left-adjusted at all times. In other words, the tree 33 | consists of any number of fully populated top levels, followed by a 34 | single bottom level which may be partially populated, such that any 35 | existing nodes form a contiguous block to the left and the spaces for 36 | missing nodes form a contiguous block to the right. For example, if 37 | there are nine threads waiting for a timeout, they are numbered and 38 | arranged in a tree exactly as follows: 39 | 40 | 1 41 | / \ 42 | 2 3 43 | / \ / \ 44 | 4 5 6 7 45 | / \ 46 | 8 9 47 | 48 | Each node has either no children, only a left child, or both a left 49 | and a right child. Children always time out later than their parents 50 | (this is called the "heap invariant"), but when a node has two 51 | children, their mutual order is unspecified - the left child may time 52 | out before or after the right child. If a node is numbered N, its 53 | left child is numbered 2N, and its right child is numbered 2N+1. 54 | 55 | There is no pointer from a child to its parent; all pointers point 56 | downward. Additions and deletions both work by starting at the root 57 | and traversing the tree towards the leaves, going left or right 58 | according to the binary digits forming the index of the destination 59 | node. As nodes are added or deleted, existing nodes are rearranged to 60 | maintain the heap invariant. 61 | -------------------------------------------------------------------------------- /ide/st_clion/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Name of the project. 2 | # Language "C" is required for find_package(Threads). 3 | if (CMAKE_VERSION VERSION_LESS 3.0) 4 | project(st CXX C ASM) 5 | else() 6 | cmake_policy(SET CMP0048 NEW) 7 | project(st VERSION 4.0.0 LANGUAGES CXX C ASM) 8 | endif() 9 | cmake_minimum_required(VERSION 2.8.12) 10 | 11 | # For utest required C++11. 12 | set (CMAKE_CXX_STANDARD 11) 13 | 14 | ########################################################### 15 | execute_process( 16 | COMMAND bash -c "cd ${PROJECT_SOURCE_DIR}/../../ && pwd" 17 | OUTPUT_VARIABLE ST_DIR 18 | ) 19 | string(STRIP ${ST_DIR} ST_DIR) 20 | message("ST home is ${ST_DIR}") 21 | 22 | ########################################################### 23 | # Start to configure ST with jobs of number of CPUs. 24 | include(ProcessorCount) 25 | ProcessorCount(JOBS) 26 | 27 | # We should always configure ST for switching between branches. 28 | IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 29 | ADD_DEFINITIONS("-arch x86_64 -DDARWIN -DMD_HAVE_KQUEUE -DMD_HAVE_SELECT -DDEBUG") 30 | ELSE () 31 | ADD_DEFINITIONS("-DLINUX -DMD_HAVE_EPOLL -DMD_HAVE_SELECT -DDEBUG") 32 | ENDIF () 33 | 34 | EXEC_PROGRAM("cd ${ST_DIR} && mkdir -p obj && cp public.h obj/st.h") 35 | 36 | ########################################################### 37 | # For whole project. 38 | INCLUDE_DIRECTORIES(${ST_DIR}/obj ${ST_DIR}/utest ${ST_DIR}/utest/gtest/include) 39 | 40 | # Common used sources for SRS and utest. 41 | list(APPEND SOURCE_FILES ${ST_DIR}/event.c) 42 | list(APPEND SOURCE_FILES ${ST_DIR}/io.c) 43 | list(APPEND SOURCE_FILES ${ST_DIR}/key.c) 44 | list(APPEND SOURCE_FILES ${ST_DIR}/sched.c) 45 | list(APPEND SOURCE_FILES ${ST_DIR}/stk.c) 46 | list(APPEND SOURCE_FILES ${ST_DIR}/sync.c) 47 | IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 48 | list(APPEND SOURCE_FILES ${ST_DIR}/md_darwin.S) 49 | ELSE () 50 | list(APPEND SOURCE_FILES ${ST_DIR}/md_linux.S) 51 | list(APPEND SOURCE_FILES ${ST_DIR}/md_linux2.S) 52 | ENDIF () 53 | 54 | ADD_DEFINITIONS("-g -O0") 55 | 56 | ########################################################### 57 | # Setup ST utest project 58 | ADD_SUBDIRECTORY(${ST_DIR}/utest/gtest-fit gtest-fit) 59 | INCLUDE_DIRECTORIES(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) 60 | 61 | set(ST_UTEST_SOURCE_FILES ${SOURCE_FILES}) 62 | AUX_SOURCE_DIRECTORY(${ST_DIR}/utest ST_UTEST_SOURCE_FILES) 63 | 64 | ADD_EXECUTABLE(st_utest ${ST_UTEST_SOURCE_FILES}) 65 | TARGET_LINK_LIBRARIES(st_utest gtest gtest_main) 66 | TARGET_LINK_LIBRARIES(st_utest dl) 67 | TARGET_LINK_LIBRARIES(st_utest ${DEPS_LIBS}) 68 | TARGET_LINK_LIBRARIES(st_utest -ldl -pthread) 69 | 70 | ########################################################### 71 | # Setup tools/backtrace project 72 | set(ST_BACKTRACE_SOURCE_FILES ${SOURCE_FILES}) 73 | AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/backtrace ST_BACKTRACE_SOURCE_FILES) 74 | 75 | ADD_EXECUTABLE(st_backtrace ${ST_BACKTRACE_SOURCE_FILES}) 76 | TARGET_LINK_LIBRARIES(st_backtrace ${DEPS_LIBS}) 77 | TARGET_LINK_LIBRARIES(st_backtrace -ldl) 78 | 79 | ########################################################### 80 | # Setup tools/helloworld project 81 | set(ST_HELLOWORLD_SOURCE_FILES ${SOURCE_FILES}) 82 | AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/helloworld ST_HELLOWORLD_SOURCE_FILES) 83 | 84 | ADD_EXECUTABLE(st_helloworld ${ST_HELLOWORLD_SOURCE_FILES}) 85 | TARGET_LINK_LIBRARIES(st_helloworld ${DEPS_LIBS}) 86 | 87 | ########################################################### 88 | # Setup tools/jmpbuf project 89 | set(ST_JMPBUF_SOURCE_FILES ${SOURCE_FILES}) 90 | AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/jmpbuf ST_JMPBUF_SOURCE_FILES) 91 | 92 | ADD_EXECUTABLE(st_jmpbuf ${ST_JMPBUF_SOURCE_FILES}) 93 | TARGET_LINK_LIBRARIES(st_jmpbuf ${DEPS_LIBS}) 94 | 95 | ########################################################### 96 | # Setup tools/pcs project 97 | set(ST_PCS_SOURCE_FILES ${SOURCE_FILES}) 98 | AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/pcs ST_PCS_SOURCE_FILES) 99 | 100 | ADD_EXECUTABLE(st_pcs ${ST_PCS_SOURCE_FILES}) 101 | TARGET_LINK_LIBRARIES(st_pcs ${DEPS_LIBS}) 102 | 103 | ########################################################### 104 | # Setup tools/porting project 105 | set(ST_PORTING_SOURCE_FILES ${SOURCE_FILES}) 106 | AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/porting ST_PORTING_SOURCE_FILES) 107 | 108 | ADD_EXECUTABLE(st_porting ${ST_PORTING_SOURCE_FILES}) 109 | TARGET_LINK_LIBRARIES(st_porting ${DEPS_LIBS}) 110 | 111 | ########################################################### 112 | # Setup tools/stack project 113 | set(ST_STACK_SOURCE_FILES ${SOURCE_FILES}) 114 | AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/stack ST_STACK_SOURCE_FILES) 115 | 116 | ADD_EXECUTABLE(st_stack ${ST_STACK_SOURCE_FILES}) 117 | TARGET_LINK_LIBRARIES(st_stack ${DEPS_LIBS}) 118 | 119 | ########################################################### 120 | # Setup tools/verify project 121 | set(ST_VERIFY_SOURCE_FILES ${SOURCE_FILES}) 122 | AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/verify ST_VERIFY_SOURCE_FILES) 123 | 124 | ADD_EXECUTABLE(st_verify ${ST_VERIFY_SOURCE_FILES}) 125 | TARGET_LINK_LIBRARIES(st_verify ${DEPS_LIBS}) 126 | 127 | ########################################################### 128 | # Done 129 | MESSAGE(STATUS "@see https://github.com/ossrs/state-threads#usage") 130 | 131 | -------------------------------------------------------------------------------- /key.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ 2 | 3 | /* 4 | * The contents of this file are subject to the Mozilla Public 5 | * License Version 1.1 (the "License"); you may not use this file 6 | * except in compliance with the License. You may obtain a copy of 7 | * the License at http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS 10 | * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * rights and limitations under the License. 13 | * 14 | * The Original Code is the Netscape Portable Runtime library. 15 | * 16 | * The Initial Developer of the Original Code is Netscape 17 | * Communications Corporation. Portions created by Netscape are 18 | * Copyright (C) 1994-2000 Netscape Communications Corporation. All 19 | * Rights Reserved. 20 | * 21 | * Contributor(s): Silicon Graphics, Inc. 22 | * 23 | * Portions created by SGI are Copyright (C) 2000-2001 Silicon 24 | * Graphics, Inc. All Rights Reserved. 25 | * 26 | * Alternatively, the contents of this file may be used under the 27 | * terms of the GNU General Public License Version 2 or later (the 28 | * "GPL"), in which case the provisions of the GPL are applicable 29 | * instead of those above. If you wish to allow use of your 30 | * version of this file only under the terms of the GPL and not to 31 | * allow others to use your version of this file under the MPL, 32 | * indicate your decision by deleting the provisions above and 33 | * replace them with the notice and other provisions required by 34 | * the GPL. If you do not delete the provisions above, a recipient 35 | * may use your version of this file under either the MPL or the 36 | * GPL. 37 | */ 38 | 39 | /* 40 | * This file is derived directly from Netscape Communications Corporation, 41 | * and consists of extensive modifications made during the year(s) 1999-2000. 42 | */ 43 | 44 | #include 45 | #include 46 | #include "common.h" 47 | 48 | 49 | /* 50 | * Destructor table for per-thread private data 51 | */ 52 | static _st_destructor_t _st_destructors[ST_KEYS_MAX]; 53 | static int key_max = 0; 54 | 55 | 56 | /* 57 | * Return a key to be used for thread specific data 58 | */ 59 | int st_key_create(int *keyp, _st_destructor_t destructor) 60 | { 61 | if (key_max >= ST_KEYS_MAX) { 62 | errno = EAGAIN; 63 | return -1; 64 | } 65 | 66 | *keyp = key_max++; 67 | _st_destructors[*keyp] = destructor; 68 | 69 | return 0; 70 | } 71 | 72 | 73 | int st_key_getlimit(void) 74 | { 75 | return ST_KEYS_MAX; 76 | } 77 | 78 | 79 | int st_thread_setspecific(int key, void *value) 80 | { 81 | _st_thread_t *me = _ST_CURRENT_THREAD(); 82 | return st_thread_setspecific2(me, key, value); 83 | } 84 | 85 | 86 | int st_thread_setspecific2(_st_thread_t *me, int key, void *value) 87 | { 88 | if (key < 0 || key >= key_max) { 89 | errno = EINVAL; 90 | return -1; 91 | } 92 | 93 | if (value != me->private_data[key]) { 94 | /* free up previously set non-NULL data value */ 95 | if (me->private_data[key] && _st_destructors[key]) { 96 | (*_st_destructors[key])(me->private_data[key]); 97 | } 98 | me->private_data[key] = value; 99 | } 100 | 101 | return 0; 102 | } 103 | 104 | 105 | void *st_thread_getspecific(int key) 106 | { 107 | if (key < 0 || key >= key_max) 108 | return NULL; 109 | 110 | return ((_ST_CURRENT_THREAD())->private_data[key]); 111 | } 112 | 113 | 114 | /* 115 | * Free up all per-thread private data 116 | */ 117 | void _st_thread_cleanup(_st_thread_t *thread) 118 | { 119 | int key; 120 | 121 | for (key = 0; key < key_max; key++) { 122 | if (thread->private_data[key] && _st_destructors[key]) { 123 | (*_st_destructors[key])(thread->private_data[key]); 124 | thread->private_data[key] = NULL; 125 | } 126 | } 127 | } 128 | 129 | -------------------------------------------------------------------------------- /libst.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | st_accept @62 3 | st_cond_broadcast @63 4 | st_cond_destroy @64 5 | st_cond_new @65 6 | st_cond_signal @66 7 | st_cond_timedwait @67 8 | st_cond_wait @68 9 | st_connect @69 10 | st_getfdlimit @70 11 | st_init @71 12 | st_key_create @72 13 | st_key_getlimit @73 14 | st_mutex_destroy @74 15 | st_mutex_lock @75 16 | st_mutex_new @76 17 | st_mutex_trylock @77 18 | st_mutex_unlock @78 19 | st_netfd_close @79 20 | st_netfd_fileno @80 21 | st_netfd_free @81 22 | st_netfd_getspecific @82 23 | st_netfd_open @83 24 | st_netfd_open_socket @84 25 | st_netfd_poll @85 26 | st_netfd_serialize_accept @86 27 | st_netfd_setspecific @87 28 | st_open @88 29 | st_poll @89 30 | st_randomize_stacks @90 31 | st_read @91 32 | st_read_fully @92 33 | st_read_resid @93 34 | st_recvfrom @94 35 | st_sendto @95 36 | st_sleep @96 37 | st_thread_create @97 38 | st_thread_exit @98 39 | st_thread_getspecific @99 40 | st_thread_interrupt @100 41 | st_thread_join @101 42 | st_thread_self @102 43 | st_thread_setspecific @103 44 | st_time @104 45 | st_timecache_set @105 46 | st_usleep @106 47 | st_utime @107 48 | st_utime_last_clock @108 49 | st_write @109 50 | st_write_resid @110 51 | st_writev @111 52 | -------------------------------------------------------------------------------- /md.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ 2 | 3 | /* 4 | * The contents of this file are subject to the Mozilla Public 5 | * License Version 1.1 (the "License"); you may not use this file 6 | * except in compliance with the License. You may obtain a copy of 7 | * the License at http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS 10 | * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * rights and limitations under the License. 13 | * 14 | * The Original Code is the Netscape Portable Runtime library. 15 | * 16 | * The Initial Developer of the Original Code is Netscape 17 | * Communications Corporation. Portions created by Netscape are 18 | * Copyright (C) 1994-2000 Netscape Communications Corporation. All 19 | * Rights Reserved. 20 | * 21 | * Contributor(s): Silicon Graphics, Inc. 22 | * 23 | * Portions created by SGI are Copyright (C) 2000-2001 Silicon 24 | * Graphics, Inc. All Rights Reserved. 25 | * 26 | * Alternatively, the contents of this file may be used under the 27 | * terms of the GNU General Public License Version 2 or later (the 28 | * "GPL"), in which case the provisions of the GPL are applicable 29 | * instead of those above. If you wish to allow use of your 30 | * version of this file only under the terms of the GPL and not to 31 | * allow others to use your version of this file under the MPL, 32 | * indicate your decision by deleting the provisions above and 33 | * replace them with the notice and other provisions required by 34 | * the GPL. If you do not delete the provisions above, a recipient 35 | * may use your version of this file under either the MPL or the 36 | * GPL. 37 | */ 38 | 39 | /* 40 | * This file is derived directly from Netscape Communications Corporation, 41 | * and consists of extensive modifications made during the year(s) 1999-2000. 42 | */ 43 | 44 | #ifndef __ST_MD_H__ 45 | #define __ST_MD_H__ 46 | 47 | #if defined(ETIMEDOUT) && !defined(ETIME) 48 | #define ETIME ETIMEDOUT 49 | #endif 50 | 51 | #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON) 52 | #define MAP_ANON MAP_ANONYMOUS 53 | #endif 54 | 55 | #ifndef MAP_FAILED 56 | #define MAP_FAILED -1 57 | #endif 58 | 59 | /* We define the jmpbuf, because the system's is different in different OS */ 60 | typedef struct _st_jmp_buf { 61 | /* 62 | * OS CPU SIZE 63 | * Darwin __amd64__/__x86_64__ long[8] 64 | * Darwin __aarch64__ long[22] 65 | * Linux __i386__ long[6] 66 | * Linux __amd64__/__x86_64__ long[8] 67 | * Linux __aarch64__ long[22] 68 | * Linux __arm__ long[16] 69 | * Linux __mips__/__mips64 long[13] 70 | * Linux __riscv long[14] 71 | * Linux __loongarch64 long[12] 72 | * Cygwin64 __amd64__/__x86_64__ long[8] 73 | */ 74 | long __jmpbuf[22]; 75 | } _st_jmp_buf_t[1]; 76 | 77 | extern int _st_md_cxt_save(_st_jmp_buf_t env); 78 | extern void _st_md_cxt_restore(_st_jmp_buf_t env, int val); 79 | 80 | /* Always use builtin setjmp/longjmp, use asm code. */ 81 | #define MD_USE_BUILTIN_SETJMP 82 | #define MD_SETJMP(env) _st_md_cxt_save(env) 83 | #define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val) 84 | #if defined(USE_LIBC_SETJMP) 85 | #error The libc setjmp is not supported now 86 | #endif 87 | 88 | /***************************************** 89 | * Platform specifics 90 | */ 91 | 92 | #if defined (DARWIN) 93 | 94 | #define MD_USE_BSD_ANON_MMAP 95 | #define MD_ACCEPT_NB_INHERITED 96 | #define MD_HAVE_SOCKLEN_T 97 | 98 | #if defined(__amd64__) || defined(__x86_64__) 99 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6])) 100 | #elif defined(__aarch64__) 101 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[13])) 102 | #else 103 | #error Unknown CPU architecture 104 | #endif 105 | 106 | #define MD_INIT_CONTEXT(_thread, _sp, _main) \ 107 | ST_BEGIN_MACRO \ 108 | if (MD_SETJMP((_thread)->context)) \ 109 | _main(); \ 110 | MD_GET_SP(_thread) = (long) (_sp); \ 111 | ST_END_MACRO 112 | 113 | #define MD_GET_UTIME() \ 114 | struct timeval tv; \ 115 | (void) gettimeofday(&tv, NULL); \ 116 | return (tv.tv_sec * 1000000LL + tv.tv_usec) 117 | 118 | #elif defined (LINUX) 119 | 120 | /* 121 | * These are properties of the linux kernel and are the same on every 122 | * flavor and architecture. 123 | */ 124 | #define MD_USE_BSD_ANON_MMAP 125 | #define MD_ACCEPT_NB_NOT_INHERITED 126 | /* 127 | * Modern GNU/Linux is Posix.1g compliant. 128 | */ 129 | #define MD_HAVE_SOCKLEN_T 130 | 131 | /* 132 | * All architectures and flavors of linux have the gettimeofday 133 | * function but if you know of a faster way, use it. 134 | */ 135 | #define MD_GET_UTIME() \ 136 | struct timeval tv; \ 137 | (void) gettimeofday(&tv, NULL); \ 138 | return (tv.tv_sec * 1000000LL + tv.tv_usec) 139 | 140 | #if defined(__i386__) 141 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[4])) 142 | #elif defined(__amd64__) || defined(__x86_64__) 143 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6])) 144 | #elif defined(__aarch64__) 145 | /* https://github.com/ossrs/state-threads/issues/9 */ 146 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[13])) 147 | #elif defined(__arm__) 148 | /* https://github.com/ossrs/state-threads/issues/1#issuecomment-244648573 */ 149 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[8])) 150 | #elif defined(__mips64) 151 | /* https://github.com/ossrs/state-threads/issues/21 */ 152 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0])) 153 | #elif defined(__mips__) 154 | /* https://github.com/ossrs/state-threads/issues/21 */ 155 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0])) 156 | #elif defined(__riscv) 157 | /* https://github.com/ossrs/state-threads/pull/28 */ 158 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0])) 159 | #elif defined(__loongarch64) 160 | /* https://github.com/ossrs/state-threads/issues/24 */ 161 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0])) 162 | #else 163 | #error "Unknown CPU architecture" 164 | #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */ 165 | 166 | #define MD_INIT_CONTEXT(_thread, _sp, _main) \ 167 | ST_BEGIN_MACRO \ 168 | if (MD_SETJMP((_thread)->context)) \ 169 | _main(); \ 170 | MD_GET_SP(_thread) = (long) (_sp); \ 171 | ST_END_MACRO 172 | 173 | #elif defined (CYGWIN64) 174 | 175 | // For CYGWIN64, build SRS on Windows. 176 | #define MD_USE_BSD_ANON_MMAP 177 | #define MD_ACCEPT_NB_INHERITED 178 | #define MD_HAVE_SOCKLEN_T 179 | 180 | #define MD_USE_BUILTIN_SETJMP 181 | 182 | #if defined(__amd64__) || defined(__x86_64__) 183 | #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6])) 184 | #else 185 | #error Unknown CPU architecture 186 | #endif 187 | 188 | #define MD_INIT_CONTEXT(_thread, _sp, _main) \ 189 | ST_BEGIN_MACRO \ 190 | if (MD_SETJMP((_thread)->context)) \ 191 | _main(); \ 192 | MD_GET_SP(_thread) = (long) (_sp); \ 193 | ST_END_MACRO 194 | 195 | #define MD_GET_UTIME() \ 196 | struct timeval tv; \ 197 | (void) gettimeofday(&tv, NULL); \ 198 | return (tv.tv_sec * 1000000LL + tv.tv_usec) 199 | 200 | #else 201 | #error Unknown OS 202 | #endif /* OS */ 203 | 204 | #ifndef MD_STACK_PAD_SIZE 205 | #define MD_STACK_PAD_SIZE 128 206 | #endif 207 | 208 | #if !defined(MD_HAVE_SOCKLEN_T) && !defined(socklen_t) 209 | #define socklen_t int 210 | #endif 211 | 212 | #ifndef MD_CAP_STACK 213 | #define MD_CAP_STACK(var_addr) 214 | #endif 215 | 216 | #endif /* !__ST_MD_H__ */ 217 | 218 | -------------------------------------------------------------------------------- /md_cygwin64.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT */ 2 | /* Copyright (c) 2021-2022 The SRS Authors */ 3 | 4 | /* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */ 5 | #if !defined(MD_ST_NO_ASM) 6 | 7 | #if defined(__amd64__) || defined(__x86_64__) 8 | 9 | /****************************************************************/ 10 | 11 | /* 12 | * Internal __jmp_buf layout 13 | */ 14 | #define JB_RBX 0 15 | #define JB_RBP 1 16 | #define JB_R12 2 /* R12:R15 Nonvolatile Must be preserved by callee */ 17 | #define JB_R13 3 /* @see https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-160#register-usage */ 18 | #define JB_R14 4 /* RBX, RBP, RDI, RSI, R12, R14, R14, and R15 must be saved in any function using them. */ 19 | #define JB_R15 5 /* @see https://software.intel.com/content/www/us/en/develop/articles/introduction-to-x64-assembly.html */ 20 | #define JB_RSP 6 21 | #define JB_PC 7 22 | 23 | .file "md_cygwin64.S" 24 | .text 25 | 26 | /* _st_md_cxt_save(__jmp_buf env) */ /* The env is rcx, https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160 */ 27 | .globl _st_md_cxt_save 28 | .align 16 29 | _st_md_cxt_save: 30 | /* 31 | * Save registers. 32 | */ 33 | movq %rbx, (JB_RBX*8)(%rcx) /* Save rbx to env[0], *(int64_t*)(rcx+0)=rbx */ 34 | movq %rbp, (JB_RBP*8)(%rcx) /* Save rbp to env[1], *(int64_t*)(rcx+1)=rbp */ 35 | movq %r12, (JB_R12*8)(%rcx) /* Save r12 to env[2], *(int64_t*)(rcx+2)=r12 */ 36 | movq %r13, (JB_R13*8)(%rcx) /* Save r13 to env[3], *(int64_t*)(rcx+3)=r13 */ 37 | movq %r14, (JB_R14*8)(%rcx) /* Save r14 to env[4], *(int64_t*)(rcx+4)=r14 */ 38 | movq %r15, (JB_R15*8)(%rcx) /* Save r15 to env[5], *(int64_t*)(rcx+5)=r15 */ 39 | /* Save SP */ 40 | leaq 8(%rsp), %r8 /* Save *(int64_t*)(rsp+8) to r8, https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 */ 41 | movq %r8, (JB_RSP*8)(%rcx) /* Save r8(rsp) to env[6], *(int64_t*)(rcx+6)=r8 */ 42 | /* Save PC we are returning to */ 43 | movq (%rsp), %r9 /* Save PC(parent function address) %(rsp) to r9, https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 */ 44 | movq %r9, (JB_PC*8)(%rcx) /* Save r9(PC) to env[7], *(int64_t*)(rcx+7)=r9 */ 45 | xorq %rax, %rax /* Reset rax(return value) to 0 */ 46 | ret 47 | 48 | 49 | /****************************************************************/ 50 | 51 | /* _st_md_cxt_restore(__jmp_buf env, int val) */ /* The env is rcx, val is edx/rdx, https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160 */ 52 | .globl _st_md_cxt_restore 53 | .align 16 54 | _st_md_cxt_restore: 55 | /* 56 | * Restore registers. 57 | */ 58 | movq (JB_RBX*8)(%rcx), %rbx /* Load rbx from env[0] */ 59 | movq (JB_RBP*8)(%rcx), %rbp /* Load rbp from env[1] */ 60 | movq (JB_R12*8)(%rcx), %r12 /* Load r12 from env[2] */ 61 | movq (JB_R13*8)(%rcx), %r13 /* Load r13 from env[3] */ 62 | movq (JB_R14*8)(%rcx), %r14 /* Load r14 from env[4] */ 63 | movq (JB_R15*8)(%rcx), %r15 /* Load r15 from env[5] */ 64 | /* Set return value */ /* The edx is param1 val, the eax is return value */ 65 | test %edx, %edx /* if (!val) { */ 66 | mov $01, %eax /* val=1; */ 67 | cmove %eax, %edx /* } */ 68 | mov %edx, %eax /* return val; */ 69 | /* Restore PC and RSP */ 70 | movq (JB_PC*8)(%rcx), %r8 /* Load r8(PC) from env[7], https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 */ 71 | movq (JB_RSP*8)(%rcx), %rsp /* Load rsp from env[6] */ 72 | /* Jump to saved PC */ 73 | jmpq *%r8 /* Jump to r8(PC) */ 74 | 75 | /****************************************************************/ 76 | 77 | #endif 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /md_darwin.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT */ 2 | /* Copyright (c) 2021-2022 The SRS Authors */ 3 | 4 | /* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */ 5 | #if !defined(MD_ST_NO_ASM) 6 | 7 | #if defined(__amd64__) || defined(__x86_64__) 8 | 9 | /****************************************************************/ 10 | 11 | /* 12 | * Internal __jmp_buf layout 13 | */ 14 | #define JB_RBX 0 15 | #define JB_RBP 1 16 | #define JB_R12 2 /* The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, R9. */ 17 | #define JB_R13 3 /* If the callee wishes to use registers RBX, RSP, RBP, and R12–R15, it must restore their original values before returning control to the caller. */ 18 | #define JB_R14 4 /* @see https://en.wikipedia.org/wiki/X86_calling_conventions */ 19 | #define JB_R15 5 /* @see https://www.cnblogs.com/Five100Miles/p/8458561.html */ 20 | #define JB_RSP 6 21 | #define JB_PC 7 22 | 23 | .file "md_darwin.S" 24 | .text 25 | 26 | /* _st_md_cxt_save(__jmp_buf env) */ /* The env is rdi, https://en.wikipedia.org/wiki/X86_calling_conventions */ 27 | .globl __st_md_cxt_save 28 | .align 16 29 | __st_md_cxt_save: 30 | /* 31 | * Save registers. 32 | */ 33 | movq %rbx, (JB_RBX*8)(%rdi) /* Save rbx to env[0], *(int64_t*)(rdi+0)=rbx */ 34 | movq %rbp, (JB_RBP*8)(%rdi) /* Save rbp to env[1], *(int64_t*)(rdi+1)=rbp */ 35 | movq %r12, (JB_R12*8)(%rdi) /* Save r12 to env[2], *(int64_t*)(rdi+2)=r12 */ 36 | movq %r13, (JB_R13*8)(%rdi) /* Save r13 to env[3], *(int64_t*)(rdi+3)=r13 */ 37 | movq %r14, (JB_R14*8)(%rdi) /* Save r14 to env[4], *(int64_t*)(rdi+4)=r14 */ 38 | movq %r15, (JB_R15*8)(%rdi) /* Save r15 to env[5], *(int64_t*)(rdi+5)=r15 */ 39 | /* Save SP */ 40 | leaq 8(%rsp), %r8 /* Save *(int64_t*)(rsp+8) to r8, https://github.com/ossrs/state-threads/issues/11#issuecomment-888709759 */ 41 | movq %r8, (JB_RSP*8)(%rdi) /* Save r8(rsp) to env[6], *(int64_t*)(rdi+6)=r8 */ 42 | /* Save PC we are returning to */ 43 | movq (%rsp), %r9 /* Save PC(parent function address) %(rsp) to r9 */ 44 | movq %r9, (JB_PC*8)(%rdi) /* Save r9(PC) to env[7], *(int64_t*)(rdi+7)=r9 */ 45 | xorq %rax, %rax /* Reset rax to 0 */ 46 | ret 47 | 48 | 49 | /****************************************************************/ 50 | 51 | /* _st_md_cxt_restore(__jmp_buf env, int val) */ /* The env is rdi, val is esi/rsi, https://en.wikipedia.org/wiki/X86_calling_conventions */ 52 | .globl __st_md_cxt_restore 53 | .align 16 54 | __st_md_cxt_restore: 55 | /* 56 | * Restore registers. 57 | */ 58 | movq (JB_RBX*8)(%rdi), %rbx /* Load rbx from env[0] */ 59 | movq (JB_RBP*8)(%rdi), %rbp /* Load rbp from env[1] */ 60 | movq (JB_R12*8)(%rdi), %r12 /* Load r12 from env[2] */ 61 | movq (JB_R13*8)(%rdi), %r13 /* Load r13 from env[3] */ 62 | movq (JB_R14*8)(%rdi), %r14 /* Load r14 from env[4] */ 63 | movq (JB_R15*8)(%rdi), %r15 /* Load r15 from env[5] */ 64 | /* Set return value */ /* The esi is param1 val, the eax is return value */ 65 | test %esi, %esi /* if (!val) { */ 66 | mov $01, %eax /* val=1; */ 67 | cmove %eax, %esi /* } */ 68 | mov %esi, %eax /* return val; */ 69 | /* Restore PC and RSP */ 70 | movq (JB_PC*8)(%rdi), %r8 /* Load r8(PC) from env[7] */ 71 | movq (JB_RSP*8)(%rdi), %rsp /* Load rsp from env[6] */ 72 | /* Jump to saved PC */ 73 | jmpq *%r8 /* Jump to r8(PC) */ 74 | 75 | /****************************************************************/ 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | #elif defined(__aarch64__) 88 | 89 | /****************************************************************/ 90 | /* See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms */ 91 | /* See https://developer.arm.com/documentation/102374/0100/Function-calls */ 92 | /* See https://developer.arm.com/documentation/102374/0100/Procedure-Call-Standard */ 93 | /* See https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#machine-registers */ 94 | /* See https://wiki.cdot.senecacollege.ca/wiki/AArch64_Register_and_Instruction_Quick_Start */ 95 | /* 96 | * See setjmp.h of Darwin. 97 | * 98 | * _JBLEN is the number of ints required to save the following: 99 | * r21-r29, sp, fp, lr == 12 registers, 8 bytes each. d8-d15 100 | * are another 8 registers, each 8 bytes long. (aapcs64 specifies 101 | * that only 64-bit versions of FP registers need to be saved). 102 | * Finally, two 8-byte fields for signal handling purposes. 103 | */ 104 | 105 | /* The called routine is expected to preserve r19-r28 *** These registers are generally 106 | safe to use in your program. */ 107 | #define JB_X19 0 108 | #define JB_X20 1 109 | #define JB_X21 2 110 | #define JB_X22 3 111 | #define JB_X23 4 112 | #define JB_X24 5 113 | #define JB_X25 6 114 | #define JB_X26 7 115 | #define JB_X27 8 116 | #define JB_X28 9 117 | /* r29 and r30 are used as the frame register and link register (avoid) */ 118 | #define JB_X29 10 119 | #define JB_LR 11 120 | /* Register '31' is one of two registers depending on the instruction context: 121 | For instructions dealing with the stack, it is the stack pointer, named rsp */ 122 | #define JB_SP 13 123 | 124 | /* FP registers */ 125 | #define JB_D8 14 126 | #define JB_D9 15 127 | #define JB_D10 16 128 | #define JB_D11 17 129 | #define JB_D12 18 130 | #define JB_D13 19 131 | #define JB_D14 20 132 | #define JB_D15 21 133 | 134 | .file "md.S" 135 | .text 136 | 137 | /* _st_md_cxt_save(__jmp_buf env) */ 138 | .globl __st_md_cxt_save 139 | .align 4 140 | __st_md_cxt_save: 141 | stp x19, x20, [x0, #JB_X19<<3] 142 | stp x21, x22, [x0, #JB_X21<<3] 143 | stp x23, x24, [x0, #JB_X23<<3] 144 | stp x25, x26, [x0, #JB_X25<<3] 145 | stp x27, x28, [x0, #JB_X27<<3] 146 | stp x29, x30, [x0, #JB_X29<<3] 147 | 148 | stp d8, d9, [x0, #JB_D8<<3] 149 | stp d10, d11, [x0, #JB_D10<<3] 150 | stp d12, d13, [x0, #JB_D12<<3] 151 | stp d14, d15, [x0, #JB_D14<<3] 152 | mov x2, sp 153 | str x2, [x0, #JB_SP<<3] 154 | 155 | mov x0, #0 156 | ret 157 | 158 | /****************************************************************/ 159 | 160 | /* _st_md_cxt_restore(__jmp_buf env, int val) */ 161 | .globl __st_md_cxt_restore 162 | .align 4 163 | __st_md_cxt_restore: 164 | ldp x19, x20, [x0, #JB_X19<<3] 165 | ldp x21, x22, [x0, #JB_X21<<3] 166 | ldp x23, x24, [x0, #JB_X23<<3] 167 | ldp x25, x26, [x0, #JB_X25<<3] 168 | ldp x27, x28, [x0, #JB_X27<<3] 169 | 170 | ldp x29, x30, [x0, #JB_X29<<3] 171 | 172 | ldp d8, d9, [x0, #JB_D8<<3] 173 | ldp d10, d11, [x0, #JB_D10<<3] 174 | ldp d12, d13, [x0, #JB_D12<<3] 175 | ldp d14, d15, [x0, #JB_D14<<3] 176 | 177 | ldr x5, [x0, #JB_SP<<3] 178 | mov sp, x5 179 | 180 | /* x0 = (x1 || 1); */ 181 | cmp x1, #0 182 | mov x0, #1 183 | csel x0, x1, x0, ne 184 | 185 | ret 186 | 187 | /****************************************************************/ 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | #endif 200 | 201 | #endif -------------------------------------------------------------------------------- /md_linux.S: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ 2 | 3 | /* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */ 4 | #if !defined(MD_ST_NO_ASM) 5 | 6 | /* 7 | * Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc. 8 | * All Rights Reserved. 9 | */ 10 | 11 | #if defined(__i386__) 12 | 13 | /****************************************************************/ 14 | 15 | /* 16 | * Internal __jmp_buf layout 17 | */ 18 | #define JB_BX 0 19 | #define JB_SI 1 20 | #define JB_DI 2 21 | #define JB_BP 3 22 | #define JB_SP 4 23 | #define JB_PC 5 24 | 25 | .file "md.S" 26 | .text 27 | 28 | /* _st_md_cxt_save(__jmp_buf env) */ 29 | .globl _st_md_cxt_save 30 | .type _st_md_cxt_save, @function 31 | .align 16 32 | _st_md_cxt_save: 33 | movl 4(%esp), %eax 34 | 35 | /* 36 | * Save registers. 37 | */ 38 | movl %ebx, (JB_BX*4)(%eax) 39 | movl %esi, (JB_SI*4)(%eax) 40 | movl %edi, (JB_DI*4)(%eax) 41 | /* Save SP */ 42 | leal 4(%esp), %ecx 43 | movl %ecx, (JB_SP*4)(%eax) 44 | /* Save PC we are returning to */ 45 | movl 0(%esp), %ecx 46 | movl %ecx, (JB_PC*4)(%eax) 47 | /* Save caller frame pointer */ 48 | movl %ebp, (JB_BP*4)(%eax) 49 | xorl %eax, %eax 50 | ret 51 | .size _st_md_cxt_save, .-_st_md_cxt_save 52 | 53 | 54 | /****************************************************************/ 55 | 56 | /* _st_md_cxt_restore(__jmp_buf env, int val) */ 57 | .globl _st_md_cxt_restore 58 | .type _st_md_cxt_restore, @function 59 | .align 16 60 | _st_md_cxt_restore: 61 | /* First argument is jmp_buf */ 62 | movl 4(%esp), %ecx 63 | /* Second argument is return value */ 64 | movl 8(%esp), %eax 65 | /* Set the return address */ 66 | movl (JB_PC*4)(%ecx), %edx 67 | /* 68 | * Restore registers. 69 | */ 70 | movl (JB_BX*4)(%ecx), %ebx 71 | movl (JB_SI*4)(%ecx), %esi 72 | movl (JB_DI*4)(%ecx), %edi 73 | movl (JB_BP*4)(%ecx), %ebp 74 | movl (JB_SP*4)(%ecx), %esp 75 | testl %eax, %eax 76 | jnz 1f 77 | incl %eax 78 | /* Jump to saved PC */ 79 | 1: jmp *%edx 80 | .size _st_md_cxt_restore, .-_st_md_cxt_restore 81 | 82 | /****************************************************************/ 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | #elif defined(__amd64__) || defined(__x86_64__) 94 | 95 | /****************************************************************/ 96 | 97 | /* 98 | * Internal __jmp_buf layout 99 | */ 100 | #define JB_RBX 0 101 | #define JB_RBP 1 102 | #define JB_R12 2 103 | #define JB_R13 3 104 | #define JB_R14 4 105 | #define JB_R15 5 106 | #define JB_RSP 6 107 | #define JB_PC 7 108 | 109 | .file "md.S" 110 | .text 111 | 112 | /* _st_md_cxt_save(__jmp_buf env) */ 113 | .globl _st_md_cxt_save 114 | .type _st_md_cxt_save, @function 115 | .align 16 116 | _st_md_cxt_save: 117 | /* 118 | * Save registers. 119 | */ 120 | movq %rbx, (JB_RBX*8)(%rdi) 121 | movq %rbp, (JB_RBP*8)(%rdi) 122 | movq %r12, (JB_R12*8)(%rdi) 123 | movq %r13, (JB_R13*8)(%rdi) 124 | movq %r14, (JB_R14*8)(%rdi) 125 | movq %r15, (JB_R15*8)(%rdi) 126 | /* Save SP */ 127 | leaq 8(%rsp), %rdx 128 | movq %rdx, (JB_RSP*8)(%rdi) 129 | /* Save PC we are returning to */ 130 | movq (%rsp), %rax 131 | movq %rax, (JB_PC*8)(%rdi) 132 | xorq %rax, %rax 133 | ret 134 | .size _st_md_cxt_save, .-_st_md_cxt_save 135 | 136 | 137 | /****************************************************************/ 138 | 139 | /* _st_md_cxt_restore(__jmp_buf env, int val) */ 140 | .globl _st_md_cxt_restore 141 | .type _st_md_cxt_restore, @function 142 | .align 16 143 | _st_md_cxt_restore: 144 | /* 145 | * Restore registers. 146 | */ 147 | movq (JB_RBX*8)(%rdi), %rbx 148 | movq (JB_RBP*8)(%rdi), %rbp 149 | movq (JB_R12*8)(%rdi), %r12 150 | movq (JB_R13*8)(%rdi), %r13 151 | movq (JB_R14*8)(%rdi), %r14 152 | movq (JB_R15*8)(%rdi), %r15 153 | /* Set return value */ 154 | test %esi, %esi 155 | mov $01, %eax 156 | cmove %eax, %esi 157 | mov %esi, %eax 158 | movq (JB_PC*8)(%rdi), %rdx 159 | movq (JB_RSP*8)(%rdi), %rsp 160 | /* Jump to saved PC */ 161 | jmpq *%rdx 162 | .size _st_md_cxt_restore, .-_st_md_cxt_restore 163 | 164 | /****************************************************************/ 165 | 166 | #endif 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /osguess.sh: -------------------------------------------------------------------------------- 1 | # 2 | # This script can be used to automatically guess target OS. 3 | # It requires the config.guess utility which is a part of GNU Autoconf. 4 | # GNU Autoconf can be downloaded from ftp://ftp.gnu.org/gnu/autoconf/ 5 | # 6 | # Use "default" as a make target for automatic builds. 7 | # 8 | 9 | 10 | # Specify path to the config.guess utility (unless set via environment) 11 | #CONFIG_GUESS_PATH= 12 | 13 | 14 | if [ x"$CONFIG_GUESS_PATH" = x ]; then 15 | echo "Error: CONFIG_GUESS_PATH variable is not set" 16 | exit 1 17 | fi 18 | 19 | if [ ! -f "$CONFIG_GUESS_PATH/config.guess" ]; then 20 | echo "Can't find $CONFIG_GUESS_PATH/config.guess utility. Wrong path?" 21 | exit 1 22 | fi 23 | 24 | sys_info=`/bin/sh $CONFIG_GUESS_PATH/config.guess` 25 | 26 | echo "Building for $sys_info" 27 | 28 | case "$sys_info" in 29 | *-ibm-aix4* ) OS=AIX ;; 30 | *-freebsd* ) OS=FREEBSD ;; 31 | hppa*-hp-hpux11*) OS=HPUX ;; 32 | *-sgi-irix6* ) OS=IRIX ;; 33 | *-linux* ) OS=LINUX ;; 34 | *-netbsd* ) OS=NETBSD ;; 35 | *-openbsd* ) OS=OPENBSD ;; 36 | *-dec-osf* ) OS=OSF1 ;; 37 | *-solaris2* ) OS=SOLARIS ;; 38 | *-darwin* ) OS=DARWIN ;; 39 | * ) OS= 40 | echo "Sorry, unsupported OS" 41 | exit 1 ;; 42 | esac 43 | 44 | echo "Making with OS=$OS" 45 | 46 | -------------------------------------------------------------------------------- /public.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ 2 | 3 | /* 4 | * The contents of this file are subject to the Mozilla Public 5 | * License Version 1.1 (the "License"); you may not use this file 6 | * except in compliance with the License. You may obtain a copy of 7 | * the License at http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS 10 | * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * rights and limitations under the License. 13 | * 14 | * The Original Code is the Netscape Portable Runtime library. 15 | * 16 | * The Initial Developer of the Original Code is Netscape 17 | * Communications Corporation. Portions created by Netscape are 18 | * Copyright (C) 1994-2000 Netscape Communications Corporation. All 19 | * Rights Reserved. 20 | * 21 | * Contributor(s): Silicon Graphics, Inc. 22 | * 23 | * Portions created by SGI are Copyright (C) 2000-2001 Silicon 24 | * Graphics, Inc. All Rights Reserved. 25 | * 26 | * Alternatively, the contents of this file may be used under the 27 | * terms of the GNU General Public License Version 2 or later (the 28 | * "GPL"), in which case the provisions of the GPL are applicable 29 | * instead of those above. If you wish to allow use of your 30 | * version of this file only under the terms of the GPL and not to 31 | * allow others to use your version of this file under the MPL, 32 | * indicate your decision by deleting the provisions above and 33 | * replace them with the notice and other provisions required by 34 | * the GPL. If you do not delete the provisions above, a recipient 35 | * may use your version of this file under either the MPL or the 36 | * GPL. 37 | */ 38 | 39 | #ifndef __ST_THREAD_H__ 40 | #define __ST_THREAD_H__ 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | 50 | #define ST_VERSION "1.9" 51 | #define ST_VERSION_MAJOR 1 52 | #define ST_VERSION_MINOR 9 53 | 54 | /* Undefine this to remove the context switch callback feature. */ 55 | #define ST_SWITCH_CB 56 | 57 | #ifndef ETIME 58 | #define ETIME ETIMEDOUT 59 | #endif 60 | 61 | #ifndef ST_UTIME_NO_TIMEOUT 62 | #define ST_UTIME_NO_TIMEOUT ((st_utime_t) -1LL) 63 | #endif 64 | 65 | #ifndef ST_UTIME_NO_WAIT 66 | #define ST_UTIME_NO_WAIT 0 67 | #endif 68 | 69 | #define ST_EVENTSYS_DEFAULT 0 70 | #define ST_EVENTSYS_SELECT 1 71 | #define ST_EVENTSYS_ALT 3 72 | 73 | #ifdef __cplusplus 74 | extern "C" { 75 | #endif 76 | 77 | typedef unsigned long long st_utime_t; 78 | typedef struct _st_thread * st_thread_t; 79 | typedef struct _st_cond * st_cond_t; 80 | typedef struct _st_mutex * st_mutex_t; 81 | typedef struct _st_netfd * st_netfd_t; 82 | #ifdef ST_SWITCH_CB 83 | typedef void (*st_switch_cb_t)(void); 84 | #endif 85 | 86 | extern int st_init(void); 87 | extern int st_getfdlimit(void); 88 | 89 | extern int st_set_eventsys(int eventsys); 90 | extern int st_get_eventsys(void); 91 | extern const char *st_get_eventsys_name(void); 92 | 93 | #ifdef ST_SWITCH_CB 94 | extern st_switch_cb_t st_set_switch_in_cb(st_switch_cb_t cb); 95 | extern st_switch_cb_t st_set_switch_out_cb(st_switch_cb_t cb); 96 | #endif 97 | 98 | extern st_thread_t st_thread_self(void); 99 | extern void st_thread_exit(void *retval); 100 | extern int st_thread_join(st_thread_t thread, void **retvalp); 101 | extern void st_thread_interrupt(st_thread_t thread); 102 | extern void st_thread_yield(); 103 | extern st_thread_t st_thread_create(void *(*start)(void *arg), void *arg, int joinable, int stack_size); 104 | extern int st_randomize_stacks(int on); 105 | extern int st_set_utime_function(st_utime_t (*func)(void)); 106 | 107 | extern st_utime_t st_utime(void); 108 | extern st_utime_t st_utime_last_clock(void); 109 | extern int st_timecache_set(int on); 110 | extern time_t st_time(void); 111 | extern int st_usleep(st_utime_t usecs); 112 | extern int st_sleep(int secs); 113 | extern st_cond_t st_cond_new(void); 114 | extern int st_cond_destroy(st_cond_t cvar); 115 | extern int st_cond_timedwait(st_cond_t cvar, st_utime_t timeout); 116 | extern int st_cond_wait(st_cond_t cvar); 117 | extern int st_cond_signal(st_cond_t cvar); 118 | extern int st_cond_broadcast(st_cond_t cvar); 119 | extern st_mutex_t st_mutex_new(void); 120 | extern int st_mutex_destroy(st_mutex_t lock); 121 | extern int st_mutex_lock(st_mutex_t lock); 122 | extern int st_mutex_unlock(st_mutex_t lock); 123 | extern int st_mutex_trylock(st_mutex_t lock); 124 | 125 | extern int st_key_create(int *keyp, void (*destructor)(void *)); 126 | extern int st_key_getlimit(void); 127 | extern int st_thread_setspecific(int key, void *value); 128 | extern void *st_thread_getspecific(int key); 129 | 130 | extern st_netfd_t st_netfd_open(int osfd); 131 | extern st_netfd_t st_netfd_open_socket(int osfd); 132 | extern void st_netfd_free(st_netfd_t fd); 133 | extern int st_netfd_close(st_netfd_t fd); 134 | extern int st_netfd_fileno(st_netfd_t fd); 135 | extern void st_netfd_setspecific(st_netfd_t fd, void *value, void (*destructor)(void *)); 136 | extern void *st_netfd_getspecific(st_netfd_t fd); 137 | extern int st_netfd_serialize_accept(st_netfd_t fd); 138 | extern int st_netfd_poll(st_netfd_t fd, int how, st_utime_t timeout); 139 | 140 | extern int st_poll(struct pollfd *pds, int npds, st_utime_t timeout); 141 | extern st_netfd_t st_accept(st_netfd_t fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout); 142 | extern int st_connect(st_netfd_t fd, const struct sockaddr *addr, int addrlen, st_utime_t timeout); 143 | extern ssize_t st_read(st_netfd_t fd, void *buf, size_t nbyte, st_utime_t timeout); 144 | extern ssize_t st_read_fully(st_netfd_t fd, void *buf, size_t nbyte, st_utime_t timeout); 145 | extern int st_read_resid(st_netfd_t fd, void *buf, size_t *resid, st_utime_t timeout); 146 | extern ssize_t st_readv(st_netfd_t fd, const struct iovec *iov, int iov_size, st_utime_t timeout); 147 | extern int st_readv_resid(st_netfd_t fd, struct iovec **iov, int *iov_size, st_utime_t timeout); 148 | extern ssize_t st_write(st_netfd_t fd, const void *buf, size_t nbyte, st_utime_t timeout); 149 | extern int st_write_resid(st_netfd_t fd, const void *buf, size_t *resid, st_utime_t timeout); 150 | extern ssize_t st_writev(st_netfd_t fd, const struct iovec *iov, int iov_size, st_utime_t timeout); 151 | extern int st_writev_resid(st_netfd_t fd, struct iovec **iov, int *iov_size, st_utime_t timeout); 152 | extern int st_recvfrom(st_netfd_t fd, void *buf, int len, struct sockaddr *from, int *fromlen, st_utime_t timeout); 153 | extern int st_sendto(st_netfd_t fd, const void *msg, int len, const struct sockaddr *to, int tolen, st_utime_t timeout); 154 | extern int st_recvmsg(st_netfd_t fd, struct msghdr *msg, int flags, st_utime_t timeout); 155 | extern int st_sendmsg(st_netfd_t fd, const struct msghdr *msg, int flags, st_utime_t timeout); 156 | 157 | extern st_netfd_t st_open(const char *path, int oflags, mode_t mode); 158 | 159 | extern void st_destroy(void); 160 | extern int st_thread_setspecific2(st_thread_t thread, int key, void *value); 161 | 162 | #ifdef DEBUG 163 | extern void _st_show_thread_stack(st_thread_t thread, const char *messg); 164 | extern void _st_iterate_threads(void); 165 | #endif 166 | 167 | #ifdef __cplusplus 168 | } 169 | #endif 170 | 171 | #endif /* !__ST_THREAD_H__ */ 172 | 173 | -------------------------------------------------------------------------------- /st.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: libst 7 | Description: State Thread Library 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lst 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /st.spec: -------------------------------------------------------------------------------- 1 | Summary: State Threads Library 2 | Name: st 3 | Version: 1.9 4 | Release: 1 5 | Copyright: MPL 1.2 or GPL 2+ 6 | Packager: Wesley W. Terpstra 7 | Source: http://prdownloads.sourceforge.net/state-threads/st-%{version}.tar.gz 8 | Prefix: /usr 9 | BuildRoot: /tmp/%{name}-%{version}-build 10 | Group: Development/Libraries 11 | 12 | %description 13 | The State Threads library has an interface similar to POSIX threads. 14 | 15 | However, the threads are actually all run in-process. This type of 16 | threading allows for controlled schedualing points. It is highly useful 17 | for designing robust and extremely scalable internet applications since 18 | there is no resource contention and locking is generally unnecessary. 19 | 20 | It can be combined with traditional threading or multiple process 21 | parallelism to take advantage of multiple processors. 22 | 23 | See: for further 24 | information about how state threads improve performance. 25 | 26 | %package -n libst-devel 27 | Summary: State Threads Library - Development Files 28 | Group: Development/Libraries 29 | Requires: libst1 30 | 31 | %description -n libst-devel 32 | Development headers and documentation for libst 33 | 34 | %package -n libst1 35 | Summary: State Threads Library - Shared Libs Major 1 36 | Group: System/Libraries 37 | 38 | %description -n libst1 39 | Shared libraries for running applications linked against api version 1. 40 | 41 | %prep 42 | %setup -q 43 | 44 | %build 45 | make CONFIG_GUESS_PATH=/usr/share/automake default-optimized 46 | 47 | %install 48 | if [ -d ${RPM_BUILD_ROOT} ]; then rm -rf ${RPM_BUILD_ROOT}; fi 49 | 50 | mkdir -m 0755 -p ${RPM_BUILD_ROOT}/%{prefix}/lib/pkgconfig 51 | mkdir -m 0755 -p ${RPM_BUILD_ROOT}/%{prefix}/include 52 | mkdir -m 0755 -p ${RPM_BUILD_ROOT}/%{prefix}/share/doc/libst-devel 53 | cp -a obj/libst.* ${RPM_BUILD_ROOT}/%{prefix}/lib 54 | cp -a obj/st.h ${RPM_BUILD_ROOT}/%{prefix}/include 55 | sed "s*@prefix@*%{prefix}*g" ${RPM_BUILD_ROOT}/%{prefix}/lib/pkgconfig/st.pc 56 | cp -a docs/* ${RPM_BUILD_ROOT}/%{prefix}/share/doc/libst-devel/ 57 | cp -a examples ${RPM_BUILD_ROOT}/%{prefix}/share/doc/libst-devel/ 58 | 59 | %post -n libst1 60 | /sbin/ldconfig %{prefix}/lib 61 | 62 | %files -n libst1 63 | %defattr(-,root,root) 64 | %{prefix}/lib/lib*.so.* 65 | 66 | %files -n libst-devel 67 | %defattr(-,root,root) 68 | %{prefix}/include/* 69 | %{prefix}/lib/lib*.a 70 | %{prefix}/lib/lib*.so 71 | %{prefix}/lib/pkgconfig/st.pc 72 | %{prefix}/share/doc/libst-devel/* 73 | 74 | %clean 75 | if [ -d ${RPM_BUILD_ROOT} ]; then rm -rf ${RPM_BUILD_ROOT}; fi 76 | 77 | %changelog 78 | * Wed Dec 26 2001 Wesley W. Terpstra 79 | - first rpms for libst-1.3.tar.gz 80 | -------------------------------------------------------------------------------- /stk.c: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later */ 2 | 3 | /* 4 | * The contents of this file are subject to the Mozilla Public 5 | * License Version 1.1 (the "License"); you may not use this file 6 | * except in compliance with the License. You may obtain a copy of 7 | * the License at http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS 10 | * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * rights and limitations under the License. 13 | * 14 | * The Original Code is the Netscape Portable Runtime library. 15 | * 16 | * The Initial Developer of the Original Code is Netscape 17 | * Communications Corporation. Portions created by Netscape are 18 | * Copyright (C) 1994-2000 Netscape Communications Corporation. All 19 | * Rights Reserved. 20 | * 21 | * Contributor(s): Silicon Graphics, Inc. 22 | * 23 | * Portions created by SGI are Copyright (C) 2000-2001 Silicon 24 | * Graphics, Inc. All Rights Reserved. 25 | * 26 | * Alternatively, the contents of this file may be used under the 27 | * terms of the GNU General Public License Version 2 or later (the 28 | * "GPL"), in which case the provisions of the GPL are applicable 29 | * instead of those above. If you wish to allow use of your 30 | * version of this file only under the terms of the GPL and not to 31 | * allow others to use your version of this file under the MPL, 32 | * indicate your decision by deleting the provisions above and 33 | * replace them with the notice and other provisions required by 34 | * the GPL. If you do not delete the provisions above, a recipient 35 | * may use your version of this file under either the MPL or the 36 | * GPL. 37 | */ 38 | 39 | /* 40 | * This file is derived directly from Netscape Communications Corporation, 41 | * and consists of extensive modifications made during the year(s) 1999-2000. 42 | */ 43 | 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include "common.h" 50 | 51 | 52 | /* How much space to leave between the stacks, at each end */ 53 | #define REDZONE _ST_PAGE_SIZE 54 | 55 | __thread _st_clist_t _st_free_stacks; 56 | __thread int _st_num_free_stacks = 0; 57 | __thread int _st_randomize_stacks = 0; 58 | 59 | static char *_st_new_stk_segment(int size); 60 | static void _st_delete_stk_segment(char *vaddr, int size); 61 | 62 | _st_stack_t *_st_stack_new(int stack_size) 63 | { 64 | _st_clist_t *qp; 65 | _st_stack_t *ts; 66 | int extra; 67 | 68 | /* If cache stack, we try to use stack from the cache list. */ 69 | #ifdef MD_CACHE_STACK 70 | for (qp = _st_free_stacks.next; qp != &_st_free_stacks; qp = qp->next) { 71 | ts = _ST_THREAD_STACK_PTR(qp); 72 | if (ts->stk_size >= stack_size) { 73 | /* Found a stack that is big enough */ 74 | ST_REMOVE_LINK(&ts->links); 75 | _st_num_free_stacks--; 76 | ts->links.next = NULL; 77 | ts->links.prev = NULL; 78 | return ts; 79 | } 80 | } 81 | #endif 82 | 83 | extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0; 84 | /* If not cache stack, we will free all stack in the list, which contains the stack to be freed. 85 | * Note that we should never directly free it at _st_stack_free, because it is still be used, 86 | * and will cause crash. */ 87 | #ifndef MD_CACHE_STACK 88 | for (qp = _st_free_stacks.next; qp != &_st_free_stacks;) { 89 | ts = _ST_THREAD_STACK_PTR(qp); 90 | /* Before qp is freed, move to next one, because the qp will be freed when free the ts. */ 91 | qp = qp->next; 92 | 93 | ST_REMOVE_LINK(&ts->links); 94 | _st_num_free_stacks--; 95 | 96 | #if defined(DEBUG) && !defined(MD_NO_PROTECT) 97 | mprotect(ts->vaddr, REDZONE, PROT_READ | PROT_WRITE); 98 | mprotect(ts->stk_top + extra, REDZONE, PROT_READ | PROT_WRITE); 99 | #endif 100 | 101 | _st_delete_stk_segment(ts->vaddr, ts->vaddr_size); 102 | free(ts); 103 | } 104 | #endif 105 | 106 | /* Make a new thread stack object. */ 107 | if ((ts = (_st_stack_t *)calloc(1, sizeof(_st_stack_t))) == NULL) 108 | return NULL; 109 | ts->vaddr_size = stack_size + 2*REDZONE + extra; 110 | ts->vaddr = _st_new_stk_segment(ts->vaddr_size); 111 | if (!ts->vaddr) { 112 | free(ts); 113 | return NULL; 114 | } 115 | ts->stk_size = stack_size; 116 | ts->stk_bottom = ts->vaddr + REDZONE; 117 | ts->stk_top = ts->stk_bottom + stack_size; 118 | 119 | /* For example, in OpenWRT, the memory at the begin minus 16B by mprotect is read-only. */ 120 | #if defined(DEBUG) && !defined(MD_NO_PROTECT) 121 | mprotect(ts->vaddr, REDZONE, PROT_NONE); 122 | mprotect(ts->stk_top + extra, REDZONE, PROT_NONE); 123 | #endif 124 | 125 | if (extra) { 126 | long offset = (random() % extra) & ~0xf; 127 | 128 | ts->stk_bottom += offset; 129 | ts->stk_top += offset; 130 | } 131 | 132 | return ts; 133 | } 134 | 135 | 136 | /* 137 | * Free the stack for the current thread 138 | */ 139 | void _st_stack_free(_st_stack_t *ts) 140 | { 141 | if (!ts) 142 | return; 143 | 144 | /* Put the stack on the free list */ 145 | ST_APPEND_LINK(&ts->links, _st_free_stacks.prev); 146 | _st_num_free_stacks++; 147 | } 148 | 149 | 150 | static char *_st_new_stk_segment(int size) 151 | { 152 | #ifdef MALLOC_STACK 153 | void *vaddr = malloc(size); 154 | #else 155 | static int zero_fd = -1; 156 | int mmap_flags = MAP_PRIVATE; 157 | void *vaddr; 158 | 159 | #if defined (MD_USE_SYSV_ANON_MMAP) 160 | if (zero_fd < 0) { 161 | if ((zero_fd = open("/dev/zero", O_RDWR, 0)) < 0) 162 | return NULL; 163 | fcntl(zero_fd, F_SETFD, FD_CLOEXEC); 164 | } 165 | #elif defined (MD_USE_BSD_ANON_MMAP) 166 | mmap_flags |= MAP_ANON; 167 | #else 168 | #error Unknown OS 169 | #endif 170 | 171 | vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, zero_fd, 0); 172 | if (vaddr == (void *)MAP_FAILED) 173 | return NULL; 174 | 175 | #endif /* MALLOC_STACK */ 176 | 177 | return (char *)vaddr; 178 | } 179 | 180 | 181 | void _st_delete_stk_segment(char *vaddr, int size) 182 | { 183 | #ifdef MALLOC_STACK 184 | free(vaddr); 185 | #else 186 | (void) munmap(vaddr, size); 187 | #endif 188 | } 189 | 190 | int st_randomize_stacks(int on) 191 | { 192 | int wason = _st_randomize_stacks; 193 | 194 | _st_randomize_stacks = on; 195 | if (on) 196 | srandom((unsigned int) st_utime()); 197 | 198 | return wason; 199 | } 200 | -------------------------------------------------------------------------------- /tools/backtrace/.gitignore: -------------------------------------------------------------------------------- 1 | backtrace -------------------------------------------------------------------------------- /tools/backtrace/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | LDLIBS=../../obj/libst.a -ldl 4 | CFLAGS=-g -O0 -rdynamic -I../../obj 5 | 6 | OS_NAME = $(shell uname -s) 7 | ST_TARGET = linux-debug 8 | ifeq ($(OS_NAME), Darwin) 9 | ST_TARGET = darwin-debug 10 | CPU_ARCHS = $(shell g++ -dM -E - 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #ifdef __linux__ 15 | #include 16 | #include 17 | #include 18 | 19 | void* parse_symbol_offset(char* frame) 20 | { 21 | char* p = NULL; 22 | char* p_symbol = NULL; 23 | int nn_symbol = 0; 24 | char* p_offset = NULL; 25 | int nn_offset = 0; 26 | 27 | // Read symbol and offset, for example: 28 | // /tools/backtrace(foo+0x1820) [0x555555555820] 29 | for (p = frame; *p; p++) { 30 | if (*p == '(') { 31 | p_symbol = p + 1; 32 | } else if (*p == '+') { 33 | if (p_symbol) nn_symbol = p - p_symbol; 34 | p_offset = p + 1; 35 | } else if (*p == ')') { 36 | if (p_offset) nn_offset = p - p_offset; 37 | } 38 | } 39 | if (!nn_symbol && !nn_offset) { 40 | return NULL; 41 | } 42 | 43 | // Convert offset(0x1820) to pointer, such as 0x1820. 44 | char tmp[128]; 45 | if (!nn_offset || nn_offset >= sizeof(tmp)) { 46 | return NULL; 47 | } 48 | 49 | int r0 = EOF; 50 | void* offset = NULL; 51 | tmp[nn_offset] = 0; 52 | if ((r0 = sscanf(strncpy(tmp, p_offset, nn_offset), "%p", &offset)) == EOF) { 53 | return NULL; 54 | } 55 | 56 | // Covert symbol(foo) to offset, such as 0x2fba. 57 | if (!nn_symbol || nn_symbol >= sizeof(tmp)) { 58 | return offset; 59 | } 60 | 61 | void* object_file; 62 | if ((object_file = dlopen(NULL, RTLD_LAZY)) == NULL) { 63 | return offset; 64 | } 65 | 66 | void* address; 67 | tmp[nn_symbol] = 0; 68 | if ((address = dlsym(object_file, strncpy(tmp, p_symbol, nn_symbol))) == NULL) { 69 | dlclose(object_file); 70 | return offset; 71 | } 72 | 73 | Dl_info symbol_info; 74 | if ((r0 = dladdr(address, &symbol_info)) == 0) { 75 | dlclose(object_file); 76 | return offset; 77 | } 78 | 79 | dlclose(object_file); 80 | return symbol_info.dli_saddr - symbol_info.dli_fbase + offset; 81 | } 82 | 83 | char* addr2line_format(void* addr, char* symbol, char* buffer, int nn_buffer) 84 | { 85 | char cmd[512] = {0}; 86 | int r0 = snprintf(cmd, sizeof(cmd), "addr2line -C -p -s -f -a -e %s %p", "backtrace", addr - 1); 87 | if (r0 < 0 || r0 >= sizeof(cmd)) return symbol; 88 | 89 | FILE* fp = popen(cmd, "r"); 90 | if (!fp) return symbol; 91 | 92 | char* p = fgets(buffer, nn_buffer, fp); 93 | pclose(fp); 94 | 95 | if (p == NULL) return symbol; 96 | if ((r0 = strlen(p)) == 0) return symbol; 97 | 98 | // Trait the last newline if exists. 99 | if (p[r0 - 1] == '\n') p[r0 - 1] = '\0'; 100 | 101 | // Find symbol not match by addr2line, like 102 | // 0x0000000000021c87: ?? ??:0 103 | // 0x0000000000002ffa: _start at ??:? 104 | for (p = buffer; p < buffer + r0 - 1; p++) { 105 | if (p[0] == '?' && p[1] == '?') return symbol; 106 | } 107 | 108 | return buffer; 109 | } 110 | #endif 111 | 112 | #ifdef __linux__ 113 | void bar2() 114 | { 115 | void* addresses[64]; 116 | int nn_addresses = backtrace(addresses, sizeof(addresses) / sizeof(void*)); 117 | printf("\naddresses:\n"); 118 | for (int i = 0; i < nn_addresses; i++) { 119 | printf("%p\n", addresses[i]); 120 | } 121 | 122 | char** symbols = backtrace_symbols(addresses, nn_addresses); 123 | printf("\nsymbols:\n"); 124 | for (int i = 0; i < nn_addresses; i++) { 125 | printf("%s\n", symbols[i]); 126 | } 127 | 128 | char buffer[128]; 129 | printf("\nframes:\n"); 130 | for (int i = 0; i < nn_addresses; i++) { 131 | void* frame = parse_symbol_offset(symbols[i]); 132 | char* fmt = addr2line_format(frame, symbols[i], buffer, sizeof(buffer)); 133 | int parsed = (fmt == buffer); 134 | printf("%p %d %s\n", frame, parsed, fmt); 135 | } 136 | 137 | free(symbols); 138 | 139 | printf("bar2 OK\n"); 140 | return; 141 | } 142 | #endif 143 | 144 | int always_use_builtin = 0; 145 | 146 | #pragma GCC diagnostic push 147 | #pragma GCC diagnostic ignored "-Wframe-address" 148 | void bar() { 149 | // Each item in the array pointed to by buffer is of type void *, and is the return address from the corresponding 150 | // stack frame. 151 | void* addresses[64]; 152 | int nn_addresses = backtrace(addresses, sizeof(addresses) / sizeof(void*)); 153 | 154 | if (!nn_addresses || always_use_builtin) { 155 | printf("Try to get return addresses by __builtin_return_address\n"); 156 | void* p = NULL; nn_addresses = 0; 157 | if ((p = __builtin_return_address(0)) != NULL) { 158 | addresses[nn_addresses++] = p; 159 | if ((p = __builtin_return_address(1)) != NULL) { 160 | addresses[nn_addresses++] = p; 161 | if ((p = __builtin_return_address(2)) != NULL) { 162 | addresses[nn_addresses++] = p; 163 | if ((p = __builtin_return_address(3)) != NULL) { 164 | addresses[nn_addresses++] = p; 165 | if ((p = __builtin_return_address(4)) != NULL) { 166 | addresses[nn_addresses++] = p; 167 | if ((p = __builtin_return_address(5)) != NULL) { 168 | addresses[nn_addresses++] = p; 169 | } 170 | } 171 | } 172 | } 173 | } 174 | } 175 | } 176 | 177 | char** symbols = backtrace_symbols(addresses, nn_addresses); 178 | printf("nn_addresses=%d, symbols=%p, symbols[0]=%p\n", nn_addresses, symbols, symbols[0]); 179 | 180 | printf("\naddresses:\n"); 181 | for (int i = 0; i < nn_addresses; i++) { 182 | printf("%p\n", addresses[i]); 183 | } 184 | 185 | printf("\nsymbols:\n"); 186 | for (int i = 0; i < nn_addresses; i++) { 187 | printf("%s\n", symbols[i]); 188 | } 189 | free(symbols); 190 | 191 | printf("bar OK\n"); 192 | return; 193 | } 194 | #pragma GCC diagnostic pop 195 | 196 | void foo() { 197 | bar(); 198 | #ifdef __linux__ 199 | bar2(); 200 | #endif 201 | 202 | printf("foo OK\n"); 203 | return; 204 | } 205 | 206 | void* start(void* arg) 207 | { 208 | foo(); 209 | 210 | printf("coroutine OK\n"); 211 | return NULL; 212 | } 213 | 214 | int main(int argc, char** argv) 215 | { 216 | if (argc > 1) { 217 | always_use_builtin = 1; 218 | } 219 | 220 | st_init(); 221 | 222 | st_thread_create(start, NULL, 0, 0); 223 | st_thread_exit(NULL); 224 | 225 | printf("main done\n"); 226 | return 0; 227 | } 228 | 229 | -------------------------------------------------------------------------------- /tools/helloworld/.gitignore: -------------------------------------------------------------------------------- 1 | helloworld 2 | -------------------------------------------------------------------------------- /tools/helloworld/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean 2 | 3 | LDLIBS=../../obj/libst.a 4 | CFLAGS=-g -O0 -I../../obj 5 | 6 | OS_NAME = $(shell uname -s) 7 | ST_TARGET = linux-debug 8 | ifeq ($(OS_NAME), Darwin) 9 | ST_TARGET = darwin-debug 10 | CPU_ARCHS = $(shell g++ -dM -E - 5 | 6 | #include 7 | 8 | int main(int argc, char** argv) 9 | { 10 | st_init(); 11 | 12 | int i; 13 | for (i = 0; i < 10000; i++) { 14 | printf("#%03d, Hello, state-threads world!\n", i); 15 | st_sleep(1); 16 | } 17 | 18 | return 0; 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tools/jmpbuf/.gitignore: -------------------------------------------------------------------------------- 1 | jmpbuf 2 | jmpbuf.E.txt 3 | 4 | -------------------------------------------------------------------------------- /tools/jmpbuf/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: default clean 2 | 3 | LDLIBS= 4 | CFLAGS=-g -O0 5 | 6 | OS_NAME = $(shell uname -s) 7 | ST_TARGET = linux-debug 8 | ifeq ($(OS_NAME), Darwin) 9 | ST_TARGET = darwin-debug 10 | CPU_ARCHS = $(shell g++ -dM -E - 5 | #include 6 | 7 | /* We define the jmpbuf, because the system's is different in different OS */ 8 | typedef struct _st_jmp_buf { 9 | /* 10 | * OS CPU SIZE 11 | * Darwin __amd64__/__x86_64__ long[8] 12 | * Darwin __aarch64__ long[22] 13 | * Linux __i386__ long[6] 14 | * Linux __amd64__/__x86_64__ long[8] 15 | * Linux __aarch64__ long[22] 16 | * Linux __arm__ long[16] 17 | * Linux __mips__/__mips64 long[13] 18 | * Linux __riscv long[14] 19 | * Linux __loongarch64 long[12] 20 | * Cygwin64 __amd64__/__x86_64__ long[8] 21 | */ 22 | long __jmpbuf[22]; 23 | } _st_jmp_buf_t[1]; 24 | 25 | int main(int argc, char** argv) 26 | { 27 | jmp_buf ctx = {0}; 28 | int r0 = setjmp(ctx); 29 | int nn_jb = sizeof(ctx); 30 | printf("jmp_buf: r0=%d, sizeof(jmp_buf)=%d (unsigned long long [%d])\n", r0, nn_jb, nn_jb/8); 31 | 32 | _st_jmp_buf_t ctx2 = {0}; 33 | int r1 = sizeof(_st_jmp_buf_t); 34 | int r2 = sizeof(ctx2); 35 | printf("_st_jmp_buf_t: sizeof(_st_jmp_buf_t)=%d/%d (unsigned long long [%d])\n", r1, r2, r2/8); 36 | 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /tools/pcs/.gitignore: -------------------------------------------------------------------------------- 1 | pcs 2 | 3 | -------------------------------------------------------------------------------- /tools/pcs/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean 2 | 3 | CFLAGS=-g -O0 4 | 5 | OS_NAME = $(shell uname -s) 6 | ST_TARGET = linux-debug 7 | ifeq ($(OS_NAME), Darwin) 8 | ST_TARGET = darwin-debug 9 | CPU_ARCHS = $(shell g++ -dM -E - 5 | #include 6 | #include 7 | #include 8 | 9 | void bar() 10 | { 11 | } 12 | 13 | void foo() 14 | { 15 | bar(); 16 | } 17 | 18 | int main(int argc, char** argv) 19 | { 20 | printf("OS specs:\n"); 21 | #ifdef __linux__ 22 | printf("__linux__: %d\n", __linux__); 23 | #endif 24 | #ifdef __APPLE__ 25 | printf("__APPLE__: %d\n", __APPLE__); 26 | #endif 27 | #ifdef __CYGWIN__ 28 | printf("__CYGWIN__: %d\n", __CYGWIN__); 29 | #endif 30 | #ifdef _WIN32 31 | printf("_WIN32: %d\n", _WIN32); 32 | #endif 33 | 34 | printf("\nCPU specs:\n"); 35 | #ifdef __mips__ 36 | // https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00565-2B-MIPS32-QRC-01.01.pdf 37 | printf("__mips__: %d, __mips: %d, _MIPSEL: %d\n", __mips__, __mips, _MIPSEL); 38 | #endif 39 | #ifdef __mips64 40 | printf("__mips64: %d\n", __mips64); 41 | #endif 42 | #ifdef __x86_64__ 43 | printf("__x86_64__: %d\n", __x86_64__); 44 | #endif 45 | #ifdef __loongarch64 46 | printf("__loongarch__: %d __loongarch64: %d\n", __loongarch__, __loongarch64); 47 | #endif 48 | #ifdef __riscv 49 | printf("__riscv: %d\n", __riscv); 50 | #endif 51 | #ifdef __arm__ 52 | printf("__arm__: %d\n", __arm__); 53 | #endif 54 | #ifdef __aarch64__ 55 | printf("__aarch64__: %d\n", __aarch64__); 56 | #endif 57 | 58 | printf("\nCompiler specs:\n"); 59 | #ifdef __GLIBC__ 60 | printf("__GLIBC__: %d\n", __GLIBC__); 61 | #endif 62 | 63 | printf("\nCalling conventions:\n"); 64 | foo(); 65 | 66 | printf("\nCall setjmp:\n"); 67 | jmp_buf ctx; 68 | if (!setjmp(ctx)) { 69 | printf("Call longjmp with return=1\n"); 70 | longjmp(ctx, 1); 71 | 72 | // Not reachable code. 73 | printf("Should never be here.\n"); 74 | } 75 | 76 | printf("\nDone\n"); 77 | return 0; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /tools/stack/.gitignore: -------------------------------------------------------------------------------- 1 | stack 2 | 3 | -------------------------------------------------------------------------------- /tools/stack/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean 2 | 3 | CFLAGS=-g -O0 4 | 5 | OS_NAME = $(shell uname -s) 6 | ST_TARGET = linux-debug 7 | ifeq ($(OS_NAME), Darwin) 8 | ST_TARGET = darwin-debug 9 | CPU_ARCHS = $(shell g++ -dM -E - 5 | 6 | #include 7 | #include 8 | 9 | st_mutex_t lock; 10 | st_cond_t cond; 11 | 12 | void* start(void* arg) 13 | { 14 | printf("ST: thread run\n"); 15 | 16 | printf("ST: thread wait for a while\n"); 17 | st_usleep(1.5 * 1000 * 1000); 18 | printf("ST: thread wait done\n"); 19 | 20 | int r0 = st_cond_signal(cond); 21 | printf("ST: thread cond signal, r0=%d\n", r0); 22 | 23 | printf("ST: thread lock\n"); 24 | r0 = st_mutex_lock(lock); 25 | assert(r0 == 0); 26 | 27 | r0 = st_mutex_unlock(lock); 28 | printf("ST: thread unlock\n"); 29 | 30 | return NULL; 31 | } 32 | 33 | int main(int argc, char** argv) 34 | { 35 | int r0 = st_init(); 36 | assert(r0 == 0); 37 | printf("ST: main init ok\n"); 38 | 39 | lock = st_mutex_new(); 40 | cond = st_cond_new(); 41 | 42 | st_thread_t trd = st_thread_create(start, NULL, 1, 0); 43 | printf("ST: main create ok\n"); 44 | 45 | printf("ST: main lock\n"); 46 | r0 = st_mutex_lock(lock); 47 | assert(r0 == 0); 48 | 49 | printf("ST: main cond waiting\n"); 50 | r0 = st_cond_wait(cond); 51 | printf("ST: main cond wait ok, r0=%d\n", r0); 52 | 53 | r0 = st_mutex_unlock(lock); 54 | printf("ST: main unlock\n"); 55 | 56 | st_thread_join(trd, NULL); 57 | printf("ST: main done\n"); 58 | 59 | st_mutex_destroy(lock); 60 | st_cond_destroy(cond); 61 | 62 | return 0; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /utest/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # The main dir of st. 3 | ST_DIR = .. 4 | # The main dir of st utest. 5 | ST_UTEST = . 6 | # The main dir of gtest. 7 | GTEST_DIR = $(ST_UTEST)/gtest-fit/googletest 8 | 9 | # Flags passed to the C++ compiler. 10 | CXXFLAGS += -g -O0 -std=c++11 11 | CXXFLAGS += -DGTEST_USE_OWN_TR1_TUPLE=1 12 | # Flags for warnings. 13 | WARNFLAGS += -Wall -Wno-deprecated-declarations -Wno-unused-private-field -Wno-unused-command-line-argument 14 | 15 | # House-keeping build targets. 16 | all : $(ST_DIR)/obj/st_utest 17 | 18 | clean : 19 | rm -f $(ST_DIR)/obj/st_utest* $(ST_DIR)/obj/gtest* 20 | 21 | # Usually you shouldn't tweak such internal variables, indicated by a 22 | # trailing _. 23 | GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_DIR)/include/gtest/*.h $(GTEST_DIR)/include/gtest/internal/*.h 24 | 25 | # For simplicity and to avoid depending on Google Test's 26 | # implementation details, the dependencies specified below are 27 | # conservative and not optimized. This is fine as Google Test 28 | # compiles fast and for ordinary users its source rarely changes. 29 | $(ST_DIR)/obj/gtest-all.o : $(GTEST_SRCS_) 30 | $(CXX) -c $(GTEST_DIR)/src/gtest-all.cc -o $@ \ 31 | $(CXXFLAGS) $(UTEST_FLAGS) \ 32 | $(WARNFLAGS) \ 33 | -I$(GTEST_DIR)/include -I$(GTEST_DIR) 34 | 35 | $(ST_DIR)/obj/gtest.a : $(ST_DIR)/obj/gtest-all.o 36 | $(AR) $(ARFLAGS) $@ $^ 37 | 38 | ##################################################################################### 39 | ##################################################################################### 40 | # ST(state-threads) utest section 41 | ##################################################################################### 42 | ##################################################################################### 43 | 44 | # Depends, the depends objects 45 | ST_UTEST_DEPS = $(ST_DIR)/obj/libst.a 46 | 47 | # Depends, utest header files 48 | UTEST_DEPS = $(ST_UTEST)/st_utest.hpp Makefile 49 | 50 | # Compile all sources files at current directory. For example: 51 | # (st_utest.cpp st_utest_coroutines.cpp st_utest_tcp.cpp) 52 | SOURCE_FILES = $(shell ls *.cpp) 53 | # 54 | # Convert all source files to object files. For example: 55 | # (st_utest.o st_utest_coroutines.o st_utest_tcp.o) 56 | # https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_8.html 57 | OBJECTS_FILES = $(patsubst %.cpp,%.o,$(SOURCE_FILES)) 58 | # 59 | # Prefix object files to objects. For example: 60 | # ($(ST_DIR)/obj/st_utest.o $(ST_DIR)/obj/st_utest_coroutines.o $(ST_DIR)/obj/st_utest_tcp.o) 61 | OBJECTS = $(addprefix $(ST_DIR)/obj/,$(OBJECTS_FILES)) 62 | 63 | # Objects, build each object of utest 64 | $(ST_DIR)/obj/%.o : %.cpp $(ST_UTEST_DEPS) $(UTEST_DEPS) 65 | $(CXX) -c $< -o $@ \ 66 | $(CXXFLAGS) $(UTEST_FLAGS) \ 67 | $(WARNFLAGS) \ 68 | -I$(GTEST_DIR)/include -I$(ST_UTEST) -I$(ST_DIR) -I$(ST_DIR)/obj 69 | 70 | # Generate the utest binary 71 | $(ST_DIR)/obj/st_utest : $(OBJECTS) $(ST_DIR)/obj/gtest.a $(ST_UTEST_DEPS) 72 | $(CXX) -o $@ $(CXXFLAGS) $(UTEST_FLAGS) \ 73 | -lpthread -ldl $^ 74 | -------------------------------------------------------------------------------- /utest/gtest-fit/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore CI build directory 2 | build/ 3 | xcuserdata 4 | cmake-build-debug/ 5 | .idea/ 6 | bazel-bin 7 | bazel-genfiles 8 | bazel-googletest 9 | bazel-out 10 | bazel-testlogs 11 | # python 12 | *.pyc 13 | 14 | # Visual Studio files 15 | .vs 16 | *.sdf 17 | *.opensdf 18 | *.VC.opendb 19 | *.suo 20 | *.user 21 | _ReSharper.Caches/ 22 | Win32-Debug/ 23 | Win32-Release/ 24 | x64-Debug/ 25 | x64-Release/ 26 | 27 | # Ignore autoconf / automake files 28 | Makefile.in 29 | aclocal.m4 30 | configure 31 | build-aux/ 32 | autom4te.cache/ 33 | googletest/m4/libtool.m4 34 | googletest/m4/ltoptions.m4 35 | googletest/m4/ltsugar.m4 36 | googletest/m4/ltversion.m4 37 | googletest/m4/lt~obsolete.m4 38 | googlemock/m4 39 | 40 | # Ignore generated directories. 41 | googlemock/fused-src/ 42 | googletest/fused-src/ 43 | 44 | # macOS files 45 | .DS_Store 46 | googletest/.DS_Store 47 | googletest/xcode/.DS_Store 48 | 49 | # Ignore cmake generated directories and files. 50 | CMakeFiles 51 | CTestTestfile.cmake 52 | Makefile 53 | cmake_install.cmake 54 | googlemock/CMakeFiles 55 | googlemock/CTestTestfile.cmake 56 | googlemock/Makefile 57 | googlemock/cmake_install.cmake 58 | googlemock/gtest 59 | /bin 60 | /googlemock/gmock.dir 61 | /googlemock/gmock_main.dir 62 | /googlemock/RUN_TESTS.vcxproj.filters 63 | /googlemock/RUN_TESTS.vcxproj 64 | /googlemock/INSTALL.vcxproj.filters 65 | /googlemock/INSTALL.vcxproj 66 | /googlemock/gmock_main.vcxproj.filters 67 | /googlemock/gmock_main.vcxproj 68 | /googlemock/gmock.vcxproj.filters 69 | /googlemock/gmock.vcxproj 70 | /googlemock/gmock.sln 71 | /googlemock/ALL_BUILD.vcxproj.filters 72 | /googlemock/ALL_BUILD.vcxproj 73 | /lib 74 | /Win32 75 | /ZERO_CHECK.vcxproj.filters 76 | /ZERO_CHECK.vcxproj 77 | /RUN_TESTS.vcxproj.filters 78 | /RUN_TESTS.vcxproj 79 | /INSTALL.vcxproj.filters 80 | /INSTALL.vcxproj 81 | /googletest-distribution.sln 82 | /CMakeCache.txt 83 | /ALL_BUILD.vcxproj.filters 84 | /ALL_BUILD.vcxproj 85 | -------------------------------------------------------------------------------- /utest/gtest-fit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Note: CMake support is community-based. The maintainers do not use CMake 2 | # internally. 3 | 4 | cmake_minimum_required(VERSION 2.8.12) 5 | 6 | if (POLICY CMP0048) 7 | cmake_policy(SET CMP0048 NEW) 8 | endif (POLICY CMP0048) 9 | 10 | project(googletest-distribution) 11 | set(GOOGLETEST_VERSION 1.11.0) 12 | 13 | if (CMAKE_VERSION VERSION_GREATER "3.0.2") 14 | if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX) 15 | set(CMAKE_CXX_EXTENSIONS OFF) 16 | endif() 17 | endif() 18 | 19 | enable_testing() 20 | 21 | include(CMakeDependentOption) 22 | include(GNUInstallDirs) 23 | 24 | #Note that googlemock target already builds googletest 25 | option(BUILD_GMOCK "Builds the googlemock subproject" ON) 26 | option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON) 27 | 28 | if(BUILD_GMOCK) 29 | add_subdirectory( googlemock ) 30 | else() 31 | add_subdirectory( googletest ) 32 | endif() 33 | -------------------------------------------------------------------------------- /utest/gtest-fit/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/README.md: -------------------------------------------------------------------------------- 1 | # Googletest Mocking (gMock) Framework 2 | 3 | ### Overview 4 | 5 | Google's framework for writing and using C++ mock classes. It can help you 6 | derive better designs of your system and write better tests. 7 | 8 | It is inspired by: 9 | 10 | * [jMock](http://www.jmock.org/) 11 | * [EasyMock](http://www.easymock.org/) 12 | * [Hamcrest](http://code.google.com/p/hamcrest/) 13 | 14 | It is designed with C++'s specifics in mind. 15 | 16 | gMock: 17 | 18 | - Provides a declarative syntax for defining mocks. 19 | - Can define partial (hybrid) mocks, which are a cross of real and mock 20 | objects. 21 | - Handles functions of arbitrary types and overloaded functions. 22 | - Comes with a rich set of matchers for validating function arguments. 23 | - Uses an intuitive syntax for controlling the behavior of a mock. 24 | - Does automatic verification of expectations (no record-and-replay needed). 25 | - Allows arbitrary (partial) ordering constraints on function calls to be 26 | expressed. 27 | - Lets a user extend it by defining new matchers and actions. 28 | - Does not use exceptions. 29 | - Is easy to learn and use. 30 | 31 | Details and examples can be found here: 32 | 33 | * [gMock for Dummies](https://google.github.io/googletest/gmock_for_dummies.html) 34 | * [Legacy gMock FAQ](https://google.github.io/googletest/gmock_faq.html) 35 | * [gMock Cookbook](https://google.github.io/googletest/gmock_cook_book.html) 36 | * [gMock Cheat Sheet](https://google.github.io/googletest/gmock_cheat_sheet.html) 37 | 38 | Please note that code under scripts/generator/ is from the 39 | [cppclean project](http://code.google.com/p/cppclean/) and under the Apache 40 | License, which is different from GoogleMock's license. 41 | 42 | GoogleMock is a part of 43 | [GoogleTest C++ testing framework](http://github.com/google/googletest/) and a 44 | subject to the same requirements. 45 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/cmake/gmock.pc.in: -------------------------------------------------------------------------------- 1 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 2 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 3 | 4 | Name: gmock 5 | Description: GoogleMock (without main() function) 6 | Version: @PROJECT_VERSION@ 7 | URL: https://github.com/google/googletest 8 | Requires: gtest = @PROJECT_VERSION@ 9 | Libs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@ 10 | Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ 11 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/cmake/gmock_main.pc.in: -------------------------------------------------------------------------------- 1 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 2 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 3 | 4 | Name: gmock_main 5 | Description: GoogleMock (with main() function) 6 | Version: @PROJECT_VERSION@ 7 | URL: https://github.com/google/googletest 8 | Requires: gmock = @PROJECT_VERSION@ 9 | Libs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@ 10 | Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ 11 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/gmock-cardinalities.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | // Google Mock - a framework for writing C++ mock classes. 32 | // 33 | // This file implements some commonly used cardinalities. More 34 | // cardinalities can be defined by the user implementing the 35 | // CardinalityInterface interface if necessary. 36 | 37 | // GOOGLETEST_CM0002 DO NOT DELETE 38 | 39 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 40 | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 41 | 42 | #include 43 | #include 44 | #include // NOLINT 45 | #include "gmock/internal/gmock-port.h" 46 | #include "gtest/gtest.h" 47 | 48 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 49 | /* class A needs to have dll-interface to be used by clients of class B */) 50 | 51 | namespace testing { 52 | 53 | // To implement a cardinality Foo, define: 54 | // 1. a class FooCardinality that implements the 55 | // CardinalityInterface interface, and 56 | // 2. a factory function that creates a Cardinality object from a 57 | // const FooCardinality*. 58 | // 59 | // The two-level delegation design follows that of Matcher, providing 60 | // consistency for extension developers. It also eases ownership 61 | // management as Cardinality objects can now be copied like plain values. 62 | 63 | // The implementation of a cardinality. 64 | class CardinalityInterface { 65 | public: 66 | virtual ~CardinalityInterface() {} 67 | 68 | // Conservative estimate on the lower/upper bound of the number of 69 | // calls allowed. 70 | virtual int ConservativeLowerBound() const { return 0; } 71 | virtual int ConservativeUpperBound() const { return INT_MAX; } 72 | 73 | // Returns true if and only if call_count calls will satisfy this 74 | // cardinality. 75 | virtual bool IsSatisfiedByCallCount(int call_count) const = 0; 76 | 77 | // Returns true if and only if call_count calls will saturate this 78 | // cardinality. 79 | virtual bool IsSaturatedByCallCount(int call_count) const = 0; 80 | 81 | // Describes self to an ostream. 82 | virtual void DescribeTo(::std::ostream* os) const = 0; 83 | }; 84 | 85 | // A Cardinality is a copyable and IMMUTABLE (except by assignment) 86 | // object that specifies how many times a mock function is expected to 87 | // be called. The implementation of Cardinality is just a std::shared_ptr 88 | // to const CardinalityInterface. Don't inherit from Cardinality! 89 | class GTEST_API_ Cardinality { 90 | public: 91 | // Constructs a null cardinality. Needed for storing Cardinality 92 | // objects in STL containers. 93 | Cardinality() {} 94 | 95 | // Constructs a Cardinality from its implementation. 96 | explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} 97 | 98 | // Conservative estimate on the lower/upper bound of the number of 99 | // calls allowed. 100 | int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } 101 | int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } 102 | 103 | // Returns true if and only if call_count calls will satisfy this 104 | // cardinality. 105 | bool IsSatisfiedByCallCount(int call_count) const { 106 | return impl_->IsSatisfiedByCallCount(call_count); 107 | } 108 | 109 | // Returns true if and only if call_count calls will saturate this 110 | // cardinality. 111 | bool IsSaturatedByCallCount(int call_count) const { 112 | return impl_->IsSaturatedByCallCount(call_count); 113 | } 114 | 115 | // Returns true if and only if call_count calls will over-saturate this 116 | // cardinality, i.e. exceed the maximum number of allowed calls. 117 | bool IsOverSaturatedByCallCount(int call_count) const { 118 | return impl_->IsSaturatedByCallCount(call_count) && 119 | !impl_->IsSatisfiedByCallCount(call_count); 120 | } 121 | 122 | // Describes self to an ostream 123 | void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } 124 | 125 | // Describes the given actual call count to an ostream. 126 | static void DescribeActualCallCountTo(int actual_call_count, 127 | ::std::ostream* os); 128 | 129 | private: 130 | std::shared_ptr impl_; 131 | }; 132 | 133 | // Creates a cardinality that allows at least n calls. 134 | GTEST_API_ Cardinality AtLeast(int n); 135 | 136 | // Creates a cardinality that allows at most n calls. 137 | GTEST_API_ Cardinality AtMost(int n); 138 | 139 | // Creates a cardinality that allows any number of calls. 140 | GTEST_API_ Cardinality AnyNumber(); 141 | 142 | // Creates a cardinality that allows between min and max calls. 143 | GTEST_API_ Cardinality Between(int min, int max); 144 | 145 | // Creates a cardinality that allows exactly n calls. 146 | GTEST_API_ Cardinality Exactly(int n); 147 | 148 | // Creates a cardinality from its implementation. 149 | inline Cardinality MakeCardinality(const CardinalityInterface* c) { 150 | return Cardinality(c); 151 | } 152 | 153 | } // namespace testing 154 | 155 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 156 | 157 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 158 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/gmock-more-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | // Google Mock - a framework for writing C++ mock classes. 32 | // 33 | // This file implements some matchers that depend on gmock-matchers.h. 34 | // 35 | // Note that tests are implemented in gmock-matchers_test.cc rather than 36 | // gmock-more-matchers-test.cc. 37 | 38 | // GOOGLETEST_CM0002 DO NOT DELETE 39 | 40 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ 41 | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ 42 | 43 | #include "gmock/gmock-matchers.h" 44 | 45 | namespace testing { 46 | 47 | // Silence C4100 (unreferenced formal 48 | // parameter) for MSVC 49 | #ifdef _MSC_VER 50 | # pragma warning(push) 51 | # pragma warning(disable:4100) 52 | #if (_MSC_VER == 1900) 53 | // and silence C4800 (C4800: 'int *const ': forcing value 54 | // to bool 'true' or 'false') for MSVC 14 55 | # pragma warning(disable:4800) 56 | #endif 57 | #endif 58 | 59 | // Defines a matcher that matches an empty container. The container must 60 | // support both size() and empty(), which all STL-like containers provide. 61 | MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { 62 | if (arg.empty()) { 63 | return true; 64 | } 65 | *result_listener << "whose size is " << arg.size(); 66 | return false; 67 | } 68 | 69 | // Define a matcher that matches a value that evaluates in boolean 70 | // context to true. Useful for types that define "explicit operator 71 | // bool" operators and so can't be compared for equality with true 72 | // and false. 73 | MATCHER(IsTrue, negation ? "is false" : "is true") { 74 | return static_cast(arg); 75 | } 76 | 77 | // Define a matcher that matches a value that evaluates in boolean 78 | // context to false. Useful for types that define "explicit operator 79 | // bool" operators and so can't be compared for equality with true 80 | // and false. 81 | MATCHER(IsFalse, negation ? "is true" : "is false") { 82 | return !static_cast(arg); 83 | } 84 | 85 | #ifdef _MSC_VER 86 | # pragma warning(pop) 87 | #endif 88 | 89 | 90 | } // namespace testing 91 | 92 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ 93 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/gmock.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | // Google Mock - a framework for writing C++ mock classes. 32 | // 33 | // This is the main header file a user should include. 34 | 35 | // GOOGLETEST_CM0002 DO NOT DELETE 36 | 37 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ 38 | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ 39 | 40 | // This file implements the following syntax: 41 | // 42 | // ON_CALL(mock_object, Method(...)) 43 | // .With(...) ? 44 | // .WillByDefault(...); 45 | // 46 | // where With() is optional and WillByDefault() must appear exactly 47 | // once. 48 | // 49 | // EXPECT_CALL(mock_object, Method(...)) 50 | // .With(...) ? 51 | // .Times(...) ? 52 | // .InSequence(...) * 53 | // .WillOnce(...) * 54 | // .WillRepeatedly(...) ? 55 | // .RetiresOnSaturation() ? ; 56 | // 57 | // where all clauses are optional and WillOnce() can be repeated. 58 | 59 | #include "gmock/gmock-actions.h" 60 | #include "gmock/gmock-cardinalities.h" 61 | #include "gmock/gmock-function-mocker.h" 62 | #include "gmock/gmock-matchers.h" 63 | #include "gmock/gmock-more-actions.h" 64 | #include "gmock/gmock-more-matchers.h" 65 | #include "gmock/gmock-nice-strict.h" 66 | #include "gmock/internal/gmock-internal-utils.h" 67 | 68 | namespace testing { 69 | 70 | // Declares Google Mock flags that we want a user to use programmatically. 71 | GMOCK_DECLARE_bool_(catch_leaked_mocks); 72 | GMOCK_DECLARE_string_(verbose); 73 | GMOCK_DECLARE_int32_(default_mock_behavior); 74 | 75 | // Initializes Google Mock. This must be called before running the 76 | // tests. In particular, it parses the command line for the flags 77 | // that Google Mock recognizes. Whenever a Google Mock flag is seen, 78 | // it is removed from argv, and *argc is decremented. 79 | // 80 | // No value is returned. Instead, the Google Mock flag variables are 81 | // updated. 82 | // 83 | // Since Google Test is needed for Google Mock to work, this function 84 | // also initializes Google Test and parses its flags, if that hasn't 85 | // been done. 86 | GTEST_API_ void InitGoogleMock(int* argc, char** argv); 87 | 88 | // This overloaded version can be used in Windows programs compiled in 89 | // UNICODE mode. 90 | GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv); 91 | 92 | // This overloaded version can be used on Arduino/embedded platforms where 93 | // there is no argc/argv. 94 | GTEST_API_ void InitGoogleMock(); 95 | 96 | } // namespace testing 97 | 98 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ 99 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/internal/custom/README.md: -------------------------------------------------------------------------------- 1 | # Customization Points 2 | 3 | The custom directory is an injection point for custom user configurations. 4 | 5 | ## Header `gmock-port.h` 6 | 7 | The following macros can be defined: 8 | 9 | ### Flag related macros: 10 | 11 | * `GMOCK_DECLARE_bool_(name)` 12 | * `GMOCK_DECLARE_int32_(name)` 13 | * `GMOCK_DECLARE_string_(name)` 14 | * `GMOCK_DEFINE_bool_(name, default_val, doc)` 15 | * `GMOCK_DEFINE_int32_(name, default_val, doc)` 16 | * `GMOCK_DEFINE_string_(name, default_val, doc)` 17 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/internal/custom/gmock-generated-actions.h: -------------------------------------------------------------------------------- 1 | // GOOGLETEST_CM0002 DO NOT DELETE 2 | 3 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 4 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 5 | 6 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 7 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/internal/custom/gmock-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // GOOGLETEST_CM0002 DO NOT DELETE 33 | 34 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ 35 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ 36 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ 37 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/internal/custom/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | // GOOGLETEST_CM0002 DO NOT DELETE 35 | 36 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 37 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 38 | 39 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 40 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/include/gmock/internal/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Low-level types and utilities for porting Google Mock to various 32 | // platforms. All macros ending with _ and symbols defined in an 33 | // internal namespace are subject to change without notice. Code 34 | // outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't 35 | // end with _ are part of Google Mock's public API and can be used by 36 | // code outside Google Mock. 37 | 38 | // GOOGLETEST_CM0002 DO NOT DELETE 39 | 40 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 41 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | // Most of the utilities needed for porting Google Mock are also 49 | // required for Google Test and are defined in gtest-port.h. 50 | // 51 | // Note to maintainers: to reduce code duplication, prefer adding 52 | // portability utilities to Google Test's gtest-port.h instead of 53 | // here, as Google Mock depends on Google Test. Only add a utility 54 | // here if it's truly specific to Google Mock. 55 | 56 | #include "gtest/internal/gtest-port.h" 57 | #include "gmock/internal/custom/gmock-port.h" 58 | 59 | // For MS Visual C++, check the compiler version. At least VS 2015 is 60 | // required to compile Google Mock. 61 | #if defined(_MSC_VER) && _MSC_VER < 1900 62 | # error "At least Visual C++ 2015 (14.0) is required to compile Google Mock." 63 | #endif 64 | 65 | // Macro for referencing flags. This is public as we want the user to 66 | // use this syntax to reference Google Mock flags. 67 | #define GMOCK_FLAG(name) FLAGS_gmock_##name 68 | 69 | #if !defined(GMOCK_DECLARE_bool_) 70 | 71 | // Macros for declaring flags. 72 | # define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) 73 | # define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name) 74 | # define GMOCK_DECLARE_string_(name) \ 75 | extern GTEST_API_ ::std::string GMOCK_FLAG(name) 76 | 77 | // Macros for defining flags. 78 | # define GMOCK_DEFINE_bool_(name, default_val, doc) \ 79 | GTEST_API_ bool GMOCK_FLAG(name) = (default_val) 80 | # define GMOCK_DEFINE_int32_(name, default_val, doc) \ 81 | GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val) 82 | # define GMOCK_DEFINE_string_(name, default_val, doc) \ 83 | GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) 84 | 85 | #endif // !defined(GMOCK_DECLARE_bool_) 86 | 87 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 88 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/src/gmock-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Google C++ Mocking Framework (Google Mock) 32 | // 33 | // This file #includes all Google Mock implementation .cc files. The 34 | // purpose is to allow a user to build Google Mock by compiling this 35 | // file alone. 36 | 37 | // This line ensures that gmock.h can be compiled on its own, even 38 | // when it's fused. 39 | #include "gmock/gmock.h" 40 | 41 | // The following lines pull in the real gmock *.cc files. 42 | #include "src/gmock-cardinalities.cc" 43 | #include "src/gmock-internal-utils.cc" 44 | #include "src/gmock-matchers.cc" 45 | #include "src/gmock-spec-builders.cc" 46 | #include "src/gmock.cc" 47 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/src/gmock-cardinalities.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | // Google Mock - a framework for writing C++ mock classes. 32 | // 33 | // This file implements cardinalities. 34 | 35 | #include "gmock/gmock-cardinalities.h" 36 | 37 | #include 38 | #include // NOLINT 39 | #include 40 | #include 41 | #include "gmock/internal/gmock-internal-utils.h" 42 | #include "gtest/gtest.h" 43 | 44 | namespace testing { 45 | 46 | namespace { 47 | 48 | // Implements the Between(m, n) cardinality. 49 | class BetweenCardinalityImpl : public CardinalityInterface { 50 | public: 51 | BetweenCardinalityImpl(int min, int max) 52 | : min_(min >= 0 ? min : 0), 53 | max_(max >= min_ ? max : min_) { 54 | std::stringstream ss; 55 | if (min < 0) { 56 | ss << "The invocation lower bound must be >= 0, " 57 | << "but is actually " << min << "."; 58 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 59 | } else if (max < 0) { 60 | ss << "The invocation upper bound must be >= 0, " 61 | << "but is actually " << max << "."; 62 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 63 | } else if (min > max) { 64 | ss << "The invocation upper bound (" << max 65 | << ") must be >= the invocation lower bound (" << min 66 | << ")."; 67 | internal::Expect(false, __FILE__, __LINE__, ss.str()); 68 | } 69 | } 70 | 71 | // Conservative estimate on the lower/upper bound of the number of 72 | // calls allowed. 73 | int ConservativeLowerBound() const override { return min_; } 74 | int ConservativeUpperBound() const override { return max_; } 75 | 76 | bool IsSatisfiedByCallCount(int call_count) const override { 77 | return min_ <= call_count && call_count <= max_; 78 | } 79 | 80 | bool IsSaturatedByCallCount(int call_count) const override { 81 | return call_count >= max_; 82 | } 83 | 84 | void DescribeTo(::std::ostream* os) const override; 85 | 86 | private: 87 | const int min_; 88 | const int max_; 89 | 90 | GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); 91 | }; 92 | 93 | // Formats "n times" in a human-friendly way. 94 | inline std::string FormatTimes(int n) { 95 | if (n == 1) { 96 | return "once"; 97 | } else if (n == 2) { 98 | return "twice"; 99 | } else { 100 | std::stringstream ss; 101 | ss << n << " times"; 102 | return ss.str(); 103 | } 104 | } 105 | 106 | // Describes the Between(m, n) cardinality in human-friendly text. 107 | void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const { 108 | if (min_ == 0) { 109 | if (max_ == 0) { 110 | *os << "never called"; 111 | } else if (max_ == INT_MAX) { 112 | *os << "called any number of times"; 113 | } else { 114 | *os << "called at most " << FormatTimes(max_); 115 | } 116 | } else if (min_ == max_) { 117 | *os << "called " << FormatTimes(min_); 118 | } else if (max_ == INT_MAX) { 119 | *os << "called at least " << FormatTimes(min_); 120 | } else { 121 | // 0 < min_ < max_ < INT_MAX 122 | *os << "called between " << min_ << " and " << max_ << " times"; 123 | } 124 | } 125 | 126 | } // Unnamed namespace 127 | 128 | // Describes the given call count to an ostream. 129 | void Cardinality::DescribeActualCallCountTo(int actual_call_count, 130 | ::std::ostream* os) { 131 | if (actual_call_count > 0) { 132 | *os << "called " << FormatTimes(actual_call_count); 133 | } else { 134 | *os << "never called"; 135 | } 136 | } 137 | 138 | // Creates a cardinality that allows at least n calls. 139 | GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); } 140 | 141 | // Creates a cardinality that allows at most n calls. 142 | GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); } 143 | 144 | // Creates a cardinality that allows any number of calls. 145 | GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); } 146 | 147 | // Creates a cardinality that allows between min and max calls. 148 | GTEST_API_ Cardinality Between(int min, int max) { 149 | return Cardinality(new BetweenCardinalityImpl(min, max)); 150 | } 151 | 152 | // Creates a cardinality that allows exactly n calls. 153 | GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); } 154 | 155 | } // namespace testing 156 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/src/gmock-internal-utils.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | // Google Mock - a framework for writing C++ mock classes. 32 | // 33 | // This file defines some utilities useful for implementing Google 34 | // Mock. They are subject to change without notice, so please DO NOT 35 | // USE THEM IN USER CODE. 36 | 37 | #include "gmock/internal/gmock-internal-utils.h" 38 | 39 | #include 40 | #include // NOLINT 41 | #include 42 | #include "gmock/gmock.h" 43 | #include "gmock/internal/gmock-port.h" 44 | #include "gtest/gtest.h" 45 | 46 | namespace testing { 47 | namespace internal { 48 | 49 | // Joins a vector of strings as if they are fields of a tuple; returns 50 | // the joined string. 51 | GTEST_API_ std::string JoinAsTuple(const Strings& fields) { 52 | switch (fields.size()) { 53 | case 0: 54 | return ""; 55 | case 1: 56 | return fields[0]; 57 | default: 58 | std::string result = "(" + fields[0]; 59 | for (size_t i = 1; i < fields.size(); i++) { 60 | result += ", "; 61 | result += fields[i]; 62 | } 63 | result += ")"; 64 | return result; 65 | } 66 | } 67 | 68 | // Converts an identifier name to a space-separated list of lower-case 69 | // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is 70 | // treated as one word. For example, both "FooBar123" and 71 | // "foo_bar_123" are converted to "foo bar 123". 72 | GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) { 73 | std::string result; 74 | char prev_char = '\0'; 75 | for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { 76 | // We don't care about the current locale as the input is 77 | // guaranteed to be a valid C++ identifier name. 78 | const bool starts_new_word = IsUpper(*p) || 79 | (!IsAlpha(prev_char) && IsLower(*p)) || 80 | (!IsDigit(prev_char) && IsDigit(*p)); 81 | 82 | if (IsAlNum(*p)) { 83 | if (starts_new_word && result != "") 84 | result += ' '; 85 | result += ToLower(*p); 86 | } 87 | } 88 | return result; 89 | } 90 | 91 | // This class reports Google Mock failures as Google Test failures. A 92 | // user can define another class in a similar fashion if they intend to 93 | // use Google Mock with a testing framework other than Google Test. 94 | class GoogleTestFailureReporter : public FailureReporterInterface { 95 | public: 96 | void ReportFailure(FailureType type, const char* file, int line, 97 | const std::string& message) override { 98 | AssertHelper(type == kFatal ? 99 | TestPartResult::kFatalFailure : 100 | TestPartResult::kNonFatalFailure, 101 | file, 102 | line, 103 | message.c_str()) = Message(); 104 | if (type == kFatal) { 105 | posix::Abort(); 106 | } 107 | } 108 | }; 109 | 110 | // Returns the global failure reporter. Will create a 111 | // GoogleTestFailureReporter and return it the first time called. 112 | GTEST_API_ FailureReporterInterface* GetFailureReporter() { 113 | // Points to the global failure reporter used by Google Mock. gcc 114 | // guarantees that the following use of failure_reporter is 115 | // thread-safe. We may need to add additional synchronization to 116 | // protect failure_reporter if we port Google Mock to other 117 | // compilers. 118 | static FailureReporterInterface* const failure_reporter = 119 | new GoogleTestFailureReporter(); 120 | return failure_reporter; 121 | } 122 | 123 | // Protects global resources (stdout in particular) used by Log(). 124 | static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); 125 | 126 | // Returns true if and only if a log with the given severity is visible 127 | // according to the --gmock_verbose flag. 128 | GTEST_API_ bool LogIsVisible(LogSeverity severity) { 129 | if (GMOCK_FLAG(verbose) == kInfoVerbosity) { 130 | // Always show the log if --gmock_verbose=info. 131 | return true; 132 | } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { 133 | // Always hide it if --gmock_verbose=error. 134 | return false; 135 | } else { 136 | // If --gmock_verbose is neither "info" nor "error", we treat it 137 | // as "warning" (its default value). 138 | return severity == kWarning; 139 | } 140 | } 141 | 142 | // Prints the given message to stdout if and only if 'severity' >= the level 143 | // specified by the --gmock_verbose flag. If stack_frames_to_skip >= 144 | // 0, also prints the stack trace excluding the top 145 | // stack_frames_to_skip frames. In opt mode, any positive 146 | // stack_frames_to_skip is treated as 0, since we don't know which 147 | // function calls will be inlined by the compiler and need to be 148 | // conservative. 149 | GTEST_API_ void Log(LogSeverity severity, const std::string& message, 150 | int stack_frames_to_skip) { 151 | if (!LogIsVisible(severity)) 152 | return; 153 | 154 | // Ensures that logs from different threads don't interleave. 155 | MutexLock l(&g_log_mutex); 156 | 157 | if (severity == kWarning) { 158 | // Prints a GMOCK WARNING marker to make the warnings easily searchable. 159 | std::cout << "\nGMOCK WARNING:"; 160 | } 161 | // Pre-pends a new-line to message if it doesn't start with one. 162 | if (message.empty() || message[0] != '\n') { 163 | std::cout << "\n"; 164 | } 165 | std::cout << message; 166 | if (stack_frames_to_skip >= 0) { 167 | #ifdef NDEBUG 168 | // In opt mode, we have to be conservative and skip no stack frame. 169 | const int actual_to_skip = 0; 170 | #else 171 | // In dbg mode, we can do what the caller tell us to do (plus one 172 | // for skipping this function's stack frame). 173 | const int actual_to_skip = stack_frames_to_skip + 1; 174 | #endif // NDEBUG 175 | 176 | // Appends a new-line to message if it doesn't end with one. 177 | if (!message.empty() && *message.rbegin() != '\n') { 178 | std::cout << "\n"; 179 | } 180 | std::cout << "Stack trace:\n" 181 | << ::testing::internal::GetCurrentOsStackTraceExceptTop( 182 | ::testing::UnitTest::GetInstance(), actual_to_skip); 183 | } 184 | std::cout << ::std::flush; 185 | } 186 | 187 | GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); } 188 | 189 | GTEST_API_ void IllegalDoDefault(const char* file, int line) { 190 | internal::Assert( 191 | false, file, line, 192 | "You are using DoDefault() inside a composite action like " 193 | "DoAll() or WithArgs(). This is not supported for technical " 194 | "reasons. Please instead spell out the default action, or " 195 | "assign the default action to an Action variable and use " 196 | "the variable in various places."); 197 | } 198 | 199 | } // namespace internal 200 | } // namespace testing 201 | -------------------------------------------------------------------------------- /utest/gtest-fit/googlemock/src/gmock_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | #include 32 | #include "gmock/gmock.h" 33 | #include "gtest/gtest.h" 34 | 35 | #if GTEST_OS_ESP8266 || GTEST_OS_ESP32 36 | #if GTEST_OS_ESP8266 37 | extern "C" { 38 | #endif 39 | void setup() { 40 | // Since Google Mock depends on Google Test, InitGoogleMock() is 41 | // also responsible for initializing Google Test. Therefore there's 42 | // no need for calling testing::InitGoogleTest() separately. 43 | testing::InitGoogleMock(); 44 | } 45 | void loop() { RUN_ALL_TESTS(); } 46 | #if GTEST_OS_ESP8266 47 | } 48 | #endif 49 | 50 | #else 51 | 52 | // MS C++ compiler/linker has a bug on Windows (not on Windows CE), which 53 | // causes a link error when _tmain is defined in a static library and UNICODE 54 | // is enabled. For this reason instead of _tmain, main function is used on 55 | // Windows. See the following link to track the current status of this bug: 56 | // https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library 57 | // // NOLINT 58 | #if GTEST_OS_WINDOWS_MOBILE 59 | # include // NOLINT 60 | 61 | GTEST_API_ int _tmain(int argc, TCHAR** argv) { 62 | #else 63 | GTEST_API_ int main(int argc, char** argv) { 64 | #endif // GTEST_OS_WINDOWS_MOBILE 65 | std::cout << "Running main() from gmock_main.cc\n"; 66 | // Since Google Mock depends on Google Test, InitGoogleMock() is 67 | // also responsible for initializing Google Test. Therefore there's 68 | // no need for calling testing::InitGoogleTest() separately. 69 | testing::InitGoogleMock(&argc, argv); 70 | return RUN_ALL_TESTS(); 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/cmake/Config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | include(CMakeFindDependencyMacro) 3 | if (@GTEST_HAS_PTHREAD@) 4 | set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@) 5 | find_dependency(Threads) 6 | endif() 7 | 8 | include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") 9 | check_required_components("@project_name@") 10 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/cmake/gtest.pc.in: -------------------------------------------------------------------------------- 1 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 2 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 3 | 4 | Name: gtest 5 | Description: GoogleTest (without main() function) 6 | Version: @PROJECT_VERSION@ 7 | URL: https://github.com/google/googletest 8 | Libs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@ 9 | Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ 10 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/cmake/gtest_main.pc.in: -------------------------------------------------------------------------------- 1 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 2 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 3 | 4 | Name: gtest_main 5 | Description: GoogleTest (with main() function) 6 | Version: @PROJECT_VERSION@ 7 | URL: https://github.com/google/googletest 8 | Requires: gtest = @PROJECT_VERSION@ 9 | Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@ 10 | Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ 11 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/cmake/libgtest.la.in: -------------------------------------------------------------------------------- 1 | # libgtest.la - a libtool library file 2 | # Generated by libtool (GNU libtool) 2.4.6 3 | 4 | # Please DO NOT delete this file! 5 | # It is necessary for linking the library. 6 | 7 | # Names of this library. 8 | library_names='libgtest.so' 9 | 10 | # Is this an already installed library? 11 | installed=yes 12 | 13 | # Should we warn about portability when linking against -modules? 14 | shouldnotlink=no 15 | 16 | # Files to dlopen/dlpreopen 17 | dlopen='' 18 | dlpreopen='' 19 | 20 | # Directory that this library needs to be installed in: 21 | libdir='@CMAKE_INSTALL_FULL_LIBDIR@' 22 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/gtest-message.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // The Google C++ Testing and Mocking Framework (Google Test) 32 | // 33 | // This header file defines the Message class. 34 | // 35 | // IMPORTANT NOTE: Due to limitation of the C++ language, we have to 36 | // leave some internal implementation details in this header file. 37 | // They are clearly marked by comments like this: 38 | // 39 | // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 40 | // 41 | // Such code is NOT meant to be used by a user directly, and is subject 42 | // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user 43 | // program! 44 | 45 | // GOOGLETEST_CM0001 DO NOT DELETE 46 | 47 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 48 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 49 | 50 | #include 51 | #include 52 | #include 53 | 54 | #include "gtest/internal/gtest-port.h" 55 | 56 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 57 | /* class A needs to have dll-interface to be used by clients of class B */) 58 | 59 | // Ensures that there is at least one operator<< in the global namespace. 60 | // See Message& operator<<(...) below for why. 61 | void operator<<(const testing::internal::Secret&, int); 62 | 63 | namespace testing { 64 | 65 | // The Message class works like an ostream repeater. 66 | // 67 | // Typical usage: 68 | // 69 | // 1. You stream a bunch of values to a Message object. 70 | // It will remember the text in a stringstream. 71 | // 2. Then you stream the Message object to an ostream. 72 | // This causes the text in the Message to be streamed 73 | // to the ostream. 74 | // 75 | // For example; 76 | // 77 | // testing::Message foo; 78 | // foo << 1 << " != " << 2; 79 | // std::cout << foo; 80 | // 81 | // will print "1 != 2". 82 | // 83 | // Message is not intended to be inherited from. In particular, its 84 | // destructor is not virtual. 85 | // 86 | // Note that stringstream behaves differently in gcc and in MSVC. You 87 | // can stream a NULL char pointer to it in the former, but not in the 88 | // latter (it causes an access violation if you do). The Message 89 | // class hides this difference by treating a NULL char pointer as 90 | // "(null)". 91 | class GTEST_API_ Message { 92 | private: 93 | // The type of basic IO manipulators (endl, ends, and flush) for 94 | // narrow streams. 95 | typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); 96 | 97 | public: 98 | // Constructs an empty Message. 99 | Message(); 100 | 101 | // Copy constructor. 102 | Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT 103 | *ss_ << msg.GetString(); 104 | } 105 | 106 | // Constructs a Message from a C-string. 107 | explicit Message(const char* str) : ss_(new ::std::stringstream) { 108 | *ss_ << str; 109 | } 110 | 111 | // Streams a non-pointer value to this object. 112 | template 113 | inline Message& operator <<(const T& val) { 114 | // Some libraries overload << for STL containers. These 115 | // overloads are defined in the global namespace instead of ::std. 116 | // 117 | // C++'s symbol lookup rule (i.e. Koenig lookup) says that these 118 | // overloads are visible in either the std namespace or the global 119 | // namespace, but not other namespaces, including the testing 120 | // namespace which Google Test's Message class is in. 121 | // 122 | // To allow STL containers (and other types that has a << operator 123 | // defined in the global namespace) to be used in Google Test 124 | // assertions, testing::Message must access the custom << operator 125 | // from the global namespace. With this using declaration, 126 | // overloads of << defined in the global namespace and those 127 | // visible via Koenig lookup are both exposed in this function. 128 | using ::operator <<; 129 | *ss_ << val; 130 | return *this; 131 | } 132 | 133 | // Streams a pointer value to this object. 134 | // 135 | // This function is an overload of the previous one. When you 136 | // stream a pointer to a Message, this definition will be used as it 137 | // is more specialized. (The C++ Standard, section 138 | // [temp.func.order].) If you stream a non-pointer, then the 139 | // previous definition will be used. 140 | // 141 | // The reason for this overload is that streaming a NULL pointer to 142 | // ostream is undefined behavior. Depending on the compiler, you 143 | // may get "0", "(nil)", "(null)", or an access violation. To 144 | // ensure consistent result across compilers, we always treat NULL 145 | // as "(null)". 146 | template 147 | inline Message& operator <<(T* const& pointer) { // NOLINT 148 | if (pointer == nullptr) { 149 | *ss_ << "(null)"; 150 | } else { 151 | *ss_ << pointer; 152 | } 153 | return *this; 154 | } 155 | 156 | // Since the basic IO manipulators are overloaded for both narrow 157 | // and wide streams, we have to provide this specialized definition 158 | // of operator <<, even though its body is the same as the 159 | // templatized version above. Without this definition, streaming 160 | // endl or other basic IO manipulators to Message will confuse the 161 | // compiler. 162 | Message& operator <<(BasicNarrowIoManip val) { 163 | *ss_ << val; 164 | return *this; 165 | } 166 | 167 | // Instead of 1/0, we want to see true/false for bool values. 168 | Message& operator <<(bool b) { 169 | return *this << (b ? "true" : "false"); 170 | } 171 | 172 | // These two overloads allow streaming a wide C string to a Message 173 | // using the UTF-8 encoding. 174 | Message& operator <<(const wchar_t* wide_c_str); 175 | Message& operator <<(wchar_t* wide_c_str); 176 | 177 | #if GTEST_HAS_STD_WSTRING 178 | // Converts the given wide string to a narrow string using the UTF-8 179 | // encoding, and streams the result to this Message object. 180 | Message& operator <<(const ::std::wstring& wstr); 181 | #endif // GTEST_HAS_STD_WSTRING 182 | 183 | // Gets the text streamed to this object so far as an std::string. 184 | // Each '\0' character in the buffer is replaced with "\\0". 185 | // 186 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 187 | std::string GetString() const; 188 | 189 | private: 190 | // We'll hold the text streamed to this object here. 191 | const std::unique_ptr< ::std::stringstream> ss_; 192 | 193 | // We declare (but don't implement) this to prevent the compiler 194 | // from implementing the assignment operator. 195 | void operator=(const Message&); 196 | }; 197 | 198 | // Streams a Message to an ostream. 199 | inline std::ostream& operator <<(std::ostream& os, const Message& sb) { 200 | return os << sb.GetString(); 201 | } 202 | 203 | namespace internal { 204 | 205 | // Converts a streamable value to an std::string. A NULL pointer is 206 | // converted to "(null)". When the input value is a ::string, 207 | // ::std::string, ::wstring, or ::std::wstring object, each NUL 208 | // character in it is replaced with "\\0". 209 | template 210 | std::string StreamableToString(const T& streamable) { 211 | return (Message() << streamable).GetString(); 212 | } 213 | 214 | } // namespace internal 215 | } // namespace testing 216 | 217 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 218 | 219 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 220 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/gtest-test-part.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // GOOGLETEST_CM0001 DO NOT DELETE 31 | 32 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 33 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 34 | 35 | #include 36 | #include 37 | #include "gtest/internal/gtest-internal.h" 38 | #include "gtest/internal/gtest-string.h" 39 | 40 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 41 | /* class A needs to have dll-interface to be used by clients of class B */) 42 | 43 | namespace testing { 44 | 45 | // A copyable object representing the result of a test part (i.e. an 46 | // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). 47 | // 48 | // Don't inherit from TestPartResult as its destructor is not virtual. 49 | class GTEST_API_ TestPartResult { 50 | public: 51 | // The possible outcomes of a test part (i.e. an assertion or an 52 | // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). 53 | enum Type { 54 | kSuccess, // Succeeded. 55 | kNonFatalFailure, // Failed but the test can continue. 56 | kFatalFailure, // Failed and the test should be terminated. 57 | kSkip // Skipped. 58 | }; 59 | 60 | // C'tor. TestPartResult does NOT have a default constructor. 61 | // Always use this constructor (with parameters) to create a 62 | // TestPartResult object. 63 | TestPartResult(Type a_type, const char* a_file_name, int a_line_number, 64 | const char* a_message) 65 | : type_(a_type), 66 | file_name_(a_file_name == nullptr ? "" : a_file_name), 67 | line_number_(a_line_number), 68 | summary_(ExtractSummary(a_message)), 69 | message_(a_message) {} 70 | 71 | // Gets the outcome of the test part. 72 | Type type() const { return type_; } 73 | 74 | // Gets the name of the source file where the test part took place, or 75 | // NULL if it's unknown. 76 | const char* file_name() const { 77 | return file_name_.empty() ? nullptr : file_name_.c_str(); 78 | } 79 | 80 | // Gets the line in the source file where the test part took place, 81 | // or -1 if it's unknown. 82 | int line_number() const { return line_number_; } 83 | 84 | // Gets the summary of the failure message. 85 | const char* summary() const { return summary_.c_str(); } 86 | 87 | // Gets the message associated with the test part. 88 | const char* message() const { return message_.c_str(); } 89 | 90 | // Returns true if and only if the test part was skipped. 91 | bool skipped() const { return type_ == kSkip; } 92 | 93 | // Returns true if and only if the test part passed. 94 | bool passed() const { return type_ == kSuccess; } 95 | 96 | // Returns true if and only if the test part non-fatally failed. 97 | bool nonfatally_failed() const { return type_ == kNonFatalFailure; } 98 | 99 | // Returns true if and only if the test part fatally failed. 100 | bool fatally_failed() const { return type_ == kFatalFailure; } 101 | 102 | // Returns true if and only if the test part failed. 103 | bool failed() const { return fatally_failed() || nonfatally_failed(); } 104 | 105 | private: 106 | Type type_; 107 | 108 | // Gets the summary of the failure message by omitting the stack 109 | // trace in it. 110 | static std::string ExtractSummary(const char* message); 111 | 112 | // The name of the source file where the test part took place, or 113 | // "" if the source file is unknown. 114 | std::string file_name_; 115 | // The line in the source file where the test part took place, or -1 116 | // if the line number is unknown. 117 | int line_number_; 118 | std::string summary_; // The test failure summary. 119 | std::string message_; // The test failure message. 120 | }; 121 | 122 | // Prints a TestPartResult object. 123 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result); 124 | 125 | // An array of TestPartResult objects. 126 | // 127 | // Don't inherit from TestPartResultArray as its destructor is not 128 | // virtual. 129 | class GTEST_API_ TestPartResultArray { 130 | public: 131 | TestPartResultArray() {} 132 | 133 | // Appends the given TestPartResult to the array. 134 | void Append(const TestPartResult& result); 135 | 136 | // Returns the TestPartResult at the given index (0-based). 137 | const TestPartResult& GetTestPartResult(int index) const; 138 | 139 | // Returns the number of TestPartResult objects in the array. 140 | int size() const; 141 | 142 | private: 143 | std::vector array_; 144 | 145 | GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); 146 | }; 147 | 148 | // This interface knows how to report a test part result. 149 | class GTEST_API_ TestPartResultReporterInterface { 150 | public: 151 | virtual ~TestPartResultReporterInterface() {} 152 | 153 | virtual void ReportTestPartResult(const TestPartResult& result) = 0; 154 | }; 155 | 156 | namespace internal { 157 | 158 | // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a 159 | // statement generates new fatal failures. To do so it registers itself as the 160 | // current test part result reporter. Besides checking if fatal failures were 161 | // reported, it only delegates the reporting to the former result reporter. 162 | // The original result reporter is restored in the destructor. 163 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 164 | class GTEST_API_ HasNewFatalFailureHelper 165 | : public TestPartResultReporterInterface { 166 | public: 167 | HasNewFatalFailureHelper(); 168 | ~HasNewFatalFailureHelper() override; 169 | void ReportTestPartResult(const TestPartResult& result) override; 170 | bool has_new_fatal_failure() const { return has_new_fatal_failure_; } 171 | private: 172 | bool has_new_fatal_failure_; 173 | TestPartResultReporterInterface* original_reporter_; 174 | 175 | GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); 176 | }; 177 | 178 | } // namespace internal 179 | 180 | } // namespace testing 181 | 182 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 183 | 184 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 185 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Google C++ Testing and Mocking Framework definitions useful in production code. 32 | // GOOGLETEST_CM0003 DO NOT DELETE 33 | 34 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void PrivateMethod(); 44 | // FRIEND_TEST(MyClassTest, PrivateMethodWorks); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, PrivateMethodWorks) { 52 | // // Can call MyClass::PrivateMethod() here. 53 | // } 54 | // 55 | // Note: The test class must be in the same namespace as the class being tested. 56 | // For example, putting MyClassTest in an anonymous namespace will not work. 57 | 58 | #define FRIEND_TEST(test_case_name, test_name)\ 59 | friend class test_case_name##_##test_name##_Test 60 | 61 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ 62 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/internal/custom/README.md: -------------------------------------------------------------------------------- 1 | # Customization Points 2 | 3 | The custom directory is an injection point for custom user configurations. 4 | 5 | ## Header `gtest.h` 6 | 7 | ### The following macros can be defined: 8 | 9 | * `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of 10 | `OsStackTraceGetterInterface`. 11 | * `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See 12 | `testing::TempDir` for semantics and signature. 13 | 14 | ## Header `gtest-port.h` 15 | 16 | The following macros can be defined: 17 | 18 | ### Flag related macros: 19 | 20 | * `GTEST_FLAG(flag_name)` 21 | * `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its 22 | own flagfile flag parsing. 23 | * `GTEST_DECLARE_bool_(name)` 24 | * `GTEST_DECLARE_int32_(name)` 25 | * `GTEST_DECLARE_string_(name)` 26 | * `GTEST_DEFINE_bool_(name, default_val, doc)` 27 | * `GTEST_DEFINE_int32_(name, default_val, doc)` 28 | * `GTEST_DEFINE_string_(name, default_val, doc)` 29 | 30 | ### Logging: 31 | 32 | * `GTEST_LOG_(severity)` 33 | * `GTEST_CHECK_(condition)` 34 | * Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too. 35 | 36 | ### Threading: 37 | 38 | * `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided. 39 | * `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal` 40 | are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)` 41 | and `GTEST_DEFINE_STATIC_MUTEX_(mutex)` 42 | * `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)` 43 | * `GTEST_LOCK_EXCLUDED_(locks)` 44 | 45 | ### Underlying library support features 46 | 47 | * `GTEST_HAS_CXXABI_H_` 48 | 49 | ### Exporting API symbols: 50 | 51 | * `GTEST_API_` - Specifier for exported symbols. 52 | 53 | ## Header `gtest-printers.h` 54 | 55 | * See documentation at `gtest/gtest-printers.h` for details on how to define a 56 | custom printer. 57 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/internal/custom/gtest-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 35 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 36 | 37 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 38 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // 35 | // Injection point for custom user configurations. See README for details 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 35 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 36 | 37 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 38 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/internal/gtest-port-arch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file defines the GTEST_OS_* macro. 33 | // It is separate from gtest-port.h so that custom/gtest-port.h can include it. 34 | 35 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 36 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 37 | 38 | // Determines the platform on which Google Test is compiled. 39 | #ifdef __CYGWIN__ 40 | # define GTEST_OS_CYGWIN 1 41 | # elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) 42 | # define GTEST_OS_WINDOWS_MINGW 1 43 | # define GTEST_OS_WINDOWS 1 44 | #elif defined _WIN32 45 | # define GTEST_OS_WINDOWS 1 46 | # ifdef _WIN32_WCE 47 | # define GTEST_OS_WINDOWS_MOBILE 1 48 | # elif defined(WINAPI_FAMILY) 49 | # include 50 | # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 51 | # define GTEST_OS_WINDOWS_DESKTOP 1 52 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) 53 | # define GTEST_OS_WINDOWS_PHONE 1 54 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 55 | # define GTEST_OS_WINDOWS_RT 1 56 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) 57 | # define GTEST_OS_WINDOWS_PHONE 1 58 | # define GTEST_OS_WINDOWS_TV_TITLE 1 59 | # else 60 | // WINAPI_FAMILY defined but no known partition matched. 61 | // Default to desktop. 62 | # define GTEST_OS_WINDOWS_DESKTOP 1 63 | # endif 64 | # else 65 | # define GTEST_OS_WINDOWS_DESKTOP 1 66 | # endif // _WIN32_WCE 67 | #elif defined __OS2__ 68 | # define GTEST_OS_OS2 1 69 | #elif defined __APPLE__ 70 | # define GTEST_OS_MAC 1 71 | # include 72 | # if TARGET_OS_IPHONE 73 | # define GTEST_OS_IOS 1 74 | # endif 75 | #elif defined __DragonFly__ 76 | # define GTEST_OS_DRAGONFLY 1 77 | #elif defined __FreeBSD__ 78 | # define GTEST_OS_FREEBSD 1 79 | #elif defined __Fuchsia__ 80 | # define GTEST_OS_FUCHSIA 1 81 | #elif defined(__GLIBC__) && defined(__FreeBSD_kernel__) 82 | # define GTEST_OS_GNU_KFREEBSD 1 83 | #elif defined __linux__ 84 | # define GTEST_OS_LINUX 1 85 | # if defined __ANDROID__ 86 | # define GTEST_OS_LINUX_ANDROID 1 87 | # endif 88 | #elif defined __MVS__ 89 | # define GTEST_OS_ZOS 1 90 | #elif defined(__sun) && defined(__SVR4) 91 | # define GTEST_OS_SOLARIS 1 92 | #elif defined(_AIX) 93 | # define GTEST_OS_AIX 1 94 | #elif defined(__hpux) 95 | # define GTEST_OS_HPUX 1 96 | #elif defined __native_client__ 97 | # define GTEST_OS_NACL 1 98 | #elif defined __NetBSD__ 99 | # define GTEST_OS_NETBSD 1 100 | #elif defined __OpenBSD__ 101 | # define GTEST_OS_OPENBSD 1 102 | #elif defined __QNX__ 103 | # define GTEST_OS_QNX 1 104 | #elif defined(__HAIKU__) 105 | #define GTEST_OS_HAIKU 1 106 | #elif defined ESP8266 107 | #define GTEST_OS_ESP8266 1 108 | #elif defined ESP32 109 | #define GTEST_OS_ESP32 1 110 | #elif defined(__XTENSA__) 111 | #define GTEST_OS_XTENSA 1 112 | #endif // __CYGWIN__ 113 | 114 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 115 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/internal/gtest-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file declares the String class and functions used internally by 33 | // Google Test. They are subject to change without notice. They should not used 34 | // by code external to Google Test. 35 | // 36 | // This header file is #included by gtest-internal.h. 37 | // It should not be #included by other files. 38 | 39 | // GOOGLETEST_CM0001 DO NOT DELETE 40 | 41 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 42 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 43 | 44 | #ifdef __BORLANDC__ 45 | // string.h is not guaranteed to provide strcpy on C++ Builder. 46 | # include 47 | #endif 48 | 49 | #include 50 | #include 51 | #include 52 | 53 | #include "gtest/internal/gtest-port.h" 54 | 55 | namespace testing { 56 | namespace internal { 57 | 58 | // String - an abstract class holding static string utilities. 59 | class GTEST_API_ String { 60 | public: 61 | // Static utility methods 62 | 63 | // Clones a 0-terminated C string, allocating memory using new. The 64 | // caller is responsible for deleting the return value using 65 | // delete[]. Returns the cloned string, or NULL if the input is 66 | // NULL. 67 | // 68 | // This is different from strdup() in string.h, which allocates 69 | // memory using malloc(). 70 | static const char* CloneCString(const char* c_str); 71 | 72 | #if GTEST_OS_WINDOWS_MOBILE 73 | // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be 74 | // able to pass strings to Win32 APIs on CE we need to convert them 75 | // to 'Unicode', UTF-16. 76 | 77 | // Creates a UTF-16 wide string from the given ANSI string, allocating 78 | // memory using new. The caller is responsible for deleting the return 79 | // value using delete[]. Returns the wide string, or NULL if the 80 | // input is NULL. 81 | // 82 | // The wide string is created using the ANSI codepage (CP_ACP) to 83 | // match the behaviour of the ANSI versions of Win32 calls and the 84 | // C runtime. 85 | static LPCWSTR AnsiToUtf16(const char* c_str); 86 | 87 | // Creates an ANSI string from the given wide string, allocating 88 | // memory using new. The caller is responsible for deleting the return 89 | // value using delete[]. Returns the ANSI string, or NULL if the 90 | // input is NULL. 91 | // 92 | // The returned string is created using the ANSI codepage (CP_ACP) to 93 | // match the behaviour of the ANSI versions of Win32 calls and the 94 | // C runtime. 95 | static const char* Utf16ToAnsi(LPCWSTR utf16_str); 96 | #endif 97 | 98 | // Compares two C strings. Returns true if and only if they have the same 99 | // content. 100 | // 101 | // Unlike strcmp(), this function can handle NULL argument(s). A 102 | // NULL C string is considered different to any non-NULL C string, 103 | // including the empty string. 104 | static bool CStringEquals(const char* lhs, const char* rhs); 105 | 106 | // Converts a wide C string to a String using the UTF-8 encoding. 107 | // NULL will be converted to "(null)". If an error occurred during 108 | // the conversion, "(failed to convert from wide string)" is 109 | // returned. 110 | static std::string ShowWideCString(const wchar_t* wide_c_str); 111 | 112 | // Compares two wide C strings. Returns true if and only if they have the 113 | // same content. 114 | // 115 | // Unlike wcscmp(), this function can handle NULL argument(s). A 116 | // NULL C string is considered different to any non-NULL C string, 117 | // including the empty string. 118 | static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); 119 | 120 | // Compares two C strings, ignoring case. Returns true if and only if 121 | // they have the same content. 122 | // 123 | // Unlike strcasecmp(), this function can handle NULL argument(s). 124 | // A NULL C string is considered different to any non-NULL C string, 125 | // including the empty string. 126 | static bool CaseInsensitiveCStringEquals(const char* lhs, 127 | const char* rhs); 128 | 129 | // Compares two wide C strings, ignoring case. Returns true if and only if 130 | // they have the same content. 131 | // 132 | // Unlike wcscasecmp(), this function can handle NULL argument(s). 133 | // A NULL C string is considered different to any non-NULL wide C string, 134 | // including the empty string. 135 | // NB: The implementations on different platforms slightly differ. 136 | // On windows, this method uses _wcsicmp which compares according to LC_CTYPE 137 | // environment variable. On GNU platform this method uses wcscasecmp 138 | // which compares according to LC_CTYPE category of the current locale. 139 | // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the 140 | // current locale. 141 | static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, 142 | const wchar_t* rhs); 143 | 144 | // Returns true if and only if the given string ends with the given suffix, 145 | // ignoring case. Any string is considered to end with an empty suffix. 146 | static bool EndsWithCaseInsensitive( 147 | const std::string& str, const std::string& suffix); 148 | 149 | // Formats an int value as "%02d". 150 | static std::string FormatIntWidth2(int value); // "%02d" for width == 2 151 | 152 | // Formats an int value to given width with leading zeros. 153 | static std::string FormatIntWidthN(int value, int width); 154 | 155 | // Formats an int value as "%X". 156 | static std::string FormatHexInt(int value); 157 | 158 | // Formats an int value as "%X". 159 | static std::string FormatHexUInt32(uint32_t value); 160 | 161 | // Formats a byte as "%02X". 162 | static std::string FormatByte(unsigned char value); 163 | 164 | private: 165 | String(); // Not meant to be instantiated. 166 | }; // class String 167 | 168 | // Gets the content of the stringstream's buffer as an std::string. Each '\0' 169 | // character in the buffer is replaced with "\\0". 170 | GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); 171 | 172 | } // namespace internal 173 | } // namespace testing 174 | 175 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 176 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/include/gtest/internal/gtest-type-util.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Type utilities needed for implementing typed and type-parameterized 31 | // tests. 32 | 33 | // GOOGLETEST_CM0001 DO NOT DELETE 34 | 35 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 36 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 37 | 38 | #include "gtest/internal/gtest-port.h" 39 | 40 | // #ifdef __GNUC__ is too general here. It is possible to use gcc without using 41 | // libstdc++ (which is where cxxabi.h comes from). 42 | # if GTEST_HAS_CXXABI_H_ 43 | # include 44 | # elif defined(__HP_aCC) 45 | # include 46 | # endif // GTEST_HASH_CXXABI_H_ 47 | 48 | namespace testing { 49 | namespace internal { 50 | 51 | // Canonicalizes a given name with respect to the Standard C++ Library. 52 | // This handles removing the inline namespace within `std` that is 53 | // used by various standard libraries (e.g., `std::__1`). Names outside 54 | // of namespace std are returned unmodified. 55 | inline std::string CanonicalizeForStdLibVersioning(std::string s) { 56 | static const char prefix[] = "std::__"; 57 | if (s.compare(0, strlen(prefix), prefix) == 0) { 58 | std::string::size_type end = s.find("::", strlen(prefix)); 59 | if (end != s.npos) { 60 | // Erase everything between the initial `std` and the second `::`. 61 | s.erase(strlen("std"), end - strlen("std")); 62 | } 63 | } 64 | return s; 65 | } 66 | 67 | #if GTEST_HAS_RTTI 68 | // GetTypeName(const std::type_info&) returns a human-readable name of type T. 69 | inline std::string GetTypeName(const std::type_info& type) { 70 | const char* const name = type.name(); 71 | #if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) 72 | int status = 0; 73 | // gcc's implementation of typeid(T).name() mangles the type name, 74 | // so we have to demangle it. 75 | #if GTEST_HAS_CXXABI_H_ 76 | using abi::__cxa_demangle; 77 | #endif // GTEST_HAS_CXXABI_H_ 78 | char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); 79 | const std::string name_str(status == 0 ? readable_name : name); 80 | free(readable_name); 81 | return CanonicalizeForStdLibVersioning(name_str); 82 | #else 83 | return name; 84 | #endif // GTEST_HAS_CXXABI_H_ || __HP_aCC 85 | } 86 | #endif // GTEST_HAS_RTTI 87 | 88 | // GetTypeName() returns a human-readable name of type T if and only if 89 | // RTTI is enabled, otherwise it returns a dummy type name. 90 | // NB: This function is also used in Google Mock, so don't move it inside of 91 | // the typed-test-only section below. 92 | template 93 | std::string GetTypeName() { 94 | #if GTEST_HAS_RTTI 95 | return GetTypeName(typeid(T)); 96 | #else 97 | return ""; 98 | #endif // GTEST_HAS_RTTI 99 | } 100 | 101 | // A unique type indicating an empty node 102 | struct None {}; 103 | 104 | # define GTEST_TEMPLATE_ template class 105 | 106 | // The template "selector" struct TemplateSel is used to 107 | // represent Tmpl, which must be a class template with one type 108 | // parameter, as a type. TemplateSel::Bind::type is defined 109 | // as the type Tmpl. This allows us to actually instantiate the 110 | // template "selected" by TemplateSel. 111 | // 112 | // This trick is necessary for simulating typedef for class templates, 113 | // which C++ doesn't support directly. 114 | template 115 | struct TemplateSel { 116 | template 117 | struct Bind { 118 | typedef Tmpl type; 119 | }; 120 | }; 121 | 122 | # define GTEST_BIND_(TmplSel, T) \ 123 | TmplSel::template Bind::type 124 | 125 | template 126 | struct Templates { 127 | using Head = TemplateSel; 128 | using Tail = Templates; 129 | }; 130 | 131 | template 132 | struct Templates { 133 | using Head = TemplateSel; 134 | using Tail = None; 135 | }; 136 | 137 | // Tuple-like type lists 138 | template 139 | struct Types { 140 | using Head = Head_; 141 | using Tail = Types; 142 | }; 143 | 144 | template 145 | struct Types { 146 | using Head = Head_; 147 | using Tail = None; 148 | }; 149 | 150 | // Helper metafunctions to tell apart a single type from types 151 | // generated by ::testing::Types 152 | template 153 | struct ProxyTypeList { 154 | using type = Types; 155 | }; 156 | 157 | template 158 | struct is_proxy_type_list : std::false_type {}; 159 | 160 | template 161 | struct is_proxy_type_list> : std::true_type {}; 162 | 163 | // Generator which conditionally creates type lists. 164 | // It recognizes if a requested type list should be created 165 | // and prevents creating a new type list nested within another one. 166 | template 167 | struct GenerateTypeList { 168 | private: 169 | using proxy = typename std::conditional::value, T, 170 | ProxyTypeList>::type; 171 | 172 | public: 173 | using type = typename proxy::type; 174 | }; 175 | 176 | } // namespace internal 177 | 178 | template 179 | using Types = internal::ProxyTypeList; 180 | 181 | } // namespace testing 182 | 183 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 184 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/src/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Google C++ Testing and Mocking Framework (Google Test) 32 | // 33 | // Sometimes it's desirable to build Google Test by compiling a single file. 34 | // This file serves this purpose. 35 | 36 | // This line ensures that gtest.h can be compiled on its own, even 37 | // when it's fused. 38 | #include "gtest/gtest.h" 39 | 40 | // The following lines pull in the real gtest *.cc files. 41 | #include "src/gtest.cc" 42 | #include "src/gtest-death-test.cc" 43 | #include "src/gtest-filepath.cc" 44 | #include "src/gtest-matchers.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/src/gtest-matchers.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This file implements just enough of the matcher interface to allow 33 | // EXPECT_DEATH and friends to accept a matcher argument. 34 | 35 | #include "gtest/internal/gtest-internal.h" 36 | #include "gtest/internal/gtest-port.h" 37 | #include "gtest/gtest-matchers.h" 38 | 39 | #include 40 | 41 | namespace testing { 42 | 43 | // Constructs a matcher that matches a const std::string& whose value is 44 | // equal to s. 45 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 46 | 47 | // Constructs a matcher that matches a const std::string& whose value is 48 | // equal to s. 49 | Matcher::Matcher(const char* s) { 50 | *this = Eq(std::string(s)); 51 | } 52 | 53 | // Constructs a matcher that matches a std::string whose value is equal to 54 | // s. 55 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 56 | 57 | // Constructs a matcher that matches a std::string whose value is equal to 58 | // s. 59 | Matcher::Matcher(const char* s) { *this = Eq(std::string(s)); } 60 | 61 | #if GTEST_INTERNAL_HAS_STRING_VIEW 62 | // Constructs a matcher that matches a const StringView& whose value is 63 | // equal to s. 64 | Matcher::Matcher(const std::string& s) { 65 | *this = Eq(s); 66 | } 67 | 68 | // Constructs a matcher that matches a const StringView& whose value is 69 | // equal to s. 70 | Matcher::Matcher(const char* s) { 71 | *this = Eq(std::string(s)); 72 | } 73 | 74 | // Constructs a matcher that matches a const StringView& whose value is 75 | // equal to s. 76 | Matcher::Matcher(internal::StringView s) { 77 | *this = Eq(std::string(s)); 78 | } 79 | 80 | // Constructs a matcher that matches a StringView whose value is equal to 81 | // s. 82 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 83 | 84 | // Constructs a matcher that matches a StringView whose value is equal to 85 | // s. 86 | Matcher::Matcher(const char* s) { 87 | *this = Eq(std::string(s)); 88 | } 89 | 90 | // Constructs a matcher that matches a StringView whose value is equal to 91 | // s. 92 | Matcher::Matcher(internal::StringView s) { 93 | *this = Eq(std::string(s)); 94 | } 95 | #endif // GTEST_INTERNAL_HAS_STRING_VIEW 96 | 97 | } // namespace testing 98 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // The Google C++ Testing and Mocking Framework (Google Test) 32 | 33 | #include "gtest/gtest-test-part.h" 34 | 35 | #include "gtest/internal/gtest-port.h" 36 | #include "src/gtest-internal-inl.h" 37 | 38 | namespace testing { 39 | 40 | using internal::GetUnitTestImpl; 41 | 42 | // Gets the summary of the failure message by omitting the stack trace 43 | // in it. 44 | std::string TestPartResult::ExtractSummary(const char* message) { 45 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 46 | return stack_trace == nullptr ? message : std::string(message, stack_trace); 47 | } 48 | 49 | // Prints a TestPartResult object. 50 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 51 | return os << internal::FormatFileLocation(result.file_name(), 52 | result.line_number()) 53 | << " " 54 | << (result.type() == TestPartResult::kSuccess 55 | ? "Success" 56 | : result.type() == TestPartResult::kSkip 57 | ? "Skipped" 58 | : result.type() == TestPartResult::kFatalFailure 59 | ? "Fatal failure" 60 | : "Non-fatal failure") 61 | << ":\n" 62 | << result.message() << std::endl; 63 | } 64 | 65 | // Appends a TestPartResult to the array. 66 | void TestPartResultArray::Append(const TestPartResult& result) { 67 | array_.push_back(result); 68 | } 69 | 70 | // Returns the TestPartResult at the given index (0-based). 71 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 72 | if (index < 0 || index >= size()) { 73 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 74 | internal::posix::Abort(); 75 | } 76 | 77 | return array_[static_cast(index)]; 78 | } 79 | 80 | // Returns the number of TestPartResult objects in the array. 81 | int TestPartResultArray::size() const { 82 | return static_cast(array_.size()); 83 | } 84 | 85 | namespace internal { 86 | 87 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 88 | : has_new_fatal_failure_(false), 89 | original_reporter_(GetUnitTestImpl()-> 90 | GetTestPartResultReporterForCurrentThread()) { 91 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 92 | } 93 | 94 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 95 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 96 | original_reporter_); 97 | } 98 | 99 | void HasNewFatalFailureHelper::ReportTestPartResult( 100 | const TestPartResult& result) { 101 | if (result.fatally_failed()) 102 | has_new_fatal_failure_ = true; 103 | original_reporter_->ReportTestPartResult(result); 104 | } 105 | 106 | } // namespace internal 107 | 108 | } // namespace testing 109 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | #include "gtest/gtest-typed-test.h" 32 | 33 | #include "gtest/gtest.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | // Skips to the first non-space char in str. Returns an empty string if str 39 | // contains only whitespace characters. 40 | static const char* SkipSpaces(const char* str) { 41 | while (IsSpace(*str)) 42 | str++; 43 | return str; 44 | } 45 | 46 | static std::vector SplitIntoTestNames(const char* src) { 47 | std::vector name_vec; 48 | src = SkipSpaces(src); 49 | for (; src != nullptr; src = SkipComma(src)) { 50 | name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); 51 | } 52 | return name_vec; 53 | } 54 | 55 | // Verifies that registered_tests match the test names in 56 | // registered_tests_; returns registered_tests if successful, or 57 | // aborts the program otherwise. 58 | const char* TypedTestSuitePState::VerifyRegisteredTestNames( 59 | const char* test_suite_name, const char* file, int line, 60 | const char* registered_tests) { 61 | RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line)); 62 | 63 | typedef RegisteredTestsMap::const_iterator RegisteredTestIter; 64 | registered_ = true; 65 | 66 | std::vector name_vec = SplitIntoTestNames(registered_tests); 67 | 68 | Message errors; 69 | 70 | std::set tests; 71 | for (std::vector::const_iterator name_it = name_vec.begin(); 72 | name_it != name_vec.end(); ++name_it) { 73 | const std::string& name = *name_it; 74 | if (tests.count(name) != 0) { 75 | errors << "Test " << name << " is listed more than once.\n"; 76 | continue; 77 | } 78 | 79 | if (registered_tests_.count(name) != 0) { 80 | tests.insert(name); 81 | } else { 82 | errors << "No test named " << name 83 | << " can be found in this test suite.\n"; 84 | } 85 | } 86 | 87 | for (RegisteredTestIter it = registered_tests_.begin(); 88 | it != registered_tests_.end(); 89 | ++it) { 90 | if (tests.count(it->first) == 0) { 91 | errors << "You forgot to list test " << it->first << ".\n"; 92 | } 93 | } 94 | 95 | const std::string& errors_str = errors.GetString(); 96 | if (errors_str != "") { 97 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 98 | errors_str.c_str()); 99 | fflush(stderr); 100 | posix::Abort(); 101 | } 102 | 103 | return registered_tests; 104 | } 105 | 106 | } // namespace internal 107 | } // namespace testing 108 | -------------------------------------------------------------------------------- /utest/gtest-fit/googletest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | #include "gtest/gtest.h" 32 | 33 | #if GTEST_OS_ESP8266 || GTEST_OS_ESP32 34 | #if GTEST_OS_ESP8266 35 | extern "C" { 36 | #endif 37 | void setup() { 38 | testing::InitGoogleTest(); 39 | } 40 | 41 | void loop() { RUN_ALL_TESTS(); } 42 | 43 | #if GTEST_OS_ESP8266 44 | } 45 | #endif 46 | 47 | #else 48 | 49 | GTEST_API_ int main(int argc, char **argv) { 50 | printf("Running main() from %s\n", __FILE__); 51 | testing::InitGoogleTest(&argc, argv); 52 | return RUN_ALL_TESTS(); 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /utest/st_utest.cpp: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT */ 2 | /* Copyright (c) 2013-2024 The SRS Authors */ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | std::ostream& operator<<(std::ostream& out, const ErrorObject* err) { 10 | if (!err) return out; 11 | if (err->r0_) out << "r0=" << err->r0_; 12 | if (err->errno_) out << ", errno=" << err->errno_; 13 | if (!err->message_.empty()) out << ", msg=" << err->message_; 14 | return out; 15 | } 16 | 17 | // We could do something in the main of utest. 18 | // Copy from gtest-1.6.0/src/gtest_main.cc 19 | GTEST_API_ int main(int argc, char **argv) { 20 | // Select the best event system available on the OS. In Linux this is 21 | // epoll(). On BSD it will be kqueue. On Cygwin it will be select. 22 | #if __CYGWIN__ 23 | assert(st_set_eventsys(ST_EVENTSYS_SELECT) != -1); 24 | #else 25 | assert(st_set_eventsys(ST_EVENTSYS_ALT) != -1); 26 | #endif 27 | 28 | // Initialize state-threads, create idle coroutine. 29 | assert(st_init() == 0); 30 | 31 | testing::InitGoogleTest(&argc, argv); 32 | return RUN_ALL_TESTS(); 33 | } 34 | 35 | // basic test and samples. 36 | VOID TEST(SampleTest, ExampleIntSizeTest) 37 | { 38 | EXPECT_EQ(1, (int)sizeof(int8_t)); 39 | EXPECT_EQ(2, (int)sizeof(int16_t)); 40 | EXPECT_EQ(4, (int)sizeof(int32_t)); 41 | EXPECT_EQ(8, (int)sizeof(int64_t)); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /utest/st_utest.hpp: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT */ 2 | /* Copyright (c) 2013-2024 The SRS Authors */ 3 | 4 | #ifndef ST_UTEST_PUBLIC_HPP 5 | #define ST_UTEST_PUBLIC_HPP 6 | 7 | // Before define the private/protected, we must include some system header files. 8 | // Or it may fail with: 9 | // redeclared with different access struct __xfer_bufptrs 10 | // @see https://stackoverflow.com/questions/47839718/sstream-redeclared-with-public-access-compiler-error 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #define VOID 17 | 18 | // Close the fd automatically. 19 | #define StFdCleanup(fd, stfd) impl__StFdCleanup _ST_free_##fd(&fd, &stfd) 20 | #define StStfdCleanup(stfd) impl__StFdCleanup _ST_free_##stfd(NULL, &stfd) 21 | class impl__StFdCleanup { 22 | int* fd_; 23 | st_netfd_t* stfd_; 24 | public: 25 | impl__StFdCleanup(int* fd, st_netfd_t* stfd) : fd_(fd), stfd_(stfd) { 26 | } 27 | virtual ~impl__StFdCleanup() { 28 | if (stfd_ && *stfd_) { 29 | st_netfd_close(*stfd_); 30 | } else if (fd_ && *fd_ > 0) { 31 | ::close(*fd_); 32 | } 33 | } 34 | }; 35 | 36 | // For coroutine function to return with error object. 37 | struct ErrorObject { 38 | int r0_; 39 | int errno_; 40 | std::string message_; 41 | 42 | ErrorObject(int r0, std::string message) : r0_(r0), errno_(errno), message_(message) { 43 | } 44 | }; 45 | extern std::ostream& operator<<(std::ostream& out, const ErrorObject* err); 46 | #define ST_ASSERT_ERROR(error, r0, message) if (error) return new ErrorObject(r0, message) 47 | #define ST_COROUTINE_JOIN(trd, r0) ErrorObject* r0 = NULL; SrsAutoFree(ErrorObject, r0); if (trd) st_thread_join(trd, (void**)&r0) 48 | #define ST_EXPECT_SUCCESS(r0) EXPECT_TRUE(!r0) << r0 49 | #define ST_EXPECT_FAILED(r0) EXPECT_TRUE(r0) << r0 50 | 51 | #include 52 | 53 | // To free the instance in the current scope, for instance, MyClass* ptr, 54 | // which is a ptr and this class will: 55 | // 1. free the ptr. 56 | // 2. set ptr to NULL. 57 | // 58 | // Usage: 59 | // MyClass* po = new MyClass(); 60 | // // ...... use po 61 | // SrsAutoFree(MyClass, po); 62 | // 63 | // Usage for array: 64 | // MyClass** pa = new MyClass*[size]; 65 | // // ....... use pa 66 | // SrsAutoFreeA(MyClass*, pa); 67 | // 68 | // @remark the MyClass can be basic type, for instance, SrsAutoFreeA(char, pstr), 69 | // where the char* pstr = new char[size]. 70 | // To delete object. 71 | #define SrsAutoFree(className, instance) \ 72 | impl_SrsAutoFree _auto_free_##instance(&instance, false, false, NULL) 73 | // To delete array. 74 | #define SrsAutoFreeA(className, instance) \ 75 | impl_SrsAutoFree _auto_free_array_##instance(&instance, true, false, NULL) 76 | // Use free instead of delete. 77 | #define SrsAutoFreeF(className, instance) \ 78 | impl_SrsAutoFree _auto_free_##instance(&instance, false, true, NULL) 79 | // Use hook instead of delete. 80 | #define SrsAutoFreeH(className, instance, hook) \ 81 | impl_SrsAutoFree _auto_free_##instance(&instance, false, false, hook) 82 | // The template implementation. 83 | template 84 | class impl_SrsAutoFree 85 | { 86 | private: 87 | T** ptr; 88 | bool is_array; 89 | bool _use_free; 90 | void (*_hook)(T*); 91 | public: 92 | // If use_free, use free(void*) to release the p. 93 | // If specified hook, use hook(p) to release it. 94 | // Use delete to release p, or delete[] if p is an array. 95 | impl_SrsAutoFree(T** p, bool array, bool use_free, void (*hook)(T*)) { 96 | ptr = p; 97 | is_array = array; 98 | _use_free = use_free; 99 | _hook = hook; 100 | } 101 | 102 | virtual ~impl_SrsAutoFree() { 103 | if (ptr == NULL || *ptr == NULL) { 104 | return; 105 | } 106 | 107 | if (_use_free) { 108 | free(*ptr); 109 | } else if (_hook) { 110 | _hook(*ptr); 111 | } else { 112 | if (is_array) { 113 | delete[] *ptr; 114 | } else { 115 | delete *ptr; 116 | } 117 | } 118 | 119 | *ptr = NULL; 120 | } 121 | }; 122 | 123 | // The time unit in ms, for example 100 * SRS_UTIME_MILLISECONDS means 100ms. 124 | #define SRS_UTIME_MILLISECONDS 1000 125 | 126 | #endif 127 | 128 | -------------------------------------------------------------------------------- /utest/st_utest_coroutines.cpp: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT */ 2 | /* Copyright (c) 2013-2024 The SRS Authors */ 3 | 4 | #include 5 | 6 | #include 7 | 8 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 9 | // The utest for empty coroutine. 10 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 11 | void* coroutine(void* /*arg*/) 12 | { 13 | st_usleep(0); 14 | return NULL; 15 | } 16 | 17 | VOID TEST(CoroutineTest, StartCoroutine) 18 | { 19 | st_thread_t trd = st_thread_create(coroutine, NULL, 1, 0); 20 | EXPECT_TRUE(trd != NULL); 21 | 22 | // Wait for joinable coroutine to quit. 23 | st_thread_join(trd, NULL); 24 | } 25 | 26 | VOID TEST(CoroutineTest, StartCoroutineX3) 27 | { 28 | st_thread_t trd0 = st_thread_create(coroutine, NULL, 1, 0); 29 | st_thread_t trd1 = st_thread_create(coroutine, NULL, 1, 0); 30 | st_thread_t trd2 = st_thread_create(coroutine, NULL, 1, 0); 31 | EXPECT_TRUE(trd0 != NULL && trd1 != NULL && trd2 != NULL); 32 | 33 | // Wait for joinable coroutine to quit. 34 | st_thread_join(trd1, NULL); 35 | st_thread_join(trd2, NULL); 36 | st_thread_join(trd0, NULL); 37 | } 38 | 39 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 40 | // The utest for adding coroutine. 41 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 42 | void* coroutine_add(void* arg) 43 | { 44 | int v = 0; 45 | int* pi = (int*)arg; 46 | 47 | // Load the change of arg. 48 | while (v != *pi) { 49 | v = *pi; 50 | st_usleep(0); 51 | } 52 | 53 | // Add with const. 54 | v += 100; 55 | *pi = v; 56 | 57 | return NULL; 58 | } 59 | 60 | VOID TEST(CoroutineTest, StartCoroutineAdd) 61 | { 62 | int v = 0; 63 | st_thread_t trd = st_thread_create(coroutine_add, &v, 1, 0); 64 | EXPECT_TRUE(trd != NULL); 65 | 66 | // Wait for joinable coroutine to quit. 67 | st_thread_join(trd, NULL); 68 | 69 | EXPECT_EQ(100, v); 70 | } 71 | 72 | VOID TEST(CoroutineTest, StartCoroutineAddX3) 73 | { 74 | int v = 0; 75 | st_thread_t trd0 = st_thread_create(coroutine_add, &v, 1, 0); 76 | st_thread_t trd1 = st_thread_create(coroutine_add, &v, 1, 0); 77 | st_thread_t trd2 = st_thread_create(coroutine_add, &v, 1, 0); 78 | EXPECT_TRUE(trd0 != NULL && trd1 != NULL && trd2 != NULL); 79 | 80 | // Wait for joinable coroutine to quit. 81 | st_thread_join(trd0, NULL); 82 | st_thread_join(trd1, NULL); 83 | st_thread_join(trd2, NULL); 84 | 85 | EXPECT_EQ(300, v); 86 | } 87 | 88 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 89 | // The utest for output params coroutine. 90 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 91 | int coroutine_params_x4(int a, int b, int c, int d) 92 | { 93 | int e = 0; 94 | 95 | st_usleep(0); 96 | 97 | e += a + b + c + d; 98 | e += 100; 99 | return e; 100 | } 101 | 102 | void* coroutine_params(void* arg) 103 | { 104 | int r0 = coroutine_params_x4(1, 2, 3, 4); 105 | *(int*)arg = r0; 106 | return NULL; 107 | } 108 | 109 | VOID TEST(CoroutineTest, StartCoroutineParams) 110 | { 111 | int r0 = 0; 112 | st_thread_t trd = st_thread_create(coroutine_params, &r0, 1, 0); 113 | EXPECT_TRUE(trd != NULL); 114 | 115 | // Wait for joinable coroutine to quit. 116 | st_thread_join(trd, NULL); 117 | 118 | EXPECT_EQ(110, r0); 119 | } 120 | 121 | -------------------------------------------------------------------------------- /utest/st_utest_tcp.cpp: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: MIT */ 2 | /* Copyright (c) 2013-2024 The SRS Authors */ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define ST_UTEST_PORT 26878 14 | #define ST_UTEST_TIMEOUT (100 * SRS_UTIME_MILLISECONDS) 15 | 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | // The utest for ping-pong TCP server coroutine. 18 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 19 | void* tcp_server(void* /*arg*/) 20 | { 21 | int fd = -1; 22 | st_netfd_t stfd = NULL; 23 | StFdCleanup(fd, stfd); 24 | 25 | fd = socket(AF_INET, SOCK_STREAM, 0); 26 | ST_ASSERT_ERROR(fd == -1, fd, "Create socket"); 27 | 28 | struct sockaddr_in addr; 29 | addr.sin_family = AF_INET; 30 | addr.sin_addr.s_addr = htonl(INADDR_ANY); 31 | addr.sin_port = htons(ST_UTEST_PORT); 32 | 33 | int v = 1; 34 | int r0 = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(int)); 35 | ST_ASSERT_ERROR(r0, r0, "Set SO_REUSEADDR"); 36 | 37 | r0 = ::bind(fd, (const sockaddr*)&addr, sizeof(addr)); 38 | ST_ASSERT_ERROR(r0, r0, "Bind socket"); 39 | 40 | r0 = ::listen(fd, 10); 41 | ST_ASSERT_ERROR(r0, r0, "Listen socket"); 42 | 43 | stfd = st_netfd_open_socket(fd); 44 | ST_ASSERT_ERROR(!stfd, fd, "Open ST socket"); 45 | 46 | st_netfd_t client = NULL; 47 | StStfdCleanup(client); 48 | 49 | client = st_accept(stfd, NULL, NULL, ST_UTEST_TIMEOUT); 50 | ST_ASSERT_ERROR(!client, fd, "Accept client"); 51 | 52 | return NULL; 53 | } 54 | 55 | void* tcp_client(void* /*arg*/) 56 | { 57 | int fd = -1; 58 | st_netfd_t stfd = NULL; 59 | StFdCleanup(fd, stfd); 60 | 61 | fd = socket(AF_INET, SOCK_STREAM, 0); 62 | ST_ASSERT_ERROR(fd == -1, fd, "Create socket"); 63 | 64 | struct sockaddr_in addr; 65 | addr.sin_family = AF_INET; 66 | addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 67 | addr.sin_port = htons(ST_UTEST_PORT); 68 | 69 | stfd = st_netfd_open_socket(fd); 70 | ST_ASSERT_ERROR(!stfd, fd, "Open ST socket"); 71 | 72 | int r0 = st_connect(stfd, (const sockaddr*)&addr, sizeof(addr), ST_UTEST_TIMEOUT); 73 | ST_ASSERT_ERROR(r0, r0, "Connect to server"); 74 | 75 | return NULL; 76 | } 77 | 78 | VOID TEST(TcpTest, TcpConnection) 79 | { 80 | st_thread_t svr = st_thread_create(tcp_server, NULL, 1, 0); 81 | EXPECT_TRUE(svr != NULL); 82 | 83 | st_thread_t client = st_thread_create(tcp_client, NULL, 1, 0); 84 | EXPECT_TRUE(client != NULL); 85 | 86 | ST_COROUTINE_JOIN(svr, r0); 87 | ST_COROUTINE_JOIN(client, r1); 88 | 89 | ST_EXPECT_SUCCESS(r0); 90 | ST_EXPECT_SUCCESS(r1); 91 | } 92 | 93 | --------------------------------------------------------------------------------