50 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 96dfc6fb09 Improve overflow fix: use goto for cleanup, free temp_queue on error, check all write paths
Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/2a126e43-3602-48d0-9027-2e7c2021a94c

Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-24 10:23:49 +00:00
copilot-swe-agent[bot] 853806b812 Fix stack buffer overflow in perform_complex_alias() - add bounds checks
Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/2a126e43-3602-48d0-9027-2e7c2021a94c

Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-24 10:19:27 +00:00
copilot-swe-agent[bot] d874a966e7 Initial plan 2026-04-24 10:15:37 +00:00
Copilot 87c75da59c Improve error message detail for wdoor/mdoor/odoor invalid args (#178) 2026-04-23 22:52:52 +02:00
Copilot ac94839eb5 Add Unity-based unit test infrastructure (Phase 1 — 117 tests) (#177)
Introduced new system for unit tests based on the Unity framework.

Added tests for some of the simple functions in four different files.
2026-04-23 01:17:48 +02:00
Copilot 552461df51 Fix all compiler warnings in build output (#176)
Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/d031438d-2711-4447-b3df-9819d95d4058

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-21 23:50:55 +02:00
Thomas Arp 10251814f6 Potential fix for code scanning alert no. 55: Call to alloca in a loop (#175)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:20:23 +02:00
Thomas Arp d4089c58e8 Potential fix for code scanning alert no. 73: Potential use after free (#168)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:15:35 +02:00
Thomas Arp a465860553 Potential fix for code scanning alert no. 70: Incorrect return-value check for a 'scanf'-like function (#169)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:14:48 +02:00
Thomas Arp b9f49478a3 Potential fix for code scanning alert no. 1: Workflow does not contain permissions (#170)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:14:01 +02:00
Thomas Arp 171381f0ea Potential fix for code scanning alert no. 5: Redundant null check due to previous dereference (#174)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:13:20 +02:00
Thomas Arp dbd6bfc103 Potential fix for code scanning alert no. 4: Redundant null check due to previous dereference (#173)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:12:55 +02:00
Thomas Arp 1dfbe0fa83 Potential fix for code scanning alert no. 3: Redundant null check due to previous dereference (#172)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:10:46 +02:00
Thomas Arp 039e45c5ef Potential fix for code scanning alert no. 2: Redundant null check due to previous dereference (#171)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-21 23:10:26 +02:00
Thomas Arp 862c887b54 Better naming in do_drink. An unlimited source is never empty. (#167)
* Better naming in do_drink. An unlimited source is never empty.
* Add guard for negative amount when drinking from infinite source
* Allow drinking from unlimited containers with current value of 0
* Fix unlimited drink container definition to allow negative current values

Tested manually on localhost. 

Fixes #156


Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 22:36:56 +02:00
Copilot 8548bbea99 Fix questmaster holding items: extract object after AQ_OBJ_RETURN quest completion (#165)
* Initial plan

* Fix questmaster holding items: call extract_obj after AQ_OBJ_RETURN quest completion

Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/f860d259-a59a-4c9b-a2b2-1f7a3a51990a

Co-authored-by: welcor <357770+welcor@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-19 02:05:31 +02:00
Thomas Arp 28622d9fe2 Add initialization and build instructions to AGENTS.md (#166)
Added instructions for initializing and building the repository for agents
2026-04-19 02:03:34 +02:00
Thomas Arp ce423e919f Fix for code scanning alert no. 74: Potential use after free (#164)
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-19 01:37:10 +02:00
Thomas Arp 6b2d800c53 Add CodeQL analysis workflow configuration (#163)
* Add CodeQL analysis workflow configuration

* Change CodeQL build mode from autobuild to manual

* Fix exit code in CodeQL workflow

Remove exit code 1 to allow successful completion of the job.
2026-04-19 01:07:22 +02:00
MBourne 0d5d2bc435 Cedit Player Kill and Player Thief (#160) -- WhiskyTest
* cedit configuration for player kill and steal

* tidy up pk_allowed
2026-02-04 00:55:59 +01:00
Thomas Arp 4e1680db1a KAIZEN remove webster from CMakeLists.txt (#158) 2025-11-07 23:53:23 +01:00
Thomas Arp f6339b495e Feature/clang tidy (#154)
* First cmake list file, simple docs.

TODO: utils folder.

* Support for building utils

* All fields except HAVE_DOPRNT in place

* Now builds and runs :)

* Added support for clang-tidy, if available.
2025-07-02 22:34:57 +02:00
Thomas Arp 3e0c1ccc18 Support cmake (#153)
* First cmake list file, simple docs.

TODO: utils folder.

* Support for building utils

* All fields except HAVE_DOPRNT in place

* Now builds and runs :)
2025-07-02 22:23:10 +02:00
Thomas Arp b9d84fc325 Make sure %target% also works in act triggers and code cleanup (#152)
* Make sure %target% works in act triggers

* code cleanup. Remove inline block, make variable names more understandable.

Ref https://www.tbamud.com/forum/4-development/4525-confused-over-piece-of-code-in-parse-room
2025-07-02 22:22:36 +02:00
Thomas Arp bdaca46e79 Added a new trigger type for mobs, called "Damage", that triggers every (#151)
time the mob is harmed, through any means.

Valid return values: 
-1: prevents damage from occurring. Will also prevent a fight from
starting.
0: forces a miss.
>0 : the damage the mob will endure.

Available variables:
%actor%: the one doing the damage
%victim%: typically the same as %self% - the one being attacked
%damage%: the damage inflicted. Always a non-negative number.
%attacktype%: The attack type. Will be UNDEFINED when hitting with a
weapon.
2025-07-02 22:22:17 +02:00
Thomas Arp f1794521cf Feature/issue 141 immort where (#142)
* perform_immort_where and print_object_location rewritten to handle paging.

Fixes #141

* A little more info in immort where now we have more space for output.

Fixes #141

* Added PRF_VERBOSE for toggling long output in where command.

Fixes #141

* Also toggle headers in `where x` depending on verbose-pref.

Fixes #141
2025-07-02 22:21:14 +02:00
Thomas Arp 89eb009c4f Remove webster lookup since it no longer works (#99)
* removed useless util/webster.c and fixed a couple of potential buffer overruns in the util functions

* removed stray utf-8 error chars. I guess someone has used an editor with fancy 's

* removed last webster integrations
2025-07-02 22:18:40 +02:00
Thomas Arp 9a0a096f85 Merge remote-tracking branch 'refs/remotes/origin/master' 2025-07-02 21:27:07 +02:00
Thomas Arp ba7dc7bf6f convert docs files to utf-8 2025-07-02 21:26:19 +02:00
Thomas Arp 558e71eed8 ignore .idea from clion IDE 2025-07-02 21:25:34 +02:00
Marthammor a4af23538f Add MTTS support (#150)
MTTS support - thanks to marthammer for the patch
2025-06-28 23:58:14 +02:00
Thomas Arp b471ff195e avoid freeing obj_proto[].name. (#149)
fixes #148
2025-05-06 23:15:06 +02:00
Rumble 392f3d90b8 Staying ahead of the power curve 2025-04-16 12:24:37 -07:00
Thomas Arp be8de64cf8 fix buffer overrun act.informative.c (#146)
Ref https://www.tbamud.com/kunena/4-development/5636-bug-in-do-toggle-in-act-informative-c#10540

Thanks to Ironfist for the fix
2025-02-19 21:18:39 +01:00
Rumble 5024dd8e66 Updated for 2025 release 2025-01-09 23:57:59 +00:00
Thomas Arp 69888a5d89 Update aedit.c (#145)
fixes #144 

Thanks to @gbstott for the bug report
2025-01-08 22:57:39 +01:00
haloway13 1ccb6adaee Update dg_olc.c (#143)
Better auto-formatting of dg_scripts. Thanks to haloway13 for the patch.
2025-01-01 11:05:54 +01:00
Thomas Arp d3227f1300 Fix bug in process_output (#140)
Based on error report from JTP in the tbamud forums. If an attacker was able to start a session and then break the connection, the  process_output function would fail. This would trigger two calls to close_socket on the same descriptor. This in turn results in a double free on the character struct.

https://www.tbamud.com/kunena/4-development/5617-another-core-dump-not-long-after-the-one-earlier
Thanks to JTP for the bug report.
2024-12-30 12:30:29 +01:00
Thomas Arp 88b3027ec6 Bugfix/135 while freezes the mud (#138)
* Added loop counter per while instead of global. fixes #135

* Revert "Added loop counter per while instead of global. fixes #135"

This reverts commit 59cf6a1fb2.

* Remove extraneous reset of loop var.

Fixes #135

Thanks to bylins for the fix - https://github.com/bylins
2024-09-28 20:29:11 +02:00
Victor Augusto Borges Dias de Almeida 7036a15782 Changes to make the code compile normally on macOS. (#137)
Changes in configure to set crypt lib dynamically depending on the OS
2024-09-22 11:15:28 +02:00
welcor e59420363a Merge branch 'master' of git@github.com:tbamud/tbamud.git 2024-09-16 22:26:44 +02:00
Thomas Arp c838a513dd Added loop counter per while instead of global. fixes #135 (#136) 2024-09-16 22:25:29 +02:00
welcor ed9e5e1c5a Merge branch 'master' of github.com:tbamud/tbamud 2024-06-20 22:48:59 +02:00
Dan Danese 762cb77c60 Fix a bug with the prior commit for handling triggers. It should have (#132)
continued the loop, not returned since it isn't likely to be the end of
the wld file.

Added the ability to specify multiple files on the command line. This
will load all files passed before processing into html files. This is to
fix the 'missing exits' from the output html files. The prior version
only worked on a single zone or wld file and generated incomplete
output. The record count was moved global to enable proper tracking of
the entire world. The index_boot function was modified to scan the files
first, get a record count, then start over and load the room records.

example usage: wld2html *.wld

This command will generate the entire world as one html file per room.

Fixed room number roll over. The original was using a short int which is
a 16bit int and rolls at 32k.

Fixed an issue where the html files would get negative names due to
integer rollover. It had something to do with sprintf an int using %d,
but only if you passed that to fopen. Casting the int (room number) to
a long before using sprintf with %ld fixed the issue.

Added the missing four directions from the dir_names array and defines.

Co-authored-by: Dan Danese <biouxtia@danese.us>
2024-06-20 19:56:51 +02:00
Thomas Arp 317286d051 Ignore project files on commit, and fix the automap bug showing two (#133)
descriptions
2024-06-20 19:31:20 +02:00
Dan Danese ac711ffff8 Update wld2html.c (#131)
Triggers on elements of the room break this utility. Added code to toss them since we don't need them. Can add handling that pulls the trigger info later if desired, but too time consuming to index them before building the room for this simple tool.
2024-06-18 20:56:13 +02:00
Thomas Arp cde4b84be1 Update FAQ.txt (#130)
Added info about generated maps for the areas on tbaMUD
2024-06-08 12:12:54 +02:00
Nick Schmoyer 5da67ddc6a Add missing lookup for flags in read_ibt (#128) 2024-03-02 23:11:28 +01:00
Roman Shapiro b2d38522e0 Added new easy way of building TbaMUD in the Visual Studio through the CMake (#127)
* Added new experimental MSVC build way through CMake

* Small build/README.md fix
2023-11-19 04:04:39 +01:00
Serge 498b652546 fixed small bug in toggle showvnum (#125)
Thanks, @prool
2023-01-07 15:43:06 +01:00
88 changed files with 9499 additions and 1005 deletions
+8
View File
@@ -0,0 +1,8 @@
Checks: >
-*,
clang-analyzer-*,
bugprone-*,
performance-*,
portability-*
#WarningsAsErrors: '*'
HeaderFilterRegex: 'src/.*'
+18 -2
View File
@@ -3,9 +3,14 @@ name: C/C++ CI
on:
push:
branches: [ "master" ]
pull_request:
pull_request_target:
branches: [ "master" ]
permissions:
contents: read
checks: write
pull-requests: write
jobs:
build:
@@ -16,4 +21,15 @@ jobs:
- name: configure
run: ./configure
- name: build
run: cd src && touch .accepted && make
working-directory: src
run: touch .accepted && make
- name: test
working-directory: tests
run: make test
- name: publish test results
uses: dorny/test-reporter@v1
if: always()
with:
name: Unity Tests
path: tests/test-results/*.xml
reporter: java-junit
+96
View File
@@ -0,0 +1,96 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "master" ]
schedule:
- cron: '42 10 * * 4'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: c-cpp
build-mode: manual
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- name: Run manual build steps
if: matrix.build-mode == 'manual'
shell: bash
run: |
./configure
cd src && touch .accepted && make
exit
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
+91
View File
@@ -7,6 +7,97 @@ config.status
src/Makefile
src/conf.h
src/util/Makefile
tests/Makefile
src/.accepted
src/depend
src/util/depend
build/*
# Do not commit files from players
lib/plrfiles/A-E/*
lib/plrfiles/F-J/*
lib/plrfiles/K-O/*
lib/plrfiles/P-T/*
lib/plrfiles/U-Z/*
lib/plrfiles/ZZZ/*
lib/plrfiles/index
# but do commit the placeholders
!lib/plrfiles/A-E/00
!lib/plrfiles/F-J/00
!lib/plrfiles/K-O/00
!lib/plrfiles/P-T/00
!lib/plrfiles/U-Z/00
!lib/plrfiles/ZZZ/00
# or vars
lib/plrvars/A-E/*
lib/plrvars/F-J/*
lib/plrvars/K-O/*
lib/plrvars/P-T/*
lib/plrvars/U-Z/*
lib/plrvars/ZZZ/*
lib/plrvars/index
# except the placeholders
!lib/plrvars/A-E/00
!lib/plrvars/F-J/00
!lib/plrvars/K-O/00
!lib/plrvars/P-T/00
!lib/plrvars/U-Z/00
!lib/plrvars/ZZZ/00
# or objects
lib/plrobjs/A-E/*
lib/plrobjs/F-J/*
lib/plrobjs/K-O/*
lib/plrobjs/P-T/*
lib/plrobjs/U-Z/*
lib/plrobjs/ZZZ/*
lib/plrobjs/index
# except the placeholders
!lib/plrobjs/A-E/00
!lib/plrobjs/F-J/00
!lib/plrobjs/K-O/00
!lib/plrobjs/P-T/00
!lib/plrobjs/U-Z/00
!lib/plrobjs/ZZZ/00
# also not autogenerated config file
/lib/etc/config
# or the list of last logins
/lib/etc/last
# or mail
lib/etc/plrmail
#or time
lib/etc/time
# test object files, etc
src/test/depend
src/test/*.o
src/test/testfile
# ide etc.
.vscode
.project
.settings
.idea
.cproject
# macOS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Unit test binaries (built artifacts)
tests/test_utils
tests/test_random
tests/test_interpreter
tests/test_class
tests/test-results/
+14
View File
@@ -0,0 +1,14 @@
# To initialize the repository:
Run these commands from the project directory.
```shell
./configure && touch src/.accepted # the src/.accepted file must exist to build.
```
# To build the code:
```shell
cd src # make must be run from the src dir
make # builds all changed source files.
```
+408
View File
@@ -0,0 +1,408 @@
cmake_minimum_required(VERSION 3.12)
project(TbaMUD C)
set(CMAKE_C_STANDARD 99)
# Include checker modules
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckTypeSize)
include(CheckStructHasMember)
include(CheckSymbolExists)
include(CheckCSourceCompiles)
# Output paths
set(BIN_OUTPUT_DIR ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIR})
# Include source and build paths
include_directories(src ${CMAKE_BINARY_DIR})
# ========== Compiler flags ==========
if (CMAKE_COMPILER_IS_GNUCC)
include(CheckCCompilerFlag)
check_c_compiler_flag(-Wall SUPPORTS_WALL)
check_c_compiler_flag(-Wno-char-subscripts SUPPORTS_WNO_CHAR_SUBSCRIPTS)
if (SUPPORTS_WALL)
set(MYFLAGS "-Wall")
if (SUPPORTS_WNO_CHAR_SUBSCRIPTS)
set(MYFLAGS "${MYFLAGS} -Wno-char-subscripts")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MYFLAGS}")
endif()
endif()
# clang-tidy if available
find_program(CLANG_TIDY_EXE NAMES clang-tidy)
if(CLANG_TIDY_EXE AND STATIC_ANALYSIS)
message(STATUS "clang-tidy enabled: ${CLANG_TIDY_EXE}")
set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_EXE}")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
else()
message(WARNING "clang-tidy not found. Static analysis disabled.")
endif()
# ========== Header checks ==========
check_include_file("fcntl.h" HAVE_FCNTL_H)
check_include_file("errno.h" HAVE_ERRNO_H)
check_include_file("string.h" HAVE_STRING_H)
check_include_file("strings.h" HAVE_STRINGS_H)
check_include_file("limits.h" HAVE_LIMITS_H)
check_include_file("sys/select.h" HAVE_SYS_SELECT_H)
check_include_file("sys/wait.h" HAVE_SYS_WAIT_H)
check_include_file("sys/types.h" HAVE_SYS_TYPES_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
check_include_file("memory.h" HAVE_MEMORY_H)
check_include_file("assert.h" HAVE_ASSERT_H)
check_include_file("arpa/telnet.h" HAVE_ARPA_TELNET_H)
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("sys/stat.h" HAVE_SYS_STAT_H)
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
check_include_file("sys/resource.h" HAVE_SYS_RESOURCE_H)
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file("netdb.h" HAVE_NETDB_H)
check_include_file("signal.h" HAVE_SIGNAL_H)
check_include_file("sys/uio.h" HAVE_SYS_UIO_H)
check_include_file("mcheck.h" HAVE_MCHECK_H)
check_include_file("stdlib.h" HAVE_STDLIB_H)
check_include_file("stdarg.h" HAVE_STDARG_H)
check_include_file("float.h" HAVE_FLOAT_H)
if (HAVE_STDLIB_H AND HAVE_STDARG_H AND HAVE_STRING_H AND HAVE_FLOAT_H)
set(STDC_HEADERS 1)
endif()
# macros
macro(check_run_return_value CODE EXPECTED_RESULT VAR_NAME)
set(_file "${CMAKE_BINARY_DIR}/check_run_${VAR_NAME}.c")
file(WRITE "${_file}" "${CODE}")
try_run(_run_result _compile_result
${CMAKE_BINARY_DIR} ${_file}
)
if (_compile_result EQUAL 0 AND _run_result EQUAL ${EXPECTED_RESULT})
set(${VAR_NAME} TRUE)
else()
set(${VAR_NAME} FALSE)
endif()
endmacro()
# ========== Function checks ==========
foreach(FUNC gettimeofday select snprintf strcasecmp strdup strerror
stricmp strlcpy strncasecmp strnicmp strstr vsnprintf vprintf
inet_addr inet_aton)
string(TOUPPER "${FUNC}" _upper_name)
check_function_exists(${FUNC} HAVE_${_upper_name})
endforeach()
if (NOT HAVE_VPRINTF)
check_function_exists(_doprnt HAVE_DOPRNT)
endif()
# ========== Type checks ==========
check_type_size("pid_t" HAVE_PID_T)
check_type_size("size_t" HAVE_SIZE_T)
check_type_size("ssize_t" HAVE_SSIZE_T)
set(CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
check_type_size("socklen_t" HAVE_SOCKLEN_T)
unset(CMAKE_EXTRA_INCLUDE_FILES)
if (NOT HAVE_PID_T)
set(pid_t int)
endif()
if (NOT HAVE_SIZE_T)
set(size_t "unsigned")
endif()
if (NOT HAVE_SSIZE_T)
set(ssize_t int)
endif()
if (NOT HAVE_SOCKLEN_T)
set(socklen_t int)
endif()
# ========== const ==========
check_c_source_compiles("
int main() {
/* Ultrix mips cc rejects this. */
typedef int charset[2]; const charset x;
/* SunOS 4.1.1 cc rejects this. */
char const *const *ccp;
char **p;
/* NEC SVR4.0.2 mips cc rejects this. */
struct point {int x, y;};
static struct point const zero = {0,0};
/* AIX XL C 1.02.0.0 rejects this.
It does not let you subtract one const X* pointer from another in an arm
of an if-expression whose if-part is not a constant expression */
const char *g = \"string\";
ccp = &g + (g ? g-g : 0);
/* HPUX 7.0 cc rejects these. */
++ccp;
p = (char**) ccp;
ccp = (char const *const *) p;
{ /* SCO 3.2v4 cc rejects this. */
char *t;
char const *s = 0 ? (char *) 0 : (char const *) 0;
*t++ = 0;
}
{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
int x[] = {25, 17};
const int *foo = &x[0];
++foo;
}
{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
typedef const int *iptr;
iptr p = 0;
++p;
}
{ /* AIX XL C 1.02.0.0 rejects this saying
\"k.c\", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
struct s { int j; const int *ap[3]; };
struct s *b; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
}
; return 0; }
" HAVE_CONST)
if (HAVE_CONST)
set(CONST_KEYWORD const)
else()
set(CONST_KEYWORD "")
endif()
# ========== Struct checks ==========
if (HAVE_NETINET_IN_H)
check_struct_has_member("struct in_addr" s_addr netinet/in.h HAVE_STRUCT_IN_ADDR)
endif()
# ========== crypt()/libcrypt ==========
find_library(CRYPT_LIBRARY crypt)
if (CRYPT_LIBRARY)
message(STATUS "Found libcrypt: ${CRYPT_LIBRARY}")
list(APPEND EXTRA_LIBS ${CRYPT_LIBRARY})
set(_saved_lib_list ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${CRYPT_LIBRARY})
check_include_file("crypt.h" HAVE_CRYPT_H)
check_function_exists(crypt CIRCLE_CRYPT)
check_run_return_value("
#include <string.h>
#include <unistd.h>
${HAVE_CRYPT_H} ? \"#include <crypt.h>\" : \"\"
int main(void)
{
char pwd[11], pwd2[11];
strncpy(pwd, (char *)crypt(\"FooBar\", \"BazQux\"), 10);
pwd[10] = '\\\\0';
strncpy(pwd2, (char *)crypt(\"xyzzy\", \"BazQux\"), 10);
pwd2[10] = '\\\\0';
if (strcmp(pwd, pwd2) == 0)
exit(0);
exit(1);
}
" 0 HAVE_UNSAFE_CRYPT)
set(CMAKE_REQUIRED_LIBRARIES ${_saved_lib_list})
endif()
# ========== network libs ==========
check_function_exists(gethostbyaddr HAVE_GETHOSTBYADDR)
if (NOT HAVE_GETHOSTBYADDR)
message(STATUS "gethostbyaddr() not available, trying nsllib")
find_library(NSL_LIBRARY nsl)
if (NSL_LIBRARY)
message(STATUS "...nsllib found.")
list(APPEND EXTRA_LIBS ${NSL_LIBRARY})
endif()
endif()
check_function_exists(socket HAVE_SOCKET)
if (NOT HAVE_SOCKET)
message(STATUS "socket() not available, trying socketlib")
find_library(SOCKET_LIBRARY socket)
if (SOCKET_LIBRARY)
message(STATUS "...socketlib found")
list(APPEND EXTRA_LIBS ${SOCKET_LIBRARY})
endif()
endif()
# ========== time.h needs special treatment ==========
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
check_include_file("sys/time.h" HAVE_TIME_H)
if (HAVE_SYS_TIME_H AND HAVE_TIME_H)
check_c_source_compiles("
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
int main() {
struct tm *tp;
; return 0; }
" TIME_WITH_SYS_TIME)
endif()
# ========== Determine return value of signal() ==========
check_c_source_compiles("
#include <signal.h>
int handler(int sig) { return 0; }
int main() {
signal(SIGINT, handler);
return 1;
}
" SIGNAL_RETURNS_INT FAIL_REGEX ".*incompatible pointer type.*")
check_c_source_compiles("
#include <signal.h>
void handler(int sig) { }
int main() {
signal(SIGINT, handler);
return 1;
}
" SIGNAL_RETURNS_VOID FAIL_REGEX ".*incompatible pointer type.*")
if (SIGNAL_RETURNS_INT)
message(STATUS "signal() returns int.")
set(RETSIGTYPE int)
elseif (SIGNAL_RETURNS_VOID)
message(STATUS "signal() returns void.")
set(RETSIGTYPE void)
else()
message(FATAL_ERROR "Could not determine return value from signal handler.")
endif()
# ========== Define general UNIX-system ==========
if (UNIX)
set(CIRCLE_UNIX 1)
endif()
set(PROTO_FUNCTIONS
accept
bind
gettimeofday
atoi
atol
bzero
chdir
close
fclose
fcntl
fflush
fprintf
fputc
fread
fscanf
fseek
fwrite
getpeername
getpid
getrlimit
getsockname
htonl
htons
inet_addr
inet_aton
inet_ntoa
listen
ntohl
perror
printf
qsort
read
remove
rewind
select
setitimer
setrlimit
setsockopt
snprintf
sprintf
sscanf
strcasecmp
strdup
strerror
stricmp
strlcpy
strncasecmp
strnicmp
system
time
unlink
vsnprintf
write
socket
)
configure_file(
${CMAKE_SOURCE_DIR}/src/conf.h.cmake.in
${CMAKE_BINARY_DIR}/tmp_conf.h
)
macro(check_function_prototype FUNCTION)
set(_code "
#define NO_LIBRARY_PROTOTYPES
#define __COMM_C__
#define __ACT_OTHER_C__
#include \"${CMAKE_BINARY_DIR}/tmp_conf.h\"
#include \"${CMAKE_SOURCE_DIR}/src/sysdep.h\"
#ifdef ${FUNCTION}
error - already defined!
#endif
void ${FUNCTION}(int a, char b, int c, char d, int e, char f, int g, char h);
int main() {
; return 0; }
")
string(TOUPPER "${FUNCTION}" _upper_name)
check_c_source_compiles("${_code}" NEED_${_upper_name}_PROTO FAIL_REGEX ".*incompatible pointer type.*")
if (NEED_${_upper_name}_PROTO)
message(STATUS "${FUNCTION}() has no prototype, NEED_${_upper_name}_PROTO set!")
else()
message(STATUS "${FUNCTION}() has a prototype, not setting NEED_${_upper_name}_PROTO")
endif()
endmacro()
foreach (FUNC ${PROTO_FUNCTIONS})
check_function_prototype(${FUNC})
endforeach()
# ========== Generate conf.h ==========
configure_file(
${CMAKE_SOURCE_DIR}/src/conf.h.cmake.in
${CMAKE_BINARY_DIR}/conf.h
)
# ========== Source-filer ==========
file(GLOB SRC_FILES src/*.c)
# ========== Bygg kjørbar ==========
add_executable(circle ${SRC_FILES})
target_link_libraries(circle ${EXTRA_LIBS})
add_subdirectory(src/util)
add_subdirectory(tests)
if (MEMORY_DEBUG)
message(STATUS "MEMORY_DEBUG is activated, setting up zmalloc")
target_compile_definitions(circle PRIVATE MEMORY_DEBUG)
endif()
+31
View File
@@ -1,3 +1,34 @@
Files for tbaMUD.
## Unit Tests
tbaMUD ships with a C unit-test suite located in the `tests/` directory.
The suite uses the [Unity](https://github.com/ThrowTheSwitch/Unity) test
framework (vendored under `tests/vendor/unity/`).
### Quick start
```
./configure
cd tests && make test
```
`make test` builds each test binary, runs it, and writes JUnit XML results to
`tests/test-results/`. A summary is printed to the terminal:
```
[PASS] test_utils
[PASS] test_random
[PASS] test_interpreter
[PASS] test_class
```
### CI
The GitHub Actions workflow (`.github/workflows/build.yml`) runs `make test`
on every push and pull request against `master` and publishes a formatted
report via the `dorny/test-reporter` action.
See [doc/testing.md](doc/testing.md) for full details on adding new tests and
understanding the test infrastructure.
+1 -1
View File
@@ -210,6 +210,6 @@ AC_CHECK_PROTO(unlink)
AC_CHECK_PROTO(vsnprintf)
AC_CHECK_PROTO(write)
AC_OUTPUT(src/Makefile src/util/Makefile)
AC_OUTPUT(src/Makefile src/util/Makefile tests/Makefile)
#
echo "Configuration completed. To compile, type: cd src; make"
Vendored
+41 -32
View File
@@ -1227,18 +1227,28 @@ if eval "test \"`echo '$ac_cv_func_'crypt`\" = yes"; then
cat >> confdefs.h <<\EOF
#define CIRCLE_CRYPT 1
EOF
CRYPTLIB="-lcrypt"
echo "CRYPTLIB set to: $CRYPTLIB" 1>&6
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
echo "configure:1235: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
echo "configure:1235: checking for crypt in -lcrypt" >&5
OS_NAME=$(uname)
if [ "$OS_NAME" = "Darwin" ]; then
# macOS: No need for -lcrypt
CRYPTLIB=""
echo "CRYPTLIB not needed on macOS" 1>&6
else
# Other systems (Linux): Use -lcrypt
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1243 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
@@ -1250,30 +1260,29 @@ int main() {
crypt()
; return 0; }
EOF
if { (eval echo configure:1254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
if { (eval echo configure:1254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
#define CIRCLE_CRYPT 1
EOF
CRYPTLIB="-lcrypt"
else
echo "$ac_t""no" 1>&6
fi
CRYPTLIB="-lcrypt"
echo "CRYPTLIB set to: $CRYPTLIB on Linux" 1>&6
else
echo "$ac_t""no" 1>&6
fi
fi
fi
@@ -5702,7 +5711,7 @@ EOF
cat >> $CONFIG_STATUS <<EOF
CONFIG_FILES=\${CONFIG_FILES-"src/Makefile src/util/Makefile"}
CONFIG_FILES=\${CONFIG_FILES-"src/Makefile src/util/Makefile tests/Makefile"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+5 -2
View File
@@ -257,6 +257,9 @@ http://tbamud.com
All donated areas have been added to the latest version of tbaMUD. If you
wish to donate some of your own work stop by the Builder Academy.
https://github.com/rds1983 has generated maps of all the existing areas,
and they can be found here: https://mudmapbuilder.github.io/
2.3. I have questions about tbaMUD. Where should I go?
Stop by The Builder Academy at tbamud.com 9091 or the website at:
@@ -697,8 +700,8 @@ trigger variables.
4.15. I want to expand the ability to pk in my MUD, allowing ASSASSINS
that'll be able to PK without getting flagged. How can I do this?
With tbaMUD simply enter Cedit (configuration editor) and select Game Play
Options. Then enable Player Killing.
With tbaMUD simply enter Cedit (configuration editor), select Game Play
(G). Select Player Killing Allowed (A) and choose (3) 'Free for all!'.
4.16. Why does it say ``Connection closed by foreign host.'' and not
display the ``Byebye!'' message I'm trying to send before cutting
+1 -1
View File
@@ -1,7 +1,7 @@
Updated: Apr 2007
tbaMUD README
-------------
All requests for help or bugs should be reported to: builderacademy.net 9091.
All requests for help or bugs should be reported to: tbamud.com 9091.
Information about CircleMUD can be found at the CircleMUD Home Page and FTP:
http://www.circlemud.org
+93
View File
@@ -0,0 +1,93 @@
Updated 2025-04
## Building TbaMUD with the cmake tool
# Building with CMake
This document describes how to configure, build and install tbamud
from source code using the CMake build tool. To build with CMake, you of
course first have to install CMake. The minimum required version of CMake is
specified in the file `CMakeLists.txt` found in the top of the tbamud source
tree. Once the correct version of CMake is installed you can follow the
instructions below for the platform you are building on.
CMake builds can be configured either from the command line, or from one of
CMake's GUIs.
NOTE: The current CMakeLists.txt only supports linux.
# Configuring
A CMake configuration of tbamud is similar to the autotools build of curl.
It consists of the following steps after you have unpacked the source.
We recommend building with CMake on Windows.
## Using `cmake`
You can configure for in source tree builds or for a build tree
that is apart from the source tree.
- Build in a separate directory (parallel to the source tree in this
example). The build directory is created for you. This is recommended over
building in the source tree to separate source and build artifacts.
```shell
$ cmake -B build -S .
```
- Build in the source tree. Not recommended.
```shell
$ cmake -B .
```
The examples below will assume you have created a build folder.
The above commands will generate the build files. If you need to regenerate
the files, you can delete the cmake cache file, and rerun the above command:
```shell
$ rm build/CMakeCache.txt
```
Once the build files are generated, the build is run with cmake
```shell
$ cmake --build build
```
This will generate the object files in a subdirectory under the specified
build folder and link the executable. The resulting binaries will be in the
bin/ folder.
### Utilities
It is possible to build only single tools, none or all of them,
by specifying the target in the build command:
```shell
# only build the mud
$ cmake --build build --target circle
# only build tools
$ cmake --build build --target utils
# only build one tool
$ cmake --build build --target wld2html
```
### Debugging memory
In case you want to run the mud with memory debugging turned on, you
can set the MEMORY_DEBUG flag during configuration by specifying the
flag:
```shell
$ cmake -B build -S . -DMEMORY_DEBUG:int=1
$ cmake --build build
```
When the mud is shut down, the zmalloc code will identify any leaks in your code.
Note that memory debugging may consume quite a lot of memory and take some time
to be handled on shutdown.
+21
View File
@@ -0,0 +1,21 @@
Updated: Apr 2025
Compiling CircleMUD under Microsoft Windows XP
using Microsoft Visual C++ 2022 (8.0)
### Overview
This guide describes how to build TbaMUD in the Visual Studio through the new experimental CMake environment.
### Prerequisites
* [Visual Studio 2022+](https://visualstudio.microsoft.com/ru/vs/)
* [CMake 3.27+](https://cmake.org/)
### Build Steps
1. Goto the folder `src` and copy `conf.h.win` to `conf.h`.
2. Run this command in the root folder:
cmake -B build -S . -G "Visual Studio 17 2022"
3. Open `build/circle.sln` in Visual Studio.
4. Compile and run.
+15 -15
View File
@@ -24,7 +24,7 @@ Contents
1.1 Overview
The act() function is used to process and send strings of text to characters
in a room. It can be used to send the same basic string to a number of
characters filling in certain segments designated by control characters
characters filling in certain segments designated by control characters
in different ways, dependant on what each character can see and who each
character is. Once the text string passed to the function has been parsed, it
is capitalized and a newline is added to its tail.
@@ -38,17 +38,17 @@ struct obj_data *obj, const void *vict_obj, int type)
These pieces are used as follows:
str: This is the basic string, a null terminated character array, including
control characters (see section 1.4 on Control Characters), to be sent to
control characters (see section 1.4 on Control Characters), to be sent to
characters designated by the targets.
hide_invisible: A TRUE or FALSE value indicating whether or not to hide the
entire output from any characters that cannot see the “performing character”.
entire output from any characters that cannot see the “performing character”.
ch: The “performing character”. This is the character that the output string
ch: The “performing character”. This is the character that the output string
is associated with. The character is used to determine the room for the output
of the action in question.
obj: An object (an actual item obj_data) used in the course of the action.
obj: An object (an actual item obj_data) used in the course of the action.
vict_obj: This can be either a character involved in the action, another
object, or even a predefined string of text.
@@ -73,7 +73,7 @@ The next parameter vict_objcan be a number of things ranging from a game object
null terminated character array (char *).
Do note, however, that obj and vict_obj are both ignored if there is no control
character reference (see section 1.4 Control Characters) to them and the type
character reference (see section 1.4 Control Characters) to them and the type
is set to TO_ROOM or TO_CHAR. In these cases, NULL should be supplied as the
input to the function.
@@ -96,7 +96,7 @@ TO_CHAR: Finally, this option sends the output to the ch.
TO_SLEEP: This is a special option that must be combined with one of the above
options. It tells act() that the output is to be sent even to characters that
are sleeping. It is combined with a bitwise or. i.e. TO_VICT | TO_SLEEP.
are sleeping. It is combined with a bitwise or. i.e. TO_VICT | TO_SLEEP.
When the string has been parsed, it is capitalized and a newline is added.
@@ -105,20 +105,20 @@ In a manner similar to the printf() family of functions, act() uses control
characters. However, instead of using the % symbol, act() uses the $ character
to indicate control characters.
$n Write name, short description, or “someone”, for ch, depending on whether
$n Write name, short description, or “someone”, for ch, depending on whether
ch is a PC, a NPC, or an invisible PC/NPC.
$N Like $n, except insert the text for vict_obj.*
$m “him,” “her,” or “it,” depending on the gender of ch.
$m “him,” “her,” or “it,” depending on the gender of ch.
$M Like $m, for vict_obj.*
$s “his,” “her,”or “it,” depending on the gender of ch.
$s “his,” “her,”or “it,” depending on the gender of ch.
$S Like $s, for vict_obj.*
$e “he,” “she,” “it,” depending on the gender of ch.
$e “he,” “she,” “it,” depending on the gender of ch.
$E Like $e, for vict_obj.*
$o Name or “something” for obj, depending on visibility.
$o Name or “something” for obj, depending on visibility.
$O Like $o, for vict_obj.*
$p Short description or “something” for obj.
$p Short description or “something” for obj.
$P Like $p for vict_obj.*
$a “an” or“a”, depending on the first character of objs name.
$a “an” or“a”, depending on the first character of objs name.
$A Like $a, for vict_obj.*
$T Prints the string pointed to by vict_obj.*
$F Processes the string pointed to by vict_obj with the fname() function prior
@@ -129,7 +129,7 @@ no action is taken.
$U Processes the buffer and uppercases the first letter of the following word
(the word immediately after to the control code). If there is no following
word, no action is taken.
$$ Print the character $.
$$ Print the character $.
NOTE*: vict_obj must be a pointer of type struct char_data *.
+24 -24
View File
@@ -9,8 +9,8 @@ to players in color in the tbaMUD game engine. Its intended audience is for
Coders of tbaMUD.
tbaMUD allows you to create colorful messages by using ANSI control sequences.
Each player may select what “level” of color he/she desires from the four
levels “off,” “brief,” “normal,” and “complete.” Each player can select his/her
Each player may select what “level” of color he/she desires from the four
levels “off,” “brief,” “normal,” and “complete.” Each player can select his/her
color level by using the TOGGLE COLOR command from within the MUD; you as the
programmer must decide which messages will be colored for each of the color
levels.
@@ -21,17 +21,17 @@ All files in which you wish to use color must have the line:
This should be put in after all other includes in the beginning of the file.
There are 8 colors available “normal,” red, green, yellow, blue, magenta,
There are 8 colors available “normal,” red, green, yellow, blue, magenta,
cyan and white. They are accessible by sending control sequences as part of
another string, for example:
sprintf(buf, "If youre %shappy%s and you know it clap "
sprintf(buf, "If youre %shappy%s and you know it clap "
"%d of your hands.\n\r", x, y, num_of_hands);
send_to_char(ch, buf);
In this example, x and y are the “on” and “off” sequences for the color you
want. There are 2 main series of color macros available for you to use (dont
actually use “x” and “y,” of course!): the K series and the CC series. The CC
In this example, x and y are the “on” and “off” sequences for the color you
want. There are 2 main series of color macros available for you to use (dont
actually use “x” and “y,” of course!): the K series and the CC series. The CC
(Conditional Color) series is recommended for most general use.
The name of the actual sequence starts with the name of its series, plus a
@@ -51,21 +51,21 @@ CCBLU() (arguments defined below).
The K series requires no arguments, and is simply a macro to the ANSI color
code. Therefore, if you use a K-series color code, the color will ALWAYS be
sent, even if the person youre sending it to has color off. This can very bad.
sent, even if the person youre sending it to has color off. This can very bad.
Some people who do not have ANSI-compatible terminals will see garbage
characters instead of colors. If the terminal correctly ignores ANSI color
codes, then nothing will show up on their screen at all. The K series is mainly
used to print colors to a string if the players color level will later be
used to print colors to a string if the players color level will later be
tested manually (for an example, see do_gen_com in act.comm.c).
The recommended series is the CC series (i.e. CCNRM(), CCRED(), etc.) The CC
series macros require two arguments a pointer to the character to whom the
series macros require two arguments a pointer to the character to whom the
string is being sent, and the minimum color level the player must be set to in
order to see the color. Color sent as 'brief' (formerly known as sparse it was
changed for consistency with the syslog command) (C_SPR) will be seen by people
with color set to sparse, normal, or complete; color sent as normal (C_NRM)
with color set to sparse, normal, or complete; color sent as normal (C_NRM)
will be seen only by people with color set to normal or complete; color sent as
complete (C_CMP) will be seen only by people with color set to complete.
complete (C_CMP) will be seen only by people with color set to complete.
To illustrate the above, an example is in order:
@@ -76,29 +76,29 @@ ACMD(do_showcolor)
{
char buf[300];
sprintf(buf, "Dont you just love %scolor%s, %scolor%s, " "%sCOLOR%s!\n\r",
sprintf(buf, "Dont you just love %scolor%s, %scolor%s, " "%sCOLOR%s!\n\r",
CCBLU(ch, C_CMP), CCNRM(ch, C_CMP), CCYEL(ch, C_NRM), CCNRM(ch, C_NRM),
CCRED(ch, C_SPR), CCNRM(ch, C_SPR));
send_to_char(ch, buf);
}
What does this do? For people with color set to Complete, it prints:
Dont you just love color, color, COLOR! (blue) (yellow) (red)
Dont you just love color, color, COLOR! (blue) (yellow) (red)
People who have color set to Normal will see:
Dont you just love color, color, COLOR! (yellow) (red)
Dont you just love color, color, COLOR! (yellow) (red)
People who have color set to Sparse will see:
Dont you just love color, color, COLOR! (red)
Dont you just love color, color, COLOR! (red)
People who have color set to Off will see:
Dont you just love color, color, COLOR! (no color, as youd expect)
Dont you just love color, color, COLOR! (no color, as youd expect)
There are several common pitfalls with using the CC series of color macros:
Do not confuse CCNRM with C_NRM. CCNRM() is a macro to turn the color back to
normal; C_NRMis a color level of “normal.” Always make sure that every pair of
“on” and “off” codes are at the same color level. For example:
normal; C_NRMis a color level of “normal.” Always make sure that every pair of
“on” and “off” codes are at the same color level. For example:
WRONG: sprintf(buf, "%sCOLOR%s\n\r", CCBLU(ch, C_NRM), CCNRM(ch, C_CMP));
@@ -110,14 +110,14 @@ WRONG: sprintf(buf, "%sCOLOR%s\n\r", CCBLU(ch, C_CMP), CCNRM(ch, C_NRM));
The above statement is also wrong, although not as bad. In this case, someone
with color set to Normal will (correctly) not get the CCBLU code, but will then
unnecessarily get the CCNRM code. Never send a color code if you dont have to.
unnecessarily get the CCNRM code. Never send a color code if you dont have to.
The codes are several bytes long, and cause a noticeable pause at 2400 baud.
This should go without saying, but dont ever send color at the C_OFF level.
This should go without saying, but dont ever send color at the C_OFF level.
Special precautions must be taken when sending a colored string to a large
group of people. You cant use the color level of “ch” (the person sending the
string) each person receiving the string must get a string appropriately
group of people. You cant use the color level of “ch” (the person sending the
string) each person receiving the string must get a string appropriately
colored for his/her level. In such cases, it is usually best to set up two
strings (one colored and one not), and test each players color level
strings (one colored and one not), and test each players color level
individually (see do_gen_comin act.comm.c for an example).
+42 -42
View File
@@ -4,14 +4,14 @@ Builder Academy at telnet://tbamud.com:9091 or email rumble@tbamud.com -- Rumble
The Art of Debugging
Originally by Michael Chastain and Sammy
The following documentation is excerpted from Merc 2.0s hacker.txt file. It
The following documentation is excerpted from Merc 2.0s hacker.txt file. It
was written by Furey of MERC Industries and is included here with his
permission. We have packaged it with tbaMUD (changed in a couple of places,
such as specific filenames) because it offers good advice and insight into the
art and science of software engineering. More information about tbaMUD,
can be found at the tbaMUD home page http://tbamud.com.
1 “Im running a Mud so I can learn C programming!”
1 “Im running a Mud so I can learn C programming!”
Yeah, right. The purpose of this document is to record some of our knowledge,
experience and philosophy. No matter what your level, we hope that this
@@ -31,11 +31,11 @@ Play with it some more.
Read documentation again.
Get the idea?
The idea is that your mind can accept only so much “new data” in a single
session. Playing with something doesnt introduce very much new data, but it
does transform data in your head from the “new” category to the “familiar”
category. Reading documentation doesnt make anything “familiar,” but it
refills your “new” hopper.
The idea is that your mind can accept only so much “new data” in a single
session. Playing with something doesnt introduce very much new data, but it
does transform data in your head from the “new” category to the “familiar”
category. Reading documentation doesnt make anything “familiar,” but it
refills your “new” hopper.
Most people, if they even read documentation in the first place, never return
to it. They come to a certain minimum level of proficiency and then never
@@ -47,17 +47,17 @@ through the two-step learning cycle many times to master it.
man gives you online manual pages.
grep stands for “global regular expression print;” searches for strings in text
grep stands for “global regular expression print;” searches for strings in text
files.
vi, emacs, jove use whatever editor floats your boat, but learn the hell out
of it; you should know every command in your editor.
ctags mags “tags” for your editor which allows you to go to functions by name
ctags mags “tags” for your editor which allows you to go to functions by name
in any source file.
>, >>, <, | input and output redirection at the command line; get someone to
show you, or dig it out of “man csh”
show you, or dig it out of “man csh”
These are the basic day-in day-out development tools. Developing without
knowing how to use all of these well is like driving a car without knowing
@@ -70,21 +70,21 @@ the hypothesis, run the program and provide it experimental input, observe its
behavior, and confirm or refute the hypothesis.
A good hypothesis is one which makes surprising predictions which then come
true; predictions that other hypotheses dont make.
true; predictions that other hypotheses dont make.
The first step in debugging is not to write bugs in the first place. This
sounds obvious, but sadly, is all too often ignored.
If you build a program, and you get any errors or any warnings, you should fix
them before continuing. C was designed so that many buggy ways of writing code
are legal, but will draw warnings from a suitably smart compiler (such as “gcc”
are legal, but will draw warnings from a suitably smart compiler (such as “gcc”
with the -Wall flag enabled). It takes only minutes to check your warnings and
to fix the code that generates them, but it takes hours to find bugs otherwise.
“Desk checking” (proof reading) is almost a lost art these days. Too bad. You
“Desk checking” (proof reading) is almost a lost art these days. Too bad. You
should desk check your code before even compiling it, and desk-check it again
periodically to keep it fresh in mind and find new errors. If you have someone
in your group whose only job it is to desk-check other peoples code, that
in your group whose only job it is to desk-check other peoples code, that
person will find and fix more bugs than everyone else combined.
One can desk-check several hundred lines of code per hour. A top-flight
@@ -95,20 +95,20 @@ fixing technique. Compare that to all the hours you spend screwing around with
broken programs trying to find one bug at a time.
The next technique beyond desk-checking is the time-honored technique of
inserting “print” statements into the code, and then watching the logged
inserting “print” statements into the code, and then watching the logged
values. Within tbaMUD code, you can call printf(), fprintf(), or log()to dump
interesting values at interesting times. Where and when to dump these values
is an art, which you will learn only with practice.
If you dont already know how to redirect output in your operating system, now
is the time to learn. On Unix, type the command “man csh”, and read the part
about the “>” operator. You should also learn the difference between “standard
output” (for example, output from “printf”) and “standard error” (for example,
output from “fprintf(stderr, ...)”).
If you dont already know how to redirect output in your operating system, now
is the time to learn. On Unix, type the command “man csh”, and read the part
about the “>” operator. You should also learn the difference between “standard
output” (for example, output from “printf”) and “standard error” (for example,
output from “fprintf(stderr, ...)”).
Ultimately, you cannot fix a program unless you understand how it is operating
in the first place. Powerful debugging tools will help you collect data, but
they cant interpret it, and they cant fix the underlying problems. Only you
they cant interpret it, and they cant fix the underlying problems. Only you
can do that.
When you find a bug... your first impulse will be to change the code, kill the
@@ -117,9 +117,9 @@ observe is often just the symptom of a deeper bug. You should keep pursuing the
bug, all the way down. You should grok the bug and cherish it in fullness
before causing its discorporation.
Also, when finding a bug, ask yourself two questions: “What design and
programming habits led to the introduction of the bug in the first place?” And:
“What habits would systematically prevent the introduction of bugs like this?”
Also, when finding a bug, ask yourself two questions: “What design and
programming habits led to the introduction of the bug in the first place?” And:
“What habits would systematically prevent the introduction of bugs like this?”
5 Debugging: Tools
@@ -127,20 +127,20 @@ When a Unix process accesses an invalid memory location, or (more rarely)
executes an illegal instruction, or (even more rarely) something else goes
wrong, the Unix operating system takes control. The process is incapable of
further execution and must be killed. Before killing the process, however, the
operating system does something for you: it opens a file named “core” and
operating system does something for you: it opens a file named “core” and
writes the entire data space of the process into it.
Thus, “dumping core” is not a cause of problems, or even an effect of problems.
Its something the operating system does to help you find fatal problems which
Thus, “dumping core” is not a cause of problems, or even an effect of problems.
Its something the operating system does to help you find fatal problems which
have rendered your process unable to continue.
One reads a “core” file with a debugger. The two most popular debuggers on Unix
One reads a “core” file with a debugger. The two most popular debuggers on Unix
are adb and gdb, although occasionally one finds dbx. Typically one starts a
debugger like this: “gdb bin/circle” or “gdb bin/circle lib/core”.
debugger like this: “gdb bin/circle” or “gdb bin/circle lib/core”.
The first thing, and often the only thing, you need to do inside the debugger
is take a stack trace. In adb, the command for this is “$c”. In gdb, the
command is “backtrace”. In dbx, the command is “where”. The stack trace will
is take a stack trace. In adb, the command for this is “$c”. In gdb, the
command is “backtrace”. In dbx, the command is “where”. The stack trace will
tell you what function your program was in when it crashed, and what functions
were calling it. The debugger will also list the arguments to these functions.
Interpreting these arguments, and using more advanced debugger features,
@@ -343,12 +343,12 @@ new tools.
7 Profiling
Another useful technique is “profiling,” to find out where your program is
Another useful technique is “profiling,” to find out where your program is
spending most of its time. This can help you to make a program more efficient.
Here is how to profile a program:
1. Remove all the .o files and the “circle” executable:
1. Remove all the .o files and the “circle” executable:
make clean
2. Edit your Makefile, and change the PROFILE=line:
@@ -359,25 +359,25 @@ make
4. Run circle as usual. Shutdown the game with the shutdown command when you
have run long enough to get a good profiling base under normal usage
conditions. If you crash the game, or kill the process externally, you wont
conditions. If you crash the game, or kill the process externally, you wont
get profiling information.
5. Run the profcommand:
prof bin/circle > prof.out
6. Read prof.out. Run “man prof” to understand the format of the output. For
advanced profiling, you can use “PROFILE = -pg” in step 2, and use the “gprof”
command in step 5. The “gprof” form of profiling gives you a report which lists
6. Read prof.out. Run “man prof” to understand the format of the output. For
advanced profiling, you can use “PROFILE = -pg” in step 2, and use the “gprof”
command in step 5. The “gprof” form of profiling gives you a report which lists
exactly how many times any function calls any other function. This information
is valuable for debugging as well as performance analysis.
Availability of “prof” and “gprof” varies from system to system. Almost every
Unix system has “prof”. Only some systems have “gprof”.
Availability of “prof” and “gprof” varies from system to system. Almost every
Unix system has “prof”. Only some systems have “gprof”.
7 Books for Serious Programmers
Out of all the thousands of books out there, three stand out:
Kernighan and Plaugher, “The Elements of Programming Style”
Kernighan and Ritchie, “The C Programming Language”
Brooks, “The Mythical Man Month”
Kernighan and Plaugher, “The Elements of Programming Style”
Kernighan and Ritchie, “The C Programming Language”
Brooks, “The Mythical Man Month”
+18 -18
View File
@@ -3,7 +3,7 @@ Builder Academy at telnet://tbamud.com:9091 or email rumble@tbamud.com -- Rumble
tbaMUD File Manifest
The main tbaMUD/ directory has the following subdirectories and files:
The main tbaMUD/ directory has the following subdirectories and files:
autorun - Shell script to run the MUD (./autorun &).
FAQ - Frequently Aske Questions with answers.
@@ -16,7 +16,7 @@ lib/ - MUD data.
log/ - System logs.
src/ - Source code.
The bin/directory contains only binaries: circle (the main MUD) and its
The bin/directory contains only binaries: circle (the main MUD) and its
utilities, which are described in utils.txt.
The doc/ directory has its own README file, describing the contents of each
@@ -51,12 +51,12 @@ time - Where the MUD time is saved.
The lib/misc/ directory contains the following files:
bugs - Bugs reported by players with the bug command.
ideas - Ideas from players from idea command.
bugs - Bugs reported by players with the bug command.
ideas - Ideas from players from idea command.
messages - Spell and skill damage messages.
socials - Text file with text of the socials.
socials.new - New format of socials you can edit via AEDIT.
typos - Typos reported by players with the typo command.
typos - Typos reported by players with the typo command.
xnames - Text file of invalid names.
The lib/plrobjs/ contains the following files and directories:
@@ -80,18 +80,18 @@ zzz/
The lib/text/ directory contains the following files:
background - Background story (for option 3 from main menu).
credits - Text for credits command.
credits - Text for credits command.
greetings - Greeting message.
handbook - Text for Immortal Handbook (handbook command).
immlist - Text for immlist command.
handbook - Text for Immortal Handbook (handbook command).
immlist - Text for immlist command.
imotd - Immortal MOTD --seen by immortals on login.
info - Text for info command.
info - Text for info command.
motd - MOTD --seen by mortals on login.
news - Text for news command.
policies - Text for policy command.
wizlist - Text for wizlist command.
/help/screen - Text for help command as a mortal with no arguments.
/help/iscreen - Text for help command an an immortal with no arguments.
news - Text for news command.
policies - Text for policy command.
wizlist - Text for wizlist command.
/help/screen - Text for help command as a mortal with no arguments.
/help/iscreen - Text for help command an an immortal with no arguments.
The lib/world/directory contains the following subdirectories:
@@ -103,8 +103,8 @@ wld - Contains *.wld files (world files)
zon - Contains *.zon files (zone files)
Each of the 6 subdirectories in the lib/world/ directory also contains two
additional files one called index, which specifies which files in that
directory should be loaded when the MUD boots, and index.mini, which
additional files one called index, which specifies which files in that
directory should be loaded when the MUD boots, and index.mini, which
specifies which files should be loaded if the MUD is booted with the -m
(mini-mud) option.
@@ -128,6 +128,6 @@ trigger - Trigedit log messages.
usage - Mud system usage (player load & memory usage info).
The src/ directory contains all of the C and header files for the MUD, along
with a Makefile. The src/util/ directory contains source for tbaMUDs utility
with a Makefile. The src/util/ directory contains source for tbaMUDs utility
programs. See admin.txt for more information on how to compile the MUD. See
utils.txt for more information on how to use tbaMUDs utilities.
utils.txt for more information on how to use tbaMUDs utilities.
+23 -23
View File
@@ -9,16 +9,16 @@ every platform that exists. This document is for experienced programmers
trying to make tbaMUD work on their platform.
tbaMUD should work on most UNIX platforms without any modifications; simply run
the “configure” script and it should automatically detect what type of system
the “configure” script and it should automatically detect what type of system
you have and anything that may be strange about it. These findings are all
stored in a header file called conf.h which is created in the src directory
from a template called conf.h.in. A Makefile is also created from the template
Makefile.in.
Non-UNIX platforms are a problem. Some cant run tbaMUD at all. However, any
Non-UNIX platforms are a problem. Some cant run tbaMUD at all. However, any
multitasking OS that has an ANSI C compiler, and supports non-blocking I/O and
socket-based TCP/IP networking, should theoretically be able to run tbaMUD; for
example, OS/2, AmigaOS, Mac OS (Classic versions; Mac OS X supports tbaMUDs
example, OS/2, AmigaOS, Mac OS (Classic versions; Mac OS X supports tbaMUDs
configure script from the command line), and all versions of Windows.
The port can be very easy or very difficult, depending mainly on whether or nor
@@ -26,7 +26,7 @@ your OS supports the Berkeley socket API.
The general steps for porting tbaMUD to a non-UNIX platform are listed below. A
number of tips for porting can be found after the porting steps. Note that we
have already ported tba to Windows, so if youre confused as to how to perform
have already ported tba to Windows, so if youre confused as to how to perform
some of these steps, you can look at what we have done as an example (see the
files README.CYGWIN).
@@ -36,11 +36,11 @@ trying to port the code.
Porting the Code
Step 1. Create a “conf.h” file for your system. Copy the template “conf.h.in”
to “conf.h”, and then define or undefine each item as directed by the comments
Step 1. Create a “conf.h” file for your system. Copy the template “conf.h.in”
to “conf.h”, and then define or undefine each item as directed by the comments
and based on the characteristics of your system. To write the conf.h file,
youll need to know which header files are included with your system, the
return type of signals, whether or not your compiler supports the const
youll need to know which header files are included with your system, the
return type of signals, whether or not your compiler supports the const
keyword, and whether or not you have various functions such as crypt()and
random(). Also, you can ignore the HAVE_LIBxxx and HAVE_xxx_PROTO constants at
the end of conf.h.in; they are not used in the code (they are part of UNIX
@@ -58,12 +58,12 @@ be in the source file comm.c.
Step 4. Test your changes! Make sure that multiple people can log in
simultaneously and that they can all type commands at the same time. No player
should ever have a “frozen” screen just because another is waiting at a prompt.
should ever have a “frozen” screen just because another is waiting at a prompt.
Leave the MUD up for at least 24 hours, preferably with people playing it, to
make sure that your changes are stable. Make sure that automatic events such as
zone resets, point regeneration, and corpse decomposition are being timed
correctly (a tick should be about 75 seconds). Try resetting all the zones
repeatedly by typing “zr *” many times. Play the MUD and make sure that the
repeatedly by typing “zr *” many times. Play the MUD and make sure that the
basic commands (killing mobs as a mortal, casting spells, etc.) work correctly.
Step 5. If you are satisfied that your changes work correctly, you are
@@ -71,20 +71,20 @@ encouraged to submit them to be included as part of the tbaMUD distribution so
that future releases of tbaMUD will support your platform. This prevents you
from re-porting the code every time a new version is released and allows other
people who use your platform to enjoy tbaMUD as well. To submit your changes
you must make a patch file using the GNU diff program. diff will create a
patch file which can be later used with the patch utility to incorporate
you must make a patch file using the GNU diff program. diff will create a
patch file which can be later used with the patch utility to incorporate
your changes into the stock tbaMUD distribution. For example, if you have a
copy of tbaMUD in the “stock-tba” directory, and your changes are in “my-tba”,
copy of tbaMUD in the “stock-tba” directory, and your changes are in “my-tba”,
you can create a patch file like this:
diff -u --new-file --recursive stock-tba/src my-tba/src > patch
This will create a file called patch with your patches. You should then try
to use the patch program (the inverse of diff) on a copy of tbaMUD to make
This will create a file called patch with your patches. You should then try
to use the patch program (the inverse of diff) on a copy of tbaMUD to make
sure that tbaMUD is correctly changed to incorporate your patches. This step is
very important: if you dont create these patches correctly, your work will be
very important: if you dont create these patches correctly, your work will be
useless because no one will be able to figure out what you did! Make sure to
read the documentation to diff and patch if you dont understand how to use
read the documentation to diff and patch if you dont understand how to use
them. If your patches work, CELEBRATE!!
Step 6. Write a README file for your operating system that describes everything
@@ -107,7 +107,7 @@ Each system to which tba is already ported has a CIRCLE_xx constant associated
with it: CIRCLE_UNIX for plain vanilla UNIX tbaMUD, CIRCLE_WINDOWS for MS
Windows, CIRCLE_OS2 for IBM OS/2, and CIRCLE_AMIGA for the Amiga. You must use
a similar constant for your system. At the top of your conf.h, make sure to
comment out “#define CIRCLE_UNIX” and add “#define CIRCLE_YOUR_SYSTEM”.
comment out “#define CIRCLE_UNIX” and add “#define CIRCLE_YOUR_SYSTEM”.
3.2 ANSI C and GCC
As long as your system has an ANSI C compiler, all of the code (except for
@@ -122,22 +122,22 @@ you use gcc.
Make absolutely sure to use non-blocking I/O; i.e. make sure to enable the
option so that the read() system call will immediately return with an error if
there is no data available. If you do not use non-blocking I/O, read() will
“block,” meaning it will wait infinitely for one particular player to type
“block,” meaning it will wait infinitely for one particular player to type
something even if other players are trying to enter commands. If your system
does not implement non-blocking I/O correctly, try using the
POSIX_NONBLOCK_BROKEN constant in sysdep.h.
3.4 Timing
tbaMUD needs a fairly precise (on the order of 5 or 10 ms) timer in order to
correctly schedule events such as zone resets, point regeneration (“ticks”),
correctly schedule events such as zone resets, point regeneration (“ticks”),
corpse decomposition, and other automatic tasks. If your system supports the
select() system call with sufficient precision, the default timing code should
work correctly. If not, youll have to find out which system calls your system
work correctly. If not, youll have to find out which system calls your system
supports for determining how much time has passed and replace the select()
timing method.
3.5 Signals and Signal Handlers
A note about signals: Most systems dont support the concept of signals in the
A note about signals: Most systems dont support the concept of signals in the
same way that UNIX does. Since signals are not a critical part of how tbaMUD
works anyway (they are only used for updating the wizlist and some other
trivial things), all signal handling is turned off by default when compiling
@@ -147,7 +147,7 @@ conf.h file and all signal code will be ignored automatically.
4 Final Note
IMPORTANT: Remember to keep any changes you make surrounded by #ifdef
statements (i.e. “#ifdef CIRCLE_WINDOWS ... #endif”). If you make absolutely
statements (i.e. “#ifdef CIRCLE_WINDOWS ... #endif”). If you make absolutely
sure to mark all of your changes with #ifdef statements, then your patches
(once you get them to work) will be suitable for incorporation into the
tbaMUD distribution, meaning that tbaMUD will officially support your platform.
+2 -1
View File
@@ -10,6 +10,7 @@ to rec.games.mud.diku which originally announced CircleMUD as a publicly
available MUD source code.
tbaMUD Release history:
Version 2025 release: January, 2025
Version 2023 release: January, 2023
Version 2021 release: March, 2021
Version 2020 release: January, 2020
@@ -142,7 +143,7 @@ communication channels
totally ignores all commands from that player until they are thawed.
--Even handier DELETE flag allows you to delete players on the fly.
--"set" command (mentioned above) allows you to freeze/unfreeze/
delete/siteok/un-siteok players --even if they arent logged in!
delete/siteok/un-siteok players --even if they arent logged in!
--Bad password attempts are written to the system log and saved;
if someone tries to hack your account, you see "4 LOGIN FAILURES
SINCE LAST SUCCESSFUL LOGIN" next time you log on.
+3 -3
View File
@@ -110,12 +110,12 @@ is being specified. The command sort name is the shortest part of the command a
player must type for it to match. The hide-flag can be either 0 or 1; if 1, the
social is hidden from OTHERS if they cannot see the character performing the
social. The action is not hidden from the VICTIM, even if s/he cannot see the
character performing the social, although in such cases the characters name
will, of course, be replaced with “someone”. The min positions should be set to
character performing the social, although in such cases the characters name
will, of course, be replaced with “someone”. The min positions should be set to
dictate the minimum position a player must be in to target the victim and
perform the social. Min level allows you to further customize who can use what
socials.Where it makes sense to do so, text fields may be left empty. If
editing manually you should by put a # in the first column on the line. Aedit
editing manually you should by put a # in the first column on the line. Aedit
does this automatically.
Examples:
+150
View File
@@ -0,0 +1,150 @@
# tbaMUD Unit Testing
_Updated 2026-04_
## Overview
tbaMUD has a C unit-test suite built on the
[Unity](https://github.com/ThrowTheSwitch/Unity) framework. Tests live in the
`tests/` directory alongside the vendored Unity source.
```
tests/
Makefile.in Autoconf template; processed by configure
test_stubs.c Weak-symbol stubs that satisfy mud headers
unity_to_junit.py Converts Unity output to JUnit XML
test_class.c Tests for src/class.c
test_interpreter.c Tests for src/interpreter.c
test_random.c Tests for src/random.c
test_utils.c Tests for src/utils.c
vendor/unity/ Vendored Unity test framework
```
## Prerequisites
| Requirement | Notes |
|---|---|
| C compiler (gcc or clang) | Same compiler used to build the mud |
| GNU make | Any POSIX-compatible make works |
| Python 3 | Required only for JUnit XML conversion (`unity_to_junit.py`) |
| autoconf / configure | Already needed to build the mud |
## Running the tests
Run `./configure` from the repository root first (only needed once):
```sh
./configure
```
Then build and run all tests from the `tests/` directory:
```sh
cd tests
make test
```
`make test` performs the following steps for each test binary:
1. Compiles the test binary (if not already up to date).
2. Runs the binary and captures stdout/stderr to `test-results/<name>.out`.
3. Measures wall-clock elapsed time.
4. Converts the Unity output to JUnit XML via `unity_to_junit.py`, writing
`test-results/<name>.xml`.
5. Prints `[PASS] <name>` or `[FAIL] <name>` and exits non-zero if any
binary failed.
To build the test binaries without running them:
```sh
cd tests
make
```
To remove all test binaries and result files:
```sh
cd tests
make clean
```
## Test suites
| Binary | Source under test | Test file |
|---|---|---|
| `test_utils` | `src/utils.c`, `src/random.c` | `test_utils.c` |
| `test_random` | `src/random.c`, `rand_number`/`dice` in `src/utils.c` | `test_random.c` |
| `test_interpreter` | `src/interpreter.c` | `test_interpreter.c` |
| `test_class` | `src/class.c` | `test_class.c` |
## Writing a new test
### Adding a test case to an existing suite
1. Open the relevant `test_<name>.c` file.
2. Write a function with the signature `void test_my_feature(void)`.
3. Use Unity assertion macros such as `TEST_ASSERT_EQUAL_INT`,
`TEST_ASSERT_NULL`, `TEST_ASSERT_TRUE`, etc.
4. Register the function in the `main()` block:
```c
RUN_TEST(test_my_feature);
```
Example:
```c
void test_str_cmp_equal_strings(void)
{
TEST_ASSERT_EQUAL_INT(0, str_cmp("hello", "hello"));
}
```
### Creating a new test suite
1. Create `tests/test_<module>.c`. Copy the boilerplate from an existing
suite: include `unity.h`, define `setUp`/`tearDown` (may be empty), write
test functions, and provide a `main()` that calls `UNITY_BEGIN()`,
`RUN_TEST(...)` for each function, and `return UNITY_END();`.
2. Add the binary to `tests/Makefile.in`:
- Add the name to the `TESTS` variable.
- Add a build rule:
```make
test_<module>: $(UNITY_SRC) $(STUBS_SRC) $(UTILS_SRC) \
$(SRCDIR)/<module>.c test_<module>.c
$(COMPILE) -o $@ $^ $(LIBS)
```
3. Re-run `./configure` from the repository root to regenerate
`tests/Makefile` from the updated `tests/Makefile.in`.
### Stubs
Many mud source files reference global variables and functions that are only
meaningful at runtime (e.g. `descriptor_list`, `log()`). `test_stubs.c`
provides zero-initialised definitions and `__attribute__((weak))` stub
implementations for these symbols so that test binaries link without pulling
in the full mud.
If a new test requires a function not yet stubbed, add a weak stub to
`test_stubs.c`:
```c
__attribute__((weak)) void my_function(void) { /* no-op */ }
```
## JUnit XML output and CI
`unity_to_junit.py` reads Unity's line-oriented output on stdin and writes a
JUnit-compatible XML file. It accepts an optional third argument with the
elapsed wall-clock time in seconds (provided by the `make test` target):
```
usage: unity_to_junit.py <suite_name> <output.xml> [elapsed_seconds]
```
The GitHub Actions workflow (`.github/workflows/build.yml`) runs `make test`
on every push and pull request against `master`. After the tests finish the
`dorny/test-reporter` action reads `tests/test-results/*.xml` and publishes a
formatted report as a GitHub Check with pass/fail counts and per-suite
execution times.
+4 -4
View File
@@ -34,7 +34,7 @@ older CircleMUD data files to the versions used in CircleMUD v3, while others
are used to convert currently existing files into different formats.
Overall, these utilities have been created in an attempt to make the tbaMUD
administrators life a bit easier, and to give the administrator some ideas of
administrators life a bit easier, and to give the administrator some ideas of
further and more grandiose utilities to create. Some are no longer applicable
but are retained as examples.
@@ -61,7 +61,7 @@ the second, and so forth.
The split utility is designed to split large world files into smaller, zone
sized files that are easier to manage and maintain. The utility reads its input
from the standard input and writes the output to files with names specified
within the larger world file. This is done by inserting =filename into the
within the larger world file. This is done by inserting =filename into the
world file at the appropriate points, where filename is the name of the file
for the following section.
@@ -141,8 +141,8 @@ The command line syntax for autowiz is as follows:
autowiz <wizlev> <wizlistfile> <immlev> <immlistfile> [pid to signal]
where <wizlev> is equal to whatever LVL_GOD is set to in your tbaMUD server,
<wizlistfile> is the filename for the file containing the games Wizlist.
<immlev> should be set to your games LVL_IMMORT, while <immlistfile>
<wizlistfile> is the filename for the file containing the games Wizlist.
<immlev> should be set to your games LVL_IMMORT, while <immlistfile>
is the name of the Immlist file.
This utility must be recompiled if you make any changes to the player file structure.
+1 -1
View File
@@ -1,5 +1,5 @@
T B A M U D
2 0 2 3
2 0 2 5
Based on CircleMUD by Jeremy Elson and DikuMUD by Hans-Henrik Staerfeldt,
Katja Nyboe, Tom Madsen, Michael Seifert, and Sebastian Hammer
+38 -58
View File
@@ -865,7 +865,7 @@ AUTOQUESTS QUESTS QUESTMASTERS QUEST-MOBS QUESTMOBS
An autoquest is a quest that can be automatically started and completed
without the intervention of an immortal. Simply visit a questmaster and join
an available quest, and get rewarded on its completion. Keep an eye out for
an available quest, and get rewarded on it's completion. Keep an eye out for
autoquests scattered throughout the World.
See Also: QUEST-FLAG, QUESTPOINTS
@@ -1584,7 +1584,6 @@ qedit (quest editor)
questpoints
buildwalk
dig
tell m-w (an in game dictionary lookup)
gemote
history
file
@@ -2444,25 +2443,6 @@ Example:
> diagnose doctor
See also: CONSIDER, HIT, KILL
#0
DICTIONARY DICTIONARIES THESAURUS M-W.COM DEFINITION MERRIAM-WEBSTER M-W-DEFINITION WEBSTER MW TELL-M-W BREATHER SPELLING WORDS
Usage: tell m-w <word>
We have a direct link to Merriam Webster. To use the dictionary just
tell m-w <word>
>tell m-w breather
You get this feedback from Merriam-Webster:
That means:
1 : one that breathes
2 : a break in activity for rest or relief
3 : a small vent in an otherwise airtight enclosure
A few obscure definitions are not available through m-w since they are in the
unabridged version that requires membership. They also offer a thesaurus at:
@Chttp://m-w.com/@n
#31
DIG UNDIG RDIG RELINK RLINKS
@@ -3173,7 +3153,7 @@ game.
Invest in a thesaurus. Makes a world of difference, and if that doesn't
help, just make up your own words for things you create (just be sure to
describe them very well. Use @Chttp://m-w.com/@n for an online thesaurus
and dictionary. You can @Rtell m-w <word>@n to lookup a definition.
and dictionary.
4. Where can I learn Trigedit?
Here! Welcor is now the developer of trigedit. We have extensive help files,
@@ -3564,8 +3544,8 @@ GRAMMAR GRAMMER TIPS
words can be particularly tricky and elude electronic spell checkers. A good
dictionary, however, will help you spell archaic words. Whenever I am building
I use our Merriam Webster dictionary link on TBA to check any tough words for
proper spelling. Test it out @RTELL M-W DEFINITION@n. We hope to add a thesaurus
soon! Goto @Chttp://m-w.com/@n until then.
proper spelling. We hope to add a thesaurus soon! Goto @Chttp://m-w.com/@n
until then.
I have found that a good principle to make is to avoid the use of all
contractions. For example, if you mean to say "it is", do not use "it's", spell
it out. This will help differentiate between "its" (which means 'belonging to
@@ -7192,7 +7172,7 @@ prefer to add the quest in the zone where quest completion takes place.
Quests use vnums in exactly the same way as mobiles, object and rooms. Each
zone will normally have 100 vnums available (#00 to #99, where # is the zone
number). Usually, when creating the first quest in a zone, #00 is used,
then #01, etc
then #01, etc.
When you qedit <vnum> to create a new quest (or edit an existing one), you will
see the menu in @RHELP QEDIT-MENU@n
@@ -7203,12 +7183,12 @@ QEDIT-ACCEPT
This is the text that is sent to the player when they start the quest. It
should describe in detail exactly what is required to complete the quest. The
text is simply output on the players screen, so be creative here. An example
text is simply output on the player's screen, so be creative here. An example
of an accept message text could be something like:
The questmaster rummages in a large pile of papers.
The questmaster says Ah, here it is
The questmaster says Bob, the local butcher has offered this quest
The questmaster says "Ah, here it is"
The questmaster says "Bob, the local butcher has offered this quest"
The questmaster shows you a hastily scrawled note, that reads:
I am willing to offer any plucky adventurer 10 quest points if they bring me a
@@ -7218,7 +7198,7 @@ order to fill. I need these within 24 hours
Thanks, Bob the Butcher, Midgaard
The questmaster sighs.
The questmaster says A tricky quest, but itll cost you 5qp to back out now
The questmaster says "A tricky quest, but it'll cost you 5qp to back out now"
#31
QEDIT-COMPLETED QEDIT-ABANDONED
@@ -7232,7 +7212,7 @@ all timed quests.
QEDIT-COMPLETION
Just like the accept message, this is simply text that is output on the
players screen when they successfully complete the quest. Prizes (quest
player's screen when they successfully complete the quest. Prizes (quest
points, gold coins, experience points or an object) are automatically
announced after this text is shown, so this text does not need to have that
information in it.
@@ -7258,7 +7238,7 @@ Quest flags: @cNOBITS@n
Enter quest flags, 0 to quit :
Currently, only one flag is available, the REPEATABLE flag. When you have
finished turning this on or off, select 0 (zero) to return to the main menu.
finished turning this on or off, select "0" (zero) to return to the main menu.
#31
QEDIT-LEVELS
@@ -7312,12 +7292,12 @@ QEDIT-NEXT
This is the quest vnum of next quest in a chain. When a player completes
the current quest, the next quest will automatically be joined. This allows
for long quests with a number of steps.
for long quests with a number of "steps".
#31
QEDIT-PREREQUISITE
This is the object vnum for a prerequisite object. The prerequisite object
should be in the players inventory in order for them to be able to join the
should be in the player's inventory in order for them to be able to join the
quest. It is not taken from the player when the quest starts.
#31
QEDIT-PREVIOUS
@@ -7328,15 +7308,15 @@ completed by the player in order to join this quest.
QEDIT-QUANTITY
This is the number of times the player needs to repeat the quest. For
example, it could be the number of items the player needs to find in a object
quest of the number of mobs the player should kill in a kill mob quest. This
should be used with caution, however. In an object quest picking up the same
example, it could be the number of items the player needs to find in a "object"
quest of the number of mobs the player should kill in a "kill mob" quest. This
should be used with caution, however. In an object quest picking up the same
object 20 times will also complete the quest.
#31
QEDIT-QUIT QEDIT-MESSAGE
The quit message is sent to the player when they type quest leave. Players
can lose quest points for abandoning a quest (see Abandoned on the next
can lose quest points for abandoning a quest (see "Abandoned" on the next
page), so if they lose quest points, this text really should inform them of
that.
#31
@@ -7365,14 +7345,14 @@ Room, Clear Room - Room VNUM
#31
QEDIT-TIME
This is the number of ticks or game hours that the player has to complete
This is the number of 'ticks' or game hours that the player has to complete
the quest. If this is set, then the builder should really try to do the quest
themselves, and time how long it takes (typing time before and after the
attempt), and then giving at least one extra tick for players to complete it.
themselves, and time how long it takes (typing 'time' before and after the
attempt), and then giving at least one extra 'tick' for players to complete it.
#31
QEDIT-TYPE
There are a few different quest types. When you select option 7 from the
There are a few different quest types. When you select option '7' from the
main menu, you will be shown a list to choose from:
0) Object - Player needs to find a particular object.
@@ -7447,7 +7427,7 @@ Usage: quest [list | join <#> | progress | leave | history]
quest - Show usage information for the quest command.
quest list - Used at the questmaster to see which quests are available.
quest join # - Used to the questmaster to join the quest listed as number nn on quest list.
quest join # - Used to the questmaster to join the quest listed as number 'nn' on quest list.
quest progress - Shows the player which quest they are doing, and their quest progress.
quest leave - Allows the player to abandon the current quest, taking the quest point penalty.
quest history - Shows all previously completed non-repeatable quests.
@@ -9352,7 +9332,7 @@ and simply bearing artistic merit. Second, by ensuring that they are absolutely
necessary to achieve the goals of the game! If your game is made for experience
and equipment gathering, and failure to read descriptions directly impedes this
goal, then players will learn to read everything. If your game is made for
exploring or role-play, most of your players probably already read them Â-
exploring or role-play, most of your players probably already read them -
because knowing their environment is a basic requirement of play. In any case,
builders exist to ensure that the goals of play are supported by game
descriptions.
@@ -9364,7 +9344,7 @@ meaning behind descriptions, areas to find, special items, unique nooks and
crannies to spend time socializing, and hints that point to these things
elsewhere outside of your own zone is an excellent idea. In fact, if you
don't wish to be building descriptions no one will read, you should employ
special secrets Â- most especially on games where knowing one's environment
special secrets - most especially on games where knowing one's environment
does deeply affect a character's development. No matter what kind of zone you
are building, keep it interesting throughout!
@@ -9387,7 +9367,7 @@ road.
shouldn't be the sole builder of your zone. Instead, seek the assistance of
someone who adds creative merit to your descriptions. You can do practically
everything from plot to secrets to minutiae, even write the zone in full and
just ask someone you know who writes well to Â'say it better' and rewrite
just ask someone you know who writes well to 'say it better' and rewrite
what you intended to have there all along. Novels have editors, and so
should any zone.
@@ -9659,19 +9639,19 @@ have a point and here it is: *drum roll please*
Building is hard work! It is a form of expression and creativity. What kind
of areas you build generally reflects on what kind of person you are. You
do not have to be a good speller but you do need a good dictionary/thesaurus.
@RHELP M-W@n. Sometimes building can seem like a thankless job and sometimes
building can be a reward in itself. Building a few areas, even a few good
ones, does not make you an Immortal or an Imp. It takes more than building to
be one of those and it entails even more work. Respect others and they will
respect you. The more detailed an area the better it is. Always choose Quality
over Quantity. Put some pride in your areas, develop a style of your own. Try
new things keep it interesting, if you become bored with building an area take
a break and play a mortal or do something else, don't take advantage of builder
privileges. Treat others as you wish to be treated. One more warning I would
give to builders before they take things personally or get insulted. Everyone
has their own ideas on how to run a MUD, what it comes down to is whoever owns
the MUD makes the final decision, so it does not matter how good you think your
idea is, it may never be used if the owner does not like it. Plain and simple.
Sometimes building can seem like a thankless job and sometimes building can be
a reward in itself. Building a few areas, even a few good ones, does not make
you an Immortal or an Imp. It takes more than building to be one of those and
it entails even more work. Respect others and they will respect you. The more
detailed an area the better it is. Always choose Quality over Quantity. Put
some pride in your areas, develop a style of your own. Try new things keep it
interesting, if you become bored with building an area take a break and play a
mortal or do something else, don't take advantage of builder privileges.
Treat others as you wish to be treated. One more warning I would give to
builders before they take things personally or get insulted. Everyone has their
own ideas on how to run a MUD, what it comes down to is whoever owns the MUD
makes the final decision, so it does not matter how good you think your idea
is, it may never be used if the owner does not like it. Plain and simple.
You see this on every MUD. So please keep the ideas coming, but do not try to
force them onto anyone. Be constructive, not critical about peoples ideas.
Everyone is allowed their opinions.
+81
View File
File diff suppressed because one or more lines are too long
+26
View File
@@ -0,0 +1,26 @@
cmake_minimum_required(VERSION 3.27)
# Set the project name
project(circle)
# Global definitions
if(MSVC)
# using Visual Studio C++
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
endif()
# circle itself
file(GLOB CIRCLE_SOURCES
"*.h"
"*.c"
)
add_executable(circle ${CIRCLE_SOURCES})
if(MSVC)
target_link_libraries(circle wsock32.lib)
set_target_properties(circle PROPERTIES
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/.."
)
endif()
+2 -2
View File
@@ -20,8 +20,8 @@ CFLAGS = @CFLAGS@ $(MYFLAGS) $(PROFILE)
LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@
SRCFILES := act.comm.c act.informative.c act.item.c act.movement.c act.offensive.c act.other.c act.social.c act.wizard.c aedit.c asciimap.c ban.c boards.c bsd-snprintf.c castle.c cedit.c class.c comm.c config.c constants.c db.c dg_comm.c dg_db_scripts.c dg_event.c dg_handler.c dg_misc.c dg_mobcmd.c dg_objcmd.c dg_olc.c dg_scripts.c dg_triggers.c dg_variables.c dg_wldcmd.c fight.c genmob.c genobj.c genolc.c genqst.c genshp.c genwld.c genzon.c graph.c handler.c hedit.c house.c ibt.c improved-edit.c interpreter.c limits.c lists.c magic.c mail.c medit.c mobact.c modify.c msgedit.c mud_event.c oasis.c oasis_copy.c oasis_delete.c oasis_list.c objsave.c oedit.c players.c prefedit.c protocol.c qedit.c quest.c random.c redit.c sedit.c shop.c spec_assign.c spec_procs.c spell_parser.c spells.c tedit.c utils.c weather.c zedit.c zmalloc.c
OBJFILES := act.comm.o act.informative.o act.item.o act.movement.o act.offensive.o act.other.o act.social.o act.wizard.o aedit.o asciimap.o ban.o boards.o bsd-snprintf.o castle.o cedit.o class.o comm.o config.o constants.o db.o dg_comm.o dg_db_scripts.o dg_event.o dg_handler.o dg_misc.o dg_mobcmd.o dg_objcmd.o dg_olc.o dg_scripts.o dg_triggers.o dg_variables.o dg_wldcmd.o fight.o genmob.o genobj.o genolc.o genqst.o genshp.o genwld.o genzon.o graph.o handler.o hedit.o house.o ibt.o improved-edit.o interpreter.o limits.o lists.o magic.o mail.o medit.o mobact.o modify.o msgedit.o mud_event.o oasis.o oasis_copy.o oasis_delete.o oasis_list.o objsave.o oedit.o players.o prefedit.o protocol.o qedit.o quest.o random.o redit.o sedit.o shop.o spec_assign.o spec_procs.o spell_parser.o spells.o tedit.o utils.o weather.o zedit.o zmalloc.o
SRCFILES := $(shell ls *.c | sort)
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
default: all
+56
View File
@@ -0,0 +1,56 @@
# tbaMUD Makefile.in - Makefile template used by 'configure'
# Clean-up provided by seqwith.
# C compiler to use
CC = gcc
# Any special flags you want to pass to the compiler
MYFLAGS = -Wall -Wno-char-subscripts -Wno-invalid-source-encoding -DMEMORY_DEBUG
#flags for profiling (see hacker.doc for more information)
PROFILE =
##############################################################################
# Do Not Modify Anything Below This Line (unless you know what you're doing) #
##############################################################################
BINDIR = ../bin
CFLAGS = -g -O0 $(MYFLAGS) $(PROFILE)
LIBS =
SRCFILES := $(shell ls *.c | sort)
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
default: all
all: .accepted
$(MAKE) $(BINDIR)/circle
$(MAKE) utils
.accepted:
@./licheck less
utils: .accepted
(cd util; $(MAKE) all)
circle:
$(MAKE) $(BINDIR)/circle
$(BINDIR)/circle : $(OBJFILES)
$(CC) -o $(BINDIR)/circle $(PROFILE) $(OBJFILES) $(LIBS)
$%.o: %.c
$(CC) $< $(CFLAGS) -c -o $@
clean:
rm -f *.o depend
# Dependencies for the object files (automagically generated with
# gcc -MM)
depend:
$(CC) -MM *.c > depend
-include depend
+1 -33
View File
@@ -150,39 +150,7 @@ ACMD(do_tell)
if (!*buf || !*buf2)
send_to_char(ch, "Who do you wish to tell what??\r\n");
else if (!strcmp(buf, "m-w")) {
#ifdef CIRCLE_WINDOWS
/* getpid() is not portable */
send_to_char(ch, "Sorry, that is not available in the windows port.\r\n");
#else /* all other configurations */
char word[MAX_INPUT_LENGTH], *p, *q;
if (last_webster_teller != -1L) {
if (GET_IDNUM(ch) == last_webster_teller) {
send_to_char(ch, "You are still waiting for a response.\r\n");
return;
} else {
send_to_char(ch, "Hold on, m-w is busy. Try again in a couple of seconds.\r\n");
return;
}
}
/* Only a-z and +/- allowed. */
for (p = buf2, q = word; *p ; p++)
if ((LOWER(*p) <= 'z' && LOWER(*p) >= 'a') || (*p == '+') || (*p == '-'))
*q++ = *p;
*q = '\0';
if (!*word) {
send_to_char(ch, "Sorry, only letters and +/- are allowed characters.\r\n");
return;
}
snprintf(buf, sizeof(buf), "../bin/webster %s %d &", word, (int) getpid());
last_webster_teller = GET_IDNUM(ch);
send_to_char(ch, "You look up '%s' in Merriam-Webster.\r\n", word);
#endif /* platform specific part */
} else if (GET_LEVEL(ch) < LVL_IMMORT && !(vict = get_player_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
else if (GET_LEVEL(ch) < LVL_IMMORT && !(vict = get_player_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
send_to_char(ch, "%s", CONFIG_NOPERSON);
else if (GET_LEVEL(ch) >= LVL_IMMORT && !(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
send_to_char(ch, "%s", CONFIG_NOPERSON);
+272 -196
View File
@@ -46,12 +46,12 @@ static void list_obj_to_char(struct obj_data *list, struct char_data *ch, int mo
static void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mode);
static void show_obj_modifiers(struct obj_data *obj, struct char_data *ch);
/* do_where utility functions */
static void perform_immort_where(struct char_data *ch, char *arg);
static void perform_immort_where(char_data *ch, const char *arg);
static void perform_mortal_where(struct char_data *ch, char *arg);
static void print_object_location(int num, struct obj_data *obj, struct char_data *ch, int recur);
static size_t print_object_location(int num, const obj_data *obj, const char_data *ch,
char *buf, size_t len, size_t buf_size, int recur);
/* Subcommands */
/* For show_obj_to_char 'mode'. /-- arbitrary */
/* For show_obj_to_char 'mode'. /-- arbitrary */
#define SHOW_OBJ_LONG 0
#define SHOW_OBJ_SHORT 1
#define SHOW_OBJ_ACTION 2
@@ -125,7 +125,7 @@ static void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mod
snprintf(notebuf, sizeof(notebuf), "There is something written on it:\r\n\r\n%s", obj->action_description);
page_string(ch->desc, notebuf, TRUE);
} else
send_to_char(ch, "It's blank.\r\n");
send_to_char(ch, "It's blank.\r\n");
return;
case ITEM_DRINKCON:
@@ -225,14 +225,14 @@ static void diag_char_to_char(struct char_data *i, struct char_data *ch)
byte percent;
const char *text;
} diagnosis[] = {
{ 100, "is in excellent condition." },
{ 90, "has a few scratches." },
{ 75, "has some small wounds and bruises." },
{ 50, "has quite a few wounds." },
{ 30, "has some big nasty wounds and scratches." },
{ 15, "looks pretty hurt." },
{ 0, "is in awful condition." },
{ -1, "is bleeding awfully from big wounds." },
{ 100, "is in excellent condition." },
{ 90, "has a few scratches." },
{ 75, "has some small wounds and bruises." },
{ 50, "has quite a few wounds." },
{ 30, "has some big nasty wounds and scratches." },
{ 15, "looks pretty hurt." },
{ 0, "is in awful condition." },
{ -1, "is bleeding awfully from big wounds." },
};
int percent, ar_index;
const char *pers = PERS(i, ch);
@@ -240,7 +240,7 @@ static void diag_char_to_char(struct char_data *i, struct char_data *ch)
if (GET_MAX_HIT(i) > 0)
percent = (100 * GET_HIT(i)) / GET_MAX_HIT(i);
else
percent = -1; /* How could MAX_HIT be < 1?? */
percent = -1; /* How could MAX_HIT be < 1?? */
for (ar_index = 0; diagnosis[ar_index].percent >= 0; ar_index++)
if (percent >= diagnosis[ar_index].percent)
@@ -269,12 +269,12 @@ static void look_at_char(struct char_data *i, struct char_data *ch)
found = TRUE;
if (found) {
send_to_char(ch, "\r\n"); /* act() does capitalization. */
send_to_char(ch, "\r\n"); /* act() does capitalization. */
act("$n is using:", FALSE, i, 0, ch, TO_VICT);
for (j = 0; j < NUM_WEARS; j++)
if (GET_EQ(i, j) && CAN_SEE_OBJ(ch, GET_EQ(i, j))) {
send_to_char(ch, "%s", wear_where[j]);
show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT);
send_to_char(ch, "%s", wear_where[j]);
show_obj_to_char(GET_EQ(i, j), ch, SHOW_OBJ_SHORT);
}
}
if (ch != i && (IS_THIEF(ch) || GET_LEVEL(ch) >= LVL_IMMORT)) {
@@ -300,7 +300,7 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS)) {
if (IS_NPC(i))
send_to_char(ch, "[%d] ", GET_MOB_VNUM(i));
send_to_char(ch, "[%d] ", GET_MOB_VNUM(i));
if (SCRIPT(i) && TRIGGERS(SCRIPT(i))) {
if (!TRIGGERS(SCRIPT(i))->next)
send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i))));
@@ -312,12 +312,12 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (GROUP(i)) {
if (GROUP(i) == GROUP(ch))
send_to_char(ch, "(%s%s%s) ", CBGRN(ch, C_NRM),
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
else
send_to_char(ch, "(%s%s%s) ", CBRED(ch, C_NRM),
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
GROUP_LEADER(GROUP(i)) == i ? "leader" : "group",
CCNRM(ch, C_NRM));
}
if (IS_NPC(i) && i->player.long_descr && GET_POS(i) == GET_DEFAULT_POS(i)) {
@@ -326,9 +326,9 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (AFF_FLAGGED(ch, AFF_DETECT_ALIGN)) {
if (IS_EVIL(i))
send_to_char(ch, "(Red Aura) ");
send_to_char(ch, "(Red Aura) ");
else if (IS_GOOD(i))
send_to_char(ch, "(Blue Aura) ");
send_to_char(ch, "(Blue Aura) ");
}
send_to_char(ch, "%s", i->player.long_descr);
@@ -361,24 +361,24 @@ static void list_one_char(struct char_data *i, struct char_data *ch)
if (GET_POS(i) != POS_FIGHTING) {
if (!SITTING(i))
send_to_char(ch, "%s", positions[(int) GET_POS(i)]);
else {
furniture = SITTING(i);
send_to_char(ch, " is %s upon %s.", (GET_POS(i) == POS_SLEEPING ?
else {
furniture = SITTING(i);
send_to_char(ch, " is %s upon %s.", (GET_POS(i) == POS_SLEEPING ?
"sleeping" : (GET_POS(i) == POS_RESTING ? "resting" : "sitting")),
OBJS(furniture, ch));
}
}
} else {
if (FIGHTING(i)) {
send_to_char(ch, " is here, fighting ");
if (FIGHTING(i) == ch)
send_to_char(ch, "YOU!");
send_to_char(ch, "YOU!");
else {
if (IN_ROOM(i) == IN_ROOM(FIGHTING(i)))
send_to_char(ch, "%s!", PERS(FIGHTING(i), ch));
else
send_to_char(ch, "someone who has already left!");
if (IN_ROOM(i) == IN_ROOM(FIGHTING(i)))
send_to_char(ch, "%s!", PERS(FIGHTING(i), ch));
else
send_to_char(ch, "someone who has already left!");
}
} else /* NIL fighting pointer */
} else /* NIL fighting pointer */
send_to_char(ch, " is here struggling with thin air.");
}
@@ -402,13 +402,13 @@ static void list_char_to_char(struct char_data *list, struct char_data *ch)
if (ch != i) {
/* hide npcs whose description starts with a '.' from non-holylighted people - Idea from Elaseth of TBA */
if (!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT) &&
IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.')
IS_NPC(i) && i->player.long_descr && *i->player.long_descr == '.')
continue;
send_to_char(ch, "%s", CCYEL(ch, C_NRM));
if (CAN_SEE(ch, i))
list_one_char(i, ch);
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch) &&
AFF_FLAGGED(i, AFF_INFRAVISION))
AFF_FLAGGED(i, AFF_INFRAVISION))
send_to_char(ch, "You see a pair of glowing red eyes looking your way.\r\n");
send_to_char(ch, "%s", CCNRM(ch, C_NRM));
}
@@ -425,12 +425,12 @@ static void do_auto_exits(struct char_data *ch)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && !CONFIG_DISP_CLOSED_DOORS)
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT))
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT))
continue;
if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))
send_to_char(ch, "%s(%s)%s ", EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? CCWHT(ch, C_NRM) : CCRED(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN))
send_to_char(ch, "%s%s%s ", CCWHT(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
send_to_char(ch, "%s(%s)%s ", EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? CCWHT(ch, C_NRM) : CCRED(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN))
send_to_char(ch, "%s%s%s ", CCWHT(ch, C_NRM), autoexits[door], CCCYN(ch, C_NRM));
else
send_to_char(ch, "\t(%s\t) ", autoexits[door]);
slen++;
@@ -519,26 +519,27 @@ void look_at_room(struct char_data *ch, int ignore_brief)
send_to_char(ch, "]");
}
}
else {
else
send_to_char(ch, "%s", world[IN_ROOM(ch)].name);
send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room);
}
send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room);
else
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
}
/*autoexits */
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
do_auto_exits(ch);
/*now list characters &objects */
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE);
list_char_to_char(world[IN_ROOM(ch)].people, ch);
}
/*autoexits */
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
do_auto_exits(ch);
/*now list characters &objects */
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE);
list_char_to_char(world[IN_ROOM(ch)].people, ch);
}
static void look_in_direction(struct char_data *ch, int dir)
@@ -566,35 +567,35 @@ static void look_in_obj(struct char_data *ch, char *arg)
if (!*arg)
send_to_char(ch, "Look in what?\r\n");
else if (!(bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM |
FIND_OBJ_EQUIP, ch, &dummy, &obj))) {
FIND_OBJ_EQUIP, ch, &dummy, &obj))) {
send_to_char(ch, "There doesn't seem to be %s %s here.\r\n", AN(arg), arg);
} else if ((GET_OBJ_TYPE(obj) != ITEM_DRINKCON) &&
(GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) &&
(GET_OBJ_TYPE(obj) != ITEM_CONTAINER))
(GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN) &&
(GET_OBJ_TYPE(obj) != ITEM_CONTAINER))
send_to_char(ch, "There's nothing inside that!\r\n");
else {
if (GET_OBJ_TYPE(obj) == ITEM_CONTAINER) {
if (OBJVAL_FLAGGED(obj, CONT_CLOSED) && (GET_LEVEL(ch) < LVL_IMMORT || !PRF_FLAGGED(ch, PRF_NOHASSLE)))
send_to_char(ch, "It is closed.\r\n");
send_to_char(ch, "It is closed.\r\n");
else {
send_to_char(ch, "%s", fname(obj->name));
switch (bits) {
case FIND_OBJ_INV:
send_to_char(ch, " (carried): \r\n");
break;
case FIND_OBJ_ROOM:
send_to_char(ch, " (here): \r\n");
break;
case FIND_OBJ_EQUIP:
send_to_char(ch, " (used): \r\n");
break;
}
send_to_char(ch, "%s", fname(obj->name));
switch (bits) {
case FIND_OBJ_INV:
send_to_char(ch, " (carried): \r\n");
break;
case FIND_OBJ_ROOM:
send_to_char(ch, " (here): \r\n");
break;
case FIND_OBJ_EQUIP:
send_to_char(ch, " (used): \r\n");
break;
}
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
list_obj_to_char(obj->contains, ch, SHOW_OBJ_SHORT, TRUE);
}
} else { /* item must be a fountain or drink container */
} else { /* item must be a fountain or drink container */
if ((GET_OBJ_VAL(obj, 1) == 0) && (GET_OBJ_VAL(obj, 0) != -1))
send_to_char(ch, "It is empty.\r\n");
send_to_char(ch, "It is empty.\r\n");
else {
if (GET_OBJ_VAL(obj, 0) < 0)
{
@@ -602,14 +603,15 @@ static void look_in_obj(struct char_data *ch, char *arg)
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's full of a %s liquid.\r\n", buf2);
}
else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0))
else if (GET_OBJ_VAL(obj,1)>GET_OBJ_VAL(obj,0))
send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */
else {
else
{
char buf2[MAX_STRING_LENGTH];
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2);
}
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
send_to_char(ch, "It's %sfull of a %s liquid.\r\n", fullness[amt], buf2);
}
}
}
}
@@ -646,14 +648,14 @@ static void look_at_target(struct char_data *ch, char *arg)
}
bits = generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_OBJ_EQUIP |
FIND_CHAR_ROOM, ch, &found_char, &found_obj);
FIND_CHAR_ROOM, ch, &found_char, &found_obj);
/* Is the target a character? */
if (found_char != NULL) {
look_at_char(found_char, ch);
if (ch != found_char) {
if (CAN_SEE(found_char, ch))
act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT);
act("$n looks at you.", TRUE, ch, 0, found_char, TO_VICT);
act("$n looks at $N.", TRUE, ch, 0, found_char, TO_NOTVICT);
}
return;
@@ -675,16 +677,16 @@ static void look_at_target(struct char_data *ch, char *arg)
for (j = 0; j < NUM_WEARS && !found; j++)
if (GET_EQ(ch, j) && CAN_SEE_OBJ(ch, GET_EQ(ch, j)))
if ((desc = find_exdesc(arg, GET_EQ(ch, j)->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
send_to_char(ch, "%s", desc);
found = TRUE;
}
/* Does the argument match an extra desc in the char's inventory? */
for (obj = ch->carrying; obj && !found; obj = obj->next_content) {
if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
send_to_char(ch, "%s", desc);
found = TRUE;
}
}
@@ -692,8 +694,8 @@ static void look_at_target(struct char_data *ch, char *arg)
for (obj = world[IN_ROOM(ch)].contents; obj && !found; obj = obj->next_content)
if (CAN_SEE_OBJ(ch, obj))
if ((desc = find_exdesc(arg, obj->ex_description)) != NULL && ++i == fnum) {
send_to_char(ch, "%s", desc);
found = TRUE;
send_to_char(ch, "%s", desc);
found = TRUE;
}
/* If an object was found back in generic_find */
@@ -723,7 +725,7 @@ ACMD(do_look)
send_to_char(ch, "You can't see a damned thing, you're blind!\r\n");
else if (IS_DARK(IN_ROOM(ch)) && !CAN_SEE_IN_DARK(ch)) {
send_to_char(ch, "It is pitch black...\r\n");
list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */
list_char_to_char(world[IN_ROOM(ch)].people, ch); /* glowing red eyes */
} else {
char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
@@ -731,12 +733,12 @@ ACMD(do_look)
if (subcmd == SCMD_READ) {
if (!*arg)
send_to_char(ch, "Read what?\r\n");
send_to_char(ch, "Read what?\r\n");
else
look_at_target(ch, strcpy(tempsave, arg));
look_at_target(ch, strcpy(tempsave, arg));
return;
}
if (!*arg) /* "look" alone, without an argument at all */
if (!*arg) /* "look" alone, without an argument at all */
look_at_room(ch, 1);
else if (is_abbrev(arg, "in"))
look_in_obj(ch, arg2);
@@ -776,15 +778,15 @@ ACMD(do_examine)
}
/* look_at_target() eats the number. */
look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */
look_at_target(ch, strcpy(tempsave, arg)); /* strcpy: OK */
generic_find(arg, FIND_OBJ_INV | FIND_OBJ_ROOM | FIND_CHAR_ROOM |
FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object);
FIND_OBJ_EQUIP, ch, &tmp_char, &tmp_object);
if (tmp_object) {
if ((GET_OBJ_TYPE(tmp_object) == ITEM_DRINKCON) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) {
(GET_OBJ_TYPE(tmp_object) == ITEM_FOUNTAIN) ||
(GET_OBJ_TYPE(tmp_object) == ITEM_CONTAINER)) {
send_to_char(ch, "When you look inside, you see:\r\n");
look_in_obj(ch, arg);
}
@@ -816,18 +818,18 @@ ACMD(do_score)
send_to_char(ch, "\r\n");
send_to_char(ch, "You have %d(%d) hit, %d(%d) mana and %d(%d) movement points.\r\n",
GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch),
GET_MOVE(ch), GET_MAX_MOVE(ch));
GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch),
GET_MOVE(ch), GET_MAX_MOVE(ch));
send_to_char(ch, "Your armor class is %d/10, and your alignment is %d.\r\n",
compute_armor_class(ch), GET_ALIGNMENT(ch));
compute_armor_class(ch), GET_ALIGNMENT(ch));
send_to_char(ch, "You have %d exp, %d gold coins, and %d questpoints.\r\n",
GET_EXP(ch), GET_GOLD(ch), GET_QUESTPOINTS(ch));
GET_EXP(ch), GET_GOLD(ch), GET_QUESTPOINTS(ch));
if (GET_LEVEL(ch) < LVL_IMMORT)
send_to_char(ch, "You need %d exp to reach your next level.\r\n",
level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch));
level_exp(GET_CLASS(ch), GET_LEVEL(ch) + 1) - GET_EXP(ch));
send_to_char(ch, "You have earned %d quest points.\r\n", GET_QUESTPOINTS(ch));
send_to_char(ch, "You have completed %d quest%s, ",
@@ -846,13 +848,13 @@ ACMD(do_score)
}
playing_time = *real_time_passed((time(0) - ch->player.time.logon) +
ch->player.time.played, 0);
ch->player.time.played, 0);
send_to_char(ch, "You have been playing for %d day%s and %d hour%s.\r\n",
playing_time.day, playing_time.day == 1 ? "" : "s",
playing_time.hours, playing_time.hours == 1 ? "" : "s");
send_to_char(ch, "This ranks you as %s %s (level %d).\r\n",
GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch));
GET_NAME(ch), GET_TITLE(ch), GET_LEVEL(ch));
switch (GET_POS(ch)) {
case POS_DEAD:
@@ -983,8 +985,8 @@ ACMD(do_time)
weekday = ((35 * time_info.month) + day) % 7;
send_to_char(ch, "It is %d o'clock %s, on %s.\r\n",
(time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12),
time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]);
(time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12),
time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]);
/* Peter Ajamian supplied the following as a fix for a bug introduced in the
* ordinal display that caused 11, 12, and 13 to be incorrectly displayed as
@@ -1006,7 +1008,7 @@ ACMD(do_time)
}
}
send_to_char(ch, "The %d%s Day of the %s, Year %d.\r\n",
day, suf, month_name[time_info.month], time_info.year);
day, suf, month_name[time_info.month], time_info.year);
}
ACMD(do_weather)
@@ -1021,8 +1023,8 @@ ACMD(do_weather)
if (OUTSIDE(ch))
{
send_to_char(ch, "The sky is %s and %s.\r\n", sky_look[weather_info.sky],
weather_info.change >= 0 ? "you feel a warm wind from south" :
"your foot tells you bad weather is due");
weather_info.change >= 0 ? "you feel a warm wind from south" :
"your foot tells you bad weather is due");
if (GET_LEVEL(ch) >= LVL_GOD)
send_to_char(ch, "Pressure: %d (change: %d), Sky: %d (%s)\r\n",
weather_info.pressure,
@@ -1380,7 +1382,7 @@ ACMD(do_users)
host_search[0] = name_search[0] = '\0';
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
strcpy(buf, argument); /* strcpy: OK (sizeof: argument == buf) */
while (*buf) {
char buf1[MAX_INPUT_LENGTH];
@@ -1390,49 +1392,49 @@ ACMD(do_users)
switch (mode) {
case 'o':
case 'k':
outlaws = 1;
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
outlaws = 1;
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'p':
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
playing = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'd':
deadweight = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
deadweight = 1;
strcpy(buf, buf1); /* strcpy: OK (sizeof: buf1 == buf) */
break;
case 'l':
playing = 1;
half_chop(buf1, arg, buf);
sscanf(arg, "%d-%d", &low, &high);
break;
playing = 1;
half_chop(buf1, arg, buf);
sscanf(arg, "%d-%d", &low, &high);
break;
case 'n':
playing = 1;
half_chop(buf1, name_search, buf);
break;
playing = 1;
half_chop(buf1, name_search, buf);
break;
case 'h':
playing = 1;
half_chop(buf1, host_search, buf);
break;
playing = 1;
half_chop(buf1, host_search, buf);
break;
case 'c':
playing = 1;
half_chop(buf1, arg, buf);
showclass = find_class_bitvector(arg);
break;
playing = 1;
half_chop(buf1, arg, buf);
showclass = find_class_bitvector(arg);
break;
default:
send_to_char(ch, "%s", USERS_FORMAT);
return;
} /* end of switch */
send_to_char(ch, "%s", USERS_FORMAT);
return;
} /* end of switch */
} else { /* endif */
} else { /* endif */
send_to_char(ch, "%s", USERS_FORMAT);
return;
}
} /* end while (parser) */
} /* end while (parser) */
send_to_char(ch,
"Num Class Name State Idl Login\t* Site\r\n"
"--- ------- ------------ -------------- ----- -------- ------------------------\r\n");
"Num Class Name State Idl Login\t* Site\r\n"
"--- ------- ------------ -------------- ----- -------- ------------------------\r\n");
one_argument(argument, arg);
@@ -1454,7 +1456,7 @@ ACMD(do_users)
if (!CAN_SEE(ch, tch) || GET_LEVEL(tch) < low || GET_LEVEL(tch) > high)
continue;
if (outlaws && !PLR_FLAGGED(tch, PLR_KILLER) &&
!PLR_FLAGGED(tch, PLR_THIEF))
!PLR_FLAGGED(tch, PLR_THIEF))
continue;
if (showclass && !(showclass & (1 << GET_CLASS(tch))))
continue;
@@ -1462,11 +1464,11 @@ ACMD(do_users)
continue;
if (d->original)
sprintf(classname, "[%2d %s]", GET_LEVEL(d->original),
CLASS_ABBR(d->original));
sprintf(classname, "[%2d %s]", GET_LEVEL(d->original),
CLASS_ABBR(d->original));
else
sprintf(classname, "[%2d %s]", GET_LEVEL(d->character),
CLASS_ABBR(d->character));
sprintf(classname, "[%2d %s]", GET_LEVEL(d->character),
CLASS_ABBR(d->character));
} else
strcpy(classname, " - ");
@@ -1479,15 +1481,15 @@ ACMD(do_users)
if (d->character && STATE(d) == CON_PLAYING)
sprintf(idletime, "%5d", d->character->char_specials.timer *
SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN);
SECS_PER_MUD_HOUR / SECS_PER_REAL_MIN);
else
strcpy(idletime, " ");
sprintf(line, "%3d %-7s %-12s %-14s %-3s %-8s ", d->desc_num, classname,
d->original && d->original->player.name ? d->original->player.name :
d->character && d->character->player.name ? d->character->player.name :
"UNDEFINED",
state, idletime, timestr);
d->original && d->original->player.name ? d->original->player.name :
d->character && d->character->player.name ? d->character->player.name :
"UNDEFINED",
state, idletime, timestr);
if (*d->host)
sprintf(line + strlen(line), "[%s]\r\n", d->host);
@@ -1577,23 +1579,23 @@ static void perform_mortal_where(struct char_data *ch, char *arg)
send_to_char(ch, "Players in %s\tn.\r\n--------------------\r\n", zone_table[j].name);
for (d = descriptor_list; d; d = d->next) {
if (STATE(d) != CON_PLAYING || d->character == ch)
continue;
continue;
if ((i = (d->original ? d->original : d->character)) == NULL)
continue;
continue;
if (IN_ROOM(i) == NOWHERE || !CAN_SEE(ch, i))
continue;
continue;
if (world[IN_ROOM(ch)].zone != world[IN_ROOM(i)].zone)
continue;
continue;
send_to_char(ch, "%-20s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
}
} else { /* print only FIRST char, not all. */
} else { /* print only FIRST char, not all. */
for (i = character_list; i; i = i->next) {
if (IN_ROOM(i) == NOWHERE || i == ch)
continue;
continue;
if (!CAN_SEE(ch, i) || world[IN_ROOM(i)].zone != world[IN_ROOM(ch)].zone)
continue;
continue;
if (!isname(arg, i->player.name))
continue;
continue;
send_to_char(ch, "%-25s%s - %s%s\r\n", GET_NAME(i), QNRM, world[IN_ROOM(i)].name, QNRM);
return;
}
@@ -1601,41 +1603,71 @@ static void perform_mortal_where(struct char_data *ch, char *arg)
}
}
static void print_object_location(int num, struct obj_data *obj, struct char_data *ch,
int recur)
static size_t print_object_location(const int num, const obj_data *obj, const char_data *ch, // NOLINT(*-no-recursion)
char *buf, size_t len, const size_t buf_size, const int recur)
{
size_t nlen = 0;
if (num > 0)
send_to_char(ch, "O%3d. %-25s%s - ", num, obj->short_description, QNRM);
nlen = snprintf(buf + len, buf_size - len, "O%4d. %-25s%s - ", num, obj->short_description, QNRM);
else
send_to_char(ch, "%33s", " - ");
nlen = snprintf(buf + len, buf_size - len, "%37s", " - ");
len += nlen;
nlen = 0;
if (len > buf_size)
return len; // let the caller know we overflowed
if (SCRIPT(obj)) {
if (!TRIGGERS(SCRIPT(obj))->next)
send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(obj))));
nlen = snprintf(buf + len, buf_size - len, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(obj))));
else
send_to_char(ch, "[TRIGS] ");
nlen = snprintf(buf + len, buf_size - len, "[TRIGS] ");
}
len += nlen;
if (len > buf_size)
return len; // let the caller know we overflowed
if (IN_ROOM(obj) != NOWHERE)
send_to_char(ch, "[%5d] %s%s\r\n", GET_ROOM_VNUM(IN_ROOM(obj)), world[IN_ROOM(obj)].name, QNRM);
else if (obj->carried_by)
send_to_char(ch, "carried by %s%s\r\n", PERS(obj->carried_by, ch), QNRM);
else if (obj->worn_by)
send_to_char(ch, "worn by %s%s\r\n", PERS(obj->worn_by, ch), QNRM);
else if (obj->in_obj) {
send_to_char(ch, "inside %s%s%s\r\n", obj->in_obj->short_description, QNRM, (recur ? ", which is" : " "));
if (recur)
print_object_location(0, obj->in_obj, ch, recur);
nlen = snprintf(buf + len, buf_size - len, "[%5d] %s%s\r\n", GET_ROOM_VNUM(IN_ROOM(obj)), world[IN_ROOM(obj)].name, QNRM);
else if (obj->carried_by) {
if (PRF_FLAGGED(ch, PRF_SHOWVNUMS))
nlen = snprintf(buf + len, buf_size - len, "carried by [%5d] %s%s\r\n", GET_MOB_VNUM(obj->carried_by), PERS(obj->carried_by, ch), QNRM);
else
nlen = snprintf(buf + len, buf_size - len, "carried by %s%s\r\n", PERS(obj->carried_by, ch), QNRM);
if (PRF_FLAGGED(ch, PRF_VERBOSE) && IN_ROOM(obj->carried_by) != NOWHERE && len + nlen < buf_size)
nlen += snprintf(buf + len + nlen, buf_size - len - nlen, "%37sin [%5d] %s%s\r\n", " - ", GET_ROOM_VNUM(IN_ROOM(obj->carried_by)), world[IN_ROOM(obj->carried_by)].name, QNRM);
} else if (obj->worn_by) {
if (PRF_FLAGGED(ch, PRF_SHOWVNUMS))
nlen = snprintf(buf + len, buf_size - len, "worn by [%5d] %s%s\r\n", GET_MOB_VNUM(obj->worn_by), PERS(obj->worn_by, ch), QNRM);
else
nlen = snprintf(buf + len, buf_size - len, "worn by %s%s\r\n", PERS(obj->worn_by, ch), QNRM);
if (PRF_FLAGGED(ch, PRF_VERBOSE) && IN_ROOM(obj->worn_by) != NOWHERE && len + nlen < buf_size)
nlen += snprintf(buf + len + nlen, buf_size - len - nlen, "%37sin [%5d] %s%s\r\n", " - ", GET_ROOM_VNUM(IN_ROOM(obj->worn_by)), world[IN_ROOM(obj->worn_by)].name, QNRM);
} else if (obj->in_obj) {
nlen = snprintf(buf + len, buf_size - len, "inside %s%s%s\r\n", obj->in_obj->short_description, QNRM, (recur ? ", which is" : " "));
if (recur && nlen + len < buf_size) {
len += nlen;
nlen = 0;
len = print_object_location(0, obj->in_obj, ch, buf, len, buf_size, recur);
}
} else
send_to_char(ch, "in an unknown location\r\n");
nlen = snprintf(buf + len, buf_size - len, "in an unknown location\r\n");
len += nlen;
return len;
}
static void perform_immort_where(struct char_data *ch, char *arg)
static void perform_immort_where(char_data *ch, const char *arg)
{
struct char_data *i;
struct obj_data *k;
char_data *i;
obj_data *k;
struct descriptor_data *d;
int num = 0, found = 0;
int num = 0, found = FALSE; // "num" here needs to match the lookup in do_stat, so "stat 4.sword" finds the right one
const char *error_message = "\r\n***OVERFLOW***\r\n";
char buf[MAX_STRING_LENGTH];
size_t len = 0, nlen = 0;
const size_t buf_size = sizeof(buf) - strlen(error_message) - 1;
if (!*arg) {
send_to_char(ch, "Players Room Location Zone\r\n");
@@ -1656,26 +1688,64 @@ static void perform_immort_where(struct char_data *ch, char *arg)
}
}
} else {
if (PRF_FLAGGED(ch, PRF_VERBOSE))
len = snprintf(buf, buf_size, " ### Mob name - Room # Room name\r\n");
for (i = character_list; i; i = i->next)
if (CAN_SEE(ch, i) && IN_ROOM(i) != NOWHERE && isname(arg, i->player.name)) {
found = 1;
send_to_char(ch, "M%3d. %-25s%s - [%5d] %-25s%s", ++num, GET_NAME(i), QNRM,
nlen = snprintf(buf + len, buf_size - len, "M%4d. %-25s%s - [%5d] %-25s%s", ++num, GET_NAME(i), QNRM,
GET_ROOM_VNUM(IN_ROOM(i)), world[IN_ROOM(i)].name, QNRM);
if (len + nlen >= buf_size) {
len += snprintf(buf + len, buf_size - len, "%s", error_message);
break;
}
len += nlen;
if (SCRIPT(i) && TRIGGERS(SCRIPT(i))) {
if (!TRIGGERS(SCRIPT(i))->next)
send_to_char(ch, "[T%d] ", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i))));
nlen = snprintf(buf + len, buf_size - len, "[T%d]", GET_TRIG_VNUM(TRIGGERS(SCRIPT(i))));
else
send_to_char(ch, "[TRIGS] ");
nlen = snprintf(buf + len, buf_size - len, "[TRIGS]");
if (len + nlen >= buf_size) {
snprintf(buf + len, buf_size - len, "%s", error_message);
break;
}
len += nlen;
}
send_to_char(ch, "%s\r\n", QNRM);
nlen = snprintf(buf + len, buf_size - len, "%s\r\n", QNRM);
if (len + nlen >= buf_size) {
snprintf(buf + len, buf_size - len, "%s", error_message);
break;
}
len += nlen;
}
for (num = 0, k = object_list; k; k = k->next)
if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) {
found = 1;
print_object_location(++num, k, ch, TRUE);
if (PRF_FLAGGED(ch, PRF_VERBOSE) && len < buf_size) {
nlen = snprintf(buf + len, buf_size - len, " ### Object name Location\r\n");
if (len + nlen >= buf_size) {
snprintf(buf + len, buf_size - len, "%s", error_message);
}
len += nlen;
}
if (len < buf_size) {
for (k = object_list; k; k = k->next) {
if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) {
found = 1;
len = print_object_location(++num, k, ch, buf, len, buf_size, TRUE);
if (len >= buf_size) {
snprintf(buf + buf_size, sizeof(buf) - buf_size, "%s", error_message);
break;
}
}
}
}
if (!found)
send_to_char(ch, "Couldn't find any such thing.\r\n");
else
page_string(ch->desc, buf, TRUE);
}
}
@@ -1736,7 +1806,7 @@ ACMD(do_levels)
for (i = min_lev; i < max_lev; i++) {
nlen = snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d-%-8d : ", (int)i,
level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1);
level_exp(GET_CLASS(ch), i), level_exp(GET_CLASS(ch), i + 1) - 1);
if (len + nlen >= sizeof(buf))
break;
len += nlen;
@@ -1760,7 +1830,7 @@ ACMD(do_levels)
if (len < sizeof(buf) && max_lev == LVL_IMMORT)
snprintf(buf + len, sizeof(buf) - len, "[%2d] %8d : Immortality\r\n",
LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT));
LVL_IMMORT, level_exp(GET_CLASS(ch), LVL_IMMORT));
page_string(ch->desc, buf, TRUE);
}
@@ -1935,6 +2005,9 @@ ACMD(do_toggle)
{"pagelength", 0, 0, "\n", "\n"},
{"screenwidth", 0, 0, "\n", "\n"},
{"color", 0, 0, "\n", "\n"},
{"verbose", PRF_VERBOSE, LVL_IMMORT,
"You will no longer see verbose output in listings.\n",
"You will now see verbose listings.\n"},
{"\n", 0, -1, "\n", "\n"} /* must be last */
};
@@ -1948,16 +2021,17 @@ ACMD(do_toggle)
if (!GET_WIMP_LEV(ch))
strcpy(buf2, "OFF"); /* strcpy: OK */
else
sprintf(buf2, "%-3.3d", GET_WIMP_LEV(ch)); /* sprintf: OK */
snprintf(buf2, sizeof(buf2), "%-3.3d", GET_WIMP_LEV(ch)); /* thanks to Ironfist for the fix for the buffer overrun here */
if (GET_LEVEL(ch) == LVL_IMPL) {
if (GET_LEVEL(ch) == LVL_IMPL) {
send_to_char(ch,
" SlowNameserver: %-3s "
" "
" Trackthru Doors: %-3s\r\n",
" "
" Trackthru Doors: %-3s\r\n",
ONOFF(CONFIG_NS_IS_SLOW),
ONOFF(CONFIG_TRACK_T_DOORS));
ONOFF(CONFIG_NS_IS_SLOW),
ONOFF(CONFIG_TRACK_T_DOORS));
}
if (GET_LEVEL(ch) >= LVL_IMMORT) {
@@ -1968,7 +2042,8 @@ ACMD(do_toggle)
" NoHassle: %-3s "
" Holylight: %-3s "
" ShowVnums: %-3s\r\n"
" Syslog: %-3s%s ",
" Syslog: %-3s "
" Verbose: %-3s%s ",
ONOFF(PRF_FLAGGED(ch, PRF_BUILDWALK)),
ONOFF(PRF_FLAGGED(ch, PRF_NOWIZ)),
@@ -1977,6 +2052,7 @@ ACMD(do_toggle)
ONOFF(PRF_FLAGGED(ch, PRF_HOLYLIGHT)),
ONOFF(PRF_FLAGGED(ch, PRF_SHOWVNUMS)),
types[(PRF_FLAGGED(ch, PRF_LOG1) ? 1 : 0) + (PRF_FLAGGED(ch, PRF_LOG2) ? 2 : 0)],
ONOFF(PRF_FLAGGED(ch, PRF_VERBOSE)),
GET_LEVEL(ch) == LVL_IMPL ? "" : "\r\n");
}
if (GET_LEVEL(ch) >= LVL_IMPL) {
+82 -59
View File
@@ -777,6 +777,15 @@ void weight_change_object(struct obj_data *obj, int weight)
}
}
#define DRINK_CON_MAX(cont) (GET_OBJ_VAL((cont), 0))
#define DRINK_CON_NOW(cont) (GET_OBJ_VAL((cont), 1))
#define DRINK_CON_TYPE(cont) (GET_OBJ_VAL((cont), 2))
#define DRINK_CON_POISON(cont) (GET_OBJ_VAL((cont), 3))
#define LIMITED_DRINK_CONTAINER(cont) (DRINK_CON_MAX((cont)) >= 0 && DRINK_CON_NOW((cont)) >= 0)
#define EMPTY_DRINK_CONTAINER(cont) (LIMITED_DRINK_CONTAINER((cont)) && DRINK_CON_NOW((cont)) < 1)
void name_from_drinkcon(struct obj_data *obj)
{
const char *liqname;
@@ -785,13 +794,15 @@ void name_from_drinkcon(struct obj_data *obj)
if (!obj || (GET_OBJ_TYPE(obj) != ITEM_DRINKCON && GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN))
return;
liqname = drinknames[GET_OBJ_VAL(obj, 2)];
if (obj->name == obj_proto[GET_OBJ_RNUM(obj)].name)
obj->name = strdup(obj_proto[GET_OBJ_RNUM(obj)].name);
liqname = drinknames[DRINK_CON_TYPE(obj)];
remove_from_string(obj->name, liqname);
new_name = right_trim_whitespace(obj->name);
free(obj->name);
obj->name = new_name;
}
void name_to_drinkcon(struct obj_data *obj, int type)
@@ -810,6 +821,7 @@ void name_to_drinkcon(struct obj_data *obj, int type)
obj->name = new_name;
}
ACMD(do_drink)
{
char arg[MAX_INPUT_LENGTH];
@@ -870,7 +882,7 @@ ACMD(do_drink)
send_to_char(ch, "Your stomach can't contain anymore!\r\n");
return;
}
if (GET_OBJ_VAL(temp, 1) < 1) {
if (EMPTY_DRINK_CONTAINER(temp)) {
send_to_char(ch, "It is empty.\r\n");
return;
}
@@ -881,33 +893,38 @@ ACMD(do_drink)
if (subcmd == SCMD_DRINK) {
char buf[MAX_STRING_LENGTH];
snprintf(buf, sizeof(buf), "$n drinks %s from $p.", drinks[GET_OBJ_VAL(temp, 2)]);
snprintf(buf, sizeof(buf), "$n drinks %s from $p.", drinks[DRINK_CON_TYPE(temp)]);
act(buf, TRUE, ch, temp, 0, TO_ROOM);
send_to_char(ch, "You drink the %s.\r\n", drinks[GET_OBJ_VAL(temp, 2)]);
send_to_char(ch, "You drink the %s.\r\n", drinks[DRINK_CON_TYPE(temp)]);
if (drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK] > 0)
amount = (25 - GET_COND(ch, THIRST)) / drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK];
if (drink_aff[DRINK_CON_TYPE(temp)][DRUNK] > 0)
amount = (25 - GET_COND(ch, THIRST)) / drink_aff[DRINK_CON_TYPE(temp)][DRUNK];
else
amount = rand_number(3, 10);
} else {
act("$n sips from $p.", TRUE, ch, temp, 0, TO_ROOM);
send_to_char(ch, "It tastes like %s.\r\n", drinks[GET_OBJ_VAL(temp, 2)]);
send_to_char(ch, "It tastes like %s.\r\n", drinks[DRINK_CON_TYPE(temp)]);
amount = 1;
}
amount = MIN(amount, GET_OBJ_VAL(temp, 1));
/* For limited drink containers with remaining contents, don't drink more
* than the amount currently in the container. Unlimited containers are
* handled separately and are not clamped here.
*/
if (LIMITED_DRINK_CONTAINER(temp))
amount = MIN(amount, DRINK_CON_NOW(temp));
/* You can't subtract more than the object weighs, unless its unlimited. */
if (GET_OBJ_VAL(temp, 0) > 0) {
if (LIMITED_DRINK_CONTAINER(temp)) {
weight = MIN(amount, GET_OBJ_WEIGHT(temp));
weight_change_object(temp, -weight); /* Subtract amount */
}
gain_condition(ch, DRUNK, drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK] * amount / 4);
gain_condition(ch, HUNGER, drink_aff[GET_OBJ_VAL(temp, 2)][HUNGER] * amount / 4);
gain_condition(ch, THIRST, drink_aff[GET_OBJ_VAL(temp, 2)][THIRST] * amount / 4);
gain_condition(ch, DRUNK, drink_aff[DRINK_CON_TYPE(temp)][DRUNK] * amount / 4);
gain_condition(ch, HUNGER, drink_aff[DRINK_CON_TYPE(temp)][HUNGER] * amount / 4);
gain_condition(ch, THIRST, drink_aff[DRINK_CON_TYPE(temp)][THIRST] * amount / 4);
if (GET_COND(ch, DRUNK) > 10)
send_to_char(ch, "You feel drunk.\r\n");
@@ -918,7 +935,7 @@ ACMD(do_drink)
if (GET_COND(ch, HUNGER) > 20)
send_to_char(ch, "You are full.\r\n");
if (GET_OBJ_VAL(temp, 3) && GET_LEVEL(ch) < LVL_IMMORT) { /* The crap was poisoned ! */
if (DRINK_CON_POISON(temp) && GET_LEVEL(ch) < LVL_IMMORT) { /* The crap was poisoned ! */
send_to_char(ch, "Oops, it tasted rather strange!\r\n");
act("$n chokes and utters some strange sounds.", TRUE, ch, 0, 0, TO_ROOM);
@@ -929,12 +946,13 @@ ACMD(do_drink)
affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE);
}
/* Empty the container (unless unlimited), and no longer poison. */
if (GET_OBJ_VAL(temp, 0) > 0) {
GET_OBJ_VAL(temp, 1) -= amount;
if (!GET_OBJ_VAL(temp, 1)) { /* The last bit */
if (LIMITED_DRINK_CONTAINER(temp)) {
amount = MIN(amount, DRINK_CON_NOW(temp)); // never subtract more than the current amount
DRINK_CON_NOW(temp) -= amount;
if (!DRINK_CON_NOW(temp)) { /* The last bit */
name_from_drinkcon(temp);
GET_OBJ_VAL(temp, 2) = 0;
GET_OBJ_VAL(temp, 3) = 0;
DRINK_CON_TYPE(temp) = 0;
DRINK_CON_POISON(temp) = 0;
}
}
return;
@@ -1061,7 +1079,7 @@ ACMD(do_pour)
return;
}
}
if (GET_OBJ_VAL(from_obj, 1) == 0) {
if (EMPTY_DRINK_CONTAINER(from_obj)) {
act("The $p is empty.", FALSE, ch, from_obj, 0, TO_CHAR);
return;
}
@@ -1071,19 +1089,22 @@ ACMD(do_pour)
return;
}
if (!str_cmp(arg2, "out")) {
if (GET_OBJ_VAL(from_obj, 0) > 0) {
act("$n empties $p.", TRUE, ch, from_obj, 0, TO_ROOM);
act("You empty $p.", FALSE, ch, from_obj, 0, TO_CHAR);
weight_change_object(from_obj, -GET_OBJ_VAL(from_obj, 1)); /* Empty */
name_from_drinkcon(from_obj);
GET_OBJ_VAL(from_obj, 1) = 0;
GET_OBJ_VAL(from_obj, 2) = 0;
GET_OBJ_VAL(from_obj, 3) = 0;
if (!LIMITED_DRINK_CONTAINER(from_obj)) {
send_to_char(ch, "You can't pour that out! There's simply too much in it.\r\n");
return;
}
else
send_to_char(ch, "You can't possibly pour that container out!\r\n");
/* pour out */
act("$n empties $p.", TRUE, ch, from_obj, 0, TO_ROOM);
act("You empty $p.", FALSE, ch, from_obj, 0, TO_CHAR);
weight_change_object(from_obj, -DRINK_CON_NOW(from_obj)); /* Empty */
name_from_drinkcon(from_obj);
DRINK_CON_NOW(from_obj) = 0;
DRINK_CON_TYPE(from_obj) = 0;
DRINK_CON_POISON(from_obj) = 0;
return;
}
@@ -1091,8 +1112,7 @@ ACMD(do_pour)
send_to_char(ch, "You can't find it!\r\n");
return;
}
if ((GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) &&
(GET_OBJ_TYPE(to_obj) != ITEM_FOUNTAIN)) {
if ((GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) && (GET_OBJ_TYPE(to_obj) != ITEM_FOUNTAIN)) {
send_to_char(ch, "You can't pour anything into that.\r\n");
return;
}
@@ -1101,59 +1121,62 @@ ACMD(do_pour)
send_to_char(ch, "A most unproductive effort.\r\n");
return;
}
if ((GET_OBJ_VAL(to_obj, 0) < 0) ||
(!(GET_OBJ_VAL(to_obj, 1) < GET_OBJ_VAL(to_obj, 0)))) {
if (!EMPTY_DRINK_CONTAINER(to_obj) && DRINK_CON_TYPE(to_obj) != DRINK_CON_TYPE(from_obj)) {
send_to_char(ch, "There is already another liquid in it!\r\n");
return;
}
if (!(GET_OBJ_VAL(to_obj, 1) < GET_OBJ_VAL(to_obj, 0))) {
// Not allowed to fill an unlimited container, or a container that is already full.
if (!LIMITED_DRINK_CONTAINER(to_obj) || DRINK_CON_NOW(to_obj) >= DRINK_CON_MAX(to_obj)) {
send_to_char(ch, "There is no room for more.\r\n");
return;
}
if (subcmd == SCMD_POUR)
send_to_char(ch, "You pour the %s into the %s.", drinks[GET_OBJ_VAL(from_obj, 2)], arg2);
send_to_char(ch, "You pour the %s into the %s.\r\n", drinks[DRINK_CON_TYPE(from_obj)], arg2);
if (subcmd == SCMD_FILL) {
act("You gently fill $p from $P.", FALSE, ch, to_obj, from_obj, TO_CHAR);
act("$n gently fills $p from $P.", TRUE, ch, to_obj, from_obj, TO_ROOM);
}
/* New alias */
if (GET_OBJ_VAL(to_obj, 1) == 0)
name_to_drinkcon(to_obj, GET_OBJ_VAL(from_obj, 2));
if (EMPTY_DRINK_CONTAINER(to_obj))
name_to_drinkcon(to_obj, DRINK_CON_TYPE(from_obj));
/* First same type liq. */
GET_OBJ_VAL(to_obj, 2) = GET_OBJ_VAL(from_obj, 2);
DRINK_CON_TYPE(to_obj) = DRINK_CON_TYPE(from_obj);
/* Then how much to pour */
if (GET_OBJ_VAL(from_obj, 0) > 0) {
GET_OBJ_VAL(from_obj, 1) -= (amount =
(GET_OBJ_VAL(to_obj, 0) - GET_OBJ_VAL(to_obj, 1)));
if (LIMITED_DRINK_CONTAINER(from_obj)) {
amount = MIN(DRINK_CON_NOW(from_obj), DRINK_CON_MAX(to_obj) - DRINK_CON_NOW(to_obj));
DRINK_CON_NOW(from_obj) -= amount;
DRINK_CON_NOW(to_obj) += amount;
GET_OBJ_VAL(to_obj, 1) = GET_OBJ_VAL(to_obj, 0);
if (GET_OBJ_VAL(from_obj, 1) < 0) { /* There was too little */
GET_OBJ_VAL(to_obj, 1) += GET_OBJ_VAL(from_obj, 1);
amount += GET_OBJ_VAL(from_obj, 1);
if (DRINK_CON_NOW(from_obj) == 0) { /* It was emptied */
name_from_drinkcon(from_obj);
GET_OBJ_VAL(from_obj, 1) = 0;
GET_OBJ_VAL(from_obj, 2) = 0;
GET_OBJ_VAL(from_obj, 3) = 0;
DRINK_CON_NOW(from_obj) = 0;
DRINK_CON_TYPE(from_obj) = 0;
DRINK_CON_POISON(from_obj) = 0;
}
}
else {
GET_OBJ_VAL(to_obj, 1) = GET_OBJ_VAL(to_obj, 0);
amount = GET_OBJ_VAL(to_obj, 0);
} else {
amount = DRINK_CON_MAX(to_obj) - DRINK_CON_NOW(to_obj);
DRINK_CON_NOW(to_obj) = DRINK_CON_MAX(to_obj);
}
/* Poisoned? */
GET_OBJ_VAL(to_obj, 3) = (GET_OBJ_VAL(to_obj, 3) || GET_OBJ_VAL(from_obj, 3))
;
DRINK_CON_POISON(to_obj) = (DRINK_CON_POISON(to_obj) || DRINK_CON_POISON(from_obj));
/* Weight change, except for unlimited. */
if (GET_OBJ_VAL(from_obj, 0) > 0) {
if (LIMITED_DRINK_CONTAINER(from_obj)) {
weight_change_object(from_obj, -amount);
}
weight_change_object(to_obj, amount); /* Add weight */
}
#undef DRINK_CON_MAX
#undef DRINK_CON_NOW
#undef DRINK_CON_TYPE
#undef DRINK_CON_POISON
#undef LIMITED_DRINK_CONTAINER
#undef EMPTY_DRINK_CONTAINER
static void wear_message(struct char_data *ch, struct obj_data *obj, int where)
{
const char *wear_messages[][2] = {
+5 -3
View File
@@ -54,7 +54,7 @@ ACMD(do_assist)
else if (!CAN_SEE(ch, opponent))
act("You can't see who is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR);
/* prevent accidental pkill */
else if (!CONFIG_PK_ALLOWED && !IS_NPC(opponent))
else if (!pk_allowed(ch, opponent))
send_to_char(ch, "You cannot kill other players.\r\n");
else {
send_to_char(ch, "You join the fight!\r\n");
@@ -82,8 +82,10 @@ ACMD(do_hit)
} else if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master == vict))
act("$N is just such a good friend, you simply can't hit $M.", FALSE, ch, 0, vict, TO_CHAR);
else {
if (!CONFIG_PK_ALLOWED && !IS_NPC(vict) && !IS_NPC(ch))
check_killer(ch, vict);
if (!pk_allowed(ch, vict)) {
send_to_char(ch, "Player killing is not allowed.\r\n");
return;
}
if ((GET_POS(ch) == POS_STANDING) && (vict != FIGHTING(ch))) {
if (GET_DEX(ch) > GET_DEX(vict) || (GET_DEX(ch) == GET_DEX(vict) && rand_number(1, 2) == 1)) /* if faster */
+21 -4
View File
@@ -154,6 +154,7 @@ ACMD(do_steal)
send_to_char(ch, "You have no idea how to do that.\r\n");
return;
}
if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n");
return;
@@ -169,20 +170,26 @@ ACMD(do_steal)
return;
}
/* Check if player stealing is allowed */
if (!IS_NPC(vict)) {
if (CONFIG_PT_SETTING == CONFIG_PT_OFF) {
send_to_char(ch, "Stealing from players is not allowed.\r\n");
return;
}
pcsteal = (CONFIG_PT_SETTING == CONFIG_PT_LIMITED);
}
/* 101% is a complete failure */
percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket;
if (GET_POS(vict) < POS_SLEEPING)
percent = -1; /* ALWAYS SUCCESS, unless heavy object. */
if (!CONFIG_PT_ALLOWED && !IS_NPC(vict))
pcsteal = 1;
if (!AWAKE(vict)) /* Easier to steal from sleeping people. */
percent -= 50;
/* No stealing if not allowed. If it is no stealing from Imm's or Shopkeepers. */
if (GET_LEVEL(vict) >= LVL_IMMORT || pcsteal || GET_MOB_SPEC(vict) == shop_keeper)
if (GET_LEVEL(vict) >= LVL_IMMORT || GET_MOB_SPEC(vict) == shop_keeper)
percent = 101; /* Failure */
if (str_cmp(obj_name, "coins") && str_cmp(obj_name, "gold")) {
@@ -221,6 +228,12 @@ ACMD(do_steal)
if (percent > GET_SKILL(ch, SKILL_STEAL)) {
ohoh = TRUE;
send_to_char(ch, "Oops..\r\n");
/* Player got caught and stealing is limited via cedit */
if ( (pcsteal) && (!PLR_FLAGGED(ch, PLR_THIEF))) {
SET_BIT_AR(PLR_FLAGS(ch), PLR_THIEF);
}
act("$n tried to steal something from you!", FALSE, ch, 0, vict, TO_VICT);
act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
} else { /* Steal the item */
@@ -242,6 +255,10 @@ ACMD(do_steal)
} else { /* Steal some coins */
if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) {
ohoh = TRUE;
/* Player got caught and stealing is limited via cedit */
if ( (pcsteal) && (!PLR_FLAGGED(ch, PLR_THIEF))) {
SET_BIT_AR(PLR_FLAGS(ch), PLR_THIEF);
}
send_to_char(ch, "Oops..\r\n");
act("You discover that $n has $s hands in your wallet.", FALSE, ch, 0, vict, TO_VICT);
act("$n tries to steal gold from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
+1 -1
View File
@@ -56,7 +56,7 @@ ACMD(do_action)
if (!action->char_found)
*arg = '\0';
if (action->char_found && argument)
if (action->char_found)
one_argument(argument, arg);
else
*arg = '\0';
+4 -1
View File
@@ -2396,7 +2396,10 @@ ACMD(do_wizutil)
act("A sudden fireball conjured from nowhere thaws $n!", FALSE, vict, 0, 0, TO_ROOM);
break;
case SCMD_UNAFFECT:
if (vict->affected || AFF_FLAGS(vict)) {
for (taeller = 0; taeller < AF_ARRAY_MAX; taeller++)
if (AFF_FLAGS(vict)[taeller])
break;
if (vict->affected || taeller < AF_ARRAY_MAX) {
while (vict->affected)
affect_remove(vict, vict->affected);
for(taeller=0; taeller < AF_ARRAY_MAX; taeller++)
+4 -4
View File
@@ -557,7 +557,7 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
}
if (OLC_ACTION(d)->command)
free(OLC_ACTION(d)->command);
OLC_ACTION(d)->command = strdup(arg);
OLC_ACTION(d)->command = strdup(arg);
break;
@@ -566,10 +566,10 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
aedit_disp_menu(d);
return;
}
if (OLC_ACTION(d)->sort_as) {
if (OLC_ACTION(d)->sort_as)
free(OLC_ACTION(d)->sort_as);
OLC_ACTION(d)->sort_as = strdup(arg);
}
OLC_ACTION(d)->sort_as = strdup(arg);
break;
case AEDIT_MIN_CHAR_POS:
+3 -3
View File
@@ -374,9 +374,9 @@ SPECIAL(king_welmar)
"$n proclaims 'principe dignos'."
};
const char bedroom_path[] = "s33004o1c1S.";
const char throne_path[] = "W3o3cG52211rg.";
const char monolog_path[] = "ABCDPPPP.";
static const char bedroom_path[] = "s33004o1c1S.";
static const char throne_path[] = "W3o3cG52211rg.";
static const char monolog_path[] = "ABCDPPPP.";
static const char *path;
static int path_index;
+47 -13
View File
@@ -79,8 +79,8 @@ static void cedit_setup(struct descriptor_data *d)
/* Copy the current configuration from the config_info to this one and copy
* the game play options from the configuration info struct. */
OLC_CONFIG(d)->play.pk_allowed = CONFIG_PK_ALLOWED;
OLC_CONFIG(d)->play.pt_allowed = CONFIG_PT_ALLOWED;
OLC_CONFIG(d)->play.pk_setting = CONFIG_PK_SETTING;
OLC_CONFIG(d)->play.pt_setting = CONFIG_PT_SETTING;
OLC_CONFIG(d)->play.level_can_shout = CONFIG_LEVEL_CAN_SHOUT;
OLC_CONFIG(d)->play.holler_move_cost = CONFIG_HOLLER_MOVE_COST;
OLC_CONFIG(d)->play.tunnel_size = CONFIG_TUNNEL_SIZE;
@@ -183,8 +183,8 @@ static void cedit_save_internally(struct descriptor_data *d)
/* see if we need to reassign spec procs on rooms */
int reassign = (CONFIG_DTS_ARE_DUMPS != OLC_CONFIG(d)->play.dts_are_dumps);
/* Copy the data back from the descriptor to the config_info structure. */
CONFIG_PK_ALLOWED = OLC_CONFIG(d)->play.pk_allowed;
CONFIG_PT_ALLOWED = OLC_CONFIG(d)->play.pt_allowed;
CONFIG_PK_SETTING = OLC_CONFIG(d)->play.pk_setting;
CONFIG_PT_SETTING = OLC_CONFIG(d)->play.pt_setting;
CONFIG_LEVEL_CAN_SHOUT = OLC_CONFIG(d)->play.level_can_shout;
CONFIG_HOLLER_MOVE_COST = OLC_CONFIG(d)->play.holler_move_cost;
CONFIG_TUNNEL_SIZE = OLC_CONFIG(d)->play.tunnel_size;
@@ -339,9 +339,9 @@ int save_config( IDXTYPE nowhere )
);
fprintf(fl, "* Is player killing allowed on the mud?\n"
"pk_allowed = %d\n\n", CONFIG_PK_ALLOWED);
"pk_setting = %d\n\n", CONFIG_PK_SETTING);
fprintf(fl, "* Is player thieving allowed on the mud?\n"
"pt_allowed = %d\n\n", CONFIG_PT_ALLOWED);
"pt_setting = %d\n\n", CONFIG_PT_SETTING);
fprintf(fl, "* What is the minimum level a player can shout/gossip/etc?\n"
"level_can_shout = %d\n\n", CONFIG_LEVEL_CAN_SHOUT);
fprintf(fl, "* How many movement points does shouting cost the player?\n"
@@ -608,8 +608,10 @@ static void cedit_disp_menu(struct descriptor_data *d)
static void cedit_disp_game_play_options(struct descriptor_data *d)
{
int m_opt;
int m_opt, pk_setting, pt_setting;
m_opt = OLC_CONFIG(d)->play.map_option;
pk_setting = OLC_CONFIG(d)->play.pk_setting;
pt_setting = OLC_CONFIG(d)->play.pt_setting;
get_char_colors(d->character);
clear_screen(d);
@@ -644,8 +646,8 @@ static void cedit_disp_game_play_options(struct descriptor_data *d)
"%s8%s) Scripts on PC's : %s%s\r\n"
"%sQ%s) Exit To The Main Menu\r\n"
"Enter your choice : ",
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pk_allowed),
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pt_allowed),
grn, nrm, cyn, pk_setting == 0 ? "Off" : (pk_setting == 1 ? "Limited" : (pk_setting == 2 ? "Free-for-all" : "Invalid!")),
grn, nrm, cyn, pt_setting == 0 ? "Off" : (pt_setting == 1 ? "Limited" : (pt_setting == 2 ? "Free-for-all" : "Invalid!")),
grn, nrm, cyn, OLC_CONFIG(d)->play.level_can_shout,
grn, nrm, cyn, OLC_CONFIG(d)->play.holler_move_cost,
grn, nrm, cyn, OLC_CONFIG(d)->play.tunnel_size,
@@ -883,13 +885,21 @@ void cedit_parse(struct descriptor_data *d, char *arg)
switch (*arg) {
case 'a':
case 'A':
TOGGLE_VAR(OLC_CONFIG(d)->play.pk_allowed);
break;
write_to_output(d, "1) No Player Killing\r\n");
write_to_output(d, "2) Limited Player Killing\r\n");
write_to_output(d, "3) Free-for-all!\r\n");
write_to_output(d, "Enter choice: ");
OLC_MODE(d) = CEDIT_PK_SETTING;
return;
case 'b':
case 'B':
TOGGLE_VAR(OLC_CONFIG(d)->play.pt_allowed);
break;
write_to_output(d, "1) No Player Thieving\r\n");
write_to_output(d, "2) Limited Player Thieving\r\n");
write_to_output(d, "3) Free-for-all!\r\n");
write_to_output(d, "Enter choice: ");
OLC_MODE(d) = CEDIT_PT_SETTING;
return;
case 'c':
case 'C':
@@ -1708,6 +1718,30 @@ void cedit_parse(struct descriptor_data *d, char *arg)
}
break;
case CEDIT_PK_SETTING:
if (!*arg || (atoi(arg) < 0) || (atoi(arg) > 3) ) {
write_to_output(d,
"That is an invalid choice!\r\n"
"Select 1, 2 or 3 (0 to cancel) :");
} else {
if ((atoi(arg) >= 1) && (atoi(arg) <= 3))
OLC_CONFIG(d)->play.pk_setting = (atoi(arg) - 1);
cedit_disp_game_play_options(d);
}
break;
case CEDIT_PT_SETTING:
if (!*arg || (atoi(arg) < 0) || (atoi(arg) > 3) ) {
write_to_output(d,
"That is an invalid choice!\r\n"
"Select 1, 2 or 3 (0 to cancel) :");
} else {
if ((atoi(arg) >= 1) && (atoi(arg) <= 3))
OLC_CONFIG(d)->play.pt_setting = (atoi(arg) - 1);
cedit_disp_game_play_options(d);
}
break;
default: /* We should never get here, but just in case... */
cleanup_olc(d, CLEANUP_CONFIG);
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: cedit_parse(): Reached default case!");
+7 -65
View File
@@ -104,8 +104,7 @@ unsigned long pulse = 0; /* number of pulses since game start */
ush_int port;
socket_t mother_desc;
int next_tick = SECS_PER_MUD_HOUR; /* Tick countdown */
/* used with do_tell and handle_webster_file utility */
long last_webster_teller = -1L;
/* static local global variable declarations (current file scope only) */
static struct txt_block *bufpool = 0; /* pool of large output buffers */
@@ -113,14 +112,11 @@ static int max_players = 0; /* max descriptors available */
static int tics_passed = 0; /* for extern checkpointing */
static struct timeval null_time; /* zero-valued time structure */
static byte reread_wizlist; /* signal: SIGUSR1 */
/* normally signal SIGUSR2, currently orphaned in favor of Webster dictionary
* lookup
static byte emergency_unban;
*/
static byte emergency_unban; /* signal: SIGUSR2 */
static int dg_act_check; /* toggle for act_trigger */
static bool fCopyOver; /* Are we booting in copyover mode? */
static char *last_act_message = NULL;
static byte webster_file_ready = FALSE;/* signal: SIGUSR2 */
/* static local function prototypes (current file scope only) */
static RETSIGTYPE reread_wizlists(int sig);
@@ -160,9 +156,6 @@ static int open_logfile(const char *filename, FILE *stderr_fp);
#if defined(POSIX)
static sigfunc *my_signal(int signo, sigfunc *func);
#endif
/* Webster Dictionary Lookup functions */
static RETSIGTYPE websterlink(int sig);
static void handle_webster_file(void);
static void msdp_update(void); /* KaVir plugin*/
@@ -958,7 +951,7 @@ void game_loop(socket_t local_mother_desc)
mudlog(CMP, LVL_IMMORT, TRUE, "Signal received - rereading wizlists.");
reboot_wizlists();
}
/* Orphaned right now as signal trapping is used for Webster lookup
if (emergency_unban) {
emergency_unban = FALSE;
mudlog(BRF, LVL_IMMORT, TRUE, "Received SIGUSR2 - completely unrestricting game (emergent)");
@@ -966,11 +959,7 @@ void game_loop(socket_t local_mother_desc)
circle_restrict = 0;
num_invalid = 0;
}
*/
if (webster_file_ready) {
webster_file_ready = FALSE;
handle_webster_file();
}
#ifdef CIRCLE_UNIX
/* Update tics_passed for deadlock protection (UNIX only) */
@@ -1596,7 +1585,7 @@ static int process_output(struct descriptor_data *t)
result = write_to_descriptor(t->descriptor, osb);
if (result < 0) { /* Oops, fatal error. Bye! */
close_socket(t);
// close_socket(t); // close_socket is called after return of negative result
return (-1);
} else if (result == 0) /* Socket buffer full. Try later. */
return (0);
@@ -2232,18 +2221,10 @@ static RETSIGTYPE reread_wizlists(int sig)
reread_wizlist = TRUE;
}
/* Orphaned right now in place of Webster ...
static RETSIGTYPE unrestrict_game(int sig)
{
emergency_unban = TRUE;
}
*/
static RETSIGTYPE websterlink(int sig)
{
webster_file_ready = TRUE;
}
#ifdef CIRCLE_UNIX
@@ -2318,7 +2299,7 @@ static void signal_setup(void)
/* user signal 2: unrestrict game. Used for emergencies if you lock
* yourself out of the MUD somehow. */
my_signal(SIGUSR2, websterlink);
my_signal(SIGUSR2, unrestrict_game);
/* set up the deadlock-protection so that the MUD aborts itself if it gets
* caught in an infinite loop for more than 3 minutes. */
@@ -2780,45 +2761,6 @@ static void circle_sleep(struct timeval *timeout)
#endif /* CIRCLE_WINDOWS */
static void handle_webster_file(void) {
FILE *fl;
struct char_data *ch = find_char(last_webster_teller);
char retval[MAX_STRING_LENGTH], line[READ_SIZE];
size_t len = 0, nlen = 0;
last_webster_teller = -1L;
if (!ch) /* they quit ? */
return;
fl = fopen("websterinfo", "r");
if (!fl) {
send_to_char(ch, "It seems the dictionary is offline..\r\n");
return;
}
unlink("websterinfo");
get_line(fl, line);
while (!feof(fl)) {
nlen = snprintf(retval + len, sizeof(retval) - len, "%s\r\n", line);
if (len + nlen >= sizeof(retval))
break;
len += nlen;
get_line(fl, line);
}
if (len >= sizeof(retval)) {
const char *overflow = "\r\n**OVERFLOW**\r\n";
strcpy(retval + sizeof(retval) - strlen(overflow) - 1, overflow); /* strcpy: OK */
}
fclose(fl);
send_to_char(ch, "You get this feedback from Merriam-Webster:\r\n");
page_string(ch->desc, retval, 1);
}
/* KaVir's plugin*/
static void msdp_update( void )
{
-3
View File
@@ -60,9 +60,6 @@ void game_loop(socket_t mother_desc);
void heartbeat(int heart_pulse);
void copyover_recover(void);
/** webster dictionary lookup */
extern long last_webster_teller;
extern struct descriptor_data *descriptor_list;
extern int buf_largecount;
extern int buf_overflows;
+337
View File
@@ -0,0 +1,337 @@
/* src/conf.h.cmake.in. Used as basis for conf.h when building with cmake */
#ifndef _CONF_H_
#define _CONF_H_
/* Define to empty if the keyword does not work. */
#define const @CONST_KEYWORD@
/* Define if you don't have vprintf but do have _doprnt. */
#cmakedefine HAVE_DOPRNT
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#cmakedefine HAVE_SYS_WAIT_H
/* Define if you have the vprintf function. */
#cmakedefine HAVE_VPRINTF
/* Define to `int' if <sys/types.h> doesn't define. */
#cmakedefine pid_t @pid_t@
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE @RETSIGTYPE@
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#cmakedefine size_t @size_t@
/* Define if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine TIME_WITH_SYS_TIME
/* Define if we're compiling CircleMUD under any type of UNIX system. */
#cmakedefine CIRCLE_UNIX
/* Define if the system is capable of using crypt() to encrypt. */
#cmakedefine CIRCLE_CRYPT
/* Define if we don't have proper support for the system's crypt(). */
#cmakedefine HAVE_UNSAFE_CRYPT
/* Define is the system has struct in_addr. */
#cmakedefine HAVE_STRUCT_IN_ADDR
/* Define to `int' if <sys/socket.h> doesn't define. */
#cmakedefine socklen_t @socklen_t@
/* Define to `int' if <sys/types.h> doesn't define. */
#cmakedefine ssize_t @ssize_t@
/* Define if you have the gettimeofday function. */
#cmakedefine HAVE_GETTIMEOFDAY
/* Define if you have the inet_addr function. */
#cmakedefine HAVE_INET_ADDR
/* Define if you have the inet_aton function. */
#cmakedefine HAVE_INET_ATON
/* Define if you have the select function. */
#cmakedefine HAVE_SELECT
/* Define if you have the snprintf function. */
#cmakedefine HAVE_SNPRINTF
/* Define if you have the strcasecmp function. */
#cmakedefine HAVE_STRCASECMP
/* Define if you have the strdup function. */
#cmakedefine HAVE_STRDUP
/* Define if you have the strerror function. */
#cmakedefine HAVE_STRERROR
/* Define if you have the stricmp function. */
#cmakedefine HAVE_STRICMP
/* Define if you have the strlcpy function. */
#cmakedefine HAVE_STRLCPY
/* Define if you have the strncasecmp function. */
#cmakedefine HAVE_STRNCASECMP
/* Define if you have the strnicmp function. */
#cmakedefine HAVE_STRNICMP
/* Define if you have the strstr function. */
#cmakedefine HAVE_STRSTR
/* Define if you have the vsnprintf function. */
#cmakedefine HAVE_VSNPRINTF
/* Define if you have the <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H
/* Define if you have the <arpa/telnet.h> header file. */
#cmakedefine HAVE_ARPA_TELNET_H
/* Define if you have the <assert.h> header file. */
#cmakedefine HAVE_ASSERT_H
/* Define if you have the <crypt.h> header file. */
#cmakedefine HAVE_CRYPT_H
/* Define if you have the <errno.h> header file. */
#cmakedefine HAVE_ERRNO_H
/* Define if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H
/* Define if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H
/* Define if you have the <mcheck.h> header file. */
#cmakedefine HAVE_MCHECK_H
/* Define if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H
/* Define if you have the <net/errno.h> header file. */
#cmakedefine HAVE_NET_ERRNO_H
/* Define if you have the <netdb.h> header file. */
#cmakedefine HAVE_NETDB_H
/* Define if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H
/* Define if you have the <signal.h> header file. */
#cmakedefine HAVE_SIGNAL_H
/* Define if you have the <string.h> header file. */
#cmakedefine HAVE_STRING_H
/* Define if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H
/* Define if you have the <sys/fcntl.h> header file. */
#cmakedefine HAVE_SYS_FCNTL_H
/* Define if you have the <sys/resource.h> header file. */
#cmakedefine HAVE_SYS_RESOURCE_H
/* Define if you have the <sys/select.h> header file. */
#cmakedefine HAVE_SYS_SELECT_H
/* Define if you have the <sys/socket.h> header file. */
#cmakedefine HAVE_SYS_SOCKET_H
/* Define if you have the <sys/stat.h> header file. */
#cmakedefine HAVE_SYS_STAT_H
/* Define if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H
/* Define if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H
/* Define if you have the <sys/uio.h> header file. */
#cmakedefine HAVE_SYS_UIO_H
/* Define if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H
/* Define if you have the malloc library (-lmalloc). */
#cmakedefine HAVE_LIBMALLOC
/* Check for a prototype to accept. */
#cmakedefine NEED_ACCEPT_PROTO
/* Check for a prototype to atoi. */
#cmakedefine NEED_ATOI_PROTO
/* Check for a prototype to atol. */
#cmakedefine NEED_ATOL_PROTO
/* Check for a prototype to bind. */
#cmakedefine NEED_BIND_PROTO
/* Check for a prototype to bzero. */
#cmakedefine NEED_BZERO_PROTO
/* Check for a prototype to chdir. */
#cmakedefine NEED_CHDIR_PROTO
/* Check for a prototype to close. */
#cmakedefine NEED_CLOSE_PROTO
/* Check for a prototype to crypt. */
#cmakedefine NEED_CRYPT_PROTO
/* Check for a prototype to fclose. */
#cmakedefine NEED_FCLOSE_PROTO
/* Check for a prototype to fcntl. */
#cmakedefine NEED_FCNTL_PROTO
/* Check for a prototype to fflush. */
#cmakedefine NEED_FFLUSH_PROTO
/* Check for a prototype to fprintf. */
#cmakedefine NEED_FPRINTF_PROTO
/* Check for a prototype to fputc. */
#cmakedefine NEED_FPUTC_PROTO
/* Check for a prototype to fputs. */
#cmakedefine NEED_FPUTS_PROTO
/* Check for a prototype to fread. */
#cmakedefine NEED_FREAD_PROTO
/* Check for a prototype to fscanf. */
#cmakedefine NEED_FSCANF_PROTO
/* Check for a prototype to fseek. */
#cmakedefine NEED_FSEEK_PROTO
/* Check for a prototype to fwrite. */
#cmakedefine NEED_FWRITE_PROTO
/* Check for a prototype to getpeername. */
#cmakedefine NEED_GETPEERNAME_PROTO
/* Check for a prototype to getpid. */
#cmakedefine NEED_GETPID_PROTO
/* Check for a prototype to getrlimit. */
#cmakedefine NEED_GETRLIMIT_PROTO
/* Check for a prototype to getsockname. */
#cmakedefine NEED_GETSOCKNAME_PROTO
/* Check for a prototype to gettimeofday. */
#cmakedefine NEED_GETTIMEOFDAY_PROTO
/* Check for a prototype to htonl. */
#cmakedefine NEED_HTONL_PROTO
/* Check for a prototype to htons. */
#cmakedefine NEED_HTONS_PROTO
/* Check for a prototype to inet_addr. */
#cmakedefine NEED_INET_ADDR_PROTO
/* Check for a prototype to inet_aton. */
#cmakedefine NEED_INET_ATON_PROTO
/* Check for a prototype to inet_ntoa. */
#cmakedefine NEED_INET_NTOA_PROTO
/* Check for a prototype to listen. */
#cmakedefine NEED_LISTEN_PROTO
/* Check for a prototype to ntohl. */
#cmakedefine NEED_NTOHL_PROTO
/* Check for a prototype to perror. */
#cmakedefine NEED_PERROR_PROTO
/* Check for a prototype to printf. */
#cmakedefine NEED_PRINTF_PROTO
/* Check for a prototype to qsort. */
#cmakedefine NEED_QSORT_PROTO
/* Check for a prototype to read. */
#cmakedefine NEED_READ_PROTO
/* Check for a prototype to remove. */
#cmakedefine NEED_REMOVE_PROTO
/* Check for a prototype to rewind. */
#cmakedefine NEED_REWIND_PROTO
/* Check for a prototype to select. */
#cmakedefine NEED_SELECT_PROTO
/* Check for a prototype to setitimer. */
#cmakedefine NEED_SETITIMER_PROTO
/* Check for a prototype to setrlimit. */
#cmakedefine NEED_SETRLIMIT_PROTO
/* Check for a prototype to setsockopt. */
#cmakedefine NEED_SETSOCKOPT_PROTO
/* Check for a prototype to snprintf. */
#cmakedefine NEED_SNPRINTF_PROTO
/* Check for a prototype to socket. */
#cmakedefine NEED_SOCKET_PROTO
/* Check for a prototype to sprintf. */
#cmakedefine NEED_SPRINTF_PROTO
/* Check for a prototype to sscanf. */
#cmakedefine NEED_SSCANF_PROTO
/* Check for a prototype to strcasecmp. */
#cmakedefine NEED_STRCASECMP_PROTO
/* Check for a prototype to strdup. */
#cmakedefine NEED_STRDUP_PROTO
/* Check for a prototype to strerror. */
#cmakedefine NEED_STRERROR_PROTO
/* Check for a prototype to stricmp. */
#cmakedefine NEED_STRICMP_PROTO
/* Check for a prototype to strlcpy. */
#cmakedefine NEED_STRLCPY_PROTO
/* Check for a prototype to strncasecmp. */
#cmakedefine NEED_STRNCASECMP_PROTO
/* Check for a prototype to strnicmp. */
#cmakedefine NEED_STRNICMP_PROTO
/* Check for a prototype to system. */
#cmakedefine NEED_SYSTEM_PROTO
/* Check for a prototype to time. */
#cmakedefine NEED_TIME_PROTO
/* Check for a prototype to unlink. */
#cmakedefine NEED_UNLINK_PROTO
/* Check for a prototype to vsnprintf. */
#cmakedefine NEED_VSNPRINTF_PROTO
/* Check for a prototype to write. */
#cmakedefine NEED_WRITE_PROTO
#endif /* _CONF_H_ */
+367
View File
@@ -0,0 +1,367 @@
#ifndef _CONF_H_
#define _CONF_H_
/* Define to empty if the keyword does not work. */
/* #undef const */
/* Define if you don't have vprintf but do have _doprnt. */
/* #undef HAVE_DOPRNT */
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1
/* Define if you have the vprintf function. */
#define HAVE_VPRINTF 1
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef pid_t */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Define to `unsigned' if <sys/types.h> doesn't define. */
/* #undef size_t */
/* Define if you have the ANSI C header files. */
/* #undef STDC_HEADERS */
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define if we're compiling CircleMUD under any type of UNIX system. */
#define CIRCLE_UNIX 1
/* Machine-specific dependencies for running on modern macOS systems 10.13+ (High Sierra)
* Updated by Victor Augusto Borges Dias de Almeida (aka Stoneheart), 26 June 2024.
*
* Tested on:
* - macOS 10.13: High Sierra - September 25, 2017 (Latest: 10.13.6)
* - macOS 10.14: Mojave - September 24, 2018 (Latest: 10.14.6)
* - macOS 10.15: Catalina - October 7, 2019 (Latest: 10.15.7)
* - macOS 11: Big Sur - November 12, 2020 (Latest: 11.7.10)
* - macOS 12: Monterey - October 25, 2021 (Latest: 12.7)
* - macOS 13: Ventura - November 7, 2022 (Latest: 13.7)
* - macOS 14: Sonoma - November 7, 2023 (Latest: 14.3)
*
* This file works on Apple Silicon Chips (M1, M2, M3) without futher configurations. */
#if defined(__APPLE__) && defined(__MACH__)
#define CIRCLE_MAC_OS 1
#endif
/* Define if the system is capable of using crypt() to encrypt. */
#define CIRCLE_CRYPT 1
/* Define if we don't have proper support for the system's crypt(). */
/* #undef HAVE_UNSAFE_CRYPT */
/* Define is the system has struct in_addr. */
#define HAVE_STRUCT_IN_ADDR 1
/* Define to `int' if <sys/socket.h> doesn't define. */
/* #undef socklen_t */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef ssize_t */
/* Define if you have the gettimeofday function. */
#define HAVE_GETTIMEOFDAY 1
/* Define if you have the inet_addr function. */
#define HAVE_INET_ADDR 1
/* Define if you have the inet_aton function. */
#define HAVE_INET_ATON 1
/* Define if you have the select function. */
#define HAVE_SELECT 1
/* Define if you have the snprintf function. */
#define HAVE_SNPRINTF 1
/* Define if you have the strcasecmp function. */
#define HAVE_STRCASECMP 1
/* Define if you have the strdup function. */
#define HAVE_STRDUP 1
/* Define if you have the strerror function. */
#define HAVE_STRERROR 1
/* Define if you have the stricmp function. */
/* #undef HAVE_STRICMP */
/* Define if you have the strlcpy function. */
#ifndef CIRCLE_MAC_OS
#define HAVE_STRLCPY 1
#else
#define HAVE_STRLCPY 0
#endif
/* Define if you have the strncasecmp function. */
#define HAVE_STRNCASECMP 1
/* Define if you have the strnicmp function. */
/* #undef HAVE_STRNICMP */
/* Define if you have the strstr function. */
#define HAVE_STRSTR 1
/* Define if you have the vsnprintf function. */
#define HAVE_VSNPRINTF 1
/* Define if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define if you have the <arpa/telnet.h> header file. */
#define HAVE_ARPA_TELNET_H 1
/* Define if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1
/* Define if you have the <crypt.h> header file. */
/* #undef HAVE_CRYPT_H */
#ifdef CIRCLE_MAC_OS
#define HAVE_CRYPT_H 1
#endif
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if you have the <mcheck.h> header file. */
/* #undef HAVE_MCHECK_H */
#ifdef CIRCLE_MAC_OS
#define HAVE_MCHECK_H 1
#endif
/* Define if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define if you have the <net/errno.h> header file. */
/* #undef HAVE_NET_ERRNO_H */
/* Define if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define if you have the <sys/fcntl.h> header file. */
#define HAVE_SYS_FCNTL_H 1
/* Define if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the malloc library (-lmalloc). */
/* #undef HAVE_LIBMALLOC */
/* Check for a prototype to accept. */
/* #undef NEED_ACCEPT_PROTO */
#ifndef CIRCLE_MAC_OS
/* Check for a prototype to atoi. */
#define NEED_ATOI_PROTO
/* Check for a prototype to atol. */
#define NEED_ATOL_PROTO
#endif
/* Check for a prototype to bind. */
/* #undef NEED_BIND_PROTO */
/* Check for a prototype to bzero. */
/* #undef NEED_BZERO_PROTO */
/* Check for a prototype to chdir. */
/* #undef NEED_CHDIR_PROTO */
/* Check for a prototype to close. */
/* #undef NEED_CLOSE_PROTO */
/* Check for a prototype to crypt. */
/* #undef NEED_CRYPT_PROTO */
/* Check for a prototype to fclose. */
/* #undef NEED_FCLOSE_PROTO */
/* Check for a prototype to fcntl. */
/* #undef NEED_FCNTL_PROTO */
/* Check for a prototype to fflush. */
/* #undef NEED_FFLUSH_PROTO */
/* Check for a prototype to fprintf. */
/* #undef NEED_FPRINTF_PROTO */
/* Check for a prototype to fputc. */
/* #undef NEED_FPUTC_PROTO */
/* Check for a prototype to fputs. */
/* #undef NEED_FPUTS_PROTO */
/* Check for a prototype to fread. */
/* #undef NEED_FREAD_PROTO */
/* Check for a prototype to fscanf. */
/* #undef NEED_FSCANF_PROTO */
/* Check for a prototype to fseek. */
/* #undef NEED_FSEEK_PROTO */
/* Check for a prototype to fwrite. */
/* #undef NEED_FWRITE_PROTO */
/* Check for a prototype to getpeername. */
/* #undef NEED_GETPEERNAME_PROTO */
/* Check for a prototype to getpid. */
/* #undef NEED_GETPID_PROTO */
/* Check for a prototype to getrlimit. */
/* #undef NEED_GETRLIMIT_PROTO */
/* Check for a prototype to getsockname. */
/* #undef NEED_GETSOCKNAME_PROTO */
/* Check for a prototype to gettimeofday. */
/* #undef NEED_GETTIMEOFDAY_PROTO */
/* Check for a prototype to htonl. */
/* #undef NEED_HTONL_PROTO */
/* Check for a prototype to htons. */
/* #undef NEED_HTONS_PROTO */
/* Check for a prototype to inet_addr. */
/* #undef NEED_INET_ADDR_PROTO */
/* Check for a prototype to inet_aton. */
/* #undef NEED_INET_ATON_PROTO */
/* Check for a prototype to inet_ntoa. */
/* #undef NEED_INET_NTOA_PROTO */
/* Check for a prototype to listen. */
/* #undef NEED_LISTEN_PROTO */
/* Check for a prototype to ntohl. */
/* #undef NEED_NTOHL_PROTO */
/* Check for a prototype to perror. */
/* #undef NEED_PERROR_PROTO */
/* Check for a prototype to printf. */
/* #undef NEED_PRINTF_PROTO */
/* Check for a prototype to qsort. */
#ifndef CIRCLE_MAC_OS
#define NEED_QSORT_PROTO
#endif
/* Check for a prototype to read. */
/* #undef NEED_READ_PROTO */
/* Check for a prototype to remove. */
/* #undef NEED_REMOVE_PROTO */
/* Check for a prototype to rewind. */
/* #undef NEED_REWIND_PROTO */
/* Check for a prototype to select. */
/* #undef NEED_SELECT_PROTO */
/* Check for a prototype to setitimer. */
/* #undef NEED_SETITIMER_PROTO */
/* Check for a prototype to setrlimit. */
/* #undef NEED_SETRLIMIT_PROTO */
/* Check for a prototype to setsockopt. */
/* #undef NEED_SETSOCKOPT_PROTO */
/* Check for a prototype to snprintf. */
/* #undef NEED_SNPRINTF_PROTO */
/* Check for a prototype to socket. */
/* #undef NEED_SOCKET_PROTO */
/* Check for a prototype to sprintf. */
/* #undef NEED_SPRINTF_PROTO */
/* Check for a prototype to sscanf. */
/* #undef NEED_SSCANF_PROTO */
/* Check for a prototype to strcasecmp. */
/* #undef NEED_STRCASECMP_PROTO */
/* Check for a prototype to strdup. */
/* #undef NEED_STRDUP_PROTO */
/* Check for a prototype to strerror. */
/* #undef NEED_STRERROR_PROTO */
/* Check for a prototype to stricmp. */
#define NEED_STRICMP_PROTO
/* Check for a prototype to strlcpy. */
/* #undef NEED_STRLCPY_PROTO */
/* Check for a prototype to strncasecmp. */
/* #undef NEED_STRNCASECMP_PROTO */
/* Check for a prototype to strnicmp. */
#define NEED_STRNICMP_PROTO
/* Check for a prototype to system. */
#ifndef CIRCLE_MAC_OS
#define NEED_SYSTEM_PROTO
#endif
/* Check for a prototype to time. */
/* #undef NEED_TIME_PROTO */
/* Check for a prototype to unlink. */
/* #undef NEED_UNLINK_PROTO */
/* Check for a prototype to vsnprintf. */
/* #undef NEED_VSNPRINTF_PROTO */
/* Check for a prototype to write. */
/* #undef NEED_WRITE_PROTO */
#endif /* _CONF_H_ */
+18 -8
View File
@@ -39,15 +39,25 @@
/* Can Scripts be attached to players? */
int script_players = NO;
/* pk_allowed sets the tone of the entire game. If pk_allowed is set to NO,
* then players will not be allowed to kill, summon, charm, or sleep other
* players, as well as a variety of other "asshole player" protections. However,
* if you decide you want to have an all-out knock-down drag-out PK Mud, just
* set pk_allowed to YES - and anything goes. */
int pk_allowed = NO;
/* pk_setting sets the tone of the entire game.
*
* CONFIG_PK_OFF 0 Players are prevented from damaging or fighting other players in code
* CONFIG_PK_LIMITED 1 Players may damage and fight but will be flagged PLR_KILLER
* CONFIG_PK_FREEFORALL 2 No restrictions or flags for player damaging or killing
*
* If pk_setting is set to 0, then players will not be allowed to kill, summon, charm, or sleep other
* players, as well as a variety of other "asshole player" protections.
* However, if you decide you want to have an all-out knock-down drag-out PK Mud, just
* set pk_setting to 2 - and anything goes. */
int pk_setting = 0;
/* Is playerthieving allowed? */
int pt_allowed = NO;
/* Is playerthieving allowed?
*
* CONFIG_PT_OFF 0 Players are prevented from stealing from other players in code
* CONFIG_PT_LIMITED 1 Players may steal from other players but will be flagged PLR_THIEF if caught
* CONFIG_PT_FREEFORALL 2 No restrictions or flags for player stealing
*/
int pt_setting = 0;
/* Minimum level a player must be to shout/holler/gossip/auction. */
int level_can_shout = 1;
+2 -2
View File
@@ -14,9 +14,9 @@
#define _CONFIG_H_
/* Global variable declarations, all settable by cedit */
extern int pk_allowed;
extern int pk_setting;
extern int script_players;
extern int pt_allowed;
extern int pt_setting;
extern int level_can_shout;
extern int holler_move_cost;
extern int tunnel_size;
+2 -1
View File
@@ -24,7 +24,7 @@
* @todo cpp_extern isn't needed here (or anywhere) as the extern reserved word
* works correctly with C compilers (at least in my Experience)
* Jeremy Osborne 1/28/2008 */
cpp_extern const char *tbamud_version = "tbaMUD 2023";
cpp_extern const char *tbamud_version = "tbaMUD 2025";
/* strings corresponding to ordinals/bitvectors in structs.h */
/* (Note: strings for class definitions in class.c instead of here) */
@@ -877,6 +877,7 @@ const char *trig_types[] = {
"Door",
"UNUSED",
"Time",
"Damage",
"\n"
};
+6 -6
View File
@@ -3838,8 +3838,8 @@ static void load_default_config( void )
/* This function is called only once, at boot-time. We assume config_info is
* empty. -Welcor */
/* Game play options. */
CONFIG_PK_ALLOWED = pk_allowed;
CONFIG_PT_ALLOWED = pt_allowed;
CONFIG_PK_SETTING = pk_setting;
CONFIG_PT_SETTING = pt_setting;
CONFIG_LEVEL_CAN_SHOUT = level_can_shout;
CONFIG_HOLLER_MOVE_COST = holler_move_cost;
CONFIG_TUNNEL_SIZE = tunnel_size;
@@ -4113,12 +4113,12 @@ void load_config( void )
break;
case 'p':
if (!str_cmp(tag, "pk_allowed"))
CONFIG_PK_ALLOWED = num;
if (!str_cmp(tag, "pk_setting"))
CONFIG_PK_SETTING = num;
else if (!str_cmp(tag, "protocol_negotiation"))
CONFIG_PROTOCOL_NEGOTIATION = num;
else if (!str_cmp(tag, "pt_allowed"))
CONFIG_PT_ALLOWED = num;
else if (!str_cmp(tag, "pt_setting"))
CONFIG_PT_SETTING = num;
break;
case 'r':
+17 -5
View File
@@ -1024,17 +1024,27 @@ ACMD(do_mdoor)
}
if ((rm = get_room(target)) == NULL) {
mob_log(ch, "mdoor: invalid target");
mob_log(ch, "mdoor: invalid target (arg == %s)", target);
return;
}
if ((dir = search_block(direction, dirs, FALSE)) == -1) {
mob_log(ch, "mdoor: invalid direction");
char dirs_str[256];
int di, doff = 0;
dirs_str[0] = '\0';
for (di = 0; *dirs[di] != '\n'; di++)
doff += snprintf(dirs_str + doff, sizeof(dirs_str) - doff, "%s%s", doff ? " " : "", dirs[di]);
mob_log(ch, "mdoor: invalid direction (arg == %s) not found in: [ %s ]", direction, dirs_str);
return;
}
if ((fd = search_block(field, door_field, FALSE)) == -1) {
mob_log(ch, "odoor: invalid field");
char fields_str[256];
int fi, foff = 0;
fields_str[0] = '\0';
for (fi = 0; *door_field[fi] != '\n'; fi++)
foff += snprintf(fields_str + foff, sizeof(fields_str) - foff, "%s%s", foff ? " " : "", door_field[fi]);
mob_log(ch, "mdoor: invalid field (arg == %s) not found in: [ %s ]", field, fields_str);
return;
}
@@ -1081,8 +1091,10 @@ ACMD(do_mdoor)
case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room;
else
mob_log(ch, "mdoor: invalid door target");
else {
newexit->to_room = NOWHERE;
mob_log(ch, "mdoor: invalid door target (arg == %s)", value);
}
break;
}
}
+17 -5
View File
@@ -625,17 +625,27 @@ static OCMD(do_odoor)
}
if ((rm = get_room(target)) == NULL) {
obj_log(obj, "odoor: invalid target");
obj_log(obj, "odoor: invalid target (arg == %s)", target);
return;
}
if ((dir = search_block(direction, dirs, FALSE)) == -1) {
obj_log(obj, "odoor: invalid direction");
char dirs_str[256];
int di, doff = 0;
dirs_str[0] = '\0';
for (di = 0; *dirs[di] != '\n'; di++)
doff += snprintf(dirs_str + doff, sizeof(dirs_str) - doff, "%s%s", doff ? " " : "", dirs[di]);
obj_log(obj, "odoor: invalid direction (arg == %s) not found in: [ %s ]", direction, dirs_str);
return;
}
if ((fd = search_block(field, door_field, FALSE)) == -1) {
obj_log(obj, "odoor: invalid field");
char fields_str[256];
int fi, foff = 0;
fields_str[0] = '\0';
for (fi = 0; *door_field[fi] != '\n'; fi++)
foff += snprintf(fields_str + foff, sizeof(fields_str) - foff, "%s%s", foff ? " " : "", door_field[fi]);
obj_log(obj, "odoor: invalid field (arg == %s) not found in: [ %s ]", field, fields_str);
return;
}
@@ -682,8 +692,10 @@ static OCMD(do_odoor)
case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room;
else
obj_log(obj, "odoor: invalid door target");
else {
newexit->to_room = NOWHERE;
obj_log(obj, "odoor: invalid door target (arg == %s)", value);
}
break;
}
}
+46 -31
View File
@@ -1091,70 +1091,85 @@ int format_script(struct descriptor_data *d)
char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE];
char *sc;
size_t len = 0, nlen = 0, llen = 0;
int indent = 0, indent_next = FALSE, found_case = FALSE, i, line_num = 0, ret;
int indent = 0, indent_next = FALSE, line_num = 0, ret, i; // Declare i here
int block_stack[READ_SIZE]; // Stack to track block types
int stack_top = -1; // Initialize stack as empty
int switch_indent[READ_SIZE]; // Array to track switch indent levels
int switch_top = -1; // Index for switch_indent array
int case_indent = 0; // Track indent for case blocks
int in_switch = 0; // Flag to indicate if we're inside a switch block
if (!d->str || !*d->str)
return FALSE;
sc = strdup(*d->str); /* we work on a copy, because of strtok() */
sc = strdup(*d->str); // Work on a copy
t = strtok(sc, "\n\r");
*nsc = '\0';
while (t) {
line_num++;
skip_spaces(&t);
if (!strn_cmp(t, "if ", 3) ||
!strn_cmp(t, "switch ", 7)) {
if (!strn_cmp(t, "switch ", 7)) {
indent_next = TRUE;
} else if (!strn_cmp(t, "while ", 6)) {
found_case = TRUE; /* so you can 'break' a loop without complains */
stack_top++;
block_stack[stack_top] = 's'; // 's' for switch
switch_top++;
switch_indent[switch_top] = indent; // Save current indent level for switch
in_switch++; // We're entering a switch block
} else if (!strn_cmp(t, "case", 4) || !strn_cmp(t, "default", 7)) {
if (in_switch > 0) { // If we're inside a switch
indent = switch_indent[switch_top] + 1; // Indent cases one level under switch
indent_next = TRUE; // Indent the next line after case
case_indent = indent; // Save indent for case block
}
} else if (!strn_cmp(t, "if ", 3) || !strn_cmp(t, "while ", 6)) {
indent_next = TRUE;
} else if (!strn_cmp(t, "end", 3) ||
!strn_cmp(t, "done", 4)) {
if (!indent) {
stack_top++;
block_stack[stack_top] = 'l'; // 'l' for loop or conditional
} else if (!strn_cmp(t, "end", 3) || !strn_cmp(t, "done", 4)) {
if (stack_top < 0) {
write_to_output(d, "Unmatched 'end' or 'done' (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
indent--;
indent_next = FALSE;
if (block_stack[stack_top] == 's') {
indent = switch_indent[switch_top]; // Reset to the exact indent level where switch was declared
switch_top--; // Decrease switch stack if ending a switch
case_indent = 0; // Reset case indent since we're leaving the switch
in_switch--; // We're leaving a switch block
} else {
indent--; // For other blocks like while
}
stack_top--;
indent_next = FALSE; // Reset for next line
} else if (!strn_cmp(t, "else", 4)) {
if (!indent) {
if (stack_top < 0 || block_stack[stack_top] != 'l') {
write_to_output(d, "Unmatched 'else' (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
indent--;
indent--; // Reduce indent for else, then increment for next statement
indent_next = TRUE;
} else if (!strn_cmp(t, "case", 4) ||
!strn_cmp(t, "default", 7)) {
if (!indent) {
write_to_output(d, "Case/default outside switch (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
if (!found_case) /* so we don't indent multiple case statements without a break */
indent_next = TRUE;
found_case = TRUE;
} else if (!strn_cmp(t, "break", 5)) {
if (!found_case || !indent ) {
write_to_output(d, "Break not in case (line %d)!\r\n", line_num);
if (stack_top < 0 || (block_stack[stack_top] != 's' && block_stack[stack_top] != 'l')) {
write_to_output(d, "Break not in case or loop (line %d)!\r\n", line_num);
free(sc);
return FALSE;
}
found_case = FALSE;
indent--;
indent = case_indent + 1; // Indent break one level deeper than case
indent_next = FALSE; // Ensure no automatic increase for next line after break
}
*line = '\0';
for (nlen = 0, i = 0;i<indent;i++) {
for (nlen = 0, i = 0; i < indent; i++) {
strncat(line, " ", sizeof(line) - strlen(line) - 1);
nlen += 2;
}
ret = snprintf(line + nlen, sizeof(line) - nlen, "%s\r\n", t);
llen = (size_t)ret;
if (ret < 0 || llen + nlen + len > d->max_str - 1 ) {
if (ret < 0 || llen + nlen + len > d->max_str - 1) {
write_to_output(d, "String too long, formatting aborted\r\n");
free(sc);
return FALSE;
@@ -1169,8 +1184,8 @@ int format_script(struct descriptor_data *d)
t = strtok(NULL, "\n\r");
}
if (indent)
write_to_output(d, "Unmatched if, while or switch ignored.\r\n");
if (stack_top >= 0)
write_to_output(d, "Unmatched block statements ignored.\r\n");
free(*d->str);
*d->str = strdup(nsc);
+1 -1
View File
@@ -16,7 +16,7 @@
#include "dg_scripts.h"
#define NUM_TRIG_TYPE_FLAGS 20
#define NUM_TRIG_TYPE_FLAGS 21
/* Submodes of TRIGEDIT connectedness. */
#define TRIGEDIT_MAIN_MENU 0
+4 -4
View File
@@ -2486,7 +2486,6 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
char cmd[MAX_INPUT_LENGTH], *p;
struct script_data *sc = 0;
struct cmdlist_element *temp;
unsigned long loops = 0;
void *go = NULL;
void obj_command_interpreter(obj_data *obj, char *argument);
@@ -2578,8 +2577,8 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
if (process_if(p + 6, go, sc, trig, type)) {
temp->original = cl;
} else {
cl->loops = 0;
cl = temp;
loops = 0;
}
} else if (!strn_cmp("switch ", p, 7)) {
cl = find_case(trig, cl, go, sc, type, p + 7);
@@ -2599,9 +2598,10 @@ int script_driver(void *go_adress, trig_data *trig, int type, int mode)
if (cl->original && process_if(orig_cmd + 6, go, sc, trig,
type)) {
cl = cl->original;
loops++;
cl->loops++;
GET_TRIG_LOOPS(trig)++;
if (loops == 30) {
if (cl->loops == 30) {
cl->loops = 0;
process_wait(go, trig, type, "wait 1", cl);
depth--;
return ret_val;
+3
View File
@@ -71,6 +71,7 @@
#define MTRIG_DOOR (1 << 17) /* door manipulated in room */
#define MTRIG_TIME (1 << 19) /* trigger based on game hour */
#define MTRIG_DAMAGE (1 << 20) /* trigger whenever mob is damaged */
/* obj trigger types */
#define OTRIG_GLOBAL (1 << 0) /* unused */
@@ -135,6 +136,7 @@ struct cmdlist_element {
char *cmd; /* one line of a trigger */
struct cmdlist_element *original;
struct cmdlist_element *next;
int loops; /* for counting number of runs in a while loop */
};
struct trig_var_data {
@@ -263,6 +265,7 @@ void time_wtrigger(room_data *room);
int login_wtrigger(struct room_data *room, char_data *actor);
int damage_mtrigger(char_data *ch, char_data *victim, int dam, int attacktype);
/* function prototypes from dg_scripts.c */
ACMD(do_attach) ;
ACMD(do_detach);
+33 -3
View File
@@ -147,7 +147,7 @@ void greet_memory_mtrigger(char_data *actor)
{
trig_data *t;
char_data *ch;
struct script_memory *mem;
struct script_memory *mem, *next_mem;
char buf[MAX_INPUT_LENGTH];
int command_performed = 0;
@@ -159,7 +159,8 @@ void greet_memory_mtrigger(char_data *actor)
AFF_FLAGGED(ch, AFF_CHARM))
continue;
/* find memory line with command only */
for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); mem=mem->next) {
for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); mem = next_mem) {
next_mem = mem->next;
if (char_script_id(actor)!=mem->id) continue;
if (mem->cmd) {
command_interpreter(ch, mem->cmd); /* no script */
@@ -245,7 +246,8 @@ void entry_memory_mtrigger(char_data *ch)
for (actor = world[IN_ROOM(ch)].people; actor && SCRIPT_MEM(ch);
actor = actor->next_in_room) {
if (actor!=ch && SCRIPT_MEM(ch)) {
for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); mem = mem->next) {
for (mem = SCRIPT_MEM(ch); mem && SCRIPT_MEM(ch); ) {
struct script_memory *next_mem = mem->next;
if (char_script_id(actor)==mem->id) {
struct script_memory *prev;
if (mem->cmd) command_interpreter(ch, mem->cmd);
@@ -270,6 +272,7 @@ void entry_memory_mtrigger(char_data *ch)
if (mem->cmd) free(mem->cmd);
free(mem);
}
mem = next_mem;
} /* for (mem =..... */
}
}
@@ -554,6 +557,33 @@ int cast_mtrigger(char_data *actor, char_data *ch, int spellnum)
return 1;
}
int damage_mtrigger(char_data *actor, char_data *victim, int dam, int attacktype)
{
trig_data *t;
char buf[MAX_INPUT_LENGTH];
if (victim == NULL)
return dam;
if (!SCRIPT_CHECK(victim, MTRIG_DAMAGE) || AFF_FLAGGED(victim, AFF_CHARM))
return dam;
for (t = TRIGGERS(SCRIPT(victim)); t; t = t->next) {
if (TRIGGER_CHECK(t, MTRIG_DAMAGE) &&
(rand_number(1, 100) <= GET_TRIG_NARG(t))) {
ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0);
ADD_UID_VAR(buf, t, char_script_id(victim), "victim", 0);
sprintf(buf, "%d", dam);
add_var(&GET_TRIG_VARS(t), "damage", buf, 0);
add_var(&GET_TRIG_VARS(t), "attacktype", skill_name(attacktype), 0);
return script_driver(&victim, t, MOB_TRIGGER, TRIG_NEW);
}
}
return dam;
}
int leave_mtrigger(char_data *actor, int dir)
{
trig_data *t;
+2 -2
View File
@@ -465,7 +465,7 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
* will return the number of bags of gold.
* Addition inspired by Jamie Nelson */
else if (!str_cmp(var, "findmob")) {
if (!field || !*field || !subfield || !*subfield) {
if (!*field || !subfield || !*subfield) {
script_log("findmob.vnum(mvnum) - illegal syntax");
strcpy(str, "0");
} else {
@@ -486,7 +486,7 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
}
/* Addition inspired by Jamie Nelson. */
else if (!str_cmp(var, "findobj")) {
if (!field || !*field || !subfield || !*subfield) {
if (!*field || !subfield || !*subfield) {
script_log("findobj.vnum(ovnum) - illegal syntax");
strcpy(str, "0");
} else {
+17 -5
View File
@@ -224,17 +224,27 @@ WCMD(do_wdoor)
}
if ((rm = get_room(target)) == NULL) {
wld_log(room, "wdoor: invalid target");
wld_log(room, "wdoor: invalid target (arg == %s)", target);
return;
}
if ((dir = search_block(direction, dirs, FALSE)) == -1) {
wld_log(room, "wdoor: invalid direction");
char dirs_str[256];
int di, doff = 0;
dirs_str[0] = '\0';
for (di = 0; *dirs[di] != '\n'; di++)
doff += snprintf(dirs_str + doff, sizeof(dirs_str) - doff, "%s%s", doff ? " " : "", dirs[di]);
wld_log(room, "wdoor: invalid direction (arg == %s) not found in: [ %s ]", direction, dirs_str);
return;
}
if ((fd = search_block(field, door_field, FALSE)) == -1) {
wld_log(room, "wdoor: invalid field");
char fields_str[256];
int fi, foff = 0;
fields_str[0] = '\0';
for (fi = 0; *door_field[fi] != '\n'; fi++)
foff += snprintf(fields_str + foff, sizeof(fields_str) - foff, "%s%s", foff ? " " : "", door_field[fi]);
wld_log(room, "wdoor: invalid field (arg == %s) not found in: [ %s ]", field, fields_str);
return;
}
@@ -281,8 +291,10 @@ WCMD(do_wdoor)
case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room;
else
wld_log(room, "wdoor: invalid door target");
else {
newexit->to_room = NOWHERE;
wld_log(room, "wdoor: invalid door target (arg == %s)", value);
}
break;
}
}
+39 -12
View File
@@ -110,10 +110,13 @@ void update_pos(struct char_data *victim)
void check_killer(struct char_data *ch, struct char_data *vict)
{
if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF))
return;
if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict)
if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF)) {
return;
}
if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict){
return;
}
SET_BIT_AR(PLR_FLAGS(ch), PLR_KILLER);
send_to_char(ch, "If you want to be a PLAYER KILLER, so be it...\r\n");
@@ -122,6 +125,22 @@ void check_killer(struct char_data *ch, struct char_data *vict)
GET_NAME(ch), GET_NAME(vict), world[IN_ROOM(vict)].name);
}
bool pk_allowed(struct char_data *ch, struct char_data *victim)
{
/* NPCs are never restricted */
if (IS_NPC(ch) || IS_NPC(victim))
return true;
if (CONFIG_PK_SETTING == CONFIG_PK_OFF)
return false;
if (CONFIG_PK_SETTING == CONFIG_PK_LIMITED)
check_killer(ch, victim);
return true;
}
/* start one char fighting another (yes, it is horrible, I know... ) */
void set_fighting(struct char_data *ch, struct char_data *vict)
{
@@ -133,6 +152,12 @@ void set_fighting(struct char_data *ch, struct char_data *vict)
return;
}
if (!pk_allowed(ch, vict)) {
send_to_char(ch, "Player killing is not permitted.\r\n");
return;
}
ch->next_fighting = combat_list;
combat_list = ch;
@@ -142,8 +167,6 @@ void set_fighting(struct char_data *ch, struct char_data *vict)
FIGHTING(ch) = vict;
GET_POS(ch) = POS_FIGHTING;
if (!CONFIG_PK_ALLOWED)
check_killer(ch, vict);
}
/* remove a char from the list of fighting chars */
@@ -603,6 +626,12 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
return (-1); /* -je, 7/7/92 */
}
/* Check for PK if this is not a PK MUD */
if (!pk_allowed(ch, victim)) {
send_to_char(ch, "Player killing is not permitted.\r\n");
return (0);
}
/* peaceful rooms */
if (ch->nr != real_mobile(DG_CASTER_PROXY) &&
ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
@@ -620,6 +649,11 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
if (!IS_NPC(victim) && ((GET_LEVEL(victim) >= LVL_IMMORT) && PRF_FLAGGED(victim, PRF_NOHASSLE)))
dam = 0;
dam = damage_mtrigger(ch, victim, dam, attacktype);
if (dam == -1) {
return (0);
}
if (victim != ch) {
/* Start the attacker fighting the victim */
if (GET_POS(ch) > POS_STUNNED && (FIGHTING(ch) == NULL))
@@ -645,13 +679,6 @@ int damage(struct char_data *ch, struct char_data *victim, int dam, int attackty
if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2)
dam /= 2;
/* Check for PK if this is not a PK MUD */
if (!CONFIG_PK_ALLOWED) {
check_killer(ch, victim);
if (PLR_FLAGGED(ch, PLR_KILLER) && (ch != victim))
dam = 0;
}
/* Set the maximum damage per round and subtract the hit points */
dam = MAX(MIN(dam, 100), 0);
GET_HIT(victim) -= dam;
+1
View File
@@ -34,6 +34,7 @@ void set_fighting(struct char_data *ch, struct char_data *victim);
int skill_message(int dam, struct char_data *ch, struct char_data *vict,
int attacktype);
void stop_fighting(struct char_data *ch);
bool pk_allowed(struct char_data *ch, struct char_data *victim);
/* Global variables */
+7
View File
@@ -177,6 +177,13 @@ static IBT_DATA *read_ibt( char *filename, FILE *fp )
}
break;
case 'F':
if (!str_cmp(word, "Flags")) {
fMatch = TRUE;
fread_flags(fp, ibtData->flags, 4);
}
break;
case 'I':
TXT_KEY("IdNum", id_num, fread_line(fp));
break;
+2 -2
View File
@@ -367,7 +367,7 @@ void parse_edit_action(int command, char *string, struct descriptor_data *d)
s++;
temp = *s;
*s = '\0';
char buf3[9];
char buf3[13];
sprintf(buf3, "%4d: ", (i - 1));
strncat(buf, buf3, sizeof(buf) - strlen(buf) - 1);
strncat(buf, t, sizeof(buf) - strlen(buf) - 1);
@@ -421,7 +421,7 @@ void parse_edit_action(int command, char *string, struct descriptor_data *d)
strncat(buf, *d->str, sizeof(buf) - strlen(buf) - 1);
*s = temp;
strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
if (s && *s)
if (*s)
strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
RECREATE(*d->str, char, strlen(buf) + 3);
+32 -9
View File
@@ -41,7 +41,7 @@
/* local (file scope) functions */
static int perform_dupe_check(struct descriptor_data *d);
static struct alias_data *find_alias(struct alias_data *alias_list, char *str);
static void perform_complex_alias(struct txt_q *input_q, char *orig, struct alias_data *a);
static void perform_complex_alias(struct txt_q *input_q, char *orig, struct alias_data *a, struct char_data *ch);
static int _parse_name(char *arg, char *name);
static bool perform_new_char_dupe_check(struct descriptor_data *d);
/* sort_commands utility */
@@ -668,9 +668,10 @@ ACMD(do_alias)
* commands. */
#define NUM_TOKENS 9
static void perform_complex_alias(struct txt_q *input_q, char *orig, struct alias_data *a)
static void perform_complex_alias(struct txt_q *input_q, char *orig, struct alias_data *a, struct char_data *ch)
{
struct txt_q temp_queue;
struct txt_block *qtmp;
char *tokens[NUM_TOKENS], *temp, *write_point;
char buf2[MAX_RAW_INPUT_LENGTH], buf[MAX_RAW_INPUT_LENGTH]; /* raw? */
int num_of_tokens = 0, num;
@@ -697,16 +698,27 @@ static void perform_complex_alias(struct txt_q *input_q, char *orig, struct alia
} else if (*temp == ALIAS_VAR_CHAR) {
temp++;
if ((num = *temp - '1') < num_of_tokens && num >= 0) {
strcpy(write_point, tokens[num]); /* strcpy: OK */
if ((write_point - buf) + strlen(tokens[num]) >= MAX_RAW_INPUT_LENGTH)
goto overflow;
strcpy(write_point, tokens[num]);
write_point += strlen(tokens[num]);
} else if (*temp == ALIAS_GLOB_CHAR) {
skip_spaces(&orig);
strcpy(write_point, orig); /* strcpy: OK */
if ((write_point - buf) + strlen(orig) >= MAX_RAW_INPUT_LENGTH)
goto overflow;
strcpy(write_point, orig);
write_point += strlen(orig);
} else if ((*(write_point++) = *temp) == '$') /* redouble $ for act safety */
*(write_point++) = '$';
} else
} else {
if (write_point - buf + 2 >= MAX_RAW_INPUT_LENGTH)
goto overflow;
if ((*(write_point++) = *temp) == '$') /* redouble $ for act safety */
*(write_point++) = '$';
}
} else {
if (write_point - buf + 1 >= MAX_RAW_INPUT_LENGTH)
goto overflow;
*(write_point++) = *temp;
}
}
*write_point = '\0';
@@ -720,6 +732,16 @@ static void perform_complex_alias(struct txt_q *input_q, char *orig, struct alia
temp_queue.tail->next = input_q->head;
input_q->head = temp_queue.head;
}
return;
overflow:
send_to_char(ch, "Alias expansion too long.\r\n");
while (temp_queue.head) {
qtmp = temp_queue.head;
temp_queue.head = qtmp->next;
free(qtmp->text);
free(qtmp);
}
}
/* Given a character and a string, perform alias replacement on it.
@@ -755,7 +777,7 @@ int perform_alias(struct descriptor_data *d, char *orig, size_t maxlen)
strlcpy(orig, a->replacement, maxlen);
return (0);
} else {
perform_complex_alias(&d->input, ptr, a);
perform_complex_alias(&d->input, ptr, a, d->character);
return (1);
}
}
@@ -1612,8 +1634,9 @@ void nanny(struct descriptor_data *d, char *arg)
if (load_result == CLASS_UNDEFINED) {
write_to_output(d, "\r\nThat's not a class.\r\nClass: ");
return;
} else
} else {
GET_CLASS(d->character) = load_result;
}
if (d->olc) {
free(d->olc);
+2 -2
View File
@@ -473,7 +473,7 @@ void mag_affects(int level, struct char_data *ch, struct char_data *victim,
break;
case SPELL_SLEEP:
if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(victim))
if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(ch) && !IS_NPC(victim))
return;
if (MOB_FLAGGED(victim, MOB_NOSLEEP))
return;
@@ -650,7 +650,7 @@ void mag_areas(int level, struct char_data *ch, int spellnum, int savetype)
continue;
if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT)
continue;
if (!CONFIG_PK_ALLOWED && !IS_NPC(ch) && !IS_NPC(tch))
if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(ch) && !IS_NPC(tch))
continue;
if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM))
continue;
+2
View File
@@ -380,6 +380,8 @@ extern const char *nrm, *grn, *cyn, *yel;
#define CEDIT_MAP_SIZE 55
#define CEDIT_MINIMAP_SIZE 56
#define CEDIT_DEBUG_MODE 57
#define CEDIT_PK_SETTING 58
#define CEDIT_PT_SETTING 59
/* Hedit Submodes of connectedness. */
#define HEDIT_CONFIRM_SAVESTRING 0
+26 -4
View File
@@ -146,7 +146,8 @@ static void prefedit_disp_main_menu(struct descriptor_data *d)
"%sImmortal Preferences\r\n"
"%s1%s) Syslog Level %s[%s%8s%s] %s4%s) ClsOLC %s[%s%3s%s]\r\n"
"%s2%s) Show Flags %s[%s%3s%s] %s5%s) No WizNet %s[%s%3s%s]\r\n"
"%s3%s) No Hassle %s[%s%3s%s] %s6%s) Holylight %s[%s%3s%s]\r\n",
"%s3%s) No Hassle %s[%s%3s%s] %s6%s) Holylight %s[%s%3s%s]\r\n"
"%s7%s) Verbose %s[%s%3s%s] ",
CBWHT(d->character, C_NRM),
/* Line 1 - syslog and clsolc */
CBYEL(d->character, C_NRM), CCNRM(d->character, C_NRM), CCCYN(d->character, C_NRM), CCYEL(d->character, C_NRM),
@@ -159,12 +160,17 @@ static void prefedit_disp_main_menu(struct descriptor_data *d)
/* Line 3 - nohassle and holylight */
CBYEL(d->character, C_NRM), CCNRM(d->character, C_NRM), CCCYN(d->character, C_NRM), CCYEL(d->character, C_NRM),
ONOFF(PREFEDIT_FLAGGED(PRF_NOHASSLE)), CCCYN(d->character, C_NRM), CBYEL(d->character, C_NRM), CCNRM(d->character, C_NRM),
CCCYN(d->character, C_NRM), CCYEL(d->character, C_NRM), ONOFF(PREFEDIT_FLAGGED(PRF_HOLYLIGHT)), CCCYN(d->character, C_NRM)
CCCYN(d->character, C_NRM), CCYEL(d->character, C_NRM), ONOFF(PREFEDIT_FLAGGED(PRF_HOLYLIGHT)), CCCYN(d->character, C_NRM),
/* Line 4 - Verbose */
CBYEL(d->character, C_NRM), CCNRM(d->character, C_NRM), CCCYN(d->character, C_NRM), CCYEL(d->character, C_NRM),
ONOFF(PREFEDIT_FLAGGED(PRF_VERBOSE)), CCCYN(d->character, C_NRM)
);
if (GET_LEVEL(PREFEDIT_GET_CHAR) == LVL_IMPL)
send_to_char(d->character, "%s7%s) Zone Resets %s[%s%3s%s]\r\n",
send_to_char(d->character, "%s8%s) Zone Resets %s[%s%3s%s]\r\n",
CBYEL(d->character, C_NRM), CCNRM(d->character, C_NRM), CCCYN(d->character, C_NRM), CCYEL(d->character, C_NRM),
ONOFF(PREFEDIT_FLAGGED(PRF_ZONERESETS)), CCCYN(d->character, C_NRM));
else
send_to_char(d->character, "\r\n");
}
/* Finishing Off */
@@ -505,7 +511,19 @@ void prefedit_parse(struct descriptor_data * d, char *arg)
}
break;
case '7':
case '7':
if (GET_LEVEL(PREFEDIT_GET_CHAR) < LVL_IMMORT)
{
send_to_char(d->character, "%sInvalid choice!%s\r\n", CBRED(d->character, C_NRM), CCNRM(d->character, C_NRM));
prefedit_disp_main_menu(d);
}
else
{
TOGGLE_BIT_AR(PREFEDIT_GET_FLAGS, PRF_VERBOSE);
}
break;
case '8':
if (GET_LEVEL(PREFEDIT_GET_CHAR) < LVL_IMPL)
{
send_to_char(d->character, "%sInvalid choice!%s\r\n", CBRED(d->character, C_NRM), CCNRM(d->character, C_NRM));
@@ -901,6 +919,10 @@ void prefedit_Restore_Defaults(struct descriptor_data *d)
if (PREFEDIT_FLAGGED(PRF_AUTODOOR))
SET_BIT_AR(PREFEDIT_GET_FLAGS, PRF_AUTODOOR);
/* PRF_VERBOSE - On */
if (PREFEDIT_FLAGGED(PRF_VERBOSE))
SET_BIT_AR(PREFEDIT_GET_FLAGS, PRF_VERBOSE);
/* Other (non-toggle) options */
PREFEDIT_GET_WIMP_LEV = 0; /* Wimpy off by default */
PREFEDIT_GET_PAGELENGTH = 22; /* Default telnet screen is 22 lines */
+40 -11
View File
@@ -13,6 +13,11 @@
#include <sys/types.h>
#include "protocol.h"
#ifdef _MSC_VER
#include "telnet.h"
#define alloca _alloca
#endif
/******************************************************************************
The following section is for Diku/Merc derivatives. Replace as needed.
******************************************************************************/
@@ -1763,7 +1768,26 @@ static void PerformSubnegotiation( descriptor_t *apDescriptor, char aCmd, char *
Write(apDescriptor, RequestTTYPE);
}
if ( PrefixString("Mudlet", pClientName) )
if ( PrefixString("MTTS ", pClientName) )
{
pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt = atoi(pClientName+5);
if (pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt & 1)
{
pProtocol->pVariables[eMSDP_ANSI_COLORS]->ValueInt = 1;
}
if (pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt & 4)
{
pProtocol->pVariables[eMSDP_UTF_8]->ValueInt = 1;
}
if (pProtocol->pVariables[eMSDP_CLIENT_VERSION]->ValueInt & 8)
{
pProtocol->pVariables[eMSDP_XTERM_256_COLORS]->ValueInt = 1;
pProtocol->b256Support = eYES;
}
}
else if ( PrefixString("Mudlet", pClientName) )
{
/* Mudlet beta 15 and later supports 256 colours, but we can't
* identify it from the mud - everything prior to 1.1 claims
@@ -2078,20 +2102,25 @@ static void ExecuteMSDPPair( descriptor_t *apDescriptor, const char *apVariable,
!strcmp(apDescriptor->pProtocol->pVariables[i]->pValueString, "Unknown") )
{
/* Store the new value if it's valid */
char *pBuffer = alloca(VariableNameTable[i].Max+1);
char *pBuffer = malloc(VariableNameTable[i].Max + 1);
int j; /* Loop counter */
for ( j = 0; j < VariableNameTable[i].Max && *apValue != '\0'; ++apValue )
if ( pBuffer != NULL )
{
if ( isprint(*apValue) )
pBuffer[j++] = *apValue;
}
pBuffer[j++] = '\0';
for ( j = 0; j < VariableNameTable[i].Max && *apValue != '\0'; ++apValue )
{
if ( isprint(*apValue) )
pBuffer[j++] = *apValue;
}
pBuffer[j++] = '\0';
if ( j >= VariableNameTable[i].Min )
{
free(apDescriptor->pProtocol->pVariables[i]->pValueString);
apDescriptor->pProtocol->pVariables[i]->pValueString = AllocString(pBuffer);
if ( j >= VariableNameTable[i].Min )
{
free(apDescriptor->pProtocol->pVariables[i]->pValueString);
apDescriptor->pProtocol->pVariables[i]->pValueString = AllocString(pBuffer);
}
free(pBuffer);
}
}
}
+4 -2
View File
@@ -410,8 +410,10 @@ void autoquest_trigger_check(struct char_data *ch, struct char_data *vict,
break;
case AQ_OBJ_RETURN:
if (IS_NPC(vict) && (GET_MOB_VNUM(vict) == QST_RETURNMOB(rnum)))
if (object && (GET_OBJ_VNUM(object) == QST_TARGET(rnum)))
if (object && (GET_OBJ_VNUM(object) == QST_TARGET(rnum))) {
generic_complete_quest(ch);
extract_obj(object);
}
break;
case AQ_ROOM_CLEAR:
if (QST_TARGET(rnum) == world[IN_ROOM(ch)].number) {
@@ -648,7 +650,7 @@ static void quest_show(struct char_data *ch, mob_vnum qm)
send_to_char(ch, "There are no quests available here at the moment.\r\n");
}
static void quest_stat(struct char_data *ch, char argument[MAX_STRING_LENGTH])
static void quest_stat(struct char_data *ch, char *argument)
{
qst_rnum rnum;
mob_rnum qmrnum;
+1 -1
View File
@@ -1052,7 +1052,7 @@ static void read_line(FILE *shop_f, const char *string, void *data)
{
char buf[READ_SIZE];
if (!get_line(shop_f, buf) || !sscanf(buf, string, data)) {
if (!get_line(shop_f, buf) || sscanf(buf, string, data) != 1) {
log("SYSERR: Error in shop #%d, near '%s' with '%s'", SHOP_NUM(top_shop), buf, string);
exit(1);
}
+2 -2
View File
@@ -202,9 +202,9 @@ SPECIAL(mayor)
{
char actbuf[MAX_INPUT_LENGTH];
const char open_path[] =
static const char open_path[] =
"W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
const char close_path[] =
static const char close_path[] =
"W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
static const char *path = NULL;
+2 -2
View File
@@ -120,7 +120,7 @@ ASPELL(spell_summon)
return;
}
if (!CONFIG_PK_ALLOWED) {
if (CONFIG_PK_SETTING == CONFIG_PK_OFF) {
if (MOB_FLAGGED(victim, MOB_AGGRESSIVE)) {
act("As the words escape your lips and $N travels\r\n"
"through time and space towards you, you realize that $E is\r\n"
@@ -265,7 +265,7 @@ ASPELL(spell_charm)
else if (AFF_FLAGGED(victim, AFF_CHARM) || level < GET_LEVEL(victim))
send_to_char(ch, "You fail.\r\n");
/* player charming another player - no legal reason for this */
else if (!CONFIG_PK_ALLOWED && !IS_NPC(victim))
else if ((CONFIG_PK_SETTING == CONFIG_PK_OFF) && !IS_NPC(victim))
send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n");
else if (circle_follow(victim, ch))
send_to_char(ch, "Sorry, following in circles is not allowed.\r\n");
+5 -4
View File
@@ -262,9 +262,10 @@
#define PRF_AUTOMAP 31 /**< Show map at the side of room descs */
#define PRF_AUTOKEY 32 /**< Automatically unlock locked doors when opening */
#define PRF_AUTODOOR 33 /**< Use the next available door */
#define PRF_ZONERESETS 34
#define PRF_ZONERESETS 34 /**< Show when zones reset */
#define PRF_VERBOSE 35 /**< Listings like where are more verbose */
/** Total number of available PRF flags */
#define NUM_PRF_FLAGS 35
#define NUM_PRF_FLAGS 36
/* Affect bits: used in char_data.char_specials.saved.affected_by */
/* WARNING: In the world files, NEVER set the bits marked "R" ("Reserved") */
@@ -1290,8 +1291,8 @@ struct recent_player
* variables. */
struct game_data
{
int pk_allowed; /**< Is player killing allowed? */
int pt_allowed; /**< Is player thieving allowed? */
int pk_setting; /**< Is player killing allowed? */
int pt_setting; /**< Is player thieving allowed? */
int level_can_shout; /**< Level player must be to shout. */
int holler_move_cost; /**< Cost to holler in move points. */
int tunnel_size; /**< Number of people allowed in a tunnel.*/
+25 -4
View File
@@ -63,6 +63,24 @@
/* Do not change anything below this line. */
#if defined(__APPLE__) && defined(__MACH__)
/* Machine-specific dependencies for running on modern macOS systems 10.13+ (High Sierra)
* Updated by Victor Augusto Borges Dias de Almeida (aka Stoneheart), 26 June 2024.
*
* Tested on:
* - macOS 10.13: High Sierra (Lobo) - September 25, 2017 (Latest: 10.13.6)
* - macOS 10.14: Mojave (Liberty) - September 24, 2018 (Latest: 10.14.6)
* - macOS 10.15: Catalina (Jazz) - October 7, 2019 (Latest: 10.15.7)
* - macOS 11: Big Sur (GoldenGate) - November 12, 2020 (Latest: 11.7.10)
* - macOS 12: Monterey (Star) - October 25, 2021 (Latest: 12.7)
* - macOS 13: Ventura (Rome) - November 7, 2022 (Latest: 13.7)
* - macOS 14: Sonoma (Sunburst) - November 7, 2023 (Latest: 14.3)
*
* This file works on Apple Silicon Chips (M1, M2, M3) without futher configurations.
*/
#define CIRCLE_MAC_OS 1
#endif
/* Set up various machine-specific things based on the values determined from
* configure and conf.h. */
@@ -78,7 +96,7 @@
#include <strings.h>
#endif
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) || defined(CIRCLE_MAC_OS))
#include <stdlib.h>
#else /* No standard headers. */
@@ -88,9 +106,8 @@
#endif
extern char *malloc(), *calloc(), *realloc();
extern void free ();
extern void abort (), exit ();
extern void free();
extern void abort(), exit();
#endif /* Standard headers. */
@@ -150,9 +167,11 @@ extern void abort (), exit ();
#include <sys/errno.h>
#endif
#ifndef CIRCLE_MAC_OS
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
@@ -434,9 +453,11 @@ struct in_addr {
char *strerror(int errnum);
#endif
#ifndef CIRCLE_MAC_OS
#ifdef NEED_STRLCPY_PROTO
size_t strlcpy(char *dest, const char *src, size_t copylen);
#endif
#endif
#ifdef NEED_SYSTEM_PROTO
int system(const char *string);
+45
View File
@@ -0,0 +1,45 @@
set(TOOLS
asciipasswd
autowiz
plrtoascii
rebuildIndex
rebuildMailIndex
shopconv
sign
split
wld2html
)
# common includes and flags
include_directories(${CMAKE_SOURCE_DIR}/src)
add_definitions(-DCIRCLE_UTIL)
find_library(CRYPT_LIBRARY crypt)
find_library(NETLIB_LIBRARY nsl socket) # for sign.c, hvis nødvendig
foreach(tool ${TOOLS})
if(${tool} STREQUAL "rebuildIndex")
add_executable(rebuildIndex rebuildAsciiIndex.c)
else()
add_executable(${tool} ${tool}.c)
endif()
# Set output location
set_target_properties(${tool} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin
)
# Link to libcrypt for asciipasswd
if(${tool} STREQUAL "asciipasswd" AND CRYPT_LIBRARY)
target_link_libraries(${tool} ${CRYPT_LIBRARY})
endif()
# Link to netlib for sign
if(${tool} STREQUAL "sign" AND NETLIB_LIBRARY)
target_link_libraries(${tool} ${NETLIB_LIBRARY})
endif()
endforeach()
add_custom_target(utils DEPENDS ${TOOLS})
+1 -6
View File
@@ -23,7 +23,7 @@ CFLAGS = @CFLAGS@ $(MYFLAGS) $(PROFILE) -I$(INCDIR)
default: all
all: $(BINDIR)/asciipasswd $(BINDIR)/autowiz $(BINDIR)/plrtoascii $(BINDIR)/rebuildIndex $(BINDIR)/rebuildMailIndex $(BINDIR)/shopconv $(BINDIR)/sign $(BINDIR)/split $(BINDIR)/wld2html $(BINDIR)/webster
all: $(BINDIR)/asciipasswd $(BINDIR)/autowiz $(BINDIR)/plrtoascii $(BINDIR)/rebuildIndex $(BINDIR)/rebuildMailIndex $(BINDIR)/shopconv $(BINDIR)/sign $(BINDIR)/split $(BINDIR)/wld2html
asciipasswd: $(BINDIR)/asciipasswd
@@ -43,8 +43,6 @@ split: $(BINDIR)/split
wld2html: $(BINDIR)/wld2html
webster: $(BINDIR)/webster
$(BINDIR)/asciipasswd: asciipasswd.c
$(CC) $(CFLAGS) -o $(BINDIR)/asciipasswd asciipasswd.c @CRYPTLIB@
@@ -72,9 +70,6 @@ $(BINDIR)/split: split.c
$(BINDIR)/wld2html: wld2html.c
$(CC) $(CFLAGS) -o $(BINDIR)/wld2html wld2html.c
$(BINDIR)/webster: webster.c
$(CC) $(CFLAGS) -o $(BINDIR)/webster webster.c
# Dependencies for the object files (automagically generated with
# gcc -MM)
+1 -1
View File
@@ -85,7 +85,7 @@ void read_file(void)
while (get_line(fl, line))
if (*line != '~')
recs++;
rewind(fl);
rewind(fl);
for (i = 0; i < recs; i++) {
get_line(fl, line);
+8 -8
View File
@@ -155,7 +155,7 @@ static int boot_the_shops_conv(FILE * shop_f, FILE * newshop_f, char *filename)
int main(int argc, char *argv[])
{
FILE *sfp, *nsfp;
char fn[256], part[256];
char fn[120], part[256];
int result, index, i;
if (argc < 2) {
@@ -173,20 +173,20 @@ int main(int argc, char *argv[])
perror(fn);
} else {
if ((nsfp = fopen(fn, "w")) == NULL) {
printf("Error writing to %s.\n", fn);
continue;
printf("Error writing to %s.\n", fn);
continue;
}
printf("%s:\n", fn);
result = boot_the_shops_conv(sfp, nsfp, fn);
fclose(nsfp);
fclose(sfp);
if (result) {
sprintf(part, "mv %s.tmp %s", fn, fn);
i = system(part);
sprintf(part, "mv %s.tmp %s", fn, fn);
i = system(part);
} else {
sprintf(part, "mv %s.tmp %s.bak", fn, fn);
i = system(part);
printf("Done!\n");
sprintf(part, "mv %s.tmp %s.bak", fn, fn);
i = system(part);
printf("Done!\n");
}
}
}
-175
View File
@@ -1,175 +0,0 @@
/* ************************************************************************
* File: webster.c Part of tbaMUD *
* Usage: Use an online dictionary via tell m-w <word>. *
* *
* Based on the Circle 3.0 syntax checker and wld2html programs. *
************************************************************************ */
#define log(msg) fprintf(stderr, "%s\n", msg)
#include "conf.h"
#include "sysdep.h"
#define MEM_USE 10000
char buf[MEM_USE];
int get_line(FILE * fl, char *buf);
void skip_spaces(char **string);
void parse_webster_html(char *arg);
int main(int argc, char **argv)
{
int pid = 0;
if (argc != 3) {
return 0; /* no word/pid given */
}
pid = atoi(argv[2]);
snprintf(buf, sizeof(buf),
"lynx -accept_all_cookies -source http://www.thefreedictionary.com/%s"
" >webster.html", argv[1]);
system(buf);
parse_webster_html(argv[1]);
if (pid)
kill(pid, SIGUSR2);
return (0);
}
void parse_webster_html(char *arg) {
FILE *infile, *outfile;
char scanbuf[MEM_USE], outline[MEM_USE], *p, *q;
outfile = fopen("websterinfo", "w");
if (!outfile)
exit(1);
infile = fopen("webster.html", "r");
if (!infile) {
fprintf(outfile, "A bug has occured in webster. (no webster.html) Please notify Welcor.");
fclose(outfile);
return;
}
unlink("webster.html"); /* We can still read */
for ( ; get_line(infile, buf)!=0; ) {
if (strncmp(buf, "<script>write_ads(AdsNum, 0, 1)</script>", 40) != 0)
continue; // read until we hit the line with results in it.
p = buf+40;
if (strncmp(p, "<br>", 4) == 0)
{
fprintf(outfile, "That word could not be found.\n");
goto end;
}
else if (strncmp(p, "<div ", 5) == 0) // definition is here, all in one line.
{
while (strncmp(p, "ds-list", 7)) //seek to the definition
p++;
strncpy(scanbuf, p, sizeof(scanbuf)); // strtok on a copy.
p = strtok(scanbuf, ">"); // chop the line at the end of tags: <br><b>word</b> becomes "<br" "<b" "word</b"
p = strtok(NULL, ">"); // skip the rest of this tag.
fprintf(outfile, "Info on: %s\n\n", arg);
while (1)
{
q = outline;
while (*p != '<')
{
assert(p < scanbuf+sizeof(scanbuf));
*q++ = *p++;
}
if (!strncmp(p, "<br", 3) || !strncmp(p, "<p", 2) || !strncmp(p, "<div class=\"ds-list\"", 23) || !strncmp(p, "<div class=\"sds-list\"", 24))
*q++ = '\n';
// if it's not a <br> tag or a <div class="sds-list"> or <div class="ds-list"> tag, ignore it.
*q++='\0';
fprintf(outfile, "%s", outline);
if (!strncmp(p, "</table", 7))
goto end;
p = strtok(NULL, ">");
}
}
else if (strncmp(p, "<div>", 5) == 0) // not found, but suggestions are ample:
{
strncpy(scanbuf, p, sizeof(scanbuf)); // strtok on a copy.
p = strtok(scanbuf, ">"); // chop the line at the end of tags: <br><b>word</b> becomes "<br>" "<b>" "word</b>"
p = strtok(NULL, ">"); // skip the rest of this tag.
while (1)
{
q = outline;
while (*p != '<')
*q++ = *p++;
if (!strncmp(p, "<td ", 4))
*q++ = '\n';
// if it's not a <td> tag, ignore it.
*q++='\0';
fprintf(outfile, "%s", outline);
if (!strncmp(p, "</table", 7))
goto end;
p = strtok(NULL, ">");
}
}
else
{
// weird.. one of the above should be correct.
fprintf(outfile, "It would appear that the free online dictionary has changed their format.\n"
"Sorry, but you might need a webrowser instead.\n\n"
"See http://www.thefreedictionary.com/%s", arg);
goto end;
}
}
end:
fclose(infile);
fprintf(outfile, "~");
fclose(outfile);
}
/* get_line reads the next non-blank line off of the input stream.
* The newline character is removed from the input.
*/
int get_line(FILE * fl, char *buf)
{
char temp[MEM_USE];
do {
fgets(temp, MEM_USE, fl);
if (*temp)
temp[strlen(temp) - 1] = '\0';
} while (!feof(fl) && !*temp);
if (feof(fl))
return (0);
else {
strcpy(buf, temp);
return (1);
}
}
/*
* Function to skip over the leading spaces of a string.
*/
void skip_spaces(char **string)
{
for (; **string && isspace(**string); (*string)++);
}
+79 -71
View File
@@ -12,7 +12,6 @@
#include "conf.h"
#include "sysdep.h"
#define NOWHERE -1 /* nil reference for room-database */
/* The cardinal directions: used as index to room_data.dir_option[] */
@@ -22,14 +21,17 @@
#define WEST 3
#define UP 4
#define DOWN 5
#define NORTHWEST 6
#define NORTHEAST 7
#define SOUTHEAST 8
#define SOUTHWEST 9
#define NUM_OF_DIRS 6
#define NUM_OF_DIRS 10
#define CREATE(result, type, number) do {\
if (!((result) = (type *) calloc ((number), sizeof(type))))\
{ perror("malloc failure"); abort(); } } while(0)
/* Exit info: used in room_data.dir_option.exit_info */
#define EX_ISDOOR (1 << 0) /* Exit is a door */
#define EX_CLOSED (1 << 1) /* The door is closed */
@@ -45,7 +47,7 @@ typedef unsigned short int ush_int;
typedef char bool;
typedef char byte;
typedef sh_int room_num;
typedef int room_num;
typedef sh_int obj_num;
@@ -133,13 +135,14 @@ struct room_data {
struct room_data *world = NULL; /* array of rooms */
int top_of_world = 0; /* ref to top element of world */
int rec_count = 0;
/* local functions */
char *fread_string(FILE * fl, char *error);
void setup_dir(FILE * fl, int room, int dir);
void index_boot(char *name);
void index_boot(int cnt, char **name);
void discrete_load(FILE * fl);
void parse_room(FILE * fl, int virtual_nr);
void parse_mobile(FILE * mob_f, int nr);
@@ -150,7 +153,7 @@ void write_output(void);
char *dir_names[] =
{"North", "East", "South", "West", "Up", "Down"};
{"North", "East", "South", "West", "Up", "Down","North West","North East","South East","South West"};
/*************************************************************************
@@ -160,14 +163,12 @@ char *dir_names[] =
/* body of the booting system */
int main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <world-file-name>\n", argv[0]);
if (argc < 2) {
fprintf(stderr, "Usage: %s <world-file-name(s)>\n", argv[0]);
exit(1);
}
index_boot(argv[1]);
log("Renumbering rooms.");
renum_world();
index_boot(argc,argv);
log("Writing output.");
write_output();
@@ -176,6 +177,21 @@ int main(int argc, char **argv)
return (0);
}
/* Since the world is loaded into memory by index
* and not room number, we need to search through
* all rooms and return the correct one. This is
* used to generate door information (ie: the name)
*/
struct room_data* findRoom(int nr)
{
int i;
for (i=0;i<rec_count;i++)
if (world[i].number==nr)
return &world[i];
return NULL;
}
void write_output(void)
{
@@ -184,11 +200,22 @@ void write_output(void)
char buf[128];
register int door, found;
for (i = 0; i <= top_of_world; i++) {
for (i=0;i<rec_count;i++) {
//print the record number, but no linefeed.
fprintf(stderr, "Record: %d ",i);
if (world[i].name == NULL) {
//linefeed the prior record since we're skipping this one.
log("");
//the name is blank, which means, most likely, the record is bad as well.
continue;
}
sprintf(buf, "Writing %d.html", world[i].number);
log(buf);
sprintf(buf, "%d.html", world[i].number);
//for some reason, if you use %d with sprintf it rolls over like its 16bit,
//but only if you use the buffer with fopen.
//using %ld and casting to long solves this in case someone really wants
//to use negative room numbers.
sprintf(buf, "%ld.html",(long)world[i].number);
if (!(fl = fopen(buf, "w"))) {
perror("opening output file");
exit(1);
@@ -203,18 +230,22 @@ void write_output(void)
found = 0;
for (door = 0; door < NUM_OF_DIRS; door++)
if (world[i].dir_option[door] &&
world[i].dir_option[door]->to_room != NOWHERE) {
found = 1;
fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n",
world[world[i].dir_option[door]->to_room].number,
dir_names[door],
world[world[i].dir_option[door]->to_room].name);
world[i].dir_option[door]->to_room != NOWHERE) {
found = 1;
//this call gets a pointer to the room referenced by the to_room for the door.
//This fixes a lot of issues introduced with the whole 'renumbering rooms' call
//and the binary search that didn't work well.
struct room_data* to_room = findRoom(world[i].dir_option[door]->to_room);
fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n",
to_room->number,
dir_names[door],
to_room->name);
}
if (!found)
fprintf(fl, "None!");
fclose(fl);
}
}
}
/* function to count how many hash-mark delimited records exist in a file */
int count_hash_records(FILE * fl)
@@ -231,19 +262,35 @@ int count_hash_records(FILE * fl)
void index_boot(char *name)
void index_boot(int cnt, char **names)
{
FILE *db_file;
int rec_count = 0;
if (!(db_file = fopen(name, "r"))) {
perror("error opening world file");
exit(1);
//throw first entry away as that is the executable.
for (int i=1;i<cnt;i++) {
if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file");
exit(1);
}
//have to loop through files twice.
//once to get total record count
//second time to load them
rec_count += count_hash_records(db_file);
fclose(db_file);
}
rec_count = count_hash_records(db_file);
sprintf(buf,"Total records: %d\n",rec_count);
log(buf);
//now that we know how many records in total
//we can create the memory structure
CREATE(world, struct room_data, rec_count);
rewind(db_file);
discrete_load(db_file);
//now loop through files and load them
for (int i=1;i<cnt;i++) {
if (!(db_file = fopen(names[i], "r"))) {
perror("error opening world file");
exit(1);
}
discrete_load(db_file);
}
}
@@ -257,6 +304,9 @@ void discrete_load(FILE * fl)
fprintf(stderr, "Format error after room #%d\n", nr);
exit(1);
}
if (*line == 'T') //Toss triggers. THey currently break this util.
continue;
if (*line == '$')
return;
@@ -394,22 +444,6 @@ void setup_dir(FILE * fl, int room, int dir)
}
/* resolve all vnums into rnums in the world */
void renum_world(void)
{
register int room, door;
for (room = 0; room <= top_of_world; room++)
for (door = 0; door < NUM_OF_DIRS; door++)
if (world[room].dir_option[door])
if (world[room].dir_option[door]->to_room != NOWHERE)
world[room].dir_option[door]->to_room =
real_room(world[room].dir_option[door]->to_room,
world[room].number);
}
/*************************************************************************
* procedures for resetting, both play-time and boot-time *
*********************************************************************** */
@@ -464,32 +498,6 @@ char *fread_string(FILE * fl, char *error)
/* returns the real number of the room with given virtual number */
int real_room(int virtual, int reference)
{
int bot, top, mid;
bot = 0;
top = top_of_world;
/* perform binary search on world-table */
for (;;) {
mid = (bot + top) / 2;
if ((world + mid)->number == virtual)
return (mid);
if (bot >= top) {
fprintf(stderr, "Room %d does not exist in database (referenced in room %d)\n", virtual, reference);
return (-1);
}
if ((world + mid)->number > virtual)
top = mid - 1;
else
bot = mid + 1;
}
}
/* get_line reads the next non-blank line off of the input stream.
* The newline character is removed from the input. Lines which begin
* with '*' are considered to be comments.
+8 -2
View File
@@ -939,9 +939,15 @@ do \
#define CONFIG_CONFFILE config_info.CONFFILE
/** Player killing allowed or not? */
#define CONFIG_PK_ALLOWED config_info.play.pk_allowed
#define CONFIG_PK_SETTING config_info.play.pk_setting
#define CONFIG_PK_OFF 0 /* Players are prevented from damaging or fighting other players in code */
#define CONFIG_PK_LIMITED 1 /* Players may damage and fight but will be flagged PLR_KILLER */
#define CONFIG_PK_FREEFORALL 2 /* No restrictions or flags for player damaging or killing */
/** Player thieving allowed or not? */
#define CONFIG_PT_ALLOWED config_info.play.pt_allowed
#define CONFIG_PT_SETTING config_info.play.pt_setting
#define CONFIG_PT_OFF 0 /* Players are prevented from stealing from other players in code */
#define CONFIG_PT_LIMITED 1 /* Players may steal from other players but will be flagged PLR_THIEF if caught */
#define CONFIG_PT_FREEFORALL 2 /* No restrictions or flags for player stealing */
/** What level to use the shout command? */
#define CONFIG_LEVEL_CAN_SHOUT config_info.play.level_can_shout
/** How many move points does holler cost? */
+103
View File
@@ -0,0 +1,103 @@
# tests/CMakeLists.txt
# Unity-based unit tests for tbaMUD
#
# Each test executable is built from:
# vendor/unity/unity.c test framework
# test_stubs.c weak-symbol stubs for all unresolved mud globals
# src/<module>.c the source file(s) under test
# test_<name>.c the test file itself
#
# Only the source files being tested are compiled in particular comm.c
# (which contains main()) is never included.
cmake_minimum_required(VERSION 3.12)
enable_testing()
# ---------------------------------------------------------------------------
# Common settings shared by all test targets
# ---------------------------------------------------------------------------
set(UNITY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/vendor/unity/unity.c)
set(STUBS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/test_stubs.c)
set(MUD_SRCDIR ${CMAKE_SOURCE_DIR}/src)
# Include paths: mud source dir for conf.h / structs.h etc.,
# CMake binary dir for the generated conf.h (cmake builds place it there),
# and the Unity header dir.
set(TEST_INCLUDES
${MUD_SRCDIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/vendor/unity
)
# Suppress warnings that fire in generated stubs / vendored code and in the
# mud sources when compiled outside their normal full-build context.
set(TEST_CFLAGS)
if(CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
list(APPEND TEST_CFLAGS
-Wno-unused-parameter
-Wno-unused-function
-Wno-unused-variable
)
endif()
# Helper macro: add_mud_test(name SRC1 [SRC2 …])
# Creates an executable, registers it with CTest.
macro(add_mud_test TEST_NAME)
add_executable(${TEST_NAME}
${UNITY_SRC}
${STUBS_SRC}
${ARGN}
)
target_include_directories(${TEST_NAME} PRIVATE ${TEST_INCLUDES})
target_compile_options(${TEST_NAME} PRIVATE ${TEST_CFLAGS})
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
endmacro()
# ---------------------------------------------------------------------------
# test_utils covers src/utils.c
# ---------------------------------------------------------------------------
add_mud_test(test_utils
${MUD_SRCDIR}/utils.c
${MUD_SRCDIR}/random.c
${CMAKE_CURRENT_SOURCE_DIR}/test_utils.c
)
# ---------------------------------------------------------------------------
# test_random covers src/random.c and rand_number/dice in src/utils.c
# ---------------------------------------------------------------------------
add_mud_test(test_random
${MUD_SRCDIR}/random.c
${MUD_SRCDIR}/utils.c
${CMAKE_CURRENT_SOURCE_DIR}/test_random.c
)
# ---------------------------------------------------------------------------
# test_interpreter covers string helpers in src/interpreter.c
# ---------------------------------------------------------------------------
add_mud_test(test_interpreter
${MUD_SRCDIR}/interpreter.c
${MUD_SRCDIR}/utils.c
${MUD_SRCDIR}/random.c
${CMAKE_CURRENT_SOURCE_DIR}/test_interpreter.c
)
# crypt() is referenced from interpreter.c (nanny password hashing).
# Reuse the crypt library detected by the top-level build when one is needed;
# on platforms where crypt() is provided by libc, no extra link library is
# required.
if(CRYPT_LIBRARY)
target_link_libraries(test_interpreter PRIVATE ${CRYPT_LIBRARY})
endif()
# ---------------------------------------------------------------------------
# test_class covers src/class.c
# ---------------------------------------------------------------------------
add_mud_test(test_class
${MUD_SRCDIR}/class.c
${MUD_SRCDIR}/utils.c
${MUD_SRCDIR}/random.c
${CMAKE_CURRENT_SOURCE_DIR}/test_class.c
)
+96
View File
@@ -0,0 +1,96 @@
# tests/Makefile.in
# Autoconf template — processed by configure to produce tests/Makefile.
#
# Build and run the tbaMUD unit-test suite.
# Usage (after running ./configure from the project root):
#
# cd tests && make # build all test binaries
# cd tests && make test # build and run all tests
CC = @CC@
MYFLAGS = @MYFLAGS@
CFLAGS = @CFLAGS@ $(MYFLAGS)
LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@
SRCDIR = ../src
UNITYDIR = vendor/unity
# Include paths:
# ../src — mud headers and the generated conf.h
# vendor/unity — Unity framework headers
INCFLAGS = -I$(SRCDIR) -I$(UNITYDIR)
# Suppress warnings that fire in generated stubs / vendored code
WARNFLAGS = -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
COMPILE = $(CC) $(CFLAGS) $(WARNFLAGS) $(INCFLAGS)
# Common object files compiled into every test binary
UNITY_SRC = $(UNITYDIR)/unity.c
STUBS_SRC = test_stubs.c
# tbaMUD source files used by the tests
UTILS_SRC = $(SRCDIR)/utils.c $(SRCDIR)/random.c
# All test binaries
TESTS = test_utils test_random test_interpreter test_class
.PHONY: all test clean
all: $(TESTS)
# ---------------------------------------------------------------------------
# test_utils — covers src/utils.c
# ---------------------------------------------------------------------------
test_utils: $(UNITY_SRC) $(STUBS_SRC) $(UTILS_SRC) test_utils.c
$(COMPILE) -o $@ $^ $(LIBS)
# ---------------------------------------------------------------------------
# test_random — covers src/random.c and rand_number/dice in src/utils.c
# ---------------------------------------------------------------------------
test_random: $(UNITY_SRC) $(STUBS_SRC) $(UTILS_SRC) test_random.c
$(COMPILE) -o $@ $^ $(LIBS)
# ---------------------------------------------------------------------------
# test_interpreter — covers string helpers in src/interpreter.c
# ---------------------------------------------------------------------------
test_interpreter: $(UNITY_SRC) $(STUBS_SRC) $(UTILS_SRC) \
$(SRCDIR)/interpreter.c test_interpreter.c
$(COMPILE) -o $@ $^ $(LIBS)
# ---------------------------------------------------------------------------
# test_class — covers src/class.c
# ---------------------------------------------------------------------------
test_class: $(UNITY_SRC) $(STUBS_SRC) $(UTILS_SRC) \
$(SRCDIR)/class.c test_class.c
$(COMPILE) -o $@ $^ $(LIBS)
# ---------------------------------------------------------------------------
# Run all tests and produce JUnit XML files in test-results/
# ---------------------------------------------------------------------------
test: $(TESTS)
@echo "=========================================="
@echo "Running tbaMUD unit tests"
@echo "=========================================="
@mkdir -p test-results
@status=0; \
for t in $(TESTS); do \
t_start=$$(date +%s%3N); \
./$$t > test-results/$$t.out 2>&1; \
rc=$$?; \
t_end=$$(date +%s%3N); \
elapsed=$$(awk "BEGIN{printf \"%.3f\", ($$t_end - $$t_start)/1000}"); \
cat test-results/$$t.out; \
python3 unity_to_junit.py $$t test-results/$$t.xml "$$elapsed" < test-results/$$t.out; \
if [ $$rc -eq 0 ]; then \
echo "[PASS] $$t"; \
else \
echo "[FAIL] $$t"; \
status=1; \
fi; \
done; \
exit $$status
clean:
rm -f $(TESTS)
rm -rf test-results
+237
View File
@@ -0,0 +1,237 @@
/**
* @file test_class.c
* Unit tests for pure functions in src/class.c:
* parse_class, thaco, backstab_mult, level_exp
*/
#include "unity.h"
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "class.h"
extern FILE *logfile;
void setUp(void) { logfile = stderr; }
void tearDown(void) { logfile = NULL; }
/* =========================================================
* parse_class
* ========================================================= */
void test_parse_class_magic_user_lowercase(void)
{
TEST_ASSERT_EQUAL_INT(CLASS_MAGIC_USER, parse_class('m'));
}
void test_parse_class_cleric_lowercase(void)
{
TEST_ASSERT_EQUAL_INT(CLASS_CLERIC, parse_class('c'));
}
void test_parse_class_warrior_lowercase(void)
{
TEST_ASSERT_EQUAL_INT(CLASS_WARRIOR, parse_class('w'));
}
void test_parse_class_thief_lowercase(void)
{
TEST_ASSERT_EQUAL_INT(CLASS_THIEF, parse_class('t'));
}
void test_parse_class_uppercase(void)
{
TEST_ASSERT_EQUAL_INT(CLASS_MAGIC_USER, parse_class('M'));
TEST_ASSERT_EQUAL_INT(CLASS_CLERIC, parse_class('C'));
TEST_ASSERT_EQUAL_INT(CLASS_WARRIOR, parse_class('W'));
TEST_ASSERT_EQUAL_INT(CLASS_THIEF, parse_class('T'));
}
void test_parse_class_invalid(void)
{
TEST_ASSERT_EQUAL_INT(CLASS_UNDEFINED, parse_class('x'));
TEST_ASSERT_EQUAL_INT(CLASS_UNDEFINED, parse_class('?'));
TEST_ASSERT_EQUAL_INT(CLASS_UNDEFINED, parse_class(' '));
}
/* =========================================================
* thaco
* ========================================================= */
void test_thaco_magic_user_level_1(void)
{
TEST_ASSERT_EQUAL_INT(20, thaco(CLASS_MAGIC_USER, 1));
}
void test_thaco_magic_user_level_10(void)
{
TEST_ASSERT_EQUAL_INT(17, thaco(CLASS_MAGIC_USER, 10));
}
void test_thaco_cleric_level_1(void)
{
TEST_ASSERT_EQUAL_INT(20, thaco(CLASS_CLERIC, 1));
}
void test_thaco_warrior_level_1(void)
{
TEST_ASSERT_EQUAL_INT(20, thaco(CLASS_WARRIOR, 1));
}
void test_thaco_warrior_level_20(void)
{
TEST_ASSERT_EQUAL_INT(2, thaco(CLASS_WARRIOR, 20));
}
void test_thaco_warrior_high_level_is_one(void)
{
/* Warriors hit thac0=1 around level 21 and stay there */
TEST_ASSERT_EQUAL_INT(1, thaco(CLASS_WARRIOR, 21));
TEST_ASSERT_EQUAL_INT(1, thaco(CLASS_WARRIOR, LVL_IMPL));
}
void test_thaco_thief_level_1(void)
{
TEST_ASSERT_EQUAL_INT(20, thaco(CLASS_THIEF, 1));
}
/* =========================================================
* backstab_mult
* ========================================================= */
void test_backstab_mult_level_1(void)
{
TEST_ASSERT_EQUAL_INT(2, backstab_mult(1));
}
void test_backstab_mult_level_7(void)
{
TEST_ASSERT_EQUAL_INT(2, backstab_mult(7));
}
void test_backstab_mult_level_8(void)
{
TEST_ASSERT_EQUAL_INT(3, backstab_mult(8));
}
void test_backstab_mult_level_13(void)
{
TEST_ASSERT_EQUAL_INT(3, backstab_mult(13));
}
void test_backstab_mult_level_14(void)
{
TEST_ASSERT_EQUAL_INT(4, backstab_mult(14));
}
void test_backstab_mult_level_20(void)
{
TEST_ASSERT_EQUAL_INT(4, backstab_mult(20));
}
void test_backstab_mult_level_21(void)
{
TEST_ASSERT_EQUAL_INT(5, backstab_mult(21));
}
void test_backstab_mult_immortal(void)
{
TEST_ASSERT_EQUAL_INT(20, backstab_mult(LVL_IMMORT));
}
/* =========================================================
* level_exp
* ========================================================= */
void test_level_exp_magic_user_level_0(void)
{
TEST_ASSERT_EQUAL_INT(0, level_exp(CLASS_MAGIC_USER, 0));
}
void test_level_exp_magic_user_level_1(void)
{
TEST_ASSERT_EQUAL_INT(1, level_exp(CLASS_MAGIC_USER, 1));
}
void test_level_exp_magic_user_level_2(void)
{
TEST_ASSERT_EQUAL_INT(2500, level_exp(CLASS_MAGIC_USER, 2));
}
void test_level_exp_cleric_level_1(void)
{
TEST_ASSERT_EQUAL_INT(1, level_exp(CLASS_CLERIC, 1));
}
void test_level_exp_thief_level_1(void)
{
TEST_ASSERT_EQUAL_INT(1, level_exp(CLASS_THIEF, 1));
}
void test_level_exp_warrior_level_1(void)
{
TEST_ASSERT_EQUAL_INT(1, level_exp(CLASS_WARRIOR, 1));
}
void test_level_exp_invalid_level_returns_zero(void)
{
/* Level > LVL_IMPL or level < 0 → logs error and returns 0 */
TEST_ASSERT_EQUAL_INT(0, level_exp(CLASS_MAGIC_USER, -1));
TEST_ASSERT_EQUAL_INT(0, level_exp(CLASS_MAGIC_USER, LVL_IMPL + 1));
}
void test_level_exp_immortal_level(void)
{
/* LVL_IMMORT for mage → 8000000 */
TEST_ASSERT_EQUAL_INT(8000000, level_exp(CLASS_MAGIC_USER, LVL_IMMORT));
}
/* =========================================================
* main
* ========================================================= */
int main(void)
{
UNITY_BEGIN();
/* parse_class */
RUN_TEST(test_parse_class_magic_user_lowercase);
RUN_TEST(test_parse_class_cleric_lowercase);
RUN_TEST(test_parse_class_warrior_lowercase);
RUN_TEST(test_parse_class_thief_lowercase);
RUN_TEST(test_parse_class_uppercase);
RUN_TEST(test_parse_class_invalid);
/* thaco */
RUN_TEST(test_thaco_magic_user_level_1);
RUN_TEST(test_thaco_magic_user_level_10);
RUN_TEST(test_thaco_cleric_level_1);
RUN_TEST(test_thaco_warrior_level_1);
RUN_TEST(test_thaco_warrior_level_20);
RUN_TEST(test_thaco_warrior_high_level_is_one);
RUN_TEST(test_thaco_thief_level_1);
/* backstab_mult */
RUN_TEST(test_backstab_mult_level_1);
RUN_TEST(test_backstab_mult_level_7);
RUN_TEST(test_backstab_mult_level_8);
RUN_TEST(test_backstab_mult_level_13);
RUN_TEST(test_backstab_mult_level_14);
RUN_TEST(test_backstab_mult_level_20);
RUN_TEST(test_backstab_mult_level_21);
RUN_TEST(test_backstab_mult_immortal);
/* level_exp */
RUN_TEST(test_level_exp_magic_user_level_0);
RUN_TEST(test_level_exp_magic_user_level_1);
RUN_TEST(test_level_exp_magic_user_level_2);
RUN_TEST(test_level_exp_cleric_level_1);
RUN_TEST(test_level_exp_thief_level_1);
RUN_TEST(test_level_exp_warrior_level_1);
RUN_TEST(test_level_exp_invalid_level_returns_zero);
RUN_TEST(test_level_exp_immortal_level);
return UNITY_END();
}
+256
View File
@@ -0,0 +1,256 @@
/**
* @file test_interpreter.c
* Unit tests for pure string-handling functions in src/interpreter.c:
* is_number, is_abbrev, delete_doubledollar, any_one_arg, one_word
*/
#include "unity.h"
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "interpreter.h"
extern FILE *logfile;
void setUp(void) { logfile = stderr; }
void tearDown(void) { logfile = NULL; }
/* =========================================================
* is_number
* ========================================================= */
void test_is_number_digits_only(void)
{
TEST_ASSERT_TRUE(is_number("42"));
}
void test_is_number_zero(void)
{
TEST_ASSERT_TRUE(is_number("0"));
}
void test_is_number_negative(void)
{
TEST_ASSERT_TRUE(is_number("-5"));
}
void test_is_number_empty_string(void)
{
TEST_ASSERT_FALSE(is_number(""));
}
void test_is_number_contains_letter(void)
{
TEST_ASSERT_FALSE(is_number("12x3"));
}
void test_is_number_minus_only(void)
{
TEST_ASSERT_FALSE(is_number("-"));
}
void test_is_number_float(void)
{
TEST_ASSERT_FALSE(is_number("3.14"));
}
/* =========================================================
* is_abbrev
* ========================================================= */
void test_is_abbrev_exact_match(void)
{
TEST_ASSERT_TRUE(is_abbrev("north", "north"));
}
void test_is_abbrev_valid_prefix(void)
{
TEST_ASSERT_TRUE(is_abbrev("nort", "north"));
TEST_ASSERT_TRUE(is_abbrev("n", "north"));
}
void test_is_abbrev_non_prefix(void)
{
TEST_ASSERT_FALSE(is_abbrev("south", "north"));
}
void test_is_abbrev_empty_arg1(void)
{
TEST_ASSERT_FALSE(is_abbrev("", "north"));
}
void test_is_abbrev_arg1_longer_than_arg2(void)
{
TEST_ASSERT_FALSE(is_abbrev("northward", "north"));
}
void test_is_abbrev_case_insensitive(void)
{
TEST_ASSERT_TRUE(is_abbrev("Nor", "north"));
TEST_ASSERT_TRUE(is_abbrev("NOR", "NORTH"));
}
/* =========================================================
* delete_doubledollar
* ========================================================= */
void test_delete_doubledollar_no_dollars(void)
{
char s[] = "hello";
delete_doubledollar(s);
TEST_ASSERT_EQUAL_STRING("hello", s);
}
void test_delete_doubledollar_double_at_start(void)
{
char s[] = "$$hello";
delete_doubledollar(s);
TEST_ASSERT_EQUAL_STRING("$hello", s);
}
void test_delete_doubledollar_double_in_middle(void)
{
char s[] = "hello$$world";
delete_doubledollar(s);
TEST_ASSERT_EQUAL_STRING("hello$world", s);
}
void test_delete_doubledollar_four_dollars(void)
{
char s[] = "$$$$";
delete_doubledollar(s);
TEST_ASSERT_EQUAL_STRING("$$", s);
}
void test_delete_doubledollar_single_dollar_unchanged(void)
{
char s[] = "hello$world";
delete_doubledollar(s);
TEST_ASSERT_EQUAL_STRING("hello$world", s);
}
/* =========================================================
* any_one_arg
* ========================================================= */
void test_any_one_arg_basic(void)
{
char first[64];
char *rest = any_one_arg("hello world", first);
TEST_ASSERT_EQUAL_STRING("hello", first);
TEST_ASSERT_EQUAL_STRING(" world", rest);
}
void test_any_one_arg_leading_spaces(void)
{
char first[64];
any_one_arg(" hello world", first);
TEST_ASSERT_EQUAL_STRING("hello", first);
}
void test_any_one_arg_single_word(void)
{
char first[64];
char *rest = any_one_arg("hello", first);
TEST_ASSERT_EQUAL_STRING("hello", first);
TEST_ASSERT_EQUAL_STRING("", rest);
}
void test_any_one_arg_empty_string(void)
{
char first[64];
any_one_arg("", first);
TEST_ASSERT_EQUAL_STRING("", first);
}
void test_any_one_arg_lowercases(void)
{
char first[64];
any_one_arg("HELLO", first);
TEST_ASSERT_EQUAL_STRING("hello", first);
}
/* =========================================================
* one_word
* ========================================================= */
void test_one_word_unquoted_like_any_one_arg(void)
{
char first[64];
char *rest = one_word("hello world", first);
TEST_ASSERT_EQUAL_STRING("hello", first);
TEST_ASSERT_EQUAL_STRING(" world", rest);
}
void test_one_word_quoted_string(void)
{
char first[64];
char *rest = one_word("\"hello world\" rest", first);
TEST_ASSERT_EQUAL_STRING("hello world", first);
/* rest points just past the closing quote */
TEST_ASSERT_EQUAL_STRING(" rest", rest);
}
void test_one_word_empty_quoted(void)
{
char first[64];
one_word("\"\" rest", first);
TEST_ASSERT_EQUAL_STRING("", first);
}
void test_one_word_leading_spaces_skipped(void)
{
char first[64];
one_word(" hello", first);
TEST_ASSERT_EQUAL_STRING("hello", first);
}
/* =========================================================
* main
* ========================================================= */
int main(void)
{
UNITY_BEGIN();
/* is_number */
RUN_TEST(test_is_number_digits_only);
RUN_TEST(test_is_number_zero);
RUN_TEST(test_is_number_negative);
RUN_TEST(test_is_number_empty_string);
RUN_TEST(test_is_number_contains_letter);
RUN_TEST(test_is_number_minus_only);
RUN_TEST(test_is_number_float);
/* is_abbrev */
RUN_TEST(test_is_abbrev_exact_match);
RUN_TEST(test_is_abbrev_valid_prefix);
RUN_TEST(test_is_abbrev_non_prefix);
RUN_TEST(test_is_abbrev_empty_arg1);
RUN_TEST(test_is_abbrev_arg1_longer_than_arg2);
RUN_TEST(test_is_abbrev_case_insensitive);
/* delete_doubledollar */
RUN_TEST(test_delete_doubledollar_no_dollars);
RUN_TEST(test_delete_doubledollar_double_at_start);
RUN_TEST(test_delete_doubledollar_double_in_middle);
RUN_TEST(test_delete_doubledollar_four_dollars);
RUN_TEST(test_delete_doubledollar_single_dollar_unchanged);
/* any_one_arg */
RUN_TEST(test_any_one_arg_basic);
RUN_TEST(test_any_one_arg_leading_spaces);
RUN_TEST(test_any_one_arg_single_word);
RUN_TEST(test_any_one_arg_empty_string);
RUN_TEST(test_any_one_arg_lowercases);
/* one_word */
RUN_TEST(test_one_word_unquoted_like_any_one_arg);
RUN_TEST(test_one_word_quoted_string);
RUN_TEST(test_one_word_empty_quoted);
RUN_TEST(test_one_word_leading_spaces_skipped);
return UNITY_END();
}
+156
View File
@@ -0,0 +1,156 @@
/**
* @file test_random.c
* Unit tests for src/random.c and the random-number helpers in src/utils.c
* (rand_number, dice).
*/
#include "unity.h"
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
extern FILE *logfile;
void setUp(void) { logfile = stderr; }
void tearDown(void) { logfile = NULL; }
/* =========================================================
* circle_srandom / circle_random deterministic sequence
*
* The Park-Miller generator with seed s produces:
* G(s) = (16807 * s) mod 2147483647
* Precomputed for seed=1:
* call 1 16807
* call 2 282475249
* call 3 1622650073
* ========================================================= */
void test_circle_random_deterministic_first(void)
{
circle_srandom(1);
TEST_ASSERT_EQUAL_UINT32(16807UL, circle_random());
}
void test_circle_random_deterministic_second(void)
{
circle_srandom(1);
circle_random(); /* discard first */
TEST_ASSERT_EQUAL_UINT32(282475249UL, circle_random());
}
void test_circle_random_deterministic_third(void)
{
circle_srandom(1);
circle_random();
circle_random();
TEST_ASSERT_EQUAL_UINT32(1622650073UL, circle_random());
}
void test_circle_random_same_seed_same_sequence(void)
{
circle_srandom(42);
unsigned long a = circle_random();
unsigned long b = circle_random();
circle_srandom(42);
TEST_ASSERT_EQUAL_UINT32(a, circle_random());
TEST_ASSERT_EQUAL_UINT32(b, circle_random());
}
/* =========================================================
* rand_number result always in [from, to]
* ========================================================= */
void test_rand_number_in_range(void)
{
int i;
circle_srandom(12345);
for (i = 0; i < 200; i++) {
int v = rand_number(1, 10);
TEST_ASSERT_GREATER_OR_EQUAL_INT(1, v);
TEST_ASSERT_LESS_OR_EQUAL_INT(10, v);
}
}
void test_rand_number_same_low_high(void)
{
int i;
circle_srandom(1);
for (i = 0; i < 50; i++)
TEST_ASSERT_EQUAL_INT(7, rand_number(7, 7));
}
void test_rand_number_inverted_args(void)
{
/* rand_number logs SYSERR and swaps; result must still be in [1,10] */
int i;
circle_srandom(1);
for (i = 0; i < 50; i++) {
int v = rand_number(10, 1);
TEST_ASSERT_GREATER_OR_EQUAL_INT(1, v);
TEST_ASSERT_LESS_OR_EQUAL_INT(10, v);
}
}
/* =========================================================
* dice num dice each of size sides
* ========================================================= */
void test_dice_zero_dice(void)
{
circle_srandom(1);
TEST_ASSERT_EQUAL_INT(0, dice(0, 6));
}
void test_dice_zero_sides(void)
{
circle_srandom(1);
TEST_ASSERT_EQUAL_INT(0, dice(3, 0));
}
void test_dice_result_in_range(void)
{
int i;
circle_srandom(99);
for (i = 0; i < 200; i++) {
int v = dice(2, 6);
TEST_ASSERT_GREATER_OR_EQUAL_INT(2, v);
TEST_ASSERT_LESS_OR_EQUAL_INT(12, v);
}
}
void test_dice_one_die_one_side(void)
{
circle_srandom(1);
TEST_ASSERT_EQUAL_INT(1, dice(1, 1));
}
/* =========================================================
* main
* ========================================================= */
int main(void)
{
UNITY_BEGIN();
/* circle_srandom / circle_random */
RUN_TEST(test_circle_random_deterministic_first);
RUN_TEST(test_circle_random_deterministic_second);
RUN_TEST(test_circle_random_deterministic_third);
RUN_TEST(test_circle_random_same_seed_same_sequence);
/* rand_number */
RUN_TEST(test_rand_number_in_range);
RUN_TEST(test_rand_number_same_low_high);
RUN_TEST(test_rand_number_inverted_args);
/* dice */
RUN_TEST(test_dice_zero_dice);
RUN_TEST(test_dice_zero_sides);
RUN_TEST(test_dice_result_in_range);
RUN_TEST(test_dice_one_die_one_side);
return UNITY_END();
}
+507
View File
@@ -0,0 +1,507 @@
/**
* @file test_stubs.c
* Stub definitions used by unit-test binaries.
*
* Every function here is declared __attribute__((weak)) so that a real
* definition provided by a compiled source file (e.g. class.c providing
* parse_class(), interpreter.c providing is_abbrev()) automatically wins
* over the stub at link time.
*
* Global-variable stubs are plain definitions (zero-initialised by the
* C standard for translation-unit scope). They satisfy the extern
* declarations in mud headers without conflicting with any source file
* that is deliberately excluded from the test build.
*/
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "db.h"
#include "handler.h"
#include "interpreter.h"
#include "class.h"
#include "dg_scripts.h"
#include "protocol.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/* =========================================================
* Global variable stubs
* ========================================================= */
/* comm.c */
FILE *logfile = NULL; /* tests init to stderr in setUp */
struct descriptor_data *descriptor_list = NULL;
int no_specials = 0;
int circle_restrict = 0;
/* db.c */
struct room_data *world = NULL;
room_rnum top_of_world = 0;
struct weather_data weather_info; /* zero-init */
struct char_data *character_list = NULL;
struct index_data *mob_index = NULL;
struct index_data *obj_index = NULL;
mob_rnum top_of_mobt = 0;
obj_rnum top_of_objt = 0;
char *motd = NULL;
char *imotd = NULL;
char *GREETINGS = NULL;
char *background = NULL;
struct happyhour happy_data; /* zero-init */
struct player_index_element *player_table = NULL;
struct player_special_data dummy_mob; /* zero-init */
struct config_data config_info; /* zero-init */
time_t motdmod = 0;
time_t newsmod = 0;
/* interpreter needs some start-room vnum stubs */
ush_int r_mortal_start_room = 0;
ush_int r_immort_start_room = 0;
ush_int r_frozen_start_room = 0;
/* config.c */
int selfdelete_fastwipe = 0;
/* constants.c only needed when class.c is NOT in the build */
__attribute__((weak)) const struct con_app_type con_app[26];
__attribute__((weak)) const struct wis_app_type wis_app[26];
/* class.c only needed when class.c is NOT in the build */
__attribute__((weak)) const char *class_menu = "";
__attribute__((weak)) const char *pc_class_types[] = { "\n" };
/* =========================================================
* Function stubs (all weak so the real implementation wins)
* ========================================================= */
/* ---------- comm.c ---------- */
__attribute__((weak))
size_t send_to_char(struct char_data *ch, const char *messg, ...)
{ (void)ch; (void)messg; return 0; }
__attribute__((weak))
char *act(const char *str, int hide_invisible, struct char_data *ch,
struct obj_data *obj, void *vict_obj, int type)
{ (void)str; (void)hide_invisible; (void)ch;
(void)obj; (void)vict_obj; (void)type; return NULL; }
__attribute__((weak))
void write_to_q(const char *txt, struct txt_q *queue, int aliased)
{ (void)txt; (void)queue; (void)aliased; }
__attribute__((weak))
size_t write_to_output(struct descriptor_data *d, const char *txt, ...)
{ (void)d; (void)txt; return 0; }
__attribute__((weak))
size_t vwrite_to_output(struct descriptor_data *d, const char *fmt, va_list args)
{ (void)d; (void)fmt; (void)args; return 0; }
__attribute__((weak))
void echo_off(struct descriptor_data *d) { (void)d; }
__attribute__((weak))
void echo_on(struct descriptor_data *d) { (void)d; }
/* ---------- modify.c ---------- */
__attribute__((weak))
void page_string(struct descriptor_data *d, char *str, int keep_internal)
{ (void)d; (void)str; (void)keep_internal; }
__attribute__((weak))
void parse_tab(char *str) { (void)str; }
/* ---------- handler.c ---------- */
__attribute__((weak))
bool affected_by_spell(struct char_data *ch, int spell)
{ (void)ch; (void)spell; return FALSE; }
__attribute__((weak))
void affect_from_char(struct char_data *ch, int type)
{ (void)ch; (void)type; }
__attribute__((weak))
void extract_char(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void extract_char_final(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void char_from_room(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void char_to_room(struct char_data *ch, room_rnum room)
{ (void)ch; (void)room; }
__attribute__((weak))
void free_char(struct char_data *ch) { (void)ch; }
/* ---------- interpreter.c ---------- */
__attribute__((weak))
int is_abbrev(const char *arg1, const char *arg2)
{ (void)arg1; (void)arg2; return 0; }
__attribute__((weak))
int parse_class(char arg)
{ (void)arg; return CLASS_UNDEFINED; }
/* ---------- class.c ---------- */
__attribute__((weak))
void set_title(struct char_data *ch, char *title) { (void)ch; (void)title; }
__attribute__((weak))
void spell_level(int spell, int chclass, int level)
{ (void)spell; (void)chclass; (void)level; }
/* ---------- players.c ---------- */
__attribute__((weak))
void save_char(struct char_data *ch) { (void)ch; }
__attribute__((weak))
int create_entry(char *name) { (void)name; return 0; }
__attribute__((weak))
int load_char(const char *name, struct char_data *ch)
{ (void)name; (void)ch; return -1; }
__attribute__((weak))
void save_player_index(void) {}
__attribute__((weak))
void remove_player(int pfilepos) { (void)pfilepos; }
__attribute__((weak))
long get_ptable_by_name(const char *name) { (void)name; return -1; }
/* ---------- act.wizard.c ---------- */
__attribute__((weak))
void snoop_check(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void add_llog_entry(struct char_data *ch, int type) { (void)ch; (void)type; }
/* ---------- db.c ---------- */
__attribute__((weak))
room_rnum real_room(room_vnum vnum) { (void)vnum; return NOWHERE; }
__attribute__((weak))
void clear_char(struct char_data *ch) { (void)ch; if (ch) memset(ch, 0, sizeof(*ch)); }
__attribute__((weak))
void reset_char(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void init_char(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void new_mobile_data(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void free_char_from_db(struct char_data *ch) { (void)ch; }
__attribute__((weak))
void Crash_crashsave(struct char_data *ch) { (void)ch; }
__attribute__((weak))
int Crash_load(struct char_data *ch) { (void)ch; return 0; }
__attribute__((weak))
int Crash_delete_file(char *name) { (void)name; return 0; }
/* ---------- ban.c ---------- */
__attribute__((weak))
int isbanned(char *hostname) { (void)hostname; return 0; }
__attribute__((weak))
int valid_name(char *newname) { (void)newname; return 1; }
/* ---------- mail.c ---------- */
__attribute__((weak))
int has_mail(long recipient) { (void)recipient; return 0; }
/* ---------- improved-edit.c ---------- */
__attribute__((weak))
void send_editor_help(struct descriptor_data *d) { (void)d; }
/* ---------- dg_scripts.c ---------- */
__attribute__((weak))
void add_to_lookup_table(long uid, void *c) { (void)uid; (void)c; }
__attribute__((weak))
void delete_variables(const char *charname) { (void)charname; }
__attribute__((weak))
void read_saved_vars(struct char_data *ch) { (void)ch; }
/* ---------- dg_triggers.c ---------- */
__attribute__((weak))
int greet_mtrigger(struct char_data *actor, int dir)
{ (void)actor; (void)dir; return 1; }
__attribute__((weak))
void greet_memory_mtrigger(struct char_data *actor) { (void)actor; }
__attribute__((weak))
int login_wtrigger(struct room_data *room, struct char_data *actor)
{ (void)room; (void)actor; return 1; }
__attribute__((weak))
int command_mtrigger(struct char_data *actor, char *cmd, char *argument)
{ (void)actor; (void)cmd; (void)argument; return 0; }
__attribute__((weak))
int command_otrigger(struct char_data *actor, char *cmd, char *argument)
{ (void)actor; (void)cmd; (void)argument; return 0; }
__attribute__((weak))
int command_wtrigger(struct char_data *actor, char *cmd, char *argument)
{ (void)actor; (void)cmd; (void)argument; return 0; }
/* ---------- act.informative.c ---------- */
__attribute__((weak))
void look_at_room(struct char_data *ch, int ignore_brief)
{ (void)ch; (void)ignore_brief; }
/* ---------- protocol.c ---------- */
__attribute__((weak))
void MXPSendTag(descriptor_t *apDescriptor, const char *apTag)
{ (void)apDescriptor; (void)apTag; }
__attribute__((weak))
void AddRecentPlayer(char *charname, char *host, bool newplr, bool cpover)
{ (void)charname; (void)host; (void)newplr; (void)cpover; }
/* ---------- OLC parse functions ---------- */
__attribute__((weak))
void aedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void cedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void hedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void ibtedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void medit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void msgedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void oedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void prefedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void qedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void redit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void sedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void trigedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
__attribute__((weak))
void zedit_parse(struct descriptor_data *d, char *arg) { (void)d; (void)arg; }
/* ---------- ACMD stubs for all do_* functions ----------
* These are function-pointer entries in the cmd_info[] table in interpreter.c.
* The table is DATA (not called at test time), but the linker still requires
* every symbol to resolve. Weak stubs satisfy the linker; the real do_*
* implementations would override them if act*.c were compiled. */
#define STUB_ACMD(name) \
__attribute__((weak)) ACMD(name) { (void)ch; (void)argument; (void)cmd; (void)subcmd; }
STUB_ACMD(do_action)
STUB_ACMD(do_advance)
STUB_ACMD(do_areas)
STUB_ACMD(do_assist)
STUB_ACMD(do_astat)
STUB_ACMD(do_at)
STUB_ACMD(do_attach)
STUB_ACMD(do_backstab)
STUB_ACMD(do_ban)
STUB_ACMD(do_bandage)
STUB_ACMD(do_bash)
STUB_ACMD(do_cast)
STUB_ACMD(do_changelog)
STUB_ACMD(do_checkloadstatus)
STUB_ACMD(do_commands)
STUB_ACMD(do_consider)
STUB_ACMD(do_copyover)
STUB_ACMD(do_date)
STUB_ACMD(do_dc)
STUB_ACMD(do_detach)
STUB_ACMD(do_diagnose)
STUB_ACMD(do_dig)
STUB_ACMD(do_display)
STUB_ACMD(do_drink)
STUB_ACMD(do_drop)
STUB_ACMD(do_eat)
STUB_ACMD(do_echo)
STUB_ACMD(do_enter)
STUB_ACMD(do_equipment)
STUB_ACMD(do_examine)
STUB_ACMD(do_exits)
STUB_ACMD(do_export_zone)
STUB_ACMD(do_file)
STUB_ACMD(do_flee)
STUB_ACMD(do_follow)
STUB_ACMD(do_force)
STUB_ACMD(do_gecho)
STUB_ACMD(do_gen_comm)
STUB_ACMD(do_gen_door)
STUB_ACMD(do_gen_ps)
STUB_ACMD(do_gen_tog)
STUB_ACMD(do_get)
STUB_ACMD(do_give)
STUB_ACMD(do_gold)
STUB_ACMD(do_goto)
STUB_ACMD(do_grab)
STUB_ACMD(do_group)
STUB_ACMD(do_gsay)
STUB_ACMD(do_happyhour)
STUB_ACMD(do_hcontrol)
STUB_ACMD(do_help)
STUB_ACMD(do_helpcheck)
STUB_ACMD(do_hide)
STUB_ACMD(do_hindex)
STUB_ACMD(do_history)
STUB_ACMD(do_hit)
STUB_ACMD(do_house)
STUB_ACMD(do_ibt)
STUB_ACMD(do_inventory)
STUB_ACMD(do_invis)
STUB_ACMD(do_kick)
STUB_ACMD(do_kill)
STUB_ACMD(do_last)
STUB_ACMD(do_leave)
STUB_ACMD(do_levels)
STUB_ACMD(do_links)
STUB_ACMD(do_load)
STUB_ACMD(do_look)
STUB_ACMD(do_map)
STUB_ACMD(do_masound)
STUB_ACMD(do_mat)
STUB_ACMD(do_mdamage)
STUB_ACMD(do_mdoor)
STUB_ACMD(do_mecho)
STUB_ACMD(do_mechoaround)
STUB_ACMD(do_mfollow)
STUB_ACMD(do_mforce)
STUB_ACMD(do_mforget)
STUB_ACMD(do_mgoto)
STUB_ACMD(do_mhunt)
STUB_ACMD(do_mjunk)
STUB_ACMD(do_mkill)
STUB_ACMD(do_mload)
STUB_ACMD(do_mlog)
STUB_ACMD(do_move)
STUB_ACMD(do_mpurge)
STUB_ACMD(do_mrecho)
STUB_ACMD(do_mremember)
STUB_ACMD(do_msend)
STUB_ACMD(do_msgedit)
STUB_ACMD(do_mteleport)
STUB_ACMD(do_mtransform)
STUB_ACMD(do_mzoneecho)
STUB_ACMD(do_not_here)
STUB_ACMD(do_oasis_aedit)
STUB_ACMD(do_oasis_cedit)
STUB_ACMD(do_oasis_copy)
STUB_ACMD(do_oasis_hedit)
STUB_ACMD(do_oasis_list)
STUB_ACMD(do_oasis_medit)
STUB_ACMD(do_oasis_oedit)
STUB_ACMD(do_oasis_prefedit)
STUB_ACMD(do_oasis_qedit)
STUB_ACMD(do_oasis_redit)
STUB_ACMD(do_oasis_sedit)
STUB_ACMD(do_oasis_trigedit)
STUB_ACMD(do_oasis_zedit)
STUB_ACMD(do_order)
STUB_ACMD(do_oset)
STUB_ACMD(do_page)
STUB_ACMD(do_peace)
STUB_ACMD(do_plist)
STUB_ACMD(do_pour)
STUB_ACMD(do_practice)
STUB_ACMD(do_purge)
STUB_ACMD(do_put)
STUB_ACMD(do_qcomm)
STUB_ACMD(do_quest)
STUB_ACMD(do_quit)
STUB_ACMD(do_reboot)
STUB_ACMD(do_recent)
STUB_ACMD(do_remove)
STUB_ACMD(do_reply)
STUB_ACMD(do_report)
STUB_ACMD(do_rescue)
STUB_ACMD(do_rest)
STUB_ACMD(do_restore)
STUB_ACMD(do_return)
STUB_ACMD(do_sac)
STUB_ACMD(do_save)
STUB_ACMD(do_saveall)
STUB_ACMD(do_say)
STUB_ACMD(do_scan)
STUB_ACMD(do_score)
STUB_ACMD(do_send)
STUB_ACMD(do_set)
STUB_ACMD(do_show)
STUB_ACMD(do_show_save_list)
STUB_ACMD(do_shutdown)
STUB_ACMD(do_sit)
STUB_ACMD(do_skillset)
STUB_ACMD(do_sleep)
STUB_ACMD(do_sneak)
STUB_ACMD(do_snoop)
STUB_ACMD(do_spec_comm)
STUB_ACMD(do_split)
STUB_ACMD(do_stand)
/* do_start has a different prototype than ACMD — it's called directly */
__attribute__((weak))
void do_start(struct char_data *ch) { (void)ch; }
STUB_ACMD(do_stat)
STUB_ACMD(do_steal)
STUB_ACMD(do_switch)
STUB_ACMD(do_tedit)
STUB_ACMD(do_teleport)
STUB_ACMD(do_tell)
STUB_ACMD(do_time)
STUB_ACMD(do_title)
STUB_ACMD(do_toggle)
STUB_ACMD(do_track)
STUB_ACMD(do_trans)
STUB_ACMD(do_tstat)
STUB_ACMD(do_unban)
STUB_ACMD(do_unfollow)
STUB_ACMD(do_use)
STUB_ACMD(do_users)
STUB_ACMD(do_vdelete)
STUB_ACMD(do_visible)
STUB_ACMD(do_vnum)
STUB_ACMD(do_vstat)
STUB_ACMD(do_wake)
STUB_ACMD(do_wear)
STUB_ACMD(do_weather)
STUB_ACMD(do_where)
STUB_ACMD(do_whirlwind)
STUB_ACMD(do_who)
STUB_ACMD(do_whois)
STUB_ACMD(do_wield)
STUB_ACMD(do_wizhelp)
STUB_ACMD(do_wizlock)
STUB_ACMD(do_wiznet)
STUB_ACMD(do_wizupdate)
STUB_ACMD(do_wizutil)
STUB_ACMD(do_write)
STUB_ACMD(do_zcheck)
STUB_ACMD(do_zlock)
STUB_ACMD(do_zpurge)
STUB_ACMD(do_zreset)
STUB_ACMD(do_zunlock)
#undef STUB_ACMD
+482
View File
@@ -0,0 +1,482 @@
/**
* @file test_utils.c
* Unit tests for pure / near-pure functions in src/utils.c
*/
#include "unity.h"
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
/* Redirect mud log output so basic_mud_vlog() doesn't print the
* "SYSERR: Using log() before stream was initialized!" warning. */
extern FILE *logfile;
void setUp(void) { logfile = stderr; }
void tearDown(void) { logfile = NULL; }
/* =========================================================
* prune_crlf
* ========================================================= */
void test_prune_crlf_strips_crlf(void)
{
char s[] = "hello\r\n";
prune_crlf(s);
TEST_ASSERT_EQUAL_STRING("hello", s);
}
void test_prune_crlf_strips_lf_only(void)
{
char s[] = "hello\n";
prune_crlf(s);
TEST_ASSERT_EQUAL_STRING("hello", s);
}
void test_prune_crlf_no_op_on_clean(void)
{
char s[] = "hello";
prune_crlf(s);
TEST_ASSERT_EQUAL_STRING("hello", s);
}
void test_prune_crlf_multiple_trailing(void)
{
char s[] = "hi\r\n\r\n";
prune_crlf(s);
TEST_ASSERT_EQUAL_STRING("hi", s);
}
/* =========================================================
* str_cmp (may be an alias for strcasecmp on this platform)
* ========================================================= */
void test_str_cmp_equal_strings(void)
{
TEST_ASSERT_EQUAL_INT(0, str_cmp("hello", "hello"));
}
void test_str_cmp_case_insensitive(void)
{
TEST_ASSERT_EQUAL_INT(0, str_cmp("Hello", "hello"));
TEST_ASSERT_EQUAL_INT(0, str_cmp("HELLO", "hello"));
}
void test_str_cmp_ordering_less(void)
{
TEST_ASSERT_LESS_THAN(0, str_cmp("a", "b"));
}
void test_str_cmp_ordering_greater(void)
{
TEST_ASSERT_GREATER_THAN(0, str_cmp("b", "a"));
}
void test_str_cmp_empty_equal(void)
{
TEST_ASSERT_EQUAL_INT(0, str_cmp("", ""));
}
/* =========================================================
* strn_cmp (may be an alias for strncasecmp on this platform)
* ========================================================= */
void test_strn_cmp_equal_prefix(void)
{
TEST_ASSERT_EQUAL_INT(0, strn_cmp("hello", "hello world", 5));
}
void test_strn_cmp_differ_past_n(void)
{
/* First 5 chars same, so strn_cmp("hello!", "hellox", 5) == 0 */
TEST_ASSERT_EQUAL_INT(0, strn_cmp("hello!", "hellox", 5));
}
void test_strn_cmp_differ_within_n(void)
{
TEST_ASSERT_NOT_EQUAL(0, strn_cmp("abc", "xyz", 3));
}
/* =========================================================
* sprintbit
* ========================================================= */
void test_sprintbit_no_bits_set(void)
{
static const char *names[] = { "FLAG_A", "FLAG_B", "\n" };
char result[256];
sprintbit(0, names, result, sizeof(result));
TEST_ASSERT_EQUAL_STRING("NOBITS ", result);
}
void test_sprintbit_single_bit(void)
{
static const char *names[] = { "FLAG_A", "FLAG_B", "\n" };
char result[256];
sprintbit(1, names, result, sizeof(result));
TEST_ASSERT_EQUAL_STRING("FLAG_A ", result);
}
void test_sprintbit_multiple_bits(void)
{
static const char *names[] = { "FLAG_A", "FLAG_B", "\n" };
char result[256];
sprintbit(3, names, result, sizeof(result));
TEST_ASSERT_EQUAL_STRING("FLAG_A FLAG_B ", result);
}
void test_sprintbit_undefined_bit(void)
{
/* Bit 2 is beyond the named array should produce "UNDEFINED" */
static const char *names[] = { "FLAG_A", "FLAG_B", "\n" };
char result[256];
sprintbit(4, names, result, sizeof(result));
TEST_ASSERT_EQUAL_STRING("UNDEFINED ", result);
}
/* =========================================================
* sprinttype
* ========================================================= */
void test_sprinttype_valid_index_zero(void)
{
static const char *names[] = { "ZERO", "ONE", "\n" };
char result[64];
sprinttype(0, names, result, sizeof(result));
TEST_ASSERT_EQUAL_STRING("ZERO", result);
}
void test_sprinttype_valid_index_one(void)
{
static const char *names[] = { "ZERO", "ONE", "\n" };
char result[64];
sprinttype(1, names, result, sizeof(result));
TEST_ASSERT_EQUAL_STRING("ONE", result);
}
void test_sprinttype_out_of_range(void)
{
static const char *names[] = { "ZERO", "ONE", "\n" };
char result[64];
sprinttype(5, names, result, sizeof(result));
TEST_ASSERT_EQUAL_STRING("UNDEFINED", result);
}
/* =========================================================
* levenshtein_distance
* ========================================================= */
void test_levenshtein_identical_strings(void)
{
TEST_ASSERT_EQUAL_INT(0, levenshtein_distance("hello", "hello"));
}
void test_levenshtein_empty_and_nonempty(void)
{
TEST_ASSERT_EQUAL_INT(5, levenshtein_distance("", "hello"));
TEST_ASSERT_EQUAL_INT(5, levenshtein_distance("hello", ""));
}
void test_levenshtein_single_insertion(void)
{
TEST_ASSERT_EQUAL_INT(1, levenshtein_distance("abc", "abcd"));
}
void test_levenshtein_single_deletion(void)
{
TEST_ASSERT_EQUAL_INT(1, levenshtein_distance("abcd", "abc"));
}
void test_levenshtein_single_substitution(void)
{
TEST_ASSERT_EQUAL_INT(1, levenshtein_distance("abc", "axc"));
}
void test_levenshtein_both_empty(void)
{
TEST_ASSERT_EQUAL_INT(0, levenshtein_distance("", ""));
}
/* =========================================================
* count_color_chars
* ========================================================= */
void test_count_color_chars_no_codes(void)
{
TEST_ASSERT_EQUAL_INT(0, count_color_chars("hello"));
}
void test_count_color_chars_empty(void)
{
TEST_ASSERT_EQUAL_INT(0, count_color_chars(""));
}
void test_count_color_chars_single_color_code(void)
{
/* "\tR" is a two-char color escape; both are skipped (counted as overhead) */
TEST_ASSERT_EQUAL_INT(2, count_color_chars("\tR"));
}
void test_count_color_chars_double_tab(void)
{
/* "\t\t" is an escaped literal tab; costs 1 overhead char */
TEST_ASSERT_EQUAL_INT(1, count_color_chars("\t\t"));
}
void test_count_color_chars_mixed(void)
{
/* "\tRhello" → 2 overhead + 0 for "hello" */
TEST_ASSERT_EQUAL_INT(2, count_color_chars("\tRhello"));
}
/* =========================================================
* count_non_protocol_chars
* ========================================================= */
void test_count_non_protocol_chars_plain(void)
{
TEST_ASSERT_EQUAL_INT(5, count_non_protocol_chars("hello"));
}
void test_count_non_protocol_chars_empty(void)
{
TEST_ASSERT_EQUAL_INT(0, count_non_protocol_chars(""));
}
void test_count_non_protocol_chars_newlines_skipped(void)
{
TEST_ASSERT_EQUAL_INT(5, count_non_protocol_chars("\r\nhello"));
}
void test_count_non_protocol_chars_bracket_tag(void)
{
/* "@[bold]hi" "@[bold]" is a protocol tag; only "hi" counted */
TEST_ASSERT_EQUAL_INT(2, count_non_protocol_chars("@[bold]hi"));
}
/* =========================================================
* atoidx
* ========================================================= */
void test_atoidx_valid_number(void)
{
TEST_ASSERT_EQUAL_INT(42, (int)atoidx("42"));
}
void test_atoidx_zero(void)
{
TEST_ASSERT_EQUAL_INT(0, (int)atoidx("0"));
}
void test_atoidx_negative_returns_nowhere(void)
{
TEST_ASSERT_EQUAL_INT((int)NOWHERE, (int)atoidx("-1"));
}
void test_atoidx_overflow_returns_nowhere(void)
{
/* IDXTYPE_MAX is 65535 on this build; a larger value overflows */
TEST_ASSERT_EQUAL_INT((int)NOWHERE, (int)atoidx("99999999"));
}
/* =========================================================
* right_trim_whitespace
* ========================================================= */
void test_right_trim_whitespace_trailing_spaces(void)
{
char *r = right_trim_whitespace("hello ");
TEST_ASSERT_EQUAL_STRING("hello", r);
free(r);
}
void test_right_trim_whitespace_no_trailing(void)
{
char *r = right_trim_whitespace("hello");
TEST_ASSERT_EQUAL_STRING("hello", r);
free(r);
}
void test_right_trim_whitespace_all_whitespace(void)
{
char *r = right_trim_whitespace(" ");
TEST_ASSERT_EQUAL_STRING("", r);
free(r);
}
void test_right_trim_whitespace_empty(void)
{
char *r = right_trim_whitespace("");
TEST_ASSERT_EQUAL_STRING("", r);
free(r);
}
/* =========================================================
* remove_from_string
* ========================================================= */
void test_remove_from_string_word_present(void)
{
char s[] = "hello world";
remove_from_string(s, "world");
/* "world" and the trailing NUL shift left; "hello " remains */
TEST_ASSERT_EQUAL_STRING("hello ", s);
}
void test_remove_from_string_word_absent(void)
{
char s[] = "hello world";
remove_from_string(s, "nope");
TEST_ASSERT_EQUAL_STRING("hello world", s);
}
void test_remove_from_string_word_at_start(void)
{
char s[] = "hello world";
remove_from_string(s, "hello");
/* "hello" removed; " world" remains */
TEST_ASSERT_EQUAL_STRING(" world", s);
}
/* =========================================================
* real_time_passed
* ========================================================= */
void test_real_time_passed_hours(void)
{
time_t base = 1000000;
struct time_info_data *t = real_time_passed(base + 3 * SECS_PER_REAL_HOUR, base);
TEST_ASSERT_EQUAL_INT(3, t->hours);
TEST_ASSERT_EQUAL_INT(0, t->day);
}
void test_real_time_passed_days(void)
{
time_t base = 1000000;
struct time_info_data *t = real_time_passed(base + 2 * SECS_PER_REAL_DAY + SECS_PER_REAL_HOUR, base);
TEST_ASSERT_EQUAL_INT(1, t->hours);
TEST_ASSERT_EQUAL_INT(2, t->day);
}
/* =========================================================
* mud_time_passed
* ========================================================= */
void test_mud_time_passed_hours(void)
{
time_t base = 1000000;
struct time_info_data *t = mud_time_passed(base + 2 * SECS_PER_MUD_HOUR, base);
TEST_ASSERT_EQUAL_INT(2, t->hours);
TEST_ASSERT_EQUAL_INT(0, t->day);
TEST_ASSERT_EQUAL_INT(0, t->month);
TEST_ASSERT_EQUAL_INT(0, t->year);
}
void test_mud_time_passed_days(void)
{
time_t base = 1000000;
struct time_info_data *t = mud_time_passed(base + SECS_PER_MUD_DAY, base);
TEST_ASSERT_EQUAL_INT(0, t->hours);
TEST_ASSERT_EQUAL_INT(1, t->day);
TEST_ASSERT_EQUAL_INT(0, t->month);
TEST_ASSERT_EQUAL_INT(0, t->year);
}
void test_mud_time_passed_months(void)
{
time_t base = 1000000;
struct time_info_data *t = mud_time_passed(base + SECS_PER_MUD_MONTH, base);
TEST_ASSERT_EQUAL_INT(0, t->hours);
TEST_ASSERT_EQUAL_INT(0, t->day);
TEST_ASSERT_EQUAL_INT(1, t->month);
TEST_ASSERT_EQUAL_INT(0, t->year);
}
/* =========================================================
* main
* ========================================================= */
int main(void)
{
UNITY_BEGIN();
/* prune_crlf */
RUN_TEST(test_prune_crlf_strips_crlf);
RUN_TEST(test_prune_crlf_strips_lf_only);
RUN_TEST(test_prune_crlf_no_op_on_clean);
RUN_TEST(test_prune_crlf_multiple_trailing);
/* str_cmp */
RUN_TEST(test_str_cmp_equal_strings);
RUN_TEST(test_str_cmp_case_insensitive);
RUN_TEST(test_str_cmp_ordering_less);
RUN_TEST(test_str_cmp_ordering_greater);
RUN_TEST(test_str_cmp_empty_equal);
/* strn_cmp */
RUN_TEST(test_strn_cmp_equal_prefix);
RUN_TEST(test_strn_cmp_differ_past_n);
RUN_TEST(test_strn_cmp_differ_within_n);
/* sprintbit */
RUN_TEST(test_sprintbit_no_bits_set);
RUN_TEST(test_sprintbit_single_bit);
RUN_TEST(test_sprintbit_multiple_bits);
RUN_TEST(test_sprintbit_undefined_bit);
/* sprinttype */
RUN_TEST(test_sprinttype_valid_index_zero);
RUN_TEST(test_sprinttype_valid_index_one);
RUN_TEST(test_sprinttype_out_of_range);
/* levenshtein_distance */
RUN_TEST(test_levenshtein_identical_strings);
RUN_TEST(test_levenshtein_empty_and_nonempty);
RUN_TEST(test_levenshtein_single_insertion);
RUN_TEST(test_levenshtein_single_deletion);
RUN_TEST(test_levenshtein_single_substitution);
RUN_TEST(test_levenshtein_both_empty);
/* count_color_chars */
RUN_TEST(test_count_color_chars_no_codes);
RUN_TEST(test_count_color_chars_empty);
RUN_TEST(test_count_color_chars_single_color_code);
RUN_TEST(test_count_color_chars_double_tab);
RUN_TEST(test_count_color_chars_mixed);
/* count_non_protocol_chars */
RUN_TEST(test_count_non_protocol_chars_plain);
RUN_TEST(test_count_non_protocol_chars_empty);
RUN_TEST(test_count_non_protocol_chars_newlines_skipped);
RUN_TEST(test_count_non_protocol_chars_bracket_tag);
/* atoidx */
RUN_TEST(test_atoidx_valid_number);
RUN_TEST(test_atoidx_zero);
RUN_TEST(test_atoidx_negative_returns_nowhere);
RUN_TEST(test_atoidx_overflow_returns_nowhere);
/* right_trim_whitespace */
RUN_TEST(test_right_trim_whitespace_trailing_spaces);
RUN_TEST(test_right_trim_whitespace_no_trailing);
RUN_TEST(test_right_trim_whitespace_all_whitespace);
RUN_TEST(test_right_trim_whitespace_empty);
/* remove_from_string */
RUN_TEST(test_remove_from_string_word_present);
RUN_TEST(test_remove_from_string_word_absent);
RUN_TEST(test_remove_from_string_word_at_start);
/* real_time_passed */
RUN_TEST(test_real_time_passed_hours);
RUN_TEST(test_real_time_passed_days);
/* mud_time_passed */
RUN_TEST(test_mud_time_passed_hours);
RUN_TEST(test_mud_time_passed_days);
RUN_TEST(test_mud_time_passed_months);
return UNITY_END();
}
+80
View File
@@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""Convert Unity test-runner output to JUnit XML.
Usage:
./test_binary | python3 unity_to_junit.py <suite_name> <output.xml> [elapsed_seconds]
Unity emits one result line per test:
path/to/file.c:LINE:TEST_NAME:PASS
path/to/file.c:LINE:TEST_NAME:FAIL:message
path/to/file.c:LINE:TEST_NAME:IGNORE:message
followed by a summary line:
N Tests N Failures N Ignored
"""
import re
import sys
import xml.etree.ElementTree as ET
def parse_unity(lines):
tests = []
total = failures = ignored = 0
for line in lines:
line = line.rstrip("\n")
m = re.match(
r"^.+:\d+:([^:]+):(PASS|FAIL|IGNORE)(?::(.*))?$", line
)
if m:
name, result, message = m.group(1), m.group(2), m.group(3) or ""
tests.append((name, result, message))
continue
m2 = re.match(r"^(\d+) Tests (\d+) Failures (\d+) Ignored", line)
if m2:
total, failures, ignored = int(m2.group(1)), int(m2.group(2)), int(m2.group(3))
if not total:
total = len(tests)
failures = sum(1 for _, r, _ in tests if r == "FAIL")
ignored = sum(1 for _, r, _ in tests if r == "IGNORE")
return tests, total, failures, ignored
def build_xml(suite_name, tests, total, failures, ignored, elapsed):
# Distribute total time evenly across tests for per-testcase timing.
per_test = round(elapsed / total, 6) if total else 0.0
suite = ET.Element(
"testsuite",
name=suite_name,
tests=str(total),
failures=str(failures),
errors="0",
skipped=str(ignored),
time=f"{elapsed:.6f}",
)
for name, result, message in tests:
case = ET.SubElement(
suite, "testcase",
name=name, classname=suite_name, time=f"{per_test:.6f}",
)
if result == "FAIL":
f = ET.SubElement(case, "failure", message=message)
f.text = message
elif result == "IGNORE":
ET.SubElement(case, "skipped", message=message)
return ET.ElementTree(suite)
def main():
if len(sys.argv) < 3 or len(sys.argv) > 4:
print(f"usage: {sys.argv[0]} <suite_name> <output.xml> [elapsed_seconds]", file=sys.stderr)
sys.exit(1)
suite_name, output_file = sys.argv[1], sys.argv[2]
elapsed = float(sys.argv[3]) if len(sys.argv) == 4 else 0.0
tests, total, failures, ignored = parse_unity(sys.stdin.readlines())
tree = build_xml(suite_name, tests, total, failures, ignored, elapsed)
ET.indent(tree, space=" ")
tree.write(output_file, encoding="unicode", xml_declaration=True)
if __name__ == "__main__":
main()
+2637
View File
File diff suppressed because it is too large Load Diff
+698
View File
@@ -0,0 +1,698 @@
/* =========================================================================
Unity - A Test Framework for C
ThrowTheSwitch.org
Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
SPDX-License-Identifier: MIT
========================================================================= */
#ifndef UNITY_FRAMEWORK_H
#define UNITY_FRAMEWORK_H
#define UNITY
#define UNITY_VERSION_MAJOR 2
#define UNITY_VERSION_MINOR 6
#define UNITY_VERSION_BUILD 3
#define UNITY_VERSION ((UNITY_VERSION_MAJOR << 16) | (UNITY_VERSION_MINOR << 8) | UNITY_VERSION_BUILD)
#ifdef __cplusplus
extern "C"
{
#endif
#include "unity_internals.h"
/*-------------------------------------------------------
* Test Setup / Teardown
*-------------------------------------------------------*/
/* These functions are intended to be called before and after each test.
* If using unity directly, these will need to be provided for each test
* executable built. If you are using the test runner generator and/or
* Ceedling, these are optional. */
void setUp(void);
void tearDown(void);
/* These functions are intended to be called at the beginning and end of an
* entire test suite. suiteTearDown() is passed the number of tests that
* failed, and its return value becomes the exit code of main(). If using
* Unity directly, you're in charge of calling these if they are desired.
* If using Ceedling or the test runner generator, these will be called
* automatically if they exist. */
void suiteSetUp(void);
int suiteTearDown(int num_failures);
/*-------------------------------------------------------
* Test Reset and Verify
*-------------------------------------------------------*/
/* These functions are intended to be called before or during tests in order
* to support complex test loops, etc. Both are NOT built into Unity. Instead
* the test runner generator will create them. resetTest will run teardown and
* setup again, verifying any end-of-test needs between. verifyTest will only
* run the verification. */
void resetTest(void);
void verifyTest(void);
/*-------------------------------------------------------
* Configuration Options
*-------------------------------------------------------
* All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above.
* Integers/longs/pointers
* - Unity attempts to automatically discover your integer sizes
* - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in <stdint.h>
* - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in <limits.h>
* - If you cannot use the automatic methods above, you can force Unity by using these options:
* - define UNITY_SUPPORT_64
* - set UNITY_INT_WIDTH
* - set UNITY_LONG_WIDTH
* - set UNITY_POINTER_WIDTH
* Floats
* - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons
* - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT
* - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats
* - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons
* - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default)
* - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE
* - define UNITY_DOUBLE_TYPE to specify something other than double
* - define UNITY_EXCLUDE_FLOAT_PRINT to trim binary size, won't print floating point values in errors
* Output
* - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired
* - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure
* Optimization
* - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge
* - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests.
* Test Cases
* - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script
* Parameterized Tests
* - you'll want to create a define of TEST_CASE(...), TEST_RANGE(...) and/or TEST_MATRIX(...) which basically evaluates to nothing
* Tests with Arguments
* - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity
*-------------------------------------------------------
* Basic Fail and Ignore
*-------------------------------------------------------*/
#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message))
#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL)
#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message))
#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL)
#define TEST_MESSAGE(message) UnityMessage((message), __LINE__)
#define TEST_ONLY()
#ifdef UNITY_INCLUDE_PRINT_FORMATTED
#define TEST_PRINTF(message, ...) UnityPrintF(__LINE__, (message), ##__VA_ARGS__)
#endif
/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails.
* This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */
#define TEST_PASS() TEST_ABORT()
#define TEST_PASS_MESSAGE(message) do { UnityMessage((message), __LINE__); TEST_ABORT(); } while (0)
/*-------------------------------------------------------
* Build Directives
*-------------------------------------------------------
* These macros do nothing, but they are useful for additional build context.
* Tools (like Ceedling) can scan for these directives and make use of them for
* per-test-executable #include search paths and linking. */
/* Add source files to a test executable's compilation and linking. Ex: TEST_SOURCE_FILE("sandwiches.c") */
#define TEST_SOURCE_FILE(a)
/* Customize #include search paths for a test executable's compilation. Ex: TEST_INCLUDE_PATH("src/module_a/inc") */
#define TEST_INCLUDE_PATH(a)
/*-------------------------------------------------------
* Test Asserts (simple)
*-------------------------------------------------------*/
/* Boolean */
#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE")
#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE")
#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE")
#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE")
#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL")
#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL")
#define TEST_ASSERT_EMPTY(pointer) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, " Expected Empty")
#define TEST_ASSERT_NOT_EMPTY(pointer) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, " Expected Non-Empty")
/* Integers (of all sizes) */
#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_size_t(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_CHAR(expected, actual) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT)(0), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(-1), (actual), __LINE__, NULL)
#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((UNITY_UINT)1 << (bit)), (UNITY_UINT)(0), (actual), __LINE__, NULL)
/* Integer Not Equal To (of all sizes) */
#define TEST_ASSERT_NOT_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_INT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_size_t(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR(threshold, actual) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, NULL)
/* Integer Ranges (of all sizes) */
#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_size_t_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_CHAR_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, NULL)
/* Integer Array Ranges (of all sizes) */
#define TEST_ASSERT_INT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_INT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_UINT64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_size_t_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX8_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX16_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX32_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_HEX64_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
#define TEST_ASSERT_CHAR_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, NULL)
/* Structs and Strings */
#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL)
/* Arrays */
#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_size_t_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_CHAR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
/* Arrays Compared To Single Value */
#define TEST_ASSERT_EACH_EQUAL_INT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_INT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_UINT64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_size_t(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX8(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX16(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX32(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_HEX64(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_PTR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_STRING(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_MEMORY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_CHAR(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, NULL)
/* Floating Point (If Enabled) */
#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_FLOAT(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL)
/* Double (If Enabled) */
#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_NOT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_NOT_WITHIN((delta), (expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN(delta, expected, actual, num_elements) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_EACH_EQUAL_DOUBLE(expected, actual, num_elements) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, NULL)
#define TEST_ASSERT_GREATER_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_THAN_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE(threshold, actual) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL)
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL)
/* Shorthand */
#ifdef UNITY_SHORTHAND_AS_OLD
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
#endif
#ifdef UNITY_SHORTHAND_AS_INT
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_MEM
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, NULL)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_RAW
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, " Expected Equal")
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal")
#endif
#ifdef UNITY_SHORTHAND_AS_NONE
#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
/*-------------------------------------------------------
* Test Asserts (with additional messages)
*-------------------------------------------------------*/
/* Boolean */
#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message))
#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message))
#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message))
#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message))
#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message))
#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message))
#define TEST_ASSERT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_EMPTY( (pointer), __LINE__, (message))
#define TEST_ASSERT_NOT_EMPTY_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_EMPTY((pointer), __LINE__, (message))
/* Integers (of all sizes) */
#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_size_t_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (UNITY_UINT32)(0), (actual), __LINE__, (message))
#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(-1), (actual), __LINE__, (message))
#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((UNITY_UINT32)1 << (bit)), (UNITY_UINT32)(0), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_CHAR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_CHAR((expected), (actual), __LINE__, (message))
/* Integer Not Equal To (of all sizes) */
#define TEST_ASSERT_NOT_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
/* Integer Greater Than/ Less Than (of all sizes) */
#define TEST_ASSERT_GREATER_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_THAN_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_INT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_INT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_UINT64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_size_t_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_UINT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX8_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX8((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX16_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX16((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX32_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX32((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_HEX64_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_HEX64((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_CHAR_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_SMALLER_OR_EQUAL_CHAR((threshold), (actual), __LINE__, (message))
/* Integer Ranges (of all sizes) */
#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_size_t_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_CHAR_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_CHAR_WITHIN((delta), (expected), (actual), __LINE__, (message))
/* Integer Array Ranges (of all sizes) */
#define TEST_ASSERT_INT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_INT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_INT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_UINT64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_size_t_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_UINT_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX8_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX8_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX16_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX16_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX32_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX32_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_HEX64_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_HEX64_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
#define TEST_ASSERT_CHAR_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_CHAR_ARRAY_WITHIN((delta), (expected), (actual), num_elements, __LINE__, (message))
/* Structs and Strings */
#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message))
#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message))
/* Arrays */
#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_size_t_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_CHAR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_CHAR_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
/* Arrays Compared To Single Value*/
#define TEST_ASSERT_EACH_EQUAL_INT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_INT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_INT64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_UINT64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_size_t_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_UINT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX8_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX8((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX16_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX16((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX32_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX32((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_HEX64_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_HEX64((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_PTR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_PTR((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_STRING_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_STRING((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_MEMORY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_MEMORY((expected), (actual), (len), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_CHAR_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_CHAR((expected), (actual), (num_elements), __LINE__, (message))
/* Floating Point (If Enabled) */
#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_FLOAT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_FLOAT_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_FLOAT_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_FLOAT((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_FLOAT_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_FLOAT((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message))
/* Double (If Enabled) */
#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message))
#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_NOT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_ARRAY_WITHIN_MESSAGE(delta, expected, actual, num_elements, message) UNITY_TEST_ASSERT_DOUBLE_ARRAY_WITHIN((delta), (expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_EACH_EQUAL_DOUBLE_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EACH_EQUAL_DOUBLE((expected), (actual), (num_elements), __LINE__, (message))
#define TEST_ASSERT_GREATER_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_THAN_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_GREATER_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_THAN_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_THAN_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_LESS_OR_EQUAL_DOUBLE_MESSAGE(threshold, actual, message) UNITY_TEST_ASSERT_LESS_OR_EQUAL_DOUBLE((threshold), (actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message))
#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message))
/* Shorthand */
#ifdef UNITY_SHORTHAND_AS_OLD
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message))
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message))
#endif
#ifdef UNITY_SHORTHAND_AS_INT
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_MEM
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((&expected), (&actual), sizeof(expected), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
#ifdef UNITY_SHORTHAND_AS_RAW
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) == (actual)), __LINE__, message)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, message)
#endif
#ifdef UNITY_SHORTHAND_AS_NONE
#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_FAIL(__LINE__, UnityStrErrShorthand)
#endif
/* end of UNITY_FRAMEWORK_H */
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff