Tcl Source Code

View Ticket
Login
Ticket UUID: 1902890
Title: compiled regexp behaves differently
Type: Bug Created on: 2008-02-27 10:20:54
Submitter: avl42 Assigned to: hobbs
Subsystem: 47. Bytecode Compiler Severity:
Priority: 8 Last modified: 2026-10-11 07:45:23
Status: Open Closed by:
Resolution: None Closed on:
Version: 8.6.18, 9.0.5, 9.1.0
Description:
From comp.lang.tcl: <[email protected]>

% set pattern --; set text ----
% regexp $pattern $text; # no error
1
% regexp -- ----   ; # error for same arguments.
wrong # args: should be "regexp ?switches? [...]"

This bug-report only documents the difference,
not which of the two is to be considered correct.
User Comments:
dgp added on 2008-03-12 03:00:46:
Logged In: YES 
user_id=80530
Originator: NO


This is the same issue as the compiled
two argument [switch].

dgp added on 2008-03-12 03:02:40:
Logged In: YES 
user_id=80530
Originator: NO

That is, 1899962.

hobbs added on 2008-03-12 12:05:23:
Logged In: YES 
user_id=72656
Originator: NO

I believe the 2nd variant (eval version) is what should be fixed.  The extended info from wrong#args is:

wrong # args: should be "regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"

This indicates 2 known required args, and 2 args are given to regexp.  Why try to find errors when we can otherwise assume a regexp+2args == [regexp $pat $str] at all times?

dgp added on 2008-03-12 12:35:35:
Logged In: YES 
user_id=80530
Originator: NO


I agree that is the most sensible
way to define the behavior of this
command.

The snag is that the implementation
over many years *and the documentation*
disagree, saying that anything that
starts with "-" gets an attempt at
interpretation as a switch.

This is stupid, and it foils many
cases that could otherwise be compiled,
so I agree we should change it like
we changed [switch].

Just be ready for the same flood of
complaints we got about the [switch]
change.

dkf added on 2008-03-28 04:09:26:
Logged In: YES 
user_id=79902
Originator: NO

Be aware of the test regexp-20.2

dgp added on 2008-03-28 04:14:19:
Logged In: YES 
user_id=80530
Originator: NO


dkf points out the roadblock case:

% regexp -about foo
0 {}
% set e -about
-about
% set s foo
foo
% regexp $e $s
0

msofer added on 2008-07-21 11:40:14:
Logged In: YES 
user_id=148712
Originator: NO

This is tclguy's turf, I believe (and hope)

serhiy.storchaka added on 2026-10-11 07:39:52:

Still the same in 8.6, 9.0 and 9.1. TclCompileRegexpCmd() can only check a literal RE for a leading "-"; an RE from a variable went straight to INST_REGEXP, which does not parse switches.

I disagree with changing regexp to match the compiled behaviour: compilation is only an optimization, and the compiled code should always behave like the interpreted command. Proposed fix in branch regexp-compile-runtime-switch: when the RE is not known at compile time and there is no --, the compiled code checks at runtime whether it starts with "-", and if so calls regexp itself. So compiled and interpreted regexp now behave the same, including -about, and ordinary REs still use INST_REGEXP. Tests regexpComp-25.1 to 25.7.


serhiy.storchaka added on 2026-10-11 07:45:23:

With -- the RE cannot be a switch, so the compiled code needs no runtime check: regexp -- $re $string is the safest and fastest way to match a variable RE. Much code in Tcl's library is already written this way.