2

My company uses FreeBSD, and therefore FreeBSD's flavor of make.

A few of our in-house ports include something like this (where BRANCH is something that came from an SVN URL, either 'trunk' or a branch name like 'branches/1.2.3').

PORTVERSION=   ${BRANCH:C,^branches/,,}

The Variable modifiers section of make(1) documents the :C colon-c modifier as

:C/pattern/replacement/[1gW]

Am I looking at the right documentation? ^branches/ looks like a regex pattern to me, but it looks like the actual code uses , instead of / as a separator. Did I skip documentation explaining that?

josaphatv
  • 633
  • 4
  • 19
  • 3
    I don't know much about BSD make in particular, but most POSIX tools that support this type of replacement process allow you to choose whatever character you like as the delimiter. Basically, whatever character comes first is assumed to be the delimiter you want to use. `sed`, etc. all work like this too. So if you use `:C,` then your delimiter is `,`; if you use `:C/` then your delimiter is `/`. If you use `:C!` then it's `!`, etc. This lets you avoid having to escape the delimiter in the regex or replacement, just by choosing the delimiter carefully. – MadScientist Jun 11 '21 at 22:21
  • I had no idea. That's super useful! – josaphatv Jun 14 '21 at 13:08

1 Answers1

3

The documentation says:

:C/pattern/replacement/[1gW]

The :C modifier is just like the :S modifier except that the old and new strings, instead of being simple strings, are an extended regular expression (see regex(3)) string pattern and an ed(1)-style string replacement.

and in :S:

Any character may be used as a delimiter for the parts of the modifier string.

As @MadScientist pointed out, it's quite common to use a different delimiter, especially when / is a part of pattern or replacement string, like in your case. Otherwise it would require escaping and would look like ${BRANCH:C/^branches\///} which seems less readable.

raspy
  • 3,995
  • 1
  • 14
  • 18