ctype

package
v0.0.0-...-eaaf421 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package ctype is a provider-only character-classification engine: it classifies and cases bytes using glibc's locale-aware *_l ctype functions, reached over dlopen/dlsym rather than cgo. It exists to give agent tooling faithful, deterministic POSIX character classes and case mapping without linking libc and without shelling out.

Scope, on purpose

This package is a LIBRARY. It wires to no applet, registers no verb, and is deliberately narrow: it accepts ONLY the "C"/"POSIX" locale and the two explicit ISO-8859-1 locale aliases already reviewed for github.com/qiangli/coreutils/pkg/collate (see Open). Everything else — a bare "de_DE" with no codeset, "de_DE.UTF-8", ISO-8859-15/"Latin-9", and arbitrary names — is rejected up front, before any libc is loaded, with ErrUnsupportedLocale.

The real provider is built only on linux/amd64 and linux/arm64 (ctype_glibc.go). Every other platform gets a stub (ctype_stub.go) whose Open returns ErrUnsupportedPlatform after the same locale validation, so callers get one consistent, honest contract everywhere.

Third-party provenance

The dlopen/dlsym FFI is provided by github.com/ebitengine/purego (v0.10.0), upstream https://github.com/ebitengine/purego, Apache-2.0 licensed. purego is used directly — no cgo — via purego.Dlopen/Dlsym/RegisterFunc, as already declared in THIRD_PARTY_LICENSES.md for pkg/collate.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedPlatform is returned by Open on any platform other than
	// linux/amd64 and linux/arm64, where no glibc provider is built.
	ErrUnsupportedPlatform = errors.New("ctype: glibc ctype provider is only built for linux/amd64 and linux/arm64")

	// ErrUnsupportedLocale is returned when the requested locale name is not
	// "C", "POSIX", or one of the two accepted ISO-8859-1 aliases. Reported
	// BEFORE any libc is loaded.
	ErrUnsupportedLocale = errors.New("ctype: unsupported locale; only \"C\", \"POSIX\", and the ISO-8859-1 aliases \"de_DE.ISO-8859-1\" / \"de_DE.iso88591\" are accepted")

	// ErrGlibcUnavailable is returned when libc.so.6 cannot be loaded, or the
	// loaded C library is not glibc (honest detection via
	// gnu_get_libc_version), or a required symbol is missing.
	ErrGlibcUnavailable = errors.New("ctype: glibc runtime not detected")

	// ErrMissingLocale is returned when glibc is present but the requested
	// locale data is not installed (newlocale failed).
	ErrMissingLocale = errors.New("ctype: locale data is not installed")

	// ErrInitFailure is returned when glibc newlocale fails due to ENOMEM or
	// other initialization failure.
	ErrInitFailure = errors.New("ctype: initialization failure")

	// ErrCodeset is returned when the opened locale's CODESET does not match
	// the codeset this package expects for that locale (ANSI_X3.4-1968 for
	// "C"/"POSIX", ISO-8859-1 for the de_DE aliases).
	ErrCodeset = errors.New("ctype: locale codeset does not match the expected codeset for this locale")

	// ErrClosed is returned by the classification and casing methods after
	// the provider has been closed.
	ErrClosed = errors.New("ctype: provider is closed")
)

Sentinel errors. These are platform-independent so callers can switch on them identically on Linux and on the stub platforms.

Functions

This section is empty.

Types

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider classifies and cases bytes in a glibc locale via the *_l ctype functions. It holds one locale_t handle carrying LC_CTYPE, obtained from a single newlocale(LC_CTYPE_MASK, ...) call owned by this Provider. A RWMutex fences concurrent classification/casing calls against Close; Close is idempotent.

func Open

func Open(name string) (*Provider, error)

Open returns a Provider for "C", "POSIX", or one of the accepted ISO-8859-1 locale aliases.

The locale name is validated before any libc is touched; an unaccepted name returns ErrUnsupportedLocale. It then requires glibc (ErrGlibcUnavailable if absent), the locale data to be installed (ErrMissingLocale), and the locale's CODESET to exactly match what this package expects for that locale (ErrCodeset). The caller owns the returned Provider and must Close it.

func (*Provider) Close

func (p *Provider) Close() error

Close frees the provider's locale_t handle. It is safe to call more than once and safe against concurrent classification/casing calls: the write lock waits for in-flight calls to finish, and the closed flag stops later ones deterministically.

func (*Provider) IsAlnum

func (p *Provider) IsAlnum(c byte) (bool, error)

IsAlnum reports whether c is alphanumeric under the provider's locale.

func (*Provider) IsAlpha

func (p *Provider) IsAlpha(c byte) (bool, error)

IsAlpha reports whether c is alphabetic under the provider's locale.

func (*Provider) IsBlank

func (p *Provider) IsBlank(c byte) (bool, error)

IsBlank reports whether c is a blank (space or tab) character.

func (*Provider) IsCntrl

func (p *Provider) IsCntrl(c byte) (bool, error)

IsCntrl reports whether c is a control character.

func (*Provider) IsDigit

func (p *Provider) IsDigit(c byte) (bool, error)

IsDigit reports whether c is a decimal digit.

func (*Provider) IsGraph

func (p *Provider) IsGraph(c byte) (bool, error)

IsGraph reports whether c has a visible glyph.

func (*Provider) IsLower

func (p *Provider) IsLower(c byte) (bool, error)

IsLower reports whether c is a lowercase letter under the provider's locale.

func (*Provider) IsPrint

func (p *Provider) IsPrint(c byte) (bool, error)

IsPrint reports whether c is printable (including space).

func (*Provider) IsPunct

func (p *Provider) IsPunct(c byte) (bool, error)

IsPunct reports whether c is punctuation.

func (*Provider) IsSpace

func (p *Provider) IsSpace(c byte) (bool, error)

IsSpace reports whether c is whitespace under the provider's locale.

func (*Provider) IsUpper

func (p *Provider) IsUpper(c byte) (bool, error)

IsUpper reports whether c is an uppercase letter under the provider's locale.

func (*Provider) IsXDigit

func (p *Provider) IsXDigit(c byte) (bool, error)

IsXDigit reports whether c is a hexadecimal digit.

func (*Provider) ToLower

func (p *Provider) ToLower(b []byte) ([]byte, error)

ToLower returns a copy of b with every byte case-mapped through the provider's locale via tolower_l. b is never mutated. Once the provider is closed, ToLower returns (nil, ErrClosed) and leaves b untouched.

func (*Provider) ToUpper

func (p *Provider) ToUpper(b []byte) ([]byte, error)

ToUpper returns a copy of b with every byte case-mapped through the provider's locale via toupper_l. b is never mutated. Once the provider is closed, ToUpper returns (nil, ErrClosed) and leaves b untouched.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL