rcs(3tcl)

πŸ“¦
version 2.0 Β· 2 versions
, in debian trixie, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸŽ€ rcs πŸŽ€ β€” RCS low level utilities

okay bestie, this is rcs(3tcl), the Tcl package for RCS low level utilities. sit down, hydrate, and let's get into it πŸ’…


✨ SYNOPSIS ✨

package require Tcl 8.5 9

package require rcs ?0.2?

::rcs::text2dict text

::rcs::dict2text dict

::rcs::file2dict filename

::rcs::dict2file filename dict

::rcs::decodeRcsPatch text

::rcs::encodeRcsPatch pcmds

::rcs::applyRcsPatch text pcmds

πŸ’– DESCRIPTION πŸ’–

so the Revision Control System, aka RCS, is a whole set of applications plus the data formats that go with them, and the whole point of them is letting a system persist the history of changes made to a text. it, and its cousin SCCS, are literally the blueprint for a ton of other systems like CVS, etc. iconic behavior fr.

πŸ’€ not me needing to say this but: this package does NOT implement RCS. it does not. nope.

what it does do is hand you a bunch of low level commands that are supposed to be useful when you're implementing any revision management system. namely:

  1. the conversion of texts into and out of data structures that let you easily modify that text with patches β€” and a patch here means a sequence of instructions for transforming one text into another one. so like, text ⇄ structure.
  2. and the conversion of one particular format for patches, the so-called RCS patches, into and out of data structures that let you easily apply them to texts. structure ⇄ patch. it's giving pipeline energy 🌈

πŸ‘‘ COMMANDS πŸ‘‘

  • ::rcs::text2dict text β€” takes that text argument and converts it into a dictionary that contains and represents the exact same text, but in an indexed form, and returns that dictionary as its result. want the deets on what the result looks like? section TEXT DICT DATA STRUCTURE, go read it bestie. also important: this command returns the canonical representation of the input. no cap.
  • ::rcs::dict2text dict β€” this is the complementary operation to ::rcs::text2dict, the lil mirror of it. it takes a dictionary in the form described in section TEXT DICT DATA STRUCTURE, turns it back into a text, and returns that text as its result. and the good news? this command does accept non-canonical representations of the text as its input. we love a flexible queen.
  • ::rcs::file2dict filename β€” literally identical to ::rcs::text2dict, except it reads the text it's supposed to convert from the file with path filename instead of from an argument. the file has to exist and it must be readable too, so no sneaking around permissions 🌸
  • ::rcs::dict2file filename dict β€” identical to ::rcs::2dict2text, except it stores the resulting text in the file with path filename. the file gets created if it didn't already exist, and it must be writable. the result of the command is the empty string. that's it, that's the whole vibe.
  • ::rcs::decodeRcsPatch text β€” converts the text argument into a patch command list (PCL) as specified in the section RCS PATCH COMMAND LIST, and returns this list as its result. it assumes the input text is in diff -n format, also known as RCS patch format, as specified in the section RCS PATCH FORMAT. πŸ‘€ heads up though: this command ignores no-ops in the input β€” in other words the resulting PCL contains only instructions that actually do something. no dead weight.
  • ::rcs::encodeRcsPatch pcmds β€” complementary operation to ::rcs::decodeRcsPatch, you guessed it. it converts a patch command list (PCL) list as specified in the section RCS PATCH COMMAND LIST back into a text in RCS PATCH FORMAT and returns that text as its result.
😭 note that this command and ::rcs::decodeRcsPatch are not exactly complementary, because the decoder strips no-ops from its input and the encoder literally cannot put them back into the generated RCS patch anymore. so like, the result of a decode/encode step may not match the original input at the character level β€” but it will match it at the functional level. so we forgive it. 🫢
  • ::rcs::applyRcsPatch text pcmds β€” this operation applies a patch, in the form of a PCL, to a text given in the form of a dictionary, and returns the modified text β€” again as a dictionary β€” as its result.

want to work with actual real text? then use the commands ::rcs::text2dict (or equivalent) and ::rcs::decodeRcsPatch to transform the inputs into data structures that this command will accept. and analogously, use the command ::rcs::dict2text (or equivalent) to transform the result of this command into actual text as required. teamwork makes the dream work πŸ’œ


πŸ¦‹ TEXT DICT DATA STRUCTURE πŸ¦‹

a text dictionary is a dictionary whose keys are integer numbers and whose associated values are text strings. the keys represent the line numbers of a text, and the values represent the text of that line. and here's the gag: one single text can have many representations as a dictionary, because the index values only have to be properly ordered for reconstruction β€” their exact values don't matter at all. similarly, the strings may actually span multiple physical lines. flexible fr.

the text

Hello World,
how are you ?
Fine, and you ?

for example can be represented by

{{1 {Hello World,}} {2 {how are you ?}} {3 {Fine, and you ?}}}

or

{{5 {Hello World,}} {8 {how are you ?}} {9 {Fine, and you ?}}}

or

{{-1 {Hello World,
how are you ?}} {4 {Fine, and you ?}}}

the first dictionary is the canonical representation of the text: line numbers starting at 1, increasing in steps of 1, with no gaps, and each value representing exactly one physical line. clean. pristine. main character energy.

all the commands that create dictionaries from text will return the canonical representation of their input text. and the commands that take a dictionary and return text will generally accept all representations, canonical or not. generous of them honestly.

πŸ’€ heads up: the result of applying a patch to a text dictionary will in general cause the dictionary to become non-canonical. it's not a bug it's just what happens.

🌈 RCS PATCH FORMAT 🌈

a patch is, in general, a series of instructions on how to transform an input text T into a different text T' β€” and it's also encoded in text form as well. double duty.

the text format for patches that this package understands is a very simple one, known under the names RCS patch or diff -n format.

patches in this format contain only two different commands: deletion of old text, and addition of new text. that's it. the replacement of some text by a different text is handled as a combination of a deletion followed by an addition. sneaky but effective ✨

the format is line oriented, with each line containing either a command or text data associated with the preceding command. and the first line of a RCS patch is always a command line. periodt.

the commands are:

  • "" β€” the empty line is a command which does nothing. it's the no-op. it exists. it does nothing. we stan a low-effort icon.
  • "astart n" β€” a line starting with the character a is a command for the addition of text to the output. it is followed by n lines of text data. when applying the patch, the data is added just between the lines start and start+1. the same effect is had by appending the data to the existing text on line start. a non-existing line start is created. πŸ’–
  • "dstart n" β€” a line starting with the character d is a command for the deletion of text from the output. when applied it deletes n lines of text, and the first line deleted is at index start. bye bestie πŸ‘‹
⚠️ note that the line indices start always refer to the text which is transformed as it is in its original state, without taking the preceding changes into account.
⚠️ note also that the instructions have to be applied in the order they occur in the patch, or in a manner which produces the same result as in-order application. no skipping ahead.

this is the format of results returned by the command ::rcs::decodeRcsPatch and accepted by the commands ::rcs::encodeRcsPatch and ::rcs::appplyRcsPatch respectively. note however that the decoder will strip no-op commands, and the encoder will not generate no-ops, making them not fully complementary at the textual level β€” only at the functional level. we've discussed this. we've accepted this. moving on 🧚

and an example of a RCS patch is

d1 2
d4 1
a4 2
The named is the mother of all things.

a11 3
They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!

πŸ’… RCS PATCH COMMAND LIST πŸ’…

patch command lists (short: PCL's) are the data structures generated by the patch decoder command and accepted by the patch encoder and applicator commands. they represent RCS patches in the form of Tcl data structures. so like, the same info, but Tcl-flavored.

a PCL is a list where each element represents a single patch instruction β€” either an addition or a deletion. the elements are lists themselves, where the first item specifies the command and the remainder represent the arguments of the command. nested lists, we love her πŸŽ€

  • a β€” this is the instruction for the addition of text. it has two arguments: the index of the line where to add the text, and the text to add β€” in that order.
  • d β€” this is the instruction for the deletion of text. it has two arguments: the index of the line where to start deleting text, and the number of lines to delete β€” in that order.

this is the format returned by the patch decoder command and accepted as input by the patch encoder and applicator commands.

an example for a patch command is shown below β€” it represents the example RCS patch found in section RCS PATCH FORMAT:

{{d 1 2} {d 4 1} {a 4 {The named is the mother of all things.

}} {a 11 {They both may be called deep and profound.
Deeper and more profound,
The door of all subtleties!}}}

πŸ™ˆ BUGS, IDEAS, FEEDBACK πŸ™ˆ

this document, and the package it describes, will undoubtedly contain bugs and other problems. obviously. please report such in the category rcs of the Tcllib Trackers at http://core.tcl.tk/tcllib/reportlist. and please also report any ideas for enhancements you may have for either the package and/or the documentation β€” we want to hear them, fr fr.

when proposing code changes, please provide unified diffs, i.e. the output of diff -u. this is not optional, bestie, this is the love language.

note further that attachments are strongly preferred over inlined patches. attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar. yep, that specific button. go get it. 🫢


🌸 SEE ALSO 🌸

struct, textutil


⭐ KEYWORDS ⭐

CVS, RCS, RCS patch, SCCS, diff -n format, patching, text conversion, text differences


πŸ“ CATEGORY πŸ“

Text processing


Copyright (c) 2005, Andreas Kupries <andreas_kupries@users.sourceforge.net>
Copyright (c) 2005, Colin McCormack <coldstore@users.sourceforge.net>

okay that's the whole page, you're officially educated πŸ’… and for the cute sign-off: this little masterpiece lives in tcllib, version 0.2, and it's the rcs(3tcl) page β€” that's the source, the version, and the date, all wrapped up with a bow πŸŽ€ bye bestie, go patch something! πŸ¦‹

πŸ“¦ where this page comes from