Commit graph

9 commits

Author SHA1 Message Date
Stephen Dennis
8808b4c375 feat(#2136): flip fargs to const UTF8 * const — and convert every site the compiler surfaced
The flip: FUNCTION/XFUNCTION/FUN::fun/delim_check and the module
interfaces take `const UTF8 * const fargs[]`.  Double-const is
load-bearing: C++ qualification conversion needs const at both pointer
levels, so builder-side `UTF8 *[]` arrays convert implicitly — the
evaluator, the JIT marshaller, and every owner site need zero casts,
and slot reassignment inside bodies becomes a compile error for free.

The conversions: the flip landed first so the compiler enumerated every
violation; this commit is that inventory worked to zero — ~250 sites
across funceval, funceval2, functions, funmath, help, mail, session,
powers, levels, predicates, conf, walkdb, stringutil, timeutil/
date_scan (regenerated, one-line diff), exp3, and mux_main, each
classified per docs/campaign-2136-const-fargs.md's four recipes.

New idioms (functions.h): trim_space_sep_n() — non-destructive trim for
(pointer, length) consumers, so trim-then-scan sites need no copy at
all; FargVec — the argv counterpart of FargCopy for CS_ARGV handlers.
countwords() and DecodeListOfIntegers() rewritten non-destructive.

The flip deleted more than it added: #2157's fun_munge list1 copy, the
engine_com help-topic copy, fun_index's in-place NUL write, and five
const_casts (process_sex x4, sha1_helper).  const_cast budget: zero
added.

Trap recorded in the brief: an old-signature definition doesn't fail
the build — it becomes a C++ overload, and the new-signature symbol
stays undefined until dlopen(RTLD_NOW).  delim_check, the conn_bridge
bridges, the dbt_spike stub, and exp3::Call were all silently shadowed;
muxscript was the only host that noticed, because netmux's own net.cpp
resolved the flat-namespace lookup.  After any signature flip, grep the
old spelling.

Verified: make test EXPECT_CONFIG="jit=yes" (35 passed / 0 failed) and
make test-scenario, including the new tests/scenario/sidefx_fargs.py
that live-probes the class-3 wrappers smoke never touches (pemit/
trigger/link/tel/wipe/destroy).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 14:34:23 -06:00
Stephen Dennis
de80e7ac31 nls: mark move/walk/help/guest/quota/power notify prose with M_() (#1670)
Phase 3 coverage slice. Player and staff notify paths that still used
T() (cast-only) now use M_() so they extract into the catalogue:

  move   arrive/leave, get/drop, teleport failures, home
  walk   destination, blocked, patrol
  help   missing topic, match list, file errors
  guest  busy/create errors, listing total
  quota  Quota/Used display templates
  powers Power not found, @power echo, Powers: header
  session Poll / Doing

Attribute names, flag/power registry keys, logs, HTML, and softcode
machine tokens stay T()/S_(). Regenerates pot (670 -> 704) and xx.po.
2026-07-28 05:34:30 +00:00
Stephen Dennis
301a7664d0 nls: mark db/cron/powers/session misc notify prose with M_ (#1419)
Remaining small engine notify piles (~45 sites across db, cron, powers,
session, object, conf, help, log). Leave tprintf formats as T().
Half-mark pass clean. Regenerate pot/xx without fuzzy entries.
2026-07-27 11:50:31 +00:00
Stephen Dennis
b5ee3b6f81 refactor: use UTF-8 text in user-facing string literals (#1513)
Replace ~900 typographic \xE2\x80\x.. escapes (curly quotes, en dashes)
and a few \xE2\x80\230 octal workarounds with real UTF-8 in message
strings under mux/modules and mux/src. Leave stringutil and convert
charset mapping tables as explicit byte sequences.
2026-07-26 21:52:48 -06:00
Stephen Dennis
e7eb6ec76d nls: route literal #-1 softcode tokens through S_ (#1475)
Mechanical hygiene under the opt-in M_() design: replace T("#-1…") and
T("#-2…") with S_() so softcode ABI tokens are obvious in source and
cannot enter a player catalog. ~400 call sites across engine, exp3,
mail, and driver. Assembled/library-spliced diagnostics (plan §4.2)
are unchanged where they are not a single literal.
2026-07-27 01:00:55 +00:00
Stephen Dennis
3b62628772 Migrate 47 more alloc_lbuf/free_lbuf sites to LBuf RAII
Second wave: convert manual alloc/free pairs in cque (1), db_rw (4),
conf (5), db (2), engine_com (6), help (7), levels (2), predicates (5),
player (7), funmath (8).  Eliminates ~80 explicit free_lbuf calls
including multi-exit error paths in getboolexp1 (5 frees → 0),
get_list, AnnounceConnect/Disconnect, and the eight NOEVAL function
variants (cand/cor/firstof/allof and bool variants).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:55:40 -06:00
Stephen Dennis
974964719c Convert all static scratch buffers to thread_local
43 static scratch-buffer arrays across 21 files (5 in mux/src, 38 in
mux/modules/) changed from `static` to `thread_local`. Under the
current single-threaded evaluator this is a zero-behavior-change swap
— `thread_local` storage has the same lifetime and zero-allocation
properties as `static` — but each thread gets its own copy, which
makes these functions safe for a future multi-threaded evaluator
without any locking.

Read-only constant tables (`aRadix64`, `aRadixPenn36`,
`aRadixPenn64`, `Empty`) left as `static` because they are immutable
shared data.

Affected areas:
  net.cpp        — queue_string co_buf, trimmed_site, dump_users NameField
  signals.cpp    — signal_desc
  stubslave.cpp  — Stub_PipePump
  attrcache.cpp  — sqlite_attr_buf
  boolexp.cpp    — parsestore
  command.cpp    — preserve_cmd, SpaceCompressCommand, LowerCaseCommand
  comsys.cpp     — NewTitle, Buffer, temp
  db.cpp         — tbuff, Buffer (x2)
  flags.cpp      — buff
  funceval.cpp   — textbuff
  functions.cpp  — TimeBuffer64, TimeBuffer80, Buffer
  help.cpp       — Line, Buffer
  mail.cpp       — aFolders, Buffer, res, szFittedMailAliasDesc
  match.cpp      — buffer
  player.cpp     — szSalt, buf (x2), buff
  plusemail.cpp   — buf
  predicates.cpp — Buf (x2), pName
  session.cpp    — szFittedDoing
  set.cpp        — pRestrictedKeyText
  unparse.cpp    — buf, boolexp_buf
  mail_mod.cpp   — result, res, buf

All 21 files verified with g++ -std=c++17 -fsyntax-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:21:14 -06:00
Stephen Dennis
53bcc37a1c Switch Windows build from /MT to /MD and add mux_fclose
The modular architecture (netmux.exe, libmux.dll, engine.dll, etc.)
with static CRT (/MT) gave each module its own CRT heap. FILE* handles
from mux_fopen (in libmux) crashed when used by stdio functions in
other modules — fclose in write_pidfile, fgets in cf_include, etc.

Switch all 11 vcxproj files to /MD (shared CRT DLL) so all modules
share one CRT instance. Ship msvcp140.dll, vcruntime140.dll, and
vcruntime140_1.dll in the binary distribution.

Also add mux_fclose to libmux as good hygiene (pairs with mux_fopen),
and replace all cross-module fclose calls. This change is safe on Unix
where everything links into one process.

Add Startmux.bat as a replacement for Startmux.wsf since Windows
Script Host is no longer associated by default on modern Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 06:07:24 -06:00
Stephen Dennis
4ff1398de1 Restructure mux/ directory: component-based layout with proper build root
Move from flat mux/src/ layout to clean component hierarchy:
- mux/ is now the autoconf/automake build root (configure.ac lives here)
- mux/include/ — shared headers used by multiple components
- mux/lib/ — libmux.so (core utilities, no game state)
- mux/src/ — netmux driver only (thin networking shell)
- mux/modules/engine/ — engine.so (game logic)
- mux/modules/{comsys,mail,exp3,sqlproxy,sqlslave}/ — external modules
- mux/ganl/ — GANL networking library
- mux/sqlite/ — SQLite amalgamation (builds libsqlite3.a)
- mux/announce/ — announce tool (was mux/src/tools/)

Build changes:
- SUBDIRS ordering: ganl sqlite lib src modules announce
- libmux.so gets -Wl,-soname,libmux.so; netmux links via -L -lmux
- engine.so links libsqlite3.a and libmux.so with -Wl,--no-undefined
- RPATH uses $ORIGIN for portable .so resolution
- Install hooks use absolute paths for game/bin symlinks

Bug fixes:
- engine.so mux_Register() now passes nullptr to mux_RegisterClassObjects
  (matches all other modules; libmux already has the factory via dlsym)
- DbConvert() now calls pcache_init() before db_write, fixing a latent
  crash (free(): invalid pointer) when exporting from SQLite databases

411/411 smoke tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:38:37 -06:00
Renamed from mux/src/help.cpp (Browse further)