SSREPLACE

SSREPLACE reads a control file, a replacement file, where each line consists of pairs of old-string and new-string. SSREPLACE searches the files in one or more version-control directories for old-strings. The default behaviour is to merely list the matches, and how they would look after the replacement. If you specify the ‑edit switch, SSREPLACE also checks out the files and performs the edits. Like SSGREP, SSREPLACE ignores comments in files of known types, unless told otherwise.

Contents:
   Command-Line Syntax
   How Checkouts Are Performed
      SourceSafe
      TFS
      File Encoding
   Format of the Replacement File
   A Crash-Course in Perl Regexps

Command-Line Syntax

ssreplace [-config config-file | -VC VC-path] [-lang SQL|VB|C ... ]
[-type filetype ...] [-comments] [-nolist] [-HTML]
[-edit] [-rename] [-exclusive] file
‑config Config-file that determines which version-control directories that SSREPLACE is to search. With SSREPLACE, any version specification in the config-file is ignored, as SSREPLACE always searches the most recently checked-in version of each file.
‑VC Specifies a VC-path for a singular version-control directory for SSREPLACE to search. SSREPLACE will search the most recently checked-in version of each file.
   You must specify one ‑config and ‑VC, unless SSREPLACE is able to map your current directory to a folder in TFS.
‑comments Whether SSREPLACE is to search and replace also within comments, or only in text outside comments. See the page for SSGREP, for which file types AbaPerls knows how to strip comments from the code.
   If you do not specify ‑comments, SSREPLACE will only search and replace text outside comments.
‑HTML Instructs SSREPLACE to produce the list of changes in HTML format, with underlining the replacements. This greatly enhances readability.
   As you will need a web browser to read the output, it is advisable to use > to redirect the output to a file.
‑type Specifies that SSREPLACE is to search only files of the specified type(s). You can specify multiple ‑type on the command line. You can specify the file type with a leading period, but this is not required. Example: to search only stored procedures and triggers you could specify: ‑type .sp ‑type TRI. As the example indicates the type names are case-insensitive.
-langThis is a shortcut to ‑type that permits you to specify all types for a certain programming language in one go. The following values are recognized:
SQL – The SQL files according to the AbaPerls SQL directory structure.
VB – Files of the types .bas, .cls, .frm and .vb.
C – Files of the types .c, .cs, .cpp, .h and .hpp.
As with ‑type you can specify multiple ‑lang on the command line. You can mix ‑lang and ‑type.
‑nolist Normally, SSPREPLACE prints all matches and their replacements it performs. SSREPLACE also prints the Perl code it creates for the replacements with statistics over the number of matches. If you specify ‑nolist, SSREPLACE prints only the number of changes in each affected file.
   The output is printed to the command-line window. Use > to redirect output to a file.
‑edit

Instructs SSREPLACE to check out the matching files and perform the replacements. Without ‑edit, SSREPLACE only searches the files and prints the replacements.

‑rename

With ‑rename, SSREPLACE also applies the replacements on file names. That is, files that matche any old-string are renamed. This is handy if you want to rename a couple of stored procedures. The ‑rename switch only has effect if you also specify ‑edit.
   If you do not specify ‑rename, SSREPLACE still lists the file names that matche the old-strings in the replacement file.

‑exclusive This option is only applicable, if you also specify ‑edit. If you specify ‑exclusive, AbaPerls will make an exclusive checkout, preventing other users from checking out the file. This also means that you will fail to check out the file, if the file is already checked out by someone else. The default is ‑noexclusive, that is concurrent checkouts are permitted. However, the corresponding option in the SourceSafe API does not seem to work, so with SourceSafe, checkouts are always exclusive.
repl-file File with the replacements to perform. Each line consists of old-string, new-string and repl-options. The fields are separated by white space. The three fields are used as input to the s/// operator in Perl with a few twists. See further below for more details on the format.

SSREPLACE always performs a deep search of the VC-path(s) you specify, either through the ‑VC option directly, or through a config-file. However, SSREPLACE exempts two categories of files from the search:

If you have a file checked out, SSREPLACE will search your copy on disk, not the copy in the version-control repository.

How Checkouts Are Performed

This section describes what happens when you specify the ‑edit, ‑rename and ‑exclusive options. There are a couple of differences between SourceSafe and TFS, and I describe how SSREPLACE works with the two version-control systems separately.

Observe that no matter the version-control system, SSREPLACE never checks in any files. You are supposed to review the files before you check in to verify that there are no unintended changes.

The default for SSREPLACE is to search and replace only outside comments. SSREPLACE first strips the code of comments, performs the replacements and then puts the comments back. AbaPerls does not really keep track on where on the line the comment is, so you may see changes if you there are comments in "odd" places.

SourceSafe

With SourceSafe, you must specify one of ‑VC and ‑config, as SSREPLACE cannot determine a version-control directory from you working folder.

If the file is not checked out, SSREPLACE checks it out. Just like all other AbaPerls tools, SSREPLACE does not honour your SourceSafe settings and ignores your working directories. Instead SSREPLACE checks out files relatively to your current directory. If you specify a single VC-path with ‑VC, SSREPLACE places checked-out files in the current directory or a subdirectory thereof. Say that you specify the path $/abc/3.20/sql and your current directory is C:\project\edits and the files $/abc/3.20/sql/grant.template, $/abc/3.20/sql/SP/abc_update_sp.sp and $/abc/3.20/sql/functions/specialfun.sqlfun match any of your search strings. These files will be checked out to C:\project\edits\grant.template, C:\project\edits\sp\abc_update_sp.sp and C:\project\functions\specialfun.sqlfun.

If you already have a file checked out, SSREPLACE will not check out the file anew, but perform the edits in the copy you already have on disk.

If someone else has the file checked out, SSREPLACE will not check out the file, no matter if you specified ‑exclusive or not. (The blame for this goes to the SourceSafe API which exposes such a flag, but does not seem to honour it.) The output from SSREPLACE will include an error message why it was not possible to check out the file.

Be very careful with the ‑rename option. In SourceSafe, rename operations takes effect immediately. Furthermore, if a file is shared among several projects, the file is renamed in all projects. Therefore, only use ‑rename if you have carefully examined the output from SSREPLACE and made sure that you have performed any branching required to prevent the change to happen in versions where it should not happen. Then again, ‑rename is very convenient. Not the least since once you have the file checked out, the SourceSafe GUI does not permit you to rename the file. If there is a match on the name of the file that you already have checked out, SSREPLACE renames the local file as well. (And, yes, in SourceSafe. While the SourceSafe GUI does not permit you, the API is more convincible.)

TFS

If you don't specify any of ‑VC or ‑config, SSREPLACE attempts to map the currect directory to a version-control folder in TFS.

If the file is not checked out, SSREPLACE checks it out. In TFS, you cannot check out a file with less than you have a workspace. Rather than creating a new workspace for you, SSREPLACE attempts to reuse an existing workspace. The following applies:

  1. If you don't have any workspace defined on the current computer, SSREPLACE is unable to check out files.
  2. If you did not specify any of ‑VC and ‑config, and this implicitly mapped to a TFS folder, SSREPLACE will use the workspace for which the mapping exists.
  3. If you specified one of ‑VC or ‑config, and there is a workspace with the same name as the computer, SSREPLACE will use this workspace.
  4. If you specified one of ‑VC or ‑config, and there are one or more workspaces on the computer, but none that matches the computer name, SSREPLACE will use the first workspace it finds.

If SSREPLACE is unable to check out a file, SSREPLACE will include the error message in the output. With TFS there are potentially many reasons why a file cannot be checked out. For instance, there is no workspace, or no local path has been defined for the TFS directory. Note that TFS does not permit you check out a file, if you have not previously gotten the file into your local directory.

If you already have file checked out, SSREPLACE will change local copy of the file. Note that if you have multiple workspaces on the computer, you may have checked out the file in a different workspace than the workspaces in which SSREPLACE performs check-outs.

If you use the ‑rename option, SSREPLACE will rename the file, and in difference to SourceSafe this is perfectly safe with TFS; the change will be a pending change that you can undo.

The ‑exclusive option works as advertised with TFS. That is, if you don't specify it, SSREPLACE will perform concurrent checkouts, and permit other users to do the same. If you use ‑exclusive, SSREPLACE will place a CheckOut lock on the file.

File Encoding

When writing a new file, it may happen that SSREPLACE changes the encoding of the file. When reading the file, SSREPLACE looks for a byte-order mark (BOM) to see if the file ia a Unicode file in any of the encodings UTF-8, UTF-16 or UTF-16BE. If there is no BOM, SSREPLACE attempts to auto-detect any UTF-16 encoding, but this is a bit of guesswork. SSREPLACE does not attempt to auto-detect UTF-8. If SSREPLACE is not able to find a BOM or auto-detect UTF-16, SSREPLACE assumes that the file has an 8-bit encoding.

When writing the output file, SSREPLACE writes an 8-bit file, if the input file is an 8-bit file. If the input file is a Unicode file, SSREPLACE retains the encoding of the input file only if you have Perl 5.14 or later, and will always write a BOM. If you have Perl 5.12, SSREPLACE will always use UTF-8 (with BOM) for Unicode files, because of a bug in Perl 5.12. If you want to retain the encoding, you will need to open the file in some environment and save it in the desired encoding.

In the case when SSREPLACE has to change the encoding, it also changes the encoding in TFS; in TFS this becomes a pending change just like the edit. SSREPLACE does not change the encoding in SourceSafe, as in SourceSafe the setting takes effect immediately, and would remain if you decide to undo the checkout. On the other hand, by default SourceSafe auto-detects the encoding of your local file.

Format of the Replacement File

Each line in the file consists of three fields, separated by blanks. The fields are old-string, new-string and repl-options. The latter field may be empty. Text that follows -- (two hyphens) is a comment and is ignored. Unless they appear in the beginning of the line, the hyphens must be preceded by space to work as a comment delimiter. (That is, two hyphens in the middle of old-string or new-string does not start a comment.) A line may be empty, or consist of comments only.

For each line that SSREPLACE traverses, SSREPLACE applies the replacements in repl-file in the order they appear in the file. That is, the second replacement is applied on the result of the first replacement. Thus, some carefulness may be in order.

A short description for the reader who already knows Perl regexps: the replacements are carried out with the operator s///. You need to observe the following differences with regards to how you use s/// in a Perl script:

A Crash-Course in Perl Regexps

Here follows a brief summary of the three fields – old-string, new-string and options – for the Perl illiterate. For a complete description, refer the perlre page or a suitable Perl book.

old-string

What is said here, also applies to the search strings you pass to SSGREP and the patterns you can use in grant.template, except for the operator \_ which is specific to SSREPLACE.

All alphanumeric characters (letters, digits and underscore) represent themselves. As far as I know, this is also true for characters outside the ASCII range; that is, Perl does not assign any particular meaning to these characters. An alphanumeric character preceded by a backslash, represents in many cases some special function. A non-alphanumeric character preceded by a backslash always matches that character and nothing else. If the character does not have any special meaning, the backslash is optional. The following non-alphanumeric characters are operators in regexps, and must be preceded by backslash to match the character itself:

$ @ / ( ) [ { + ? \ * . ^ | 

Also keep in mind, that if old-string starts with two hyphens, you need to use a backslash to prevent AbaPerls to interpret them as a comment delimiter.

The follow table lists the most commonly used components to build regular expressions.

. Matches any character.
* Previous regular expression 0 or more times. hej* matches "he", "hej", "hejj", but not "hejhej". The expression (hej)* matches "hejhej".
+ Previous regular expression 1 or more times.
? Previous regular expression 0 or 1 time. E.g. EXEC(UTE)? matches "EXEC" and "EXECUTE".
() Grouping to control in which order the expressions are evaluated, but also to get a back reference to use in new-string, more below.
^ Matches beginning of line.
$ Matches end of line.
[] A group of possible characters. Works like in SQL. For instance, [^0-9] matches all non-digit characters.
| Separates alternatives. E.g. (nisse|pelle) matches both "nisse" and "pelle".
\_ Matches a space character. (Applies to SSREPLACE only; this is not a Perl operator.)
\b Matches word boundary. If you wish to search for "insid", but not want a match for "insidnew" or "newinsid", specify \binsid\b as your search string.
\s \S \s matches a white-space character, i.e. space or tab. \S matches all characters that \s does not match.
\w \W \w matches a word character, that is, a-z, A-Z, 0-9 and underscore. Whether it matches letters like ÅÄÖ is up to Perl. \W matches everything that \w does not match.
\d \D \d matches a digit, 0-9. \D matches everything else.

new-string

Also for new-string the rule is that letters, digits and underscore represent themselves, but may carry a special meaning if they are preceded by backslash. You must precede the following non-alphanumeric characters with backslash to prevent Perl from apply any special meaning to them:

@ $ / \

If new-string begins with two hyphens, you must precede them with backslash to prevent SSREPLACE to interpret the hyphens as a comment delimiter.

The following special characters are of interest:

\U Change the case of the letters following \U to uppercase.
\L Change the case of the letters following \L to lowercase.
\E Closes \U or \L.
\_ Inserts a space. This is not a Perl operator, but added by SSREPLACE.
$1 $2 ... Refers back to parenthesized groups in old-string. $1 refers to the first parenthesis hectic. You can also write ${1}. See example below.

Say that we are change the datatype for all columns and variables that has "curcode" in the name from "ab_code" to "aba_curcode". We write this in the replacement file as:

(curcode\s+)ab_code  ${1}aba_curcode

${1} here refers back to "curcode" and all white-space that follows it. "aba_curcode" will then appear in the same column as "ab_code" did.

repl-options

The search option which you are most likely to use is I, which instructs SSREPLACE to use a case-sensitive search.

You could also use G or O to prevent SSREPLACE to use s/// with the g and o options, but it is questionable whether this is a good idea.

The option x enables extended regular expressions in Perl. These are beyond the scope of this crash-course.

An advanced option is e which means that new-string is a Perl-expression. If you use e, you still need to use \_ to specify a space.

You cannot use the options s and m with SSREPLACE.

For detailed information about these options, please refer to the Perl documentation.