Hex Artifact Content

Artifact 363d0862484a9bd5c4aa55d58d62876c51638bb7:


0000: 23 20 6a 73 6f 6e 2e 74 63 6c 20 2d 2d 0a 23 0a  # json.tcl --.#.
0010: 23 09 4a 53 4f 4e 20 70 61 72 73 65 72 20 66 6f  #.JSON parser fo
0020: 72 20 54 63 6c 2e 20 4d 61 6e 61 67 65 6d 65 6e  r Tcl. Managemen
0030: 74 20 63 6f 64 65 2c 20 54 63 6c 2f 43 20 64 65  t code, Tcl/C de
0040: 74 65 63 74 69 6f 6e 20 61 6e 64 20 73 65 6c 65  tection and sele
0050: 63 74 69 6f 6e 2e 0a 23 0a 23 20 43 6f 70 79 72  ction..#.# Copyr
0060: 69 67 68 74 20 28 63 29 20 32 30 31 33 20 62 79  ight (c) 2013 by
0070: 20 41 6e 64 72 65 61 73 20 4b 75 70 72 69 65 73   Andreas Kupries
0080: 0a 0a 23 20 40 6d 64 67 65 6e 20 45 58 43 4c 55  ..# @mdgen EXCLU
0090: 44 45 3a 20 6a 73 6f 6e 63 2e 74 63 6c 0a 0a 70  DE: jsonc.tcl..p
00a0: 61 63 6b 61 67 65 20 72 65 71 75 69 72 65 20 54  ackage require T
00b0: 63 6c 20 38 2e 34 0a 6e 61 6d 65 73 70 61 63 65  cl 8.4.namespace
00c0: 20 65 76 61 6c 20 3a 3a 6a 73 6f 6e 20 7b 7d 0a   eval ::json {}.
00d0: 0a 23 20 23 23 23 20 23 23 23 20 23 23 23 20 23  .# ### ### ### #
00e0: 23 23 23 23 23 23 23 23 20 23 23 23 23 23 23 23  ######## #######
00f0: 23 23 20 23 23 23 23 23 23 23 23 23 0a 23 23 20  ## #########.## 
0100: 4d 61 6e 61 67 65 6d 65 6e 74 20 6f 66 20 6a 73  Management of js
0110: 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  on implementatio
0120: 6e 73 2e 0a 0a 23 20 3a 3a 6a 73 6f 6e 3a 3a 4c  ns...# ::json::L
0130: 6f 61 64 41 63 63 65 6c 65 72 61 74 6f 72 20 2d  oadAccelerator -
0140: 2d 0a 23 0a 23 09 4c 6f 61 64 73 20 61 20 6e 61  -.#.#.Loads a na
0150: 6d 65 64 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  med implementati
0160: 6f 6e 2c 20 69 66 20 70 6f 73 73 69 62 6c 65 2e  on, if possible.
0170: 0a 23 0a 23 20 41 72 67 75 6d 65 6e 74 73 3a 0a  .#.# Arguments:.
0180: 23 09 6b 65 79 09 4e 61 6d 65 20 6f 66 20 74 68  #.key.Name of th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 74 6f 20 6c 6f 61 64 2e 0a 23 0a 23 20 52 65   to load..#.# Re
01b0: 73 75 6c 74 73 3a 0a 23 09 41 20 62 6f 6f 6c 65  sults:.#.A boole
01c0: 61 6e 20 66 6c 61 67 2e 20 54 72 75 65 20 69 66  an flag. True if
01d0: 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74   the implementat
01e0: 69 6f 6e 0a 23 09 77 61 73 20 73 75 63 63 65 73  ion.#.was succes
01f0: 73 66 75 6c 6c 79 20 6c 6f 61 64 65 64 3b 20 61  sfully loaded; a
0200: 6e 64 20 46 61 6c 73 65 20 6f 74 68 65 72 77 69  nd False otherwi
0210: 73 65 2e 0a 0a 70 72 6f 63 20 3a 3a 6a 73 6f 6e  se...proc ::json
0220: 3a 3a 4c 6f 61 64 41 63 63 65 6c 65 72 61 74 6f  ::LoadAccelerato
0230: 72 20 7b 6b 65 79 7d 20 7b 0a 20 20 20 20 76 61  r {key} {.    va
0240: 72 69 61 62 6c 65 20 61 63 63 65 6c 0a 20 20 20  riable accel.   
0250: 20 73 65 74 20 72 20 30 0a 20 20 20 20 73 77 69   set r 0.    swi
0260: 74 63 68 20 2d 65 78 61 63 74 20 2d 2d 20 24 6b  tch -exact -- $k
0270: 65 79 20 7b 0a 09 63 72 69 74 63 6c 20 7b 0a 09  ey {..critcl {..
0280: 20 20 20 20 23 20 43 72 69 74 63 6c 20 69 6d 70      # Critcl imp
0290: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 6a  lementation of j
02a0: 73 6f 6e 20 72 65 71 75 69 72 65 73 20 54 63 6c  son requires Tcl
02b0: 20 38 2e 34 2e 0a 09 20 20 20 20 69 66 20 7b 21   8.4...    if {!
02c0: 5b 70 61 63 6b 61 67 65 20 76 73 61 74 69 73 66  [package vsatisf
02d0: 69 65 73 20 5b 70 61 63 6b 61 67 65 20 70 72 6f  ies [package pro
02e0: 76 69 64 65 20 54 63 6c 5d 20 38 2e 34 5d 7d 20  vide Tcl] 8.4]} 
02f0: 7b 72 65 74 75 72 6e 20 30 7d 0a 09 20 20 20 20  {return 0}..    
0300: 69 66 20 7b 5b 63 61 74 63 68 20 7b 70 61 63 6b  if {[catch {pack
0310: 61 67 65 20 72 65 71 75 69 72 65 20 74 63 6c 6c  age require tcll
0320: 69 62 63 7d 5d 7d 20 7b 72 65 74 75 72 6e 20 30  ibc}]} {return 0
0330: 7d 0a 09 20 20 20 20 23 20 43 68 65 63 6b 20 66  }..    # Check f
0340: 6f 72 20 74 68 65 20 6a 73 6f 6e 63 20 31 2e 31  or the jsonc 1.1
0350: 2e 31 20 41 50 49 20 77 65 20 61 72 65 20 66 69  .1 API we are fi
0360: 78 69 6e 67 20 6c 61 74 65 72 2e 0a 09 20 20 20  xing later...   
0370: 20 73 65 74 20 72 20 5b 6c 6c 65 6e 67 74 68 20   set r [llength 
0380: 5b 69 6e 66 6f 20 63 6f 6d 6d 61 6e 64 73 20 3a  [info commands :
0390: 3a 6a 73 6f 6e 3a 3a 6d 61 6e 79 5f 6a 73 6f 6e  :json::many_json
03a0: 32 64 69 63 74 5f 63 72 69 74 63 6c 5d 5d 0a 09  2dict_critcl]]..
03b0: 7d 0a 09 74 63 6c 20 7b 0a 09 20 20 20 20 76 61  }..tcl {..    va
03c0: 72 69 61 62 6c 65 20 73 65 6c 66 64 69 72 0a 09  riable selfdir..
03d0: 20 20 20 20 73 6f 75 72 63 65 20 5b 66 69 6c 65      source [file
03e0: 20 6a 6f 69 6e 20 24 73 65 6c 66 64 69 72 20 6a   join $selfdir j
03f0: 73 6f 6e 5f 74 63 6c 2e 74 63 6c 5d 0a 09 20 20  son_tcl.tcl]..  
0400: 20 20 73 65 74 20 72 20 31 0a 09 7d 0a 20 20 20    set r 1..}.   
0410: 20 20 20 20 20 64 65 66 61 75 6c 74 20 7b 0a 20       default {. 
0420: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
0430: 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 69  n -code error "i
0440: 6e 76 61 6c 69 64 20 61 63 63 65 6c 65 72 61 74  nvalid accelerat
0450: 6f 72 2f 69 6d 70 6c 2e 20 70 61 63 6b 61 67 65  or/impl. package
0460: 20 24 6b 65 79 3a 5c 0a 20 20 20 20 20 20 20 20   $key:\.        
0470: 20 20 20 20 20 20 20 20 6d 75 73 74 20 62 65 20          must be 
0480: 6f 6e 65 20 6f 66 20 5b 6a 6f 69 6e 20 5b 4b 6e  one of [join [Kn
0490: 6f 77 6e 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ownImplementatio
04a0: 6e 73 5d 20 7b 2c 20 7d 5d 22 0a 20 20 20 20 20  ns] {, }]".     
04b0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73     }.    }.    s
04c0: 65 74 20 61 63 63 65 6c 28 24 6b 65 79 29 20 24  et accel($key) $
04d0: 72 0a 20 20 20 20 72 65 74 75 72 6e 20 24 72 0a  r.    return $r.
04e0: 7d 0a 0a 23 20 3a 3a 6a 73 6f 6e 3a 3a 53 77 69  }..# ::json::Swi
04f0: 74 63 68 54 6f 20 2d 2d 0a 23 0a 23 09 41 63 74  tchTo --.#.#.Act
0500: 69 76 61 74 65 73 20 61 20 6c 6f 61 64 65 64 20  ivates a loaded 
0510: 6e 61 6d 65 64 20 69 6d 70 6c 65 6d 65 6e 74 61  named implementa
0520: 74 69 6f 6e 2e 0a 23 0a 23 20 41 72 67 75 6d 65  tion..#.# Argume
0530: 6e 74 73 3a 0a 23 09 6b 65 79 09 4e 61 6d 65 20  nts:.#.key.Name 
0540: 6f 66 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  of the implement
0550: 61 74 69 6f 6e 20 74 6f 20 61 63 74 69 76 61 74  ation to activat
0560: 65 2e 0a 23 0a 23 20 52 65 73 75 6c 74 73 3a 0a  e..#.# Results:.
0570: 23 09 4e 6f 6e 65 2e 0a 0a 70 72 6f 63 20 3a 3a  #.None...proc ::
0580: 6a 73 6f 6e 3a 3a 53 77 69 74 63 68 54 6f 20 7b  json::SwitchTo {
0590: 6b 65 79 7d 20 7b 0a 20 20 20 20 76 61 72 69 61  key} {.    varia
05a0: 62 6c 65 20 61 63 63 65 6c 0a 20 20 20 20 76 61  ble accel.    va
05b0: 72 69 61 62 6c 65 20 6c 6f 61 64 65 64 0a 20 20  riable loaded.  
05c0: 20 20 76 61 72 69 61 62 6c 65 20 61 70 69 63 6d    variable apicm
05d0: 64 73 0a 0a 20 20 20 20 69 66 20 7b 5b 73 74 72  ds..    if {[str
05e0: 69 6e 67 20 65 71 75 61 6c 20 24 6b 65 79 20 24  ing equal $key $
05f0: 6c 6f 61 64 65 64 5d 7d 20 7b 0a 09 23 20 4e 6f  loaded]} {..# No
0600: 20 63 68 61 6e 67 65 2c 20 6e 6f 74 68 69 6e 67   change, nothing
0610: 20 74 6f 20 64 6f 2e 0a 09 72 65 74 75 72 6e 0a   to do...return.
0620: 20 20 20 20 7d 20 65 6c 73 65 69 66 20 7b 21 5b      } elseif {![
0630: 73 74 72 69 6e 67 20 65 71 75 61 6c 20 24 6b 65  string equal $ke
0640: 79 20 22 22 5d 7d 20 7b 0a 09 23 20 56 61 6c 69  y ""]} {..# Vali
0650: 64 61 74 65 20 74 68 65 20 74 61 72 67 65 74 20  date the target 
0660: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  implementation o
0670: 66 20 74 68 65 20 73 77 69 74 63 68 2e 0a 0a 09  f the switch....
0680: 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74  if {![info exist
0690: 73 20 61 63 63 65 6c 28 24 6b 65 79 29 5d 7d 20  s accel($key)]} 
06a0: 7b 0a 09 20 20 20 20 72 65 74 75 72 6e 20 2d 63  {..    return -c
06b0: 6f 64 65 20 65 72 72 6f 72 20 22 55 6e 61 62 6c  ode error "Unabl
06c0: 65 20 74 6f 20 61 63 74 69 76 61 74 65 20 75 6e  e to activate un
06d0: 6b 6e 6f 77 6e 20 69 6d 70 6c 65 6d 65 6e 74 61  known implementa
06e0: 74 69 6f 6e 20 5c 22 24 6b 65 79 5c 22 22 0a 09  tion \"$key\""..
06f0: 7d 20 65 6c 73 65 69 66 20 7b 21 5b 69 6e 66 6f  } elseif {![info
0700: 20 65 78 69 73 74 73 20 61 63 63 65 6c 28 24 6b   exists accel($k
0710: 65 79 29 5d 20 7c 7c 20 21 24 61 63 63 65 6c 28  ey)] || !$accel(
0720: 24 6b 65 79 29 7d 20 7b 0a 09 20 20 20 20 72 65  $key)} {..    re
0730: 74 75 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72  turn -code error
0740: 20 22 55 6e 61 62 6c 65 20 74 6f 20 61 63 74 69   "Unable to acti
0750: 76 61 74 65 20 6d 69 73 73 69 6e 67 20 69 6d 70  vate missing imp
0760: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 5c 22 24 6b  lementation \"$k
0770: 65 79 5c 22 22 0a 09 7d 0a 20 20 20 20 7d 0a 0a  ey\""..}.    }..
0780: 20 20 20 20 23 20 44 65 61 63 74 69 76 61 74 65      # Deactivate
0790: 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 69 6d   the previous im
07a0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2c 20 69 66  plementation, if
07b0: 20 74 68 65 72 65 20 77 61 73 20 61 6e 79 2e 0a   there was any..
07c0: 0a 20 20 20 20 69 66 20 7b 21 5b 73 74 72 69 6e  .    if {![strin
07d0: 67 20 65 71 75 61 6c 20 24 6c 6f 61 64 65 64 20  g equal $loaded 
07e0: 22 22 5d 7d 20 7b 0a 09 66 6f 72 65 61 63 68 20  ""]} {..foreach 
07f0: 63 20 24 61 70 69 63 6d 64 73 20 7b 0a 09 20 20  c $apicmds {..  
0800: 20 20 72 65 6e 61 6d 65 20 3a 3a 6a 73 6f 6e 3a    rename ::json:
0810: 3a 24 7b 63 7d 20 3a 3a 6a 73 6f 6e 3a 3a 24 7b  :${c} ::json::${
0820: 63 7d 5f 24 6c 6f 61 64 65 64 0a 09 7d 0a 20 20  c}_$loaded..}.  
0830: 20 20 7d 0a 0a 20 20 20 20 23 20 41 63 74 69 76    }..    # Activ
0840: 61 74 65 20 74 68 65 20 6e 65 77 20 69 6d 70 6c  ate the new impl
0850: 65 6d 65 6e 74 61 74 69 6f 6e 2c 20 69 66 20 74  ementation, if t
0860: 68 65 72 65 20 69 73 20 61 6e 79 2e 0a 0a 20 20  here is any...  
0870: 20 20 69 66 20 7b 21 5b 73 74 72 69 6e 67 20 65    if {![string e
0880: 71 75 61 6c 20 24 6b 65 79 20 22 22 5d 7d 20 7b  qual $key ""]} {
0890: 0a 09 66 6f 72 65 61 63 68 20 63 20 24 61 70 69  ..foreach c $api
08a0: 63 6d 64 73 20 7b 0a 09 20 20 20 20 72 65 6e 61  cmds {..    rena
08b0: 6d 65 20 3a 3a 6a 73 6f 6e 3a 3a 24 7b 63 7d 5f  me ::json::${c}_
08c0: 24 6b 65 79 20 3a 3a 6a 73 6f 6e 3a 3a 24 7b 63  $key ::json::${c
08d0: 7d 0a 09 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20  }..}.    }..    
08e0: 23 20 52 65 6d 65 6d 62 65 72 20 74 68 65 20 61  # Remember the a
08f0: 63 74 69 76 65 20 69 6d 70 6c 65 6d 65 6e 74 61  ctive implementa
0900: 74 69 6f 6e 2c 20 66 6f 72 20 64 65 61 63 74 69  tion, for deacti
0910: 76 61 74 69 6f 6e 20 62 79 20 66 75 74 75 72 65  vation by future
0920: 0a 20 20 20 20 23 20 73 77 69 74 63 68 65 73 2e  .    # switches.
0930: 0a 0a 20 20 20 20 73 65 74 20 6c 6f 61 64 65 64  ..    set loaded
0940: 20 24 6b 65 79 0a 20 20 20 20 72 65 74 75 72 6e   $key.    return
0950: 0a 7d 0a 0a 23 20 3a 3a 6a 73 6f 6e 3a 3a 49 6d  .}..# ::json::Im
0960: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 20 2d 2d  plementations --
0970: 0a 23 0a 23 09 44 65 74 65 72 6d 69 6e 65 73 20  .#.#.Determines 
0980: 77 68 69 63 68 20 69 6d 70 6c 65 6d 65 6e 74 61  which implementa
0990: 74 69 6f 6e 73 20 61 72 65 0a 23 09 70 72 65 73  tions are.#.pres
09a0: 65 6e 74 2c 20 69 2e 65 2e 20 6c 6f 61 64 65 64  ent, i.e. loaded
09b0: 2e 0a 23 0a 23 20 41 72 67 75 6d 65 6e 74 73 3a  ..#.# Arguments:
09c0: 0a 23 09 4e 6f 6e 65 2e 0a 23 0a 23 20 52 65 73  .#.None..#.# Res
09d0: 75 6c 74 73 3a 0a 23 09 41 20 6c 69 73 74 20 6f  ults:.#.A list o
09e0: 66 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  f implementation
09f0: 20 6b 65 79 73 2e 0a 0a 70 72 6f 63 20 3a 3a 6a   keys...proc ::j
0a00: 73 6f 6e 3a 3a 49 6d 70 6c 65 6d 65 6e 74 61 74  son::Implementat
0a10: 69 6f 6e 73 20 7b 7d 20 7b 0a 20 20 20 20 76 61  ions {} {.    va
0a20: 72 69 61 62 6c 65 20 61 63 63 65 6c 0a 20 20 20  riable accel.   
0a30: 20 73 65 74 20 72 65 73 20 7b 7d 0a 20 20 20 20   set res {}.    
0a40: 66 6f 72 65 61 63 68 20 6e 20 5b 61 72 72 61 79  foreach n [array
0a50: 20 6e 61 6d 65 73 20 61 63 63 65 6c 5d 20 7b 0a   names accel] {.
0a60: 09 69 66 20 7b 21 24 61 63 63 65 6c 28 24 6e 29  .if {!$accel($n)
0a70: 7d 20 63 6f 6e 74 69 6e 75 65 0a 09 6c 61 70 70  } continue..lapp
0a80: 65 6e 64 20 72 65 73 20 24 6e 0a 20 20 20 20 7d  end res $n.    }
0a90: 0a 20 20 20 20 72 65 74 75 72 6e 20 24 72 65 73  .    return $res
0aa0: 0a 7d 0a 0a 23 20 3a 3a 6a 73 6f 6e 3a 3a 4b 6e  .}..# ::json::Kn
0ab0: 6f 77 6e 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ownImplementatio
0ac0: 6e 73 20 2d 2d 0a 23 0a 23 09 44 65 74 65 72 6d  ns --.#.#.Determ
0ad0: 69 6e 65 73 20 77 68 69 63 68 20 69 6d 70 6c 65  ines which imple
0ae0: 6d 65 6e 74 61 74 69 6f 6e 73 20 61 72 65 20 6b  mentations are k
0af0: 6e 6f 77 6e 0a 23 09 61 73 20 70 6f 73 73 69 62  nown.#.as possib
0b00: 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  le implementatio
0b10: 6e 73 2e 0a 23 0a 23 20 41 72 67 75 6d 65 6e 74  ns..#.# Argument
0b20: 73 3a 0a 23 09 4e 6f 6e 65 2e 0a 23 0a 23 20 52  s:.#.None..#.# R
0b30: 65 73 75 6c 74 73 3a 0a 23 09 41 20 6c 69 73 74  esults:.#.A list
0b40: 20 6f 66 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69   of implementati
0b50: 6f 6e 20 6b 65 79 73 2e 20 49 6e 20 74 68 65 20  on keys. In the 
0b60: 6f 72 64 65 72 0a 23 09 6f 66 20 70 72 65 66 65  order.#.of prefe
0b70: 72 65 6e 63 65 2c 20 6d 6f 73 74 20 70 72 65 66  rence, most pref
0b80: 65 72 65 64 20 66 69 72 73 74 2e 0a 0a 70 72 6f  ered first...pro
0b90: 63 20 3a 3a 6a 73 6f 6e 3a 3a 4b 6e 6f 77 6e 49  c ::json::KnownI
0ba0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 20 7b  mplementations {
0bb0: 7d 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 7b  } {.    return {
0bc0: 63 72 69 74 63 6c 20 74 63 6c 7d 0a 7d 0a 0a 70  critcl tcl}.}..p
0bd0: 72 6f 63 20 3a 3a 6a 73 6f 6e 3a 3a 4e 61 6d 65  roc ::json::Name
0be0: 73 20 7b 7d 20 7b 0a 20 20 20 20 72 65 74 75 72  s {} {.    retur
0bf0: 6e 20 7b 0a 09 63 72 69 74 63 6c 20 7b 74 63 6c  n {..critcl {tcl
0c00: 6c 69 62 63 20 62 61 73 65 64 7d 0a 09 74 63 6c  libc based}..tcl
0c10: 20 20 20 20 7b 70 75 72 65 20 54 63 6c 7d 0a 20      {pure Tcl}. 
0c20: 20 20 20 7d 0a 7d 0a 0a 23 20 23 23 23 20 23 23     }.}..# ### ##
0c30: 23 20 23 23 23 20 23 23 23 23 23 23 23 23 23 20  # ### ######### 
0c40: 23 23 23 23 23 23 23 23 23 20 23 23 23 23 23 23  ######### ######
0c50: 23 23 23 0a 23 23 20 49 6e 69 74 69 61 6c 69 7a  ###.## Initializ
0c60: 61 74 69 6f 6e 3a 20 44 61 74 61 20 73 74 72 75  ation: Data stru
0c70: 63 74 75 72 65 73 2e 0a 0a 6e 61 6d 65 73 70 61  ctures...namespa
0c80: 63 65 20 65 76 61 6c 20 3a 3a 6a 73 6f 6e 20 7b  ce eval ::json {
0c90: 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 20 73  .    variable  s
0ca0: 65 6c 66 64 69 72 20 5b 66 69 6c 65 20 64 69 72  elfdir [file dir
0cb0: 6e 61 6d 65 20 5b 69 6e 66 6f 20 73 63 72 69 70  name [info scrip
0cc0: 74 5d 5d 0a 20 20 20 20 76 61 72 69 61 62 6c 65  t]].    variable
0cd0: 20 20 61 63 63 65 6c 0a 20 20 20 20 61 72 72 61    accel.    arra
0ce0: 79 20 73 65 74 20 61 63 63 65 6c 20 20 20 7b 74  y set accel   {t
0cf0: 63 6c 20 30 20 63 72 69 74 63 6c 20 30 7d 0a 20  cl 0 critcl 0}. 
0d00: 20 20 20 76 61 72 69 61 62 6c 65 20 20 6c 6f 61     variable  loa
0d10: 64 65 64 20 20 7b 7d 0a 0a 20 20 20 20 76 61 72  ded  {}..    var
0d20: 69 61 62 6c 65 20 61 70 69 63 6d 64 73 20 7b 0a  iable apicmds {.
0d30: 09 6a 73 6f 6e 32 64 69 63 74 0a 09 6d 61 6e 79  .json2dict..many
0d40: 2d 6a 73 6f 6e 32 64 69 63 74 0a 20 20 20 20 7d  -json2dict.    }
0d50: 0a 7d 0a 0a 23 20 23 23 23 20 23 23 23 20 23 23  .}..# ### ### ##
0d60: 23 20 23 23 23 23 23 23 23 23 23 20 23 23 23 23  # ######### ####
0d70: 23 23 23 23 23 20 23 23 23 23 23 23 23 23 23 0a  ##### #########.
0d80: 23 23 20 57 72 61 70 70 65 72 20 66 69 78 20 66  ## Wrapper fix f
0d90: 6f 72 20 74 68 65 20 6a 73 6f 6e 63 20 70 61 63  or the jsonc pac
0da0: 6b 61 67 65 20 74 6f 20 6d 61 74 63 68 20 41 50  kage to match AP
0db0: 49 73 2e 0a 0a 70 72 6f 63 20 3a 3a 6a 73 6f 6e  Is...proc ::json
0dc0: 3a 3a 6d 61 6e 79 2d 6a 73 6f 6e 32 64 69 63 74  ::many-json2dict
0dd0: 5f 63 72 69 74 63 6c 20 7b 61 72 67 73 7d 20 7b  _critcl {args} {
0de0: 0a 20 20 20 20 65 76 61 6c 20 5b 6c 69 6e 73 65  .    eval [linse
0df0: 72 74 20 24 61 72 67 73 20 30 20 3a 3a 6a 73 6f  rt $args 0 ::jso
0e00: 6e 3a 3a 6d 61 6e 79 5f 6a 73 6f 6e 32 64 69 63  n::many_json2dic
0e10: 74 5f 63 72 69 74 63 6c 5d 0a 7d 0a 0a 23 20 23  t_critcl].}..# #
0e20: 23 23 20 23 23 23 20 23 23 23 20 23 23 23 23 23  ## ### ### #####
0e30: 23 23 23 23 20 23 23 23 23 23 23 23 23 23 20 23  #### ######### #
0e40: 23 23 23 23 23 23 23 23 0a 23 23 20 49 6e 69 74  ########.## Init
0e50: 69 61 6c 69 7a 61 74 69 6f 6e 3a 20 43 68 6f 6f  ialization: Choo
0e60: 73 65 20 61 6e 20 69 6d 70 6c 65 6d 65 6e 74 61  se an implementa
0e70: 74 69 6f 6e 2c 0a 23 23 20 6d 6f 73 74 20 70 72  tion,.## most pr
0e80: 65 66 65 72 65 64 20 66 69 72 73 74 2e 20 4c 6f  efered first. Lo
0e90: 61 64 73 20 6f 6e 6c 79 20 6f 6e 65 20 6f 66 20  ads only one of 
0ea0: 74 68 65 0a 23 23 20 70 6f 73 73 69 62 6c 65 20  the.## possible 
0eb0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 2e  implementations.
0ec0: 20 41 6e 64 20 61 63 74 69 76 61 74 65 73 20 69   And activates i
0ed0: 74 2e 0a 0a 6e 61 6d 65 73 70 61 63 65 20 65 76  t...namespace ev
0ee0: 61 6c 20 3a 3a 6a 73 6f 6e 20 7b 0a 20 20 20 20  al ::json {.    
0ef0: 76 61 72 69 61 62 6c 65 20 65 0a 20 20 20 20 66  variable e.    f
0f00: 6f 72 65 61 63 68 20 65 20 5b 4b 6e 6f 77 6e 49  oreach e [KnownI
0f10: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 73 5d 20  mplementations] 
0f20: 7b 0a 09 69 66 20 7b 5b 4c 6f 61 64 41 63 63 65  {..if {[LoadAcce
0f30: 6c 65 72 61 74 6f 72 20 24 65 5d 7d 20 7b 0a 09  lerator $e]} {..
0f40: 20 20 20 20 53 77 69 74 63 68 54 6f 20 24 65 0a      SwitchTo $e.
0f50: 09 20 20 20 20 62 72 65 61 6b 0a 09 7d 0a 20 20  .    break..}.  
0f60: 20 20 7d 0a 20 20 20 20 75 6e 73 65 74 20 65 0a    }.    unset e.
0f70: 7d 0a 0a 23 20 23 23 23 20 23 23 23 20 23 23 23  }..# ### ### ###
0f80: 20 23 23 23 23 23 23 23 23 23 20 23 23 23 23 23   ######### #####
0f90: 23 23 23 23 20 23 23 23 23 23 23 23 23 23 0a 23  #### #########.#
0fa0: 23 20 54 63 6c 20 69 6d 70 6c 65 6d 65 6e 74 61  # Tcl implementa
0fb0: 74 69 6f 6e 20 6f 66 20 76 61 6c 69 64 61 74 69  tion of validati
0fc0: 6f 6e 2c 20 73 68 61 72 65 64 20 66 6f 72 20 54  on, shared for T
0fd0: 63 6c 20 61 6e 64 20 43 20 69 6d 70 6c 65 6d 65  cl and C impleme
0fe0: 6e 74 61 74 69 6f 6e 2e 0a 23 23 0a 23 23 20 54  ntation..##.## T
0ff0: 68 65 20 72 65 67 65 78 70 20 62 61 73 65 64 20  he regexp based 
1000: 76 61 6c 69 64 61 74 69 6f 6e 20 69 73 20 63 6f  validation is co
1010: 6e 73 69 73 74 65 6e 74 6c 79 20 66 61 73 74 65  nsistently faste
1020: 72 20 74 68 61 6e 20 6a 73 6f 6e 2d 63 2e 0a 23  r than json-c..#
1030: 23 20 53 75 73 70 65 63 74 65 64 20 72 65 61 73  # Suspected reas
1040: 6f 6e 73 3a 20 54 63 6c 20 52 45 73 20 61 72 65  ons: Tcl REs are
1050: 20 6d 61 69 6e 6c 79 20 69 6e 20 43 20 61 73 20   mainly in C as 
1060: 77 65 6c 6c 2c 20 61 6e 64 20 6a 73 6f 6e 2d 63  well, and json-c
1070: 20 68 61 73 0a 23 23 20 6f 76 65 72 68 65 61 64   has.## overhead
1080: 20 69 6e 20 63 6f 6e 73 74 72 75 63 74 69 6e 67   in constructing
1090: 20 69 74 73 20 6f 77 6e 20 64 61 74 61 20 73 74   its own data st
10a0: 72 75 63 74 75 72 65 73 2e 20 57 68 69 6c 65 20  ructures. While 
10b0: 69 72 72 65 6c 65 76 61 6e 74 0a 23 23 20 74 6f  irrelevant.## to
10c0: 20 76 61 6c 69 64 61 74 69 6f 6e 20 6a 73 6f 6e   validation json
10d0: 2d 63 20 73 74 69 6c 6c 20 62 75 69 6c 64 73 20  -c still builds 
10e0: 74 68 65 6d 2c 20 69 74 20 68 61 73 20 6e 6f 20  them, it has no 
10f0: 6d 6f 64 65 20 64 6f 69 6e 67 20 70 75 72 65 0a  mode doing pure.
1100: 23 23 20 73 79 6e 74 61 78 20 63 68 65 63 6b 69  ## syntax checki
1110: 6e 67 2e 0a 0a 6e 61 6d 65 73 70 61 63 65 20 65  ng...namespace e
1120: 76 61 6c 20 3a 3a 6a 73 6f 6e 20 7b 0a 20 20 20  val ::json {.   
1130: 20 23 20 52 65 67 75 6c 61 72 20 65 78 70 72 65   # Regular expre
1140: 73 73 69 6f 6e 20 66 6f 72 20 74 6f 6b 65 6e 69  ssion for tokeni
1150: 7a 69 6e 67 20 61 20 4a 53 4f 4e 20 74 65 78 74  zing a JSON text
1160: 20 28 63 66 2e 20 68 74 74 70 3a 2f 2f 6a 73 6f   (cf. http://jso
1170: 6e 2e 6f 72 67 2f 29 0a 0a 20 20 20 20 23 20 74  n.org/)..    # t
1180: 6f 6b 65 6e 73 20 63 6f 6e 73 69 73 74 69 6e 67  okens consisting
1190: 20 6f 66 20 61 20 73 69 6e 67 6c 65 20 63 68 61   of a single cha
11a0: 72 61 63 74 65 72 0a 20 20 20 20 76 61 72 69 61  racter.    varia
11b0: 62 6c 65 20 73 69 6e 67 6c 65 43 68 61 72 54 6f  ble singleCharTo
11c0: 6b 65 6e 73 20 7b 20 22 7b 22 20 22 7d 22 20 22  kens { "{" "}" "
11d0: 3a 22 20 22 5c 5c 5b 22 20 22 5c 5c 5d 22 20 22  :" "\\[" "\\]" "
11e0: 2c 22 20 7d 0a 20 20 20 20 76 61 72 69 61 62 6c  ," }.    variabl
11f0: 65 20 73 69 6e 67 6c 65 43 68 61 72 54 6f 6b 65  e singleCharToke
1200: 6e 52 45 20 22 5c 5b 5b 6a 6f 69 6e 20 24 73 69  nRE "\[[join $si
1210: 6e 67 6c 65 43 68 61 72 54 6f 6b 65 6e 73 20 7b  ngleCharTokens {
1220: 7d 5d 5c 5d 22 0a 0a 20 20 20 20 23 20 71 75 6f  }]\]"..    # quo
1230: 74 65 64 20 73 74 72 69 6e 67 20 74 6f 6b 65 6e  ted string token
1240: 73 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 65  s.    variable e
1250: 73 63 61 70 61 62 6c 65 52 45 73 20 7b 20 22 5b  scapableREs { "[
1260: 5c 5c 5c 22 5c 5c 5c 5c 2f 62 66 6e 72 74 5d 22  \\\"\\\\/bfnrt]"
1270: 20 22 75 5b 5b 3a 78 64 69 67 69 74 3a 5d 5d 7b   "u[[:xdigit:]]{
1280: 34 7d 22 20 22 2e 22 20 7d 0a 20 20 20 20 76 61  4}" "." }.    va
1290: 72 69 61 62 6c 65 20 65 73 63 61 70 65 64 43 68  riable escapedCh
12a0: 61 72 52 45 20 22 5c 5c 5c 5c 28 3f 3a 5b 6a 6f  arRE "\\\\(?:[jo
12b0: 69 6e 20 24 65 73 63 61 70 61 62 6c 65 52 45 73  in $escapableREs
12c0: 20 7c 5d 29 22 0a 20 20 20 20 76 61 72 69 61 62   |])".    variab
12d0: 6c 65 20 75 6e 65 73 63 61 70 65 64 43 68 61 72  le unescapedChar
12e0: 52 45 20 7b 5b 5e 5c 5c 5c 22 5d 7d 0a 20 20 20  RE {[^\\\"]}.   
12f0: 20 76 61 72 69 61 62 6c 65 20 73 74 72 69 6e 67   variable string
1300: 52 45 20 22 5c 22 28 3f 3a 24 65 73 63 61 70 65  RE "\"(?:$escape
1310: 64 43 68 61 72 52 45 7c 24 75 6e 65 73 63 61 70  dCharRE|$unescap
1320: 65 64 43 68 61 72 52 45 29 2a 5c 22 22 0a 0a 20  edCharRE)*\"".. 
1330: 20 20 20 23 20 61 73 20 61 62 6f 76 65 2c 20 66     # as above, f
1340: 6f 72 20 76 61 6c 69 64 61 74 69 6f 6e 0a 20 20  or validation.  
1350: 20 20 76 61 72 69 61 62 6c 65 20 65 73 63 61 70    variable escap
1360: 61 62 6c 65 52 45 73 76 20 7b 20 22 5b 5c 5c 5c  ableREsv { "[\\\
1370: 22 5c 5c 5c 5c 2f 62 66 6e 72 74 5d 22 20 22 75  "\\\\/bfnrt]" "u
1380: 5b 5b 3a 78 64 69 67 69 74 3a 5d 5d 7b 34 7d 22  [[:xdigit:]]{4}"
1390: 20 7d 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20   }.    variable 
13a0: 65 73 63 61 70 65 64 43 68 61 72 52 45 76 20 22  escapedCharREv "
13b0: 5c 5c 5c 5c 28 3f 3a 5b 6a 6f 69 6e 20 24 65 73  \\\\(?:[join $es
13c0: 63 61 70 61 62 6c 65 52 45 73 76 20 7c 5d 29 22  capableREsv |])"
13d0: 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 73 74  .    variable st
13e0: 72 69 6e 67 52 45 76 20 22 5c 22 28 3f 3a 24 65  ringREv "\"(?:$e
13f0: 73 63 61 70 65 64 43 68 61 72 52 45 76 7c 24 75  scapedCharREv|$u
1400: 6e 65 73 63 61 70 65 64 43 68 61 72 52 45 29 2a  nescapedCharRE)*
1410: 5c 22 22 0a 0a 20 20 20 20 23 20 28 75 6e 71 75  \""..    # (unqu
1420: 6f 74 65 64 29 20 77 6f 72 64 73 0a 20 20 20 20  oted) words.    
1430: 76 61 72 69 61 62 6c 65 20 77 6f 72 64 54 6f 6b  variable wordTok
1440: 65 6e 73 20 7b 20 22 74 72 75 65 22 20 22 66 61  ens { "true" "fa
1450: 6c 73 65 22 20 22 6e 75 6c 6c 22 20 7d 0a 20 20  lse" "null" }.  
1460: 20 20 76 61 72 69 61 62 6c 65 20 77 6f 72 64 54    variable wordT
1470: 6f 6b 65 6e 52 45 20 5b 6a 6f 69 6e 20 24 77 6f  okenRE [join $wo
1480: 72 64 54 6f 6b 65 6e 73 20 22 7c 22 5d 0a 0a 20  rdTokens "|"].. 
1490: 20 20 20 23 20 6e 75 6d 62 65 72 20 74 6f 6b 65     # number toke
14a0: 6e 73 0a 20 20 20 20 23 20 6e 65 67 61 74 69 76  ns.    # negativ
14b0: 65 20 6c 6f 6f 6b 61 68 65 61 64 20 28 3f 21 30  e lookahead (?!0
14c0: 29 5b 5b 3a 64 69 67 69 74 3a 5d 5d 2b 20 6d 69  )[[:digit:]]+ mi
14d0: 67 68 74 20 62 65 20 6d 6f 72 65 20 65 6c 65 67  ght be more eleg
14e0: 61 6e 74 2c 20 62 75 74 0a 20 20 20 20 23 20 77  ant, but.    # w
14f0: 6f 75 6c 64 20 73 6c 6f 77 20 64 6f 77 6e 20 74  ould slow down t
1500: 6f 6b 65 6e 69 7a 69 6e 67 20 62 79 20 61 20 66  okenizing by a f
1510: 61 63 74 6f 72 20 6f 66 20 75 70 20 74 6f 20 33  actor of up to 3
1520: 21 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 70  !.    variable p
1530: 6f 73 69 74 69 76 65 52 45 20 7b 5b 31 2d 39 5d  ositiveRE {[1-9]
1540: 5b 5b 3a 64 69 67 69 74 3a 5d 5d 2a 7d 0a 20 20  [[:digit:]]*}.  
1550: 20 20 76 61 72 69 61 62 6c 65 20 63 61 72 64 69    variable cardi
1560: 6e 61 6c 52 45 20 22 2d 3f 28 3f 3a 24 70 6f 73  nalRE "-?(?:$pos
1570: 69 74 69 76 65 52 45 7c 30 29 22 0a 20 20 20 20  itiveRE|0)".    
1580: 76 61 72 69 61 62 6c 65 20 66 72 61 63 74 69 6f  variable fractio
1590: 6e 52 45 20 7b 5b 2e 5d 5b 5b 3a 64 69 67 69 74  nRE {[.][[:digit
15a0: 3a 5d 5d 2b 7d 0a 20 20 20 20 76 61 72 69 61 62  :]]+}.    variab
15b0: 6c 65 20 65 78 70 6f 6e 65 6e 74 69 61 6c 52 45  le exponentialRE
15c0: 20 7b 5b 65 45 5d 5b 2b 2d 5d 3f 5b 5b 3a 64 69   {[eE][+-]?[[:di
15d0: 67 69 74 3a 5d 5d 2b 7d 0a 20 20 20 20 76 61 72  git:]]+}.    var
15e0: 69 61 62 6c 65 20 6e 75 6d 62 65 72 52 45 20 22  iable numberRE "
15f0: 24 7b 63 61 72 64 69 6e 61 6c 52 45 7d 28 3f 3a  ${cardinalRE}(?:
1600: 24 66 72 61 63 74 69 6f 6e 52 45 29 3f 28 3f 3a  $fractionRE)?(?:
1610: 24 65 78 70 6f 6e 65 6e 74 69 61 6c 52 45 29 3f  $exponentialRE)?
1620: 22 0a 0a 20 20 20 20 23 20 4a 53 4f 4e 20 74 6f  "..    # JSON to
1630: 6b 65 6e 2c 20 61 6e 64 20 76 61 6c 69 64 61 74  ken, and validat
1640: 69 6f 6e 0a 20 20 20 20 76 61 72 69 61 62 6c 65  ion.    variable
1650: 20 74 6f 6b 65 6e 52 45 20 22 24 73 69 6e 67 6c   tokenRE "$singl
1660: 65 43 68 61 72 54 6f 6b 65 6e 52 45 7c 24 73 74  eCharTokenRE|$st
1670: 72 69 6e 67 52 45 7c 24 77 6f 72 64 54 6f 6b 65  ringRE|$wordToke
1680: 6e 52 45 7c 24 6e 75 6d 62 65 72 52 45 22 0a 20  nRE|$numberRE". 
1690: 20 20 20 76 61 72 69 61 62 6c 65 20 74 6f 6b 65     variable toke
16a0: 6e 52 45 76 20 22 24 73 69 6e 67 6c 65 43 68 61  nREv "$singleCha
16b0: 72 54 6f 6b 65 6e 52 45 7c 24 73 74 72 69 6e 67  rTokenRE|$string
16c0: 52 45 76 7c 24 77 6f 72 64 54 6f 6b 65 6e 52 45  REv|$wordTokenRE
16d0: 7c 24 6e 75 6d 62 65 72 52 45 22 0a 0a 0a 20 20  |$numberRE"...  
16e0: 20 20 23 20 30 2e 2e 6e 20 77 68 69 74 65 20 73    # 0..n white s
16f0: 70 61 63 65 20 63 68 61 72 61 63 74 65 72 73 0a  pace characters.
1700: 20 20 20 20 73 65 74 20 77 68 69 74 65 53 70 61      set whiteSpa
1710: 63 65 52 45 20 7b 5b 5b 3a 73 70 61 63 65 3a 5d  ceRE {[[:space:]
1720: 5d 2a 7d 0a 0a 20 20 20 20 23 20 52 65 67 75 6c  ]*}..    # Regul
1730: 61 72 20 65 78 70 72 65 73 73 69 6f 6e 20 66 6f  ar expression fo
1740: 72 20 76 61 6c 69 64 61 74 69 6e 67 20 61 20 4a  r validating a J
1750: 53 4f 4e 20 74 65 78 74 0a 20 20 20 20 76 61 72  SON text.    var
1760: 69 61 62 6c 65 20 76 61 6c 69 64 4a 73 6f 6e 52  iable validJsonR
1770: 45 20 22 5e 28 3f 3a 24 7b 77 68 69 74 65 53 70  E "^(?:${whiteSp
1780: 61 63 65 52 45 7d 28 3f 3a 24 74 6f 6b 65 6e 52  aceRE}(?:$tokenR
1790: 45 76 29 29 2a 24 7b 77 68 69 74 65 53 70 61 63  Ev))*${whiteSpac
17a0: 65 52 45 7d 24 22 0a 7d 0a 0a 0a 23 20 56 61 6c  eRE}$".}...# Val
17b0: 69 64 61 74 65 20 4a 53 4f 4e 20 74 65 78 74 0a  idate JSON text.
17c0: 23 20 40 70 61 72 61 6d 20 6a 73 6f 6e 54 65 78  # @param jsonTex
17d0: 74 20 4a 53 4f 4e 20 74 65 78 74 0a 23 20 40 72  t JSON text.# @r
17e0: 65 74 75 72 6e 20 31 20 69 66 66 20 24 6a 73 6f  eturn 1 iff $jso
17f0: 6e 54 65 78 74 20 63 6f 6e 66 6f 72 6d 73 20 74  nText conforms t
1800: 6f 20 74 68 65 20 4a 53 4f 4e 20 67 72 61 6d 6d  o the JSON gramm
1810: 61 72 0a 23 20 20 20 20 20 20 20 20 20 20 20 28  ar.#           (
1820: 40 73 65 65 20 68 74 74 70 3a 2f 2f 6a 73 6f 6e  @see http://json
1830: 2e 6f 72 67 2f 29 0a 70 72 6f 63 20 3a 3a 6a 73  .org/).proc ::js
1840: 6f 6e 3a 3a 76 61 6c 69 64 61 74 65 20 7b 6a 73  on::validate {js
1850: 6f 6e 54 65 78 74 7d 20 7b 0a 20 20 20 20 76 61  onText} {.    va
1860: 72 69 61 62 6c 65 20 76 61 6c 69 64 4a 73 6f 6e  riable validJson
1870: 52 45 0a 0a 20 20 20 20 72 65 74 75 72 6e 20 5b  RE..    return [
1880: 72 65 67 65 78 70 20 2d 2d 20 24 76 61 6c 69 64  regexp -- $valid
1890: 4a 73 6f 6e 52 45 20 24 6a 73 6f 6e 54 65 78 74  JsonRE $jsonText
18a0: 5d 0a 7d 0a 0a 23 20 23 23 23 20 23 23 23 20 23  ].}..# ### ### #
18b0: 23 23 20 23 23 23 23 23 23 23 23 23 20 23 23 23  ## ######### ###
18c0: 23 23 23 23 23 23 20 23 23 23 23 23 23 23 23 23  ###### #########
18d0: 0a 23 23 20 54 68 65 73 65 20 74 68 72 65 65 20  .## These three 
18e0: 70 72 6f 63 65 64 75 72 65 73 20 73 68 61 72 65  procedures share
18f0: 64 20 62 65 74 77 65 65 6e 20 54 63 6c 20 61 6e  d between Tcl an
1900: 64 20 43 72 69 74 63 6c 20 69 6d 70 6c 65 6d 65  d Critcl impleme
1910: 6e 74 61 74 69 6f 6e 73 2e 0a 23 23 20 53 65 65  ntations..## See
1920: 20 61 6c 73 6f 20 70 61 63 6b 61 67 65 20 22 6a   also package "j
1930: 73 6f 6e 3a 3a 77 72 69 74 65 22 2e 0a 0a 70 72  son::write"...pr
1940: 6f 63 20 3a 3a 6a 73 6f 6e 3a 3a 64 69 63 74 32  oc ::json::dict2
1950: 6a 73 6f 6e 20 7b 64 69 63 74 56 61 6c 7d 20 7b  json {dictVal} {
1960: 0a 20 20 20 20 23 20 58 58 58 3a 20 43 75 72 72  .    # XXX: Curr
1970: 65 6e 74 6c 79 20 74 68 69 73 20 41 50 49 20 69  ently this API i
1980: 73 6e 27 74 20 73 79 6d 6d 65 74 72 69 63 61 6c  sn't symmetrical
1990: 2c 20 61 73 20 74 6f 20 63 72 65 61 74 65 20 70  , as to create p
19a0: 72 6f 70 65 72 0a 20 20 20 20 23 20 58 58 58 3a  roper.    # XXX:
19b0: 20 4a 53 4f 4e 20 74 65 78 74 20 72 65 71 75 69   JSON text requi
19c0: 72 65 73 20 74 79 70 65 20 6b 6e 6f 77 6c 65 64  res type knowled
19d0: 67 65 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20  ge of the input 
19e0: 64 61 74 61 0a 20 20 20 20 73 65 74 20 6a 73 6f  data.    set jso
19f0: 6e 20 22 22 0a 20 20 20 20 73 65 74 20 70 72 65  n "".    set pre
1a00: 66 69 78 20 22 22 0a 0a 20 20 20 20 66 6f 72 65  fix ""..    fore
1a10: 61 63 68 20 7b 6b 65 79 20 76 61 6c 7d 20 24 64  ach {key val} $d
1a20: 69 63 74 56 61 6c 20 7b 0a 09 23 20 6b 65 79 20  ictVal {..# key 
1a30: 6d 75 73 74 20 61 6c 77 61 79 73 20 62 65 20 61  must always be a
1a40: 20 73 74 72 69 6e 67 2c 20 76 61 6c 20 6d 61 79   string, val may
1a50: 20 62 65 20 61 20 6e 75 6d 62 65 72 2c 20 73 74   be a number, st
1a60: 72 69 6e 67 20 6f 72 0a 09 23 20 62 61 72 65 20  ring or..# bare 
1a70: 77 6f 72 64 20 28 74 72 75 65 7c 66 61 6c 73 65  word (true|false
1a80: 7c 6e 75 6c 6c 29 0a 09 69 66 20 7b 30 20 26 26  |null)..if {0 &&
1a90: 20 21 5b 73 74 72 69 6e 67 20 69 73 20 64 6f 75   ![string is dou
1aa0: 62 6c 65 20 2d 73 74 72 69 63 74 20 24 76 61 6c  ble -strict $val
1ab0: 5d 0a 09 20 20 20 20 26 26 20 21 5b 72 65 67 65  ]..    && ![rege
1ac0: 78 70 20 7b 5e 28 3f 3a 74 72 75 65 7c 66 61 6c  xp {^(?:true|fal
1ad0: 73 65 7c 6e 75 6c 6c 29 24 7d 20 24 76 61 6c 5d  se|null)$} $val]
1ae0: 7d 20 7b 0a 09 20 20 20 20 73 65 74 20 76 61 6c  } {..    set val
1af0: 20 22 5c 22 24 76 61 6c 5c 22 22 0a 09 7d 0a 20   "\"$val\""..}. 
1b00: 20 20 20 09 61 70 70 65 6e 64 20 6a 73 6f 6e 20     .append json 
1b10: 22 24 70 72 65 66 69 78 5c 22 24 6b 65 79 5c 22  "$prefix\"$key\"
1b20: 3a 20 24 76 61 6c 22 20 5c 6e 0a 09 73 65 74 20  : $val" \n..set 
1b30: 70 72 65 66 69 78 20 2c 0a 20 20 20 20 7d 0a 0a  prefix ,.    }..
1b40: 20 20 20 20 72 65 74 75 72 6e 20 22 5c 7b 24 7b      return "\{${
1b50: 6a 73 6f 6e 7d 5c 7d 22 0a 7d 0a 0a 70 72 6f 63  json}\}".}..proc
1b60: 20 3a 3a 6a 73 6f 6e 3a 3a 6c 69 73 74 32 6a 73   ::json::list2js
1b70: 6f 6e 20 7b 6c 69 73 74 56 61 6c 7d 20 7b 0a 20  on {listVal} {. 
1b80: 20 20 20 72 65 74 75 72 6e 20 22 5c 5b 5b 6a 6f     return "\[[jo
1b90: 69 6e 20 24 6c 69 73 74 56 61 6c 20 2c 5d 5c 5d  in $listVal ,]\]
1ba0: 22 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 6a 73 6f 6e  ".}..proc ::json
1bb0: 3a 3a 73 74 72 69 6e 67 32 6a 73 6f 6e 20 7b 73  ::string2json {s
1bc0: 74 72 7d 20 7b 0a 20 20 20 20 72 65 74 75 72 6e  tr} {.    return
1bd0: 20 22 5c 22 24 73 74 72 5c 22 22 0a 7d 0a 0a 23   "\"$str\"".}..#
1be0: 20 23 23 23 20 23 23 23 20 23 23 23 20 23 23 23   ### ### ### ###
1bf0: 23 23 23 23 23 23 20 23 23 23 23 23 23 23 23 23  ###### #########
1c00: 20 23 23 23 23 23 23 23 23 23 0a 23 23 20 52 65   #########.## Re
1c10: 61 64 79 0a 0a 70 61 63 6b 61 67 65 20 70 72 6f  ady..package pro
1c20: 76 69 64 65 20 6a 73 6f 6e 20 31 2e 33 2e 33 0a  vide json 1.3.3.