Merge pull request #8020 from hashicorp/vendor-hcl2-20200519
Update hcl2 vendoring
This commit is contained in:
commit
1bd4496feb
|
@ -11,7 +11,7 @@ import (
|
||||||
metrics "github.com/armon/go-metrics"
|
metrics "github.com/armon/go-metrics"
|
||||||
log "github.com/hashicorp/go-hclog"
|
log "github.com/hashicorp/go-hclog"
|
||||||
multierror "github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/hcl2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/nomad/client/allocdir"
|
"github.com/hashicorp/nomad/client/allocdir"
|
||||||
"github.com/hashicorp/nomad/client/allocrunner/interfaces"
|
"github.com/hashicorp/nomad/client/allocrunner/interfaces"
|
||||||
"github.com/hashicorp/nomad/client/allocrunner/taskrunner/restarts"
|
"github.com/hashicorp/nomad/client/allocrunner/taskrunner/restarts"
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/gohcl"
|
hcl "github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2/gohcl"
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/hashicorp/nomad/nomad/mock"
|
"github.com/hashicorp/nomad/nomad/mock"
|
||||||
"github.com/hashicorp/nomad/nomad/structs"
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
"github.com/hashicorp/nomad/plugins/drivers"
|
"github.com/hashicorp/nomad/plugins/drivers"
|
||||||
|
|
|
@ -3,9 +3,9 @@ package hclspecutils
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
hcl "github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/hcl2/hcldec"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/hashicorp/nomad/plugins/shared/hclspec"
|
"github.com/hashicorp/nomad/plugins/shared/hclspec"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package hclspecutils
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/nomad/plugins/shared/hclspec"
|
"github.com/hashicorp/nomad/plugins/shared/hclspec"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
hcl "github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/function"
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/go-msgpack/codec"
|
"github.com/hashicorp/go-msgpack/codec"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
hcl "github.com/hashicorp/hcl/v2"
|
||||||
hjson "github.com/hashicorp/hcl2/hcl/json"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/hcl2/hcldec"
|
hjson "github.com/hashicorp/hcl/v2/json"
|
||||||
"github.com/hashicorp/nomad/nomad/structs"
|
"github.com/hashicorp/nomad/nomad/structs"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/function"
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
|
|
|
@ -3,7 +3,7 @@ package hclutils_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/nomad/drivers/docker"
|
"github.com/hashicorp/nomad/drivers/docker"
|
||||||
"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils"
|
"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils"
|
||||||
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
|
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
plugin "github.com/hashicorp/go-plugin"
|
plugin "github.com/hashicorp/go-plugin"
|
||||||
"github.com/hashicorp/hcl"
|
"github.com/hashicorp/hcl"
|
||||||
"github.com/hashicorp/hcl/hcl/ast"
|
"github.com/hashicorp/hcl/hcl/ast"
|
||||||
"github.com/hashicorp/hcl2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils"
|
"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils"
|
||||||
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
|
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
|
||||||
"github.com/hashicorp/nomad/plugins/base"
|
"github.com/hashicorp/nomad/plugins/base"
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
package textseg
|
|
||||||
|
|
||||||
//go:generate go run make_tables.go -output tables.go
|
|
||||||
//go:generate go run make_test_tables.go -output tables_test.go
|
|
||||||
//go:generate ruby unicode2ragel.rb --url=http://www.unicode.org/Public/9.0.0/ucd/auxiliary/GraphemeBreakProperty.txt -m GraphemeCluster -p "Prepend,CR,LF,Control,Extend,Regional_Indicator,SpacingMark,L,V,T,LV,LVT,E_Base,E_Modifier,ZWJ,Glue_After_Zwj,E_Base_GAZ" -o grapheme_clusters_table.rl
|
|
||||||
//go:generate ragel -Z grapheme_clusters.rl
|
|
||||||
//go:generate gofmt -w grapheme_clusters.go
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,95 @@
|
||||||
|
Copyright (c) 2017 Martin Atkins
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
|
Unicode table generation programs are under a separate copyright and license:
|
||||||
|
|
||||||
|
Copyright (c) 2014 Couchbase, Inc.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||||
|
except in compliance with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software distributed under the
|
||||||
|
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
either express or implied. See the License for the specific language governing permissions
|
||||||
|
and limitations under the License.
|
||||||
|
|
||||||
|
---------
|
||||||
|
|
||||||
|
Grapheme break data is provided as part of the Unicode character database,
|
||||||
|
copright 2016 Unicode, Inc, which is provided with the following license:
|
||||||
|
|
||||||
|
Unicode Data Files include all data files under the directories
|
||||||
|
http://www.unicode.org/Public/, http://www.unicode.org/reports/,
|
||||||
|
http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and
|
||||||
|
http://www.unicode.org/utility/trac/browser/.
|
||||||
|
|
||||||
|
Unicode Data Files do not include PDF online code charts under the
|
||||||
|
directory http://www.unicode.org/Public/.
|
||||||
|
|
||||||
|
Software includes any source code published in the Unicode Standard
|
||||||
|
or under the directories
|
||||||
|
http://www.unicode.org/Public/, http://www.unicode.org/reports/,
|
||||||
|
http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and
|
||||||
|
http://www.unicode.org/utility/trac/browser/.
|
||||||
|
|
||||||
|
NOTICE TO USER: Carefully read the following legal agreement.
|
||||||
|
BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
|
||||||
|
DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
|
||||||
|
YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
||||||
|
TERMS AND CONDITIONS OF THIS AGREEMENT.
|
||||||
|
IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
|
||||||
|
THE DATA FILES OR SOFTWARE.
|
||||||
|
|
||||||
|
COPYRIGHT AND PERMISSION NOTICE
|
||||||
|
|
||||||
|
Copyright © 1991-2017 Unicode, Inc. All rights reserved.
|
||||||
|
Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Unicode data files and any associated documentation
|
||||||
|
(the "Data Files") or Unicode software and any associated documentation
|
||||||
|
(the "Software") to deal in the Data Files or Software
|
||||||
|
without restriction, including without limitation the rights to use,
|
||||||
|
copy, modify, merge, publish, distribute, and/or sell copies of
|
||||||
|
the Data Files or Software, and to permit persons to whom the Data Files
|
||||||
|
or Software are furnished to do so, provided that either
|
||||||
|
(a) this copyright and permission notice appear with all copies
|
||||||
|
of the Data Files or Software, or
|
||||||
|
(b) this copyright and permission notice appear in associated
|
||||||
|
Documentation.
|
||||||
|
|
||||||
|
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
|
||||||
|
NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
|
||||||
|
DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||||
|
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of a copyright holder
|
||||||
|
shall not be used in advertising or otherwise to promote the sale,
|
||||||
|
use or other dealings in these Data Files or Software without prior
|
||||||
|
written authorization of the copyright holder.
|
290
vendor/github.com/apparentlymart/go-textseg/v12/textseg/emoji_table.rl
generated
vendored
Normal file
290
vendor/github.com/apparentlymart/go-textseg/v12/textseg/emoji_table.rl
generated
vendored
Normal file
|
@ -0,0 +1,290 @@
|
||||||
|
# The following Ragel file was autogenerated with unicode2ragel.rb
|
||||||
|
# from: https://www.unicode.org/Public/emoji/12.0/emoji-data.txt
|
||||||
|
#
|
||||||
|
# It defines ["Extended_Pictographic"].
|
||||||
|
#
|
||||||
|
# To use this, make sure that your alphtype is set to byte,
|
||||||
|
# and that your input is in utf8.
|
||||||
|
|
||||||
|
%%{
|
||||||
|
machine Emoji;
|
||||||
|
|
||||||
|
Extended_Pictographic =
|
||||||
|
0xC2 0xA9 #1.1 [1] (©️) copyright
|
||||||
|
| 0xC2 0xAE #1.1 [1] (®️) registered
|
||||||
|
| 0xE2 0x80 0xBC #1.1 [1] (‼️) double exclamation mark
|
||||||
|
| 0xE2 0x81 0x89 #3.0 [1] (⁉️) exclamation question mark
|
||||||
|
| 0xE2 0x84 0xA2 #1.1 [1] (™️) trade mark
|
||||||
|
| 0xE2 0x84 0xB9 #3.0 [1] (ℹ️) information
|
||||||
|
| 0xE2 0x86 0x94..0x99 #1.1 [6] (↔️..↙️) left-right arrow..down...
|
||||||
|
| 0xE2 0x86 0xA9..0xAA #1.1 [2] (↩️..↪️) right arrow curving le...
|
||||||
|
| 0xE2 0x8C 0x9A..0x9B #1.1 [2] (⌚..⌛) watch..hourglass done
|
||||||
|
| 0xE2 0x8C 0xA8 #1.1 [1] (⌨️) keyboard
|
||||||
|
| 0xE2 0x8E 0x88 #3.0 [1] (⎈) HELM SYMBOL
|
||||||
|
| 0xE2 0x8F 0x8F #4.0 [1] (⏏️) eject button
|
||||||
|
| 0xE2 0x8F 0xA9..0xB3 #6.0 [11] (⏩..⏳) fast-forward button..hou...
|
||||||
|
| 0xE2 0x8F 0xB8..0xBA #7.0 [3] (⏸️..⏺️) pause button..record b...
|
||||||
|
| 0xE2 0x93 0x82 #1.1 [1] (Ⓜ️) circled M
|
||||||
|
| 0xE2 0x96 0xAA..0xAB #1.1 [2] (▪️..▫️) black small square..wh...
|
||||||
|
| 0xE2 0x96 0xB6 #1.1 [1] (▶️) play button
|
||||||
|
| 0xE2 0x97 0x80 #1.1 [1] (◀️) reverse button
|
||||||
|
| 0xE2 0x97 0xBB..0xBE #3.2 [4] (◻️..◾) white medium square..bl...
|
||||||
|
| 0xE2 0x98 0x80..0x85 #1.1 [6] (☀️..★) sun..BLACK STAR
|
||||||
|
| 0xE2 0x98 0x87..0x92 #1.1 [12] (☇..☒) LIGHTNING..BALLOT BOX WI...
|
||||||
|
| 0xE2 0x98 0x94..0x95 #4.0 [2] (☔..☕) umbrella with rain drops...
|
||||||
|
| 0xE2 0x98 0x96..0x97 #3.2 [2] (☖..☗) WHITE SHOGI PIECE..BLACK...
|
||||||
|
| 0xE2 0x98 0x98 #4.1 [1] (☘️) shamrock
|
||||||
|
| 0xE2 0x98 0x99 #3.0 [1] (☙) REVERSED ROTATED FLORAL ...
|
||||||
|
| 0xE2 0x98 0x9A..0xFF #1.1 [86] (☚..♯) BLACK LEFT POINTING INDE...
|
||||||
|
| 0xE2 0x99 0x00..0xAF #
|
||||||
|
| 0xE2 0x99 0xB0..0xB1 #3.0 [2] (♰..♱) WEST SYRIAC CROSS..EAST ...
|
||||||
|
| 0xE2 0x99 0xB2..0xBD #3.2 [12] (♲..♽) UNIVERSAL RECYCLING SYMB...
|
||||||
|
| 0xE2 0x99 0xBE..0xBF #4.1 [2] (♾️..♿) infinity..wheelchair sy...
|
||||||
|
| 0xE2 0x9A 0x80..0x85 #3.2 [6] (⚀..⚅) DIE FACE-1..DIE FACE-6
|
||||||
|
| 0xE2 0x9A 0x90..0x91 #4.0 [2] (⚐..⚑) WHITE FLAG..BLACK FLAG
|
||||||
|
| 0xE2 0x9A 0x92..0x9C #4.1 [11] (⚒️..⚜️) hammer and pick..fleur...
|
||||||
|
| 0xE2 0x9A 0x9D #5.1 [1] (⚝) OUTLINED WHITE STAR
|
||||||
|
| 0xE2 0x9A 0x9E..0x9F #5.2 [2] (⚞..⚟) THREE LINES CONVERGING R...
|
||||||
|
| 0xE2 0x9A 0xA0..0xA1 #4.0 [2] (⚠️..⚡) warning..high voltage
|
||||||
|
| 0xE2 0x9A 0xA2..0xB1 #4.1 [16] (⚢..⚱️) DOUBLED FEMALE SIGN..fu...
|
||||||
|
| 0xE2 0x9A 0xB2 #5.0 [1] (⚲) NEUTER
|
||||||
|
| 0xE2 0x9A 0xB3..0xBC #5.1 [10] (⚳..⚼) CERES..SESQUIQUADRATE
|
||||||
|
| 0xE2 0x9A 0xBD..0xBF #5.2 [3] (⚽..⚿) soccer ball..SQUARED KEY
|
||||||
|
| 0xE2 0x9B 0x80..0x83 #5.1 [4] (⛀..⛃) WHITE DRAUGHTS MAN..BLAC...
|
||||||
|
| 0xE2 0x9B 0x84..0x8D #5.2 [10] (⛄..⛍) snowman without snow..DI...
|
||||||
|
| 0xE2 0x9B 0x8E #6.0 [1] (⛎) Ophiuchus
|
||||||
|
| 0xE2 0x9B 0x8F..0xA1 #5.2 [19] (⛏️..⛡) pick..RESTRICTED LEFT E...
|
||||||
|
| 0xE2 0x9B 0xA2 #6.0 [1] (⛢) ASTRONOMICAL SYMBOL FOR ...
|
||||||
|
| 0xE2 0x9B 0xA3 #5.2 [1] (⛣) HEAVY CIRCLE WITH STROKE...
|
||||||
|
| 0xE2 0x9B 0xA4..0xA7 #6.0 [4] (⛤..⛧) PENTAGRAM..INVERTED PENT...
|
||||||
|
| 0xE2 0x9B 0xA8..0xBF #5.2 [24] (⛨..⛿) BLACK CROSS ON SHIELD..W...
|
||||||
|
| 0xE2 0x9C 0x80 #7.0 [1] (✀) BLACK SAFETY SCISSORS
|
||||||
|
| 0xE2 0x9C 0x81..0x84 #1.1 [4] (✁..✄) UPPER BLADE SCISSORS..WH...
|
||||||
|
| 0xE2 0x9C 0x85 #6.0 [1] (✅) check mark button
|
||||||
|
| 0xE2 0x9C 0x88..0x89 #1.1 [2] (✈️..✉️) airplane..envelope
|
||||||
|
| 0xE2 0x9C 0x8A..0x8B #6.0 [2] (✊..✋) raised fist..raised hand
|
||||||
|
| 0xE2 0x9C 0x8C..0x92 #1.1 [7] (✌️..✒️) victory hand..black nib
|
||||||
|
| 0xE2 0x9C 0x94 #1.1 [1] (✔️) check mark
|
||||||
|
| 0xE2 0x9C 0x96 #1.1 [1] (✖️) multiplication sign
|
||||||
|
| 0xE2 0x9C 0x9D #1.1 [1] (✝️) latin cross
|
||||||
|
| 0xE2 0x9C 0xA1 #1.1 [1] (✡️) star of David
|
||||||
|
| 0xE2 0x9C 0xA8 #6.0 [1] (✨) sparkles
|
||||||
|
| 0xE2 0x9C 0xB3..0xB4 #1.1 [2] (✳️..✴️) eight-spoked asterisk....
|
||||||
|
| 0xE2 0x9D 0x84 #1.1 [1] (❄️) snowflake
|
||||||
|
| 0xE2 0x9D 0x87 #1.1 [1] (❇️) sparkle
|
||||||
|
| 0xE2 0x9D 0x8C #6.0 [1] (❌) cross mark
|
||||||
|
| 0xE2 0x9D 0x8E #6.0 [1] (❎) cross mark button
|
||||||
|
| 0xE2 0x9D 0x93..0x95 #6.0 [3] (❓..❕) question mark..white exc...
|
||||||
|
| 0xE2 0x9D 0x97 #5.2 [1] (❗) exclamation mark
|
||||||
|
| 0xE2 0x9D 0xA3..0xA7 #1.1 [5] (❣️..❧) heart exclamation..ROTA...
|
||||||
|
| 0xE2 0x9E 0x95..0x97 #6.0 [3] (➕..➗) plus sign..division sign
|
||||||
|
| 0xE2 0x9E 0xA1 #1.1 [1] (➡️) right arrow
|
||||||
|
| 0xE2 0x9E 0xB0 #6.0 [1] (➰) curly loop
|
||||||
|
| 0xE2 0x9E 0xBF #6.0 [1] (➿) double curly loop
|
||||||
|
| 0xE2 0xA4 0xB4..0xB5 #3.2 [2] (⤴️..⤵️) right arrow curving up...
|
||||||
|
| 0xE2 0xAC 0x85..0x87 #4.0 [3] (⬅️..⬇️) left arrow..down arrow
|
||||||
|
| 0xE2 0xAC 0x9B..0x9C #5.1 [2] (⬛..⬜) black large square..whit...
|
||||||
|
| 0xE2 0xAD 0x90 #5.1 [1] (⭐) star
|
||||||
|
| 0xE2 0xAD 0x95 #5.2 [1] (⭕) hollow red circle
|
||||||
|
| 0xE3 0x80 0xB0 #1.1 [1] (〰️) wavy dash
|
||||||
|
| 0xE3 0x80 0xBD #3.2 [1] (〽️) part alternation mark
|
||||||
|
| 0xE3 0x8A 0x97 #1.1 [1] (㊗️) Japanese “congratulatio...
|
||||||
|
| 0xE3 0x8A 0x99 #1.1 [1] (㊙️) Japanese “secret” button
|
||||||
|
| 0xF0 0x9F 0x80 0x80..0xAB #5.1 [44] (🀀..🀫) MAHJONG TILE EAST WIN...
|
||||||
|
| 0xF0 0x9F 0x80 0xAC..0xAF #NA [4] (..) <reserved-1F02C>..<res...
|
||||||
|
| 0xF0 0x9F 0x80 0xB0..0xFF #5.1[100] (🀰..🂓) DOMINO TILE HOR...
|
||||||
|
| 0xF0 0x9F 0x81..0x81 0x00..0xFF #
|
||||||
|
| 0xF0 0x9F 0x82 0x00..0x93 #
|
||||||
|
| 0xF0 0x9F 0x82 0x94..0x9F #NA [12] (..) <reserved-1F094>..<res...
|
||||||
|
| 0xF0 0x9F 0x82 0xA0..0xAE #6.0 [15] (🂠..🂮) PLAYING CARD BACK..PL...
|
||||||
|
| 0xF0 0x9F 0x82 0xAF..0xB0 #NA [2] (..) <reserved-1F0AF>..<res...
|
||||||
|
| 0xF0 0x9F 0x82 0xB1..0xBE #6.0 [14] (🂱..🂾) PLAYING CARD ACE OF H...
|
||||||
|
| 0xF0 0x9F 0x82 0xBF #7.0 [1] (🂿) PLAYING CARD RED JOKER
|
||||||
|
| 0xF0 0x9F 0x83 0x80 #NA [1] () <reserved-1F0C0>
|
||||||
|
| 0xF0 0x9F 0x83 0x81..0x8F #6.0 [15] (🃁..🃏) PLAYING CARD ACE OF D...
|
||||||
|
| 0xF0 0x9F 0x83 0x90 #NA [1] () <reserved-1F0D0>
|
||||||
|
| 0xF0 0x9F 0x83 0x91..0x9F #6.0 [15] (🃑..🃟) PLAYING CARD ACE OF C...
|
||||||
|
| 0xF0 0x9F 0x83 0xA0..0xB5 #7.0 [22] (🃠..🃵) PLAYING CARD FOOL..PL...
|
||||||
|
| 0xF0 0x9F 0x83 0xB6..0xBF #NA [10] (..) <reserved-1F0F6>..<res...
|
||||||
|
| 0xF0 0x9F 0x84 0x8D..0x8F #NA [3] (🄍..🄏) <reserved-1F10D>..<res...
|
||||||
|
| 0xF0 0x9F 0x84 0xAF #11.0 [1] (🄯) COPYLEFT SYMBOL
|
||||||
|
| 0xF0 0x9F 0x85 0xAC #12.0 [1] (🅬) RAISED MR SIGN
|
||||||
|
| 0xF0 0x9F 0x85 0xAD..0xAF #NA [3] (🅭..🅯) <reserved-1F16D>..<res...
|
||||||
|
| 0xF0 0x9F 0x85 0xB0..0xB1 #6.0 [2] (🅰️..🅱️) A button (blood typ...
|
||||||
|
| 0xF0 0x9F 0x85 0xBE #6.0 [1] (🅾️) O button (blood type)
|
||||||
|
| 0xF0 0x9F 0x85 0xBF #5.2 [1] (🅿️) P button
|
||||||
|
| 0xF0 0x9F 0x86 0x8E #6.0 [1] (🆎) AB button (blood type)
|
||||||
|
| 0xF0 0x9F 0x86 0x91..0x9A #6.0 [10] (🆑..🆚) CL button..VS button
|
||||||
|
| 0xF0 0x9F 0x86 0xAD..0xFF #NA [57] (🆭..) <reserved-1F1AD>..<res...
|
||||||
|
| 0xF0 0x9F 0x87 0x00..0xA5 #
|
||||||
|
| 0xF0 0x9F 0x88 0x81..0x82 #6.0 [2] (🈁..🈂️) Japanese “here” butt...
|
||||||
|
| 0xF0 0x9F 0x88 0x83..0x8F #NA [13] (..) <reserved-1F203>..<res...
|
||||||
|
| 0xF0 0x9F 0x88 0x9A #5.2 [1] (🈚) Japanese “free of charge...
|
||||||
|
| 0xF0 0x9F 0x88 0xAF #5.2 [1] (🈯) Japanese “reserved” button
|
||||||
|
| 0xF0 0x9F 0x88 0xB2..0xBA #6.0 [9] (🈲..🈺) Japanese “prohibited”...
|
||||||
|
| 0xF0 0x9F 0x88 0xBC..0xBF #NA [4] (..) <reserved-1F23C>..<res...
|
||||||
|
| 0xF0 0x9F 0x89 0x89..0x8F #NA [7] (..) <reserved-1F249>..<res...
|
||||||
|
| 0xF0 0x9F 0x89 0x90..0x91 #6.0 [2] (🉐..🉑) Japanese “bargain” bu...
|
||||||
|
| 0xF0 0x9F 0x89 0x92..0x9F #NA [14] (..) <reserved-1F252>..<res...
|
||||||
|
| 0xF0 0x9F 0x89 0xA0..0xA5 #10.0 [6] (🉠..🉥) ROUNDED SYMBOL FOR F...
|
||||||
|
| 0xF0 0x9F 0x89 0xA6..0xFF #NA[154] (..) <reserved-1F266>...
|
||||||
|
| 0xF0 0x9F 0x8A..0x8A 0x00..0xFF #
|
||||||
|
| 0xF0 0x9F 0x8B 0x00..0xBF #
|
||||||
|
| 0xF0 0x9F 0x8C 0x80..0xA0 #6.0 [33] (🌀..🌠) cyclone..shooting star
|
||||||
|
| 0xF0 0x9F 0x8C 0xA1..0xAC #7.0 [12] (🌡️..🌬️) thermometer..wind face
|
||||||
|
| 0xF0 0x9F 0x8C 0xAD..0xAF #8.0 [3] (🌭..🌯) hot dog..burrito
|
||||||
|
| 0xF0 0x9F 0x8C 0xB0..0xB5 #6.0 [6] (🌰..🌵) chestnut..cactus
|
||||||
|
| 0xF0 0x9F 0x8C 0xB6 #7.0 [1] (🌶️) hot pepper
|
||||||
|
| 0xF0 0x9F 0x8C 0xB7..0xFF #6.0 [70] (🌷..🍼) tulip..baby bottle
|
||||||
|
| 0xF0 0x9F 0x8D 0x00..0xBC #
|
||||||
|
| 0xF0 0x9F 0x8D 0xBD #7.0 [1] (🍽️) fork and knife with plate
|
||||||
|
| 0xF0 0x9F 0x8D 0xBE..0xBF #8.0 [2] (🍾..🍿) bottle with popping c...
|
||||||
|
| 0xF0 0x9F 0x8E 0x80..0x93 #6.0 [20] (🎀..🎓) ribbon..graduation cap
|
||||||
|
| 0xF0 0x9F 0x8E 0x94..0x9F #7.0 [12] (🎔..🎟️) HEART WITH TIP ON TH...
|
||||||
|
| 0xF0 0x9F 0x8E 0xA0..0xFF #6.0 [37] (🎠..🏄) carousel horse..perso...
|
||||||
|
| 0xF0 0x9F 0x8F 0x00..0x84 #
|
||||||
|
| 0xF0 0x9F 0x8F 0x85 #7.0 [1] (🏅) sports medal
|
||||||
|
| 0xF0 0x9F 0x8F 0x86..0x8A #6.0 [5] (🏆..🏊) trophy..person swimming
|
||||||
|
| 0xF0 0x9F 0x8F 0x8B..0x8E #7.0 [4] (🏋️..🏎️) person lifting weig...
|
||||||
|
| 0xF0 0x9F 0x8F 0x8F..0x93 #8.0 [5] (🏏..🏓) cricket game..ping pong
|
||||||
|
| 0xF0 0x9F 0x8F 0x94..0x9F #7.0 [12] (🏔️..🏟️) snow-capped mountai...
|
||||||
|
| 0xF0 0x9F 0x8F 0xA0..0xB0 #6.0 [17] (🏠..🏰) house..castle
|
||||||
|
| 0xF0 0x9F 0x8F 0xB1..0xB7 #7.0 [7] (🏱..🏷️) WHITE PENNANT..label
|
||||||
|
| 0xF0 0x9F 0x8F 0xB8..0xBA #8.0 [3] (🏸..🏺) badminton..amphora
|
||||||
|
| 0xF0 0x9F 0x90 0x80..0xBE #6.0 [63] (🐀..🐾) rat..paw prints
|
||||||
|
| 0xF0 0x9F 0x90 0xBF #7.0 [1] (🐿️) chipmunk
|
||||||
|
| 0xF0 0x9F 0x91 0x80 #6.0 [1] (👀) eyes
|
||||||
|
| 0xF0 0x9F 0x91 0x81 #7.0 [1] (👁️) eye
|
||||||
|
| 0xF0 0x9F 0x91 0x82..0xFF #6.0[182] (👂..📷) ear..camera
|
||||||
|
| 0xF0 0x9F 0x92..0x92 0x00..0xFF #
|
||||||
|
| 0xF0 0x9F 0x93 0x00..0xB7 #
|
||||||
|
| 0xF0 0x9F 0x93 0xB8 #7.0 [1] (📸) camera with flash
|
||||||
|
| 0xF0 0x9F 0x93 0xB9..0xBC #6.0 [4] (📹..📼) video camera..videoca...
|
||||||
|
| 0xF0 0x9F 0x93 0xBD..0xBE #7.0 [2] (📽️..📾) film projector..PORT...
|
||||||
|
| 0xF0 0x9F 0x93 0xBF #8.0 [1] (📿) prayer beads
|
||||||
|
| 0xF0 0x9F 0x94 0x80..0xBD #6.0 [62] (🔀..🔽) shuffle tracks button...
|
||||||
|
| 0xF0 0x9F 0x95 0x86..0x8A #7.0 [5] (🕆..🕊️) WHITE LATIN CROSS..dove
|
||||||
|
| 0xF0 0x9F 0x95 0x8B..0x8F #8.0 [5] (🕋..🕏) kaaba..BOWL OF HYGIEIA
|
||||||
|
| 0xF0 0x9F 0x95 0x90..0xA7 #6.0 [24] (🕐..🕧) one o’clock..twelve-t...
|
||||||
|
| 0xF0 0x9F 0x95 0xA8..0xB9 #7.0 [18] (🕨..🕹️) RIGHT SPEAKER..joystick
|
||||||
|
| 0xF0 0x9F 0x95 0xBA #9.0 [1] (🕺) man dancing
|
||||||
|
| 0xF0 0x9F 0x95 0xBB..0xFF #7.0 [41] (🕻..🖣) LEFT HAND TELEPHONE R...
|
||||||
|
| 0xF0 0x9F 0x96 0x00..0xA3 #
|
||||||
|
| 0xF0 0x9F 0x96 0xA4 #9.0 [1] (🖤) black heart
|
||||||
|
| 0xF0 0x9F 0x96 0xA5..0xFF #7.0 [86] (🖥️..🗺️) desktop computer..w...
|
||||||
|
| 0xF0 0x9F 0x97 0x00..0xBA #
|
||||||
|
| 0xF0 0x9F 0x97 0xBB..0xBF #6.0 [5] (🗻..🗿) mount fuji..moai
|
||||||
|
| 0xF0 0x9F 0x98 0x80 #6.1 [1] (😀) grinning face
|
||||||
|
| 0xF0 0x9F 0x98 0x81..0x90 #6.0 [16] (😁..😐) beaming face with smi...
|
||||||
|
| 0xF0 0x9F 0x98 0x91 #6.1 [1] (😑) expressionless face
|
||||||
|
| 0xF0 0x9F 0x98 0x92..0x94 #6.0 [3] (😒..😔) unamused face..pensiv...
|
||||||
|
| 0xF0 0x9F 0x98 0x95 #6.1 [1] (😕) confused face
|
||||||
|
| 0xF0 0x9F 0x98 0x96 #6.0 [1] (😖) confounded face
|
||||||
|
| 0xF0 0x9F 0x98 0x97 #6.1 [1] (😗) kissing face
|
||||||
|
| 0xF0 0x9F 0x98 0x98 #6.0 [1] (😘) face blowing a kiss
|
||||||
|
| 0xF0 0x9F 0x98 0x99 #6.1 [1] (😙) kissing face with smilin...
|
||||||
|
| 0xF0 0x9F 0x98 0x9A #6.0 [1] (😚) kissing face with closed...
|
||||||
|
| 0xF0 0x9F 0x98 0x9B #6.1 [1] (😛) face with tongue
|
||||||
|
| 0xF0 0x9F 0x98 0x9C..0x9E #6.0 [3] (😜..😞) winking face with ton...
|
||||||
|
| 0xF0 0x9F 0x98 0x9F #6.1 [1] (😟) worried face
|
||||||
|
| 0xF0 0x9F 0x98 0xA0..0xA5 #6.0 [6] (😠..😥) angry face..sad but r...
|
||||||
|
| 0xF0 0x9F 0x98 0xA6..0xA7 #6.1 [2] (😦..😧) frowning face with op...
|
||||||
|
| 0xF0 0x9F 0x98 0xA8..0xAB #6.0 [4] (😨..😫) fearful face..tired face
|
||||||
|
| 0xF0 0x9F 0x98 0xAC #6.1 [1] (😬) grimacing face
|
||||||
|
| 0xF0 0x9F 0x98 0xAD #6.0 [1] (😭) loudly crying face
|
||||||
|
| 0xF0 0x9F 0x98 0xAE..0xAF #6.1 [2] (😮..😯) face with open mouth....
|
||||||
|
| 0xF0 0x9F 0x98 0xB0..0xB3 #6.0 [4] (😰..😳) anxious face with swe...
|
||||||
|
| 0xF0 0x9F 0x98 0xB4 #6.1 [1] (😴) sleeping face
|
||||||
|
| 0xF0 0x9F 0x98 0xB5..0xFF #6.0 [12] (😵..🙀) dizzy face..weary cat
|
||||||
|
| 0xF0 0x9F 0x99 0x00..0x80 #
|
||||||
|
| 0xF0 0x9F 0x99 0x81..0x82 #7.0 [2] (🙁..🙂) slightly frowning fac...
|
||||||
|
| 0xF0 0x9F 0x99 0x83..0x84 #8.0 [2] (🙃..🙄) upside-down face..fac...
|
||||||
|
| 0xF0 0x9F 0x99 0x85..0x8F #6.0 [11] (🙅..🙏) person gesturing NO.....
|
||||||
|
| 0xF0 0x9F 0x9A 0x80..0xFF #6.0 [70] (🚀..🛅) rocket..left luggage
|
||||||
|
| 0xF0 0x9F 0x9B 0x00..0x85 #
|
||||||
|
| 0xF0 0x9F 0x9B 0x86..0x8F #7.0 [10] (🛆..🛏️) TRIANGLE WITH ROUNDE...
|
||||||
|
| 0xF0 0x9F 0x9B 0x90 #8.0 [1] (🛐) place of worship
|
||||||
|
| 0xF0 0x9F 0x9B 0x91..0x92 #9.0 [2] (🛑..🛒) stop sign..shopping cart
|
||||||
|
| 0xF0 0x9F 0x9B 0x93..0x94 #10.0 [2] (🛓..🛔) STUPA..PAGODA
|
||||||
|
| 0xF0 0x9F 0x9B 0x95 #12.0 [1] (🛕) hindu temple
|
||||||
|
| 0xF0 0x9F 0x9B 0x96..0x9F #NA [10] (🛖..🛟) <reserved-1F6D6>..<res...
|
||||||
|
| 0xF0 0x9F 0x9B 0xA0..0xAC #7.0 [13] (🛠️..🛬) hammer and wrench..a...
|
||||||
|
| 0xF0 0x9F 0x9B 0xAD..0xAF #NA [3] (..) <reserved-1F6ED>..<res...
|
||||||
|
| 0xF0 0x9F 0x9B 0xB0..0xB3 #7.0 [4] (🛰️..🛳️) satellite..passenge...
|
||||||
|
| 0xF0 0x9F 0x9B 0xB4..0xB6 #9.0 [3] (🛴..🛶) kick scooter..canoe
|
||||||
|
| 0xF0 0x9F 0x9B 0xB7..0xB8 #10.0 [2] (🛷..🛸) sled..flying saucer
|
||||||
|
| 0xF0 0x9F 0x9B 0xB9 #11.0 [1] (🛹) skateboard
|
||||||
|
| 0xF0 0x9F 0x9B 0xBA #12.0 [1] (🛺) auto rickshaw
|
||||||
|
| 0xF0 0x9F 0x9B 0xBB..0xBF #NA [5] (🛻..) <reserved-1F6FB>..<res...
|
||||||
|
| 0xF0 0x9F 0x9D 0xB4..0xBF #NA [12] (🝴..🝿) <reserved-1F774>..<res...
|
||||||
|
| 0xF0 0x9F 0x9F 0x95..0x98 #11.0 [4] (🟕..🟘) CIRCLED TRIANGLE..NE...
|
||||||
|
| 0xF0 0x9F 0x9F 0x99..0x9F #NA [7] (🟙..) <reserved-1F7D9>..<res...
|
||||||
|
| 0xF0 0x9F 0x9F 0xA0..0xAB #12.0 [12] (🟠..🟫) orange circle..brown...
|
||||||
|
| 0xF0 0x9F 0x9F 0xAC..0xBF #NA [20] (..) <reserved-1F7EC>..<res...
|
||||||
|
| 0xF0 0x9F 0xA0 0x8C..0x8F #NA [4] (..) <reserved-1F80C>..<res...
|
||||||
|
| 0xF0 0x9F 0xA1 0x88..0x8F #NA [8] (..) <reserved-1F848>..<res...
|
||||||
|
| 0xF0 0x9F 0xA1 0x9A..0x9F #NA [6] (..) <reserved-1F85A>..<res...
|
||||||
|
| 0xF0 0x9F 0xA2 0x88..0x8F #NA [8] (..) <reserved-1F888>..<res...
|
||||||
|
| 0xF0 0x9F 0xA2 0xAE..0xFF #NA [82] (..) <reserved-1F8AE>..<res...
|
||||||
|
| 0xF0 0x9F 0xA3 0x00..0xBF #
|
||||||
|
| 0xF0 0x9F 0xA4 0x8C #NA [1] (🤌) <reserved-1F90C>
|
||||||
|
| 0xF0 0x9F 0xA4 0x8D..0x8F #12.0 [3] (🤍..🤏) white heart..pinchin...
|
||||||
|
| 0xF0 0x9F 0xA4 0x90..0x98 #8.0 [9] (🤐..🤘) zipper-mouth face..si...
|
||||||
|
| 0xF0 0x9F 0xA4 0x99..0x9E #9.0 [6] (🤙..🤞) call me hand..crossed...
|
||||||
|
| 0xF0 0x9F 0xA4 0x9F #10.0 [1] (🤟) love-you gesture
|
||||||
|
| 0xF0 0x9F 0xA4 0xA0..0xA7 #9.0 [8] (🤠..🤧) cowboy hat face..snee...
|
||||||
|
| 0xF0 0x9F 0xA4 0xA8..0xAF #10.0 [8] (🤨..🤯) face with raised eye...
|
||||||
|
| 0xF0 0x9F 0xA4 0xB0 #9.0 [1] (🤰) pregnant woman
|
||||||
|
| 0xF0 0x9F 0xA4 0xB1..0xB2 #10.0 [2] (🤱..🤲) breast-feeding..palm...
|
||||||
|
| 0xF0 0x9F 0xA4 0xB3..0xBA #9.0 [8] (🤳..🤺) selfie..person fencing
|
||||||
|
| 0xF0 0x9F 0xA4 0xBC..0xBE #9.0 [3] (🤼..🤾) people wrestling..per...
|
||||||
|
| 0xF0 0x9F 0xA4 0xBF #12.0 [1] (🤿) diving mask
|
||||||
|
| 0xF0 0x9F 0xA5 0x80..0x85 #9.0 [6] (🥀..🥅) wilted flower..goal net
|
||||||
|
| 0xF0 0x9F 0xA5 0x87..0x8B #9.0 [5] (🥇..🥋) 1st place medal..mart...
|
||||||
|
| 0xF0 0x9F 0xA5 0x8C #10.0 [1] (🥌) curling stone
|
||||||
|
| 0xF0 0x9F 0xA5 0x8D..0x8F #11.0 [3] (🥍..🥏) lacrosse..flying disc
|
||||||
|
| 0xF0 0x9F 0xA5 0x90..0x9E #9.0 [15] (🥐..🥞) croissant..pancakes
|
||||||
|
| 0xF0 0x9F 0xA5 0x9F..0xAB #10.0 [13] (🥟..🥫) dumpling..canned food
|
||||||
|
| 0xF0 0x9F 0xA5 0xAC..0xB0 #11.0 [5] (🥬..🥰) leafy green..smiling...
|
||||||
|
| 0xF0 0x9F 0xA5 0xB1 #12.0 [1] (🥱) yawning face
|
||||||
|
| 0xF0 0x9F 0xA5 0xB2 #NA [1] (🥲) <reserved-1F972>
|
||||||
|
| 0xF0 0x9F 0xA5 0xB3..0xB6 #11.0 [4] (🥳..🥶) partying face..cold ...
|
||||||
|
| 0xF0 0x9F 0xA5 0xB7..0xB9 #NA [3] (🥷..🥹) <reserved-1F977>..<res...
|
||||||
|
| 0xF0 0x9F 0xA5 0xBA #11.0 [1] (🥺) pleading face
|
||||||
|
| 0xF0 0x9F 0xA5 0xBB #12.0 [1] (🥻) sari
|
||||||
|
| 0xF0 0x9F 0xA5 0xBC..0xBF #11.0 [4] (🥼..🥿) lab coat..flat shoe
|
||||||
|
| 0xF0 0x9F 0xA6 0x80..0x84 #8.0 [5] (🦀..🦄) crab..unicorn
|
||||||
|
| 0xF0 0x9F 0xA6 0x85..0x91 #9.0 [13] (🦅..🦑) eagle..squid
|
||||||
|
| 0xF0 0x9F 0xA6 0x92..0x97 #10.0 [6] (🦒..🦗) giraffe..cricket
|
||||||
|
| 0xF0 0x9F 0xA6 0x98..0xA2 #11.0 [11] (🦘..🦢) kangaroo..swan
|
||||||
|
| 0xF0 0x9F 0xA6 0xA3..0xA4 #NA [2] (🦣..🦤) <reserved-1F9A3>..<res...
|
||||||
|
| 0xF0 0x9F 0xA6 0xA5..0xAA #12.0 [6] (🦥..🦪) sloth..oyster
|
||||||
|
| 0xF0 0x9F 0xA6 0xAB..0xAD #NA [3] (🦫..🦭) <reserved-1F9AB>..<res...
|
||||||
|
| 0xF0 0x9F 0xA6 0xAE..0xAF #12.0 [2] (🦮..🦯) guide dog..probing cane
|
||||||
|
| 0xF0 0x9F 0xA6 0xB0..0xB9 #11.0 [10] (🦰..🦹) red hair..supervillain
|
||||||
|
| 0xF0 0x9F 0xA6 0xBA..0xBF #12.0 [6] (🦺..🦿) safety vest..mechani...
|
||||||
|
| 0xF0 0x9F 0xA7 0x80 #8.0 [1] (🧀) cheese wedge
|
||||||
|
| 0xF0 0x9F 0xA7 0x81..0x82 #11.0 [2] (🧁..🧂) cupcake..salt
|
||||||
|
| 0xF0 0x9F 0xA7 0x83..0x8A #12.0 [8] (🧃..🧊) beverage box..ice cube
|
||||||
|
| 0xF0 0x9F 0xA7 0x8B..0x8C #NA [2] (🧋..🧌) <reserved-1F9CB>..<res...
|
||||||
|
| 0xF0 0x9F 0xA7 0x8D..0x8F #12.0 [3] (🧍..🧏) person standing..dea...
|
||||||
|
| 0xF0 0x9F 0xA7 0x90..0xA6 #10.0 [23] (🧐..🧦) face with monocle..s...
|
||||||
|
| 0xF0 0x9F 0xA7 0xA7..0xBF #11.0 [25] (🧧..🧿) red envelope..nazar ...
|
||||||
|
| 0xF0 0x9F 0xA8 0x80..0xFF #12.0 [84] (🨀..🩓) NEUTRAL CHESS KING.....
|
||||||
|
| 0xF0 0x9F 0xA9 0x00..0x93 #
|
||||||
|
| 0xF0 0x9F 0xA9 0x94..0x9F #NA [12] (..) <reserved-1FA54>..<res...
|
||||||
|
| 0xF0 0x9F 0xA9 0xA0..0xAD #11.0 [14] (🩠..🩭) XIANGQI RED GENERAL....
|
||||||
|
| 0xF0 0x9F 0xA9 0xAE..0xAF #NA [2] (..) <reserved-1FA6E>..<res...
|
||||||
|
| 0xF0 0x9F 0xA9 0xB0..0xB3 #12.0 [4] (🩰..🩳) ballet shoes..shorts
|
||||||
|
| 0xF0 0x9F 0xA9 0xB4..0xB7 #NA [4] (🩴..🩷) <reserved-1FA74>..<res...
|
||||||
|
| 0xF0 0x9F 0xA9 0xB8..0xBA #12.0 [3] (🩸..🩺) drop of blood..steth...
|
||||||
|
| 0xF0 0x9F 0xA9 0xBB..0xBF #NA [5] (🩻..) <reserved-1FA7B>..<res...
|
||||||
|
| 0xF0 0x9F 0xAA 0x80..0x82 #12.0 [3] (🪀..🪂) yo-yo..parachute
|
||||||
|
| 0xF0 0x9F 0xAA 0x83..0x8F #NA [13] (🪃..) <reserved-1FA83>..<res...
|
||||||
|
| 0xF0 0x9F 0xAA 0x90..0x95 #12.0 [6] (🪐..🪕) ringed planet..banjo
|
||||||
|
| 0xF0 0x9F 0xAA 0x96..0xFF #NA[1384] (🪖..) <reserved-1FA96>...
|
||||||
|
| 0xF0 0x9F 0xAB..0xBE 0x00..0xFF #
|
||||||
|
| 0xF0 0x9F 0xBF 0x00..0xBD #
|
||||||
|
;
|
||||||
|
|
||||||
|
}%%
|
8
vendor/github.com/apparentlymart/go-textseg/v12/textseg/generate.go
generated
vendored
Normal file
8
vendor/github.com/apparentlymart/go-textseg/v12/textseg/generate.go
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package textseg
|
||||||
|
|
||||||
|
//go:generate go run make_tables.go -output tables.go
|
||||||
|
//go:generate go run make_test_tables.go -output tables_test.go
|
||||||
|
//go:generate ruby unicode2ragel.rb --url=https://www.unicode.org/Public/12.0.0/ucd/auxiliary/GraphemeBreakProperty.txt -m GraphemeCluster -p "Prepend,CR,LF,Control,Extend,Regional_Indicator,SpacingMark,L,V,T,LV,LVT,ZWJ" -o grapheme_clusters_table.rl
|
||||||
|
//go:generate ruby unicode2ragel.rb --url=https://www.unicode.org/Public/emoji/12.0/emoji-data.txt -m Emoji -p "Extended_Pictographic" -o emoji_table.rl
|
||||||
|
//go:generate ragel -Z grapheme_clusters.rl
|
||||||
|
//go:generate gofmt -w grapheme_clusters.go
|
4078
vendor/github.com/apparentlymart/go-textseg/v12/textseg/grapheme_clusters.go
generated
vendored
Normal file
4078
vendor/github.com/apparentlymart/go-textseg/v12/textseg/grapheme_clusters.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -42,6 +42,7 @@ func ScanGraphemeClusters(data []byte, atEOF bool) (int, []byte, error) {
|
||||||
|
|
||||||
%%{
|
%%{
|
||||||
include GraphemeCluster "grapheme_clusters_table.rl";
|
include GraphemeCluster "grapheme_clusters_table.rl";
|
||||||
|
include Emoji "emoji_table.rl";
|
||||||
|
|
||||||
action start {
|
action start {
|
||||||
startPos = p
|
startPos = p
|
||||||
|
@ -55,7 +56,7 @@ func ScanGraphemeClusters(data []byte, atEOF bool) (int, []byte, error) {
|
||||||
return endPos+1, data[startPos:endPos+1], nil
|
return endPos+1, data[startPos:endPos+1], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ZWJGlue = ZWJ (Glue_After_Zwj | E_Base_GAZ Extend* E_Modifier?)?;
|
ZWJGlue = ZWJ (Extended_Pictographic Extend*)?;
|
||||||
AnyExtender = Extend | ZWJGlue | SpacingMark;
|
AnyExtender = Extend | ZWJGlue | SpacingMark;
|
||||||
Extension = AnyExtender*;
|
Extension = AnyExtender*;
|
||||||
ReplacementChar = (0xEF 0xBF 0xBD);
|
ReplacementChar = (0xEF 0xBF 0xBD);
|
||||||
|
@ -69,8 +70,8 @@ func ScanGraphemeClusters(data []byte, atEOF bool) (int, []byte, error) {
|
||||||
LVT T* |
|
LVT T* |
|
||||||
T+
|
T+
|
||||||
) Extension;
|
) Extension;
|
||||||
EmojiSeq = (E_Base | E_Base_GAZ) Extend* E_Modifier? Extension;
|
EmojiSeq = Extended_Pictographic Extend* Extension;
|
||||||
ZWJSeq = ZWJGlue Extension;
|
ZWJSeq = ZWJ (ZWJ | Extend | SpacingMark)*;
|
||||||
EmojiFlagSeq = Regional_Indicator Regional_Indicator? Extension;
|
EmojiFlagSeq = Regional_Indicator Regional_Indicator? Extension;
|
||||||
|
|
||||||
UTF8Cont = 0x80 .. 0xBF;
|
UTF8Cont = 0x80 .. 0xBF;
|
||||||
|
@ -82,7 +83,7 @@ func ScanGraphemeClusters(data []byte, atEOF bool) (int, []byte, error) {
|
||||||
);
|
);
|
||||||
|
|
||||||
# OtherSeq is any character that isn't at the start of one of the extended sequences above, followed by extension
|
# OtherSeq is any character that isn't at the start of one of the extended sequences above, followed by extension
|
||||||
OtherSeq = (AnyUTF8 - (CR|LF|Control|ReplacementChar|L|LV|V|LVT|T|E_Base|E_Base_GAZ|ZWJ|Regional_Indicator|Prepend)) Extension;
|
OtherSeq = (AnyUTF8 - (CR|LF|Control|ReplacementChar|L|LV|V|LVT|T|Extended_Pictographic|ZWJ|Regional_Indicator|Prepend)) (Extend | ZWJ | SpacingMark)*;
|
||||||
|
|
||||||
# PrependSeq is prepend followed by any of the other patterns above, except control characters which explicitly break
|
# PrependSeq is prepend followed by any of the other patterns above, except control characters which explicitly break
|
||||||
PrependSeq = Prepend+ (HangulSeq|EmojiSeq|ZWJSeq|EmojiFlagSeq|OtherSeq)?;
|
PrependSeq = Prepend+ (HangulSeq|EmojiSeq|ZWJSeq|EmojiFlagSeq|OtherSeq)?;
|
|
@ -1,7 +1,7 @@
|
||||||
# The following Ragel file was autogenerated with unicode2ragel.rb
|
# The following Ragel file was autogenerated with unicode2ragel.rb
|
||||||
# from: http://www.unicode.org/Public/9.0.0/ucd/auxiliary/GraphemeBreakProperty.txt
|
# from: https://www.unicode.org/Public/12.0.0/ucd/auxiliary/GraphemeBreakProperty.txt
|
||||||
#
|
#
|
||||||
# It defines ["Prepend", "CR", "LF", "Control", "Extend", "Regional_Indicator", "SpacingMark", "L", "V", "T", "LV", "LVT", "E_Base", "E_Modifier", "ZWJ", "Glue_After_Zwj", "E_Base_GAZ"].
|
# It defines ["Prepend", "CR", "LF", "Control", "Extend", "Regional_Indicator", "SpacingMark", "L", "V", "T", "LV", "LVT", "ZWJ"].
|
||||||
#
|
#
|
||||||
# To use this, make sure that your alphtype is set to byte,
|
# To use this, make sure that your alphtype is set to byte,
|
||||||
# and that your input is in utf8.
|
# and that your input is in utf8.
|
||||||
|
@ -16,7 +16,11 @@
|
||||||
| 0xE0 0xA3 0xA2 #Cf ARABIC DISPUTED END OF AYAH
|
| 0xE0 0xA3 0xA2 #Cf ARABIC DISPUTED END OF AYAH
|
||||||
| 0xE0 0xB5 0x8E #Lo MALAYALAM LETTER DOT REPH
|
| 0xE0 0xB5 0x8E #Lo MALAYALAM LETTER DOT REPH
|
||||||
| 0xF0 0x91 0x82 0xBD #Cf KAITHI NUMBER SIGN
|
| 0xF0 0x91 0x82 0xBD #Cf KAITHI NUMBER SIGN
|
||||||
|
| 0xF0 0x91 0x83 0x8D #Cf KAITHI NUMBER SIGN ABOVE
|
||||||
| 0xF0 0x91 0x87 0x82..0x83 #Lo [2] SHARADA SIGN JIHVAMULIYA..SHARA...
|
| 0xF0 0x91 0x87 0x82..0x83 #Lo [2] SHARADA SIGN JIHVAMULIYA..SHARA...
|
||||||
|
| 0xF0 0x91 0xA8 0xBA #Lo ZANABAZAR SQUARE CLUSTER-INITIAL L...
|
||||||
|
| 0xF0 0x91 0xAA 0x84..0x89 #Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOM...
|
||||||
|
| 0xF0 0x91 0xB5 0x86 #Lo MASARAM GONDI REPHA
|
||||||
;
|
;
|
||||||
|
|
||||||
CR =
|
CR =
|
||||||
|
@ -44,12 +48,10 @@
|
||||||
| 0xE2 0x81 0xA0..0xA4 #Cf [5] WORD JOINER..INVISIBLE PLUS
|
| 0xE2 0x81 0xA0..0xA4 #Cf [5] WORD JOINER..INVISIBLE PLUS
|
||||||
| 0xE2 0x81 0xA5 #Cn <reserved-2065>
|
| 0xE2 0x81 0xA5 #Cn <reserved-2065>
|
||||||
| 0xE2 0x81 0xA6..0xAF #Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIG...
|
| 0xE2 0x81 0xA6..0xAF #Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIG...
|
||||||
| 0xED 0xA0 0x80..0xFF #Cs [2048] <surrogate-D800>..<surrogate-...
|
|
||||||
| 0xED 0xA1..0xBE 0x00..0xFF #
|
|
||||||
| 0xED 0xBF 0x00..0xBF #
|
|
||||||
| 0xEF 0xBB 0xBF #Cf ZERO WIDTH NO-BREAK SPACE
|
| 0xEF 0xBB 0xBF #Cf ZERO WIDTH NO-BREAK SPACE
|
||||||
| 0xEF 0xBF 0xB0..0xB8 #Cn [9] <reserved-FFF0>..<reserved-FFF8>
|
| 0xEF 0xBF 0xB0..0xB8 #Cn [9] <reserved-FFF0>..<reserved-FFF8>
|
||||||
| 0xEF 0xBF 0xB9..0xBB #Cf [3] INTERLINEAR ANNOTATION ANCHOR..INT...
|
| 0xEF 0xBF 0xB9..0xBB #Cf [3] INTERLINEAR ANNOTATION ANCHOR..INT...
|
||||||
|
| 0xF0 0x93 0x90 0xB0..0xB8 #Cf [9] EGYPTIAN HIEROGLYPH VERTICAL JO...
|
||||||
| 0xF0 0x9B 0xB2 0xA0..0xA3 #Cf [4] SHORTHAND FORMAT LETTER OVERLAP...
|
| 0xF0 0x9B 0xB2 0xA0..0xA3 #Cf [4] SHORTHAND FORMAT LETTER OVERLAP...
|
||||||
| 0xF0 0x9D 0x85 0xB3..0xBA #Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSI...
|
| 0xF0 0x9D 0x85 0xB3..0xBA #Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSI...
|
||||||
| 0xF3 0xA0 0x80 0x80 #Cn <reserved-E0000>
|
| 0xF3 0xA0 0x80 0x80 #Cn <reserved-E0000>
|
||||||
|
@ -84,12 +86,13 @@
|
||||||
| 0xDD 0x00..0x8A #
|
| 0xDD 0x00..0x8A #
|
||||||
| 0xDE 0xA6..0xB0 #Mn [11] THAANA ABAFILI..THAANA SUKUN
|
| 0xDE 0xA6..0xB0 #Mn [11] THAANA ABAFILI..THAANA SUKUN
|
||||||
| 0xDF 0xAB..0xB3 #Mn [9] NKO COMBINING SHORT HIGH TONE..NKO...
|
| 0xDF 0xAB..0xB3 #Mn [9] NKO COMBINING SHORT HIGH TONE..NKO...
|
||||||
|
| 0xDF 0xBD #Mn NKO DANTAYALAN
|
||||||
| 0xE0 0xA0 0x96..0x99 #Mn [4] SAMARITAN MARK IN..SAMARITAN MARK ...
|
| 0xE0 0xA0 0x96..0x99 #Mn [4] SAMARITAN MARK IN..SAMARITAN MARK ...
|
||||||
| 0xE0 0xA0 0x9B..0xA3 #Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAM...
|
| 0xE0 0xA0 0x9B..0xA3 #Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAM...
|
||||||
| 0xE0 0xA0 0xA5..0xA7 #Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMA...
|
| 0xE0 0xA0 0xA5..0xA7 #Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMA...
|
||||||
| 0xE0 0xA0 0xA9..0xAD #Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMAR...
|
| 0xE0 0xA0 0xA9..0xAD #Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMAR...
|
||||||
| 0xE0 0xA1 0x99..0x9B #Mn [3] MANDAIC AFFRICATION MARK..MANDAIC ...
|
| 0xE0 0xA1 0x99..0x9B #Mn [3] MANDAIC AFFRICATION MARK..MANDAIC ...
|
||||||
| 0xE0 0xA3 0x94..0xA1 #Mn [14] ARABIC SMALL HIGH WORD AR-RUB..ARA...
|
| 0xE0 0xA3 0x93..0xA1 #Mn [15] ARABIC SMALL LOW WAW..ARABIC SMALL...
|
||||||
| 0xE0 0xA3 0xA3..0xFF #Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAG...
|
| 0xE0 0xA3 0xA3..0xFF #Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAG...
|
||||||
| 0xE0 0xA4 0x00..0x82 #
|
| 0xE0 0xA4 0x00..0x82 #
|
||||||
| 0xE0 0xA4 0xBA #Mn DEVANAGARI VOWEL SIGN OE
|
| 0xE0 0xA4 0xBA #Mn DEVANAGARI VOWEL SIGN OE
|
||||||
|
@ -105,6 +108,7 @@
|
||||||
| 0xE0 0xA7 0x8D #Mn BENGALI SIGN VIRAMA
|
| 0xE0 0xA7 0x8D #Mn BENGALI SIGN VIRAMA
|
||||||
| 0xE0 0xA7 0x97 #Mc BENGALI AU LENGTH MARK
|
| 0xE0 0xA7 0x97 #Mc BENGALI AU LENGTH MARK
|
||||||
| 0xE0 0xA7 0xA2..0xA3 #Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENG...
|
| 0xE0 0xA7 0xA2..0xA3 #Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENG...
|
||||||
|
| 0xE0 0xA7 0xBE #Mn BENGALI SANDHI MARK
|
||||||
| 0xE0 0xA8 0x81..0x82 #Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI...
|
| 0xE0 0xA8 0x81..0x82 #Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI...
|
||||||
| 0xE0 0xA8 0xBC #Mn GURMUKHI SIGN NUKTA
|
| 0xE0 0xA8 0xBC #Mn GURMUKHI SIGN NUKTA
|
||||||
| 0xE0 0xA9 0x81..0x82 #Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VO...
|
| 0xE0 0xA9 0x81..0x82 #Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VO...
|
||||||
|
@ -119,6 +123,7 @@
|
||||||
| 0xE0 0xAB 0x87..0x88 #Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VO...
|
| 0xE0 0xAB 0x87..0x88 #Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VO...
|
||||||
| 0xE0 0xAB 0x8D #Mn GUJARATI SIGN VIRAMA
|
| 0xE0 0xAB 0x8D #Mn GUJARATI SIGN VIRAMA
|
||||||
| 0xE0 0xAB 0xA2..0xA3 #Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJ...
|
| 0xE0 0xAB 0xA2..0xA3 #Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJ...
|
||||||
|
| 0xE0 0xAB 0xBA..0xBF #Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN...
|
||||||
| 0xE0 0xAC 0x81 #Mn ORIYA SIGN CANDRABINDU
|
| 0xE0 0xAC 0x81 #Mn ORIYA SIGN CANDRABINDU
|
||||||
| 0xE0 0xAC 0xBC #Mn ORIYA SIGN NUKTA
|
| 0xE0 0xAC 0xBC #Mn ORIYA SIGN NUKTA
|
||||||
| 0xE0 0xAC 0xBE #Mc ORIYA VOWEL SIGN AA
|
| 0xE0 0xAC 0xBE #Mc ORIYA VOWEL SIGN AA
|
||||||
|
@ -134,6 +139,7 @@
|
||||||
| 0xE0 0xAF 0x8D #Mn TAMIL SIGN VIRAMA
|
| 0xE0 0xAF 0x8D #Mn TAMIL SIGN VIRAMA
|
||||||
| 0xE0 0xAF 0x97 #Mc TAMIL AU LENGTH MARK
|
| 0xE0 0xAF 0x97 #Mc TAMIL AU LENGTH MARK
|
||||||
| 0xE0 0xB0 0x80 #Mn TELUGU SIGN COMBINING CANDRABINDU ...
|
| 0xE0 0xB0 0x80 #Mn TELUGU SIGN COMBINING CANDRABINDU ...
|
||||||
|
| 0xE0 0xB0 0x84 #Mn TELUGU SIGN COMBINING ANUSVARA ABOVE
|
||||||
| 0xE0 0xB0 0xBE..0xFF #Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL...
|
| 0xE0 0xB0 0xBE..0xFF #Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL...
|
||||||
| 0xE0 0xB1 0x00..0x80 #
|
| 0xE0 0xB1 0x00..0x80 #
|
||||||
| 0xE0 0xB1 0x86..0x88 #Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL ...
|
| 0xE0 0xB1 0x86..0x88 #Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL ...
|
||||||
|
@ -148,7 +154,8 @@
|
||||||
| 0xE0 0xB3 0x8C..0x8D #Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIG...
|
| 0xE0 0xB3 0x8C..0x8D #Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIG...
|
||||||
| 0xE0 0xB3 0x95..0x96 #Mc [2] KANNADA LENGTH MARK..KANNADA AI LE...
|
| 0xE0 0xB3 0x95..0x96 #Mc [2] KANNADA LENGTH MARK..KANNADA AI LE...
|
||||||
| 0xE0 0xB3 0xA2..0xA3 #Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANN...
|
| 0xE0 0xB3 0xA2..0xA3 #Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANN...
|
||||||
| 0xE0 0xB4 0x81 #Mn MALAYALAM SIGN CANDRABINDU
|
| 0xE0 0xB4 0x80..0x81 #Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ...
|
||||||
|
| 0xE0 0xB4 0xBB..0xBC #Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA...
|
||||||
| 0xE0 0xB4 0xBE #Mc MALAYALAM VOWEL SIGN AA
|
| 0xE0 0xB4 0xBE #Mc MALAYALAM VOWEL SIGN AA
|
||||||
| 0xE0 0xB5 0x81..0x84 #Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM ...
|
| 0xE0 0xB5 0x81..0x84 #Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM ...
|
||||||
| 0xE0 0xB5 0x8D #Mn MALAYALAM SIGN VIRAMA
|
| 0xE0 0xB5 0x8D #Mn MALAYALAM SIGN VIRAMA
|
||||||
|
@ -163,8 +170,7 @@
|
||||||
| 0xE0 0xB8 0xB4..0xBA #Mn [7] THAI CHARACTER SARA I..THAI CHARAC...
|
| 0xE0 0xB8 0xB4..0xBA #Mn [7] THAI CHARACTER SARA I..THAI CHARAC...
|
||||||
| 0xE0 0xB9 0x87..0x8E #Mn [8] THAI CHARACTER MAITAIKHU..THAI CHA...
|
| 0xE0 0xB9 0x87..0x8E #Mn [8] THAI CHARACTER MAITAIKHU..THAI CHA...
|
||||||
| 0xE0 0xBA 0xB1 #Mn LAO VOWEL SIGN MAI KAN
|
| 0xE0 0xBA 0xB1 #Mn LAO VOWEL SIGN MAI KAN
|
||||||
| 0xE0 0xBA 0xB4..0xB9 #Mn [6] LAO VOWEL SIGN I..LAO VOWEL SIGN UU
|
| 0xE0 0xBA 0xB4..0xBC #Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SI...
|
||||||
| 0xE0 0xBA 0xBB..0xBC #Mn [2] LAO VOWEL SIGN MAI KON..LAO SEMIVO...
|
|
||||||
| 0xE0 0xBB 0x88..0x8D #Mn [6] LAO TONE MAI EK..LAO NIGGAHITA
|
| 0xE0 0xBB 0x88..0x8D #Mn [6] LAO TONE MAI EK..LAO NIGGAHITA
|
||||||
| 0xE0 0xBC 0x98..0x99 #Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD P...
|
| 0xE0 0xBC 0x98..0x99 #Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD P...
|
||||||
| 0xE0 0xBC 0xB5 #Mn TIBETAN MARK NGAS BZUNG NYI ZLA
|
| 0xE0 0xBC 0xB5 #Mn TIBETAN MARK NGAS BZUNG NYI ZLA
|
||||||
|
@ -217,6 +223,7 @@
|
||||||
| 0xE1 0xAA 0xBE #Me COMBINING PARENTHESES OVERLAY
|
| 0xE1 0xAA 0xBE #Me COMBINING PARENTHESES OVERLAY
|
||||||
| 0xE1 0xAC 0x80..0x83 #Mn [4] BALINESE SIGN ULU RICEM..BALINESE ...
|
| 0xE1 0xAC 0x80..0x83 #Mn [4] BALINESE SIGN ULU RICEM..BALINESE ...
|
||||||
| 0xE1 0xAC 0xB4 #Mn BALINESE SIGN REREKAN
|
| 0xE1 0xAC 0xB4 #Mn BALINESE SIGN REREKAN
|
||||||
|
| 0xE1 0xAC 0xB5 #Mc BALINESE VOWEL SIGN TEDUNG
|
||||||
| 0xE1 0xAC 0xB6..0xBA #Mn [5] BALINESE VOWEL SIGN ULU..BALINESE ...
|
| 0xE1 0xAC 0xB6..0xBA #Mn [5] BALINESE VOWEL SIGN ULU..BALINESE ...
|
||||||
| 0xE1 0xAC 0xBC #Mn BALINESE VOWEL SIGN LA LENGA
|
| 0xE1 0xAC 0xBC #Mn BALINESE VOWEL SIGN LA LENGA
|
||||||
| 0xE1 0xAD 0x82 #Mn BALINESE VOWEL SIGN PEPET
|
| 0xE1 0xAD 0x82 #Mn BALINESE VOWEL SIGN PEPET
|
||||||
|
@ -237,7 +244,7 @@
|
||||||
| 0xE1 0xB3 0xAD #Mn VEDIC SIGN TIRYAK
|
| 0xE1 0xB3 0xAD #Mn VEDIC SIGN TIRYAK
|
||||||
| 0xE1 0xB3 0xB4 #Mn VEDIC TONE CANDRA ABOVE
|
| 0xE1 0xB3 0xB4 #Mn VEDIC TONE CANDRA ABOVE
|
||||||
| 0xE1 0xB3 0xB8..0xB9 #Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE ...
|
| 0xE1 0xB3 0xB8..0xB9 #Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE ...
|
||||||
| 0xE1 0xB7 0x80..0xB5 #Mn [54] COMBINING DOTTED GRAVE ACCENT..COM...
|
| 0xE1 0xB7 0x80..0xB9 #Mn [58] COMBINING DOTTED GRAVE ACCENT..COM...
|
||||||
| 0xE1 0xB7 0xBB..0xBF #Mn [5] COMBINING DELETION MARK..COMBINING...
|
| 0xE1 0xB7 0xBB..0xBF #Mn [5] COMBINING DELETION MARK..COMBINING...
|
||||||
| 0xE2 0x80 0x8C #Cf ZERO WIDTH NON-JOINER
|
| 0xE2 0x80 0x8C #Cf ZERO WIDTH NON-JOINER
|
||||||
| 0xE2 0x83 0x90..0x9C #Mn [13] COMBINING LEFT HARPOON ABOVE..COMB...
|
| 0xE2 0x83 0x90..0x9C #Mn [13] COMBINING LEFT HARPOON ABOVE..COMB...
|
||||||
|
@ -262,12 +269,13 @@
|
||||||
| 0xEA 0xA0 0xA5..0xA6 #Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI ...
|
| 0xEA 0xA0 0xA5..0xA6 #Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI ...
|
||||||
| 0xEA 0xA3 0x84..0x85 #Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA...
|
| 0xEA 0xA3 0x84..0x85 #Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA...
|
||||||
| 0xEA 0xA3 0xA0..0xB1 #Mn [18] COMBINING DEVANAGARI DIGIT ZERO..C...
|
| 0xEA 0xA3 0xA0..0xB1 #Mn [18] COMBINING DEVANAGARI DIGIT ZERO..C...
|
||||||
|
| 0xEA 0xA3 0xBF #Mn DEVANAGARI VOWEL SIGN AY
|
||||||
| 0xEA 0xA4 0xA6..0xAD #Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE C...
|
| 0xEA 0xA4 0xA6..0xAD #Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE C...
|
||||||
| 0xEA 0xA5 0x87..0x91 #Mn [11] REJANG VOWEL SIGN I..REJANG CONSON...
|
| 0xEA 0xA5 0x87..0x91 #Mn [11] REJANG VOWEL SIGN I..REJANG CONSON...
|
||||||
| 0xEA 0xA6 0x80..0x82 #Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE ...
|
| 0xEA 0xA6 0x80..0x82 #Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE ...
|
||||||
| 0xEA 0xA6 0xB3 #Mn JAVANESE SIGN CECAK TELU
|
| 0xEA 0xA6 0xB3 #Mn JAVANESE SIGN CECAK TELU
|
||||||
| 0xEA 0xA6 0xB6..0xB9 #Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE...
|
| 0xEA 0xA6 0xB6..0xB9 #Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE...
|
||||||
| 0xEA 0xA6 0xBC #Mn JAVANESE VOWEL SIGN PEPET
|
| 0xEA 0xA6 0xBC..0xBD #Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANES...
|
||||||
| 0xEA 0xA7 0xA5 #Mn MYANMAR SIGN SHAN SAW
|
| 0xEA 0xA7 0xA5 #Mn MYANMAR SIGN SHAN SAW
|
||||||
| 0xEA 0xA8 0xA9..0xAE #Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIG...
|
| 0xEA 0xA8 0xA9..0xAE #Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIG...
|
||||||
| 0xEA 0xA8 0xB1..0xB2 #Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIG...
|
| 0xEA 0xA8 0xB1..0xB2 #Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIG...
|
||||||
|
@ -298,6 +306,8 @@
|
||||||
| 0xF0 0x90 0xA8 0xB8..0xBA #Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAR...
|
| 0xF0 0x90 0xA8 0xB8..0xBA #Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAR...
|
||||||
| 0xF0 0x90 0xA8 0xBF #Mn KHAROSHTHI VIRAMA
|
| 0xF0 0x90 0xA8 0xBF #Mn KHAROSHTHI VIRAMA
|
||||||
| 0xF0 0x90 0xAB 0xA5..0xA6 #Mn [2] MANICHAEAN ABBREVIATION MARK AB...
|
| 0xF0 0x90 0xAB 0xA5..0xA6 #Mn [2] MANICHAEAN ABBREVIATION MARK AB...
|
||||||
|
| 0xF0 0x90 0xB4 0xA4..0xA7 #Mn [4] HANIFI ROHINGYA SIGN HARBAHAY.....
|
||||||
|
| 0xF0 0x90 0xBD 0x86..0x90 #Mn [11] SOGDIAN COMBINING DOT BELOW..SO...
|
||||||
| 0xF0 0x91 0x80 0x81 #Mn BRAHMI SIGN ANUSVARA
|
| 0xF0 0x91 0x80 0x81 #Mn BRAHMI SIGN ANUSVARA
|
||||||
| 0xF0 0x91 0x80 0xB8..0xFF #Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VI...
|
| 0xF0 0x91 0x80 0xB8..0xFF #Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VI...
|
||||||
| 0xF0 0x91 0x81 0x00..0x86 #
|
| 0xF0 0x91 0x81 0x00..0x86 #
|
||||||
|
@ -311,7 +321,7 @@
|
||||||
| 0xF0 0x91 0x85 0xB3 #Mn MAHAJANI SIGN NUKTA
|
| 0xF0 0x91 0x85 0xB3 #Mn MAHAJANI SIGN NUKTA
|
||||||
| 0xF0 0x91 0x86 0x80..0x81 #Mn [2] SHARADA SIGN CANDRABINDU..SHARA...
|
| 0xF0 0x91 0x86 0x80..0x81 #Mn [2] SHARADA SIGN CANDRABINDU..SHARA...
|
||||||
| 0xF0 0x91 0x86 0xB6..0xBE #Mn [9] SHARADA VOWEL SIGN U..SHARADA V...
|
| 0xF0 0x91 0x86 0xB6..0xBE #Mn [9] SHARADA VOWEL SIGN U..SHARADA V...
|
||||||
| 0xF0 0x91 0x87 0x8A..0x8C #Mn [3] SHARADA SIGN NUKTA..SHARADA EXT...
|
| 0xF0 0x91 0x87 0x89..0x8C #Mn [4] SHARADA SANDHI MARK..SHARADA EX...
|
||||||
| 0xF0 0x91 0x88 0xAF..0xB1 #Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOW...
|
| 0xF0 0x91 0x88 0xAF..0xB1 #Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOW...
|
||||||
| 0xF0 0x91 0x88 0xB4 #Mn KHOJKI SIGN ANUSVARA
|
| 0xF0 0x91 0x88 0xB4 #Mn KHOJKI SIGN ANUSVARA
|
||||||
| 0xF0 0x91 0x88 0xB6..0xB7 #Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN ...
|
| 0xF0 0x91 0x88 0xB6..0xB7 #Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN ...
|
||||||
|
@ -319,7 +329,7 @@
|
||||||
| 0xF0 0x91 0x8B 0x9F #Mn KHUDAWADI SIGN ANUSVARA
|
| 0xF0 0x91 0x8B 0x9F #Mn KHUDAWADI SIGN ANUSVARA
|
||||||
| 0xF0 0x91 0x8B 0xA3..0xAA #Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWA...
|
| 0xF0 0x91 0x8B 0xA3..0xAA #Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWA...
|
||||||
| 0xF0 0x91 0x8C 0x80..0x81 #Mn [2] GRANTHA SIGN COMBINING ANUSVARA...
|
| 0xF0 0x91 0x8C 0x80..0x81 #Mn [2] GRANTHA SIGN COMBINING ANUSVARA...
|
||||||
| 0xF0 0x91 0x8C 0xBC #Mn GRANTHA SIGN NUKTA
|
| 0xF0 0x91 0x8C 0xBB..0xBC #Mn [2] COMBINING BINDU BELOW..GRANTHA ...
|
||||||
| 0xF0 0x91 0x8C 0xBE #Mc GRANTHA VOWEL SIGN AA
|
| 0xF0 0x91 0x8C 0xBE #Mc GRANTHA VOWEL SIGN AA
|
||||||
| 0xF0 0x91 0x8D 0x80 #Mn GRANTHA VOWEL SIGN II
|
| 0xF0 0x91 0x8D 0x80 #Mn GRANTHA VOWEL SIGN II
|
||||||
| 0xF0 0x91 0x8D 0x97 #Mc GRANTHA AU LENGTH MARK
|
| 0xF0 0x91 0x8D 0x97 #Mc GRANTHA AU LENGTH MARK
|
||||||
|
@ -328,6 +338,7 @@
|
||||||
| 0xF0 0x91 0x90 0xB8..0xBF #Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL S...
|
| 0xF0 0x91 0x90 0xB8..0xBF #Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL S...
|
||||||
| 0xF0 0x91 0x91 0x82..0x84 #Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANU...
|
| 0xF0 0x91 0x91 0x82..0x84 #Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANU...
|
||||||
| 0xF0 0x91 0x91 0x86 #Mn NEWA SIGN NUKTA
|
| 0xF0 0x91 0x91 0x86 #Mn NEWA SIGN NUKTA
|
||||||
|
| 0xF0 0x91 0x91 0x9E #Mn NEWA SANDHI MARK
|
||||||
| 0xF0 0x91 0x92 0xB0 #Mc TIRHUTA VOWEL SIGN AA
|
| 0xF0 0x91 0x92 0xB0 #Mc TIRHUTA VOWEL SIGN AA
|
||||||
| 0xF0 0x91 0x92 0xB3..0xB8 #Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA V...
|
| 0xF0 0x91 0x92 0xB3..0xB8 #Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA V...
|
||||||
| 0xF0 0x91 0x92 0xBA #Mn TIRHUTA VOWEL SIGN SHORT E
|
| 0xF0 0x91 0x92 0xBA #Mn TIRHUTA VOWEL SIGN SHORT E
|
||||||
|
@ -352,6 +363,19 @@
|
||||||
| 0xF0 0x91 0x9C 0x9D..0x9F #Mn [3] AHOM CONSONANT SIGN MEDIAL LA.....
|
| 0xF0 0x91 0x9C 0x9D..0x9F #Mn [3] AHOM CONSONANT SIGN MEDIAL LA.....
|
||||||
| 0xF0 0x91 0x9C 0xA2..0xA5 #Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL S...
|
| 0xF0 0x91 0x9C 0xA2..0xA5 #Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL S...
|
||||||
| 0xF0 0x91 0x9C 0xA7..0xAB #Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN K...
|
| 0xF0 0x91 0x9C 0xA7..0xAB #Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN K...
|
||||||
|
| 0xF0 0x91 0xA0 0xAF..0xB7 #Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ...
|
||||||
|
| 0xF0 0x91 0xA0 0xB9..0xBA #Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN N...
|
||||||
|
| 0xF0 0x91 0xA7 0x94..0x97 #Mn [4] NANDINAGARI VOWEL SIGN U..NANDI...
|
||||||
|
| 0xF0 0x91 0xA7 0x9A..0x9B #Mn [2] NANDINAGARI VOWEL SIGN E..NANDI...
|
||||||
|
| 0xF0 0x91 0xA7 0xA0 #Mn NANDINAGARI SIGN VIRAMA
|
||||||
|
| 0xF0 0x91 0xA8 0x81..0x8A #Mn [10] ZANABAZAR SQUARE VOWEL SIGN I.....
|
||||||
|
| 0xF0 0x91 0xA8 0xB3..0xB8 #Mn [6] ZANABAZAR SQUARE FINAL CONSONAN...
|
||||||
|
| 0xF0 0x91 0xA8 0xBB..0xBE #Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL ...
|
||||||
|
| 0xF0 0x91 0xA9 0x87 #Mn ZANABAZAR SQUARE SUBJOINER
|
||||||
|
| 0xF0 0x91 0xA9 0x91..0x96 #Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO V...
|
||||||
|
| 0xF0 0x91 0xA9 0x99..0x9B #Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..S...
|
||||||
|
| 0xF0 0x91 0xAA 0x8A..0x96 #Mn [13] SOYOMBO FINAL CONSONANT SIGN G....
|
||||||
|
| 0xF0 0x91 0xAA 0x98..0x99 #Mn [2] SOYOMBO GEMINATION MARK..SOYOMB...
|
||||||
| 0xF0 0x91 0xB0 0xB0..0xB6 #Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSU...
|
| 0xF0 0x91 0xB0 0xB0..0xB6 #Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSU...
|
||||||
| 0xF0 0x91 0xB0 0xB8..0xBD #Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSU...
|
| 0xF0 0x91 0xB0 0xB8..0xBD #Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSU...
|
||||||
| 0xF0 0x91 0xB0 0xBF #Mn BHAIKSUKI SIGN VIRAMA
|
| 0xF0 0x91 0xB0 0xBF #Mn BHAIKSUKI SIGN VIRAMA
|
||||||
|
@ -359,8 +383,19 @@
|
||||||
| 0xF0 0x91 0xB2 0xAA..0xB0 #Mn [7] MARCHEN SUBJOINED LETTER RA..MA...
|
| 0xF0 0x91 0xB2 0xAA..0xB0 #Mn [7] MARCHEN SUBJOINED LETTER RA..MA...
|
||||||
| 0xF0 0x91 0xB2 0xB2..0xB3 #Mn [2] MARCHEN VOWEL SIGN U..MARCHEN V...
|
| 0xF0 0x91 0xB2 0xB2..0xB3 #Mn [2] MARCHEN VOWEL SIGN U..MARCHEN V...
|
||||||
| 0xF0 0x91 0xB2 0xB5..0xB6 #Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN ...
|
| 0xF0 0x91 0xB2 0xB5..0xB6 #Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN ...
|
||||||
|
| 0xF0 0x91 0xB4 0xB1..0xB6 #Mn [6] MASARAM GONDI VOWEL SIGN AA..MA...
|
||||||
|
| 0xF0 0x91 0xB4 0xBA #Mn MASARAM GONDI VOWEL SIGN E
|
||||||
|
| 0xF0 0x91 0xB4 0xBC..0xBD #Mn [2] MASARAM GONDI VOWEL SIGN AI..MA...
|
||||||
|
| 0xF0 0x91 0xB4 0xBF..0xFF #Mn [7] MASARAM GONDI VOWEL SIGN AU..MA...
|
||||||
|
| 0xF0 0x91 0xB5 0x00..0x85 #
|
||||||
|
| 0xF0 0x91 0xB5 0x87 #Mn MASARAM GONDI RA-KARA
|
||||||
|
| 0xF0 0x91 0xB6 0x90..0x91 #Mn [2] GUNJALA GONDI VOWEL SIGN EE..GU...
|
||||||
|
| 0xF0 0x91 0xB6 0x95 #Mn GUNJALA GONDI SIGN ANUSVARA
|
||||||
|
| 0xF0 0x91 0xB6 0x97 #Mn GUNJALA GONDI VIRAMA
|
||||||
|
| 0xF0 0x91 0xBB 0xB3..0xB4 #Mn [2] MAKASAR VOWEL SIGN I..MAKASAR V...
|
||||||
| 0xF0 0x96 0xAB 0xB0..0xB4 #Mn [5] BASSA VAH COMBINING HIGH TONE.....
|
| 0xF0 0x96 0xAB 0xB0..0xB4 #Mn [5] BASSA VAH COMBINING HIGH TONE.....
|
||||||
| 0xF0 0x96 0xAC 0xB0..0xB6 #Mn [7] PAHAWH HMONG MARK CIM TUB..PAHA...
|
| 0xF0 0x96 0xAC 0xB0..0xB6 #Mn [7] PAHAWH HMONG MARK CIM TUB..PAHA...
|
||||||
|
| 0xF0 0x96 0xBD 0x8F #Mn MIAO SIGN CONSONANT MODIFIER BAR
|
||||||
| 0xF0 0x96 0xBE 0x8F..0x92 #Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
|
| 0xF0 0x96 0xBE 0x8F..0x92 #Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
|
||||||
| 0xF0 0x9B 0xB2 0x9D..0x9E #Mn [2] DUPLOYAN THICK LETTER SELECTOR....
|
| 0xF0 0x9B 0xB2 0x9D..0x9E #Mn [2] DUPLOYAN THICK LETTER SELECTOR....
|
||||||
| 0xF0 0x9D 0x85 0xA5 #Mc MUSICAL SYMBOL COMBINING STEM
|
| 0xF0 0x9D 0x85 0xA5 #Mc MUSICAL SYMBOL COMBINING STEM
|
||||||
|
@ -383,8 +418,11 @@
|
||||||
| 0xF0 0x9E 0x80 0x9B..0xA1 #Mn [7] COMBINING GLAGOLITIC LETTER SHT...
|
| 0xF0 0x9E 0x80 0x9B..0xA1 #Mn [7] COMBINING GLAGOLITIC LETTER SHT...
|
||||||
| 0xF0 0x9E 0x80 0xA3..0xA4 #Mn [2] COMBINING GLAGOLITIC LETTER YU....
|
| 0xF0 0x9E 0x80 0xA3..0xA4 #Mn [2] COMBINING GLAGOLITIC LETTER YU....
|
||||||
| 0xF0 0x9E 0x80 0xA6..0xAA #Mn [5] COMBINING GLAGOLITIC LETTER YO....
|
| 0xF0 0x9E 0x80 0xA6..0xAA #Mn [5] COMBINING GLAGOLITIC LETTER YO....
|
||||||
|
| 0xF0 0x9E 0x84 0xB0..0xB6 #Mn [7] NYIAKENG PUACHUE HMONG TONE-B.....
|
||||||
|
| 0xF0 0x9E 0x8B 0xAC..0xAF #Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI
|
||||||
| 0xF0 0x9E 0xA3 0x90..0x96 #Mn [7] MENDE KIKAKUI COMBINING NUMBER ...
|
| 0xF0 0x9E 0xA3 0x90..0x96 #Mn [7] MENDE KIKAKUI COMBINING NUMBER ...
|
||||||
| 0xF0 0x9E 0xA5 0x84..0x8A #Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
|
| 0xF0 0x9E 0xA5 0x84..0x8A #Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
|
||||||
|
| 0xF0 0x9F 0x8F 0xBB..0xBF #Sk [5] EMOJI MODIFIER FITZPATRICK TYPE...
|
||||||
| 0xF3 0xA0 0x80 0xA0..0xFF #Cf [96] TAG SPACE..CANCEL TAG
|
| 0xF3 0xA0 0x80 0xA0..0xFF #Cf [96] TAG SPACE..CANCEL TAG
|
||||||
| 0xF3 0xA0 0x81 0x00..0xBF #
|
| 0xF3 0xA0 0x81 0x00..0xBF #
|
||||||
| 0xF3 0xA0 0x84 0x80..0xFF #Mn [240] VARIATION SELECTOR-17..VA...
|
| 0xF3 0xA0 0x84 0x80..0xFF #Mn [240] VARIATION SELECTOR-17..VA...
|
||||||
|
@ -462,7 +500,6 @@
|
||||||
| 0xE1 0xA9 0x97 #Mc TAI THAM CONSONANT SIGN LA TANG LAI
|
| 0xE1 0xA9 0x97 #Mc TAI THAM CONSONANT SIGN LA TANG LAI
|
||||||
| 0xE1 0xA9 0xAD..0xB2 #Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM V...
|
| 0xE1 0xA9 0xAD..0xB2 #Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM V...
|
||||||
| 0xE1 0xAC 0x84 #Mc BALINESE SIGN BISAH
|
| 0xE1 0xAC 0x84 #Mc BALINESE SIGN BISAH
|
||||||
| 0xE1 0xAC 0xB5 #Mc BALINESE VOWEL SIGN TEDUNG
|
|
||||||
| 0xE1 0xAC 0xBB #Mc BALINESE VOWEL SIGN RA REPA TEDUNG
|
| 0xE1 0xAC 0xBB #Mc BALINESE VOWEL SIGN RA REPA TEDUNG
|
||||||
| 0xE1 0xAC 0xBD..0xFF #Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUN...
|
| 0xE1 0xAC 0xBD..0xFF #Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUN...
|
||||||
| 0xE1 0xAD 0x00..0x81 #
|
| 0xE1 0xAD 0x00..0x81 #
|
||||||
|
@ -478,7 +515,7 @@
|
||||||
| 0xE1 0xB0 0xA4..0xAB #Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA...
|
| 0xE1 0xB0 0xA4..0xAB #Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA...
|
||||||
| 0xE1 0xB0 0xB4..0xB5 #Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEP...
|
| 0xE1 0xB0 0xB4..0xB5 #Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEP...
|
||||||
| 0xE1 0xB3 0xA1 #Mc VEDIC TONE ATHARVAVEDIC INDEPENDEN...
|
| 0xE1 0xB3 0xA1 #Mc VEDIC TONE ATHARVAVEDIC INDEPENDEN...
|
||||||
| 0xE1 0xB3 0xB2..0xB3 #Mc [2] VEDIC SIGN ARDHAVISARGA..VEDIC SIG...
|
| 0xE1 0xB3 0xB7 #Mc VEDIC SIGN ATIKRAMA
|
||||||
| 0xEA 0xA0 0xA3..0xA4 #Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI ...
|
| 0xEA 0xA0 0xA3..0xA4 #Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI ...
|
||||||
| 0xEA 0xA0 0xA7 #Mc SYLOTI NAGRI VOWEL SIGN OO
|
| 0xEA 0xA0 0xA7 #Mc SYLOTI NAGRI VOWEL SIGN OO
|
||||||
| 0xEA 0xA2 0x80..0x81 #Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHT...
|
| 0xEA 0xA2 0x80..0x81 #Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHT...
|
||||||
|
@ -488,7 +525,7 @@
|
||||||
| 0xEA 0xA6 0x83 #Mc JAVANESE SIGN WIGNYAN
|
| 0xEA 0xA6 0x83 #Mc JAVANESE SIGN WIGNYAN
|
||||||
| 0xEA 0xA6 0xB4..0xB5 #Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANE...
|
| 0xEA 0xA6 0xB4..0xB5 #Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANE...
|
||||||
| 0xEA 0xA6 0xBA..0xBB #Mc [2] JAVANESE VOWEL SIGN TALING..JAVANE...
|
| 0xEA 0xA6 0xBA..0xBB #Mc [2] JAVANESE VOWEL SIGN TALING..JAVANE...
|
||||||
| 0xEA 0xA6 0xBD..0xFF #Mc [4] JAVANESE CONSONANT SIGN KERET..JAV...
|
| 0xEA 0xA6 0xBE..0xFF #Mc [3] JAVANESE CONSONANT SIGN PENGKAL..J...
|
||||||
| 0xEA 0xA7 0x00..0x80 #
|
| 0xEA 0xA7 0x00..0x80 #
|
||||||
| 0xEA 0xA8 0xAF..0xB0 #Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
|
| 0xEA 0xA8 0xAF..0xB0 #Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
|
||||||
| 0xEA 0xA8 0xB3..0xB4 #Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSO...
|
| 0xEA 0xA8 0xB3..0xB4 #Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSO...
|
||||||
|
@ -506,6 +543,7 @@
|
||||||
| 0xF0 0x91 0x82 0xB0..0xB2 #Mc [3] KAITHI VOWEL SIGN AA..KAITHI VO...
|
| 0xF0 0x91 0x82 0xB0..0xB2 #Mc [3] KAITHI VOWEL SIGN AA..KAITHI VO...
|
||||||
| 0xF0 0x91 0x82 0xB7..0xB8 #Mc [2] KAITHI VOWEL SIGN O..KAITHI VOW...
|
| 0xF0 0x91 0x82 0xB7..0xB8 #Mc [2] KAITHI VOWEL SIGN O..KAITHI VOW...
|
||||||
| 0xF0 0x91 0x84 0xAC #Mc CHAKMA VOWEL SIGN E
|
| 0xF0 0x91 0x84 0xAC #Mc CHAKMA VOWEL SIGN E
|
||||||
|
| 0xF0 0x91 0x85 0x85..0x86 #Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VO...
|
||||||
| 0xF0 0x91 0x86 0x82 #Mc SHARADA SIGN VISARGA
|
| 0xF0 0x91 0x86 0x82 #Mc SHARADA SIGN VISARGA
|
||||||
| 0xF0 0x91 0x86 0xB3..0xB5 #Mc [3] SHARADA VOWEL SIGN AA..SHARADA ...
|
| 0xF0 0x91 0x86 0xB3..0xB5 #Mc [3] SHARADA VOWEL SIGN AA..SHARADA ...
|
||||||
| 0xF0 0x91 0x86 0xBF..0xFF #Mc [2] SHARADA VOWEL SIGN AU..SHARADA ...
|
| 0xF0 0x91 0x86 0xBF..0xFF #Mc [2] SHARADA VOWEL SIGN AU..SHARADA ...
|
||||||
|
@ -539,12 +577,25 @@
|
||||||
| 0xF0 0x91 0x9A 0xB6 #Mc TAKRI SIGN VIRAMA
|
| 0xF0 0x91 0x9A 0xB6 #Mc TAKRI SIGN VIRAMA
|
||||||
| 0xF0 0x91 0x9C 0xA0..0xA1 #Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL S...
|
| 0xF0 0x91 0x9C 0xA0..0xA1 #Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL S...
|
||||||
| 0xF0 0x91 0x9C 0xA6 #Mc AHOM VOWEL SIGN E
|
| 0xF0 0x91 0x9C 0xA6 #Mc AHOM VOWEL SIGN E
|
||||||
|
| 0xF0 0x91 0xA0 0xAC..0xAE #Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWE...
|
||||||
|
| 0xF0 0x91 0xA0 0xB8 #Mc DOGRA SIGN VISARGA
|
||||||
|
| 0xF0 0x91 0xA7 0x91..0x93 #Mc [3] NANDINAGARI VOWEL SIGN AA..NAND...
|
||||||
|
| 0xF0 0x91 0xA7 0x9C..0x9F #Mc [4] NANDINAGARI VOWEL SIGN O..NANDI...
|
||||||
|
| 0xF0 0x91 0xA7 0xA4 #Mc NANDINAGARI VOWEL SIGN PRISHTHAMAT...
|
||||||
|
| 0xF0 0x91 0xA8 0xB9 #Mc ZANABAZAR SQUARE SIGN VISARGA
|
||||||
|
| 0xF0 0x91 0xA9 0x97..0x98 #Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO ...
|
||||||
|
| 0xF0 0x91 0xAA 0x97 #Mc SOYOMBO SIGN VISARGA
|
||||||
| 0xF0 0x91 0xB0 0xAF #Mc BHAIKSUKI VOWEL SIGN AA
|
| 0xF0 0x91 0xB0 0xAF #Mc BHAIKSUKI VOWEL SIGN AA
|
||||||
| 0xF0 0x91 0xB0 0xBE #Mc BHAIKSUKI SIGN VISARGA
|
| 0xF0 0x91 0xB0 0xBE #Mc BHAIKSUKI SIGN VISARGA
|
||||||
| 0xF0 0x91 0xB2 0xA9 #Mc MARCHEN SUBJOINED LETTER YA
|
| 0xF0 0x91 0xB2 0xA9 #Mc MARCHEN SUBJOINED LETTER YA
|
||||||
| 0xF0 0x91 0xB2 0xB1 #Mc MARCHEN VOWEL SIGN I
|
| 0xF0 0x91 0xB2 0xB1 #Mc MARCHEN VOWEL SIGN I
|
||||||
| 0xF0 0x91 0xB2 0xB4 #Mc MARCHEN VOWEL SIGN O
|
| 0xF0 0x91 0xB2 0xB4 #Mc MARCHEN VOWEL SIGN O
|
||||||
| 0xF0 0x96 0xBD 0x91..0xBE #Mc [46] MIAO SIGN ASPIRATION..MIAO VOWE...
|
| 0xF0 0x91 0xB6 0x8A..0x8E #Mc [5] GUNJALA GONDI VOWEL SIGN AA..GU...
|
||||||
|
| 0xF0 0x91 0xB6 0x93..0x94 #Mc [2] GUNJALA GONDI VOWEL SIGN OO..GU...
|
||||||
|
| 0xF0 0x91 0xB6 0x96 #Mc GUNJALA GONDI SIGN VISARGA
|
||||||
|
| 0xF0 0x91 0xBB 0xB5..0xB6 #Mc [2] MAKASAR VOWEL SIGN E..MAKASAR V...
|
||||||
|
| 0xF0 0x96 0xBD 0x91..0xFF #Mc [55] MIAO SIGN ASPIRATION..MIAO VOWE...
|
||||||
|
| 0xF0 0x96 0xBE 0x00..0x87 #
|
||||||
| 0xF0 0x9D 0x85 0xA6 #Mc MUSICAL SYMBOL COMBINING SPRECHGES...
|
| 0xF0 0x9D 0x85 0xA6 #Mc MUSICAL SYMBOL COMBINING SPRECHGES...
|
||||||
| 0xF0 0x9D 0x85 0xAD #Mc MUSICAL SYMBOL COMBINING AUGMENTAT...
|
| 0xF0 0x9D 0x85 0xAD #Mc MUSICAL SYMBOL COMBINING AUGMENTAT...
|
||||||
;
|
;
|
||||||
|
@ -1531,53 +1582,8 @@
|
||||||
| 0xED 0x9E 0x89..0xA3 #Lo [27] HANGUL SYLLABLE HIG..HANGUL SYLLAB...
|
| 0xED 0x9E 0x89..0xA3 #Lo [27] HANGUL SYLLABLE HIG..HANGUL SYLLAB...
|
||||||
;
|
;
|
||||||
|
|
||||||
E_Base =
|
|
||||||
0xE2 0x98 0x9D #So WHITE UP POINTING INDEX
|
|
||||||
| 0xE2 0x9B 0xB9 #So PERSON WITH BALL
|
|
||||||
| 0xE2 0x9C 0x8A..0x8D #So [4] RAISED FIST..WRITING HAND
|
|
||||||
| 0xF0 0x9F 0x8E 0x85 #So FATHER CHRISTMAS
|
|
||||||
| 0xF0 0x9F 0x8F 0x83..0x84 #So [2] RUNNER..SURFER
|
|
||||||
| 0xF0 0x9F 0x8F 0x8A..0x8B #So [2] SWIMMER..WEIGHT LIFTER
|
|
||||||
| 0xF0 0x9F 0x91 0x82..0x83 #So [2] EAR..NOSE
|
|
||||||
| 0xF0 0x9F 0x91 0x86..0x90 #So [11] WHITE UP POINTING BACKHAND INDE...
|
|
||||||
| 0xF0 0x9F 0x91 0xAE #So POLICE OFFICER
|
|
||||||
| 0xF0 0x9F 0x91 0xB0..0xB8 #So [9] BRIDE WITH VEIL..PRINCESS
|
|
||||||
| 0xF0 0x9F 0x91 0xBC #So BABY ANGEL
|
|
||||||
| 0xF0 0x9F 0x92 0x81..0x83 #So [3] INFORMATION DESK PERSON..DANCER
|
|
||||||
| 0xF0 0x9F 0x92 0x85..0x87 #So [3] NAIL POLISH..HAIRCUT
|
|
||||||
| 0xF0 0x9F 0x92 0xAA #So FLEXED BICEPS
|
|
||||||
| 0xF0 0x9F 0x95 0xB5 #So SLEUTH OR SPY
|
|
||||||
| 0xF0 0x9F 0x95 0xBA #So MAN DANCING
|
|
||||||
| 0xF0 0x9F 0x96 0x90 #So RAISED HAND WITH FINGERS SPLAYED
|
|
||||||
| 0xF0 0x9F 0x96 0x95..0x96 #So [2] REVERSED HAND WITH MIDDLE FINGE...
|
|
||||||
| 0xF0 0x9F 0x99 0x85..0x87 #So [3] FACE WITH NO GOOD GESTURE..PERS...
|
|
||||||
| 0xF0 0x9F 0x99 0x8B..0x8F #So [5] HAPPY PERSON RAISING ONE HAND.....
|
|
||||||
| 0xF0 0x9F 0x9A 0xA3 #So ROWBOAT
|
|
||||||
| 0xF0 0x9F 0x9A 0xB4..0xB6 #So [3] BICYCLIST..PEDESTRIAN
|
|
||||||
| 0xF0 0x9F 0x9B 0x80 #So BATH
|
|
||||||
| 0xF0 0x9F 0xA4 0x98..0x9E #So [7] SIGN OF THE HORNS..HAND WITH IN...
|
|
||||||
| 0xF0 0x9F 0xA4 0xA6 #So FACE PALM
|
|
||||||
| 0xF0 0x9F 0xA4 0xB0 #So PREGNANT WOMAN
|
|
||||||
| 0xF0 0x9F 0xA4 0xB3..0xB9 #So [7] SELFIE..JUGGLING
|
|
||||||
| 0xF0 0x9F 0xA4 0xBC..0xBE #So [3] WRESTLERS..HANDBALL
|
|
||||||
;
|
|
||||||
|
|
||||||
E_Modifier =
|
|
||||||
0xF0 0x9F 0x8F 0xBB..0xBF #Sk [5] EMOJI MODIFIER FITZPATRICK TYPE...
|
|
||||||
;
|
|
||||||
|
|
||||||
ZWJ =
|
ZWJ =
|
||||||
0xE2 0x80 0x8D #Cf ZERO WIDTH JOINER
|
0xE2 0x80 0x8D #Cf ZERO WIDTH JOINER
|
||||||
;
|
;
|
||||||
|
|
||||||
Glue_After_Zwj =
|
|
||||||
0xE2 0x9D 0xA4 #So HEAVY BLACK HEART
|
|
||||||
| 0xF0 0x9F 0x92 0x8B #So KISS MARK
|
|
||||||
| 0xF0 0x9F 0x97 0xA8 #So LEFT SPEECH BUBBLE
|
|
||||||
;
|
|
||||||
|
|
||||||
E_Base_GAZ =
|
|
||||||
0xF0 0x9F 0x91 0xA6..0xA9 #So [4] BOY..WOMAN
|
|
||||||
;
|
|
||||||
|
|
||||||
}%%
|
}%%
|
307
vendor/github.com/apparentlymart/go-textseg/v12/textseg/make_tables.go
generated
vendored
Normal file
307
vendor/github.com/apparentlymart/go-textseg/v12/textseg/make_tables.go
generated
vendored
Normal file
|
@ -0,0 +1,307 @@
|
||||||
|
// Copyright (c) 2014 Couchbase, Inc.
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||||
|
// except in compliance with the License. You may obtain a copy of the License at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||||
|
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
|
||||||
|
// Modified by Martin Atkins to serve the needs of package textseg.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
var url = flag.String("url",
|
||||||
|
"http://www.unicode.org/Public/12.0.0/ucd/auxiliary/",
|
||||||
|
"URL of Unicode database directory")
|
||||||
|
var verbose = flag.Bool("verbose",
|
||||||
|
false,
|
||||||
|
"write data to stdout as it is parsed")
|
||||||
|
var localFiles = flag.Bool("local",
|
||||||
|
false,
|
||||||
|
"data files have been copied to the current directory; for debugging only")
|
||||||
|
var outputFile = flag.String("output",
|
||||||
|
"",
|
||||||
|
"output file for generated tables; default stdout")
|
||||||
|
|
||||||
|
var output *bufio.Writer
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
setupOutput()
|
||||||
|
|
||||||
|
graphemePropertyRanges := make(map[string]*unicode.RangeTable)
|
||||||
|
loadUnicodeData("GraphemeBreakProperty.txt", graphemePropertyRanges)
|
||||||
|
wordPropertyRanges := make(map[string]*unicode.RangeTable)
|
||||||
|
loadUnicodeData("WordBreakProperty.txt", wordPropertyRanges)
|
||||||
|
sentencePropertyRanges := make(map[string]*unicode.RangeTable)
|
||||||
|
loadUnicodeData("SentenceBreakProperty.txt", sentencePropertyRanges)
|
||||||
|
|
||||||
|
fmt.Fprintf(output, fileHeader, *url)
|
||||||
|
generateTables("Grapheme", graphemePropertyRanges)
|
||||||
|
generateTables("Word", wordPropertyRanges)
|
||||||
|
generateTables("Sentence", sentencePropertyRanges)
|
||||||
|
|
||||||
|
flushOutput()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WordBreakProperty.txt has the form:
|
||||||
|
// 05F0..05F2 ; Hebrew_Letter # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
|
||||||
|
// FB1D ; Hebrew_Letter # Lo HEBREW LETTER YOD WITH HIRIQ
|
||||||
|
func openReader(file string) (input io.ReadCloser) {
|
||||||
|
if *localFiles {
|
||||||
|
f, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
input = f
|
||||||
|
} else {
|
||||||
|
path := *url + file
|
||||||
|
resp, err := http.Get(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
log.Fatal("bad GET status for "+file, resp.Status)
|
||||||
|
}
|
||||||
|
input = resp.Body
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadUnicodeData(filename string, propertyRanges map[string]*unicode.RangeTable) {
|
||||||
|
f := openReader(filename)
|
||||||
|
defer f.Close()
|
||||||
|
bufioReader := bufio.NewReader(f)
|
||||||
|
line, err := bufioReader.ReadString('\n')
|
||||||
|
for err == nil {
|
||||||
|
parseLine(line, propertyRanges)
|
||||||
|
line, err = bufioReader.ReadString('\n')
|
||||||
|
}
|
||||||
|
// if the err was EOF still need to process last value
|
||||||
|
if err == io.EOF {
|
||||||
|
parseLine(line, propertyRanges)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const comment = "#"
|
||||||
|
const sep = ";"
|
||||||
|
const rnge = ".."
|
||||||
|
|
||||||
|
func parseLine(line string, propertyRanges map[string]*unicode.RangeTable) {
|
||||||
|
if strings.HasPrefix(line, comment) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if len(line) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
commentStart := strings.Index(line, comment)
|
||||||
|
if commentStart > 0 {
|
||||||
|
line = line[0:commentStart]
|
||||||
|
}
|
||||||
|
pieces := strings.Split(line, sep)
|
||||||
|
if len(pieces) != 2 {
|
||||||
|
log.Printf("unexpected %d pieces in %s", len(pieces), line)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
propertyName := strings.TrimSpace(pieces[1])
|
||||||
|
|
||||||
|
rangeTable, ok := propertyRanges[propertyName]
|
||||||
|
if !ok {
|
||||||
|
rangeTable = &unicode.RangeTable{
|
||||||
|
LatinOffset: 0,
|
||||||
|
}
|
||||||
|
propertyRanges[propertyName] = rangeTable
|
||||||
|
}
|
||||||
|
|
||||||
|
codepointRange := strings.TrimSpace(pieces[0])
|
||||||
|
rngeIndex := strings.Index(codepointRange, rnge)
|
||||||
|
|
||||||
|
if rngeIndex < 0 {
|
||||||
|
// single codepoint, not range
|
||||||
|
codepointInt, err := strconv.ParseUint(codepointRange, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error parsing int: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if codepointInt < 0x10000 {
|
||||||
|
r16 := unicode.Range16{
|
||||||
|
Lo: uint16(codepointInt),
|
||||||
|
Hi: uint16(codepointInt),
|
||||||
|
Stride: 1,
|
||||||
|
}
|
||||||
|
addR16ToTable(rangeTable, r16)
|
||||||
|
} else {
|
||||||
|
r32 := unicode.Range32{
|
||||||
|
Lo: uint32(codepointInt),
|
||||||
|
Hi: uint32(codepointInt),
|
||||||
|
Stride: 1,
|
||||||
|
}
|
||||||
|
addR32ToTable(rangeTable, r32)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rngeStart := codepointRange[0:rngeIndex]
|
||||||
|
rngeEnd := codepointRange[rngeIndex+2:]
|
||||||
|
rngeStartInt, err := strconv.ParseUint(rngeStart, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error parsing int: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rngeEndInt, err := strconv.ParseUint(rngeEnd, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error parsing int: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if rngeStartInt < 0x10000 && rngeEndInt < 0x10000 {
|
||||||
|
r16 := unicode.Range16{
|
||||||
|
Lo: uint16(rngeStartInt),
|
||||||
|
Hi: uint16(rngeEndInt),
|
||||||
|
Stride: 1,
|
||||||
|
}
|
||||||
|
addR16ToTable(rangeTable, r16)
|
||||||
|
} else if rngeStartInt >= 0x10000 && rngeEndInt >= 0x10000 {
|
||||||
|
r32 := unicode.Range32{
|
||||||
|
Lo: uint32(rngeStartInt),
|
||||||
|
Hi: uint32(rngeEndInt),
|
||||||
|
Stride: 1,
|
||||||
|
}
|
||||||
|
addR32ToTable(rangeTable, r32)
|
||||||
|
} else {
|
||||||
|
log.Printf("unexpected range")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addR16ToTable(r *unicode.RangeTable, r16 unicode.Range16) {
|
||||||
|
if r.R16 == nil {
|
||||||
|
r.R16 = make([]unicode.Range16, 0, 1)
|
||||||
|
}
|
||||||
|
r.R16 = append(r.R16, r16)
|
||||||
|
if r16.Hi <= unicode.MaxLatin1 {
|
||||||
|
r.LatinOffset++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addR32ToTable(r *unicode.RangeTable, r32 unicode.Range32) {
|
||||||
|
if r.R32 == nil {
|
||||||
|
r.R32 = make([]unicode.Range32, 0, 1)
|
||||||
|
}
|
||||||
|
r.R32 = append(r.R32, r32)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTables(prefix string, propertyRanges map[string]*unicode.RangeTable) {
|
||||||
|
prNames := make([]string, 0, len(propertyRanges))
|
||||||
|
for k := range propertyRanges {
|
||||||
|
prNames = append(prNames, k)
|
||||||
|
}
|
||||||
|
sort.Strings(prNames)
|
||||||
|
for _, key := range prNames {
|
||||||
|
rt := propertyRanges[key]
|
||||||
|
fmt.Fprintf(output, "var _%s%s = %s\n", prefix, key, generateRangeTable(rt))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(output, "type _%sRuneRange unicode.RangeTable\n", prefix)
|
||||||
|
|
||||||
|
fmt.Fprintf(output, "func _%sRuneType(r rune) *_%sRuneRange {\n", prefix, prefix)
|
||||||
|
fmt.Fprintf(output, "\tswitch {\n")
|
||||||
|
for _, key := range prNames {
|
||||||
|
fmt.Fprintf(output, "\tcase unicode.Is(_%s%s, r):\n\t\treturn (*_%sRuneRange)(_%s%s)\n", prefix, key, prefix, prefix, key)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(output, "\tdefault:\n\t\treturn nil\n")
|
||||||
|
fmt.Fprintf(output, "\t}\n")
|
||||||
|
fmt.Fprintf(output, "}\n")
|
||||||
|
|
||||||
|
fmt.Fprintf(output, "func (rng *_%sRuneRange) String() string {\n", prefix)
|
||||||
|
fmt.Fprintf(output, "\tswitch (*unicode.RangeTable)(rng) {\n")
|
||||||
|
for _, key := range prNames {
|
||||||
|
fmt.Fprintf(output, "\tcase _%s%s:\n\t\treturn %q\n", prefix, key, key)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(output, "\tdefault:\n\t\treturn \"Other\"\n")
|
||||||
|
fmt.Fprintf(output, "\t}\n")
|
||||||
|
fmt.Fprintf(output, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateRangeTable(rt *unicode.RangeTable) string {
|
||||||
|
rv := "&unicode.RangeTable{\n"
|
||||||
|
if rt.R16 != nil {
|
||||||
|
rv += "\tR16: []unicode.Range16{\n"
|
||||||
|
for _, r16 := range rt.R16 {
|
||||||
|
rv += fmt.Sprintf("\t\t%#v,\n", r16)
|
||||||
|
}
|
||||||
|
rv += "\t},\n"
|
||||||
|
}
|
||||||
|
if rt.R32 != nil {
|
||||||
|
rv += "\tR32: []unicode.Range32{\n"
|
||||||
|
for _, r32 := range rt.R32 {
|
||||||
|
rv += fmt.Sprintf("\t\t%#v,\n", r32)
|
||||||
|
}
|
||||||
|
rv += "\t},\n"
|
||||||
|
}
|
||||||
|
rv += fmt.Sprintf("\t\tLatinOffset: %d,\n", rt.LatinOffset)
|
||||||
|
rv += "}\n"
|
||||||
|
return rv
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileHeader = `// Generated by running
|
||||||
|
// maketables --url=%s
|
||||||
|
// DO NOT EDIT
|
||||||
|
|
||||||
|
package textseg
|
||||||
|
|
||||||
|
import(
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
`
|
||||||
|
|
||||||
|
func setupOutput() {
|
||||||
|
output = bufio.NewWriter(startGofmt())
|
||||||
|
}
|
||||||
|
|
||||||
|
// startGofmt connects output to a gofmt process if -output is set.
|
||||||
|
func startGofmt() io.Writer {
|
||||||
|
if *outputFile == "" {
|
||||||
|
return os.Stdout
|
||||||
|
}
|
||||||
|
stdout, err := os.Create(*outputFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
// Pipe output to gofmt.
|
||||||
|
gofmt := exec.Command("gofmt")
|
||||||
|
fd, err := gofmt.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
gofmt.Stdout = stdout
|
||||||
|
gofmt.Stderr = os.Stderr
|
||||||
|
err = gofmt.Start()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return fd
|
||||||
|
}
|
||||||
|
|
||||||
|
func flushOutput() {
|
||||||
|
err := output.Flush()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
211
vendor/github.com/apparentlymart/go-textseg/v12/textseg/make_test_tables.go
generated
vendored
Normal file
211
vendor/github.com/apparentlymart/go-textseg/v12/textseg/make_test_tables.go
generated
vendored
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
// Copyright (c) 2014 Couchbase, Inc.
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
||||||
|
// except in compliance with the License. You may obtain a copy of the License at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed under the
|
||||||
|
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var url = flag.String("url",
|
||||||
|
"http://www.unicode.org/Public/12.0.0/ucd/auxiliary/",
|
||||||
|
"URL of Unicode database directory")
|
||||||
|
var verbose = flag.Bool("verbose",
|
||||||
|
false,
|
||||||
|
"write data to stdout as it is parsed")
|
||||||
|
var localFiles = flag.Bool("local",
|
||||||
|
false,
|
||||||
|
"data files have been copied to the current directory; for debugging only")
|
||||||
|
|
||||||
|
var outputFile = flag.String("output",
|
||||||
|
"",
|
||||||
|
"output file for generated tables; default stdout")
|
||||||
|
|
||||||
|
var output *bufio.Writer
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
setupOutput()
|
||||||
|
|
||||||
|
graphemeTests := make([]test, 0)
|
||||||
|
graphemeTests = loadUnicodeData("GraphemeBreakTest.txt", graphemeTests)
|
||||||
|
wordTests := make([]test, 0)
|
||||||
|
wordTests = loadUnicodeData("WordBreakTest.txt", wordTests)
|
||||||
|
sentenceTests := make([]test, 0)
|
||||||
|
sentenceTests = loadUnicodeData("SentenceBreakTest.txt", sentenceTests)
|
||||||
|
|
||||||
|
fmt.Fprintf(output, fileHeader, *url)
|
||||||
|
generateTestTables("Grapheme", graphemeTests)
|
||||||
|
generateTestTables("Word", wordTests)
|
||||||
|
generateTestTables("Sentence", sentenceTests)
|
||||||
|
|
||||||
|
flushOutput()
|
||||||
|
}
|
||||||
|
|
||||||
|
// WordBreakProperty.txt has the form:
|
||||||
|
// 05F0..05F2 ; Hebrew_Letter # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
|
||||||
|
// FB1D ; Hebrew_Letter # Lo HEBREW LETTER YOD WITH HIRIQ
|
||||||
|
func openReader(file string) (input io.ReadCloser) {
|
||||||
|
if *localFiles {
|
||||||
|
f, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
input = f
|
||||||
|
} else {
|
||||||
|
path := *url + file
|
||||||
|
resp, err := http.Get(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
log.Fatal("bad GET status for "+file, resp.Status)
|
||||||
|
}
|
||||||
|
input = resp.Body
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadUnicodeData(filename string, tests []test) []test {
|
||||||
|
f := openReader(filename)
|
||||||
|
defer f.Close()
|
||||||
|
bufioReader := bufio.NewReader(f)
|
||||||
|
line, err := bufioReader.ReadString('\n')
|
||||||
|
for err == nil {
|
||||||
|
tests = parseLine(line, tests)
|
||||||
|
line, err = bufioReader.ReadString('\n')
|
||||||
|
}
|
||||||
|
// if the err was EOF still need to process last value
|
||||||
|
if err == io.EOF {
|
||||||
|
tests = parseLine(line, tests)
|
||||||
|
}
|
||||||
|
return tests
|
||||||
|
}
|
||||||
|
|
||||||
|
const comment = "#"
|
||||||
|
const brk = "÷"
|
||||||
|
const nbrk = "×"
|
||||||
|
|
||||||
|
type test [][]byte
|
||||||
|
|
||||||
|
func parseLine(line string, tests []test) []test {
|
||||||
|
if strings.HasPrefix(line, comment) {
|
||||||
|
return tests
|
||||||
|
}
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if len(line) == 0 {
|
||||||
|
return tests
|
||||||
|
}
|
||||||
|
commentStart := strings.Index(line, comment)
|
||||||
|
if commentStart > 0 {
|
||||||
|
line = line[0:commentStart]
|
||||||
|
}
|
||||||
|
pieces := strings.Split(line, brk)
|
||||||
|
t := make(test, 0)
|
||||||
|
for _, piece := range pieces {
|
||||||
|
piece = strings.TrimSpace(piece)
|
||||||
|
if len(piece) > 0 {
|
||||||
|
codePoints := strings.Split(piece, nbrk)
|
||||||
|
word := ""
|
||||||
|
for _, codePoint := range codePoints {
|
||||||
|
codePoint = strings.TrimSpace(codePoint)
|
||||||
|
r, err := strconv.ParseInt(codePoint, 16, 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("err: %v for '%s'", err, string(r))
|
||||||
|
return tests
|
||||||
|
}
|
||||||
|
|
||||||
|
word += string(r)
|
||||||
|
}
|
||||||
|
t = append(t, []byte(word))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tests = append(tests, t)
|
||||||
|
return tests
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTestTables(prefix string, tests []test) {
|
||||||
|
fmt.Fprintf(output, testHeader, prefix)
|
||||||
|
for _, t := range tests {
|
||||||
|
fmt.Fprintf(output, "\t\t{\n")
|
||||||
|
fmt.Fprintf(output, "\t\t\tinput: %#v,\n", bytes.Join(t, []byte{}))
|
||||||
|
fmt.Fprintf(output, "\t\t\toutput: %s,\n", generateTest(t))
|
||||||
|
fmt.Fprintf(output, "\t\t},\n")
|
||||||
|
}
|
||||||
|
fmt.Fprintf(output, "}\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTest(t test) string {
|
||||||
|
rv := "[][]byte{"
|
||||||
|
for _, te := range t {
|
||||||
|
rv += fmt.Sprintf("%#v,", te)
|
||||||
|
}
|
||||||
|
rv += "}"
|
||||||
|
return rv
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileHeader = `// Generated by running
|
||||||
|
// maketesttables --url=%s
|
||||||
|
// DO NOT EDIT
|
||||||
|
|
||||||
|
package textseg
|
||||||
|
`
|
||||||
|
|
||||||
|
const testHeader = `var unicode%sTests = []struct {
|
||||||
|
input []byte
|
||||||
|
output [][]byte
|
||||||
|
}{
|
||||||
|
`
|
||||||
|
|
||||||
|
func setupOutput() {
|
||||||
|
output = bufio.NewWriter(startGofmt())
|
||||||
|
}
|
||||||
|
|
||||||
|
// startGofmt connects output to a gofmt process if -output is set.
|
||||||
|
func startGofmt() io.Writer {
|
||||||
|
if *outputFile == "" {
|
||||||
|
return os.Stdout
|
||||||
|
}
|
||||||
|
stdout, err := os.Create(*outputFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
// Pipe output to gofmt.
|
||||||
|
gofmt := exec.Command("gofmt")
|
||||||
|
fd, err := gofmt.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
gofmt.Stdout = stdout
|
||||||
|
gofmt.Stderr = os.Stderr
|
||||||
|
err = gofmt.Start()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return fd
|
||||||
|
}
|
||||||
|
|
||||||
|
func flushOutput() {
|
||||||
|
err := output.Flush()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -82,7 +82,7 @@ def each_alpha( url, property )
|
||||||
open( url ) do |file|
|
open( url ) do |file|
|
||||||
file.each_line do |line|
|
file.each_line do |line|
|
||||||
next if line =~ /^#/;
|
next if line =~ /^#/;
|
||||||
next if line !~ /; #{property} #/;
|
next if line !~ /; #{property} *#/;
|
||||||
|
|
||||||
range, description = line.split(/;/)
|
range, description = line.split(/;/)
|
||||||
range.strip!
|
range.strip!
|
|
@ -0,0 +1,79 @@
|
||||||
|
# HCL Changelog
|
||||||
|
|
||||||
|
## v2.5.1 (May 14, 2020)
|
||||||
|
|
||||||
|
### Bugs Fixed
|
||||||
|
|
||||||
|
* hclwrite: handle legacy dot access of numeric indexes. ([#369](https://github.com/hashicorp/hcl/pull/369))
|
||||||
|
* hclwrite: Fix panic for dotted full splat (`foo.*`) ([#374](https://github.com/hashicorp/hcl/pull/374))
|
||||||
|
|
||||||
|
## v2.5.0 (May 6, 2020)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* hclwrite: Generate multi-line objects and maps. ([#372](https://github.com/hashicorp/hcl/pull/372))
|
||||||
|
|
||||||
|
## v2.4.0 (Apr 13, 2020)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* The Unicode data tables that HCL uses to produce user-perceived "column" positions in diagnostics and other source ranges are now updated to Unicode 12.0.0, which will cause HCL to produce more accurate column numbers for combining characters introduced to Unicode since Unicode 9.0.0.
|
||||||
|
|
||||||
|
### Bugs Fixed
|
||||||
|
|
||||||
|
* json: Fix panic when parsing malformed JSON. ([#358](https://github.com/hashicorp/hcl/pull/358))
|
||||||
|
|
||||||
|
## v2.3.0 (Jan 3, 2020)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* ext/tryfunc: Optional functions `try` and `can` to include in your `hcl.EvalContext` when evaluating expressions, which allow users to make decisions based on the success of expressions. ([#330](https://github.com/hashicorp/hcl/pull/330))
|
||||||
|
* ext/typeexpr: Now has an optional function `convert` which you can include in your `hcl.EvalContext` when evaluating expressions, allowing users to convert values to specific type constraints using the type constraint expression syntax. ([#330](https://github.com/hashicorp/hcl/pull/330))
|
||||||
|
* ext/typeexpr: A new `cty` capsule type `typeexpr.TypeConstraintType` which, when used as either a type constraint for a function parameter or as a type constraint for a `hcldec` attribute specification will cause the given expression to be interpreted as a type constraint expression rather than a value expression. ([#330](https://github.com/hashicorp/hcl/pull/330))
|
||||||
|
* ext/customdecode: An optional extension that allows overriding the static decoding behavior for expressions either in function arguments or `hcldec` attribute specifications. ([#330](https://github.com/hashicorp/hcl/pull/330))
|
||||||
|
* ext/customdecode: New `cty` capsuletypes `customdecode.ExpressionType` and `customdecode.ExpressionClosureType` which, when used as either a type constraint for a function parameter or as a type constraint for a `hcldec` attribute specification will cause the given expression (and, for the closure type, also the `hcl.EvalContext` it was evaluated in) to be captured for later analysis, rather than immediately evaluated. ([#330](https://github.com/hashicorp/hcl/pull/330))
|
||||||
|
|
||||||
|
## v2.2.0 (Dec 11, 2019)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* hcldec: Attribute evaluation (as part of `AttrSpec` or `BlockAttrsSpec`) now captures expression evaluation metadata in any errors it produces during type conversions, allowing for better feedback in calling applications that are able to make use of this metadata when printing diagnostic messages. ([#329](https://github.com/hashicorp/hcl/pull/329))
|
||||||
|
|
||||||
|
### Bugs Fixed
|
||||||
|
|
||||||
|
* hclsyntax: `IndexExpr`, `SplatExpr`, and `RelativeTraversalExpr` will now report a source range that covers all of their child expression nodes. Previously they would report only the operator part, such as `["foo"]`, `[*]`, or `.foo`, which was problematic for callers using source ranges for code analysis. ([#328](https://github.com/hashicorp/hcl/pull/328))
|
||||||
|
* hclwrite: Parser will no longer panic when the input includes index, splat, or relative traversal syntax. ([#328](https://github.com/hashicorp/hcl/pull/328))
|
||||||
|
|
||||||
|
## v2.1.0 (Nov 19, 2019)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* gohcl: When decoding into a struct value with some fields already populated, those values will be retained if not explicitly overwritten in the given HCL body, with similar overriding/merging behavior as `json.Unmarshal` in the Go standard library.
|
||||||
|
* hclwrite: New interface to set the expression for an attribute to be a raw token sequence, with no special processing. This has some caveats, so if you intend to use it please refer to the godoc comments. ([#320](https://github.com/hashicorp/hcl/pull/320))
|
||||||
|
|
||||||
|
### Bugs Fixed
|
||||||
|
|
||||||
|
* hclwrite: The `Body.Blocks` method was returing the blocks in an indefined order, rather than preserving the order of declaration in the source input. ([#313](https://github.com/hashicorp/hcl/pull/313))
|
||||||
|
* hclwrite: The `TokensForTraversal` function (and thus in turn the `Body.SetAttributeTraversal` method) was not correctly handling index steps in traversals, and thus producing invalid results. ([#319](https://github.com/hashicorp/hcl/pull/319))
|
||||||
|
|
||||||
|
## v2.0.0 (Oct 2, 2019)
|
||||||
|
|
||||||
|
Initial release of HCL 2, which is a new implementating combining the HCL 1
|
||||||
|
language with the HIL expression language to produce a single language
|
||||||
|
supporting both nested configuration structures and arbitrary expressions.
|
||||||
|
|
||||||
|
HCL 2 has an entirely new Go library API and so is _not_ a drop-in upgrade
|
||||||
|
relative to HCL 1. It's possible to import both versions of HCL into a single
|
||||||
|
program using Go's _semantic import versioning_ mechanism:
|
||||||
|
|
||||||
|
```
|
||||||
|
import (
|
||||||
|
hcl1 "github.com/hashicorp/hcl"
|
||||||
|
hcl2 "github.com/hashicorp/hcl/v2"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Prior to v2.0.0 there was not a curated changelog. Consult the git history
|
||||||
|
from the latest v1.x.x tag for information on the changes to HCL 1.
|
|
@ -0,0 +1,205 @@
|
||||||
|
# HCL
|
||||||
|
|
||||||
|
HCL is a toolkit for creating structured configuration languages that are
|
||||||
|
both human- and machine-friendly, for use with command-line tools.
|
||||||
|
Although intended to be generally useful, it is primarily targeted
|
||||||
|
towards devops tools, servers, etc.
|
||||||
|
|
||||||
|
> **NOTE:** This is major version 2 of HCL, whose Go API is incompatible with
|
||||||
|
> major version 1. Both versions are available for selection in Go Modules
|
||||||
|
> projects. HCL 2 _cannot_ be imported from Go projects that are not using Go Modules. For more information, see
|
||||||
|
> [our version selection guide](https://github.com/hashicorp/hcl/wiki/Version-Selection).
|
||||||
|
|
||||||
|
HCL has both a _native syntax_, intended to be pleasant to read and write for
|
||||||
|
humans, and a JSON-based variant that is easier for machines to generate
|
||||||
|
and parse.
|
||||||
|
|
||||||
|
The HCL native syntax is inspired by [libucl](https://github.com/vstakhov/libucl),
|
||||||
|
[nginx configuration](http://nginx.org/en/docs/beginners_guide.html#conf_structure),
|
||||||
|
and others.
|
||||||
|
|
||||||
|
It includes an expression syntax that allows basic inline computation and,
|
||||||
|
with support from the calling application, use of variables and functions
|
||||||
|
for more dynamic configuration languages.
|
||||||
|
|
||||||
|
HCL provides a set of constructs that can be used by a calling application to
|
||||||
|
construct a configuration language. The application defines which attribute
|
||||||
|
names and nested block types are expected, and HCL parses the configuration
|
||||||
|
file, verifies that it conforms to the expected structure, and returns
|
||||||
|
high-level objects that the application can use for further processing.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"github.com/hashicorp/hcl/v2/hclsimple"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
LogLevel string `hcl:"log_level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var config Config
|
||||||
|
err := hclsimple.DecodeFile("config.hcl", nil, &config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to load configuration: %s", err)
|
||||||
|
}
|
||||||
|
log.Printf("Configuration is %#v", config)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A lower-level API is available for applications that need more control over
|
||||||
|
the parsing, decoding, and evaluation of configuration. For more information,
|
||||||
|
see [the package documentation](https://pkg.go.dev/github.com/hashicorp/hcl/v2).
|
||||||
|
|
||||||
|
## Why?
|
||||||
|
|
||||||
|
Newcomers to HCL often ask: why not JSON, YAML, etc?
|
||||||
|
|
||||||
|
Whereas JSON and YAML are formats for serializing data structures, HCL is
|
||||||
|
a syntax and API specifically designed for building structured configuration
|
||||||
|
formats.
|
||||||
|
|
||||||
|
HCL attempts to strike a compromise between generic serialization formats
|
||||||
|
such as JSON and configuration formats built around full programming languages
|
||||||
|
such as Ruby. HCL syntax is designed to be easily read and written by humans,
|
||||||
|
and allows _declarative_ logic to permit its use in more complex applications.
|
||||||
|
|
||||||
|
HCL is intended as a base syntax for configuration formats built
|
||||||
|
around key-value pairs and hierarchical blocks whose structure is well-defined
|
||||||
|
by the calling application, and this definition of the configuration structure
|
||||||
|
allows for better error messages and more convenient definition within the
|
||||||
|
calling application.
|
||||||
|
|
||||||
|
It can't be denied that JSON is very convenient as a _lingua franca_
|
||||||
|
for interoperability between different pieces of software. Because of this,
|
||||||
|
HCL defines a common configuration model that can be parsed from either its
|
||||||
|
native syntax or from a well-defined equivalent JSON structure. This allows
|
||||||
|
configuration to be provided as a mixture of human-authored configuration
|
||||||
|
files in the native syntax and machine-generated files in JSON.
|
||||||
|
|
||||||
|
## Information Model and Syntax
|
||||||
|
|
||||||
|
HCL is built around two primary concepts: _attributes_ and _blocks_. In
|
||||||
|
native syntax, a configuration file for a hypothetical application might look
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
io_mode = "async"
|
||||||
|
|
||||||
|
service "http" "web_proxy" {
|
||||||
|
listen_addr = "127.0.0.1:8080"
|
||||||
|
|
||||||
|
process "main" {
|
||||||
|
command = ["/usr/local/bin/awesome-app", "server"]
|
||||||
|
}
|
||||||
|
|
||||||
|
process "mgmt" {
|
||||||
|
command = ["/usr/local/bin/awesome-app", "mgmt"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The JSON equivalent of this configuration is the following:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"io_mode": "async",
|
||||||
|
"service": {
|
||||||
|
"http": {
|
||||||
|
"web_proxy": {
|
||||||
|
"listen_addr": "127.0.0.1:8080",
|
||||||
|
"process": {
|
||||||
|
"main": {
|
||||||
|
"command": ["/usr/local/bin/awesome-app", "server"]
|
||||||
|
},
|
||||||
|
"mgmt": {
|
||||||
|
"command": ["/usr/local/bin/awesome-app", "mgmt"]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Regardless of which syntax is used, the API within the calling application
|
||||||
|
is the same. It can either work directly with the low-level attributes and
|
||||||
|
blocks, for more advanced use-cases, or it can use one of the _decoder_
|
||||||
|
packages to declaratively extract into either Go structs or dynamic value
|
||||||
|
structures.
|
||||||
|
|
||||||
|
Attribute values can be expressions as well as just literal values:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
# Arithmetic with literals and application-provided variables
|
||||||
|
sum = 1 + addend
|
||||||
|
|
||||||
|
# String interpolation and templates
|
||||||
|
message = "Hello, ${name}!"
|
||||||
|
|
||||||
|
# Application-provided functions
|
||||||
|
shouty_message = upper(message)
|
||||||
|
```
|
||||||
|
|
||||||
|
Although JSON syntax doesn't permit direct use of expressions, the interpolation
|
||||||
|
syntax allows use of arbitrary expressions within JSON strings:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"sum": "${1 + addend}",
|
||||||
|
"message": "Hello, ${name}!",
|
||||||
|
"shouty_message": "${upper(message)}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information, see the detailed specifications:
|
||||||
|
|
||||||
|
* [Syntax-agnostic Information Model](spec.md)
|
||||||
|
* [HCL Native Syntax](hclsyntax/spec.md)
|
||||||
|
* [JSON Representation](json/spec.md)
|
||||||
|
|
||||||
|
## Changes in 2.0
|
||||||
|
|
||||||
|
Version 2.0 of HCL combines the features of HCL 1.0 with those of the
|
||||||
|
interpolation language HIL to produce a single configuration language that
|
||||||
|
supports arbitrary expressions.
|
||||||
|
|
||||||
|
This new version has a completely new parser and Go API, with no direct
|
||||||
|
migration path. Although the syntax is similar, the implementation takes some
|
||||||
|
very different approaches to improve on some "rough edges" that existed with
|
||||||
|
the original implementation and to allow for more robust error handling.
|
||||||
|
|
||||||
|
It's possible to import both HCL 1 and HCL 2 into the same program using Go's
|
||||||
|
_semantic import versioning_ mechanism:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
hcl1 "github.com/hashicorp/hcl"
|
||||||
|
hcl2 "github.com/hashicorp/hcl/v2"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
HCL was heavily inspired by [libucl](https://github.com/vstakhov/libucl),
|
||||||
|
by [Vsevolod Stakhov](https://github.com/vstakhov).
|
||||||
|
|
||||||
|
HCL and HIL originate in [HashiCorp Terraform](https://terraform.io/),
|
||||||
|
with the original parsers for each written by
|
||||||
|
[Mitchell Hashimoto](https://github.com/mitchellh).
|
||||||
|
|
||||||
|
The original HCL parser was ported to pure Go (from yacc) by
|
||||||
|
[Fatih Arslan](https://github.com/fatih). The structure-related portions of
|
||||||
|
the new native syntax parser build on that work.
|
||||||
|
|
||||||
|
The original HIL parser was ported to pure Go (from yacc) by
|
||||||
|
[Martin Atkins](https://github.com/apparentlymart). The expression-related
|
||||||
|
portions of the new native syntax parser build on that work.
|
||||||
|
|
||||||
|
HCL 2, which merged the original HCL and HIL languages into this single new
|
||||||
|
language, builds on design and prototyping work by
|
||||||
|
[Martin Atkins](https://github.com/apparentlymart) in
|
||||||
|
[zcl](https://github.com/zclconf/go-zcl).
|
|
@ -0,0 +1,13 @@
|
||||||
|
build: off
|
||||||
|
|
||||||
|
clone_folder: c:\gopath\src\github.com\hashicorp\hcl
|
||||||
|
|
||||||
|
environment:
|
||||||
|
GOPATH: c:\gopath
|
||||||
|
GO111MODULE: on
|
||||||
|
GOPROXY: https://goproxy.io
|
||||||
|
|
||||||
|
stack: go 1.12
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- go test ./...
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Package hcl contains the main modelling types and general utility functions
|
||||||
|
// for HCL.
|
||||||
|
//
|
||||||
|
// For a simple entry point into HCL, see the package in the subdirectory
|
||||||
|
// "hclsimple", which has an opinionated function Decode that can decode HCL
|
||||||
|
// configurations in either native HCL syntax or JSON syntax into a Go struct
|
||||||
|
// type:
|
||||||
|
//
|
||||||
|
// package main
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "log"
|
||||||
|
// "github.com/hashicorp/hcl/v2/hclsimple"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// type Config struct {
|
||||||
|
// LogLevel string `hcl:"log_level"`
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func main() {
|
||||||
|
// var config Config
|
||||||
|
// err := hclsimple.DecodeFile("config.hcl", nil, &config)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatalf("Failed to load configuration: %s", err)
|
||||||
|
// }
|
||||||
|
// log.Printf("Configuration is %#v", config)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// If your application needs more control over the evaluation of the
|
||||||
|
// configuration, you can use the functions in the subdirectories hclparse,
|
||||||
|
// gohcl, hcldec, etc. Splitting the handling of configuration into multiple
|
||||||
|
// phases allows for advanced patterns such as allowing expressions in one
|
||||||
|
// part of the configuration to refer to data defined in another part.
|
||||||
|
package hcl
|
|
@ -0,0 +1,209 @@
|
||||||
|
# HCL Custom Static Decoding Extension
|
||||||
|
|
||||||
|
This HCL extension provides a mechanism for defining arguments in an HCL-based
|
||||||
|
language whose values are derived using custom decoding rules against the
|
||||||
|
HCL expression syntax, overriding the usual behavior of normal expression
|
||||||
|
evaluation.
|
||||||
|
|
||||||
|
"Arguments", for the purpose of this extension, currently includes the
|
||||||
|
following two contexts:
|
||||||
|
|
||||||
|
* For applications using `hcldec` for dynamic decoding, a `hcldec.AttrSpec`
|
||||||
|
or `hcldec.BlockAttrsSpec` can be given a special type constraint that
|
||||||
|
opts in to custom decoding behavior for the attribute(s) that are selected
|
||||||
|
by that specification.
|
||||||
|
|
||||||
|
* When working with the HCL native expression syntax, a function given in
|
||||||
|
the `hcl.EvalContext` during evaluation can have parameters with special
|
||||||
|
type constraints that opt in to custom decoding behavior for the argument
|
||||||
|
expression associated with that parameter in any call.
|
||||||
|
|
||||||
|
The above use-cases are rather abstract, so we'll consider a motivating
|
||||||
|
real-world example: sometimes we (language designers) need to allow users
|
||||||
|
to specify type constraints directly in the language itself, such as in
|
||||||
|
[Terraform's Input Variables](https://www.terraform.io/docs/configuration/variables.html).
|
||||||
|
Terraform's `variable` blocks include an argument called `type` which takes
|
||||||
|
a type constraint given using HCL expression building-blocks as defined by
|
||||||
|
[the HCL `typeexpr` extension](../typeexpr/README.md).
|
||||||
|
|
||||||
|
A "type constraint expression" of that sort is not an expression intended to
|
||||||
|
be evaluated in the usual way. Instead, the physical expression is
|
||||||
|
deconstructed using [the static analysis operations](../../spec.md#static-analysis)
|
||||||
|
to produce a `cty.Type` as the result, rather than a `cty.Value`.
|
||||||
|
|
||||||
|
The purpose of this Custom Static Decoding Extension, then, is to provide a
|
||||||
|
bridge to allow that sort of custom decoding to be used via mechanisms that
|
||||||
|
normally deal in `cty.Value`, such as `hcldec` and native syntax function
|
||||||
|
calls as listed above.
|
||||||
|
|
||||||
|
(Note: [`gohcl`](https://pkg.go.dev/github.com/hashicorp/hcl/v2/gohcl) has
|
||||||
|
its own mechanism to support this use case, exploiting the fact that it is
|
||||||
|
working directly with "normal" Go types. Decoding into a struct field of
|
||||||
|
type `hcl.Expression` obtains the expression directly without evaluating it
|
||||||
|
first. The Custom Static Decoding Extension is not necessary for that `gohcl`
|
||||||
|
technique. You can also implement custom decoding by working directly with
|
||||||
|
the lowest-level HCL API, which separates extraction of and evaluation of
|
||||||
|
expressions into two steps.)
|
||||||
|
|
||||||
|
## Custom Decoding Types
|
||||||
|
|
||||||
|
This extension relies on a convention implemented in terms of
|
||||||
|
[_Capsule Types_ in the underlying `cty` type system](https://github.com/zclconf/go-cty/blob/master/docs/types.md#capsule-types). `cty` allows a capsule type to carry arbitrary
|
||||||
|
extension metadata values as an aid to creating higher-level abstractions like
|
||||||
|
this extension.
|
||||||
|
|
||||||
|
A custom argument decoding mode, then, is implemented by creating a new `cty`
|
||||||
|
capsule type that implements the `ExtensionData` custom operation to return
|
||||||
|
a decoding function when requested. For example:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var keywordType cty.Type
|
||||||
|
keywordType = cty.CapsuleWithOps("keyword", reflect.TypeOf(""), &cty.CapsuleOps{
|
||||||
|
ExtensionData: func(key interface{}) interface{} {
|
||||||
|
switch key {
|
||||||
|
case customdecode.CustomExpressionDecoder:
|
||||||
|
return customdecode.CustomExpressionDecoderFunc(
|
||||||
|
func(expr hcl.Expression, ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
||||||
|
var diags hcl.Diagnostics
|
||||||
|
kw := hcl.ExprAsKeyword(expr)
|
||||||
|
if kw == "" {
|
||||||
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
|
Severity: hcl.DiagError,
|
||||||
|
Summary: "Invalid keyword",
|
||||||
|
Detail: "A keyword is required",
|
||||||
|
Subject: expr.Range().Ptr(),
|
||||||
|
})
|
||||||
|
return cty.UnkownVal(keywordType), diags
|
||||||
|
}
|
||||||
|
return cty.CapsuleVal(keywordType, &kw)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
The boilerplate here is a bit fussy, but the important part for our purposes
|
||||||
|
is the `case customdecode.CustomExpressionDecoder:` clause, which uses
|
||||||
|
a custom extension key type defined in this package to recognize when a
|
||||||
|
component implementing this extension is checking to see if a target type
|
||||||
|
has a custom decode implementation.
|
||||||
|
|
||||||
|
In the above case we've defined a type that decodes expressions as static
|
||||||
|
keywords, so a keyword like `foo` would decode as an encapsulated `"foo"`
|
||||||
|
string, while any other sort of expression like `"baz"` or `1 + 1` would
|
||||||
|
return an error.
|
||||||
|
|
||||||
|
We could then use `keywordType` as a type constraint either for a function
|
||||||
|
parameter or a `hcldec` attribute specification, which would require the
|
||||||
|
argument for that function parameter or the expression for the matching
|
||||||
|
attributes to be a static keyword, rather than an arbitrary expression.
|
||||||
|
For example, in a `hcldec.AttrSpec`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
keywordSpec := &hcldec.AttrSpec{
|
||||||
|
Name: "keyword",
|
||||||
|
Type: keywordType,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The above would accept input like the following and would set its result to
|
||||||
|
a `cty.Value` of `keywordType`, after decoding:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
keyword = foo
|
||||||
|
```
|
||||||
|
|
||||||
|
## The Expression and Expression Closure `cty` types
|
||||||
|
|
||||||
|
Building on the above, this package also includes two capsule types that use
|
||||||
|
the above mechanism to allow calling applications to capture expressions
|
||||||
|
directly and thus defer analysis to a later step, after initial decoding.
|
||||||
|
|
||||||
|
The `customdecode.ExpressionType` type encapsulates an `hcl.Expression` alone,
|
||||||
|
for situations like our type constraint expression example above where it's
|
||||||
|
the static structure of the expression we want to inspect, and thus any
|
||||||
|
variables and functions defined in the evaluation context are irrelevant.
|
||||||
|
|
||||||
|
The `customdecode.ExpressionClosureType` type encapsulates a
|
||||||
|
`*customdecode.ExpressionClosure` value, which binds the given expression to
|
||||||
|
the `hcl.EvalContext` it was asked to evaluate against and thus allows the
|
||||||
|
receiver of that result to later perform normal evaluation of the expression
|
||||||
|
with all the same variables and functions that would've been available to it
|
||||||
|
naturally.
|
||||||
|
|
||||||
|
Both of these types can be used as type constraints either for `hcldec`
|
||||||
|
attribute specifications or for function arguments. Here's an example of
|
||||||
|
`ExpressionClosureType` to implement a function that can evaluate
|
||||||
|
an expression with some additional variables defined locally, which we'll
|
||||||
|
call the `with(...)` function:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var WithFunc = function.New(&function.Spec{
|
||||||
|
Params: []function.Parameter{
|
||||||
|
{
|
||||||
|
Name: "variables",
|
||||||
|
Type: cty.DynamicPseudoType,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "expression",
|
||||||
|
Type: customdecode.ExpressionClosureType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Type: func(args []cty.Value) (cty.Type, error) {
|
||||||
|
varsVal := args[0]
|
||||||
|
exprVal := args[1]
|
||||||
|
if !varsVal.Type().IsObjectType() {
|
||||||
|
return cty.NilVal, function.NewArgErrorf(0, "must be an object defining local variables")
|
||||||
|
}
|
||||||
|
if !varsVal.IsKnown() {
|
||||||
|
// We can't predict our result type until the variables object
|
||||||
|
// is known.
|
||||||
|
return cty.DynamicPseudoType, nil
|
||||||
|
}
|
||||||
|
vars := varsVal.AsValueMap()
|
||||||
|
closure := customdecode.ExpressionClosureFromVal(exprVal)
|
||||||
|
result, err := evalWithLocals(vars, closure)
|
||||||
|
if err != nil {
|
||||||
|
return cty.NilVal, err
|
||||||
|
}
|
||||||
|
return result.Type(), nil
|
||||||
|
},
|
||||||
|
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||||
|
varsVal := args[0]
|
||||||
|
exprVal := args[1]
|
||||||
|
vars := varsVal.AsValueMap()
|
||||||
|
closure := customdecode.ExpressionClosureFromVal(exprVal)
|
||||||
|
return evalWithLocals(vars, closure)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
func evalWithLocals(locals map[string]cty.Value, closure *customdecode.ExpressionClosure) (cty.Value, error) {
|
||||||
|
childCtx := closure.EvalContext.NewChild()
|
||||||
|
childCtx.Variables = locals
|
||||||
|
val, diags := closure.Expression.Value(childCtx)
|
||||||
|
if diags.HasErrors() {
|
||||||
|
return cty.NilVal, function.NewArgErrorf(1, "couldn't evaluate expression: %s", diags.Error())
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the above function were placed into an `hcl.EvalContext` as `with`, it
|
||||||
|
could be used in a native syntax call to that function as follows:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
foo = with({name = "Cory"}, "${greeting}, ${name}!")
|
||||||
|
```
|
||||||
|
|
||||||
|
The above assumes a variable in the main context called `greeting`, to which
|
||||||
|
the `with` function adds `name` before evaluating the expression given in
|
||||||
|
its second argument. This makes that second argument context-sensitive -- it
|
||||||
|
would behave differently if the user wrote the same thing somewhere else -- so
|
||||||
|
this capability should be used with care to make sure it doesn't cause confusion
|
||||||
|
for the end-users of your language.
|
||||||
|
|
||||||
|
There are some other examples of this capability to evaluate expressions in
|
||||||
|
unusual ways in the `tryfunc` directory that is a sibling of this one.
|
56
vendor/github.com/hashicorp/hcl/v2/ext/customdecode/customdecode.go
generated
vendored
Normal file
56
vendor/github.com/hashicorp/hcl/v2/ext/customdecode/customdecode.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Package customdecode contains a HCL extension that allows, in certain
|
||||||
|
// contexts, expression evaluation to be overridden by custom static analysis.
|
||||||
|
//
|
||||||
|
// This mechanism is only supported in certain specific contexts where
|
||||||
|
// expressions are decoded with a specific target type in mind. For more
|
||||||
|
// information, see the documentation on CustomExpressionDecoder.
|
||||||
|
package customdecode
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
type customDecoderImpl int
|
||||||
|
|
||||||
|
// CustomExpressionDecoder is a value intended to be used as a cty capsule
|
||||||
|
// type ExtensionData key for capsule types whose values are to be obtained
|
||||||
|
// by static analysis of an expression rather than normal evaluation of that
|
||||||
|
// expression.
|
||||||
|
//
|
||||||
|
// When a cooperating capsule type is asked for ExtensionData with this key,
|
||||||
|
// it must return a non-nil CustomExpressionDecoderFunc value.
|
||||||
|
//
|
||||||
|
// This mechanism is not universally supported; instead, it's handled in a few
|
||||||
|
// specific places where expressions are evaluated with the intent of producing
|
||||||
|
// a cty.Value of a type given by the calling application.
|
||||||
|
//
|
||||||
|
// Specifically, this currently works for type constraints given in
|
||||||
|
// hcldec.AttrSpec and hcldec.BlockAttrsSpec, and it works for arguments to
|
||||||
|
// function calls in the HCL native syntax. HCL extensions implemented outside
|
||||||
|
// of the main HCL module may also implement this; consult their own
|
||||||
|
// documentation for details.
|
||||||
|
const CustomExpressionDecoder = customDecoderImpl(1)
|
||||||
|
|
||||||
|
// CustomExpressionDecoderFunc is the type of value that must be returned by
|
||||||
|
// a capsule type handling the key CustomExpressionDecoder in its ExtensionData
|
||||||
|
// implementation.
|
||||||
|
//
|
||||||
|
// If no error diagnostics are returned, the result value MUST be of the
|
||||||
|
// capsule type that the decoder function was derived from. If the returned
|
||||||
|
// error diagnostics prevent producing a value at all, return cty.NilVal.
|
||||||
|
type CustomExpressionDecoderFunc func(expr hcl.Expression, ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics)
|
||||||
|
|
||||||
|
// CustomExpressionDecoderForType takes any cty type and returns its
|
||||||
|
// custom expression decoder implementation if it has one. If it is not a
|
||||||
|
// capsule type or it does not implement a custom expression decoder, this
|
||||||
|
// function returns nil.
|
||||||
|
func CustomExpressionDecoderForType(ty cty.Type) CustomExpressionDecoderFunc {
|
||||||
|
if !ty.IsCapsuleType() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if fn, ok := ty.CapsuleExtensionData(CustomExpressionDecoder).(CustomExpressionDecoderFunc); ok {
|
||||||
|
return fn
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
146
vendor/github.com/hashicorp/hcl/v2/ext/customdecode/expression_type.go
generated
vendored
Normal file
146
vendor/github.com/hashicorp/hcl/v2/ext/customdecode/expression_type.go
generated
vendored
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
package customdecode
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExpressionType is a cty capsule type that carries hcl.Expression values.
|
||||||
|
//
|
||||||
|
// This type implements custom decoding in the most general way possible: it
|
||||||
|
// just captures whatever expression is given to it, with no further processing
|
||||||
|
// whatsoever. It could therefore be useful in situations where an application
|
||||||
|
// must defer processing of the expression content until a later step.
|
||||||
|
//
|
||||||
|
// ExpressionType only captures the expression, not the evaluation context it
|
||||||
|
// was destined to be evaluated in. That means this type can be fine for
|
||||||
|
// situations where the recipient of the value only intends to do static
|
||||||
|
// analysis, but ExpressionClosureType is more appropriate in situations where
|
||||||
|
// the recipient will eventually evaluate the given expression.
|
||||||
|
var ExpressionType cty.Type
|
||||||
|
|
||||||
|
// ExpressionVal returns a new cty value of type ExpressionType, wrapping the
|
||||||
|
// given expression.
|
||||||
|
func ExpressionVal(expr hcl.Expression) cty.Value {
|
||||||
|
return cty.CapsuleVal(ExpressionType, &expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpressionFromVal returns the expression encapsulated in the given value, or
|
||||||
|
// panics if the value is not a known value of ExpressionType.
|
||||||
|
func ExpressionFromVal(v cty.Value) hcl.Expression {
|
||||||
|
if !v.Type().Equals(ExpressionType) {
|
||||||
|
panic("value is not of ExpressionType")
|
||||||
|
}
|
||||||
|
ptr := v.EncapsulatedValue().(*hcl.Expression)
|
||||||
|
return *ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpressionClosureType is a cty capsule type that carries hcl.Expression
|
||||||
|
// values along with their original evaluation contexts.
|
||||||
|
//
|
||||||
|
// This is similar to ExpressionType except that during custom decoding it
|
||||||
|
// also captures the hcl.EvalContext that was provided, allowing callers to
|
||||||
|
// evaluate the expression later in the same context where it would originally
|
||||||
|
// have been evaluated, or a context derived from that one.
|
||||||
|
var ExpressionClosureType cty.Type
|
||||||
|
|
||||||
|
// ExpressionClosure is the type encapsulated in ExpressionClosureType
|
||||||
|
type ExpressionClosure struct {
|
||||||
|
Expression hcl.Expression
|
||||||
|
EvalContext *hcl.EvalContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpressionClosureVal returns a new cty value of type ExpressionClosureType,
|
||||||
|
// wrapping the given expression closure.
|
||||||
|
func ExpressionClosureVal(closure *ExpressionClosure) cty.Value {
|
||||||
|
return cty.CapsuleVal(ExpressionClosureType, closure)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value evaluates the closure's expression using the closure's EvalContext,
|
||||||
|
// returning the result.
|
||||||
|
func (c *ExpressionClosure) Value() (cty.Value, hcl.Diagnostics) {
|
||||||
|
return c.Expression.Value(c.EvalContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpressionClosureFromVal returns the expression closure encapsulated in the
|
||||||
|
// given value, or panics if the value is not a known value of
|
||||||
|
// ExpressionClosureType.
|
||||||
|
//
|
||||||
|
// The caller MUST NOT modify the returned closure or the EvalContext inside
|
||||||
|
// it. To derive a new EvalContext, either create a child context or make
|
||||||
|
// a copy.
|
||||||
|
func ExpressionClosureFromVal(v cty.Value) *ExpressionClosure {
|
||||||
|
if !v.Type().Equals(ExpressionClosureType) {
|
||||||
|
panic("value is not of ExpressionClosureType")
|
||||||
|
}
|
||||||
|
return v.EncapsulatedValue().(*ExpressionClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Getting hold of a reflect.Type for hcl.Expression is a bit tricky because
|
||||||
|
// it's an interface type, but we can do it with some indirection.
|
||||||
|
goExpressionType := reflect.TypeOf((*hcl.Expression)(nil)).Elem()
|
||||||
|
|
||||||
|
ExpressionType = cty.CapsuleWithOps("expression", goExpressionType, &cty.CapsuleOps{
|
||||||
|
ExtensionData: func(key interface{}) interface{} {
|
||||||
|
switch key {
|
||||||
|
case CustomExpressionDecoder:
|
||||||
|
return CustomExpressionDecoderFunc(
|
||||||
|
func(expr hcl.Expression, ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
||||||
|
return ExpressionVal(expr), nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TypeGoString: func(_ reflect.Type) string {
|
||||||
|
return "customdecode.ExpressionType"
|
||||||
|
},
|
||||||
|
GoString: func(raw interface{}) string {
|
||||||
|
exprPtr := raw.(*hcl.Expression)
|
||||||
|
return fmt.Sprintf("customdecode.ExpressionVal(%#v)", *exprPtr)
|
||||||
|
},
|
||||||
|
RawEquals: func(a, b interface{}) bool {
|
||||||
|
aPtr := a.(*hcl.Expression)
|
||||||
|
bPtr := b.(*hcl.Expression)
|
||||||
|
return reflect.DeepEqual(*aPtr, *bPtr)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
ExpressionClosureType = cty.CapsuleWithOps("expression closure", reflect.TypeOf(ExpressionClosure{}), &cty.CapsuleOps{
|
||||||
|
ExtensionData: func(key interface{}) interface{} {
|
||||||
|
switch key {
|
||||||
|
case CustomExpressionDecoder:
|
||||||
|
return CustomExpressionDecoderFunc(
|
||||||
|
func(expr hcl.Expression, ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
||||||
|
return ExpressionClosureVal(&ExpressionClosure{
|
||||||
|
Expression: expr,
|
||||||
|
EvalContext: ctx,
|
||||||
|
}), nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TypeGoString: func(_ reflect.Type) string {
|
||||||
|
return "customdecode.ExpressionClosureType"
|
||||||
|
},
|
||||||
|
GoString: func(raw interface{}) string {
|
||||||
|
closure := raw.(*ExpressionClosure)
|
||||||
|
return fmt.Sprintf("customdecode.ExpressionClosureVal(%#v)", closure)
|
||||||
|
},
|
||||||
|
RawEquals: func(a, b interface{}) bool {
|
||||||
|
closureA := a.(*ExpressionClosure)
|
||||||
|
closureB := b.(*ExpressionClosure)
|
||||||
|
// The expression itself compares by deep equality, but EvalContexts
|
||||||
|
// conventionally compare by pointer identity, so we'll comply
|
||||||
|
// with both conventions here by testing them separately.
|
||||||
|
return closureA.EvalContext == closureB.EvalContext &&
|
||||||
|
reflect.DeepEqual(closureA.Expression, closureB.Expression)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
module github.com/hashicorp/hcl/v2
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/agext/levenshtein v1.2.1
|
||||||
|
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3
|
||||||
|
github.com/apparentlymart/go-textseg/v12 v12.0.0
|
||||||
|
github.com/davecgh/go-spew v1.1.1
|
||||||
|
github.com/go-test/deep v1.0.3
|
||||||
|
github.com/google/go-cmp v0.3.1
|
||||||
|
github.com/kr/pretty v0.1.0
|
||||||
|
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348
|
||||||
|
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/sergi/go-diff v1.0.0
|
||||||
|
github.com/spf13/pflag v1.0.2
|
||||||
|
github.com/stretchr/testify v1.2.2 // indirect
|
||||||
|
github.com/zclconf/go-cty v1.2.0
|
||||||
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
|
||||||
|
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 // indirect
|
||||||
|
golang.org/x/text v0.3.2 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,53 @@
|
||||||
|
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
|
||||||
|
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||||
|
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA=
|
||||||
|
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
|
||||||
|
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
|
||||||
|
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
||||||
|
github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbjdL7GzRt3F8NvfJ0=
|
||||||
|
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||||
|
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
|
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||||
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
|
||||||
|
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||||
|
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
|
||||||
|
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/spf13/pflag v1.0.2 h1:Fy0orTDgHdbnzHcsOgfCN4LtHf0ec3wwtiwJqwvf3Gc=
|
||||||
|
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||||
|
github.com/zclconf/go-cty v1.2.0 h1:sPHsy7ADcIZQP3vILvTjrh74ZA175TFP5vqiNK1UmlI=
|
||||||
|
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
|
||||||
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82 h1:vsphBvatvfbhlb4PO1BYSr9dzugGxJ/SQHoNufZJq1w=
|
||||||
|
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
"github.com/zclconf/go-cty/cty/gocty"
|
"github.com/zclconf/go-cty/cty/gocty"
|
||||||
)
|
)
|
||||||
|
@ -147,7 +147,9 @@ func decodeBodyToStruct(body hcl.Body, ctx *hcl.EvalContext, val reflect.Value)
|
||||||
|
|
||||||
if len(blocks) == 0 {
|
if len(blocks) == 0 {
|
||||||
if isSlice || isPtr {
|
if isSlice || isPtr {
|
||||||
val.Field(fieldIdx).Set(reflect.Zero(field.Type))
|
if val.Field(fieldIdx).IsNil() {
|
||||||
|
val.Field(fieldIdx).Set(reflect.Zero(field.Type))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
|
@ -166,11 +168,20 @@ func decodeBodyToStruct(body hcl.Body, ctx *hcl.EvalContext, val reflect.Value)
|
||||||
if isPtr {
|
if isPtr {
|
||||||
elemType = reflect.PtrTo(ty)
|
elemType = reflect.PtrTo(ty)
|
||||||
}
|
}
|
||||||
sli := reflect.MakeSlice(reflect.SliceOf(elemType), len(blocks), len(blocks))
|
sli := val.Field(fieldIdx)
|
||||||
|
if sli.IsNil() {
|
||||||
|
sli = reflect.MakeSlice(reflect.SliceOf(elemType), len(blocks), len(blocks))
|
||||||
|
}
|
||||||
|
|
||||||
for i, block := range blocks {
|
for i, block := range blocks {
|
||||||
if isPtr {
|
if isPtr {
|
||||||
v := reflect.New(ty)
|
if i >= sli.Len() {
|
||||||
|
sli = reflect.Append(sli, reflect.New(ty))
|
||||||
|
}
|
||||||
|
v := sli.Index(i)
|
||||||
|
if v.IsNil() {
|
||||||
|
v = reflect.New(ty)
|
||||||
|
}
|
||||||
diags = append(diags, decodeBlockToValue(block, ctx, v.Elem())...)
|
diags = append(diags, decodeBlockToValue(block, ctx, v.Elem())...)
|
||||||
sli.Index(i).Set(v)
|
sli.Index(i).Set(v)
|
||||||
} else {
|
} else {
|
||||||
|
@ -178,12 +189,19 @@ func decodeBodyToStruct(body hcl.Body, ctx *hcl.EvalContext, val reflect.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sli.Len() > len(blocks) {
|
||||||
|
sli.SetLen(len(blocks))
|
||||||
|
}
|
||||||
|
|
||||||
val.Field(fieldIdx).Set(sli)
|
val.Field(fieldIdx).Set(sli)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
block := blocks[0]
|
block := blocks[0]
|
||||||
if isPtr {
|
if isPtr {
|
||||||
v := reflect.New(ty)
|
v := val.Field(fieldIdx)
|
||||||
|
if v.IsNil() {
|
||||||
|
v = reflect.New(ty)
|
||||||
|
}
|
||||||
diags = append(diags, decodeBlockToValue(block, ctx, v.Elem())...)
|
diags = append(diags, decodeBlockToValue(block, ctx, v.Elem())...)
|
||||||
val.Field(fieldIdx).Set(v)
|
val.Field(fieldIdx).Set(v)
|
||||||
} else {
|
} else {
|
|
@ -17,6 +17,7 @@
|
||||||
// attr (the default) indicates that the value is to be populated from an attribute
|
// attr (the default) indicates that the value is to be populated from an attribute
|
||||||
// block indicates that the value is to populated from a block
|
// block indicates that the value is to populated from a block
|
||||||
// label indicates that the value is to populated from a block label
|
// label indicates that the value is to populated from a block label
|
||||||
|
// optional is the same as attr, but the field is optional
|
||||||
// remain indicates that the value is to be populated from the remaining body after populating other fields
|
// remain indicates that the value is to be populated from the remaining body after populating other fields
|
||||||
//
|
//
|
||||||
// "attr" fields may either be of type *hcl.Expression, in which case the raw
|
// "attr" fields may either be of type *hcl.Expression, in which case the raw
|
||||||
|
@ -34,6 +35,9 @@
|
||||||
// the blocks being decoded. In this case, the name token is used only as
|
// the blocks being decoded. In this case, the name token is used only as
|
||||||
// an identifier for the label in diagnostic messages.
|
// an identifier for the label in diagnostic messages.
|
||||||
//
|
//
|
||||||
|
// "optional" fields behave like "attr" fields, but they are optional
|
||||||
|
// and will not give parsing errors if they are missing.
|
||||||
|
//
|
||||||
// "remain" can be placed on a single field that may be either of type
|
// "remain" can be placed on a single field that may be either of type
|
||||||
// hcl.Body or hcl.Attributes, in which case any remaining body content is
|
// hcl.Body or hcl.Attributes, in which case any remaining body content is
|
||||||
// placed into this field for delayed processing. If no "remain" field is
|
// placed into this field for delayed processing. If no "remain" field is
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hclwrite"
|
"github.com/hashicorp/hcl/v2/hclwrite"
|
||||||
"github.com/zclconf/go-cty/cty/gocty"
|
"github.com/zclconf/go-cty/cty/gocty"
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImpliedBodySchema produces a hcl.BodySchema derived from the type of the
|
// ImpliedBodySchema produces a hcl.BodySchema derived from the type of the
|
|
@ -3,7 +3,7 @@ package gohcl
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var victimExpr hcl.Expression
|
var victimExpr hcl.Expression
|
|
@ -1,7 +1,7 @@
|
||||||
package hcldec
|
package hcldec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type blockLabel struct {
|
type blockLabel struct {
|
|
@ -1,7 +1,7 @@
|
||||||
package hcldec
|
package hcldec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package hcldec
|
package hcldec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package hcldec
|
package hcldec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ImpliedSchema returns the *hcl.BodySchema implied by the given specification.
|
// ImpliedSchema returns the *hcl.BodySchema implied by the given specification.
|
|
@ -5,7 +5,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/hashicorp/hcl/v2/ext/customdecode"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
"github.com/zclconf/go-cty/cty/function"
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
|
@ -193,6 +194,14 @@ func (s *AttrSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel, ct
|
||||||
return cty.NullVal(s.Type), nil
|
return cty.NullVal(s.Type), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if decodeFn := customdecode.CustomExpressionDecoderForType(s.Type); decodeFn != nil {
|
||||||
|
v, diags := decodeFn(attr.Expr, ctx)
|
||||||
|
if v == cty.NilVal {
|
||||||
|
v = cty.UnknownVal(s.Type)
|
||||||
|
}
|
||||||
|
return v, diags
|
||||||
|
}
|
||||||
|
|
||||||
val, diags := attr.Expr.Value(ctx)
|
val, diags := attr.Expr.Value(ctx)
|
||||||
|
|
||||||
convVal, err := convert.Convert(val, s.Type)
|
convVal, err := convert.Convert(val, s.Type)
|
||||||
|
@ -204,8 +213,10 @@ func (s *AttrSpec) decode(content *hcl.BodyContent, blockLabels []blockLabel, ct
|
||||||
"Inappropriate value for attribute %q: %s.",
|
"Inappropriate value for attribute %q: %s.",
|
||||||
s.Name, err.Error(),
|
s.Name, err.Error(),
|
||||||
),
|
),
|
||||||
Subject: attr.Expr.StartRange().Ptr(),
|
Subject: attr.Expr.Range().Ptr(),
|
||||||
Context: hcl.RangeBetween(attr.NameRange, attr.Expr.StartRange()).Ptr(),
|
Context: hcl.RangeBetween(attr.NameRange, attr.Expr.Range()).Ptr(),
|
||||||
|
Expression: attr.Expr,
|
||||||
|
EvalContext: ctx,
|
||||||
})
|
})
|
||||||
// We'll return an unknown value of the _correct_ type so that the
|
// We'll return an unknown value of the _correct_ type so that the
|
||||||
// incomplete result can still be used for some analysis use-cases.
|
// incomplete result can still be used for some analysis use-cases.
|
||||||
|
@ -1221,16 +1232,29 @@ func (s *BlockAttrsSpec) decode(content *hcl.BodyContent, blockLabels []blockLab
|
||||||
|
|
||||||
vals := make(map[string]cty.Value, len(attrs))
|
vals := make(map[string]cty.Value, len(attrs))
|
||||||
for name, attr := range attrs {
|
for name, attr := range attrs {
|
||||||
|
if decodeFn := customdecode.CustomExpressionDecoderForType(s.ElementType); decodeFn != nil {
|
||||||
|
attrVal, attrDiags := decodeFn(attr.Expr, ctx)
|
||||||
|
diags = append(diags, attrDiags...)
|
||||||
|
if attrVal == cty.NilVal {
|
||||||
|
attrVal = cty.UnknownVal(s.ElementType)
|
||||||
|
}
|
||||||
|
vals[name] = attrVal
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
attrVal, attrDiags := attr.Expr.Value(ctx)
|
attrVal, attrDiags := attr.Expr.Value(ctx)
|
||||||
diags = append(diags, attrDiags...)
|
diags = append(diags, attrDiags...)
|
||||||
|
|
||||||
attrVal, err := convert.Convert(attrVal, s.ElementType)
|
attrVal, err := convert.Convert(attrVal, s.ElementType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Invalid attribute value",
|
Summary: "Invalid attribute value",
|
||||||
Detail: fmt.Sprintf("Invalid value for attribute of %q block: %s.", s.TypeName, err),
|
Detail: fmt.Sprintf("Invalid value for attribute of %q block: %s.", s.TypeName, err),
|
||||||
Subject: attr.Expr.Range().Ptr(),
|
Subject: attr.Expr.Range().Ptr(),
|
||||||
|
Context: hcl.RangeBetween(attr.NameRange, attr.Expr.Range()).Ptr(),
|
||||||
|
Expression: attr.Expr,
|
||||||
|
EvalContext: ctx,
|
||||||
})
|
})
|
||||||
attrVal = cty.UnknownVal(s.ElementType)
|
attrVal = cty.UnknownVal(s.ElementType)
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package hcldec
|
package hcldec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Variables processes the given body with the given spec and returns a
|
// Variables processes the given body with the given spec and returns a
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// setDiagEvalContext is an internal helper that will impose a particular
|
// setDiagEvalContext is an internal helper that will impose a particular
|
|
@ -4,7 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/hashicorp/hcl/v2/ext/customdecode"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
"github.com/zclconf/go-cty/cty/function"
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
|
@ -350,26 +351,38 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti
|
||||||
param = varParam
|
param = varParam
|
||||||
}
|
}
|
||||||
|
|
||||||
val, argDiags := argExpr.Value(ctx)
|
var val cty.Value
|
||||||
if len(argDiags) > 0 {
|
if decodeFn := customdecode.CustomExpressionDecoderForType(param.Type); decodeFn != nil {
|
||||||
|
var argDiags hcl.Diagnostics
|
||||||
|
val, argDiags = decodeFn(argExpr, ctx)
|
||||||
diags = append(diags, argDiags...)
|
diags = append(diags, argDiags...)
|
||||||
}
|
if val == cty.NilVal {
|
||||||
|
val = cty.UnknownVal(param.Type)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var argDiags hcl.Diagnostics
|
||||||
|
val, argDiags = argExpr.Value(ctx)
|
||||||
|
if len(argDiags) > 0 {
|
||||||
|
diags = append(diags, argDiags...)
|
||||||
|
}
|
||||||
|
|
||||||
// Try to convert our value to the parameter type
|
// Try to convert our value to the parameter type
|
||||||
val, err := convert.Convert(val, param.Type)
|
var err error
|
||||||
if err != nil {
|
val, err = convert.Convert(val, param.Type)
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
if err != nil {
|
||||||
Severity: hcl.DiagError,
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Summary: "Invalid function argument",
|
Severity: hcl.DiagError,
|
||||||
Detail: fmt.Sprintf(
|
Summary: "Invalid function argument",
|
||||||
"Invalid value for %q parameter: %s.",
|
Detail: fmt.Sprintf(
|
||||||
param.Name, err,
|
"Invalid value for %q parameter: %s.",
|
||||||
),
|
param.Name, err,
|
||||||
Subject: argExpr.StartRange().Ptr(),
|
),
|
||||||
Context: e.Range().Ptr(),
|
Subject: argExpr.StartRange().Ptr(),
|
||||||
Expression: argExpr,
|
Context: e.Range().Ptr(),
|
||||||
EvalContext: ctx,
|
Expression: argExpr,
|
||||||
})
|
EvalContext: ctx,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argVals[i] = val
|
argVals[i] = val
|
||||||
|
@ -473,8 +486,35 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
|
||||||
falseResult, falseDiags := e.FalseResult.Value(ctx)
|
falseResult, falseDiags := e.FalseResult.Value(ctx)
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
|
|
||||||
// Try to find a type that both results can be converted to.
|
resultType := cty.DynamicPseudoType
|
||||||
resultType, convs := convert.UnifyUnsafe([]cty.Type{trueResult.Type(), falseResult.Type()})
|
convs := make([]convert.Conversion, 2)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
// If either case is a dynamic null value (which would result from a
|
||||||
|
// literal null in the config), we know that it can convert to the expected
|
||||||
|
// type of the opposite case, and we don't need to speculatively reduce the
|
||||||
|
// final result type to DynamicPseudoType.
|
||||||
|
|
||||||
|
// If we know that either Type is a DynamicPseudoType, we can be certain
|
||||||
|
// that the other value can convert since it's a pass-through, and we don't
|
||||||
|
// need to unify the types. If the final evaluation results in the dynamic
|
||||||
|
// value being returned, there's no conversion we can do, so we return the
|
||||||
|
// value directly.
|
||||||
|
case trueResult.RawEquals(cty.NullVal(cty.DynamicPseudoType)):
|
||||||
|
resultType = falseResult.Type()
|
||||||
|
convs[0] = convert.GetConversionUnsafe(cty.DynamicPseudoType, resultType)
|
||||||
|
case falseResult.RawEquals(cty.NullVal(cty.DynamicPseudoType)):
|
||||||
|
resultType = trueResult.Type()
|
||||||
|
convs[1] = convert.GetConversionUnsafe(cty.DynamicPseudoType, resultType)
|
||||||
|
case trueResult.Type() == cty.DynamicPseudoType, falseResult.Type() == cty.DynamicPseudoType:
|
||||||
|
// the final resultType type is still unknown
|
||||||
|
// we don't need to get the conversion, because both are a noop.
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Try to find a type that both results can be converted to.
|
||||||
|
resultType, convs = convert.UnifyUnsafe([]cty.Type{trueResult.Type(), falseResult.Type()})
|
||||||
|
}
|
||||||
|
|
||||||
if resultType == cty.NilType {
|
if resultType == cty.NilType {
|
||||||
return cty.DynamicVal, hcl.Diagnostics{
|
return cty.DynamicVal, hcl.Diagnostics{
|
||||||
{
|
{
|
||||||
|
@ -588,8 +628,9 @@ type IndexExpr struct {
|
||||||
Collection Expression
|
Collection Expression
|
||||||
Key Expression
|
Key Expression
|
||||||
|
|
||||||
SrcRange hcl.Range
|
SrcRange hcl.Range
|
||||||
OpenRange hcl.Range
|
OpenRange hcl.Range
|
||||||
|
BracketRange hcl.Range
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *IndexExpr) walkChildNodes(w internalWalkFunc) {
|
func (e *IndexExpr) walkChildNodes(w internalWalkFunc) {
|
||||||
|
@ -604,7 +645,7 @@ func (e *IndexExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
||||||
diags = append(diags, collDiags...)
|
diags = append(diags, collDiags...)
|
||||||
diags = append(diags, keyDiags...)
|
diags = append(diags, keyDiags...)
|
||||||
|
|
||||||
val, indexDiags := hcl.Index(coll, key, &e.SrcRange)
|
val, indexDiags := hcl.Index(coll, key, &e.BracketRange)
|
||||||
setDiagEvalContext(indexDiags, e, ctx)
|
setDiagEvalContext(indexDiags, e, ctx)
|
||||||
diags = append(diags, indexDiags...)
|
diags = append(diags, indexDiags...)
|
||||||
return val, diags
|
return val, diags
|
||||||
|
@ -777,7 +818,8 @@ func (e *ObjectConsExpr) ExprMap() []hcl.KeyValuePair {
|
||||||
// which deals with the special case that a naked identifier in that position
|
// which deals with the special case that a naked identifier in that position
|
||||||
// must be interpreted as a literal string rather than evaluated directly.
|
// must be interpreted as a literal string rather than evaluated directly.
|
||||||
type ObjectConsKeyExpr struct {
|
type ObjectConsKeyExpr struct {
|
||||||
Wrapped Expression
|
Wrapped Expression
|
||||||
|
ForceNonLiteral bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ObjectConsKeyExpr) literalName() string {
|
func (e *ObjectConsKeyExpr) literalName() string {
|
||||||
|
@ -807,19 +849,21 @@ func (e *ObjectConsKeyExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnost
|
||||||
// (This is handled at evaluation time rather than parse time because
|
// (This is handled at evaluation time rather than parse time because
|
||||||
// an application using static analysis _can_ accept a naked multi-step
|
// an application using static analysis _can_ accept a naked multi-step
|
||||||
// traversal here, if desired.)
|
// traversal here, if desired.)
|
||||||
if travExpr, isTraversal := e.Wrapped.(*ScopeTraversalExpr); isTraversal && len(travExpr.Traversal) > 1 {
|
if !e.ForceNonLiteral {
|
||||||
var diags hcl.Diagnostics
|
if travExpr, isTraversal := e.Wrapped.(*ScopeTraversalExpr); isTraversal && len(travExpr.Traversal) > 1 {
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
var diags hcl.Diagnostics
|
||||||
Severity: hcl.DiagError,
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Summary: "Ambiguous attribute key",
|
Severity: hcl.DiagError,
|
||||||
Detail: "If this expression is intended to be a reference, wrap it in parentheses. If it's instead intended as a literal name containing periods, wrap it in quotes to create a string literal.",
|
Summary: "Ambiguous attribute key",
|
||||||
Subject: e.Range().Ptr(),
|
Detail: "If this expression is intended to be a reference, wrap it in parentheses. If it's instead intended as a literal name containing periods, wrap it in quotes to create a string literal.",
|
||||||
})
|
Subject: e.Range().Ptr(),
|
||||||
return cty.DynamicVal, diags
|
})
|
||||||
}
|
return cty.DynamicVal, diags
|
||||||
|
}
|
||||||
|
|
||||||
if ln := e.literalName(); ln != "" {
|
if ln := e.literalName(); ln != "" {
|
||||||
return cty.StringVal(ln), nil
|
return cty.StringVal(ln), nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return e.Wrapped.Value(ctx)
|
return e.Wrapped.Value(ctx)
|
||||||
}
|
}
|
||||||
|
@ -834,6 +878,12 @@ func (e *ObjectConsKeyExpr) StartRange() hcl.Range {
|
||||||
|
|
||||||
// Implementation for hcl.AbsTraversalForExpr.
|
// Implementation for hcl.AbsTraversalForExpr.
|
||||||
func (e *ObjectConsKeyExpr) AsTraversal() hcl.Traversal {
|
func (e *ObjectConsKeyExpr) AsTraversal() hcl.Traversal {
|
||||||
|
// If we're forcing a non-literal then we can never be interpreted
|
||||||
|
// as a traversal.
|
||||||
|
if e.ForceNonLiteral {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// We can produce a traversal only if our wrappee can.
|
// We can produce a traversal only if our wrappee can.
|
||||||
st, diags := hcl.AbsTraversalForExpr(e.Wrapped)
|
st, diags := hcl.AbsTraversalForExpr(e.Wrapped)
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
|
@ -3,7 +3,7 @@ package hclsyntax
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
"github.com/zclconf/go-cty/cty/function"
|
"github.com/zclconf/go-cty/cty/function"
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-cty/cty/convert"
|
"github.com/zclconf/go-cty/cty/convert"
|
||||||
)
|
)
|
||||||
|
@ -89,6 +89,26 @@ func (e *TemplateExpr) StartRange() hcl.Range {
|
||||||
return e.Parts[0].StartRange()
|
return e.Parts[0].StartRange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsStringLiteral returns true if and only if the template consists only of
|
||||||
|
// single string literal, as would be created for a simple quoted string like
|
||||||
|
// "foo".
|
||||||
|
//
|
||||||
|
// If this function returns true, then calling Value on the same expression
|
||||||
|
// with a nil EvalContext will return the literal value.
|
||||||
|
//
|
||||||
|
// Note that "${"foo"}", "${1}", etc aren't considered literal values for the
|
||||||
|
// purposes of this method, because the intent of this method is to identify
|
||||||
|
// situations where the user seems to be explicitly intending literal string
|
||||||
|
// interpretation, not situations that result in literals as a technicality
|
||||||
|
// of the template expression unwrapping behavior.
|
||||||
|
func (e *TemplateExpr) IsStringLiteral() bool {
|
||||||
|
if len(e.Parts) != 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, ok := e.Parts[0].(*LiteralValueExpr)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
// TemplateJoinExpr is used to convert tuples of strings produced by template
|
// TemplateJoinExpr is used to convert tuples of strings produced by template
|
||||||
// constructs (i.e. for loops) into flat strings, by converting the values
|
// constructs (i.e. for loops) into flat strings, by converting the values
|
||||||
// tos strings and joining them. This AST node is not used directly; it's
|
// tos strings and joining them. This AST node is not used directly; it's
|
|
@ -4,7 +4,7 @@ package hclsyntax
|
||||||
// Run 'go generate' on this package to update the set of functions here.
|
// Run 'go generate' on this package to update the set of functions here.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *AnonSymbolExpr) Variables() []hcl.Traversal {
|
func (e *AnonSymbolExpr) Variables() []hcl.Traversal {
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// File is the top-level object resulting from parsing a configuration file.
|
// File is the top-level object resulting from parsing a configuration file.
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type navigation struct {
|
type navigation struct {
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Node is the abstract type that every AST node implements.
|
// Node is the abstract type that every AST node implements.
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/apparentlymart/go-textseg/textseg"
|
"github.com/apparentlymart/go-textseg/v12/textseg"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -670,6 +670,7 @@ Traversal:
|
||||||
trav := make(hcl.Traversal, 0, 1)
|
trav := make(hcl.Traversal, 0, 1)
|
||||||
var firstRange, lastRange hcl.Range
|
var firstRange, lastRange hcl.Range
|
||||||
firstRange = p.NextRange()
|
firstRange = p.NextRange()
|
||||||
|
lastRange = marker.Range
|
||||||
for p.Peek().Type == TokenDot {
|
for p.Peek().Type == TokenDot {
|
||||||
dot := p.Read()
|
dot := p.Read()
|
||||||
|
|
||||||
|
@ -760,7 +761,7 @@ Traversal:
|
||||||
Each: travExpr,
|
Each: travExpr,
|
||||||
Item: itemExpr,
|
Item: itemExpr,
|
||||||
|
|
||||||
SrcRange: hcl.RangeBetween(dot.Range, lastRange),
|
SrcRange: hcl.RangeBetween(from.Range(), lastRange),
|
||||||
MarkerRange: hcl.RangeBetween(dot.Range, marker.Range),
|
MarkerRange: hcl.RangeBetween(dot.Range, marker.Range),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,7 +820,7 @@ Traversal:
|
||||||
Each: travExpr,
|
Each: travExpr,
|
||||||
Item: itemExpr,
|
Item: itemExpr,
|
||||||
|
|
||||||
SrcRange: hcl.RangeBetween(open.Range, travExpr.Range()),
|
SrcRange: hcl.RangeBetween(from.Range(), travExpr.Range()),
|
||||||
MarkerRange: hcl.RangeBetween(open.Range, close.Range),
|
MarkerRange: hcl.RangeBetween(open.Range, close.Range),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,14 +854,23 @@ Traversal:
|
||||||
SrcRange: rng,
|
SrcRange: rng,
|
||||||
}
|
}
|
||||||
ret = makeRelativeTraversal(ret, step, rng)
|
ret = makeRelativeTraversal(ret, step, rng)
|
||||||
|
} else if tmpl, isTmpl := keyExpr.(*TemplateExpr); isTmpl && tmpl.IsStringLiteral() {
|
||||||
|
litKey, _ := tmpl.Value(nil)
|
||||||
|
rng := hcl.RangeBetween(open.Range, close.Range)
|
||||||
|
step := hcl.TraverseIndex{
|
||||||
|
Key: litKey,
|
||||||
|
SrcRange: rng,
|
||||||
|
}
|
||||||
|
ret = makeRelativeTraversal(ret, step, rng)
|
||||||
} else {
|
} else {
|
||||||
rng := hcl.RangeBetween(open.Range, close.Range)
|
rng := hcl.RangeBetween(open.Range, close.Range)
|
||||||
ret = &IndexExpr{
|
ret = &IndexExpr{
|
||||||
Collection: ret,
|
Collection: ret,
|
||||||
Key: keyExpr,
|
Key: keyExpr,
|
||||||
|
|
||||||
SrcRange: rng,
|
SrcRange: hcl.RangeBetween(from.Range(), rng),
|
||||||
OpenRange: open.Range,
|
OpenRange: open.Range,
|
||||||
|
BracketRange: rng,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -891,7 +901,7 @@ func makeRelativeTraversal(expr Expression, next hcl.Traverser, rng hcl.Range) E
|
||||||
return &RelativeTraversalExpr{
|
return &RelativeTraversalExpr{
|
||||||
Source: expr,
|
Source: expr,
|
||||||
Traversal: hcl.Traversal{next},
|
Traversal: hcl.Traversal{next},
|
||||||
SrcRange: rng,
|
SrcRange: hcl.RangeBetween(expr.Range(), rng),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1283,6 +1293,13 @@ func (p *parser) parseObjectCons() (Expression, hcl.Diagnostics) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wrapping parens are not explicitly represented in the AST, but
|
||||||
|
// we want to use them here to disambiguate intepreting a mapping
|
||||||
|
// key as a full expression rather than just a name, and so
|
||||||
|
// we'll remember this was present and use it to force the
|
||||||
|
// behavior of our final ObjectConsKeyExpr.
|
||||||
|
forceNonLiteral := (p.Peek().Type == TokenOParen)
|
||||||
|
|
||||||
var key Expression
|
var key Expression
|
||||||
var keyDiags hcl.Diagnostics
|
var keyDiags hcl.Diagnostics
|
||||||
key, keyDiags = p.ParseExpression()
|
key, keyDiags = p.ParseExpression()
|
||||||
|
@ -1299,7 +1316,10 @@ func (p *parser) parseObjectCons() (Expression, hcl.Diagnostics) {
|
||||||
// We wrap up the key expression in a special wrapper that deals
|
// We wrap up the key expression in a special wrapper that deals
|
||||||
// with our special case that naked identifiers as object keys
|
// with our special case that naked identifiers as object keys
|
||||||
// are interpreted as literal strings.
|
// are interpreted as literal strings.
|
||||||
key = &ObjectConsKeyExpr{Wrapped: key}
|
key = &ObjectConsKeyExpr{
|
||||||
|
Wrapped: key,
|
||||||
|
ForceNonLiteral: forceNonLiteral,
|
||||||
|
}
|
||||||
|
|
||||||
next = p.Peek()
|
next = p.Peek()
|
||||||
if next.Type != TokenEqual && next.Type != TokenColon {
|
if next.Type != TokenEqual && next.Type != TokenColon {
|
||||||
|
@ -1643,7 +1663,7 @@ Token:
|
||||||
break Token
|
break Token
|
||||||
|
|
||||||
case TokenQuotedLit:
|
case TokenQuotedLit:
|
||||||
s, sDiags := p.decodeStringLit(tok)
|
s, sDiags := ParseStringLiteralToken(tok)
|
||||||
diags = append(diags, sDiags...)
|
diags = append(diags, sDiags...)
|
||||||
ret.WriteString(s)
|
ret.WriteString(s)
|
||||||
|
|
||||||
|
@ -1703,13 +1723,13 @@ Token:
|
||||||
return ret.String(), hcl.RangeBetween(oQuote.Range, cQuote.Range), diags
|
return ret.String(), hcl.RangeBetween(oQuote.Range, cQuote.Range), diags
|
||||||
}
|
}
|
||||||
|
|
||||||
// decodeStringLit processes the given token, which must be either a
|
// ParseStringLiteralToken processes the given token, which must be either a
|
||||||
// TokenQuotedLit or a TokenStringLit, returning the string resulting from
|
// TokenQuotedLit or a TokenStringLit, returning the string resulting from
|
||||||
// resolving any escape sequences.
|
// resolving any escape sequences.
|
||||||
//
|
//
|
||||||
// If any error diagnostics are returned, the returned string may be incomplete
|
// If any error diagnostics are returned, the returned string may be incomplete
|
||||||
// or otherwise invalid.
|
// or otherwise invalid.
|
||||||
func (p *parser) decodeStringLit(tok Token) (string, hcl.Diagnostics) {
|
func ParseStringLiteralToken(tok Token) (string, hcl.Diagnostics) {
|
||||||
var quoted bool
|
var quoted bool
|
||||||
switch tok.Type {
|
switch tok.Type {
|
||||||
case TokenQuotedLit:
|
case TokenQuotedLit:
|
||||||
|
@ -1717,7 +1737,7 @@ func (p *parser) decodeStringLit(tok Token) (string, hcl.Diagnostics) {
|
||||||
case TokenStringLit:
|
case TokenStringLit:
|
||||||
quoted = false
|
quoted = false
|
||||||
default:
|
default:
|
||||||
panic("decodeQuotedLit can only be used with TokenStringLit and TokenQuotedLit tokens")
|
panic("ParseStringLiteralToken can only be used with TokenStringLit and TokenQuotedLit tokens")
|
||||||
}
|
}
|
||||||
var diags hcl.Diagnostics
|
var diags hcl.Diagnostics
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/apparentlymart/go-textseg/textseg"
|
"github.com/apparentlymart/go-textseg/v12/textseg"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ Token:
|
||||||
|
|
||||||
switch next.Type {
|
switch next.Type {
|
||||||
case TokenStringLit, TokenQuotedLit:
|
case TokenStringLit, TokenQuotedLit:
|
||||||
str, strDiags := p.decodeStringLit(next)
|
str, strDiags := ParseStringLiteralToken(next)
|
||||||
diags = append(diags, strDiags...)
|
diags = append(diags, strDiags...)
|
||||||
|
|
||||||
if ltrim {
|
if ltrim {
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is set to true at init() time in tests, to enable more useful output
|
// This is set to true at init() time in tests, to enable more useful output
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParseConfig parses the given buffer as a whole HCL config file, returning
|
// ParseConfig parses the given buffer as a whole HCL config file, returning
|
|
@ -5,7 +5,7 @@ package hclsyntax
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file is generated from scan_tokens.rl. DO NOT EDIT.
|
// This file is generated from scan_tokens.rl. DO NOT EDIT.
|
|
@ -4,7 +4,7 @@ package hclsyntax
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file is generated from scan_tokens.rl. DO NOT EDIT.
|
// This file is generated from scan_tokens.rl. DO NOT EDIT.
|
|
@ -71,14 +71,13 @@ except as described below.
|
||||||
Whitespace is defined as a sequence of zero or more space characters
|
Whitespace is defined as a sequence of zero or more space characters
|
||||||
(U+0020). Newline sequences (either U+000A or U+000D followed by U+000A)
|
(U+0020). Newline sequences (either U+000A or U+000D followed by U+000A)
|
||||||
are _not_ considered whitespace but are ignored as such in certain contexts.
|
are _not_ considered whitespace but are ignored as such in certain contexts.
|
||||||
|
Horizontal tab characters (U+0009) are also treated as whitespace, but are
|
||||||
Horizontal tab characters (U+0009) are not considered to be whitespace and
|
counted only as one "column" for the purpose of reporting source positions.
|
||||||
are not valid within HCL native syntax.
|
|
||||||
|
|
||||||
Comments serve as program documentation and come in two forms:
|
Comments serve as program documentation and come in two forms:
|
||||||
|
|
||||||
- _Line comments_ start with either the `//` or `#` sequences and end with
|
- _Line comments_ start with either the `//` or `#` sequences and end with
|
||||||
the next newline sequence. A line comments is considered equivalent to a
|
the next newline sequence. A line comment is considered equivalent to a
|
||||||
newline sequence.
|
newline sequence.
|
||||||
|
|
||||||
- _Inline comments_ start with the `/*` sequence and end with the `*/`
|
- _Inline comments_ start with the `/*` sequence and end with the `*/`
|
||||||
|
@ -187,7 +186,7 @@ for later evaluation by the calling application.
|
||||||
### Blocks
|
### Blocks
|
||||||
|
|
||||||
A _block_ creates a child body that is annotated with a block _type_ and
|
A _block_ creates a child body that is annotated with a block _type_ and
|
||||||
zero or more block _labels_. Blocks create a structural hierachy which can be
|
zero or more block _labels_. Blocks create a structural hierarchy which can be
|
||||||
interpreted by the calling application.
|
interpreted by the calling application.
|
||||||
|
|
||||||
Block labels can either be quoted literal strings or naked identifiers.
|
Block labels can either be quoted literal strings or naked identifiers.
|
||||||
|
@ -274,7 +273,7 @@ tuple = "[" (
|
||||||
object = "{" (
|
object = "{" (
|
||||||
(objectelem ("," objectelem)* ","?)?
|
(objectelem ("," objectelem)* ","?)?
|
||||||
) "}";
|
) "}";
|
||||||
objectelem = (Identifier | Expression) "=" Expression;
|
objectelem = (Identifier | Expression) ("=" | ":") Expression;
|
||||||
```
|
```
|
||||||
|
|
||||||
Only tuple and object values can be directly constructed via native syntax.
|
Only tuple and object values can be directly constructed via native syntax.
|
||||||
|
@ -543,6 +542,22 @@ return type.
|
||||||
Within the brackets that delimit the index key, newline sequences are ignored
|
Within the brackets that delimit the index key, newline sequences are ignored
|
||||||
as whitespace.
|
as whitespace.
|
||||||
|
|
||||||
|
The HCL native syntax also includes a _legacy_ index operator that exists
|
||||||
|
only for compatibility with the precursor language HIL:
|
||||||
|
|
||||||
|
```ebnf
|
||||||
|
LegacyIndex = '.' digit+
|
||||||
|
```
|
||||||
|
|
||||||
|
This legacy index operator must be supported by parser for compatibility but
|
||||||
|
should not be used in new configurations. This allows an attribute-access-like
|
||||||
|
syntax for indexing, must still be interpreted as an index operation rather
|
||||||
|
than attribute access.
|
||||||
|
|
||||||
|
The legacy syntax does not support chaining of index operations, like
|
||||||
|
`foo.0.0.bar`, because the interpretation of `0.0` as a number literal token
|
||||||
|
takes priority and thus renders the resulting sequence invalid.
|
||||||
|
|
||||||
### Attribute Access Operator
|
### Attribute Access Operator
|
||||||
|
|
||||||
The _attribute access_ operator returns the value of a single attribute in
|
The _attribute access_ operator returns the value of a single attribute in
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AsHCLBlock returns the block data expressed as a *hcl.Block.
|
// AsHCLBlock returns the block data expressed as a *hcl.Block.
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
|
@ -4,8 +4,8 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/apparentlymart/go-textseg/textseg"
|
"github.com/apparentlymart/go-textseg/v12/textseg"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Token represents a sequence of bytes from some HCL code that has been
|
// Token represents a sequence of bytes from some HCL code that has been
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Variables returns all of the variables referenced within a given experssion.
|
// Variables returns all of the variables referenced within a given experssion.
|
|
@ -1,7 +1,7 @@
|
||||||
package hclsyntax
|
package hclsyntax
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VisitFunc is the callback signature for VisitAll.
|
// VisitFunc is the callback signature for VisitAll.
|
|
@ -1,7 +1,7 @@
|
||||||
package hclwrite
|
package hclwrite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Attribute struct {
|
type Attribute struct {
|
|
@ -1,7 +1,7 @@
|
||||||
package hclwrite
|
package hclwrite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -72,3 +72,47 @@ func (b *Block) init(typeName string, labels []string) {
|
||||||
func (b *Block) Body() *Body {
|
func (b *Block) Body() *Body {
|
||||||
return b.body.content.(*Body)
|
return b.body.content.(*Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type returns the type name of the block.
|
||||||
|
func (b *Block) Type() string {
|
||||||
|
typeNameObj := b.typeName.content.(*identifier)
|
||||||
|
return string(typeNameObj.token.Bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Labels returns the labels of the block.
|
||||||
|
func (b *Block) Labels() []string {
|
||||||
|
labelNames := make([]string, 0, len(b.labels))
|
||||||
|
list := b.labels.List()
|
||||||
|
|
||||||
|
for _, label := range list {
|
||||||
|
switch labelObj := label.content.(type) {
|
||||||
|
case *identifier:
|
||||||
|
if labelObj.token.Type == hclsyntax.TokenIdent {
|
||||||
|
labelString := string(labelObj.token.Bytes)
|
||||||
|
labelNames = append(labelNames, labelString)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *quoted:
|
||||||
|
tokens := labelObj.tokens
|
||||||
|
if len(tokens) == 3 &&
|
||||||
|
tokens[0].Type == hclsyntax.TokenOQuote &&
|
||||||
|
tokens[1].Type == hclsyntax.TokenQuotedLit &&
|
||||||
|
tokens[2].Type == hclsyntax.TokenCQuote {
|
||||||
|
// Note that TokenQuotedLit may contain escape sequences.
|
||||||
|
labelString, diags := hclsyntax.ParseStringLiteralToken(tokens[1].asHCLSyntax())
|
||||||
|
|
||||||
|
// If parsing the string literal returns error diagnostics
|
||||||
|
// then we can just assume the label doesn't match, because it's invalid in some way.
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
labelNames = append(labelNames, labelString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// If neither of the previous cases are true (should be impossible)
|
||||||
|
// then we can just ignore it, because it's invalid too.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return labelNames
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
package hclwrite
|
package hclwrite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"reflect"
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,7 +60,7 @@ func (b *Body) Attributes() map[string]*Attribute {
|
||||||
// Blocks returns a new slice of all the blocks in the body.
|
// Blocks returns a new slice of all the blocks in the body.
|
||||||
func (b *Body) Blocks() []*Block {
|
func (b *Body) Blocks() []*Block {
|
||||||
ret := make([]*Block, 0, len(b.items))
|
ret := make([]*Block, 0, len(b.items))
|
||||||
for n := range b.items {
|
for _, n := range b.items.List() {
|
||||||
if block, isBlock := n.content.(*Block); isBlock {
|
if block, isBlock := n.content.(*Block); isBlock {
|
||||||
ret = append(ret, block)
|
ret = append(ret, block)
|
||||||
}
|
}
|
||||||
|
@ -82,6 +84,76 @@ func (b *Body) GetAttribute(name string) *Attribute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getAttributeNode is like GetAttribute but it returns the node containing
|
||||||
|
// the selected attribute (if one is found) rather than the attribute itself.
|
||||||
|
func (b *Body) getAttributeNode(name string) *node {
|
||||||
|
for n := range b.items {
|
||||||
|
if attr, isAttr := n.content.(*Attribute); isAttr {
|
||||||
|
nameObj := attr.name.content.(*identifier)
|
||||||
|
if nameObj.hasName(name) {
|
||||||
|
// We've found it!
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FirstMatchingBlock returns a first matching block from the body that has the
|
||||||
|
// given name and labels or returns nil if there is currently no matching
|
||||||
|
// block.
|
||||||
|
func (b *Body) FirstMatchingBlock(typeName string, labels []string) *Block {
|
||||||
|
for _, block := range b.Blocks() {
|
||||||
|
if typeName == block.Type() {
|
||||||
|
labelNames := block.Labels()
|
||||||
|
if len(labels) == 0 && len(labelNames) == 0 {
|
||||||
|
return block
|
||||||
|
}
|
||||||
|
if reflect.DeepEqual(labels, labelNames) {
|
||||||
|
return block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveBlock removes the given block from the body, if it's in that body.
|
||||||
|
// If it isn't present, this is a no-op.
|
||||||
|
//
|
||||||
|
// Returns true if it removed something, or false otherwise.
|
||||||
|
func (b *Body) RemoveBlock(block *Block) bool {
|
||||||
|
for n := range b.items {
|
||||||
|
if n.content == block {
|
||||||
|
n.Detach()
|
||||||
|
b.items.Remove(n)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAttributeRaw either replaces the expression of an existing attribute
|
||||||
|
// of the given name or adds a new attribute definition to the end of the block,
|
||||||
|
// using the given tokens verbatim as the expression.
|
||||||
|
//
|
||||||
|
// The same caveats apply to this function as for NewExpressionRaw on which
|
||||||
|
// it is based. If possible, prefer to use SetAttributeValue or
|
||||||
|
// SetAttributeTraversal.
|
||||||
|
func (b *Body) SetAttributeRaw(name string, tokens Tokens) *Attribute {
|
||||||
|
attr := b.GetAttribute(name)
|
||||||
|
expr := NewExpressionRaw(tokens)
|
||||||
|
if attr != nil {
|
||||||
|
attr.expr = attr.expr.ReplaceWith(expr)
|
||||||
|
} else {
|
||||||
|
attr := newAttribute()
|
||||||
|
attr.init(name, expr)
|
||||||
|
b.appendItem(attr)
|
||||||
|
}
|
||||||
|
return attr
|
||||||
|
}
|
||||||
|
|
||||||
// SetAttributeValue either replaces the expression of an existing attribute
|
// SetAttributeValue either replaces the expression of an existing attribute
|
||||||
// of the given name or adds a new attribute definition to the end of the block.
|
// of the given name or adds a new attribute definition to the end of the block.
|
||||||
//
|
//
|
||||||
|
@ -124,6 +196,20 @@ func (b *Body) SetAttributeTraversal(name string, traversal hcl.Traversal) *Attr
|
||||||
return attr
|
return attr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveAttribute removes the attribute with the given name from the body.
|
||||||
|
//
|
||||||
|
// The return value is the attribute that was removed, or nil if there was
|
||||||
|
// no such attribute (in which case the call was a no-op).
|
||||||
|
func (b *Body) RemoveAttribute(name string) *Attribute {
|
||||||
|
node := b.getAttributeNode(name)
|
||||||
|
if node == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
node.Detach()
|
||||||
|
b.items.Remove(node)
|
||||||
|
return node.content.(*Attribute)
|
||||||
|
}
|
||||||
|
|
||||||
// AppendBlock appends an existing block (which must not be already attached
|
// AppendBlock appends an existing block (which must not be already attached
|
||||||
// to a body) to the end of the receiving body.
|
// to a body) to the end of the receiving body.
|
||||||
func (b *Body) AppendBlock(block *Block) *Block {
|
func (b *Body) AppendBlock(block *Block) *Block {
|
|
@ -3,8 +3,8 @@ package hclwrite
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,6 +21,29 @@ func newExpression() *Expression {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewExpressionRaw constructs an expression containing the given raw tokens.
|
||||||
|
//
|
||||||
|
// There is no automatic validation that the given tokens produce a valid
|
||||||
|
// expression. Callers of thus function must take care to produce invalid
|
||||||
|
// expression tokens. Where possible, use the higher-level functions
|
||||||
|
// NewExpressionLiteral or NewExpressionAbsTraversal instead.
|
||||||
|
//
|
||||||
|
// Because NewExpressionRaw does not interpret the given tokens in any way,
|
||||||
|
// an expression created by NewExpressionRaw will produce an empty result
|
||||||
|
// for calls to its method Variables, even if the given token sequence
|
||||||
|
// contains a subslice that would normally be interpreted as a traversal under
|
||||||
|
// parsing.
|
||||||
|
func NewExpressionRaw(tokens Tokens) *Expression {
|
||||||
|
expr := newExpression()
|
||||||
|
// We copy the tokens here in order to make sure that later mutations
|
||||||
|
// by the caller don't inadvertently cause our expression to become
|
||||||
|
// invalid.
|
||||||
|
copyTokens := make(Tokens, len(tokens))
|
||||||
|
copy(copyTokens, tokens)
|
||||||
|
expr.children.AppendUnstructuredTokens(copyTokens)
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
|
||||||
// NewExpressionLiteral constructs an an expression that represents the given
|
// NewExpressionLiteral constructs an an expression that represents the given
|
||||||
// literal value.
|
// literal value.
|
||||||
//
|
//
|
|
@ -1,7 +1,7 @@
|
||||||
package hclwrite
|
package hclwrite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
)
|
)
|
||||||
|
|
||||||
var inKeyword = hclsyntax.Keyword([]byte{'i', 'n'})
|
var inKeyword = hclsyntax.Keyword([]byte{'i', 'n'})
|
||||||
|
@ -54,22 +54,12 @@ func formatIndent(lines []formatLine) {
|
||||||
// which should be more than enough for reasonable HCL uses.
|
// which should be more than enough for reasonable HCL uses.
|
||||||
indents := make([]int, 0, 10)
|
indents := make([]int, 0, 10)
|
||||||
|
|
||||||
inHeredoc := false
|
|
||||||
for i := range lines {
|
for i := range lines {
|
||||||
line := &lines[i]
|
line := &lines[i]
|
||||||
if len(line.lead) == 0 {
|
if len(line.lead) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if inHeredoc {
|
|
||||||
for _, token := range line.lead {
|
|
||||||
if token.Type == hclsyntax.TokenCHeredoc {
|
|
||||||
inHeredoc = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue // don't touch indentation inside heredocs
|
|
||||||
}
|
|
||||||
|
|
||||||
if line.lead[0].Type == hclsyntax.TokenNewline {
|
if line.lead[0].Type == hclsyntax.TokenNewline {
|
||||||
// Never place spaces before a newline
|
// Never place spaces before a newline
|
||||||
line.lead[0].SpacesBefore = 0
|
line.lead[0].SpacesBefore = 0
|
||||||
|
@ -80,9 +70,10 @@ func formatIndent(lines []formatLine) {
|
||||||
for _, token := range line.lead {
|
for _, token := range line.lead {
|
||||||
netBrackets += tokenBracketChange(token)
|
netBrackets += tokenBracketChange(token)
|
||||||
if token.Type == hclsyntax.TokenOHeredoc {
|
if token.Type == hclsyntax.TokenOHeredoc {
|
||||||
inHeredoc = true
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, token := range line.assign {
|
for _, token := range line.assign {
|
||||||
netBrackets += tokenBracketChange(token)
|
netBrackets += tokenBracketChange(token)
|
||||||
}
|
}
|
||||||
|
@ -326,7 +317,7 @@ func spaceAfterToken(subject, before, after *Token) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
// Don't add spaces between interpolated items
|
// Don't add spaces between interpolated items
|
||||||
case subject.Type == hclsyntax.TokenTemplateSeqEnd && after.Type == hclsyntax.TokenTemplateInterp:
|
case subject.Type == hclsyntax.TokenTemplateSeqEnd && (after.Type == hclsyntax.TokenTemplateInterp || after.Type == hclsyntax.TokenTemplateControl):
|
||||||
return false
|
return false
|
||||||
|
|
||||||
case tokenBracketChange(subject) > 0:
|
case tokenBracketChange(subject) > 0:
|
||||||
|
@ -391,9 +382,9 @@ func linesForFormat(tokens Tokens) []formatLine {
|
||||||
|
|
||||||
// Now we'll pick off any trailing comments and attribute assignments
|
// Now we'll pick off any trailing comments and attribute assignments
|
||||||
// to shuffle off into the "comment" and "assign" cells.
|
// to shuffle off into the "comment" and "assign" cells.
|
||||||
inHeredoc := false
|
|
||||||
for i := range lines {
|
for i := range lines {
|
||||||
line := &lines[i]
|
line := &lines[i]
|
||||||
|
|
||||||
if len(line.lead) == 0 {
|
if len(line.lead) == 0 {
|
||||||
// if the line is empty then there's nothing for us to do
|
// if the line is empty then there's nothing for us to do
|
||||||
// (this should happen only for the final line, because all other
|
// (this should happen only for the final line, because all other
|
||||||
|
@ -401,26 +392,6 @@ func linesForFormat(tokens Tokens) []formatLine {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if inHeredoc {
|
|
||||||
for _, tok := range line.lead {
|
|
||||||
if tok.Type == hclsyntax.TokenCHeredoc {
|
|
||||||
inHeredoc = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Inside a heredoc everything is "lead", even if there's a
|
|
||||||
// template interpolation embedded in there that might otherwise
|
|
||||||
// confuse our logic below.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tok := range line.lead {
|
|
||||||
if tok.Type == hclsyntax.TokenOHeredoc {
|
|
||||||
inHeredoc = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(line.lead) > 1 && line.lead[len(line.lead)-1].Type == hclsyntax.TokenComment {
|
if len(line.lead) > 1 && line.lead[len(line.lead)-1].Type == hclsyntax.TokenComment {
|
||||||
line.comment = line.lead[len(line.lead)-1:]
|
line.comment = line.lead[len(line.lead)-1:]
|
||||||
line.lead = line.lead[:len(line.lead)-1]
|
line.lead = line.lead[:len(line.lead)-1]
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -119,15 +119,15 @@ func appendTokensForValue(val cty.Value, toks Tokens) Tokens {
|
||||||
Type: hclsyntax.TokenOBrace,
|
Type: hclsyntax.TokenOBrace,
|
||||||
Bytes: []byte{'{'},
|
Bytes: []byte{'{'},
|
||||||
})
|
})
|
||||||
|
if val.LengthInt() > 0 {
|
||||||
|
toks = append(toks, &Token{
|
||||||
|
Type: hclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
for it := val.ElementIterator(); it.Next(); {
|
for it := val.ElementIterator(); it.Next(); {
|
||||||
if i > 0 {
|
|
||||||
toks = append(toks, &Token{
|
|
||||||
Type: hclsyntax.TokenComma,
|
|
||||||
Bytes: []byte{','},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
eKey, eVal := it.Element()
|
eKey, eVal := it.Element()
|
||||||
if hclsyntax.ValidIdentifier(eKey.AsString()) {
|
if hclsyntax.ValidIdentifier(eKey.AsString()) {
|
||||||
toks = append(toks, &Token{
|
toks = append(toks, &Token{
|
||||||
|
@ -142,6 +142,10 @@ func appendTokensForValue(val cty.Value, toks Tokens) Tokens {
|
||||||
Bytes: []byte{'='},
|
Bytes: []byte{'='},
|
||||||
})
|
})
|
||||||
toks = appendTokensForValue(eVal, toks)
|
toks = appendTokensForValue(eVal, toks)
|
||||||
|
toks = append(toks, &Token{
|
||||||
|
Type: hclsyntax.TokenNewline,
|
||||||
|
Bytes: []byte{'\n'},
|
||||||
|
})
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,12 +163,12 @@ func appendTokensForValue(val cty.Value, toks Tokens) Tokens {
|
||||||
|
|
||||||
func appendTokensForTraversal(traversal hcl.Traversal, toks Tokens) Tokens {
|
func appendTokensForTraversal(traversal hcl.Traversal, toks Tokens) Tokens {
|
||||||
for _, step := range traversal {
|
for _, step := range traversal {
|
||||||
appendTokensForTraversalStep(step, toks)
|
toks = appendTokensForTraversalStep(step, toks)
|
||||||
}
|
}
|
||||||
return toks
|
return toks
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendTokensForTraversalStep(step hcl.Traverser, toks Tokens) {
|
func appendTokensForTraversalStep(step hcl.Traverser, toks Tokens) Tokens {
|
||||||
switch ts := step.(type) {
|
switch ts := step.(type) {
|
||||||
case hcl.TraverseRoot:
|
case hcl.TraverseRoot:
|
||||||
toks = append(toks, &Token{
|
toks = append(toks, &Token{
|
||||||
|
@ -188,7 +192,7 @@ func appendTokensForTraversalStep(step hcl.Traverser, toks Tokens) {
|
||||||
Type: hclsyntax.TokenOBrack,
|
Type: hclsyntax.TokenOBrack,
|
||||||
Bytes: []byte{'['},
|
Bytes: []byte{'['},
|
||||||
})
|
})
|
||||||
appendTokensForValue(ts.Key, toks)
|
toks = appendTokensForValue(ts.Key, toks)
|
||||||
toks = append(toks, &Token{
|
toks = append(toks, &Token{
|
||||||
Type: hclsyntax.TokenCBrack,
|
Type: hclsyntax.TokenCBrack,
|
||||||
Bytes: []byte{']'},
|
Bytes: []byte{']'},
|
||||||
|
@ -196,6 +200,8 @@ func appendTokensForTraversalStep(step hcl.Traverser, toks Tokens) {
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unsupported traversal step type %T", step))
|
panic(fmt.Sprintf("unsupported traversal step type %T", step))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return toks
|
||||||
}
|
}
|
||||||
|
|
||||||
func escapeQuotedStringLit(s string) []byte {
|
func escapeQuotedStringLit(s string) []byte {
|
|
@ -1,7 +1,7 @@
|
||||||
package hclwrite
|
package hclwrite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nativeNodeSorter struct {
|
type nativeNodeSorter struct {
|
|
@ -140,6 +140,18 @@ func (ns *nodes) AppendUnstructuredTokens(tokens Tokens) *node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNodeWithContent searches the nodes for a node whose content equals
|
||||||
|
// the given content. If it finds one then it returns it. Otherwise it returns
|
||||||
|
// nil.
|
||||||
|
func (ns *nodes) FindNodeWithContent(content nodeContent) *node {
|
||||||
|
for n := ns.first; n != nil; n = n.after {
|
||||||
|
if n.content == content {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// nodeSet is an unordered set of nodes. It is used to describe a set of nodes
|
// nodeSet is an unordered set of nodes. It is used to describe a set of nodes
|
||||||
// that all belong to the same list that have some role or characteristic
|
// that all belong to the same list that have some role or characteristic
|
||||||
// in common.
|
// in common.
|
||||||
|
@ -192,6 +204,18 @@ func (ns nodeSet) List() []*node {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNodeWithContent searches the nodes for a node whose content equals
|
||||||
|
// the given content. If it finds one then it returns it. Otherwise it returns
|
||||||
|
// nil.
|
||||||
|
func (ns nodeSet) FindNodeWithContent(content nodeContent) *node {
|
||||||
|
for n := range ns {
|
||||||
|
if n.content == content {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type internalWalkFunc func(*node)
|
type internalWalkFunc func(*node)
|
||||||
|
|
||||||
// inTree can be embedded into a content struct that has child nodes to get
|
// inTree can be embedded into a content struct that has child nodes to get
|
|
@ -4,8 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
"github.com/zclconf/go-cty/cty"
|
"github.com/zclconf/go-cty/cty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -88,6 +88,16 @@ func (it inputTokens) PartitionType(ty hclsyntax.TokenType) (before, within, aft
|
||||||
panic(fmt.Sprintf("didn't find any token of type %s", ty))
|
panic(fmt.Sprintf("didn't find any token of type %s", ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (it inputTokens) PartitionTypeOk(ty hclsyntax.TokenType) (before, within, after inputTokens, ok bool) {
|
||||||
|
for i, t := range it.writerTokens {
|
||||||
|
if t.Type == ty {
|
||||||
|
return it.Slice(0, i), it.Slice(i, i+1), it.Slice(i+1, len(it.nativeTokens)), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputTokens{}, inputTokens{}, inputTokens{}, false
|
||||||
|
}
|
||||||
|
|
||||||
func (it inputTokens) PartitionTypeSingle(ty hclsyntax.TokenType) (before inputTokens, found *Token, after inputTokens) {
|
func (it inputTokens) PartitionTypeSingle(ty hclsyntax.TokenType) (before inputTokens, found *Token, after inputTokens) {
|
||||||
before, within, after := it.PartitionType(ty)
|
before, within, after := it.PartitionType(ty)
|
||||||
if within.Len() != 1 {
|
if within.Len() != 1 {
|
||||||
|
@ -307,7 +317,12 @@ func parseBlock(nativeBlock *hclsyntax.Block, from, leadComments, lineComments,
|
||||||
before, labelTokens, from = from.Partition(rng)
|
before, labelTokens, from = from.Partition(rng)
|
||||||
children.AppendUnstructuredTokens(before.Tokens())
|
children.AppendUnstructuredTokens(before.Tokens())
|
||||||
tokens := labelTokens.Tokens()
|
tokens := labelTokens.Tokens()
|
||||||
ln := newNode(newQuoted(tokens))
|
var ln *node
|
||||||
|
if len(tokens) == 1 && tokens[0].Type == hclsyntax.TokenIdent {
|
||||||
|
ln = newNode(newIdentifier(tokens[0]))
|
||||||
|
} else {
|
||||||
|
ln = newNode(newQuoted(tokens))
|
||||||
|
}
|
||||||
block.labels.Add(ln)
|
block.labels.Add(ln)
|
||||||
children.AppendNode(ln)
|
children.AppendNode(ln)
|
||||||
}
|
}
|
||||||
|
@ -399,6 +414,19 @@ func parseTraversalStep(nativeStep hcl.Traverser, from inputTokens) (before inpu
|
||||||
children = step.inTree.children
|
children = step.inTree.children
|
||||||
before, from, after = from.Partition(nativeStep.SourceRange())
|
before, from, after = from.Partition(nativeStep.SourceRange())
|
||||||
|
|
||||||
|
if inBefore, dot, from, ok := from.PartitionTypeOk(hclsyntax.TokenDot); ok {
|
||||||
|
children.AppendUnstructuredTokens(inBefore.Tokens())
|
||||||
|
children.AppendUnstructuredTokens(dot.Tokens())
|
||||||
|
|
||||||
|
valBefore, valToken, valAfter := from.PartitionTypeSingle(hclsyntax.TokenNumberLit)
|
||||||
|
children.AppendUnstructuredTokens(valBefore.Tokens())
|
||||||
|
key := newNumber(valToken)
|
||||||
|
step.key = children.Append(key)
|
||||||
|
children.AppendUnstructuredTokens(valAfter.Tokens())
|
||||||
|
|
||||||
|
return before, newNode(step), after
|
||||||
|
}
|
||||||
|
|
||||||
var inBefore, oBrack, keyTokens, cBrack inputTokens
|
var inBefore, oBrack, keyTokens, cBrack inputTokens
|
||||||
inBefore, oBrack, from = from.PartitionType(hclsyntax.TokenOBrack)
|
inBefore, oBrack, from = from.PartitionType(hclsyntax.TokenOBrack)
|
||||||
children.AppendUnstructuredTokens(inBefore.Tokens())
|
children.AppendUnstructuredTokens(inBefore.Tokens())
|
|
@ -3,7 +3,7 @@ package hclwrite
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewFile creates a new file object that is empty and ready to have constructs
|
// NewFile creates a new file object that is empty and ready to have constructs
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/apparentlymart/go-textseg/textseg"
|
"github.com/apparentlymart/go-textseg/v12/textseg"
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Token is a single sequence of bytes annotated with a type. It is similar
|
// Token is a single sequence of bytes annotated with a type. It is similar
|
|
@ -3,7 +3,7 @@ package json
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl2/hcl"
|
"github.com/hashicorp/hcl/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type node interface {
|
type node interface {
|
|
@ -5,4 +5,8 @@
|
||||||
// This is not a generic JSON parser. Instead, it deals with the mapping from
|
// This is not a generic JSON parser. Instead, it deals with the mapping from
|
||||||
// the JSON information model to the HCL information model, using a number
|
// the JSON information model to the HCL information model, using a number
|
||||||
// of hard-coded structural conventions.
|
// of hard-coded structural conventions.
|
||||||
|
//
|
||||||
|
// In most cases applications will not import this package directly, but will
|
||||||
|
// instead access its functionality indirectly through functions in the main
|
||||||
|
// "hcl" package and in the "hclparse" package.
|
||||||
package json
|
package json
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue