49 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 80b77808f3 Fix OS command injection in fix_filename() - use allowlist for safe chars
Agent-Logs-Url: https://github.com/tbamud/tbamud/sessions/a9e10199-b353-440a-ba26-279f0d0e42bf

Co-authored-by: welcor <357770+welcor@users.noreply.github.com>
2026-04-24 10:22:33 +00:00
copilot-swe-agent[bot] c5bed0e141 Initial plan 2026-04-24 10:16:38 +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
89 changed files with 9483 additions and 1012 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: on:
push: push:
branches: [ "master" ] branches: [ "master" ]
pull_request: pull_request_target:
branches: [ "master" ] branches: [ "master" ]
permissions:
contents: read
checks: write
pull-requests: write
jobs: jobs:
build: build:
@@ -16,4 +21,15 @@ jobs:
- name: configure - name: configure
run: ./configure run: ./configure
- name: build - 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/Makefile
src/conf.h src/conf.h
src/util/Makefile src/util/Makefile
tests/Makefile
src/.accepted src/.accepted
src/depend src/depend
src/util/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. 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(vsnprintf)
AC_CHECK_PROTO(write) 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" echo "Configuration completed. To compile, type: cd src; make"
Vendored
+13 -4
View File
@@ -1227,11 +1227,21 @@ if eval "test \"`echo '$ac_cv_func_'crypt`\" = yes"; then
cat >> confdefs.h <<\EOF cat >> confdefs.h <<\EOF
#define CIRCLE_CRYPT 1 #define CIRCLE_CRYPT 1
EOF EOF
CRYPTLIB="-lcrypt"
echo "CRYPTLIB set to: $CRYPTLIB" 1>&6
else else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
echo "configure:1235: checking for crypt in -lcrypt" >&5 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_%'` ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@@ -1261,7 +1271,6 @@ else
fi fi
rm -f conftest* rm -f conftest*
LIBS="$ac_save_LIBS" LIBS="$ac_save_LIBS"
fi fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6 echo "$ac_t""yes" 1>&6
@@ -1269,11 +1278,11 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
#define CIRCLE_CRYPT 1 #define CIRCLE_CRYPT 1
EOF EOF
CRYPTLIB="-lcrypt" CRYPTLIB="-lcrypt"
echo "CRYPTLIB set to: $CRYPTLIB on Linux" 1>&6
else else
echo "$ac_t""no" 1>&6 echo "$ac_t""no" 1>&6
fi fi
fi
fi fi
@@ -5702,7 +5711,7 @@ EOF
cat >> $CONFIG_STATUS <<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 EOF
cat >> $CONFIG_STATUS <<\EOF cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then 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 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. 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? 2.3. I have questions about tbaMUD. Where should I go?
Stop by The Builder Academy at tbamud.com 9091 or the website at: 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 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? 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 With tbaMUD simply enter Cedit (configuration editor), select Game Play
Options. Then enable Player Killing. (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 4.16. Why does it say ``Connection closed by foreign host.'' and not
display the ``Byebye!'' message I'm trying to send before cutting display the ``Byebye!'' message I'm trying to send before cutting
+1 -1
View File
@@ -1,7 +1,7 @@
Updated: Apr 2007 Updated: Apr 2007
tbaMUD README 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: Information about CircleMUD can be found at the CircleMUD Home Page and FTP:
http://www.circlemud.org 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 1.1 Overview
The act() function is used to process and send strings of text to characters 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 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 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 character is. Once the text string passed to the function has been parsed, it
is capitalized and a newline is added to its tail. 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: These pieces are used as follows:
str: This is the basic string, a null terminated character array, including 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. characters designated by the targets.
hide_invisible: A TRUE or FALSE value indicating whether or not to hide the 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 is associated with. The character is used to determine the room for the output
of the action in question. 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 vict_obj: This can be either a character involved in the action, another
object, or even a predefined string of text. 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 *). null terminated character array (char *).
Do note, however, that obj and vict_obj are both ignored if there is no control 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 is set to TO_ROOM or TO_CHAR. In these cases, NULL should be supplied as the
input to the function. 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 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 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. 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 characters. However, instead of using the % symbol, act() uses the $ character
to indicate control characters. 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. ch is a PC, a NPC, or an invisible PC/NPC.
$N Like $n, except insert the text for vict_obj.* $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.* $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.* $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.* $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.* $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.* $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.* $A Like $a, for vict_obj.*
$T Prints the string pointed to by 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 $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 $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 (the word immediately after to the control code). If there is no following
word, no action is taken. word, no action is taken.
$$ Print the character $. $$ Print the character $.
NOTE*: vict_obj must be a pointer of type struct char_data *. 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. Coders of tbaMUD.
tbaMUD allows you to create colorful messages by using ANSI control sequences. 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 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 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 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 programmer must decide which messages will be colored for each of the color
levels. 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. 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 cyan and white. They are accessible by sending control sequences as part of
another string, for example: 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); "%d of your hands.\n\r", x, y, num_of_hands);
send_to_char(ch, buf); send_to_char(ch, buf);
In this example, x and y are the “on” and “off” sequences for the color you 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 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 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. (Conditional Color) series is recommended for most general use.
The name of the actual sequence starts with the name of its series, plus a 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 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 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 Some people who do not have ANSI-compatible terminals will see garbage
characters instead of colors. If the terminal correctly ignores ANSI color 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 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). 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 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 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 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 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 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: To illustrate the above, an example is in order:
@@ -76,29 +76,29 @@ ACMD(do_showcolor)
{ {
char buf[300]; 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), CCBLU(ch, C_CMP), CCNRM(ch, C_CMP), CCYEL(ch, C_NRM), CCNRM(ch, C_NRM),
CCRED(ch, C_SPR), CCNRM(ch, C_SPR)); CCRED(ch, C_SPR), CCNRM(ch, C_SPR));
send_to_char(ch, buf); send_to_char(ch, buf);
} }
What does this do? For people with color set to Complete, it prints: 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: 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: 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: 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: 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 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 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: “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)); 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 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 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. 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 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 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 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 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). 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 The Art of Debugging
Originally by Michael Chastain and Sammy 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 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, 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 such as specific filenames) because it offers good advice and insight into the
art and science of software engineering. More information about tbaMUD, art and science of software engineering. More information about tbaMUD,
can be found at the tbaMUD home page http://tbamud.com. 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, 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 experience and philosophy. No matter what your level, we hope that this
@@ -31,11 +31,11 @@ Play with it some more.
Read documentation again. Read documentation again.
Get the idea? Get the idea?
The idea is that your mind can accept only so much “new data” in a single 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 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” does transform data in your head from the “new” category to the “familiar”
category. Reading documentation doesnt make anything “familiar,” but it category. Reading documentation doesnt make anything “familiar,” but it
refills your “new” hopper. refills your “new” hopper.
Most people, if they even read documentation in the first place, never return 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 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. 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. files.
vi, emacs, jove use whatever editor floats your boat, but learn the hell out vi, emacs, jove use whatever editor floats your boat, but learn the hell out
of it; you should know every command in your editor. 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. in any source file.
>, >>, <, | input and output redirection at the command line; get someone to >, >>, <, | 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 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 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. behavior, and confirm or refute the hypothesis.
A good hypothesis is one which makes surprising predictions which then come 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 The first step in debugging is not to write bugs in the first place. This
sounds obvious, but sadly, is all too often ignored. 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 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 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 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. 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 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 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. 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 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. broken programs trying to find one bug at a time.
The next technique beyond desk-checking is the time-honored technique of 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 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 interesting values at interesting times. Where and when to dump these values
is an art, which you will learn only with practice. is an art, which you will learn only with practice.
If you dont already know how to redirect output in your operating system, now 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 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 about the “>” operator. You should also learn the difference between “standard
output” (for example, output from “printf”) and “standard error” (for example, output” (for example, output from “printf”) and “standard error” (for example,
output from “fprintf(stderr, ...)”). output from “fprintf(stderr, ...)”).
Ultimately, you cannot fix a program unless you understand how it is operating 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 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. can do that.
When you find a bug... your first impulse will be to change the code, kill the 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 bug, all the way down. You should grok the bug and cherish it in fullness
before causing its discorporation. before causing its discorporation.
Also, when finding a bug, ask yourself two questions: “What design and 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: 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?” “What habits would systematically prevent the introduction of bugs like this?”
5 Debugging: Tools 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 executes an illegal instruction, or (even more rarely) something else goes
wrong, the Unix operating system takes control. The process is incapable of wrong, the Unix operating system takes control. The process is incapable of
further execution and must be killed. Before killing the process, however, the 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. 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. 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 Its something the operating system does to help you find fatal problems which
have rendered your process unable to continue. 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 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 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 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 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 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. were calling it. The debugger will also list the arguments to these functions.
Interpreting these arguments, and using more advanced debugger features, Interpreting these arguments, and using more advanced debugger features,
@@ -343,12 +343,12 @@ new tools.
7 Profiling 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. spending most of its time. This can help you to make a program more efficient.
Here is how to profile a program: 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 make clean
2. Edit your Makefile, and change the PROFILE=line: 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 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 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. get profiling information.
5. Run the profcommand: 5. Run the profcommand:
prof bin/circle > prof.out prof bin/circle > prof.out
6. Read prof.out. Run “man prof” to understand the format of the output. For 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” 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 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 exactly how many times any function calls any other function. This information
is valuable for debugging as well as performance analysis. is valuable for debugging as well as performance analysis.
Availability of “prof” and “gprof” varies from system to system. Almost every Availability of “prof” and “gprof” varies from system to system. Almost every
Unix system has “prof”. Only some systems have “gprof”. Unix system has “prof”. Only some systems have “gprof”.
7 Books for Serious Programmers 7 Books for Serious Programmers
Out of all the thousands of books out there, three stand out: Out of all the thousands of books out there, three stand out:
Kernighan and Plaugher, “The Elements of Programming Style” Kernighan and Plaugher, “The Elements of Programming Style”
Kernighan and Ritchie, “The C Programming Language” Kernighan and Ritchie, “The C Programming Language”
Brooks, “The Mythical Man Month” 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 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 &). autorun - Shell script to run the MUD (./autorun &).
FAQ - Frequently Aske Questions with answers. FAQ - Frequently Aske Questions with answers.
@@ -16,7 +16,7 @@ lib/ - MUD data.
log/ - System logs. log/ - System logs.
src/ - Source code. 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. utilities, which are described in utils.txt.
The doc/ directory has its own README file, describing the contents of each 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: The lib/misc/ directory contains the following files:
bugs - Bugs reported by players with the bug command. bugs - Bugs reported by players with the bug command.
ideas - Ideas from players from idea command. ideas - Ideas from players from idea command.
messages - Spell and skill damage messages. messages - Spell and skill damage messages.
socials - Text file with text of the socials. socials - Text file with text of the socials.
socials.new - New format of socials you can edit via AEDIT. 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. xnames - Text file of invalid names.
The lib/plrobjs/ contains the following files and directories: The lib/plrobjs/ contains the following files and directories:
@@ -80,18 +80,18 @@ zzz/
The lib/text/ directory contains the following files: The lib/text/ directory contains the following files:
background - Background story (for option 3 from main menu). background - Background story (for option 3 from main menu).
credits - Text for credits command. credits - Text for credits command.
greetings - Greeting message. greetings - Greeting message.
handbook - Text for Immortal Handbook (handbook command). handbook - Text for Immortal Handbook (handbook command).
immlist - Text for immlist command. immlist - Text for immlist command.
imotd - Immortal MOTD --seen by immortals on login. 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. motd - MOTD --seen by mortals on login.
news - Text for news command. news - Text for news command.
policies - Text for policy command. policies - Text for policy command.
wizlist - Text for wizlist command. wizlist - Text for wizlist command.
/help/screen - Text for help command as a mortal with no arguments. /help/screen - Text for help command as a mortal with no arguments.
/help/iscreen - Text for help command an an immortal with no arguments. /help/iscreen - Text for help command an an immortal with no arguments.
The lib/world/directory contains the following subdirectories: The lib/world/directory contains the following subdirectories:
@@ -103,8 +103,8 @@ wld - Contains *.wld files (world files)
zon - Contains *.zon files (zone files) zon - Contains *.zon files (zone files)
Each of the 6 subdirectories in the lib/world/ directory also contains two Each of the 6 subdirectories in the lib/world/ directory also contains two
additional files one called index, which specifies which files in that additional files one called index, which specifies which files in that
directory should be loaded when the MUD boots, and index.mini, which 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 specifies which files should be loaded if the MUD is booted with the -m
(mini-mud) option. (mini-mud) option.
@@ -128,6 +128,6 @@ trigger - Trigedit log messages.
usage - Mud system usage (player load & memory usage info). usage - Mud system usage (player load & memory usage info).
The src/ directory contains all of the C and header files for the MUD, along 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 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. trying to make tbaMUD work on their platform.
tbaMUD should work on most UNIX platforms without any modifications; simply run 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 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 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 from a template called conf.h.in. A Makefile is also created from the template
Makefile.in. 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 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 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. 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 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 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 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 some of these steps, you can look at what we have done as an example (see the
files README.CYGWIN). files README.CYGWIN).
@@ -36,11 +36,11 @@ trying to port the code.
Porting the Code Porting the Code
Step 1. Create a “conf.h” file for your system. Copy the template “conf.h.in” 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 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, 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 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 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 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 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 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 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 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 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 make sure that your changes are stable. Make sure that automatic events such as
zone resets, point regeneration, and corpse decomposition are being timed zone resets, point regeneration, and corpse decomposition are being timed
correctly (a tick should be about 75 seconds). Try resetting all the zones 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. 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 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 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 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 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 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 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 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: you can create a patch file like this:
diff -u --new-file --recursive stock-tba/src my-tba/src > patch 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 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 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 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 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!! them. If your patches work, CELEBRATE!!
Step 6. Write a README file for your operating system that describes everything 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 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 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 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 3.2 ANSI C and GCC
As long as your system has an ANSI C compiler, all of the code (except for 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 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 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 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 something even if other players are trying to enter commands. If your system
does not implement non-blocking I/O correctly, try using the does not implement non-blocking I/O correctly, try using the
POSIX_NONBLOCK_BROKEN constant in sysdep.h. POSIX_NONBLOCK_BROKEN constant in sysdep.h.
3.4 Timing 3.4 Timing
tbaMUD needs a fairly precise (on the order of 5 or 10 ms) timer in order to 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 corpse decomposition, and other automatic tasks. If your system supports the
select() system call with sufficient precision, the default timing code should 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() supports for determining how much time has passed and replace the select()
timing method. timing method.
3.5 Signals and Signal Handlers 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 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 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 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 4 Final Note
IMPORTANT: Remember to keep any changes you make surrounded by #ifdef 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 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 (once you get them to work) will be suitable for incorporation into the
tbaMUD distribution, meaning that tbaMUD will officially support your platform. 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. available MUD source code.
tbaMUD Release history: tbaMUD Release history:
Version 2025 release: January, 2025
Version 2023 release: January, 2023 Version 2023 release: January, 2023
Version 2021 release: March, 2021 Version 2021 release: March, 2021
Version 2020 release: January, 2020 Version 2020 release: January, 2020
@@ -142,7 +143,7 @@ communication channels
totally ignores all commands from that player until they are thawed. totally ignores all commands from that player until they are thawed.
--Even handier DELETE flag allows you to delete players on the fly. --Even handier DELETE flag allows you to delete players on the fly.
--"set" command (mentioned above) allows you to freeze/unfreeze/ --"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; --Bad password attempts are written to the system log and saved;
if someone tries to hack your account, you see "4 LOGIN FAILURES if someone tries to hack your account, you see "4 LOGIN FAILURES
SINCE LAST SUCCESSFUL LOGIN" next time you log on. 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 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 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 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 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 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 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 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 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. does this automatically.
Examples: 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. are used to convert currently existing files into different formats.
Overall, these utilities have been created in an attempt to make the tbaMUD 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 further and more grandiose utilities to create. Some are no longer applicable
but are retained as examples. 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 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 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 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 world file at the appropriate points, where filename is the name of the file
for the following section. 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] autowiz <wizlev> <wizlistfile> <immlev> <immlistfile> [pid to signal]
where <wizlev> is equal to whatever LVL_GOD is set to in your tbaMUD server, 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. <wizlistfile> is the filename for the file containing the games Wizlist.
<immlev> should be set to your games LVL_IMMORT, while <immlistfile> <immlev> should be set to your games LVL_IMMORT, while <immlistfile>
is the name of the Immlist file. is the name of the Immlist file.
This utility must be recompiled if you make any changes to the player file structure. 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 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, Based on CircleMUD by Jeremy Elson and DikuMUD by Hans-Henrik Staerfeldt,
Katja Nyboe, Tom Madsen, Michael Seifert, and Sebastian Hammer 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 An autoquest is a quest that can be automatically started and completed
without the intervention of an immortal. Simply visit a questmaster and join 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. autoquests scattered throughout the World.
See Also: QUEST-FLAG, QUESTPOINTS See Also: QUEST-FLAG, QUESTPOINTS
@@ -1584,7 +1584,6 @@ qedit (quest editor)
questpoints questpoints
buildwalk buildwalk
dig dig
tell m-w (an in game dictionary lookup)
gemote gemote
history history
file file
@@ -2444,25 +2443,6 @@ Example:
> diagnose doctor > diagnose doctor
See also: CONSIDER, HIT, KILL 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 #31
DIG UNDIG RDIG RELINK RLINKS DIG UNDIG RDIG RELINK RLINKS
@@ -3173,7 +3153,7 @@ game.
Invest in a thesaurus. Makes a world of difference, and if that doesn't 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 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 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? 4. Where can I learn Trigedit?
Here! Welcor is now the developer of trigedit. We have extensive help files, 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 words can be particularly tricky and elude electronic spell checkers. A good
dictionary, however, will help you spell archaic words. Whenever I am building 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 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 proper spelling. We hope to add a thesaurus soon! Goto @Chttp://m-w.com/@n
soon! Goto @Chttp://m-w.com/@n until then. until then.
I have found that a good principle to make is to avoid the use of all 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 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 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 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 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, 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 When you qedit <vnum> to create a new quest (or edit an existing one), you will
see the menu in @RHELP QEDIT-MENU@n 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 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 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: of an accept message text could be something like:
The questmaster rummages in a large pile of papers. The questmaster rummages in a large pile of papers.
The questmaster says Ah, here it is The questmaster says "Ah, here it is"
The questmaster says Bob, the local butcher has offered this quest The questmaster says "Bob, the local butcher has offered this quest"
The questmaster shows you a hastily scrawled note, that reads: 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 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 Thanks, Bob the Butcher, Midgaard
The questmaster sighs. 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 #31
QEDIT-COMPLETED QEDIT-ABANDONED QEDIT-COMPLETED QEDIT-ABANDONED
@@ -7232,7 +7212,7 @@ all timed quests.
QEDIT-COMPLETION QEDIT-COMPLETION
Just like the accept message, this is simply text that is output on the 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 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 announced after this text is shown, so this text does not need to have that
information in it. information in it.
@@ -7258,7 +7238,7 @@ Quest flags: @cNOBITS@n
Enter quest flags, 0 to quit : Enter quest flags, 0 to quit :
Currently, only one flag is available, the REPEATABLE flag. When you have 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 #31
QEDIT-LEVELS QEDIT-LEVELS
@@ -7312,12 +7292,12 @@ QEDIT-NEXT
This is the quest vnum of next quest in a chain. When a player completes 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 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 #31
QEDIT-PREREQUISITE QEDIT-PREREQUISITE
This is the object vnum for a prerequisite object. The prerequisite object 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. quest. It is not taken from the player when the quest starts.
#31 #31
QEDIT-PREVIOUS QEDIT-PREVIOUS
@@ -7328,15 +7308,15 @@ completed by the player in order to join this quest.
QEDIT-QUANTITY QEDIT-QUANTITY
This is the number of times the player needs to repeat the quest. For 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 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 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 should be used with caution, however. In an object quest picking up the same
object 20 times will also complete the quest. object 20 times will also complete the quest.
#31 #31
QEDIT-QUIT QEDIT-MESSAGE QEDIT-QUIT QEDIT-MESSAGE
The quit message is sent to the player when they type quest leave. Players 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 page), so if they lose quest points, this text really should inform them of
that. that.
#31 #31
@@ -7365,14 +7345,14 @@ Room, Clear Room - Room VNUM
#31 #31
QEDIT-TIME 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 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 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. attempt), and then giving at least one extra 'tick' for players to complete it.
#31 #31
QEDIT-TYPE 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: main menu, you will be shown a list to choose from:
0) Object - Player needs to find a particular object. 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 - Show usage information for the quest command.
quest list - Used at the questmaster to see which quests are available. 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 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 leave - Allows the player to abandon the current quest, taking the quest point penalty.
quest history - Shows all previously completed non-repeatable quests. 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 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 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 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, 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 builders exist to ensure that the goals of play are supported by game
descriptions. 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 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 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 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 does deeply affect a character's development. No matter what kind of zone you
are building, keep it interesting throughout! 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 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 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 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 what you intended to have there all along. Novels have editors, and so
should any zone. 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 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 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. 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 Sometimes building can seem like a thankless job and sometimes building can be
building can be a reward in itself. Building a few areas, even a few good a reward in itself. Building a few areas, even a few good ones, does not make
ones, does not make you an Immortal or an Imp. It takes more than building to you an Immortal or an Imp. It takes more than building to be one of those and
be one of those and it entails even more work. Respect others and they will it entails even more work. Respect others and they will respect you. The more
respect you. The more detailed an area the better it is. Always choose Quality detailed an area the better it is. Always choose Quality over Quantity. Put
over Quantity. Put some pride in your areas, develop a style of your own. Try some pride in your areas, develop a style of your own. Try new things keep it
new things keep it interesting, if you become bored with building an area take interesting, if you become bored with building an area take a break and play a
a break and play a mortal or do something else, don't take advantage of builder mortal or do something else, don't take advantage of builder privileges.
privileges. Treat others as you wish to be treated. One more warning I would Treat others as you wish to be treated. One more warning I would give to
give to builders before they take things personally or get insulted. Everyone builders before they take things personally or get insulted. Everyone has their
has their own ideas on how to run a MUD, what it comes down to is whoever owns own ideas on how to run a MUD, what it comes down to is whoever owns the MUD
the MUD makes the final decision, so it does not matter how good you think your makes the final decision, so it does not matter how good you think your idea
idea is, it may never be used if the owner does not like it. Plain and simple. 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 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. force them onto anyone. Be constructive, not critical about peoples ideas.
Everyone is allowed their opinions. 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@ 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 SRCFILES := $(shell ls *.c | sort)
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 OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
default: all 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) if (!*buf || !*buf2)
send_to_char(ch, "Who do you wish to tell what??\r\n"); send_to_char(ch, "Who do you wish to tell what??\r\n");
else if (!strcmp(buf, "m-w")) { else if (GET_LEVEL(ch) < LVL_IMMORT && !(vict = get_player_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
#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)))
send_to_char(ch, "%s", CONFIG_NOPERSON); send_to_char(ch, "%s", CONFIG_NOPERSON);
else if (GET_LEVEL(ch) >= LVL_IMMORT && !(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_WORLD))) else if (GET_LEVEL(ch) >= LVL_IMMORT && !(vict = get_char_vis(ch, buf, NULL, FIND_CHAR_WORLD)))
send_to_char(ch, "%s", CONFIG_NOPERSON); send_to_char(ch, "%s", CONFIG_NOPERSON);
+111 -35
View File
@@ -46,10 +46,10 @@ 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_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); static void show_obj_modifiers(struct obj_data *obj, struct char_data *ch);
/* do_where utility functions */ /* 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 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 */ /* Subcommands */
/* For show_obj_to_char 'mode'. /-- arbitrary */ /* For show_obj_to_char 'mode'. /-- arbitrary */
#define SHOW_OBJ_LONG 0 #define SHOW_OBJ_LONG 0
@@ -519,17 +519,19 @@ void look_at_room(struct char_data *ch, int ignore_brief)
send_to_char(ch, "]"); send_to_char(ch, "]");
} }
} }
else { else
send_to_char(ch, "%s", world[IN_ROOM(ch)].name); send_to_char(ch, "%s", world[IN_ROOM(ch)].name);
send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM)); send_to_char(ch, "%s\r\n", CCNRM(ch, C_NRM));
if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief || if ((!IS_NPC(ch) && !PRF_FLAGGED(ch, PRF_BRIEF)) || ignore_brief ||
ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) { ROOM_FLAGGED(IN_ROOM(ch), ROOM_DEATH)) {
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch)) if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOMAP) && can_see_map(ch))
str_and_map(world[target_room].description, ch, target_room); str_and_map(world[target_room].description, ch, target_room);
else
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
} }
send_to_char(ch, "%s", world[IN_ROOM(ch)].description);
/*autoexits */ /*autoexits */
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT)) if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_AUTOEXIT))
@@ -539,7 +541,6 @@ void look_at_room(struct char_data *ch, int ignore_brief)
list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE); list_obj_to_char(world[IN_ROOM(ch)].contents, ch, SHOW_OBJ_LONG, FALSE);
list_char_to_char(world[IN_ROOM(ch)].people, ch); list_char_to_char(world[IN_ROOM(ch)].people, ch);
} }
}
static void look_in_direction(struct char_data *ch, int dir) static void look_in_direction(struct char_data *ch, int dir)
{ {
@@ -604,7 +605,8 @@ static void look_in_obj(struct char_data *ch, char *arg)
} }
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 */ send_to_char(ch, "Its contents seem somewhat murky.\r\n"); /* BUG */
else { else
{
char buf2[MAX_STRING_LENGTH]; char buf2[MAX_STRING_LENGTH];
amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0); amt = (GET_OBJ_VAL(obj, 1) * 3) / GET_OBJ_VAL(obj, 0);
sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2)); sprinttype(GET_OBJ_VAL(obj, 2), color_liquid, buf2, sizeof(buf2));
@@ -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, static size_t print_object_location(const int num, const obj_data *obj, const char_data *ch, // NOLINT(*-no-recursion)
int recur) char *buf, size_t len, const size_t buf_size, const int recur)
{ {
size_t nlen = 0;
if (num > 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 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 (SCRIPT(obj)) {
if (!TRIGGERS(SCRIPT(obj))->next) 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 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) 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); 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) else if (obj->carried_by) {
send_to_char(ch, "carried by %s%s\r\n", PERS(obj->carried_by, ch), QNRM); if (PRF_FLAGGED(ch, PRF_SHOWVNUMS))
else if (obj->worn_by) 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);
send_to_char(ch, "worn by %s%s\r\n", PERS(obj->worn_by, ch), QNRM); else
else if (obj->in_obj) { nlen = snprintf(buf + len, buf_size - len, "carried by %s%s\r\n", PERS(obj->carried_by, ch), QNRM);
send_to_char(ch, "inside %s%s%s\r\n", obj->in_obj->short_description, QNRM, (recur ? ", which is" : " ")); if (PRF_FLAGGED(ch, PRF_VERBOSE) && IN_ROOM(obj->carried_by) != NOWHERE && len + nlen < buf_size)
if (recur) 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);
print_object_location(0, obj->in_obj, ch, recur); } 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 } 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; char_data *i;
struct obj_data *k; obj_data *k;
struct descriptor_data *d; 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) { if (!*arg) {
send_to_char(ch, "Players Room Location Zone\r\n"); 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 { } 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) for (i = character_list; i; i = i->next)
if (CAN_SEE(ch, i) && IN_ROOM(i) != NOWHERE && isname(arg, i->player.name)) { if (CAN_SEE(ch, i) && IN_ROOM(i) != NOWHERE && isname(arg, i->player.name)) {
found = 1; 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); 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 (SCRIPT(i) && TRIGGERS(SCRIPT(i))) {
if (!TRIGGERS(SCRIPT(i))->next) 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 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;
} }
send_to_char(ch, "%s\r\n", QNRM); len += nlen;
} }
for (num = 0, k = object_list; k; k = k->next) 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;
}
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)) { if (CAN_SEE_OBJ(ch, k) && isname(arg, k->name)) {
found = 1; found = 1;
print_object_location(++num, k, ch, TRUE); 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) if (!found)
send_to_char(ch, "Couldn't find any such thing.\r\n"); send_to_char(ch, "Couldn't find any such thing.\r\n");
else
page_string(ch->desc, buf, TRUE);
} }
} }
@@ -1935,6 +2005,9 @@ ACMD(do_toggle)
{"pagelength", 0, 0, "\n", "\n"}, {"pagelength", 0, 0, "\n", "\n"},
{"screenwidth", 0, 0, "\n", "\n"}, {"screenwidth", 0, 0, "\n", "\n"},
{"color", 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 */ {"\n", 0, -1, "\n", "\n"} /* must be last */
}; };
@@ -1948,7 +2021,8 @@ ACMD(do_toggle)
if (!GET_WIMP_LEV(ch)) if (!GET_WIMP_LEV(ch))
strcpy(buf2, "OFF"); /* strcpy: OK */ strcpy(buf2, "OFF"); /* strcpy: OK */
else 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, send_to_char(ch,
@@ -1968,7 +2042,8 @@ ACMD(do_toggle)
" NoHassle: %-3s " " NoHassle: %-3s "
" Holylight: %-3s " " Holylight: %-3s "
" ShowVnums: %-3s\r\n" " ShowVnums: %-3s\r\n"
" Syslog: %-3s%s ", " Syslog: %-3s "
" Verbose: %-3s%s ",
ONOFF(PRF_FLAGGED(ch, PRF_BUILDWALK)), ONOFF(PRF_FLAGGED(ch, PRF_BUILDWALK)),
ONOFF(PRF_FLAGGED(ch, PRF_NOWIZ)), ONOFF(PRF_FLAGGED(ch, PRF_NOWIZ)),
@@ -1977,6 +2052,7 @@ ACMD(do_toggle)
ONOFF(PRF_FLAGGED(ch, PRF_HOLYLIGHT)), ONOFF(PRF_FLAGGED(ch, PRF_HOLYLIGHT)),
ONOFF(PRF_FLAGGED(ch, PRF_SHOWVNUMS)), ONOFF(PRF_FLAGGED(ch, PRF_SHOWVNUMS)),
types[(PRF_FLAGGED(ch, PRF_LOG1) ? 1 : 0) + (PRF_FLAGGED(ch, PRF_LOG2) ? 2 : 0)], 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"); GET_LEVEL(ch) == LVL_IMPL ? "" : "\r\n");
} }
if (GET_LEVEL(ch) >= LVL_IMPL) { if (GET_LEVEL(ch) >= LVL_IMPL) {
+78 -55
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) void name_from_drinkcon(struct obj_data *obj)
{ {
const char *liqname; 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)) if (!obj || (GET_OBJ_TYPE(obj) != ITEM_DRINKCON && GET_OBJ_TYPE(obj) != ITEM_FOUNTAIN))
return; 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); remove_from_string(obj->name, liqname);
new_name = right_trim_whitespace(obj->name); new_name = right_trim_whitespace(obj->name);
free(obj->name); free(obj->name);
obj->name = new_name; obj->name = new_name;
} }
void name_to_drinkcon(struct obj_data *obj, int type) 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; obj->name = new_name;
} }
ACMD(do_drink) ACMD(do_drink)
{ {
char arg[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH];
@@ -870,7 +882,7 @@ ACMD(do_drink)
send_to_char(ch, "Your stomach can't contain anymore!\r\n"); send_to_char(ch, "Your stomach can't contain anymore!\r\n");
return; return;
} }
if (GET_OBJ_VAL(temp, 1) < 1) { if (EMPTY_DRINK_CONTAINER(temp)) {
send_to_char(ch, "It is empty.\r\n"); send_to_char(ch, "It is empty.\r\n");
return; return;
} }
@@ -881,33 +893,38 @@ ACMD(do_drink)
if (subcmd == SCMD_DRINK) { if (subcmd == SCMD_DRINK) {
char buf[MAX_STRING_LENGTH]; 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); 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) if (drink_aff[DRINK_CON_TYPE(temp)][DRUNK] > 0)
amount = (25 - GET_COND(ch, THIRST)) / drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK]; amount = (25 - GET_COND(ch, THIRST)) / drink_aff[DRINK_CON_TYPE(temp)][DRUNK];
else else
amount = rand_number(3, 10); amount = rand_number(3, 10);
} else { } else {
act("$n sips from $p.", TRUE, ch, temp, 0, TO_ROOM); 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 = 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. */ /* 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 = MIN(amount, GET_OBJ_WEIGHT(temp));
weight_change_object(temp, -weight); /* Subtract amount */ weight_change_object(temp, -weight); /* Subtract amount */
} }
gain_condition(ch, DRUNK, drink_aff[GET_OBJ_VAL(temp, 2)][DRUNK] * amount / 4); gain_condition(ch, DRUNK, drink_aff[DRINK_CON_TYPE(temp)][DRUNK] * amount / 4);
gain_condition(ch, HUNGER, drink_aff[GET_OBJ_VAL(temp, 2)][HUNGER] * amount / 4); gain_condition(ch, HUNGER, drink_aff[DRINK_CON_TYPE(temp)][HUNGER] * amount / 4);
gain_condition(ch, THIRST, drink_aff[GET_OBJ_VAL(temp, 2)][THIRST] * amount / 4); gain_condition(ch, THIRST, drink_aff[DRINK_CON_TYPE(temp)][THIRST] * amount / 4);
if (GET_COND(ch, DRUNK) > 10) if (GET_COND(ch, DRUNK) > 10)
send_to_char(ch, "You feel drunk.\r\n"); send_to_char(ch, "You feel drunk.\r\n");
@@ -918,7 +935,7 @@ ACMD(do_drink)
if (GET_COND(ch, HUNGER) > 20) if (GET_COND(ch, HUNGER) > 20)
send_to_char(ch, "You are full.\r\n"); 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"); 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); 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); affect_join(ch, &af, FALSE, FALSE, FALSE, FALSE);
} }
/* Empty the container (unless unlimited), and no longer poison. */ /* Empty the container (unless unlimited), and no longer poison. */
if (GET_OBJ_VAL(temp, 0) > 0) { if (LIMITED_DRINK_CONTAINER(temp)) {
GET_OBJ_VAL(temp, 1) -= amount; amount = MIN(amount, DRINK_CON_NOW(temp)); // never subtract more than the current amount
if (!GET_OBJ_VAL(temp, 1)) { /* The last bit */ DRINK_CON_NOW(temp) -= amount;
if (!DRINK_CON_NOW(temp)) { /* The last bit */
name_from_drinkcon(temp); name_from_drinkcon(temp);
GET_OBJ_VAL(temp, 2) = 0; DRINK_CON_TYPE(temp) = 0;
GET_OBJ_VAL(temp, 3) = 0; DRINK_CON_POISON(temp) = 0;
} }
} }
return; return;
@@ -1061,7 +1079,7 @@ ACMD(do_pour)
return; 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); act("The $p is empty.", FALSE, ch, from_obj, 0, TO_CHAR);
return; return;
} }
@@ -1071,19 +1089,22 @@ ACMD(do_pour)
return; return;
} }
if (!str_cmp(arg2, "out")) { if (!str_cmp(arg2, "out")) {
if (GET_OBJ_VAL(from_obj, 0) > 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;
}
/* pour out */
act("$n empties $p.", TRUE, ch, from_obj, 0, TO_ROOM); act("$n empties $p.", TRUE, ch, from_obj, 0, TO_ROOM);
act("You empty $p.", FALSE, ch, from_obj, 0, TO_CHAR); act("You empty $p.", FALSE, ch, from_obj, 0, TO_CHAR);
weight_change_object(from_obj, -GET_OBJ_VAL(from_obj, 1)); /* Empty */ weight_change_object(from_obj, -DRINK_CON_NOW(from_obj)); /* Empty */
name_from_drinkcon(from_obj); name_from_drinkcon(from_obj);
GET_OBJ_VAL(from_obj, 1) = 0;
GET_OBJ_VAL(from_obj, 2) = 0; DRINK_CON_NOW(from_obj) = 0;
GET_OBJ_VAL(from_obj, 3) = 0; DRINK_CON_TYPE(from_obj) = 0;
} DRINK_CON_POISON(from_obj) = 0;
else
send_to_char(ch, "You can't possibly pour that container out!\r\n");
return; return;
} }
@@ -1091,8 +1112,7 @@ ACMD(do_pour)
send_to_char(ch, "You can't find it!\r\n"); send_to_char(ch, "You can't find it!\r\n");
return; return;
} }
if ((GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) && if ((GET_OBJ_TYPE(to_obj) != ITEM_DRINKCON) && (GET_OBJ_TYPE(to_obj) != ITEM_FOUNTAIN)) {
(GET_OBJ_TYPE(to_obj) != ITEM_FOUNTAIN)) {
send_to_char(ch, "You can't pour anything into that.\r\n"); send_to_char(ch, "You can't pour anything into that.\r\n");
return; return;
} }
@@ -1101,59 +1121,62 @@ ACMD(do_pour)
send_to_char(ch, "A most unproductive effort.\r\n"); send_to_char(ch, "A most unproductive effort.\r\n");
return; return;
} }
if ((GET_OBJ_VAL(to_obj, 0) < 0) || if (!EMPTY_DRINK_CONTAINER(to_obj) && DRINK_CON_TYPE(to_obj) != DRINK_CON_TYPE(from_obj)) {
(!(GET_OBJ_VAL(to_obj, 1) < GET_OBJ_VAL(to_obj, 0)))) {
send_to_char(ch, "There is already another liquid in it!\r\n"); send_to_char(ch, "There is already another liquid in it!\r\n");
return; 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"); send_to_char(ch, "There is no room for more.\r\n");
return; return;
} }
if (subcmd == SCMD_POUR) 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) { if (subcmd == SCMD_FILL) {
act("You gently fill $p from $P.", FALSE, ch, to_obj, from_obj, TO_CHAR); 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); act("$n gently fills $p from $P.", TRUE, ch, to_obj, from_obj, TO_ROOM);
} }
/* New alias */ /* New alias */
if (GET_OBJ_VAL(to_obj, 1) == 0) if (EMPTY_DRINK_CONTAINER(to_obj))
name_to_drinkcon(to_obj, GET_OBJ_VAL(from_obj, 2)); name_to_drinkcon(to_obj, DRINK_CON_TYPE(from_obj));
/* First same type liq. */ /* 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 */ /* Then how much to pour */
if (GET_OBJ_VAL(from_obj, 0) > 0) { if (LIMITED_DRINK_CONTAINER(from_obj)) {
GET_OBJ_VAL(from_obj, 1) -= (amount = amount = MIN(DRINK_CON_NOW(from_obj), DRINK_CON_MAX(to_obj) - DRINK_CON_NOW(to_obj));
(GET_OBJ_VAL(to_obj, 0) - GET_OBJ_VAL(to_obj, 1))); 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 (DRINK_CON_NOW(from_obj) == 0) { /* It was emptied */
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);
name_from_drinkcon(from_obj); name_from_drinkcon(from_obj);
GET_OBJ_VAL(from_obj, 1) = 0; DRINK_CON_NOW(from_obj) = 0;
GET_OBJ_VAL(from_obj, 2) = 0; DRINK_CON_TYPE(from_obj) = 0;
GET_OBJ_VAL(from_obj, 3) = 0; DRINK_CON_POISON(from_obj) = 0;
} }
} } else {
else { amount = DRINK_CON_MAX(to_obj) - DRINK_CON_NOW(to_obj);
GET_OBJ_VAL(to_obj, 1) = GET_OBJ_VAL(to_obj, 0); DRINK_CON_NOW(to_obj) = DRINK_CON_MAX(to_obj);
amount = GET_OBJ_VAL(to_obj, 0);
} }
/* Poisoned? */ /* 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. */ /* 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(from_obj, -amount);
} }
weight_change_object(to_obj, amount); /* Add weight */ 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) static void wear_message(struct char_data *ch, struct obj_data *obj, int where)
{ {
const char *wear_messages[][2] = { const char *wear_messages[][2] = {
+5 -3
View File
@@ -54,7 +54,7 @@ ACMD(do_assist)
else if (!CAN_SEE(ch, opponent)) else if (!CAN_SEE(ch, opponent))
act("You can't see who is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR); act("You can't see who is fighting $M!", FALSE, ch, 0, helpee, TO_CHAR);
/* prevent accidental pkill */ /* 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"); send_to_char(ch, "You cannot kill other players.\r\n");
else { else {
send_to_char(ch, "You join the fight!\r\n"); 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)) } 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); act("$N is just such a good friend, you simply can't hit $M.", FALSE, ch, 0, vict, TO_CHAR);
else { else {
if (!CONFIG_PK_ALLOWED && !IS_NPC(vict) && !IS_NPC(ch)) if (!pk_allowed(ch, vict)) {
check_killer(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_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 */ 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"); send_to_char(ch, "You have no idea how to do that.\r\n");
return; return;
} }
if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { if (ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) {
send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n"); send_to_char(ch, "This room just has such a peaceful, easy feeling...\r\n");
return; return;
@@ -169,20 +170,26 @@ ACMD(do_steal)
return; 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 */ /* 101% is a complete failure */
percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket; percent = rand_number(1, 101) - dex_app_skill[GET_DEX(ch)].p_pocket;
if (GET_POS(vict) < POS_SLEEPING) if (GET_POS(vict) < POS_SLEEPING)
percent = -1; /* ALWAYS SUCCESS, unless heavy object. */ 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. */ if (!AWAKE(vict)) /* Easier to steal from sleeping people. */
percent -= 50; percent -= 50;
/* No stealing if not allowed. If it is no stealing from Imm's or Shopkeepers. */ /* 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 */ percent = 101; /* Failure */
if (str_cmp(obj_name, "coins") && str_cmp(obj_name, "gold")) { 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)) { if (percent > GET_SKILL(ch, SKILL_STEAL)) {
ohoh = TRUE; ohoh = TRUE;
send_to_char(ch, "Oops..\r\n"); 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 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); act("$n tries to steal something from $N.", TRUE, ch, 0, vict, TO_NOTVICT);
} else { /* Steal the item */ } else { /* Steal the item */
@@ -242,6 +255,10 @@ ACMD(do_steal)
} else { /* Steal some coins */ } else { /* Steal some coins */
if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) { if (AWAKE(vict) && (percent > GET_SKILL(ch, SKILL_STEAL))) {
ohoh = TRUE; 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"); 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("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); 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) if (!action->char_found)
*arg = '\0'; *arg = '\0';
if (action->char_found && argument) if (action->char_found)
one_argument(argument, arg); one_argument(argument, arg);
else else
*arg = '\0'; *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); act("A sudden fireball conjured from nowhere thaws $n!", FALSE, vict, 0, 0, TO_ROOM);
break; break;
case SCMD_UNAFFECT: 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) while (vict->affected)
affect_remove(vict, vict->affected); affect_remove(vict, vict->affected);
for(taeller=0; taeller < AF_ARRAY_MAX; taeller++) for(taeller=0; taeller < AF_ARRAY_MAX; taeller++)
+2 -2
View File
@@ -566,10 +566,10 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
aedit_disp_menu(d); aedit_disp_menu(d);
return; return;
} }
if (OLC_ACTION(d)->sort_as) { if (OLC_ACTION(d)->sort_as)
free(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; break;
case AEDIT_MIN_CHAR_POS: case AEDIT_MIN_CHAR_POS:
+3 -3
View File
@@ -374,9 +374,9 @@ SPECIAL(king_welmar)
"$n proclaims 'principe dignos'." "$n proclaims 'principe dignos'."
}; };
const char bedroom_path[] = "s33004o1c1S."; static const char bedroom_path[] = "s33004o1c1S.";
const char throne_path[] = "W3o3cG52211rg."; static const char throne_path[] = "W3o3cG52211rg.";
const char monolog_path[] = "ABCDPPPP."; static const char monolog_path[] = "ABCDPPPP.";
static const char *path; static const char *path;
static int path_index; 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 /* Copy the current configuration from the config_info to this one and copy
* the game play options from the configuration info struct. */ * the game play options from the configuration info struct. */
OLC_CONFIG(d)->play.pk_allowed = CONFIG_PK_ALLOWED; OLC_CONFIG(d)->play.pk_setting = CONFIG_PK_SETTING;
OLC_CONFIG(d)->play.pt_allowed = CONFIG_PT_ALLOWED; OLC_CONFIG(d)->play.pt_setting = CONFIG_PT_SETTING;
OLC_CONFIG(d)->play.level_can_shout = CONFIG_LEVEL_CAN_SHOUT; 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.holler_move_cost = CONFIG_HOLLER_MOVE_COST;
OLC_CONFIG(d)->play.tunnel_size = CONFIG_TUNNEL_SIZE; 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 */ /* see if we need to reassign spec procs on rooms */
int reassign = (CONFIG_DTS_ARE_DUMPS != OLC_CONFIG(d)->play.dts_are_dumps); 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. */ /* Copy the data back from the descriptor to the config_info structure. */
CONFIG_PK_ALLOWED = OLC_CONFIG(d)->play.pk_allowed; CONFIG_PK_SETTING = OLC_CONFIG(d)->play.pk_setting;
CONFIG_PT_ALLOWED = OLC_CONFIG(d)->play.pt_allowed; CONFIG_PT_SETTING = OLC_CONFIG(d)->play.pt_setting;
CONFIG_LEVEL_CAN_SHOUT = OLC_CONFIG(d)->play.level_can_shout; CONFIG_LEVEL_CAN_SHOUT = OLC_CONFIG(d)->play.level_can_shout;
CONFIG_HOLLER_MOVE_COST = OLC_CONFIG(d)->play.holler_move_cost; CONFIG_HOLLER_MOVE_COST = OLC_CONFIG(d)->play.holler_move_cost;
CONFIG_TUNNEL_SIZE = OLC_CONFIG(d)->play.tunnel_size; 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" 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" 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" fprintf(fl, "* What is the minimum level a player can shout/gossip/etc?\n"
"level_can_shout = %d\n\n", CONFIG_LEVEL_CAN_SHOUT); "level_can_shout = %d\n\n", CONFIG_LEVEL_CAN_SHOUT);
fprintf(fl, "* How many movement points does shouting cost the player?\n" 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) 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; 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); get_char_colors(d->character);
clear_screen(d); 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" "%s8%s) Scripts on PC's : %s%s\r\n"
"%sQ%s) Exit To The Main Menu\r\n" "%sQ%s) Exit To The Main Menu\r\n"
"Enter your choice : ", "Enter your choice : ",
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pk_allowed), grn, nrm, cyn, pk_setting == 0 ? "Off" : (pk_setting == 1 ? "Limited" : (pk_setting == 2 ? "Free-for-all" : "Invalid!")),
grn, nrm, cyn, CHECK_VAR(OLC_CONFIG(d)->play.pt_allowed), 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.level_can_shout,
grn, nrm, cyn, OLC_CONFIG(d)->play.holler_move_cost, grn, nrm, cyn, OLC_CONFIG(d)->play.holler_move_cost,
grn, nrm, cyn, OLC_CONFIG(d)->play.tunnel_size, grn, nrm, cyn, OLC_CONFIG(d)->play.tunnel_size,
@@ -883,13 +885,21 @@ void cedit_parse(struct descriptor_data *d, char *arg)
switch (*arg) { switch (*arg) {
case 'a': case 'a':
case 'A': case 'A':
TOGGLE_VAR(OLC_CONFIG(d)->play.pk_allowed); write_to_output(d, "1) No Player Killing\r\n");
break; 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':
case 'B': case 'B':
TOGGLE_VAR(OLC_CONFIG(d)->play.pt_allowed); write_to_output(d, "1) No Player Thieving\r\n");
break; 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':
case 'C': case 'C':
@@ -1708,6 +1718,30 @@ void cedit_parse(struct descriptor_data *d, char *arg)
} }
break; 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... */ default: /* We should never get here, but just in case... */
cleanup_olc(d, CLEANUP_CONFIG); cleanup_olc(d, CLEANUP_CONFIG);
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: cedit_parse(): Reached default case!"); 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; ush_int port;
socket_t mother_desc; socket_t mother_desc;
int next_tick = SECS_PER_MUD_HOUR; /* Tick countdown */ 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 local global variable declarations (current file scope only) */
static struct txt_block *bufpool = 0; /* pool of large output buffers */ 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 int tics_passed = 0; /* for extern checkpointing */
static struct timeval null_time; /* zero-valued time structure */ static struct timeval null_time; /* zero-valued time structure */
static byte reread_wizlist; /* signal: SIGUSR1 */ static byte reread_wizlist; /* signal: SIGUSR1 */
/* normally signal SIGUSR2, currently orphaned in favor of Webster dictionary static byte emergency_unban; /* signal: SIGUSR2 */
* lookup
static byte emergency_unban;
*/
static int dg_act_check; /* toggle for act_trigger */ static int dg_act_check; /* toggle for act_trigger */
static bool fCopyOver; /* Are we booting in copyover mode? */ static bool fCopyOver; /* Are we booting in copyover mode? */
static char *last_act_message = NULL; static char *last_act_message = NULL;
static byte webster_file_ready = FALSE;/* signal: SIGUSR2 */
/* static local function prototypes (current file scope only) */ /* static local function prototypes (current file scope only) */
static RETSIGTYPE reread_wizlists(int sig); static RETSIGTYPE reread_wizlists(int sig);
@@ -160,9 +156,6 @@ static int open_logfile(const char *filename, FILE *stderr_fp);
#if defined(POSIX) #if defined(POSIX)
static sigfunc *my_signal(int signo, sigfunc *func); static sigfunc *my_signal(int signo, sigfunc *func);
#endif #endif
/* Webster Dictionary Lookup functions */
static RETSIGTYPE websterlink(int sig);
static void handle_webster_file(void);
static void msdp_update(void); /* KaVir plugin*/ 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."); mudlog(CMP, LVL_IMMORT, TRUE, "Signal received - rereading wizlists.");
reboot_wizlists(); reboot_wizlists();
} }
/* Orphaned right now as signal trapping is used for Webster lookup
if (emergency_unban) { if (emergency_unban) {
emergency_unban = FALSE; emergency_unban = FALSE;
mudlog(BRF, LVL_IMMORT, TRUE, "Received SIGUSR2 - completely unrestricting game (emergent)"); 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; circle_restrict = 0;
num_invalid = 0; num_invalid = 0;
} }
*/
if (webster_file_ready) {
webster_file_ready = FALSE;
handle_webster_file();
}
#ifdef CIRCLE_UNIX #ifdef CIRCLE_UNIX
/* Update tics_passed for deadlock protection (UNIX only) */ /* 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); result = write_to_descriptor(t->descriptor, osb);
if (result < 0) { /* Oops, fatal error. Bye! */ if (result < 0) { /* Oops, fatal error. Bye! */
close_socket(t); // close_socket(t); // close_socket is called after return of negative result
return (-1); return (-1);
} else if (result == 0) /* Socket buffer full. Try later. */ } else if (result == 0) /* Socket buffer full. Try later. */
return (0); return (0);
@@ -2232,18 +2221,10 @@ static RETSIGTYPE reread_wizlists(int sig)
reread_wizlist = TRUE; reread_wizlist = TRUE;
} }
/* Orphaned right now in place of Webster ...
static RETSIGTYPE unrestrict_game(int sig) static RETSIGTYPE unrestrict_game(int sig)
{ {
emergency_unban = TRUE; emergency_unban = TRUE;
} }
*/
static RETSIGTYPE websterlink(int sig)
{
webster_file_ready = TRUE;
}
#ifdef CIRCLE_UNIX #ifdef CIRCLE_UNIX
@@ -2318,7 +2299,7 @@ static void signal_setup(void)
/* user signal 2: unrestrict game. Used for emergencies if you lock /* user signal 2: unrestrict game. Used for emergencies if you lock
* yourself out of the MUD somehow. */ * 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 /* set up the deadlock-protection so that the MUD aborts itself if it gets
* caught in an infinite loop for more than 3 minutes. */ * caught in an infinite loop for more than 3 minutes. */
@@ -2780,45 +2761,6 @@ static void circle_sleep(struct timeval *timeout)
#endif /* CIRCLE_WINDOWS */ #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*/ /* KaVir's plugin*/
static void msdp_update( void ) 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 heartbeat(int heart_pulse);
void copyover_recover(void); void copyover_recover(void);
/** webster dictionary lookup */
extern long last_webster_teller;
extern struct descriptor_data *descriptor_list; extern struct descriptor_data *descriptor_list;
extern int buf_largecount; extern int buf_largecount;
extern int buf_overflows; 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? */ /* Can Scripts be attached to players? */
int script_players = NO; int script_players = NO;
/* pk_allowed sets the tone of the entire game. If pk_allowed is set to NO, /* pk_setting sets the tone of the entire game.
* 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, * CONFIG_PK_OFF 0 Players are prevented from damaging or fighting other players in code
* if you decide you want to have an all-out knock-down drag-out PK Mud, just * CONFIG_PK_LIMITED 1 Players may damage and fight but will be flagged PLR_KILLER
* set pk_allowed to YES - and anything goes. */ * CONFIG_PK_FREEFORALL 2 No restrictions or flags for player damaging or killing
int pk_allowed = NO; *
* 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? */ /* Is playerthieving allowed?
int pt_allowed = NO; *
* 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. */ /* Minimum level a player must be to shout/holler/gossip/auction. */
int level_can_shout = 1; int level_can_shout = 1;
+2 -2
View File
@@ -14,9 +14,9 @@
#define _CONFIG_H_ #define _CONFIG_H_
/* Global variable declarations, all settable by cedit */ /* Global variable declarations, all settable by cedit */
extern int pk_allowed; extern int pk_setting;
extern int script_players; extern int script_players;
extern int pt_allowed; extern int pt_setting;
extern int level_can_shout; extern int level_can_shout;
extern int holler_move_cost; extern int holler_move_cost;
extern int tunnel_size; 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 * @todo cpp_extern isn't needed here (or anywhere) as the extern reserved word
* works correctly with C compilers (at least in my Experience) * works correctly with C compilers (at least in my Experience)
* Jeremy Osborne 1/28/2008 */ * 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 */ /* strings corresponding to ordinals/bitvectors in structs.h */
/* (Note: strings for class definitions in class.c instead of here) */ /* (Note: strings for class definitions in class.c instead of here) */
@@ -877,6 +877,7 @@ const char *trig_types[] = {
"Door", "Door",
"UNUSED", "UNUSED",
"Time", "Time",
"Damage",
"\n" "\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 /* This function is called only once, at boot-time. We assume config_info is
* empty. -Welcor */ * empty. -Welcor */
/* Game play options. */ /* Game play options. */
CONFIG_PK_ALLOWED = pk_allowed; CONFIG_PK_SETTING = pk_setting;
CONFIG_PT_ALLOWED = pt_allowed; CONFIG_PT_SETTING = pt_setting;
CONFIG_LEVEL_CAN_SHOUT = level_can_shout; CONFIG_LEVEL_CAN_SHOUT = level_can_shout;
CONFIG_HOLLER_MOVE_COST = holler_move_cost; CONFIG_HOLLER_MOVE_COST = holler_move_cost;
CONFIG_TUNNEL_SIZE = tunnel_size; CONFIG_TUNNEL_SIZE = tunnel_size;
@@ -4113,12 +4113,12 @@ void load_config( void )
break; break;
case 'p': case 'p':
if (!str_cmp(tag, "pk_allowed")) if (!str_cmp(tag, "pk_setting"))
CONFIG_PK_ALLOWED = num; CONFIG_PK_SETTING = num;
else if (!str_cmp(tag, "protocol_negotiation")) else if (!str_cmp(tag, "protocol_negotiation"))
CONFIG_PROTOCOL_NEGOTIATION = num; CONFIG_PROTOCOL_NEGOTIATION = num;
else if (!str_cmp(tag, "pt_allowed")) else if (!str_cmp(tag, "pt_setting"))
CONFIG_PT_ALLOWED = num; CONFIG_PT_SETTING = num;
break; break;
case 'r': case 'r':
+17 -5
View File
@@ -1024,17 +1024,27 @@ ACMD(do_mdoor)
} }
if ((rm = get_room(target)) == NULL) { if ((rm = get_room(target)) == NULL) {
mob_log(ch, "mdoor: invalid target"); mob_log(ch, "mdoor: invalid target (arg == %s)", target);
return; return;
} }
if ((dir = search_block(direction, dirs, FALSE)) == -1) { 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; return;
} }
if ((fd = search_block(field, door_field, FALSE)) == -1) { 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; return;
} }
@@ -1081,8 +1091,10 @@ ACMD(do_mdoor)
case 5: /* room */ case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE) if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room; newexit->to_room = to_room;
else else {
mob_log(ch, "mdoor: invalid door target"); newexit->to_room = NOWHERE;
mob_log(ch, "mdoor: invalid door target (arg == %s)", value);
}
break; break;
} }
} }
+17 -5
View File
@@ -625,17 +625,27 @@ static OCMD(do_odoor)
} }
if ((rm = get_room(target)) == NULL) { if ((rm = get_room(target)) == NULL) {
obj_log(obj, "odoor: invalid target"); obj_log(obj, "odoor: invalid target (arg == %s)", target);
return; return;
} }
if ((dir = search_block(direction, dirs, FALSE)) == -1) { 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; return;
} }
if ((fd = search_block(field, door_field, FALSE)) == -1) { 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; return;
} }
@@ -682,8 +692,10 @@ static OCMD(do_odoor)
case 5: /* room */ case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE) if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room; newexit->to_room = to_room;
else else {
obj_log(obj, "odoor: invalid door target"); newexit->to_room = NOWHERE;
obj_log(obj, "odoor: invalid door target (arg == %s)", value);
}
break; break;
} }
} }
+44 -29
View File
@@ -1091,59 +1091,74 @@ int format_script(struct descriptor_data *d)
char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE]; char nsc[MAX_CMD_LENGTH], *t, line[READ_SIZE];
char *sc; char *sc;
size_t len = 0, nlen = 0, llen = 0; 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) if (!d->str || !*d->str)
return FALSE; 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"); t = strtok(sc, "\n\r");
*nsc = '\0'; *nsc = '\0';
while (t) { while (t) {
line_num++; line_num++;
skip_spaces(&t); skip_spaces(&t);
if (!strn_cmp(t, "if ", 3) ||
!strn_cmp(t, "switch ", 7)) { if (!strn_cmp(t, "switch ", 7)) {
indent_next = TRUE; indent_next = TRUE;
} else if (!strn_cmp(t, "while ", 6)) { stack_top++;
found_case = TRUE; /* so you can 'break' a loop without complains */ 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; indent_next = TRUE;
} else if (!strn_cmp(t, "end", 3) || stack_top++;
!strn_cmp(t, "done", 4)) { block_stack[stack_top] = 'l'; // 'l' for loop or conditional
if (!indent) { } 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); write_to_output(d, "Unmatched 'end' or 'done' (line %d)!\r\n", line_num);
free(sc); free(sc);
return FALSE; return FALSE;
} }
indent--; if (block_stack[stack_top] == 's') {
indent_next = FALSE; 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)) { } 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); write_to_output(d, "Unmatched 'else' (line %d)!\r\n", line_num);
free(sc); free(sc);
return FALSE; return FALSE;
} }
indent--; indent--; // Reduce indent for else, then increment for next statement
indent_next = TRUE; 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)) { } else if (!strn_cmp(t, "break", 5)) {
if (!found_case || !indent ) { if (stack_top < 0 || (block_stack[stack_top] != 's' && block_stack[stack_top] != 'l')) {
write_to_output(d, "Break not in case (line %d)!\r\n", line_num); write_to_output(d, "Break not in case or loop (line %d)!\r\n", line_num);
free(sc); free(sc);
return FALSE; return FALSE;
} }
found_case = FALSE; indent = case_indent + 1; // Indent break one level deeper than case
indent--; indent_next = FALSE; // Ensure no automatic increase for next line after break
} }
*line = '\0'; *line = '\0';
@@ -1169,8 +1184,8 @@ int format_script(struct descriptor_data *d)
t = strtok(NULL, "\n\r"); t = strtok(NULL, "\n\r");
} }
if (indent) if (stack_top >= 0)
write_to_output(d, "Unmatched if, while or switch ignored.\r\n"); write_to_output(d, "Unmatched block statements ignored.\r\n");
free(*d->str); free(*d->str);
*d->str = strdup(nsc); *d->str = strdup(nsc);
+1 -1
View File
@@ -16,7 +16,7 @@
#include "dg_scripts.h" #include "dg_scripts.h"
#define NUM_TRIG_TYPE_FLAGS 20 #define NUM_TRIG_TYPE_FLAGS 21
/* Submodes of TRIGEDIT connectedness. */ /* Submodes of TRIGEDIT connectedness. */
#define TRIGEDIT_MAIN_MENU 0 #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; char cmd[MAX_INPUT_LENGTH], *p;
struct script_data *sc = 0; struct script_data *sc = 0;
struct cmdlist_element *temp; struct cmdlist_element *temp;
unsigned long loops = 0;
void *go = NULL; void *go = NULL;
void obj_command_interpreter(obj_data *obj, char *argument); 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)) { if (process_if(p + 6, go, sc, trig, type)) {
temp->original = cl; temp->original = cl;
} else { } else {
cl->loops = 0;
cl = temp; cl = temp;
loops = 0;
} }
} else if (!strn_cmp("switch ", p, 7)) { } else if (!strn_cmp("switch ", p, 7)) {
cl = find_case(trig, cl, go, sc, type, 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, if (cl->original && process_if(orig_cmd + 6, go, sc, trig,
type)) { type)) {
cl = cl->original; cl = cl->original;
loops++; cl->loops++;
GET_TRIG_LOOPS(trig)++; GET_TRIG_LOOPS(trig)++;
if (loops == 30) { if (cl->loops == 30) {
cl->loops = 0;
process_wait(go, trig, type, "wait 1", cl); process_wait(go, trig, type, "wait 1", cl);
depth--; depth--;
return ret_val; return ret_val;
+3
View File
@@ -71,6 +71,7 @@
#define MTRIG_DOOR (1 << 17) /* door manipulated in room */ #define MTRIG_DOOR (1 << 17) /* door manipulated in room */
#define MTRIG_TIME (1 << 19) /* trigger based on game hour */ #define MTRIG_TIME (1 << 19) /* trigger based on game hour */
#define MTRIG_DAMAGE (1 << 20) /* trigger whenever mob is damaged */
/* obj trigger types */ /* obj trigger types */
#define OTRIG_GLOBAL (1 << 0) /* unused */ #define OTRIG_GLOBAL (1 << 0) /* unused */
@@ -135,6 +136,7 @@ struct cmdlist_element {
char *cmd; /* one line of a trigger */ char *cmd; /* one line of a trigger */
struct cmdlist_element *original; struct cmdlist_element *original;
struct cmdlist_element *next; struct cmdlist_element *next;
int loops; /* for counting number of runs in a while loop */
}; };
struct trig_var_data { 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 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 */ /* function prototypes from dg_scripts.c */
ACMD(do_attach) ; ACMD(do_attach) ;
ACMD(do_detach); ACMD(do_detach);
+33 -3
View File
@@ -147,7 +147,7 @@ void greet_memory_mtrigger(char_data *actor)
{ {
trig_data *t; trig_data *t;
char_data *ch; char_data *ch;
struct script_memory *mem; struct script_memory *mem, *next_mem;
char buf[MAX_INPUT_LENGTH]; char buf[MAX_INPUT_LENGTH];
int command_performed = 0; int command_performed = 0;
@@ -159,7 +159,8 @@ void greet_memory_mtrigger(char_data *actor)
AFF_FLAGGED(ch, AFF_CHARM)) AFF_FLAGGED(ch, AFF_CHARM))
continue; continue;
/* find memory line with command only */ /* 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 (char_script_id(actor)!=mem->id) continue;
if (mem->cmd) { if (mem->cmd) {
command_interpreter(ch, mem->cmd); /* no script */ 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); for (actor = world[IN_ROOM(ch)].people; actor && SCRIPT_MEM(ch);
actor = actor->next_in_room) { actor = actor->next_in_room) {
if (actor!=ch && SCRIPT_MEM(ch)) { 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) { if (char_script_id(actor)==mem->id) {
struct script_memory *prev; struct script_memory *prev;
if (mem->cmd) command_interpreter(ch, mem->cmd); 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); if (mem->cmd) free(mem->cmd);
free(mem); free(mem);
} }
mem = next_mem;
} /* for (mem =..... */ } /* for (mem =..... */
} }
} }
@@ -554,6 +557,33 @@ int cast_mtrigger(char_data *actor, char_data *ch, int spellnum)
return 1; 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) int leave_mtrigger(char_data *actor, int dir)
{ {
trig_data *t; 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. * will return the number of bags of gold.
* Addition inspired by Jamie Nelson */ * Addition inspired by Jamie Nelson */
else if (!str_cmp(var, "findmob")) { else if (!str_cmp(var, "findmob")) {
if (!field || !*field || !subfield || !*subfield) { if (!*field || !subfield || !*subfield) {
script_log("findmob.vnum(mvnum) - illegal syntax"); script_log("findmob.vnum(mvnum) - illegal syntax");
strcpy(str, "0"); strcpy(str, "0");
} else { } else {
@@ -486,7 +486,7 @@ void find_replacement(void *go, struct script_data *sc, trig_data *trig,
} }
/* Addition inspired by Jamie Nelson. */ /* Addition inspired by Jamie Nelson. */
else if (!str_cmp(var, "findobj")) { else if (!str_cmp(var, "findobj")) {
if (!field || !*field || !subfield || !*subfield) { if (!*field || !subfield || !*subfield) {
script_log("findobj.vnum(ovnum) - illegal syntax"); script_log("findobj.vnum(ovnum) - illegal syntax");
strcpy(str, "0"); strcpy(str, "0");
} else { } else {
+17 -5
View File
@@ -224,17 +224,27 @@ WCMD(do_wdoor)
} }
if ((rm = get_room(target)) == NULL) { if ((rm = get_room(target)) == NULL) {
wld_log(room, "wdoor: invalid target"); wld_log(room, "wdoor: invalid target (arg == %s)", target);
return; return;
} }
if ((dir = search_block(direction, dirs, FALSE)) == -1) { 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; return;
} }
if ((fd = search_block(field, door_field, FALSE)) == -1) { 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; return;
} }
@@ -281,8 +291,10 @@ WCMD(do_wdoor)
case 5: /* room */ case 5: /* room */
if ((to_room = real_room(atoi(value))) != NOWHERE) if ((to_room = real_room(atoi(value))) != NOWHERE)
newexit->to_room = to_room; newexit->to_room = to_room;
else else {
wld_log(room, "wdoor: invalid door target"); newexit->to_room = NOWHERE;
wld_log(room, "wdoor: invalid door target (arg == %s)", value);
}
break; break;
} }
} }
+38 -11
View File
@@ -110,10 +110,13 @@ void update_pos(struct char_data *victim)
void check_killer(struct char_data *ch, struct char_data *vict) void check_killer(struct char_data *ch, struct char_data *vict)
{ {
if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF)) if (PLR_FLAGGED(vict, PLR_KILLER) || PLR_FLAGGED(vict, PLR_THIEF)) {
return; return;
if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict) }
if (PLR_FLAGGED(ch, PLR_KILLER) || IS_NPC(ch) || IS_NPC(vict) || ch == vict){
return; return;
}
SET_BIT_AR(PLR_FLAGS(ch), PLR_KILLER); 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"); 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); 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... ) */ /* start one char fighting another (yes, it is horrible, I know... ) */
void set_fighting(struct char_data *ch, struct char_data *vict) 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; return;
} }
if (!pk_allowed(ch, vict)) {
send_to_char(ch, "Player killing is not permitted.\r\n");
return;
}
ch->next_fighting = combat_list; ch->next_fighting = combat_list;
combat_list = ch; combat_list = ch;
@@ -142,8 +167,6 @@ void set_fighting(struct char_data *ch, struct char_data *vict)
FIGHTING(ch) = vict; FIGHTING(ch) = vict;
GET_POS(ch) = POS_FIGHTING; GET_POS(ch) = POS_FIGHTING;
if (!CONFIG_PK_ALLOWED)
check_killer(ch, vict);
} }
/* remove a char from the list of fighting chars */ /* 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 */ 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 */ /* peaceful rooms */
if (ch->nr != real_mobile(DG_CASTER_PROXY) && if (ch->nr != real_mobile(DG_CASTER_PROXY) &&
ch != victim && ROOM_FLAGGED(IN_ROOM(ch), ROOM_PEACEFUL)) { 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))) if (!IS_NPC(victim) && ((GET_LEVEL(victim) >= LVL_IMMORT) && PRF_FLAGGED(victim, PRF_NOHASSLE)))
dam = 0; dam = 0;
dam = damage_mtrigger(ch, victim, dam, attacktype);
if (dam == -1) {
return (0);
}
if (victim != ch) { if (victim != ch) {
/* Start the attacker fighting the victim */ /* Start the attacker fighting the victim */
if (GET_POS(ch) > POS_STUNNED && (FIGHTING(ch) == NULL)) 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) if (AFF_FLAGGED(victim, AFF_SANCTUARY) && dam >= 2)
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 */ /* Set the maximum damage per round and subtract the hit points */
dam = MAX(MIN(dam, 100), 0); dam = MAX(MIN(dam, 100), 0);
GET_HIT(victim) -= dam; 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 skill_message(int dam, struct char_data *ch, struct char_data *vict,
int attacktype); int attacktype);
void stop_fighting(struct char_data *ch); void stop_fighting(struct char_data *ch);
bool pk_allowed(struct char_data *ch, struct char_data *victim);
/* Global variables */ /* Global variables */
+13 -14
View File
@@ -277,7 +277,10 @@ int sprintascii(char *out, bitvector_t bits)
return j; return j;
} }
/* converts illegal filename chars into appropriate equivalents */ /* converts illegal filename chars into appropriate equivalents.
* Uses an allowlist: alphanumerics, underscore, hyphen, and dot are kept;
* spaces are converted to underscores; all other characters (including shell
* metacharacters such as ; | & ` $ > < \n) are silently dropped. */
static void fix_filename(const char *str, char *outbuf, size_t maxlen) static void fix_filename(const char *str, char *outbuf, size_t maxlen)
{ {
const char *in = str; const char *in = str;
@@ -285,21 +288,17 @@ static void fix_filename(const char *str, char *outbuf, size_t maxlen)
int count = 0; int count = 0;
while (*in) { while (*in) {
switch(*in) { if (isalnum((unsigned char)*in) || *in == '_' || *in == '-' || *in == '.') {
case ' ': *out = '_'; out++; break; /* Safe characters kept as-is */
case '(': *out = '{'; out++; break; *out++ = *in;
case ')': *out = '}'; out++; break; if (++count == maxlen - 1) break;
} else if (*in == ' ') {
/* skip the following */ /* Spaces become underscores */
case '\'': break; *out++ = '_';
case '"': break; if (++count == maxlen - 1) break;
/* Legal character */
default: *out = *in; out++;break;
} }
/* All other characters, including shell metacharacters, are dropped */
in++; in++;
count++;
if (count == maxlen - 1) break;
} }
*out = '\0'; *out = '\0';
} }
+7
View File
@@ -177,6 +177,13 @@ static IBT_DATA *read_ibt( char *filename, FILE *fp )
} }
break; break;
case 'F':
if (!str_cmp(word, "Flags")) {
fMatch = TRUE;
fread_flags(fp, ibtData->flags, 4);
}
break;
case 'I': case 'I':
TXT_KEY("IdNum", id_num, fread_line(fp)); TXT_KEY("IdNum", id_num, fread_line(fp));
break; break;
+2 -2
View File
@@ -367,7 +367,7 @@ void parse_edit_action(int command, char *string, struct descriptor_data *d)
s++; s++;
temp = *s; temp = *s;
*s = '\0'; *s = '\0';
char buf3[9]; char buf3[13];
sprintf(buf3, "%4d: ", (i - 1)); sprintf(buf3, "%4d: ", (i - 1));
strncat(buf, buf3, sizeof(buf) - strlen(buf) - 1); strncat(buf, buf3, sizeof(buf) - strlen(buf) - 1);
strncat(buf, t, 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); strncat(buf, *d->str, sizeof(buf) - strlen(buf) - 1);
*s = temp; *s = temp;
strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1); strncat(buf, buf2, sizeof(buf) - strlen(buf) - 1);
if (s && *s) if (*s)
strncat(buf, s, sizeof(buf) - strlen(buf) - 1); strncat(buf, s, sizeof(buf) - strlen(buf) - 1);
RECREATE(*d->str, char, strlen(buf) + 3); RECREATE(*d->str, char, strlen(buf) + 3);
+2 -1
View File
@@ -1612,8 +1612,9 @@ void nanny(struct descriptor_data *d, char *arg)
if (load_result == CLASS_UNDEFINED) { if (load_result == CLASS_UNDEFINED) {
write_to_output(d, "\r\nThat's not a class.\r\nClass: "); write_to_output(d, "\r\nThat's not a class.\r\nClass: ");
return; return;
} else } else {
GET_CLASS(d->character) = load_result; GET_CLASS(d->character) = load_result;
}
if (d->olc) { if (d->olc) {
free(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; break;
case SPELL_SLEEP: 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; return;
if (MOB_FLAGGED(victim, MOB_NOSLEEP)) if (MOB_FLAGGED(victim, MOB_NOSLEEP))
return; return;
@@ -650,7 +650,7 @@ void mag_areas(int level, struct char_data *ch, int spellnum, int savetype)
continue; continue;
if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT) if (!IS_NPC(tch) && GET_LEVEL(tch) >= LVL_IMMORT)
continue; 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; continue;
if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM)) if (!IS_NPC(ch) && IS_NPC(tch) && AFF_FLAGGED(tch, AFF_CHARM))
continue; continue;
+2
View File
@@ -380,6 +380,8 @@ extern const char *nrm, *grn, *cyn, *yel;
#define CEDIT_MAP_SIZE 55 #define CEDIT_MAP_SIZE 55
#define CEDIT_MINIMAP_SIZE 56 #define CEDIT_MINIMAP_SIZE 56
#define CEDIT_DEBUG_MODE 57 #define CEDIT_DEBUG_MODE 57
#define CEDIT_PK_SETTING 58
#define CEDIT_PT_SETTING 59
/* Hedit Submodes of connectedness. */ /* Hedit Submodes of connectedness. */
#define HEDIT_CONFIRM_SAVESTRING 0 #define HEDIT_CONFIRM_SAVESTRING 0
+25 -3
View File
@@ -146,7 +146,8 @@ static void prefedit_disp_main_menu(struct descriptor_data *d)
"%sImmortal Preferences\r\n" "%sImmortal Preferences\r\n"
"%s1%s) Syslog Level %s[%s%8s%s] %s4%s) ClsOLC %s[%s%3s%s]\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" "%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), CBWHT(d->character, C_NRM),
/* Line 1 - syslog and clsolc */ /* 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), 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 */ /* 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), 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), 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) 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), 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)); ONOFF(PREFEDIT_FLAGGED(PRF_ZONERESETS)), CCCYN(d->character, C_NRM));
else
send_to_char(d->character, "\r\n");
} }
/* Finishing Off */ /* Finishing Off */
@@ -506,6 +512,18 @@ void prefedit_parse(struct descriptor_data * d, char *arg)
break; 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) 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)); 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)) if (PREFEDIT_FLAGGED(PRF_AUTODOOR))
SET_BIT_AR(PREFEDIT_GET_FLAGS, 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 */ /* Other (non-toggle) options */
PREFEDIT_GET_WIMP_LEV = 0; /* Wimpy off by default */ PREFEDIT_GET_WIMP_LEV = 0; /* Wimpy off by default */
PREFEDIT_GET_PAGELENGTH = 22; /* Default telnet screen is 22 lines */ PREFEDIT_GET_PAGELENGTH = 22; /* Default telnet screen is 22 lines */
+31 -2
View File
@@ -13,6 +13,11 @@
#include <sys/types.h> #include <sys/types.h>
#include "protocol.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. 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); 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 /* Mudlet beta 15 and later supports 256 colours, but we can't
* identify it from the mud - everything prior to 1.1 claims * identify it from the mud - everything prior to 1.1 claims
@@ -2078,9 +2102,11 @@ static void ExecuteMSDPPair( descriptor_t *apDescriptor, const char *apVariable,
!strcmp(apDescriptor->pProtocol->pVariables[i]->pValueString, "Unknown") ) !strcmp(apDescriptor->pProtocol->pVariables[i]->pValueString, "Unknown") )
{ {
/* Store the new value if it's valid */ /* 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 */ int j; /* Loop counter */
if ( pBuffer != NULL )
{
for ( j = 0; j < VariableNameTable[i].Max && *apValue != '\0'; ++apValue ) for ( j = 0; j < VariableNameTable[i].Max && *apValue != '\0'; ++apValue )
{ {
if ( isprint(*apValue) ) if ( isprint(*apValue) )
@@ -2093,6 +2119,9 @@ static void ExecuteMSDPPair( descriptor_t *apDescriptor, const char *apVariable,
free(apDescriptor->pProtocol->pVariables[i]->pValueString); free(apDescriptor->pProtocol->pVariables[i]->pValueString);
apDescriptor->pProtocol->pVariables[i]->pValueString = AllocString(pBuffer); apDescriptor->pProtocol->pVariables[i]->pValueString = AllocString(pBuffer);
} }
free(pBuffer);
}
} }
} }
else /* This variable only accepts numeric values */ else /* This variable only accepts numeric values */
+4 -2
View File
@@ -410,8 +410,10 @@ void autoquest_trigger_check(struct char_data *ch, struct char_data *vict,
break; break;
case AQ_OBJ_RETURN: case AQ_OBJ_RETURN:
if (IS_NPC(vict) && (GET_MOB_VNUM(vict) == QST_RETURNMOB(rnum))) 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); generic_complete_quest(ch);
extract_obj(object);
}
break; break;
case AQ_ROOM_CLEAR: case AQ_ROOM_CLEAR:
if (QST_TARGET(rnum) == world[IN_ROOM(ch)].number) { 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"); 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; qst_rnum rnum;
mob_rnum qmrnum; 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]; 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); log("SYSERR: Error in shop #%d, near '%s' with '%s'", SHOP_NUM(top_shop), buf, string);
exit(1); exit(1);
} }
+2 -2
View File
@@ -202,9 +202,9 @@ SPECIAL(mayor)
{ {
char actbuf[MAX_INPUT_LENGTH]; char actbuf[MAX_INPUT_LENGTH];
const char open_path[] = static const char open_path[] =
"W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S."; "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
const char close_path[] = static const char close_path[] =
"W3a3003b33000c111d0d111CE333333CE22c222112212111a1S."; "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
static const char *path = NULL; static const char *path = NULL;
+2 -2
View File
@@ -120,7 +120,7 @@ ASPELL(spell_summon)
return; return;
} }
if (!CONFIG_PK_ALLOWED) { if (CONFIG_PK_SETTING == CONFIG_PK_OFF) {
if (MOB_FLAGGED(victim, MOB_AGGRESSIVE)) { if (MOB_FLAGGED(victim, MOB_AGGRESSIVE)) {
act("As the words escape your lips and $N travels\r\n" 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" "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)) else if (AFF_FLAGGED(victim, AFF_CHARM) || level < GET_LEVEL(victim))
send_to_char(ch, "You fail.\r\n"); send_to_char(ch, "You fail.\r\n");
/* player charming another player - no legal reason for this */ /* 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"); send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n");
else if (circle_follow(victim, ch)) else if (circle_follow(victim, ch))
send_to_char(ch, "Sorry, following in circles is not allowed.\r\n"); 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_AUTOMAP 31 /**< Show map at the side of room descs */
#define PRF_AUTOKEY 32 /**< Automatically unlock locked doors when opening */ #define PRF_AUTOKEY 32 /**< Automatically unlock locked doors when opening */
#define PRF_AUTODOOR 33 /**< Use the next available door */ #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 */ /** 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 */ /* Affect bits: used in char_data.char_specials.saved.affected_by */
/* WARNING: In the world files, NEVER set the bits marked "R" ("Reserved") */ /* WARNING: In the world files, NEVER set the bits marked "R" ("Reserved") */
@@ -1290,8 +1291,8 @@ struct recent_player
* variables. */ * variables. */
struct game_data struct game_data
{ {
int pk_allowed; /**< Is player killing allowed? */ int pk_setting; /**< Is player killing allowed? */
int pt_allowed; /**< Is player thieving allowed? */ int pt_setting; /**< Is player thieving allowed? */
int level_can_shout; /**< Level player must be to shout. */ int level_can_shout; /**< Level player must be to shout. */
int holler_move_cost; /**< Cost to holler in move points. */ int holler_move_cost; /**< Cost to holler in move points. */
int tunnel_size; /**< Number of people allowed in a tunnel.*/ int tunnel_size; /**< Number of people allowed in a tunnel.*/
+23 -2
View File
@@ -63,6 +63,24 @@
/* Do not change anything below this line. */ /* 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 /* Set up various machine-specific things based on the values determined from
* configure and conf.h. */ * configure and conf.h. */
@@ -78,7 +96,7 @@
#include <strings.h> #include <strings.h>
#endif #endif
#if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)) #if (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) || defined(CIRCLE_MAC_OS))
#include <stdlib.h> #include <stdlib.h>
#else /* No standard headers. */ #else /* No standard headers. */
@@ -89,7 +107,6 @@
extern char *malloc(), *calloc(), *realloc(); extern char *malloc(), *calloc(), *realloc();
extern void free(); extern void free();
extern void abort(), exit(); extern void abort(), exit();
#endif /* Standard headers. */ #endif /* Standard headers. */
@@ -150,9 +167,11 @@ extern void abort (), exit ();
#include <sys/errno.h> #include <sys/errno.h>
#endif #endif
#ifndef CIRCLE_MAC_OS
#ifdef HAVE_CRYPT_H #ifdef HAVE_CRYPT_H
#include <crypt.h> #include <crypt.h>
#endif #endif
#endif
#ifdef TIME_WITH_SYS_TIME #ifdef TIME_WITH_SYS_TIME
# include <sys/time.h> # include <sys/time.h>
@@ -434,9 +453,11 @@ struct in_addr {
char *strerror(int errnum); char *strerror(int errnum);
#endif #endif
#ifndef CIRCLE_MAC_OS
#ifdef NEED_STRLCPY_PROTO #ifdef NEED_STRLCPY_PROTO
size_t strlcpy(char *dest, const char *src, size_t copylen); size_t strlcpy(char *dest, const char *src, size_t copylen);
#endif #endif
#endif
#ifdef NEED_SYSTEM_PROTO #ifdef NEED_SYSTEM_PROTO
int system(const char *string); 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 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 asciipasswd: $(BINDIR)/asciipasswd
@@ -43,8 +43,6 @@ split: $(BINDIR)/split
wld2html: $(BINDIR)/wld2html wld2html: $(BINDIR)/wld2html
webster: $(BINDIR)/webster
$(BINDIR)/asciipasswd: asciipasswd.c $(BINDIR)/asciipasswd: asciipasswd.c
$(CC) $(CFLAGS) -o $(BINDIR)/asciipasswd asciipasswd.c @CRYPTLIB@ $(CC) $(CFLAGS) -o $(BINDIR)/asciipasswd asciipasswd.c @CRYPTLIB@
@@ -72,9 +70,6 @@ $(BINDIR)/split: split.c
$(BINDIR)/wld2html: wld2html.c $(BINDIR)/wld2html: wld2html.c
$(CC) $(CFLAGS) -o $(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 # Dependencies for the object files (automagically generated with
# gcc -MM) # gcc -MM)
+1 -1
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[]) int main(int argc, char *argv[])
{ {
FILE *sfp, *nsfp; FILE *sfp, *nsfp;
char fn[256], part[256]; char fn[120], part[256];
int result, index, i; int result, index, i;
if (argc < 2) { if (argc < 2) {
-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)++);
}
+71 -63
View File
@@ -12,7 +12,6 @@
#include "conf.h" #include "conf.h"
#include "sysdep.h" #include "sysdep.h"
#define NOWHERE -1 /* nil reference for room-database */ #define NOWHERE -1 /* nil reference for room-database */
/* The cardinal directions: used as index to room_data.dir_option[] */ /* The cardinal directions: used as index to room_data.dir_option[] */
@@ -22,14 +21,17 @@
#define WEST 3 #define WEST 3
#define UP 4 #define UP 4
#define DOWN 5 #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 {\ #define CREATE(result, type, number) do {\
if (!((result) = (type *) calloc ((number), sizeof(type))))\ if (!((result) = (type *) calloc ((number), sizeof(type))))\
{ perror("malloc failure"); abort(); } } while(0) { perror("malloc failure"); abort(); } } while(0)
/* Exit info: used in room_data.dir_option.exit_info */ /* Exit info: used in room_data.dir_option.exit_info */
#define EX_ISDOOR (1 << 0) /* Exit is a door */ #define EX_ISDOOR (1 << 0) /* Exit is a door */
#define EX_CLOSED (1 << 1) /* The door is closed */ #define EX_CLOSED (1 << 1) /* The door is closed */
@@ -45,7 +47,7 @@ typedef unsigned short int ush_int;
typedef char bool; typedef char bool;
typedef char byte; typedef char byte;
typedef sh_int room_num; typedef int room_num;
typedef sh_int obj_num; typedef sh_int obj_num;
@@ -133,13 +135,14 @@ struct room_data {
struct room_data *world = NULL; /* array of rooms */ struct room_data *world = NULL; /* array of rooms */
int top_of_world = 0; /* ref to top element of world */ int top_of_world = 0; /* ref to top element of world */
int rec_count = 0;
/* local functions */ /* local functions */
char *fread_string(FILE * fl, char *error); char *fread_string(FILE * fl, char *error);
void setup_dir(FILE * fl, int room, int dir); 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 discrete_load(FILE * fl);
void parse_room(FILE * fl, int virtual_nr); void parse_room(FILE * fl, int virtual_nr);
void parse_mobile(FILE * mob_f, int nr); void parse_mobile(FILE * mob_f, int nr);
@@ -150,7 +153,7 @@ void write_output(void);
char *dir_names[] = 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 */ /* body of the booting system */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 2) { if (argc < 2) {
fprintf(stderr, "Usage: %s <world-file-name>\n", argv[0]); fprintf(stderr, "Usage: %s <world-file-name(s)>\n", argv[0]);
exit(1); exit(1);
} }
index_boot(argv[1]);
log("Renumbering rooms."); index_boot(argc,argv);
renum_world();
log("Writing output."); log("Writing output.");
write_output(); write_output();
@@ -176,6 +177,21 @@ int main(int argc, char **argv)
return (0); 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) void write_output(void)
{ {
@@ -184,11 +200,22 @@ void write_output(void)
char buf[128]; char buf[128];
register int door, found; 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); sprintf(buf, "Writing %d.html", world[i].number);
log(buf); 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"))) { if (!(fl = fopen(buf, "w"))) {
perror("opening output file"); perror("opening output file");
exit(1); exit(1);
@@ -205,10 +232,14 @@ void write_output(void)
if (world[i].dir_option[door] && if (world[i].dir_option[door] &&
world[i].dir_option[door]->to_room != NOWHERE) { world[i].dir_option[door]->to_room != NOWHERE) {
found = 1; 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", fprintf(fl, "<a href = \"%d.html\"> %s to %s</a> <p>\n",
world[world[i].dir_option[door]->to_room].number, to_room->number,
dir_names[door], dir_names[door],
world[world[i].dir_option[door]->to_room].name); to_room->name);
} }
if (!found) if (!found)
fprintf(fl, "None!"); fprintf(fl, "None!");
@@ -231,20 +262,36 @@ int count_hash_records(FILE * fl)
void index_boot(char *name) void index_boot(int cnt, char **names)
{ {
FILE *db_file; FILE *db_file;
int rec_count = 0;
if (!(db_file = fopen(name, "r"))) { //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"); perror("error opening world file");
exit(1); exit(1);
} }
rec_count = count_hash_records(db_file); //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);
}
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); CREATE(world, struct room_data, rec_count);
rewind(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); discrete_load(db_file);
} }
}
void discrete_load(FILE * fl) void discrete_load(FILE * fl)
@@ -257,6 +304,9 @@ void discrete_load(FILE * fl)
fprintf(stderr, "Format error after room #%d\n", nr); fprintf(stderr, "Format error after room #%d\n", nr);
exit(1); exit(1);
} }
if (*line == 'T') //Toss triggers. THey currently break this util.
continue;
if (*line == '$') if (*line == '$')
return; 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 * * 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. /* get_line reads the next non-blank line off of the input stream.
* The newline character is removed from the input. Lines which begin * The newline character is removed from the input. Lines which begin
* with '*' are considered to be comments. * with '*' are considered to be comments.
+8 -2
View File
@@ -939,9 +939,15 @@ do \
#define CONFIG_CONFFILE config_info.CONFFILE #define CONFIG_CONFFILE config_info.CONFFILE
/** Player killing allowed or not? */ /** 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? */ /** 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? */ /** What level to use the shout command? */
#define CONFIG_LEVEL_CAN_SHOUT config_info.play.level_can_shout #define CONFIG_LEVEL_CAN_SHOUT config_info.play.level_can_shout
/** How many move points does holler cost? */ /** 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