Hex Artifact Content
Not logged in

Artifact 166f9426d07992ec350dc3c6790bcc575727f039:

File tools/lib/rcsparser.tcl part of check-in [3852590ce6] - New feature for importer. rcs parser extended so that it can store parse results for quick loading in future runs. This feature has no real use in regular use of the importer, i.e. one-shot conversion of a CVS repository to fossil. It is however useful for debugging when the source repository is scanned many times during test runs. Especially for large files, with lots of changes (like ChangeLogs), the direct loading of a Tcl dictionary is much faster than actually parsing the archive files. by aku on 2007-09-26 05:02:06.

0000: 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  # --------------
0010: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0020: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0030: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0040: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
0050: 23 20 54 6f 6f 6c 20 70 61 63 6b 61 67 65 73 2e  # Tool packages.
0060: 20 50 61 72 73 69 6e 67 20 52 43 53 20 66 69 6c   Parsing RCS fil
0070: 65 73 2e 0a 23 0a 23 20 53 6f 6d 65 20 6f 66 20  es..#.# Some of 
0080: 74 68 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  the information 
0090: 69 6e 20 52 43 53 20 66 69 6c 65 73 20 69 73 20  in RCS files is 
00a0: 73 6b 69 70 70 65 64 20 6f 76 65 72 2c 20 6d 6f  skipped over, mo
00b0: 73 74 0a 23 20 69 6d 70 6f 72 74 61 6e 74 6c 79  st.# importantly
00c0: 20 74 68 65 20 61 63 74 75 61 6c 20 64 65 6c 74   the actual delt
00d0: 61 20 74 65 78 74 73 2e 20 54 68 65 20 75 73 65  a texts. The use
00e0: 72 73 20 6f 66 20 74 68 69 73 20 70 61 72 73 65  rs of this parse
00f0: 72 20 6e 65 65 64 0a 23 20 6f 6e 6c 79 20 74 68  r need.# only th
0100: 65 20 6d 65 74 61 2d 64 61 74 61 20 61 62 6f 75  e meta-data abou
0110: 74 20 77 68 65 6e 20 72 65 76 69 73 69 6f 6e 73  t when revisions
0120: 20 77 65 72 65 20 61 64 64 65 64 2c 20 74 68 65   were added, the
0130: 20 74 72 65 65 0a 23 20 28 62 72 61 6e 63 68 69   tree.# (branchi
0140: 6e 67 29 20 73 74 72 75 63 74 75 72 65 2c 20 63  ng) structure, c
0150: 6f 6d 6d 69 74 20 6d 65 73 73 61 67 65 73 2e 0a  ommit messages..
0160: 23 0a 23 20 54 68 65 20 70 61 72 73 65 72 20 69  #.# The parser i
0170: 73 20 62 61 73 65 64 20 6f 6e 20 52 65 63 75 72  s based on Recur
0180: 73 69 76 65 20 44 65 73 63 65 6e 74 2e 0a 0a 23  sive Descent...#
0190: 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   ---------------
01a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
01b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
01c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
01d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23  --------------.#
01e0: 20 52 65 71 75 69 72 65 6d 65 6e 74 73 0a 0a 70   Requirements..p
01f0: 61 63 6b 61 67 65 20 72 65 71 75 69 72 65 20 54  ackage require T
0200: 63 6c 20 38 2e 34 0a 70 61 63 6b 61 67 65 20 72  cl 8.4.package r
0210: 65 71 75 69 72 65 20 66 69 6c 65 75 74 69 6c 20  equire fileutil 
0220: 20 20 20 20 20 20 3b 20 23 20 54 63 6c 6c 69 62        ; # Tcllib
0230: 20 28 63 61 74 29 0a 70 61 63 6b 61 67 65 20 72   (cat).package r
0240: 65 71 75 69 72 65 20 76 63 3a 3a 74 6f 6f 6c 73  equire vc::tools
0250: 3a 3a 6c 6f 67 20 3b 20 23 20 55 73 65 72 20 66  ::log ; # User f
0260: 65 65 64 62 61 63 6b 0a 0a 6e 61 6d 65 73 70 61  eedback..namespa
0270: 63 65 20 65 76 61 6c 20 3a 3a 76 63 3a 3a 72 63  ce eval ::vc::rc
0280: 73 3a 3a 70 61 72 73 65 72 20 7b 0a 20 20 20 20  s::parser {.    
0290: 76 63 3a 3a 74 6f 6f 6c 73 3a 3a 6c 6f 67 3a 3a  vc::tools::log::
02a0: 73 79 73 74 65 6d 20 72 63 73 0a 20 20 20 20 6e  system rcs.    n
02b0: 61 6d 65 73 70 61 63 65 20 69 6d 70 6f 72 74 20  amespace import 
02c0: 3a 3a 76 63 3a 3a 74 6f 6f 6c 73 3a 3a 6c 6f 67  ::vc::tools::log
02d0: 3a 3a 2a 0a 7d 0a 0a 23 20 2d 2d 2d 2d 2d 2d 2d  ::*.}..# -------
02e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
02f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0300: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0310: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0320: 2d 2d 2d 2d 2d 2d 0a 23 20 41 50 49 0a 0a 23 20  ------.# API..# 
0330: 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a  vc::rcs::parser:
0340: 3a 70 72 6f 63 65 73 73 20 66 69 6c 65 0a 23 0a  :process file.#.
0350: 23 20 50 61 72 73 65 73 20 74 68 65 20 72 63 73  # Parses the rcs
0360: 20 66 69 6c 65 20 61 6e 64 20 72 65 74 75 72 6e   file and return
0370: 73 20 61 20 64 69 63 74 69 6f 6e 61 72 79 20 63  s a dictionary c
0380: 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 6d 65  ontaining the me
0390: 74 61 0a 23 20 64 61 74 61 2e 20 54 68 65 20 66  ta.# data. The f
03a0: 6f 6c 6c 6f 77 69 6e 67 20 6b 65 79 73 20 61 72  ollowing keys ar
03b0: 65 20 75 73 65 64 0a 23 0a 23 20 4b 65 79 09 09  e used.#.# Key..
03c0: 4d 65 61 6e 69 6e 67 0a 23 20 2d 2d 2d 09 09 2d  Meaning.# ---..-
03d0: 2d 2d 2d 2d 2d 2d 0a 23 20 27 68 65 61 64 27 09  ------.# 'head'.
03e0: 68 65 61 64 20 72 65 76 69 73 69 6f 6e 0a 23 20  head revision.# 
03f0: 27 62 72 61 6e 63 68 27 09 3f 0a 23 20 27 73 79  'branch'.?.# 'sy
0400: 6d 62 6f 6c 27 09 64 69 63 74 20 28 73 79 6d 62  mbol'.dict (symb
0410: 6f 6c 20 2d 3e 20 72 65 76 69 73 69 6f 6e 29 0a  ol -> revision).
0420: 23 20 27 6c 6f 63 6b 27 09 64 69 63 74 20 28 73  # 'lock'.dict (s
0430: 79 6d 62 6f 6c 20 2d 3e 20 72 65 76 69 73 69 6f  ymbol -> revisio
0440: 6e 29 0a 23 20 27 63 6f 6d 6d 65 6e 74 27 09 66  n).# 'comment'.f
0450: 69 6c 65 20 63 6f 6d 6d 65 6e 74 0a 23 20 27 65  ile comment.# 'e
0460: 78 70 61 6e 64 27 09 3f 0a 23 20 27 64 61 74 65  xpand'.?.# 'date
0470: 27 09 64 69 63 74 20 28 72 65 76 69 73 69 6f 6e  '.dict (revision
0480: 20 2d 3e 20 64 61 74 65 29 0a 23 20 27 61 75 74   -> date).# 'aut
0490: 68 6f 72 27 09 64 69 63 74 20 28 72 65 76 69 73  hor'.dict (revis
04a0: 69 6f 6e 20 2d 3e 20 61 75 74 68 6f 72 29 0a 23  ion -> author).#
04b0: 20 27 73 74 61 74 65 27 09 64 69 63 74 20 28 72   'state'.dict (r
04c0: 65 76 69 73 69 6f 6e 20 2d 3e 20 73 74 61 74 65  evision -> state
04d0: 29 0a 23 20 27 70 61 72 65 6e 74 27 09 64 69 63  ).# 'parent'.dic
04e0: 74 20 28 72 65 76 69 73 69 6f 6e 20 2d 3e 20 70  t (revision -> p
04f0: 61 72 65 6e 74 20 72 65 76 69 73 69 6f 6e 29 0a  arent revision).
0500: 23 20 27 63 6f 6d 6d 69 74 27 09 64 69 63 74 20  # 'commit'.dict 
0510: 28 72 65 76 69 73 69 6f 6e 20 2d 3e 20 63 6f 6d  (revision -> com
0520: 6d 69 74 20 6d 65 73 73 61 67 65 29 0a 23 0a 23  mit message).#.#
0530: 20 54 68 65 20 73 74 61 74 65 20 27 64 65 61 64   The state 'dead
0540: 27 20 68 61 73 20 73 70 65 63 69 61 6c 20 6d 65  ' has special me
0550: 61 6e 69 6e 67 2c 20 74 68 65 20 75 73 65 72 20  aning, the user 
0560: 73 68 6f 75 6c 64 20 6b 6e 6f 77 20 74 68 61 74  should know that
0570: 2e 0a 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ...# -----------
0580: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0590: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
05a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
05b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
05c0: 2d 2d 0a 23 20 41 50 49 20 49 6d 70 6c 65 6d 65  --.# API Impleme
05d0: 6e 74 61 74 69 6f 6e 0a 0a 70 72 6f 63 20 3a 3a  ntation..proc ::
05e0: 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a  vc::rcs::parser:
05f0: 3a 63 6f 6e 66 69 67 75 72 65 20 7b 6b 65 79 20  :configure {key 
0600: 76 61 6c 75 65 7d 20 7b 0a 20 20 20 20 76 61 72  value} {.    var
0610: 69 61 62 6c 65 20 63 61 63 68 65 0a 20 20 20 20  iable cache.    
0620: 73 77 69 74 63 68 20 2d 65 78 61 63 74 20 2d 2d  switch -exact --
0630: 20 24 6b 65 79 20 7b 0a 09 2d 63 61 63 68 65 20   $key {..-cache 
0640: 20 7b 0a 09 20 20 20 20 73 65 74 20 63 61 63 68   {..    set cach
0650: 65 20 24 76 61 6c 75 65 0a 09 7d 0a 09 64 65 66  e $value..}..def
0660: 61 75 6c 74 20 7b 0a 09 20 20 20 20 72 65 74 75  ault {..    retu
0670: 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22  rn -code error "
0680: 55 6e 6b 6e 6f 77 6e 20 73 77 69 74 63 68 20 24  Unknown switch $
0690: 6b 65 79 2c 20 65 78 70 65 63 74 65 64 20 6f 6e  key, expected on
06a0: 65 20 6f 66 20 2d 63 61 63 68 65 22 0a 09 7d 0a  e of -cache"..}.
06b0: 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e      }.    return
06c0: 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72  .}..proc ::vc::r
06d0: 63 73 3a 3a 70 61 72 73 65 72 3a 3a 70 72 6f 63  cs::parser::proc
06e0: 65 73 73 20 7b 70 61 74 68 7d 20 7b 0a 20 20 20  ess {path} {.   
06f0: 20 73 65 74 20 63 61 63 68 65 20 5b 43 61 63 68   set cache [Cach
0700: 65 20 24 70 61 74 68 5d 0a 20 20 20 20 69 66 20  e $path].    if 
0710: 7b 0a 09 5b 66 69 6c 65 20 65 78 69 73 74 73 20  {..[file exists 
0720: 24 63 61 63 68 65 5d 20 26 26 0a 09 28 5b 66 69  $cache] &&..([fi
0730: 6c 65 20 6d 74 69 6d 65 20 24 63 61 63 68 65 5d  le mtime $cache]
0740: 20 3e 20 5b 66 69 6c 65 20 6d 74 69 6d 65 20 24   > [file mtime $
0750: 70 61 74 68 5d 29 0a 20 20 20 20 7d 20 7b 0a 09  path]).    } {..
0760: 23 20 55 73 65 20 70 72 65 70 61 72 73 65 64 20  # Use preparsed 
0770: 64 61 74 61 20 69 66 20 6e 6f 74 20 69 6e 76 61  data if not inva
0780: 6c 69 64 61 74 65 64 20 62 79 20 63 68 61 6e 67  lidated by chang
0790: 65 73 20 74 6f 20 74 68 65 0a 09 23 20 61 72 63  es to the..# arc
07a0: 68 69 76 65 20 74 68 65 79 20 61 72 65 20 64 65  hive they are de
07b0: 72 69 76 65 64 20 66 72 6f 6d 2e 0a 09 77 72 69  rived from...wri
07c0: 74 65 20 34 20 72 63 73 20 7b 4c 6f 61 64 20 70  te 4 rcs {Load p
07d0: 72 65 70 61 72 73 65 64 20 64 61 74 61 20 62 6c  reparsed data bl
07e0: 6f 63 6b 7d 0a 09 72 65 74 75 72 6e 20 5b 66 69  ock}..return [fi
07f0: 6c 65 75 74 69 6c 3a 3a 63 61 74 20 2d 65 6e 63  leutil::cat -enc
0800: 6f 64 69 6e 67 20 62 69 6e 61 72 79 20 24 63 61  oding binary $ca
0810: 63 68 65 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20  che].    }..    
0820: 73 65 74 20 72 65 73 20 5b 50 72 6f 63 65 73 73  set res [Process
0830: 20 24 70 61 74 68 5d 0a 0a 20 20 20 20 23 20 53   $path]..    # S
0840: 61 76 65 20 70 61 72 73 65 20 72 65 73 75 6c 74  ave parse result
0850: 20 66 6f 72 20 71 75 69 63 6b 20 70 69 63 6b 75   for quick picku
0860: 70 20 62 79 20 66 75 74 75 72 65 20 72 75 6e 73  p by future runs
0870: 2e 0a 20 20 20 20 66 69 6c 65 75 74 69 6c 3a 3a  ..    fileutil::
0880: 77 72 69 74 65 46 69 6c 65 20 24 63 61 63 68 65  writeFile $cache
0890: 20 24 72 65 73 0a 0a 20 20 20 20 72 65 74 75 72   $res..    retur
08a0: 6e 20 24 72 65 73 0a 7d 0a 0a 23 20 2d 2d 2d 2d  n $res.}..# ----
08b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
08c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
08d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
08e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
08f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63 20  ---------..proc 
0900: 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65  ::vc::rcs::parse
0910: 72 3a 3a 50 72 6f 63 65 73 73 20 7b 70 61 74 68  r::Process {path
0920: 7d 20 7b 0a 20 20 20 20 73 65 74 20 64 61 74 61  } {.    set data
0930: 20 5b 66 69 6c 65 75 74 69 6c 3a 3a 63 61 74 20   [fileutil::cat 
0940: 2d 65 6e 63 6f 64 69 6e 67 20 62 69 6e 61 72 79  -encoding binary
0950: 20 24 70 61 74 68 5d 0a 20 20 20 20 61 72 72 61   $path].    arra
0960: 79 20 73 65 74 20 72 65 73 20 7b 7d 0a 20 20 20  y set res {}.   
0970: 20 73 65 74 20 72 65 73 28 73 69 7a 65 29 20 5b   set res(size) [
0980: 66 69 6c 65 20 73 69 7a 65 20 24 70 61 74 68 5d  file size $path]
0990: 0a 20 20 20 20 73 65 74 20 72 65 73 28 64 6f 6e  .    set res(don
09a0: 65 29 20 30 0a 20 20 20 20 73 65 74 20 72 65 73  e) 0.    set res
09b0: 28 6e 73 69 7a 65 29 20 5b 73 74 72 69 6e 67 20  (nsize) [string 
09c0: 6c 65 6e 67 74 68 20 24 72 65 73 28 73 69 7a 65  length $res(size
09d0: 29 5d 0a 0a 20 20 20 20 41 64 6d 69 6e 0a 20 20  )]..    Admin.  
09e0: 20 20 44 65 6c 74 61 73 0a 20 20 20 20 44 65 73    Deltas.    Des
09f0: 63 72 69 70 74 69 6f 6e 0a 20 20 20 20 44 65 6c  cription.    Del
0a00: 74 61 54 65 78 74 73 0a 0a 20 20 20 20 23 20 52  taTexts..    # R
0a10: 65 6d 6f 76 65 20 70 61 72 73 65 72 20 73 74 61  emove parser sta
0a20: 74 65 0a 20 20 20 20 63 61 74 63 68 20 7b 75 6e  te.    catch {un
0a30: 73 65 74 20 72 65 73 28 69 64 29 7d 0a 20 20 20  set res(id)}.   
0a40: 20 63 61 74 63 68 20 7b 75 6e 73 65 74 20 72 65   catch {unset re
0a50: 73 28 6c 61 73 74 76 61 6c 29 7d 0a 20 20 20 20  s(lastval)}.    
0a60: 75 6e 73 65 74 20 72 65 73 28 73 69 7a 65 29 0a  unset res(size).
0a70: 20 20 20 20 75 6e 73 65 74 20 72 65 73 28 6e 73      unset res(ns
0a80: 69 7a 65 29 0a 20 20 20 20 75 6e 73 65 74 20 72  ize).    unset r
0a90: 65 73 28 64 6f 6e 65 29 0a 0a 20 20 20 20 72 65  es(done)..    re
0aa0: 74 75 72 6e 20 5b 61 72 72 61 79 20 67 65 74 20  turn [array get 
0ab0: 72 65 73 5d 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 76  res].}..proc ::v
0ac0: 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a 3a  c::rcs::parser::
0ad0: 43 61 63 68 65 20 7b 70 61 74 68 7d 20 7b 0a 20  Cache {path} {. 
0ae0: 20 20 20 72 65 74 75 72 6e 20 24 7b 70 61 74 68     return ${path
0af0: 7d 2c 2c 70 72 65 70 61 72 73 65 64 0a 7d 0a 0a  },,preparsed.}..
0b00: 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  # --------------
0b10: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0b20: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0b30: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0b40: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
0b50: 23 20 49 6e 74 65 72 6e 61 6c 20 2d 20 52 65 63  # Internal - Rec
0b60: 75 72 73 69 76 65 20 44 65 73 63 65 6e 74 20 66  ursive Descent f
0b70: 75 6e 63 74 69 6f 6e 73 20 69 6d 70 6c 65 6d 65  unctions impleme
0b80: 6e 74 69 6e 67 20 74 68 65 20 73 79 6e 74 61 78  nting the syntax
0b90: 2e 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63  ...proc ::vc::rc
0ba0: 73 3a 3a 70 61 72 73 65 72 3a 3a 41 64 6d 69 6e  s::parser::Admin
0bb0: 20 7b 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20   {} {.    upvar 
0bc0: 31 20 64 61 74 61 20 64 61 74 61 20 72 65 73 20  1 data data res 
0bd0: 72 65 73 0a 20 20 20 20 48 65 61 64 20 3b 20 42  res.    Head ; B
0be0: 72 61 6e 63 68 20 3b 20 41 63 63 65 73 73 20 3b  ranch ; Access ;
0bf0: 20 53 79 6d 62 6f 6c 73 20 3b 20 4c 6f 63 6b 73   Symbols ; Locks
0c00: 20 3b 20 53 74 72 69 63 74 20 3b 20 43 6f 6d 6d   ; Strict ; Comm
0c10: 65 6e 74 20 3b 20 45 78 70 61 6e 64 0a 20 20 20  ent ; Expand.   
0c20: 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20   return.}..proc 
0c30: 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65  ::vc::rcs::parse
0c40: 72 3a 3a 44 65 6c 74 61 73 20 7b 7d 20 7b 0a 20  r::Deltas {} {. 
0c50: 20 20 20 75 70 76 61 72 20 31 20 64 61 74 61 20     upvar 1 data 
0c60: 64 61 74 61 20 72 65 73 20 72 65 73 0a 20 20 20  data res res.   
0c70: 20 77 68 69 6c 65 20 7b 5b 4e 75 6d 20 30 5d 7d   while {[Num 0]}
0c80: 20 7b 20 49 73 49 64 65 6e 74 20 3b 20 44 61 74   { IsIdent ; Dat
0c90: 65 20 3b 20 41 75 74 68 6f 72 20 3b 20 53 74 61  e ; Author ; Sta
0ca0: 74 65 20 3b 20 42 72 61 6e 63 68 65 73 20 3b 20  te ; Branches ; 
0cb0: 4e 65 78 74 52 65 76 20 7d 0a 20 20 20 20 72 65  NextRev }.    re
0cc0: 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 76  turn.}..proc ::v
0cd0: 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a 3a  c::rcs::parser::
0ce0: 44 65 73 63 72 69 70 74 69 6f 6e 20 7b 7d 20 7b  Description {} {
0cf0: 0a 20 20 20 20 75 70 76 61 72 20 31 20 64 61 74  .    upvar 1 dat
0d00: 61 20 64 61 74 61 20 72 65 73 20 72 65 73 0a 20  a data res res. 
0d10: 20 20 20 4c 69 74 65 72 61 6c 20 64 65 73 63 0a     Literal desc.
0d20: 20 20 20 20 53 74 72 69 6e 67 20 31 0a 20 20 20      String 1.   
0d30: 20 44 65 66 20 64 65 73 63 0a 20 20 20 20 72 65   Def desc.    re
0d40: 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 76  turn.}..proc ::v
0d50: 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a 3a  c::rcs::parser::
0d60: 44 65 6c 74 61 54 65 78 74 73 20 7b 7d 20 7b 0a  DeltaTexts {} {.
0d70: 20 20 20 20 75 70 76 61 72 20 31 20 64 61 74 61      upvar 1 data
0d80: 20 64 61 74 61 20 72 65 73 20 72 65 73 0a 20 20   data res res.  
0d90: 20 20 77 68 69 6c 65 20 7b 5b 4e 75 6d 20 30 5d    while {[Num 0]
0da0: 7d 20 7b 20 49 73 49 64 65 6e 74 20 3b 20 4c 6f  } { IsIdent ; Lo
0db0: 67 20 3b 20 54 65 78 74 20 7d 0a 20 20 20 20 72  g ; Text }.    r
0dc0: 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a 3a  eturn.}..proc ::
0dd0: 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a  vc::rcs::parser:
0de0: 3a 48 65 61 64 20 7b 7d 20 7b 0a 20 20 20 20 75  :Head {} {.    u
0df0: 70 76 61 72 20 31 20 64 61 74 61 20 64 61 74 61  pvar 1 data data
0e00: 20 72 65 73 20 72 65 73 0a 20 20 20 20 4c 69 74   res res.    Lit
0e10: 65 72 61 6c 20 68 65 61 64 20 3b 20 4e 75 6d 20  eral head ; Num 
0e20: 31 20 3b 20 4c 69 74 65 72 61 6c 20 5c 3b 0a 20  1 ; Literal \;. 
0e30: 20 20 20 44 65 66 20 68 65 61 64 0a 20 20 20 20     Def head.    
0e40: 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a  return.}..proc :
0e50: 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72  :vc::rcs::parser
0e60: 3a 3a 42 72 61 6e 63 68 20 7b 7d 20 7b 0a 20 20  ::Branch {} {.  
0e70: 20 20 75 70 76 61 72 20 31 20 64 61 74 61 20 64    upvar 1 data d
0e80: 61 74 61 20 72 65 73 20 72 65 73 0a 20 20 20 20  ata res res.    
0e90: 69 66 20 7b 21 5b 4c 69 74 65 72 61 6c 20 62 72  if {![Literal br
0ea0: 61 6e 63 68 20 30 5d 7d 20 72 65 74 75 72 6e 20  anch 0]} return 
0eb0: 3b 20 4e 75 6d 20 31 20 3b 20 4c 69 74 65 72 61  ; Num 1 ; Litera
0ec0: 6c 20 5c 3b 0a 20 20 20 20 44 65 66 20 62 72 61  l \;.    Def bra
0ed0: 6e 63 68 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d  nch.    return.}
0ee0: 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73  ..proc ::vc::rcs
0ef0: 3a 3a 70 61 72 73 65 72 3a 3a 41 63 63 65 73 73  ::parser::Access
0f00: 20 7b 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20   {} {.    upvar 
0f10: 31 20 64 61 74 61 20 64 61 74 61 20 72 65 73 20  1 data data res 
0f20: 72 65 73 0a 20 20 20 20 4c 69 74 65 72 61 6c 20  res.    Literal 
0f30: 61 63 63 65 73 73 20 3b 20 4c 69 74 65 72 61 6c  access ; Literal
0f40: 20 5c 3b 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d   \;.    return.}
0f50: 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73  ..proc ::vc::rcs
0f60: 3a 3a 70 61 72 73 65 72 3a 3a 53 79 6d 62 6f 6c  ::parser::Symbol
0f70: 73 20 7b 7d 20 7b 0a 20 20 20 20 75 70 76 61 72  s {} {.    upvar
0f80: 20 31 20 64 61 74 61 20 64 61 74 61 20 72 65 73   1 data data res
0f90: 20 72 65 73 0a 20 20 20 20 4c 69 74 65 72 61 6c   res.    Literal
0fa0: 20 73 79 6d 62 6f 6c 73 0a 20 20 20 20 77 68 69   symbols.    whi
0fb0: 6c 65 20 7b 5b 49 64 65 6e 74 5d 7d 20 7b 20 4e  le {[Ident]} { N
0fc0: 75 6d 20 31 20 3b 20 4d 61 70 20 73 79 6d 62 6f  um 1 ; Map symbo
0fd0: 6c 20 7d 0a 20 20 20 20 4c 69 74 65 72 61 6c 20  l }.    Literal 
0fe0: 5c 3b 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a  \;.    return.}.
0ff0: 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73 3a  .proc ::vc::rcs:
1000: 3a 70 61 72 73 65 72 3a 3a 4c 6f 63 6b 73 20 7b  :parser::Locks {
1010: 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20 31 20  } {.    upvar 1 
1020: 64 61 74 61 20 64 61 74 61 20 72 65 73 20 72 65  data data res re
1030: 73 0a 20 20 20 20 4c 69 74 65 72 61 6c 20 6c 6f  s.    Literal lo
1040: 63 6b 73 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b  cks.    while {[
1050: 49 64 65 6e 74 5d 7d 20 7b 20 4e 75 6d 20 31 20  Ident]} { Num 1 
1060: 3b 20 4d 61 70 20 6c 6f 63 6b 20 7d 0a 20 20 20  ; Map lock }.   
1070: 20 4c 69 74 65 72 61 6c 20 5c 3b 0a 20 20 20 20   Literal \;.    
1080: 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a  return.}..proc :
1090: 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72  :vc::rcs::parser
10a0: 3a 3a 53 74 72 69 63 74 20 7b 7d 20 7b 0a 20 20  ::Strict {} {.  
10b0: 20 20 75 70 76 61 72 20 31 20 64 61 74 61 20 64    upvar 1 data d
10c0: 61 74 61 20 72 65 73 20 72 65 73 0a 20 20 20 20  ata res res.    
10d0: 69 66 20 7b 21 5b 4c 69 74 65 72 61 6c 20 73 74  if {![Literal st
10e0: 72 69 63 74 20 30 5d 7d 20 72 65 74 75 72 6e 20  rict 0]} return 
10f0: 3b 20 4c 69 74 65 72 61 6c 20 5c 3b 0a 20 20 20  ; Literal \;.   
1100: 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20   return.}..proc 
1110: 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65  ::vc::rcs::parse
1120: 72 3a 3a 43 6f 6d 6d 65 6e 74 20 7b 7d 20 7b 0a  r::Comment {} {.
1130: 20 20 20 20 75 70 76 61 72 20 31 20 64 61 74 61      upvar 1 data
1140: 20 64 61 74 61 20 72 65 73 20 72 65 73 0a 20 20   data res res.  
1150: 20 20 69 66 20 7b 21 5b 4c 69 74 65 72 61 6c 20    if {![Literal 
1160: 63 6f 6d 6d 65 6e 74 20 30 5d 7d 20 72 65 74 75  comment 0]} retu
1170: 72 6e 20 3b 0a 20 20 20 20 69 66 20 7b 21 5b 53  rn ;.    if {![S
1180: 74 72 69 6e 67 20 30 5d 7d 20 72 65 74 75 72 6e  tring 0]} return
1190: 20 3b 0a 20 20 20 20 4c 69 74 65 72 61 6c 20 5c   ;.    Literal \
11a0: 3b 0a 20 20 20 20 44 65 66 20 63 6f 6d 6d 65 6e  ;.    Def commen
11b0: 74 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a  t.    return.}..
11c0: 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73 3a 3a  proc ::vc::rcs::
11d0: 70 61 72 73 65 72 3a 3a 45 78 70 61 6e 64 20 7b  parser::Expand {
11e0: 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20 31 20  } {.    upvar 1 
11f0: 64 61 74 61 20 64 61 74 61 20 72 65 73 20 72 65  data data res re
1200: 73 0a 20 20 20 20 69 66 20 7b 21 5b 4c 69 74 65  s.    if {![Lite
1210: 72 61 6c 20 65 78 70 61 6e 64 20 30 5d 7d 20 72  ral expand 0]} r
1220: 65 74 75 72 6e 20 3b 0a 20 20 20 20 69 66 20 7b  eturn ;.    if {
1230: 21 5b 53 74 72 69 6e 67 20 30 5d 7d 20 72 65 74  ![String 0]} ret
1240: 75 72 6e 20 3b 0a 20 20 20 20 4c 69 74 65 72 61  urn ;.    Litera
1250: 6c 20 5c 3b 0a 20 20 20 20 44 65 66 20 65 78 70  l \;.    Def exp
1260: 61 6e 64 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d  and.    return.}
1270: 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73  ..proc ::vc::rcs
1280: 3a 3a 70 61 72 73 65 72 3a 3a 44 61 74 65 20 7b  ::parser::Date {
1290: 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20 31 20  } {.    upvar 1 
12a0: 64 61 74 61 20 64 61 74 61 20 72 65 73 20 72 65  data data res re
12b0: 73 0a 20 20 20 20 4c 69 74 65 72 61 6c 20 64 61  s.    Literal da
12c0: 74 65 20 3b 20 4e 75 6d 20 31 20 3b 20 4c 69 74  te ; Num 1 ; Lit
12d0: 65 72 61 6c 20 5c 3b 0a 0a 20 20 20 20 66 6f 72  eral \;..    for
12e0: 65 61 63 68 20 7b 79 72 20 6d 6f 20 64 79 20 68  each {yr mo dy h
12f0: 20 6d 20 73 7d 20 5b 73 70 6c 69 74 20 24 72 65   m s} [split $re
1300: 73 28 6c 61 73 74 76 61 6c 29 20 2e 5d 20 62 72  s(lastval) .] br
1310: 65 61 6b 0a 20 20 20 20 69 66 20 7b 24 79 72 20  eak.    if {$yr 
1320: 3c 20 31 30 30 7d 20 7b 69 6e 63 72 20 79 72 20  < 100} {incr yr 
1330: 31 39 30 30 7d 0a 20 20 20 20 73 65 74 20 72 65  1900}.    set re
1340: 73 28 6c 61 73 74 76 61 6c 29 20 5b 6a 6f 69 6e  s(lastval) [join
1350: 20 5b 6c 69 73 74 20 24 79 72 20 24 6d 6f 20 24   [list $yr $mo $
1360: 64 79 20 24 68 20 24 6d 20 24 73 5d 20 2e 5d 0a  dy $h $m $s] .].
1370: 20 20 20 20 4d 61 70 20 64 61 74 65 0a 20 20 20      Map date.   
1380: 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20   return.}..proc 
1390: 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65  ::vc::rcs::parse
13a0: 72 3a 3a 41 75 74 68 6f 72 20 7b 7d 20 7b 0a 20  r::Author {} {. 
13b0: 20 20 20 75 70 76 61 72 20 31 20 64 61 74 61 20     upvar 1 data 
13c0: 64 61 74 61 20 72 65 73 20 72 65 73 0a 20 20 20  data res res.   
13d0: 20 4c 69 74 65 72 61 6c 20 61 75 74 68 6f 72 20   Literal author 
13e0: 3b 20 53 6b 69 70 20 3b 20 4c 69 74 65 72 61 6c  ; Skip ; Literal
13f0: 20 5c 3b 20 3b 20 4d 61 70 20 61 75 74 68 6f 72   \; ; Map author
1400: 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 70  .    return.}..p
1410: 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70  roc ::vc::rcs::p
1420: 61 72 73 65 72 3a 3a 53 74 61 74 65 20 7b 7d 20  arser::State {} 
1430: 7b 0a 20 20 20 20 75 70 76 61 72 20 31 20 64 61  {.    upvar 1 da
1440: 74 61 20 64 61 74 61 20 72 65 73 20 72 65 73 0a  ta data res res.
1450: 20 20 20 20 4c 69 74 65 72 61 6c 20 73 74 61 74      Literal stat
1460: 65 20 3b 20 53 6b 69 70 20 3b 20 4c 69 74 65 72  e ; Skip ; Liter
1470: 61 6c 20 5c 3b 20 3b 20 4d 61 70 20 73 74 61 74  al \; ; Map stat
1480: 65 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a  e.    return.}..
1490: 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73 3a 3a  proc ::vc::rcs::
14a0: 70 61 72 73 65 72 3a 3a 42 72 61 6e 63 68 65 73  parser::Branches
14b0: 20 7b 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20   {} {.    upvar 
14c0: 31 20 64 61 74 61 20 64 61 74 61 20 72 65 73 20  1 data data res 
14d0: 72 65 73 0a 20 20 20 20 4c 69 74 65 72 61 6c 20  res.    Literal 
14e0: 62 72 61 6e 63 68 65 73 20 3b 20 53 6b 69 70 20  branches ; Skip 
14f0: 3b 20 4c 69 74 65 72 61 6c 20 5c 3b 0a 20 20 20  ; Literal \;.   
1500: 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20   return.}..proc 
1510: 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65  ::vc::rcs::parse
1520: 72 3a 3a 4e 65 78 74 52 65 76 20 7b 7d 20 7b 0a  r::NextRev {} {.
1530: 20 20 20 20 75 70 76 61 72 20 31 20 64 61 74 61      upvar 1 data
1540: 20 64 61 74 61 20 72 65 73 20 72 65 73 0a 20 20   data res res.  
1550: 20 20 4c 69 74 65 72 61 6c 20 6e 65 78 74 20 3b    Literal next ;
1560: 20 53 6b 69 70 20 3b 20 4c 69 74 65 72 61 6c 20   Skip ; Literal 
1570: 5c 3b 20 3b 20 4d 61 70 20 70 61 72 65 6e 74 0a  \; ; Map parent.
1580: 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72      return.}..pr
1590: 6f 63 20 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61  oc ::vc::rcs::pa
15a0: 72 73 65 72 3a 3a 4c 6f 67 20 7b 7d 20 7b 0a 20  rser::Log {} {. 
15b0: 20 20 20 75 70 76 61 72 20 31 20 64 61 74 61 20     upvar 1 data 
15c0: 64 61 74 61 20 72 65 73 20 72 65 73 0a 20 20 20  data res res.   
15d0: 20 4c 69 74 65 72 61 6c 20 6c 6f 67 20 3b 20 53   Literal log ; S
15e0: 74 72 69 6e 67 20 31 20 3b 20 4d 61 70 20 63 6f  tring 1 ; Map co
15f0: 6d 6d 69 74 0a 20 20 20 20 72 65 74 75 72 6e 0a  mmit.    return.
1600: 7d 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63  }..proc ::vc::rc
1610: 73 3a 3a 70 61 72 73 65 72 3a 3a 54 65 78 74 20  s::parser::Text 
1620: 7b 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20 31  {} {.    upvar 1
1630: 20 64 61 74 61 20 64 61 74 61 20 72 65 73 20 72   data data res r
1640: 65 73 0a 20 20 20 20 4c 69 74 65 72 61 6c 20 74  es.    Literal t
1650: 65 78 74 20 3b 20 53 74 72 69 6e 67 20 31 0a 20  ext ; String 1. 
1660: 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 23 20 2d     return.}..# -
1670: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1680: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1690: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
16a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
16b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 49  ------------.# I
16c0: 6e 74 65 72 6e 61 6c 20 2d 20 4c 65 78 69 63 6f  nternal - Lexico
16d0: 67 72 61 70 68 69 63 61 6c 20 63 6f 6d 6d 61 6e  graphical comman
16e0: 64 73 20 61 6e 64 20 64 61 74 61 20 61 71 75 69  ds and data aqui
16f0: 73 69 74 69 6f 6e 20 70 72 65 70 61 72 61 74 69  sition preparati
1700: 6f 6e 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72  on..proc ::vc::r
1710: 63 73 3a 3a 70 61 72 73 65 72 3a 3a 49 64 65 6e  cs::parser::Iden
1720: 74 20 7b 7d 20 7b 0a 20 20 20 20 75 70 76 61 72  t {} {.    upvar
1730: 20 31 20 64 61 74 61 20 64 61 74 61 20 72 65 73   1 data data res
1740: 20 72 65 73 0a 0a 20 20 20 20 23 70 75 74 73 20   res..    #puts 
1750: 49 40 3f 3c 5b 73 74 72 69 6e 67 20 72 61 6e 67  I@?<[string rang
1760: 65 20 24 64 61 74 61 20 30 20 31 30 5d 2e 2e 2e  e $data 0 10]...
1770: 3e 0a 0a 20 20 20 20 69 66 20 7b 5b 72 65 67 65  >..    if {[rege
1780: 78 70 20 2d 69 6e 64 69 63 65 73 20 2d 2d 20 7b  xp -indices -- {
1790: 5e 5c 73 2a 3b 5c 73 2a 7d 20 24 64 61 74 61 5d  ^\s*;\s*} $data]
17a0: 7d 20 7b 0a 09 72 65 74 75 72 6e 20 30 0a 20 20  } {..return 0.  
17b0: 20 20 7d 20 65 6c 73 65 69 66 20 7b 21 5b 72 65    } elseif {![re
17c0: 67 65 78 70 20 2d 69 6e 64 69 63 65 73 20 2d 2d  gexp -indices --
17d0: 20 7b 5e 5c 73 2a 28 5b 5e 3a 5d 2a 29 5c 73 2a   {^\s*([^:]*)\s*
17e0: 3a 5c 73 2a 7d 20 24 64 61 74 61 20 6d 61 74 63  :\s*} $data matc
17f0: 68 20 76 61 6c 5d 7d 20 7b 0a 09 72 65 74 75 72  h val]} {..retur
1800: 6e 20 30 0a 20 20 20 20 7d 0a 0a 20 20 20 20 47  n 0.    }..    G
1810: 65 74 20 24 76 61 6c 20 3b 20 49 73 49 64 65 6e  et $val ; IsIden
1820: 74 0a 20 20 20 20 4e 65 78 74 0a 20 20 20 20 72  t.    Next.    r
1830: 65 74 75 72 6e 20 31 0a 7d 0a 0a 70 72 6f 63 20  eturn 1.}..proc 
1840: 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65  ::vc::rcs::parse
1850: 72 3a 3a 4c 69 74 65 72 61 6c 20 7b 6e 61 6d 65  r::Literal {name
1860: 20 7b 72 65 71 75 69 72 65 64 20 31 7d 7d 20 7b   {required 1}} {
1870: 0a 20 20 20 20 75 70 76 61 72 20 31 20 64 61 74  .    upvar 1 dat
1880: 61 20 64 61 74 61 20 72 65 73 20 72 65 73 0a 20  a data res res. 
1890: 20 20 20 69 66 20 7b 21 5b 72 65 67 65 78 70 20     if {![regexp 
18a0: 2d 69 6e 64 69 63 65 73 20 2d 2d 20 22 5e 5c 5c  -indices -- "^\\
18b0: 73 2a 24 6e 61 6d 65 5c 5c 73 2a 22 20 24 64 61  s*$name\\s*" $da
18c0: 74 61 20 6d 61 74 63 68 5d 7d 20 7b 0a 09 69 66  ta match]} {..if
18d0: 20 7b 24 72 65 71 75 69 72 65 64 7d 20 7b 0a 09   {$required} {..
18e0: 20 20 20 20 72 65 74 75 72 6e 20 2d 63 6f 64 65      return -code
18f0: 20 65 72 72 6f 72 20 22 45 78 70 65 63 74 65 64   error "Expected
1900: 20 27 24 6e 61 6d 65 27 20 40 20 27 5b 73 74 72   '$name' @ '[str
1910: 69 6e 67 20 72 61 6e 67 65 20 24 64 61 74 61 20  ing range $data 
1920: 30 20 33 30 5d 2e 2e 2e 27 22 0a 09 7d 0a 09 72  0 30]...'"..}..r
1930: 65 74 75 72 6e 20 30 0a 20 20 20 20 7d 0a 0a 20  eturn 0.    }.. 
1940: 20 20 20 4e 65 78 74 0a 20 20 20 20 72 65 74 75     Next.    retu
1950: 72 6e 20 31 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 76  rn 1.}..proc ::v
1960: 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a 3a  c::rcs::parser::
1970: 53 74 72 69 6e 67 20 7b 7b 72 65 71 75 69 72 65  String {{require
1980: 64 20 31 7d 7d 20 7b 0a 20 20 20 20 75 70 76 61  d 1}} {.    upva
1990: 72 20 31 20 64 61 74 61 20 64 61 74 61 20 72 65  r 1 data data re
19a0: 73 20 72 65 73 0a 0a 20 20 20 20 69 66 20 7b 21  s res..    if {!
19b0: 5b 72 65 67 65 78 70 20 2d 69 6e 64 69 63 65 73  [regexp -indices
19c0: 20 2d 2d 20 7b 5e 5c 73 2a 40 28 28 5b 5e 40 5d   -- {^\s*@(([^@]
19d0: 2a 28 40 40 29 2a 29 2a 29 40 5c 73 2a 7d 20 24  *(@@)*)*)@\s*} $
19e0: 64 61 74 61 20 6d 61 74 63 68 20 76 61 6c 5d 7d  data match val]}
19f0: 20 7b 0a 09 69 66 20 7b 24 72 65 71 75 69 72 65   {..if {$require
1a00: 64 7d 20 7b 0a 09 20 20 20 20 72 65 74 75 72 6e  d} {..    return
1a10: 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 45 78   -code error "Ex
1a20: 70 65 63 74 65 64 20 73 74 72 69 6e 67 20 40 20  pected string @ 
1a30: 27 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24  '[string range $
1a40: 64 61 74 61 20 30 20 33 30 5d 2e 2e 2e 27 22 0a  data 0 30]...'".
1a50: 09 7d 0a 09 72 65 74 75 72 6e 20 30 0a 20 20 20  .}..return 0.   
1a60: 20 7d 0a 0a 20 20 20 20 47 65 74 20 24 76 61 6c   }..    Get $val
1a70: 0a 20 20 20 20 4e 65 78 74 0a 20 20 20 20 72 65  .    Next.    re
1a80: 74 75 72 6e 20 31 0a 7d 0a 0a 70 72 6f 63 20 3a  turn 1.}..proc :
1a90: 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72  :vc::rcs::parser
1aa0: 3a 3a 4e 75 6d 20 7b 72 65 71 75 69 72 65 64 7d  ::Num {required}
1ab0: 20 7b 0a 20 20 20 20 75 70 76 61 72 20 31 20 64   {.    upvar 1 d
1ac0: 61 74 61 20 64 61 74 61 20 72 65 73 20 72 65 73  ata data res res
1ad0: 0a 20 20 20 20 69 66 20 7b 21 5b 72 65 67 65 78  .    if {![regex
1ae0: 70 20 2d 69 6e 64 69 63 65 73 20 2d 2d 20 7b 5e  p -indices -- {^
1af0: 5c 73 2a 28 28 5c 64 7c 5c 2e 29 2b 29 5c 73 2a  \s*((\d|\.)+)\s*
1b00: 7d 20 24 64 61 74 61 20 6d 61 74 63 68 20 76 61  } $data match va
1b10: 6c 5d 7d 20 7b 0a 09 69 66 20 7b 24 72 65 71 75  l]} {..if {$requ
1b20: 69 72 65 64 7d 20 7b 0a 09 20 20 20 20 72 65 74  ired} {..    ret
1b30: 75 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20  urn -code error 
1b40: 22 45 78 70 65 63 74 65 64 20 69 64 20 40 20 27  "Expected id @ '
1b50: 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 64  [string range $d
1b60: 61 74 61 20 30 20 33 30 5d 2e 2e 2e 27 22 0a 09  ata 0 30]...'"..
1b70: 7d 0a 09 72 65 74 75 72 6e 20 30 0a 20 20 20 20  }..return 0.    
1b80: 7d 0a 0a 20 20 20 20 47 65 74 20 24 76 61 6c 0a  }..    Get $val.
1b90: 20 20 20 20 4e 65 78 74 0a 20 20 20 20 72 65 74      Next.    ret
1ba0: 75 72 6e 20 31 0a 7d 0a 0a 70 72 6f 63 20 3a 3a  urn 1.}..proc ::
1bb0: 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a  vc::rcs::parser:
1bc0: 3a 53 6b 69 70 20 7b 7d 20 7b 0a 20 20 20 20 75  :Skip {} {.    u
1bd0: 70 76 61 72 20 31 20 64 61 74 61 20 64 61 74 61  pvar 1 data data
1be0: 20 72 65 73 20 72 65 73 0a 20 20 20 20 72 65 67   res res.    reg
1bf0: 65 78 70 20 2d 69 6e 64 69 63 65 73 20 2d 2d 20  exp -indices -- 
1c00: 7b 5e 5c 73 2a 28 5b 5e 3b 5d 2a 29 5c 73 2a 7d  {^\s*([^;]*)\s*}
1c10: 20 24 64 61 74 61 20 6d 61 74 63 68 20 76 61 6c   $data match val
1c20: 0a 20 20 20 20 47 65 74 20 24 76 61 6c 0a 20 20  .    Get $val.  
1c30: 20 20 4e 65 78 74 0a 20 20 20 20 72 65 74 75 72    Next.    retur
1c40: 6e 0a 7d 0a 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d  n.}..# ---------
1c50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1c60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1c70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1c80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1c90: 2d 2d 2d 2d 0a 23 20 49 6e 74 65 72 6e 61 6c 20  ----.# Internal 
1ca0: 2d 20 44 61 74 61 20 61 71 75 69 73 69 74 69 6f  - Data aquisitio
1cb0: 6e 0a 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63  n..proc ::vc::rc
1cc0: 73 3a 3a 70 61 72 73 65 72 3a 3a 44 65 66 20 7b  s::parser::Def {
1cd0: 6b 65 79 7d 20 7b 0a 20 20 20 20 75 70 76 61 72  key} {.    upvar
1ce0: 20 31 20 64 61 74 61 20 64 61 74 61 20 72 65 73   1 data data res
1cf0: 20 72 65 73 0a 20 20 20 20 73 65 74 20 72 65 73   res.    set res
1d00: 28 24 6b 65 79 29 20 24 72 65 73 28 6c 61 73 74  ($key) $res(last
1d10: 76 61 6c 29 0a 20 20 20 20 75 6e 73 65 74 20 72  val).    unset r
1d20: 65 73 28 6c 61 73 74 76 61 6c 29 0a 20 20 20 20  es(lastval).    
1d30: 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a  return.}..proc :
1d40: 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72  :vc::rcs::parser
1d50: 3a 3a 4d 61 70 20 7b 6b 65 79 7d 20 7b 0a 20 20  ::Map {key} {.  
1d60: 20 20 75 70 76 61 72 20 31 20 64 61 74 61 20 64    upvar 1 data d
1d70: 61 74 61 20 72 65 73 20 72 65 73 0a 20 20 20 20  ata res res.    
1d80: 6c 61 70 70 65 6e 64 20 72 65 73 28 24 6b 65 79  lappend res($key
1d90: 29 20 24 72 65 73 28 69 64 29 20 24 72 65 73 28  ) $res(id) $res(
1da0: 6c 61 73 74 76 61 6c 29 0a 20 20 20 20 23 70 75  lastval).    #pu
1db0: 74 73 20 4d 61 70 28 24 72 65 73 28 69 64 29 29  ts Map($res(id))
1dc0: 3d 28 24 72 65 73 28 6c 61 73 74 76 61 6c 29 29  =($res(lastval))
1dd0: 0a 20 20 20 20 75 6e 73 65 74 20 72 65 73 28 6c  .    unset res(l
1de0: 61 73 74 76 61 6c 29 0a 20 20 20 20 23 75 6e 73  astval).    #uns
1df0: 65 74 20 72 65 73 28 69 64 29 3b 23 4b 65 65 70  et res(id);#Keep
1e00: 20 69 64 20 66 6f 72 20 61 64 64 69 74 69 6f 6e   id for addition
1e10: 61 6c 20 6d 61 70 70 69 6e 67 73 2e 0a 20 20 20  al mappings..   
1e20: 20 72 65 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20   return.}..proc 
1e30: 3a 3a 76 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65  ::vc::rcs::parse
1e40: 72 3a 3a 49 73 49 64 65 6e 74 20 7b 7d 20 7b 0a  r::IsIdent {} {.
1e50: 20 20 20 20 75 70 76 61 72 20 31 20 64 61 74 61      upvar 1 data
1e60: 20 64 61 74 61 20 72 65 73 20 72 65 73 0a 20 20   data res res.  
1e70: 20 20 73 65 74 20 72 65 73 28 69 64 29 20 24 72    set res(id) $r
1e80: 65 73 28 6c 61 73 74 76 61 6c 29 0a 20 20 20 20  es(lastval).    
1e90: 75 6e 73 65 74 20 72 65 73 28 6c 61 73 74 76 61  unset res(lastva
1ea0: 6c 29 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a  l).    return.}.
1eb0: 0a 70 72 6f 63 20 3a 3a 76 63 3a 3a 72 63 73 3a  .proc ::vc::rcs:
1ec0: 3a 70 61 72 73 65 72 3a 3a 47 65 74 20 7b 76 61  :parser::Get {va
1ed0: 6c 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20 31  l} {.    upvar 1
1ee0: 20 64 61 74 61 20 64 61 74 61 20 72 65 73 20 72   data data res r
1ef0: 65 73 0a 20 20 20 20 66 6f 72 65 61 63 68 20 7b  es.    foreach {
1f00: 73 20 65 7d 20 24 76 61 6c 20 62 72 65 61 6b 0a  s e} $val break.
1f10: 20 20 20 20 73 65 74 20 72 65 73 28 6c 61 73 74      set res(last
1f20: 76 61 6c 29 20 5b 73 74 72 69 6e 67 20 72 61 6e  val) [string ran
1f30: 67 65 20 24 64 61 74 61 20 24 73 20 24 65 5d 0a  ge $data $s $e].
1f40: 20 20 20 20 23 70 75 74 73 20 47 7c 24 72 65 73      #puts G|$res
1f50: 28 6c 61 73 74 76 61 6c 29 0a 20 20 20 20 72 65  (lastval).    re
1f60: 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 76  turn.}..proc ::v
1f70: 63 3a 3a 72 63 73 3a 3a 70 61 72 73 65 72 3a 3a  c::rcs::parser::
1f80: 4e 65 78 74 20 7b 7d 20 7b 0a 20 20 20 20 75 70  Next {} {.    up
1f90: 76 61 72 20 31 20 6d 61 74 63 68 20 6d 61 74 63  var 1 match matc
1fa0: 68 20 64 61 74 61 20 64 61 74 61 20 72 65 73 20  h data data res 
1fb0: 72 65 73 0a 20 20 20 20 66 6f 72 65 61 63 68 20  res.    foreach 
1fc0: 7b 73 20 65 7d 20 24 6d 61 74 63 68 20 62 72 65  {s e} $match bre
1fd0: 61 6b 20 3b 20 69 6e 63 72 20 65 0a 20 20 20 20  ak ; incr e.    
1fe0: 73 65 74 20 64 61 74 61 20 5b 73 74 72 69 6e 67  set data [string
1ff0: 20 72 61 6e 67 65 20 24 64 61 74 61 20 24 65 20   range $data $e 
2000: 65 6e 64 5d 0a 20 20 20 20 73 65 74 20 72 65 73  end].    set res
2010: 28 64 6f 6e 65 29 20 5b 65 78 70 72 20 7b 24 72  (done) [expr {$r
2020: 65 73 28 73 69 7a 65 29 20 2d 20 5b 73 74 72 69  es(size) - [stri
2030: 6e 67 20 6c 65 6e 67 74 68 20 24 64 61 74 61 5d  ng length $data]
2040: 7d 5d 0a 0a 20 20 20 20 70 72 6f 67 72 65 73 73  }]..    progress
2050: 20 32 20 72 63 73 20 24 72 65 73 28 64 6f 6e 65   2 rcs $res(done
2060: 29 20 24 72 65 73 28 73 69 7a 65 29 0a 20 20 20  ) $res(size).   
2070: 20 72 65 74 75 72 6e 0a 7d 0a 0a 23 20 2d 2d 2d   return.}..# ---
2080: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2090: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
20a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
20b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
20c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 6e 61 6d 65  ----------..name
20d0: 73 70 61 63 65 20 65 76 61 6c 20 3a 3a 76 63 3a  space eval ::vc:
20e0: 3a 72 63 73 3a 3a 70 61 72 73 65 72 20 7b 0a 20  :rcs::parser {. 
20f0: 20 20 20 76 61 72 69 61 62 6c 65 20 63 61 63 68     variable cach
2100: 65 20 30 20 3b 20 23 20 4e 6f 20 72 65 73 75 6c  e 0 ; # No resul
2110: 74 20 63 61 63 68 69 6e 67 20 62 79 20 64 65 66  t caching by def
2120: 61 75 6c 74 2e 0a 0a 20 20 20 20 6e 61 6d 65 73  ault...    names
2130: 70 61 63 65 20 65 78 70 6f 72 74 20 70 72 6f 63  pace export proc
2140: 65 73 73 20 63 6f 6e 66 69 67 75 72 65 0a 7d 0a  ess configure.}.
2150: 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .# -------------
2160: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2170: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2180: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2190: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
21a0: 0a 23 20 52 65 61 64 79 0a 0a 70 61 63 6b 61 67  .# Ready..packag
21b0: 65 20 70 72 6f 76 69 64 65 20 76 63 3a 3a 72 63  e provide vc::rc
21c0: 73 3a 3a 70 61 72 73 65 72 20 31 2e 30 0a 72 65  s::parser 1.0.re
21d0: 74 75 72 6e 0a                                   turn.