bump gocui
parent
be347a7216
commit
57379252a5
@ -1,16 +0,0 @@
|
||||
language: go
|
||||
sudo: false
|
||||
go:
|
||||
- 1.13.x
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- go get -t -v ./...
|
||||
|
||||
script:
|
||||
- go generate
|
||||
- git diff --cached --exit-code
|
||||
- ./go.test.sh
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
echo "" > coverage.txt
|
||||
|
||||
for d in $(go list ./... | grep -v vendor); do
|
||||
go test -race -coverprofile=profile.out -covermode=atomic "$d"
|
||||
if [ -f profile.out ]; then
|
||||
cat profile.out >> coverage.txt
|
||||
rm profile.out
|
||||
fi
|
||||
done
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,256 @@
|
||||
//go:build generate
|
||||
|
||||
// This program generates a property file in Go file from Unicode Character
|
||||
// Database auxiliary data files. The command line arguments are as follows:
|
||||
//
|
||||
// 1. The name of the Unicode data file (just the filename, without extension).
|
||||
// Can be "-" (to skip) if the emoji flag is included.
|
||||
// 2. The name of the locally generated Go file.
|
||||
// 3. The name of the slice mapping code points to properties.
|
||||
// 4. The name of the generator, for logging purposes.
|
||||
// 5. (Optional) Flags, comma-separated. The following flags are available:
|
||||
// - "emojis=<property>": include the specified emoji properties (e.g.
|
||||
// "Extended_Pictographic").
|
||||
// - "gencat": include general category properties.
|
||||
//
|
||||
//go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis=Extended_Pictographic
|
||||
//go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis=Extended_Pictographic
|
||||
//go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences
|
||||
//go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat
|
||||
//go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth
|
||||
//go:generate go run gen_properties.go - emojipresentation.go emojiPresentation emojipresentation emojis=Emoji_Presentation
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// We want to test against a specific version rather than the latest. When the
|
||||
// package is upgraded to a new version, change these to generate new tests.
|
||||
const (
|
||||
propertyURL = `https://www.unicode.org/Public/14.0.0/ucd/%s.txt`
|
||||
emojiURL = `https://unicode.org/Public/14.0.0/ucd/emoji/emoji-data.txt`
|
||||
)
|
||||
|
||||
// The regular expression for a line containing a code point range property.
|
||||
var propertyPattern = regexp.MustCompile(`^([0-9A-F]{4,6})(\.\.([0-9A-F]{4,6}))?\s*;\s*([A-Za-z0-9_]+)\s*#\s(.+)$`)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 5 {
|
||||
fmt.Println("Not enough arguments, see code for details")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.SetPrefix("gen_properties (" + os.Args[4] + "): ")
|
||||
log.SetFlags(0)
|
||||
|
||||
// Parse flags.
|
||||
flags := make(map[string]string)
|
||||
if len(os.Args) >= 6 {
|
||||
for _, flag := range strings.Split(os.Args[5], ",") {
|
||||
flagFields := strings.Split(flag, "=")
|
||||
if len(flagFields) == 1 {
|
||||
flags[flagFields[0]] = "yes"
|
||||
} else {
|
||||
flags[flagFields[0]] = flagFields[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the text file and generate Go source code from it.
|
||||
_, includeGeneralCategory := flags["gencat"]
|
||||
var mainURL string
|
||||
if os.Args[1] != "-" {
|
||||
mainURL = fmt.Sprintf(propertyURL, os.Args[1])
|
||||
}
|
||||
src, err := parse(mainURL, flags["emojis"], includeGeneralCategory)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Format the Go code.
|
||||
formatted, err := format.Source([]byte(src))
|
||||
if err != nil {
|
||||
log.Fatal("gofmt:", err)
|
||||
}
|
||||
|
||||
// Save it to the (local) target file.
|
||||
log.Print("Writing to ", os.Args[2])
|
||||
if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// parse parses the Unicode Properties text files located at the given URLs and
|
||||
// returns their equivalent Go source code to be used in the uniseg package. If
|
||||
// "emojiProperty" is not an empty string, emoji code points for that emoji
|
||||
// property (e.g. "Extended_Pictographic") will be included. In those cases, you
|
||||
// may pass an empty "propertyURL" to skip parsing the main properties file. If
|
||||
// "includeGeneralCategory" is true, the Unicode General Category property will
|
||||
// be extracted from the comments and included in the output.
|
||||
func parse(propertyURL, emojiProperty string, includeGeneralCategory bool) (string, error) {
|
||||
if propertyURL == "" && emojiProperty == "" {
|
||||
return "", errors.New("no properties to parse")
|
||||
}
|
||||
|
||||
// Temporary buffer to hold properties.
|
||||
var properties [][4]string
|
||||
|
||||
// Open the first URL.
|
||||
if propertyURL != "" {
|
||||
log.Printf("Parsing %s", propertyURL)
|
||||
res, err := http.Get(propertyURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
in1 := res.Body
|
||||
defer in1.Close()
|
||||
|
||||
// Parse it.
|
||||
scanner := bufio.NewScanner(in1)
|
||||
num := 0
|
||||
for scanner.Scan() {
|
||||
num++
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
// Skip comments and empty lines.
|
||||
if strings.HasPrefix(line, "#") || line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Everything else must be a code point range, a property and a comment.
|
||||
from, to, property, comment, err := parseProperty(line)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err)
|
||||
}
|
||||
properties = append(properties, [4]string{from, to, property, comment})
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Open the second URL.
|
||||
if emojiProperty != "" {
|
||||
log.Printf("Parsing %s", emojiURL)
|
||||
res, err := http.Get(emojiURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
in2 := res.Body
|
||||
defer in2.Close()
|
||||
|
||||
// Parse it.
|
||||
scanner := bufio.NewScanner(in2)
|
||||
num := 0
|
||||
for scanner.Scan() {
|
||||
num++
|
||||
line := scanner.Text()
|
||||
|
||||
// Skip comments, empty lines, and everything not containing
|
||||
// "Extended_Pictographic".
|
||||
if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, emojiProperty) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Everything else must be a code point range, a property and a comment.
|
||||
from, to, property, comment, err := parseProperty(line)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("emojis line %d: %v", num, err)
|
||||
}
|
||||
properties = append(properties, [4]string{from, to, property, comment})
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// Sort properties.
|
||||
sort.Slice(properties, func(i, j int) bool {
|
||||
left, _ := strconv.ParseUint(properties[i][0], 16, 64)
|
||||
right, _ := strconv.ParseUint(properties[j][0], 16, 64)
|
||||
return left < right
|
||||
})
|
||||
|
||||
// Header.
|
||||
var (
|
||||
buf bytes.Buffer
|
||||
emojiComment string
|
||||
)
|
||||
columns := 3
|
||||
if includeGeneralCategory {
|
||||
columns = 4
|
||||
}
|
||||
if emojiURL != "" {
|
||||
emojiComment = `
|
||||
// and
|
||||
// ` + emojiURL + `
|
||||
// ("Extended_Pictographic" only)`
|
||||
}
|
||||
buf.WriteString(`package uniseg
|
||||
|
||||
// Code generated via go generate from gen_properties.go. DO NOT EDIT.
|
||||
|
||||
// ` + os.Args[3] + ` are taken from
|
||||
// ` + propertyURL + emojiComment + `
|
||||
// on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode
|
||||
// license agreement.
|
||||
var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{
|
||||
`)
|
||||
|
||||
// Properties.
|
||||
for _, prop := range properties {
|
||||
if includeGeneralCategory {
|
||||
generalCategory := "gc" + prop[3][:2]
|
||||
if generalCategory == "gcL&" {
|
||||
generalCategory = "gcLC"
|
||||
}
|
||||
prop[3] = prop[3][3:]
|
||||
fmt.Fprintf(&buf, "{0x%s,0x%s,%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), generalCategory, prop[3])
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "{0x%s,0x%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), prop[3])
|
||||
}
|
||||
}
|
||||
|
||||
// Tail.
|
||||
buf.WriteString("}")
|
||||
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// parseProperty parses a line of the Unicode properties text file containing a
|
||||
// property for a code point range and returns it along with its comment.
|
||||
func parseProperty(line string) (from, to, property, comment string, err error) {
|
||||
fields := propertyPattern.FindStringSubmatch(line)
|
||||
if fields == nil {
|
||||
err = errors.New("no property found")
|
||||
return
|
||||
}
|
||||
from = fields[1]
|
||||
to = fields[3]
|
||||
if to == "" {
|
||||
to = from
|
||||
}
|
||||
property = fields[4]
|
||||
comment = fields[5]
|
||||
return
|
||||
}
|
||||
|
||||
// translateProperty translates a property name as used in the Unicode data file
|
||||
// to a variable used in the Go code.
|
||||
func translateProperty(prefix, property string) string {
|
||||
return prefix + strings.ReplaceAll(property, "_", "")
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,138 @@
|
||||
package uniseg
|
||||
|
||||
// The states of the grapheme cluster parser.
|
||||
const (
|
||||
grAny = iota
|
||||
grCR
|
||||
grControlLF
|
||||
grL
|
||||
grLVV
|
||||
grLVTT
|
||||
grPrepend
|
||||
grExtendedPictographic
|
||||
grExtendedPictographicZWJ
|
||||
grRIOdd
|
||||
grRIEven
|
||||
)
|
||||
|
||||
// The grapheme cluster parser's breaking instructions.
|
||||
const (
|
||||
grNoBoundary = iota
|
||||
grBoundary
|
||||
)
|
||||
|
||||
// The grapheme cluster parser's state transitions. Maps (state, property) to
|
||||
// (new state, breaking instruction, rule number). The breaking instruction
|
||||
// always refers to the boundary between the last and next code point.
|
||||
//
|
||||
// This map is queried as follows:
|
||||
//
|
||||
// 1. Find specific state + specific property. Stop if found.
|
||||
// 2. Find specific state + any property.
|
||||
// 3. Find any state + specific property.
|
||||
// 4. If only (2) or (3) (but not both) was found, stop.
|
||||
// 5. If both (2) and (3) were found, use state from (3) and breaking instruction
|
||||
// from the transition with the lower rule number, prefer (3) if rule numbers
|
||||
// are equal. Stop.
|
||||
// 6. Assume grAny and grBoundary.
|
||||
//
|
||||
// Unicode version 14.0.0.
|
||||
var grTransitions = map[[2]int][3]int{
|
||||
// GB5
|
||||
{grAny, prCR}: {grCR, grBoundary, 50},
|
||||
{grAny, prLF}: {grControlLF, grBoundary, 50},
|
||||
{grAny, prControl}: {grControlLF, grBoundary, 50},
|
||||
|
||||
// GB4
|
||||
{grCR, prAny}: {grAny, grBoundary, 40},
|
||||
{grControlLF, prAny}: {grAny, grBoundary, 40},
|
||||
|
||||
// GB3.
|
||||
{grCR, prLF}: {grAny, grNoBoundary, 30},
|
||||
|
||||
// GB6.
|
||||
{grAny, prL}: {grL, grBoundary, 9990},
|
||||
{grL, prL}: {grL, grNoBoundary, 60},
|
||||
{grL, prV}: {grLVV, grNoBoundary, 60},
|
||||
{grL, prLV}: {grLVV, grNoBoundary, 60},
|
||||
{grL, prLVT}: {grLVTT, grNoBoundary, 60},
|
||||
|
||||
// GB7.
|
||||
{grAny, prLV}: {grLVV, grBoundary, 9990},
|
||||
{grAny, prV}: {grLVV, grBoundary, 9990},
|
||||
{grLVV, prV}: {grLVV, grNoBoundary, 70},
|
||||
{grLVV, prT}: {grLVTT, grNoBoundary, 70},
|
||||
|
||||
// GB8.
|
||||
{grAny, prLVT}: {grLVTT, grBoundary, 9990},
|
||||
{grAny, prT}: {grLVTT, grBoundary, 9990},
|
||||
{grLVTT, prT}: {grLVTT, grNoBoundary, 80},
|
||||
|
||||
// GB9.
|
||||
{grAny, prExtend}: {grAny, grNoBoundary, 90},
|
||||
{grAny, prZWJ}: {grAny, grNoBoundary, 90},
|
||||
|
||||
// GB9a.
|
||||
{grAny, prSpacingMark}: {grAny, grNoBoundary, 91},
|
||||
|
||||
// GB9b.
|
||||
{grAny, prPrepend}: {grPrepend, grBoundary, 9990},
|
||||
{grPrepend, prAny}: {grAny, grNoBoundary, 92},
|
||||
|
||||
// GB11.
|
||||
{grAny, prExtendedPictographic}: {grExtendedPictographic, grBoundary, 9990},
|
||||
{grExtendedPictographic, prExtend}: {grExtendedPictographic, grNoBoundary, 110},
|
||||
{grExtendedPictographic, prZWJ}: {grExtendedPictographicZWJ, grNoBoundary, 110},
|
||||
{grExtendedPictographicZWJ, prExtendedPictographic}: {grExtendedPictographic, grNoBoundary, 110},
|
||||
|
||||
// GB12 / GB13.
|
||||
{grAny, prRegionalIndicator}: {grRIOdd, grBoundary, 9990},
|
||||
{grRIOdd, prRegionalIndicator}: {grRIEven, grNoBoundary, 120},
|
||||
{grRIEven, prRegionalIndicator}: {grRIOdd, grBoundary, 120},
|
||||
}
|
||||
|
||||
// transitionGraphemeState determines the new state of the grapheme cluster
|
||||
// parser given the current state and the next code point. It also returns the
|
||||
// code point's grapheme property (the value mapped by the [graphemeCodePoints]
|
||||
// table) and whether a cluster boundary was detected.
|
||||
func transitionGraphemeState(state int, r rune) (newState, prop int, boundary bool) {
|
||||
// Determine the property of the next character.
|
||||
prop = property(graphemeCodePoints, r)
|
||||
|
||||
// Find the applicable transition.
|
||||
transition, ok := grTransitions[[2]int{state, prop}]
|
||||
if ok {
|
||||
// We have a specific transition. We'll use it.
|
||||
return transition[0], prop, transition[1] == grBoundary
|
||||
}
|
||||
|
||||
// No specific transition found. Try the less specific ones.
|
||||
transAnyProp, okAnyProp := grTransitions[[2]int{state, prAny}]
|
||||
transAnyState, okAnyState := grTransitions[[2]int{grAny, prop}]
|
||||
if okAnyProp && okAnyState {
|
||||
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||
newState = transAnyState[0]
|
||||
boundary = transAnyState[1] == grBoundary
|
||||
if transAnyProp[2] < transAnyState[2] {
|
||||
boundary = transAnyProp[1] == grBoundary
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if okAnyProp {
|
||||
// We only have a specific state.
|
||||
return transAnyProp[0], prop, transAnyProp[1] == grBoundary
|
||||
// This branch will probably never be reached because okAnyState will
|
||||
// always be true given the current transition map. But we keep it here
|
||||
// for future modifications to the transition map where this may not be
|
||||
// true anymore.
|
||||
}
|
||||
|
||||
if okAnyState {
|
||||
// We only have a specific property.
|
||||
return transAnyState[0], prop, transAnyState[1] == grBoundary
|
||||
}
|
||||
|
||||
// No known transition. GB999: Any ÷ Any.
|
||||
return grAny, prop, true
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// FirstLineSegment returns the prefix of the given byte slice after which a
|
||||
// decision to break the string over to the next line can or must be made,
|
||||
// according to the rules of Unicode Standard Annex #14. This is used to
|
||||
// implement line breaking.
|
||||
//
|
||||
// Line breaking, also known as word wrapping, is the process of breaking a
|
||||
// section of text into lines such that it will fit in the available width of a
|
||||
// page, window or other display area.
|
||||
//
|
||||
// The returned "segment" may not be broken into smaller parts, unless no other
|
||||
// breaking opportunities present themselves, in which case you may break by
|
||||
// grapheme clusters (using the [FirstGraphemeCluster] function to determine the
|
||||
// grapheme clusters).
|
||||
//
|
||||
// The "mustBreak" flag indicates whether you MUST break the line after the
|
||||
// given segment (true), for example after newline characters, or you MAY break
|
||||
// the line after the given segment (false).
|
||||
//
|
||||
// This function can be called continuously to extract all non-breaking sub-sets
|
||||
// from a byte slice, as illustrated in the example below.
|
||||
//
|
||||
// If you don't know the current state, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified line segment. If the length of the
|
||||
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||
// "segment" byte slice is the sub-slice of the input slice containing the
|
||||
// identified line segment.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
//
|
||||
// Note that in accordance with UAX #14 LB3, the final segment will end with
|
||||
// "mustBreak" set to true. You can choose to ignore this by checking if the
|
||||
// length of the "rest" slice is 0 and calling [HasTrailingLineBreak] or
|
||||
// [HasTrailingLineBreakInString] on the last rune.
|
||||
//
|
||||
// Note also that this algorithm may break within grapheme clusters. This is
|
||||
// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use
|
||||
// the [Step] function instead.
|
||||
func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return b, nil, true, lbAny // LB3.
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionLineBreakState(state, r, b[length:], "")
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary int
|
||||
for {
|
||||
r, l := utf8.DecodeRune(b[length:])
|
||||
state, boundary = transitionLineBreakState(state, r, b[length+l:], "")
|
||||
|
||||
if boundary != LineDontBreak {
|
||||
return b[:length], b[length:], boundary == LineMustBreak, state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, true, lbAny // LB3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FirstLineSegmentInString is like FirstLineSegment() but its input and outputs
|
||||
// are strings.
|
||||
func FirstLineSegmentInString(str string, state int) (segment, rest string, mustBreak bool, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return str, "", true, lbAny // LB3.
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionLineBreakState(state, r, nil, str[length:])
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary int
|
||||
for {
|
||||
r, l := utf8.DecodeRuneInString(str[length:])
|
||||
state, boundary = transitionLineBreakState(state, r, nil, str[length+l:])
|
||||
|
||||
if boundary != LineDontBreak {
|
||||
return str[:length], str[length:], boundary == LineMustBreak, state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", true, lbAny // LB3.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HasTrailingLineBreak returns true if the last rune in the given byte slice is
|
||||
// one of the hard line break code points defined in LB4 and LB5 of [UAX #14].
|
||||
//
|
||||
// [UAX #14]: https://www.unicode.org/reports/tr14/#Algorithm
|
||||
func HasTrailingLineBreak(b []byte) bool {
|
||||
r, _ := utf8.DecodeLastRune(b)
|
||||
property, _ := propertyWithGenCat(lineBreakCodePoints, r)
|
||||
return property == lbBK || property == lbCR || property == lbLF || property == lbNL
|
||||
}
|
||||
|
||||
// HasTrailingLineBreakInString is like [HasTrailingLineBreak] but for a string.
|
||||
func HasTrailingLineBreakInString(str string) bool {
|
||||
r, _ := utf8.DecodeLastRuneInString(str)
|
||||
property, _ := propertyWithGenCat(lineBreakCodePoints, r)
|
||||
return property == lbBK || property == lbCR || property == lbLF || property == lbNL
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,470 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// The states of the line break parser.
|
||||
const (
|
||||
lbAny = iota
|
||||
lbBK
|
||||
lbCR
|
||||
lbLF
|
||||
lbNL
|
||||
lbSP
|
||||
lbZW
|
||||
lbWJ
|
||||
lbGL
|
||||
lbBA
|
||||
lbHY
|
||||
lbCL
|
||||
lbCP
|
||||
lbEX
|
||||
lbIS
|
||||
lbSY
|
||||
lbOP
|
||||
lbQU
|
||||
lbQUSP
|
||||
lbNS
|
||||
lbCLCPSP
|
||||
lbB2
|
||||
lbB2SP
|
||||
lbCB
|
||||
lbBB
|
||||
lbLB21a
|
||||
lbHL
|
||||
lbAL
|
||||
lbNU
|
||||
lbPR
|
||||
lbEB
|
||||
lbIDEM
|
||||
lbNUNU
|
||||
lbNUSY
|
||||
lbNUIS
|
||||
lbNUCL
|
||||
lbNUCP
|
||||
lbPO
|
||||
lbJL
|
||||
lbJV
|
||||
lbJT
|
||||
lbH2
|
||||
lbH3
|
||||
lbOddRI
|
||||
lbEvenRI
|
||||
lbExtPicCn
|
||||
lbZWJBit = 64
|
||||
lbCPeaFWHBit = 128
|
||||
)
|
||||
|
||||
// These constants define whether a given text may be broken into the next line.
|
||||
// If the break is optional (LineCanBreak), you may choose to break or not based
|
||||
// on your own criteria, for example, if the text has reached the available
|
||||
// width.
|
||||
const (
|
||||
LineDontBreak = iota // You may not break the line here.
|
||||
LineCanBreak // You may or may not break the line here.
|
||||
LineMustBreak // You must break the line here.
|
||||
)
|
||||
|
||||
// The line break parser's state transitions. It's anologous to grTransitions,
|
||||
// see comments there for details. Unicode version 14.0.0.
|
||||
var lbTransitions = map[[2]int][3]int{
|
||||
// LB4.
|
||||
{lbAny, prBK}: {lbBK, LineCanBreak, 310},
|
||||
{lbBK, prAny}: {lbAny, LineMustBreak, 40},
|
||||
|
||||
// LB5.
|
||||
{lbAny, prCR}: {lbCR, LineCanBreak, 310},
|
||||
{lbAny, prLF}: {lbLF, LineCanBreak, 310},
|
||||
{lbAny, prNL}: {lbNL, LineCanBreak, 310},
|
||||
{lbCR, prLF}: {lbLF, LineDontBreak, 50},
|
||||
{lbCR, prAny}: {lbAny, LineMustBreak, 50},
|
||||
{lbLF, prAny}: {lbAny, LineMustBreak, 50},
|
||||
{lbNL, prAny}: {lbAny, LineMustBreak, 50},
|
||||
|
||||
// LB6.
|
||||
{lbAny, prBK}: {lbBK, LineDontBreak, 60},
|
||||
{lbAny, prCR}: {lbCR, LineDontBreak, 60},
|
||||
{lbAny, prLF}: {lbLF, LineDontBreak, 60},
|
||||
{lbAny, prNL}: {lbNL, LineDontBreak, 60},
|
||||
|
||||
// LB7.
|
||||
{lbAny, prSP}: {lbSP, LineDontBreak, 70},
|
||||
{lbAny, prZW}: {lbZW, LineDontBreak, 70},
|
||||
|
||||
// LB8.
|
||||
{lbZW, prSP}: {lbZW, LineDontBreak, 70},
|
||||
{lbZW, prAny}: {lbAny, LineCanBreak, 80},
|
||||
|
||||
// LB11.
|
||||
{lbAny, prWJ}: {lbWJ, LineDontBreak, 110},
|
||||
{lbWJ, prAny}: {lbAny, LineDontBreak, 110},
|
||||
|
||||
// LB12.
|
||||
{lbAny, prGL}: {lbGL, LineCanBreak, 310},
|
||||
{lbGL, prAny}: {lbAny, LineDontBreak, 120},
|
||||
|
||||
// LB13 (simple transitions).
|
||||
{lbAny, prCL}: {lbCL, LineCanBreak, 310},
|
||||
{lbAny, prCP}: {lbCP, LineCanBreak, 310},
|
||||
{lbAny, prEX}: {lbEX, LineDontBreak, 130},
|
||||
{lbAny, prIS}: {lbIS, LineCanBreak, 310},
|
||||
{lbAny, prSY}: {lbSY, LineCanBreak, 310},
|
||||
|
||||
// LB14.
|
||||
{lbAny, prOP}: {lbOP, LineCanBreak, 310},
|
||||
{lbOP, prSP}: {lbOP, LineDontBreak, 70},
|
||||
{lbOP, prAny}: {lbAny, LineDontBreak, 140},
|
||||
|
||||
// LB15.
|
||||
{lbQU, prSP}: {lbQUSP, LineDontBreak, 70},
|
||||
{lbQU, prOP}: {lbOP, LineDontBreak, 150},
|
||||
{lbQUSP, prOP}: {lbOP, LineDontBreak, 150},
|
||||
|
||||
// LB16.
|
||||
{lbCL, prSP}: {lbCLCPSP, LineDontBreak, 70},
|
||||
{lbNUCL, prSP}: {lbCLCPSP, LineDontBreak, 70},
|
||||
{lbCP, prSP}: {lbCLCPSP, LineDontBreak, 70},
|
||||
{lbNUCP, prSP}: {lbCLCPSP, LineDontBreak, 70},
|
||||
{lbCL, prNS}: {lbNS, LineDontBreak, 160},
|
||||
{lbNUCL, prNS}: {lbNS, LineDontBreak, 160},
|
||||
{lbCP, prNS}: {lbNS, LineDontBreak, 160},
|
||||
{lbNUCP, prNS}: {lbNS, LineDontBreak, 160},
|
||||
{lbCLCPSP, prNS}: {lbNS, LineDontBreak, 160},
|
||||
|
||||
// LB17.
|
||||
{lbAny, prB2}: {lbB2, LineCanBreak, 310},
|
||||
{lbB2, prSP}: {lbB2SP, LineDontBreak, 70},
|
||||
{lbB2, prB2}: {lbB2, LineDontBreak, 170},
|
||||
{lbB2SP, prB2}: {lbB2, LineDontBreak, 170},
|
||||
|
||||
// LB18.
|
||||
{lbSP, prAny}: {lbAny, LineCanBreak, 180},
|
||||
{lbQUSP, prAny}: {lbAny, LineCanBreak, 180},
|
||||
{lbCLCPSP, prAny}: {lbAny, LineCanBreak, 180},
|
||||
{lbB2SP, prAny}: {lbAny, LineCanBreak, 180},
|
||||
|
||||
// LB19.
|
||||
{lbAny, prQU}: {lbQU, LineDontBreak, 190},
|
||||
{lbQU, prAny}: {lbAny, LineDontBreak, 190},
|
||||
|
||||
// LB20.
|
||||
{lbAny, prCB}: {lbCB, LineCanBreak, 200},
|
||||
{lbCB, prAny}: {lbAny, LineCanBreak, 200},
|
||||
|
||||
// LB21.
|
||||
{lbAny, prBA}: {lbBA, LineDontBreak, 210},
|
||||
{lbAny, prHY}: {lbHY, LineDontBreak, 210},
|
||||
{lbAny, prNS}: {lbNS, LineDontBreak, 210},
|
||||
{lbAny, prBB}: {lbBB, LineCanBreak, 310},
|
||||
{lbBB, prAny}: {lbAny, LineDontBreak, 210},
|
||||
|
||||
// LB21a.
|
||||
{lbAny, prHL}: {lbHL, LineCanBreak, 310},
|
||||
{lbHL, prHY}: {lbLB21a, LineDontBreak, 210},
|
||||
{lbHL, prBA}: {lbLB21a, LineDontBreak, 210},
|
||||
{lbLB21a, prAny}: {lbAny, LineDontBreak, 211},
|
||||
|
||||
// LB21b.
|
||||
{lbSY, prHL}: {lbHL, LineDontBreak, 212},
|
||||
{lbNUSY, prHL}: {lbHL, LineDontBreak, 212},
|
||||
|
||||
// LB22.
|
||||
{lbAny, prIN}: {lbAny, LineDontBreak, 220},
|
||||
|
||||
// LB23.
|
||||
{lbAny, prAL}: {lbAL, LineCanBreak, 310},
|
||||
{lbAny, prNU}: {lbNU, LineCanBreak, 310},
|
||||
{lbAL, prNU}: {lbNU, LineDontBreak, 230},
|
||||
{lbHL, prNU}: {lbNU, LineDontBreak, 230},
|
||||
{lbNU, prAL}: {lbAL, LineDontBreak, 230},
|
||||
{lbNU, prHL}: {lbHL, LineDontBreak, 230},
|
||||
{lbNUNU, prAL}: {lbAL, LineDontBreak, 230},
|
||||
{lbNUNU, prHL}: {lbHL, LineDontBreak, 230},
|
||||
|
||||
// LB23a.
|
||||
{lbAny, prPR}: {lbPR, LineCanBreak, 310},
|
||||
{lbAny, prID}: {lbIDEM, LineCanBreak, 310},
|
||||
{lbAny, prEB}: {lbEB, LineCanBreak, 310},
|
||||
{lbAny, prEM}: {lbIDEM, LineCanBreak, 310},
|
||||
{lbPR, prID}: {lbIDEM, LineDontBreak, 231},
|
||||
{lbPR, prEB}: {lbEB, LineDontBreak, 231},
|
||||
{lbPR, prEM}: {lbIDEM, LineDontBreak, 231},
|
||||
{lbIDEM, prPO}: {lbPO, LineDontBreak, 231},
|
||||
{lbEB, prPO}: {lbPO, LineDontBreak, 231},
|
||||
|
||||
// LB24.
|
||||
{lbAny, prPO}: {lbPO, LineCanBreak, 310},
|
||||
{lbPR, prAL}: {lbAL, LineDontBreak, 240},
|
||||
{lbPR, prHL}: {lbHL, LineDontBreak, 240},
|
||||
{lbPO, prAL}: {lbAL, LineDontBreak, 240},
|
||||
{lbPO, prHL}: {lbHL, LineDontBreak, 240},
|
||||
{lbAL, prPR}: {lbPR, LineDontBreak, 240},
|
||||
{lbAL, prPO}: {lbPO, LineDontBreak, 240},
|
||||
{lbHL, prPR}: {lbPR, LineDontBreak, 240},
|
||||
{lbHL, prPO}: {lbPO, LineDontBreak, 240},
|
||||
|
||||
// LB25 (simple transitions).
|
||||
{lbPR, prNU}: {lbNU, LineDontBreak, 250},
|
||||
{lbPO, prNU}: {lbNU, LineDontBreak, 250},
|
||||
{lbOP, prNU}: {lbNU, LineDontBreak, 250},
|
||||
{lbHY, prNU}: {lbNU, LineDontBreak, 250},
|
||||
{lbNU, prNU}: {lbNUNU, LineDontBreak, 250},
|
||||
{lbNU, prSY}: {lbNUSY, LineDontBreak, 250},
|
||||
{lbNU, prIS}: {lbNUIS, LineDontBreak, 250},
|
||||
{lbNUNU, prNU}: {lbNUNU, LineDontBreak, 250},
|
||||
{lbNUNU, prSY}: {lbNUSY, LineDontBreak, 250},
|
||||
{lbNUNU, prIS}: {lbNUIS, LineDontBreak, 250},
|
||||
{lbNUSY, prNU}: {lbNUNU, LineDontBreak, 250},
|
||||
{lbNUSY, prSY}: {lbNUSY, LineDontBreak, 250},
|
||||
{lbNUSY, prIS}: {lbNUIS, LineDontBreak, 250},
|
||||
{lbNUIS, prNU}: {lbNUNU, LineDontBreak, 250},
|
||||
{lbNUIS, prSY}: {lbNUSY, LineDontBreak, 250},
|
||||
{lbNUIS, prIS}: {lbNUIS, LineDontBreak, 250},
|
||||
{lbNU, prCL}: {lbNUCL, LineDontBreak, 250},
|
||||
{lbNU, prCP}: {lbNUCP, LineDontBreak, 250},
|
||||
{lbNUNU, prCL}: {lbNUCL, LineDontBreak, 250},
|
||||
{lbNUNU, prCP}: {lbNUCP, LineDontBreak, 250},
|
||||
{lbNUSY, prCL}: {lbNUCL, LineDontBreak, 250},
|
||||
{lbNUSY, prCP}: {lbNUCP, LineDontBreak, 250},
|
||||
{lbNUIS, prCL}: {lbNUCL, LineDontBreak, 250},
|
||||
{lbNUIS, prCP}: {lbNUCP, LineDontBreak, 250},
|
||||
{lbNU, prPO}: {lbPO, LineDontBreak, 250},
|
||||
{lbNUNU, prPO}: {lbPO, LineDontBreak, 250},
|
||||
{lbNUSY, prPO}: {lbPO, LineDontBreak, 250},
|
||||
{lbNUIS, prPO}: {lbPO, LineDontBreak, 250},
|
||||
{lbNUCL, prPO}: {lbPO, LineDontBreak, 250},
|
||||
{lbNUCP, prPO}: {lbPO, LineDontBreak, 250},
|
||||
{lbNU, prPR}: {lbPR, LineDontBreak, 250},
|
||||
{lbNUNU, prPR}: {lbPR, LineDontBreak, 250},
|
||||
{lbNUSY, prPR}: {lbPR, LineDontBreak, 250},
|
||||
{lbNUIS, prPR}: {lbPR, LineDontBreak, 250},
|
||||
{lbNUCL, prPR}: {lbPR, LineDontBreak, 250},
|
||||
{lbNUCP, prPR}: {lbPR, LineDontBreak, 250},
|
||||
|
||||
// LB26.
|
||||
{lbAny, prJL}: {lbJL, LineCanBreak, 310},
|
||||
{lbAny, prJV}: {lbJV, LineCanBreak, 310},
|
||||
{lbAny, prJT}: {lbJT, LineCanBreak, 310},
|
||||
{lbAny, prH2}: {lbH2, LineCanBreak, 310},
|
||||
{lbAny, prH3}: {lbH3, LineCanBreak, 310},
|
||||
{lbJL, prJL}: {lbJL, LineDontBreak, 260},
|
||||
{lbJL, prJV}: {lbJV, LineDontBreak, 260},
|
||||
{lbJL, prH2}: {lbH2, LineDontBreak, 260},
|
||||
{lbJL, prH3}: {lbH3, LineDontBreak, 260},
|
||||
{lbJV, prJV}: {lbJV, LineDontBreak, 260},
|
||||
{lbJV, prJT}: {lbJT, LineDontBreak, 260},
|
||||
{lbH2, prJV}: {lbJV, LineDontBreak, 260},
|
||||
{lbH2, prJT}: {lbJT, LineDontBreak, 260},
|
||||
{lbJT, prJT}: {lbJT, LineDontBreak, 260},
|
||||
{lbH3, prJT}: {lbJT, LineDontBreak, 260},
|
||||
|
||||
// LB27.
|
||||
{lbJL, prPO}: {lbPO, LineDontBreak, 270},
|
||||
{lbJV, prPO}: {lbPO, LineDontBreak, 270},
|
||||
{lbJT, prPO}: {lbPO, LineDontBreak, 270},
|
||||
{lbH2, prPO}: {lbPO, LineDontBreak, 270},
|
||||
{lbH3, prPO}: {lbPO, LineDontBreak, 270},
|
||||
{lbPR, prJL}: {lbJL, LineDontBreak, 270},
|
||||
{lbPR, prJV}: {lbJV, LineDontBreak, 270},
|
||||
{lbPR, prJT}: {lbJT, LineDontBreak, 270},
|
||||
{lbPR, prH2}: {lbH2, LineDontBreak, 270},
|
||||
{lbPR, prH3}: {lbH3, LineDontBreak, 270},
|
||||
|
||||
// LB28.
|
||||
{lbAL, prAL}: {lbAL, LineDontBreak, 280},
|
||||
{lbAL, prHL}: {lbHL, LineDontBreak, 280},
|
||||
{lbHL, prAL}: {lbAL, LineDontBreak, 280},
|
||||
{lbHL, prHL}: {lbHL, LineDontBreak, 280},
|
||||
|
||||
// LB29.
|
||||
{lbIS, prAL}: {lbAL, LineDontBreak, 290},
|
||||
{lbIS, prHL}: {lbHL, LineDontBreak, 290},
|
||||
{lbNUIS, prAL}: {lbAL, LineDontBreak, 290},
|
||||
{lbNUIS, prHL}: {lbHL, LineDontBreak, 290},
|
||||
}
|
||||
|
||||
// transitionLineBreakState determines the new state of the line break parser
|
||||
// given the current state and the next code point. It also returns the type of
|
||||
// line break: LineDontBreak, LineCanBreak, or LineMustBreak. If more than one
|
||||
// code point is needed to determine the new state, the byte slice or the string
|
||||
// starting after rune "r" can be used (whichever is not nil or empty) for
|
||||
// further lookups.
|
||||
func transitionLineBreakState(state int, r rune, b []byte, str string) (newState int, lineBreak int) {
|
||||
// Determine the property of the next character.
|
||||
nextProperty, generalCategory := propertyWithGenCat(lineBreakCodePoints, r)
|
||||
|
||||
// Prepare.
|
||||
var forceNoBreak, isCPeaFWH bool
|
||||
if state >= 0 && state&lbCPeaFWHBit != 0 {
|
||||
isCPeaFWH = true // LB30: CP but ea is not F, W, or H.
|
||||
state = state &^ lbCPeaFWHBit
|
||||
}
|
||||
if state >= 0 && state&lbZWJBit != 0 {
|
||||
state = state &^ lbZWJBit // Extract zero-width joiner bit.
|
||||
forceNoBreak = true // LB8a.
|
||||
}
|
||||
|
||||
defer func() {
|
||||
// Transition into LB30.
|
||||
if newState == lbCP || newState == lbNUCP {
|
||||
ea := property(eastAsianWidth, r)
|
||||
if ea != prF && ea != prW && ea != prH {
|
||||
newState |= lbCPeaFWHBit
|
||||
}
|
||||
}
|
||||
|
||||
// Override break.
|
||||
if forceNoBreak {
|
||||
lineBreak = LineDontBreak
|
||||
}
|
||||
}()
|
||||
|
||||
// LB1.
|
||||
if nextProperty == prAI || nextProperty == prSG || nextProperty == prXX {
|
||||
nextProperty = prAL
|
||||
} else if nextProperty == prSA {
|
||||
if generalCategory == gcMn || generalCategory == gcMc {
|
||||
nextProperty = prCM
|
||||
} else {
|
||||
nextProperty = prAL
|
||||
}
|
||||
} else if nextProperty == prCJ {
|
||||
nextProperty = prNS
|
||||
}
|
||||
|
||||
// Combining marks.
|
||||
if nextProperty == prZWJ || nextProperty == prCM {
|
||||
var bit int
|
||||
if nextProperty == prZWJ {
|
||||
bit = lbZWJBit
|
||||
}
|
||||
mustBreakState := state < 0 || state == lbBK || state == lbCR || state == lbLF || state == lbNL
|
||||
if !mustBreakState && state != lbSP && state != lbZW && state != lbQUSP && state != lbCLCPSP && state != lbB2SP {
|
||||
// LB9.
|
||||
return state | bit, LineDontBreak
|
||||
} else {
|
||||
// LB10.
|
||||
if mustBreakState {
|
||||
return lbAL | bit, LineMustBreak
|
||||
}
|
||||
return lbAL | bit, LineCanBreak
|
||||
}
|
||||
}
|
||||
|
||||
// Find the applicable transition in the table.
|
||||
var rule int
|
||||
transition, ok := lbTransitions[[2]int{state, nextProperty}]
|
||||
if ok {
|
||||
// We have a specific transition. We'll use it.
|
||||
newState, lineBreak, rule = transition[0], transition[1], transition[2]
|
||||
} else {
|
||||
// No specific transition found. Try the less specific ones.
|
||||
transAnyProp, okAnyProp := lbTransitions[[2]int{state, prAny}]
|
||||
transAnyState, okAnyState := lbTransitions[[2]int{lbAny, nextProperty}]
|
||||
if okAnyProp && okAnyState {
|
||||
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||
newState, lineBreak, rule = transAnyState[0], transAnyState[1], transAnyState[2]
|
||||
if transAnyProp[2] < transAnyState[2] {
|
||||
lineBreak, rule = transAnyProp[1], transAnyProp[2]
|
||||
}
|
||||
} else if okAnyProp {
|
||||
// We only have a specific state.
|
||||
newState, lineBreak, rule = transAnyProp[0], transAnyProp[1], transAnyProp[2]
|
||||
// This branch will probably never be reached because okAnyState will
|
||||
// always be true given the current transition map. But we keep it here
|
||||
// for future modifications to the transition map where this may not be
|
||||
// true anymore.
|
||||
} else if okAnyState {
|
||||
// We only have a specific property.
|
||||
newState, lineBreak, rule = transAnyState[0], transAnyState[1], transAnyState[2]
|
||||
} else {
|
||||
// No known transition. LB31: ALL ÷ ALL.
|
||||
newState, lineBreak, rule = lbAny, LineCanBreak, 310
|
||||
}
|
||||
}
|
||||
|
||||
// LB12a.
|
||||
if rule > 121 &&
|
||||
nextProperty == prGL &&
|
||||
(state != lbSP && state != lbBA && state != lbHY && state != lbLB21a && state != lbQUSP && state != lbCLCPSP && state != lbB2SP) {
|
||||
return lbGL, LineDontBreak
|
||||
}
|
||||
|
||||
// LB13.
|
||||
if rule > 130 && state != lbNU && state != lbNUNU {
|
||||
switch nextProperty {
|
||||
case prCL:
|
||||
return lbCL, LineDontBreak
|
||||
case prCP:
|
||||
return lbCP, LineDontBreak
|
||||
case prIS:
|
||||
return lbIS, LineDontBreak
|
||||
case prSY:
|
||||
return lbSY, LineDontBreak
|
||||
}
|
||||
}
|
||||
|
||||
// LB25 (look ahead).
|
||||
if rule > 250 &&
|
||||
(state == lbPR || state == lbPO) &&
|
||||
nextProperty == prOP || nextProperty == prHY {
|
||||
var r rune
|
||||
if b != nil { // Byte slice version.
|
||||
r, _ = utf8.DecodeRune(b)
|
||||
} else { // String version.
|
||||
r, _ = utf8.DecodeRuneInString(str)
|
||||
}
|
||||
if r != utf8.RuneError {
|
||||
pr, _ := propertyWithGenCat(lineBreakCodePoints, r)
|
||||
if pr == prNU {
|
||||
return lbNU, LineDontBreak
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LB30 (part one).
|
||||
if rule > 300 {
|
||||
if (state == lbAL || state == lbHL || state == lbNU || state == lbNUNU) && nextProperty == prOP {
|
||||
ea := property(eastAsianWidth, r)
|
||||
if ea != prF && ea != prW && ea != prH {
|
||||
return lbOP, LineDontBreak
|
||||
}
|
||||
} else if isCPeaFWH {
|
||||
switch nextProperty {
|
||||
case prAL:
|
||||
return lbAL, LineDontBreak
|
||||
case prHL:
|
||||
return lbHL, LineDontBreak
|
||||
case prNU:
|
||||
return lbNU, LineDontBreak
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LB30a.
|
||||
if newState == lbAny && nextProperty == prRI {
|
||||
if state != lbOddRI && state != lbEvenRI { // Includes state == -1.
|
||||
// Transition into the first RI.
|
||||
return lbOddRI, lineBreak
|
||||
}
|
||||
if state == lbOddRI {
|
||||
// Don't break pairs of Regional Indicators.
|
||||
return lbEvenRI, LineDontBreak
|
||||
}
|
||||
return lbOddRI, lineBreak
|
||||
}
|
||||
|
||||
// LB30b.
|
||||
if rule > 302 {
|
||||
if nextProperty == prEM {
|
||||
if state == lbEB || state == lbExtPicCn {
|
||||
return prAny, LineDontBreak
|
||||
}
|
||||
}
|
||||
graphemeProperty := property(graphemeCodePoints, r)
|
||||
if graphemeProperty == prExtendedPictographic && generalCategory == gcCn {
|
||||
return lbExtPicCn, LineCanBreak
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,88 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// FirstSentence returns the first sentence found in the given byte slice
|
||||
// according to the rules of Unicode Standard Annex #29, Sentence Boundaries.
|
||||
// This function can be called continuously to extract all sentences from a byte
|
||||
// slice, as illustrated in the example below.
|
||||
//
|
||||
// If you don't know the current state, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified sentence. If the length of the "rest"
|
||||
// slice is 0, the entire byte slice "b" has been processed. The "sentence" byte
|
||||
// slice is the sub-slice of the input slice containing the identified sentence.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
func FirstSentence(b []byte, state int) (sentence, rest []byte, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return b, nil, sbAny
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionSentenceBreakState(state, r, b[length:], "")
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary bool
|
||||
for {
|
||||
r, l := utf8.DecodeRune(b[length:])
|
||||
state, boundary = transitionSentenceBreakState(state, r, b[length+l:], "")
|
||||
|
||||
if boundary {
|
||||
return b[:length], b[length:], state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, sbAny
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FirstSentenceInString is like [FirstSentence] but its input and outputs are
|
||||
// strings.
|
||||
func FirstSentenceInString(str string, state int) (sentence, rest string, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return str, "", sbAny
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionSentenceBreakState(state, r, nil, str[length:])
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary bool
|
||||
for {
|
||||
r, l := utf8.DecodeRuneInString(str[length:])
|
||||
state, boundary = transitionSentenceBreakState(state, r, nil, str[length+l:])
|
||||
|
||||
if boundary {
|
||||
return str[:length], str[length:], state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", sbAny
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,244 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// The bit masks used to extract boundary information returned by [Step].
|
||||
const (
|
||||
MaskLine = 3
|
||||
MaskWord = 4
|
||||
MaskSentence = 8
|
||||
)
|
||||
|
||||
// The number of bits to shift the boundary information returned by [Step] to
|
||||
// obtain the monospace width of the grapheme cluster.
|
||||
const ShiftWidth = 4
|
||||
|
||||
// The bit positions by which boundary flags are shifted by the [Step] function.
|
||||
// These must correspond to the Mask constants.
|
||||
const (
|
||||
shiftWord = 2
|
||||
shiftSentence = 3
|
||||
// shiftwWidth is ShiftWidth above. No mask as these are always the remaining bits.
|
||||
)
|
||||
|
||||
// The bit positions by which states are shifted by the [Step] function. These
|
||||
// values must ensure state values defined for each of the boundary algorithms
|
||||
// don't overlap (and that they all still fit in a single int). These must
|
||||
// correspond to the Mask constants.
|
||||
const (
|
||||
shiftWordState = 4
|
||||
shiftSentenceState = 9
|
||||
shiftLineState = 13
|
||||
shiftPropState = 21 // No mask as these are always the remaining bits.
|
||||
)
|
||||
|
||||
// The bit mask used to extract the state returned by the [Step] function, after
|
||||
// shifting. These values must correspond to the shift constants.
|
||||
const (
|
||||
maskGraphemeState = 0xf
|
||||
maskWordState = 0x1f
|
||||
maskSentenceState = 0xf
|
||||
maskLineState = 0xff
|
||||
)
|
||||
|
||||
// Step returns the first grapheme cluster (user-perceived character) found in
|
||||
// the given byte slice. It also returns information about the boundary between
|
||||
// that grapheme cluster and the one following it as well as the monospace width
|
||||
// of the grapheme cluster. There are three types of boundary information: word
|
||||
// boundaries, sentence boundaries, and line breaks. This function is therefore
|
||||
// a combination of [FirstGraphemeCluster], [FirstWord], [FirstSentence], and
|
||||
// [FirstLineSegment].
|
||||
//
|
||||
// The "boundaries" return value can be evaluated as follows:
|
||||
//
|
||||
// - boundaries&MaskWord != 0: The boundary is a word boundary.
|
||||
// - boundaries&MaskWord == 0: The boundary is not a word boundary.
|
||||
// - boundaries&MaskSentence != 0: The boundary is a sentence boundary.
|
||||
// - boundaries&MaskSentence == 0: The boundary is not a sentence boundary.
|
||||
// - boundaries&MaskLine == LineDontBreak: You must not break the line at the
|
||||
// boundary.
|
||||
// - boundaries&MaskLine == LineMustBreak: You must break the line at the
|
||||
// boundary.
|
||||
// - boundaries&MaskLine == LineCanBreak: You may or may not break the line at
|
||||
// the boundary.
|
||||
// - boundaries >> ShiftWidth: The width of the grapheme cluster for most
|
||||
// monospace fonts where a value of 1 represents one character cell.
|
||||
//
|
||||
// This function can be called continuously to extract all grapheme clusters
|
||||
// from a byte slice, as illustrated in the examples below.
|
||||
//
|
||||
// If you don't know which state to pass, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified grapheme cluster. If the length of the
|
||||
// "rest" slice is 0, the entire byte slice "b" has been processed. The
|
||||
// "cluster" byte slice is the sub-slice of the input slice containing the
|
||||
// first identified grapheme cluster.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
//
|
||||
// While slightly less convenient than using the Graphemes class, this function
|
||||
// has much better performance and makes no allocations. It lends itself well to
|
||||
// large byte slices.
|
||||
//
|
||||
// Note that in accordance with UAX #14 LB3, the final segment will end with
|
||||
// a mandatory line break (boundaries&MaskLine == LineMustBreak). You can choose
|
||||
// to ignore this by checking if the length of the "rest" slice is 0 and calling
|
||||
// [HasTrailingLineBreak] or [HasTrailingLineBreakInString] on the last rune.
|
||||
func Step(b []byte, state int) (cluster, rest []byte, boundaries int, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
var prop int
|
||||
if state < 0 {
|
||||
prop = property(graphemeCodePoints, r)
|
||||
} else {
|
||||
prop = state >> shiftPropState
|
||||
}
|
||||
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
var graphemeState, wordState, sentenceState, lineState, firstProp int
|
||||
remainder := b[length:]
|
||||
if state < 0 {
|
||||
graphemeState, firstProp, _ = transitionGraphemeState(state, r)
|
||||
wordState, _ = transitionWordBreakState(state, r, remainder, "")
|
||||
sentenceState, _ = transitionSentenceBreakState(state, r, remainder, "")
|
||||
lineState, _ = transitionLineBreakState(state, r, remainder, "")
|
||||
} else {
|
||||
graphemeState = state & maskGraphemeState
|
||||
wordState = (state >> shiftWordState) & maskWordState
|
||||
sentenceState = (state >> shiftSentenceState) & maskSentenceState
|
||||
lineState = (state >> shiftLineState) & maskLineState
|
||||
firstProp = state >> shiftPropState
|
||||
}
|
||||
|
||||
// Transition until we find a grapheme cluster boundary.
|
||||
width := runeWidth(r, firstProp)
|
||||
for {
|
||||
var (
|
||||
graphemeBoundary, wordBoundary, sentenceBoundary bool
|
||||
lineBreak, prop int
|
||||
)
|
||||
|
||||
r, l := utf8.DecodeRune(remainder)
|
||||
remainder = b[length+l:]
|
||||
|
||||
graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
|
||||
wordState, wordBoundary = transitionWordBreakState(wordState, r, remainder, "")
|
||||
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, remainder, "")
|
||||
lineState, lineBreak = transitionLineBreakState(lineState, r, remainder, "")
|
||||
|
||||
if graphemeBoundary {
|
||||
boundary := lineBreak | (width << ShiftWidth)
|
||||
if wordBoundary {
|
||||
boundary |= 1 << shiftWord
|
||||
}
|
||||
if sentenceBoundary {
|
||||
boundary |= 1 << shiftSentence
|
||||
}
|
||||
return b[:length], b[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
|
||||
if r == vs16 {
|
||||
width = 2
|
||||
} else if firstProp != prExtendedPictographic && firstProp != prRegionalIndicator && firstProp != prL {
|
||||
width += runeWidth(r, prop)
|
||||
} else if firstProp == prExtendedPictographic {
|
||||
if r == vs15 {
|
||||
width = 1
|
||||
} else {
|
||||
width = 2
|
||||
}
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StepString is like [Step] but its input and outputs are strings.
|
||||
func StepString(str string, state int) (cluster, rest string, boundaries int, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
prop := property(graphemeCodePoints, r)
|
||||
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (runeWidth(r, prop) << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState)
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
var graphemeState, wordState, sentenceState, lineState, firstProp int
|
||||
remainder := str[length:]
|
||||
if state < 0 {
|
||||
graphemeState, firstProp, _ = transitionGraphemeState(state, r)
|
||||
wordState, _ = transitionWordBreakState(state, r, nil, remainder)
|
||||
sentenceState, _ = transitionSentenceBreakState(state, r, nil, remainder)
|
||||
lineState, _ = transitionLineBreakState(state, r, nil, remainder)
|
||||
} else {
|
||||
graphemeState = state & maskGraphemeState
|
||||
wordState = (state >> shiftWordState) & maskWordState
|
||||
sentenceState = (state >> shiftSentenceState) & maskSentenceState
|
||||
lineState = (state >> shiftLineState) & maskLineState
|
||||
firstProp = state >> shiftPropState
|
||||
}
|
||||
|
||||
// Transition until we find a grapheme cluster boundary.
|
||||
width := runeWidth(r, firstProp)
|
||||
for {
|
||||
var (
|
||||
graphemeBoundary, wordBoundary, sentenceBoundary bool
|
||||
lineBreak, prop int
|
||||
)
|
||||
|
||||
r, l := utf8.DecodeRuneInString(remainder)
|
||||
remainder = str[length+l:]
|
||||
|
||||
graphemeState, prop, graphemeBoundary = transitionGraphemeState(graphemeState, r)
|
||||
wordState, wordBoundary = transitionWordBreakState(wordState, r, nil, remainder)
|
||||
sentenceState, sentenceBoundary = transitionSentenceBreakState(sentenceState, r, nil, remainder)
|
||||
lineState, lineBreak = transitionLineBreakState(lineState, r, nil, remainder)
|
||||
|
||||
if graphemeBoundary {
|
||||
boundary := lineBreak | (width << ShiftWidth)
|
||||
if wordBoundary {
|
||||
boundary |= 1 << shiftWord
|
||||
}
|
||||
if sentenceBoundary {
|
||||
boundary |= 1 << shiftSentence
|
||||
}
|
||||
return str[:length], str[length:], boundary, graphemeState | (wordState << shiftWordState) | (sentenceState << shiftSentenceState) | (lineState << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
|
||||
if r == vs16 {
|
||||
width = 2
|
||||
} else if firstProp != prExtendedPictographic && firstProp != prRegionalIndicator && firstProp != prL {
|
||||
width += runeWidth(r, prop)
|
||||
} else if firstProp == prExtendedPictographic {
|
||||
if r == vs15 {
|
||||
width = 1
|
||||
} else {
|
||||
width = 2
|
||||
}
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", LineMustBreak | (1 << shiftWord) | (1 << shiftSentence) | (width << ShiftWidth), grAny | (wbAny << shiftWordState) | (sbAny << shiftSentenceState) | (lbAny << shiftLineState) | (prop << shiftPropState)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package uniseg
|
||||
|
||||
// runeWidth returns the monospace width for the given rune. The provided
|
||||
// grapheme property is a value mapped by the [graphemeCodePoints] table.
|
||||
//
|
||||
// Every rune has a width of 1, except for runes with the following properties
|
||||
// (evaluated in this order):
|
||||
//
|
||||
// - Control, CR, LF, Extend, ZWJ: Width of 0
|
||||
// - \u2e3a, TWO-EM DASH: Width of 3
|
||||
// - \u2e3b, THREE-EM DASH: Width of 4
|
||||
// - East-Asian width Fullwidth and Wide: Width of 2 (Ambiguous and Neutral
|
||||
// have a width of 1)
|
||||
// - Regional Indicator: Width of 2
|
||||
// - Extended Pictographic: Width of 2, unless Emoji Presentation is "No".
|
||||
func runeWidth(r rune, graphemeProperty int) int {
|
||||
switch graphemeProperty {
|
||||
case prControl, prCR, prLF, prExtend, prZWJ:
|
||||
return 0
|
||||
case prRegionalIndicator:
|
||||
return 2
|
||||
case prExtendedPictographic:
|
||||
if property(emojiPresentation, r) == prEmojiPresentation {
|
||||
return 2
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
switch r {
|
||||
case 0x2e3a:
|
||||
return 3
|
||||
case 0x2e3b:
|
||||
return 4
|
||||
}
|
||||
|
||||
switch property(eastAsianWidth, r) {
|
||||
case prW, prF:
|
||||
return 2
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
// StringWidth returns the monospace width for the given string, that is, the
|
||||
// number of same-size cells to be occupied by the string.
|
||||
func StringWidth(s string) (width int) {
|
||||
state := -1
|
||||
for len(s) > 0 {
|
||||
var w int
|
||||
_, s, w, state = FirstGraphemeClusterInString(s, state)
|
||||
width += w
|
||||
}
|
||||
return
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// FirstWord returns the first word found in the given byte slice according to
|
||||
// the rules of Unicode Standard Annex #29, Word Boundaries. This function can
|
||||
// be called continuously to extract all words from a byte slice, as illustrated
|
||||
// in the example below.
|
||||
//
|
||||
// If you don't know the current state, for example when calling the function
|
||||
// for the first time, you must pass -1. For consecutive calls, pass the state
|
||||
// and rest slice returned by the previous call.
|
||||
//
|
||||
// The "rest" slice is the sub-slice of the original byte slice "b" starting
|
||||
// after the last byte of the identified word. If the length of the "rest" slice
|
||||
// is 0, the entire byte slice "b" has been processed. The "word" byte slice is
|
||||
// the sub-slice of the input slice containing the identified word.
|
||||
//
|
||||
// Given an empty byte slice "b", the function returns nil values.
|
||||
func FirstWord(b []byte, state int) (word, rest []byte, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(b) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRune(b)
|
||||
if len(b) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return b, nil, wbAny
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionWordBreakState(state, r, b[length:], "")
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary bool
|
||||
for {
|
||||
r, l := utf8.DecodeRune(b[length:])
|
||||
state, boundary = transitionWordBreakState(state, r, b[length+l:], "")
|
||||
|
||||
if boundary {
|
||||
return b[:length], b[length:], state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(b) <= length {
|
||||
return b, nil, wbAny
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FirstWordInString is like [FirstWord] but its input and outputs are strings.
|
||||
func FirstWordInString(str string, state int) (word, rest string, newState int) {
|
||||
// An empty byte slice returns nothing.
|
||||
if len(str) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract the first rune.
|
||||
r, length := utf8.DecodeRuneInString(str)
|
||||
if len(str) <= length { // If we're already past the end, there is nothing else to parse.
|
||||
return str, "", wbAny
|
||||
}
|
||||
|
||||
// If we don't know the state, determine it now.
|
||||
if state < 0 {
|
||||
state, _ = transitionWordBreakState(state, r, nil, str[length:])
|
||||
}
|
||||
|
||||
// Transition until we find a boundary.
|
||||
var boundary bool
|
||||
for {
|
||||
r, l := utf8.DecodeRuneInString(str[length:])
|
||||
state, boundary = transitionWordBreakState(state, r, nil, str[length+l:])
|
||||
|
||||
if boundary {
|
||||
return str[:length], str[length:], state
|
||||
}
|
||||
|
||||
length += l
|
||||
if len(str) <= length {
|
||||
return str, "", wbAny
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,246 @@
|
||||
package uniseg
|
||||
|
||||
import "unicode/utf8"
|
||||
|
||||
// The states of the word break parser.
|
||||
const (
|
||||
wbAny = iota
|
||||
wbCR
|
||||
wbLF
|
||||
wbNewline
|
||||
wbWSegSpace
|
||||
wbHebrewLetter
|
||||
wbALetter
|
||||
wbWB7
|
||||
wbWB7c
|
||||
wbNumeric
|
||||
wbWB11
|
||||
wbKatakana
|
||||
wbExtendNumLet
|
||||
wbOddRI
|
||||
wbEvenRI
|
||||
wbZWJBit = 16 // This bit is set for any states followed by at least one zero-width joiner (see WB4 and WB3c).
|
||||
)
|
||||
|
||||
// The word break parser's breaking instructions.
|
||||
const (
|
||||
wbDontBreak = iota
|
||||
wbBreak
|
||||
)
|
||||
|
||||
// The word break parser's state transitions. It's anologous to grTransitions,
|
||||
// see comments there for details. Unicode version 14.0.0.
|
||||
var wbTransitions = map[[2]int][3]int{
|
||||
// WB3b.
|
||||
{wbAny, prNewline}: {wbNewline, wbBreak, 32},
|
||||
{wbAny, prCR}: {wbCR, wbBreak, 32},
|
||||
{wbAny, prLF}: {wbLF, wbBreak, 32},
|
||||
|
||||
// WB3a.
|
||||
{wbNewline, prAny}: {wbAny, wbBreak, 31},
|
||||
{wbCR, prAny}: {wbAny, wbBreak, 31},
|
||||
{wbLF, prAny}: {wbAny, wbBreak, 31},
|
||||
|
||||
// WB3.
|
||||
{wbCR, prLF}: {wbLF, wbDontBreak, 30},
|
||||
|
||||
// WB3d.
|
||||
{wbAny, prWSegSpace}: {wbWSegSpace, wbBreak, 9990},
|
||||
{wbWSegSpace, prWSegSpace}: {wbWSegSpace, wbDontBreak, 34},
|
||||
|
||||
// WB5.
|
||||
{wbAny, prALetter}: {wbALetter, wbBreak, 9990},
|
||||
{wbAny, prHebrewLetter}: {wbHebrewLetter, wbBreak, 9990},
|
||||
{wbALetter, prALetter}: {wbALetter, wbDontBreak, 50},
|
||||
{wbALetter, prHebrewLetter}: {wbHebrewLetter, wbDontBreak, 50},
|
||||
{wbHebrewLetter, prALetter}: {wbALetter, wbDontBreak, 50},
|
||||
{wbHebrewLetter, prHebrewLetter}: {wbHebrewLetter, wbDontBreak, 50},
|
||||
|
||||
// WB7. Transitions to wbWB7 handled by transitionWordBreakState().
|
||||
{wbWB7, prALetter}: {wbALetter, wbDontBreak, 70},
|
||||
{wbWB7, prHebrewLetter}: {wbHebrewLetter, wbDontBreak, 70},
|
||||
|
||||
// WB7a.
|
||||
{wbHebrewLetter, prSingleQuote}: {wbAny, wbDontBreak, 71},
|
||||
|
||||
// WB7c. Transitions to wbWB7c handled by transitionWordBreakState().
|
||||
{wbWB7c, prHebrewLetter}: {wbHebrewLetter, wbDontBreak, 73},
|
||||
|
||||
// WB8.
|
||||
{wbAny, prNumeric}: {wbNumeric, wbBreak, 9990},
|
||||
{wbNumeric, prNumeric}: {wbNumeric, wbDontBreak, 80},
|
||||
|
||||
// WB9.
|
||||
{wbALetter, prNumeric}: {wbNumeric, wbDontBreak, 90},
|
||||
{wbHebrewLetter, prNumeric}: {wbNumeric, wbDontBreak, 90},
|
||||
|
||||
// WB10.
|
||||
{wbNumeric, prALetter}: {wbALetter, wbDontBreak, 100},
|
||||
{wbNumeric, prHebrewLetter}: {wbHebrewLetter, wbDontBreak, 100},
|
||||
|
||||
// WB11. Transitions to wbWB11 handled by transitionWordBreakState().
|
||||
{wbWB11, prNumeric}: {wbNumeric, wbDontBreak, 110},
|
||||
|
||||
// WB13.
|
||||
{wbAny, prKatakana}: {wbKatakana, wbBreak, 9990},
|
||||
{wbKatakana, prKatakana}: {wbKatakana, wbDontBreak, 130},
|
||||
|
||||
// WB13a.
|
||||
{wbAny, prExtendNumLet}: {wbExtendNumLet, wbBreak, 9990},
|
||||
{wbALetter, prExtendNumLet}: {wbExtendNumLet, wbDontBreak, 131},
|
||||
{wbHebrewLetter, prExtendNumLet}: {wbExtendNumLet, wbDontBreak, 131},
|
||||
{wbNumeric, prExtendNumLet}: {wbExtendNumLet, wbDontBreak, 131},
|
||||
{wbKatakana, prExtendNumLet}: {wbExtendNumLet, wbDontBreak, 131},
|
||||
{wbExtendNumLet, prExtendNumLet}: {wbExtendNumLet, wbDontBreak, 131},
|
||||
|
||||
// WB13b.
|
||||
{wbExtendNumLet, prALetter}: {wbALetter, wbDontBreak, 132},
|
||||
{wbExtendNumLet, prHebrewLetter}: {wbHebrewLetter, wbDontBreak, 132},
|
||||
{wbExtendNumLet, prNumeric}: {wbNumeric, wbDontBreak, 132},
|
||||
{wbExtendNumLet, prKatakana}: {prKatakana, wbDontBreak, 132},
|
||||
}
|
||||
|
||||
// transitionWordBreakState determines the new state of the word break parser
|
||||
// given the current state and the next code point. It also returns whether a
|
||||
// word boundary was detected. If more than one code point is needed to
|
||||
// determine the new state, the byte slice or the string starting after rune "r"
|
||||
// can be used (whichever is not nil or empty) for further lookups.
|
||||
func transitionWordBreakState(state int, r rune, b []byte, str string) (newState int, wordBreak bool) {
|
||||
// Determine the property of the next character.
|
||||
nextProperty := property(workBreakCodePoints, r)
|
||||
|
||||
// "Replacing Ignore Rules".
|
||||
if nextProperty == prZWJ {
|
||||
// WB4 (for zero-width joiners).
|
||||
if state == wbNewline || state == wbCR || state == wbLF {
|
||||
return wbAny | wbZWJBit, true // Make sure we don't apply WB4 to WB3a.
|
||||
}
|
||||
if state < 0 {
|
||||
return wbAny | wbZWJBit, false
|
||||
}
|
||||
return state | wbZWJBit, false
|
||||
} else if nextProperty == prExtend || nextProperty == prFormat {
|
||||
// WB4 (for Extend and Format).
|
||||
if state == wbNewline || state == wbCR || state == wbLF {
|
||||
return wbAny, true // Make sure we don't apply WB4 to WB3a.
|
||||
}
|
||||
if state == wbWSegSpace || state == wbAny|wbZWJBit {
|
||||
return wbAny, false // We don't break but this is also not WB3d or WB3c.
|
||||
}
|
||||
if state < 0 {
|
||||
return wbAny, false
|
||||
}
|
||||
return state, false
|
||||
} else if nextProperty == prExtendedPictographic && state >= 0 && state&wbZWJBit != 0 {
|
||||
// WB3c.
|
||||
return wbAny, false
|
||||
}
|
||||
if state >= 0 {
|
||||
state = state &^ wbZWJBit
|
||||
}
|
||||
|
||||
// Find the applicable transition in the table.
|
||||
var rule int
|
||||
transition, ok := wbTransitions[[2]int{state, nextProperty}]
|
||||
if ok {
|
||||
// We have a specific transition. We'll use it.
|
||||
newState, wordBreak, rule = transition[0], transition[1] == wbBreak, transition[2]
|
||||
} else {
|
||||
// No specific transition found. Try the less specific ones.
|
||||
transAnyProp, okAnyProp := wbTransitions[[2]int{state, prAny}]
|
||||
transAnyState, okAnyState := wbTransitions[[2]int{wbAny, nextProperty}]
|
||||
if okAnyProp && okAnyState {
|
||||
// Both apply. We'll use a mix (see comments for grTransitions).
|
||||
newState, wordBreak, rule = transAnyState[0], transAnyState[1] == wbBreak, transAnyState[2]
|
||||
if transAnyProp[2] < transAnyState[2] {
|
||||
wordBreak, rule = transAnyProp[1] == wbBreak, transAnyProp[2]
|
||||
}
|
||||
} else if okAnyProp {
|
||||
// We only have a specific state.
|
||||
newState, wordBreak, rule = transAnyProp[0], transAnyProp[1] == wbBreak, transAnyProp[2]
|
||||
// This branch will probably never be reached because okAnyState will
|
||||
// always be true given the current transition map. But we keep it here
|
||||
// for future modifications to the transition map where this may not be
|
||||
// true anymore.
|
||||
} else if okAnyState {
|
||||
// We only have a specific property.
|
||||
newState, wordBreak, rule = transAnyState[0], transAnyState[1] == wbBreak, transAnyState[2]
|
||||
} else {
|
||||
// No known transition. WB999: Any ÷ Any.
|
||||
newState, wordBreak, rule = wbAny, true, 9990
|
||||
}
|
||||
}
|
||||
|
||||
// For those rules that need to look up runes further in the string, we
|
||||
// determine the property after nextProperty, skipping over Format, Extend,
|
||||
// and ZWJ (according to WB4). It's -1 if not needed, if such a rune cannot
|
||||
// be determined (because the text ends or the rune is faulty).
|
||||
farProperty := -1
|
||||
if rule > 60 &&
|
||||
(state == wbALetter || state == wbHebrewLetter || state == wbNumeric) &&
|
||||
(nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote || // WB6.
|
||||
nextProperty == prDoubleQuote || // WB7b.
|
||||
nextProperty == prMidNum) { // WB12.
|
||||
for {
|
||||
var (
|
||||
r rune
|
||||
length int
|
||||
)
|
||||
if b != nil { // Byte slice version.
|
||||
r, length = utf8.DecodeRune(b)
|
||||
b = b[length:]
|
||||
} else { // String version.
|
||||
r, length = utf8.DecodeRuneInString(str)
|
||||
str = str[length:]
|
||||
}
|
||||
if r == utf8.RuneError {
|
||||
break
|
||||
}
|
||||
prop := property(workBreakCodePoints, r)
|
||||
if prop == prExtend || prop == prFormat || prop == prZWJ {
|
||||
continue
|
||||
}
|
||||
farProperty = prop
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// WB6.
|
||||
if rule > 60 &&
|
||||
(state == wbALetter || state == wbHebrewLetter) &&
|
||||
(nextProperty == prMidLetter || nextProperty == prMidNumLet || nextProperty == prSingleQuote) &&
|
||||
(farProperty == prALetter || farProperty == prHebrewLetter) {
|
||||
return wbWB7, false
|
||||
}
|
||||
|
||||
// WB7b.
|
||||
if rule > 72 &&
|
||||
state == wbHebrewLetter &&
|
||||
nextProperty == prDoubleQuote &&
|
||||
farProperty == prHebrewLetter {
|
||||
return wbWB7c, false
|
||||
}
|
||||
|
||||
// WB12.
|
||||
if rule > 120 &&
|
||||
state == wbNumeric &&
|
||||
(nextProperty == prMidNum || nextProperty == prMidNumLet || nextProperty == prSingleQuote) &&
|
||||
farProperty == prNumeric {
|
||||
return wbWB11, false
|
||||
}
|
||||
|
||||
// WB15 and WB16.
|
||||
if newState == wbAny && nextProperty == prRegionalIndicator {
|
||||
if state != wbOddRI && state != wbEvenRI { // Includes state == -1.
|
||||
// Transition into the first RI.
|
||||
return wbOddRI, true
|
||||
}
|
||||
if state == wbOddRI {
|
||||
// Don't break pairs of Regional Indicators.
|
||||
return wbEvenRI, false
|
||||
}
|
||||
return wbOddRI, true // We can break after a pair.
|
||||
}
|
||||
|
||||
return
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
@ -1,3 +0,0 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
@ -0,0 +1,31 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ppc64, BSD
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
@ -0,0 +1,29 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (darwin || freebsd || netbsd || openbsd) && gc
|
||||
// +build darwin freebsd netbsd openbsd
|
||||
// +build gc
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// System call support for RISCV64 BSD
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
@ -1,233 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IFF_SMART = 0x20
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
IFT_AAL2 = 0xbb
|
||||
IFT_AAL5 = 0x31
|
||||
IFT_ADSL = 0x5e
|
||||
IFT_AFLANE8023 = 0x3b
|
||||
IFT_AFLANE8025 = 0x3c
|
||||
IFT_ARAP = 0x58
|
||||
IFT_ARCNET = 0x23
|
||||
IFT_ARCNETPLUS = 0x24
|
||||
IFT_ASYNC = 0x54
|
||||
IFT_ATM = 0x25
|
||||
IFT_ATMDXI = 0x69
|
||||
IFT_ATMFUNI = 0x6a
|
||||
IFT_ATMIMA = 0x6b
|
||||
IFT_ATMLOGICAL = 0x50
|
||||
IFT_ATMRADIO = 0xbd
|
||||
IFT_ATMSUBINTERFACE = 0x86
|
||||
IFT_ATMVCIENDPT = 0xc2
|
||||
IFT_ATMVIRTUAL = 0x95
|
||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
||||
IFT_BSC = 0x53
|
||||
IFT_CCTEMUL = 0x3d
|
||||
IFT_CEPT = 0x13
|
||||
IFT_CES = 0x85
|
||||
IFT_CHANNEL = 0x46
|
||||
IFT_CNR = 0x55
|
||||
IFT_COFFEE = 0x84
|
||||
IFT_COMPOSITELINK = 0x9b
|
||||
IFT_DCN = 0x8d
|
||||
IFT_DIGITALPOWERLINE = 0x8a
|
||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
||||
IFT_DLSW = 0x4a
|
||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
||||
IFT_DS0 = 0x51
|
||||
IFT_DS0BUNDLE = 0x52
|
||||
IFT_DS1FDL = 0xaa
|
||||
IFT_DS3 = 0x1e
|
||||
IFT_DTM = 0x8c
|
||||
IFT_DVBASILN = 0xac
|
||||
IFT_DVBASIOUT = 0xad
|
||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
||||
IFT_DVBRCCMACLAYER = 0x92
|
||||
IFT_DVBRCCUPSTREAM = 0x94
|
||||
IFT_ENC = 0xf4
|
||||
IFT_EON = 0x19
|
||||
IFT_EPLRS = 0x57
|
||||
IFT_ESCON = 0x49
|
||||
IFT_ETHER = 0x6
|
||||
IFT_FAITH = 0xf2
|
||||
IFT_FAST = 0x7d
|
||||
IFT_FASTETHER = 0x3e
|
||||
IFT_FASTETHERFX = 0x45
|
||||
IFT_FDDI = 0xf
|
||||
IFT_FIBRECHANNEL = 0x38
|
||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
||||
IFT_FRAMERELAYMPI = 0x5c
|
||||
IFT_FRDLCIENDPT = 0xc1
|
||||
IFT_FRELAY = 0x20
|
||||
IFT_FRELAYDCE = 0x2c
|
||||
IFT_FRF16MFRBUNDLE = 0xa3
|
||||
IFT_FRFORWARD = 0x9e
|
||||
IFT_G703AT2MB = 0x43
|
||||
IFT_G703AT64K = 0x42
|
||||
IFT_GIF = 0xf0
|
||||
IFT_GIGABITETHERNET = 0x75
|
||||
IFT_GR303IDT = 0xb2
|
||||
IFT_GR303RDT = 0xb1
|
||||
IFT_H323GATEKEEPER = 0xa4
|
||||
IFT_H323PROXY = 0xa5
|
||||
IFT_HDH1822 = 0x3
|
||||
IFT_HDLC = 0x76
|
||||
IFT_HDSL2 = 0xa8
|
||||
IFT_HIPERLAN2 = 0xb7
|
||||
IFT_HIPPI = 0x2f
|
||||
IFT_HIPPIINTERFACE = 0x39
|
||||
IFT_HOSTPAD = 0x5a
|
||||
IFT_HSSI = 0x2e
|
||||
IFT_HY = 0xe
|
||||
IFT_IBM370PARCHAN = 0x48
|
||||
IFT_IDSL = 0x9a
|
||||
IFT_IEEE80211 = 0x47
|
||||
IFT_IEEE80212 = 0x37
|
||||
IFT_IEEE8023ADLAG = 0xa1
|
||||
IFT_IFGSN = 0x91
|
||||
IFT_IMT = 0xbe
|
||||
IFT_INTERLEAVE = 0x7c
|
||||
IFT_IP = 0x7e
|
||||
IFT_IPFORWARD = 0x8e
|
||||
IFT_IPOVERATM = 0x72
|
||||
IFT_IPOVERCDLC = 0x6d
|
||||
IFT_IPOVERCLAW = 0x6e
|
||||
IFT_IPSWITCH = 0x4e
|
||||
IFT_IPXIP = 0xf9
|
||||
IFT_ISDN = 0x3f
|
||||
IFT_ISDNBASIC = 0x14
|
||||
IFT_ISDNPRIMARY = 0x15
|
||||
IFT_ISDNS = 0x4b
|
||||
IFT_ISDNU = 0x4c
|
||||
IFT_ISO88022LLC = 0x29
|
||||
IFT_ISO88023 = 0x7
|
||||
IFT_ISO88024 = 0x8
|
||||
IFT_ISO88025 = 0x9
|
||||
IFT_ISO88025CRFPINT = 0x62
|
||||
IFT_ISO88025DTR = 0x56
|
||||
IFT_ISO88025FIBER = 0x73
|
||||
IFT_ISO88026 = 0xa
|
||||
IFT_ISUP = 0xb3
|
||||
IFT_L3IPXVLAN = 0x89
|
||||
IFT_LAPB = 0x10
|
||||
IFT_LAPD = 0x4d
|
||||
IFT_LAPF = 0x77
|
||||
IFT_LOCALTALK = 0x2a
|
||||
IFT_LOOP = 0x18
|
||||
IFT_MEDIAMAILOVERIP = 0x8b
|
||||
IFT_MFSIGLINK = 0xa7
|
||||
IFT_MIOX25 = 0x26
|
||||
IFT_MODEM = 0x30
|
||||
IFT_MPC = 0x71
|
||||
IFT_MPLS = 0xa6
|
||||
IFT_MPLSTUNNEL = 0x96
|
||||
IFT_MSDSL = 0x8f
|
||||
IFT_MVL = 0xbf
|
||||
IFT_MYRINET = 0x63
|
||||
IFT_NFAS = 0xaf
|
||||
IFT_NSIP = 0x1b
|
||||
IFT_OPTICALCHANNEL = 0xc3
|
||||
IFT_OPTICALTRANSPORT = 0xc4
|
||||
IFT_OTHER = 0x1
|
||||
IFT_P10 = 0xc
|
||||
IFT_P80 = 0xd
|
||||
IFT_PARA = 0x22
|
||||
IFT_PFLOG = 0xf6
|
||||
IFT_PFSYNC = 0xf7
|
||||
IFT_PLC = 0xae
|
||||
IFT_POS = 0xab
|
||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
||||
IFT_PROPBWAP2MP = 0xb8
|
||||
IFT_PROPCNLS = 0x59
|
||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
||||
IFT_PROPMUX = 0x36
|
||||
IFT_PROPWIRELESSP2P = 0x9d
|
||||
IFT_PTPSERIAL = 0x16
|
||||
IFT_PVC = 0xf1
|
||||
IFT_QLLC = 0x44
|
||||
IFT_RADIOMAC = 0xbc
|
||||
IFT_RADSL = 0x5f
|
||||
IFT_REACHDSL = 0xc0
|
||||
IFT_RFC1483 = 0x9f
|
||||
IFT_RS232 = 0x21
|
||||
IFT_RSRB = 0x4f
|
||||
IFT_SDLC = 0x11
|
||||
IFT_SDSL = 0x60
|
||||
IFT_SHDSL = 0xa9
|
||||
IFT_SIP = 0x1f
|
||||
IFT_SLIP = 0x1c
|
||||
IFT_SMDSDXI = 0x2b
|
||||
IFT_SMDSICIP = 0x34
|
||||
IFT_SONET = 0x27
|
||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
||||
IFT_SONETPATH = 0x32
|
||||
IFT_SONETVT = 0x33
|
||||
IFT_SRP = 0x97
|
||||
IFT_SS7SIGLINK = 0x9c
|
||||
IFT_STACKTOSTACK = 0x6f
|
||||
IFT_STARLAN = 0xb
|
||||
IFT_STF = 0xd7
|
||||
IFT_T1 = 0x12
|
||||
IFT_TDLC = 0x74
|
||||
IFT_TERMPAD = 0x5b
|
||||
IFT_TR008 = 0xb0
|
||||
IFT_TRANSPHDLC = 0x7b
|
||||
IFT_TUNNEL = 0x83
|
||||
IFT_ULTRA = 0x1d
|
||||
IFT_USB = 0xa0
|
||||
IFT_V11 = 0x40
|
||||
IFT_V35 = 0x2d
|
||||
IFT_V36 = 0x41
|
||||
IFT_V37 = 0x78
|
||||
IFT_VDSL = 0x61
|
||||
IFT_VIRTUALIPADDRESS = 0x70
|
||||
IFT_VOICEEM = 0x64
|
||||
IFT_VOICEENCAP = 0x67
|
||||
IFT_VOICEFXO = 0x65
|
||||
IFT_VOICEFXS = 0x66
|
||||
IFT_VOICEOVERATM = 0x98
|
||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
||||
IFT_VOICEOVERIP = 0x68
|
||||
IFT_X213 = 0x5d
|
||||
IFT_X25 = 0x5
|
||||
IFT_X25DDN = 0x4
|
||||
IFT_X25HUNTGROUP = 0x7a
|
||||
IFT_X25MLP = 0x79
|
||||
IFT_X25PLE = 0x28
|
||||
IFT_XETHER = 0x1a
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_FAITH = 0x16
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
SIOCADDRT = 0x8030720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8030720b
|
||||
SIOCDLIFADDR = 0x8118691d
|
||||
SIOCGLIFADDR = 0xc118691c
|
||||
SIOCGLIFPHYADDR = 0xc118694b
|
||||
SIOCSLIFPHYADDR = 0x8118694a
|
||||
)
|
@ -1,233 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IFF_SMART = 0x20
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
IFT_AAL2 = 0xbb
|
||||
IFT_AAL5 = 0x31
|
||||
IFT_ADSL = 0x5e
|
||||
IFT_AFLANE8023 = 0x3b
|
||||
IFT_AFLANE8025 = 0x3c
|
||||
IFT_ARAP = 0x58
|
||||
IFT_ARCNET = 0x23
|
||||
IFT_ARCNETPLUS = 0x24
|
||||
IFT_ASYNC = 0x54
|
||||
IFT_ATM = 0x25
|
||||
IFT_ATMDXI = 0x69
|
||||
IFT_ATMFUNI = 0x6a
|
||||
IFT_ATMIMA = 0x6b
|
||||
IFT_ATMLOGICAL = 0x50
|
||||
IFT_ATMRADIO = 0xbd
|
||||
IFT_ATMSUBINTERFACE = 0x86
|
||||
IFT_ATMVCIENDPT = 0xc2
|
||||
IFT_ATMVIRTUAL = 0x95
|
||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
||||
IFT_BSC = 0x53
|
||||
IFT_CCTEMUL = 0x3d
|
||||
IFT_CEPT = 0x13
|
||||
IFT_CES = 0x85
|
||||
IFT_CHANNEL = 0x46
|
||||
IFT_CNR = 0x55
|
||||
IFT_COFFEE = 0x84
|
||||
IFT_COMPOSITELINK = 0x9b
|
||||
IFT_DCN = 0x8d
|
||||
IFT_DIGITALPOWERLINE = 0x8a
|
||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
||||
IFT_DLSW = 0x4a
|
||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
||||
IFT_DS0 = 0x51
|
||||
IFT_DS0BUNDLE = 0x52
|
||||
IFT_DS1FDL = 0xaa
|
||||
IFT_DS3 = 0x1e
|
||||
IFT_DTM = 0x8c
|
||||
IFT_DVBASILN = 0xac
|
||||
IFT_DVBASIOUT = 0xad
|
||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
||||
IFT_DVBRCCMACLAYER = 0x92
|
||||
IFT_DVBRCCUPSTREAM = 0x94
|
||||
IFT_ENC = 0xf4
|
||||
IFT_EON = 0x19
|
||||
IFT_EPLRS = 0x57
|
||||
IFT_ESCON = 0x49
|
||||
IFT_ETHER = 0x6
|
||||
IFT_FAITH = 0xf2
|
||||
IFT_FAST = 0x7d
|
||||
IFT_FASTETHER = 0x3e
|
||||
IFT_FASTETHERFX = 0x45
|
||||
IFT_FDDI = 0xf
|
||||
IFT_FIBRECHANNEL = 0x38
|
||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
||||
IFT_FRAMERELAYMPI = 0x5c
|
||||
IFT_FRDLCIENDPT = 0xc1
|
||||
IFT_FRELAY = 0x20
|
||||
IFT_FRELAYDCE = 0x2c
|
||||
IFT_FRF16MFRBUNDLE = 0xa3
|
||||
IFT_FRFORWARD = 0x9e
|
||||
IFT_G703AT2MB = 0x43
|
||||
IFT_G703AT64K = 0x42
|
||||
IFT_GIF = 0xf0
|
||||
IFT_GIGABITETHERNET = 0x75
|
||||
IFT_GR303IDT = 0xb2
|
||||
IFT_GR303RDT = 0xb1
|
||||
IFT_H323GATEKEEPER = 0xa4
|
||||
IFT_H323PROXY = 0xa5
|
||||
IFT_HDH1822 = 0x3
|
||||
IFT_HDLC = 0x76
|
||||
IFT_HDSL2 = 0xa8
|
||||
IFT_HIPERLAN2 = 0xb7
|
||||
IFT_HIPPI = 0x2f
|
||||
IFT_HIPPIINTERFACE = 0x39
|
||||
IFT_HOSTPAD = 0x5a
|
||||
IFT_HSSI = 0x2e
|
||||
IFT_HY = 0xe
|
||||
IFT_IBM370PARCHAN = 0x48
|
||||
IFT_IDSL = 0x9a
|
||||
IFT_IEEE80211 = 0x47
|
||||
IFT_IEEE80212 = 0x37
|
||||
IFT_IEEE8023ADLAG = 0xa1
|
||||
IFT_IFGSN = 0x91
|
||||
IFT_IMT = 0xbe
|
||||
IFT_INTERLEAVE = 0x7c
|
||||
IFT_IP = 0x7e
|
||||
IFT_IPFORWARD = 0x8e
|
||||
IFT_IPOVERATM = 0x72
|
||||
IFT_IPOVERCDLC = 0x6d
|
||||
IFT_IPOVERCLAW = 0x6e
|
||||
IFT_IPSWITCH = 0x4e
|
||||
IFT_IPXIP = 0xf9
|
||||
IFT_ISDN = 0x3f
|
||||
IFT_ISDNBASIC = 0x14
|
||||
IFT_ISDNPRIMARY = 0x15
|
||||
IFT_ISDNS = 0x4b
|
||||
IFT_ISDNU = 0x4c
|
||||
IFT_ISO88022LLC = 0x29
|
||||
IFT_ISO88023 = 0x7
|
||||
IFT_ISO88024 = 0x8
|
||||
IFT_ISO88025 = 0x9
|
||||
IFT_ISO88025CRFPINT = 0x62
|
||||
IFT_ISO88025DTR = 0x56
|
||||
IFT_ISO88025FIBER = 0x73
|
||||
IFT_ISO88026 = 0xa
|
||||
IFT_ISUP = 0xb3
|
||||
IFT_L3IPXVLAN = 0x89
|
||||
IFT_LAPB = 0x10
|
||||
IFT_LAPD = 0x4d
|
||||
IFT_LAPF = 0x77
|
||||
IFT_LOCALTALK = 0x2a
|
||||
IFT_LOOP = 0x18
|
||||
IFT_MEDIAMAILOVERIP = 0x8b
|
||||
IFT_MFSIGLINK = 0xa7
|
||||
IFT_MIOX25 = 0x26
|
||||
IFT_MODEM = 0x30
|
||||
IFT_MPC = 0x71
|
||||
IFT_MPLS = 0xa6
|
||||
IFT_MPLSTUNNEL = 0x96
|
||||
IFT_MSDSL = 0x8f
|
||||
IFT_MVL = 0xbf
|
||||
IFT_MYRINET = 0x63
|
||||
IFT_NFAS = 0xaf
|
||||
IFT_NSIP = 0x1b
|
||||
IFT_OPTICALCHANNEL = 0xc3
|
||||
IFT_OPTICALTRANSPORT = 0xc4
|
||||
IFT_OTHER = 0x1
|
||||
IFT_P10 = 0xc
|
||||
IFT_P80 = 0xd
|
||||
IFT_PARA = 0x22
|
||||
IFT_PFLOG = 0xf6
|
||||
IFT_PFSYNC = 0xf7
|
||||
IFT_PLC = 0xae
|
||||
IFT_POS = 0xab
|
||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
||||
IFT_PROPBWAP2MP = 0xb8
|
||||
IFT_PROPCNLS = 0x59
|
||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
||||
IFT_PROPMUX = 0x36
|
||||
IFT_PROPWIRELESSP2P = 0x9d
|
||||
IFT_PTPSERIAL = 0x16
|
||||
IFT_PVC = 0xf1
|
||||
IFT_QLLC = 0x44
|
||||
IFT_RADIOMAC = 0xbc
|
||||
IFT_RADSL = 0x5f
|
||||
IFT_REACHDSL = 0xc0
|
||||
IFT_RFC1483 = 0x9f
|
||||
IFT_RS232 = 0x21
|
||||
IFT_RSRB = 0x4f
|
||||
IFT_SDLC = 0x11
|
||||
IFT_SDSL = 0x60
|
||||
IFT_SHDSL = 0xa9
|
||||
IFT_SIP = 0x1f
|
||||
IFT_SLIP = 0x1c
|
||||
IFT_SMDSDXI = 0x2b
|
||||
IFT_SMDSICIP = 0x34
|
||||
IFT_SONET = 0x27
|
||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
||||
IFT_SONETPATH = 0x32
|
||||
IFT_SONETVT = 0x33
|
||||
IFT_SRP = 0x97
|
||||
IFT_SS7SIGLINK = 0x9c
|
||||
IFT_STACKTOSTACK = 0x6f
|
||||
IFT_STARLAN = 0xb
|
||||
IFT_STF = 0xd7
|
||||
IFT_T1 = 0x12
|
||||
IFT_TDLC = 0x74
|
||||
IFT_TERMPAD = 0x5b
|
||||
IFT_TR008 = 0xb0
|
||||
IFT_TRANSPHDLC = 0x7b
|
||||
IFT_TUNNEL = 0x83
|
||||
IFT_ULTRA = 0x1d
|
||||
IFT_USB = 0xa0
|
||||
IFT_V11 = 0x40
|
||||
IFT_V35 = 0x2d
|
||||
IFT_V36 = 0x41
|
||||
IFT_V37 = 0x78
|
||||
IFT_VDSL = 0x61
|
||||
IFT_VIRTUALIPADDRESS = 0x70
|
||||
IFT_VOICEEM = 0x64
|
||||
IFT_VOICEENCAP = 0x67
|
||||
IFT_VOICEFXO = 0x65
|
||||
IFT_VOICEFXS = 0x66
|
||||
IFT_VOICEOVERATM = 0x98
|
||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
||||
IFT_VOICEOVERIP = 0x68
|
||||
IFT_X213 = 0x5d
|
||||
IFT_X25 = 0x5
|
||||
IFT_X25DDN = 0x4
|
||||
IFT_X25HUNTGROUP = 0x7a
|
||||
IFT_X25MLP = 0x79
|
||||
IFT_X25PLE = 0x28
|
||||
IFT_XETHER = 0x1a
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_FAITH = 0x16
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
SIOCADDRT = 0x8040720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8040720b
|
||||
SIOCDLIFADDR = 0x8118691d
|
||||
SIOCGLIFADDR = 0xc118691c
|
||||
SIOCGLIFPHYADDR = 0xc118694b
|
||||
SIOCSLIFPHYADDR = 0x8118694a
|
||||
)
|
@ -1,226 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
IFT_1822 = 0x2
|
||||
IFT_A12MPPSWITCH = 0x82
|
||||
IFT_AAL2 = 0xbb
|
||||
IFT_AAL5 = 0x31
|
||||
IFT_ADSL = 0x5e
|
||||
IFT_AFLANE8023 = 0x3b
|
||||
IFT_AFLANE8025 = 0x3c
|
||||
IFT_ARAP = 0x58
|
||||
IFT_ARCNET = 0x23
|
||||
IFT_ARCNETPLUS = 0x24
|
||||
IFT_ASYNC = 0x54
|
||||
IFT_ATM = 0x25
|
||||
IFT_ATMDXI = 0x69
|
||||
IFT_ATMFUNI = 0x6a
|
||||
IFT_ATMIMA = 0x6b
|
||||
IFT_ATMLOGICAL = 0x50
|
||||
IFT_ATMRADIO = 0xbd
|
||||
IFT_ATMSUBINTERFACE = 0x86
|
||||
IFT_ATMVCIENDPT = 0xc2
|
||||
IFT_ATMVIRTUAL = 0x95
|
||||
IFT_BGPPOLICYACCOUNTING = 0xa2
|
||||
IFT_BSC = 0x53
|
||||
IFT_CCTEMUL = 0x3d
|
||||
IFT_CEPT = 0x13
|
||||
IFT_CES = 0x85
|
||||
IFT_CHANNEL = 0x46
|
||||
IFT_CNR = 0x55
|
||||
IFT_COFFEE = 0x84
|
||||
IFT_COMPOSITELINK = 0x9b
|
||||
IFT_DCN = 0x8d
|
||||
IFT_DIGITALPOWERLINE = 0x8a
|
||||
IFT_DIGITALWRAPPEROVERHEADCHANNEL = 0xba
|
||||
IFT_DLSW = 0x4a
|
||||
IFT_DOCSCABLEDOWNSTREAM = 0x80
|
||||
IFT_DOCSCABLEMACLAYER = 0x7f
|
||||
IFT_DOCSCABLEUPSTREAM = 0x81
|
||||
IFT_DS0 = 0x51
|
||||
IFT_DS0BUNDLE = 0x52
|
||||
IFT_DS1FDL = 0xaa
|
||||
IFT_DS3 = 0x1e
|
||||
IFT_DTM = 0x8c
|
||||
IFT_DVBASILN = 0xac
|
||||
IFT_DVBASIOUT = 0xad
|
||||
IFT_DVBRCCDOWNSTREAM = 0x93
|
||||
IFT_DVBRCCMACLAYER = 0x92
|
||||
IFT_DVBRCCUPSTREAM = 0x94
|
||||
IFT_ENC = 0xf4
|
||||
IFT_EON = 0x19
|
||||
IFT_EPLRS = 0x57
|
||||
IFT_ESCON = 0x49
|
||||
IFT_ETHER = 0x6
|
||||
IFT_FAST = 0x7d
|
||||
IFT_FASTETHER = 0x3e
|
||||
IFT_FASTETHERFX = 0x45
|
||||
IFT_FDDI = 0xf
|
||||
IFT_FIBRECHANNEL = 0x38
|
||||
IFT_FRAMERELAYINTERCONNECT = 0x3a
|
||||
IFT_FRAMERELAYMPI = 0x5c
|
||||
IFT_FRDLCIENDPT = 0xc1
|
||||
IFT_FRELAY = 0x20
|
||||
IFT_FRELAYDCE = 0x2c
|
||||
IFT_FRF16MFRBUNDLE = 0xa3
|
||||
IFT_FRFORWARD = 0x9e
|
||||
IFT_G703AT2MB = 0x43
|
||||
IFT_G703AT64K = 0x42
|
||||
IFT_GIF = 0xf0
|
||||
IFT_GIGABITETHERNET = 0x75
|
||||
IFT_GR303IDT = 0xb2
|
||||
IFT_GR303RDT = 0xb1
|
||||
IFT_H323GATEKEEPER = 0xa4
|
||||
IFT_H323PROXY = 0xa5
|
||||
IFT_HDH1822 = 0x3
|
||||
IFT_HDLC = 0x76
|
||||
IFT_HDSL2 = 0xa8
|
||||
IFT_HIPERLAN2 = 0xb7
|
||||
IFT_HIPPI = 0x2f
|
||||
IFT_HIPPIINTERFACE = 0x39
|
||||
IFT_HOSTPAD = 0x5a
|
||||
IFT_HSSI = 0x2e
|
||||
IFT_HY = 0xe
|
||||
IFT_IBM370PARCHAN = 0x48
|
||||
IFT_IDSL = 0x9a
|
||||
IFT_IEEE80211 = 0x47
|
||||
IFT_IEEE80212 = 0x37
|
||||
IFT_IEEE8023ADLAG = 0xa1
|
||||
IFT_IFGSN = 0x91
|
||||
IFT_IMT = 0xbe
|
||||
IFT_INTERLEAVE = 0x7c
|
||||
IFT_IP = 0x7e
|
||||
IFT_IPFORWARD = 0x8e
|
||||
IFT_IPOVERATM = 0x72
|
||||
IFT_IPOVERCDLC = 0x6d
|
||||
IFT_IPOVERCLAW = 0x6e
|
||||
IFT_IPSWITCH = 0x4e
|
||||
IFT_ISDN = 0x3f
|
||||
IFT_ISDNBASIC = 0x14
|
||||
IFT_ISDNPRIMARY = 0x15
|
||||
IFT_ISDNS = 0x4b
|
||||
IFT_ISDNU = 0x4c
|
||||
IFT_ISO88022LLC = 0x29
|
||||
IFT_ISO88023 = 0x7
|
||||
IFT_ISO88024 = 0x8
|
||||
IFT_ISO88025 = 0x9
|
||||
IFT_ISO88025CRFPINT = 0x62
|
||||
IFT_ISO88025DTR = 0x56
|
||||
IFT_ISO88025FIBER = 0x73
|
||||
IFT_ISO88026 = 0xa
|
||||
IFT_ISUP = 0xb3
|
||||
IFT_L3IPXVLAN = 0x89
|
||||
IFT_LAPB = 0x10
|
||||
IFT_LAPD = 0x4d
|
||||
IFT_LAPF = 0x77
|
||||
IFT_LOCALTALK = 0x2a
|
||||
IFT_LOOP = 0x18
|
||||
IFT_MEDIAMAILOVERIP = 0x8b
|
||||
IFT_MFSIGLINK = 0xa7
|
||||
IFT_MIOX25 = 0x26
|
||||
IFT_MODEM = 0x30
|
||||
IFT_MPC = 0x71
|
||||
IFT_MPLS = 0xa6
|
||||
IFT_MPLSTUNNEL = 0x96
|
||||
IFT_MSDSL = 0x8f
|
||||
IFT_MVL = 0xbf
|
||||
IFT_MYRINET = 0x63
|
||||
IFT_NFAS = 0xaf
|
||||
IFT_NSIP = 0x1b
|
||||
IFT_OPTICALCHANNEL = 0xc3
|
||||
IFT_OPTICALTRANSPORT = 0xc4
|
||||
IFT_OTHER = 0x1
|
||||
IFT_P10 = 0xc
|
||||
IFT_P80 = 0xd
|
||||
IFT_PARA = 0x22
|
||||
IFT_PFLOG = 0xf6
|
||||
IFT_PFSYNC = 0xf7
|
||||
IFT_PLC = 0xae
|
||||
IFT_POS = 0xab
|
||||
IFT_PPPMULTILINKBUNDLE = 0x6c
|
||||
IFT_PROPBWAP2MP = 0xb8
|
||||
IFT_PROPCNLS = 0x59
|
||||
IFT_PROPDOCSWIRELESSDOWNSTREAM = 0xb5
|
||||
IFT_PROPDOCSWIRELESSMACLAYER = 0xb4
|
||||
IFT_PROPDOCSWIRELESSUPSTREAM = 0xb6
|
||||
IFT_PROPMUX = 0x36
|
||||
IFT_PROPWIRELESSP2P = 0x9d
|
||||
IFT_PTPSERIAL = 0x16
|
||||
IFT_PVC = 0xf1
|
||||
IFT_QLLC = 0x44
|
||||
IFT_RADIOMAC = 0xbc
|
||||
IFT_RADSL = 0x5f
|
||||
IFT_REACHDSL = 0xc0
|
||||
IFT_RFC1483 = 0x9f
|
||||
IFT_RS232 = 0x21
|
||||
IFT_RSRB = 0x4f
|
||||
IFT_SDLC = 0x11
|
||||
IFT_SDSL = 0x60
|
||||
IFT_SHDSL = 0xa9
|
||||
IFT_SIP = 0x1f
|
||||
IFT_SLIP = 0x1c
|
||||
IFT_SMDSDXI = 0x2b
|
||||
IFT_SMDSICIP = 0x34
|
||||
IFT_SONET = 0x27
|
||||
IFT_SONETOVERHEADCHANNEL = 0xb9
|
||||
IFT_SONETPATH = 0x32
|
||||
IFT_SONETVT = 0x33
|
||||
IFT_SRP = 0x97
|
||||
IFT_SS7SIGLINK = 0x9c
|
||||
IFT_STACKTOSTACK = 0x6f
|
||||
IFT_STARLAN = 0xb
|
||||
IFT_STF = 0xd7
|
||||
IFT_T1 = 0x12
|
||||
IFT_TDLC = 0x74
|
||||
IFT_TERMPAD = 0x5b
|
||||
IFT_TR008 = 0xb0
|
||||
IFT_TRANSPHDLC = 0x7b
|
||||
IFT_TUNNEL = 0x83
|
||||
IFT_ULTRA = 0x1d
|
||||
IFT_USB = 0xa0
|
||||
IFT_V11 = 0x40
|
||||
IFT_V35 = 0x2d
|
||||
IFT_V36 = 0x41
|
||||
IFT_V37 = 0x78
|
||||
IFT_VDSL = 0x61
|
||||
IFT_VIRTUALIPADDRESS = 0x70
|
||||
IFT_VOICEEM = 0x64
|
||||
IFT_VOICEENCAP = 0x67
|
||||
IFT_VOICEFXO = 0x65
|
||||
IFT_VOICEFXS = 0x66
|
||||
IFT_VOICEOVERATM = 0x98
|
||||
IFT_VOICEOVERFRAMERELAY = 0x99
|
||||
IFT_VOICEOVERIP = 0x68
|
||||
IFT_X213 = 0x5d
|
||||
IFT_X25 = 0x5
|
||||
IFT_X25DDN = 0x4
|
||||
IFT_X25HUNTGROUP = 0x7a
|
||||
IFT_X25MLP = 0x79
|
||||
IFT_X25PLE = 0x28
|
||||
IFT_XETHER = 0x1a
|
||||
|
||||
// missing constants on FreeBSD-11.1-RELEASE, copied from old values in ztypes_freebsd_arm.go
|
||||
IFF_SMART = 0x20
|
||||
IFT_FAITH = 0xf2
|
||||
IFT_IPXIP = 0xf9
|
||||
IPPROTO_MAXID = 0x34
|
||||
IPV6_FAITH = 0x1d
|
||||
IP_FAITH = 0x16
|
||||
MAP_NORESERVE = 0x40
|
||||
MAP_RENAME = 0x20
|
||||
NET_RT_MAXID = 0x6
|
||||
RTF_PRCLONING = 0x10000
|
||||
RTM_OLDADD = 0x9
|
||||
RTM_OLDDEL = 0xa
|
||||
SIOCADDRT = 0x8030720a
|
||||
SIOCALIFADDR = 0x8118691b
|
||||
SIOCDELRT = 0x8030720b
|
||||
SIOCDLIFADDR = 0x8118691d
|
||||
SIOCGLIFADDR = 0xc118691c
|
||||
SIOCGLIFPHYADDR = 0xc118694b
|
||||
SIOCSLIFPHYADDR = 0x8118694a
|
||||
)
|
@ -1,17 +0,0 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Constants that were deprecated or moved to enums in the FreeBSD headers. Keep
|
||||
// them here for backwards compatibility.
|
||||
|
||||
package unix
|
||||
|
||||
const (
|
||||
DLT_HHDLC = 0x79
|
||||
IPV6_MIN_MEMBERSHIPS = 0x1f
|
||||
IP_MAX_SOURCE_FILTER = 0x400
|
||||
IP_MIN_MEMBERSHIPS = 0x1f
|
||||
RT_CACHING_CONTEXT = 0x1
|
||||
RT_NORTREF = 0x2
|
||||
)
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package unix
|
||||
|
||||
func itoa(val int) string { // do it here rather than with fmt to avoid dependency
|
||||
if val < 0 {
|
||||
return "-" + uitoa(uint(-val))
|
||||
}
|
||||
return uitoa(uint(val))
|
||||
}
|
||||
|
||||
func uitoa(val uint) string {
|
||||
var buf [32]byte // big enough for int64
|
||||
i := len(buf) - 1
|
||||
for val >= 10 {
|
||||
buf[i] = byte(val%10 + '0')
|
||||
i--
|
||||
val /= 10
|
||||
}
|
||||
buf[i] = byte(val + '0')
|
||||
return string(buf[i:])
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build darwin && go1.12 && !go1.13
|
||||
// +build darwin,go1.12,!go1.13
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const _SYS_GETDIRENTRIES64 = 344
|
||||
|
||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
// To implement this using libSystem we'd need syscall_syscallPtr for
|
||||
// fdopendir. However, syscallPtr was only added in Go 1.13, so we fall
|
||||
// back to raw syscalls for this func on Go 1.12.
|
||||
var p unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
p = unsafe.Pointer(&buf[0])
|
||||
} else {
|
||||
p = unsafe.Pointer(&_zero)
|
||||
}
|
||||
r0, _, e1 := Syscall6(_SYS_GETDIRENTRIES64, uintptr(fd), uintptr(p), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
n = int(r0)
|
||||
if e1 != 0 {
|
||||
return n, errnoErr(e1)
|
||||
}
|
||||
return n, nil
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build darwin && go1.13
|
||||
// +build darwin,go1.13
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/internal/unsafeheader"
|
||||
)
|
||||
|
||||
//sys closedir(dir uintptr) (err error)
|
||||
//sys readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno)
|
||||
|
||||
func fdopendir(fd int) (dir uintptr, err error) {
|
||||
r0, _, e1 := syscall_syscallPtr(libc_fdopendir_trampoline_addr, uintptr(fd), 0, 0)
|
||||
dir = uintptr(r0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var libc_fdopendir_trampoline_addr uintptr
|
||||
|
||||
//go:cgo_import_dynamic libc_fdopendir fdopendir "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
// Simulate Getdirentries using fdopendir/readdir_r/closedir.
|
||||
// We store the number of entries to skip in the seek
|
||||
// offset of fd. See issue #31368.
|
||||
// It's not the full required semantics, but should handle the case
|
||||
// of calling Getdirentries or ReadDirent repeatedly.
|
||||
// It won't handle assigning the results of lseek to *basep, or handle
|
||||
// the directory being edited underfoot.
|
||||
skip, err := Seek(fd, 0, 1 /* SEEK_CUR */)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// We need to duplicate the incoming file descriptor
|
||||
// because the caller expects to retain control of it, but
|
||||
// fdopendir expects to take control of its argument.
|
||||
// Just Dup'ing the file descriptor is not enough, as the
|
||||
// result shares underlying state. Use Openat to make a really
|
||||
// new file descriptor referring to the same directory.
|
||||
fd2, err := Openat(fd, ".", O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
d, err := fdopendir(fd2)
|
||||
if err != nil {
|
||||
Close(fd2)
|
||||
return 0, err
|
||||
}
|
||||
defer closedir(d)
|
||||
|
||||
var cnt int64
|
||||
for {
|
||||
var entry Dirent
|
||||
var entryp *Dirent
|
||||
e := readdir_r(d, &entry, &entryp)
|
||||
if e != 0 {
|
||||
return n, errnoErr(e)
|
||||
}
|
||||
if entryp == nil {
|
||||
break
|
||||
}
|
||||
if skip > 0 {
|
||||
skip--
|
||||
cnt++
|
||||
continue
|
||||
}
|
||||
|
||||
reclen := int(entry.Reclen)
|
||||
if reclen > len(buf) {
|
||||
// Not enough room. Return for now.
|
||||
// The counter will let us know where we should start up again.
|
||||
// Note: this strategy for suspending in the middle and
|
||||
// restarting is O(n^2) in the length of the directory. Oh well.
|
||||
break
|
||||
}
|
||||
|
||||
// Copy entry into return buffer.
|
||||
var s []byte
|
||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
|
||||
hdr.Data = unsafe.Pointer(&entry)
|
||||
hdr.Cap = reclen
|
||||
hdr.Len = reclen
|
||||
copy(buf, s)
|
||||
|
||||
buf = buf[reclen:]
|
||||
n += reclen
|
||||
cnt++
|
||||
}
|
||||
// Set the seek offset of the input fd to record
|
||||
// how many files we've already returned.
|
||||
_, err = Seek(fd, cnt, 0 /* SEEK_SET */)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build riscv64 && freebsd
|
||||
// +build riscv64,freebsd
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec {
|
||||
return Timespec{Sec: sec, Nsec: nsec}
|
||||
}
|
||||
|
||||
func setTimeval(sec, usec int64) Timeval {
|
||||
return Timeval{Sec: sec, Usec: usec}
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint64(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
||||
func (iov *Iovec) SetLen(length int) {
|
||||
iov.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) {
|
||||
msghdr.Controllen = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||
msghdr.Iovlen = int32(length)
|
||||
}
|
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
|
||||
var writtenOut uint64 = 0
|
||||
_, _, e1 := Syscall9(SYS_SENDFILE, uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(count), 0, uintptr(unsafe.Pointer(&writtenOut)), 0, 0, 0)
|
||||
|
||||
written = int(writtenOut)
|
||||
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
|
||||
|
||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
|
||||
ioDesc := PtraceIoDesc{Op: int32(req), Offs: uintptr(unsafe.Pointer(addr)), Addr: uintptr(unsafe.Pointer(&out[0])), Len: uint64(countin)}
|
||||
err = ptrace(PT_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
|
||||
return int(ioDesc.Len), err
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build openbsd && !mips64
|
||||
// +build openbsd,!mips64
|
||||
|
||||
package unix
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
// Implemented in the runtime package (runtime/sys_openbsd3.go)
|
||||
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
//go:linkname syscall_syscall syscall.syscall
|
||||
//go:linkname syscall_syscall6 syscall.syscall6
|
||||
//go:linkname syscall_syscall10 syscall.syscall10
|
||||
//go:linkname syscall_rawSyscall syscall.rawSyscall
|
||||
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
|
||||
|
||||
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build ppc64 && openbsd
|
||||
// +build ppc64,openbsd
|
||||
|
||||
package unix
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec {
|
||||
return Timespec{Sec: sec, Nsec: nsec}
|
||||
}
|
||||
|
||||
func setTimeval(sec, usec int64) Timeval {
|
||||
return Timeval{Sec: sec, Usec: usec}
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint64(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
||||
func (iov *Iovec) SetLen(length int) {
|
||||
iov.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) {
|
||||
msghdr.Controllen = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||
msghdr.Iovlen = uint32(length)
|
||||
}
|
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||
// of openbsd/ppc64 the syscall is called sysctl instead of __sysctl.
|
||||
const SYS___SYSCTL = SYS_SYSCTL
|
@ -0,0 +1,42 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build riscv64 && openbsd
|
||||
// +build riscv64,openbsd
|
||||
|
||||
package unix
|
||||
|
||||
func setTimespec(sec, nsec int64) Timespec {
|
||||
return Timespec{Sec: sec, Nsec: nsec}
|
||||
}
|
||||
|
||||
func setTimeval(sec, usec int64) Timeval {
|
||||
return Timeval{Sec: sec, Usec: usec}
|
||||
}
|
||||
|
||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
|
||||
k.Ident = uint64(fd)
|
||||
k.Filter = int16(mode)
|
||||
k.Flags = uint16(flags)
|
||||
}
|
||||
|
||||
func (iov *Iovec) SetLen(length int) {
|
||||
iov.Len = uint64(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetControllen(length int) {
|
||||
msghdr.Controllen = uint32(length)
|
||||
}
|
||||
|
||||
func (msghdr *Msghdr) SetIovlen(length int) {
|
||||
msghdr.Iovlen = uint32(length)
|
||||
}
|
||||
|
||||
func (cmsg *Cmsghdr) SetLen(length int) {
|
||||
cmsg.Len = uint32(length)
|
||||
}
|
||||
|
||||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
|
||||
// of openbsd/riscv64 the syscall is called sysctl instead of __sysctl.
|
||||
const SYS___SYSCTL = SYS_SYSCTL
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue