System Variable Entry: CLAUTOLISPCASEINSENSITIVEPATHS

← Prev | ↑ Chapter | Next → | Index | Symbols

System Variable Entry: CLAUTOLISPCASEINSENSITIVEPATHS

Name

CLAUTOLISPCASEINSENSITIVEPATHS

Type

integer

Default

0

Read-Only

no

Scope

session

Description

clautolisp-only. At 0 (the default) paths are used exactly as written. At 1 every incoming path is validated against the filesystem without regard to case and returned under its real name.

Resolution is per component, and deterministic:

  1. an exact match wins, without even listing the directory — the common case, and it costs nothing;
  2. otherwise a unique case-insensitive match is taken;
  3. otherwise — several entries differing only by case, which a case-sensitive filesystem permits — it is an error naming the candidates, never an arbitrary choice.

Normalising matters as much as finding: what findfile returns is stored by the caller and used again later, so the real name is what is handed back.

Reading and creating are treated differently, and deliberately so. For a path that must exist, the whole path is resolved. For a path being created, the last component is taken as written(open "Rapport.txt" "w") creates Rapport.txt and does not fall back onto a pre-existing RAPPORT.TXT, which would overwrite a file the author never named — while the directories leading to it are still resolved. Mode "a" is the mixed case: an existing file is appended to under its real name, a new one is created under the name as written.

Whenever a path is located only because the case was folded, a [path-case] diagnostic names the real spelling. The run proceeds and the developer learns of a path that would fail on a strict filesystem; without it the sysvar would only hide the problem.

Read/Written By

  • findfile
  • load
  • open
  • vl-file-copy, vl-file-delete, vl-file-directory-p, vl-file-rename, vl-file-size, vl-file-systime
  • vl-directory-files, vl-mkdir

Compatibility

clautolisp extension; the vendors have no such system variable.

Present under every dialect except --strict, and read/write in all of them. That includes the emulation dialects, where a vendor's getvar would not know the name — accepted deliberately, since the vendors' own system-variable lists already differ from one another. It matters because a --bricscad / --autocad run is how a corpus WRITTEN FOR WINDOWS is exercised, and that corpus is the one whose path spellings nobody ever checked: registering the variable only under --clautolisp put it exactly where it was least needed, and left setvar and the environment with no purchase where the need actually arises.

--strict is the exception, and for its own reason: its job is to report what a portable engine would refuse, and a path whose case does not match the disk is precisely that.

Seedable from the environment variable of the same name (precedence setvar > env > default), so a whole corpus or a CI job can be treated without editing a line of it — including under an emulation dialect:

CLAUTOLISPCASEINSENSITIVEPATHS=1 clautolisp --dialect bricscad-v26 …

The default is 0 EVERYWHERE, emulation dialects included, and that is a decision rather than an omission. One could argue that a dialect emulating Windows should fold case by default, since Windows filesystems do — but BricsCAD on Linux is not believed to fold case on a case-sensitive filesystem, so folding by default would be clautolisp's own invention rather than fidelity to the emulated engine. It stays an explicit request.

There is also a security reason for the default, independent of dialect: at 1 a program reaches files an exact spelling would not have reached, so a program building a path from user input has a wider surface.

Source Notes

  • No vendor reference. Requested from SCHMS+ after a failure that appeared only under Linux; specified and implemented per issues/open/case-insensitive-pathname-resolution.issue in 1.8.52.
  • Widened to every dialect but --strict in 1.8.56, per issues/closed/case-insensitive-paths-ignored-in-cad-dialects.issue: SCHMS+ runs its suites under --dialect bricscad-v26, to exercise the code as it will run, and there the variable did not exist at all.