Exchange Items - X


An exchange item consists of the code X followed by an exchange specification. An exchange item is used swap two different strings at the same time.  This performs a task that is difficult to do with standard CHANGE commands.


Consider the task of swapping (interchanging) two different words within some range of lines.  Suppose everywhere the word “ONE” was present, you wanted “TWO”, and vice-versa (and let’s assume your data has both kinds of words).  You can’t just say CHANGE ONE TWO WORD ALL, because as soon as you did, all the “ONE” words in question would become “TWO”, so you would be unable to change the original instances of “TWO” back to “ONE”.  


Using an intermediate value of "///" you could try doing CHANGE ONE "///" WORD ALL first, then follow it with CHANGE TWO ONE WORD ALL, and then finally, with CHANGE "///" TWO WORD ALL.  But there are problems with that.  First, it takes three different commands, and they are hard to keep straight without making a mistake.  Second, if your strings are WORD delimited, and your intermediate value is "///", those special characters may not meet the rules you have defined for “WORD” characters.


There are also potential issues on how the change will be handled if the two strings are of different sizes, depending of whether your edit session is set for CHANGE DS mode or CHANGE CS mode; the formatting might get done improperly with all those CHANGE commands being performed with varying sizes of data, depending on what was adjacent to your data (and where) when the commands were issued.


You could possibly add "/" as a recognized WORD character on the WORD line command, but you might need your original WORD definition left alone.  You could also try picking some other intermediate value, but you could still run into problems.  Any attempt to swap these two values “the hard way” is awkward, unreliable and inefficient.  


In contrast, using the string exchange mapping item to do this is much easier.  To illustrate, exchanging the two strings we discussed above could be done with the command  CHANGE P'@@@' M"X'ONE=TWO'" WORD ALL.



Syntax of a string exchange item:


       X  exchange-pair  column-reference  


X :


Introduces the string exchange item.





Exchange-pair:


Defines the pair of strings to be exchanged.  The pair is a quoted string set or string-pair, in the format of:


       'first =second'                        -- in string-set notation

       or

       'first'='second'                        -- in string-pair notation


For example, X'one=two'.  This operand can have a suffix of C, T or X.  If the suffix is T, values are compared as case-insensitive.  When the command has a string-pair separator of : colon, it implies string type T, and it is allowed but not necessary to also use the type code T when the : colon is present.  To avoid ambiguity, the : colon notation is only allowed on a string pair, not in a single string set.  That is, X'one':'two' is valid but  X'one:two' is not valid.  If you want both case-conformance and a use a string set, you must specify it as  X'one=two'T.  The colon notation is just a shorthand for putting T on both sides of a string pair.


If no string suffix or colon notation is present, a CC or CT mapping item is used to specify case-sensitivity, or else the PROFILE CASE setting on the current edit file is used to determine case-sensitivity.  In case a hex string is used to define the values of first and second, you would still use an = equal sign to separate the two values.  When the command has a : colon separator like X'one':'two', these considerations are ignored, because then the strings are treated as type T and compared as case-insensitive.


For non-hex values, in the event that the = equal sign is part of the values you are exchanging, you must specify the two values as a string pair.  For example, if you wanted to exchange A=B with C=D, you would use M"X'A=B'='C=D'"  When you are not dealing with embedded equal signs, the shorter string set form will be easier to use.  In a string pair, each side of the string can use different quote types, if desired.  See the Mapping Strings Quick Reference for a summary of how varying string type code combinations are handled.  With a few exceptions, the various combinations of type codes work the same way they do on the string‑1 and string-2 values of an SPFLite CHANGE primary command.


When the command has a : colon separator, the strings are assumed to be case insensitive, so the only use for a type code is if you wanted to specify a string in hex with an X code on one or both sides.  Note that if you want one string to be hex and one to be non-hex, both parts of the string pair must have their own type codes; you put X on one side alone, an X is implied for the other side.


It would be unusual to treat hex value as case-insensitive.  If you went to the trouble of writing out some value in hex, chances are good you wanted that specific value, and not some upper- or lower-case version of your hex data where some of the bytes happened to contain the hex codes for alphabetic data.  Perhaps you do need to do this, but real uses for it will be rare.


If the mapping string has a CT command code prior to the X command, or the edit file has a PROFILE CASE T active, but the string exchange item does not specify a : colon separator or a string type code of T, string comparisons are done as case-insensitive, without the changes being case conformant.


Column-reference:


Defines a column or column-range where characters of the source data string are obtained, and checked against the first and second string values, as follows:





Because X is a is a copying command that will auto-reference, if X is the first command of your mapping string, it will refer to the entire source string, and either store the first or second string value into the result string, or it will copy the value of the source string into the result string.


For example, if your mapping string is M"X'one=two'C" and a 3-character value is selected, then:


If the value selected is …

it becomes …

one

Two

two

One

ten

Ten

ONE

ONE


To perform this operation on the current contents of the result string, specify a . dot symbol instead of, or in addition to, a standard column-range operand.    When this is done, the value obtained is appended to the current contents of the result string, if either the first or second string matches; otherwise the value you are testing is appended to the current contents of the result string.  


In this example, if the result string originally was one it will now contain onetwo.  If you really needed to create a result string that contains both the original value and the new value, this might be of some use.  Otherwise, the . dot notation may not be what you need.


Here is an example of a case conformant exchange operation.  If your mapping string  is M"X'one=two'T   or   M"X'one':'two' and a 3-character value is selected, then:


If the value selected is …

it becomes …

one

two

One

Two

ONE

TWO

two

one

Two

One

TWO

ONE

Ten

Ten


The X mapping item can only exchange one pair of strings at a time.  If you need capabilities beyond this, an execute-macro string¸ also known as an “E string”, may be useful.


Special handling when X is used on the result string


As noted, X is a copying command that will auto-reference.  If you want to use X to exchange a string (or substring) that is already in the result string, you can use dot notation.  For instance, if the source string contains “oneFiveSix” and you issued a command like M"1-3 X'one=two'.1-3", the usual way commands operate is that the product of the command is appended to the end of the result string.  In this example, you would first copy the value “one” and then exchange “one” and “two”, appending that to the result.  The final value would have been “onetwo”.  


For most people, that would be a peculiar result, and would not be very useful.  To avoid this problem, X takes note that the value you asked to work on is already in the result string.   When it is, X will store the resulting value in place, and not append it.  So, when the source string contains “oneFiveSix” and you issued a command like M"1-3 X'one=two'.1-3", the result string will contain “two”.




Created with the Personal Edition of HelpNDoc: Easily create HTML Help documents