binfmt-magic-match.dhover×375all
#!/usr/bin/env dub
/+ dub.sdl:
    name "autological_binfmt_magic_match"
    targetPath "build"
    dflags "-preview=in" "-preview=dip1000"
    buildType "checked" {
        buildOptions "optimize" "inline" "debugInfo"
    }
+/
/**
 * `binfmt_misc` registration strings, parsed and evaluated the way the kernel does.
 *
 * `fs/binfmt_misc.c` turns a line of the form
 *
 *     :name:type:offset:magic:mask:interpreter:flags
 *
 * into a predicate over the first bytes of a file. This program implements that
 * predicate — including the `\xNN` escaping of `magic`/`mask` and the
 * mask-is-optional rule — and evaluates a small registration table against a
 * set of specimen buffers, so the *dispatch* half of the catalog's thesis is
 * executable rather than described.
 *
 * The registrations included are the ones the catalog argues about:
 *
 *   - `qemu-aarch64`  — the canonical `E_MACHINE`-masked ELF rule, and the
 *     reason the `F` (fix binary) flag exists: without it the interpreter is
 *     resolved in the mount namespace of the *process being executed*, so a
 *     container without the interpreter inside it cannot run foreign binaries.
 *   - `self`          — magic at **offset 68**, which is a field SQLite has
 *     promised never to interpret (see `sqlite-header-probe.d`). This is the
 *     whole dispatch story for SELF: no new format, one kernel rule.
 *   - `jar`           — `PK\x03\x04` at offset 0, the rule that made GIFAR
 *     interesting, because a JAR is located by its *footer* while `binfmt_misc`
 *     matches on its *header*.
 *
 * If `/proc/sys/fs/binfmt_misc` is mounted and readable, the program also parses
 * the host's live registrations through the same code, which is the honest test:
 * the parser either handles what the kernel actually emitted, or it does not.
 *
 * Companions:
 *   docs/research/autological-artifacts/binfmt-misc.md
 *   docs/research/autological-artifacts/self-selfdb/index.md
 *   docs/research/autological-artifacts/parser-differentials.md
 *
 * Run with: `dub run --single binfmt-magic-match.d`
 *
 * Portability: the parser and matcher are pure `std` and run everywhere; the
 * live-registration read is Linux-only and prints a `SKIP:` line elsewhere (or
 * when `binfmt_misc` is not mounted), still exiting 0.
 */
module 
(module) autological_binfmt_magic_match

binfmt_misc registration strings, parsed and evaluated the way the kernel does.

fs/binfmt_misc.c turns a line of the form

:name:type:offset:magic:mask:interpreter:flags

into a predicate over the first bytes of a file. This program implements that predicate — including the \xNN escaping of magic/mask and the mask-is-optional rule — and evaluates a small registration table against a set of specimen buffers, so the dispatch half of the catalog's thesis is executable rather than described.

The registrations included are the ones the catalog argues about:

  • qemu-aarch64 — the canonical E_MACHINE-masked ELF rule, and the reason the F (fix binary) flag exists: without it the interpreter is resolved in the mount namespace of the process being executed, so a container without the interpreter inside it cannot run foreign binaries.

  • self — magic at offset 68, which is a field SQLite has promised never to interpret (see sqlite-header-probe.d). This is the whole dispatch story for SELF: no new format, one kernel rule.

  • jarPK\x03\x04 at offset 0, the rule that made GIFAR interesting, because a JAR is located by its footer while binfmt_misc matches on its header.

If /proc/sys/fs/binfmt_misc is mounted and readable, the program also parses the host's live registrations through the same code, which is the honest test: the parser either handles what the kernel actually emitted, or it does not.

Companions

docs/research/autological-artifacts/binfmt-misc.md docs/research/autological-artifacts/self-selfdb/index.md docs/research/autological-artifacts/parser-differentials.md

Run with: dub run --single binfmt-magic-match.d

Portability

the parser and matcher are pure std and run everywhere; the live-registration read is Linux-only and prints a SKIP: line elsewhere (or when binfmt_misc is not mounted), still exiting 0.

autological_binfmt_magic_match
;
import
(package) std
std
.
(module) std.algorithm

This package implements generic algorithms oriented towards the processing of sequences. Sequences processed by these functions define range-based interfaces. See also Reference on ranges and tutorial on ranges.

Algorithms are categorized into the following submodules:

Submodule Functions

| Searching | all any balancedParens boyerMooreFinder canFind commonPrefix count countUntil endsWith find findAdjacent findAmong findSkip findSplit findSplitAfter findSplitBefore minCount maxCount minElement maxElement minIndex maxIndex minPos maxPos skipOver startsWith until |

| Comparison | among castSwitch clamp cmp either equal isPermutation isSameLength levenshteinDistance levenshteinDistanceAndPath max min mismatch predSwitch |

| Iteration | cache cacheBidirectional chunkBy cumulativeFold each filter filterBidirectional fold group joiner map mean permutations reduce splitWhen splitter substitute sum uniq |

| Sorting | completeSort isPartitioned isSorted isStrictlyMonotonic ordered strictlyOrdered makeIndex merge multiSort nextEvenPermutation nextPermutation nthPermutation partialSort partition partition3 schwartzSort sort topN topNCopy topNIndex |

| Set operations (setops) | cartesianProduct largestPartialIntersection largestPartialIntersectionWeighted multiwayMerge multiwayUnion setDifference setIntersection setSymmetricDifference |

| Mutation | bringToFront copy fill initializeAll move moveAll moveSome moveEmplace moveEmplaceAll moveEmplaceSome remove reverse strip stripLeft stripRight swap swapRanges uninitializedFill |

Many functions in this package are parameterized with a predicate. The predicate may be any suitable callable type (a function, a delegate, a functor, or a lambda), or a compile-time string. The string may consist of any legal D expression that uses the symbol a (for unary functions) or the symbols a and b (for binary functions). These names will NOT interfere with other homonym symbols in user code because they are evaluated in a different context. The default for all binary comparison predicates is "a == b" for unordered operations and "a < b" for ordered operations.

Example

int[] a = ...;
static bool greater(int a, int b)
{
    return a > b;
}
sort!greater(a);           // predicate as alias
sort!((a, b) => a > b)(a); // predicate as a lambda.
sort!"a > b"(a);           // predicate as string
                           // (no ambiguity with array name)
sort(a);                   // no predicate, "a < b" is implicit

Source

std/algorithm/package.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
algorithm
:
(alias template) autological_binfmt_magic_match.filter = std.algorithm.iteration.filter(alias predicate) if (is(typeof(unaryFun!predicate)))

``filter!(predicate)(range) returns a new range containing only elements x in range for which predicate(x) returns true.

The predicate is passed to unaryFun, and can be either a string, or any callable that can be executed via pred(element).

@parampredicate Function to apply to each element of range@returnsAn input range that contains the filtered elements. If range is at least a forward range, the return value of filter will also be a forward range.@seeFilter (higher-order function), filterBidirectional
filter
,
(alias template) autological_binfmt_magic_match.map = std.algorithm.iteration.map(fun...) if (fun.length >= 1)

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

@paramfun one or more transformation functions@seeMap (higher-order function)
map
,
(alias template) autological_binfmt_magic_match.startsWith = std.algorithm.searching.startsWith(alias pred = (a, b) => a == b, Range, Needles...)(Range doesThisStart, Needles withOneOfThese) if (isInputRange!Range && (Needles.length > 1) && allSatisfy!(canTestStartsWith!(pred, Range), Needles))

Checks whether the given input range starts with (one of) the given needle(s) or, if no needles are given, if its front element fulfils predicate pred.

For more information about pred see find.

@parampred Predicate to use in comparing the elements of the haystack and the needle(s). Mandatory if no needles are given.@paramdoesThisStart The input range to check.@paramwithOneOfThese The needles against which the range is to be checked, which may be individual elements or input ranges of elements.@paramwithThis The single needle to check, which may be either a single element or an input range of elements.@returns

0 if the needle(s) do not occur at the beginning of the given range; otherwise the position of the matching needle, that is, 1 if the range starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so on.

In the case where doesThisStart starts with multiple of the ranges or elements in withOneOfThese, then the shortest one matches (if there are two which match which are of the same length (e.g. "a" and 'a'), then the left-most of them in the argument list matches).

In the case when no needle parameters are given, return true iff front of doesThisStart fulfils predicate pred.

startsWith
;
import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) autological_binfmt_magic_match.array = std.array.array(Range)(Range r) if (isIterable!Range && !isAutodecodableString!Range && !isInfinite!Range)

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
,
(alias template) autological_binfmt_magic_match.split = std.array.split(S)(S s) if (isSomeString!S)

Eagerly splits range into an array, using sep as the delimiter.

When no delimiter is provided, strings are split into an array of words, using whitespace as delimiter. Runs of whitespace are merged together (no empty words are produced).

The range must be a forward range. The separator can be a value of the same type as the elements in range or it can be another forward range.

@params the string to split by word if no separator is given@paramrange the range to split@paramsep a value of the same type as the elements of range or another@paramisTerminator a predicate that splits the range when it returns true.@returnsAn array containing the divided parts of range (or the words of s).@see

splitter for a lazy version without allocating memory.

splitter for a version that splits using a regular expression defined separator.

split
;
import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) autological_binfmt_magic_match.text = std.conv.text(T...)(T args) if (T.length > 0)

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
,
(alias template) autological_binfmt_magic_match.to = std.conv.to(T)

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

to
;
import
(package) std
std
.
(module) std.file

Utilities for manipulating files and scanning directories. Functions in this module handle files as a unit, e.g., read or write one file at a time. For opening files and manipulating them via handles refer to module std.stdio.

Category Functions
General exists isDir isFile isSymlink rename thisExePath
Directories chdir dirEntries getcwd mkdir mkdirRecurse rmdir rmdirRecurse tempDir
Files append copy read readText remove slurp write
Symlinks symlink readLink
Attributes attrIsDir attrIsFile attrIsSymlink getAttributes getLinkAttributes getSize setAttributes
Timestamp getTimes getTimesWin setTimes timeLastModified timeLastAccessed timeStatusChanged
Other DirEntry FileException PreserveAttributes SpanMode getAvailableDiskSpace

Source

std/file.d

@copyrightCopyright The D Language Foundation 2007 - 2011.@seeThe official tutorial for an introduction to working with files in D, module std.stdio for opening files and manipulating them via handles, and module std.path for manipulating path strings.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis
file
:
(alias template) autological_binfmt_magic_match.dirEntries = std.file.dirEntries(bool useDIP1000 = dip1000Enabled)(string path, SpanMode mode, bool followSymlink = true)

Returns an input range of DirEntry that lazily iterates a given directory, also provides two ways of foreach iteration. The iteration variable can be of type string if only the name is needed, or DirEntry if additional details are needed. The span mode dictates how the directory is traversed. The name of each iterated directory entry contains the absolute or relative path (depending on pathname).

Note

The order of returned directory entries is as it is provided by the operating system / filesystem, and may not follow any particular sorting.

Example

// Iterate a directory in depth
foreach (string name; dirEntries("destroy/me", SpanMode.depth))
{
    remove(name);
}

// Iterate the current directory in breadth
foreach (string name; dirEntries("", SpanMode.breadth))
{
    writeln(name);
}

// Iterate a directory and get detailed info about it
foreach (DirEntry e; dirEntries("dmd-testing", SpanMode.breadth))
{
    writeln(e.name, "\t", e.size);
}

// Iterate over all *.d files in current directory and all its subdirectories
auto dFiles = dirEntries("", SpanMode.depth).filter!(f => f.name.endsWith(".d"));
foreach (d; dFiles)
    writeln(d.name);

// Hook it up with std.parallelism to compile them all in parallel:
foreach (d; parallel(dFiles, 1)) //passes by 1 file to each thread
{
    string cmd = "dmd -c "  ~ d.name;
    writeln(cmd);
    std.process.executeShell(cmd);
}

// Iterate over all D source files in current directory and all its
// subdirectories
auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth);
foreach (d; dFiles)
    writeln(d.name);

To handle subdirectories with denied read permission, use SpanMode.shallow:

void scan(string path)
{
    foreach (DirEntry entry; dirEntries(path, SpanMode.shallow))
    {
        try
        {
            writeln(entry.name);
            if (entry.isDir)
                scan(entry.name);
        }
        catch (FileException fe) { continue; } // ignore
    }
}

scan("");
@paramuseDIP1000 used to instantiate this function separately for code with and without -preview=dip1000 compiler switch, because it affects the ABI of this function. Set automatically - don't touch.@parampath The directory to iterate over. If empty, the current directory will be iterated.@parampattern Optional string with wildcards, such as "*.d". When present, it is used to filter the results by their file name. The supported wildcard strings are described under globMatch.@parammode Whether the directory's sub-directories should be iterated in depth-first post-order (depth), depth-first pre-order (breadth), or not at all (shallow).@paramfollowSymlink Whether symbolic links which point to directories should be treated as directories and their contents iterated over.@returnsAn input range of DirEntry.@throws
  • FileException if the path directory does not exist or read permission is denied.

  • FileException if mode is not shallow and a subdirectory cannot be read.

dirEntries
,
(alias template) autological_binfmt_magic_match.exists = std.file.exists(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Determine whether the given file (or directory) exists.

@paramname string or range of characters representing the file name@returnstrue if the file name specified as input exists
exists
,
(alias template) autological_binfmt_magic_match.isDir = std.file.isDir(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Returns whether the given file is a directory.

@paramname The path to the file.@returnstrue if name specifies a directory@throwsFileException if the given file does not exist.
isDir
,
(alias template) autological_binfmt_magic_match.readText = std.file.readText(S = string, R)(auto ref R name) if (isSomeString!S && (isSomeFiniteCharInputRange!R || is(StringTypeOf!R)))

Reads and validates (using validate) a text file. S can be an array of any character type. However, no width or endian conversions are performed. So, if the width or endianness of the characters in the given file differ from the width or endianness of the element type of S, then validation will fail.

@paramS the string type of the file@paramname string or range of characters representing the file name@returnsArray of characters read.@throwsFileException if there is an error reading the file, UTFException on UTF decoding error.@seeread for reading a binary file.
readText
,
(enum) std.file.SpanMode

Dictates directory spanning policy for dirEntries (see below).

Examples

import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;
import std.algorithm.sorting : sort;
import std.array : array;
import std.path : buildPath, relativePath;

auto root = deleteme ~ "root";
scope(exit) root.rmdirRecurse;
root.mkdir;

root.buildPath("animals").mkdir;
root.buildPath("animals", "cat").mkdir;

alias removeRoot = (return scope e) => e.relativePath(root);

assert(root.dirEntries(SpanMode.depth).map!removeRoot.equal(
    [buildPath("animals", "cat"), "animals"]));

assert(root.dirEntries(SpanMode.breadth).map!removeRoot.equal(
    ["animals", buildPath("animals", "cat")]));

root.buildPath("plants").mkdir;

assert(root.dirEntries(SpanMode.shallow).array.sort.map!removeRoot.equal(
    ["animals", "plants"]));
SpanMode
;
import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio is publically imported when importing std.stdio.

There are three layers of I/O:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(alias template) autological_binfmt_magic_match.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

Equivalent to writef(fmt, args, '\n').

writefln
,
(alias template) autological_binfmt_magic_match.writeln = std.stdio.writeln(T...)(T args)

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
import
(package) std
std
.
(module) std.string

String handling functions.

Category Functions
Searching
column
indexOf
indexOfAny
indexOfNeither
lastIndexOf
lastIndexOfAny
lastIndexOfNeither
Comparison
isNumeric
Mutation
capitalize
Pruning and Filling
center
chomp
chompPrefix
chop
detabber
detab
entab
entabber
leftJustify
outdent
rightJustify
strip
stripLeft
stripRight
wrap
Substitution
abbrev
soundex
soundexer
succ
tr
translate
Miscellaneous
assumeUTF
fromStringz
lineSplitter
representation
splitLines
toStringz
Objects of types string, wstring, and dstring are value types
and cannot be mutated element-by-element. For using mutation during building
strings, use char[], wchar[], or dchar[]. The xxxstring
types are preferable because they don't exhibit undesired aliasing, thus
making code more robust.

The following functions are publicly imported:

Module Functions
Publicly imported functions
std.algorithm
cmp, std,algorithm,comparison
count, std,algorithm,searching
endsWith, std,algorithm,searching
startsWith, std,algorithm,searching
std.array
join, std,array
replace, std,array
replaceInPlace, std,array
split, std,array
empty, std,array
std.format
format, std,format
sformat, std,format
std.uni
icmp, std,uni
toLower, std,uni
toLowerInPlace, std,uni
toUpper, std,uni
toUpperInPlace, std,uni
There is a rich set of functions for string handling defined in other modules.
Functions related to Unicode and ASCII are found in std.uni
and std.ascii, respectively. Other functions that have a
wider generality than just strings can be found in std.algorithm
and std.range.

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) autological_binfmt_magic_match.representation = std.string.representation(Char)(Char[] s) if (isSomeChar!Char)

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

@params The string to return the representation of.@returnsThe representation of the passed string.
representation
,
(alias template) autological_binfmt_magic_match.strip = std.string.strip(Range)(Range str) if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range))

Strips both leading and trailing whitespace (as defined by isWhite) or as specified in the second argument.

@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
;
/++ A parsed `binfmt_misc` registration. `type` is `M` for magic-and-mask matching or `E` for an extension match; only `M` participates in the byte-level dispatch this catalog cares about, and the kernel rejects a non-empty `offset`/`magic` for `E` rules. +/ struct
(struct) autological_binfmt_magic_match.Registration

A parsed binfmt_misc registration.

type is M for magic-and-mask matching or E for an extension match; only M participates in the byte-level dispatch this catalog cares about, and the kernel rejects a non-empty offset/magic for E rules.

Registration
{
(alias) object.string = string
string
(field) string autological_binfmt_magic_match.Registration.name
name
;
char
(field) char autological_binfmt_magic_match.Registration.type
type
; // 'M' (magic) or 'E' (extension)
(alias) object.size_t = ulong
size_t
(field) ulong autological_binfmt_magic_match.Registration.offset
offset
;
immutable(ubyte)[]
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.magic
magic
;
immutable(ubyte)[]
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.mask
mask
; // empty == all-0xff, i.e. literal
(alias) object.string = string
string
(field) string autological_binfmt_magic_match.Registration.interpreter
interpreter
;
(alias) object.string = string
string
(field) string autological_binfmt_magic_match.Registration.flags
flags
;
/// True when the `F` flag is set — the interpreter is opened at registration /// time and held, so the rule survives a mount-namespace change. bool
bool autological_binfmt_magic_match.Registration.fixBinary() const pure nothrow @nogc @safe

True when the F flag is set — the interpreter is opened at registration time and held, so the rule survives a mount-namespace change.

fixBinary
() const @safe pure nothrow @nogc =>
(field) string autological_binfmt_magic_match.Registration.flags
flags
.
bool autological_binfmt_magic_match.hasFlag(in string flags, char f) pure nothrow @nogc @safe

Case-sensitive flag membership.

hasFlag
('F');
/// True when the `P` flag is set — `argv[0]` is preserved and the original /// path is passed as an extra argument. bool
bool autological_binfmt_magic_match.Registration.preserveArgv0() const pure nothrow @nogc @safe

True when the P flag is set — argv[0] is preserved and the original path is passed as an extra argument.

preserveArgv0
() const @safe pure nothrow @nogc =>
(field) string autological_binfmt_magic_match.Registration.flags
flags
.
bool autological_binfmt_magic_match.hasFlag(in string flags, char f) pure nothrow @nogc @safe

Case-sensitive flag membership.

hasFlag
('P');
/// True when the `C` flag is set — credentials are computed from the binary /// rather than the interpreter, which implies `O`. bool
bool autological_binfmt_magic_match.Registration.credentialsFromBinary() const pure nothrow @nogc @safe

True when the C flag is set — credentials are computed from the binary rather than the interpreter, which implies O.

credentialsFromBinary
() const @safe pure nothrow @nogc =>
(field) string autological_binfmt_magic_match.Registration.flags
flags
.
bool autological_binfmt_magic_match.hasFlag(in string flags, char f) pure nothrow @nogc @safe

Case-sensitive flag membership.

hasFlag
('C');
/// True when the `O` flag is set — the binary is opened and its descriptor /// passed to the interpreter as `/dev/fd/N`. bool
bool autological_binfmt_magic_match.Registration.openBinary() const pure nothrow @nogc @safe

True when the O flag is set — the binary is opened and its descriptor passed to the interpreter as /dev/fd/N.

openBinary
() const @safe pure nothrow @nogc =>
(field) string autological_binfmt_magic_match.Registration.flags
flags
.
bool autological_binfmt_magic_match.hasFlag(in string flags, char f) pure nothrow @nogc @safe

Case-sensitive flag membership.

hasFlag
('O');
} /// Case-sensitive flag membership. private bool
bool autological_binfmt_magic_match.hasFlag(in string flags, char f) pure nothrow @nogc @safe

Case-sensitive flag membership.

hasFlag
(in
(alias) object.string = string
string
(parameter) const(string) flags
flags
, char
(parameter) char f
f
) @safe pure nothrow @nogc
{ foreach (
(parameter) immutable(char) c
c
;
(parameter) const(string) flags
flags
)
if (
(local variable) immutable(char) c
c
==
(parameter) char f
f
)
return true; return false; } /++ Decodes the `\xNN` escaping the kernel accepts in `magic` and `mask`. The kernel's own decoder handles `\x` hex pairs and passes everything else through literally; a lone backslash is not special. Anything that is not a valid hex pair after `\x` is a malformed registration, and the kernel returns `EINVAL` rather than guessing. +/ immutable(ubyte)[]
immutable(ubyte)[] autological_binfmt_magic_match.unescape(string s) pure @safe

Decodes the \xNN escaping the kernel accepts in magic and mask.

The kernel's own decoder handles \x hex pairs and passes everything else through literally; a lone backslash is not special. Anything that is not a valid hex pair after \x is a malformed registration, and the kernel returns EINVAL rather than guessing.

unescape
(
(alias) object.string = string
string
(parameter) string s
s
) @safe pure
{ ubyte[]
(local variable) ubyte[] out_
out_
;
(alias) object.size_t = ulong
size_t
(local variable) ulong i
i
;
while (
(local variable) ulong i
i
<
(parameter) string s
s
.
(field) ulong string.length
length
)
{ if (
(parameter) string s
s
[
(local variable) ulong i
i
] == '\\' &&
(local variable) ulong i
i
+ 3 <
(parameter) string s
s
.
(field) ulong string.length
length
&&
(parameter) string s
s
[
(local variable) ulong i
i
+ 1] == 'x')
{
(local variable) ubyte[] out_
out_
~=
(parameter) string s
s
[
(local variable) ulong i
i
+ 2 ..
(local variable) ulong i
i
+ 4].
ubyte std.conv.to!ubyte.to!(string, int)(string __param_0, int __param_1) pure @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!ubyte(16);
(local variable) ulong i
i
+= 4;
} else {
(local variable) ubyte[] out_
out_
~= cast(ubyte)
(parameter) string s
s
[
(local variable) ulong i
i
];
(local variable) ulong i
i
++;
} } return
(local variable) ubyte[] out_
out_
.
immutable(ubyte)[] object.idup!ubyte(ubyte[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
} /++ Parses one registration line. The delimiter is whatever character follows the leading colon in the kernel's grammar; every real-world registration uses `:`, and that is what is assumed here. Throws on a field count the kernel would reject. +/
(struct) autological_binfmt_magic_match.Registration

A parsed binfmt_misc registration.

type is M for magic-and-mask matching or E for an extension match; only M participates in the byte-level dispatch this catalog cares about, and the kernel rejects a non-empty offset/magic for E rules.

Registration
autological_binfmt_magic_match.Registration autological_binfmt_magic_match.parse(string line) pure @safe

Parses one registration line.

The delimiter is whatever character follows the leading colon in the kernel's grammar; every real-world registration uses :, and that is what is assumed here. Throws on a field count the kernel would reject.

parse
(
(alias) object.string = string
string
(parameter) string line
line
) @safe pure
{ const
(local variable) const(string[]) fields
fields
=
(parameter) string line
line
.
string std.string.strip!string(string str) pure nothrow @nogc @safe

Strips both leading and trailing whitespace (as defined by isWhite) or as specified in the second argument.

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
.
string[] std.array.split!(string, string)(string range, string sep) pure nothrow @safe
split
(":");
// A leading ':' produces an empty first field, so a well-formed line has 8. if (
(local variable) const(string[]) fields
fields
.
(field) ulong const(string[]).length
length
!= 8)
throw new
(class) object.Exception

The base class of all errors that are safe to catch and handle.

In principle, only thrown objects derived from this class are safe to catch inside a catch block. Thrown objects not derived from Exception represent runtime errors that should not be caught, as certain runtime guarantees may not hold, making it unsafe to continue program execution.

Examples

bool gotCaught;
try
{
    throw new Exception("msg");
}
catch (Exception e)
{
    gotCaught = true;
    assert(e.msg == "msg");
}
assert(gotCaught);
Exception
("expected 8 ':'-separated fields, got " ~
(local variable) const(string[]) fields
fields
.
(field) ulong const(string[]).length
length
.
string std.conv.text!ulong(ulong __param_0) pure nothrow @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
~ ": " ~
(parameter) string line
line
);
(struct) autological_binfmt_magic_match.Registration

A parsed binfmt_misc registration.

type is M for magic-and-mask matching or E for an extension match; only M participates in the byte-level dispatch this catalog cares about, and the kernel rejects a non-empty offset/magic for E rules.

Registration
(local variable) autological_binfmt_magic_match.Registration r
r
;
(local variable) autological_binfmt_magic_match.Registration r
r
.
(field) string autological_binfmt_magic_match.Registration.name
name
=
(local variable) const(string[]) fields
fields
[1];
(local variable) autological_binfmt_magic_match.Registration r
r
.
(field) char autological_binfmt_magic_match.Registration.type
type
=
(local variable) const(string[]) fields
fields
[2].
(field) ulong const(string).length
length
?
(local variable) const(string[]) fields
fields
[2][0] : 'M';
(local variable) autological_binfmt_magic_match.Registration r
r
.
(field) ulong autological_binfmt_magic_match.Registration.offset
offset
=
(local variable) const(string[]) fields
fields
[3].
(field) ulong const(string).length
length
?
(local variable) const(string[]) fields
fields
[3].
ulong std.conv.to!ulong.to!string(string __param_0) pure @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.size_t = ulong
size_t
: 0;
(local variable) autological_binfmt_magic_match.Registration r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.magic
magic
=
immutable(ubyte)[] autological_binfmt_magic_match.unescape(string s) pure @safe

Decodes the \xNN escaping the kernel accepts in magic and mask.

The kernel's own decoder handles \x hex pairs and passes everything else through literally; a lone backslash is not special. Anything that is not a valid hex pair after \x is a malformed registration, and the kernel returns EINVAL rather than guessing.

unescape
(
(local variable) const(string[]) fields
fields
[4]);
(local variable) autological_binfmt_magic_match.Registration r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.mask
mask
=
immutable(ubyte)[] autological_binfmt_magic_match.unescape(string s) pure @safe

Decodes the \xNN escaping the kernel accepts in magic and mask.

The kernel's own decoder handles \x hex pairs and passes everything else through literally; a lone backslash is not special. Anything that is not a valid hex pair after \x is a malformed registration, and the kernel returns EINVAL rather than guessing.

unescape
(
(local variable) const(string[]) fields
fields
[5]);
(local variable) autological_binfmt_magic_match.Registration r
r
.
(field) string autological_binfmt_magic_match.Registration.interpreter
interpreter
=
(local variable) const(string[]) fields
fields
[6];
(local variable) autological_binfmt_magic_match.Registration r
r
.
(field) string autological_binfmt_magic_match.Registration.flags
flags
=
(local variable) const(string[]) fields
fields
[7];
return
(local variable) autological_binfmt_magic_match.Registration r
r
;
} /++ The kernel's match predicate, transcribed. Two properties are worth naming because they shape what can be dispatched: `offset` is a *fixed* position — there is no search — and the comparison is `(byte & mask) == (magic & mask)` bytewise, so a mask makes a rule tolerant of fields that vary between otherwise identical binaries (an ELF's `e_machine` being the archetype). +/ bool
bool autological_binfmt_magic_match.matches(in autological_binfmt_magic_match.Registration r, in ubyte[] buf) pure nothrow @nogc @safe

The kernel's match predicate, transcribed.

Two properties are worth naming because they shape what can be dispatched: offset is a fixed position — there is no search — and the comparison is (byte & mask) == (magic & mask) bytewise, so a mask makes a rule tolerant of fields that vary between otherwise identical binaries (an ELF's e_machine being the archetype).

matches
(in
(struct) autological_binfmt_magic_match.Registration

A parsed binfmt_misc registration.

type is M for magic-and-mask matching or E for an extension match; only M participates in the byte-level dispatch this catalog cares about, and the kernel rejects a non-empty offset/magic for E rules.

Registration
(parameter) const(autological_binfmt_magic_match.Registration) r
r
, in ubyte[]
(parameter) const(ubyte[]) buf
buf
) @safe pure nothrow @nogc
{ if (
(parameter) const(autological_binfmt_magic_match.Registration) r
r
.
(field) char autological_binfmt_magic_match.Registration.type
type
!= 'M')
return false; // extension rules do not look at bytes if (
(parameter) const(autological_binfmt_magic_match.Registration) r
r
.
(field) ulong autological_binfmt_magic_match.Registration.offset
offset
+
(parameter) const(autological_binfmt_magic_match.Registration) r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.magic
magic
.
(field) ulong const(immutable(ubyte)[]).length
length
>
(parameter) const(ubyte[]) buf
buf
.
(field) ulong const(ubyte[]).length
length
)
return false; foreach (
(parameter) ulong i
i
,
(parameter) immutable(ubyte) m
m
;
(parameter) const(autological_binfmt_magic_match.Registration) r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.magic
magic
)
{ const
(local variable) const(int) mask
mask
=
(parameter) const(autological_binfmt_magic_match.Registration) r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.mask
mask
.
(field) ulong const(immutable(ubyte)[]).length
length
>
(local variable) ulong i
i
?
(parameter) const(autological_binfmt_magic_match.Registration) r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.mask
mask
[
(local variable) ulong i
i
] : 0xff;
if ((
(parameter) const(ubyte[]) buf
buf
[
(parameter) const(autological_binfmt_magic_match.Registration) r
r
.
(field) ulong autological_binfmt_magic_match.Registration.offset
offset
+
(local variable) ulong i
i
] &
(local variable) const(int) mask
mask
) != (
(local variable) immutable(ubyte) m
m
&
(local variable) const(int) mask
mask
))
return false; } return true; } /// A named specimen buffer. struct
(struct) autological_binfmt_magic_match.Specimen

A named specimen buffer.

Specimen
{
(alias) object.string = string
string
(field) string autological_binfmt_magic_match.Specimen.label
label
;
immutable(ubyte)[]
(field) immutable(ubyte)[] autological_binfmt_magic_match.Specimen.bytes
bytes
;
} /// A 64-bit little-endian ELF header with `e_machine` set to `EM_AARCH64` (183). immutable(ubyte)[]
immutable(ubyte)[] autological_binfmt_magic_match.aarch64Elf() pure @safe

A 64-bit little-endian ELF header with e_machine set to EM_AARCH64 (183).

aarch64Elf
() @safe pure
{ auto
(local variable) ubyte[] b
b
= new ubyte[64];
(local variable) ubyte[] b
b
[0 .. 4] = [0x7f, 'E', 'L', 'F'];
(local variable) ubyte[] b
b
[4] = 2; // ELFCLASS64
(local variable) ubyte[] b
b
[5] = 1; // ELFDATA2LSB
(local variable) ubyte[] b
b
[6] = 1; // EV_CURRENT
(local variable) ubyte[] b
b
[16] = 2; // ET_EXEC
(local variable) ubyte[] b
b
[18] = 183; // e_machine = EM_AARCH64, little-endian
return
(local variable) ubyte[] b
b
.
immutable(ubyte)[] object.idup!ubyte(ubyte[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
} /// The same header, but `e_machine` = `EM_X86_64` (62) — the mask must reject it. immutable(ubyte)[]
immutable(ubyte)[] autological_binfmt_magic_match.x86Elf() pure @safe

The same header, but e_machine = EM_X86_64 (62) — the mask must reject it.

x86Elf
() @safe pure
{ auto
(local variable) ubyte[] b
b
= cast(ubyte[])
immutable(ubyte)[] autological_binfmt_magic_match.aarch64Elf() pure @safe

A 64-bit little-endian ELF header with e_machine set to EM_AARCH64 (183).

aarch64Elf
().
ubyte[] object.dup!ubyte(const(ubyte)[] a) pure nothrow @property @safe
dup
;
(local variable) ubyte[] b
b
[18] = 62;
return
(local variable) ubyte[] b
b
.
immutable(ubyte)[] object.idup!ubyte(ubyte[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
} /// A SQLite header whose `application_id` at offset 68 reads `SELF`. immutable(ubyte)[]
immutable(ubyte)[] autological_binfmt_magic_match.selfDb() pure @safe

A SQLite header whose application_id at offset 68 reads SELF.

selfDb
() @safe pure
{ auto
(local variable) ubyte[] b
b
= new ubyte[100];
(local variable) ubyte[] b
b
[0 .. 16] = "SQLite format 3\0".
immutable(ubyte)[] std.string.representation!(immutable(char))(string s) pure nothrow @nogc @safe

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

Examples

string s = "hello";
static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
assert(representation(s) is cast(immutable(ubyte)[]) s);
assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);
@params The string to return the representation of.@returnsThe representation of the passed string.
representation
;
(local variable) ubyte[] b
b
[16] = 0x10; // page size 4096
(local variable) ubyte[] b
b
[68 .. 72] = "SELF".
immutable(ubyte)[] std.string.representation!(immutable(char))(string s) pure nothrow @nogc @safe

Returns the representation of a string, which has the same type as the string except the character type is replaced by ubyte, ushort, or uint depending on the character width.

Examples

string s = "hello";
static assert(is(typeof(representation(s)) == immutable(ubyte)[]));
assert(representation(s) is cast(immutable(ubyte)[]) s);
assert(representation(s) == [0x68, 0x65, 0x6c, 0x6c, 0x6f]);
@params The string to return the representation of.@returnsThe representation of the passed string.
representation
;
return
(local variable) ubyte[] b
b
.
immutable(ubyte)[] object.idup!ubyte(ubyte[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
} /// An ordinary SQLite database — same magic at 0, nothing at 68. immutable(ubyte)[]
immutable(ubyte)[] autological_binfmt_magic_match.plainDb() pure @safe

An ordinary SQLite database — same magic at 0, nothing at 68.

plainDb
() @safe pure
{ auto
(local variable) ubyte[] b
b
= cast(ubyte[])
immutable(ubyte)[] autological_binfmt_magic_match.selfDb() pure @safe

A SQLite header whose application_id at offset 68 reads SELF.

selfDb
().
ubyte[] object.dup!ubyte(const(ubyte)[] a) pure nothrow @property @safe
dup
;
(local variable) ubyte[] b
b
[68 .. 72] = [0, 0, 0, 0];
return
(local variable) ubyte[] b
b
.
immutable(ubyte)[] object.idup!ubyte(ubyte[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
} /// A ZIP/JAR: local file header magic at offset 0. immutable(ubyte)[]
immutable(ubyte)[] autological_binfmt_magic_match.jar() pure @safe

A ZIP/JAR: local file header magic at offset 0.

jar
() @safe pure
{ immutable(ubyte)[]
(local variable) immutable(ubyte)[] z
z
= [0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00];
return
(local variable) immutable(ubyte)[] z
z
;
} int
int D main()
main
()
{ // Real-shaped registrations. The qemu rule is the standard one shipped by // `qemu-user-static`; the mask lets every other ELF header field vary. const
(local variable) const(autological_binfmt_magic_match.Registration[]) table
table
= [
autological_binfmt_magic_match.Registration autological_binfmt_magic_match.parse(string line) pure @safe

Parses one registration line.

The delimiter is whatever character follows the leading colon in the kernel's grammar; every real-world registration uses :, and that is what is assumed here. Throws on a field count the kernel would reject.

parse
(":qemu-aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00" ~
"\\x02\\x00\\xb7\\x00:" ~ "\\xff\\xff\\xff\\xff\\xff\\xfe\\xfe\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff" ~ "\\xfe\\xff\\xff\\xff:/usr/bin/qemu-aarch64-static:FPO"),
autological_binfmt_magic_match.Registration autological_binfmt_magic_match.parse(string line) pure @safe

Parses one registration line.

The delimiter is whatever character follows the leading colon in the kernel's grammar; every real-world registration uses :, and that is what is assumed here. Throws on a field count the kernel would reject.

parse
(":self:M:68:SELF::/usr/bin/self-exec:F"),
autological_binfmt_magic_match.Registration autological_binfmt_magic_match.parse(string line) pure @safe

Parses one registration line.

The delimiter is whatever character follows the leading colon in the kernel's grammar; every real-world registration uses :, and that is what is assumed here. Throws on a field count the kernel would reject.

parse
(":jar:M::PK\\x03\\x04::/usr/bin/jarwrapper:"),
autological_binfmt_magic_match.Registration autological_binfmt_magic_match.parse(string line) pure @safe

Parses one registration line.

The delimiter is whatever character follows the leading colon in the kernel's grammar; every real-world registration uses :, and that is what is assumed here. Throws on a field count the kernel would reject.

parse
(":python-ext:E::py::/usr/bin/python3:"),
]; const
(local variable) const(autological_binfmt_magic_match.Specimen[]) specimens
specimens
= [
(struct) autological_binfmt_magic_match.Specimen

A named specimen buffer.

Specimen
("aarch64 ELF",
immutable(ubyte)[] autological_binfmt_magic_match.aarch64Elf() pure @safe

A 64-bit little-endian ELF header with e_machine set to EM_AARCH64 (183).

aarch64Elf
()),
(struct) autological_binfmt_magic_match.Specimen

A named specimen buffer.

Specimen
("x86-64 ELF",
immutable(ubyte)[] autological_binfmt_magic_match.x86Elf() pure @safe

The same header, but e_machine = EM_X86_64 (62) — the mask must reject it.

x86Elf
()),
(struct) autological_binfmt_magic_match.Specimen

A named specimen buffer.

Specimen
("SELF database",
immutable(ubyte)[] autological_binfmt_magic_match.selfDb() pure @safe

A SQLite header whose application_id at offset 68 reads SELF.

selfDb
()),
(struct) autological_binfmt_magic_match.Specimen

A named specimen buffer.

Specimen
("plain SQLite db",
immutable(ubyte)[] autological_binfmt_magic_match.plainDb() pure @safe

An ordinary SQLite database — same magic at 0, nothing at 68.

plainDb
()),
(struct) autological_binfmt_magic_match.Specimen

A named specimen buffer.

Specimen
("JAR / ZIP",
immutable(ubyte)[] autological_binfmt_magic_match.jar() pure @safe

A ZIP/JAR: local file header magic at offset 0.

jar
()),
];
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("Registrations parsed from their kernel wire form:");
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
foreach (
(parameter) const(autological_binfmt_magic_match.Registration) r
r
;
(local variable) const(autological_binfmt_magic_match.Registration[]) table
table
)
{
void std.stdio.writefln!(char, string, const(char), const(ulong), ulong, string, string)(in char[] fmt, string __param_1, const(char) __param_2, const(ulong) __param_3, ulong __param_4, string __param_5, string __param_6) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %-14s type=%s offset=%-3s magic=%s bytes mask=%s flags=%s",
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) string autological_binfmt_magic_match.Registration.name
name
,
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) char autological_binfmt_magic_match.Registration.type
type
,
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) ulong autological_binfmt_magic_match.Registration.offset
offset
,
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.magic
magic
.
(field) ulong const(immutable(ubyte)[]).length
length
,
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.mask
mask
.
(field) ulong const(immutable(ubyte)[]).length
length
?
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) immutable(ubyte)[] autological_binfmt_magic_match.Registration.mask
mask
.
(field) ulong const(immutable(ubyte)[]).length
length
.
string std.conv.text!ulong(ulong __param_0) pure nothrow @safe

Convenience functions for converting one or more arguments of any type into text (the three character widths).

text
~ " bytes" : "none (literal)",
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) string autological_binfmt_magic_match.Registration.flags
flags
.
(field) ulong const(string).length
length
?
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) string autological_binfmt_magic_match.Registration.flags
flags
: "(none)");
void std.stdio.writefln!(char, string, string, string, string, string)(in char[] fmt, string __param_1, string __param_2, string __param_3, string __param_4, string __param_5) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" interpreter %s%s%s%s%s",
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
(field) string autological_binfmt_magic_match.Registration.interpreter
interpreter
,
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
bool autological_binfmt_magic_match.Registration.fixBinary() const pure nothrow @nogc @safe

True when the F flag is set — the interpreter is opened at registration time and held, so the rule survives a mount-namespace change.

fixBinary
? " [F: interpreter pinned at registration — works inside containers]" : "",
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
bool autological_binfmt_magic_match.Registration.preserveArgv0() const pure nothrow @nogc @safe

True when the P flag is set — argv[0] is preserved and the original path is passed as an extra argument.

preserveArgv0
? " [P: argv[0] preserved]" : "",
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
bool autological_binfmt_magic_match.Registration.openBinary() const pure nothrow @nogc @safe

True when the O flag is set — the binary is opened and its descriptor passed to the interpreter as /dev/fd/N.

openBinary
? " [O: binary passed as /dev/fd/N]" : "",
(local variable) const(autological_binfmt_magic_match.Registration) r
r
.
bool autological_binfmt_magic_match.Registration.credentialsFromBinary() const pure nothrow @nogc @safe

True when the C flag is set — credentials are computed from the binary rather than the interpreter, which implies O.

credentialsFromBinary
? " [C: credentials from the binary]" : "");
}
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("Match matrix — which rule claims which specimen:");
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
void std.stdio.writefln!(char, string, string)(in char[] fmt, string __param_1, string __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %-18s | %s", "specimen",
(local variable) const(autological_binfmt_magic_match.Registration[]) table
table
.
autological_binfmt_magic_match.main.MapResult!(__lambda_L274_C20, const(Registration)[]) autological_binfmt_magic_match.main.map!(const(autological_binfmt_magic_match.Registration)[])(const(autological_binfmt_magic_match.Registration)[] r) pure nothrow @nogc @safe

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Examples

import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
    chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));

Multiple functions can be passed to map. In that case, the element type of map is a tuple containing one element for each function.

auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];

size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
    assert(result[0] == sums[i]);
    assert(result[1] == products[i]);
    ++i;
}

You may alias map with some function(s) to a symbol and use it separately:

import std.algorithm.comparison : equal;
import std.conv : to;

alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
@paramfun one or more transformation functions@seeMap (higher-order function)@paramr an input range@returnsA range with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.
map
!(r => pad(r.name, 14)).
string[] std.array.array!(autological_binfmt_magic_match.main.MapResult!(__lambda_L274_C20, const(Registration)[]))(autological_binfmt_magic_match.main.MapResult!(__lambda_L274_C20, const(Registration)[]) r) pure @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
.
string autological_binfmt_magic_match.joinWith(string[] parts, string sep) pure @safe

join under a name that does not collide with the std.array overload set.

joinWith
(" "));
void std.stdio.writefln!(char, string, string)(in char[] fmt, string __param_1, string __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %-18s-+-%s", "------------------",
(local variable) const(autological_binfmt_magic_match.Registration[]) table
table
.
autological_binfmt_magic_match.main.MapResult!(__lambda_L276_C20, const(Registration)[]) autological_binfmt_magic_match.main.map!(const(autological_binfmt_magic_match.Registration)[])(const(autological_binfmt_magic_match.Registration)[] r) pure nothrow @nogc @safe

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Examples

import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
    chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));

Multiple functions can be passed to map. In that case, the element type of map is a tuple containing one element for each function.

auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];

size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
    assert(result[0] == sums[i]);
    assert(result[1] == products[i]);
    ++i;
}

You may alias map with some function(s) to a symbol and use it separately:

import std.algorithm.comparison : equal;
import std.conv : to;

alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
@paramfun one or more transformation functions@seeMap (higher-order function)@paramr an input range@returnsA range with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.
map
!(_ => "--------------").
string[] std.array.array!(autological_binfmt_magic_match.main.MapResult!(__lambda_L276_C20, const(Registration)[]))(autological_binfmt_magic_match.main.MapResult!(__lambda_L276_C20, const(Registration)[]) r) pure @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
.
string autological_binfmt_magic_match.joinWith(string[] parts, string sep) pure @safe

join under a name that does not collide with the std.array overload set.

joinWith
("-"));
foreach (
(parameter) const(autological_binfmt_magic_match.Specimen) s
s
;
(local variable) const(autological_binfmt_magic_match.Specimen[]) specimens
specimens
)
void std.stdio.writefln!(char, string, string)(in char[] fmt, string __param_1, string __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %-18s | %s",
(local variable) const(autological_binfmt_magic_match.Specimen) s
s
.
(field) string autological_binfmt_magic_match.Specimen.label
label
,
(local variable) const(autological_binfmt_magic_match.Registration[]) table
table
.
autological_binfmt_magic_match.main.MapResult!(__lambda_L279_C24, const(Registration)[]) autological_binfmt_magic_match.main.map!(const(autological_binfmt_magic_match.Registration)[])(const(autological_binfmt_magic_match.Registration)[] r) pure nothrow @nogc @safe

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Examples

import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
    chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));

Multiple functions can be passed to map. In that case, the element type of map is a tuple containing one element for each function.

auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];

size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
    assert(result[0] == sums[i]);
    assert(result[1] == products[i]);
    ++i;
}

You may alias map with some function(s) to a symbol and use it separately:

import std.algorithm.comparison : equal;
import std.conv : to;

alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
@paramfun one or more transformation functions@seeMap (higher-order function)@paramr an input range@returnsA range with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.
map
!(r => pad(matches(r, s.bytes) ? " ✓" : "", 14)).
string[] std.array.array!(autological_binfmt_magic_match.main.MapResult!(__lambda_L279_C24, const(Registration)[]))(autological_binfmt_magic_match.main.MapResult!(__lambda_L279_C24, const(Registration)[]) r) pure @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
.
string autological_binfmt_magic_match.joinWith(string[] parts, string sep) pure @safe

join under a name that does not collide with the std.array overload set.

joinWith
(" "));
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("Read the `x86-64 ELF` row against the `aarch64 ELF` row: the two buffers");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("differ in exactly one byte (`e_machine`), and the mask is what turns that");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("byte into the decision. Read the `SELF database` row against `plain SQLite`:");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("same magic at offset 0, different byte at offset 68 — a format the kernel");
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("can dispatch without SQLite knowing dispatch exists.");
void std.stdio.writeln!()() @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
// The honest test: run the same parser over whatever this host has registered. enum
(constant) string autological_binfmt_magic_match.main.procDir = "/proc/sys/fs/binfmt_misc"
procDir
= "/proc/sys/fs/binfmt_misc";
version (
linux
linux
)
{ if (!
(constant) string autological_binfmt_magic_match.main.procDir = "/proc/sys/fs/binfmt_misc"
procDir
.
bool std.file.exists!string(string name) nothrow @nogc @safe

Determine whether the given file (or directory) exists.

@paramname string or range of characters representing the file name@returnstrue if the file name specified as input exists
exists
|| !
(constant) string autological_binfmt_magic_match.main.procDir = "/proc/sys/fs/binfmt_misc"
procDir
.
bool std.file.isDir!string(string name) @property @safe

Returns whether the given file is a directory.

@paramname The path to the file.@returnstrue if name specifies a directory@throwsFileException if the given file does not exist.
isDir
)
{
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("SKIP: " ~
(constant) string autological_binfmt_magic_match.main.procDir = "/proc/sys/fs/binfmt_misc"
procDir
~ " is not mounted — no live registrations to parse.");
return 0; }
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("Live registrations on this host, re-parsed through the same code:");
(alias) object.size_t = ulong
size_t
(local variable) ulong seen
seen
;
foreach (
(local variable) std.file.DirEntry entry
entry
;
std.file._DirIterator!true std.file.dirEntries!true(string path, std.file.SpanMode mode, bool followSymlink = true) @safe

Returns an input range of DirEntry that lazily iterates a given directory, also provides two ways of foreach iteration. The iteration variable can be of type string if only the name is needed, or DirEntry if additional details are needed. The span mode dictates how the directory is traversed. The name of each iterated directory entry contains the absolute or relative path (depending on pathname).

Note

The order of returned directory entries is as it is provided by the operating system / filesystem, and may not follow any particular sorting.

Example

// Iterate a directory in depth
foreach (string name; dirEntries("destroy/me", SpanMode.depth))
{
    remove(name);
}

// Iterate the current directory in breadth
foreach (string name; dirEntries("", SpanMode.breadth))
{
    writeln(name);
}

// Iterate a directory and get detailed info about it
foreach (DirEntry e; dirEntries("dmd-testing", SpanMode.breadth))
{
    writeln(e.name, "\t", e.size);
}

// Iterate over all *.d files in current directory and all its subdirectories
auto dFiles = dirEntries("", SpanMode.depth).filter!(f => f.name.endsWith(".d"));
foreach (d; dFiles)
    writeln(d.name);

// Hook it up with std.parallelism to compile them all in parallel:
foreach (d; parallel(dFiles, 1)) //passes by 1 file to each thread
{
    string cmd = "dmd -c "  ~ d.name;
    writeln(cmd);
    std.process.executeShell(cmd);
}

// Iterate over all D source files in current directory and all its
// subdirectories
auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth);
foreach (d; dFiles)
    writeln(d.name);

To handle subdirectories with denied read permission, use SpanMode.shallow:

void scan(string path)
{
    foreach (DirEntry entry; dirEntries(path, SpanMode.shallow))
    {
        try
        {
            writeln(entry.name);
            if (entry.isDir)
                scan(entry.name);
        }
        catch (FileException fe) { continue; } // ignore
    }
}

scan("");

Examples

Duplicate functionality of D1's std.file.listdir():

string[] listdir(string pathname)
{
    import std.algorithm.iteration : map, filter;
    import std.array : array;
    import std.path : baseName;

    return dirEntries(pathname, SpanMode.shallow)
        .filter!(a => a.isFile)
        .map!((return a) => baseName(a.name))
        .array;
}

// Can be safe only with -preview=dip1000
@safe void main(string[] args)
{
    import std.stdio : writefln;

    string[] files = listdir(args[1]);
    writefln("%s", files);
}
@paramuseDIP1000 used to instantiate this function separately for code with and without -preview=dip1000 compiler switch, because it affects the ABI of this function. Set automatically - don't touch.@parampath The directory to iterate over. If empty, the current directory will be iterated.@parampattern Optional string with wildcards, such as "*.d". When present, it is used to filter the results by their file name. The supported wildcard strings are described under globMatch.@parammode Whether the directory's sub-directories should be iterated in depth-first post-order (depth), depth-first pre-order (breadth), or not at all (shallow).@paramfollowSymlink Whether symbolic links which point to directories should be treated as directories and their contents iterated over.@returnsAn input range of DirEntry.@throws
  • FileException if the path directory does not exist or read permission is denied.

  • FileException if mode is not shallow and a subdirectory cannot be read.

dirEntries
(
(constant) string autological_binfmt_magic_match.main.procDir = "/proc/sys/fs/binfmt_misc"
procDir
,
(enum) std.file.SpanMode

Dictates directory spanning policy for dirEntries (see below).

Examples

import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;
import std.algorithm.sorting : sort;
import std.array : array;
import std.path : buildPath, relativePath;

auto root = deleteme ~ "root";
scope(exit) root.rmdirRecurse;
root.mkdir;

root.buildPath("animals").mkdir;
root.buildPath("animals", "cat").mkdir;

alias removeRoot = (return scope e) => e.relativePath(root);

assert(root.dirEntries(SpanMode.depth).map!removeRoot.equal(
    [buildPath("animals", "cat"), "animals"]));

assert(root.dirEntries(SpanMode.breadth).map!removeRoot.equal(
    ["animals", buildPath("animals", "cat")]));

root.buildPath("plants").mkdir;

assert(root.dirEntries(SpanMode.shallow).array.sort.map!removeRoot.equal(
    ["animals", "plants"]));
SpanMode
.
(enum value) std.file.SpanMode.shallow = 0

Only spans one directory.

shallow
))
{ const
(local variable) const(string) base
base
=
(local variable) std.file.DirEntry entry
entry
.
string std.file.DirEntry.name() const pure nothrow @property return scope @safe
name
["/proc/sys/fs/binfmt_misc/".
(constant) ulong "/proc/sys/fs/binfmt_misc/".length = 25LU
length
.. $];
if (
(local variable) const(string) base
base
== "register" ||
(local variable) const(string) base
base
== "status")
continue;
(local variable) ulong seen
seen
++;
const
(local variable) const(string) body_
body_
=
string std.file.readText!(string, string)(string name) @safe

Reads and validates (using validate) a text file. S can be an array of any character type. However, no width or endian conversions are performed. So, if the width or endianness of the characters in the given file differ from the width or endianness of the element type of S, then validation will fail.

Examples

Read file with UTF-8 text.

write(deleteme, "abc"); // deleteme is the name of a temporary file
scope(exit) remove(deleteme);
string content = readText(deleteme);
assert(content == "abc");
@paramS the string type of the file@paramname string or range of characters representing the file name@returnsArray of characters read.@throwsFileException if there is an error reading the file, UTFException on UTF decoding error.@seeread for reading a binary file.
readText
(
(local variable) std.file.DirEntry entry
entry
.
string std.file.DirEntry.name() const pure nothrow @property return scope @safe
name
);
const
(local variable) const(bool) enabled
enabled
=
(local variable) const(string) body_
body_
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

Checks whether the given input range starts with (one of) the given needle(s) or, if no needles are given, if its front element fulfils predicate pred.

For more information about pred see find.

@parampred Predicate to use in comparing the elements of the haystack and the needle(s). Mandatory if no needles are given.@paramdoesThisStart The input range to check.@paramwithOneOfThese The needles against which the range is to be checked, which may be individual elements or input ranges of elements.@paramwithThis The single needle to check, which may be either a single element or an input range of elements.@returns

0 if the needle(s) do not occur at the beginning of the given range; otherwise the position of the matching needle, that is, 1 if the range starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so on.

In the case where doesThisStart starts with multiple of the ranges or elements in withOneOfThese, then the shortest one matches (if there are two which match which are of the same length (e.g. "a" and 'a'), then the left-most of them in the argument list matches).

In the case when no needle parameters are given, return true iff front of doesThisStart fulfils predicate pred.

startsWith
("enabled");
void std.stdio.writefln!(char, string, string)(in char[] fmt, string __param_1, string __param_2) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %-20s %s",
(local variable) const(string) base
base
,
(local variable) const(bool) enabled
enabled
? "enabled" : "disabled");
foreach (
(local variable) string line
line
;
(local variable) const(string) body_
body_
.
std.string.LineSplitter!(Flag.no, string) autological_binfmt_magic_match.lineRange(string s) pure nothrow @nogc @safe

lineSplitter as a named helper, so call sites stay single-expression.

lineRange
.
autological_binfmt_magic_match.main.FilterResult!(__lambda_L310_C52, LineSplitter!(Flag.no, string)) autological_binfmt_magic_match.main.filter!(std.string.LineSplitter!(Flag.no, string))(std.string.LineSplitter!(Flag.no, string) range) pure nothrow @nogc @safe

filter`!(predicate)(`range`)` returns a new `range` containing only elements `x` in range`` for which predicate(x) returns true.

The predicate is passed to unaryFun, and can be either a string, or any callable that can be executed via pred(element).

Examples

import std.algorithm.comparison : equal;
import std.math.operations : isClose;
import std.range;

int[] arr = [ 1, 2, 3, 4, 5 ];

// Filter below 3
auto small = filter!(a => a < 3)(arr);
assert(equal(small, [ 1, 2 ]));

// Filter again, but with Uniform Function Call Syntax (UFCS)
auto sum = arr.filter!(a => a < 3);
assert(equal(sum, [ 1, 2 ]));

// In combination with chain() to span multiple ranges
int[] a = [ 3, -2, 400 ];
int[] b = [ 100, -101, 102 ];
auto r = chain(a, b).filter!(a => a > 0);
assert(equal(r, [ 3, 400, 100, 102 ]));

// Mixing convertible types is fair game, too
double[] c = [ 2.5, 3.0 ];
auto r1 = chain(c, a, b).filter!(a => cast(int) a != a);
assert(isClose(r1, [ 2.5 ]));
@parampredicate Function to apply to each element of range@returnsAn input range that contains the filtered elements. If range is at least a forward range, the return value of filter will also be a forward range.@seeFilter (higher-order function), filterBidirectional@paramrange An input range of elements@returnsA range containing only elements x in range for which predicate(x) returns true.
filter
!(l => l.startsWith("offset ") || l.startsWith("magic ")
|| l.startsWith("mask ") || l.startsWith("interpreter ") || l.startsWith("flags")))
void std.stdio.writefln!(char, string)(in char[] fmt, string __param_1) @safe

Equivalent to writef(fmt, args, '\n').

writefln
(" %s",
(local variable) string line
line
.
string std.string.strip!string(string str) pure nothrow @nogc @safe

Strips both leading and trailing whitespace (as defined by isWhite) or as specified in the second argument.

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
);
} if (
(local variable) ulong seen
seen
== 0)
void std.stdio.writeln!string(string __param_0) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
(" (none registered)");
} else { writeln("SKIP: not Linux — `binfmt_misc` is a Linux facility; the parser above ran anyway."); } return 0; } /// Pads to a fixed display width so the matrix lines up.
(alias) object.string = string
string
string autological_binfmt_magic_match.pad(string s, ulong width) pure @safe

Pads to a fixed display width so the matrix lines up.

pad
(
(alias) object.string = string
string
(parameter) string s
s
,
(alias) object.size_t = ulong
size_t
(parameter) ulong width
width
) @safe pure
{ import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) replicate = std.array.replicate(S)(S s, size_t n) if (isDynamicArray!S)

Params: s = an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) or a dynamic array n = number of times to repeat s

Returns: An array that consists of s repeated n times. This function allocates, fills, and returns a new array.

See_Also: For a lazy version, refer to $(REF repeat, std,range).

replicate
;
import
(package) std
std
.
(module) std.utf

Encode and decode UTF-8, UTF-16 and UTF-32 strings.

UTF character support is restricted to '\u0000' &lt;= character &lt;= '\U0010FFFF'.

Category Functions
Decode decode decodeFront
Lazy decode byCodeUnit byChar byWchar byDchar byUTF
Encode encode toUTF8 toUTF16 toUTF32 toUTFz toUTF16z
Length codeLength count stride strideBack
Index toUCSindex toUTFindex
Validation isValidDchar isValidCodepoint validate
Miscellaneous replacementDchar UseReplacementDchar UTFException

Source

std/utf.d

utf
:
(alias template) count = std.utf.count(C)(const(C)[] str) if (isSomeChar!C)

Returns the total number of code points encoded in str.

    Supercedes: This function supercedes $(LREF toUCSindex).

    Standards: Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252

    Throws:
        `UTFException` if `str` is not well-formed.
count
;
const
(local variable) const(ulong) len
len
=
(parameter) string s
s
.
ulong std.utf.count!char(const(char)[] str) pure nothrow @nogc @safe

Returns the total number of code points encoded in str.

Supercedes

This function supercedes toUCSindex.

Examples

assert(count("") == 0);
assert(count("a") == 1);
assert(count("abc") == 3);
assert(count("\u20AC100") == 4);
@standardsUnicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252@throwsUTFException if str is not well-formed.
count
;
return
(local variable) const(ulong) len
len
>=
(parameter) ulong width
width
?
(parameter) string s
s
:
(parameter) string s
s
~ " ".
string std.array.replicate!string(string s, ulong n) pure nothrow @safe
@params an input range or a dynamic array@paramn number of times to repeat s@returnsAn array that consists of s repeated n times. This function allocates, fills, and returns a new array.@seeFor a lazy version, refer to repeat.
replicate
(
(parameter) ulong width
width
-
(local variable) const(ulong) len
len
);
} /// `join` under a name that does not collide with the `std.array` overload set.
(alias) object.string = string
string
string autological_binfmt_magic_match.joinWith(string[] parts, string sep) pure @safe

join under a name that does not collide with the std.array overload set.

joinWith
(
(alias) object.string = string
string
[]
(parameter) string[] parts
parts
,
(alias) object.string = string
string
(parameter) string sep
sep
) @safe pure
{ import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) join = std.array.join(RoR, R)(RoR ror, R sep) if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && isInputRange!R && (is(immutable(ElementType!(ElementType!RoR)) == immutable(ElementType!R)) || isSomeChar!(ElementType!(ElementType!RoR)) && isSomeChar!(ElementType!R)))

Eagerly concatenates all of the ranges in ror together (with the GC) into one array using sep as the separator if present.

Params: ror = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of input ranges sep = An input range, or a single element, to join the ranges on

Returns: An array of elements

See_Also: For a lazy version, see $(REF joiner, std,algorithm,iteration)

join
;
return
(parameter) string[] parts
parts
.
string std.array.join!(string[], string)(string[] ror, string sep) pure nothrow @safe

Eagerly concatenates all of the ranges in ror together (with the GC) into one array using sep as the separator if present.

@paramror An input range of input ranges@paramsep An input range, or a single element, to join the ranges on@returnsAn array of elements@seeFor a lazy version, see joiner
join
(
(parameter) string sep
sep
);
} /// `lineSplitter` as a named helper, so call sites stay single-expression. private auto
std.string.LineSplitter!(Flag.no, string) autological_binfmt_magic_match.lineRange(string s) pure nothrow @nogc @safe

lineSplitter as a named helper, so call sites stay single-expression.

lineRange
(
(alias) object.string = string
string
(parameter) string s
s
) @safe pure nothrow
{ import
(package) std
std
.
(module) std.string

String handling functions.

Category Functions
Searching
column
indexOf
indexOfAny
indexOfNeither
lastIndexOf
lastIndexOfAny
lastIndexOfNeither
Comparison
isNumeric
Mutation
capitalize
Pruning and Filling
center
chomp
chompPrefix
chop
detabber
detab
entab
entabber
leftJustify
outdent
rightJustify
strip
stripLeft
stripRight
wrap
Substitution
abbrev
soundex
soundexer
succ
tr
translate
Miscellaneous
assumeUTF
fromStringz
lineSplitter
representation
splitLines
toStringz
Objects of types string, wstring, and dstring are value types
and cannot be mutated element-by-element. For using mutation during building
strings, use char[], wchar[], or dchar[]. The xxxstring
types are preferable because they don't exhibit undesired aliasing, thus
making code more robust.

The following functions are publicly imported:

Module Functions
Publicly imported functions
std.algorithm
cmp, std,algorithm,comparison
count, std,algorithm,searching
endsWith, std,algorithm,searching
startsWith, std,algorithm,searching
std.array
join, std,array
replace, std,array
replaceInPlace, std,array
split, std,array
empty, std,array
std.format
format, std,format
sformat, std,format
std.uni
icmp, std,uni
toLower, std,uni
toLowerInPlace, std,uni
toUpper, std,uni
toUpperInPlace, std,uni
There is a rich set of functions for string handling defined in other modules.
Functions related to Unicode and ASCII are found in std.uni
and std.ascii, respectively. Other functions that have a
wider generality than just strings can be found in std.algorithm
and std.range.

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) lineSplitter = std.string.lineSplitter(Flag keepTerm = No.keepTerminator, Range)(Range r) if (hasSlicing!Range && hasLength!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)

Split an array or slicable range of characters into a range of lines using '\r', '\n', '\v', '\f', "\r\n", $(REF lineSep, std,uni), $(REF paraSep, std,uni) and '\u0085' (NEL) as delimiters. If keepTerm is set to Yes.keepTerminator, then the delimiter is included in the slices returned.

    Does not throw on invalid UTF; such is simply passed unchanged
    to the output.

    Adheres to $(HTTP www.unicode.org/versions/Unicode7.0.0/ch05.pdf, Unicode 7.0).

    Does not allocate memory.

Params: r = array of chars, wchars, or dchars or a slicable range keepTerm = whether delimiter is included or not in the results Returns: range of slices of the input range r

See_Also: $(LREF splitLines) $(REF splitter, std,algorithm) $(REF splitter, std,regex)

lineSplitter
;
return
(parameter) string s
s
.
std.string.LineSplitter!(Flag.no, string) std.string.lineSplitter!(Flag.no, immutable(char))(string r) pure nothrow @nogc @safe

Split an array or slicable range of characters into a range of lines using '\r', '\n', '\v', '\f', "\r\n", lineSep, paraSep and '\u0085' (NEL) as delimiters. If keepTerm is set to Yes.keepTerminator, then the delimiter is included in the slices returned.

Does not throw on invalid UTF; such is simply passed unchanged to the output.

Adheres to Unicode 7.0.

Does not allocate memory.

Examples

import std.array : array;

string s = "Hello\nmy\rname\nis";

/* notice the call to 'array' to turn the lazy range created by
lineSplitter comparable to the string[] created by splitLines.
*/
assert(lineSplitter(s).array == splitLines(s));
auto s = "\rpeter\n\rpaul\r\njerry\u2028ice\u2029cream\n\nsunday\nmon\u2030day\n";
auto lines = s.lineSplitter();
static immutable witness = ["", "peter", "", "paul", "jerry", "ice", "cream", "", "sunday", "mon\u2030day"];
uint i;
foreach (line; lines)
{
    assert(line == witness[i++]);
}
assert(i == witness.length);
@paramr array of chars, wchars, or dchars or a slicable range@paramkeepTerm whether delimiter is included or not in the results@returnsrange of slices of the input range r@seesplitLines splitter splitter
lineSplitter
;
}